Version 2.2.0

Merge commit 'f2255563431b5ec71194d959c3ff74d0f824b36e' into stable
diff --git a/.gitignore b/.gitignore
index 3e23d6d..2e3efaa3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@
 .idea
 CMakeLists.txt
 .clang_complete
+cmake-build-debug
 
 # VSCode project files
 .vscode
@@ -49,6 +50,9 @@
 # GDB files
 .gdb_history
 
+# https://github.com/Dart-Code/Dart-Code/issues/1295
+analysis_options.yaml
+
 # Built by chromebot and downloaded from Google Storage
 client/tests/drt
 
diff --git a/.packages b/.packages
index 597ffb9..a686ef2 100644
--- a/.packages
+++ b/.packages
@@ -8,6 +8,7 @@
 #
 analysis_server:pkg/analysis_server/lib
 analysis_server_client:pkg/analysis_server_client/lib
+analysis_tool:pkg/analysis_tool/lib
 analyzer:pkg/analyzer/lib
 analyzer_cli:pkg/analyzer_cli/lib
 analyzer_fe_comparison:pkg/analyzer_fe_comparison/lib
@@ -20,7 +21,6 @@
 boolean_selector:third_party/pkg/boolean_selector/lib
 build_integration:pkg/build_integration/lib
 charcode:third_party/pkg/charcode/lib
-charted:third_party/observatory_pub_packages/packages/charted/lib
 cli_util:third_party/pkg/cli_util/lib
 collection:third_party/pkg/collection/lib
 compiler:pkg/compiler/lib
@@ -36,10 +36,8 @@
 dev_compiler:pkg/dev_compiler/lib
 diagnostic:pkg/diagnostic/lib
 expect:pkg/expect/lib
-file:third_party/pkg/file/packages/file/lib
 fixnum:third_party/pkg/fixnum/lib
 front_end:pkg/front_end/lib
-func:third_party/pkg/func/lib
 gardening:tools/gardening/lib
 glob:third_party/pkg/glob/lib
 html:third_party/pkg/html/lib
@@ -63,22 +61,18 @@
 meta:pkg/meta/lib
 mime:third_party/pkg/mime/lib
 mockito:third_party/pkg/mockito/lib
-mustache4dart:third_party/pkg/mustache4dart/lib
+mustache:third_party/pkg/mustache/lib
 oauth2:third_party/pkg/oauth2/lib
 observatory:runtime/observatory/lib
 package_config:third_party/pkg_tested/package_config/lib
 package_resolver:third_party/pkg_tested/package_resolver/lib
 path:third_party/pkg/path/lib
-petitparser:third_party/pkg/petitparser/lib
-platform:third_party/pkg/platform/lib
 plugin:third_party/pkg/plugin/lib
 pool:third_party/pkg/pool/lib
-process:third_party/pkg/process/lib
 protobuf:third_party/pkg/protobuf/lib
 pub:third_party/pkg/pub/lib
 pub_semver:third_party/pkg/pub_semver/lib
 quiver:third_party/pkg/quiver/lib
-quiver_hashcode:third_party/pkg/quiver_hashcode/lib
 resource:third_party/pkg/resource/lib
 sdk_library_metadata:sdk/lib/_internal/sdk_library_metadata/lib
 shelf:third_party/pkg/shelf/lib
diff --git a/BUILD.gn b/BUILD.gn
index 27a1cf8..6d899ee 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -46,6 +46,9 @@
     "runtime/bin:run_vm_tests",
     "runtime/bin:sample_extension",
     "runtime/bin:test_extension",
+    "runtime/bin:entrypoints_verification_test_extension",
+    "runtime/bin:ffi_test_dynamic_library",
+    "runtime/bin:ffi_test_functions",
     "runtime/vm:kernel_platform_files($host_toolchain)",
     "utils/kernel-service:kernel-service",
   ]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43f645a..1289493 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,79 @@
+## 2.2.0 - 2019-02-26
+
+### Language
+
+Sets now have a literal syntax like lists and maps do:
+
+```dart
+var set = {1, 2, 3};
+```
+
+Using curly braces makes empty sets ambiguous with maps:
+
+```dart
+var collection = {}; // Empty set or map?
+```
+
+To avoid breaking existing code, an ambiguous literal is treated as a map.
+To create an empty set, you can rely on either a surrounding context type
+or an explicit type argument:
+
+```dart
+// Variable type forces this to be a set:
+Set<int> set = {};
+
+// A single type argument means this must be a set:
+var set2 = <int>{};
+```
+
+Set literals are released on all platforms. The `set-literals` experiment flag
+has been disabled.
+
+### Tools
+
+#### Analyzer
+
+*   The `DEPRECATED_MEMBER_USE` hint was split into two hints:
+
+    *   `DEPRECATED_MEMBER_USE` reports on usage of `@deprecated` members
+        declared in a different package.
+    *   `DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE` reports on usage of
+        `@deprecated` members declared in the same package.
+
+#### Linter
+
+Upgraded the linter to `0.1.82` which adds the following improvements:
+
+*   Added `provide_deprecation_message`, and
+    `use_full_hex_values_for_flutter_colors`, `prefer_null_aware_operators`.
+*   Fixed `prefer_const_declarations` set literal false-positives.
+*   Updated `prefer_collection_literals` to support set literals.
+*   Updated `unnecessary_parenthesis` play nicer with cascades.
+*   Removed deprecated lints from the "all options" sample.
+*   Stopped registering "default lints".
+*   Fixed `hash_and_equals` to respect `hashCode` fields.
+
+### Other libraries
+
+#### `package:kernel`
+
+*   **Breaking change:** The `klass` getter on the `InstanceConstant` class in
+    the Kernel AST API has been renamed to `classNode` for consistency.
+
+*   **Breaking change:** Updated `Link` implementation to utilize true symbolic
+    links instead of junctions on Windows. Existing junctions will continue to
+    work with the new `Link` implementation, but all new links will create
+    symbolic links.
+
+    To create a symbolic link, Dart must be run with administrative privileges
+    or Developer Mode must be enabled, otherwise a `FileSystemException` will be
+    raised with errno set to `ERROR_PRIVILEGE_NOT_HELD` (Issue [33966]).
+
+[33966]: https://github.com/dart-lang/sdk/issues/33966
+
 ## 2.1.1 - 2019-02-18
 
-This is a minor version release. Again, the team's focus was mostly on improving
+This is a patch version release. Again, the team's focus was mostly on improving
 performance and stability after the large changes in Dart 2.0.0. In particular,
 dart2js now always uses the "fast startup" emitter and the old emitter has been
 removed.
@@ -2783,7 +2856,7 @@
     people in practice.
 
   * **Breaking:** Support for `barback` versions prior to 0.15.0 (released July
-    2014) has been dropped. Pub will no longer install these older barback
+    1)    has been dropped. Pub will no longer install these older barback
     versions.
 
   * `pub serve` now GZIPs the assets it serves to make load times more similar
diff --git a/DEPS b/DEPS
index ae2451a..e8098e9 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
-  "co19_2_rev": "9c03cd19b61a9307db192f174a7e7a1ec6759bb2",
+  "co19_2_rev": "31f7dc1e222910ce64ab57ffee286382b03446a4",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
   # should be kept up to date with the revisions pulled by the Flutter engine.
@@ -81,13 +81,11 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "1.2.2",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "v0.27.0",
-  "file_rev": "515ed1dd48740ab14b625de1be464cb2bca4fefd",  # 5.0.6
+  "dartdoc_tag" : "v0.28.1+2",
   "fixnum_tag": "0.10.9",
-  "func_rev": "25eec48146a58967d75330075ab376b3838b18a8",
   "glob_tag": "1.1.7",
   "html_tag" : "0.13.3+2",
-  "http_io_rev": "265e90afbffacb7b2988385d4a6aa2f14e970d44",
+  "http_io_rev": "57da05a66f5bf7df3dd7aebe7b7efe0dfc477baa",
   "http_multi_server_tag" : "2.0.5",
   "http_parser_tag" : "3.1.1",
   "http_retry_tag": "0.1.1",
@@ -97,23 +95,22 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.78",
+  "linter_tag": "0.1.82",
   "logging_tag": "0.11.3+2",
+  "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.0.2",
   "matcher_tag": "0.12.3",
   "mime_tag": "0.9.6+2",
   "mockito_tag": "d39ac507483b9891165e422ec98d9fb480037c8b",
-  "mustache4dart_tag" : "v2.1.2",
+  "mustache_tag" : "5e81b12215566dbe2473b2afd01a8a8aedd56ad9",
   "oauth2_tag": "1.2.1",
   "observatory_pub_packages_rev": "0894122173b0f98eb08863a7712e78407d4477bc",
   "package_config_tag": "1.0.5",
   "package_resolver_tag": "1.0.4",
   "path_tag": "1.6.2",
-  "platform_rev": "c368ca95775a4ec8d0b60899ce51299a9fbda399", # 2.2.0
   "plugin_tag": "f5b4b0e32d1406d62daccea030ba6457d14b1c47",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "1.3.6",
-  "process_rev": "b8d73f0bad7be5ab5130baf10cd042aae4366d7c", # 3.0.5
   "protobuf_tag": "0.9.0",
   "pub_rev": "9f00679ef47bc79cadc18e143720ade6c06c0100",
   "pub_semver_tag": "1.4.2",
@@ -180,6 +177,10 @@
       "dep_type": "cipd",
   },
 
+  Var("dart_root") + "/third_party/markupsafe":
+      Var("chromium_git") + "/chromium/src/third_party/markupsafe.git" +
+      "@" + Var("markupsafe_rev"),
+
   Var("dart_root") + "/third_party/zlib":
       Var("chromium_git") + "/chromium/src/third_party/zlib.git" +
       "@" + Var("zlib_rev"),
@@ -248,12 +249,8 @@
       Var("dart_git") + "dart2js_info.git" + "@" + Var("dart2js_info_tag"),
   Var("dart_root") + "/third_party/pkg/dartdoc":
       Var("dart_git") + "dartdoc.git" + "@" + Var("dartdoc_tag"),
-  Var("dart_root") + "/third_party/pkg/file":
-      Var("dart_git") + "file.dart.git" + "@" + Var("file_rev"),
   Var("dart_root") + "/third_party/pkg/fixnum":
       Var("dart_git") + "fixnum.git" + "@" + Var("fixnum_tag"),
-  Var("dart_root") + "/third_party/pkg/func":
-      Var("dart_git") + "func.git" + "@" + Var("func_rev"),
   Var("dart_root") + "/third_party/pkg/glob":
       Var("dart_git") + "glob.git" + "@" + Var("glob_tag"),
   Var("dart_root") + "/third_party/pkg/html":
@@ -289,10 +286,10 @@
       Var("dart_git") + "mime.git" + "@" + Var("mime_tag"),
   Var("dart_root") + "/third_party/pkg/mockito":
       Var("dart_git") + "mockito.git" + "@" + Var("mockito_tag"),
-  Var("dart_root") + "/third_party/pkg/mustache4dart":
-      Var("chromium_git")
-      + "/external/github.com/valotas/mustache4dart.git"
-      + "@" + Var("mustache4dart_tag"),
+  Var("dart_root") + "/third_party/pkg/mustache":
+      Var("dart_git")
+      + "external/github.com/xxgreg/mustache"
+      + "@" + 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":
@@ -306,14 +303,10 @@
       + "@" + Var("package_resolver_tag"),
   Var("dart_root") + "/third_party/pkg/path":
       Var("dart_git") + "path.git" + "@" + Var("path_tag"),
-  Var("dart_root") + "/third_party/pkg/platform":
-      Var("dart_git") + "platform.dart.git" + "@" + Var("platform_rev"),
   Var("dart_root") + "/third_party/pkg/plugin":
       Var("dart_git") + "plugin.git" + "@" + Var("plugin_tag"),
   Var("dart_root") + "/third_party/pkg/pool":
       Var("dart_git") + "pool.git" + "@" + Var("pool_tag"),
-  Var("dart_root") + "/third_party/pkg/process":
-      Var("dart_git") + "process.dart.git" + "@" + Var("process_rev"),
   Var("dart_root") + "/third_party/pkg/protobuf":
       Var("dart_git") + "protobuf.git" + "@" + Var("protobuf_tag"),
   Var("dart_root") + "/third_party/pkg/pub_semver":
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index f7291e8..8bf1471 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -22,6 +22,8 @@
   upstream = input_api.change._upstream
   unformatted_files = []
   for git_file in input_api.AffectedTextFiles():
+    if git_file.LocalPath().startswith("pkg/front_end/testcases/"):
+      continue
     filename = git_file.AbsoluteLocalPath()
     if filename.endswith(extension) and hasFormatErrors(filename=filename):
       old_version_has_errors = False
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 6edb3b3..0a6a259 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -91,6 +91,11 @@
       ldflags += [ "-Wl,--fatal-warnings" ]
     }
 
+    # Enable mitigations for Cortex-A53 Erratum #843419 bug.
+    if (current_cpu == "arm64" && is_clang) {
+      ldflags += [ "-Wl,--fix-cortex-a53-843419" ]
+    }
+
     # Common options for AddressSanitizer, LeakSanitizer, ThreadSanitizer and
     # MemorySanitizer
     if (using_sanitizer) {
diff --git a/dartdoc_options.yaml b/dartdoc_options.yaml
deleted file mode 100644
index 6c233f4..0000000
--- a/dartdoc_options.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-dartdoc:
-  categoryOrder: ["Core", VM", "Web"]
diff --git a/docs/language/dart.sty b/docs/language/dart.sty
index 0776ec0..0ad847e 100644
--- a/docs/language/dart.sty
+++ b/docs/language/dart.sty
@@ -96,7 +96,7 @@
 
 % Auxiliary functions.
 \newcommand{\flatten}[1]{\ensuremath{\mbox{\it flatten}({#1})}}
-\newcommand{\basetype}[1]{\ensuremath{\mbox{\it basetype}({#1})}}
+\newcommand{\futureOrBase}[1]{\ensuremath{\mbox{\it futureOrBase}({#1})}}
 \newcommand{\overrides}[1]{\ensuremath{\mbox{\it overrides}({#1})}}
 \newcommand{\inherited}[1]{\ensuremath{\mbox{\it inherited}({#1})}}
 
@@ -133,6 +133,11 @@
 \newcommand{\IndexCustom}[2]{%
   \leavevmode\marginpar{\ensuremath{\diamond}}\emph{#1}\index{#2}}
 
+% Used when one concept should have >1 entry in the index. Does not add
+% the diamond in the margin and shows no text where the command occurs.
+% Intended to be used immediately after another \Index... command.
+\newcommand{\IndexExtraEntry}[1]{\index{#1}}
+
 % Used for a defining occurrence of a phrase, adding it to the index.
 \newcommand{\Index}[1]{\IndexCustom{#1}{#1}}
 
@@ -184,10 +189,15 @@
   {#1}_1\FunctionTypeExtends{#2}_1,\,\ldots,\ %
   {#1}_{#3}\FunctionTypeExtends{#2}_{#3}}}
 
-% Used to specify non-generic function types: Same syntax as in source.
+% Used to specify simple non-generic function types: Same syntax as in source.
 % Arguments: Return type, formal parameter declarations.
 \newcommand{\FunctionTypeSimple}[2]{\code{\ensuremath{#1}\ \FUNCTION({#2})}}
 
+% Used to specify simple generic function types: Same syntax as in source.
+% Arguments: Return type, formal parameter declarations.
+\newcommand{\FunctionTypeSimpleGeneric}[3]{\code{%
+  \ensuremath{#1}\ \FUNCTION<{#2}>({#3})}}
+
 % Used to specify function types: Same syntax as in source.
 % Arguments: Return type, spacer, type parameter name, bound name,
 %   number of type parameters, formal parameter declarations.
@@ -237,13 +247,13 @@
 %   name of optional parameters, number of optional parameters.
 \newcommand{\FunctionTypeNamed}[9]{%
   \FunctionType{#1}{#2}{#3}{#4}{#5}{%
-    \FunctionTypePositionalArguments{#6}{#7}{#8}{#9}}}
+    \FunctionTypeNamedArguments{#6}{#7}{#8}{#9}}}
 
 % Same as \FunctionType except suitable for inline usage, hence omitting
 % the spacer argument.
 \newcommand{\RawFunctionTypeNamed}[8]{%
   \RawFunctionType{#1}{#2}{#3}{#4}{%
-    \FunctionTypePositionalArguments{#5}{#6}{#7}{#8}}}
+    \FunctionTypeNamedArguments{#5}{#6}{#7}{#8}}}
 
 % Used to specify function types with no optional parameters:
 % Arguments: Return type, spacer, type parameter name, bound name,
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 2202ec5..04bdb83 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -732,10 +732,10 @@
 A static warning must be reported by a Dart compiler before the associated code is executed.
 
 \LMHash{}%
-When this specification says that a \Index{run-time error} occurs,
+When this specification says that a \Index{dynamic error} occurs,
 it means that a corresponding error object is thrown.
 When it says that a \Index{dynamic type error} occurs,
-it represents a failed run-time type check,
+it represents a failed type check at run time,
 and the object which is thrown implements \code{TypeError}.
 
 \LMHash{}%
@@ -944,6 +944,7 @@
 that has been initialized by means of an initializing formal of a constructor $k$
 is also initialized in the initializer list of $k$ (\ref{initializerLists}).
 
+%% TODO(eernst): Not quite true, because of special lookup for assignment!
 A static final variable $v$ does not induce a setter,
 so unless a setter named \code{$v$=} is in scope
 it is a compile-time error to assign to $v$.
@@ -956,6 +957,7 @@
 but initialization and assignment is not the same thing.
 When the receiver has type \DYNAMIC{}
 such an assignment is not a compile-time error,
+% This error can occur because the receiver is dynamic.
 but if there is no setter it will cause a dynamic error.
 }
 
@@ -1002,8 +1004,9 @@
 }
 
 \LMHash{}%
-It is a dynamic type error if $o$ is not the null object (\ref{null})
-and the dynamic type of $o$ is not
+% This error can occur due to implicit casts, and
+% for instance variables also when a setter is called dynamically.
+It is a dynamic type error if the dynamic type of $o$ is not
 a subtype of the actual type of the variable $v$
 (\ref{actualTypeOfADeclaration}).
 
@@ -1584,8 +1587,10 @@
 
 \LMHash{}%
 In this specification,
-the notation used to denote the type of a function follows
-the syntax of the language, except that \EXTENDS{} is abbreviated to
+the notation used to denote the type of a function,
+that is, a \Index{function type},
+follows the syntax of the language,
+except that \EXTENDS{} is abbreviated to
 \FunctionTypeExtends.
 This means that every function type is of one of the forms
 \FunctionTypePositionalStd{T_0}
@@ -1594,7 +1599,8 @@
 \noindent
 where $T_0$ is the return type,
 $X_j$ are the formal type parameters with bounds $B_j$, $j \in 1 .. s$,
-$T_j$ are the formal parameter types for $j \in 1 .. n + k$.
+$T_j$ are the formal parameter types for $j \in 1 .. n + k$,
+and $x_{n+j}$ are the names of named parameters for $j \in 1 .. k$.
 Non-generic function types are covered by the case $s = 0$,
 where the type parameter declaration list
 \code{<\ldots{}>}
@@ -1664,7 +1670,8 @@
 type parameters \TypeParametersStd,
 required formal parameter types \List{T}{1}{n},
 return type $T_0$,
-and named parameters \PairList{T}{x}{n+1}{n+k}.
+and named parameters \PairList{T}{x}{n+1}{n+k},
+where $x_{n+j}$, $j \in 1 .. k$ may or may not have a default value.
 Then the static type of $F$ is
 \FunctionTypeNamedStd{T_0}.
 
@@ -1684,12 +1691,12 @@
 $u$ is a class that implements the built-in class \FUNCTION{};
 $u$ is a subtype of $t$;
 and $u$ is not a subtype of any function type which is a proper subtype of $t$.
-\commentary{
+\commentary{%
 If we had omitted the last requirement then
 \code{f \IS{} int\,\FUNCTION([int])}
 could evaluate to \TRUE{} with the declaration
 \code{\VOID{} f()\,\{\}},
-e.g., by letting $u$ be \code{Null}.
+which is obviously not the intention.%
 }
 
 \rationale{
@@ -1746,12 +1753,10 @@
 
 \begin{grammar}
 <classDefinition> ::= <metadata> \ABSTRACT{}? \CLASS{} <identifier> <typeParameters>?
-  \gnewline{} <superclass>? <mixins>? <interfaces>?
+  \gnewline{} <superclass>? <interfaces>?
   \gnewline{} `{' (<metadata> <classMemberDefinition>)* `}'
   \alt <metadata> \ABSTRACT{}? \CLASS{} <mixinApplicationClass>
 
-<mixins> ::= \WITH{} <typeNotVoidList>
-
 <typeNotVoidList> ::= <typeNotVoid> (`,' <typeNotVoid>)*
 
 <classMemberDefinition> ::= <declaration> `;'
@@ -1768,10 +1773,10 @@
   \alt <constructorSignature> (<redirection> | <initializers>)?
   \alt \EXTERNAL{} <constantConstructorSignature>
   \alt \EXTERNAL{} <constructorSignature>
-  \alt ((\EXTERNAL{} \STATIC{}?))? <getterSignature>
-  \alt ((\EXTERNAL{} \STATIC{}?))? <setterSignature>
+  \alt (\EXTERNAL{} \STATIC{}?)? <getterSignature>
+  \alt (\EXTERNAL{} \STATIC{}?)? <setterSignature>
   \alt \EXTERNAL{}? <operatorSignature>
-  \alt ((\EXTERNAL{} \STATIC{}?))? <functionSignature>
+  \alt (\EXTERNAL{} \STATIC{}?)? <functionSignature>
   \alt \STATIC{} (\FINAL{} | \CONST{}) <type>? <staticFinalDeclarationList>
   \alt \FINAL{} <type>? <initializedIdentifierList>
   \alt (\STATIC{} | \COVARIANT{})? (\VAR{} | <type>) <initializedIdentifierList>
@@ -1883,15 +1888,12 @@
 (in which case it will be overridden by another \code{noSuchMethod} forwarder).
 }
 
-% making an exception for the setters generated for final fields is tempting but problematic.
-% If a super type defines a setter, it will be overridden yet have no impact on the interface.
-% Maybe the final field hides the setter in scope?
-% I think the original rules were best.
-
 \commentary{
 It is a compile-time error if a class declares two members of the same name,
-either because it declares the same name twice in the same scope (\ref{scoping}),
-or because it declares a static member and an instance member with the same name
+either because it declares the same name twice in the same scope
+(\ref{scoping}),
+or because it declares a static member and an instance member
+with the same name
 (\ref{classMemberConflicts}).
 }
 
@@ -2030,71 +2032,72 @@
 
 \LMHash{}%
 The following names are allowed for user-defined operators:
-\syntax{`<'},
-\syntax{`>'},
-\syntax{`<='},
-\syntax{`>='},
-\syntax{`=='},
-\syntax{`-'},
-\syntax{`+'},
-\syntax{`/'},
-\syntax{`~'},
-\syntax{`*'},
-\syntax{`\%'},
-\syntax{`|'},
-\syntax{`^'},
-\syntax{`\&'},
-\syntax{`\ltlt'},
-\syntax{`\gtgt'},
-\syntax{`\gtgtgt'},
-\syntax{`[]='},
-\syntax{`[]'},
-\syntax{`~'}.
+\lit{<},
+\lit{>},
+\lit{<=},
+\lit{>=},
+\lit{==},
+\lit{-},
+\lit{+},
+\lit{/},
+\lit{\~{}/},
+\lit{*},
+\lit{\%},
+\lit{|},
+\lit{\^},
+\lit{\&},
+\lit{\ltlt},
+\lit{\gtgt},
+\lit{\gtgtgt},
+\lit{[]=},
+\lit{[]},
+\lit{\~{}}.
 
 \LMHash{}%
 It is a compile-time error if the arity of the user-declared operator
-\syntax{`[]='} is not 2.
+\lit{[]=} is not 2.
 It is a compile-time error if the arity of a user-declared operator with one of the names:
-\syntax{`<'},
-\syntax{`>'},
-\syntax{`<='},
-\syntax{`>='},
-\syntax{`=='},
-\syntax{`-'},
-\syntax{`+'},
-\syntax{`~/'},
-\syntax{`/'},
-\syntax{`*'},
-\syntax{`\%'},
-\syntax{`|'},
-\syntax{`^'},
-\syntax{`\&'},
-\syntax{`\ltlt'},
-\syntax{`\gtgt'},
-\syntax{`\gtgtgt'},
-\syntax{`[]'}
+\lit{<},
+\lit{>},
+\lit{<=},
+\lit{>=},
+\lit{==},
+\lit{-},
+\lit{+},
+\lit{\~{}/},
+\lit{/},
+\lit{*},
+\lit{\%},
+\lit{|},
+\lit{\^},
+\lit{\&},
+\lit{\ltlt},
+\lit{\gtgt},
+\lit{\gtgtgt},
+\lit{[]}
 is not 1.
 It is a compile-time error if the arity of the user-declared operator
-\syntax{`-'}
+\lit{-}
 is not 0 or 1.
 
 \commentary{
-The \syntax{`-'} operator is unique
+The \lit{-} operator is unique
 in that two overloaded versions are permitted.
 If the operator has no arguments, it denotes unary minus.
 If it has an argument, it denotes binary subtraction.
 }
 
 \LMHash{}%
-The name of the unary operator \syntax{`-'} is \code{unary-}.
+The name of the unary operator \lit{-} is \code{unary-}.
 
 \rationale{
-This device allows the two methods to be distinguished for purposes of method lookup, override and reflection.
+This device allows the two methods to be distinguished
+for purposes of method lookup, override and reflection.
 }
 
 \LMHash{}%
 It is a compile-time error if the arity of the user-declared operator
-\syntax{`~'}
+\lit{\~{}}
 is not 0.
 
 \LMHash{}%
@@ -2102,25 +2105,26 @@
 
 \LMHash{}%
 It is a static warning if the return type of a user-declared operator
-\syntax{`[]='}
+\lit{[]=}
 is explicitly declared and not \VOID{}.
 
 \commentary{
 If no return type is specified for a user-declared operator
-\syntax{`[]='},
+\lit{[]=},
 its return type is \VOID{} (\ref{typeOfAFunction}).
 }
 
 \rationale{
 The return type is \VOID{} because
 a return statement in an implementation of operator
-\syntax{`[]='}
+\lit{[]=}
 does not return a value.
-Consider a non-throwing evaluation of an expression $e$ of the form \code{$e_1$[$e_2$] = $e_3$},
+Consider a non-throwing evaluation of an expression $e$ of the form
+\code{$e_1$[$e_2$] = $e_3$},
 and assume that the evaluation of $e_3$ yields an instance $o$.
 $e$ will then evaluate to $o$,
 and even if the executed body of operator
-\syntax{`[]='}
+\lit{[]=}
 completes with a value $o'$,
 that is, if $o'$ is returned, that value is simply ignored.
 The rationale for this behavior is that assignments should be guaranteed to evaluate to the assigned value.
@@ -2420,6 +2424,61 @@
 \end{dartCode}
 
 
+\subsubsection{The Operator `=='}
+\LMLabel{theOperatorEqualsEquals}
+
+\LMHash{}%
+The operator \lit{==} is used implicitly in certain situations,
+and in particular constant expressions
+(\ref{constants})
+give rise to constraints on that operator.
+In order to specify these constraints just once we introduce the notion of a
+% Neither \syntax nor \lit works, so we fall back to `\code{==}'.
+\IndexCustom{primitive operator `\code{==}'}{%
+  operator `\code{==}'!primitive}:
+
+\begin{itemize}
+\item Every instance of type \code{int} and \code{String}
+  has a primitive operator \lit{==}.
+\item Every instance of type \code{Symbol}
+  which was originally obtained by evaluation of a literal symbol or
+  a constant invocation of a constructor of the \code{Symbol} class
+  has a primitive operator \lit{==}.
+\item Every instance of type \code{Type}
+  which was originally obtained by evaluating a constant type literal
+  (\ref{dynamicTypeSystem})
+  has a primitive operator \lit{==}.
+\item An instance $o$ has a primitive operator \lit{==}
+  if the dynamic type of $o$ is a class $C$,
+  and $C$ has a primitive operator \lit{==}.
+\item The class \code{Object} has a primitive operator \lit{==}.
+\item A class $C$ has a primitive operator \lit{==}
+  if it does not have an implementation of the operator \lit{==}
+  that overrides the one inherited from \code{Object}.
+  \commentary{%
+  In particular, the following have a primitive operator \lit{==}:
+  The null object (\ref{null}),
+  function objects obtained by function closurization of
+  a static method or a top-level function
+  (\ref{functionClosurization}),
+  instances of type \code{bool}
+  (\ref{booleans}),
+  and instances obtained by evaluation of a list literal
+  (\ref{lists}),
+  a map literal
+  (\ref{maps}), or
+  a set literal
+  (\ref{sets}).
+  }
+\end{itemize}
+
+\LMHash{}%
+When we say that the operator \lit{==} of a given instance or class
+\IndexCustom{is not primitive}{operator `\code{==}'!is not primitive},
+it means that it is not true that said instance or class
+has a primitive operator \lit{==}.
+
+
 \subsection{Getters}
 \LMLabel{getters}
 
@@ -2639,8 +2698,10 @@
 It is a compile-time error if the name of a constructor is not a constructor name.
 
 \LMHash{}%
-The \Index{function type of a constructor} $k$ is the function type whose
-return type is the class that contains the declaration of $k$,
+The
+\IndexCustom{function type of a constructor}{function type!of a constructor}
+$k$ is the function type
+whose return type is the class that contains the declaration of $k$,
 and whose formal parameter types, optionality, and names of named parameters
 correspond to the declaration of $k$.
 
@@ -2711,10 +2772,15 @@
 }
 
 \LMHash{}%
-Initializing formals are executed during the execution of generative constructors detailed below.
-Executing an initializing formal \code{\THIS{}.\id} causes the instance variable \id{} of the immediately surrounding class to be assigned the value of the corresponding actual parameter,
-%% TODO(eernst): This should be a compile-time error -- check, revise if true!
-unless \id{} is a final variable that has already been initialized, in which case a run-time error occurs.
+Initializing formals are executed during
+the execution of generative constructors detailed below.
+Executing an initializing formal \code{\THIS{}.\id}
+causes the instance variable \id{} of the immediately surrounding class
+to be assigned the value of the corresponding actual parameter,
+% This can occur due to a failing implicit cast.
+unless the assigned value has a dynamic type
+which is not a subtype of the declared type of the instance variable \id{},
+in which case a dynamic error occurs.
 
 \commentary{
 The above rule allows initializing formals to be used as optional parameters:
@@ -2822,10 +2888,14 @@
 must be a potentially constant expression (\ref{constantConstructors}).
 
 \LMHash{}%
-It is a dynamic type error if an actual argument passed in an invocation of a redirecting generative constructor $k$
+% This error can occur due to a failed implicit cast.
+It is a dynamic type error if an actual argument passed
+in an invocation of a redirecting generative constructor $k$
 is not a subtype of the actual type (\ref{actualTypeOfADeclaration})
 of the corresponding formal parameter in the declaration of $k$.
-It is a dynamic type error if an actual argument passed to the redirectee $k'$ of a redirecting generative constructor
+% This error can occur due to a failed implicit cast.
+It is a dynamic type error if an actual argument passed
+to the redirectee $k'$ of a redirecting generative constructor
 is not a subtype of the actual type
 (\ref{actualTypeOfADeclaration})
 of the corresponding formal parameter in the declaration of the redirectee.
@@ -2964,9 +3034,10 @@
 Execution then proceeds as follows:
 
 \LMHash{}%
-The instance variable declarations of the immediately enclosing class are visited in the order they appear in the program text.
+The instance variable declarations of the immediately enclosing class
+are visited in the order they appear in the program text.
 For each such declaration $d$, if $d$ has the form
-\code{\syntax{finalConstVarOrType} $v$ = $e$; }
+\code{\synt{finalConstVarOrType} $v$ = $e$; }
 then $e$ is evaluated to an object $o$
 and the instance variable $v$ of $i$ is bound to $o$.
 
@@ -3015,9 +3086,9 @@
 \LMHash{}%
 First, the expression $e$ is evaluated to an object $o$.
 Then, the instance variable $v$ of $i$ is bound to $o$.
-It is a dynamic type error if $o$ is not the null object
-(\ref{null})
-and the dynamic type of $o$ is not a subtype of the actual type
+% This error can occur due to an implicit cast.
+It is a dynamic type error if the dynamic type of $o$ is not
+a subtype of the actual type
 (\ref{actualTypeOfADeclaration})
 of the instance variable $v$.
 
@@ -3080,6 +3151,7 @@
 It is a compile-time error if $M$ is not the name of the immediately enclosing class.
 
 \LMHash{}%
+% This error can occur due to an implicit cast.
 It is a dynamic type error if a factory returns a non-null object
 whose type is not a subtype of its actual
 (\ref{actualTypeOfADeclaration})
@@ -3166,12 +3238,15 @@
 
 \rationale{
 We require a subtype match
-(rather than the more forgiving assignable match which is used with a generative redirecting constructor),
-because a factory redirecting constructor $k$ always invokes its redirectee $k'$
-with exactly the same actual arguments that $k$ received.
+(rather than the more forgiving assignable match
+which is used with a generative redirecting constructor),
+because a factory redirecting constructor $k$ always invokes
+its redirectee $k'$ with
+exactly the same actual arguments that $k$ received.
 This means that a downcast on an actual argument
 ``between'' $k$ and $k'$
-would either be unused because the actual argument has the type required by $k'$,
+would either be unused because the actual argument has
+the type required by $k'$,
 or it would amount to a dynamic error which is simply delayed a single step.
 }
 
@@ -3184,10 +3259,10 @@
 \LMHash{}%
 It is a compile-time error if $k$ explicitly specifies a default value for an optional parameter.
 
-\commentary{
+\rationale{%
 Default values specified in $k$ would be ignored,
 since it is the \emph{actual} parameters that are passed to $k'$.
-Hence, default values are disallowed.
+Hence, default values are disallowed.%
 }
 
 \LMHash{}%
@@ -3233,6 +3308,7 @@
 and $k'$ is the redirectee of $k$.
 
 \LMHash{}%
+% This error can occur due to an implicit cast.
 It is a dynamic type error if an actual argument passed in an invocation of $k$
 is not a subtype of the actual type (\ref{actualTypeOfADeclaration})
 of the corresponding formal parameter in the declaration of $k$.
@@ -3330,7 +3406,7 @@
 \CLASS{} D \{
   \FINAL{} w;
   \CONST{} D.makeList(p): w = \CONST{} [p]; // \comment{compile-time error}
-  \CONST{} D.makeMap(p): w = \CONST{} \{``help'': q\}; // \comment{compile-time error}
+  \CONST{} D.makeMap(p): w = \CONST{} \{"help": q\}; // \comment{compile-time error}
   \CONST{} D.makeC(p): w = \CONST{} C(p, 12); // \comment{compile-time error}
 \}
 \end{dartCode}
@@ -3431,7 +3507,10 @@
 for class \code{Object}.
 
 \begin{grammar}
-<superclass> ::= \EXTENDS{} <typeNotVoid>
+<superclass> ::= \EXTENDS{} <typeNotVoid> <mixins>?
+    \alt <mixins>
+
+<mixins> ::= \WITH{} <typeNotVoidList>
 \end{grammar}
 
 %The superclass clause of a class C is processed within the enclosing scope of the static scope of C.
@@ -3445,7 +3524,7 @@
 \LMHash{}%
 It is a compile-time error if the type in the \EXTENDS{} clause of a class $C$ is
 a type variable (\ref{generics}), a type alias that does not denote a class (\ref{typedef}),
-an enumerated type (\ref{enums}), a malformed type (\ref{staticTypes}),
+an enumerated type (\ref{enums}),
 a deferred type (\ref{staticTypes}), type \DYNAMIC{} (\ref{typeDynamic}),
 or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
 
@@ -3635,7 +3714,7 @@
 \LMHash{}%
 It is a compile-time error if an element in the type list of the \IMPLEMENTS{} clause of a class $C$ is
 a type variable (\ref{generics}), a type alias that does not denote a class (\ref{typedef}),
-an enumerated type (\ref{enums}), a malformed type (\ref{staticTypes}),
+an enumerated type (\ref{enums}),
 a deferred type (\ref{staticTypes}), type \DYNAMIC{} (\ref{typeDynamic}),
 or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
 It is a compile-time error if two elements in the type list of the \IMPLEMENTS{} clause of a class $C$ specifies the same type $T$.
@@ -4016,7 +4095,7 @@
 \Case{Methods and setters}
 In this case $M_0$ consists of setter signatures only,
 or method signatures only,
-because the name \id{} in the former case always end in \syntax{`='},
+because the name \id{} in the former case always ends in \lit{=},
 which is never true in the latter case.
 
 \LMHash{}%
@@ -4155,6 +4234,7 @@
 It is a compile-time error
 if the computation of said combined member signature fails.
 
+
 \subsubsection{Correct Member Overrides}
 \LMLabel{correctMemberOverrides}
 
@@ -4218,33 +4298,16 @@
 
 \LMHash{}%
 A mixin describes the difference between a class and its superclass.
-A mixin is always derived from an existing class declaration.
+A mixin is either derived from an existing class declaration
+or introduced by a mixin declaration.
 
 \LMHash{}%
-It is a compile-time error to derive a mixin from a class which explicitly declares a generative constructor.
-It is a compile-time error to derive a mixin from a class which has a superclass other than \code{Object}.
+Mixin application occurs when one or more mixins are mixed into a class declaration via its \WITH{} clause (\ref{mixinApplication}).
+Mixin application may be used to extend a class per section \ref{classes};
+alternatively, a class may be defined as a mixin application as described in the following section.
 
-\rationale{
-This restriction is temporary.
-We expect to remove it in later versions of Dart.
-
-The restriction on constructors simplifies the construction of mixin applications because the process of creating instances is simpler.
-}
-
-
-\subsection{Mixin Application}
-\LMLabel{mixinApplication}
-
-\LMHash{}%
-A mixin may be applied to a superclass, yielding a new class.
-Mixin application occurs when one or more mixins are mixed into a class declaration via its \WITH{} clause.
-The mixin application may be used to extend a class per section \ref{classes};
-alternatively, a class may be defined as a mixin application as described in this section.
-It is a compile-time error if an element in the type list of the \WITH{} clause of a mixin application is
-a type variable (\ref{generics}), a type alias that does not denote a class (\ref{typedef}),
-an enumerated type (\ref{enums}), a malformed type (\ref{staticTypes}),
-a deferred type (\ref{staticTypes}), type \DYNAMIC{} (\ref{typeDynamic}),
-or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
+\subsection{Mixin Classes}
+\LMLabel{mixinClasses}
 
 \begin{grammar}
 <mixinApplicationClass> ::= \gnewline{}
@@ -4254,26 +4317,207 @@
 \end{grammar}
 
 \LMHash{}%
-A mixin application of the form \code{$S$ \WITH{} $M$;} for the name $N$ defines a class $C$ with superclass $S$ and name $N$.
+It is a compile-time error if an element in the type list of the \WITH{} clause of a mixin application is
+a type variable (\ref{generics}),
+a function type (\ref{functionTypes}),
+a type alias that does not denote a class (\ref{typedef}),
+an enumerated type (\ref{enums}),
+a deferred type (\ref{staticTypes}),
+type \DYNAMIC{} (\ref{typeDynamic}),
+type \VOID{} (\ref{typeVoid}),
+or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
+If $T$ is a type in a \WITH{} clause, \IndexCustom{the mixin of}{type!mixin of}
+$T$ is either the mixin derived from $T$ if $T$ denotes a class,
+or the mixin introduced by $T$ if $T$ denotes a mixin declaration.
 
 \LMHash{}%
-A mixin application of the form \code{$S$ \WITH{} $M_1,\ \ldots,\ M_k$;} for the name $N$ defines a class $C$ whose superclass is the application of the mixin composition (\ref{mixinComposition}) $M_{k-1} * \ldots * M_1$ to $S$ of a name that is a fresh identifer, and whose name is $N$.
-\rationale{The name of the resulting class is necessary because it is part of the names of the introduced constructors.}
+Let $D$ be a mixin application class declaration of the form
+\begin{normativeDartCode}
+\ABSTRACT? \CLASS{} $N$ = $S$ \WITH{} $M_1$, \ldots{}, $M_n$ \IMPLEMENTS{} $I_1$, \ldots, $I_k$;
+\end{normativeDartCode}
 
 \LMHash{}%
-In both cases above, $C$ declares the same instance members as $M$ (respectively, $M_k$),
-and it does not declare any static members.
-If any of the instance variables of $M$ (respectively, $M_k$) have initializers,
-they are executed in the instance scope of $M$ (respectively, $M_k$)
-to initialize the corresponding instance variables of $C$.
+It is a compile-time error if $S$ is an enumerated type (\ref{enums}).
+It is a compile-time error if any of $M_1, \ldots, M_k$ is an enumerated type (\ref{enums}).
+It is a compile-time error if a well formed mixin cannot be derived from each of $M_1, \ldots, M_k$.
+
+\LMHash{}%
+The effect of $D$ in library $L$ is to introduce the name $N$ into the scope of $L$, bound to the class (\ref{classes}) defined by the clause \code{$S$ \WITH{} $M_1$, \ldots{}, $M_n$} with name $N$, as described below.
+If $k > 0$ then the class also implements $I_1$, \ldots{}, $I_k$.
+If{}f the class declaration is prefixed by the built-in identifier \ABSTRACT{}, the class being defined is made an abstract class.
+
+\LMHash{}%
+A clause of the form \code{$S$ \WITH{} $M_1$, \ldots{}, $M_n$}
+with name $N$ defines a class as follows:
+
+\LMHash{}%
+If there is only one mixin ($n = 1$), then \code{$S$ \WITH{} $M_1$}
+defines the class yielded by the mixin application (\ref{mixinApplication})
+of the mixin of $M_1$ (\ref{mixinDeclaration}) to the class denoted by
+$S$ with name $N$.
+
+\LMHash{}%
+If there is more than one mixin ($n > 1$), then
+let $X$ be the class defined by \code{$S$ \WITH{} $M_1$, \ldots{}, $M_{n-1}$}
+with name $F$, where $F$ is a fresh name, and make $X$ abstract.
+Then \code{$S$ \WITH{} $M_1$, \ldots{}, $M_n$} defines the class yielded
+by the mixin application of the mixin of $M_n$ to the class $X$ with name $N$.
+
+\LMHash{}%
+In either case, let $K$ be a class declaration with the same constructors, superclass, interfaces and instance members as the defined class.
+It is a compile-time error if the declaration of $K$ would cause a compile-time error.
+% TODO(eernst): Not completely!
+% We do not want super-invocations on covariant implementations
+% to be compile-time errors.
+
+\commentary{
+It is an error, for example, if $M$ contains a member declaration $d$ which overrides a member signature $m$ in the interface of $S$, but which is not a correct override of $m$ (\ref{correctMemberOverrides}).
+}
+
+\subsection{Mixin Declaration}
+\LMLabel{mixinDeclaration}
+
+\LMHash{}%
+A mixin defines zero or more \IndexCustom{mixin member declarations}{mixin!member declaration},
+zero or more \IndexCustom{required superinterfaces}{mixin!required superinterface},
+one \IndexCustom{combined superinterface}{mixin!combined superinterface},
+and zero or more \IndexCustom{implemented interfaces}{mixin!implemented interface}.
+
+\LMHash{}%
+The mixin derived from a class declaration:
+\begin{normativeDartCode}
+\ABSTRACT? \CLASS{} $X$ \IMPLEMENTS{} $I_1$, \ldots{}, $I_k$ \{
+  \metavar{members}
+\}
+\end{normativeDartCode}
+has \code{Object} as required superinterface
+and combined superinterface,
+$I_1$, \ldots, $I_k$ as implemented interfaces,
+and the instance members of \metavar{members} as mixin member declarations.
+If $X$ is generic, so is the mixin.
+
+\LMHash{}%
+A mixin declaration introduces a mixin and provides a scope
+for static member declarations.
+
+\begin{grammar}
+<mixinDeclaration> ::= <metadata> \MIXIN{} <identifier> <typeParameters>?
+  \gnewline{} (\ON{} <typeNotVoidList>)? <interfaces>?
+  \gnewline{} `\{' (<metadata> <classMemberDefinition>)* `\}'
+\end{grammar}
+
+\LMHash{}
+It is a compile-time error to declare a constructor in a mixin-declaration.
+
+\LMHash{}
+A mixin declaration with no \code{\ON{}} clause is equivalent
+to one with the clause \code{\ON{} Object}.
+
+\LMHash{}
+Let $M$ be a \MIXIN{} declaration of the form
+\begin{normativeDartCode}
+\MIXIN{} $N$<\TypeParametersStd> \ON{} \List{T}{1}{n} \IMPLEMENTS{} \List{I}{1}{k} \{
+  \metavar{members}
+\}
+\end{normativeDartCode}
+It is a compile-time error if any of the types $T_1$ through $T_n$
+or $I_1$ through $I_k$ is
+a type variable (\ref{generics}),
+a function type (\ref{functionTypes}),
+a type alias not denoting a class (\ref{typedef}),
+an enumerated type (\ref{enums}),
+a deferred type (\ref{staticTypes}),
+type \DYNAMIC{} (\ref{typeDynamic}),
+type \VOID{} (\ref{typeVoid}),
+or type \code{FutureOr<$T$>} for any $T$ (\ref{typeFutureOr}).
+
+\LMHash{}%
+Let $M_S$ be the interface declared by the class declaration
+\begin{normativeDartCode}
+abstract \CLASS{} $M_{super}$<$P_1$, \ldots{}, $P_m$> implements $T_1$, $\dots{}$, $T_n$ \{\}
+\end{normativeDartCode}
+where $M_{super}$ is a fresh name.
+It is a compile-time error for the mixin declaration if the $M_S$
+class declaration would cause a compile-time error,
+\commentary{
+that is, if any member is declared by more than one declared superinterface,
+and there is not a most specific signature for that member among the super
+interfaces}.
+The interface $M_S$ is called the
+\Index{superinvocation interface} of the mixin declaration $M$.
+\commentary{
+If the mixin declaration $M$ has only one declared superinterface, $T_1$,
+then the superinvocation interface $M_{super}$ has exactly the same members
+as the interface $T_1$.}
+
+\LMHash{}
+Let $M_I$ be the interface that would be defined by the class declaration
+\begin{normativeDartCode}
+\ABSTRACT{} \CLASS{} $N$<\TypeParametersStd> \IMPLEMENTS{} \List{T}{1}{n}, \List{I}{1}{k} \{
+  $\metavar{members}'$
+\}
+\end{normativeDartCode}
+where $\metavar{members}'$ are the member declarations of
+the mixin declaration $M$ except that all superinvocations are treated
+as if \SUPER{} was a valid expression with static type $M_S$.
+It is a compile-time error for the mixin $M$ if this $N$ class
+declaration would cause a compile-time error, \commentary{that is, if the
+required superinterfaces, the implemented interfaces and the declarations do not
+define a consistent interface, if any member declaration contains a
+compile-time error other than a super-invocation, or if a super-invocation
+is not valid against the interface $M_S$}.
+The interface introduced by the mixin declaration $M$ has the same member
+signatures and superinterfaces as $M_I$.
+
+\LMHash{}%
+The mixin declaration $M$ introduces a mixin
+with the \NoIndex{required superinterface}s $T_1$, \ldots{}, $T_n$,
+the \NoIndex{combined superinterface} $M_S$,
+\NoIndex{implemented interface}s $I_1$, \ldots{}, $I_k$
+and the instance members declared in $M$ as \Index{mixin member declarations}.
+
+\subsection{Mixin Application}
+\LMLabel{mixinApplication}
+
+\LMHash{}%
+A mixin may be applied to a superclass, yielding a new class.
+
+\LMHash{}%
+Let $S$ be a class,
+$M$ be a mixin with \NoIndex{required superinterface}s $T_1$, \ldots, $T_n$,
+\NoIndex{combined superinterface} $M_S$,
+\NoIndex{implemented interfaces} $I_1$, \ldots{}, $I_k$ and
+\metavar{members} as \NoIndex{mixin member declarations},
+and let $N$ be a name.
+
+\LMHash{}%
+It is a compile-time error to apply $M$ to $S$ if $S$ does not implement,
+directly or indirectly, all of $T_1$, \ldots, $T_n$.
+It is a compile-time error if any of \metavar{members} contains a
+super-invocation of a member $m$ \commentary{(for example \code{super.foo},
+\code{super + 2}, or \code{super[1] = 2})}, and $S$ does not have a concrete
+implementation of $m$ which is a valid override of the member $m$ in
+the interface $M_S$. \rationale{We treat super-invocations in mixins as
+interface invocations on the combined superinterface, so we require the
+superclass of a mixin application to have valid implementations of those
+interface members that are actually super-invoked.}
+
+\LMHash{}%
+The mixin application of $M$ to $S$ with name $N$ introduces a new
+class, $C$, with name $N$, superclass $S$,
+implemented interface $I_1$, \ldots{}, $I_k$
+and \metavar{members} as instance members.
+The class $C$ has no static members.
+If $S$ declares any generative constructors, then the application
+introduces generative constructors on $C$ as follows:
 
 \LMHash{}%
 Let $L_C$ be the library containing the mixin application.
 \commentary{That is, the library containing the clause \code{$S$ \WITH{} $M$}
-or the clause \code{$S_0$ \WITH{} $M_1$, \ldots,\ $M_k$, $M$}.}
+or the clause \code{$S_0$ \WITH{} $M_1$, \ldots,\ $M_k$, $M$} giving rise
+to the mixin application.}
 
-Let $N_C$ be the name of the mixin application class $C$,
-let $S$ be the superclass of $C$, and let $S_N$ be the name of $S$.
+Let $S_N$ be the name of $S$.
 
 For each generative constructor of the form \code{$S_q$($T_{1}$ $a_{1}$, $\ldots$, $T_{k}$ $a_{k}$)} of $S$ that is accessible to $L_C$, $C$ has an implicitly declared constructor of the form
 
@@ -4283,10 +4527,10 @@
 
 \noindent
 where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$,
-which denote the superclass, by $N_C$, and $\SUPER_q$ is obtained from $S_q$ by
+which denote the superclass, by $N$, and $\SUPER_q$ is obtained from $S_q$ by
 replacing occurrences of $S_N$ which denote the superclass by \SUPER{}.
-If $S_q$ is a generative const constructor, and $M$ does not declare any
-fields, $C_q$ is also a const constructor.
+If $S_q$ is a generative const constructor, and $C$ does not declare any
+instance variables, $C_q$ is also a const constructor.
 
 \LMHash{}%
 For each generative constructor of the form \code{$S_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, [$T_{k+1}$ $a_{k+1}$ = $d_1$, \ldots , $T_{k+p}$ $a_{k+p}$ = $d_p$])} of $S$ that is accessible to $L_C$, $C$ has an implicitly declared constructor of the form
@@ -4298,13 +4542,13 @@
 
 \noindent
 where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$,
-which denote the superclass, by $N_C$,
+which denote the superclass, by $N$,
 $\SUPER_q$ is obtained from $S_q$ by replacing occurrences of $S_N$
 which denote the superclass by \SUPER{},
 and $d'_i$, $i \in 1..p$, is a constant expression evaluating
 to the same value as $d_i$.
-If $S_q$ is a generative const constructor, and $M$ does not declare any
-fields, $C_q$ is also a const constructor.
+If $S_q$ is a generative const constructor, and $MC$ does not declare any
+instance variables, $C_q$ is also a const constructor.
 
 \LMHash{}%
 For each generative constructor of the form \code{$S_q$($T_{1}$ $a_{1}$, \ldots , $T_{k}$ $a_{k}$, \{$T_{k+1}$ $a_{k+1}$ = $d_1$, \ldots , $T_{k+n}$ $a_{k+n}$ = $d_n$\})} of $S$ that is accessible to $L_C$, $C$ has an implicitly declared constructor of the form
@@ -4316,104 +4560,13 @@
 
 \noindent
 where $C_q$ is obtained from $S_q$ by replacing occurrences of $S_N$
-which denote the superclass by $N_C$,
+which denote the superclass by $N$,
 $\SUPER_q$ is obtained from $S_q$ by replacing occurrences of $S_N$
 which denote the superclass by \SUPER{},
 and $d'_i$, $i \in 1..n$, is a constant expression evaluating to the same value as $d_i$.
 If $S_q$ is a generative const constructor, and $M$ does not declare any
 fields, $C_q$ is also a const constructor.
 
-\LMHash{}%
-If the mixin application class declares interfaces, the resulting class also implements those interfaces.
-
-\LMHash{}%
-It is a compile-time error if $S$ is an enumerated type (\ref{enums}) or a malformed type.
-It is a compile-time error if $M$ (respectively, any of $M_1, \ldots, M_k$) is an enumerated type (\ref{enums}) or a malformed type.
-It is a compile-time error if a well formed mixin cannot be derived from $M$ (respectively, from each of $M_1, \ldots, M_k$).
-
-\commentary{%
-Note that \VOID{} is a reserved word,
-which implies that the same restrictions apply for the type \VOID,
-and similar restrictions are specified for other types like
-\code{Null} (\ref{null}) and
-\code{String} (\ref{strings}).%
-}
-
-\LMHash{}%
-Let $K$ be a class declaration with the same constructors, superclass and interfaces as $C$, and the instance members declared by $M$ (respectively $M_1, \ldots, M_k$).
-It is a compile-time error if the declaration of $K$ would cause a compile-time error.
-
-\commentary{
-If, for example,
-$M$ declares an instance member $im$ whose type is at odds with the type of a member of the same name in $S$,
-this will result in a compile-time error just as if we had defined $K$ by means of an ordinary class declaration extending $S$, with a body that included $im$.
-}
-
-\LMHash{}%
-The effect of a class definition of the form \code{\CLASS{} $C$ = $M$; } or the form \code{\CLASS{} $C<T_1, \ldots,\ T_n>$ = $M$; } in library $L$ is to introduce the name $C$ into the scope of $L$, bound to the class (\ref{classes}) defined by the mixin application $M$ for the name $C$.
-The name of the class is also set to $C$.
-If{}f the class is prefixed by the built-in identifier \ABSTRACT{}, the class being defined is an abstract class.
-
-\LMHash{}%
-Let $M_A$ be a mixin derived from a class $M$ with direct superclass $S_{static}$, e.g., as defined by the class declaration \code{class M extends S$_{static}$ \{ \ldots \}}.
-
-\LMHash{}%
-Let $A$ be an application of $M_A$.
-It is a compile-time error if the superclass of $A$ is not a subtype of $S_{static}$.
-
-\LMHash{}%
-Let $C$ be a class declaration that includes $M_A$ in a with clause.
-It is a compile-time error if $C$ does not implement, directly or indirectly, all the direct superinterfaces of $M$.
-
-
-\subsection{Mixin Composition}
-\LMLabel{mixinComposition}
-
-\rationale{
-Dart does not directly support mixin composition, but the concept is useful when defining how the superclass of a class with a mixin clause is created.
-}
-
-\LMHash{}%
-The \Index{composition of two mixins},
-\code{$M_1$<$T_1, \ldots, T_{k_{M_1}}$>} and
-\code{$M_2$<$U_1, \ldots, U_{k_{M_2}}$>}, written
-\code{$M_1$<$T_1, \ldots, T_{k_{M_1}}$>$ * M_2$<$U_1, \ldots, U_{k_{M_2}}$>}
-defines an anonymous mixin such that for any class
-\code{$S$<$V_1, \ldots, V_{k_S}$>},
-the application of
-
-\code{$M_1$<$T_1, \ldots, T_{k_{M_1}}$> $*$ $M_2$<$U_1, \ldots, U_{k_{M_2}}$>}
-
-to \code{$S$<$V_1, \ldots, V_{k_S}$>} for the name $C$ is equivalent to
-
-\begin{normativeDartCode}
-\ABSTRACT{} \CLASS{} $C<T_1, \ldots, T_{k_{M_1}}, U_1, \ldots, U_{k_{M_2}}, V_1, \ldots, V_{k_S}> = $
-      $Id_2<U_1, \ldots, U_{k_{M_2}}, V_1 \ldots V_{k_S}>$ \WITH{} $M_1 <T_1, \ldots, T_{k_{M_1}}>$;
-\end{normativeDartCode}
-
-where $Id_2$ denotes
-
-\begin{normativeDartCode}
-\ABSTRACT{} \CLASS{} $Id_2<U_1, \ldots, U_{k_{M_2}}, V_1, \ldots, V_{k_S}> =$
-                         $S<V_1, \ldots, V_{k_S}>$ \WITH{} $M_2<U_1, \ldots, U_{k_{M_2}}>$;
-\end{normativeDartCode}
-
-and $Id_2$ is a unique identifier that does not exist anywhere in the program.
-
-\rationale{
-The intermediate classes produced by mixin composition are regarded as abstract because they cannot be instantiated independently.
-They are only introduced as anonymous superclasses of ordinary class declarations and mixin applications.
-Consequently, no errors are raised if a mixin composition includes abstract members, or incompletely implements an interface.
-}
-
-\LMHash{}%
-Mixin composition is associative.
-
-\commentary{
-Note that any subset of $M_1$, $M_2$ and $S$ may or may not be generic.
-For any non-generic declaration, the corresponding type parameters may be elided, and if no type parameters remain in the derived declarations $C$ and/or $Id_2$ then the those declarations need not be generic either.
-}
-
 
 \section{Enums}
 \LMLabel{enums}
@@ -4513,7 +4666,7 @@
 $T$ is a type,
 and \code{$S$?} is a type or the empty string.
 Let $S'$ be \code{$S$?} if it is a type, otherwise let $S'$ be \DYNAMIC.
-The associated function type of $D$, call it $F$, is, respectively:
+The associated type of $D$, call it $F$, is, respectively:
 
 \begin{itemize}
 \item $T$
@@ -4554,7 +4707,7 @@
 $[T_1/X_1, \ldots, T_s/X_s]F$.
 
 \commentary{%
-Note that the type alias syntax without \syntax{`='}
+Note that the type alias syntax without \lit{=}
 can only express function types,
 and it cannot express the type of a generic function.
 When such a type alias is generic,
@@ -4643,10 +4796,14 @@
 \LMHash{}%
 Type parameters are declared in the type parameter scope of a class or function.
 The type parameters of a generic $G$ are in scope in the bounds of all of the type parameters of $G$.
-The type parameters of a generic class declaration $G$ are also in scope in the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exist) and in the body of $G$.
-However, a type parameter of a generic class is considered to be a malformed type when referenced by a static member.
+The type parameters of a generic class declaration $G$ are also in scope in
+the \EXTENDS{} and \IMPLEMENTS{} clauses of $G$ (if these exist) and in the body of $G$.
 
-\commentary{
+\commentary{%
+However, a type parameter of a generic class
+is considered to be a malformed type
+when referenced by a static member
+(\ref{staticTypes}).
 The scopes associated with the type parameters of a generic function are described in (\ref{formalParameters}).
 }
 
@@ -5353,6 +5510,7 @@
 etc.
 }
 
+
 \subsubsection{The Instantiation to Bound Algorithm}
 \LMLabel{theInstantiationToBoundAlgorithm}
 
@@ -5811,7 +5969,7 @@
 \item $e_1$ evaluates to \FALSE{} and $e_2$ is a constant expression that evaluates to a value of type \code{bool}.
 \end{enumerate}
 
-\item An expression of the form \code{~$e_1$} is a potentially constant expression if $e_1$ is a potentially constant expression. It is further a constant expression if $e_1$ is a constant expression that evaluates to a value of type \code{int}.
+\item An expression of the form \code{\~{}$e_1$} is a potentially constant expression if $e_1$ is a potentially constant expression. It is further a constant expression if $e_1$ is a constant expression that evaluates to a value of type \code{int}.
 
 \item An expression of one of the forms \code{$e_1$\,\&\,$e_2$}, \code{$e_1$\,|\,$e_2$}, or \code{$e_1$\,\^\,$e_2$} is potentially constant if $e_1$ and $e_2$ are both potentially constant expressions. It is further constant if both $e_1$ and $e_2$ are constant expressions that both evaluate to values that are both instances of \code{int}, or that are both instances of \code{bool}.
 % The bool case is new in 2.1.
@@ -5858,17 +6016,28 @@
 
 \LMHash{}%
 % New in 2.1.
-A constant type expression is one of:
+A
+\Index{constant type expression}
+is one of:
 \begin{itemize}
-\item An simple or qualified identifier denoting a type declaration (a type alias, class or mixin declaration) that is not qualified by a deferred prefix,
-optionally followed by type arguments of the form
-\code{<$T_1$,\ \ldots,\ $T_n$>}
-where $T_1$, \ldots{}, $T_n$ are constant type expressions.
-\item A type of the form \code{FutureOr<$T$>} where $T$ is a constant type expression.
-\item A function type
-\code{$R$ Function<\metavar{typeParameters}>(\metavar{argumentTypes})}
-(where $R$ and \code{<\metavar{typeParameters}>} may be omitted)
-and where $R$, \metavar{typeParameters} and \metavar{argumentTypes} (if present) contain only constant type expressions.
+\item An simple or qualified identifier
+  denoting a type declaration (a type alias, class or mixin declaration)
+  that is not qualified by a deferred prefix,
+  optionally followed by type arguments of the form
+  \code{<$T_1$,\ \ldots,\ $T_n$>}
+  where $T_1$, \ldots{}, $T_n$ are constant type expressions.
+\item A type of the form \code{FutureOr<$T$>}
+  where $T$ is a constant type expression.
+\item
+  %% TODO(eernst): This does not allow for type variables introduced by
+  %% the type itself. `Function<X>(X)` could be a constant type expression,
+  %% but that is not covered by the current rules: `X` is a type variable,
+  %% and they are never allowed.
+  A function type
+  \code{$R$ Function<\metavar{typeParameters}>(\metavar{argumentTypes})}
+  (where $R$ and \code{<\metavar{typeParameters}>} may be omitted)
+  and where $R$, \metavar{typeParameters} and \metavar{argumentTypes}
+  (if present) contain only constant type expressions.
 \item The type \VOID{}.
 \item The type \DYNAMIC{}.
 \end{itemize}
@@ -5992,11 +6161,13 @@
 
 \LMHash{}%
 The null object is the sole instance of the built-in class \code{Null}.
-Attempting to instantiate \code{Null} causes a run-time error.
+% The following can be a consequence of the declaration of `Null`,
+% but we don't spell that out, we just require that it is an error.
+Attempting to instantiate \code{Null} causes a compile-time error.
 It is a compile-time error for a class to extend, mix in or implement \code{Null}.
 The \code{Null} class extends the \code{Object} class and declares no methods except those also declared by \code{Object}.
-\commentary{As such, it does not override the \code{==} operator inherited
-from the \code{Object} class.}
+In particular, the \code{Null} class does not override the \lit{==} operator
+inherited from the \code{Object} class.
 
 \LMHash{}%
 The static type of \NULL{} is the \code{Null} type.
@@ -6111,7 +6282,8 @@
 It is a compile-time error for any class other than \code{int} and \code{double} to extend, mix in or implement \code{num}.
 
 \LMHash{}%
-The instances of \code{int} and \code{double} all override the \code{==} operator inherited from the \code{Object} class.
+The instances of \code{int} and \code{double} all override the \lit{==} operator inherited from the \code{Object} class.
+
 
 \subsection{Booleans}
 \LMLabel{booleans}
@@ -6132,10 +6304,11 @@
 Both \NoIndex{true} and \NoIndex{false} are instances of
 the built-in class \code{bool},
 and there are no other objects that implement \code{bool}.
-It is a compile-time error for a class to extend, mix in or implement \code{bool}.
+It is a compile-time error for a class to
+extend, mix in or implement \code{bool}.
 
 \LMHash{}%
-The \code{bool} class does not override the \code{==} operator inherited from
+The \code{bool} class does not override the \lit{==} operator inherited from
 the \code{Object} class.
 
 \LMHash{}%
@@ -6251,8 +6424,15 @@
 \end{grammar}
 
 \LMHash{}%
-Multiline strings are delimited by either matching triples of single quotes or matching triples of double quotes.
-If the first line of a multiline string consists solely of the whitespace characters defined by the production \synt{WHITESPACE} (\ref{lexicalRules}), possibly prefixed by \syntax{`\\'}, then that line is ignored, including the line break at its end.
+Multiline strings are delimited by either
+matching triples of single quotes or
+matching triples of double quotes.
+If the first line of a multiline string consists solely of
+the whitespace characters defined by the production \synt{WHITESPACE}
+(\ref{lexicalRules}),
+possibly prefixed by \syntax{`\\'},
+then that line is ignored,
+including the line break at its end.
 
 \rationale{
 The idea is to ignore a whitespace-only first line of a multiline string, where whitespace is defined as tabs, spaces and the final line break.
@@ -6267,42 +6447,60 @@
 Strings support escape sequences for special characters.
 The escapes are:
 \begin{itemize}
-\item \syntax{`\\n'} for newline, equivalent to \syntax{`\\x0A'}.
-\item \syntax{`\\r'} for carriage return, equivalent to \syntax{`\\x0D'}.
-\item \syntax{`\\f'} for form feed, equivalent to \syntax{`\\x0C'}.
-\item \syntax{`\\b'} for backspace, equivalent to \syntax{`\\x08'}.
-\item \syntax{`\\t'} for tab, equivalent to \syntax{`\\x09'}.
-\item \syntax{`\\v'} for vertical tab, equivalent to \syntax{`\\x0B'}.
-\item \syntax{`\\x' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$}, equivalent to
+\item
+  \syntax{`\\n'} for newline, equivalent to \syntax{`\\x0A'}.
+\item
+  \syntax{`\\r'} for carriage return, equivalent to \syntax{`\\x0D'}.
+\item
+  \syntax{`\\f'} for form feed, equivalent to \syntax{`\\x0C'}.
+\item
+  \syntax{`\\b'} for backspace, equivalent to \syntax{`\\x08'}.
+\item
+  \syntax{`\\t'} for tab, equivalent to \syntax{`\\x09'}.
+\item
+  \syntax{`\\v'} for vertical tab, equivalent to \syntax{`\\x0B'}.
+\item
+  \syntax{`\\x' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$}, equivalent to
 
-\syntax{`\\u{' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ `}'}.
-\item \syntax{`\\u' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ <HEX\_DIGIT>$_3$ <HEX\_DIGIT>$_4$},
-equivalent to
+  \syntax{`\\u{' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ `}'}.
+\item
+  \syntax{`\\u' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ <HEX\_DIGIT>$_3$ <HEX\_DIGIT>$_4$},
+  equivalent to
 
-\noindent
-\syntax{`\\u{' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ <HEX\_DIGIT>$_3$ <HEX\_DIGIT>$_4$ `}'}.
-\item \syntax{`\\u{' <HEX\_DIGIT\_SEQUENCE> `}'} is the Unicode code point represented by the
-\syntax{<HEX\_DIGIT\_SEQUENCE>}.
-It is a compile-time error if the value of the
-\syntax{<HEX\_DIGIT\_SEQUENCE>}
-is not a valid Unicode code point.
-\item \syntax{`$'} indicating the beginning of an interpolated expression.
-\item Otherwise, \syntax{`\\'$k$} indicates the character $k$ for any $k$ not in
-\syntax{$\{$`n', `r', `f', `b', `t', `v', `x', `u'$\}$}.
+  \noindent
+  \syntax{`\\u{' <HEX\_DIGIT>$_1$ <HEX\_DIGIT>$_2$ <HEX\_DIGIT>$_3$ <HEX\_DIGIT>$_4$ `}'}.
+\item
+  \syntax{`\\u{' <HEX\_DIGIT\_SEQUENCE> `}'} is
+  the Unicode code point represented by the
+  \syntax{<HEX\_DIGIT\_SEQUENCE>}.
+  It is a compile-time error if the value of the
+  \syntax{<HEX\_DIGIT\_SEQUENCE>}
+  is not a valid Unicode code point.
+\item
+  \lit{\$} indicating the beginning of an interpolated expression.
+\item
+  Otherwise, \syntax{`\\$k$'} indicates the character $k$ for
+  any $k$ not in \syntax{$\{$`n', `r', `f', `b', `t', `v', `x', `u'$\}$}.
 \end{itemize}
 
 \LMHash{}%
-Any string may be prefixed with the character \syntax{`r'},
+Any string may be prefixed with the character \lit{r},
 indicating that it is a \Index{raw string},
 in which case no escapes or interpolations are recognized.
 
 \LMHash{}%
-Line breaks in a multiline string are represented by the \syntax{<NEWLINE>} production.
+Line breaks in a multiline string are represented by
+the \syntax{<NEWLINE>} production.
 A line break introduces a single newline character into the string value.
 
 \LMHash{}%
-It is a compile-time error if a non-raw string literal contains a character sequence of the form \syntax{`\\x'} that is not followed by a sequence of two hexadecimal digits.
-It is a compile-time error if a non-raw string literal contains a character sequence of the form \syntax{`\\u'} that is not followed by either a sequence of four hexadecimal digits, or by curly brace delimited sequence of hexadecimal digits.
+It is a compile-time error if a non-raw string literal contains
+a character sequence of the form \syntax{`\\x'} that is not followed by
+a sequence of two hexadecimal digits.
+It is a compile-time error if a non-raw string literal contains
+a character sequence of the form \syntax{`\\u'} that is not followed by
+either a sequence of four hexadecimal digits,
+or by curly brace delimited sequence of hexadecimal digits.
 
 \begin{grammar}
 <stringContentDQ> ::= \~{}( `\\' | `"' | `$' | <NEWLINE> )
@@ -6328,8 +6526,9 @@
 
 \LMHash{}%
 All string literals evaluate to instances of the built-in class \code{String}.
-It is a compile-time error for a class to extend, mix in or implement \code{String}.
-The \code{String} class overrides the \code{==} operator inherited from
+It is a compile-time error for a class to
+extend, mix in or implement \code{String}.
+The \code{String} class overrides the \lit{==} operator inherited from
 the \code{Object} class.
 The static type of a string literal is \code{String}.
 
@@ -6338,7 +6537,10 @@
 \LMLabel{stringInterpolation}
 
 \LMHash{}%
-It is possible to embed expressions within non-raw string literals, such that these expressions are evaluated, and the resulting values are converted into strings and concatenated with the enclosing string.
+It is possible to embed expressions within non-raw string literals,
+such that these expressions are evaluated,
+and the resulting values are converted into strings and
+concatenated with the enclosing string.
 This process is known as \Index{string interpolation}.
 
 \begin{grammar}
@@ -6347,14 +6549,17 @@
 \end{grammar}
 
 \commentary{
-The reader will note that the expression inside the interpolation could itself include strings, which could again be interpolated recursively.
+The reader will note that the expression inside the interpolation
+could itself include strings,
+which could again be interpolated recursively.
 }
 
 \LMHash{}%
-An unescaped \syntax{`$'} character in a string signifies the beginning of an interpolated expression.
-The \syntax{`$'} sign may be followed by either:
+An unescaped \lit{\$} character in a string signifies
+the beginning of an interpolated expression.
+The \lit{\$} sign may be followed by either:
 \begin{itemize}
-\item A single identifier \id{} that must not contain the \syntax{`$'} character.
+\item A single identifier \id{} that does not contain the \lit{\$} character.
 \item An expression $e$ delimited by curly braces.
 \end{itemize}
 
@@ -6386,13 +6591,13 @@
 
 \LMHash{}%
 A symbol literal \code{\#\id} where \id{} is an identifier
-that does not begin with an underscore ('\code{\_}'),
+that does not begin with an underscore (`\code{\_}'),
 evaluates to an instance of \code{Symbol} representing the identifier \id.
 All occurrences of \code{\#\id} evaluate to the same instance
 \commentary{(symbol instances are canonicalized)},
 and no other symbol literals evaluate to that \code{Symbol} instance
 or to a \code{Symbol} instance that is equal
-(according to the \code{==} operator \ref{equality}) to that instance.
+(according to the \lit{==} operator \ref{equality}) to that instance.
 
 \LMHash{}%
 A symbol literal \code{\#$\id.\id_2\ldots\id_n$}
@@ -6401,7 +6606,7 @@
 All occurrences of \code{\#$\id.\id_2\ldots\id_n$} with the same sequence of identifiers
 evaluate to the same instance,
 and no other symbol literals evaluate to that \code{Symbol} instance
-or to a \code{Symbol} instance that is \code{==} to that instance.
+or to a \code{Symbol} instance that is \lit{==} to that instance.
 \commentary{This kind of symbol literal denotes the name of a library declaration. Library names are not subject to library privacy, even
 if some of its identifiers begin with an underscore.}
 
@@ -6410,18 +6615,18 @@
 representing that particular operator name.
 All occurrences of \code{\#\metavar{operator}} evaluate to the same instance,
 and no other symbol literals evaluate to that \code{Symbol} instance
-or to a \code{Symbol} instance that is \code{==} to that instance.
+or to a \code{Symbol} instance that is \lit{==} to that instance.
 
 \LMHash{}%
 A symbol literal \code{\#\_\id}, evaluates to an instance of \code{Symbol}
 representing the private identifier \code{\_\id} of the containing library.
 All occurrences of \code{\#\_\id} \emph{in the same library} evaluate to the same instance,
 and no other symbol literals evaluate to that \code{Symbol} instance
-or to a \code{Symbol} instance that is \code{==} to that instance.
+or to a \code{Symbol} instance that is \lit{==} to that instance.
 
 \LMHash{}%
 The objects created by symbol literals all override
-the \code{==} operator inherited from the \code{Object} class.
+the \lit{==} operator inherited from the \code{Object} class.
 
 \rationale{
 One may well ask what is the motivation for introducing literal symbols? In some languages, symbols are canonicalized whereas strings are not.
@@ -6441,6 +6646,7 @@
 \LMHash{}%
 The static type of a symbol literal is \code{Symbol}.
 
+
 \subsection{Lists}
 \LMLabel{lists}
 
@@ -6458,7 +6664,8 @@
 A list has an associated set of indices.
 An empty list has an empty set of indices.
 A non-empty list has the index set $\{0, \ldots, n - 1\}$ where $n$ is the size of the list.
-It is a run-time error to attempt to access a list using an index that is not a member of its set of indices.
+It is a dynamic error to attempt to access a list
+using an index that is not a member of its set of indices.
 
 \LMHash{}%
 If a list literal begins with the reserved word \CONST{}, it is a
@@ -6469,11 +6676,11 @@
 and it is evaluated at run time.
 Only run-time list literals can be mutated
 after they are created.
+% This error can occur because being constant is a dynamic property, here.
 Attempting to mutate a constant list literal will result in a dynamic error.
 
 \LMHash{}%
 It is a compile-time error if an element of a constant list literal is not a constant expression.
-% Need 'free': `const <Function(Function<X>(X))>[]` is OK, but `X` is not free.
 It is a compile-time error if the type argument of a constant list literal is
 not a constant type expression.
 \rationale{
@@ -6509,26 +6716,31 @@
 is evaluated as follows:
 \begin{itemize}
 \item
-First, the expressions $e_1, \ldots, e_n$ are evaluated in order they appear in the program, producing objects $o_1, \ldots, o_n$.
-\item A fresh instance (\ref{generativeConstructors}) $a$, of size $n$, whose class implements the built-in class
-\code{List<$E$>}
-is allocated.
+  First, the expressions $e_1, \ldots, e_n$ are evaluated
+  in order they appear in the program,
+  producing objects $o_1, \ldots, o_n$.
 \item
-The operator \syntax{`[]='} is invoked on $a$ with first argument $i$ and second argument
-%The $i$th element of $a$ is set to
-$o_{i+1}, 0 \le i < n$.
+  A fresh instance (\ref{generativeConstructors}) $a$, of size $n$,
+  whose class implements the built-in class \code{List<$E$>}
+  is allocated.
 \item
-The result of the evaluation is $a$.
+  The operator \lit{[]=} is invoked on $a$ with
+  first argument $i$ and second argument
+  $o_{i+1}, 0 \le i < n$.
+\item
+  The result of the evaluation is $a$.
 \end{itemize}
 
 \LMHash{}%
 The objects created by list literals do not override
-the \code{==} operator inherited from the \code{Object} class.
+the \lit{==} operator inherited from the \code{Object} class.
 
 \commentary{
-Note that this document does not specify an order in which the elements are set.
-This allows for parallel assignments into the list if an implementation so desires.
-The order can only be observed (and may not be relied upon):
+Note that this document does not specify an order
+in which the elements are set.
+This allows for parallel assignments into the list
+if an implementation so desires.
+The order can only be observed as follows (and may not be relied upon):
 if element $i$ is not a subtype of the element type of the list,
 a dynamic type error will occur when $a[i]$ is assigned $o_{i-1}$.
 }
@@ -6583,8 +6795,8 @@
 If $e$ has three or more type arguments, it is a compile-time error.
 If $e$ has \emph{no} type arguments,
 then let $S$ be the static context type of the literal.
-If $\basetype{S}$ (\ref{typeFutureOr}) is a subtype of \code{Iterable<Object>}
-and $\basetype{S}$ is not a subtype of \code{Map<Object, Object>},
+If $\futureOrBase{S}$ (\ref{typeFutureOr}) is a subtype of \code{Iterable<Object>}
+and $\futureOrBase{S}$ is not a subtype of \code{Map<Object, Object>},
 then $e$ is set literal,
 and otherwise it is a map literal.
 A map literal derived from \synt{setOrMapLiteral}
@@ -6606,24 +6818,20 @@
 \IndexCustom{run-time map literal}{literal!map!run-time}
 and it is evaluated at run time.
 Only run-time map literals can be mutated after they are created.
+% This error can occur because being constant is a dynamic property, here.
 Attempting to mutate a constant map literal will result in a dynamic error.
 
 \LMHash{}%
-It is a compile-time error if either a key or a value of an entry in a constant map literal is not a constant expression.
-It is a compile-time error if the key of an entry in a constant map literal is an instance of
-a class that has a concrete operator \syntax{`=='} declaration different from the one in \code{Object},
-unless the key is a string or an integer,
-the key expression evaluates to an instance of the built-in
-class \code{Symbol} which was originally obtained by evaluation of a
-literal symbol or
-a constant invocation of a constructor of the \code{Symbol} class,
-or to an object implementing the built-in class \code{Type}
-which was originally obtained by evaluating a constant type literal
-(\ref{dynamicTypeSystem}).
-% Needs 'free': `const <int, Function(Function<X>(X))>{}` is OK, but
-% `X` is not free.
+It is a compile-time error if
+either a key or a value of an entry in a constant map literal
+is not a constant expression.
+It is a compile-time error if
+the operator \lit{==} of the key of an entry in a constant map literal
+is not primitive
+(\ref{theOperatorEqualsEquals}).
 It is a compile-time error if a type argument of a constant map literal
-is not a constant type expression \ref{constants}.
+is not a constant type expression
+(\ref{constants}).
 
 \LMHash{}%
 The value of a constant map literal
@@ -6651,7 +6859,7 @@
 
 \LMHash{}%
 It is a compile-time error if two keys of a constant map literal are equal
-according to their \code{==} operator (\ref{equality}).
+according to their \lit{==} operator (\ref{equality}).
 
 \LMHash{}%
 A run-time map literal
@@ -6659,21 +6867,25 @@
 is evaluated as follows:
 \begin{itemize}
 \item
-For each $i \in 1 .. n$ in numeric order,
-first the expression $k_i$ is evaluated producing object $u_i$,
-and then $e_i$ is evaluated producing object $o_i$.
-This produces all the objects $u_1, o_1, \ldots, u_n, o_n$.
-\item A fresh instance (\ref{generativeConstructors}) $m$
-whose class implements the built-in class \code{Map<$K, V$>}, is allocated.
+  For each $i \in 1 .. n$ in numeric order,
+  first the expression $k_i$ is evaluated producing object $u_i$,
+  and then $e_i$ is evaluated producing object $o_i$.
+  This produces all the objects $u_1, o_1, \ldots, u_n, o_n$.
 \item
-The operator \syntax{`[]='} is invoked on $m$ with first argument $u_i$ and second argument $o_i$ for each $i \in 1 .. n$.
+  A fresh instance (\ref{generativeConstructors}) $m$
+  whose class implements the built-in class \code{Map<$K, V$>},
+  is allocated.
 \item
-The result of the evaluation is $m$.
+  The operator \lit{[]=} is invoked on $m$
+  with first argument $u_i$ and second argument $o_i$
+  for each $i \in 1 .. n$.
+\item
+  The result of the evaluation is $m$.
 \end{itemize}
 
 \LMHash{}%
 The objects created by map literals do not override
-the \code{==} operator inherited from the \code{Object} class.
+the \lit{==} operator inherited from the \code{Object} class.
 
 \LMHash{}%
 A run-time map literal
@@ -6683,11 +6895,13 @@
 \code{<\DYNAMIC{}, \DYNAMIC{}>\{$k_1:e_1, \ldots, k_n:e_n$\}}.
 
 \LMHash{}%
-A map literal is ordered: iterating over the keys and/or values of the maps always happens in the
- order the keys appeared in the source code.
+A map literal is ordered:
+iterating over the keys and/or values of the maps
+always happens in the order the keys appeared in the source code.
 
 \commentary{
-Of course, if a key repeats, the order is defined by first occurrence, but the value is defined by the last.
+Of course, if a key repeats, the order is defined by first occurrence,
+but the value is defined by the last.
 }
 
 \LMHash{}%
@@ -6740,24 +6954,22 @@
 \IndexCustom{run-time set literal}{literal!set!run-time}
 and it is evaluated at run time.
 Only run-time set literals can be mutated after they are created.
+% This error can occur because being constant is a dynamic property, here.
 Attempting to mutate a constant set literal will result in a dynamic error.
 
 \LMHash{}%
-It is a compile-time error if an element expression in a constant set literal is not a constant expression.
-It is a compile-time error if the element object in a constant set literal is an instance of
-a class that has a concrete operator \syntax{`=='} declaration different from the one in \code{Object},
-unless the element is a string or an integer,
-the element expression evaluates to an instance of the built-in
-class \code{Symbol} which was originally obtained by evaluation of a
-literal symbol or
-a constant invocation of a constructor of the \code{Symbol} class,
-or to an object implementing the built-in class \code{Type}
-which was originally obtained by evaluating a constant type literal
-(\ref{dynamicTypeSystem}).
+It is a compile-time error if an element expression in a constant set literal
+is not a constant expression.
+It is a compile-time error if
+the operator \lit{==} of an element expression in a constant map literal
+is not primitive
+(\ref{theOperatorEqualsEquals}).
 It is a compile-time error if the type argument of a constant set literal
-is not a constant type expression \ref{constants}.
+is not a constant type expression
+(\ref{constants}).
 It is a compile-time error if two elements of a constant set literal are equal
-according to their \code{==} operator (\ref{equality}).
+according to their \lit{==} operator
+(\ref{equality}).
 
 \LMHash{}%
 The value of a constant set literal with element expressions
@@ -6801,7 +7013,7 @@
 
 \LMHash{}%
 The objects created by set literals do not override
-the \code{==} operator inherited from the \code{Object} class.
+the \lit{==} operator inherited from the \code{Object} class.
 
 \LMHash{}%
 A set literal is ordered: iterating over the elements of the sets
@@ -6819,6 +7031,7 @@
 is
 \code{Set<$E$>}.
 
+
 \subsection{Throw}
 \LMLabel{throw}
 
@@ -7191,9 +7404,7 @@
 \code{\CONST{} $T$($a_1, \ldots,\ a_n,\ x_{n+1}$: $a_{n+1}, \ldots,\ x_{n+k}$: $a_{n+k}$)}
 
 \noindent
-is malformed (\ref{staticTypes}),
-is malbounded (\ref{parameterizedTypes}),
-or is an enumerated type (\ref{enums}).
+is an enumerated type (\ref{enums}).
 
 
 \subsubsection{New}
@@ -7307,6 +7518,7 @@
 
 \noindent
 \commentary{Note that the non-generic case is covered by letting $m = 0$.}
+% This error can occur due to an implicit cast.
 If for any
 $j \in 1 .. n + k$
 the run-time type of $o_j$ is not a subtype of
@@ -7315,7 +7527,10 @@
 
 \LMHash{}%
 \Case{Non-loaded deferred constructors}
-If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs.
+% This error can occur because being-loaded is a dynamic property.
+If $T$ is a deferred type with prefix $p$,
+then if $p$ has not been successfully loaded,
+a dynamic error occurs.
 \EndCase
 
 \LMHash{}%
@@ -7582,7 +7797,10 @@
 
 \LMHash{}%
 An isolate's memory is finite, as is the space available to its thread's call stack.
-It is possible for a running isolate to exhaust its memory or stack, resulting in a run-time error that cannot be effectively caught, which will force the isolate to be suspended.
+% This error can occur because memory usage is a dynamic property.
+It is possible for a running isolate to exhaust its memory or stack,
+resulting in a dynamic error that cannot be effectively caught,
+which will force the isolate to be suspended.
 
 \commentary{
 As discussed in section \ref{errorsAndWarnings}, the handling of a suspended isolate is the responsibility of the embedder.
@@ -7748,10 +7966,13 @@
 \end{grammar}
 
 \LMHash{}%
-Argument lists allow an optional trailing comma after the last argument (\syntax{`,'?}).
-An argument list with such a trailing comma is equivalent in all ways to the same parameter list without the trailing comma.
+Argument lists allow an optional trailing comma after the last argument
+(\syntax{`,'?}).
+An argument list with such a trailing comma is equivalent in all ways to
+the same parameter list without the trailing comma.
 All argument lists in this specification are shown without a trailing comma,
-but the rules and semantics apply equally to the corresponding argument list with a trailing comma.
+but the rules and semantics apply equally to
+the corresponding argument list with a trailing comma.
 
 \LMHash{}%
 Let $L$ be an argument list of the form
@@ -7771,15 +7992,18 @@
 \code{($T_1\ x_1 \ldots,\ T_n\ x_n,\ $[$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$])}
 
 \noindent
-where each parameter may be marked \COVARIANT{} (\commentary{not shown, but allowed}).
+where each parameter may be marked \COVARIANT{}
+(\commentary{not shown, but allowed}).
 
 \LMHash{}%
 We say that $\argumentList{S}$ is
 a \Index{subtype match} for $\parameterList{P}$
-if{}f $p = 0$, $n \leq m \leq n+k$, and $S_i$ is a subtype of $T_i$ for all $i \in 1 .. m$.
+if{}f $p = 0$, $n \leq m \leq n+k$, and $S_i$ is
+a subtype of $T_i$ for all $i \in 1 .. m$.
 We say that $\argumentList{S}$ is
 an \Index{assignable match} for $\parameterList{P}$
-if{}f $p = 0$, $n \leq m \leq n+k$, and $S_i$ is assignable to $T_i$ for all $i \in 1 .. m$.
+if{}f $p = 0$, $n \leq m \leq n+k$, and $S_i$ is
+assignable to $T_i$ for all $i \in 1 .. m$.
 
 \LMHash{}%
 Let $\argumentList{S}$ be the static argument list type
@@ -7792,7 +8016,8 @@
 \code{($T_1\ x_1 \ldots,\ T_n\ x_n,\ $\{$T_{n+1}\ x_{n+1} = d_1, \ldots,\ T_{n+k}\ x_{n+k} = d_k$\})}
 
 \noindent
-where each parameter may be marked \COVARIANT{} (\commentary{not shown, but allowed}).
+where each parameter may be marked \COVARIANT{}
+(\commentary{not shown, but allowed}).
 
 \LMHash{}%
 We say that $\argumentList{S}$ is
@@ -8099,15 +8324,18 @@
 
 \LMHash{}%
 % Check the type arguments.
+% This error can occur due to covariance and due to dynamic invocation.
 It is a dynamic type error if $t_i$ is not a subtype of the actual bound
 (\ref{actualTypeOfADeclaration})
 of the $i$th type argument of $f$, for actual type arguments $t_1, \ldots, t_r$.
 % Check the types of positional arguments.
+% This error can occur due to implicit casts, covariance, and dynamic calls.
 It is a dynamic type error if $o_i$ is not the null object (\ref{null})
 and the actual type
 (\ref{actualTypeOfADeclaration})
 of $p_i$ is not a supertype of the dynamic type of $o_i, i \in 1 .. m$.
 % Check the types of named arguments.
+% This error can occur due to implicit casts, covariance, and dynamic calls.
 It is a dynamic type error if $o_{m+j}$ is
 not the null object and the actual type
 (\ref{actualTypeOfADeclaration})
@@ -8304,15 +8532,15 @@
 There does not exist a function type $F'$ which is a proper subtype of $F$
 such that $C$ is a subtype of $F'$.
 If $f$ denotes a static method or top-level function,
-class $C$ does not override the \code{==} operator
+class $C$ does not override the \lit{==} operator
 inherited from the \code{Object} class.
 
-\commentary{
+\commentary{%
 In other words, $C$ has the freedom to be a proper subtype of
 the function type that we can read off of the declaration of $f$
 because it may need to be a specific internal platform defined class,
 but $C$ does not have the freedom to be a subtype of
-a different and more special function type, and it cannot be \code{Null}.
+a different and more special function type, and it cannot be \code{Null}.%
 }
 
 \LMHash{}%
@@ -8326,6 +8554,217 @@
 as the invocation of $f$ would have yielded.
 
 
+\subsubsection{Generic Function Instantiation}
+\LMLabel{genericFunctionInstantiation}
+
+%% TODO(eernst): The specification of generic function instantiation relies
+%% on type inference in a different way than other mechanisms that we have
+%% specified, because it is impossible to claim that 'type inference is
+%% assumed to have taken place already' and then we just consider the
+%% program where the missing type arguments or type annotations have been
+%% added syntactically. Consequently, this section will probably need to be
+%% rewritten rather extensively when we add a specification of inference.
+
+\LMHash{}%
+Generic function instantiation is a mechanism that yields
+a non-generic function object,
+based on a reference to a generic function.
+
+\commentary{%
+It is a mechanism which is very similar to function closurization
+(\ref{functionClosurization}),
+but it only occurs in situations where
+a compile-time error would otherwise occur.
+}
+
+\rationale{%
+The essence of generic function instantiation
+is to allow for ``curried'' invocations,
+in the sense that a generic function can receive its actual
+type arguments separately during closurization
+(it must then receive \emph{all} type arguments, not just some of them),
+and that yields a non-generic function object.
+The type arguments are passed implicitly, based on type inference;
+a future version of Dart may allow for passing them explicitly.%
+}
+\commentary{Here is an example:}
+
+\begin{dartCode}
+X fg<X \EXTENDS{} num>(X x) => x;
+\\
+\CLASS{} A \{
+  \STATIC{} X fs<X \EXTENDS{} num>(X x) => x;
+\}
+\\
+\VOID{} main() \{
+  X fl<X \EXTENDS{} num>(X x) => x;
+  List<int \FUNCTION{}(int)> functions = [fg, A.fs, fl];
+\}
+\end{dartCode}
+
+\commentary{%
+\noindent
+Each function object stored in \code{functions}
+has dynamic type \code{int\,\,\FUNCTION(int)},
+and it is obtained by implicitly
+``passing the actual type argument \code{int}''
+to the corresponding generic function.
+}
+
+\LMHash{}%
+Let $f$ of the form
+\syntax{<identifier> ('.'~<identifier>\,('.'~<identifier>)?)?}~be
+an expression that denotes
+a declaration of a local function, a static method, or a top-level function,
+and let $G$ be the static type of $f$.
+Consider the situation where $G$ is a function type of the form
+\RawFunctionType{T_0}{X}{B}{s}{\metavar{parameters}}
+with $s > 0$
+(\commentary{that is, $G$ is a generic function type}),
+and the context type is a non-generic function type $F$.
+In this situation a compile-time error occurs
+(\ref{variables},
+\ref{functions},
+\ref{generativeConstructors},
+\ref{redirectingGenerativeConstructors},
+\ref{initializerLists},
+\ref{new},
+\ref{const},
+\ref{bindingActualsToFormals},
+\ref{assignment},
+\ref{localVariableDeclaration},
+\ref{switch},
+\ref{return},
+\ref{yieldEach}),
+except when the following step succeeds:
+
+\LMHash{}%
+\IndexCustom{Generic function type instantiation}{%
+  generic function type instantiation}:
+Type inference is applied to $G$ with context type $F$,
+and it succeeds, yielding the actual type argument list
+\List{T}{1}{s}.
+
+\commentary{%
+The generic function type instantiation fails
+in the case where type inference fails,
+in which case the above mentioned compile-time error occurs.
+It will be specified in a future version of this document
+how type inference computes \List{T}{1}{s}
+(\ref{overview}).
+}
+
+\LMHash{}%
+Otherwise, the generic function type instantiation succeeded.
+Let $F'$ denote the type
+$[T_1/X_1, \ldots, T_s/X_s]%
+(\FunctionTypeSimple{T_0}{\metavar{parameters}})$.
+\commentary{%
+Note that it is guaranteed that $F'$ is assignable to $F$,
+or inference would have failed.%
+}
+
+\LMHash{}%
+\Case{Top-level Functions and Static Methods}
+Consider the situation where $f$ denotes
+a top-level function or a static method.
+%
+In this situation, the program is modified such that $f$ is replaced by
+a reference $f'$ to an implicitly induced non-generic function
+whose signature is $F'$,
+whose dynamic type is $[t_1/T_1, \ldots, t_s/T_s]F'$,
+and whose semantics for each invocation is the same as
+invoking $f$ with \List{t}{1}{s} as the actual type argument list,
+where \List{t}{1}{s} is the actual value of \List{T}{1}{s}
+at the point during execution where $f'$ was evaluated.
+\commentary{Here is an example:}
+
+\begin{dartCode}
+List<T> foo<T>(T t) => [t];
+List<int> fooOfInt(int i) => [i];
+\\
+String bar(List<int> f(int)) => "\${f(42)}";
+\\
+\VOID{} main() \{
+  print(bar(foo));
+\}
+\end{dartCode}
+
+\commentary{%
+In this example,
+\code{foo} as an actual argument to \code{bar} will be modified
+as if the call had been \code{bar(fooOfInt)},
+except for equality, which is specified next.
+}
+
+\LMHash{}%
+Consider the situation where the program
+before generic function instantiation contains
+two occurrences of $f$ in the same scope or different scopes,
+but denoting the same function,
+respectively the situation where
+an execution of the program containing $f$ evaluates it twice.
+Let $o_1$ and $o_2$ denote the function objects obtained by
+evaluation of those two expressions,
+respectively the two evaluations of that expression.
+
+\LMHash{}%
+In the case where the actual values of the type arguments
+are the same for both evaluations,
+it is guaranteed that $o_1$ and $o_2$ are equal
+according to operator \lit{==}.
+However, it is unspecified whether
+\code{identical($o_1$, $o_2$)} evaluates to \TRUE{} or \FALSE{}.
+
+\rationale{%
+No notion of equality is appropriate
+when different type arguments are provided,
+even if the resulting function objects
+turn out to have exactly the same type at run time,
+because execution of two function objects that differ in these ways
+can have different side-effects and return different results
+when executed starting from exactly the same state.%
+}
+\commentary{%
+For instance, there could be a type parameter \code{X}
+that does not occur in the signature of the function,
+and the function could create and return a \code{List<X>}.%
+}
+
+\LMHash{}%
+\Case{Local Functions}
+Consider the situation where $f$ is an identifier denoting a local function.
+\commentary{For a local function, only an identifier can denote it.}
+%
+In this situation, the program is modified such that $f$ is replaced by
+a reference $f'$ to an implicitly induced non-generic function
+whose signature is $F'$,
+whose dynamic type is $[t_1/T_1, \ldots, t_s/T_s]F'$,
+and whose semantics for each invocation is the same as
+invoking $f$ with \List{t}{1}{s} as the actual type argument list,
+where \List{t}{1}{s} is the actual value of \List{T}{1}{s}
+at the point during execution where $f'$ was evaluated.
+
+\commentary{%
+No guarantees are provided regarding equality
+of non-generic functions obtained from a local function
+by generic function instantiation.%
+}
+
+\rationale{%
+Such a local function could have received exactly
+the same actual type arguments in the two cases,
+and still its body could contain references
+to declarations of types, variables, and other entities
+in the enclosing scopes.
+Those references could denote different entities
+when the two function objects were created.
+In that situation it is unreasonable
+to consider the two function objects to be the same function.%
+}
+\EndCase{}
+
+
 \subsection{Lookup}
 \LMLabel{lookup}
 
@@ -8337,12 +8776,12 @@
 A lookup may be part of the static analysis, and it may be performed
 at run time. It may succeed or fail.
 
-\commentary{
+\commentary{%
 We define several kinds of lookup with a very similar structure.
 We spell out each of them in spite of the redundancy,
 in order to avoid introducing meta-level abstraction mechanisms just for this purpose.
 The point is that we must indicate for each lookup which kind of member it is looking for,
-because, e.g., a `method lookup' and a `getter lookup' are used in different situations.
+because, e.g., a `method lookup' and a `getter lookup' are used in different situations.%
 }
 
 { % Scope for 'lookup' definition.
@@ -9237,6 +9676,259 @@
 \code{$c_1$ == $c_2$} is then true if and only if $o_1$ and $o_2$ is the same object.
 
 
+\subsubsection{Generic Method Instantiation}
+\LMLabel{genericMethodInstantiation}
+
+%% TODO(eernst): Like generic function instantiation, generic method instantiation
+%% relies on type inference. See the comment in \ref{genericFunctionInstantiation}
+%% for further details.
+
+\LMHash{}%
+Generic method instantiation is a mechanism that yields
+a non-generic function object,
+based on a property extraction which denotes an instance method closurization
+(\ref{ordinaryMemberClosurization}, \ref{superClosurization}).
+
+\commentary{%
+It is a mechanism which is very similar to instance method closurization,
+but it only occurs in situations where
+a compile-time error would otherwise occur.%
+}
+
+\rationale{%
+The essence of generic method instantiation
+is to allow for ``curried'' invocations,
+in the sense that a generic instance method can receive its actual
+type arguments separately during closurization
+(it must then receive \emph{all} type arguments, not just some of them),
+and that yields a non-generic function object.
+The type arguments are passed implicitly, based on type inference;
+a future version of Dart may allow for passing them explicitly.%
+}
+\commentary{Here is an example:}
+
+\begin{dartCode}
+\CLASS{} A \{
+  X fi<X \EXTENDS{} num>(X x) => x;
+\}
+\\
+\CLASS{} B \EXTENDS{} /*\,or\,\,\IMPLEMENTS\,*/ A \{
+  X fi<X \EXTENDS{} num>(X x, [List<X> xs]) => x;
+\}
+\\
+\VOID{} main() \{
+  A a = B();
+  int \FUNCTION{}(int) f = a.fi;
+\}
+\end{dartCode}
+
+\commentary{%
+\noindent
+The function object which is stored in \code{f} at the end of \code{main}
+has dynamic type \code{int\,\,\FUNCTION(int,\,[List<int>])},
+and it is obtained by implicitly
+``passing the actual type argument \code{int}''
+to the denoted generic instance method,
+thus obtaining a non-generic function object of the specified type.
+%
+Note that this function object accepts an optional positional argument,
+even though this is not part of
+the statically known type of the corresponding instance method,
+nor of the context type.
+}
+
+\rationale{%
+In other words, generic method instantiation yields a function
+whose signature matches the context type as far as possible,
+but with respect to its parameter list shape
+(that is, the number of positional parameters and their optionality,
+or the set of names of named parameters),
+it will be determined by the method signature of the actual instance method
+of the given receiver.
+Of course, the difference can only be such that the actual type is
+% This is about the dynamic type, so there is no exception for \COVARIANT.
+a subtype of the given context type,
+otherwise the declaration of that instance method
+would have been a compile-time error.%
+}
+
+\LMHash{}%
+Let $i$ be a property extraction expression of the form
+\code{$e$?.\id}, \code{$e$.\id}, or \code{\SUPER.\id}
+(\ref{propertyExtraction}, \ref{superGetterAccessAndMethodClosurization}),
+which is statically resolved to denote an instance method named \id,
+and let $G$ be the static type of $i$.
+Consider the situation where $G$ is a function type of the form
+\RawFunctionType{T_0}{X}{B}{s}{\metavar{parameters}}
+with $s > 0$
+(\commentary{that is, $G$ is a generic function type}),
+and the context type is a non-generic function type $F$.
+In this situation a compile-time error occurs
+(\ref{variables},
+\ref{functions},
+\ref{generativeConstructors},
+\ref{redirectingGenerativeConstructors},
+\ref{initializerLists},
+\ref{new},
+\ref{const},
+\ref{bindingActualsToFormals},
+\ref{assignment},
+\ref{localVariableDeclaration},
+\ref{switch},
+\ref{return},
+\ref{yieldEach}),
+except when generic function type instantiation
+(\ref{genericFunctionInstantiation})
+succeeds, that is:
+
+\LMHash{}%
+Type inference is applied to $G$ with context type $F$,
+and it succeeds, yielding the actual type argument list
+\List{T}{1}{s}.
+
+{ % Scope for \gmiName.
+
+\def\gmiName{\metavar{gmiName\ensuremath{_{\id}}}}
+
+% For any given method name \id, \gmiName is the "associated" name which
+% is used for the implicitly induced method that we use to get the function
+% object which is the result of a generic method instantiation. Let's call
+% that associated method the "generic instantiation method".
+%
+% The basic idea is that we consider all libraries included in the
+% compilation of a complete Dart program, and then we select a suffix,
+% say `_*`, which is globally unique (because no user-written identifier
+% can have that suffix, and the compiler doesn't use anything similar
+% for other purposes).
+%
+% When we have found such a "globally fresh suffix", it is easy to see
+% that we can use it to specify the implicitly induced methods in a way
+% that will do the right thing:
+%
+% Assume that a class `C` has a generic method `foo`, and it is subject
+% to generic method instantiation.
+%
+% We then generate a generic instantiation method for `foo` in in `C`, with the
+% name `foo_*`. If there is a subclass `D` of `C` which has an overriding
+% declaration of `foo` then we also generate a `foo_*` generic instantiation
+% method in `D`, and that one might return a closure with a different parameter
+% list shape, because that's the way `foo` is declared in `D`.
+%
+% We can then call `e.foo_*<...>()` where `e` has static type `C`,
+% at a location where the original source code had `e.foo` and the context
+% type was non-generic (so generic method instantiation kicked in).
+% This may invoke `foo_*` in `C`, or `D`, or some other class, whatever is the
+% dynamic type of the result of evaluating `e`.
+%
+% Altogether, this ensures that we obtain a function object whose parameter
+% list shape corresponds precisely to the parameter list shape of `foo` in
+% the dynamic type of the receiver, as it should. There will not be any
+% name clashes with user-written declarations, and overriding declarations
+% will actually override as they should, because they all use that same
+% "globally fresh suffix".
+%
+% The text below tries to communicate how this could work without being too
+% much like a particular implementation.
+
+\LMHash{}%
+Consider the situation where generic function type instantiation succeeded.
+Let \gmiName{} be a fresh name which is associated with \id{},
+which is private if and only if \id{} is private.
+\commentary{%
+An implementation could use, say, \code{foo_*} when \id{} is \code{foo},
+which is known to be fresh because user-written identifiers cannot contain `\code{*}'.%
+}
+The program is then modified as follows:
+
+\begin{itemize}
+\item When $i$ is \code{$e$?.\id}:
+  Replace $i$ by \code{$e$?.\gmiName<\List{T}{1}{s}>()}.
+\item When $i$ is \code{$e$.\id}:
+  Replace $i$ by \code{$e$.\gmiName<\List{T}{1}{s}>()}.
+\item When $i$ is \code{\SUPER.\id}:
+  Replace $i$ by \code{\SUPER.\gmiName<\List{T}{1}{s}>()}.
+\end{itemize}
+
+\LMHash{}%
+The inserted expressions have no compile-time error and can be executed,
+because the corresponding generic method is induced implicitly.
+We use the phrase
+\Index{generic instantiation method}
+to denote these implicitly induced methods,
+and designate the method that induced it as its
+\IndexCustom{target}{generic instantiation method!target}.
+
+\LMHash{}%
+Assume that a class $C$ declares a generic instance method named \id,
+with a method signature corresponding to a generic function type $G$,
+formal type parameters \TypeParametersStd{},
+and formal parameter declarations \metavar{parameters}.
+Let \metavar{arguments} denote the corresponding actual argument list,
+passing these parameters.
+\commentary{%
+For instance, \metavar{parameters} could be
+
+\noindent
+\code{$\PairList{T}{p}{1}{n},\ $\{$T_{n+1}\ p_{n+1} = d_1, \ldots,\ T_{n+k}\ p_{n+k} = d_k$\}}
+
+\noindent
+in which case \metavar{arguments} would be
+\code{\List{p}{1}{n},\ $p_{n+1}$:\ $p_{n+1}$,\ $p_{n+k}$:\ $p_{n+k}$}.%
+}
+
+\LMHash{}%
+Let $G'$ be the same function type as $G$,
+except that it omits the formal type parameter declarations.
+\commentary{%
+For instance, if $G$ is
+\FunctionTypeSimpleGeneric{\VOID}{$X$, $Y$ \EXTENDS\ num}{X x, List<Y> ys}
+then $G'$ is
+\FunctionTypeSimple{\VOID}{X x, List<Y> ys}.
+Note that $G'$ will typically contain free type variables.
+}
+
+\LMHash{}%
+An instance method with the name \gmiName{} is then implicitly induced,
+with the same behavior as the following declaration
+(except for equality of the returned function object,
+which is specified below):
+
+% Use `\THIS.\id..` because there could be a parameter named \id.
+\begin{normativeDartCode}
+$G'$ \gmiName<\TypeParametersStd{}>() \{
+\ \ \RETURN{} (\metavar{parameters}) => \THIS.\id<\List{X}{1}{s}>(\metavar{arguments});
+\}
+\end{normativeDartCode}
+
+\LMHash{}%
+Let $o$ be an instance of a class which contains
+an implicitly induced declaration of \gmiName{}
+as described above.
+%
+Consider the situation where the program evaluates
+two invocations of this method with the same receiver $o$,
+and with actual type arguments whose actual values are
+the same types \List{t}{1}{s} for both invocations,
+and assume that the invocations returned
+the instances $o_1$ respectively $o_2$.
+%
+It is then guaranteed that $o_1$ and $o_2$ are equal
+according to operator \lit{==}.
+It is unspecified whether
+\code{identical($o_1$, $o_2$)}
+evaluates to \TRUE{} or \FALSE{}.
+
+} % End of scope for \gmiName.
+
+\rationale{%
+No notion of equality is appropriate with different receivers,
+nor when different type arguments are provided,
+because execution of two function objects that differ in these ways
+can have different side-effects and return different results
+when executed starting from exactly the same state.%
+}
+
+
 \subsection{Assignment}
 \LMLabel{assignment}
 
@@ -9314,8 +10006,9 @@
 Otherwise, the assignment is equivalent to the assignment \code{\THIS{}.$v$ = $e$}.
 
 \LMHash{}%
-It is a dynamic type error if $o$ is not the null object (\ref{null})
-and the dynamic type of $o$ is not a subtype of the actual type
+% This error can occur due to implicit casts.
+It is a dynamic type error if the dynamic type of $o$
+is not a subtype of the actual type
 (\ref{actualTypeOfADeclaration})
 of $v$.
 \EndCase
@@ -9356,6 +10049,7 @@
 The expression $e_1$ is evaluated to an object $o_1$.
 Then, the expression $e_2$ is evaluated to an object $o_2$.
 Then, the setter \code{$v$=} is looked up (\ref{lookup}) in $o_1$ with respect to the current library.
+% This error can occur due to implicit casts and dynamic calls.
 It is a dynamic type error if the dynamic type of $o_2$
 is not a subtype of the actual parameter type of said setter
 (\ref{actualTypeOfADeclaration}).
@@ -9416,6 +10110,7 @@
 The value of the assignment expression is $o$.
 
 \LMHash{}%
+% This error can occur due to implicit casts and mixin+covariance.
 It is a dynamic type error if $o$ is not the null object (\ref{null})
 and the dynamic type of $o$ is
 not a subtype of the actual type of the formal parameter of \code{$v$=}
@@ -9583,7 +10278,7 @@
 \Case{\code{$C$?.$v$ ??= $e_2$}}
 A compound assignment of the form \code{$C$?.$v$ ??= $e_2$}
 where $C$ is a type literal
-that may or may not be be qualified by an import prefix
+that may or may not be qualified by an import prefix
 is equivalent to the expression \code{$C$.$v$ ??= $e$}.
 \EndCase
 
@@ -9693,7 +10388,8 @@
 
 \LMHash{}%
 First, $e_1$ is evaluated to an object $o_1$.
-It is a run-time error if the run-time type of $o_1$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o_1$ is not \code{bool}.
 If $r$ is \TRUE, then the value of $c$ is the result of evaluating the expression $e_2$.
 Otherwise the value of $c$ is the result of evaluating the expression $e_3$.
 
@@ -9756,16 +10452,20 @@
 
 \LMHash{}%
 Evaluation of a logical boolean expression $b$ of the form $e_1 || e_2$ causes the evaluation of $e_1$ to a value $o_1$.
-It is a run-time error if the run-time type of $o_1$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o_1$ is not \code{bool}.
 If $o_1$ is \TRUE, the result of evaluating $b$ is \TRUE, otherwise $e_2$ is evaluated to an object $o_2$.
-It is a run-time error if the run-time type of $o_2$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o_2$ is not \code{bool}.
 Otherwise the result of evaluating $b$ is $o_2$.
 
 \LMHash{}%
 Evaluation of a logical boolean expression $b$ of the form $e_1 \&\& e_2$ causes the evaluation of $e_1$ producing an object $o_1$.
-It is a run-time error if the run-time type of $o_1$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o_1$ is not \code{bool}.
 If $o_1$ is \FALSE, the result of evaluating $b$ is \FALSE, otherwise $e_2$ is evaluated to an object $o_2$.
-It is a run-time error if the run-time type of $o_2$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o_2$ is not \code{bool}.
 Otherwise the result of evaluating $b$ is $o_2$.
 
 \LMHash{}%
@@ -9842,7 +10542,7 @@
 \end{itemize}
 
 \commentary{
-As a result of the above definition, user defined \code{==} methods can assume that their argument is non-null, and avoid the standard boiler-plate prelude:
+As a result of the above definition, user defined \lit{==} methods can assume that their argument is non-null, and avoid the standard boiler-plate prelude:
 
 \code{if (identical(\NULL{}, arg)) return \FALSE{};}
 
@@ -10012,6 +10712,7 @@
 The static type of an expression $e_1 * e_2$ where $e_1$ has static type \code{int} is \code{int} if the static type of $e_2$ is \code{int}, and \code{double} if the static type of $e_2$ is \code{double}.
 The static type of an expression $e_1 \% e_2$ where $e_1$ has static type \code{int} is \code{int} if the static type of $e_2$ is \code{int}, and \code{double} if the static type of $e_2$ is \code{double}.
 
+
 \subsection{Unary Expressions}
 \LMLabel{unaryExpressions}
 
@@ -10110,22 +10811,24 @@
 
 %Otherwise, the value of $a$ is the value of $e$. If evaluation of $e$ raises an exception $x$, $a$ raises $x$.
 
-\commentary{
-It is a compile-time error if the function immediately enclosing $a$ is not declared asynchronous.
-However, this error is simply a syntax error, because in the context of a normal function, \AWAIT{} has no special meaning.
-% TODO(lrn): Update this, it's not actually correct,
-% the expression "await(expr)" is valid non-async syntax *and* a valid
-% async await expression.
+\commentary{%
+It is typically a compile-time error
+if the function immediately enclosing $a$ is not declared asynchronous.
+E.g., it can be a syntax error because \AWAIT{} has no special meaning
+in the context of a normal function.
+However, \code{\AWAIT($e$)} can also be a function invocation.%
 }
 
-\rationale{
+\rationale{%
 An await expression has no meaning in a synchronous function.
-If such a function were to suspend waiting for a future, it would no longer be synchronous.
+If such a function were to suspend waiting for a future,
+it would no longer be synchronous.%
 }
 
-\commentary{
-It is not a compile-time error if the type of $e$ is not a subtype of \code{Future}.
-Tools may choose to give a hint in such cases.
+\commentary{%
+It is not a compile-time error if the type of $e$ is not
+a subtype of \code{Future}.
+Tools may choose to give a hint in such cases.%
 }
 
 \LMHash{}%
@@ -10436,7 +11139,7 @@
 If no such declaration exists in the lexical scope, let $d$ be the declaration of the inherited member named \id{} if it exists.
 
 \begin{itemize}
-\item if $d$ is a prefix $p$, a compile-time error occurs unless the token immediately following $d$ is \code{'.'}.
+\item if $d$ is a prefix $p$, a compile-time error occurs unless the token immediately following $d$ is `\code{.}'.
 \item If $d$ is a class or type alias $T$, the value of $e$ is an object implementing the class \code{Type} which reifies $T$.
 \item If $d$ is a type parameter $T$, then the value of $e$ is the value of the actual type argument corresponding to $T$ that was passed to the generative constructor that created the current binding of \THIS{}.
 If, however, $e$ occurs inside a static member, a compile-time error occurs.
@@ -10511,9 +11214,8 @@
 
 \LMHash{}%
 The expression $e$ is evaluated to a value $v$.
-% TODO(eernst): https://github.com/dart-lang/sdk/issues/34521.
-Then, if $T$ is a malformed or deferred type (\ref{staticTypes}), a dynamic error occurs.
-Otherwise, if the dynamic type of $v$ is a subtype of $T$, the is-expression evaluates to \TRUE.
+If the dynamic type of $v$ is a subtype of $T$,
+the is-expression evaluates to \TRUE.
 Otherwise it evaluates to \FALSE.
 
 \commentary{
@@ -10580,9 +11282,8 @@
 
 \LMHash{}%
 The expression $e$ is evaluated to a value $v$.
-%% TODO(eernst): https://github.com/dart-lang/sdk/issues/34521
-Then, if $T$ is a malformed or deferred type (\ref{staticTypes}), a dynamic error occurs.
-It is a dynamic type error if $o$ is not the null object (\ref{null})
+% This error can occur, by design of `as`.
+It is a dynamic type error if $o$ is not the null object (\ref{null}),
 and the dynamic type of $o$ is not a subtype of $T$.
 Otherwise $e$ evaluates to $v$.
 
@@ -10696,22 +11397,24 @@
 
 \LMHash{}%
 An \Index{expression statement} consists of an expression that does not
-begin with a \syntax{`{'} character.
+begin with a \lit{\{} character.
 
 \begin{grammar}
 <expressionStatement> ::= <expression>? `;'
 \end{grammar}
 
 \LMHash{}%
-The expression of an expression statement is not allowed to begin with a \syntax{`\{'}.
+The expression of an expression statement is not allowed
+to begin with a \lit{\{}.
 \commentary{
 This means that if some source text could otherwise be parsed as an expression
-followed by a \syntax{`;'}, then this grammar production does not apply
-when the expression starts with a \syntax{`\{'}.
+followed by a \lit{;}, then this grammar production does not apply
+when the expression starts with a \lit{\{}.
 }
 \rationale{
 The restriction resolves an ambiguity while parsing where a
-\syntax{`\{'} can start either a block (\ref{blocks}) or a map literal (\ref{maps}).
+\lit{\{} can start either a block (\ref{blocks}) or
+a map literal (\ref{maps}).
 By disallowing the latter from starting an expression statement,
 the parser does not need to look further ahead
 before deciding that it is parsing a block statement.
@@ -10884,6 +11587,7 @@
 \LMHash{}%
 The expression $e$ is evaluated to an object $o$.
 Then, the variable $v$ is set to $o$.
+% This error can occur due to implicit casts.
 A dynamic type error occurs
 if the dynamic type of $o$ is not a subtype of the actual type
 (\ref{actualTypeOfADeclaration})
@@ -10999,7 +11703,8 @@
 
 \LMHash{}%
 First, the expression $b$ is evaluated to an object $o$.
-It is a run-time error if the run-time type of $o$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o$ is not \code{bool}.
 If $o$ is \TRUE{}, then the block statement $s_1$ is executed, otherwise the block statement $s_2$ is executed.
 
 \LMHash{}%
@@ -11061,7 +11766,8 @@
 Otherwise, let $v'$ be the variable $v''$ created in the previous execution of step \ref{allocateFreshVar}.
 \item
 The expression $[v'/v]c$ is evaluated to a value $o$.
-It is a run-time error if the run-time type of $o$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o$ is not \code{bool}.
 If $o$ is \FALSE{}, the for loop completes normally.
 Otherwise, execution continues at step \ref{beginIteration}.
 \item
@@ -11149,6 +11855,7 @@
 
 \LMHash{}%
 The expression $e$ is evaluated to an object $o$.
+% This error can occur due to implicit casts and null.
 It is a dynamic type error if $o$ is not an instance of a class that implements \code{Stream}.
 It is a compile-time error if $D$ is empty and \id{} is a final variable.
 
@@ -11234,7 +11941,8 @@
 
 \LMHash{}%
 The expression $e$ is evaluated to an object $o$.
-It is a run-time error if the run-time type of $o$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o$ is not \code{bool}.
 
 \LMHash{}%
 If $o$ is \FALSE{}, then execution of the while statement completes normally (\ref{statementCompletion}).
@@ -11271,7 +11979,8 @@
 
 \LMHash{}%
 Then, the expression $e$ is evaluated to an object $o$.
-It is a run-time error if the run-time type of $o$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o$ is not \code{bool}.
 If $o$ is \FALSE{}, execution of the do statement completes normally (\ref{statementCompletion}).
 If $o$ is \TRUE{}, then the do statement is re-executed.
 
@@ -11334,25 +12043,23 @@
 }
 
 \LMHash{}%
-It is a compile-time error if the class $C$ has an implementation of
-the operator \code{==} other than the one inherited from \code{Object},
-unless the expression evaluates to a string or an integer,
-the expression evaluates to an instance of the built-in
-class \code{Symbol} which was initially obtained by evaluation of a
-literal symbol or
-a constant invocation of a constructor of the \code{Symbol} class,
-or to an object implementing the built-in class \code{Type}
-which was originally created by evaluating a constant type literal
-(\ref{dynamicTypeSystem}).
+It is a compile-time error if the operator \lit{==} of class $C$
+is not primitive
+(\ref{theOperatorEqualsEquals}).
 
 \rationale{
-The prohibition on user defined equality allows us to implement the switch efficiently for user defined types.
-We could formulate matching in terms of identity instead with the same efficiency.
-However, if a type defines an equality operator, programmers would find it quite surprising that equal objects did not match.
+The prohibition on user defined equality allows us to
+implement the switch efficiently for user defined types.
+We could formulate matching in terms of identity instead,
+with the same efficiency.
+However, if a type defines an equality operator,
+programmers would presumably find it quite surprising
+if equal objects did not match.
 }
 
 \commentary{
-The \SWITCH{} statement should only be used in very limited situations (e.g., interpreters or scanners).
+The \SWITCH{} statement should only be used in
+very limited situations (e.g., interpreters or scanners).
 }
 
 \LMHash{}%
@@ -11381,7 +12088,9 @@
 
 \LMHash{}%
 The statement \code{\VAR{} \id{} = $e$;} is evaluated, where \id{} is a fresh variable.
-It is a run-time error if the value of $e$ is
+% This error can occur due to implicit casts and standard subsumption.
+%% TODO(eernst): But why couldn't $e$ be an instance of a subtype?!
+It is a dynamic error if the value of $e$ is
 not an instance of the same class as the constants $e_1, \ldots, e_n$.
 
 \commentary{
@@ -11408,7 +12117,8 @@
 
 \LMHash{}%
 The expression \code{$e_k$ == \id} is evaluated to an object $o$.
-It is a run-time error if the run-time type of $o$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o$ is not \code{bool}.
 If $o$ is \FALSE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$, and if $k = n$, then the \DEFAULT{} clause's statements are executed (\ref{case-execute}).
 If $o$ is \TRUE{}, let $h$ be the smallest number such that $h \ge k$ and $s_h$ is non-empty.
 If no such $h$ exists, let $h = n + 1$.
@@ -11429,7 +12139,8 @@
 
 \LMHash{}%
 The expression \code{$e_k$ == \id} is evaluated to an object $o$.
-It is a run-time error if the run-time type of $o$ is not \code{bool}.
+% This error can occur due to implicit casts and null.
+It is a dynamic error if the run-time type of $o$ is not \code{bool}.
 If $o$ is \FALSE{} the following case, \CASE{} $e_{k+1}: s_{k+1}$ is matched against \id{} if $k < n$.
 If $o$ is \TRUE{}, let $h$ be the smallest integer such that $h \ge k$ and $s_h$ is non-empty.
 If such a $h$ exists, the case statements $s_h$ are executed (\ref{case-execute}).
@@ -11635,8 +12346,7 @@
 Otherwise the \TRY{} statement completes in the same way as the execution of $b$.
 
 \LMHash{}%
-If $T_1$ is a malformed or deferred type (\ref{staticTypes}), then performing a match causes a run-time error.
-It is a compile-time error if $T_i$, $1 \le i \le n$ is a deferred or malformed type.
+It is a compile-time error if $T_i$, $1 \le i \le n$ is a deferred type.
 
 
 \subsubsection{\ON{}-\CATCH{} clauses}
@@ -11871,8 +12581,10 @@
 \begin{itemize}
 \item
   If the body of $f$ is marked \ASYNC{} (\ref{functions})
+  % This error can occur due to implicit casts.
   it is a dynamic type error if \code{Future<$U$>} is not a subtype of $T$.
 \item
+  % This error can occur due to implicit casts.
   Otherwise, it is a dynamic type error if $U$ is not a subtype of $T$.
 \end{itemize}
 
@@ -12058,16 +12770,30 @@
 \LMHash{}%
 If the immediately enclosing function $m$ is marked \code{\SYNC*} (\ref{functions}), then:
 \begin{enumerate}
-\item It is a dynamic type error if the class of $o$ does not implement \code{Iterable}.
-Otherwise
-\item The method \code{iterator} is invoked upon $o$ returning an object $i$.
-\item \label{moveNext} The \code{moveNext} method of $i$ is invoked on it with no arguments.
-If \code{moveNext} returns \FALSE{} execution of $s$ is complete.
-Otherwise
-\item The getter \code{current} is invoked on $i$.
-If the invocation throws (\ref{evaluation}), execution of $s$ throws the same exception object and stack trace (\ref{statementCompletion}).
-Otherwise, the result $x$ of the getter invocation is added to the iterable associated with $m$.
-Execution of the function $m$ immediately enclosing $s$ is suspended until the nullary method \code{moveNext()} is invoked upon the iterator used to initiate the current invocation of $m$, at which point execution of $s$ continues at \ref{moveNext}.
+\item
+  % This error can occur due to implicit casts.
+  It is a dynamic type error
+  if the class of $o$ does not implement \code{Iterable}.
+  Otherwise
+\item
+  The method \code{iterator} is invoked upon $o$ returning an object $i$.
+\item
+  \label{moveNext} The \code{moveNext} method of $i$ is invoked on it
+  with no arguments.
+  If \code{moveNext} returns \FALSE{} execution of $s$ is complete.
+  Otherwise
+\item
+  The getter \code{current} is invoked on $i$.
+  If the invocation throws
+  (\ref{evaluation}),
+  execution of $s$ throws the same exception object and stack trace
+  (\ref{statementCompletion}).
+  Otherwise, the result $x$ of the getter invocation is added to
+  the iterable associated with $m$.
+  Execution of the function $m$ immediately enclosing $s$ is suspended
+  until the nullary method \code{moveNext()} is invoked
+  upon the iterator used to initiate the current invocation of $m$,
+  at which point execution of $s$ continues at \ref{moveNext}.
 \item
 The current call to \code{moveNext()} returns \TRUE.
 \end{enumerate}
@@ -12075,32 +12801,50 @@
 \LMHash{}%
 If $m$ is marked \code{\ASYNC*} (\ref{functions}), then:
 \begin{itemize}
-\item It is a dynamic type error if the class of $o$ does not implement \code{Stream}.
+\item
+  % This error can occur due to implicit casts.
+  It is a dynamic type error if the class of $o$
+  does not implement \code{Stream}.
 Otherwise
-\item The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}), if any, is paused.
-\item The $o$ stream is listened to, creating a subscription $s$, and for each event $x$, or error $e$ with stack trace $t$, of $s$:
+\item
+  The nearest enclosing asynchronous for loop (\ref{asynchronousFor-in}),
+  if any, is paused.
+\item
+  The $o$ stream is listened to, creating a subscription $s$,
+  and for each event $x$, or error $e$ with stack trace $t$, of $s$:
 \begin{itemize}
 \item
-If the stream $u$ associated with $m$ has been paused, then execution of $m$ is suspended until $u$ is resumed or canceled.
+  If the stream $u$ associated with $m$ has been paused,
+  then execution of $m$ is suspended until $u$ is resumed or canceled.
 \item
-If the stream $u$ associated with $m$ has been canceled,
-then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()} where $v$ is a fresh variable referencing the stream subscription $s$.
-Then, if the cancel completed normally, the stream execution of $s$ returns without a value (\ref{statementCompletion}).
+  If the stream $u$ associated with $m$ has been canceled,
+  then $s$ is canceled by evaluating \code{\AWAIT{} v.cancel()}
+  where $v$ is a fresh variable referencing the stream subscription $s$.
+  Then, if the cancel completed normally,
+  the stream execution of $s$ returns without a value
+  (\ref{statementCompletion}).
 \item
-Otherwise, $x$, or $e$ with $t$, are added to the stream associated with $m$ in the order they appear in $o$.
-The function $m$ may suspend.
+  Otherwise, $x$, or $e$ with $t$, are added to
+  the stream associated with $m$ in the order they appear in $o$.
+  The function $m$ may suspend.
 \end{itemize}
-\item If the stream $o$ is done, execution of $s$ completes normally.
+\item
+  If the stream $o$ is done, execution of $s$ completes normally.
 \end{itemize}
 
 \LMHash{}%
-It is a compile-time error if a yield-each statement appears in a function that is not a generator function.
+It is a compile-time error if a yield-each statement appears
+in a function that is not a generator function.
 
 \LMHash{}%
-Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing function.
-It is a compile-time error if $T$ may not be assigned to the declared return type of $f$.
-If $f$ is synchronous it is a compile-time error if $T$ may not be assigned to \code{Iterable}.
-If $f$ is asynchronous it is a compile-time error if $T$ may not be assigned to \code{Stream}.
+Let $T$ be the static type of $e$ and let $f$ be
+the immediately enclosing function.
+It is a compile-time error if $T$ may not be assigned to
+the declared return type of $f$.
+If $f$ is synchronous it is a compile-time error
+if $T$ may not be assigned to \code{Iterable}.
+If $f$ is asynchronous it is a compile-time error
+if $T$ may not be assigned to \code{Stream}.
 
 
 \subsection{Assert}
@@ -12138,6 +12882,7 @@
 
 \LMHash{}%
 The expression $c$ is evaluated to an object $r$.
+% This error can occur due to implicit casts and null.
 It is a dynamic type error if $r$ is not of type \code{bool}.
 \commentary{
 Hence it is a compile-time error if that situation arises during evaluation of an assertion in a \CONST{} constructor invocation.
@@ -12249,8 +12994,9 @@
 Script tags are intended for use with scripts (\ref{scripts}).
 A script tag can be used to identify the interpreter of the script to whatever computing environment the script is embedded in.
 The script tag must appear before any whitespace or comments.
-A script tag begins with \syntax{`#!'} and ends at the end of the line.
-Any characters that follow \syntax{`#!'} in the script tag are ignored by the Dart implementation.
+A script tag begins with \lit{\#!} and ends at the end of the line.
+Any characters that follow \lit{\#!} in the script tag are ignored by
+the Dart implementation.
 
 \LMHash{}%
 Libraries are units of privacy.
@@ -12316,7 +13062,8 @@
 It is a compile-time error if a prefix used in a deferred import is used in another import clause.
 
 \LMHash{}%
-An import directive $I$ may optionally include a namespace combinator clauses used to restrict the set of names imported by $I$.
+An import directive $I$ may optionally include namespace combinator clauses
+used to restrict the set of names imported by $I$.
 Currently, two namespace combinators are supported: \HIDE{} and \SHOW{}.
 
 \LMHash{}%
@@ -12336,14 +13083,26 @@
 When called, the method causes an immediate import $I'$ to be executed at some future time, where $I'$ is derived from $I$ by eliding the word \DEFERRED{} and adding a \HIDE{} \code{loadLibrary} combinator clause.
 When $I'$ executes without error, $f$ completes successfully.
 If $I'$ executes without error, we say that the call to \code{loadLibrary} has succeeded, otherwise we say the call has failed.
-\item For every top level function $f$ named \id{} in the imported library $B$, a corresponding method named \id{} with the same signature as $f$.
-Calling the method results in a run-time error.
-\item For every top level getter $g$ named \id{} in $B$, a corresponding getter named \id{} with the same signature as $g$.
-Calling the method results in a run-time error.
-\item For every top level setter $s$ named \id{} in $B$, a corresponding setter named \id{} with the same signature as $s$.
-Calling the method results in a run-time error.
-\item For every type $T$ named \id{} in $B$, a corresponding getter named \id{} with return type \code{Type}.
-Calling the method results in a run-time error.
+\item
+  For every top level function $f$ named \id{} in the imported library $B$,
+  a corresponding method named \id{} with the same signature as $f$.
+  % This error can occur because being-loaded is a dynamic property.
+  Calling the method results in a dynamic error.
+\item
+  For every top level getter $g$ named \id{} in $B$,
+  a corresponding getter named \id{} with the same signature as $g$.
+  % This error can occur because being-loaded is a dynamic property.
+  Calling the method results in a dynamic error.
+\item
+  For every top level setter $s$ named \id{} in $B$,
+  a corresponding setter named \id{} with the same signature as $s$.
+  % This error can occur because being-loaded is a dynamic property.
+  Calling the method results in a dynamic error.
+\item
+  For every type $T$ named \id{} in $B$,
+  a corresponding getter named \id{} with return type \code{Type}.
+  % This error can occur because being-loaded is a dynamic property.
+  Calling the method results in a dynamic error.
 \end{itemize}
 
 \rationale{
@@ -12418,7 +13177,10 @@
 \end{itemize}
 
 \LMHash{}%
-Next, if $I$ includes a prefix clause of the form \AS{} $p$, let $NS = NS_n \cup \{p: prefixObject(NS_n)\}$ where $prefixObject(NS_n)$ is a \Index{prefix object} for the namespace $NS_n$, which is an object that has the following members:
+Next, if $I$ includes a prefix clause of the form \AS{} $p$,
+let $NS = \{p: prefixObject(NS_n)\}$ where $prefixObject(NS_n)$ is
+a \Index{prefix object} for the namespace $NS_n$,
+which is an object that has the following members:
 
 \begin{itemize}
 \item For every top level function $f$ named \id{} in $NS_n$, a corresponding method with the same name and signature as $f$ that forwards (\ref{functionDeclarations}) to $f$.
@@ -12686,7 +13448,7 @@
 Then, the top-level function defined by \code{main}
 in the exported namespace of $S$ is invoked (\ref{functionInvocation})
 as follows:
-If \code{main} can be be called with with two positional arguments,
+If \code{main} can be called with with two positional arguments,
 it is invoked with the following two actual arguments:
 \begin{enumerate}
 \item An object whose run-time type implements \code{List<String>}.
@@ -12752,7 +13514,7 @@
 \item{} Let $u$ be \metavar{uri}.
 \item{} For each of the following configuration URIs of the form \code{\IF{} ($\metavar{test}_i$) $\metavar{uri}_i$}, in source order, do the following.
 \begin{itemize}
-  \item{} If $\metavar{test}_i$ is \code{\metavar{ids}} with no \code{==} clause, it is
+  \item{} If $\metavar{test}_i$ is \code{\metavar{ids}} with no \lit{==} clause, it is
   equivalent to \code{\metavar{ids} == "true"}.
   \item{} If $\metavar{test}_i$ is \code{\metavar{ids} == \metavar{string}},
   then create a string, \metavar{key}, from \metavar{ids}
@@ -12923,19 +13685,20 @@
 \item
   $T$ has the form \id{} or the form \code{\metavar{prefix}.\id},
   and in the enclosing lexical scope,
-  the name \id{} (respectively \code{\metavar{prefix}.\id}) does not denote a type.
-
+  the name \id{} (respectively \code{\metavar{prefix}.\id})
+  does not denote a type.
 \item
   $T$ denotes a type variable in the enclosing lexical scope,
   but occurs in the signature or body of a static member.
-
-\item $T$ is a parameterized type of the form \code{$G$<$S_1, \ldots,\ S_n$>},
+\item
+  $T$ is a parameterized type of the form \code{$G$<$S_1, \ldots,\ S_n$>},
   and $G$ is malformed,
   or $G$ is not a generic type,
-  or $G$ is a generic type, but it declares $n'$ type parameters and $n' \not= n$,
+  or $G$ is a generic type,
+  but it declares $n'$ type parameters and $n' \not= n$,
   or $S_j$ is malformed for some $j \in 1 .. n$.
-
-\item $T$ is a function type of the form
+\item
+  $T$ is a function type of the form
 
   \code{$T_0$ \FUNCTION{}<$X_1\ \EXTENDS\ B_1, \ldots,\ X_m\ \EXTENDS\ B_m$>}
 
@@ -12952,24 +13715,20 @@
   where each $x_j$ which is not a named parameter may be omitted,
   and $T_j$ is malformed for some $j \in 0 .. n$,
   or $B_j$ is malformed for some $j \in 1 .. m$.
-
 \item
   $T$ denotes declarations that were imported from multiple imports clauses.
 \end{itemize}
 
 \LMHash{}%
-Any use of a malformed type gives rise to a compile-time error.
-A malformed type is then interpreted as \DYNAMIC{} by the static type checker unless explicitly specified otherwise.
-
-\rationale{
-This ensures that the developer is spared a series of cascading errors as the malformed type interacts with other types.
-}
+Any occurrence of a malformed type in a library is a compile-time error.
 
 \LMHash{}%
 A type $T$ is \IndexCustom{deferred}{type!deferred}
 if{}f it is of the form $p.T$ where $p$ is a deferred prefix.
-It is a compile-time error to use a deferred type in a type annotation, type test, type cast or as a type parameter.
-However, all other compile-time errors must be issued under the assumption that all deferred libraries have successfully been loaded.
+It is a compile-time error to use a deferred type
+in a type annotation, type test, type cast or as a type parameter.
+However, all other compile-time errors must be issued
+under the assumption that all deferred libraries have successfully been loaded.
 
 % Now, when passed to a generic, p.T also has to be treated as dynamic - otherwise we have to fail immediately. Where do we say that? And how does this fit with idea that as a type object it fails? Should we say that the accessor on p returns dynamic instead of failing? Do we distinguish its use in a constructor vs its use in an annotation? It's not that we evaluate type objects in constructor args - these cannot represent parameterized types.
 
@@ -13046,9 +13805,9 @@
 
 \LMHash{}%
 When types are reified as instances of the built-in class \code{Type},
-those objects override the \code{==} operator
+those objects override the \lit{==} operator
 inherited from the \code{Object} class, so that
-two \code{Type} objects are equal according to operator \syntax{`=='}
+two \code{Type} objects are equal according to operator \lit{==}
 if{}f the corresponding types are subtypes of each other.
 
 \commentary{
@@ -13090,6 +13849,7 @@
 A constant type literal is a constant expression (\ref{constants}).
 }
 
+
 \subsection{Type Aliases}
 \LMLabel{typedef}
 
@@ -13252,7 +14012,10 @@
 \LMHash{}%
 %% TODO(eernst): Introduce these specialized intersection types
 %% in a suitable location where type promotion is specified.
-Types of the form $X \& S$ arise during static analysis due to type promotion
+Types of the form
+\IndexCustom{$X \& S$}{type!of the form $X \& S$}%
+\IndexExtraEntry{\&@$X \& S$}
+arise during static analysis due to type promotion
 (\ref{typePromotion}).
 They never occur during execution,
 they are never a type argument of another type,
@@ -13996,7 +14759,7 @@
 
 \commentary{
 This \code{Type} object must compare equal to the corresponding \code{Type}
-objects for \code{Object} and \VOID{} according to operator `\code{==}'
+objects for \code{Object} and \VOID{} according to operator \lit{==}
 (\ref{dynamicTypeSystem}).
 }
 
@@ -14125,24 +14888,31 @@
 
 \LMHash{}%
 The built-in type declaration \code{FutureOr},
-which is declared in the library \code{dart:async},
+which is exported by the library \code{dart:async},
 defines a generic type with one type parameter (\ref{generics}).
+The type \code{FutureOr<$T$>} is a non-class type
+which is regular-bounded for all $T$.
 
-\LMHash{}%
-The \code{FutureOr<$T$>} type is a non-class type with the following
-type relations:
+\commentary{%
+The subtype relations involving \code{FutureOr} are specified elsewhere
+(\ref{subtypeRules}).
+Note, however, that they entail certain useful properties:
 \begin{itemize}
-    \item{} $T$ <: \code{FutureOr<$T$>}.
-    \item{} \code{Future<$T$>} <: \code{FutureOr<$T$>}.
-    \item{} If $T$ <: $S$ and \code{Future<$T$>} <: $S$
-        then \code{FutureOr<$T$>} <: $S$.
-        \commentary{In particular, \code{FutureOr<$T$>} <: \code{Object}.}
+\item[$\bullet$]
+  $T <: \code{FutureOr<$T$>}$.
+\item[$\bullet$]
+  $\code{Future<$T$>} <: \code{FutureOr<$T$>}$.
+\item[$\bullet$]
+  If $T <: S$ and $\code{Future<$T$>} <: S$, then $\code{FutureOr<$T$>} <: S$.
 \end{itemize}.
 
-\commentary{
-The last point guarantees that generic type \code{FutureOr} is
-\emph{covariant} in its type parameter, just like class types.
-That is, if $S$ <: $T$ then \code{FutureOr<$S$>} <: \code{FutureOr<$T$>}.
+That is, \code{FutureOr} is in a sense
+the union of $T$ and the corresponding future type.
+The last point guarantees that
+\code{FutureOr<$T$>} <: \code{Object},
+and also that \code{FutureOr} is covariant in its type parameter,
+just like class types:
+if $S$ <: $T$ then \code{FutureOr<$S$>} <: \code{FutureOr<$T$>}.%
 }
 
 \LMHash{}%
@@ -14153,42 +14923,45 @@
 denotes a \code{Type} object representing the type \code{FutureOr<dynamic>}.
 
 \rationale{
-The \code{FutureOr<\metavar{type}>} type represents a case where a value can be
-either an instance of the type \metavar{type}
-or the type \code{Future<\metavar{type}>}.
+The \code{FutureOr<$T$>} type represents a case where a value can be
+either an instance of the type $T$
+or the type \code{Future<$T$>}.
 Such cases occur naturally in asynchronous code.
-Using \code{FutureOr} instead of \DYNAMIC{} allows some tools
-to provide a more precise type analysis.
+The available alternative would be to use a top type (e.g., \DYNAMIC{}),
+but \code{FutureOr} allows some tools to provide a more precise type analysis.
 }
 
 \LMHash{}%
 The type \code{FutureOr<$T$>} has an interface that is identical to that
 of \code{Object}.
-
-\commentary{
-The only members that can be invoked on a value with static type
-\code{FutureOr<$T$>} are members that are also on \code{Object}.
+\commentary{%
+That is, only members that \code{Object} has can be invoked
+on a value with static type \code{FutureOr<$T$>}.%
 }
 
 \rationale{
 We only want to allow invocations of members that are inherited from
 a common supertype of both $T$ and \code{Future<$T$>}.
-In most cases the only common supertype is \code{Object}. The exceptions, like
-\code{FutureOr<Future<Object\gtgt} which has \code{Future<Object>} as common
-supertype, are few and not practically useful, so for now we choose to
-only allow invocations of members inherited from \code{Object}.
+In most cases the only common supertype is \code{Object}.
+The exceptions, like \code{FutureOr<Future<Object\gtgt}
+which has \code{Future<Object>} as common supertype,
+are few and not practically useful,
+so for now we choose to only allow invocations of
+members inherited from \code{Object}.
 }
 
 \LMHash{}%
 We define the auxiliary function
-\IndexCustom{\basetype{T}}{basetype(t)@\emph{basetype}$(T)$}
+\IndexCustom{\futureOrBase{T}}{futureOrBase(t)@\emph{futureOrBase}$(T)$}
 as follows:
 
 \begin{itemize}
-\item If $T$ is \code{FutureOr<$S$>} for some $S$ then $\basetype{T} = \basetype{S}$.
-\item Otherwise $\basetype{T} = T$.
+\item If $T$ is \code{FutureOr<$S$>} for some $S$
+  then $\futureOrBase{T} = \futureOrBase{S}$.
+\item Otherwise $\futureOrBase{T} = T$.
 \end{itemize}
 
+
 \subsection{Type Void}
 \LMLabel{typeVoid}
 
@@ -14225,7 +14998,7 @@
 the value of an expression of type \VOID.
 %
 Consequently, any instance of type \code{Type} which reifies the type \VOID{}
-must compare equal (according to the \code{==} operator \ref{equality})
+must compare equal (according to the \lit{==} operator \ref{equality})
 to any instance of \code{Type} which reifies the type \code{Object}
 (\ref{dynamicTypeSystem}).
 It is not guaranteed that \code{identical(\VOID, Object)} evaluates to true.
@@ -14381,7 +15154,8 @@
 because it has type \VOID.%
 }
 
-\paragraph{Void Soundness}
+
+\subsubsection{Void Soundness}
 \LMLabel{voidSoundness}
 
 \LMHash{}%
diff --git a/docs/language/informal/generic-function-instantiation.md b/docs/language/informal/generic-function-instantiation.md
index 50098c2..80e9241 100644
--- a/docs/language/informal/generic-function-instantiation.md
+++ b/docs/language/informal/generic-function-instantiation.md
@@ -1,10 +1,11 @@
 # Generic Function Instantiation
 
-Author: eernst@.
+**Author**: eernst@.
 
-Version: 0.3 (2018-04-05)
+**Version**: 0.3 (2018-04-05)
 
-Status: Under implementation.
+**Status**: This document is now background material.
+For normative text, please consult the language specification.
 
 **This document** is a Dart 2 feature specification of _generic function
 instantiation_, which is the feature that implicitly coerces a reference to
diff --git a/docs/language/informal/subtyping.md b/docs/language/informal/subtyping.md
new file mode 100644
index 0000000..dedd41a
--- /dev/null
+++ b/docs/language/informal/subtyping.md
@@ -0,0 +1,9 @@
+# Dart 2.0 Static and Runtime Subtyping
+
+leafp@google.com
+
+**Status**: This document has been integrated into the language specification.
+Also, an updated version taking non-null types into account exists
+[here](https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md).
+
+**Contents of this document**: Deleted.
diff --git a/docs/process/breaking-changes.md b/docs/process/breaking-changes.md
new file mode 100644
index 0000000..adf71a2
--- /dev/null
+++ b/docs/process/breaking-changes.md
@@ -0,0 +1,155 @@
+# Dart SDK breaking change process
+
+The present document describes the Dart SDK philosophy for compatibility, and
+process for breaking changes.
+
+## Dart compatibility and philosophy
+
+Generally the Dart team strives to not make breaking changes, and to preserve
+compatibility of all Dart programs across stable Dart SDK releases. However, on
+occasion, we believe that breaking changes are needed, or justified:
+
+* Security: To resolve a security issue in the specification or implementation.
+
+* Unspecified behavior: Programs that depend on unspecified behavior may break
+  as such behavior is specified and implemented.
+
+* Implementation bugs: If the implementation deviates unintentionally from the
+  specification, programs may break as we rectify the implementation.
+
+* Evolution: If we deem that there is a very large benefit to changing current
+  behavior, we may choose to do so after careful consideration of the associated
+  impact of the change.
+
+## Scope of compatibility
+
+It is not practical to offer compatability to programs that do not follow
+best practices. Thus, the breaking change process assumes that programs
+abide by the following basic conditions:
+
+* Must contain no static analysis **errors**.
+
+* Must not rely on a certain runtime **error** being thrown (in other words, 
+  a new SDK might throw fewer errors than an old SDK).
+
+* Must access libraries via the public API (for example, must not reach into
+  the internals of a package located in the `/src/` directory).
+
+* Must not rely on an [experiment flag](flags.md).
+
+* Must not circumvent clear restrictions documented in the public API
+  documentation (for example, must not mixin a class clearly documented as
+  not intended to be used as a mixin).
+
+Compatibility is only considered between stable releases (i.e. releases from the
+[Dart stable
+channel](https://www.dartlang.org/tools/sdk/archive#stable-channel)).
+
+## Breaking change notification
+
+Anyone wishing to make a breaking change to Dart is expected to perform the
+following steps.  It is expected that all of these steps are followed prior
+to a change being released in a dev channel release.
+
+### Step 1: Announcement
+
+* Create an issue in the Dart SDK issue tracker labelled
+  `breaking-change-request` containing the following:
+
+  * The intended change in behavior.
+
+  * The justification/rationale for making the change.
+
+  * The expected impact of this change.
+
+  * Clear steps for mitigating the change.
+
+[TODO: Link to an issue template for this]
+
+* Email `announce@dartlang.org, flutter-announce@googlegroups.com`,:
+
+  * Subject: 'Breaking change [bug ID]: [short summary]'
+
+  * Very short summary of the intended change
+
+  * Link to the above mentioned issue
+
+  * A request that developers may leave comments in the linked issue, if this
+    breaking change poses a severe problem.
+
+### Step 2: Approval
+
+If there is a general agreement that the benefit of the change outweighs the
+cost of the change, a set of Dart SDK approvers will approve the change.
+Adequate time must be allowed after step 1, at a minimum 24 hours during the
+work week for smaller impact changes, and proportionally longer for higher
+impact changes.
+### Step 3: Execution
+
+If approved, the change may be made.
+
+After the breaking change had been made, the person who made the change must:
+
+* Resolve the breaking change issue and make a note that the change has landed
+
+* Make a note in the [Dart SDK changelog](`changelog.md`) detailing the change.
+  This must be prefixed `** Breaking change:`.
+
+* Reply to the original announcement email, and make a note that the change is
+  being implemented.
+
+If not approved, or if the requestor decides to not pursue the change, the
+requestor must:
+
+* Reply to the original announcement email, and make a note that the change is
+  has been rejected, with a quick summary of the rationale for that.
+## Unexpected breaking changes & roll-back requests
+
+If a developer notices a breaking change has been made in the dev or stable
+channels, and this change impacts a program that abides to the above defined
+scope of compatibility, and for which either:
+
+  * No breaking change was announced, or
+
+  * The impact of the change was significantly larger than described in the
+    breaking change announcement
+
+, then they may file a 'request for roll-back' using the following steps:
+
+* Create an issue in the Dart SDK issue tracker labelled
+  `roll-back-request` containing the following:
+
+  * If applicable, a link to the associated breaking change request issue
+
+  * A clear description of the actual impact, and if applicable a description of
+    how this differs from the expected impact.
+
+  * A link to the program that was affected, or another program that illustrated
+    the same effect.
+
+[TODO: Link to an issue template for this]
+
+Upon receiving such an issue the Dart SDK team will either:
+
+  * Roll-back the change, or
+
+  * Make a quick corrective action to correct the change, or
+
+  * Detail how the change in their opinion does not warrant a roll-back.
+
+If a breaking change is rolled-back, in addition:
+
+  * The breaking change request issue should be reopened
+
+### Roll-backs following unexpected changes
+
+If a roll-back occurs after what should have been a breaking change, the
+originator of the change is expected to follow the breaking change process to
+move forward.
+
+If a roll-back occurs after a breaking change, but where the impact was larger
+than anticipated, then the impacted party is expected to make a best effort to
+quickly rectify their program to either not be affected by the breaking change,
+or in some other way offer the originator a clear timeline for when the breaking
+change can be landed.
+
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index bf31832..f7ed499 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.22.1
+  1.23.0
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -1447,6 +1447,10 @@
   </p>
   
   
+  
+  
+  
+  
 <h3>Requests</h3><dl><dt class="request"><a name="request_completion.getSuggestions">completion.getSuggestions</a></dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "completion.getSuggestions"
@@ -1493,6 +1497,9 @@
     "<b>replacementLength</b>": int
     "<b>results</b>": List&lt;<a href="#type_CompletionSuggestion">CompletionSuggestion</a>&gt;
     "<b>isLast</b>": bool
+    "<b>includedSuggestionSets</b>": <span style="color:#999999">optional</span> List&lt;<a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a>&gt;
+    "<b>includedSuggestionKinds</b>": <span style="color:#999999">optional</span> List&lt;<a href="#type_ElementKind">ElementKind</a>&gt;
+    "<b>includedSuggestionRelevanceTags</b>": <span style="color:#999999">optional</span> List&lt;<a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a>&gt;
   }
 }</pre></div>
     <p>
@@ -1541,6 +1548,44 @@
           True if this is that last set of results that will be
           returned for the indicated completion.
         </p>
+      </dd><dt class="field"><b>includedSuggestionSets: List&lt;<a href="#type_IncludedSuggestionSet">IncludedSuggestionSet</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          This field is experimental.
+        </p>
+        <p>
+          References to <tt>AvailableSuggestionSet</tt> objects previously sent
+          to the client. The client can include applicable names from the
+          referenced library in code completion suggestions.
+        </p>
+      </dd><dt class="field"><b>includedSuggestionKinds: List&lt;<a href="#type_ElementKind">ElementKind</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          This field is experimental.
+        </p>
+        <p>
+          The client is expected to check this list against the
+          <tt>ElementKind</tt> sent in <tt>IncludedSuggestionSet</tt> to decide
+          whether or not these symbols should should be presented to the user.
+        </p>
+      </dd><dt class="field"><b>includedSuggestionRelevanceTags: List&lt;<a href="#type_IncludedSuggestionRelevanceTag">IncludedSuggestionRelevanceTag</a>&gt;<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          This field is experimental.
+        </p>
+        <p>
+          The client is expected to check this list against the values of the
+          field <tt>relevanceTags</tt> of <tt>AvailableSuggestion</tt> to
+          decide if the suggestion should be given a different relevance than
+          the <tt>IncludedSuggestionSet</tt> that contains it. This might be
+          used for example to give higher relevance to suggestions of matching
+          types.
+        </p>
+        <p>
+          If an <tt>AvailableSuggestion</tt> has relevance tags that match more
+          than one <tt>IncludedSuggestionRelevanceTag</tt>, the maximum
+          relevance boost is used.
+        </p>
       </dd></dl></dd></dl>
 <h2 class="domain"><a name="domain_search">search domain</a></h2>
   <p>
@@ -1835,6 +1880,7 @@
   
   
   
+  
 <h3>Requests</h3><dl><dt class="request"><a name="request_edit.format">edit.format</a></dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.format"
@@ -2644,6 +2690,14 @@
   
   
   
+  
+  
+  
+  
+  
+  
+  
+  
 <dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
     <p>
       A directive to begin overlaying the contents of a file. The supplied
@@ -2827,7 +2881,12 @@
           The name of the current target of analysis. This field is
           omitted if analyzing is false.
         </p>
-      </dd></dl></dd><dt class="typeDefinition"><a name="type_ChangeContentOverlay">ChangeContentOverlay: object</a></dt><dd>
+      </dd></dl></dd><dt class="typeDefinition"><a name="type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag: String</a></dt><dd>
+    
+    <p>
+      The opaque tag value.
+    </p>
+  </dd><dt class="typeDefinition"><a name="type_ChangeContentOverlay">ChangeContentOverlay: object</a></dt><dd>
     <p>
       A directive to modify an existing file content overlay. One or more ranges
       of text are deleted from the old file content overlay and replaced with
@@ -4348,6 +4407,12 @@
           An "edit.sortMembers" request specified a Dart file that has
           scan or parse errors.
         </p>
+      </dd><dt class="value">UNKNOWN_FIX</dt><dd>
+        
+        <p>
+          A dartfix request was received containing the name of a fix
+          which does not match the name of any known fixes.
+        </p>
       </dd><dt class="value">UNKNOWN_REQUEST</dt><dd>
         
         <p>
@@ -5045,7 +5110,7 @@
   TODO: TBD
 </p>
 <h2 class="domain"><a name="index">Index</a></h2>
-<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+<h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.closingLabels">closingLabels</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li><li><a href="#notification_completion.availableSuggestions">availableSuggestions</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.getSuggestions">getSuggestions</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li><li><a href="#request_diagnostic.getServerPort">getServerPort</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_AvailableSuggestionRelevanceTag">AvailableSuggestionRelevanceTag</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_ClosingLabel">ClosingLabel</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementDeclaration">ElementDeclaration</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_ImportedElements">ImportedElements</a></li><li><a href="#type_KytheEntry">KytheEntry</a></li><li><a href="#type_KytheVName">KytheVName</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PostfixTemplateDescriptor">PostfixTemplateDescriptor</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_RuntimeCompletionExpression">RuntimeCompletionExpression</a></li><li><a href="#type_RuntimeCompletionExpressionType">RuntimeCompletionExpressionType</a></li><li><a href="#type_RuntimeCompletionExpressionTypeKind">RuntimeCompletionExpressionTypeKind</a></li><li><a href="#type_RuntimeCompletionVariable">RuntimeCompletionVariable</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_EXTRACT_WIDGET">EXTRACT_WIDGET</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
 
 
 </body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
new file mode 100644
index 0000000..dc8817d
--- /dev/null
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_custom_generated.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for 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/lsp_spec/generate_all.dart".
+
+// ignore_for_file: deprecated_member_use
+// ignore_for_file: deprecated_member_use_from_same_package
+// ignore_for_file: unnecessary_brace_in_string_interps
+// ignore_for_file: unused_import
+
+import 'dart:core' hide deprecated;
+import 'dart:core' as core show deprecated;
+import 'dart:convert' show JsonEncoder;
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/protocol/protocol_internal.dart'
+    show listEqual, mapEqual;
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+const jsonEncoder = const JsonEncoder.withIndent('    ');
+
+class DartDiagnosticServer implements ToJsonable {
+  DartDiagnosticServer(this.port) {
+    if (port == null) {
+      throw 'port is required but was not provided';
+    }
+  }
+  static DartDiagnosticServer fromJson(Map<String, dynamic> json) {
+    final port = json['port'];
+    return new DartDiagnosticServer(port);
+  }
+
+  final num port;
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> __result = {};
+    __result['port'] = port ?? (throw 'port is required but was not set');
+    return __result;
+  }
+
+  static bool canParse(Object obj) {
+    return obj is Map<String, dynamic> &&
+        obj.containsKey('port') &&
+        obj['port'] is num;
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is DartDiagnosticServer) {
+      return port == other.port && true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, port.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+
+  @override
+  String toString() => jsonEncoder.convert(toJson());
+}
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index 8e0f2a2..e0484bf 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -7,7 +7,9 @@
 // "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
 
 // ignore_for_file: deprecated_member_use
+// ignore_for_file: deprecated_member_use_from_same_package
 // ignore_for_file: unnecessary_brace_in_string_interps
+// ignore_for_file: unused_import
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
@@ -4980,10 +4982,15 @@
   /// range at the mouse position.
   final Range originSelectionRange;
 
-  /// The full target range of this link.
+  /// The full target range of this link. If the target for example is a symbol
+  /// then target range is the range enclosing this symbol not including
+  /// leading/trailing whitespace but everything else like comments. This
+  /// information is typically used to highlight the range in the editor.
   final Range targetRange;
 
-  /// The span of this link.
+  /// The range that should be selected and revealed when this link is being
+  /// followed, e.g the name of a function. Must be contained by the the
+  /// `targetRange`. See also `DocumentSymbol#range`
   final Range targetSelectionRange;
 
   /// The target resource identifier of this link.
@@ -4998,9 +5005,8 @@
         targetUri ?? (throw 'targetUri is required but was not set');
     __result['targetRange'] =
         targetRange ?? (throw 'targetRange is required but was not set');
-    if (targetSelectionRange != null) {
-      __result['targetSelectionRange'] = targetSelectionRange;
-    }
+    __result['targetSelectionRange'] = targetSelectionRange ??
+        (throw 'targetSelectionRange is required but was not set');
     return __result;
   }
 
@@ -5009,7 +5015,9 @@
         obj.containsKey('targetUri') &&
         obj['targetUri'] is String &&
         obj.containsKey('targetRange') &&
-        Range.canParse(obj['targetRange']);
+        Range.canParse(obj['targetRange']) &&
+        obj.containsKey('targetSelectionRange') &&
+        Range.canParse(obj['targetSelectionRange']);
   }
 
   @override
@@ -5353,234 +5361,182 @@
 
 /// Valid LSP methods known at the time of code generation from the spec.
 class Method {
-  const Method._(this._value);
+  const Method(this._value);
   const Method.fromJson(this._value);
 
   final String _value;
 
   static bool canParse(Object obj) {
-    switch (obj) {
-      case r'$/cancelRequest':
-      case r'initialize':
-      case r'initialized':
-      case r'shutdown':
-      case r'exit':
-      case r'window/showMessage':
-      case r'window/showMessageRequest':
-      case r'window/logMessage':
-      case r'telemetry/event':
-      case r'client/registerCapability':
-      case r'client/unregisterCapability':
-      case r'workspace/workspaceFolders':
-      case r'workspace/didChangeWorkspaceFolders':
-      case r'workspace/configuration':
-      case r'workspace/didChangeWatchedFiles':
-      case r'workspace/symbol':
-      case r'workspace/executeCommand':
-      case r'workspace/applyEdit':
-      case r'textDocument/didOpen':
-      case r'textDocument/didChange':
-      case r'textDocument/willSave':
-      case r'textDocument/willSaveWaitUntil':
-      case r'textDocument/didClose':
-      case r'textDocument/publishDiagnostics':
-      case r'textDocument/completion':
-      case r'completionItem/resolve':
-      case r'textDocument/hover':
-      case r'textDocument/signatureHelp':
-      case r'textDocument/declaration':
-      case r'textDocument/definition':
-      case r'textDocument/typeDefinition':
-      case r'textDocument/implementation':
-      case r'textDocument/references':
-      case r'textDocument/documentHighlight':
-      case r'textDocument/documentSymbol':
-      case r'textDocument/codeAction':
-      case r'textDocument/codeLens':
-      case r'codeLens/resolve':
-      case r'textDocument/documentLink':
-      case r'documentLink/resolve':
-      case r'textDocument/documentColor':
-      case r'textDocument/colorPresentation':
-      case r'textDocument/formatting':
-      case r'textDocument/onTypeFormatting':
-      case r'textDocument/rename':
-      case r'textDocument/prepareRename':
-      case r'textDocument/foldingRange':
-        return true;
-    }
-    return false;
+    return obj is String;
   }
 
   /// Constant for the '$/cancelRequest' method.
-  static const cancelRequest = const Method._(r'$/cancelRequest');
+  static const cancelRequest = const Method(r'$/cancelRequest');
 
   /// Constant for the 'initialize' method.
-  static const initialize = const Method._(r'initialize');
+  static const initialize = const Method(r'initialize');
 
   /// Constant for the 'initialized' method.
-  static const initialized = const Method._(r'initialized');
+  static const initialized = const Method(r'initialized');
 
   /// Constant for the 'shutdown' method.
-  static const shutdown = const Method._(r'shutdown');
+  static const shutdown = const Method(r'shutdown');
 
   /// Constant for the 'exit' method.
-  static const exit = const Method._(r'exit');
+  static const exit = const Method(r'exit');
 
   /// Constant for the 'window/showMessage' method.
-  static const window_showMessage = const Method._(r'window/showMessage');
+  static const window_showMessage = const Method(r'window/showMessage');
 
   /// Constant for the 'window/showMessageRequest' method.
   static const window_showMessageRequest =
-      const Method._(r'window/showMessageRequest');
+      const Method(r'window/showMessageRequest');
 
   /// Constant for the 'window/logMessage' method.
-  static const window_logMessage = const Method._(r'window/logMessage');
+  static const window_logMessage = const Method(r'window/logMessage');
 
   /// Constant for the 'telemetry/event' method.
-  static const telemetry_event = const Method._(r'telemetry/event');
+  static const telemetry_event = const Method(r'telemetry/event');
 
   /// Constant for the 'client/registerCapability' method.
   static const client_registerCapability =
-      const Method._(r'client/registerCapability');
+      const Method(r'client/registerCapability');
 
   /// Constant for the 'client/unregisterCapability' method.
   static const client_unregisterCapability =
-      const Method._(r'client/unregisterCapability');
+      const Method(r'client/unregisterCapability');
 
   /// Constant for the 'workspace/workspaceFolders' method.
   static const workspace_workspaceFolders =
-      const Method._(r'workspace/workspaceFolders');
+      const Method(r'workspace/workspaceFolders');
 
   /// Constant for the 'workspace/didChangeWorkspaceFolders' method.
   static const workspace_didChangeWorkspaceFolders =
-      const Method._(r'workspace/didChangeWorkspaceFolders');
+      const Method(r'workspace/didChangeWorkspaceFolders');
 
   /// Constant for the 'workspace/configuration' method.
   static const workspace_configuration =
-      const Method._(r'workspace/configuration');
+      const Method(r'workspace/configuration');
 
   /// Constant for the 'workspace/didChangeWatchedFiles' method.
   static const workspace_didChangeWatchedFiles =
-      const Method._(r'workspace/didChangeWatchedFiles');
+      const Method(r'workspace/didChangeWatchedFiles');
 
   /// Constant for the 'workspace/symbol' method.
-  static const workspace_symbol = const Method._(r'workspace/symbol');
+  static const workspace_symbol = const Method(r'workspace/symbol');
 
   /// Constant for the 'workspace/executeCommand' method.
   static const workspace_executeCommand =
-      const Method._(r'workspace/executeCommand');
+      const Method(r'workspace/executeCommand');
 
   /// Constant for the 'workspace/applyEdit' method.
-  static const workspace_applyEdit = const Method._(r'workspace/applyEdit');
+  static const workspace_applyEdit = const Method(r'workspace/applyEdit');
 
   /// Constant for the 'textDocument/didOpen' method.
-  static const textDocument_didOpen = const Method._(r'textDocument/didOpen');
+  static const textDocument_didOpen = const Method(r'textDocument/didOpen');
 
   /// Constant for the 'textDocument/didChange' method.
-  static const textDocument_didChange =
-      const Method._(r'textDocument/didChange');
+  static const textDocument_didChange = const Method(r'textDocument/didChange');
 
   /// Constant for the 'textDocument/willSave' method.
-  static const textDocument_willSave = const Method._(r'textDocument/willSave');
+  static const textDocument_willSave = const Method(r'textDocument/willSave');
 
   /// Constant for the 'textDocument/willSaveWaitUntil' method.
   static const textDocument_willSaveWaitUntil =
-      const Method._(r'textDocument/willSaveWaitUntil');
+      const Method(r'textDocument/willSaveWaitUntil');
 
   /// Constant for the 'textDocument/didClose' method.
-  static const textDocument_didClose = const Method._(r'textDocument/didClose');
+  static const textDocument_didClose = const Method(r'textDocument/didClose');
 
   /// Constant for the 'textDocument/publishDiagnostics' method.
   static const textDocument_publishDiagnostics =
-      const Method._(r'textDocument/publishDiagnostics');
+      const Method(r'textDocument/publishDiagnostics');
 
   /// Constant for the 'textDocument/completion' method.
   static const textDocument_completion =
-      const Method._(r'textDocument/completion');
+      const Method(r'textDocument/completion');
 
   /// Constant for the 'completionItem/resolve' method.
-  static const completionItem_resolve =
-      const Method._(r'completionItem/resolve');
+  static const completionItem_resolve = const Method(r'completionItem/resolve');
 
   /// Constant for the 'textDocument/hover' method.
-  static const textDocument_hover = const Method._(r'textDocument/hover');
+  static const textDocument_hover = const Method(r'textDocument/hover');
 
   /// Constant for the 'textDocument/signatureHelp' method.
   static const textDocument_signatureHelp =
-      const Method._(r'textDocument/signatureHelp');
+      const Method(r'textDocument/signatureHelp');
 
   /// Constant for the 'textDocument/declaration' method.
   static const textDocument_declaration =
-      const Method._(r'textDocument/declaration');
+      const Method(r'textDocument/declaration');
 
   /// Constant for the 'textDocument/definition' method.
   static const textDocument_definition =
-      const Method._(r'textDocument/definition');
+      const Method(r'textDocument/definition');
 
   /// Constant for the 'textDocument/typeDefinition' method.
   static const textDocument_typeDefinition =
-      const Method._(r'textDocument/typeDefinition');
+      const Method(r'textDocument/typeDefinition');
 
   /// Constant for the 'textDocument/implementation' method.
   static const textDocument_implementation =
-      const Method._(r'textDocument/implementation');
+      const Method(r'textDocument/implementation');
 
   /// Constant for the 'textDocument/references' method.
   static const textDocument_references =
-      const Method._(r'textDocument/references');
+      const Method(r'textDocument/references');
 
   /// Constant for the 'textDocument/documentHighlight' method.
   static const textDocument_documentHighlight =
-      const Method._(r'textDocument/documentHighlight');
+      const Method(r'textDocument/documentHighlight');
 
   /// Constant for the 'textDocument/documentSymbol' method.
   static const textDocument_documentSymbol =
-      const Method._(r'textDocument/documentSymbol');
+      const Method(r'textDocument/documentSymbol');
 
   /// Constant for the 'textDocument/codeAction' method.
   static const textDocument_codeAction =
-      const Method._(r'textDocument/codeAction');
+      const Method(r'textDocument/codeAction');
 
   /// Constant for the 'textDocument/codeLens' method.
-  static const textDocument_codeLens = const Method._(r'textDocument/codeLens');
+  static const textDocument_codeLens = const Method(r'textDocument/codeLens');
 
   /// Constant for the 'codeLens/resolve' method.
-  static const codeLens_resolve = const Method._(r'codeLens/resolve');
+  static const codeLens_resolve = const Method(r'codeLens/resolve');
 
   /// Constant for the 'textDocument/documentLink' method.
   static const textDocument_documentLink =
-      const Method._(r'textDocument/documentLink');
+      const Method(r'textDocument/documentLink');
 
   /// Constant for the 'documentLink/resolve' method.
-  static const documentLink_resolve = const Method._(r'documentLink/resolve');
+  static const documentLink_resolve = const Method(r'documentLink/resolve');
 
   /// Constant for the 'textDocument/documentColor' method.
   static const textDocument_documentColor =
-      const Method._(r'textDocument/documentColor');
+      const Method(r'textDocument/documentColor');
 
   /// Constant for the 'textDocument/colorPresentation' method.
   static const textDocument_colorPresentation =
-      const Method._(r'textDocument/colorPresentation');
+      const Method(r'textDocument/colorPresentation');
 
   /// Constant for the 'textDocument/formatting' method.
   static const textDocument_formatting =
-      const Method._(r'textDocument/formatting');
+      const Method(r'textDocument/formatting');
 
   /// Constant for the 'textDocument/onTypeFormatting' method.
   static const textDocument_onTypeFormatting =
-      const Method._(r'textDocument/onTypeFormatting');
+      const Method(r'textDocument/onTypeFormatting');
 
   /// Constant for the 'textDocument/rename' method.
-  static const textDocument_rename = const Method._(r'textDocument/rename');
+  static const textDocument_rename = const Method(r'textDocument/rename');
 
   /// Constant for the 'textDocument/prepareRename' method.
   static const textDocument_prepareRename =
-      const Method._(r'textDocument/prepareRename');
+      const Method(r'textDocument/prepareRename');
 
   /// Constant for the 'textDocument/foldingRange' method.
   static const textDocument_foldingRange =
-      const Method._(r'textDocument/foldingRange');
+      const Method(r'textDocument/foldingRange');
 
   Object toJson() => _value;
 
@@ -6668,9 +6624,9 @@
   /// A number indicating the error type that occurred.
   final ErrorCodes code;
 
-  /// A Primitive or Structured value that contains additional information about
-  /// the error. Can be omitted.
-  final D data;
+  /// A string that contains additional information about the error. Can be
+  /// omitted.
+  final String data;
 
   /// A string providing a short description of the error.
   final String message;
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index fd21adb..d599adc 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.22.1';
+const String PROTOCOL_VERSION = '1.23.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -110,8 +110,21 @@
 const String ANALYTICS_REQUEST_SEND_TIMING_EVENT = 'event';
 const String ANALYTICS_REQUEST_SEND_TIMING_MILLIS = 'millis';
 const String ANALYTICS_RESPONSE_IS_ENABLED_ENABLED = 'enabled';
+const String COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS =
+    'completion.availableSuggestions';
+const String COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS_CHANGED_LIBRARIES =
+    'changedLibraries';
+const String COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS_REMOVED_LIBRARIES =
+    'removedLibraries';
 const String COMPLETION_NOTIFICATION_RESULTS = 'completion.results';
 const String COMPLETION_NOTIFICATION_RESULTS_ID = 'id';
+const String COMPLETION_NOTIFICATION_RESULTS_INCLUDED_SUGGESTION_KINDS =
+    'includedSuggestionKinds';
+const String
+    COMPLETION_NOTIFICATION_RESULTS_INCLUDED_SUGGESTION_RELEVANCE_TAGS =
+    'includedSuggestionRelevanceTags';
+const String COMPLETION_NOTIFICATION_RESULTS_INCLUDED_SUGGESTION_SETS =
+    'includedSuggestionSets';
 const String COMPLETION_NOTIFICATION_RESULTS_IS_LAST = 'isLast';
 const String COMPLETION_NOTIFICATION_RESULTS_REPLACEMENT_LENGTH =
     'replacementLength';
@@ -121,13 +134,33 @@
 const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS =
+    'completion.getSuggestionDetails';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_FILE = 'file';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_ID = 'id';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_LABEL = 'label';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_OFFSET = 'offset';
+const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS =
+    'completion.registerLibraryPaths';
+const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS_PATHS = 'paths';
+const String COMPLETION_REQUEST_SET_SUBSCRIPTIONS =
+    'completion.setSubscriptions';
+const String COMPLETION_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS =
+    'subscriptions';
 const String COMPLETION_RESPONSE_GET_SUGGESTIONS_ID = 'id';
+const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_CHANGE = 'change';
+const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_COMPLETION =
+    'completion';
 const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
 const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
 const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
 const String DIAGNOSTIC_RESPONSE_GET_SERVER_PORT_PORT = 'port';
 const String EDIT_REQUEST_DARTFIX = 'edit.dartfix';
+const String EDIT_REQUEST_DARTFIX_EXCLUDED_FIXES = 'excludedFixes';
 const String EDIT_REQUEST_DARTFIX_INCLUDED = 'included';
+const String EDIT_REQUEST_DARTFIX_INCLUDED_FIXES = 'includedFixes';
+const String EDIT_REQUEST_DARTFIX_INCLUDE_REQUIRED_FIXES =
+    'includeRequiredFixes';
 const String EDIT_REQUEST_FORMAT = 'edit.format';
 const String EDIT_REQUEST_FORMAT_FILE = 'file';
 const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength';
@@ -142,6 +175,7 @@
 const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_FILE = 'file';
 const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_LENGTH = 'length';
 const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_OFFSET = 'offset';
+const String EDIT_REQUEST_GET_DARTFIX_INFO = 'edit.getDartfixInfo';
 const String EDIT_REQUEST_GET_FIXES = 'edit.getFixes';
 const String EDIT_REQUEST_GET_FIXES_FILE = 'file';
 const String EDIT_REQUEST_GET_FIXES_OFFSET = 'offset';
@@ -183,6 +217,7 @@
 const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset';
 const String EDIT_RESPONSE_GET_ASSISTS_ASSISTS = 'assists';
 const String EDIT_RESPONSE_GET_AVAILABLE_REFACTORINGS_KINDS = 'kinds';
+const String EDIT_RESPONSE_GET_DARTFIX_INFO_FIXES = 'fixes';
 const String EDIT_RESPONSE_GET_FIXES_FIXES = 'fixes';
 const String EDIT_RESPONSE_GET_POSTFIX_COMPLETION_CHANGE = 'change';
 const String EDIT_RESPONSE_GET_REFACTORING_CHANGE = 'change';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 5130033..9f29f1a 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -5071,6 +5071,415 @@
 }
 
 /**
+ * AvailableSuggestion
+ *
+ * {
+ *   "label": String
+ *   "element": Element
+ *   "docComplete": optional String
+ *   "docSummary": optional String
+ *   "parameterNames": optional List<String>
+ *   "parameterTypes": optional List<String>
+ *   "relevanceTags": optional List<AvailableSuggestionRelevanceTag>
+ *   "requiredParameterCount": optional int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class AvailableSuggestion implements HasToJson {
+  String _label;
+
+  Element _element;
+
+  String _docComplete;
+
+  String _docSummary;
+
+  List<String> _parameterNames;
+
+  List<String> _parameterTypes;
+
+  List<String> _relevanceTags;
+
+  int _requiredParameterCount;
+
+  /**
+   * The identifier to present to the user for code completion.
+   */
+  String get label => _label;
+
+  /**
+   * The identifier to present to the user for code completion.
+   */
+  void set label(String value) {
+    assert(value != null);
+    this._label = value;
+  }
+
+  /**
+   * Information about the element reference being suggested.
+   */
+  Element get element => _element;
+
+  /**
+   * Information about the element reference being suggested.
+   */
+  void set element(Element value) {
+    assert(value != null);
+    this._element = value;
+  }
+
+  /**
+   * The Dartdoc associated with the element being suggested. This field is
+   * omitted if there is no Dartdoc associated with the element.
+   */
+  String get docComplete => _docComplete;
+
+  /**
+   * The Dartdoc associated with the element being suggested. This field is
+   * omitted if there is no Dartdoc associated with the element.
+   */
+  void set docComplete(String value) {
+    this._docComplete = value;
+  }
+
+  /**
+   * An abbreviated version of the Dartdoc associated with the element being
+   * suggested. This field is omitted if there is no Dartdoc associated with
+   * the element.
+   */
+  String get docSummary => _docSummary;
+
+  /**
+   * An abbreviated version of the Dartdoc associated with the element being
+   * suggested. This field is omitted if there is no Dartdoc associated with
+   * the element.
+   */
+  void set docSummary(String value) {
+    this._docSummary = value;
+  }
+
+  /**
+   * If the element is an executable, the names of the formal parameters of all
+   * kinds - required, optional positional, and optional named. The names of
+   * positional parameters are empty strings. Omitted if the element is not an
+   * executable.
+   */
+  List<String> get parameterNames => _parameterNames;
+
+  /**
+   * If the element is an executable, the names of the formal parameters of all
+   * kinds - required, optional positional, and optional named. The names of
+   * positional parameters are empty strings. Omitted if the element is not an
+   * executable.
+   */
+  void set parameterNames(List<String> value) {
+    this._parameterNames = value;
+  }
+
+  /**
+   * If the element is an executable, the declared types of the formal
+   * parameters of all kinds - required, optional positional, and optional
+   * named. Omitted if the element is not an executable.
+   */
+  List<String> get parameterTypes => _parameterTypes;
+
+  /**
+   * If the element is an executable, the declared types of the formal
+   * parameters of all kinds - required, optional positional, and optional
+   * named. Omitted if the element is not an executable.
+   */
+  void set parameterTypes(List<String> value) {
+    this._parameterTypes = value;
+  }
+
+  /**
+   * This field is set if the relevance of this suggestion might be changed
+   * depending on where completion is requested.
+   */
+  List<String> get relevanceTags => _relevanceTags;
+
+  /**
+   * This field is set if the relevance of this suggestion might be changed
+   * depending on where completion is requested.
+   */
+  void set relevanceTags(List<String> value) {
+    this._relevanceTags = value;
+  }
+
+  int get requiredParameterCount => _requiredParameterCount;
+
+  void set requiredParameterCount(int value) {
+    this._requiredParameterCount = value;
+  }
+
+  AvailableSuggestion(String label, Element element,
+      {String docComplete,
+      String docSummary,
+      List<String> parameterNames,
+      List<String> parameterTypes,
+      List<String> relevanceTags,
+      int requiredParameterCount}) {
+    this.label = label;
+    this.element = element;
+    this.docComplete = docComplete;
+    this.docSummary = docSummary;
+    this.parameterNames = parameterNames;
+    this.parameterTypes = parameterTypes;
+    this.relevanceTags = relevanceTags;
+    this.requiredParameterCount = requiredParameterCount;
+  }
+
+  factory AvailableSuggestion.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String label;
+      if (json.containsKey("label")) {
+        label = jsonDecoder.decodeString(jsonPath + ".label", json["label"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "label");
+      }
+      Element element;
+      if (json.containsKey("element")) {
+        element = new Element.fromJson(
+            jsonDecoder, jsonPath + ".element", json["element"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "element");
+      }
+      String docComplete;
+      if (json.containsKey("docComplete")) {
+        docComplete = jsonDecoder.decodeString(
+            jsonPath + ".docComplete", json["docComplete"]);
+      }
+      String docSummary;
+      if (json.containsKey("docSummary")) {
+        docSummary = jsonDecoder.decodeString(
+            jsonPath + ".docSummary", json["docSummary"]);
+      }
+      List<String> parameterNames;
+      if (json.containsKey("parameterNames")) {
+        parameterNames = jsonDecoder.decodeList(jsonPath + ".parameterNames",
+            json["parameterNames"], jsonDecoder.decodeString);
+      }
+      List<String> parameterTypes;
+      if (json.containsKey("parameterTypes")) {
+        parameterTypes = jsonDecoder.decodeList(jsonPath + ".parameterTypes",
+            json["parameterTypes"], jsonDecoder.decodeString);
+      }
+      List<String> relevanceTags;
+      if (json.containsKey("relevanceTags")) {
+        relevanceTags = jsonDecoder.decodeList(jsonPath + ".relevanceTags",
+            json["relevanceTags"], jsonDecoder.decodeString);
+      }
+      int requiredParameterCount;
+      if (json.containsKey("requiredParameterCount")) {
+        requiredParameterCount = jsonDecoder.decodeInt(
+            jsonPath + ".requiredParameterCount",
+            json["requiredParameterCount"]);
+      }
+      return new AvailableSuggestion(label, element,
+          docComplete: docComplete,
+          docSummary: docSummary,
+          parameterNames: parameterNames,
+          parameterTypes: parameterTypes,
+          relevanceTags: relevanceTags,
+          requiredParameterCount: requiredParameterCount);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "AvailableSuggestion", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["label"] = label;
+    result["element"] = element.toJson();
+    if (docComplete != null) {
+      result["docComplete"] = docComplete;
+    }
+    if (docSummary != null) {
+      result["docSummary"] = docSummary;
+    }
+    if (parameterNames != null) {
+      result["parameterNames"] = parameterNames;
+    }
+    if (parameterTypes != null) {
+      result["parameterTypes"] = parameterTypes;
+    }
+    if (relevanceTags != null) {
+      result["relevanceTags"] = relevanceTags;
+    }
+    if (requiredParameterCount != null) {
+      result["requiredParameterCount"] = requiredParameterCount;
+    }
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is AvailableSuggestion) {
+      return label == other.label &&
+          element == other.element &&
+          docComplete == other.docComplete &&
+          docSummary == other.docSummary &&
+          listEqual(parameterNames, other.parameterNames,
+              (String a, String b) => a == b) &&
+          listEqual(parameterTypes, other.parameterTypes,
+              (String a, String b) => a == b) &&
+          listEqual(relevanceTags, other.relevanceTags,
+              (String a, String b) => a == b) &&
+          requiredParameterCount == other.requiredParameterCount;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, label.hashCode);
+    hash = JenkinsSmiHash.combine(hash, element.hashCode);
+    hash = JenkinsSmiHash.combine(hash, docComplete.hashCode);
+    hash = JenkinsSmiHash.combine(hash, docSummary.hashCode);
+    hash = JenkinsSmiHash.combine(hash, parameterNames.hashCode);
+    hash = JenkinsSmiHash.combine(hash, parameterTypes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, relevanceTags.hashCode);
+    hash = JenkinsSmiHash.combine(hash, requiredParameterCount.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * AvailableSuggestionSet
+ *
+ * {
+ *   "id": int
+ *   "uri": String
+ *   "items": List<AvailableSuggestion>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class AvailableSuggestionSet implements HasToJson {
+  int _id;
+
+  String _uri;
+
+  List<AvailableSuggestion> _items;
+
+  /**
+   * The id associated with the library.
+   */
+  int get id => _id;
+
+  /**
+   * The id associated with the library.
+   */
+  void set id(int value) {
+    assert(value != null);
+    this._id = value;
+  }
+
+  /**
+   * The URI of the library.
+   */
+  String get uri => _uri;
+
+  /**
+   * The URI of the library.
+   */
+  void set uri(String value) {
+    assert(value != null);
+    this._uri = value;
+  }
+
+  List<AvailableSuggestion> get items => _items;
+
+  void set items(List<AvailableSuggestion> value) {
+    assert(value != null);
+    this._items = value;
+  }
+
+  AvailableSuggestionSet(int id, String uri, List<AvailableSuggestion> items) {
+    this.id = id;
+    this.uri = uri;
+    this.items = items;
+  }
+
+  factory AvailableSuggestionSet.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      int id;
+      if (json.containsKey("id")) {
+        id = jsonDecoder.decodeInt(jsonPath + ".id", json["id"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "id");
+      }
+      String uri;
+      if (json.containsKey("uri")) {
+        uri = jsonDecoder.decodeString(jsonPath + ".uri", json["uri"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "uri");
+      }
+      List<AvailableSuggestion> items;
+      if (json.containsKey("items")) {
+        items = jsonDecoder.decodeList(
+            jsonPath + ".items",
+            json["items"],
+            (String jsonPath, Object json) =>
+                new AvailableSuggestion.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "items");
+      }
+      return new AvailableSuggestionSet(id, uri, items);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "AvailableSuggestionSet", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["id"] = id;
+    result["uri"] = uri;
+    result["items"] =
+        items.map((AvailableSuggestion value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is AvailableSuggestionSet) {
+      return id == other.id &&
+          uri == other.uri &&
+          listEqual(items, other.items,
+              (AvailableSuggestion a, AvailableSuggestion b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, id.hashCode);
+    hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+    hash = JenkinsSmiHash.combine(hash, items.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * ClosingLabel
  *
  * {
@@ -5196,6 +5605,417 @@
 }
 
 /**
+ * completion.availableSuggestions params
+ *
+ * {
+ *   "changedLibraries": optional List<AvailableSuggestionSet>
+ *   "removedLibraries": optional List<int>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionAvailableSuggestionsParams implements HasToJson {
+  List<AvailableSuggestionSet> _changedLibraries;
+
+  List<int> _removedLibraries;
+
+  /**
+   * A list of pre-computed, potential completions coming from this set of
+   * completion suggestions.
+   */
+  List<AvailableSuggestionSet> get changedLibraries => _changedLibraries;
+
+  /**
+   * A list of pre-computed, potential completions coming from this set of
+   * completion suggestions.
+   */
+  void set changedLibraries(List<AvailableSuggestionSet> value) {
+    this._changedLibraries = value;
+  }
+
+  /**
+   * A list of library ids that no longer apply.
+   */
+  List<int> get removedLibraries => _removedLibraries;
+
+  /**
+   * A list of library ids that no longer apply.
+   */
+  void set removedLibraries(List<int> value) {
+    this._removedLibraries = value;
+  }
+
+  CompletionAvailableSuggestionsParams(
+      {List<AvailableSuggestionSet> changedLibraries,
+      List<int> removedLibraries}) {
+    this.changedLibraries = changedLibraries;
+    this.removedLibraries = removedLibraries;
+  }
+
+  factory CompletionAvailableSuggestionsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<AvailableSuggestionSet> changedLibraries;
+      if (json.containsKey("changedLibraries")) {
+        changedLibraries = jsonDecoder.decodeList(
+            jsonPath + ".changedLibraries",
+            json["changedLibraries"],
+            (String jsonPath, Object json) =>
+                new AvailableSuggestionSet.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      List<int> removedLibraries;
+      if (json.containsKey("removedLibraries")) {
+        removedLibraries = jsonDecoder.decodeList(
+            jsonPath + ".removedLibraries",
+            json["removedLibraries"],
+            jsonDecoder.decodeInt);
+      }
+      return new CompletionAvailableSuggestionsParams(
+          changedLibraries: changedLibraries,
+          removedLibraries: removedLibraries);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.availableSuggestions params", json);
+    }
+  }
+
+  factory CompletionAvailableSuggestionsParams.fromNotification(
+      Notification notification) {
+    return new CompletionAvailableSuggestionsParams.fromJson(
+        new ResponseDecoder(null), "params", notification.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    if (changedLibraries != null) {
+      result["changedLibraries"] = changedLibraries
+          .map((AvailableSuggestionSet value) => value.toJson())
+          .toList();
+    }
+    if (removedLibraries != null) {
+      result["removedLibraries"] = removedLibraries;
+    }
+    return result;
+  }
+
+  Notification toNotification() {
+    return new Notification("completion.availableSuggestions", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionAvailableSuggestionsParams) {
+      return listEqual(changedLibraries, other.changedLibraries,
+              (AvailableSuggestionSet a, AvailableSuggestionSet b) => a == b) &&
+          listEqual(removedLibraries, other.removedLibraries,
+              (int a, int b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, changedLibraries.hashCode);
+    hash = JenkinsSmiHash.combine(hash, removedLibraries.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.getSuggestionDetails params
+ *
+ * {
+ *   "file": FilePath
+ *   "id": int
+ *   "label": String
+ *   "offset": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionGetSuggestionDetailsParams implements RequestParams {
+  String _file;
+
+  int _id;
+
+  String _label;
+
+  int _offset;
+
+  /**
+   * The path of the file into which this completion is being inserted.
+   */
+  String get file => _file;
+
+  /**
+   * The path of the file into which this completion is being inserted.
+   */
+  void set file(String value) {
+    assert(value != null);
+    this._file = value;
+  }
+
+  /**
+   * The identifier of the AvailableSuggestionSet containing the selected
+   * label.
+   */
+  int get id => _id;
+
+  /**
+   * The identifier of the AvailableSuggestionSet containing the selected
+   * label.
+   */
+  void set id(int value) {
+    assert(value != null);
+    this._id = value;
+  }
+
+  /**
+   * The label from the AvailableSuggestionSet with the `id` for which
+   * insertion information is requested.
+   */
+  String get label => _label;
+
+  /**
+   * The label from the AvailableSuggestionSet with the `id` for which
+   * insertion information is requested.
+   */
+  void set label(String value) {
+    assert(value != null);
+    this._label = value;
+  }
+
+  /**
+   * The offset in the file where the completion will be inserted.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset in the file where the completion will be inserted.
+   */
+  void set offset(int value) {
+    assert(value != null);
+    this._offset = value;
+  }
+
+  CompletionGetSuggestionDetailsParams(
+      String file, int id, String label, int offset) {
+    this.file = file;
+    this.id = id;
+    this.label = label;
+    this.offset = offset;
+  }
+
+  factory CompletionGetSuggestionDetailsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String file;
+      if (json.containsKey("file")) {
+        file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "file");
+      }
+      int id;
+      if (json.containsKey("id")) {
+        id = jsonDecoder.decodeInt(jsonPath + ".id", json["id"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "id");
+      }
+      String label;
+      if (json.containsKey("label")) {
+        label = jsonDecoder.decodeString(jsonPath + ".label", json["label"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "label");
+      }
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "offset");
+      }
+      return new CompletionGetSuggestionDetailsParams(file, id, label, offset);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.getSuggestionDetails params", json);
+    }
+  }
+
+  factory CompletionGetSuggestionDetailsParams.fromRequest(Request request) {
+    return new CompletionGetSuggestionDetailsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["file"] = file;
+    result["id"] = id;
+    result["label"] = label;
+    result["offset"] = offset;
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "completion.getSuggestionDetails", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionGetSuggestionDetailsParams) {
+      return file == other.file &&
+          id == other.id &&
+          label == other.label &&
+          offset == other.offset;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    hash = JenkinsSmiHash.combine(hash, id.hashCode);
+    hash = JenkinsSmiHash.combine(hash, label.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.getSuggestionDetails result
+ *
+ * {
+ *   "completion": String
+ *   "change": optional SourceChange
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionGetSuggestionDetailsResult implements ResponseResult {
+  String _completion;
+
+  SourceChange _change;
+
+  /**
+   * The full text to insert, including any optional import prefix.
+   */
+  String get completion => _completion;
+
+  /**
+   * The full text to insert, including any optional import prefix.
+   */
+  void set completion(String value) {
+    assert(value != null);
+    this._completion = value;
+  }
+
+  /**
+   * A change for the client to apply in case the library containing the
+   * accepted completion suggestion needs to be imported. The field will be
+   * omitted if there are no additional changes that need to be made.
+   */
+  SourceChange get change => _change;
+
+  /**
+   * A change for the client to apply in case the library containing the
+   * accepted completion suggestion needs to be imported. The field will be
+   * omitted if there are no additional changes that need to be made.
+   */
+  void set change(SourceChange value) {
+    this._change = value;
+  }
+
+  CompletionGetSuggestionDetailsResult(String completion,
+      {SourceChange change}) {
+    this.completion = completion;
+    this.change = change;
+  }
+
+  factory CompletionGetSuggestionDetailsResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String completion;
+      if (json.containsKey("completion")) {
+        completion = jsonDecoder.decodeString(
+            jsonPath + ".completion", json["completion"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "completion");
+      }
+      SourceChange change;
+      if (json.containsKey("change")) {
+        change = new SourceChange.fromJson(
+            jsonDecoder, jsonPath + ".change", json["change"]);
+      }
+      return new CompletionGetSuggestionDetailsResult(completion,
+          change: change);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.getSuggestionDetails result", json);
+    }
+  }
+
+  factory CompletionGetSuggestionDetailsResult.fromResponse(Response response) {
+    return new CompletionGetSuggestionDetailsResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        "result",
+        response.result);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["completion"] = completion;
+    if (change != null) {
+      result["change"] = change.toJson();
+    }
+    return result;
+  }
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionGetSuggestionDetailsResult) {
+      return completion == other.completion && change == other.change;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, completion.hashCode);
+    hash = JenkinsSmiHash.combine(hash, change.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * completion.getSuggestions params
  *
  * {
@@ -5391,6 +6211,130 @@
 }
 
 /**
+ * completion.registerLibraryPaths params
+ *
+ * {
+ *   "paths": List<LibraryPathSet>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionRegisterLibraryPathsParams implements RequestParams {
+  List<LibraryPathSet> _paths;
+
+  /**
+   * A list of objects each containing a path and the additional libraries from
+   * which the client is interested in receiving completion suggestions. If one
+   * configured path is beneath another, the descendent will override the
+   * ancestors' configured libraries of interest.
+   */
+  List<LibraryPathSet> get paths => _paths;
+
+  /**
+   * A list of objects each containing a path and the additional libraries from
+   * which the client is interested in receiving completion suggestions. If one
+   * configured path is beneath another, the descendent will override the
+   * ancestors' configured libraries of interest.
+   */
+  void set paths(List<LibraryPathSet> value) {
+    assert(value != null);
+    this._paths = value;
+  }
+
+  CompletionRegisterLibraryPathsParams(List<LibraryPathSet> paths) {
+    this.paths = paths;
+  }
+
+  factory CompletionRegisterLibraryPathsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<LibraryPathSet> paths;
+      if (json.containsKey("paths")) {
+        paths = jsonDecoder.decodeList(
+            jsonPath + ".paths",
+            json["paths"],
+            (String jsonPath, Object json) =>
+                new LibraryPathSet.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "paths");
+      }
+      return new CompletionRegisterLibraryPathsParams(paths);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.registerLibraryPaths params", json);
+    }
+  }
+
+  factory CompletionRegisterLibraryPathsParams.fromRequest(Request request) {
+    return new CompletionRegisterLibraryPathsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["paths"] =
+        paths.map((LibraryPathSet value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "completion.registerLibraryPaths", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionRegisterLibraryPathsParams) {
+      return listEqual(
+          paths, other.paths, (LibraryPathSet a, LibraryPathSet b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, paths.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.registerLibraryPaths result
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionRegisterLibraryPathsResult implements ResponseResult {
+  @override
+  Map<String, dynamic> toJson() => <String, dynamic>{};
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: null);
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionRegisterLibraryPathsResult) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return 104675661;
+  }
+}
+
+/**
  * completion.results params
  *
  * {
@@ -5399,6 +6343,9 @@
  *   "replacementLength": int
  *   "results": List<CompletionSuggestion>
  *   "isLast": bool
+ *   "includedSuggestionSets": optional List<IncludedSuggestionSet>
+ *   "includedSuggestionKinds": optional List<ElementKind>
+ *   "includedSuggestionRelevanceTags": optional List<IncludedSuggestionRelevanceTag>
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -5414,6 +6361,12 @@
 
   bool _isLast;
 
+  List<IncludedSuggestionSet> _includedSuggestionSets;
+
+  List<ElementKind> _includedSuggestionKinds;
+
+  List<IncludedSuggestionRelevanceTag> _includedSuggestionRelevanceTags;
+
   /**
    * The id associated with the completion.
    */
@@ -5499,13 +6452,92 @@
     this._isLast = value;
   }
 
+  /**
+   * This field is experimental.
+   *
+   * References to AvailableSuggestionSet objects previously sent to the
+   * client. The client can include applicable names from the referenced
+   * library in code completion suggestions.
+   */
+  List<IncludedSuggestionSet> get includedSuggestionSets =>
+      _includedSuggestionSets;
+
+  /**
+   * This field is experimental.
+   *
+   * References to AvailableSuggestionSet objects previously sent to the
+   * client. The client can include applicable names from the referenced
+   * library in code completion suggestions.
+   */
+  void set includedSuggestionSets(List<IncludedSuggestionSet> value) {
+    this._includedSuggestionSets = value;
+  }
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the ElementKind sent in
+   * IncludedSuggestionSet to decide whether or not these symbols should should
+   * be presented to the user.
+   */
+  List<ElementKind> get includedSuggestionKinds => _includedSuggestionKinds;
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the ElementKind sent in
+   * IncludedSuggestionSet to decide whether or not these symbols should should
+   * be presented to the user.
+   */
+  void set includedSuggestionKinds(List<ElementKind> value) {
+    this._includedSuggestionKinds = value;
+  }
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the values of the field
+   * relevanceTags of AvailableSuggestion to decide if the suggestion should be
+   * given a different relevance than the IncludedSuggestionSet that contains
+   * it. This might be used for example to give higher relevance to suggestions
+   * of matching types.
+   *
+   * If an AvailableSuggestion has relevance tags that match more than one
+   * IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
+   */
+  List<IncludedSuggestionRelevanceTag> get includedSuggestionRelevanceTags =>
+      _includedSuggestionRelevanceTags;
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the values of the field
+   * relevanceTags of AvailableSuggestion to decide if the suggestion should be
+   * given a different relevance than the IncludedSuggestionSet that contains
+   * it. This might be used for example to give higher relevance to suggestions
+   * of matching types.
+   *
+   * If an AvailableSuggestion has relevance tags that match more than one
+   * IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
+   */
+  void set includedSuggestionRelevanceTags(
+      List<IncludedSuggestionRelevanceTag> value) {
+    this._includedSuggestionRelevanceTags = value;
+  }
+
   CompletionResultsParams(String id, int replacementOffset,
-      int replacementLength, List<CompletionSuggestion> results, bool isLast) {
+      int replacementLength, List<CompletionSuggestion> results, bool isLast,
+      {List<IncludedSuggestionSet> includedSuggestionSets,
+      List<ElementKind> includedSuggestionKinds,
+      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags}) {
     this.id = id;
     this.replacementOffset = replacementOffset;
     this.replacementLength = replacementLength;
     this.results = results;
     this.isLast = isLast;
+    this.includedSuggestionSets = includedSuggestionSets;
+    this.includedSuggestionKinds = includedSuggestionKinds;
+    this.includedSuggestionRelevanceTags = includedSuggestionRelevanceTags;
   }
 
   factory CompletionResultsParams.fromJson(
@@ -5550,8 +6582,37 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "isLast");
       }
+      List<IncludedSuggestionSet> includedSuggestionSets;
+      if (json.containsKey("includedSuggestionSets")) {
+        includedSuggestionSets = jsonDecoder.decodeList(
+            jsonPath + ".includedSuggestionSets",
+            json["includedSuggestionSets"],
+            (String jsonPath, Object json) =>
+                new IncludedSuggestionSet.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      List<ElementKind> includedSuggestionKinds;
+      if (json.containsKey("includedSuggestionKinds")) {
+        includedSuggestionKinds = jsonDecoder.decodeList(
+            jsonPath + ".includedSuggestionKinds",
+            json["includedSuggestionKinds"],
+            (String jsonPath, Object json) =>
+                new ElementKind.fromJson(jsonDecoder, jsonPath, json));
+      }
+      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+      if (json.containsKey("includedSuggestionRelevanceTags")) {
+        includedSuggestionRelevanceTags = jsonDecoder.decodeList(
+            jsonPath + ".includedSuggestionRelevanceTags",
+            json["includedSuggestionRelevanceTags"],
+            (String jsonPath, Object json) =>
+                new IncludedSuggestionRelevanceTag.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
       return new CompletionResultsParams(
-          id, replacementOffset, replacementLength, results, isLast);
+          id, replacementOffset, replacementLength, results, isLast,
+          includedSuggestionSets: includedSuggestionSets,
+          includedSuggestionKinds: includedSuggestionKinds,
+          includedSuggestionRelevanceTags: includedSuggestionRelevanceTags);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "completion.results params", json);
     }
@@ -5571,6 +6632,22 @@
     result["results"] =
         results.map((CompletionSuggestion value) => value.toJson()).toList();
     result["isLast"] = isLast;
+    if (includedSuggestionSets != null) {
+      result["includedSuggestionSets"] = includedSuggestionSets
+          .map((IncludedSuggestionSet value) => value.toJson())
+          .toList();
+    }
+    if (includedSuggestionKinds != null) {
+      result["includedSuggestionKinds"] = includedSuggestionKinds
+          .map((ElementKind value) => value.toJson())
+          .toList();
+    }
+    if (includedSuggestionRelevanceTags != null) {
+      result["includedSuggestionRelevanceTags"] =
+          includedSuggestionRelevanceTags
+              .map((IncludedSuggestionRelevanceTag value) => value.toJson())
+              .toList();
+    }
     return result;
   }
 
@@ -5589,7 +6666,17 @@
           replacementLength == other.replacementLength &&
           listEqual(results, other.results,
               (CompletionSuggestion a, CompletionSuggestion b) => a == b) &&
-          isLast == other.isLast;
+          isLast == other.isLast &&
+          listEqual(includedSuggestionSets, other.includedSuggestionSets,
+              (IncludedSuggestionSet a, IncludedSuggestionSet b) => a == b) &&
+          listEqual(includedSuggestionKinds, other.includedSuggestionKinds,
+              (ElementKind a, ElementKind b) => a == b) &&
+          listEqual(
+              includedSuggestionRelevanceTags,
+              other.includedSuggestionRelevanceTags,
+              (IncludedSuggestionRelevanceTag a,
+                      IncludedSuggestionRelevanceTag b) =>
+                  a == b);
     }
     return false;
   }
@@ -5602,11 +6689,191 @@
     hash = JenkinsSmiHash.combine(hash, replacementLength.hashCode);
     hash = JenkinsSmiHash.combine(hash, results.hashCode);
     hash = JenkinsSmiHash.combine(hash, isLast.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includedSuggestionSets.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includedSuggestionKinds.hashCode);
+    hash =
+        JenkinsSmiHash.combine(hash, includedSuggestionRelevanceTags.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
 
 /**
+ * CompletionService
+ *
+ * enum {
+ *   AVAILABLE_SUGGESTION_SETS
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionService implements Enum {
+  /**
+   * The client will receive notifications once subscribed with completion
+   * suggestion sets from the libraries of interest. The client should keep an
+   * up-to-date record of these in memory so that it will be able to union
+   * these candidates with other completion suggestions when applicable at
+   * completion time.
+   */
+  static const CompletionService AVAILABLE_SUGGESTION_SETS =
+      const CompletionService._("AVAILABLE_SUGGESTION_SETS");
+
+  /**
+   * A list containing all of the enum values that are defined.
+   */
+  static const List<CompletionService> VALUES = const <CompletionService>[
+    AVAILABLE_SUGGESTION_SETS
+  ];
+
+  @override
+  final String name;
+
+  const CompletionService._(this.name);
+
+  factory CompletionService(String name) {
+    switch (name) {
+      case "AVAILABLE_SUGGESTION_SETS":
+        return AVAILABLE_SUGGESTION_SETS;
+    }
+    throw new Exception('Illegal enum value: $name');
+  }
+
+  factory CompletionService.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json is String) {
+      try {
+        return new CompletionService(json);
+      } catch (_) {
+        // Fall through
+      }
+    }
+    throw jsonDecoder.mismatch(jsonPath, "CompletionService", json);
+  }
+
+  @override
+  String toString() => "CompletionService.$name";
+
+  String toJson() => name;
+}
+
+/**
+ * completion.setSubscriptions params
+ *
+ * {
+ *   "subscriptions": List<CompletionService>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionSetSubscriptionsParams implements RequestParams {
+  List<CompletionService> _subscriptions;
+
+  /**
+   * A list of the services being subscribed to.
+   */
+  List<CompletionService> get subscriptions => _subscriptions;
+
+  /**
+   * A list of the services being subscribed to.
+   */
+  void set subscriptions(List<CompletionService> value) {
+    assert(value != null);
+    this._subscriptions = value;
+  }
+
+  CompletionSetSubscriptionsParams(List<CompletionService> subscriptions) {
+    this.subscriptions = subscriptions;
+  }
+
+  factory CompletionSetSubscriptionsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<CompletionService> subscriptions;
+      if (json.containsKey("subscriptions")) {
+        subscriptions = jsonDecoder.decodeList(
+            jsonPath + ".subscriptions",
+            json["subscriptions"],
+            (String jsonPath, Object json) =>
+                new CompletionService.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "subscriptions");
+      }
+      return new CompletionSetSubscriptionsParams(subscriptions);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.setSubscriptions params", json);
+    }
+  }
+
+  factory CompletionSetSubscriptionsParams.fromRequest(Request request) {
+    return new CompletionSetSubscriptionsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["subscriptions"] =
+        subscriptions.map((CompletionService value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "completion.setSubscriptions", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionSetSubscriptionsParams) {
+      return listEqual(subscriptions, other.subscriptions,
+          (CompletionService a, CompletionService b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.setSubscriptions result
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionSetSubscriptionsResult implements ResponseResult {
+  @override
+  Map<String, dynamic> toJson() => <String, dynamic>{};
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: null);
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionSetSubscriptionsResult) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return 2482770;
+  }
+}
+
+/**
  * ContextData
  *
  * {
@@ -5877,6 +7144,132 @@
 }
 
 /**
+ * DartFix
+ *
+ * {
+ *   "name": String
+ *   "description": optional String
+ *   "isRequired": optional bool
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DartFix implements HasToJson {
+  String _name;
+
+  String _description;
+
+  bool _isRequired;
+
+  /**
+   * The name of the fix.
+   */
+  String get name => _name;
+
+  /**
+   * The name of the fix.
+   */
+  void set name(String value) {
+    assert(value != null);
+    this._name = value;
+  }
+
+  /**
+   * A human readable description of the fix.
+   */
+  String get description => _description;
+
+  /**
+   * A human readable description of the fix.
+   */
+  void set description(String value) {
+    this._description = value;
+  }
+
+  /**
+   * `true` if the fix is in the "required" fixes group.
+   */
+  bool get isRequired => _isRequired;
+
+  /**
+   * `true` if the fix is in the "required" fixes group.
+   */
+  void set isRequired(bool value) {
+    this._isRequired = value;
+  }
+
+  DartFix(String name, {String description, bool isRequired}) {
+    this.name = name;
+    this.description = description;
+    this.isRequired = isRequired;
+  }
+
+  factory DartFix.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String name;
+      if (json.containsKey("name")) {
+        name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "name");
+      }
+      String description;
+      if (json.containsKey("description")) {
+        description = jsonDecoder.decodeString(
+            jsonPath + ".description", json["description"]);
+      }
+      bool isRequired;
+      if (json.containsKey("isRequired")) {
+        isRequired = jsonDecoder.decodeBool(
+            jsonPath + ".isRequired", json["isRequired"]);
+      }
+      return new DartFix(name,
+          description: description, isRequired: isRequired);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "DartFix", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["name"] = name;
+    if (description != null) {
+      result["description"] = description;
+    }
+    if (isRequired != null) {
+      result["isRequired"] = isRequired;
+    }
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is DartFix) {
+      return name == other.name &&
+          description == other.description &&
+          isRequired == other.isRequired;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, name.hashCode);
+    hash = JenkinsSmiHash.combine(hash, description.hashCode);
+    hash = JenkinsSmiHash.combine(hash, isRequired.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * DartFixSuggestion
  *
  * {
@@ -6214,6 +7607,9 @@
  *
  * {
  *   "included": List<FilePath>
+ *   "includedFixes": optional List<String>
+ *   "includeRequiredFixes": optional bool
+ *   "excludedFixes": optional List<String>
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -6221,6 +7617,12 @@
 class EditDartfixParams implements RequestParams {
   List<String> _included;
 
+  List<String> _includedFixes;
+
+  bool _includeRequiredFixes;
+
+  List<String> _excludedFixes;
+
   /**
    * A list of the files and directories for which edits should be suggested.
    *
@@ -6248,8 +7650,62 @@
     this._included = value;
   }
 
-  EditDartfixParams(List<String> included) {
+  /**
+   * A list of names indicating which fixes should be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  List<String> get includedFixes => _includedFixes;
+
+  /**
+   * A list of names indicating which fixes should be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  void set includedFixes(List<String> value) {
+    this._includedFixes = value;
+  }
+
+  /**
+   * A flag indicating that "required" fixes should be applied.
+   */
+  bool get includeRequiredFixes => _includeRequiredFixes;
+
+  /**
+   * A flag indicating that "required" fixes should be applied.
+   */
+  void set includeRequiredFixes(bool value) {
+    this._includeRequiredFixes = value;
+  }
+
+  /**
+   * A list of names indicating which fixes should not be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  List<String> get excludedFixes => _excludedFixes;
+
+  /**
+   * A list of names indicating which fixes should not be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  void set excludedFixes(List<String> value) {
+    this._excludedFixes = value;
+  }
+
+  EditDartfixParams(List<String> included,
+      {List<String> includedFixes,
+      bool includeRequiredFixes,
+      List<String> excludedFixes}) {
     this.included = included;
+    this.includedFixes = includedFixes;
+    this.includeRequiredFixes = includeRequiredFixes;
+    this.excludedFixes = excludedFixes;
   }
 
   factory EditDartfixParams.fromJson(
@@ -6265,7 +7721,25 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "included");
       }
-      return new EditDartfixParams(included);
+      List<String> includedFixes;
+      if (json.containsKey("includedFixes")) {
+        includedFixes = jsonDecoder.decodeList(jsonPath + ".includedFixes",
+            json["includedFixes"], jsonDecoder.decodeString);
+      }
+      bool includeRequiredFixes;
+      if (json.containsKey("includeRequiredFixes")) {
+        includeRequiredFixes = jsonDecoder.decodeBool(
+            jsonPath + ".includeRequiredFixes", json["includeRequiredFixes"]);
+      }
+      List<String> excludedFixes;
+      if (json.containsKey("excludedFixes")) {
+        excludedFixes = jsonDecoder.decodeList(jsonPath + ".excludedFixes",
+            json["excludedFixes"], jsonDecoder.decodeString);
+      }
+      return new EditDartfixParams(included,
+          includedFixes: includedFixes,
+          includeRequiredFixes: includeRequiredFixes,
+          excludedFixes: excludedFixes);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "edit.dartfix params", json);
     }
@@ -6280,6 +7754,15 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["included"] = included;
+    if (includedFixes != null) {
+      result["includedFixes"] = includedFixes;
+    }
+    if (includeRequiredFixes != null) {
+      result["includeRequiredFixes"] = includeRequiredFixes;
+    }
+    if (excludedFixes != null) {
+      result["excludedFixes"] = excludedFixes;
+    }
     return result;
   }
 
@@ -6295,7 +7778,12 @@
   bool operator ==(other) {
     if (other is EditDartfixParams) {
       return listEqual(
-          included, other.included, (String a, String b) => a == b);
+              included, other.included, (String a, String b) => a == b) &&
+          listEqual(includedFixes, other.includedFixes,
+              (String a, String b) => a == b) &&
+          includeRequiredFixes == other.includeRequiredFixes &&
+          listEqual(excludedFixes, other.excludedFixes,
+              (String a, String b) => a == b);
     }
     return false;
   }
@@ -6304,6 +7792,9 @@
   int get hashCode {
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, included.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includedFixes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includeRequiredFixes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, excludedFixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -7267,6 +8758,152 @@
 }
 
 /**
+ * edit.getDartfixInfo params
+ *
+ * {
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class EditGetDartfixInfoParams implements RequestParams {
+  EditGetDartfixInfoParams();
+
+  factory EditGetDartfixInfoParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      return new EditGetDartfixInfoParams();
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "edit.getDartfixInfo params", json);
+    }
+  }
+
+  factory EditGetDartfixInfoParams.fromRequest(Request request) {
+    return new EditGetDartfixInfoParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "edit.getDartfixInfo", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is EditGetDartfixInfoParams) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * edit.getDartfixInfo result
+ *
+ * {
+ *   "fixes": List<DartFix>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class EditGetDartfixInfoResult implements ResponseResult {
+  List<DartFix> _fixes;
+
+  /**
+   * A list of fixes that can be specified in an edit.dartfix request.
+   */
+  List<DartFix> get fixes => _fixes;
+
+  /**
+   * A list of fixes that can be specified in an edit.dartfix request.
+   */
+  void set fixes(List<DartFix> value) {
+    assert(value != null);
+    this._fixes = value;
+  }
+
+  EditGetDartfixInfoResult(List<DartFix> fixes) {
+    this.fixes = fixes;
+  }
+
+  factory EditGetDartfixInfoResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<DartFix> fixes;
+      if (json.containsKey("fixes")) {
+        fixes = jsonDecoder.decodeList(
+            jsonPath + ".fixes",
+            json["fixes"],
+            (String jsonPath, Object json) =>
+                new DartFix.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "fixes");
+      }
+      return new EditGetDartfixInfoResult(fixes);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "edit.getDartfixInfo result", json);
+    }
+  }
+
+  factory EditGetDartfixInfoResult.fromResponse(Response response) {
+    return new EditGetDartfixInfoResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        "result",
+        response.result);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["fixes"] = fixes.map((DartFix value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is EditGetDartfixInfoResult) {
+      return listEqual(fixes, other.fixes, (DartFix a, DartFix b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * edit.getFixes params
  *
  * {
@@ -14330,6 +15967,213 @@
 }
 
 /**
+ * IncludedSuggestionRelevanceTag
+ *
+ * {
+ *   "tag": AvailableSuggestionRelevanceTag
+ *   "relevanceBoost": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class IncludedSuggestionRelevanceTag implements HasToJson {
+  String _tag;
+
+  int _relevanceBoost;
+
+  /**
+   * The opaque value of the tag.
+   */
+  String get tag => _tag;
+
+  /**
+   * The opaque value of the tag.
+   */
+  void set tag(String value) {
+    assert(value != null);
+    this._tag = value;
+  }
+
+  /**
+   * The boost to the relevance of the completion suggestions that match this
+   * tag, which is added to the relevance of the containing
+   * IncludedSuggestionSet.
+   */
+  int get relevanceBoost => _relevanceBoost;
+
+  /**
+   * The boost to the relevance of the completion suggestions that match this
+   * tag, which is added to the relevance of the containing
+   * IncludedSuggestionSet.
+   */
+  void set relevanceBoost(int value) {
+    assert(value != null);
+    this._relevanceBoost = value;
+  }
+
+  IncludedSuggestionRelevanceTag(String tag, int relevanceBoost) {
+    this.tag = tag;
+    this.relevanceBoost = relevanceBoost;
+  }
+
+  factory IncludedSuggestionRelevanceTag.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String tag;
+      if (json.containsKey("tag")) {
+        tag = jsonDecoder.decodeString(jsonPath + ".tag", json["tag"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "tag");
+      }
+      int relevanceBoost;
+      if (json.containsKey("relevanceBoost")) {
+        relevanceBoost = jsonDecoder.decodeInt(
+            jsonPath + ".relevanceBoost", json["relevanceBoost"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "relevanceBoost");
+      }
+      return new IncludedSuggestionRelevanceTag(tag, relevanceBoost);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "IncludedSuggestionRelevanceTag", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["tag"] = tag;
+    result["relevanceBoost"] = relevanceBoost;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is IncludedSuggestionRelevanceTag) {
+      return tag == other.tag && relevanceBoost == other.relevanceBoost;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, tag.hashCode);
+    hash = JenkinsSmiHash.combine(hash, relevanceBoost.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * IncludedSuggestionSet
+ *
+ * {
+ *   "id": int
+ *   "relevance": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class IncludedSuggestionSet implements HasToJson {
+  int _id;
+
+  int _relevance;
+
+  /**
+   * Clients should use it to access the set of precomputed completions to be
+   * displayed to the user.
+   */
+  int get id => _id;
+
+  /**
+   * Clients should use it to access the set of precomputed completions to be
+   * displayed to the user.
+   */
+  void set id(int value) {
+    assert(value != null);
+    this._id = value;
+  }
+
+  /**
+   * The relevance of completion suggestions from this library where a higher
+   * number indicates a higher relevance.
+   */
+  int get relevance => _relevance;
+
+  /**
+   * The relevance of completion suggestions from this library where a higher
+   * number indicates a higher relevance.
+   */
+  void set relevance(int value) {
+    assert(value != null);
+    this._relevance = value;
+  }
+
+  IncludedSuggestionSet(int id, int relevance) {
+    this.id = id;
+    this.relevance = relevance;
+  }
+
+  factory IncludedSuggestionSet.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      int id;
+      if (json.containsKey("id")) {
+        id = jsonDecoder.decodeInt(jsonPath + ".id", json["id"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "id");
+      }
+      int relevance;
+      if (json.containsKey("relevance")) {
+        relevance =
+            jsonDecoder.decodeInt(jsonPath + ".relevance", json["relevance"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "relevance");
+      }
+      return new IncludedSuggestionSet(id, relevance);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "IncludedSuggestionSet", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["id"] = id;
+    result["relevance"] = relevance;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is IncludedSuggestionSet) {
+      return id == other.id && relevance == other.relevance;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, id.hashCode);
+    hash = JenkinsSmiHash.combine(hash, relevance.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * inlineLocalVariable feedback
  *
  * {
@@ -14905,6 +16749,113 @@
 }
 
 /**
+ * LibraryPathSet
+ *
+ * {
+ *   "scope": FilePath
+ *   "libraryPaths": List<FilePath>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class LibraryPathSet implements HasToJson {
+  String _scope;
+
+  List<String> _libraryPaths;
+
+  /**
+   * The filepath for which this request's libraries should be active in
+   * completion suggestions. This object associates filesystem regions to
+   * libraries and library directories of interest to the client.
+   */
+  String get scope => _scope;
+
+  /**
+   * The filepath for which this request's libraries should be active in
+   * completion suggestions. This object associates filesystem regions to
+   * libraries and library directories of interest to the client.
+   */
+  void set scope(String value) {
+    assert(value != null);
+    this._scope = value;
+  }
+
+  /**
+   * The paths of the libraries of interest to the client for completion
+   * suggestions.
+   */
+  List<String> get libraryPaths => _libraryPaths;
+
+  /**
+   * The paths of the libraries of interest to the client for completion
+   * suggestions.
+   */
+  void set libraryPaths(List<String> value) {
+    assert(value != null);
+    this._libraryPaths = value;
+  }
+
+  LibraryPathSet(String scope, List<String> libraryPaths) {
+    this.scope = scope;
+    this.libraryPaths = libraryPaths;
+  }
+
+  factory LibraryPathSet.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String scope;
+      if (json.containsKey("scope")) {
+        scope = jsonDecoder.decodeString(jsonPath + ".scope", json["scope"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "scope");
+      }
+      List<String> libraryPaths;
+      if (json.containsKey("libraryPaths")) {
+        libraryPaths = jsonDecoder.decodeList(jsonPath + ".libraryPaths",
+            json["libraryPaths"], jsonDecoder.decodeString);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "libraryPaths");
+      }
+      return new LibraryPathSet(scope, libraryPaths);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "LibraryPathSet", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["scope"] = scope;
+    result["libraryPaths"] = libraryPaths;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is LibraryPathSet) {
+      return scope == other.scope &&
+          listEqual(
+              libraryPaths, other.libraryPaths, (String a, String b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, scope.hashCode);
+    hash = JenkinsSmiHash.combine(hash, libraryPaths.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * moveFile feedback
  *
  * Clients may not extend, implement or mix-in this class.
@@ -15953,6 +17904,7 @@
  *   SERVER_ERROR
  *   SORT_MEMBERS_INVALID_FILE
  *   SORT_MEMBERS_PARSE_ERRORS
+ *   UNKNOWN_FIX
  *   UNKNOWN_REQUEST
  *   UNSUPPORTED_FEATURE
  * }
@@ -16143,6 +18095,13 @@
       const RequestErrorCode._("SORT_MEMBERS_PARSE_ERRORS");
 
   /**
+   * A dartfix request was received containing the name of a fix which does not
+   * match the name of any known fixes.
+   */
+  static const RequestErrorCode UNKNOWN_FIX =
+      const RequestErrorCode._("UNKNOWN_FIX");
+
+  /**
    * A request was received which the analysis server does not recognize, or
    * cannot handle in its current configuration.
    */
@@ -16189,6 +18148,7 @@
     SERVER_ERROR,
     SORT_MEMBERS_INVALID_FILE,
     SORT_MEMBERS_PARSE_ERRORS,
+    UNKNOWN_FIX,
     UNKNOWN_REQUEST,
     UNSUPPORTED_FEATURE
   ];
@@ -16252,6 +18212,8 @@
         return SORT_MEMBERS_INVALID_FILE;
       case "SORT_MEMBERS_PARSE_ERRORS":
         return SORT_MEMBERS_PARSE_ERRORS;
+      case "UNKNOWN_FIX":
+        return UNKNOWN_FIX;
       case "UNKNOWN_REQUEST":
         return UNKNOWN_REQUEST;
       case "UNSUPPORTED_FEATURE":
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index a917fb1..745f48d 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -31,6 +31,7 @@
 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';
@@ -65,6 +66,7 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/plugin/resolver_provider.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:telemetry/crash_reporting.dart';
@@ -150,16 +152,12 @@
 
   ByteStore byteStore;
   nd.AnalysisDriverScheduler analysisDriverScheduler;
+  DeclarationsTracker declarationsTracker;
 
   /// The controller for [onAnalysisSetChanged].
   final StreamController _onAnalysisSetChangedController =
       new StreamController.broadcast(sync: true);
 
-  /// The DiagnosticServer for this AnalysisServer. If available, it can be used
-  /// to start an http diagnostics server or return the port for an existing
-  /// server.
-  final DiagnosticServer diagnosticServer;
-
   final DetachableFileSystemManager detachableFileSystemManager;
 
   /// Initialize a newly created server to receive requests from and send
@@ -175,11 +173,11 @@
     AnalysisServerOptions options,
     this.sdkManager,
     this.instrumentationService, {
-    this.diagnosticServer,
+    DiagnosticServer diagnosticServer,
     ResolverProvider fileResolverProvider: null,
     ResolverProvider packageResolverProvider: null,
     this.detachableFileSystemManager: null,
-  }) : super(options, baseResourceProvider) {
+  }) : super(options, diagnosticServer, baseResourceProvider) {
     notificationManager = new NotificationManager(channel, resourceProvider);
 
     pluginManager = new PluginManager(
@@ -281,6 +279,36 @@
     return _onAnalysisStartedController.stream;
   }
 
+  void createDeclarationsTracker(void Function(LibraryChange) listener) {
+    if (declarationsTracker != null) return;
+
+    declarationsTracker = DeclarationsTracker(byteStore, resourceProvider);
+    declarationsTracker.changes.listen(listener);
+
+    _addContextsToDeclarationsTracker();
+
+    // Configure the scheduler to run the tracker.
+    analysisDriverScheduler.outOfBandWorker =
+        CompletionLibrariesWorker(declarationsTracker);
+
+    // We might have done running drivers work, so ask the scheduler to check.
+    analysisDriverScheduler.notify(null);
+  }
+
+  /// Notify the declarations tracker that the file with the given [path] was
+  /// changed - added, updated, or removed.  Schedule processing of the file.
+  void notifyDeclarationsTracker(String path) {
+    if (declarationsTracker != null) {
+      declarationsTracker.changeFile(path);
+      analysisDriverScheduler.notify(null);
+    }
+  }
+
+  void disposeDeclarationsTracker() {
+    declarationsTracker = null;
+    analysisDriverScheduler.outOfBandWorker = null;
+  }
+
   /// The socket from which requests are being read has been closed.
   void done() {}
 
@@ -351,6 +379,12 @@
     });
   }
 
+  /// Return `true` if the [path] is both absolute and normalized.
+  bool isAbsoluteAndNormalized(String path) {
+    var pathContext = resourceProvider.pathContext;
+    return pathContext.isAbsolute(path) && pathContext.normalize(path) == path;
+  }
+
   /// Return `true` if analysis is complete.
   bool isAnalysisComplete() {
     return !analysisDriverScheduler.isAnalyzing;
@@ -382,6 +416,16 @@
     channel.sendResponse(response);
   }
 
+  /// If the [path] is not a valid file path, that is absolute and normalized,
+  /// send an error response, and return `true`. If OK then return `false`.
+  bool sendResponseErrorIfInvalidFilePath(Request request, String path) {
+    if (!isAbsoluteAndNormalized(path)) {
+      sendResponse(Response.invalidFilePathFormat(request, path));
+      return true;
+    }
+    return false;
+  }
+
   /// Sends a `server.error` notification.
   void sendServerErrorNotification(
     String message,
@@ -472,6 +516,7 @@
   /// projects/contexts support.
   void setAnalysisRoots(String requestId, List<String> includedPaths,
       List<String> excludedPaths, Map<String, String> packageRoots) {
+    declarationsTracker?.discardContexts();
     if (notificationManager != null) {
       notificationManager.setAnalysisRoots(includedPaths, excludedPaths);
     }
@@ -481,6 +526,7 @@
       throw new RequestFailure(
           new Response.unsupportedFeature(requestId, e.message));
     }
+    _addContextsToDeclarationsTracker();
   }
 
   /// Implementation for `analysis.setSubscriptions`.
@@ -612,8 +658,11 @@
       }
 
       if (newContents != null) {
-        resourceProvider.setOverlay(file,
-            content: newContents, modificationStamp: 0);
+        resourceProvider.setOverlay(
+          file,
+          content: newContents,
+          modificationStamp: overlayModificationStamp++,
+        );
       } else {
         resourceProvider.removeOverlay(file);
       }
@@ -626,6 +675,8 @@
       // analyzed. Add it to driver to which it should have been added.
       contextManager.getDriverFor(file)?.addFile(file);
 
+      notifyDeclarationsTracker(file);
+
       // TODO(scheglov) implement other cases
     });
   }
@@ -655,6 +706,15 @@
 //    });
   }
 
+  void _addContextsToDeclarationsTracker() {
+    if (declarationsTracker != null) {
+      for (var driver in driverMap.values) {
+        declarationsTracker.addContext(driver.analysisContext);
+        driver.resetUriResolution();
+      }
+    }
+  }
+
   /// Return the path to the location of the byte store on disk, or `null` if
   /// there is no on-disk byte store.
   String _getByteStorePath() {
@@ -902,6 +962,7 @@
 
   @override
   void broadcastWatchEvent(WatchEvent event) {
+    analysisServer.notifyDeclarationsTracker(event.path);
     analysisServer.pluginManager.broadcastWatchEvent(event);
   }
 
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index f784b71..50834b3 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -8,6 +8,7 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/context_manager.dart';
+import 'package:analysis_server/src/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:analyzer/dart/analysis/results.dart';
@@ -24,6 +25,7 @@
     show EvictingFileByteStore;
 import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
 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/generated/engine.dart';
 import 'package:analyzer/src/util/glob.dart';
@@ -38,6 +40,11 @@
   /// context directories.
   ContextManager contextManager;
 
+  /// The DiagnosticServer for this AnalysisServer. If available, it can be used
+  /// to start an http diagnostics server or return the port for an existing
+  /// server.
+  final DiagnosticServer diagnosticServer;
+
   /// A [RecentBuffer] of the most recent exceptions encountered by the analysis
   /// server.
   final RecentBuffer<ServerException> exceptions = new RecentBuffer(10);
@@ -69,11 +76,15 @@
   /// The [ResourceProvider] using which paths are converted into [Resource]s.
   final OverlayResourceProvider resourceProvider;
 
+  /// The next modification stamp for a changed file in the [resourceProvider].
+  int overlayModificationStamp = 0;
+
   /// A list of the globs used to determine which files should be analyzed. The
   /// list is lazily created and should be accessed using [analyzedFilesGlobs].
   List<Glob> _analyzedFilesGlobs = null;
 
-  AbstractAnalysisServer(this.options, ResourceProvider baseResourceProvider)
+  AbstractAnalysisServer(this.options, this.diagnosticServer,
+      ResourceProvider baseResourceProvider)
       : resourceProvider = OverlayResourceProvider(baseResourceProvider) {
     performance = performanceDuringStartup;
   }
@@ -221,6 +232,15 @@
     return null;
   }
 
+  /// Return the unresolved unit for the file with the given [path].
+  ParsedUnitResult getParsedUnit(String path) {
+    if (!AnalysisEngine.isDartFileName(path)) {
+      return null;
+    }
+
+    return getAnalysisDriver(path)?.currentSession?.getParsedUnit(path);
+  }
+
   /// Return the resolved unit for the file with the given [path]. The file is
   /// analyzed in one of the analysis drivers to which the file was added,
   /// otherwise in the first driver, otherwise `null` is returned.
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 39c1e8e..0076909 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -475,6 +475,18 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
+    super.visitForEachPartsWithIdentifier(node);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
     computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
@@ -483,12 +495,26 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
+    super.visitForElement(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
     super.visitForStatement(node);
   }
 
   @override
+  void visitForStatement2(ForStatement2 node) {
+    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
+    super.visitForStatement2(node);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
@@ -524,8 +550,16 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
     super.visitIfStatement(node);
   }
 
@@ -581,6 +615,13 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitListLiteral2(node);
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
     computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
@@ -588,6 +629,13 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitMapLiteral2(node);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
@@ -652,6 +700,20 @@
   }
 
   @override
+  void visitSetLiteral(SetLiteral node) {
+//    computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitSetLiteral(node);
+  }
+
+  @override
+  void visitSetLiteral2(SetLiteral2 node) {
+//    computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitSetLiteral2(node);
+  }
+
+  @override
   void visitShowCombinator(ShowCombinator node) {
     computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
     super.visitShowCombinator(node);
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index 6ae85e2..1f0326f 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -566,6 +566,18 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
+    super.visitForEachPartsWithIdentifier(node);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
     computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
@@ -574,12 +586,26 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
+    super.visitForElement(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
     super.visitForStatement(node);
   }
 
   @override
+  void visitForStatement2(ForStatement2 node) {
+    computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
+    computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
+    super.visitForStatement2(node);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
@@ -615,8 +641,16 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
+    computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
     super.visitIfStatement(node);
   }
 
@@ -678,6 +712,13 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitListLiteral2(node);
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
     computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
@@ -685,6 +726,13 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitMapLiteral2(node);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     computer._addRegion_token(
         node.externalKeyword, HighlightRegionType.BUILT_IN);
@@ -749,6 +797,20 @@
   }
 
   @override
+  void visitSetLiteral(SetLiteral node) {
+//    computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitSetLiteral(node);
+  }
+
+  @override
+  void visitSetLiteral2(SetLiteral2 node) {
+//    computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
+    computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
+    super.visitSetLiteral2(node);
+  }
+
+  @override
   void visitShowCombinator(ShowCombinator node) {
     computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
     super.visitShowCombinator(node);
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index eb20b24..3af0fbd 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -5,11 +5,12 @@
 import 'package:analysis_server/protocol/protocol_generated.dart'
     show HoverInformation;
 import 'package:analysis_server/src/computer/computer_overrides.dart';
-import 'package:analysis_server/src/utilities/documentation.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/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/util/comment.dart';
 
 /**
  * A computer for the hover at the specified offset of a Dart [CompilationUnit].
@@ -118,7 +119,7 @@
     }
     // The documentation of the element itself.
     if (element.documentationComment != null) {
-      return removeDartDocDelimiters(element.documentationComment);
+      return getDartDocPlainText(element.documentationComment);
     }
     // Look for documentation comments of overridden members.
     OverriddenElements overridden = findOverriddenElements(element);
@@ -128,7 +129,7 @@
       String rawDoc = superElement.documentationComment;
       if (rawDoc != null) {
         Element interfaceClass = superElement.enclosingElement;
-        return removeDartDocDelimiters(rawDoc) +
+        return getDartDocPlainText(rawDoc) +
             '\n\nCopied from `${interfaceClass.displayName}`.';
       }
     }
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index cd1ff67..7eb2b68 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -32,7 +32,7 @@
    */
   List<proto.Override> compute() {
     for (CompilationUnitMember unitMember in _unit.declarations) {
-      if (unitMember is ClassDeclaration) {
+      if (unitMember is ClassOrMixinDeclaration) {
         for (ClassMember classMember in unitMember.members) {
           if (classMember is MethodDeclaration) {
             if (classMember.isStatic) {
@@ -198,6 +198,7 @@
 
     _addSuperOverrides(type.superclass);
     type.mixins.forEach(_addSuperOverrides);
+    type.superclassConstraints.forEach(_addSuperOverrides);
   }
 
   Element _lookupMember(ClassElement classElement) {
diff --git a/pkg/analysis_server/lib/src/computer/computer_signature.dart b/pkg/analysis_server/lib/src/computer/computer_signature.dart
index 518a488..2dd950c 100644
--- a/pkg/analysis_server/lib/src/computer/computer_signature.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_signature.dart
@@ -8,6 +8,7 @@
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 9d2cbe9..6886c65 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -47,6 +47,11 @@
    */
   Future<void> getErrors(Request request) async {
     String file = new AnalysisGetErrorsParams.fromRequest(request).file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     ResolvedUnitResult result = await server.getResolvedUnit(file);
 
     if (result?.state != ResultState.VALID) {
@@ -70,9 +75,14 @@
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     var params = new AnalysisGetHoverParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
 
     // Prepare the resolved units.
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
     CompilationUnit unit = result?.unit;
 
     // Prepare the hovers.
@@ -96,12 +106,17 @@
   Future<void> getImportedElements(Request request) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
-    AnalysisGetImportedElementsParams params =
-        new AnalysisGetImportedElementsParams.fromRequest(request);
+    var params = new AnalysisGetImportedElementsParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     //
     // Prepare the resolved unit.
     //
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
     if (result?.state != ResultState.VALID) {
       server.sendResponse(new Response.getImportedElementsInvalidFile(request));
       return;
@@ -160,6 +175,10 @@
     int offset = params.offset;
     int length = params.length;
 
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     AnalysisDriver driver = server.getAnalysisDriver(file);
     if (driver == null) {
       server.sendResponse(new Response.getNavigationInvalidFile(request));
@@ -242,9 +261,14 @@
    */
   Future<void> getSignature(Request request) async {
     var params = new AnalysisGetSignatureParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
 
     // Prepare the resolved units.
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
 
     if (result?.state != ResultState.VALID) {
       server.sendResponse(new Response.getSignatureInvalidFile(request));
@@ -388,6 +412,12 @@
   Response setPriorityFiles(Request request) {
     var params = new AnalysisSetPriorityFilesParams.fromRequest(request);
 
+    for (var file in params.files) {
+      if (!server.isAbsoluteAndNormalized(file)) {
+        return Response.invalidFilePathFormat(request, file);
+      }
+    }
+
     if (server.options.enableUXExperiment1) {
       // If this experiment is enabled, set the analysis root to be the
       // containing directory.
@@ -445,6 +475,15 @@
    */
   Response setSubscriptions(Request request) {
     var params = new AnalysisSetSubscriptionsParams.fromRequest(request);
+
+    for (var fileList in params.subscriptions.values) {
+      for (var file in fileList) {
+        if (!server.isAbsoluteAndNormalized(file)) {
+          return Response.invalidFilePathFormat(request, file);
+        }
+      }
+    }
+
     // parse subscriptions
     Map<AnalysisService, Set<String>> subMap = mapMap(params.subscriptions,
         valueCallback: (List<String> subscriptions) => subscriptions.toSet());
@@ -466,6 +505,13 @@
    */
   Response updateContent(Request request) {
     var params = new AnalysisUpdateContentParams.fromRequest(request);
+
+    for (var file in params.files.keys) {
+      if (!server.isAbsoluteAndNormalized(file)) {
+        return Response.invalidFilePathFormat(request, file);
+      }
+    }
+
     server.updateContent(request.id, params.files);
     //
     // Forward the request to the plugins.
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 2b61900..b9d51ae 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/domain_abstract.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/completion_core.dart';
@@ -21,6 +22,7 @@
 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:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 
 /**
  * Instances of the class [CompletionDomainHandler] implement a [RequestHandler]
@@ -33,6 +35,11 @@
   static const int performanceListMaxLength = 50;
 
   /**
+   * The completion services that the client is currently subscribed.
+   */
+  final Set<CompletionService> _subscriptions = Set<CompletionService>();
+
+  /**
    * The next completion response id.
    */
   int _nextCompletionId = 0;
@@ -66,8 +73,12 @@
    * Subclasses should override this method, append at least one result
    * to the [controller], and close the controller stream once complete.
    */
-  Future<CompletionResult> computeSuggestions(CompletionRequestImpl request,
-      CompletionGetSuggestionsParams params) async {
+  Future<CompletionResult> computeSuggestions(
+    CompletionRequestImpl request,
+    CompletionGetSuggestionsParams params,
+    Set<ElementKind> includedSuggestionKinds,
+    List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
+  ) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     //
@@ -91,11 +102,15 @@
       const COMPUTE_SUGGESTIONS_TAG = 'computeSuggestions';
       performance.logStartTime(COMPUTE_SUGGESTIONS_TAG);
 
-      CompletionContributor contributor = new DartCompletionManager();
-      String contributorTag = 'computeSuggestions - ${contributor.runtimeType}';
+      var manager = new DartCompletionManager(
+        includedSuggestionKinds: includedSuggestionKinds,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+      );
+
+      String contributorTag = 'computeSuggestions - ${manager.runtimeType}';
       performance.logStartTime(contributorTag);
       try {
-        suggestions.addAll(await contributor.computeSuggestions(request));
+        suggestions.addAll(await manager.computeSuggestions(request));
       } on AbortCompletion {
         suggestions.clear();
       }
@@ -136,13 +151,78 @@
         request.replacementOffset, request.replacementLength, suggestions);
   }
 
+  /**
+   * Process a `completion.getSuggestionDetails` request.
+   */
+  void getSuggestionDetails(Request request) async {
+    var params = CompletionGetSuggestionDetailsParams.fromRequest(request);
+
+    var file = params.file;
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
+    var libraryId = params.id;
+    var library = server.declarationsTracker.getLibrary(libraryId);
+    if (library == null) {
+      server.sendResponse(Response.invalidParameter(
+        request,
+        'libraryId',
+        'No such library: $libraryId',
+      ));
+      return;
+    }
+
+    var analysisDriver = server.getAnalysisDriver(file);
+    var session = analysisDriver.currentSession;
+    var resolvedLibrary = await session.getResolvedLibrary(file);
+    var requestedLibraryElement = await session.getLibraryByUri(library.uriStr);
+
+    // The label might be `MyEnum.myValue`, but we import only `MyEnum`.
+    var requestedName = params.label;
+    if (requestedName.contains('.')) {
+      requestedName = requestedName.substring(
+        0,
+        requestedName.indexOf('.'),
+      );
+    }
+
+    var completion = params.label;
+    var builder = DartChangeBuilder(session);
+    await builder.addFileEdit(file, (builder) {
+      var result = builder.importLibraryElement(
+        targetLibrary: resolvedLibrary,
+        targetPath: file,
+        targetOffset: params.offset,
+        requestedLibrary: requestedLibraryElement,
+        requestedName: requestedName,
+      );
+      if (result.prefix != null) {
+        completion = '${result.prefix}.$completion';
+      }
+    });
+
+    server.sendResponse(
+      CompletionGetSuggestionDetailsResult(
+        completion,
+        change: builder.sourceChange,
+      ).toResponse(request.id),
+    );
+  }
+
   @override
   Response handleRequest(Request request) {
     return runZoned(() {
       String requestName = request.method;
-      if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
+
+      if (requestName == COMPLETION_REQUEST_GET_SUGGESTION_DETAILS) {
+        getSuggestionDetails(request);
+        return Response.DELAYED_RESPONSE;
+      } else if (requestName == COMPLETION_REQUEST_GET_SUGGESTIONS) {
         processRequest(request);
         return Response.DELAYED_RESPONSE;
+      } else if (requestName == COMPLETION_REQUEST_SET_SUBSCRIPTIONS) {
+        return setSubscriptions(request);
       }
       return null;
     }, onError: (exception, stackTrace) {
@@ -170,13 +250,16 @@
     // extract and validate params
     CompletionGetSuggestionsParams params =
         new CompletionGetSuggestionsParams.fromRequest(request);
-    String filePath = params.file;
+    String file = params.file;
     int offset = params.offset;
 
-    ResolvedUnitResult result = await server.getResolvedUnit(filePath);
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
 
-    if (result?.state == ResultState.VALID) {
-      if (offset < 0 || offset > result.content.length) {
+    ResolvedUnitResult resolvedUnit = await server.getResolvedUnit(file);
+    if (resolvedUnit?.state == ResultState.VALID) {
+      if (offset < 0 || offset > resolvedUnit.content.length) {
         server.sendResponse(new Response.invalidParameter(
             request,
             'params.offset',
@@ -185,10 +268,10 @@
         return;
       }
 
-      recordRequest(performance, filePath, result.content, offset);
+      recordRequest(performance, file, resolvedUnit.content, offset);
     }
     CompletionRequestImpl completionRequest =
-        new CompletionRequestImpl(result, offset, performance);
+        new CompletionRequestImpl(resolvedUnit, offset, performance);
 
     String completionId = (_nextCompletionId++).toString();
 
@@ -198,14 +281,45 @@
     server.sendResponse(new CompletionGetSuggestionsResult(completionId)
         .toResponse(request.id));
 
+    // If the client opted into using available suggestion sets,
+    // create the kinds set, so signal the completion manager about opt-in.
+    Set<ElementKind> includedSuggestionKinds;
+    List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+    if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+      includedSuggestionKinds = Set<ElementKind>();
+      includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
+    }
+
     // Compute suggestions in the background
-    computeSuggestions(completionRequest, params)
-        .then((CompletionResult result) {
+    computeSuggestions(
+      completionRequest,
+      params,
+      includedSuggestionKinds,
+      includedSuggestionRelevanceTags,
+    ).then((CompletionResult result) {
+      List<IncludedSuggestionSet> includedSuggestionSets;
+      if (includedSuggestionKinds != null && resolvedUnit != null) {
+        includedSuggestionSets = computeIncludedSetList(
+          server.declarationsTracker,
+          resolvedUnit,
+        );
+      } else {
+        includedSuggestionSets = [];
+      }
+
       const SEND_NOTIFICATION_TAG = 'send notification';
       performance.logStartTime(SEND_NOTIFICATION_TAG);
-      sendCompletionNotification(completionId, result.replacementOffset,
-          result.replacementLength, result.suggestions);
+      sendCompletionNotification(
+        completionId,
+        result.replacementOffset,
+        result.replacementLength,
+        result.suggestions,
+        includedSuggestionSets,
+        includedSuggestionKinds?.toList(),
+        includedSuggestionRelevanceTags,
+      );
       performance.logElapseTime(SEND_NOTIFICATION_TAG);
+
       performance.notificationCount = 1;
       performance.logFirstNotificationComplete('notification 1 complete');
       performance.suggestionCountFirst = result.suggestions.length;
@@ -233,11 +347,27 @@
   /**
    * Send completion notification results.
    */
-  void sendCompletionNotification(String completionId, int replacementOffset,
-      int replacementLength, Iterable<CompletionSuggestion> results) {
-    server.sendNotification(new CompletionResultsParams(
-            completionId, replacementOffset, replacementLength, results, true)
-        .toNotification());
+  void sendCompletionNotification(
+    String completionId,
+    int replacementOffset,
+    int replacementLength,
+    Iterable<CompletionSuggestion> results,
+    List<IncludedSuggestionSet> includedSuggestionSets,
+    List<ElementKind> includedSuggestionKinds,
+    List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags,
+  ) {
+    server.sendNotification(
+      new CompletionResultsParams(
+        completionId,
+        replacementOffset,
+        replacementLength,
+        results,
+        true,
+        includedSuggestionSets: includedSuggestionSets,
+        includedSuggestionKinds: includedSuggestionKinds,
+        includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
+      ).toNotification(),
+    );
   }
 
   void setNewRequest(CompletionRequest completionRequest) {
@@ -246,6 +376,28 @@
   }
 
   /**
+   * Implement the 'completion.setSubscriptions' request.
+   */
+  Response setSubscriptions(Request request) {
+    var params = CompletionSetSubscriptionsParams.fromRequest(request);
+
+    _subscriptions.clear();
+    _subscriptions.addAll(params.subscriptions);
+
+    if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+      server.createDeclarationsTracker((change) {
+        server.sendNotification(
+          createCompletionAvailableSuggestionsNotification(change),
+        );
+      });
+    } else {
+      server.disposeDeclarationsTracker();
+    }
+
+    return CompletionSetSubscriptionsResult().toResponse(request.id);
+  }
+
+  /**
    * Abort the current completion request, if any.
    */
   void _abortCurrentRequest() {
diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
index 2885948..6139967 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
@@ -18,26 +18,11 @@
   ImplementedComputer(this.searchEngine, this.unitElement);
 
   compute() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    for (ClassElement type in unitElement.types) {
-      // Always include Object and its members.
-      if (type.supertype == null) {
-        _addImplementedClass(type);
-        type.accessors.forEach(_addImplementedMember);
-        type.fields.forEach(_addImplementedMember);
-        type.methods.forEach(_addImplementedMember);
-        continue;
-      }
-
-      // Analyze subtypes.
-      subtypeMembers = await searchEngine.membersOfSubtypes(type);
-      if (subtypeMembers != null) {
-        _addImplementedClass(type);
-        type.accessors.forEach(_addMemberIfImplemented);
-        type.fields.forEach(_addMemberIfImplemented);
-        type.methods.forEach(_addMemberIfImplemented);
-      }
+    for (var element in unitElement.mixins) {
+      await _computeForClassElement(element);
+    }
+    for (var element in unitElement.types) {
+      await _computeForClassElement(element);
     }
   }
 
@@ -62,6 +47,26 @@
     }
   }
 
+  Future<void> _computeForClassElement(ClassElement element) async {
+    // Always include Object and its members.
+    if (element.supertype == null && !element.isMixin) {
+      _addImplementedClass(element);
+      element.accessors.forEach(_addImplementedMember);
+      element.fields.forEach(_addImplementedMember);
+      element.methods.forEach(_addImplementedMember);
+      return;
+    }
+
+    // Analyze subtypes.
+    subtypeMembers = await searchEngine.membersOfSubtypes(element);
+    if (subtypeMembers != null) {
+      _addImplementedClass(element);
+      element.accessors.forEach(_addMemberIfImplemented);
+      element.fields.forEach(_addMemberIfImplemented);
+      element.methods.forEach(_addMemberIfImplemented);
+    }
+  }
+
   bool _hasOverride(Element element) {
     String name = element.displayName;
     return subtypeMembers.contains(name);
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
new file mode 100644
index 0000000..69f51f6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/analysis/results.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
+
+/// Compute which suggestion sets should be included into completion inside
+/// the given [resolvedUnit] of a file.  Depending on the file path, it might
+/// include different sets, e.g. inside the `lib/` directory of a `Pub` package
+/// only regular dependencies can be referenced, but `test/` can reference
+/// both regular and "dev" dependencies.
+List<protocol.IncludedSuggestionSet> computeIncludedSetList(
+  DeclarationsTracker tracker,
+  ResolvedUnitResult resolvedUnit,
+) {
+  var analysisContext = resolvedUnit.session.analysisContext;
+  var context = tracker.getContext(analysisContext);
+  if (context == null) return const [];
+
+  var librariesObject = context.getLibraries(resolvedUnit.path);
+  var includedSetList = <protocol.IncludedSuggestionSet>[];
+
+  var importedUriSet = resolvedUnit.libraryElement.importedLibraries
+      .map((importedLibrary) => importedLibrary.source.uri)
+      .toSet();
+
+  void includeLibrary(
+    Library library,
+    int importedRelevance,
+    int deprecatedRelevance,
+    int otherwiseRelevance,
+  ) {
+    int relevance;
+    if (importedUriSet.contains(library.uri)) {
+      relevance = importedRelevance;
+    } else if (library.isDeprecated) {
+      relevance = deprecatedRelevance;
+    } else {
+      relevance = otherwiseRelevance;
+    }
+
+    includedSetList.add(
+      protocol.IncludedSuggestionSet(library.id, relevance),
+    );
+  }
+
+  for (var library in librariesObject.context) {
+    includeLibrary(library, 8, 2, 5);
+  }
+
+  for (var library in librariesObject.dependencies) {
+    includeLibrary(library, 7, 1, 4);
+  }
+
+  for (var library in librariesObject.sdk) {
+    includeLibrary(library, 6, 0, 3);
+  }
+
+  return includedSetList;
+}
+
+/// Convert the [LibraryChange] into the corresponding protocol notification.
+protocol.Notification createCompletionAvailableSuggestionsNotification(
+  LibraryChange change,
+) {
+  return protocol.CompletionAvailableSuggestionsParams(
+    changedLibraries: change.changed.map((library) {
+      return protocol.AvailableSuggestionSet(
+        library.id,
+        library.uriStr,
+        library.declarations.map((declaration) {
+          return _protocolAvailableSuggestion(declaration);
+        }).toList(),
+      );
+    }).toList(),
+    removedLibraries: change.removed,
+  ).toNotification();
+}
+
+protocol.AvailableSuggestion _protocolAvailableSuggestion(
+    Declaration declaration) {
+  var label = declaration.name;
+  if (declaration.kind == DeclarationKind.ENUM_CONSTANT) {
+    label = '${declaration.name2}.${declaration.name}';
+  }
+
+  return protocol.AvailableSuggestion(
+    label,
+    _protocolElement(declaration),
+    docComplete: declaration.docComplete,
+    docSummary: declaration.docSummary,
+    parameterNames: declaration.parameterNames,
+    parameterTypes: declaration.parameterTypes,
+    requiredParameterCount: declaration.requiredParameterCount,
+    relevanceTags: declaration.relevanceTags,
+  );
+}
+
+protocol.Element _protocolElement(Declaration declaration) {
+  return protocol.Element(
+    _protocolElementKind(declaration.kind),
+    declaration.name,
+    _protocolElementFlags(declaration),
+    location: protocol.Location(
+      declaration.locationPath,
+      declaration.locationOffset,
+      0, // length
+      declaration.locationStartLine,
+      declaration.locationStartColumn,
+    ),
+    parameters: declaration.parameters,
+    returnType: declaration.returnType,
+    typeParameters: declaration.typeParameters,
+  );
+}
+
+int _protocolElementFlags(Declaration declaration) {
+  return protocol.Element.makeFlags(
+    isAbstract: declaration.isAbstract,
+    isConst: declaration.isConst,
+    isFinal: declaration.isFinal,
+    isDeprecated: declaration.isDeprecated,
+  );
+}
+
+protocol.ElementKind _protocolElementKind(DeclarationKind kind) {
+  switch (kind) {
+    case DeclarationKind.CLASS:
+      return protocol.ElementKind.CLASS;
+    case DeclarationKind.CLASS_TYPE_ALIAS:
+      return protocol.ElementKind.CLASS_TYPE_ALIAS;
+    case DeclarationKind.ENUM:
+      return protocol.ElementKind.ENUM;
+    case DeclarationKind.ENUM_CONSTANT:
+      return protocol.ElementKind.ENUM_CONSTANT;
+    case DeclarationKind.FUNCTION:
+      return protocol.ElementKind.FUNCTION;
+    case DeclarationKind.FUNCTION_TYPE_ALIAS:
+      return protocol.ElementKind.FUNCTION_TYPE_ALIAS;
+    case DeclarationKind.GETTER:
+      return protocol.ElementKind.GETTER;
+    case DeclarationKind.MIXIN:
+      return protocol.ElementKind.MIXIN;
+    case DeclarationKind.SETTER:
+      return protocol.ElementKind.SETTER;
+    case DeclarationKind.VARIABLE:
+      return protocol.ElementKind.TOP_LEVEL_VARIABLE;
+  }
+  return protocol.ElementKind.UNKNOWN;
+}
+
+class CompletionLibrariesWorker implements SchedulerWorker {
+  final DeclarationsTracker tracker;
+
+  CompletionLibrariesWorker(this.tracker);
+
+  @override
+  AnalysisDriverPriority get workPriority {
+    if (tracker.hasWork) {
+      return AnalysisDriverPriority.priority;
+    } else {
+      return AnalysisDriverPriority.nothing;
+    }
+  }
+
+  @override
+  Future<void> performWork() async {
+    tracker.doWork();
+  }
+}
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index dbba4ea..594580d 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -15,21 +15,19 @@
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 
 class RuntimeCompletionComputer {
-  final ResourceProvider resourceProvider;
-  final FileContentOverlay fileContentOverlay;
+  final OverlayResourceProvider resourceProvider;
   final AnalysisDriver analysisDriver;
 
   final String code;
   final int offset;
 
-  final String contextFile;
+  final String contextPath;
   final int contextOffset;
 
   final List<RuntimeCompletionVariable> variables;
@@ -37,11 +35,10 @@
 
   RuntimeCompletionComputer(
       this.resourceProvider,
-      this.fileContentOverlay,
       this.analysisDriver,
       this.code,
       this.offset,
-      this.contextFile,
+      this.contextPath,
       this.contextOffset,
       this.variables,
       this.expressions);
@@ -49,7 +46,7 @@
   Future<RuntimeCompletionResult> compute() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
-    var contextResult = await analysisDriver.getResult(contextFile);
+    var contextResult = await analysisDriver.getResult(contextPath);
     var session = contextResult.session;
 
     const codeMarker = '__code_\_';
@@ -57,7 +54,7 @@
     // Insert the code being completed at the context offset.
     var changeBuilder = new DartChangeBuilder(session);
     int nextImportPrefixIndex = 0;
-    await changeBuilder.addFileEdit(contextFile, (builder) {
+    await changeBuilder.addFileEdit(contextPath, (builder) {
       builder.addInsertion(contextOffset, (builder) {
         builder.writeln('{');
 
@@ -83,15 +80,9 @@
     // Update the context file content to include the code being completed.
     // Then resolve it, and restore the file to its initial state.
     ResolvedUnitResult targetResult;
-    String contentFileOverlay = fileContentOverlay[contextFile];
-    try {
-      fileContentOverlay[contextFile] = targetCode;
-      analysisDriver.changeFile(contextFile);
-      targetResult = await analysisDriver.getResult(contextFile);
-    } finally {
-      fileContentOverlay[contextFile] = contentFileOverlay;
-      analysisDriver.changeFile(contextFile);
-    }
+    await _withContextFileContent(targetCode, () async {
+      targetResult = await analysisDriver.getResult(contextPath);
+    });
 
     CompletionContributor contributor = new DartCompletionManager();
     CompletionRequestImpl request = new CompletionRequestImpl(
@@ -108,6 +99,44 @@
     var expressions = <RuntimeCompletionExpression>[];
     return new RuntimeCompletionResult(expressions, suggestions);
   }
+
+  Future<void> _withContextFileContent(
+      String newContent, Future<void> Function() f) async {
+    if (resourceProvider.hasOverlay(contextPath)) {
+      var contextFile = resourceProvider.getFile(contextPath);
+      var prevOverlayContent = contextFile.readAsStringSync();
+      var prevOverlayStamp = contextFile.modificationStamp;
+      try {
+        resourceProvider.setOverlay(
+          contextPath,
+          content: newContent,
+          modificationStamp: 0,
+        );
+        analysisDriver.changeFile(contextPath);
+        await f();
+      } finally {
+        resourceProvider.setOverlay(
+          contextPath,
+          content: prevOverlayContent,
+          modificationStamp: prevOverlayStamp,
+        );
+        analysisDriver.changeFile(contextPath);
+      }
+    } else {
+      try {
+        resourceProvider.setOverlay(
+          contextPath,
+          content: newContent,
+          modificationStamp: 0,
+        );
+        analysisDriver.changeFile(contextPath);
+        await f();
+      } finally {
+        resourceProvider.removeOverlay(contextPath);
+        analysisDriver.changeFile(contextPath);
+      }
+    }
+  }
 }
 
 /// The result of performing runtime completion.
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index c9b2ff1..9b5c226 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -2,74 +2,69 @@
 // for details. All 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/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
-import 'package:analysis_server/src/edit/fix/prefer_int_literals_fix.dart';
-import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.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:analysis_server/src/edit/fix/dartfix_info.dart';
+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/fix/fix_error_task.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/lint/linter.dart';
-import 'package:analyzer/src/lint/linter_visitor.dart';
-import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart'
-    show Location, SourceChange, SourceEdit, SourceFileEdit;
-import 'package:front_end/src/fasta/fasta_codes.dart';
-import 'package:front_end/src/scanner/token.dart';
-import 'package:source_span/src/span.dart';
 
-class EditDartFix {
+class EditDartFix
+    with FixCodeProcessor, FixErrorProcessor, FixLintProcessor
+    implements DartFixRegistrar {
   final AnalysisServer server;
+
   final Request request;
   final fixFolders = <Folder>[];
   final fixFiles = <File>[];
 
-  List<DartFixSuggestion> suggestions;
-  List<DartFixSuggestion> otherSuggestions;
-  SourceChange sourceChange;
+  DartFixListener listener;
 
-  EditDartFix(this.server, this.request);
-
-  void addSourceChange(
-      String description, Location location, SourceChange change) {
-    suggestions.add(new DartFixSuggestion(description, location: location));
-    for (SourceFileEdit fileEdit in change.edits) {
-      for (SourceEdit sourceEdit in fileEdit.edits) {
-        sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
-      }
-    }
-  }
-
-  void addSourceFileEdit(
-      String description, Location location, SourceFileEdit fileEdit) {
-    suggestions.add(new DartFixSuggestion(description, location: location));
-    for (SourceEdit sourceEdit in fileEdit.edits) {
-      sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
-    }
-  }
-
-  void addRecommendation(String description, [Location location]) {
-    otherSuggestions
-        .add(new DartFixSuggestion(description, location: location));
+  EditDartFix(this.server, this.request) {
+    listener = new DartFixListener(server);
   }
 
   Future<Response> compute() async {
     final params = new EditDartfixParams.fromRequest(request);
 
+    // Determine the fixes to be applied
+    final fixInfo = <DartFixInfo>[];
+    if (params.includeRequiredFixes == true) {
+      fixInfo.addAll(allFixes.where((i) => i.isRequired));
+    }
+    if (params.includedFixes != null) {
+      for (String key in params.includedFixes) {
+        var info = allFixes.firstWhere((i) => i.key == key, orElse: () => null);
+        if (info != null) {
+          fixInfo.add(info);
+        } else {
+          // TODO(danrubel): Report unknown fix to the user
+        }
+      }
+    }
+    if (fixInfo.isEmpty) {
+      fixInfo.addAll(allFixes.where((i) => i.isDefault));
+    }
+    if (params.excludedFixes != null) {
+      for (String key in params.excludedFixes) {
+        var info = allFixes.firstWhere((i) => i.key == key, orElse: () => null);
+        if (info != null) {
+          fixInfo.remove(info);
+        } else {
+          // TODO(danrubel): Report unknown fix to the user
+        }
+      }
+    }
+    for (DartFixInfo info in fixInfo) {
+      info.setup(this, listener);
+    }
+
     // Validate each included file and directory.
     final resourceProvider = server.resourceProvider;
     final contextManager = server.contextManager;
@@ -90,156 +85,52 @@
       }
     }
 
-    // Get the desired lints
-    final lintRules = Registry.ruleRegistry;
-
-    final preferMixin = lintRules['prefer_mixin'];
-    final preferMixinFix = new PreferMixinFix(this);
-    preferMixin.reporter = preferMixinFix;
-
-    final preferIntLiterals = lintRules['prefer_int_literals'];
-    final preferIntLiteralsFix = new PreferIntLiteralsFix(this);
-    final nonNullableFix = new NonNullableFix(this);
-    preferIntLiterals?.reporter = preferIntLiteralsFix;
-
-    // Setup
-    final linters = <Linter>[
-      preferMixin,
-      preferIntLiterals,
-    ];
-    final fixes = <LinterFix>[
-      preferMixinFix,
-      preferIntLiteralsFix,
-    ];
-    final lintVisitorsBySession = <AnalysisSession, _LintVisitors>{};
-
-    // TODO(danrubel): Determine if a lint is configured to run as part of
-    // standard analysis and use those results if available instead of
-    // running the lint again.
-
-    // Analyze each source file.
-    final resources = <Resource>[];
-    for (String rootPath in contextManager.includedPaths) {
-      resources.add(resourceProvider.getResource(rootPath));
-    }
-    suggestions = <DartFixSuggestion>[];
-    otherSuggestions = <DartFixSuggestion>[];
-    sourceChange = new SourceChange('dartfix');
+    // Process each source file.
     bool hasErrors = false;
-    while (resources.isNotEmpty) {
-      Resource res = resources.removeLast();
-      if (res is Folder) {
-        for (Resource child in res.getChildren()) {
-          if (!child.shortName.startsWith('.') &&
-              contextManager.isInAnalysisRoot(child.path) &&
-              !contextManager.isIgnored(child.path)) {
-            resources.add(child);
-          }
+    String changedPath;
+    server.contextManager.driverMap.values
+        .forEach((d) => d.onCurrentSessionAboutToBeDiscarded = (String path) {
+              // Remember the resource that changed during analysis
+              changedPath = path;
+            });
+
+    try {
+      await processResources((ResolvedUnitResult result) async {
+        if (await processErrors(result)) {
+          hasErrors = true;
         }
-        continue;
+        await processLints(result);
+        await processCodeTasks(result);
+      });
+      if (needsSecondPass) {
+        await processResources((ResolvedUnitResult result) async {
+          await processCodeTasks2(result);
+        });
       }
-
-      const maxAttempts = 3;
-      int attempt = 0;
-      while (attempt < maxAttempts) {
-        ResolvedUnitResult result = await server.getResolvedUnit(res.path);
-
-        // TODO(danrubel): Investigate why InconsistentAnalysisException occurs
-        // and whether this is an appropriate way to handle the situation
-        ++attempt;
-        try {
-          CompilationUnit unit = result?.unit;
-          if (unit != null) {
-            if (!hasErrors) {
-              for (AnalysisError error in result.errors) {
-                if (!(await fixError(result, error))) {
-                  if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
-                    hasErrors = true;
-                  }
-                }
-              }
-            }
-            Source source = result.unit.declaredElement.source;
-            for (Linter linter in linters) {
-              if (linter != null) {
-                linter.reporter.source = source;
-              }
-            }
-            var lintVisitors = lintVisitorsBySession[result.session] ??=
-                await _setupLintVisitors(result, linters);
-            if (lintVisitors.astVisitor != null) {
-              unit.accept(lintVisitors.astVisitor);
-            }
-            unit.accept(lintVisitors.linterVisitor);
-            for (LinterFix fix in fixes) {
-              await fix.applyLocalFixes(result);
-            }
-            if (isIncluded(source.fullName)) {
-              nonNullableFix.applyLocalFixes(result);
-            }
-          }
-          break;
-        } on InconsistentAnalysisException catch (_) {
-          if (attempt == maxAttempts) {
-            // TODO(danrubel): Consider improving the edit.dartfix protocol
-            // to gracefully report inconsistent results for a particular
-            // file rather than aborting the entire operation.
-            rethrow;
-          }
-          // try again
-        }
-      }
-    }
-
-    // Cleanup
-    for (Linter linter in linters) {
-      if (linter != null) {
-        linter.reporter.source = null;
-        linter.reporter = null;
-      }
-    }
-
-    // Apply distributed fixes
-    if (preferIntLiterals == null) {
-      // TODO(danrubel): Remove this once linter rolled into sdk/third_party.
-      addRecommendation('*** Convert double literal not available'
-          ' because prefer_int_literal not found. May need to roll linter');
-    }
-    for (LinterFix fix in fixes) {
-      await fix.applyRemainingFixes();
+      await finishLints();
+      await finishCodeTasks();
+    } on InconsistentAnalysisException catch (_) {
+      // If a resource changed, report the problem without suggesting fixes
+      var changedMessage = changedPath != null
+          ? 'resource changed during analysis: $changedPath'
+          : 'multiple resources changed during analysis.';
+      return new EditDartfixResult(
+        [new DartFixSuggestion('Analysis canceled because $changedMessage')],
+        listener.otherSuggestions,
+        hasErrors,
+        listener.sourceChange.edits,
+      ).toResponse(request.id);
+    } finally {
+      server.contextManager.driverMap.values
+          .forEach((d) => d.onCurrentSessionAboutToBeDiscarded = null);
     }
 
     return new EditDartfixResult(
-            suggestions, otherSuggestions, hasErrors, sourceChange.edits)
-        .toResponse(request.id);
-  }
-
-  Future<bool> fixError(ResolvedUnitResult result, AnalysisError error) async {
-    if (error.errorCode ==
-        StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR) {
-      // TODO(danrubel): Rather than comparing the error codes individually,
-      // it would be better if each error code could specify
-      // whether or not it could be fixed automatically.
-
-      // Fall through to calculate and apply the fix
-    } else {
-      // This error cannot be automatically fixed
-      return false;
-    }
-
-    final workspace = DartChangeWorkspace(server.currentSessions);
-    final dartContext = new DartFixContextImpl(workspace, result, error);
-    final processor = new FixProcessor(dartContext);
-    Fix fix = await processor.computeFix();
-    final location = locationFor(result, error.offset, error.length);
-    if (fix != null) {
-      addSourceChange(fix.change.message, location, fix.change);
-    } else {
-      // TODO(danrubel): Determine why the fix could not be applied
-      // and report that in the description.
-      addRecommendation('Could not fix "${error.message}"', location);
-    }
-    return true;
+      listener.suggestions,
+      listener.otherSuggestions,
+      hasErrors,
+      listener.sourceChange.edits,
+    ).toResponse(request.id);
   }
 
   /// Return `true` if the path in within the set of `included` files
@@ -260,122 +151,35 @@
     return false;
   }
 
-  Location locationFor(ResolvedUnitResult result, int offset, int length) {
-    final locInfo = result.unit.lineInfo.getLocation(offset);
-    final location = new Location(
-        result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
-    return location;
-  }
-
-  Future<_LintVisitors> _setupLintVisitors(
-      ResolvedUnitResult result, List<Linter> linters) async {
-    final visitors = <AstVisitor>[];
-    final registry = new NodeLintRegistry(false);
-    // TODO(paulberry): use an API that provides this information more readily
-    var unitElement = result.unit.declaredElement;
-    var session = result.session;
-    var currentUnit = LinterContextUnit(result.content, result.unit);
-    var allUnits = <LinterContextUnit>[];
-    for (var cu in unitElement.library.units) {
-      if (identical(cu, unitElement)) {
-        allUnits.add(currentUnit);
-      } else {
-        Source source = cu.source;
-        if (source != null) {
-          var result = await session.getResolvedUnit(source.fullName);
-          allUnits.add(LinterContextUnit(result.content, result.unit));
-        }
-      }
+  /// Call the supplied [process] function to process each compilation unit.
+  Future processResources(
+      Future<void> Function(ResolvedUnitResult result) process) async {
+    final contextManager = server.contextManager;
+    final resourceProvider = server.resourceProvider;
+    final resources = <Resource>[];
+    for (String rootPath in contextManager.includedPaths) {
+      resources.add(resourceProvider.getResource(rootPath));
     }
-    var context = LinterContextImpl(allUnits, currentUnit,
-        session.declaredVariables, result.typeProvider, result.typeSystem);
-    for (Linter linter in linters) {
-      if (linter != null) {
-        final visitor = linter.getVisitor();
-        if (visitor != null) {
-          visitors.add(visitor);
+    while (resources.isNotEmpty) {
+      Resource res = resources.removeLast();
+      if (res is Folder) {
+        for (Resource child in res.getChildren()) {
+          if (!child.shortName.startsWith('.') &&
+              contextManager.isInAnalysisRoot(child.path) &&
+              !contextManager.isIgnored(child.path)) {
+            resources.add(child);
+          }
         }
-        if (linter is NodeLintRule) {
-          (linter as NodeLintRule).registerNodeProcessors(registry, context);
-        }
+        continue;
       }
+      if (!isIncluded(res.path)) {
+        continue;
+      }
+      ResolvedUnitResult result = await server.getResolvedUnit(res.path);
+      if (result == null || result.unit == null) {
+        continue;
+      }
+      await process(result);
     }
-    final AstVisitor astVisitor = visitors.isNotEmpty
-        ? new ExceptionHandlingDelegatingAstVisitor(
-            visitors, ExceptionHandlingDelegatingAstVisitor.logException)
-        : null;
-    final AstVisitor linterVisitor = new LinterVisitor(
-        registry, ExceptionHandlingDelegatingAstVisitor.logException);
-    return _LintVisitors(astVisitor, linterVisitor);
   }
 }
-
-abstract class LinterFix implements ErrorReporter {
-  final EditDartFix dartFix;
-
-  @override
-  Source source;
-
-  LinterFix(this.dartFix);
-
-  /// Apply fixes for the current compilation unit.
-  Future<void> applyLocalFixes(ResolvedUnitResult result);
-
-  /// Apply any fixes remaining after analysis is complete.
-  Future<void> applyRemainingFixes();
-
-  @override
-  void reportError(AnalysisError error) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForElement(ErrorCode errorCode, Element element,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForNode(ErrorCode errorCode, AstNode node,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForSpan(ErrorCode errorCode, SourceSpan span,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorForToken(ErrorCode errorCode, Token token,
-      [List<Object> arguments]) {
-    // ignored
-  }
-
-  @override
-  void reportErrorMessage(
-      ErrorCode errorCode, int offset, int length, Message message) {
-    // ignored
-  }
-
-  @override
-  void reportTypeErrorForNode(
-      ErrorCode errorCode, AstNode node, List<Object> arguments) {
-    // ignored
-  }
-}
-
-class _LintVisitors {
-  final AstVisitor astVisitor;
-
-  final AstVisitor linterVisitor;
-
-  _LintVisitors(this.astVisitor, this.linterVisitor);
-}
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 2e1f6e2..efccaeb 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -11,7 +11,8 @@
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/computer/import_elements_computer.dart';
 import 'package:analysis_server/src/domain_abstract.dart';
-import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/edit_dartfix.dart' show EditDartFix;
+import 'package:analysis_server/src/edit/fix/dartfix_info.dart' show allFixes;
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/plugin/result_converter.dart';
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
@@ -165,6 +166,10 @@
     int offset = params.offset;
     int length = params.length;
 
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     List<SourceChange> changes = <SourceChange>[];
     //
     // Allow plugins to start computing assists.
@@ -222,12 +227,21 @@
         .sendResponse(new EditGetAssistsResult(changes).toResponse(request.id));
   }
 
+  Response getDartfixInfo(Request request) =>
+      new EditGetDartfixInfoResult(allFixes.map((i) => i.asDartFix()).toList())
+          .toResponse(request.id);
+
   Future getFixes(Request request) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     EditGetFixesParams params = new EditGetFixesParams.fromRequest(request);
     String file = params.file;
     int offset = params.offset;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     //
     // Allow plugins to start computing fixes.
     //
@@ -277,9 +291,15 @@
     server.options.analytics?.sendEvent('edit', 'getPostfixCompletion');
 
     var params = new EditGetPostfixCompletionParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     SourceChange change;
 
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
     if (result != null) {
       PostfixCompletionContext context = new PostfixCompletionContext(
         result,
@@ -303,10 +323,17 @@
   Future getStatementCompletion(Request request) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
+
     var params = new EditGetStatementCompletionParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     SourceChange change;
 
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
     if (result != null) {
       var context = new StatementCompletionContext(result, params.offset);
       StatementCompletionProcessor processor =
@@ -334,6 +361,8 @@
         return Response.DELAYED_RESPONSE;
       } else if (requestName == EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS) {
         return _getAvailableRefactorings(request);
+      } else if (requestName == EDIT_REQUEST_GET_DARTFIX_INFO) {
+        return getDartfixInfo(request);
       } else if (requestName == EDIT_REQUEST_GET_FIXES) {
         getFixes(request);
         return Response.DELAYED_RESPONSE;
@@ -377,12 +406,18 @@
   Future<void> importElements(Request request) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
-    EditImportElementsParams params =
-        new EditImportElementsParams.fromRequest(request);
+
+    var params = new EditImportElementsParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     //
     // Prepare the resolved unit.
     //
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
     if (result == null) {
       server.sendResponse(new Response.importElementsInvalidFile(request));
     }
@@ -415,9 +450,15 @@
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     var params = new EditGetPostfixCompletionParams.fromRequest(request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     bool value = false;
 
-    ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+    ResolvedUnitResult result = await server.getResolvedUnit(file);
     if (result != null) {
       var context = new PostfixCompletionContext(
         result,
@@ -452,12 +493,16 @@
     server.options.analytics?.sendEvent('edit', 'organizeDirectives');
 
     var params = new EditOrganizeDirectivesParams.fromRequest(request);
-    // prepare file
-    String file = params.file;
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
     if (!engine.AnalysisEngine.isDartFileName(file)) {
       server.sendResponse(new Response.fileNotAnalyzed(request, file));
       return;
     }
+
     // Prepare the file information.
     ResolvedUnitResult result = await server.getResolvedUnit(file);
     if (result == null) {
@@ -487,19 +532,23 @@
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     var params = new EditSortMembersParams.fromRequest(request);
-    // prepare file
-    String file = params.file;
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
     if (!engine.AnalysisEngine.isDartFileName(file)) {
       server.sendResponse(new Response.sortMembersInvalidFile(request));
       return;
     }
+
     // Prepare the file information.
-    var driver = server.getAnalysisDriver(file);
-    ParsedUnitResult result = await driver?.parseFile(file);
+    ParsedUnitResult result = await server.getParsedUnit(file);
     if (result == null) {
       server.sendResponse(new Response.fileNotAnalyzed(request, file));
       return;
     }
+
     int fileStamp = -1;
     String code = result.content;
     CompilationUnit unit = result.unit;
@@ -560,13 +609,15 @@
   }
 
   Future _getAvailableRefactoringsImpl(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    // prepare parameters
     var params = new EditGetAvailableRefactoringsParams.fromRequest(request);
     String file = params.file;
     int offset = params.offset;
     int length = params.length;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
+
     // add refactoring kinds
     List<RefactoringKind> kinds = <RefactoringKind>[];
     // Check nodes.
@@ -731,6 +782,11 @@
         EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST, EMPTY_PROBLEM_LIST);
     // process the request
     var params = new EditGetRefactoringParams.fromRequest(_request);
+    var file = params.file;
+
+    if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
+      return;
+    }
 
     if (params.kind != null) {
       server.options.analytics
@@ -740,7 +796,7 @@
     runZoned(() async {
       // TODO(brianwilkerson) Determine whether this await is necessary.
       await null;
-      await _init(params.kind, params.file, params.offset, params.length);
+      await _init(params.kind, file, params.offset, params.length);
       if (initStatus.hasFatalError) {
         feedback = null;
         _sendResultResponse();
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
new file mode 100644
index 0000000..3e6c9c8
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/protocol/protocol_generated.dart' show DartFix;
+import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
+import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_int_literals_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart';
+
+const allFixes = <DartFixInfo>[
+  //
+  // Required fixes
+  //
+  const DartFixInfo(
+    'fix-named-constructor-type-arguments',
+    'Move named constructor type arguments from the name to the type.',
+    FixErrorTask.fixNamedConstructorTypeArgs,
+    isRequired: true,
+  ),
+  const DartFixInfo(
+    'use-mixin',
+    'Convert classes used as a mixin to the new mixin syntax.',
+    PreferMixinFix.task,
+    isRequired: true,
+  ),
+  //
+  // Suggested fixes
+  //
+  const DartFixInfo(
+    'double-to-int',
+    'Find double literals ending in .0 and remove the .0\n'
+        'wherever double context can be inferred.',
+    PreferIntLiteralsFix.task,
+  ),
+  //
+  // Expermimental fixes
+  //
+  const DartFixInfo(
+    'non-nullable',
+    // TODO(danrubel) update description and make default/required
+    // when NNBD fix is ready
+    'Experimental: Update sources to be non-nullable by default.\n'
+        'Requires the experimental non-nullable flag to be enabled.\n'
+        'This is not applied unless explicitly included.',
+    NonNullableFix.task,
+    isDefault: false,
+  ),
+];
+
+/// [DartFixInfo] represents a fix that can be applied by [EditDartFix].
+class DartFixInfo {
+  final String key;
+  final String description;
+  final bool isDefault;
+  final bool isRequired;
+  final void Function(DartFixRegistrar dartfix, DartFixListener listener) setup;
+
+  const DartFixInfo(this.key, this.description, this.setup,
+      {this.isDefault = true, this.isRequired = false});
+
+  DartFix asDartFix() =>
+      new DartFix(key, description: description, isRequired: isRequired);
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
new file mode 100644
index 0000000..73805d4
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show Location, SourceChange, SourceEdit, SourceFileEdit;
+
+/// Tasks use this API to report results.
+class DartFixListener {
+  final AnalysisServer server;
+
+  final List<DartFixSuggestion> suggestions = <DartFixSuggestion>[];
+  final List<DartFixSuggestion> otherSuggestions = <DartFixSuggestion>[];
+  final SourceChange sourceChange = new SourceChange('dartfix');
+
+  DartFixListener(this.server);
+
+  /// Record a source change to be sent to the client.
+  void addSourceChange(
+      String description, Location location, SourceChange change) {
+    suggestions.add(new DartFixSuggestion(description, location: location));
+    for (SourceFileEdit fileEdit in change.edits) {
+      for (SourceEdit sourceEdit in fileEdit.edits) {
+        sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
+      }
+    }
+  }
+
+  /// Record edits for a single source to be sent to the client.
+  void addSourceEdits(String description, Location location, Source source,
+      Iterable<SourceEdit> edits) {
+    suggestions.add(new DartFixSuggestion(description, location: location));
+    for (SourceEdit edit in edits) {
+      sourceChange.addEdit(source.fullName, -1, edit);
+    }
+  }
+
+  /// Record a source change to be sent to the client.
+  void addSourceFileEdit(
+      String description, Location location, SourceFileEdit fileEdit) {
+    suggestions.add(new DartFixSuggestion(description, location: location));
+    for (SourceEdit sourceEdit in fileEdit.edits) {
+      sourceChange.addEdit(fileEdit.file, fileEdit.fileStamp, sourceEdit);
+    }
+  }
+
+  /// Record a recommendation to be sent to the client.
+  void addRecommendation(String description, [Location location]) {
+    otherSuggestions
+        .add(new DartFixSuggestion(description, location: location));
+  }
+
+  /// Return the [Location] representing the specified offset and length
+  /// in the given compilation unit.
+  Location locationFor(ResolvedUnitResult result, int offset, int length) {
+    final locInfo = result.unit.lineInfo.getLocation(offset);
+    final location = new Location(
+        result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
+    return location;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.dart
new file mode 100644
index 0000000..07652c0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_registrar.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:analysis_server/src/edit/fix/dartfix_info.dart';
+import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/linter.dart';
+
+/// Fixes use this API to register tasks. See [DartFixInfo.setup].
+abstract class DartFixRegistrar {
+  /// Register the specified task to analyze and fix problems.
+  void registerCodeTask(FixCodeTask task);
+
+  /// Register the specified task to fix the given error condition.
+  void registerErrorTask(ErrorCode errorCode, FixErrorTask task);
+
+  /// Register the specified task to fix the given lint.
+  void registerLintTask(LintRule ruleRegistry, FixLintTask task);
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
new file mode 100644
index 0000000..71d491b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/edit_dartfix.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+/// A general task for performing a fix.
+abstract class FixCodeTask {
+  /// [processUnit] is called for each compilation unit.
+  Future<void> processUnit(ResolvedUnitResult result);
+
+  /// [finish] is called after [processUnit] (and [processUnit2] if this
+  /// is a FixCodeTask2) has been called for each compilation unit.
+  Future<void> finish();
+}
+
+/// A general task for performing a fix which needs a 2nd pass.
+abstract class FixCodeTask2 extends FixCodeTask {
+  /// [processUnit2] is called for each compilation unit
+  /// after [processUnit] has been called for each compilation unit.
+  Future<void> processUnit2(ResolvedUnitResult result);
+}
+
+/// A processor used by [EditDartFix] to manage [FixCodeTask]s.
+mixin FixCodeProcessor {
+  final codeTasks = <FixCodeTask>[];
+  final codeTasks2 = <FixCodeTask2>[];
+
+  Future<void> finishCodeTasks() async {
+    for (FixCodeTask task in codeTasks) {
+      await task.finish();
+    }
+  }
+
+  bool get needsSecondPass => codeTasks2.isNotEmpty;
+
+  Future<void> processCodeTasks(ResolvedUnitResult result) async {
+    for (FixCodeTask task in codeTasks) {
+      await task.processUnit(result);
+    }
+  }
+
+  Future<void> processCodeTasks2(ResolvedUnitResult result) async {
+    for (FixCodeTask2 task in codeTasks) {
+      await task.processUnit2(result);
+    }
+  }
+
+  void registerCodeTask(FixCodeTask task) {
+    codeTasks.add(task);
+    if (task is FixCodeTask2) {
+      codeTasks2.add(task);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
new file mode 100644
index 0000000..e71fd1d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_error_task.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/edit/edit_dartfix.dart';
+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/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/dart/analysis/results.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+/// A task for fixing a particular error
+class FixErrorTask {
+  static void fixNamedConstructorTypeArgs(
+      DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerErrorTask(
+        StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
+        new FixErrorTask(listener));
+  }
+
+  final DartFixListener listener;
+
+  FixErrorTask(this.listener);
+
+  Future<void> fixError(ResolvedUnitResult result, AnalysisError error) async {
+    final workspace = DartChangeWorkspace(listener.server.currentSessions);
+    final dartContext = new DartFixContextImpl(workspace, result, error);
+    final processor = new FixProcessor(dartContext);
+    Fix fix = await processor.computeFix();
+    final location = listener.locationFor(result, error.offset, error.length);
+    if (fix != null) {
+      listener.addSourceChange(fix.change.message, location, fix.change);
+    } else {
+      // TODO(danrubel): Determine why the fix could not be applied
+      // and report that in the description.
+      listener.addRecommendation('Could not fix "${error.message}"', location);
+    }
+  }
+}
+
+/// A processor used by [EditDartFix] to manage [FixErrorTask]s.
+mixin FixErrorProcessor {
+  /// A mapping from [ErrorCode] to the fix that should be applied.
+  final errorTaskMap = <ErrorCode, FixErrorTask>{};
+
+  Future<bool> processErrors(ResolvedUnitResult result) async {
+    bool foundError = false;
+    for (AnalysisError error in result.errors) {
+      final task = errorTaskMap[error.errorCode];
+      if (task != null) {
+        await task.fixError(result, error);
+      } else if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  Future<bool> fixError(ResolvedUnitResult result, AnalysisError error) async {
+    return true;
+  }
+
+  void registerErrorTask(ErrorCode errorCode, FixErrorTask task) {
+    errorTaskMap[errorCode] = task;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
new file mode 100644
index 0000000..0885046
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_lint_task.dart
@@ -0,0 +1,170 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:analyzer/src/lint/linter_visitor.dart';
+import 'package:analyzer/src/services/lint.dart';
+import 'package:front_end/src/fasta/fasta_codes.dart';
+import 'package:front_end/src/scanner/token.dart';
+import 'package:source_span/src/span.dart';
+
+/// A task for fixing a particular lint.
+/// Subclasses should implement [applyLocalFixes] and [applyRemainingFixes]
+/// and may override any of the reportSomething() methods as needed.
+abstract class FixLintTask implements ErrorReporter {
+  final DartFixListener listener;
+
+  @override
+  Source source;
+
+  FixLintTask(this.listener);
+
+  /// Apply fixes for the current compilation unit.
+  Future<void> applyLocalFixes(ResolvedUnitResult result);
+
+  /// Apply any fixes remaining after all local changes have been applied.
+  Future<void> applyRemainingFixes();
+
+  @override
+  void reportError(AnalysisError error) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForElement(ErrorCode errorCode, Element element,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForSpan(ErrorCode errorCode, SourceSpan span,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorForToken(ErrorCode errorCode, Token token,
+      [List<Object> arguments]) {
+    // ignored
+  }
+
+  @override
+  void reportErrorMessage(
+      ErrorCode errorCode, int offset, int length, Message message) {
+    // ignored
+  }
+
+  @override
+  void reportTypeErrorForNode(
+      ErrorCode errorCode, AstNode node, List<Object> arguments) {
+    // ignored
+  }
+}
+
+/// A processor used by [EditDartFix] to manage [FixLintTask]s.
+mixin FixLintProcessor {
+  final linters = <Linter>[];
+  final lintTasks = <FixLintTask>[];
+
+  Future<void> finishLints() async {
+    for (Linter linter in linters) {
+      linter.reporter = null;
+    }
+    for (FixLintTask fix in lintTasks) {
+      fix.source = null;
+      await fix.applyRemainingFixes();
+    }
+  }
+
+  Future<void> processLints(ResolvedUnitResult result) async {
+    // TODO(danrubel): Determine if a lint is configured to run as part of
+    // standard analysis and use those results if available instead of
+    // running the lint again.
+
+    Source source = result.unit.declaredElement.source;
+    for (Linter linter in linters) {
+      if (linter != null) {
+        linter.reporter.source = source;
+      }
+    }
+
+    // TODO(paulberry): use an API that provides this information more readily
+
+    var unitElement = result.unit.declaredElement;
+    var session = result.session;
+    var currentUnit = LinterContextUnit(result.content, result.unit);
+    var allUnits = <LinterContextUnit>[];
+    for (var cu in unitElement.library.units) {
+      if (identical(cu, unitElement)) {
+        allUnits.add(currentUnit);
+      } else {
+        Source source = cu.source;
+        if (source != null) {
+          var result = await session.getResolvedUnit(source.fullName);
+          allUnits.add(LinterContextUnit(result.content, result.unit));
+        }
+      }
+    }
+
+    final visitors = <AstVisitor>[];
+    final registry = new NodeLintRegistry(false);
+    var context = LinterContextImpl(
+        allUnits,
+        currentUnit,
+        session.declaredVariables,
+        result.typeProvider,
+        result.typeSystem,
+        result.session.analysisContext.analysisOptions);
+    for (Linter linter in linters) {
+      if (linter != null) {
+        final visitor = linter.getVisitor();
+        if (visitor != null) {
+          visitors.add(visitor);
+        }
+        if (linter is NodeLintRule) {
+          (linter as NodeLintRule).registerNodeProcessors(registry, context);
+        }
+      }
+    }
+
+    CompilationUnit unit = result.unit;
+    if (visitors.isNotEmpty) {
+      unit.accept(new ExceptionHandlingDelegatingAstVisitor(
+          visitors, ExceptionHandlingDelegatingAstVisitor.logException));
+    }
+    unit.accept(new LinterVisitor(
+        registry, ExceptionHandlingDelegatingAstVisitor.logException));
+
+    for (FixLintTask fix in lintTasks) {
+      await fix.applyLocalFixes(result);
+    }
+  }
+
+  void registerLintTask(LintRule lint, FixLintTask task) {
+    linters.add(lint);
+    lintTasks.add(task);
+    lint.reporter = task;
+  }
+}
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 14bad20..c80cf39 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
@@ -1,82 +1,59 @@
-import 'package:analysis_server/src/edit/edit_dartfix.dart';
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
-class NonNullableFix {
-  final EditDartFix dartFix;
+/// [NonNullableFix] visits each named type in a resolved compilation unit
+/// and determines whether the associated variable or parameter can be null
+/// then adds or removes a '?' trailing the named type as appropriate.
+class NonNullableFix extends FixCodeTask2 {
+  /// TODO(paulberry): stop using permissive mode once the migration logic is
+  /// mature enough.
+  static const bool _usePermissiveMode = true;
 
-  /// The current source being "fixed"
-  Source source;
-
-  /// The source file change or `null` if none
-  SourceFileEdit fileEdit;
-
-  int firstOffset;
-  int firstLength;
-
-  NonNullableFix(this.dartFix);
-
-  void addEdit(int offset, int length, String replacementText) {
-    fileEdit ??= new SourceFileEdit(source.fullName, 0);
-    fileEdit.edits.add(new SourceEdit(offset, length, replacementText));
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerCodeTask(new NonNullableFix(listener));
   }
 
-  /// Update the source to be non-nullable by
-  /// 1) adding trailing '?' to type references of nullable variables, and
-  /// 2) removing trailing '?' from type references of non-nullable variables.
-  void applyLocalFixes(ResolvedUnitResult result) {
-    final context = result.session.analysisContext;
-    AnalysisOptionsImpl options = context.analysisOptions;
-    if (!options.experimentStatus.non_nullable) {
-      return;
-    }
+  final DartFixListener listener;
 
-    final unit = result.unit;
-    source = unit.declaredElement.source;
+  final NullabilityMigration migration;
 
-    // find and fix types
-    unit.accept(new _NonNullableTypeVisitor(this));
+  NonNullableFix(this.listener)
+      : migration = new NullabilityMigration(
+            new NullabilityMigrationAdapter(listener),
+            permissive: _usePermissiveMode);
 
-    // add source changes to the collection of fixes
-    source = null;
-    if (fileEdit != null) {
-      dartFix.addSourceFileEdit('Update non-nullable type references',
-          dartFix.locationFor(result, firstOffset, firstLength), fileEdit);
-    }
+  @override
+  Future<void> finish() async {
+    migration.finish();
+  }
+
+  @override
+  Future<void> processUnit(ResolvedUnitResult result) async {
+    migration.prepareInput(result);
+  }
+
+  @override
+  Future<void> processUnit2(ResolvedUnitResult result) async {
+    migration.processInput(result);
   }
 }
 
-class _NonNullableTypeVisitor extends RecursiveAstVisitor<void> {
-  final NonNullableFix fix;
+class NullabilityMigrationAdapter implements NullabilityMigrationListener {
+  final DartFixListener listener;
 
-  _NonNullableTypeVisitor(this.fix);
+  NullabilityMigrationAdapter(this.listener);
 
   @override
-  void visitConstructorName(ConstructorName node) {
-    // skip the type name associated with the constructor
-    node.type?.typeArguments?.accept(this);
-  }
-
-  @override
-  void visitTypeName(TypeName node) {
-    // TODO(danrubel): Replace this braindead implementation
-    // with something that determines whether or not the type should be nullable
-    // and adds or removes the trailing `?` to match.
-    if (node.question == null) {
-      final identifier = node.name;
-      if (identifier is SimpleIdentifier) {
-        if (identifier.name == 'void') {
-          return;
-        }
-      }
-      fix.addEdit(node.end, 0, '?');
-      fix.firstOffset ??= node.offset;
-      fix.firstLength ??= node.length;
-    }
-    super.visitTypeName(node);
+  void addFix(SingleNullabilityFix fix) {
+    // TODO(danrubel): Update the description based upon the [fix.kind]
+    listener.addSourceEdits(
+        fix.kind.appliedMessage, fix.location, fix.source, fix.sourceEdits);
   }
 }
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
index 871eb2b..e483d05 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
@@ -3,18 +3,28 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
-import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
 
-class PreferIntLiteralsFix extends LinterFix {
+class PreferIntLiteralsFix extends FixLintTask {
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_int_literals'],
+      new PreferIntLiteralsFix(listener),
+    );
+  }
+
   final literalsToConvert = <DoubleLiteral>[];
 
-  PreferIntLiteralsFix(EditDartFix dartFix) : super(dartFix);
+  PreferIntLiteralsFix(DartFixListener listener) : super(listener);
 
   @override
   Future<void> applyLocalFixes(ResolvedUnitResult result) async {
@@ -22,7 +32,7 @@
       DoubleLiteral literal = literalsToConvert.removeLast();
       AssistProcessor processor = new AssistProcessor(
         new DartAssistContextImpl(
-          DartChangeWorkspace(dartFix.server.currentSessions),
+          DartChangeWorkspace(listener.server.currentSessions),
           result,
           literal.offset,
           0,
@@ -31,10 +41,10 @@
       List<Assist> assists =
           await processor.computeAssist(DartAssistKind.CONVERT_TO_INT_LITERAL);
       final location =
-          dartFix.locationFor(result, literal.offset, literal.length);
+          listener.locationFor(result, literal.offset, literal.length);
       if (assists.isNotEmpty) {
         for (Assist assist in assists) {
-          dartFix.addSourceChange(
+          listener.addSourceChange(
               'Replace a double literal with an int literal',
               location,
               assist.change);
@@ -42,7 +52,7 @@
       } else {
         // TODO(danrubel): If assists is empty, then determine why
         // assist could not be performed and report that in the description.
-        dartFix.addRecommendation(
+        listener.addRecommendation(
             'Could not replace a double literal with an int literal', location);
       }
     }
@@ -57,8 +67,7 @@
   @override
   void reportErrorForNode(ErrorCode errorCode, AstNode node,
       [List<Object> arguments]) {
-    String filePath = source.fullName;
-    if (filePath != null && dartFix.isIncluded(filePath)) {
+    if (source.fullName != null) {
       literalsToConvert.add(node);
     }
   }
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
index 2972f49..2fec097 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
-import 'package:analysis_server/src/edit/edit_dartfix.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
@@ -11,11 +13,19 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
 
-class PreferMixinFix extends LinterFix {
+class PreferMixinFix extends FixLintTask {
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_mixin'],
+      new PreferMixinFix(listener),
+    );
+  }
+
   final classesToConvert = new Set<Element>();
 
-  PreferMixinFix(EditDartFix dartFix) : super(dartFix);
+  PreferMixinFix(DartFixListener listener) : super(listener);
 
   @override
   Future<void> applyLocalFixes(ResolvedUnitResult result) {
@@ -32,14 +42,14 @@
 
   Future<void> convertClassToMixin(Element elem) async {
     ResolvedUnitResult result =
-        await dartFix.server.getResolvedUnit(elem.source?.fullName);
+        await listener.server.getResolvedUnit(elem.source?.fullName);
 
     for (CompilationUnitMember declaration in result.unit.declarations) {
       if (declaration is ClassOrMixinDeclaration &&
           declaration.name.name == elem.name) {
         AssistProcessor processor = new AssistProcessor(
           new DartAssistContextImpl(
-              DartChangeWorkspace(dartFix.server.currentSessions),
+              DartChangeWorkspace(listener.server.currentSessions),
               result,
               declaration.name.offset,
               0),
@@ -47,16 +57,16 @@
         List<Assist> assists = await processor
             .computeAssist(DartAssistKind.CONVERT_CLASS_TO_MIXIN);
         final location =
-            dartFix.locationFor(result, elem.nameOffset, elem.nameLength);
+            listener.locationFor(result, elem.nameOffset, elem.nameLength);
         if (assists.isNotEmpty) {
           for (Assist assist in assists) {
-            dartFix.addSourceChange('Convert ${elem.displayName} to a mixin',
+            listener.addSourceChange('Convert ${elem.displayName} to a mixin',
                 location, assist.change);
           }
         } else {
           // TODO(danrubel): If assists is empty, then determine why
           // assist could not be performed and report that in the description.
-          dartFix.addRecommendation(
+          listener.addRecommendation(
               'Could not convert ${elem.displayName} to a mixin'
               ' because the class contains a constructor',
               location);
@@ -70,8 +80,7 @@
       [List<Object> arguments]) {
     TypeName type = node;
     Element element = type.name.staticElement;
-    String filePath = element.source?.fullName;
-    if (filePath != null && dartFix.isIncluded(filePath)) {
+    if (element.source?.fullName != null) {
       classesToConvert.add(element);
     }
   }
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
index b81c125..d412402 100644
--- a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
@@ -62,7 +62,9 @@
       onError: onError,
       onDone: () {
         close();
-        onDone();
+        if (onDone != null) {
+          onDone();
+        }
       },
     );
   }
diff --git a/pkg/analysis_server/lib/src/lsp/constants.dart b/pkg/analysis_server/lib/src/lsp/constants.dart
index 464ab95..aaf762f 100644
--- a/pkg/analysis_server/lib/src/lsp/constants.dart
+++ b/pkg/analysis_server/lib/src/lsp/constants.dart
@@ -56,3 +56,7 @@
   ///   if it crashes 5 times in the last 180 seconds."
   static const ClientServerInconsistentState = const ErrorCodes(-32010);
 }
+
+abstract class CustomMethods {
+  static const DiagnosticServer = const Method('dart/diagnosticServer');
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
index 4161f20..674201f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
@@ -33,7 +33,7 @@
     final path = arguments.single;
     final docIdentifier = server.getVersionedDocumentIdentifier(path);
 
-    final result = await requireUnit(path);
+    final result = await requireResolvedUnit(path);
     return result.mapResult((result) {
       final code = result.content;
       final unit = result.unit;
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
index 24c7b7d..64c5877 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/simple_edit_handler.dart
@@ -47,7 +47,7 @@
       return error(
         ServerErrorCodes.ClientFailedToApplyEdit,
         'Client failed to apply workspace edit for $commandName',
-        editResponse.error,
+        editResponse.error.toString(),
       );
     }
 
@@ -64,7 +64,7 @@
       return error(
         ServerErrorCodes.ClientFailedToApplyEdit,
         'Client failed to apply workspace edit for $commandName',
-        workspaceEdit,
+        workspaceEdit.toString(),
       );
     }
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.dart
new file mode 100644
index 0000000..7a3dec6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_diagnostic_server.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 'dart:async';
+
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+class DiagnosticServerHandler
+    extends MessageHandler<void, DartDiagnosticServer> {
+  DiagnosticServerHandler(LspAnalysisServer server) : super(server);
+  Method get handlesMessage => CustomMethods.DiagnosticServer;
+
+  @override
+  void convertParams(Map<String, dynamic> json) => null;
+
+  @override
+  Future<ErrorOr<DartDiagnosticServer>> handle(void _) async {
+    final port = await server.diagnosticServer.getServerPort();
+    return success(new DartDiagnosticServer(port));
+  }
+}
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 41d3014..3788e2c 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
@@ -43,7 +43,7 @@
         capabilities?.codeActionLiteralSupport?.codeActionKind?.valueSet ?? []);
 
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
 
     return unit.mapResult((unit) {
       final startOffset = toOffset(unit.lineInfo, params.range.start);
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 bc81078..1f845ef 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -60,7 +60,7 @@
 
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
     return offset.mapResult((offset) => _getItems(
           completionCapabilities,
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 c3e9246..90912c6 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -26,7 +26,7 @@
       TextDocumentPositionParams params) async {
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
index 9f6822e..cc21c40 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_highlights.dart
@@ -25,7 +25,7 @@
       TextDocumentPositionParams params) async {
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((requestedOffset) {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
index e1fda79..7810b7f 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
@@ -61,7 +61,7 @@
         symbolCapabilities?.hierarchicalDocumentSymbolSupport ?? false;
 
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     return unit.mapResult((unit) => _getSymbols(clientSupportedSymbolKinds,
         clientSupportsDocumentSymbol, path.result, unit));
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
index f2b3579..4f3f320 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
@@ -18,6 +18,10 @@
 
   @override
   Future<ErrorOr<void>> handle(void _) async {
+    // TODO(dantup): Spec says we should exit with a code of 1 if we had not
+    // received a shutdown request prior to exit.
+    // TODO(dantup): Probably we should add a new state for "shutting down"
+    // that refuses any more requests between shutdown and exit.
     await server.shutdown();
     return success();
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.dart
new file mode 100644
index 0000000..96e1a4a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_folding.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:async';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/computer/computer_folding.dart';
+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';
+
+class FoldingHandler
+    extends MessageHandler<FoldingRangeParams, List<FoldingRange>> {
+  FoldingHandler(LspAnalysisServer server) : super(server);
+  Method get handlesMessage => Method.textDocument_foldingRange;
+
+  @override
+  FoldingRangeParams convertParams(Map<String, dynamic> json) =>
+      FoldingRangeParams.fromJson(json);
+
+  Future<ErrorOr<List<FoldingRange>>> handle(FoldingRangeParams params) async {
+    final path = pathOfDoc(params.textDocument);
+    final unit = await path.mapResult(requireUnresolvedUnit);
+
+    return unit.mapResult((unit) {
+      final lineInfo = unit.lineInfo;
+      final regions =
+          new DartUnitFoldingComputer(lineInfo, unit.unit).compute();
+
+      return success(
+        regions.map((region) => toFoldingRange(lineInfo, region)).toList(),
+      );
+    });
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
index 6fb1c2f..37d6a9d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
@@ -6,11 +6,11 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/lsp/source_edits.dart';
-import 'package:analyzer/dart/analysis/results.dart';
 
 class FormatOnTypeHandler
     extends MessageHandler<DocumentOnTypeFormattingParams, List<TextEdit>> {
@@ -21,17 +21,19 @@
   DocumentOnTypeFormattingParams convertParams(Map<String, dynamic> json) =>
       DocumentOnTypeFormattingParams.fromJson(json);
 
-  ErrorOr<List<TextEdit>> formatFile(String path, ResolvedUnitResult unit) {
-    final unformattedSource =
-        server.resourceProvider.getFile(path).readAsStringSync();
+  ErrorOr<List<TextEdit>> formatFile(String path) {
+    final file = server.resourceProvider.getFile(path);
+    if (!file.exists) {
+      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+    }
 
+    final unformattedSource = file.readAsStringSync();
     return success(generateEditsForFormatting(unformattedSource));
   }
 
   Future<ErrorOr<List<TextEdit>>> handle(
       DocumentOnTypeFormattingParams params) async {
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
-    return unit.mapResult((unit) => formatFile(path.result, unit));
+    return path.mapResult((path) => formatFile(path));
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
index e226bc4..b4e0b60 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -6,11 +6,11 @@
 
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/lsp/source_edits.dart';
-import 'package:analyzer/dart/analysis/results.dart';
 
 class FormattingHandler
     extends MessageHandler<DocumentFormattingParams, List<TextEdit>> {
@@ -21,17 +21,19 @@
   DocumentFormattingParams convertParams(Map<String, dynamic> json) =>
       DocumentFormattingParams.fromJson(json);
 
-  ErrorOr<List<TextEdit>> formatFile(String path, ResolvedUnitResult unit) {
-    final unformattedSource =
-        server.resourceProvider.getFile(path).readAsStringSync();
+  ErrorOr<List<TextEdit>> formatFile(String path) {
+    final file = server.resourceProvider.getFile(path);
+    if (!file.exists) {
+      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+    }
 
+    final unformattedSource = file.readAsStringSync();
     return success(generateEditsForFormatting(unformattedSource));
   }
 
   Future<ErrorOr<List<TextEdit>>> handle(
       DocumentFormattingParams params) async {
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
-    return unit.mapResult((unit) => formatFile(path.result, unit));
+    return path.mapResult((path) => formatFile(path));
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
index a5396e5..d9302ae 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
@@ -26,7 +26,7 @@
   Future<ErrorOr<Hover>> handle(TextDocumentPositionParams params) async {
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
     return offset.mapResult((offset) => _getHover(unit.result, offset));
   }
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 e1a72f6..a67c282 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -29,11 +29,11 @@
     }
     if (params.rootUri != null) {
       openWorkspacePaths.add(Uri.parse(params.rootUri).toFilePath());
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
     } else if (params.rootPath != null) {
       // This is deprecated according to LSP spec, but we still want to support
       // it in case older clients send us it.
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       openWorkspacePaths.add(params.rootPath);
     }
 
@@ -60,10 +60,25 @@
           false,
           // Set the characters that will cause the editor to automatically
           // trigger completion.
-          // TODO(dantup): This is quite eager and may need filtering in the
-          // completion handler.
-          // See https://github.com/Dart-Code/Dart-Code/blob/c616c93c87972713454eb0518f97c0278201a99a/src/providers/dart_completion_item_provider.ts#L36
-          r'''.: =(${'"/\'''.split(''),
+          // TODO(dantup): There are several characters that we want to conditionally
+          // allow to trigger completion, but they can only be added when the completion
+          // provider is able to handle them in context:
+          //
+          //    {   trigger if being typed in a string immediately after a $
+          //    '   trigger if the opening quote for an import/export
+          //    "   trigger if the opening quote for an import/export
+          //    /   trigger if as part of a path in an import/export
+          //    \   trigger if as part of a path in an import/export
+          //    :   don't trigger when typing case expressions (`case x:`)
+          //
+          // Additionally, we need to prefix `filterText` on completion items
+          // with spaces for those that can follow whitespace (eg. `foo` in
+          // `myArg: foo`) to ensure they're not filtered away when the user
+          // types space.
+          //
+          // See https://github.com/Dart-Code/Dart-Code/blob/68d1cd271e88a785570257d487adbdec17abd6a3/src/providers/dart_completion_item_provider.ts#L36-L64
+          // for the VS Code implementation of this.
+          r'''.=($'''.split(''),
         ),
         new SignatureHelpOptions(
           // TODO(dantup): Signature help triggering is even more sensitive to
@@ -77,7 +92,7 @@
         true, // referencesProvider
         true, // documentHighlightProvider
         true, // documentSymbolProvider
-        null,
+        true, // workspaceSymbolProvider
         // "The `CodeActionOptions` return type is only valid if the client
         // signals code action literal support via the property
         // `textDocument.codeAction.codeActionLiteralSupport`."
@@ -94,7 +109,7 @@
             : Either2<bool, RenameOptions>.t1(true),
         null,
         null,
-        null,
+        Either3<bool, FoldingRangeProviderOptions, dynamic>.t1(true),
         new ExecuteCommandOptions(Commands.serverSupportedCommands),
         new ServerCapabilitiesWorkspace(
             new ServerCapabilitiesWorkspaceFolders(true, true)),
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 f6f803f..5f3fe45 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -31,7 +31,7 @@
   Future<ErrorOr<List<Location>>> handle(ReferenceParams params) async {
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
     return offset.mapResult(
         (offset) => _getRefererences(path.result, offset, params, unit.result));
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
index 3a9075e..5433077 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_rename.dart
@@ -24,7 +24,7 @@
       TextDocumentPositionParams params) async {
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) async {
@@ -84,7 +84,7 @@
         params.textDocument is VersionedTextDocumentIdentifier
             ? params.textDocument
             : server.getVersionedDocumentIdentifier(path)));
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) async {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
index 2fe40ef..3f3e195 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
@@ -24,7 +24,7 @@
       TextDocumentPositionParams params) async {
     final pos = params.position;
     final path = pathOfDoc(params.textDocument);
-    final unit = await path.mapResult(requireUnit);
+    final unit = await path.mapResult(requireResolvedUnit);
     final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
 
     return offset.mapResult((offset) {
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index 9375b8b..7594631 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -7,12 +7,14 @@
 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/custom/handler_diagnostic_server.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_code_actions.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_completion.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_definition.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_document_highlights.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_document_symbols.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_execute_command.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_folding.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_formatting.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_hover.dart';
@@ -23,6 +25,7 @@
 import 'package:analysis_server/src/lsp/handlers/handler_signature_help.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_text_document_changes.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_change_workspace_folders.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_workspace_symbols.dart';
 import 'package:analysis_server/src/lsp/handlers/handlers.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
 
@@ -64,6 +67,9 @@
     registerHandler(new WorkspaceFoldersHandler(server));
     registerHandler(new PrepareRenameHandler(server));
     registerHandler(new RenameHandler(server));
+    registerHandler(new FoldingHandler(server));
+    registerHandler(new DiagnosticServerHandler(server));
+    registerHandler(new WorkspaceSymbolHandler(server));
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
new file mode 100644
index 0000000..3d41c0e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_workspace_symbols.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:collection';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_document_symbols.dart'
+    show defaultSupportedSymbolKinds;
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/src/dart/analysis/search.dart' as search;
+
+class WorkspaceSymbolHandler
+    extends MessageHandler<WorkspaceSymbolParams, List<SymbolInformation>> {
+  WorkspaceSymbolHandler(LspAnalysisServer server) : super(server);
+  Method get handlesMessage => Method.workspace_symbol;
+
+  @override
+  WorkspaceSymbolParams convertParams(Map<String, dynamic> json) =>
+      WorkspaceSymbolParams.fromJson(json);
+
+  Future<ErrorOr<List<SymbolInformation>>> handle(
+      WorkspaceSymbolParams params) async {
+    // Respond to empty queries with an empty list. The spec says this should
+    // be non-empty, however VS Code's client sends empty requests (but then
+    // appears to not render the results we supply anyway).
+    final query = params?.query ?? '';
+    if (query == '') {
+      return success([]);
+    }
+
+    final symbolCapabilities = server?.clientCapabilities?.workspace?.symbol;
+
+    final clientSupportedSymbolKinds =
+        symbolCapabilities?.symbolKind?.valueSet != null
+            ? new HashSet<SymbolKind>.of(symbolCapabilities.symbolKind.valueSet)
+            : defaultSupportedSymbolKinds;
+
+    // Convert the string input into a case-insensitive regex that has wildcards
+    // between every character and at start/end to allow for fuzzy matching.
+    final fuzzyQuery = query.split('').map(RegExp.escape).join('.*');
+    final partialFuzzyQuery = '.*$fuzzyQuery.*';
+    final regex = new RegExp(partialFuzzyQuery, caseSensitive: false);
+
+    // Cap the number of results we'll return because short queries may match
+    // huge numbers on large projects.
+    var remainingResults = 500;
+
+    final declarations = <search.Declaration>[];
+    final filePathsHashSet = new LinkedHashSet<String>();
+    for (var driver in server.driverMap.values) {
+      final driverResults = await driver.search
+          .declarations(regex, remainingResults, filePathsHashSet);
+      declarations.addAll(driverResults);
+      remainingResults -= driverResults.length;
+    }
+
+    // Convert the file paths to something we can quickly index into since
+    // we'll be looking things up by index a lot.
+    final filePaths = filePathsHashSet.toList();
+
+    // Map the results to SymbolInformations and flatten the list of lists.
+    final symbols = declarations
+        .map((declaration) => _asSymbolInformation(
+              declaration,
+              clientSupportedSymbolKinds,
+              filePaths,
+            ))
+        .toList();
+
+    return success(symbols);
+  }
+
+  SymbolInformation _asSymbolInformation(
+    search.Declaration declaration,
+    HashSet<SymbolKind> clientSupportedSymbolKinds,
+    List<String> filePaths,
+  ) {
+    final filePath = filePaths[declaration.fileIndex];
+
+    final kind = declarationKindToSymbolKind(
+      clientSupportedSymbolKinds,
+      declaration.kind,
+    );
+    final range = toRange(
+      declaration.lineInfo,
+      declaration.codeOffset,
+      declaration.codeLength,
+    );
+    final location = new Location(
+      Uri.file(filePath).toString(),
+      range,
+    );
+
+    return new SymbolInformation(
+        declaration.name,
+        kind,
+        null, // We don't have easy access to isDeprecated here.
+        location,
+        declaration.className ?? declaration.mixinName);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 9fd98d8..78684ec 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -32,13 +32,13 @@
 mixin Handler<P, R> {
   LspAnalysisServer server;
 
-  ErrorOr<R> error<R>(ErrorCodes code, String message, Object data) =>
+  ErrorOr<R> error<R>(ErrorCodes code, String message, String data) =>
       new ErrorOr<R>.error(new ResponseError(code, message, data));
 
   ErrorOr<R> failure<R>(ErrorOr<dynamic> error) =>
       new ErrorOr<R>.error(error.error);
 
-  Future<ErrorOr<ResolvedUnitResult>> requireUnit(String path) async {
+  Future<ErrorOr<ResolvedUnitResult>> requireResolvedUnit(String path) async {
     final result = await server.getResolvedUnit(path);
     if (result?.state != ResultState.VALID) {
       return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
@@ -46,6 +46,14 @@
     return success(result);
   }
 
+  ErrorOr<ParsedUnitResult> requireUnresolvedUnit(String path) {
+    final result = server.getParsedUnit(path);
+    if (result?.state != ResultState.VALID) {
+      return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+    }
+    return success(result);
+  }
+
   ErrorOr<R> success<R>([R t]) => new ErrorOr<R>.success(t);
 }
 
@@ -85,7 +93,7 @@
   }
 
   ErrorOr<Object> failure<Object>(ErrorCodes code, String message,
-          [Object data]) =>
+          [String data]) =>
       new ErrorOr<Object>.error(new ResponseError(code, message, data));
 
   /// Handle the given [message]. If the [message] is a [RequestMessage], then the
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 925e5a7..5f99c59 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -22,6 +22,7 @@
 import 'package:analysis_server/src/lsp/mapping.dart';
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+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';
@@ -141,8 +142,9 @@
     AnalysisServerOptions options,
     this.sdkManager,
     this.instrumentationService, {
+    DiagnosticServer diagnosticServer,
     ResolverProvider packageResolverProvider: null,
-  }) : super(options, baseResourceProvider) {
+  }) : super(options, diagnosticServer, baseResourceProvider) {
     messageHandler = new UninitializedStateMessageHandler(this);
     defaultContextOptions.generateImplicitErrors = false;
     defaultContextOptions.useFastaParser = options.useFastaParser;
@@ -299,16 +301,14 @@
                 errorMessage,
                 null,
               ));
-          logError(error.toString());
-          if (stackTrace != null) {
-            logError(stackTrace.toString());
-          }
+          logException(errorMessage, error, stackTrace);
         }
       });
     }, onError: error);
   }
 
-  void logError(String message) {
+  /// Logs the error on the client using window/logMessage.
+  void logErrorToClient(String message) {
     channel.sendNotification(new NotificationMessage(
       Method.window_logMessage,
       new LogMessageParams(MessageType.Error, message),
@@ -341,7 +341,7 @@
           new ResponseMessage(message.id, null, error, jsonRpcVersion));
       // Since the LSP client might not show the failed requests to the user,
       // also ensure the error is logged to the client.
-      logError(error.message);
+      logErrorToClient(error.message);
     } else if (message is ResponseMessage) {
       // For bad response messages where we can't respond with an error, send it as
       // show instead of log.
@@ -359,7 +359,7 @@
       messageHandler = new FailureStateMessageHandler(this);
 
       final message = 'An unrecoverable error occurred.';
-      logError(
+      logErrorToClient(
           '$message\n\n${error.message}\n\n${error.code}\n\n${error.data}');
 
       shutdown();
@@ -399,24 +399,28 @@
   }
 
   void sendServerErrorNotification(String message, exception, stackTrace) {
-    final fullError = new StringBuffer();
-
-    fullError.writeln(exception == null ? message : '$message: $exception');
+    message = exception == null ? message : '$message: $exception';
 
     // Show message (without stack) to the user.
-    showError(fullError.toString());
+    showError(message);
 
-    if (stackTrace != null) {
-      fullError.writeln(stackTrace.toString());
-    }
-    // Log the full message since showMessage above may be truncated or formatted
-    // badly (eg. VS Code takes the newlines out).
-    logError(fullError.toString());
+    logException(message, exception, stackTrace);
+  }
 
-    // remember the last few exceptions
+  /// Logs an exception by sending it to the client (window/logMessage) and
+  /// recording it in a buffer on the server for diagnostics.
+  void logException(String message, exception, stackTrace) {
     if (exception is CaughtException) {
       stackTrace ??= exception.stackTrace;
     }
+
+    final fullError = stackTrace == null ? message : '$message\n$stackTrace';
+
+    // Log the full message since showMessage above may be truncated or formatted
+    // badly (eg. VS Code takes the newlines out).
+    logErrorToClient(fullError);
+
+    // remember the last few exceptions
     exceptions.add(new ServerException(
       message,
       exception,
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
index 25a15e1..aee1dca 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
@@ -8,6 +8,7 @@
 import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
 import 'package:analysis_server/src/lsp/constants.dart';
 import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/server/diagnostic_server.dart';
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -31,11 +32,12 @@
    * The function used to create a new SDK using the default SDK.
    */
   final DartSdkManager sdkManager;
-
+  final DiagnosticServer diagnosticServer;
   final InstrumentationService instrumentationService;
 
   LspSocketServer(
     this.analysisServerOptions,
+    this.diagnosticServer,
     this.sdkManager,
     this.instrumentationService,
   );
@@ -78,6 +80,7 @@
     }
 
     analysisServer = new LspAnalysisServer(serverChannel, resourceProvider,
-        analysisServerOptions, sdkManager, instrumentationService);
+        analysisServerOptions, sdkManager, instrumentationService,
+        diagnosticServer: diagnosticServer);
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index d69d15d..2f9dd65 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -15,6 +15,8 @@
 import 'package:analyzer/dart/analysis/results.dart' as server;
 import 'package:analyzer/error/error.dart' as server;
 import 'package:analyzer/source/line_info.dart' as server;
+import 'package:analyzer/src/dart/analysis/search.dart' as server
+    show DeclarationKind;
 import 'package:analyzer/src/generated/source.dart' as server;
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart' as server;
 
@@ -47,6 +49,48 @@
           .toList());
 }
 
+lsp.SymbolKind declarationKindToSymbolKind(
+  HashSet<lsp.SymbolKind> clientSupportedSymbolKinds,
+  server.DeclarationKind kind,
+) {
+  bool isSupported(lsp.SymbolKind kind) =>
+      clientSupportedSymbolKinds.contains(kind);
+
+  List<lsp.SymbolKind> getKindPreferences() {
+    switch (kind) {
+      case server.DeclarationKind.CLASS:
+      case server.DeclarationKind.CLASS_TYPE_ALIAS:
+        return const [lsp.SymbolKind.Class];
+      case server.DeclarationKind.CONSTRUCTOR:
+        return const [lsp.SymbolKind.Constructor];
+      case server.DeclarationKind.ENUM:
+      case server.DeclarationKind.ENUM_CONSTANT:
+        return const [lsp.SymbolKind.Enum];
+      case server.DeclarationKind.FIELD:
+        return const [lsp.SymbolKind.Field];
+      case server.DeclarationKind.FUNCTION:
+        return const [lsp.SymbolKind.Function];
+      case server.DeclarationKind.FUNCTION_TYPE_ALIAS:
+        return const [lsp.SymbolKind.Class];
+      case server.DeclarationKind.GETTER:
+        return const [lsp.SymbolKind.Property];
+      case server.DeclarationKind.METHOD:
+        return const [lsp.SymbolKind.Method];
+      case server.DeclarationKind.MIXIN:
+        return const [lsp.SymbolKind.Class];
+      case server.DeclarationKind.SETTER:
+        return const [lsp.SymbolKind.Property];
+      case server.DeclarationKind.VARIABLE:
+        return const [lsp.SymbolKind.Variable];
+      default:
+        assert(false, 'Unexpected declaration kind $kind');
+        return null;
+    }
+  }
+
+  return getKindPreferences().firstWhere(isSupported, orElse: () => null);
+}
+
 lsp.CompletionItemKind elementKindToCompletionItemKind(
   HashSet<lsp.CompletionItemKind> clientSupportedCompletionKinds,
   server.ElementKind kind,
@@ -256,7 +300,7 @@
     return new ErrorOr<String>.error(new ResponseError(
         lsp.ServerErrorCodes.InvalidFilePath,
         'URI was not a valid file:// URI',
-        uri));
+        uri.toString()));
   }
   try {
     return new ErrorOr<String>.success(uri.toFilePath());
@@ -266,7 +310,7 @@
     return new ErrorOr<String>.error(new ResponseError(
         lsp.ServerErrorCodes.InvalidFilePath,
         'File URI did not contain a valid file path',
-        uri));
+        uri.toString()));
   }
 }
 
@@ -417,6 +461,28 @@
   }
 }
 
+lsp.FoldingRange toFoldingRange(
+    server.LineInfo lineInfo, server.FoldingRegion region) {
+  final range = toRange(lineInfo, region.offset, region.length);
+  return new lsp.FoldingRange(range.start.line, range.start.character,
+      range.end.line, range.end.character, toFoldingRangeKind(region.kind));
+}
+
+lsp.FoldingRangeKind toFoldingRangeKind(server.FoldingKind kind) {
+  switch (kind) {
+    case server.FoldingKind.DOCUMENTATION_COMMENT:
+    case server.FoldingKind.FILE_HEADER:
+      return lsp.FoldingRangeKind.Comment;
+    case server.FoldingKind.DIRECTIVES:
+      return lsp.FoldingRangeKind.Imports;
+    default:
+      // null (actually undefined in LSP, the toJson() takes care of that) is
+      // valid, and actually the value used for the majority of folds
+      // (class/functions/etc.).
+      return null;
+  }
+}
+
 List<lsp.DocumentHighlight> toHighlights(
     server.LineInfo lineInfo, server.Occurrences occurrences) {
   return occurrences.offsets
@@ -436,7 +502,7 @@
             ? lsp.ServerErrorCodes.ClientServerInconsistentState
             : lsp.ServerErrorCodes.InvalidFileLineCol,
         'Invalid line number',
-        pos.line));
+        pos.line.toString()));
   }
   // TODO(dantup): Is there any way to validate the character? We could ensure
   // it's less than the offset of the next line, but that would only work for
diff --git a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart b/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
new file mode 100644
index 0000000..4b47370
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/conditional_discard.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 'package:analysis_server/src/nullability/unit_propagation.dart';
+
+/// Container for information gathered during nullability migration about a
+/// conditional check that might need to be discarded.
+///
+/// This information will be associated with an Expression in the input program
+/// whose boolean value influences control flow (e.g. the condition of an `if`
+/// statement).
+class ConditionalDiscard {
+  /// Constraint variable whose value will be `true` if the code path that
+  /// results from the condition evaluating to `true` will be reachable after
+  /// nullability migration, and therefore should be kept.
+  final ConstraintVariable keepTrue;
+
+  /// Constraint variable whose value will be `false` if the code path that
+  /// results from the condition evaluating to `false` will be reachable after
+  /// nullability migration, and therefore should be kept.
+  final ConstraintVariable keepFalse;
+
+  /// Indicates whether the condition is pure (free from side effects).
+  ///
+  /// For example, a condition like `x == null` is pure (assuming `x` is a local
+  /// variable or static variable), because evaluating it has no user-visible
+  /// effect other than returning a boolean value.
+  ///
+  /// If [pureCondition] is `false`, and either [keepTrue] or [keepFalse] is
+  /// `false`, that it is safe to delete the condition expression as well as the
+  /// dead code branch (e.g. it means that `if (x == null) f(); else g();` could
+  /// be changed to simply `g();`).
+  final bool pureCondition;
+
+  ConditionalDiscard(this.keepTrue, this.keepFalse, this.pureCondition);
+}
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
new file mode 100644
index 0000000..ec6f294
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
@@ -0,0 +1,548 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/conditional_discard.dart';
+import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
+import 'package:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:meta/meta.dart';
+
+/// Visitor that gathers nullability migration constraints from code to be
+/// migrated.
+///
+/// The return type of each `visit...` method is a [DecoratedType] indicating
+/// the static type of the visited expression, along with the constraint
+/// variables that will determine its nullability.  For `visit...` methods that
+/// don't visit expressions, `null` will be returned.
+class ConstraintGatherer extends GeneralizingAstVisitor<DecoratedType> {
+  /// The repository of constraint variables and decorated types (from a
+  /// previous pass over the source code).
+  final VariableRepository _variables;
+
+  final bool _permissive;
+
+  final NullabilityMigrationAssumptions assumptions;
+
+  /// Constraints gathered by the visitor are stored here.
+  final Constraints _constraints;
+
+  /// The file being analyzed.
+  final Source _source;
+
+  /// For convenience, a [DecoratedType] representing non-nullable `Object`.
+  final DecoratedType _notNullType;
+
+  /// For convenience, a [DecoratedType] representing non-nullable `bool`.
+  final DecoratedType _nonNullableBoolType;
+
+  /// For convenience, a [DecoratedType] representing non-nullable `Type`.
+  final DecoratedType _nonNullableTypeType;
+
+  /// For convenience, a [DecoratedType] representing `Null`.
+  final DecoratedType _nullType;
+
+  /// The [DecoratedType] of the innermost function or method being visited, or
+  /// `null` if the visitor is not inside any function or method.
+  ///
+  /// This is needed to construct the appropriate nullability constraints for
+  /// return statements.
+  DecoratedType _currentFunctionType;
+
+  /// Information about the most recently visited binary expression whose
+  /// boolean value could possibly affect nullability analysis.
+  _ConditionInfo _conditionInfo;
+
+  /// The set of constraint variables that would have to be assigned the value
+  /// of `true` for the code currently being visited to be reachable.
+  ///
+  /// Guard variables are attached to the left hand side of any generated
+  /// constraints, so that constraints do not take effect if they come from
+  /// code that can be proven unreachable by the migration tool.
+  final _guards = <ConstraintVariable>[];
+
+  /// Indicates whether the statement or expression being visited is within
+  /// conditional control flow.  If `true`, this means that the enclosing
+  /// function might complete normally without executing the current statement
+  /// or expression.
+  bool _inConditionalControlFlow = false;
+
+  ConstraintGatherer(TypeProvider typeProvider, this._variables,
+      this._constraints, this._source, this._permissive, this.assumptions)
+      : _notNullType = DecoratedType(typeProvider.objectType, null),
+        _nonNullableBoolType = DecoratedType(typeProvider.boolType, null),
+        _nonNullableTypeType = DecoratedType(typeProvider.typeType, null),
+        _nullType =
+            DecoratedType(typeProvider.nullType, ConstraintVariable.always);
+
+  /// Gets the decorated type of [element] from [_variables], performing any
+  /// necessary substitutions.
+  DecoratedType getOrComputeElementType(Element element,
+      {DecoratedType targetType}) {
+    Map<TypeParameterElement, DecoratedType> substitution;
+    Element baseElement;
+    if (element is Member) {
+      assert(targetType != null);
+      baseElement = element.baseElement;
+      var targetTypeType = targetType.type;
+      if (targetTypeType is InterfaceType &&
+          baseElement is ClassMemberElement) {
+        var enclosingClass = baseElement.enclosingElement;
+        assert(targetTypeType.element == enclosingClass); // TODO(paulberry)
+        substitution = <TypeParameterElement, DecoratedType>{};
+        assert(enclosingClass.typeParameters.length ==
+            targetTypeType.typeArguments.length); // TODO(paulberry)
+        for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
+          substitution[enclosingClass.typeParameters[i]] =
+              targetType.typeArguments[i];
+        }
+      }
+    } else {
+      baseElement = element;
+    }
+    var decoratedBaseType =
+        _variables.decoratedElementType(baseElement, create: true);
+    if (substitution != null) {
+      DartType elementType;
+      if (element is MethodElement) {
+        elementType = element.type;
+      } else {
+        throw element.runtimeType; // TODO(paulberry)
+      }
+      return decoratedBaseType.substitute(
+          _constraints, substitution, elementType);
+    } else {
+      return decoratedBaseType;
+    }
+  }
+
+  @override
+  DecoratedType visitAssertStatement(AssertStatement node) {
+    _handleAssignment(_notNullType, node.condition);
+    if (identical(_conditionInfo?.condition, node.condition)) {
+      if (!_inConditionalControlFlow &&
+          _conditionInfo.trueDemonstratesNonNullIntent != null) {
+        _recordFact(_conditionInfo.trueDemonstratesNonNullIntent);
+      }
+    }
+    node.message?.accept(this);
+    return null;
+  }
+
+  @override
+  DecoratedType visitBinaryExpression(BinaryExpression node) {
+    switch (node.operator.type) {
+      case TokenType.EQ_EQ:
+      case TokenType.BANG_EQ:
+        assert(node.leftOperand is! NullLiteral); // TODO(paulberry)
+        var leftType = node.leftOperand.accept(this);
+        node.rightOperand.accept(this);
+        if (node.rightOperand is NullLiteral) {
+          // TODO(paulberry): figure out what the rules for isPure should be.
+          // TODO(paulberry): only set falseChecksNonNull in unconditional
+          // control flow
+          bool isPure = node.leftOperand is SimpleIdentifier;
+          var conditionInfo = _ConditionInfo(node,
+              isPure: isPure,
+              trueGuard: leftType.nullable,
+              falseDemonstratesNonNullIntent: leftType.nonNullIntent);
+          _conditionInfo = node.operator.type == TokenType.EQ_EQ
+              ? conditionInfo
+              : conditionInfo.not(node);
+        }
+        return _nonNullableBoolType;
+      case TokenType.PLUS:
+        _handleAssignment(_notNullType, node.leftOperand);
+        var callee = node.staticElement;
+        assert(!(callee is ClassMemberElement &&
+            callee.enclosingElement.typeParameters
+                .isNotEmpty)); // TODO(paulberry)
+        assert(callee != null); // TODO(paulberry)
+        var calleeType = getOrComputeElementType(callee);
+        // TODO(paulberry): substitute if necessary
+        assert(calleeType.positionalParameters.length > 0); // TODO(paulberry)
+        _handleAssignment(
+            calleeType.positionalParameters[0], node.rightOperand);
+        return calleeType.returnType;
+      default:
+        assert(false); // TODO(paulberry)
+        return null;
+    }
+  }
+
+  @override
+  DecoratedType visitClassDeclaration(ClassDeclaration node) {
+    node.members.accept(this);
+    return null;
+  }
+
+  @override
+  DecoratedType visitConditionalExpression(ConditionalExpression node) {
+    _handleAssignment(_notNullType, node.condition);
+    // TODO(paulberry): guard anything inside the true and false branches
+    var thenType = node.thenExpression.accept(this);
+    assert(_isSimple(thenType)); // TODO(paulberry)
+    var elseType = node.elseExpression.accept(this);
+    assert(_isSimple(elseType)); // TODO(paulberry)
+    var overallType = DecoratedType(node.staticType,
+        _joinNullabilities(node, thenType.nullable, elseType.nullable));
+    _variables.recordDecoratedExpressionType(node, overallType);
+    return overallType;
+  }
+
+  @override
+  DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
+    var defaultValue = node.defaultValue;
+    if (defaultValue == null) {
+      if (node.declaredElement.hasRequired) {
+        // Nothing to do; the implicit default value of `null` will never be
+        // reached.
+      } else if (node.declaredElement.isOptionalPositional ||
+          assumptions.namedNoDefaultParameterHeuristic ==
+              NamedNoDefaultParameterHeuristic.assumeNullable) {
+        _recordFact(getOrComputeElementType(node.declaredElement).nullable);
+      } else {
+        assert(assumptions.namedNoDefaultParameterHeuristic ==
+            NamedNoDefaultParameterHeuristic.assumeRequired);
+      }
+    } else {
+      _handleAssignment(
+          getOrComputeElementType(node.declaredElement), defaultValue);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _handleAssignment(_currentFunctionType.returnType, node.expression);
+    return null;
+  }
+
+  @override
+  DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
+    node.functionExpression.parameters.accept(this);
+    assert(_currentFunctionType == null);
+    _currentFunctionType =
+        _variables.decoratedElementType(node.declaredElement);
+    node.functionExpression.body.accept(this);
+    _currentFunctionType = null;
+    return null;
+  }
+
+  @override
+  DecoratedType visitIfStatement(IfStatement node) {
+    // TODO(paulberry): should the use of a boolean in an if-statement be
+    // treated like an implicit `assert(b != null)`?  Probably.
+    _handleAssignment(_notNullType, node.condition);
+    _inConditionalControlFlow = true;
+    ConstraintVariable trueGuard;
+    ConstraintVariable falseGuard;
+    if (identical(_conditionInfo?.condition, node.condition)) {
+      trueGuard = _conditionInfo.trueGuard;
+      falseGuard = _conditionInfo.falseGuard;
+      _variables.recordConditionalDiscard(
+          _source,
+          node,
+          ConditionalDiscard(trueGuard ?? ConstraintVariable.always,
+              falseGuard ?? ConstraintVariable.always, _conditionInfo.isPure));
+    }
+    if (trueGuard != null) {
+      _guards.add(trueGuard);
+    }
+    node.thenStatement.accept(this);
+    if (trueGuard != null) {
+      _guards.removeLast();
+    }
+    if (falseGuard != null) {
+      _guards.add(falseGuard);
+    }
+    node.elseStatement?.accept(this);
+    if (falseGuard != null) {
+      _guards.removeLast();
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitIntegerLiteral(IntegerLiteral node) {
+    return DecoratedType(node.staticType, null);
+  }
+
+  @override
+  DecoratedType visitMethodDeclaration(MethodDeclaration node) {
+    node.parameters.accept(this);
+    assert(_currentFunctionType == null);
+    _currentFunctionType =
+        _variables.decoratedElementType(node.declaredElement);
+    node.body.accept(this);
+    _currentFunctionType = null;
+    return null;
+  }
+
+  @override
+  DecoratedType visitMethodInvocation(MethodInvocation node) {
+    DecoratedType targetType;
+    if (node.target != null) {
+      assert(node.operator.type == TokenType.PERIOD);
+      _checkNonObjectMember(node.methodName.name); // TODO(paulberry)
+      targetType = _handleAssignment(_notNullType, node.target);
+    }
+    var callee = node.methodName.staticElement;
+    assert(callee != null); // TODO(paulberry)
+    var calleeType = getOrComputeElementType(callee, targetType: targetType);
+    // TODO(paulberry): substitute if necessary
+    var arguments = node.argumentList.arguments;
+    int i = 0;
+    var suppliedNamedParameters = Set<String>();
+    for (var expression in arguments) {
+      if (expression is NamedExpression) {
+        var name = expression.name.label.name;
+        var parameterType = calleeType.namedParameters[name];
+        assert(parameterType != null); // TODO(paulberry)
+        _handleAssignment(parameterType, expression.expression);
+        suppliedNamedParameters.add(name);
+      } else {
+        assert(calleeType.positionalParameters.length > i); // TODO(paulberry)
+        _handleAssignment(calleeType.positionalParameters[i++], expression);
+      }
+    }
+    // Any parameters not supplied must be optional.
+    for (var entry in calleeType.namedParameterOptionalVariables.entries) {
+      assert(entry.value != null);
+      if (suppliedNamedParameters.contains(entry.key)) continue;
+      _recordFact(entry.value);
+    }
+    return calleeType.returnType;
+  }
+
+  @override
+  DecoratedType visitNode(AstNode node) {
+    if (_permissive) {
+      try {
+        return super.visitNode(node);
+      } catch (_) {
+        return null;
+      }
+    } else {
+      return super.visitNode(node);
+    }
+  }
+
+  @override
+  DecoratedType visitNullLiteral(NullLiteral node) {
+    return _nullType;
+  }
+
+  @override
+  DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
+    return node.expression.accept(this);
+  }
+
+  @override
+  DecoratedType visitReturnStatement(ReturnStatement node) {
+    if (node.expression == null) {
+      _checkAssignment(_currentFunctionType.returnType, _nullType, null);
+    } else {
+      _handleAssignment(_currentFunctionType.returnType, node.expression);
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
+    var staticElement = node.staticElement;
+    if (staticElement is ParameterElement) {
+      return getOrComputeElementType(staticElement);
+    } else if (staticElement is ClassElement) {
+      return _nonNullableTypeType;
+    } else {
+      // TODO(paulberry)
+      throw new UnimplementedError('${staticElement.runtimeType}');
+    }
+  }
+
+  @override
+  DecoratedType visitStringLiteral(StringLiteral node) {
+    return DecoratedType(node.staticType, null);
+  }
+
+  @override
+  DecoratedType visitThisExpression(ThisExpression node) {
+    return DecoratedType(node.staticType, null);
+  }
+
+  @override
+  DecoratedType visitThrowExpression(ThrowExpression node) {
+    node.expression.accept(this);
+    // TODO(paulberry): do we need to check the expression type?  I think not.
+    return DecoratedType(node.staticType, null);
+  }
+
+  @override
+  DecoratedType visitTypeName(TypeName typeName) {
+    return DecoratedType(typeName.type, null);
+  }
+
+  /// Creates the necessary constraint(s) for an assignment from [sourceType] to
+  /// [destinationType].  [expression] is the expression whose type is
+  /// [sourceType]; it is the expression we will have to null-check in the case
+  /// where a nullable source is assigned to a non-nullable destination.
+  void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType,
+      Expression expression) {
+    if (sourceType.nullable != null) {
+      if (destinationType.nullable != null) {
+        _recordConstraint(sourceType.nullable, destinationType.nullable);
+      } else {
+        assert(expression != null); // TODO(paulberry)
+        var checkNotNull = CheckExpression(expression);
+        _recordConstraint(sourceType.nullable, checkNotNull);
+        _variables.recordExpressionChecks(
+            expression, ExpressionChecks(_source, checkNotNull));
+      }
+    }
+    // TODO(paulberry): it's a cheat to pass in expression=null for the
+    // recursive checks.  Really we want to unify all the checks in a single
+    // ExpressionChecks object.
+    expression = null;
+    // TODO(paulberry): generalize this.
+    if ((_isSimple(sourceType) || destinationType.type.isObject) &&
+        _isSimple(destinationType)) {
+      // Ok; nothing further to do.
+    } else if (sourceType.type is InterfaceType &&
+        destinationType.type is InterfaceType &&
+        sourceType.type.element == destinationType.type.element) {
+      assert(sourceType.typeArguments.length ==
+          destinationType.typeArguments.length);
+      for (int i = 0; i < sourceType.typeArguments.length; i++) {
+        _checkAssignment(destinationType.typeArguments[i],
+            sourceType.typeArguments[i], expression);
+      }
+    } else if (destinationType.type.isDynamic || sourceType.type.isDynamic) {
+      // ok; nothing further to do.
+    } else {
+      throw '$destinationType <= $sourceType'; // TODO(paulberry)
+    }
+  }
+
+  /// Double checks that [name] is not the name of a method or getter declared
+  /// on [Object].
+  ///
+  /// TODO(paulberry): get rid of this method and put the correct logic into the
+  /// call sites.
+  void _checkNonObjectMember(String name) {
+    assert(name != 'toString');
+    assert(name != 'hashCode');
+    assert(name != 'noSuchMethod');
+    assert(name != 'runtimeType');
+  }
+
+  /// Creates the necessary constraint(s) for an assignment of the given
+  /// [expression] to a destination whose type is [destinationType].
+  DecoratedType _handleAssignment(
+      DecoratedType destinationType, Expression expression) {
+    var sourceType = expression.accept(this);
+    _checkAssignment(destinationType, sourceType, expression);
+    return sourceType;
+  }
+
+  /// Double checks that [type] is sufficiently simple for this naive prototype
+  /// implementation.
+  ///
+  /// TODO(paulberry): get rid of this method and put the correct logic into the
+  /// call sites.
+  bool _isSimple(DecoratedType type) {
+    if (type.type.isBottom) return true;
+    if (type.type.isVoid) return true;
+    if (type.type is! InterfaceType) return false;
+    if ((type.type as InterfaceType).typeParameters.isNotEmpty) return false;
+    return true;
+  }
+
+  /// Creates a constraint variable (if necessary) representing the nullability
+  /// of [node], which is the disjunction of the nullabilities [a] and [b].
+  ConstraintVariable _joinNullabilities(
+      ConditionalExpression node, ConstraintVariable a, ConstraintVariable b) {
+    if (a == null) return b;
+    if (b == null) return a;
+    if (identical(a, ConstraintVariable.always) ||
+        identical(b, ConstraintVariable.always)) {
+      return ConstraintVariable.always;
+    }
+    var result = TypeIsNullable(node.offset);
+    _recordConstraint(a, result);
+    _recordConstraint(b, result);
+    _recordConstraint(result, ConstraintVariable.or(_constraints, a, b));
+    return result;
+  }
+
+  /// Records a constraint having [condition] as its left hand side and
+  /// [consequence] as its right hand side.  Any [_guards] are included in the
+  /// left hand side.
+  void _recordConstraint(
+      ConstraintVariable condition, ConstraintVariable consequence) {
+    _guards.add(condition);
+    _recordFact(consequence);
+    _guards.removeLast();
+  }
+
+  /// Records a constraint having [consequence] as its right hand side.  Any
+  /// [_guards] are used as the right hand side.
+  void _recordFact(ConstraintVariable consequence) {
+    _constraints.record(_guards, consequence);
+  }
+}
+
+/// Information about a binary expression whose boolean value could possibly
+/// affect nullability analysis.
+class _ConditionInfo {
+  /// The [expression] of interest.
+  final Expression condition;
+
+  /// Indicates whether [condition] is pure (free from side effects).
+  ///
+  /// For example, a condition like `x == null` is pure (assuming `x` is a local
+  /// variable or static variable), because evaluating it has no user-visible
+  /// effect other than returning a boolean value.
+  final bool isPure;
+
+  /// If not `null`, the [ConstraintVariable] whose value must be `true` in
+  /// order for [condition] to evaluate to `true`.
+  final ConstraintVariable trueGuard;
+
+  /// If not `null`, the [ConstraintVariable] whose value must be `true` in
+  /// order for [condition] to evaluate to `false`.
+  final ConstraintVariable falseGuard;
+
+  /// If not `null`, the [ConstraintVariable] whose value should be set to
+  /// `true` if [condition] is asserted to be `true`.
+  final ConstraintVariable trueDemonstratesNonNullIntent;
+
+  /// If not `null`, the [ConstraintVariable] whose value should be set to
+  /// `true` if [condition] is asserted to be `false`.
+  final ConstraintVariable falseDemonstratesNonNullIntent;
+
+  _ConditionInfo(this.condition,
+      {@required this.isPure,
+      this.trueGuard,
+      this.falseGuard,
+      this.trueDemonstratesNonNullIntent,
+      this.falseDemonstratesNonNullIntent});
+
+  /// Returns a new [_ConditionInfo] describing the boolean "not" of `this`.
+  _ConditionInfo not(Expression condition) => _ConditionInfo(condition,
+      isPure: isPure,
+      trueGuard: falseGuard,
+      falseGuard: trueGuard,
+      trueDemonstratesNonNullIntent: falseDemonstratesNonNullIntent,
+      falseDemonstratesNonNullIntent: trueDemonstratesNonNullIntent);
+}
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
new file mode 100644
index 0000000..d3a89538
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
@@ -0,0 +1,233 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/conditional_discard.dart';
+import 'package:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/// Visitor that gathers constraint variables for nullability migration from
+/// code to be migrated.
+///
+/// The return type of each `visit...` method is a [DecoratedType] indicating
+/// the static type of the element declared by the visited node, along with the
+/// constraint variables that will determine its nullability.  For `visit...`
+/// methods that don't visit declarations, `null` will be returned.
+class ConstraintVariableGatherer extends GeneralizingAstVisitor<DecoratedType> {
+  /// Constraint variables and decorated types are stored here.
+  final VariableRecorder _variables;
+
+  /// The file being analyzed.
+  final Source _source;
+
+  /// If the parameters of a function or method are being visited, the
+  /// [DecoratedType] of the corresponding function or method type.
+  ///
+  /// TODO(paulberry): should this be updated when we visit generic function
+  /// type syntax?  How about when we visit old-style function-typed formal
+  /// parameters?
+  DecoratedType _currentFunctionType;
+
+  final bool _permissive;
+
+  final NullabilityMigrationAssumptions assumptions;
+
+  ConstraintVariableGatherer(
+      this._variables, this._source, this._permissive, this.assumptions);
+
+  /// Creates and stores a [DecoratedType] object corresponding to the given
+  /// [type] AST, and returns it.
+  DecoratedType decorateType(TypeAnnotation type) {
+    return type == null
+        // TODO(danrubel): Return something other than this
+        // to indicate that we should insert a type for the declaration
+        // that is missing a type reference.
+        ? new DecoratedType(DynamicTypeImpl.instance, ConstraintVariable.always)
+        : type.accept(this);
+  }
+
+  @override
+  DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
+    var decoratedType = node.parameter.accept(this);
+    ConstraintVariable optional;
+    if (node.declaredElement.hasRequired) {
+      optional = null;
+    } else if (node.defaultValue != null) {
+      optional = ConstraintVariable.always;
+    } else {
+      optional = decoratedType.nullable;
+      _variables.recordPossiblyOptional(_source, node, optional);
+    }
+    if (optional != null) {
+      _currentFunctionType
+              .namedParameterOptionalVariables[node.declaredElement.name] =
+          optional;
+    }
+    return null;
+  }
+
+  @override
+  DecoratedType visitFormalParameter(FormalParameter node) {
+    // Do not visit children
+    // TODO(paulberry): handle all types of formal parameters
+    // - NormalFormalParameter
+    // - SimpleFormalParameter
+    // - FieldFormalParameter
+    // - FunctionTypedFormalParameter
+    // - DefaultFormalParameter
+    return null;
+  }
+
+  @override
+  DecoratedType visitFunctionDeclaration(FunctionDeclaration node) {
+    _handleExecutableDeclaration(node.declaredElement, node.returnType,
+        node.functionExpression.parameters);
+    return null;
+  }
+
+  @override
+  DecoratedType visitMethodDeclaration(MethodDeclaration node) {
+    _handleExecutableDeclaration(
+        node.declaredElement, node.returnType, node.parameters);
+    return null;
+  }
+
+  @override
+  DecoratedType visitNode(AstNode node) {
+    if (_permissive) {
+      try {
+        return super.visitNode(node);
+      } catch (_) {
+        return null;
+      }
+    } else {
+      return super.visitNode(node);
+    }
+  }
+
+  @override
+  DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
+    var type = decorateType(node.type);
+    var declaredElement = node.declaredElement;
+    assert(type.nonNullIntent == null);
+    type.nonNullIntent = NonNullIntent(node.offset);
+    _variables.recordDecoratedElementType(declaredElement, type);
+    if (declaredElement.isNamed) {
+      _currentFunctionType.namedParameters[declaredElement.name] = type;
+    } else {
+      _currentFunctionType.positionalParameters.add(type);
+    }
+    return type;
+  }
+
+  @override
+  DecoratedType visitTypeAnnotation(TypeAnnotation node) {
+    assert(node != null); // TODO(paulberry)
+    assert(node is NamedType); // TODO(paulberry)
+    var type = node.type;
+    if (type.isVoid) return DecoratedType(type, ConstraintVariable.always);
+    assert(
+        type is InterfaceType || type is TypeParameterType); // TODO(paulberry)
+    var typeArguments = const <DecoratedType>[];
+    if (type is InterfaceType && type.typeParameters.isNotEmpty) {
+      if (node is TypeName) {
+        assert(node.typeArguments != null);
+        typeArguments =
+            node.typeArguments.arguments.map((t) => t.accept(this)).toList();
+      } else {
+        assert(false); // TODO(paulberry): is this possible?
+      }
+    }
+    var nullable = node.question == null
+        ? TypeIsNullable(node.end)
+        : ConstraintVariable.always;
+    var decoratedType = DecoratedTypeAnnotation(
+        type, nullable, _source, node.end,
+        typeArguments: typeArguments);
+    _variables.recordDecoratedTypeAnnotation(node, decoratedType);
+    return decoratedType;
+  }
+
+  @override
+  DecoratedType visitTypeName(TypeName node) => visitTypeAnnotation(node);
+
+  /// Common handling of function and method declarations.
+  void _handleExecutableDeclaration(ExecutableElement declaredElement,
+      TypeAnnotation returnType, FormalParameterList parameters) {
+    var decoratedReturnType = decorateType(returnType);
+    var previousFunctionType = _currentFunctionType;
+    // TODO(paulberry): test that it's correct to use `null` for the nullability
+    // of the function type
+    var functionType = DecoratedType(declaredElement.type, null,
+        returnType: decoratedReturnType,
+        positionalParameters: [],
+        namedParameters: {},
+        namedParameterOptionalVariables: {});
+    _currentFunctionType = functionType;
+    parameters.accept(this);
+    _currentFunctionType = previousFunctionType;
+    _variables.recordDecoratedElementType(declaredElement, functionType);
+  }
+}
+
+/// Repository of constraint variables and decorated types corresponding to the
+/// code being migrated.
+///
+/// This data structure records the results of the first pass of migration
+/// ([ConstraintVariableGatherer], which finds all the variables that need to be
+/// constrained).
+abstract class VariableRecorder {
+  /// Associates decorated type information with the given [element].
+  void recordDecoratedElementType(Element element, DecoratedType type);
+
+  /// Associates decorated type information with the given [type] node.
+  void recordDecoratedTypeAnnotation(
+      TypeAnnotation node, DecoratedTypeAnnotation type);
+
+  /// Associates a constraint variable with the question of whether the given
+  /// named parameter should be optional (should not have a `required`
+  /// annotation added to it).
+  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
+      ConstraintVariable variable);
+}
+
+/// Repository of constraint variables and decorated types corresponding to the
+/// code being migrated.
+///
+/// This data structure allows the second pass of migration
+/// ([ConstraintGatherer], which builds all the constraints) to access the
+/// results of the first ([ConstraintVariableGatherer], which finds all the
+/// variables that need to be constrained).
+abstract class VariableRepository {
+  /// Retrieves the [DecoratedType] associated with the static type of the given
+  /// [element].
+  ///
+  /// If [create] is `true`, and no decorated type is found for the given
+  /// element, one is synthesized using [DecoratedType.forElement].
+  DecoratedType decoratedElementType(Element element, {bool create: false});
+
+  /// Records conditional discard information for the given AST node (which is
+  /// an `if` statement or a conditional (`?:`) expression).
+  void recordConditionalDiscard(
+      Source source, AstNode node, ConditionalDiscard conditionalDiscard);
+
+  /// Associates decorated type information with the given [element].
+  ///
+  /// TODO(paulberry): why is this in both [VariableRecorder] and
+  /// [VariableRepository]?
+  void recordDecoratedElementType(Element element, DecoratedType type);
+
+  /// Associates decorated type information with the given expression [node].
+  void recordDecoratedExpressionType(Expression node, DecoratedType type);
+
+  /// Associates a set of nullability checks with the given expression [node].
+  void recordExpressionChecks(Expression expression, ExpressionChecks checks);
+}
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
new file mode 100644
index 0000000..53c023b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+
+/// Representation of a type in the code to be migrated.  In addition to
+/// tracking the (unmigrated) [DartType], we track the [ConstraintVariable]s
+/// indicating whether the type, and the types that compose it, are nullable.
+class DecoratedType {
+  final DartType type;
+
+  /// [ConstraintVariable] whose value will be set to `true` if this type needs
+  /// to be nullable.
+  ///
+  /// If `null`, that means that an external constraint (outside the code being
+  /// migrated) forces this type to be non-nullable.
+  final ConstraintVariable nullable;
+
+  /// [ConstraintVariable] whose value will be set to `true` if the usage of
+  /// this type suggests that it is intended to be non-null (because of the
+  /// presence of a statement or expression that would unconditionally lead to
+  /// an exception being thrown in the case of a `null` value at runtime).
+  ConstraintVariable nonNullIntent;
+
+  /// If `this` is a function type, the [DecoratedType] of its return type.
+  final DecoratedType returnType;
+
+  /// If `this` is a function type, the [DecoratedType] of each of its
+  /// positional parameters (including both required and optional positional
+  /// parameters).
+  final List<DecoratedType> positionalParameters;
+
+  /// If `this` is a function type, the [DecoratedType] of each of its named
+  /// parameters.
+  final Map<String, DecoratedType> namedParameters;
+
+  /// If `this` is a function type, [ConstraintVariable] for each of its named
+  /// parameters indicating whether the given named parameter needs to be
+  /// optional (no `required` annotation).
+  ///
+  /// If there is no entry in this map corresponding to a given named parameter,
+  /// that means that it has already been decided (prior to migration) that the
+  /// given named parameter is required.  TODO(paulberry): test that this works
+  /// for already-migrated code.
+  final Map<String, ConstraintVariable> namedParameterOptionalVariables;
+
+  /// If `this` is a parameterized type, the [DecoratedType] of each of its
+  /// type parameters.
+  ///
+  /// TODO(paulberry): how should we handle generic typedefs?
+  final List<DecoratedType> typeArguments;
+
+  DecoratedType(this.type, this.nullable,
+      {this.returnType,
+      this.positionalParameters = const [],
+      this.namedParameters = const {},
+      this.namedParameterOptionalVariables = const {},
+      this.typeArguments = const []}) {
+    // The type system doesn't have a non-nullable version of `dynamic`.  So if
+    // the type is `dynamic`, verify that `nullable` is `always`.
+    assert(!type.isDynamic || identical(nullable, ConstraintVariable.always));
+  }
+
+  /// Creates a [DecoratedType] corresponding to the given [element], which is
+  /// presumed to have come from code that is already migrated.
+  factory DecoratedType.forElement(Element element) {
+    DecoratedType decorate(DartType type) {
+      assert((type as TypeImpl).nullability ==
+          Nullability.indeterminate); // TODO(paulberry)
+      if (type is FunctionType) {
+        var decoratedType = DecoratedType(type, null,
+            returnType: decorate(type.returnType), positionalParameters: []);
+        for (var parameter in type.parameters) {
+          assert(parameter.isPositional); // TODO(paulberry)
+          decoratedType.positionalParameters.add(decorate(parameter.type));
+        }
+        return decoratedType;
+      } else if (type is InterfaceType) {
+        assert(type.typeParameters.isEmpty); // TODO(paulberry)
+        return DecoratedType(type, null);
+      } else {
+        throw type.runtimeType; // TODO(paulberry)
+      }
+    }
+
+    DecoratedType decoratedType;
+    if (element is MethodElement) {
+      decoratedType = decorate(element.type);
+    } else {
+      throw element.runtimeType; // TODO(paulberry)
+    }
+    return decoratedType;
+  }
+
+  /// Apply the given [substitution] to this type.
+  ///
+  /// [undecoratedResult] is the result of the substitution, as determined by
+  /// the normal type system.
+  DecoratedType substitute(
+      Constraints constraints,
+      Map<TypeParameterElement, DecoratedType> substitution,
+      DartType undecoratedResult) {
+    if (substitution.isEmpty) return this;
+    return _substitute(constraints, substitution, undecoratedResult);
+  }
+
+  @override
+  String toString() {
+    var trailing = nullable == null ? '' : '?($nullable)';
+    var type = this.type;
+    if (type is TypeParameterType || type is VoidType) {
+      return '$type$trailing';
+    } else if (type is InterfaceType) {
+      var name = type.element.name;
+      var args = '';
+      if (type.typeArguments.isNotEmpty) {
+        args = '<${type.typeArguments.join(', ')}>';
+      }
+      return '$name$args$trailing';
+    } else if (type is FunctionType) {
+      assert(type.typeFormals.isEmpty); // TODO(paulberry)
+      assert(type.namedParameterTypes.isEmpty &&
+          namedParameters.isEmpty); // TODO(paulberry)
+      var args = positionalParameters.map((p) => p.toString()).join(', ');
+      return '$returnType Function($args)$trailing';
+    } else if (type is DynamicTypeImpl) {
+      return 'dynamic';
+    } else {
+      throw '$type'; // TODO(paulberry)
+    }
+  }
+
+  /// Internal implementation of [_substitute], used as a recursion target.
+  DecoratedType _substitute(
+      Constraints constraints,
+      Map<TypeParameterElement, DecoratedType> substitution,
+      DartType undecoratedResult) {
+    var type = this.type;
+    if (type is FunctionType && undecoratedResult is FunctionType) {
+      assert(type.typeFormals.isEmpty); // TODO(paulberry)
+      var newPositionalParameters = <DecoratedType>[];
+      for (int i = 0; i < positionalParameters.length; i++) {
+        var numRequiredParameters =
+            undecoratedResult.normalParameterTypes.length;
+        var undecoratedParameterType = i < numRequiredParameters
+            ? undecoratedResult.normalParameterTypes[i]
+            : undecoratedResult
+                .optionalParameterTypes[i - numRequiredParameters];
+        newPositionalParameters.add(positionalParameters[i]
+            ._substitute(constraints, substitution, undecoratedParameterType));
+      }
+      return DecoratedType(undecoratedResult, nullable,
+          returnType: returnType._substitute(
+              constraints, substitution, undecoratedResult.returnType),
+          positionalParameters: newPositionalParameters);
+    } else if (type is TypeParameterType) {
+      var inner = substitution[type.element];
+      return DecoratedType(undecoratedResult,
+          ConstraintVariable.or(constraints, inner?.nullable, nullable));
+    } else if (type is VoidType) {
+      return this;
+    }
+    throw '$type.substitute($substitution)'; // TODO(paulberry)
+  }
+}
+
+/// A [DecoratedType] based on a type annotation appearing explicitly in the
+/// source code.
+///
+/// This class implements [PotentialModification] because it knows how to update
+/// the source code to reflect its nullability.
+class DecoratedTypeAnnotation extends DecoratedType
+    implements PotentialModification {
+  @override
+  final Source source;
+
+  final int _offset;
+
+  DecoratedTypeAnnotation(
+      DartType type, ConstraintVariable nullable, this.source, this._offset,
+      {List<DecoratedType> typeArguments = const []})
+      : super(type, nullable, typeArguments: typeArguments);
+
+  @override
+  bool get isEmpty =>
+      identical(nullable, ConstraintVariable.always) || !nullable.value;
+
+  @override
+  Iterable<SourceEdit> get modifications =>
+      isEmpty ? [] : [SourceEdit(_offset, 0, '?')];
+}
+
+/// Type of a [ConstraintVariable] representing the fact that a type is intended
+/// to be non-null.
+class NonNullIntent extends ConstraintVariable {
+  final int _offset;
+
+  NonNullIntent(this._offset);
+
+  @override
+  toString() => 'nonNullIntent($_offset)';
+}
+
+/// Type of a [ConstraintVariable] representing the fact that a type is
+/// nullable.
+class TypeIsNullable extends ConstraintVariable {
+  final int _offset;
+
+  TypeIsNullable(this._offset);
+
+  @override
+  toString() => 'nullable($_offset)';
+}
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type_operations.dart b/pkg/analysis_server/lib/src/nullability/decorated_type_operations.dart
new file mode 100644
index 0000000..59164ce
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/decorated_type_operations.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:analysis_server/src/nullability/constraint_variable_gatherer.dart';
+import 'package:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+
+/// [TypeOperations] that works with [DecoratedType]s.
+class DecoratedTypeOperations implements TypeOperations<DecoratedType> {
+  final TypeSystem _typeSystem;
+  final VariableRepository _variableRepository;
+
+  DecoratedTypeOperations(this._typeSystem, this._variableRepository);
+
+  @override
+  DecoratedType elementType(VariableElement element) {
+    return _variableRepository.decoratedElementType(element);
+  }
+
+  @override
+  bool isSubtypeOf(DecoratedType leftType, DecoratedType rightType) {
+    return _typeSystem.isSubtypeOf(leftType.type, rightType.type);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/nullability/expression_checks.dart b/pkg/analysis_server/lib/src/nullability/expression_checks.dart
new file mode 100644
index 0000000..3c4af10
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/expression_checks.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:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.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
+/// expression.
+///
+/// TODO(paulberry): the only check we support now is [nullCheck], which checks
+/// that the expression is not null.  We need to add other checks, e.g. to check
+/// that a List<int?> is actually a List<int>.
+class ExpressionChecks extends PotentialModification {
+  @override
+  final Source source;
+
+  /// Constraint variable whose value will be `true` if this expression requires
+  /// a null check.
+  final CheckExpression nullCheck;
+
+  ExpressionChecks(this.source, this.nullCheck);
+
+  @override
+  bool get isEmpty => !nullCheck.value;
+
+  @override
+  Iterable<SourceEdit> get modifications =>
+      nullCheck.value ? [SourceEdit(nullCheck.offset, 0, '!')] : [];
+}
diff --git a/pkg/analysis_server/lib/src/nullability/provisional_api.dart b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
new file mode 100644
index 0000000..6352b4d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/decorated_type.dart'
+    as analyzer;
+import 'package:analysis_server/src/nullability/expression_checks.dart'
+    as analyzer;
+import 'package:analysis_server/src/nullability/transitional_api.dart'
+    as analyzer;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:meta/meta.dart';
+
+export 'package:analysis_server/src/nullability/transitional_api.dart'
+    show NamedNoDefaultParameterHeuristic, NullabilityMigrationAssumptions;
+
+/// Kinds of fixes that might be performed by nullability migration.
+class NullabilityFixKind {
+  /// A formal parameter needs to have a required annotation added.
+  static const addRequired =
+      const NullabilityFixKind._(appliedMessage: 'Add a required annotation');
+
+  /// An expression's value needs to be null-checked.
+  static const checkExpression = const NullabilityFixKind._(
+    appliedMessage: 'Added a null check to an expression',
+  );
+
+  /// An explicit type mentioned in the source program needs to be made
+  /// nullable.
+  static const makeTypeNullable = const NullabilityFixKind._(
+    appliedMessage: 'Changed a type to be nullable',
+  );
+
+  /// An if-test or conditional expression needs to have its "then" branch
+  /// discarded.
+  static const discardThen = const NullabilityFixKind._(
+    appliedMessage: 'Discarded an unreachable conditional then branch',
+  );
+
+  /// An if-test or conditional expression needs to have its "else" branch
+  /// discarded.
+  static const discardElse = const NullabilityFixKind._(
+    appliedMessage: 'Discarded an unreachable conditional else branch',
+  );
+
+  /// A message used by dartfix to indicate a fix has been applied.
+  final String appliedMessage;
+
+  const NullabilityFixKind._({@required this.appliedMessage});
+}
+
+/// Provisional API for DartFix to perform nullability migration.
+///
+/// Usage: pass each input source file to [prepareInput].  Then pass each input
+/// source file to [processInput].  Then call [finish] to obtain the
+/// modifications that need to be made to each source file.
+///
+/// TODO(paulberry): figure out whether this API is what we want, and figure out
+/// what file/folder it belongs in.
+class NullabilityMigration {
+  final analyzer.NullabilityMigration _analyzerMigration;
+  final NullabilityMigrationListener listener;
+
+  /// Prepares to perform nullability migration.
+  ///
+  /// If [permissive] is `true`, exception handling logic will try to proceed
+  /// as far as possible even though the migration algorithm is not yet
+  /// complete.  TODO(paulberry): remove this mode once the migration algorithm
+  /// is fully implemented.
+  NullabilityMigration(this.listener,
+      {bool permissive: false,
+      analyzer.NullabilityMigrationAssumptions assumptions:
+          const analyzer.NullabilityMigrationAssumptions()})
+      : _analyzerMigration = analyzer.NullabilityMigration(
+            permissive: permissive, assumptions: assumptions);
+
+  void finish() {
+    _analyzerMigration.finish().forEach((pm) {
+      listener.addFix(_SingleNullabilityFix(pm));
+    });
+  }
+
+  void prepareInput(ResolvedUnitResult result) {
+    _analyzerMigration.prepareInput(result.unit);
+  }
+
+  void processInput(ResolvedUnitResult result) {
+    _analyzerMigration.processInput(result.unit, result.typeProvider);
+  }
+}
+
+/// [NullabilityMigrationListener] is used by [NullabilityMigration]
+/// to communicate source changes or "fixes" to the client.
+abstract class NullabilityMigrationListener {
+  /// [addFix] is called once for each source change.
+  void addFix(SingleNullabilityFix fix);
+}
+
+/// Representation of a single conceptual change made by the nullability
+/// migration algorithm.  This change might require multiple source edits to
+/// achieve.
+abstract class SingleNullabilityFix {
+  /// What kind of fix this is.
+  NullabilityFixKind get kind;
+
+  /// Location of the change, for reporting to the user.
+  Location get location;
+
+  /// File to change.
+  Source get source;
+
+  /// Individual source edits to achieve the change.  May be returned in any
+  /// order.
+  Iterable<SourceEdit> get sourceEdits;
+}
+
+/// Implementation of [SingleNullabilityFix] used internally by
+/// [NullabilityMigration].
+class _SingleNullabilityFix extends SingleNullabilityFix {
+  @override
+  final List<SourceEdit> sourceEdits;
+
+  @override
+  final Source source;
+
+  @override
+  final NullabilityFixKind kind;
+
+  factory _SingleNullabilityFix(
+      analyzer.PotentialModification potentialModification) {
+    // TODO(paulberry): once everything is migrated into the analysis server,
+    // the migration engine can just create SingleNullabilityFix objects
+    // directly and set their kind appropriately; we won't need to translate the
+    // kinds using a bunch of `is` checks.
+    NullabilityFixKind kind;
+    if (potentialModification is analyzer.ExpressionChecks) {
+      kind = NullabilityFixKind.checkExpression;
+    } else if (potentialModification is analyzer.DecoratedTypeAnnotation) {
+      kind = NullabilityFixKind.makeTypeNullable;
+    } else if (potentialModification is analyzer.ConditionalModification) {
+      kind = potentialModification.discard.keepFalse.value
+          ? NullabilityFixKind.discardThen
+          : NullabilityFixKind.discardElse;
+    } else if (potentialModification is analyzer.PotentiallyAddRequired) {
+      kind = NullabilityFixKind.addRequired;
+    } else {
+      throw new UnimplementedError('TODO(paulberry)');
+    }
+    return _SingleNullabilityFix._(potentialModification.modifications.toList(),
+        potentialModification.source, kind);
+  }
+
+  _SingleNullabilityFix._(this.sourceEdits, this.source, this.kind);
+
+  /// TODO(paulberry): do something better
+  Location get location => null;
+}
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
new file mode 100644
index 0000000..4f0c81a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
@@ -0,0 +1,310 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/conditional_discard.dart';
+import 'package:analysis_server/src/nullability/constraint_gatherer.dart';
+import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
+import 'package:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+
+/// Type of a [ConstraintVariable] representing the addition of a null check.
+class CheckExpression extends ConstraintVariable {
+  final int offset;
+
+  CheckExpression(Expression expression) : offset = expression.end;
+
+  @override
+  toString() => 'checkNotNull($offset)';
+}
+
+/// Records information about how a conditional expression or statement might
+/// need to be modified.
+class ConditionalModification extends PotentialModification {
+  final int offset;
+
+  final int end;
+
+  final bool isStatement;
+
+  final ConditionalDiscard discard;
+
+  final _KeepNode condition;
+
+  final _KeepNode thenStatement;
+
+  final _KeepNode elseStatement;
+
+  @override
+  final Source source;
+
+  factory ConditionalModification(
+      Source source, AstNode node, ConditionalDiscard discard) {
+    if (node is IfStatement) {
+      return ConditionalModification._(
+          node.offset,
+          node.end,
+          node is Statement,
+          discard,
+          _KeepNode(node.condition),
+          _KeepNode(node.thenStatement),
+          _KeepNode(node.elseStatement),
+          source);
+    } else {
+      throw new UnimplementedError('TODO(paulberry)');
+    }
+  }
+
+  ConditionalModification._(
+      this.offset,
+      this.end,
+      this.isStatement,
+      this.discard,
+      this.condition,
+      this.thenStatement,
+      this.elseStatement,
+      this.source);
+
+  @override
+  bool get isEmpty => discard.keepTrue.value && discard.keepFalse.value;
+
+  @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.value) {
+      keepNodes.add(thenStatement); // TODO(paulberry): test
+    }
+    if (discard.keepFalse.value) {
+      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;
+  }
+}
+
+/// Enum encapsulating the various options proposed at
+/// https://github.com/dart-lang/language/issues/156#issuecomment-460525075
+enum DefaultParameterHandling {
+  /// Option 2: Add required named parameters
+  ///
+  /// - `{int x}` implicitly means `x` is required
+  ///   - required-ness goes into the function type:
+  ///     `int Function({required int x})`
+  /// - `{required int? x}` is allowed
+  ///   - means that something must be passed
+  ///   - passing null is allowed
+  /// - `{int x = 3}` is allowed
+  ///   - `x` is optional
+  ///   - passing null to it is an error
+  ///   - passing nothing to it results in it getting the default value
+  /// - `[int x]` is an error
+  /// - `[int x = 3]` is allowed
+  option2_addRequiredNamedParameters,
+}
+
+/// Enum representing the possible heuristics for handling named parameters with
+/// no default value.
+enum NamedNoDefaultParameterHeuristic {
+  /// Assume that the parameter should be considered nullable, unless the user
+  /// has explicitly marked it as `@required`.
+  assumeNullable,
+
+  /// Assume that the parameter should be considered required, unless the user
+  /// has explicitly marked it as nullable.
+  assumeRequired,
+}
+
+/// Transitional migration API.
+///
+/// Usage: pass each input source file to [prepareInput].  Then pass each input
+/// source file to [processInput].  Then call [finish] to obtain the
+/// modifications that need to be made to each source file.
+///
+/// TODO(paulberry): this implementation keeps a lot of CompilationUnit objects
+/// around.  Can we do better?
+class NullabilityMigration {
+  final bool _permissive;
+
+  final NullabilityMigrationAssumptions assumptions;
+
+  final _variables = Variables();
+
+  final _constraints = Solver();
+
+  /// Prepares to perform nullability migration.
+  ///
+  /// If [permissive] is `true`, exception handling logic will try to proceed
+  /// as far as possible even though the migration algorithm is not yet
+  /// complete.  TODO(paulberry): remove this mode once the migration algorithm
+  /// is fully implemented.
+  NullabilityMigration(
+      {bool permissive: false,
+      this.assumptions: const NullabilityMigrationAssumptions()})
+      : _permissive = permissive;
+
+  List<PotentialModification> finish() {
+    _constraints.applyHeuristics();
+    return _variables.getPotentialModifications();
+  }
+
+  void prepareInput(CompilationUnit unit) {
+    unit.accept(ConstraintVariableGatherer(
+        _variables, unit.declaredElement.source, _permissive, assumptions));
+  }
+
+  void processInput(CompilationUnit unit, TypeProvider typeProvider) {
+    unit.accept(ConstraintGatherer(typeProvider, _variables, _constraints,
+        unit.declaredElement.source, _permissive, assumptions));
+  }
+}
+
+/// Assumptions affecting the behavior of the nullability migration tool.
+///
+/// These options generally reflect design decisions that have not yet been
+/// made.  They don't reflect behavioral differences we would want to expose to
+/// the user.
+///
+/// TODO(paulberry): hardcode these assumptions once decisions have been made.
+class NullabilityMigrationAssumptions {
+  /// Handling of default parameters.
+  final DefaultParameterHandling defaultParameterHandling;
+
+  /// Heuristic for handling named parameters with no default value.
+  final NamedNoDefaultParameterHeuristic namedNoDefaultParameterHeuristic;
+
+  const NullabilityMigrationAssumptions(
+      {this.defaultParameterHandling:
+          DefaultParameterHandling.option2_addRequiredNamedParameters,
+      this.namedNoDefaultParameterHeuristic:
+          NamedNoDefaultParameterHeuristic.assumeRequired});
+}
+
+/// Records information about the possible addition of a `@required` annotation
+/// to the source code.
+class PotentiallyAddRequired extends PotentialModification {
+  @override
+  final Source source;
+
+  final ConstraintVariable _optionalVariable;
+
+  final int _offset;
+
+  PotentiallyAddRequired(
+      this.source, DefaultFormalParameter parameter, this._optionalVariable)
+      : _offset = parameter.offset;
+
+  @override
+  bool get isEmpty => _optionalVariable.value;
+
+  @override
+  Iterable<SourceEdit> get modifications =>
+      isEmpty ? const [] : [SourceEdit(_offset, 0, '@required ')];
+}
+
+/// Interface used by data structures representing potential modifications to
+/// the code being migrated.
+abstract class PotentialModification {
+  bool get isEmpty;
+
+  /// Gets the individual migrations that need to be done, considering the
+  /// solution to the constraint equations.
+  Iterable<SourceEdit> get modifications;
+
+  Source get source;
+}
+
+class Variables implements VariableRecorder, VariableRepository {
+  final _decoratedElementTypes = <Element, DecoratedType>{};
+
+  final _potentialModifications = <PotentialModification>[];
+
+  @override
+  DecoratedType decoratedElementType(Element element, {bool create: false}) =>
+      _decoratedElementTypes[element] ??= create
+          ? DecoratedType.forElement(element)
+          : throw StateError('No element found');
+
+  List<PotentialModification> getPotentialModifications() =>
+      _potentialModifications.where((m) => !m.isEmpty).toList();
+
+  @override
+  void recordConditionalDiscard(
+      Source source, AstNode node, ConditionalDiscard conditionalDiscard) {
+    _potentialModifications
+        .add(ConditionalModification(source, node, conditionalDiscard));
+  }
+
+  void recordDecoratedElementType(Element element, DecoratedType type) {
+    _decoratedElementTypes[element] = type;
+  }
+
+  void recordDecoratedExpressionType(Expression node, DecoratedType type) {}
+
+  void recordDecoratedTypeAnnotation(
+      TypeAnnotation node, DecoratedTypeAnnotation type) {
+    _potentialModifications.add(type);
+  }
+
+  @override
+  void recordExpressionChecks(Expression expression, ExpressionChecks checks) {
+    _potentialModifications.add(checks);
+  }
+
+  @override
+  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
+      ConstraintVariable variable) {
+    _potentialModifications
+        .add(PotentiallyAddRequired(source, parameter, variable));
+  }
+}
+
+/// Helper object used by [ConditionalModification] to keep track of AST nodes
+/// within the conditional expression.
+class _KeepNode {
+  final int offset;
+
+  final int end;
+
+  final bool isExpression;
+
+  factory _KeepNode(AstNode node) {
+    int offset = node.offset;
+    int end = node.end;
+    if (node is Block && node.statements.isNotEmpty) {
+      offset = node.statements.beginToken.offset;
+      end = node.statements.endToken.end;
+    }
+    return _KeepNode._(offset, end, node is Expression);
+  }
+
+  _KeepNode._(this.offset, this.end, this.isExpression);
+}
diff --git a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
new file mode 100644
index 0000000..1add712
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Repository of constraints corresponding to the code being migrated.
+///
+/// This data structure carries information from the second pass of migration
+/// ([ConstraintGatherer]) to the third (which creates individual code
+/// modifications from each constraint).
+abstract class Constraints {
+  /// Records a new constraint equation.
+  void record(
+      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence);
+}
+
+/// Representation of a single boolean variable in the constraint solver.
+class ConstraintVariable {
+  /// A special boolean variable whose value is known to be `true`.
+  static final ConstraintVariable always = _Always();
+
+  /// A list of all constraints containing this variable on their left hand side
+  /// that may not have been satisfied yet.
+  final _dependencies = <_Clause>[];
+
+  /// The value assigned to this constraint variable by the solution currently
+  /// being computed.
+  bool _value = false;
+
+  /// If this variable represents a disjunction ("or") of several other
+  /// variables, the variables in the disjunction.  Otherwise a singleton list
+  /// containing `this`.
+  final List<ConstraintVariable> _disjunctionParts;
+
+  ConstraintVariable() : _disjunctionParts = List.filled(1, null) {
+    _disjunctionParts[0] = this;
+  }
+
+  /// Creates a [ConstraintVariable] representing a disjunction ("or") of
+  /// several other variables.
+  ///
+  /// Additional constraints will be recorded in [constraints] to ensure that
+  /// the solution will be consistent.
+  factory ConstraintVariable.or(
+      Constraints constraints, ConstraintVariable a, ConstraintVariable b) {
+    if (a == null) return b;
+    if (b == null) return a;
+    var parts = a.disjunctionParts.toList();
+    parts.addAll(b.disjunctionParts);
+    assert(parts.length > 1);
+    var result = ConstraintVariable._(parts);
+    constraints.record([a], result);
+    constraints.record([b], result);
+    return result;
+  }
+
+  ConstraintVariable._(this._disjunctionParts);
+
+  /// If this variable represents a disjunction ("or") of several other
+  /// variables, the variables in the disjunction.  Otherwise a singleton list
+  /// containing `this`.
+  Iterable<ConstraintVariable> get disjunctionParts => _disjunctionParts;
+
+  /// Indicates whether this variable represents a disjunction ("or") of several
+  /// other variables.
+  bool get isDisjunction => _disjunctionParts.length > 1;
+
+  /// The value assigned to this constraint variable by the solution currently
+  /// being computed.
+  get value => _value;
+
+  @override
+  String toString() =>
+      isDisjunction ? '(${_disjunctionParts.join(' | ')})' : super.toString();
+}
+
+/// The core of the migration tool's constraint solver.  This class implements
+/// unit propagation (see https://en.wikipedia.org/wiki/Unit_propagation),
+/// extended to support disjunctions.
+///
+/// The extension works approximately as follows: first we perform ordinary unit
+/// propagation, accumulating a list of any disjunction variables that need to
+/// be assigned a value of `true`.  Once this finishes, we heuristically choose
+/// one of these disjunction variables and ensure that it is assigned a value of
+/// `true` by setting one of its constituent variables to `true` and propagating
+/// again.  Once all disjunctions have been resolved, we have a final solution.
+class Solver extends Constraints {
+  /// Clauses that should be evaluated as part of ordinary unit propagation.
+  final _pending = <_Clause>[];
+
+  /// Disjunction variables that have been determined by unit propagation to be
+  /// `true`, but for which we have not yet propagated the `true` value to one
+  /// of the constituent variables.
+  final _pendingDisjunctions = <ConstraintVariable>[];
+
+  /// Heuristically resolves any pending disjunctions.
+  void applyHeuristics() {
+    while (_pendingDisjunctions.isNotEmpty) {
+      var disjunction = _pendingDisjunctions.removeLast();
+      if (disjunction.disjunctionParts.any((v) => v.value)) continue;
+      // TODO(paulberry): smarter heuristics
+      var choice = disjunction.disjunctionParts.first;
+      record([], choice);
+    }
+  }
+
+  @override
+  void record(Iterable<ConstraintVariable> conditions,
+      covariant ConstraintVariable consequence) {
+    var _conditions = List<ConstraintVariable>.from(conditions);
+    var clause = _Clause(_conditions, consequence);
+    int i = 0;
+    while (i < _conditions.length) {
+      ConstraintVariable variable = _conditions[i];
+      if (variable._value) {
+        int j = _conditions.length - 1;
+        _conditions[i] = _conditions[j];
+        _conditions.removeLast();
+        continue;
+      }
+      variable._dependencies.add(clause);
+      i++;
+    }
+    if (i == 0) {
+      if (!consequence._value) {
+        consequence._value = true;
+        if (consequence.isDisjunction) {
+          _pendingDisjunctions.add(consequence);
+        }
+        _pending.addAll(consequence._dependencies);
+        _propagate();
+      }
+    } else {
+      consequence._dependencies.add(clause);
+    }
+  }
+
+  /// Performs ordinary unit propagation, recording any disjunctions encountered
+  /// in [_pendingDisjunctions].
+  void _propagate() {
+    while (_pending.isNotEmpty) {
+      var clause = _pending.removeLast();
+      var conditions = clause.conditions;
+      int i = 0;
+      while (i < conditions.length) {
+        ConstraintVariable variable = conditions[i];
+        if (variable._value) {
+          int j = conditions.length - 1;
+          conditions[i] = conditions[j];
+          conditions.removeLast();
+          continue;
+        }
+        i++;
+      }
+      if (i == 0) {
+        var consequence = clause.consequence;
+        if (!consequence._value) {
+          consequence._value = true;
+          if (consequence.isDisjunction) {
+            _pendingDisjunctions.add(consequence);
+          }
+          _pending.addAll(consequence._dependencies);
+        }
+      }
+    }
+  }
+}
+
+/// The special singleton [ConstraintVariable] whose value is always `true`.
+class _Always extends ConstraintVariable {
+  _Always() {
+    _value = true;
+  }
+
+  @override
+  String toString() => 'always';
+}
+
+/// A single equation in a system of constraints.
+class _Clause {
+  /// The conditions on the left hand side of the equation.
+  final List<ConstraintVariable> conditions;
+
+  /// The single variable on the right hand side of the equation.
+  final ConstraintVariable consequence;
+
+  _Clause(this.conditions, this.consequence);
+}
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 29d59bb..305b455 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -554,6 +554,7 @@
 
     final socketServer = new LspSocketServer(
       analysisServerOptions,
+      diagnosticServer,
       dartSdkManager,
       instrumentationService,
     );
diff --git a/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart b/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
index 1b5cde5..92fd980 100644
--- a/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
+++ b/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
@@ -33,7 +33,7 @@
    */
   Future serveStdio() {
     LspByteStreamServerChannel serverChannel = new LspByteStreamServerChannel(
-        stdin, stdout, socketServer.instrumentationService);
+        stdin, stdout.nonBlocking, socketServer.instrumentationService);
     socketServer.createAnalysisServer(serverChannel);
     return serverChannel.closed;
   }
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 f7ddb32..4c4b692 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
@@ -8,11 +8,11 @@
     hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
-import 'package:analysis_server/src/utilities/documentation.dart';
 import 'package:analysis_server/src/utilities/flutter.dart' as flutter;
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/util/comment.dart';
 
 /**
  * Determine the number of arguments.
@@ -32,52 +32,6 @@
 }
 
 /**
- * If the containing [node] is an argument list
- * or named expression in an argument list
- * then return the simple identifier for the method, constructor, or annotation
- * to which the argument list is associated
- */
-SimpleIdentifier _getTargetId(AstNode node) {
-  if (node is NamedExpression) {
-    return _getTargetId(node.parent);
-  }
-  if (node is ArgumentList) {
-    AstNode parent = node.parent;
-    if (parent is MethodInvocation) {
-      return parent.methodName;
-    }
-    if (parent is InstanceCreationExpression) {
-      ConstructorName constructorName = parent.constructorName;
-      if (constructorName != null) {
-        if (constructorName.name != null) {
-          return constructorName.name;
-        }
-        Identifier typeName = constructorName.type.name;
-        if (typeName is SimpleIdentifier) {
-          return typeName;
-        }
-        if (typeName is PrefixedIdentifier) {
-          return typeName.identifier;
-        }
-      }
-    }
-    if (parent is Annotation) {
-      SimpleIdentifier name = parent.constructorName;
-      if (name == null) {
-        Identifier parentName = parent.name;
-        if (parentName is SimpleIdentifier) {
-          return parentName;
-        } else if (parentName is PrefixedIdentifier) {
-          return parentName.identifier;
-        }
-      }
-      return name;
-    }
-  }
-  return null;
-}
-
-/**
  * Determine if the completion target is at the end of the list of arguments.
  */
 bool _isAppendingToArgList(DartCompletionRequest request) {
@@ -193,35 +147,13 @@
     this.request = request;
     this.suggestions = <CompletionSuggestion>[];
 
-    // Determine if the target is in an argument list
-    // for a method or a constructor or an annotation
-    SimpleIdentifier targetId = _getTargetId(request.target.containingNode);
-    if (targetId == null) {
-      return const <CompletionSuggestion>[];
-    }
-    Element elem = targetId.staticElement;
-    if (elem == null) {
+    var executable = request.target.executableElement;
+    if (executable == null) {
       return const <CompletionSuggestion>[];
     }
 
-    // Generate argument list suggestion based upon the type of element
-    if (elem is ClassElement) {
-      _addSuggestions(elem.unnamedConstructor?.parameters);
-      return suggestions;
-    }
-    if (elem is ConstructorElement) {
-      _addSuggestions(elem.parameters);
-      return suggestions;
-    }
-    if (elem is FunctionElement) {
-      _addSuggestions(elem.parameters);
-      return suggestions;
-    }
-    if (elem is MethodElement) {
-      _addSuggestions(elem.parameters);
-      return suggestions;
-    }
-    return const <CompletionSuggestion>[];
+    _addSuggestions(executable.parameters);
+    return suggestions;
   }
 
   void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters,
@@ -280,6 +212,7 @@
       if (parameter is FieldFormalParameterElement) {
         _setDocumentation(suggestion, parameter.field?.documentationComment);
         suggestion.element = convertElement(parameter);
+        suggestion.elementUri = parameter.source.toString();
       }
 
       suggestions.add(suggestion);
@@ -341,7 +274,7 @@
   static void _setDocumentation(
       CompletionSuggestion suggestion, String comment) {
     if (comment != null) {
-      String doc = removeDartDocDelimiters(comment);
+      String doc = getDartDocPlainText(comment);
       suggestion.docComplete = doc;
       suggestion.docSummary = getDartDocSummary(doc);
     }
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 0989365..7661185 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
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
     show AbortCompletion, CompletionContributor, CompletionRequest;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
@@ -32,13 +33,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/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -55,6 +56,22 @@
    */
   static DartContributionSorter contributionSorter = new CommonUsageSorter();
 
+  /// 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
+  /// sets.
+  final Set<protocol.ElementKind> includedSuggestionKinds;
+
+  /// If [includedSuggestionKinds] is not null, must be also not `null`, and
+  /// will be filled with tags for suggestions that should be given higher
+  /// relevance than other included suggestions.
+  final List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+
+  DartCompletionManager({
+    this.includedSuggestionKinds,
+    this.includedSuggestionRelevanceTags,
+  });
+
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       CompletionRequest request) async {
@@ -88,7 +105,6 @@
       new ArgListContributor(),
       new CombinatorContributor(),
       new FieldFormalContributor(),
-      new ImportedReferenceContributor(),
       new InheritedReferenceContributor(),
       new KeywordContributor(),
       new LabelContributor(),
@@ -104,6 +120,14 @@
       new UriContributor(),
       new VariableNameContributor()
     ];
+
+    if (includedSuggestionKinds != null) {
+      _addIncludedSuggestionKinds(dartRequest);
+      _addIncludedSuggestionRelevanceTags(dartRequest);
+    } else {
+      contributors.add(new ImportedReferenceContributor());
+    }
+
     try {
       for (DartCompletionContributor contributor in contributors) {
         String contributorTag =
@@ -153,6 +177,79 @@
     return suggestions;
   }
 
+  void _addIncludedSuggestionKinds(DartCompletionRequestImpl request) {
+    var opType = request.opType;
+
+    if (!opType.includeIdentifiers) return;
+
+    var kinds = includedSuggestionKinds;
+    if (kinds != null) {
+      if (opType.includeTypeNameSuggestions) {
+        kinds.add(protocol.ElementKind.CLASS);
+        kinds.add(protocol.ElementKind.CLASS_TYPE_ALIAS);
+        kinds.add(protocol.ElementKind.ENUM);
+        kinds.add(protocol.ElementKind.FUNCTION_TYPE_ALIAS);
+        kinds.add(protocol.ElementKind.MIXIN);
+      }
+      if (opType.includeReturnValueSuggestions) {
+        kinds.add(protocol.ElementKind.ENUM_CONSTANT);
+        kinds.add(protocol.ElementKind.FUNCTION);
+        kinds.add(protocol.ElementKind.TOP_LEVEL_VARIABLE);
+      }
+    }
+  }
+
+  void _addIncludedSuggestionRelevanceTags(DartCompletionRequestImpl request) {
+    var target = request.target;
+
+    void addTypeTag(DartType type) {
+      if (type is InterfaceType) {
+        var element = type.element;
+        var tag = '${element.librarySource.uri}::${element.name}';
+        if (element.isEnum) {
+          includedSuggestionRelevanceTags.add(
+            IncludedSuggestionRelevanceTag(
+              tag,
+              DART_RELEVANCE_BOOST_AVAILABLE_ENUM,
+            ),
+          );
+        } else {
+          includedSuggestionRelevanceTags.add(
+            IncludedSuggestionRelevanceTag(
+              tag,
+              DART_RELEVANCE_BOOST_AVAILABLE_DECLARATION,
+            ),
+          );
+        }
+      }
+    }
+
+    var parameter = target.parameterElement;
+    if (parameter != null) {
+      addTypeTag(parameter.type);
+    }
+
+    var containingNode = target.containingNode;
+
+    if (containingNode is AssignmentExpression &&
+        containingNode.operator.type == TokenType.EQ &&
+        target.offset >= containingNode.operator.end) {
+      addTypeTag(containingNode.leftHandSide.staticType);
+    }
+
+    if (containingNode is ListLiteral &&
+        target.offset >= containingNode.leftBracket.end &&
+        target.offset <= containingNode.rightBracket.offset) {
+      var type = containingNode.staticType;
+      if (type is InterfaceType) {
+        var typeArguments = type.typeArguments;
+        if (typeArguments.isNotEmpty) {
+          addTypeTag(typeArguments[0]);
+        }
+      }
+    }
+  }
+
   static List<String> _ensureList(Map<String, List<String>> map, String key) {
     List<String> list = map[key];
     if (list == null) {
@@ -303,8 +400,7 @@
    * based on the given [request]. This method will throw [AbortCompletion]
    * if the completion request has been aborted.
    */
-  static Future<DartCompletionRequest> from(CompletionRequest request,
-      {ResultDescriptor resultDescriptor}) async {
+  static Future<DartCompletionRequest> from(CompletionRequest request) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     request.checkAborted();
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 77b4ebf..d89ed2f 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
@@ -103,6 +103,7 @@
         suggestion.element = createLocalElement(
             request.source, protocol.ElementKind.LABEL, label.label,
             returnType: NO_RETURN_TYPE);
+        suggestion.elementUri = request.source.toString();
       }
     }
   }
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 a883a59..b1d8459 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
@@ -11,12 +11,12 @@
     show DartCompletionRequestImpl;
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analysis_server/src/services/correction/strings.dart';
-import 'package:analysis_server/src/utilities/documentation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/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';
@@ -317,14 +317,30 @@
     }
   }
 
+  @override
+  void declaredTypeParameter(TypeParameter node) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(
+        null,
+        node.name,
+        null,
+        protocol.ElementKind.TYPE_PARAMETER,
+        isDeprecated: isDeprecated(node),
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_TYPE_PARAMETER,
+      );
+    }
+  }
+
   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}) {
-    CompletionSuggestionKind kind = targetIsFunctionalArgument
+    kind ??= targetIsFunctionalArgument
         ? CompletionSuggestionKind.IDENTIFIER
         : optype.suggestKind;
     CompletionSuggestion suggestion = createLocalSuggestion(
@@ -342,6 +358,7 @@
           isDeprecated: isDeprecated,
           parameters: param?.toSource(),
           returnType: typeName);
+      suggestion.elementUri = request.source.toString();
       if ((elemKind == protocol.ElementKind.METHOD ||
               elemKind == protocol.ElementKind.FUNCTION) &&
           param != null) {
@@ -383,6 +400,7 @@
             constantDeclaration.name.length,
             0,
             0));
+    suggestion.elementUri = request.source.uri.toString();
   }
 
   void _addLocalSuggestion_includeReturnValueSuggestions(
@@ -524,7 +542,7 @@
           .map((Token t) => t.toString())
           .join('\n')
           .replaceAll('\r\n', '\n');
-      String doc = removeDartDocDelimiters(text);
+      String doc = getDartDocPlainText(text);
       suggestion.docComplete = doc;
       suggestion.docSummary = getDartDocSummary(doc);
     }
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 aa25fba..e2d567d 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,9 +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:analyzer/dart/analysis/results.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/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -33,30 +31,29 @@
     if (targetId == null) {
       return const <CompletionSuggestion>[];
     }
-    ClassDeclaration classDecl =
-        targetId.thisOrAncestorOfType<ClassDeclaration>();
+    var classDecl = targetId.thisOrAncestorOfType<ClassOrMixinDeclaration>();
     if (classDecl == null) {
       return const <CompletionSuggestion>[];
     }
 
-    // TODO(brianwilkerson) Consider making the type system visible from the
-    // request.result.
-    var inheritance = new InheritanceManager2(
-        await request.result.libraryElement.session.typeSystem);
+    var inheritance = new InheritanceManager2(request.result.typeSystem);
 
     // Generate a collection of inherited members
-    ClassElement classElem = classDecl.declaredElement;
-    var interface = inheritance.getInterface(classElem.type).map;
-    var namesToOverride = _namesToOverride(classElem, interface.keys);
+    var classElem = classDecl.declaredElement;
+    var interface = inheritance.getInterface(classElem.type);
+    var interfaceMap = interface.map;
+    var namesToOverride =
+        _namesToOverride(classElem.librarySource.uri, interface);
 
     // Build suggestions
     List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
     for (Name name in namesToOverride) {
-      FunctionType signature = interface[name];
+      FunctionType signature = interfaceMap[name];
       // Gracefully degrade if the overridden element has not been resolved.
       if (signature.returnType != null) {
-        CompletionSuggestion suggestion =
-            await _buildSuggestion(request, targetId, signature);
+        var invokeSuper = interface.isSuperImplemented(name);
+        var suggestion =
+            await _buildSuggestion(request, targetId, signature, invokeSuper);
         if (suggestion != null) {
           suggestions.add(suggestion);
         }
@@ -66,42 +63,33 @@
   }
 
   /**
-   * Return a template for an override of the given [signature]. If selected,
-   * the template will replace [targetId].
+   * Build a suggestion to replace [targetId] in the given [request] with an
+   * override of the given [signature].
    */
-  Future<DartChangeBuilder> _buildReplacementText(
-      ResolvedUnitResult result,
+  Future<CompletionSuggestion> _buildSuggestion(
+      DartCompletionRequest request,
       SimpleIdentifier targetId,
       FunctionType signature,
-      StringBuffer displayTextBuffer) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    DartChangeBuilder builder = new DartChangeBuilder(result.session);
-    await builder.addFileEdit(result.path, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(targetId), (DartEditBuilder builder) {
-        ExecutableElement element = signature.element;
+      bool invokeSuper) async {
+    var displayTextBuffer = new StringBuffer();
+    var builder = new DartChangeBuilder(request.result.session);
+    await builder.addFileEdit(request.result.path, (builder) {
+      builder.addReplacement(range.node(targetId), (builder) {
         builder.writeOverride(
           signature,
           displayTextBuffer: displayTextBuffer,
-          invokeSuper: !element.isAbstract,
+          invokeSuper: invokeSuper,
         );
       });
     });
-    return builder;
-  }
 
-  /**
-   * Build a suggestion to replace [targetId] in the given [unit]
-   * with an override of the given [signature].
-   */
-  Future<CompletionSuggestion> _buildSuggestion(DartCompletionRequest request,
-      SimpleIdentifier targetId, FunctionType signature) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    StringBuffer displayTextBuffer = new StringBuffer();
-    DartChangeBuilder builder = await _buildReplacementText(
-        request.result, targetId, signature, displayTextBuffer);
-    String replacement = builder.sourceChange.edits[0].edits[0].replacement;
+    var fileEdits = builder.sourceChange.edits;
+    if (fileEdits.length != 1) return null;
+
+    var sourceEdits = fileEdits[0].edits;
+    if (sourceEdits.length != 1) return null;
+
+    String replacement = sourceEdits[0].replacement;
     String completion = replacement.trim();
     String overrideAnnotation = '@override';
     if (_hasOverride(request.target.containingNode) &&
@@ -129,6 +117,7 @@
         false,
         displayText: displayText);
     suggestion.element = protocol.convertElement(signature.element);
+    suggestion.elementUri = signature.element.source.toString();
     return suggestion;
   }
 
@@ -138,7 +127,7 @@
    */
   SimpleIdentifier _getTargetId(CompletionTarget target) {
     AstNode node = target.containingNode;
-    if (node is ClassDeclaration) {
+    if (node is ClassOrMixinDeclaration) {
       Object entity = target.entity;
       if (entity is FieldDeclaration) {
         return _getTargetIdFromVarList(entity.fields);
@@ -174,17 +163,6 @@
   }
 
   /**
-   * Return `true` if the given [classElement] directly declares a member with
-   * the given [memberName].
-   */
-  bool _hasMember(ClassElement classElement, String memberName) {
-    return classElement.getField(memberName) != null ||
-        classElement.getGetter(memberName) != null ||
-        classElement.getMethod(memberName) != null ||
-        classElement.getSetter(memberName) != null;
-  }
-
-  /**
    * Return `true` if the given [node] has an `override` annotation.
    */
   bool _hasOverride(AstNode node) {
@@ -201,16 +179,14 @@
   }
 
   /**
-   * Return a list containing the subset of [interfaceNames] that are not
-   * defined yet in the given [classElement].
+   * Return the list of names that belong to the [interface] of a class, but
+   * are not yet declared in the class.
    */
-  List<Name> _namesToOverride(
-      ClassElement classElement, Iterable<Name> interfaceNames) {
-    var libraryUri = classElement.library.source.uri;
+  List<Name> _namesToOverride(Uri libraryUri, Interface interface) {
     var namesToOverride = <Name>[];
-    for (var name in interfaceNames) {
+    for (var name in interface.map.keys) {
       if (name.isAccessibleFor(libraryUri)) {
-        if (!_hasMember(classElement, name.name)) {
+        if (!interface.declared.containsKey(name)) {
           namesToOverride.add(name);
         }
       }
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 7c65f43..c7186e2 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
@@ -7,11 +7,11 @@
     hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
-import 'package:analysis_server/src/utilities/documentation.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/comment.dart';
 import 'package:path/path.dart' as path;
 
 /**
@@ -46,11 +46,12 @@
       false);
 
   // Attach docs.
-  String doc = removeDartDocDelimiters(element.documentationComment);
+  String doc = getDartDocPlainText(element.documentationComment);
   suggestion.docComplete = doc;
   suggestion.docSummary = getDartDocSummary(doc);
 
   suggestion.element = protocol.convertElement(element);
+  suggestion.elementUri = element.source.uri.toString();
   Element enclosingElement = element.enclosingElement;
   if (enclosingElement is ClassElement) {
     suggestion.declaringType = enclosingElement.displayName;
@@ -165,6 +166,7 @@
     CompletionSuggestion suggestion = createSuggestion(element,
         completion: completion, kind: kind, relevance: relevance);
     if (suggestion != null) {
+      suggestion.elementUri = element.source.uri.toString();
       if (element.isSynthetic && element is PropertyAccessorElement) {
         String cacheKey;
         if (element.isGetter) {
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 f3974ce..63faf71 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
@@ -423,6 +423,7 @@
       if (nextType.superclass != null) {
         typesToVisit.add(nextType.superclass);
       }
+      typesToVisit.addAll(nextType.superclassConstraints);
       typesToVisit.addAll(nextType.mixins);
     }
     return result;
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 8601163..7bc89e0 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -32,7 +32,11 @@
  */
 class DartAssistKind {
   static const ADD_TYPE_ANNOTATION = const AssistKind(
-      'dart.assist.addTypeAnnotation', 30, "Add type annotation");
+      'dart.assist.addTypeAnnotation', 30, "Add type annotation",
+      associatedErrorCodes: <String>[
+        'always_specify_types',
+        'type_annotate_public_apis'
+      ]);
   static const ASSIGN_TO_LOCAL_VARIABLE = const AssistKind(
       'dart.assist.assignToVariable', 30, "Assign value to new local variable");
   static const CONVERT_CLASS_TO_MIXIN = const AssistKind(
@@ -44,15 +48,18 @@
   static const CONVERT_DOCUMENTATION_INTO_LINE = const AssistKind(
       'dart.assist.convert.lineComment',
       30,
-      "Convert to line documentation comment");
+      "Convert to line documentation comment",
+      associatedErrorCodes: <String>['slash_for_doc_comments']);
   static const CONVERT_INTO_ASYNC_BODY = const AssistKind(
       'dart.assist.convert.bodyToAsync', 30, "Convert to async function body");
   static const CONVERT_INTO_BLOCK_BODY = const AssistKind(
       'dart.assist.convert.bodyToBlock', 30, "Convert to block body");
   static const CONVERT_INTO_EXPRESSION_BODY = const AssistKind(
-      'dart.assist.convert.bodyToExpression', 30, "Convert to expression body");
+      'dart.assist.convert.bodyToExpression', 30, "Convert to expression body",
+      associatedErrorCodes: <String>['prefer_expression_function_bodies']);
   static const CONVERT_INTO_FINAL_FIELD = const AssistKind(
-      'dart.assist.convert.getterToFinalField', 30, "Convert to final field");
+      'dart.assist.convert.getterToFinalField', 30, "Convert to final field",
+      associatedErrorCodes: <String>['prefer_final_fields']);
   static const CONVERT_INTO_FOR_INDEX = const AssistKind(
       'dart.assist.convert.forEachToForIndex', 30, "Convert to for-index loop");
   static const CONVERT_INTO_GENERIC_FUNCTION_SYNTAX = const AssistKind(
@@ -64,7 +71,8 @@
   static const CONVERT_INTO_IS_NOT =
       const AssistKind('dart.assist.convert.isNot', 30, "Convert to is!");
   static const CONVERT_INTO_IS_NOT_EMPTY = const AssistKind(
-      'dart.assist.convert.isNotEmpty', 30, "Convert to 'isNotEmpty'");
+      'dart.assist.convert.isNotEmpty', 30, "Convert to 'isNotEmpty'",
+      associatedErrorCodes: <String>['prefer_is_not_empty']);
   static const CONVERT_PART_OF_TO_URI = const AssistKind(
       'dart.assist.convert.partOfToPartUri', 30, "Convert to use a URI");
   static const CONVERT_TO_DOUBLE_QUOTED_STRING = const AssistKind(
@@ -75,16 +83,38 @@
       'dart.assist.convert.toConstructorFieldParameter',
       30,
       "Convert to field formal parameter");
+  static const CONVERT_TO_IF_ELEMENT = const AssistKind(
+      'dart.assist.convertToIfElement', 30, "Convert to an 'if' element");
   static const CONVERT_TO_INT_LITERAL = const AssistKind(
-      'dart.assist.convert.toIntLiteral', 30, "Convert to an int literal");
+      'dart.assist.convert.toIntLiteral', 30, "Convert to an int literal",
+      associatedErrorCodes: <String>['prefer_int_literals']);
+  static const CONVERT_TO_LIST_LITERAL = const AssistKind(
+      'dart.assist.convert.toListLiteral', 30, "Convert to list literal",
+      // todo (brianwilkerson): unify w/ fix
+      associatedErrorCodes: <String>['prefer_collection_literals']);
+  static const CONVERT_TO_MAP_LITERAL = const AssistKind(
+      'dart.assist.convert.toMapLiteral', 30, "Convert to map literal",
+      // todo (brianwilkerson): unify w/ fix
+      associatedErrorCodes: <String>['prefer_collection_literals']);
+  static const CONVERT_TO_MULTILINE_STRING = const AssistKind(
+      'dart.assist.convert.toMultilineString',
+      30,
+      "Convert to multiline string");
   static const CONVERT_TO_NORMAL_PARAMETER = const AssistKind(
       'dart.assist.convert.toConstructorNormalParameter',
       30,
       "Convert to normal parameter");
+  static const CONVERT_TO_SET_LITERAL = const AssistKind(
+      'dart.assist.convert.toSetLiteral', 30, "Convert to set literal",
+      // todo (brianwilkerson): unify w/ fix
+      associatedErrorCodes: <String>['prefer_collection_literals']);
   static const CONVERT_TO_SINGLE_QUOTED_STRING = const AssistKind(
       'dart.assist.convert.toSingleQuotedString',
       30,
-      "Convert to single quoted string");
+      "Convert to single quoted string",
+      associatedErrorCodes: <String>['prefer_single_quotes']);
+  static const CONVERT_TO_SPREAD = const AssistKind(
+      'dart.assist.convertToSpread', 30, "Convert to a spread");
   static const ENCAPSULATE_FIELD =
       const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field");
   static const EXCHANGE_OPERANDS =
@@ -140,7 +170,11 @@
   static const JOIN_VARIABLE_DECLARATION = const AssistKind(
       'dart.assist.joinVariableDeclaration', 30, "Join variable declaration");
   static const REMOVE_TYPE_ANNOTATION = const AssistKind(
-      'dart.assist.removeTypeAnnotation', 29, "Remove type annotation");
+      'dart.assist.removeTypeAnnotation', 29, "Remove type annotation",
+      associatedErrorCodes: <String>[
+        'avoid_return_types_on_setters',
+        'type_init_formals'
+      ]);
   static const REPLACE_CONDITIONAL_WITH_IF_ELSE = const AssistKind(
       'dart.assist.convert.conditionalToIfElse',
       30,
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 135f6dc..18b210c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -20,9 +20,11 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -71,6 +73,13 @@
    */
   String get eol => utils.endOfLine;
 
+  /**
+   * Return the status of the known experiments.
+   */
+  ExperimentStatus get experimentStatus =>
+      (session.analysisContext.analysisOptions as AnalysisOptionsImpl)
+          .experimentStatus;
+
   Future<List<Assist>> compute() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -83,22 +92,27 @@
     await _addProposal_addTypeAnnotation_VariableDeclaration();
     await _addProposal_assignToLocalVariable();
     await _addProposal_convertClassToMixin();
-    await _addProposal_convertIntoFinalField();
-    await _addProposal_convertIntoGetter();
     await _addProposal_convertDocumentationIntoBlock();
     await _addProposal_convertDocumentationIntoLine();
+    await _addProposal_convertIntoFinalField();
+    await _addProposal_convertIntoGetter();
+    await _addProposal_convertListConstructorToListLiteral();
+    await _addProposal_convertListToSetToSetLiteral();
+    await _addProposal_convertMapConstructorToMapLiteral();
+    await _addProposal_convertPartOfToUri();
+    await _addProposal_convertSetConstructorToSetLiteral();
     await _addProposal_convertToAsyncFunctionBody();
     await _addProposal_convertToBlockFunctionBody();
     await _addProposal_convertToDoubleQuotedString();
     await _addProposal_convertToExpressionFunctionBody();
-    await _addProposal_convertPartOfToUri();
+    await _addProposal_convertToFieldParameter();
     await _addProposal_convertToForIndexLoop();
     await _addProposal_convertToGenericFunctionSyntax();
     await _addProposal_convertToIntLiteral();
     await _addProposal_convertToIsNot_onIs();
     await _addProposal_convertToIsNot_onNot();
     await _addProposal_convertToIsNotEmpty();
-    await _addProposal_convertToFieldParameter();
+    await _addProposal_convertToMultilineString();
     await _addProposal_convertToNormalParameter();
     await _addProposal_convertToSingleQuotedString();
     await _addProposal_encapsulateField();
@@ -129,6 +143,14 @@
     await _addProposal_splitVariableDeclaration();
     await _addProposal_surroundWith();
 
+    if (experimentStatus.control_flow_collections) {
+      await _addProposal_convertConditionalExpressionToIfElement();
+      await _addProposal_convertMapFromIterableToIfLiteral();
+    }
+    if (experimentStatus.spread_collections) {
+      await _addProposal_convertAddAllToSpread();
+    }
+
     return assists;
   }
 
@@ -402,6 +424,63 @@
     }
   }
 
+  Future<void> _addProposal_convertAddAllToSpread() async {
+    AstNode node = this.node;
+    if (node is! SimpleIdentifier || node.parent is! MethodInvocation) {
+      _coverageMarker();
+      return;
+    }
+    SimpleIdentifier name = node;
+    MethodInvocation invocation = node.parent;
+    if (name != invocation.methodName ||
+        name.name != 'addAll' ||
+        !invocation.isCascaded ||
+        invocation.argumentList.arguments.length != 1) {
+      _coverageMarker();
+      return;
+    }
+    CascadeExpression cascade = invocation.thisOrAncestorOfType();
+    NodeList<Expression> sections = cascade.cascadeSections;
+    Expression target = cascade.target;
+    if (target is! ListLiteral2 || sections[0] != invocation) {
+      _coverageMarker();
+      return;
+    }
+
+    bool isEmptyListLiteral(Expression expression) =>
+        expression is ListLiteral2 && expression.elements.isEmpty;
+
+    ListLiteral2 list = target;
+    Expression argument = invocation.argumentList.arguments[0];
+    String elementText;
+    if (argument is BinaryExpression &&
+        argument.operator.type == TokenType.QUESTION_QUESTION) {
+      Expression 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) {
+      Expression elseExpression = argument.elseExpression;
+      if (isEmptyListLiteral(elseExpression)) {
+        // ..addAll(condition ? things : const [])
+        // ..addAll(condition ? things : [])
+        String conditionText = utils.getNodeText(argument.condition);
+        String thenText = utils.getNodeText(argument.thenExpression);
+        elementText = 'if ($conditionText) ...$thenText';
+      }
+    }
+    elementText ??= '...${utils.getNodeText(argument)}';
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      builder.addDeletion(range.node(invocation));
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SPREAD);
+  }
+
   Future<void> _addProposal_convertClassToMixin() async {
     ClassDeclaration classDeclaration =
         node.thisOrAncestorOfType<ClassDeclaration>();
@@ -458,6 +537,42 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_CLASS_TO_MIXIN);
   }
 
+  Future<void> _addProposal_convertConditionalExpressionToIfElement() async {
+    AstNode node = this.node;
+    if (node is! ConditionalExpression) {
+      _coverageMarker();
+      return;
+    }
+    AstNode nodeToReplace = node;
+    AstNode parent = node.parent;
+    while (parent is ParenthesizedExpression) {
+      nodeToReplace = parent;
+      parent = parent.parent;
+    }
+    // TODO(brianwilkerson) Consider adding support for map literals.
+    if (parent is ListLiteral2 || parent is SetLiteral2) {
+      ConditionalExpression conditional = node;
+      Expression condition = conditional.condition.unParenthesized;
+      Expression thenExpression = conditional.thenExpression.unParenthesized;
+      Expression elseExpression = conditional.elseExpression.unParenthesized;
+
+      DartChangeBuilder 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));
+        });
+      });
+      _addAssistFromBuilder(
+          changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT);
+    }
+  }
+
   Future<void> _addProposal_convertDocumentationIntoBlock() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -534,11 +649,11 @@
           _coverageMarker();
           return;
         }
-        line = line.substring(expectedPrefix.length).trim();
+        line = line.substring(expectedPrefix.length);
         if (line.isEmpty) {
           newLines.add('$linePrefix///');
         } else {
-          newLines.add('$linePrefix/// $line');
+          newLines.add('$linePrefix///$line');
         }
         linePrefix = eol + prefix;
       }
@@ -678,6 +793,289 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_INTO_GETTER);
   }
 
+  Future<void> _addProposal_convertListConstructorToListLiteral() async {
+    //
+    // Ensure that this is the default constructor defined on `List`.
+    //
+    InstanceCreationExpression creation = node.thisOrAncestorOfType();
+    if (creation == null ||
+        node.offset > creation.argumentList.offset ||
+        creation.staticType.element != typeProvider.listType.element ||
+        creation.constructorName.name != null ||
+        creation.argumentList.arguments.length > 0) {
+      _coverageMarker();
+      return;
+    }
+    //
+    // Extract the information needed to build the edit.
+    //
+    TypeArgumentList constructorTypeArguments =
+        creation.constructorName.type.typeArguments;
+    //
+    // Build the change and return the assist.
+    //
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
+        if (constructorTypeArguments != null) {
+          builder.write(_getNodeText(constructorTypeArguments));
+        }
+        builder.write('[]');
+      });
+    });
+    _addAssistFromBuilder(
+        changeBuilder, DartAssistKind.CONVERT_TO_LIST_LITERAL);
+  }
+
+  Future<void> _addProposal_convertListToSetToSetLiteral() async {
+    //
+    // Ensure that this is an invocation of `toSet` on a list literal.
+    //
+    if (node is! SimpleIdentifier) {
+      _coverageMarker();
+      return;
+    }
+    AstNode parent = node.parent;
+    if (parent is! MethodInvocation) {
+      _coverageMarker();
+      return;
+    }
+    MethodInvocation invocation = parent as MethodInvocation;
+    if (invocation.methodName != node ||
+        invocation.methodName.name != 'toSet') {
+      _coverageMarker();
+      return;
+    }
+    //
+    // Extract the information needed to build the edit.
+    //
+    Expression target = invocation.target;
+    bool hasTypeArgs;
+    SourceRange openRange;
+    SourceRange closeRange;
+    if (target is ListLiteral) {
+      hasTypeArgs = target.typeArguments != null;
+      openRange = range.token(target.leftBracket);
+      closeRange = range.startEnd(target.rightBracket, invocation);
+    } else if (target is ListLiteral2) {
+      hasTypeArgs = target.typeArguments != null;
+      openRange = range.token(target.leftBracket);
+      closeRange = range.startEnd(target.rightBracket, invocation);
+    } else {
+      _coverageMarker();
+      return;
+    }
+    //
+    // Build the change and return the assist.
+    //
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      if (hasTypeArgs || _listHasUnambiguousElement(target)) {
+        builder.addSimpleReplacement(openRange, '{');
+      } else {
+        builder.addSimpleReplacement(openRange, '<dynamic>{');
+      }
+      builder.addSimpleReplacement(closeRange, '}');
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SET_LITERAL);
+  }
+
+  Future<void> _addProposal_convertMapConstructorToMapLiteral() async {
+    bool isMapClass(Element element) =>
+        element is ClassElement &&
+        (element == typeProvider.mapType.element ||
+            (element.name == 'LinkedHashMap' &&
+                element.library.name == 'dart.collection'));
+    //
+    // Ensure that this is the default constructor defined on either `Map` or
+    // `LinkedHashMap`.
+    //
+    InstanceCreationExpression creation = node.thisOrAncestorOfType();
+    if (creation == null ||
+        node.offset > creation.argumentList.offset ||
+        creation.constructorName.name != null ||
+        creation.argumentList.arguments.isNotEmpty ||
+        !isMapClass(creation.staticType.element)) {
+      _coverageMarker();
+      return;
+    }
+    //
+    // Extract the information needed to build the edit.
+    //
+    TypeArgumentList constructorTypeArguments =
+        creation.constructorName.type.typeArguments;
+    //
+    // Build the change and return the assist.
+    //
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
+        if (constructorTypeArguments != null) {
+          builder.write(_getNodeText(constructorTypeArguments));
+        }
+        builder.write('{}');
+      });
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_MAP_LITERAL);
+  }
+
+  Future<void> _addProposal_convertMapFromIterableToIfLiteral() async {
+    //
+    // Ensure that the selection is inside an invocation of Map.fromIterable.
+    //
+    InstanceCreationExpression creation =
+        node.thisOrAncestorOfType<InstanceCreationExpression>();
+    if (creation == null) {
+      _coverageMarker();
+      return;
+    }
+    ConstructorElement element = creation.staticElement;
+    if (element.name != 'fromIterable' ||
+        element.enclosingElement != typeProvider.mapType.element) {
+      _coverageMarker();
+      return;
+    }
+    //
+    // Ensure that the arguments have the right form.
+    //
+    NodeList<Expression> arguments = creation.argumentList.arguments;
+    if (arguments.length != 3) {
+      _coverageMarker();
+      return;
+    }
+    Expression iterator = arguments[0].unParenthesized;
+    Expression secondArg = arguments[1];
+    Expression thirdArg = arguments[2];
+
+    Expression extractBody(FunctionExpression expression) {
+      FunctionBody body = expression.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else if (body is BlockFunctionBody) {
+        NodeList<Statement> statements = body.block.statements;
+        if (statements.length == 1) {
+          Statement 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) {
+        Expression expression = argument.expression.unParenthesized;
+        if (expression is FunctionExpression) {
+          NodeList<FormalParameter> parameters =
+              expression.parameters.parameters;
+          if (parameters.length == 1 && parameters[0].isRequired) {
+            if (extractBody(expression) != null) {
+              return expression;
+            }
+          }
+        }
+      }
+      return null;
+    }
+
+    FunctionExpression keyClosure =
+        extractClosure('key', secondArg) ?? extractClosure('key', thirdArg);
+    FunctionExpression valueClosure =
+        extractClosure('value', thirdArg) ?? extractClosure('value', secondArg);
+    if (keyClosure == null || valueClosure == null) {
+      _coverageMarker();
+      return;
+    }
+    //
+    // Compute the loop variable name and convert the key and value closures if
+    // necessary.
+    //
+    SimpleFormalParameter keyParameter = keyClosure.parameters.parameters[0];
+    String keyParameterName = keyParameter.identifier.name;
+    SimpleFormalParameter valueParameter =
+        valueClosure.parameters.parameters[0];
+    String valueParameterName = valueParameter.identifier.name;
+    Expression keyBody = extractBody(keyClosure);
+    String keyExpressionText = utils.getNodeText(keyBody);
+    Expression valueBody = extractBody(valueClosure);
+    String valueExpressionText = utils.getNodeText(valueBody);
+
+    String loopVariableName;
+    if (keyParameterName == valueParameterName) {
+      loopVariableName = keyParameterName;
+    } else {
+      _ParameterReferenceFinder keyFinder =
+          new _ParameterReferenceFinder(keyParameter.declaredElement);
+      keyBody.accept(keyFinder);
+
+      _ParameterReferenceFinder valueFinder =
+          new _ParameterReferenceFinder(valueParameter.declaredElement);
+      valueBody.accept(valueFinder);
+
+      String computeUnusedVariableName() {
+        String 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.
+    //
+    DartChangeBuilder 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(' }');
+      });
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT);
+  }
+
   Future<void> _addProposal_convertPartOfToUri() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -697,11 +1095,111 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_PART_OF_TO_URI);
   }
 
+  Future<void> _addProposal_convertSetConstructorToSetLiteral() async {
+    //
+    // Ensure that this is one of the constructors defined on `Set`.
+    //
+    InstanceCreationExpression creation = node.thisOrAncestorOfType();
+    if (creation == null ||
+        node.offset > creation.argumentList.offset ||
+        creation.staticType.element != typeProvider.setType.element) {
+      // TODO(brianwilkerson) Consider also accepting uses of LinkedHashSet.
+      _coverageMarker();
+      return;
+    }
+    //
+    // Extract the information needed to build the edit.
+    //
+    SimpleIdentifier name = creation.constructorName.name;
+    TypeArgumentList constructorTypeArguments =
+        creation.constructorName.type.typeArguments;
+    TypeArgumentList elementTypeArguments;
+    SourceRange elementsRange;
+    if (name == null) {
+      // Handle an invocation of the default constructor `Set()`.
+    } else if (name.name == 'from' || name.name == 'of') {
+      // Handle an invocation of the constructor `Set.from()` or `Set.of()`.
+      NodeList<Expression> arguments = creation.argumentList.arguments;
+      if (arguments.length != 1) {
+        _coverageMarker();
+        return;
+      }
+      if (arguments[0] is ListLiteral) {
+        ListLiteral elements = arguments[0] as ListLiteral;
+        elementTypeArguments = elements.typeArguments;
+        elementsRange =
+            range.endStart(elements.leftBracket, elements.rightBracket);
+      } else if (arguments[0] is ListLiteral2) {
+        ListLiteral2 elements = arguments[0] as ListLiteral2;
+        elementTypeArguments = elements.typeArguments;
+        elementsRange =
+            range.endStart(elements.leftBracket, elements.rightBracket);
+      } else {
+        // TODO(brianwilkerson) Consider handling other iterables. Literal sets
+        //  could be treated like lists, and arbitrary iterables by using a
+        //  spread.
+        _coverageMarker();
+        return;
+      }
+    } else {
+      // Invocation of an unhandled constructor.
+      _coverageMarker();
+      return;
+    }
+    new Map();
+    //
+    // Determine whether type arguments are strictly required in cases where no
+    // type arguments were explicitly provided.
+    //
+    bool hasUnambiguousElement() {
+      NodeList<Expression> arguments = creation.argumentList.arguments;
+      if (arguments == null || arguments.isEmpty) {
+        return false;
+      }
+      return _listHasUnambiguousElement(arguments[0]);
+    }
+
+    bool setWouldBeInferred() {
+      AstNode parent = creation.parent;
+      if (parent is VariableDeclaration) {
+        AstNode parent2 = parent.parent;
+        if (parent2 is VariableDeclarationList &&
+            parent2.type?.type?.element == typeProvider.setType.element) {
+          return true;
+        }
+      }
+      return hasUnambiguousElement();
+    }
+
+    //
+    // Build the change and return the assist.
+    //
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addReplacement(range.node(creation), (DartEditBuilder builder) {
+        if (constructorTypeArguments != null) {
+          builder.write(_getNodeText(constructorTypeArguments));
+        } else if (elementTypeArguments != null) {
+          builder.write(_getNodeText(elementTypeArguments));
+        } else if (!setWouldBeInferred()) {
+          builder.write('<dynamic>');
+        }
+        builder.write('{');
+        if (elementsRange != null) {
+          builder.write(_getRangeText(elementsRange));
+        }
+        builder.write('}');
+      });
+    });
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SET_LITERAL);
+  }
+
   Future<void> _addProposal_convertToAsyncFunctionBody() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     FunctionBody body = getEnclosingFunctionBody();
-    if (body == null || body.isAsynchronous || body.isGenerator) {
+    if (body == null ||
+        body is EmptyFunctionBody ||
+        body.isAsynchronous ||
+        body.isGenerator) {
       _coverageMarker();
       return;
     }
@@ -1225,6 +1723,36 @@
         changeBuilder, DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
   }
 
+  Future<void> _addProposal_convertToMultilineString() async {
+    var node = this.node;
+    if (node is InterpolationElement) {
+      node = (node as InterpolationElement).parent;
+    }
+    if (node is SingleStringLiteral) {
+      SingleStringLiteral literal = node;
+      if (!literal.isMultiline) {
+        var changeBuilder = _newDartChangeBuilder();
+        await changeBuilder.addFileEdit(file, (builder) {
+          var newQuote = literal.isSingleQuoted ? "'''" : '"""';
+          builder.addReplacement(
+            SourceRange(literal.offset + (literal.isRaw ? 1 : 0), 1),
+            (builder) {
+              builder.writeln(newQuote);
+            },
+          );
+          builder.addSimpleReplacement(
+            SourceRange(literal.end - 1, 1),
+            newQuote,
+          );
+        });
+        _addAssistFromBuilder(
+          changeBuilder,
+          DartAssistKind.CONVERT_TO_MULTILINE_STRING,
+        );
+      }
+    }
+  }
+
   Future<void> _addProposal_convertToNormalParameter() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -1501,7 +2029,7 @@
     }
 
     String widgetName = widgetClassElement.displayName;
-    String stateName = widgetName + 'State';
+    String stateName = '_${widgetName}State';
 
     // Find fields assigned in constructors.
     var fieldsAssignedInConstructors = new Set<FieldElement>();
@@ -1624,9 +2152,7 @@
                 builder.writeln();
               }
               builder.writeln('  @override');
-              builder.writeln('  $stateName createState() {');
-              builder.writeln('    return new $stateName();');
-              builder.writeln('  }');
+              builder.writeln('  $stateName createState() => $stateName();');
               if (hasEmptyLineAfterCreateState) {
                 builder.writeln();
               }
@@ -1817,8 +2343,8 @@
       return;
     }
 
-    // child: new ThisWidget(child: ourChild)
-    // children: [foo, new ThisWidget(child: ourChild), bar]
+    // child: ThisWidget(child: ourChild)
+    // children: [foo, ThisWidget(child: ourChild), bar]
     var changeBuilder = _newDartChangeBuilder();
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
       var childExpression = childArgument.expression;
@@ -2608,7 +3134,6 @@
         builder.write('[');
         builder.write(eol);
         builder.write(indentArg);
-        builder.write('new ');
         builder.addSimpleLinkedEdit('WIDGET', 'widget');
         builder.write('(');
         builder.write(eol);
@@ -3361,6 +3886,36 @@
     return utils.getRangeText(range);
   }
 
+  /// Return `true` if the [element] is sufficient to lexically make the
+  /// enclosing literal a set literal rather than a map.
+  bool _isUnambiguousElement(CollectionElement element) {
+    if (element is ForElement) {
+      return _isUnambiguousElement(element.body);
+    } else if (element is IfElement) {
+      return _isUnambiguousElement(element.thenElement) ||
+          _isUnambiguousElement(element.elseElement);
+    } else if (element is Expression) {
+      return true;
+    }
+    return false;
+  }
+
+  /// Return `true` if the given [node] is a list literal whose elements, if
+  /// placed inside curly braces, would lexically make the resulting literal a
+  /// set literal rather than a map literal.
+  bool _listHasUnambiguousElement(AstNode node) {
+    if (node is ListLiteral && node.elements.length > 0) {
+      return true;
+    } else if (node is ListLiteral2) {
+      for (CollectionElement element in node.elements) {
+        if (_isUnambiguousElement(element)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
   DartChangeBuilder _newDartChangeBuilder() {
     return new DartChangeBuilderImpl.forWorkspace(context.workspace);
   }
@@ -3509,6 +4064,70 @@
   }
 }
 
+/**
+ * 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 = new Set<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) {
+    int oldLength = parameter.name.length;
+    for (int i = references.length - 1; i >= 0; i--) {
+      int 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);
+    }
+  }
+}
+
 class _SimpleIdentifierRecursiveAstVisitor extends RecursiveAstVisitor {
   final _SimpleIdentifierVisitor visitor;
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index e9bf18d..f193dd1 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -201,6 +201,8 @@
       'MOVE_TYPE_ARGUMENTS_TO_CLASS',
       50,
       "Move type arguments to after class name");
+  static const REMOVE_ANNOTATION =
+      const FixKind('REMOVE_ANNOTATION', 50, "Remove the '{0}' annotation");
   static const REMOVE_AWAIT = const FixKind('REMOVE_AWAIT', 50, "Remove await");
   static const REMOVE_DEAD_CODE =
       const FixKind('REMOVE_DEAD_CODE', 50, "Remove dead code");
@@ -220,6 +222,8 @@
       "Remove unnecessary interpolation braces");
   static const REMOVE_METHOD_DECLARATION = const FixKind(
       'REMOVE_METHOD_DECLARATION', 50, "Remove method declaration");
+  static const REMOVE_NAME_FROM_COMBINATOR = const FixKind(
+      'REMOVE_NAME_FROM_COMBINATOR', 50, "Remove name from '{0}'");
   static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = const FixKind(
       'REMOVE_PARAMETERS_IN_GETTER_DECLARATION',
       50,
@@ -263,8 +267,6 @@
       'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??=");
   static const REPLACE_WITH_IDENTIFIER =
       const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier");
-  static const REPLACE_WITH_LITERAL =
-      const FixKind('REPLACE_WITH_LITERAL', 50, "Replace with literal");
   static const REPLACE_WITH_NULL_AWARE = const FixKind(
       'REPLACE_WITH_NULL_AWARE',
       50,
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 0db0fb2..c6600c1 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -282,27 +282,107 @@
     if (errorCode == HintCode.DEAD_CODE) {
       await _addFix_removeDeadCode();
     }
+    if (errorCode == HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH ||
+        errorCode == HintCode.DEAD_CODE_ON_CATCH_SUBTYPE) {
+      await _addFix_removeDeadCode();
+      // TODO(brianwilkerson) Add a fix to move the unreachable catch clause to
+      //  a place where it can be reached (when possible).
+    }
+    // TODO(brianwilkerson) Define a syntax for deprecated members to indicate
+    //  how to update the code and implement a fix to apply the update.
+//    if (errorCode == HintCode.DEPRECATED_MEMBER_USE ||
+//        errorCode == HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE) {
+//      await _addFix_replaceDeprecatedMemberUse();
+//    }
     if (errorCode == HintCode.DIVISION_OPTIMIZATION) {
       await _addFix_useEffectiveIntegerDivision();
     }
+    if (errorCode == HintCode.DUPLICATE_IMPORT) {
+      await _addFix_removeUnusedImport();
+    }
+    if (errorCode == HintCode.DUPLICATE_HIDDEN_NAME ||
+        errorCode == HintCode.DUPLICATE_SHOWN_NAME) {
+      await _addFix_removeNameFromCombinator();
+    }
+    // TODO(brianwilkerson) Add a fix to convert the path to a package: import.
+//    if (errorCode == HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE) {
+//      await _addFix_convertPathToPackageUri();
+//    }
+    if (errorCode == HintCode.INVALID_FACTORY_ANNOTATION ||
+        errorCode == HintCode.INVALID_IMMUTABLE_ANNOTATION ||
+        errorCode == HintCode.INVALID_LITERAL_ANNOTATION ||
+        errorCode == HintCode.INVALID_REQUIRED_PARAM ||
+        errorCode == HintCode.INVALID_SEALED_ANNOTATION) {
+      await _addFix_removeAnnotation();
+    }
+    if (errorCode == HintCode.MISSING_REQUIRED_PARAM ||
+        errorCode == HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS) {
+      await _addFix_addMissingRequiredArgument();
+    }
+    if (errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER ||
+        errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD ||
+        errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD ||
+        errorCode == HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER) {
+      await _addFix_removeAnnotation();
+    }
+    // TODO(brianwilkerson) Add a fix to normalize the path.
+//    if (errorCode == HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT) {
+//      await _addFix_normalizeUri();
+//    }
+    if (errorCode == HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE) {
+      await _addFix_importAsync();
+      await _addFix_updateSdkConstraints();
+    }
     if (errorCode == HintCode.TYPE_CHECK_IS_NOT_NULL) {
       await _addFix_isNotNull();
     }
     if (errorCode == HintCode.TYPE_CHECK_IS_NULL) {
       await _addFix_isNull();
     }
+    if (errorCode == HintCode.UNDEFINED_HIDDEN_NAME ||
+        errorCode == HintCode.UNDEFINED_SHOWN_NAME) {
+      await _addFix_removeNameFromCombinator();
+    }
     if (errorCode == HintCode.UNNECESSARY_CAST) {
       await _addFix_removeUnnecessaryCast();
     }
+    // TODO(brianwilkerson) Add a fix to remove the method.
+//    if (errorCode == HintCode.UNNECESSARY_NO_SUCH_METHOD) {
+//      await _addFix_removeMethodDeclaration();
+//    }
+    // TODO(brianwilkerson) Add a fix to remove the type check.
+//    if (errorCode == HintCode.UNNECESSARY_TYPE_CHECK_FALSE ||
+//        errorCode == HintCode.UNNECESSARY_TYPE_CHECK_TRUE) {
+//      await _addFix_removeUnnecessaryTypeCheck();
+//    }
     if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) {
       await _addFix_removeUnusedCatchClause();
     }
     if (errorCode == HintCode.UNUSED_CATCH_STACK) {
       await _addFix_removeUnusedCatchStack();
     }
+    // TODO(brianwilkerson) Add a fix to remove the declaration. Decide whether
+    //  this should be a single general fix, or multiple more specific fixes
+    //  such as [_addFix_removeMethodDeclaration].
+//    if (errorCode == HintCode.UNUSED_ELEMENT ||
+//        errorCode == HintCode.UNUSED_FIELD) {
+//      await _addFix_removeUnusedDeclaration();
+//    }
     if (errorCode == HintCode.UNUSED_IMPORT) {
       await _addFix_removeUnusedImport();
     }
+    // TODO(brianwilkerson) Add a fix to remove the label.
+//    if (errorCode == HintCode.UNUSED_LABEL) {
+//      await _addFix_removeUnusedLabel();
+//    }
+    // TODO(brianwilkerson) Add a fix to remove the local variable, either with
+    //  or without the initialization code.
+//    if (errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
+//      await _addFix_removeUnusedLocalVariable();
+//    }
+    if (errorCode == HintCode.UNUSED_SHOWN_NAME) {
+      await _addFix_removeNameFromCombinator();
+    }
     if (errorCode == ParserErrorCode.EXPECTED_TOKEN) {
       await _addFix_insertSemicolon();
     }
@@ -327,10 +407,6 @@
       await _addFix_createConstructor_insteadOfSyntheticDefault();
       await _addFix_addMissingParameter();
     }
-    if (errorCode == HintCode.MISSING_REQUIRED_PARAM ||
-        errorCode == HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS) {
-      await _addFix_addMissingRequiredArgument();
-    }
     if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
       await _addFix_createConstructor_named();
     }
@@ -469,10 +545,6 @@
         CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE) {
       await _addFix_extendClassForMixin();
     }
-    if (errorCode == HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE) {
-      await _addFix_importAsync();
-      await _addFix_updateSdkConstraints();
-    }
     // lints
     if (errorCode is LintCode) {
       String name = errorCode.name;
@@ -512,9 +584,6 @@
       if (name == LintNames.non_constant_identifier_names) {
         await _addFix_renameToCamelCase();
       }
-      if (name == LintNames.prefer_collection_literals) {
-        await _addFix_replaceWithLiteral();
-      }
       if (name == LintNames.prefer_conditional_assignment) {
         await _addFix_replaceWithConditionalAssignment();
       }
@@ -859,9 +928,12 @@
           if (arguments.isNotEmpty) {
             builder.write(', ');
           }
-          String defaultValue =
-              getDefaultStringParameterValue(missingParameter);
-          builder.write('$missingParameterName: $defaultValue');
+
+          builder.write('$missingParameterName: ');
+
+          var defaultValue = getDefaultStringParameterValue(missingParameter);
+          builder.addSimpleLinkedEdit('VALUE', defaultValue);
+
           // Insert a trailing comma after Flutter instance creation params.
           if (!hasTrailingComma && flutter.isWidgetExpression(creation)) {
             builder.write(',');
@@ -2509,6 +2581,49 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.ADD_NE_NULL);
   }
 
+  Future<void> _addFix_removeAnnotation() async {
+    void addFix(Annotation node) async {
+      if (node == null) {
+        return;
+      }
+      Token followingToken = node.endToken.next;
+      followingToken = followingToken.precedingComments ?? followingToken;
+      DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addDeletion(range.startStart(node, followingToken));
+      });
+      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_ANNOTATION,
+          args: [node.name.name]);
+    }
+
+    Annotation findAnnotation(
+        NodeList<Annotation> metadata, String targetName) {
+      return metadata.firstWhere(
+          (annotation) => annotation.name.name == targetName,
+          orElse: () => null);
+    }
+
+    AstNode node = this.coveredNode;
+    if (node is Annotation) {
+      await addFix(node);
+    } else if (node is DefaultFormalParameter) {
+      await addFix(findAnnotation(node.parameter.metadata, 'required'));
+    } else if (node is NormalFormalParameter) {
+      await addFix(findAnnotation(node.metadata, 'required'));
+    } else if (node is DeclaredSimpleIdentifier) {
+      AstNode parent = node.parent;
+      if (parent is MethodDeclaration) {
+        await addFix(findAnnotation(parent.metadata, 'override'));
+      } else if (parent is VariableDeclaration) {
+        FieldDeclaration fieldDeclaration =
+            parent.thisOrAncestorOfType<FieldDeclaration>();
+        if (fieldDeclaration != null) {
+          await addFix(findAnnotation(fieldDeclaration.metadata, 'override'));
+        }
+      }
+    }
+  }
+
   Future<void> _addFix_removeAwait() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -2524,8 +2639,6 @@
   }
 
   Future<void> _addFix_removeDeadCode() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     AstNode coveringNode = this.coveredNode;
     if (coveringNode is Expression) {
       AstNode parent = coveredNode.parent;
@@ -2564,6 +2677,17 @@
         builder.addDeletion(rangeToRemove);
       });
       _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
+    } else if (coveringNode is CatchClause) {
+      TryStatement tryStatement = coveringNode.parent;
+      NodeList<CatchClause> catchClauses = tryStatement.catchClauses;
+      int index = catchClauses.indexOf(coveringNode);
+      AstNode previous =
+          index == 0 ? tryStatement.body : catchClauses[index - 1];
+      DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addDeletion(range.endEnd(previous, coveringNode));
+      });
+      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_DEAD_CODE);
     }
   }
 
@@ -2673,6 +2797,68 @@
     }
   }
 
+  Future<void> _addFix_removeNameFromCombinator() async {
+    SourceRange rangeForCombinator(Combinator combinator) {
+      AstNode parent = combinator.parent;
+      if (parent is NamespaceDirective) {
+        NodeList<Combinator> combinators = parent.combinators;
+        if (combinators.length == 1) {
+          Token previousToken =
+              combinator.parent.findPrevious(combinator.beginToken);
+          return range.endEnd(previousToken, combinator);
+        }
+        int index = combinators.indexOf(combinator);
+        if (index < 0) {
+          return null;
+        } else if (index == combinators.length - 1) {
+          return range.endEnd(combinators[index - 1], combinator);
+        }
+        return range.startStart(combinator, combinators[index + 1]);
+      }
+      return null;
+    }
+
+    SourceRange rangeForNameInCombinator(
+        Combinator combinator, SimpleIdentifier name) {
+      NodeList<SimpleIdentifier> names;
+      if (combinator is HideCombinator) {
+        names = combinator.hiddenNames;
+      } else if (combinator is ShowCombinator) {
+        names = combinator.shownNames;
+      } else {
+        return null;
+      }
+      if (names.length == 1) {
+        return rangeForCombinator(combinator);
+      }
+      int index = names.indexOf(name);
+      if (index < 0) {
+        return null;
+      } else if (index == names.length - 1) {
+        return range.endEnd(names[index - 1], name);
+      }
+      return range.startStart(name, names[index + 1]);
+    }
+
+    AstNode node = this.coveredNode;
+    if (node is SimpleIdentifier) {
+      AstNode parent = coveredNode.parent;
+      if (parent is Combinator) {
+        SourceRange rangeToRemove = rangeForNameInCombinator(parent, node);
+        if (rangeToRemove == null) {
+          return;
+        }
+        DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+          builder.addDeletion(rangeToRemove);
+        });
+        _addFixFromBuilder(
+            changeBuilder, DartFixKind.REMOVE_NAME_FROM_COMBINATOR,
+            args: [parent is HideCombinator ? 'hide' : 'show']);
+      }
+    }
+  }
+
   Future<void> _addFix_removeParameters_inGetterDeclaration() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
@@ -2973,30 +3159,6 @@
     }
   }
 
-  Future<void> _addFix_replaceWithLiteral() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    final InstanceCreationExpression instanceCreation =
-        node.thisOrAncestorOfType<InstanceCreationExpression>();
-    final InterfaceType type = instanceCreation.staticType;
-    final generics = instanceCreation.constructorName.type.typeArguments;
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addReplacement(range.node(instanceCreation),
-          (DartEditBuilder builder) {
-        if (generics != null) {
-          builder.write(utils.getNodeText(generics));
-        }
-        if (type.name == 'List') {
-          builder.write('[]');
-        } else {
-          builder.write('{}');
-        }
-      });
-    });
-    _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_LITERAL);
-  }
-
   Future<void> _addFix_replaceWithTearOff() async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index b9cdaf0..80e07cc 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -17,6 +17,7 @@
 abstract class AbstractSocketServer {
   AnalysisServerOptions get analysisServerOptions;
   AbstractAnalysisServer get analysisServer;
+  DiagnosticServer get diagnosticServer;
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/utilities/documentation.dart b/pkg/analysis_server/lib/src/utilities/documentation.dart
deleted file mode 100644
index b47bb2f..0000000
--- a/pkg/analysis_server/lib/src/utilities/documentation.dart
+++ /dev/null
@@ -1,67 +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.
-
-String getDartDocSummary(String str) {
-  if (str == null) {
-    return null;
-  }
-  List<String> lines = str.split('\n');
-  StringBuffer sb = new StringBuffer();
-  bool firstLine = true;
-  for (String line in lines) {
-    if (sb.length != 0 && line.isEmpty) {
-      return sb.toString();
-    }
-    if (!firstLine) {
-      sb.write('\n');
-    }
-    firstLine = false;
-    sb.write(line);
-  }
-  return sb.toString();
-}
-
-/**
- * Converts [str] from a Dart Doc string with slashes and stars to a plain text
- * representation of the comment.
- */
-String removeDartDocDelimiters(String str) {
-  if (str == null) {
-    return null;
-  }
-  // remove /** */
-  if (str.startsWith('/**')) {
-    str = str.substring(3);
-  }
-  if (str.endsWith("*/")) {
-    str = str.substring(0, str.length - 2);
-  }
-  str = str.trim();
-  // remove leading '* ' and '/// '
-  List<String> lines = str.split('\n');
-  StringBuffer sb = new StringBuffer();
-  bool firstLine = true;
-  for (String line in lines) {
-    line = line.trim();
-    if (line.startsWith("*")) {
-      line = line.substring(1);
-      if (line.startsWith(" ")) {
-        line = line.substring(1);
-      }
-    } else if (line.startsWith("///")) {
-      line = line.substring(3);
-      if (line.startsWith(" ")) {
-        line = line.substring(1);
-      }
-    }
-    if (!firstLine) {
-      sb.write('\n');
-    }
-    firstLine = false;
-    sb.write(line);
-  }
-  str = sb.toString();
-  // done
-  return str;
-}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
new file mode 100644
index 0000000..d9f2c93
--- /dev/null
+++ b/pkg/analysis_server/pubspec.yaml
@@ -0,0 +1,29 @@
+name: analysis_server
+publish_to: none
+
+environment:
+  sdk: '>=2.1.0-dev.5.0 <3.0.0'
+
+dependencies:
+  analyzer: any
+  analyzer_plugin: any
+  args: any
+  convert: any
+  crypto: any
+  dart_style: any
+  front_end: any
+  linter: any
+  logging: any
+  meta: any
+  source_span: any
+  package_config: any
+  path: any
+  watcher: any
+  yaml: any
+
+dev_dependencies:
+  analysis_tool: any
+  html: any
+  http: any
+  test_reflective_loader: any
+  test: any
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 2d94d63..578053b 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -11,10 +11,10 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/overlay_file_system.dart';
 import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
-import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
@@ -45,11 +45,15 @@
 typedef void _ElementVisitorFunction(Element element);
 
 class AbstractContextTest with ResourceProviderMixin {
-  FileContentOverlay fileContentOverlay = new FileContentOverlay();
+  OverlayResourceProvider overlayResourceProvider;
 
   AnalysisContextCollection _analysisContextCollection;
   AnalysisDriver _driver;
 
+  /// The file system specific `/home/test/analysis_options.yaml` path.
+  String get analysisOptionsPath =>
+      convertPath('/home/test/analysis_options.yaml');
+
   AnalysisDriver get driver => _driver;
 
   AnalysisSession get session => driver.currentSession;
@@ -67,17 +71,67 @@
     addPackageFile('meta', 'meta.dart', r'''
 library meta;
 
+const _AlwaysThrows alwaysThrows = const _AlwaysThrows();
+
+@deprecated
+const _Checked checked = const _Checked();
+
+const _Experimental experimental = const _Experimental();
+
+const _Factory factory = const _Factory();
+
+const Immutable immutable = const Immutable();
+
 const _IsTest isTest = const _IsTest();
 
 const _IsTestGroup isTestGroup = const _IsTestGroup();
 
+const _Literal literal = const _Literal();
+
+const _MustCallSuper mustCallSuper = const _MustCallSuper();
+
+const _OptionalTypeArgs optionalTypeArgs = const _OptionalTypeArgs();
+
+const _Protected protected = const _Protected();
+
 const Required required = const Required();
 
+const _Sealed sealed = const _Sealed();
+
+@deprecated
+const _Virtual virtual = const _Virtual();
+
+const _VisibleForOverriding visibleForOverriding =
+    const _VisibleForOverriding();
+
+const _VisibleForTesting visibleForTesting = const _VisibleForTesting();
+
+class Immutable {
+  final String reason;
+  const Immutable([this.reason]);
+}
+
 class Required {
   final String reason;
   const Required([this.reason]);
 }
 
+class _AlwaysThrows {
+  const _AlwaysThrows();
+}
+
+class _Checked {
+  const _Checked();
+}
+
+class _Experimental {
+  const _Experimental();
+}
+
+class _Factory {
+  const _Factory();
+}
+
 class _IsTest {
   const _IsTest();
 }
@@ -85,6 +139,39 @@
 class _IsTestGroup {
   const _IsTestGroup();
 }
+
+class _Literal {
+  const _Literal();
+}
+
+class _MustCallSuper {
+  const _MustCallSuper();
+}
+
+class _OptionalTypeArgs {
+  const _OptionalTypeArgs();
+}
+
+class _Protected {
+  const _Protected();
+}
+
+class _Sealed {
+  const _Sealed();
+}
+
+@deprecated
+class _Virtual {
+  const _Virtual();
+}
+
+class _VisibleForOverriding {
+  const _VisibleForOverriding();
+}
+
+class _VisibleForTesting {
+  const _VisibleForTesting();
+}
 ''');
   }
 
@@ -127,8 +214,7 @@
     _analysisContextCollection = AnalysisContextCollectionImpl(
       includedPaths: [convertPath('/home')],
       enableIndex: true,
-      fileContentOverlay: fileContentOverlay,
-      resourceProvider: resourceProvider,
+      resourceProvider: overlayResourceProvider,
       sdkPath: convertPath('/sdk'),
     );
 
@@ -136,6 +222,22 @@
     _driver = getDriver(testPath);
   }
 
+  /// Create an analysis options file based on the given arguments.
+  void createAnalysisOptionsFile({List<String> experiments}) {
+    StringBuffer buffer = new StringBuffer();
+    if (experiments != null) {
+      buffer.writeln('analyzer:');
+      buffer.writeln('  enable-experiment:');
+      for (String experiment in experiments) {
+        buffer.writeln('    - $experiment');
+      }
+    }
+    newFile(analysisOptionsPath, content: buffer.toString());
+    if (_driver != null) {
+      createAnalysisContexts();
+    }
+  }
+
   /// Return the existing analysis context that should be used to analyze the
   /// given [path], or throw [StateError] if the [path] is not analyzed in any
   /// of the created analysis contexts.
@@ -159,6 +261,7 @@
 
   void setUp() {
     setupResourceProvider();
+    overlayResourceProvider = OverlayResourceProvider(resourceProvider);
 
     new MockSdk(resourceProvider: resourceProvider);
 
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index b0901725..798bedb 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index db150ad..b32c59d 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -12,6 +12,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -95,6 +96,24 @@
     }
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = _createGetErrorsRequest('test.dart');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure(requestId, RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = _createGetErrorsRequest(convertPath('/foo/../bar/test.dart'));
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure(requestId, RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_noErrors() async {
     addTestFile('''
 main() {
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index faadc26..7dc1119 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -10,6 +10,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -416,6 +417,26 @@
     expect(hover.parameter, 'double myParameter');
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new AnalysisGetHoverParams('test.dart', 0).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        new AnalysisGetHoverParams(convertPath('/foo/../bar/test.dart'), 0)
+            .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_localVariable_declaration() async {
     addTestFile('''
 library my.library;
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index cc31c34..b99aa74 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -9,6 +9,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../mocks.dart';
 import 'notification_navigation_test.dart';
 
 main() {
@@ -129,6 +130,25 @@
     expect(testTargets[0].kind, ElementKind.LIBRARY);
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = _createGetNavigationRequest('test.dart', 0, 0);
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure(requestId, RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        _createGetNavigationRequest(convertPath('/foo/../bar/test.dart'), 0, 0);
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure(requestId, RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_multipleRegions() async {
     addTestFile('''
 main() {
diff --git a/pkg/analysis_server/test/analysis/get_signature_test.dart b/pkg/analysis_server/test/analysis/get_signature_test.dart
index e91c889..4242908 100644
--- a/pkg/analysis_server/test/analysis/get_signature_test.dart
+++ b/pkg/analysis_server/test/analysis/get_signature_test.dart
@@ -11,6 +11,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -131,13 +132,6 @@
         equals(RequestErrorCode.GET_SIGNATURE_UNKNOWN_FUNCTION));
   }
 
-  test_error_file_invalid_path() async {
-    var result = await prepareRawSignatureAt(0, file: ':\\/?*');
-    expect(result.error, isNotNull);
-    expect(
-        result.error.code, equals(RequestErrorCode.GET_SIGNATURE_INVALID_FILE));
-  }
-
   test_error_file_not_analyzed() async {
     var result = await prepareRawSignatureAt(0,
         file: convertPath('/not/in/project.dart'));
@@ -407,6 +401,26 @@
     expect(result.parameters, hasLength(0));
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new AnalysisGetSignatureParams('test.dart', 0).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        new AnalysisGetSignatureParams(convertPath('/foo/../bar/test.dart'), 0)
+            .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_method_instance() async {
     addTestFile('''
 /// MyClass doc
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
index bd83a7d..9073af2 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
@@ -119,7 +119,7 @@
     expect(analyzedFilesReceived, isTrue);
 
     analyzedFilesReceived = false;
-    modifyTestFile('import "${convertAbsolutePathToUri('/foo.dart')}";');
+    modifyTestFile('import "${toUriStr('/foo.dart')}";');
     await prepareAnalyzedFiles();
     assertHasFile(convertPath('/foo.dart'));
   }
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 1046cbe..4aa6ddc 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -16,102 +16,13 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisNotificationHighlightsTest);
+    defineReflectiveTests(HighlightsWithControlFlowCollectionsTest);
     defineReflectiveTests(HighlightTypeTest);
   });
 }
 
 @reflectiveTest
-class AnalysisNotificationHighlightsTest extends AbstractAnalysisTest {
-  List<HighlightRegion> regions;
-
-  Completer _resultsAvailable = new Completer();
-
-  void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
-    for (HighlightRegion region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        return;
-      }
-    }
-    fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
-        '${regions.join('\n')}');
-  }
-
-  void assertHasRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    int offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertHasStringRegion(HighlightRegionType type, String str) {
-    int offset = findOffset(str);
-    int length = str.length;
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
-    for (HighlightRegion region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        fail(
-            'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
-            '${regions.join('\n')}');
-      }
-    }
-  }
-
-  void assertNoRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    int offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertNoRawRegion(type, offset, length);
-  }
-
-  int findRegionLength(String search, int length) {
-    if (length == -1) {
-      length = 0;
-      while (length < search.length) {
-        int c = search.codeUnitAt(length);
-        if (length == 0 && c == '@'.codeUnitAt(0)) {
-          length++;
-          continue;
-        }
-        if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
-            c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
-            c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
-          break;
-        }
-        length++;
-      }
-    }
-    return length;
-  }
-
-  Future prepareHighlights() {
-    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
-    return _resultsAvailable.future;
-  }
-
-  void processNotification(Notification notification) {
-    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
-      var params = new AnalysisHighlightsParams.fromNotification(notification);
-      if (params.file == testFile) {
-        regions = params.regions;
-        _resultsAvailable.complete(null);
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    server.options.useAnalysisHighlight2 = true;
-    createProject();
-  }
-
+class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
   test_ANNOTATION_hasArguments() async {
     addTestFile('''
 class AAA {
@@ -791,6 +702,17 @@
     assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
   }
 
+  test_KEYWORD_ifElse_statement() async {
+    addTestFile('''
+f(a, b) {
+  if (a < b) {} else {}
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
   test_KEYWORD_mixin() async {
     addTestFile('''
 mixin M {}
@@ -1122,6 +1044,103 @@
     assertHasRegion(type, 'unresolved(2)');
     assertHasRegion(type, 'unresolved(3)');
   }
+}
+
+class HighlightsTestSupport extends AbstractAnalysisTest {
+  List<HighlightRegion> regions;
+
+  Completer _resultsAvailable = new Completer();
+
+  void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
+    for (HighlightRegion region in regions) {
+      if (region.offset == offset &&
+          region.length == length &&
+          region.type == type) {
+        return;
+      }
+    }
+    fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
+        '${regions.join('\n')}');
+  }
+
+  void assertHasRegion(HighlightRegionType type, String search,
+      [int length = -1]) {
+    int offset = findOffset(search);
+    length = findRegionLength(search, length);
+    assertHasRawRegion(type, offset, length);
+  }
+
+  void assertHasStringRegion(HighlightRegionType type, String str) {
+    int offset = findOffset(str);
+    int length = str.length;
+    assertHasRawRegion(type, offset, length);
+  }
+
+  void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
+    for (HighlightRegion region in regions) {
+      if (region.offset == offset &&
+          region.length == length &&
+          region.type == type) {
+        fail(
+            'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
+            '${regions.join('\n')}');
+      }
+    }
+  }
+
+  void assertNoRegion(HighlightRegionType type, String search,
+      [int length = -1]) {
+    int offset = findOffset(search);
+    length = findRegionLength(search, length);
+    assertNoRawRegion(type, offset, length);
+  }
+
+  int findRegionLength(String search, int length) {
+    if (length == -1) {
+      length = 0;
+      while (length < search.length) {
+        int c = search.codeUnitAt(length);
+        if (length == 0 && c == '@'.codeUnitAt(0)) {
+          length++;
+          continue;
+        }
+        if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
+            c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
+            c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
+          break;
+        }
+        length++;
+      }
+    }
+    return length;
+  }
+
+  Future prepareHighlights() {
+    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
+    return _resultsAvailable.future;
+  }
+
+  void processNotification(Notification notification) {
+    if (notification.event == SERVER_NOTIFICATION_ERROR) {
+      print('SERVER_NOTIFICATION_ERROR: ${notification.toJson()}');
+      _resultsAvailable.complete(null);
+      fail('SERVER_NOTIFICATION_ERROR');
+    }
+    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
+      var params = new AnalysisHighlightsParams.fromNotification(notification);
+      if (params.file == testFile) {
+        regions = params.regions;
+        _resultsAvailable.complete(null);
+      }
+    }
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    server.options.useAnalysisHighlight2 = true;
+    createProject();
+  }
 
   void _addLibraryForTestPart() {
     newFile(join(testFolder, 'my_lib.dart'), content: '''
@@ -1132,6 +1151,158 @@
 }
 
 @reflectiveTest
+class HighlightsWithControlFlowCollectionsTest extends HighlightsTestSupport {
+  @override
+  void createProject({Map<String, String> packageRoots}) {
+    addAnalysisOptionsFile('''
+analyzer:
+  enable-experiment:
+    - control-flow-collections
+''');
+    super.createProject(packageRoots: packageRoots);
+  }
+
+  @failingTest
+  test_KEYWORD_awaitForIn_list() async {
+    addTestFile('''
+f(a) async {
+  return [await for(var b in a) b];
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+  }
+
+  @failingTest
+  test_KEYWORD_awaitForIn_map() async {
+    addTestFile('''
+f(a, b) async {
+  return {await for(var b in a) b};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+  }
+
+  @failingTest
+  test_KEYWORD_awaitForIn_set() async {
+    addTestFile('''
+f(a, b) async {
+  return {await for(var b in a) b};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+  }
+
+  test_KEYWORD_const_list() async {
+    addTestFile('''
+var v = const [];
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+  }
+
+  test_KEYWORD_const_map() async {
+    addTestFile('''
+var v = const {0 : 1};
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+  }
+
+  test_KEYWORD_const_set() async {
+    addTestFile('''
+var v = const {0};
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+  }
+
+  test_KEYWORD_if_list() async {
+    addTestFile('''
+f(a, b) {
+  return [if (a < b) 'a'];
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+  }
+
+  test_KEYWORD_if_map() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a' : 1};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+  }
+
+  test_KEYWORD_if_set() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a'};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+  }
+
+  test_KEYWORD_ifElse_list() async {
+    addTestFile('''
+f(a, b) {
+  return [if (a < b) 'a' else 'b'];
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
+  test_KEYWORD_ifElse_map() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a' : 1 else 'b' : 2};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
+  test_KEYWORD_ifElse_set() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a' else 'b'};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
+  test_LITERAL_LIST() async {
+    addTestFile('var V = <int>[1, 2, 3];');
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
+  }
+
+  test_LITERAL_MAP() async {
+    addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
+        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
+  }
+}
+
+@reflectiveTest
 class HighlightTypeTest {
   void test_constructor() {
     expect(HighlightRegionType.CLASS,
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index 030addf..b992bc9 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -16,101 +16,13 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisNotificationHighlightsTest);
+    defineReflectiveTests(HighlightsWithControlFlowCollectionsTest);
     defineReflectiveTests(HighlightTypeTest);
   });
 }
 
 @reflectiveTest
-class AnalysisNotificationHighlightsTest extends AbstractAnalysisTest {
-  List<HighlightRegion> regions;
-
-  Completer _resultsAvailable = new Completer();
-
-  void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
-    for (HighlightRegion region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        return;
-      }
-    }
-    fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
-        '${regions.join('\n')}');
-  }
-
-  void assertHasRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    int offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertHasStringRegion(HighlightRegionType type, String str) {
-    int offset = findOffset(str);
-    int length = str.length;
-    assertHasRawRegion(type, offset, length);
-  }
-
-  void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
-    for (HighlightRegion region in regions) {
-      if (region.offset == offset &&
-          region.length == length &&
-          region.type == type) {
-        fail(
-            'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
-            '${regions.join('\n')}');
-      }
-    }
-  }
-
-  void assertNoRegion(HighlightRegionType type, String search,
-      [int length = -1]) {
-    int offset = findOffset(search);
-    length = findRegionLength(search, length);
-    assertNoRawRegion(type, offset, length);
-  }
-
-  int findRegionLength(String search, int length) {
-    if (length == -1) {
-      length = 0;
-      while (length < search.length) {
-        int c = search.codeUnitAt(length);
-        if (length == 0 && c == '@'.codeUnitAt(0)) {
-          length++;
-          continue;
-        }
-        if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
-            c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
-            c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
-          break;
-        }
-        length++;
-      }
-    }
-    return length;
-  }
-
-  Future prepareHighlights() {
-    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
-    return _resultsAvailable.future;
-  }
-
-  void processNotification(Notification notification) {
-    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
-      var params = new AnalysisHighlightsParams.fromNotification(notification);
-      if (params.file == testFile) {
-        regions = params.regions;
-        _resultsAvailable.complete(null);
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
-  }
-
+class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
   test_ANNOTATION_hasArguments() async {
     addTestFile('''
 class AAA {
@@ -781,6 +693,17 @@
     assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
   }
 
+  test_KEYWORD_ifElse_statement() async {
+    addTestFile('''
+f(a, b) {
+  if (a < b) {} else {}
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
   test_KEYWORD_mixin() async {
     addTestFile('''
 mixin M {}
@@ -971,6 +894,102 @@
     assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
     assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
   }
+}
+
+class HighlightsTestSupport extends AbstractAnalysisTest {
+  List<HighlightRegion> regions;
+
+  Completer _resultsAvailable = new Completer();
+
+  void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
+    for (HighlightRegion region in regions) {
+      if (region.offset == offset &&
+          region.length == length &&
+          region.type == type) {
+        return;
+      }
+    }
+    fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
+        '${regions.join('\n')}');
+  }
+
+  void assertHasRegion(HighlightRegionType type, String search,
+      [int length = -1]) {
+    int offset = findOffset(search);
+    length = findRegionLength(search, length);
+    assertHasRawRegion(type, offset, length);
+  }
+
+  void assertHasStringRegion(HighlightRegionType type, String str) {
+    int offset = findOffset(str);
+    int length = str.length;
+    assertHasRawRegion(type, offset, length);
+  }
+
+  void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
+    for (HighlightRegion region in regions) {
+      if (region.offset == offset &&
+          region.length == length &&
+          region.type == type) {
+        fail(
+            'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
+            '${regions.join('\n')}');
+      }
+    }
+  }
+
+  void assertNoRegion(HighlightRegionType type, String search,
+      [int length = -1]) {
+    int offset = findOffset(search);
+    length = findRegionLength(search, length);
+    assertNoRawRegion(type, offset, length);
+  }
+
+  int findRegionLength(String search, int length) {
+    if (length == -1) {
+      length = 0;
+      while (length < search.length) {
+        int c = search.codeUnitAt(length);
+        if (length == 0 && c == '@'.codeUnitAt(0)) {
+          length++;
+          continue;
+        }
+        if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
+            c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
+            c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
+          break;
+        }
+        length++;
+      }
+    }
+    return length;
+  }
+
+  Future prepareHighlights() {
+    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
+    return _resultsAvailable.future;
+  }
+
+  void processNotification(Notification notification) {
+    if (notification.event == SERVER_NOTIFICATION_ERROR) {
+      print('SERVER_NOTIFICATION_ERROR: ${notification.toJson()}');
+      _resultsAvailable.complete(null);
+      fail('SERVER_NOTIFICATION_ERROR');
+    }
+    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
+      var params = new AnalysisHighlightsParams.fromNotification(notification);
+      if (params.file == testFile) {
+        regions = params.regions;
+        _resultsAvailable.complete(null);
+      }
+    }
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    createProject();
+  }
 
   void _addLibraryForTestPart() {
     newFile(join(testFolder, 'my_lib.dart'), content: '''
@@ -981,6 +1000,158 @@
 }
 
 @reflectiveTest
+class HighlightsWithControlFlowCollectionsTest extends HighlightsTestSupport {
+  @override
+  void createProject({Map<String, String> packageRoots}) {
+    addAnalysisOptionsFile('''
+analyzer:
+  enable-experiment:
+    - control-flow-collections
+''');
+    super.createProject(packageRoots: packageRoots);
+  }
+
+  @failingTest
+  test_KEYWORD_awaitForIn_list() async {
+    addTestFile('''
+f(a) async {
+  return [await for(var b in a) b];
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+  }
+
+  @failingTest
+  test_KEYWORD_awaitForIn_map() async {
+    addTestFile('''
+f(a, b) async {
+  return {await for(var b in a) b};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+  }
+
+  @failingTest
+  test_KEYWORD_awaitForIn_set() async {
+    addTestFile('''
+f(a, b) async {
+  return {await for(var b in a) b};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'await');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+  }
+
+  test_KEYWORD_const_list() async {
+    addTestFile('''
+var v = const [];
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+  }
+
+  test_KEYWORD_const_map() async {
+    addTestFile('''
+var v = const {0 : 1};
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+  }
+
+  test_KEYWORD_const_set() async {
+    addTestFile('''
+var v = const {0};
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+  }
+
+  test_KEYWORD_if_list() async {
+    addTestFile('''
+f(a, b) {
+  return [if (a < b) 'a'];
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+  }
+
+  test_KEYWORD_if_map() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a' : 1};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+  }
+
+  test_KEYWORD_if_set() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a'};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+  }
+
+  test_KEYWORD_ifElse_list() async {
+    addTestFile('''
+f(a, b) {
+  return [if (a < b) 'a' else 'b'];
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
+  test_KEYWORD_ifElse_map() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a' : 1 else 'b' : 2};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
+  test_KEYWORD_ifElse_set() async {
+    addTestFile('''
+f(a, b) {
+  return {if (a < b) 'a' else 'b'};
+}
+''');
+    await prepareHighlights();
+    assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+    assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+  }
+
+  test_LITERAL_LIST_withControlFlow() async {
+    addTestFile('var V = <int>[1, 2, 3];');
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
+  }
+
+  test_LITERAL_MAP_withControlFlow() async {
+    addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
+    await prepareHighlights();
+    assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
+        "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
+  }
+}
+
+@reflectiveTest
 class HighlightTypeTest {
   void test_constructor() {
     expect(HighlightRegionType.CLASS,
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index 4401087..539354b 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -71,7 +71,7 @@
   }
 
   /**
-   * Validates that there is no an [ImplementedClass] at the offset of [search].
+   * Validates that there is no [ImplementedMember] at the offset of [search].
    *
    * If [length] is not specified explicitly, then length of an identifier
    * from [search] is used.
@@ -167,6 +167,21 @@
     assertHasImplementedClass('A {');
   }
 
+  test_class_inMixin() async {
+    addTestFile('''
+class A {} // ref
+class B {} // ref
+class C {} // ref
+class D {} // ref
+mixin M on A, B implements C, D {}
+''');
+    await prepareImplementedElements();
+    assertHasImplementedClass('A {} // ref');
+    assertHasImplementedClass('B {} // ref');
+    assertHasImplementedClass('C {} // ref');
+    assertHasImplementedClass('D {} // ref');
+  }
+
   test_class_mixed() async {
     addTestFile('''
 class A {}
@@ -313,6 +328,40 @@
     assertHasImplementedMember('m(); // A');
   }
 
+  test_mixin_implemented() async {
+    addTestFile('''
+mixin M { // ref
+  void foo() {} // ref
+  void bar() {} // ref
+}
+
+class A implements M {
+  void foo() {}
+}
+''');
+    await prepareImplementedElements();
+    assertHasImplementedClass('M { // ref');
+    assertHasImplementedMember('foo() {} // ref');
+    assertNoImplementedMember('bar() {} // ref');
+  }
+
+  test_mixin_mixed() async {
+    addTestFile('''
+mixin M { // ref
+  void foo() {} // ref
+  void bar() {} // ref
+}
+
+class A extends Object with M {
+  void foo() {}
+}
+''');
+    await prepareImplementedElements();
+    assertHasImplementedClass('M { // ref');
+    assertHasImplementedMember('foo() {} // ref');
+    assertNoImplementedMember('bar() {} // ref');
+  }
+
   test_setter_withField() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index dfaec37..c840005 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -305,6 +305,38 @@
     assertHasInterfaceMember('m() {} // in A');
   }
 
+  test_inMixin_interface_method_direct_single() async {
+    addTestFile('''
+class A {
+  m() {} // in A
+}
+
+mixin M implements A {
+  m() {} // in M
+}
+''');
+    await prepareOverrides();
+    assertHasOverride('m() {} // in M');
+    assertNoSuperMember();
+    assertHasInterfaceMember('m() {} // in A');
+  }
+
+  test_inMixin_superclassConstraint_method_direct() async {
+    addTestFile('''
+class A {
+  m() {} // in A
+}
+
+mixin M on A {
+  m() {} // in M
+}
+''');
+    await prepareOverrides();
+    assertHasOverride('m() {} // in M');
+    assertHasSuperElement('m() {} // in A');
+    assertNoInterfaceMembers();
+  }
+
   test_interface_method_direct_multiple() async {
     addTestFile('''
 class IA {
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index bb6530d..dc03a1b 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -31,7 +31,7 @@
   }
 
   test_fileDoesNotExist() async {
-    String file = '$projectPath/doesNotExist.dart';
+    String file = convertPath('$projectPath/doesNotExist.dart');
     Response response = await _setPriorityFile(file);
     expect(response, isResponseSuccess('0'));
   }
@@ -48,7 +48,7 @@
   test_fileInSdk() async {
     addTestFile('');
     // set priority files
-    String filePath = '/lib/convert/convert.dart';
+    String filePath = convertPath('/lib/convert/convert.dart');
     Response response = await _setPriorityFile(filePath);
     expect(response, isResponseSuccess('0'));
     // verify
@@ -56,14 +56,14 @@
   }
 
   test_fileNotInAnalysisRoot() async {
-    String path = '/other/file.dart';
+    String path = convertPath('/other/file.dart');
     newFile(path);
     await _setPriorityFile(path);
     _verifyPriorityFiles(path);
   }
 
   test_ignoredInAnalysisOptions() async {
-    String sampleFile = '$projectPath/samples/sample.dart';
+    String sampleFile = convertPath('$projectPath/samples/sample.dart');
     newFile('$projectPath/.analysis_options', content: r'''
 analyzer:
   exclude:
@@ -78,7 +78,7 @@
   test_ignoredInAnalysisOptions_inChildContext() async {
     newFile('$projectPath/.packages');
     newFile('$projectPath/child/.packages');
-    String sampleFile = '$projectPath/child/samples/sample.dart';
+    String sampleFile = convertPath('$projectPath/child/samples/sample.dart');
     newFile('$projectPath/child/.analysis_options', content: r'''
 analyzer:
   exclude:
@@ -93,7 +93,7 @@
   test_ignoredInAnalysisOptions_inRootContext() async {
     newFile('$projectPath/.packages');
     newFile('$projectPath/child/.packages');
-    String sampleFile = '$projectPath/child/samples/sample.dart';
+    String sampleFile = convertPath('$projectPath/child/samples/sample.dart');
     newFile('$projectPath/.analysis_options', content: r'''
 analyzer:
   exclude:
@@ -105,6 +105,26 @@
     _verifyPriorityFiles(sampleFile);
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request =
+        new AnalysisSetPriorityFilesParams(['test.dart']).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new AnalysisSetPriorityFilesParams(
+        [convertPath('/foo/../bar/test.dart')]).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_sentToPlugins() async {
     addTestFile('');
     // set priority files
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index 5ab9a4e..9245872 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -14,6 +14,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -60,6 +61,28 @@
     }
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new AnalysisUpdateContentParams(
+      {'test.dart': AddContentOverlay('')},
+    ).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new AnalysisUpdateContentParams(
+      {convertPath('/foo/../bar/test.dart'): AddContentOverlay('')},
+    ).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_multiple_contexts() async {
     String project1path = convertPath('/project1');
     String project2path = convertPath('/project2');
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 8415bc9..6135864 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -73,6 +73,12 @@
 
   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];
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index d0cd508..692cbb4 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -163,19 +163,13 @@
         <String>["1+DateTime", "2+List"],
         failingTests: '12');
 
-    buildTests(
-        'testCommentSnippets030',
-        '''
+    buildTests('testCommentSnippets030', '''
 class Bar<T extends Foo> {const Bar(!1T!2 k);T!3 m(T!4 a, T!5 b){}final T!6 f = null;}''',
-        <String>["1+T", "2+T", "3+T", "4+T", "5+T", "6+T"],
-        failingTests: '123456');
+        <String>["1+T", "2+T", "3+T", "4+T", "5+T", "6+T"]);
 
-    buildTests(
-        'testCommentSnippets031',
-        '''
+    buildTests('testCommentSnippets031', '''
 class Bar<T extends Foo> {m(x){if (x is !1) return;if (x is!!!2)}}''',
-        <String>["1+Bar", "1+T", "2+T", "2+Bar"],
-        failingTests: '12');
+        <String>["1+Bar", "1+T", "2+T", "2+Bar"]);
 
     buildTests(
         'testCommentSnippets032',
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index e50b52f..ae88bc8 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -105,8 +105,9 @@
   }
 
   test_setPriorityFiles_invalid() {
-    var request = new AnalysisSetPriorityFilesParams(['/project/lib.dart'])
-        .toRequest('0');
+    var request = new AnalysisSetPriorityFilesParams(
+      [convertPath('/project/lib.dart')],
+    ).toRequest('0');
     var response = handler.handleRequest(request);
     expect(response, isResponseSuccess('0'));
   }
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index f22f2f2..fa74e67 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -19,6 +19,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'domain_completion_util.dart';
+import 'mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -251,7 +252,7 @@
 
   test_import_uri_with_trailing() {
     final filePath = '/project/bin/testA.dart';
-    final incompleteImportText = convertAbsolutePathToUri('/project/bin/t');
+    final incompleteImportText = toUriStr('/project/bin/t');
     newFile(filePath, content: 'library libA;');
     addTestFile('''
     import "$incompleteImportText^.dart";
@@ -260,8 +261,7 @@
       expect(replacementOffset,
           equals(completionOffset - incompleteImportText.length));
       expect(replacementLength, equals(5 + incompleteImportText.length));
-      assertHasResult(
-          CompletionSuggestionKind.IMPORT, convertAbsolutePathToUri(filePath));
+      assertHasResult(CompletionSuggestionKind.IMPORT, toUriStr(filePath));
       assertNoResult('test');
     });
   }
@@ -509,7 +509,7 @@
   foo(bar) => 0;''');
     addTestFile('''
   library libA;
-  part "${convertAbsolutePathToUri('/testA.dart')}";
+  part "${toUriStr('/testA.dart')}";
   import "dart:math";
   /// The [^]
   main(aaa, bbb) {}
@@ -548,6 +548,27 @@
     });
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request =
+        new CompletionGetSuggestionsParams('test.dart', 0).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new CompletionGetSuggestionsParams(
+            convertPath('/foo/../bar/test.dart'), 0)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_invocation() {
     addTestFile('class A {b() {}} main() {A a; a.^}');
     return getSuggestions().then((_) {
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index edd543c..3f322e6 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -37,15 +37,20 @@
   }
 
   void expectSuggestion(DartFixSuggestion suggestion, String partialText,
-      int offset, int length) {
+      [int offset, int length]) {
     expect(suggestion.description, contains(partialText));
-    expect(suggestion.location.offset, offset);
-    expect(suggestion.location.length, length);
+    if (offset == null) {
+      expect(suggestion.location, isNull);
+    } else {
+      expect(suggestion.location.offset, offset);
+      expect(suggestion.location.length, length);
+    }
   }
 
-  Future<EditDartfixResult> performFix() async {
+  Future<EditDartfixResult> performFix({List<String> includedFixes}) async {
     final id = nextRequestId;
     final params = new EditDartfixParams([projectPath]);
+    params.includedFixes = includedFixes;
     final request = new Request(id, 'edit.dartfix', params.toJson());
 
     final response = await new EditDartFix(server, request).compute();
@@ -63,12 +68,12 @@
   }
 
   test_dartfix_convertClassToMixin() async {
-    createProject();
     addTestFile('''
 class A {}
 class B extends A {}
 class C with B {}
     ''');
+    createProject();
     EditDartfixResult result = await performFix();
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'mixin', 17, 1);
@@ -80,10 +85,10 @@
   }
 
   test_dartfix_convertToIntLiteral() async {
-    createProject();
     addTestFile('''
 const double myDouble = 42.0;
     ''');
+    createProject();
     EditDartfixResult result = await performFix();
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'int literal', 24, 4);
@@ -93,13 +98,13 @@
   }
 
   test_dartfix_moveTypeArgumentToClass() async {
-    createProject();
     addTestFile('''
 class A<T> { A.from(Object obj) { } }
 main() {
   print(new A.from<String>([]));
 }
     ''');
+    createProject();
     EditDartfixResult result = await performFix();
     expect(result.suggestions, hasLength(1));
     expectSuggestion(result.suggestions[0], 'type arguments', 65, 8);
@@ -118,44 +123,23 @@
   enable-experiment:
     - non-nullable
 ''');
-
-    createProject();
     addTestFile('''
-main() {
-  functionWithNullableParam(new List<Object>(1));
-  functionWithNullableParam(null);
-}
-
-void functionWithNullableParam(Object object) {
-  if (object == null) {
-    print('object is null');
-  } else {
-    print('object is not-null');
-  }
-  List<Object> list = null;
-  list = <Object>[];
-  list.add(object);
+int f(int i) => 0;
+int g(int i) => f(i);
+void test() {
+  g(null);
 }
 ''');
-    EditDartfixResult result = await performFix();
-    expect(result.suggestions, hasLength(1));
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
     expect(result.hasErrors, isFalse);
-    expectSuggestion(result.suggestions[0], 'non-nullable', 46, 6);
     expectEdits(result.edits, '''
-main() {
-  functionWithNullableParam(new List<Object?>(1));
-  functionWithNullableParam(null);
-}
-
-void functionWithNullableParam(Object? object) {
-  if (object == null) {
-    print('object is null');
-  } else {
-    print('object is not-null');
-  }
-  List<Object?>? list = null;
-  list = <Object?>[];
-  list.add(object);
+int f(int? i) => 0;
+int g(int? i) => f(i);
+void test() {
+  g(null);
 }
 ''');
   }
@@ -168,10 +152,10 @@
     - lib/**
 ''');
 
-    createProject();
     addTestFile('''
 const double myDouble = 42.0;
     ''');
+    createProject();
 
     // Assert no suggestions now that source has been excluded
     final result = await performFix();
@@ -180,7 +164,6 @@
   }
 
   test_dartfix_partFile() async {
-    createProject();
     newFile('/project/lib/lib.dart', content: '''
 library lib2;
 part 'fileToBeFixed.dart';
@@ -189,6 +172,7 @@
 part of lib2;
 const double myDouble = 42.0;
     ''');
+    createProject();
 
     // Assert dartfix suggestions
     EditDartfixResult result = await performFix();
@@ -201,11 +185,11 @@
   }
 
   test_dartfix_partFile_loose() async {
-    createProject();
     addTestFile('''
 part of lib2;
 const double myDouble = 42.0;
     ''');
+    createProject();
 
     // Assert dartfix suggestions
     EditDartfixResult result = await performFix();
diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart
index d8a77f0..51c4da0 100644
--- a/pkg/analysis_server/test/edit/assists_test.dart
+++ b/pkg/analysis_server/test/edit/assists_test.dart
@@ -16,6 +16,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -68,6 +69,26 @@
     _assertHasChange(message, 'xmain() {}');
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditGetAssistsParams('test.dart', 0, 0).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        new EditGetAssistsParams(convertPath('/foo/../bar/test.dart'), 0, 0)
+            .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_removeTypeAnnotation() async {
     addTestFile('''
 main() {
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index c9c5eaa..2fa8a24 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -16,6 +16,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -43,7 +44,7 @@
         await _getFixesAt('Completer<String>');
     expect(errorFixes, hasLength(1));
     AnalysisError error = errorFixes[0].error;
-    expect(error.severity, AnalysisErrorSeverity.WARNING);
+    expect(error.severity, AnalysisErrorSeverity.ERROR);
     expect(error.type, AnalysisErrorType.STATIC_WARNING);
     List<SourceChange> fixes = errorFixes[0].fixes;
     expect(fixes, hasLength(3));
@@ -96,6 +97,26 @@
     }
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditGetFixesParams('test.dart', 0).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        new EditGetFixesParams(convertPath('/foo/../bar/test.dart'), 0)
+            .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_overlayOnlyFile() async {
     createProject();
     testCode = '''
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
index e8424aa..116427e 100644
--- a/pkg/analysis_server/test/edit/organize_directives_test.dart
+++ b/pkg/analysis_server/test/edit/organize_directives_test.dart
@@ -55,13 +55,34 @@
   }
 
   Future test_BAD_notDartFile() async {
-    Request request =
-        new EditOrganizeDirectivesParams('/not-a-Dart-file.txt').toRequest('0');
+    Request request = new EditOrganizeDirectivesParams(
+      convertPath('/not-a-Dart-file.txt'),
+    ).toRequest('0');
     Response response = await waitResponse(request);
     expect(
         response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED));
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditOrganizeDirectivesParams('test.dart').toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        new EditOrganizeDirectivesParams(convertPath('/foo/../bar/test.dart'))
+            .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   Future test_OK_remove_duplicateImports_withSamePrefix() {
     addTestFile('''
 library lib;
diff --git a/pkg/analysis_server/test/edit/postfix_completion_test.dart b/pkg/analysis_server/test/edit/postfix_completion_test.dart
index 00139e5..c8cede9 100644
--- a/pkg/analysis_server/test/edit/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/edit/postfix_completion_test.dart
@@ -10,6 +10,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -45,6 +46,27 @@
 ''');
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditGetPostfixCompletionParams('test.dart', '.for', 0)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new EditGetPostfixCompletionParams(
+            convertPath('/foo/../bar/test.dart'), '.for', 0)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   void _assertHasChange(String message, String expectedCode, [Function cmp]) {
     if (change.message == message) {
       if (!change.edits.isEmpty) {
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index da70280..df6558d 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -352,6 +352,32 @@
 ''');
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditGetRefactoringParams(
+            RefactoringKind.EXTRACT_LOCAL_VARIABLE, 'test.dart', 0, 0, true)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new EditGetRefactoringParams(
+            RefactoringKind.EXTRACT_LOCAL_VARIABLE,
+            convertPath('/foo/../bar/test.dart'),
+            0,
+            0,
+            true)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_names() async {
     addTestFile('''
 class TreeItem {}
@@ -901,6 +927,27 @@
     expect(kinds, contains(RefactoringKind.EXTRACT_WIDGET));
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditGetAvailableRefactoringsParams('test.dart', 0, 0)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new EditGetAvailableRefactoringsParams(
+            convertPath('/foo/../bar/test.dart'), 0, 0)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   Future test_rename_hasElement_class() {
     return assertHasRenameRefactoring('''
 class Test {}
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index 04828b6..29c9cb9 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -55,13 +55,34 @@
   }
 
   test_BAD_notDartFile() async {
-    Request request =
-        new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0');
+    Request request = new EditSortMembersParams(
+      convertPath('/not-a-Dart-file.txt'),
+    ).toRequest('0');
     Response response = await waitResponse(request);
     expect(response,
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request = new EditSortMembersParams('test.dart').toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request =
+        new EditSortMembersParams(convertPath('/foo/../bar/test.dart'))
+            .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_OK_afterWaitForAnalysis() async {
     addTestFile('''
 class C {}
diff --git a/pkg/analysis_server/test/edit/statement_completion_test.dart b/pkg/analysis_server/test/edit/statement_completion_test.dart
index 50f834b..4b381be 100644
--- a/pkg/analysis_server/test/edit/statement_completion_test.dart
+++ b/pkg/analysis_server/test/edit/statement_completion_test.dart
@@ -10,6 +10,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../analysis_abstract.dart';
+import '../mocks.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -28,6 +29,27 @@
     handler = new EditDomainHandler(server);
   }
 
+  test_invalidFilePathFormat_notAbsolute() async {
+    var request =
+        new EditGetStatementCompletionParams('test.dart', 0).toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
+  test_invalidFilePathFormat_notNormalized() async {
+    var request = new EditGetStatementCompletionParams(
+            convertPath('/foo/../bar/test.dart'), 0)
+        .toRequest('0');
+    var response = await waitResponse(request);
+    expect(
+      response,
+      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
+    );
+  }
+
   test_plainEnterFromStart() async {
     addTestFile('''
 main() {
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart
index 4da91dc..0a7948b 100644
--- a/pkg/analysis_server/test/integration/analysis/error_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -88,7 +88,7 @@
   }
 }
 ''');
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     await sendAnalysisUpdateOptions(
         new AnalysisOptions()..enableSuperMixins = true);
     standardAnalysisSetup();
diff --git a/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart b/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart
index 286a24e..dee7a87 100644
--- a/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_reachable_sources_test.dart
@@ -35,7 +35,7 @@
     await analysisFinished;
 
     AnalysisGetReachableSourcesResult result =
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
         await sendAnalysisGetReachableSources(pathname);
     Map<String, List<String>> sources = result.sources;
     List<String> keys = sources.keys.toList();
diff --git a/pkg/analysis_server/test/integration/analysis/update_options_test.dart b/pkg/analysis_server/test/integration/analysis/update_options_test.dart
index b61db22..871e4fe 100644
--- a/pkg/analysis_server/test/integration/analysis/update_options_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/update_options_test.dart
@@ -30,14 +30,14 @@
 ''');
     standardAnalysisSetup();
 
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     await sendAnalysisUpdateOptions(
         new AnalysisOptions()..generateHints = false);
     await sendAnalysisReanalyze();
     await analysisFinished;
     expect(getErrors(pathname), isEmpty);
 
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     await sendAnalysisUpdateOptions(
         new AnalysisOptions()..generateHints = true);
     await sendAnalysisReanalyze();
diff --git a/pkg/analysis_server/test/integration/coverage.md b/pkg/analysis_server/test/integration/coverage.md
index dcec50a..6f13a5e 100644
--- a/pkg/analysis_server/test/integration/coverage.md
+++ b/pkg/analysis_server/test/integration/coverage.md
@@ -30,18 +30,23 @@
 - [x] analysis.overrides
 
 ## completion domain
+- [ ] completion.availableSuggestions
+- [ ] completion.getSuggestionDetails
 - [x] completion.getSuggestions
+- [ ] completion.registerLibraryPaths
 - [ ] completion.results
+- [ ] completion.setSubscriptions
 
 ## diagnostic domain
 - [x] diagnostic.getDiagnostics
 - [x] diagnostic.getServerPort
 
 ## edit domain
-- [ ] edit.dartfix
+- [x] edit.dartfix
 - [x] edit.format
 - [x] edit.getAssists
 - [x] edit.getAvailableRefactorings
+- [x] edit.getDartfixInfo
 - [x] edit.getFixes
 - [x] edit.getPostfixCompletion
 - [x] edit.getRefactoring
diff --git a/pkg/analysis_server/test/integration/edit/dartfix_test.dart b/pkg/analysis_server/test/integration/edit/dartfix_test.dart
new file mode 100644
index 0000000..d389950
--- /dev/null
+++ b/pkg/analysis_server/test/integration/edit/dartfix_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(DartfixTest);
+  });
+}
+
+@reflectiveTest
+class DartfixTest extends AbstractAnalysisServerIntegrationTest {
+  void setupTarget() {
+    writeFile(sourcePath('test.dart'), '''
+class A {}
+class B extends A {}
+class C with B {}
+    ''');
+    standardAnalysisSetup();
+  }
+
+  test_dartfix() async {
+    setupTarget();
+    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)]);
+    expect(result.hasErrors, isFalse);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.edits.length, greaterThanOrEqualTo(1));
+  }
+
+  test_dartfix_exclude() async {
+    setupTarget();
+    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
+        excludedFixes: ['use-mixin']);
+    expect(result.hasErrors, isFalse);
+    expect(result.suggestions.length, 0);
+    expect(result.edits.length, 0);
+  }
+
+  test_dartfix_exclude_other() async {
+    setupTarget();
+    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
+        excludedFixes: ['double-to-int']);
+    expect(result.hasErrors, isFalse);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.edits.length, greaterThanOrEqualTo(1));
+  }
+
+  test_dartfix_include() async {
+    setupTarget();
+    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
+        includedFixes: ['use-mixin']);
+    expect(result.hasErrors, isFalse);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.edits.length, greaterThanOrEqualTo(1));
+  }
+
+  test_dartfix_include_other() async {
+    setupTarget();
+    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
+        includedFixes: ['double-to-int']);
+    expect(result.hasErrors, isFalse);
+    expect(result.suggestions.length, 0);
+    expect(result.edits.length, 0);
+  }
+
+  test_dartfix_required() async {
+    setupTarget();
+    EditDartfixResult result = await sendEditDartfix([(sourceDirectory.path)],
+        includeRequiredFixes: true);
+    expect(result.hasErrors, isFalse);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.edits.length, greaterThanOrEqualTo(1));
+  }
+}
diff --git a/pkg/analysis_server/test/integration/edit/get_dartfix_info_test.dart b/pkg/analysis_server/test/integration/edit/get_dartfix_info_test.dart
new file mode 100644
index 0000000..2d92b6a
--- /dev/null
+++ b/pkg/analysis_server/test/integration/edit/get_dartfix_info_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.
+
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(GetDartfixInfoTest);
+  });
+}
+
+@reflectiveTest
+class GetDartfixInfoTest extends AbstractAnalysisServerIntegrationTest {
+  test_getDartfixInfo() async {
+    standardAnalysisSetup();
+    EditGetDartfixInfoResult info = await sendEditGetDartfixInfo();
+    expect(info.fixes.length, greaterThanOrEqualTo(3));
+    var fix = info.fixes.firstWhere((f) => f.name == 'use-mixin');
+    expect(fix.isRequired, isTrue);
+  }
+}
diff --git a/pkg/analysis_server/test/integration/edit/test_all.dart b/pkg/analysis_server/test/integration/edit/test_all.dart
index 6706806..3a71a95 100644
--- a/pkg/analysis_server/test/integration/edit/test_all.dart
+++ b/pkg/analysis_server/test/integration/edit/test_all.dart
@@ -4,10 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'dartfix_test.dart' as dartfix_test;
 import 'format_test.dart' as format_test;
 import 'get_assists_test.dart' as get_assists_test;
 import 'get_available_refactorings_test.dart'
     as get_available_refactorings_test;
+import 'get_dartfix_info_test.dart' as get_dartfix_info_test;
 import 'get_fixes_test.dart' as get_fixes_test;
 import 'get_postfix_completion_test.dart' as get_postfix_completion_test;
 import 'get_refactoring_test.dart' as get_refactoring_test;
@@ -22,9 +24,11 @@
 
 main() {
   defineReflectiveSuite(() {
+    dartfix_test.main();
     format_test.main();
     get_assists_test.main();
     get_available_refactorings_test.main();
+    get_dartfix_info_test.main();
     get_fixes_test.main();
     get_refactoring_test.main();
     get_postfix_completion_test.main();
diff --git a/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart b/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart
index a95fc27..82c3739 100644
--- a/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart
+++ b/pkg/analysis_server/test/integration/execution/set_subscriptions_test.dart
@@ -17,7 +17,7 @@
 class SetSubscriptionsTest extends AbstractAnalysisServerIntegrationTest {
   test_subscribe() async {
     standardAnalysisSetup();
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     await sendExecutionSetSubscriptions([ExecutionService.LAUNCH_DATA]);
   }
 }
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
new file mode 100644
index 0000000..8f21d53
--- /dev/null
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.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.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/src/lsp/channel/lsp_byte_stream_channel.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:path/path.dart';
+
+import '../../lsp/server_abstract.dart';
+
+class AbstractLspAnalysisServerIntegrationTest
+    with
+        ResourceProviderMixin,
+        ClientCapabilitiesHelperMixin,
+        LspAnalysisServerTestMixin {
+  LspServerClient client;
+
+  final Map<int, Completer<ResponseMessage>> _completers = {};
+
+  @override
+  Stream<Message> get serverToClient => client.serverToClient;
+
+  @override
+  void sendNotificationToServer(NotificationMessage notification) =>
+      client.channel.sendNotification(notification);
+
+  @override
+  Future<ResponseMessage> sendRequestToServer(RequestMessage request) {
+    final completer = new Completer<ResponseMessage>();
+    final id = request.id.map(
+        (num) => num, (string) => throw 'String IDs not supported in tests');
+    _completers[id] = completer;
+
+    client.channel.sendRequest(request);
+
+    return completer.future;
+  }
+
+  @override
+  void sendResponseToServer(ResponseMessage response) =>
+      client.channel.sendResponse(response);
+
+  Future setUp() async {
+    client = new LspServerClient();
+    await client.start();
+    client.serverToClient.listen((message) {
+      if (message is ResponseMessage) {
+        final id = message.id.map((num) => num,
+            (string) => throw 'String IDs not supported in tests');
+
+        final completer = _completers[id];
+        if (completer == null) {
+          throw 'Response with ID $id was unexpected';
+        } else {
+          _completers.remove(id);
+          completer.complete(message);
+        }
+      }
+    });
+  }
+
+  tearDown() {
+    // TODO(dantup): Graceful shutdown?
+    client.close();
+  }
+}
+
+class LspServerClient {
+  Process _process;
+  LspByteStreamServerChannel channel;
+  final StreamController<Message> _serverToClient =
+      new StreamController<Message>.broadcast();
+
+  Future<int> get exitCode => _process.exitCode;
+
+  Stream<Message> get serverToClient => _serverToClient.stream;
+
+  void close() {
+    channel.close();
+    _process.kill();
+  }
+
+  /**
+   * Find the root directory of the analysis_server package by proceeding
+   * upward to the 'test' dir, and then going up one more directory.
+   */
+  String findRoot(String pathname) {
+    while (!['benchmark', 'test'].contains(basename(pathname))) {
+      String parent = dirname(pathname);
+      if (parent.length >= pathname.length) {
+        throw new Exception("Can't find root directory");
+      }
+      pathname = parent;
+    }
+    return dirname(pathname);
+  }
+
+  Future start() async {
+    if (_process != null) {
+      throw new Exception('Process already started');
+    }
+
+    String dartBinary = Platform.executable;
+
+    // TODO(dantup): The other servers integration tests can run with a snapshot
+    // which is much faster - we may wish to investigate doing the same here.
+    final rootDir =
+        findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+    final serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+
+    final arguments = [serverPath, '--lsp', '--suppress-analytics'];
+    _process = await Process.start(dartBinary, arguments);
+    _process.exitCode.then((int code) {
+      if (code != 0) {
+        // TODO(dantup): Log/fail tests...
+      }
+    });
+
+    channel = new LspByteStreamServerChannel(
+        _process.stdout, _process.stdin, InstrumentationService.NULL_SERVICE);
+    channel.listen(_serverToClient.add);
+  }
+}
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
new file mode 100644
index 0000000..0e3c8c0
--- /dev/null
+++ b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'integration_tests.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ServerTest);
+  });
+}
+
+@reflectiveTest
+class ServerTest extends AbstractLspAnalysisServerIntegrationTest {
+  test_exit_afterShutdown() async {
+    await sendShutdown();
+    sendExit();
+
+    await client.channel.closed.timeout(const Duration(seconds: 10),
+        onTimeout: () =>
+            fail('Server channel did not close within 10 seconds'));
+
+    final exitCode = await client.exitCode.timeout(const Duration(seconds: 10),
+        onTimeout: () => fail('Server process did not exit within 10 seconds'));
+
+    expect(exitCode, equals(0));
+  }
+
+  @failingTest
+  test_exit_withoutShutdown() async {
+    sendExit();
+
+    await client.channel.closed.timeout(const Duration(seconds: 10),
+        onTimeout: () =>
+            fail('Server channel did not close within 10 seconds'));
+
+    final exitCode = await client.exitCode.timeout(const Duration(seconds: 10),
+        onTimeout: () => fail('Server process did not exit within 10 seconds'));
+
+    // TODO(dantup): Fix the server so this works.
+    expect(exitCode, equals(1));
+  }
+}
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index 65b4cec..c536416 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -1056,6 +1056,105 @@
   }
 
   /**
+   * Subscribe for completion services. All previous subscriptions are replaced
+   * by the given set of services.
+   *
+   * It is an error if any of the elements in the list are not valid services.
+   * If there is an error, then the current subscriptions will remain
+   * unchanged.
+   *
+   * Parameters
+   *
+   * subscriptions: List<CompletionService>
+   *
+   *   A list of the services being subscribed to.
+   */
+  Future sendCompletionSetSubscriptions(
+      List<CompletionService> subscriptions) async {
+    var params = new CompletionSetSubscriptionsParams(subscriptions).toJson();
+    var result = await server.send("completion.setSubscriptions", params);
+    outOfTestExpect(result, isNull);
+    return null;
+  }
+
+  /**
+   * The client can make this request to express interest in certain libraries
+   * to receive completion suggestions from based on the client path. If this
+   * request is received before the client has used
+   * 'completion.setSubscriptions' to subscribe to the
+   * AVAILABLE_SUGGESTION_SETS service, then an error of type
+   * NOT_SUBSCRIBED_TO_AVAILABLE_SUGGESTION_SETS will be generated. All
+   * previous paths are replaced by the given set of paths.
+   *
+   * Parameters
+   *
+   * paths: List<LibraryPathSet>
+   *
+   *   A list of objects each containing a path and the additional libraries
+   *   from which the client is interested in receiving completion suggestions.
+   *   If one configured path is beneath another, the descendent will override
+   *   the ancestors' configured libraries of interest.
+   */
+  Future sendCompletionRegisterLibraryPaths(List<LibraryPathSet> paths) async {
+    var params = new CompletionRegisterLibraryPathsParams(paths).toJson();
+    var result = await server.send("completion.registerLibraryPaths", params);
+    outOfTestExpect(result, isNull);
+    return null;
+  }
+
+  /**
+   * Clients must make this request when the user has selected a completion
+   * suggestion from an AvailableSuggestionSet. Analysis server will respond
+   * with the text to insert as well as any SourceChange that needs to be
+   * applied in case the completion requires an additional import to be added.
+   * It is an error if the id is no longer valid, for instance if the library
+   * has been removed after the completion suggestion is accepted.
+   *
+   * Parameters
+   *
+   * file: FilePath
+   *
+   *   The path of the file into which this completion is being inserted.
+   *
+   * id: int
+   *
+   *   The identifier of the AvailableSuggestionSet containing the selected
+   *   label.
+   *
+   * label: String
+   *
+   *   The label from the AvailableSuggestionSet with the `id` for which
+   *   insertion information is requested.
+   *
+   * offset: int
+   *
+   *   The offset in the file where the completion will be inserted.
+   *
+   * Returns
+   *
+   * completion: String
+   *
+   *   The full text to insert, including any optional import prefix.
+   *
+   * change: SourceChange (optional)
+   *
+   *   A change for the client to apply in case the library containing the
+   *   accepted completion suggestion needs to be imported. The field will be
+   *   omitted if there are no additional changes that need to be made.
+   */
+  Future<CompletionGetSuggestionDetailsResult>
+      sendCompletionGetSuggestionDetails(
+          String file, int id, String label, int offset) async {
+    var params =
+        new CompletionGetSuggestionDetailsParams(file, id, label, offset)
+            .toJson();
+    var result = await server.send("completion.getSuggestionDetails", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new CompletionGetSuggestionDetailsResult.fromJson(
+        decoder, 'result', result);
+  }
+
+  /**
    * Reports the completion suggestions that should be presented to the user.
    * The set of suggestions included in the notification is always a complete
    * list that supersedes any previously reported suggestions.
@@ -1092,6 +1191,36 @@
    *
    *   True if this is that last set of results that will be returned for the
    *   indicated completion.
+   *
+   * includedSuggestionSets: List<IncludedSuggestionSet> (optional)
+   *
+   *   This field is experimental.
+   *
+   *   References to AvailableSuggestionSet objects previously sent to the
+   *   client. The client can include applicable names from the referenced
+   *   library in code completion suggestions.
+   *
+   * includedSuggestionKinds: List<ElementKind> (optional)
+   *
+   *   This field is experimental.
+   *
+   *   The client is expected to check this list against the ElementKind sent
+   *   in IncludedSuggestionSet to decide whether or not these symbols should
+   *   should be presented to the user.
+   *
+   * includedSuggestionRelevanceTags: List<IncludedSuggestionRelevanceTag>
+   * (optional)
+   *
+   *   This field is experimental.
+   *
+   *   The client is expected to check this list against the values of the
+   *   field relevanceTags of AvailableSuggestion to decide if the suggestion
+   *   should be given a different relevance than the IncludedSuggestionSet
+   *   that contains it. This might be used for example to give higher
+   *   relevance to suggestions of matching types.
+   *
+   *   If an AvailableSuggestion has relevance tags that match more than one
+   *   IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
    */
   Stream<CompletionResultsParams> onCompletionResults;
 
@@ -1101,6 +1230,34 @@
   StreamController<CompletionResultsParams> _onCompletionResults;
 
   /**
+   * Reports the pre-computed, candidate completions from symbols defined in a
+   * corresponding library. This notification may be sent multiple times. When
+   * a notification is processed, clients should replace any previous
+   * information about the libraries in the list of changedLibraries, discard
+   * any information about the libraries in the list of removedLibraries, and
+   * preserve any previously received information about any libraries that are
+   * not included in either list.
+   *
+   * Parameters
+   *
+   * changedLibraries: List<AvailableSuggestionSet> (optional)
+   *
+   *   A list of pre-computed, potential completions coming from this set of
+   *   completion suggestions.
+   *
+   * removedLibraries: List<int> (optional)
+   *
+   *   A list of library ids that no longer apply.
+   */
+  Stream<CompletionAvailableSuggestionsParams> onCompletionAvailableSuggestions;
+
+  /**
+   * Stream controller for [onCompletionAvailableSuggestions].
+   */
+  StreamController<CompletionAvailableSuggestionsParams>
+      _onCompletionAvailableSuggestions;
+
+  /**
    * Perform a search for references to the element defined or referenced at
    * the given offset in the given file.
    *
@@ -1482,11 +1639,38 @@
   }
 
   /**
+   * Request information about edit.dartfix such as the list of known fixes
+   * that can be specified in an edit.dartfix request.
+   *
+   * Parameters
+   *
+   * Returns
+   *
+   * fixes: List<DartFix>
+   *
+   *   A list of fixes that can be specified in an edit.dartfix request.
+   */
+  Future<EditGetDartfixInfoResult> sendEditGetDartfixInfo() async {
+    var params = new EditGetDartfixInfoParams().toJson();
+    var result = await server.send("edit.getDartfixInfo", params);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    return new EditGetDartfixInfoResult.fromJson(decoder, 'result', result);
+  }
+
+  /**
    * Analyze the specified sources for recommended changes and return a set of
    * suggested edits for those sources. These edits may include changes to
    * sources outside the set of specified sources if a change in a specified
    * source requires it.
    *
+   * If includedFixes is specified, then those fixes will be applied. If
+   * includeRequiredFixes is specified, then "required" fixes will be applied
+   * in addition to whatever fixes are specified in includedFixes if any. If
+   * neither includedFixes nor includeRequiredFixes is specified, then all
+   * fixes will be applied. If excludedFixes is specified, then those fixes
+   * will not be applied regardless of whether they are "required" or specified
+   * in includedFixes.
+   *
    * Parameters
    *
    * included: List<FilePath>
@@ -1501,6 +1685,24 @@
    *   analysis.setAnalysisRoots), an error of type FILE_NOT_ANALYZED will be
    *   generated.
    *
+   * includedFixes: List<String> (optional)
+   *
+   *   A list of names indicating which fixes should be applied.
+   *
+   *   If a name is specified that does not match the name of a known fix, an
+   *   error of type UNKNOWN_FIX will be generated.
+   *
+   * includeRequiredFixes: bool (optional)
+   *
+   *   A flag indicating that "required" fixes should be applied.
+   *
+   * excludedFixes: List<String> (optional)
+   *
+   *   A list of names indicating which fixes should not be applied.
+   *
+   *   If a name is specified that does not match the name of a known fix, an
+   *   error of type UNKNOWN_FIX will be generated.
+   *
    * Returns
    *
    * suggestions: List<DartFixSuggestion>
@@ -1522,8 +1724,15 @@
    *
    *   A list of source edits to apply the recommended changes.
    */
-  Future<EditDartfixResult> sendEditDartfix(List<String> included) async {
-    var params = new EditDartfixParams(included).toJson();
+  Future<EditDartfixResult> sendEditDartfix(List<String> included,
+      {List<String> includedFixes,
+      bool includeRequiredFixes,
+      List<String> excludedFixes}) async {
+    var params = new EditDartfixParams(included,
+            includedFixes: includedFixes,
+            includeRequiredFixes: includeRequiredFixes,
+            excludedFixes: excludedFixes)
+        .toJson();
     var result = await server.send("edit.dartfix", params);
     ResponseDecoder decoder = new ResponseDecoder(null);
     return new EditDartfixResult.fromJson(decoder, 'result', result);
@@ -2459,6 +2668,10 @@
     _onCompletionResults =
         new StreamController<CompletionResultsParams>(sync: true);
     onCompletionResults = _onCompletionResults.stream.asBroadcastStream();
+    _onCompletionAvailableSuggestions =
+        new StreamController<CompletionAvailableSuggestionsParams>(sync: true);
+    onCompletionAvailableSuggestions =
+        _onCompletionAvailableSuggestions.stream.asBroadcastStream();
     _onSearchResults = new StreamController<SearchResultsParams>(sync: true);
     onSearchResults = _onSearchResults.stream.asBroadcastStream();
     _onExecutionLaunchData =
@@ -2555,6 +2768,12 @@
         _onCompletionResults.add(
             new CompletionResultsParams.fromJson(decoder, 'params', params));
         break;
+      case "completion.availableSuggestions":
+        outOfTestExpect(params, isCompletionAvailableSuggestionsParams);
+        _onCompletionAvailableSuggestions.add(
+            new CompletionAvailableSuggestionsParams.fromJson(
+                decoder, 'params', params));
+        break;
       case "search.results":
         outOfTestExpect(params, isSearchResultsParams);
         _onSearchResults
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 6630dbe..ef2ded9 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -164,6 +164,56 @@
     optionalFields: {"analysisTarget": isString}));
 
 /**
+ * AvailableSuggestion
+ *
+ * {
+ *   "label": String
+ *   "element": Element
+ *   "docComplete": optional String
+ *   "docSummary": optional String
+ *   "parameterNames": optional List<String>
+ *   "parameterTypes": optional List<String>
+ *   "relevanceTags": optional List<AvailableSuggestionRelevanceTag>
+ *   "requiredParameterCount": optional int
+ * }
+ */
+final Matcher isAvailableSuggestion =
+    new LazyMatcher(() => new MatchesJsonObject("AvailableSuggestion", {
+          "label": isString,
+          "element": isElement
+        }, optionalFields: {
+          "docComplete": isString,
+          "docSummary": isString,
+          "parameterNames": isListOf(isString),
+          "parameterTypes": isListOf(isString),
+          "relevanceTags": isListOf(isAvailableSuggestionRelevanceTag),
+          "requiredParameterCount": isInt
+        }));
+
+/**
+ * AvailableSuggestionRelevanceTag
+ *
+ * String
+ */
+final Matcher isAvailableSuggestionRelevanceTag = isString;
+
+/**
+ * AvailableSuggestionSet
+ *
+ * {
+ *   "id": int
+ *   "uri": String
+ *   "items": List<AvailableSuggestion>
+ * }
+ */
+final Matcher isAvailableSuggestionSet = new LazyMatcher(() =>
+    new MatchesJsonObject("AvailableSuggestionSet", {
+      "id": isInt,
+      "uri": isString,
+      "items": isListOf(isAvailableSuggestion)
+    }));
+
+/**
  * ChangeContentOverlay
  *
  * {
@@ -195,6 +245,16 @@
 final Matcher isCompletionId = isString;
 
 /**
+ * CompletionService
+ *
+ * enum {
+ *   AVAILABLE_SUGGESTION_SETS
+ * }
+ */
+final Matcher isCompletionService =
+    new MatchesEnum("CompletionService", ["AVAILABLE_SUGGESTION_SETS"]);
+
+/**
  * CompletionSuggestion
  *
  * {
@@ -300,6 +360,19 @@
         }));
 
 /**
+ * DartFix
+ *
+ * {
+ *   "name": String
+ *   "description": optional String
+ *   "isRequired": optional bool
+ * }
+ */
+final Matcher isDartFix = new LazyMatcher(() => new MatchesJsonObject(
+    "DartFix", {"name": isString},
+    optionalFields: {"description": isString, "isRequired": isBool}));
+
+/**
  * DartFixSuggestion
  *
  * {
@@ -873,6 +946,30 @@
     {"path": isFilePath, "prefix": isString, "elements": isListOf(isString)}));
 
 /**
+ * IncludedSuggestionRelevanceTag
+ *
+ * {
+ *   "tag": AvailableSuggestionRelevanceTag
+ *   "relevanceBoost": int
+ * }
+ */
+final Matcher isIncludedSuggestionRelevanceTag = new LazyMatcher(() =>
+    new MatchesJsonObject("IncludedSuggestionRelevanceTag",
+        {"tag": isAvailableSuggestionRelevanceTag, "relevanceBoost": isInt}));
+
+/**
+ * IncludedSuggestionSet
+ *
+ * {
+ *   "id": int
+ *   "relevance": int
+ * }
+ */
+final Matcher isIncludedSuggestionSet = new LazyMatcher(() =>
+    new MatchesJsonObject(
+        "IncludedSuggestionSet", {"id": isInt, "relevance": isInt}));
+
+/**
  * KytheEntry
  *
  * {
@@ -914,6 +1011,18 @@
         }));
 
 /**
+ * LibraryPathSet
+ *
+ * {
+ *   "scope": FilePath
+ *   "libraryPaths": List<FilePath>
+ * }
+ */
+final Matcher isLibraryPathSet = new LazyMatcher(() => new MatchesJsonObject(
+    "LibraryPathSet",
+    {"scope": isFilePath, "libraryPaths": isListOf(isFilePath)}));
+
+/**
  * LinkedEditGroup
  *
  * {
@@ -1294,6 +1403,7 @@
  *   SERVER_ERROR
  *   SORT_MEMBERS_INVALID_FILE
  *   SORT_MEMBERS_PARSE_ERRORS
+ *   UNKNOWN_FIX
  *   UNKNOWN_REQUEST
  *   UNSUPPORTED_FEATURE
  * }
@@ -1325,6 +1435,7 @@
   "SERVER_ERROR",
   "SORT_MEMBERS_INVALID_FILE",
   "SORT_MEMBERS_PARSE_ERRORS",
+  "UNKNOWN_FIX",
   "UNKNOWN_REQUEST",
   "UNSUPPORTED_FEATURE"
 ]);
@@ -2032,6 +2143,48 @@
 final Matcher isAnalyticsSendTimingResult = isNull;
 
 /**
+ * completion.availableSuggestions params
+ *
+ * {
+ *   "changedLibraries": optional List<AvailableSuggestionSet>
+ *   "removedLibraries": optional List<int>
+ * }
+ */
+final Matcher isCompletionAvailableSuggestionsParams = new LazyMatcher(() =>
+    new MatchesJsonObject("completion.availableSuggestions params", null,
+        optionalFields: {
+          "changedLibraries": isListOf(isAvailableSuggestionSet),
+          "removedLibraries": isListOf(isInt)
+        }));
+
+/**
+ * completion.getSuggestionDetails params
+ *
+ * {
+ *   "file": FilePath
+ *   "id": int
+ *   "label": String
+ *   "offset": int
+ * }
+ */
+final Matcher isCompletionGetSuggestionDetailsParams = new LazyMatcher(() =>
+    new MatchesJsonObject("completion.getSuggestionDetails params",
+        {"file": isFilePath, "id": isInt, "label": isString, "offset": isInt}));
+
+/**
+ * completion.getSuggestionDetails result
+ *
+ * {
+ *   "completion": String
+ *   "change": optional SourceChange
+ * }
+ */
+final Matcher isCompletionGetSuggestionDetailsResult = new LazyMatcher(() =>
+    new MatchesJsonObject(
+        "completion.getSuggestionDetails result", {"completion": isString},
+        optionalFields: {"change": isSourceChange}));
+
+/**
  * completion.getSuggestions params
  *
  * {
@@ -2055,6 +2208,22 @@
         "completion.getSuggestions result", {"id": isCompletionId}));
 
 /**
+ * completion.registerLibraryPaths params
+ *
+ * {
+ *   "paths": List<LibraryPathSet>
+ * }
+ */
+final Matcher isCompletionRegisterLibraryPathsParams = new LazyMatcher(() =>
+    new MatchesJsonObject("completion.registerLibraryPaths params",
+        {"paths": isListOf(isLibraryPathSet)}));
+
+/**
+ * completion.registerLibraryPaths result
+ */
+final Matcher isCompletionRegisterLibraryPathsResult = isNull;
+
+/**
  * completion.results params
  *
  * {
@@ -2063,6 +2232,9 @@
  *   "replacementLength": int
  *   "results": List<CompletionSuggestion>
  *   "isLast": bool
+ *   "includedSuggestionSets": optional List<IncludedSuggestionSet>
+ *   "includedSuggestionKinds": optional List<ElementKind>
+ *   "includedSuggestionRelevanceTags": optional List<IncludedSuggestionRelevanceTag>
  * }
  */
 final Matcher isCompletionResultsParams =
@@ -2072,9 +2244,30 @@
           "replacementLength": isInt,
           "results": isListOf(isCompletionSuggestion),
           "isLast": isBool
+        }, optionalFields: {
+          "includedSuggestionSets": isListOf(isIncludedSuggestionSet),
+          "includedSuggestionKinds": isListOf(isElementKind),
+          "includedSuggestionRelevanceTags":
+              isListOf(isIncludedSuggestionRelevanceTag)
         }));
 
 /**
+ * completion.setSubscriptions params
+ *
+ * {
+ *   "subscriptions": List<CompletionService>
+ * }
+ */
+final Matcher isCompletionSetSubscriptionsParams = new LazyMatcher(() =>
+    new MatchesJsonObject("completion.setSubscriptions params",
+        {"subscriptions": isListOf(isCompletionService)}));
+
+/**
+ * completion.setSubscriptions result
+ */
+final Matcher isCompletionSetSubscriptionsResult = isNull;
+
+/**
  * convertGetterToMethod feedback
  */
 final Matcher isConvertGetterToMethodFeedback = isNull;
@@ -2130,10 +2323,19 @@
  *
  * {
  *   "included": List<FilePath>
+ *   "includedFixes": optional List<String>
+ *   "includeRequiredFixes": optional bool
+ *   "excludedFixes": optional List<String>
  * }
  */
-final Matcher isEditDartfixParams = new LazyMatcher(() => new MatchesJsonObject(
-    "edit.dartfix params", {"included": isListOf(isFilePath)}));
+final Matcher isEditDartfixParams =
+    new LazyMatcher(() => new MatchesJsonObject("edit.dartfix params", {
+          "included": isListOf(isFilePath)
+        }, optionalFields: {
+          "includedFixes": isListOf(isString),
+          "includeRequiredFixes": isBool,
+          "excludedFixes": isListOf(isString)
+        }));
 
 /**
  * edit.dartfix result
@@ -2233,6 +2435,26 @@
         {"kinds": isListOf(isRefactoringKind)}));
 
 /**
+ * edit.getDartfixInfo params
+ *
+ * {
+ * }
+ */
+final Matcher isEditGetDartfixInfoParams = new LazyMatcher(
+    () => new MatchesJsonObject("edit.getDartfixInfo params", null));
+
+/**
+ * edit.getDartfixInfo result
+ *
+ * {
+ *   "fixes": List<DartFix>
+ * }
+ */
+final Matcher isEditGetDartfixInfoResult = new LazyMatcher(() =>
+    new MatchesJsonObject(
+        "edit.getDartfixInfo result", {"fixes": isListOf(isDartFix)}));
+
+/**
  * edit.getFixes params
  *
  * {
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
index 23f9b39..26685ec 100644
--- a/pkg/analysis_server/test/lsp/completion_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_test.dart
@@ -195,7 +195,7 @@
     expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
     final item = res.singleWhere((c) => c.label == 'abcdefghij');
     expect(item.insertTextFormat, equals(InsertTextFormat.PlainText));
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
     final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
     expect(updated, contains('a.abcdefghij'));
@@ -219,7 +219,7 @@
     expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
     final item = res.singleWhere((c) => c.label == 'abcdefghij');
     expect(item.insertTextFormat, equals(InsertTextFormat.PlainText));
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
     final updated = applyTextEdits(withoutMarkers(content), [item.textEdit]);
     expect(updated, contains('a.abcdefghij'));
diff --git a/pkg/analysis_server/test/lsp/folding_test.dart b/pkg/analysis_server/test/lsp/folding_test.dart
new file mode 100644
index 0000000..0b41612
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/folding_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FoldingTest);
+  });
+}
+
+@reflectiveTest
+class FoldingTest extends AbstractLspAnalysisServerTest {
+  test_class() async {
+    final content = '''
+    class MyClass2 {[[
+      // Class content
+    ]]}
+    ''';
+
+    final range1 = rangeFromMarkers(content);
+    final expectedRegions = [
+      new FoldingRange(
+        range1.start.line,
+        range1.start.character,
+        range1.end.line,
+        range1.end.character,
+        null,
+      )
+    ];
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final regions = await getFoldingRegions(mainFileUri);
+    expect(regions, unorderedEquals(expectedRegions));
+  }
+
+  test_comments() async {
+    final content = '''
+    [[/// This is a comment
+    /// that spans many lines]]
+    class MyClass2 {}
+    ''';
+
+    final range1 = rangeFromMarkers(content);
+    final expectedRegions = [
+      new FoldingRange(
+        range1.start.line,
+        range1.start.character,
+        range1.end.line,
+        range1.end.character,
+        FoldingRangeKind.Comment,
+      )
+    ];
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final regions = await getFoldingRegions(mainFileUri);
+    expect(regions, unorderedEquals(expectedRegions));
+  }
+
+  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
+    // just starts at the logical block.
+    // The LSP spec doesn't give any guidance on whether the first part of
+    // the surrounded content should be visible or not after folding
+    // so we'll need to revisit this once there's clarification:
+    // https://github.com/Microsoft/language-server-protocol/issues/659
+    final content = '''
+    // Copyright some year by some people[[
+    // See LICENCE etc.]]
+
+    import[[ 'dart:io';
+    import 'dart:async';]]
+
+    [[/// This is not the file header
+    /// It's just a comment]]
+    main() {}
+    ''';
+
+    final ranges = rangesFromMarkers(content);
+
+    final expectedRegions = [
+      _toFoldingRange(ranges[0], FoldingRangeKind.Comment),
+      _toFoldingRange(ranges[1], FoldingRangeKind.Imports),
+      _toFoldingRange(ranges[2], FoldingRangeKind.Comment),
+    ];
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final regions = await getFoldingRegions(mainFileUri);
+    expect(regions, unorderedEquals(expectedRegions));
+  }
+
+  FoldingRange _toFoldingRange(Range range, FoldingRangeKind kind) {
+    return new FoldingRange(
+      range.start.line,
+      range.start.character,
+      range.end.line,
+      range.end.character,
+      kind,
+    );
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 7afb2a5..edbad6e 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -66,7 +66,7 @@
   test_uninitialized_dropsNotifications() async {
     final notification =
         makeNotification(new Method.fromJson('randomNotification'), null);
-    final nextNotification = channel.errorNotificationsFromServer.first;
+    final nextNotification = errorNotificationsFromServer.first;
     channel.sendNotificationToServer(notification);
 
     // Wait up to 1sec to ensure no error/log notifications were sent back.
diff --git a/pkg/analysis_server/test/lsp/rename_test.dart b/pkg/analysis_server/test/lsp/rename_test.dart
index 6226b60..2406dbb 100644
--- a/pkg/analysis_server/test/lsp/rename_test.dart
+++ b/pkg/analysis_server/test/lsp/rename_test.dart
@@ -17,11 +17,6 @@
 
 @reflectiveTest
 class RenameTest extends AbstractLspAnalysisServerTest {
-  // TODO(dantup): send a rename without a version
-  // TODO(dantup): send an old version of the doc?
-  // TODO(dantup): check the version returned matches?
-  // TODO(dantup): renames across multiple files
-
   test_prepare_class() {
     const content = '''
     class MyClass {}
@@ -122,6 +117,23 @@
         content, 'MyNewClass', expectedContent);
   }
 
+  test_rename_withoutVersionedIdentifier() {
+    // Without sending a document version, the rename should still work because
+    // the server should use the version it had at the start of the rename
+    // operation.
+    const content = '''
+    class MyClass {}
+    final a = new [[My^Class]]();
+    ''';
+    const expectedContent = '''
+    class MyNewClass {}
+    final a = new MyNewClass();
+    ''';
+    return _test_rename_withDocumentChanges(
+        content, 'MyNewClass', expectedContent,
+        sendRenameVersion: false);
+  }
+
   test_rename_classNewKeyword() async {
     const content = '''
     class MyClass {}
@@ -321,16 +333,25 @@
   }
 
   _test_rename_withDocumentChanges(
-      String content, String newName, String expectedContent) async {
+    String content,
+    String newName,
+    String expectedContent, {
+    sendDocumentVersion = true,
+    sendRenameVersion = true,
+  }) async {
+    // The specific number doesn't matter here, it's just a placeholder to confirm
+    // the values match.
+    final documentVersion = 222;
     await initialize(
       workspaceCapabilities:
           withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
     );
-    await openFile(mainFileUri, withoutMarkers(content), version: 222);
+    await openFile(mainFileUri, withoutMarkers(content),
+        version: sendDocumentVersion ? documentVersion : null);
 
     final result = await rename(
       mainFileUri,
-      222,
+      sendRenameVersion ? documentVersion : null,
       positionFromMarker(content),
       newName,
     );
@@ -341,8 +362,70 @@
       final contents = {
         mainFilePath: withoutMarkers(content),
       };
-      applyDocumentChanges(contents, result.documentChanges);
+      final documentVersions = {
+        mainFilePath: documentVersion,
+      };
+      applyDocumentChanges(
+        contents,
+        result.documentChanges,
+        expectedVersions: documentVersions,
+      );
       expect(contents[mainFilePath], equals(expectedContent));
     }
   }
+
+  test_rename_multipleFiles() async {
+    final referencedFilePath =
+        join(projectFolderPath, 'lib', 'referenced.dart');
+    final referencedFileUri = Uri.file(referencedFilePath);
+    const mainContent = '''
+    import 'referenced.dart';
+    final a = new My^Class();
+    ''';
+    const referencedContent = '''
+    class MyClass {}
+    ''';
+    const expectedMainContent = '''
+    import 'referenced.dart';
+    final a = new MyNewClass();
+    ''';
+    const expectedReferencedContent = '''
+    class MyNewClass {}
+    ''';
+    const mainVersion = 111;
+    const referencedVersion = 222;
+
+    await initialize(
+      workspaceCapabilities:
+          withDocumentChangesSupport(emptyWorkspaceClientCapabilities),
+    );
+    await openFile(mainFileUri, withoutMarkers(mainContent),
+        version: mainVersion);
+    await openFile(referencedFileUri, withoutMarkers(referencedContent),
+        version: referencedVersion);
+
+    final result = await rename(
+      mainFileUri,
+      mainVersion,
+      positionFromMarker(mainContent),
+      'MyNewClass',
+    );
+
+    // Ensure applying the changes will give us the expected content.
+    final contents = {
+      mainFilePath: withoutMarkers(mainContent),
+      referencedFilePath: withoutMarkers(referencedContent),
+    };
+    final documentVersions = {
+      mainFilePath: mainVersion,
+      referencedFilePath: referencedVersion,
+    };
+    applyDocumentChanges(
+      contents,
+      result.documentChanges,
+      expectedVersions: documentVersions,
+    );
+    expect(contents[mainFilePath], equals(expectedMainContent));
+    expect(contents[referencedFilePath], equals(expectedReferencedContent));
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index fad7baf..a1735ec 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -4,9 +4,11 @@
 
 import 'dart:async';
 
+import 'package:analysis_server/lsp_protocol/protocol_custom_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/src/analysis_server.dart';
+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:analyzer/instrumentation/instrumentation.dart';
@@ -28,8 +30,8 @@
 
 final beginningOfDocument = new Range(new Position(0, 0), new Position(0, 0));
 
-abstract class AbstractLspAnalysisServerTest
-    with ResourceProviderMixin, ClientCapabilitiesHelperMixin {
+mixin LspAnalysisServerTestMixin
+    implements ResourceProviderMixin, ClientCapabilitiesHelperMixin {
   static const positionMarker = '^';
   static const rangeMarkerStart = '[[';
   static const rangeMarkerEnd = ']]';
@@ -37,13 +39,46 @@
   static final allMarkersPattern =
       new RegExp(allMarkers.map(RegExp.escape).join('|'));
 
-  MockLspServerChannel channel;
-  LspAnalysisServer server;
-
   int _id = 0;
   String projectFolderPath, mainFilePath;
   Uri projectFolderUri, mainFileUri;
 
+  Stream<Message> get serverToClient;
+
+  /**
+   * A stream of [NotificationMessage]s from the server that may be errors.
+   */
+  Stream<NotificationMessage> get errorNotificationsFromServer {
+    return notificationsFromServer.where(_isErrorNotification);
+  }
+
+  /**
+   * A stream of [NotificationMessage]s from the server.
+   */
+  Stream<NotificationMessage> get notificationsFromServer {
+    return serverToClient
+        .where((m) => m is NotificationMessage)
+        .cast<NotificationMessage>();
+  }
+
+  /// Checks whether a notification is likely an error from the server (for
+  /// example a window/showMessage). This is useful for tests that want to
+  /// ensure no errors come from the server in response to notifications (which
+  /// don't have their own responses).
+  bool _isErrorNotification(NotificationMessage notification) {
+    return notification.method == Method.window_logMessage ||
+        notification.method == Method.window_showMessage;
+  }
+
+  /**
+   * A stream of [RequestMessage]s from the server.
+   */
+  Stream<RequestMessage> get requestsFromServer {
+    return serverToClient
+        .where((m) => m is RequestMessage)
+        .cast<RequestMessage>();
+  }
+
   void applyChanges(
     Map<String, String> fileContents,
     Map<String, List<TextEdit>> changes,
@@ -55,13 +90,17 @@
   }
 
   void applyDocumentChanges(
-      Map<String, String> fileContents,
-      Either2<
-              List<TextDocumentEdit>,
-              List<
-                  Either4<TextDocumentEdit, CreateFile, RenameFile,
-                      DeleteFile>>>
-          documentChanges) {
+    Map<String, String> fileContents,
+    Either2<List<TextDocumentEdit>,
+            List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>
+        documentChanges, {
+    Map<String, int> expectedVersions,
+  }) {
+    // If we were supplied with expected versions, ensure that all returned
+    // edits match the versions.
+    if (expectedVersions != null) {
+      expectDocumentVersions(documentChanges, expectedVersions);
+    }
     documentChanges.map(
       (edits) => applyTextDocumentEdits(fileContents, edits),
       (changes) => applyResourceChanges(fileContents, changes),
@@ -152,8 +191,7 @@
         changes,
       ),
     );
-    channel.sendNotificationToServer(notification);
-    await pumpEventQueue();
+    sendNotificationToServer(notification);
   }
 
   Future changeWorkspaceFolders({List<Uri> add, List<Uri> remove}) async {
@@ -166,8 +204,7 @@
         ),
       ),
     );
-    channel.sendNotificationToServer(notification);
-    await pumpEventQueue();
+    sendNotificationToServer(notification);
   }
 
   Future closeFile(Uri uri) async {
@@ -176,8 +213,7 @@
       new DidCloseTextDocumentParams(
           new TextDocumentIdentifier(uri.toString())),
     );
-    channel.sendNotificationToServer(notification);
-    await pumpEventQueue();
+    sendNotificationToServer(notification);
   }
 
   Future<Object> executeCommand(Command command) async {
@@ -191,11 +227,50 @@
     return expectSuccessfulResponseTo(request);
   }
 
+  void expectDocumentVersion(
+    TextDocumentEdit edit,
+    Map<String, int> expectedVersions,
+  ) {
+    final path = Uri.parse(edit.textDocument.uri).toFilePath();
+    final expectedVersion = expectedVersions[path];
+
+    if (edit.textDocument is VersionedTextDocumentIdentifier) {
+      expect(edit.textDocument.version, equals(expectedVersion));
+    } else {
+      throw 'Document identifier for $path was not versioned (expected version $expectedVersion)';
+    }
+  }
+
+  /// Validates the document versions for a set of edits match the versions in
+  /// the supplied map.
+  void expectDocumentVersions(
+    Either2<List<TextDocumentEdit>,
+            List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>
+        documentChanges,
+    Map<String, int> expectedVersions,
+  ) {
+    documentChanges.map(
+      // Validate versions on simple doc edits
+      (edits) => edits
+          .forEach((edit) => expectDocumentVersion(edit, expectedVersions)),
+      // For resource changes, we only need to validate changes since
+      // creates/renames/deletes do not supply versions.
+      (changes) => changes.forEach((change) {
+            change.map(
+              (edit) => expectDocumentVersion(edit, expectedVersions),
+              (create) => {},
+              (rename) {},
+              (delete) {},
+            );
+          }),
+    );
+  }
+
   Future<T> expectErrorNotification<T>(
     FutureOr<void> f(), {
     Duration timeout = const Duration(seconds: 5),
   }) async {
-    final firstError = channel.errorNotificationsFromServer.first;
+    final firstError = errorNotificationsFromServer.first;
     await f();
 
     final notificationFromServer = await firstError.timeout(timeout);
@@ -211,7 +286,7 @@
     Duration timeout = const Duration(seconds: 5),
   }) async {
     final firstRequest =
-        channel.requestsFromServer.firstWhere((n) => n.method == method);
+        requestsFromServer.firstWhere((n) => n.method == method);
     await f();
 
     final requestFromServer = await firstRequest.timeout(timeout);
@@ -223,7 +298,7 @@
   /// Sends a request to the server and unwraps the result. Throws if the
   /// response was not successful or returned an error.
   Future<T> expectSuccessfulResponseTo<T>(RequestMessage request) async {
-    final resp = await channel.sendRequestToServer(request);
+    final resp = await sendRequestToServer(request);
     if (resp.error != null) {
       throw resp.error;
     } else {
@@ -298,6 +373,14 @@
     return expectSuccessfulResponseTo<List<Location>>(request);
   }
 
+  Future<DartDiagnosticServer> getDiagnosticServer() {
+    final request = makeRequest(
+      CustomMethods.DiagnosticServer,
+      null,
+    );
+    return expectSuccessfulResponseTo(request);
+  }
+
   Future<List<DocumentHighlight>> getDocumentHighlights(Uri uri, Position pos) {
     final request = makeRequest(
       Method.textDocument_documentHighlight,
@@ -320,6 +403,22 @@
     return expectSuccessfulResponseTo(request);
   }
 
+  Future<List<SymbolInformation>> getWorkspaceSymbols(String query) {
+    final request = makeRequest(
+      Method.workspace_symbol,
+      new WorkspaceSymbolParams(query),
+    );
+    return expectSuccessfulResponseTo(request);
+  }
+
+  Future<List<FoldingRange>> getFoldingRegions(Uri uri) {
+    final request = makeRequest(
+      Method.textDocument_foldingRange,
+      new FoldingRangeParams(new TextDocumentIdentifier(uri.toString())),
+    );
+    return expectSuccessfulResponseTo<List<FoldingRange>>(request);
+  }
+
   Future<Hover> getHover(Uri uri, Position pos) {
     final request = makeRequest(
       Method.textDocument_hover,
@@ -430,12 +529,12 @@
             ),
             null,
             workspaceFolders?.map(toWorkspaceFolder)?.toList()));
-    final response = await channel.sendRequestToServer(request);
+    final response = await sendRequestToServer(request);
     expect(response.id, equals(request.id));
 
     if (response.error == null) {
       final notification = makeNotification(Method.initialized, null);
-      channel.sendNotificationToServer(notification);
+      sendNotificationToServer(notification);
       await pumpEventQueue();
     }
 
@@ -469,7 +568,7 @@
       new DidOpenTextDocumentParams(new TextDocumentItem(
           uri.toString(), dartLanguageId, version, content)),
     );
-    channel.sendNotificationToServer(notification);
+    sendNotificationToServer(notification);
     await pumpEventQueue();
   }
 
@@ -560,7 +659,7 @@
     String newName,
   ) {
     final request = makeRenameRequest(version, uri, pos, newName);
-    return channel.sendRequestToServer(request);
+    return sendRequestToServer(request);
   }
 
   Future replaceFile(int newVersion, Uri uri, String content) {
@@ -574,10 +673,77 @@
   /// Sends [responseParams] to the server as a successful response to
   /// a server-initiated [request].
   void respondTo<T>(RequestMessage request, T responseParams) {
-    channel.sendResponseToServer(
+    sendResponseToServer(
         new ResponseMessage(request.id, responseParams, null, jsonRpcVersion));
   }
 
+  Future<Null> sendShutdown() {
+    final request = makeRequest(Method.shutdown, null);
+    return expectSuccessfulResponseTo(request);
+  }
+
+  void sendExit() {
+    final request = makeRequest(Method.exit, null);
+    sendRequestToServer(request);
+  }
+
+  FutureOr<void> sendNotificationToServer(NotificationMessage notification);
+
+  Future<ResponseMessage> sendRequestToServer(RequestMessage request);
+
+  void sendResponseToServer(ResponseMessage response);
+
+  WorkspaceFolder toWorkspaceFolder(Uri uri) {
+    return WorkspaceFolder(uri.toString(), path.basename(uri.toFilePath()));
+  }
+
+  Future<List<Diagnostic>> waitForDiagnostics(Uri uri) async {
+    PublishDiagnosticsParams diagnosticParams;
+    await serverToClient.firstWhere((message) {
+      if (message is NotificationMessage &&
+          message.method == Method.textDocument_publishDiagnostics) {
+        diagnosticParams = message.params;
+
+        return diagnosticParams.uri == uri.toString();
+      }
+      return false;
+    });
+    return diagnosticParams.diagnostics;
+  }
+
+  /// Removes markers like `[[` and `]]` and `^` that are used for marking
+  /// positions/ranges in strings to avoid hard-coding positions in tests.
+  String withoutMarkers(String contents) =>
+      contents.replaceAll(allMarkersPattern, '');
+
+  /// Removes range markers from strings to give accurate position offsets.
+  String withoutRangeMarkers(String contents) =>
+      contents.replaceAll(rangeMarkerStart, '').replaceAll(rangeMarkerEnd, '');
+}
+
+abstract class AbstractLspAnalysisServerTest
+    with
+        ResourceProviderMixin,
+        ClientCapabilitiesHelperMixin,
+        LspAnalysisServerTestMixin {
+  MockLspServerChannel channel;
+  LspAnalysisServer server;
+
+  Stream<Message> get serverToClient => channel.serverToClient;
+
+  Future sendNotificationToServer(NotificationMessage notification) async {
+    channel.sendNotificationToServer(notification);
+    await pumpEventQueue();
+  }
+
+  Future<ResponseMessage> sendRequestToServer(RequestMessage request) {
+    return channel.sendRequestToServer(request);
+  }
+
+  void sendResponseToServer(ResponseMessage response) {
+    channel.sendResponseToServer(response);
+  }
+
   void setUp() {
     channel = new MockLspServerChannel(debugPrintCommunication);
     // Create an SDK in the mock file system.
@@ -604,33 +770,6 @@
     channel.close();
     await server.shutdown();
   }
-
-  WorkspaceFolder toWorkspaceFolder(Uri uri) {
-    return WorkspaceFolder(uri.toString(), path.basename(uri.toFilePath()));
-  }
-
-  Future<List<Diagnostic>> waitForDiagnostics(Uri uri) async {
-    PublishDiagnosticsParams diagnosticParams;
-    await channel.serverToClient.firstWhere((message) {
-      if (message is NotificationMessage &&
-          message.method == Method.textDocument_publishDiagnostics) {
-        diagnosticParams = message.params;
-
-        return diagnosticParams.uri == uri.toString();
-      }
-      return false;
-    });
-    return diagnosticParams.diagnostics;
-  }
-
-  /// Removes markers like `[[` and `]]` and `^` that are used for marking
-  /// positions/ranges in strings to avoid hard-coding positions in tests.
-  String withoutMarkers(String contents) =>
-      contents.replaceAll(allMarkersPattern, '');
-
-  /// Removes range markers from strings to give accurate position offsets.
-  String withoutRangeMarkers(String contents) =>
-      contents.replaceAll(rangeMarkerStart, '').replaceAll(rangeMarkerEnd, '');
 }
 
 mixin ClientCapabilitiesHelperMixin {
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
index 233b57a..f935b60 100644
--- a/pkg/analysis_server/test/lsp/server_test.dart
+++ b/pkg/analysis_server/test/lsp/server_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 'dart:convert';
+import 'dart:io';
+
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -37,19 +40,13 @@
 
   test_shutdown_initialized() async {
     await initialize();
-    final request = makeRequest(Method.shutdown, null);
-    final response = await channel.sendRequestToServer(request);
-    expect(response.id, equals(request.id));
-    expect(response.error, isNull);
-    expect(response.result, isNull);
+    final response = await sendShutdown();
+    expect(response, isNull);
   }
 
   test_shutdown_uninitialized() async {
-    final request = makeRequest(Method.shutdown, null);
-    final response = await channel.sendRequestToServer(request);
-    expect(response.id, equals(request.id));
-    expect(response.error, isNull);
-    expect(response.result, isNull);
+    final response = await sendShutdown();
+    expect(response, isNull);
   }
 
   test_unknownNotifications_logError() async {
@@ -68,11 +65,36 @@
     );
   }
 
+  @failingTest
+  test_diagnosticServer() async {
+    // TODO(dantup): This test fails because server.diagnosticServer is not
+    // set up in these tests. This needs moving to an integration test (which
+    // we don't yet have for LSP, but the existing server does have that we
+    // can mirror).
+    await initialize();
+
+    // Send the custom request to the LSP server to get the Dart diagnostic
+    // server info.
+    final server = await getDiagnosticServer();
+
+    expect(server.port, isNotNull);
+    expect(server.port, isNonZero);
+    expect(server.port, isPositive);
+
+    // Ensure the server was actually started.
+    final client = new HttpClient();
+    HttpClientRequest request = await client
+        .getUrl(Uri.parse('http://localhost:${server.port}/status'));
+    final response = await request.close();
+    final responseBody = await utf8.decodeStream(response);
+    expect(responseBody, contains('<title>Analysis Server</title>'));
+  }
+
   test_unknownOptionalNotifications_silentlyDropped() async {
     await initialize();
     final notification =
         makeNotification(new Method.fromJson(r'$/randomNotification'), null);
-    final firstError = channel.errorNotificationsFromServer.first;
+    final firstError = errorNotificationsFromServer.first;
     channel.sendNotificationToServer(notification);
 
     // Wait up to 1sec to ensure no error/log notifications were sent back.
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index d1e29ad..bdd25b3 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -15,6 +15,7 @@
 import 'document_highlights_test.dart' as document_highlights_test;
 import 'document_symbols_test.dart' as document_symbols_test;
 import 'file_modification_test.dart' as file_modification_test;
+import 'folding_test.dart' as folding_test;
 import 'format_test.dart' as format_test;
 import 'hover_test.dart' as hover_test;
 import 'initialization_test.dart' as initialization_test;
@@ -23,6 +24,7 @@
 import 'rename_test.dart' as rename_test;
 import 'server_test.dart' as server_test;
 import 'signature_help_test.dart' as signature_help_test;
+import 'workspace_symbols_test.dart' as workspace_symbols_test;
 
 main() {
   defineReflectiveSuite(() {
@@ -44,5 +46,7 @@
     assists_code_action_tests.main();
     packet_transformer_tests.main();
     rename_test.main();
+    folding_test.main();
+    workspace_symbols_test.main();
   }, name: 'lsp');
 }
diff --git a/pkg/analysis_server/test/lsp/workspace_symbols_test.dart b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
new file mode 100644
index 0000000..72cad45
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/workspace_symbols_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(WorkspaceSymbolsTest);
+  });
+}
+
+@reflectiveTest
+class WorkspaceSymbolsTest extends AbstractLspAnalysisServerTest {
+  test_fullMatch() async {
+    const content = '''
+    [[String topLevel = '']];
+    class MyClass {
+      int myField;
+      MyClass(this.myField);
+      myMethod() {}
+    }
+    ''';
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+
+    final symbols = await getWorkspaceSymbols('topLevel');
+
+    final topLevel = symbols.firstWhere((s) => s.name == 'topLevel');
+    expect(topLevel.kind, equals(SymbolKind.Variable));
+    expect(topLevel.containerName, isNull);
+    expect(topLevel.location.uri, equals(mainFileUri.toString()));
+    expect(topLevel.location.range, equals(rangeFromMarkers(content)));
+
+    // Ensure we didn't get some things that definitely do not match.
+    expect(symbols.any((s) => s.name == 'MyClass'), isFalse);
+    expect(symbols.any((s) => s.name == 'myMethod'), isFalse);
+  }
+
+  test_fuzzyMatch() async {
+    const content = '''
+    String topLevel = '';
+    class MyClass {
+      [[int myField]];
+      MyClass(this.myField);
+      myMethod() {}
+    }
+    ''';
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+
+    // meld should match myField
+    final symbols = await getWorkspaceSymbols('meld');
+
+    final field = symbols.firstWhere((s) => s.name == 'myField');
+    expect(field.kind, equals(SymbolKind.Field));
+    expect(field.containerName, equals('MyClass'));
+    expect(field.location.uri, equals(mainFileUri.toString()));
+    expect(field.location.range, equals(rangeFromMarkers(content)));
+
+    // Ensure we didn't get some things that definitely do not match.
+    expect(symbols.any((s) => s.name == 'MyClass'), isFalse);
+    expect(symbols.any((s) => s.name == 'myMethod'), isFalse);
+  }
+
+  test_partialMatch() async {
+    const content = '''
+    String topLevel = '';
+    class MyClass {
+      [[int myField]];
+      MyClass(this.myField);
+      [[myMethod() {}]]
+    }
+    ''';
+    newFile(mainFilePath, content: withoutMarkers(content));
+    await initialize();
+
+    final symbols = await getWorkspaceSymbols('my');
+    final ranges = rangesFromMarkers(content);
+    final fieldRange = ranges[0];
+    final methodRange = ranges[1];
+
+    final field = symbols.firstWhere((s) => s.name == 'myField');
+    expect(field.kind, equals(SymbolKind.Field));
+    expect(field.containerName, equals('MyClass'));
+    expect(field.location.uri, equals(mainFileUri.toString()));
+    expect(field.location.range, equals(fieldRange));
+
+    final klass = symbols.firstWhere((s) => s.name == 'MyClass');
+    expect(klass.kind, equals(SymbolKind.Class));
+    expect(klass.containerName, isNull);
+    expect(klass.location.uri, equals(mainFileUri.toString()));
+
+    final method = symbols.firstWhere((s) => s.name == 'myMethod');
+    expect(method.kind, equals(SymbolKind.Method));
+    expect(method.containerName, equals('MyClass'));
+    expect(method.location.uri, equals(mainFileUri.toString()));
+    expect(method.location.range, equals(methodRange));
+
+    // Ensure we didn't get some things that definitely do not match.
+    expect(symbols.any((s) => s.name == 'topLevel'), isFalse);
+  }
+}
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 286da86..367e52e 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -8,6 +8,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
 import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
 import 'package:analysis_server/lsp_protocol/protocol_special.dart' as lsp;
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
@@ -64,31 +65,6 @@
     return _closed.future;
   }
 
-  /**
-   * A stream of [NotificationMessage]s from the server that may be errors.
-   */
-  Stream<lsp.NotificationMessage> get errorNotificationsFromServer {
-    return notificationsFromServer.where(_isErrorNotification);
-  }
-
-  /**
-   * A stream of [NotificationMessage]s from the server.
-   */
-  Stream<lsp.NotificationMessage> get notificationsFromServer {
-    return _serverToClient.stream
-        .where((m) => m is lsp.NotificationMessage)
-        .cast<lsp.NotificationMessage>();
-  }
-
-  /**
-   * A stream of [RequestMessage]s from the server.
-   */
-  Stream<lsp.RequestMessage> get requestsFromServer {
-    return _serverToClient.stream
-        .where((m) => m is lsp.RequestMessage)
-        .cast<lsp.RequestMessage>();
-  }
-
   Stream<lsp.Message> get serverToClient => _serverToClient.stream;
 
   @override
@@ -98,6 +74,13 @@
     }
   }
 
+  /// Run the object through JSON serialisation to catch any
+  /// issues like fields that are unserialisable types. This is used for
+  /// messages going server-to-client.
+  void ensureMessageCanBeJsonSerialized(ToJsonable message) {
+    jsonEncode(message.toJson());
+  }
+
   @override
   void listen(void Function(lsp.Message message) onMessage,
       {Function onError, void Function() onDone}) {
@@ -110,6 +93,9 @@
     if (_closed.isCompleted) {
       return;
     }
+
+    ensureMessageCanBeJsonSerialized(notification);
+
     _serverToClient.add(notification);
   }
 
@@ -118,7 +104,9 @@
     if (_closed.isCompleted) {
       return;
     }
+
     notification = _convertJson(notification, lsp.NotificationMessage.fromJson);
+
     _clientToServer.add(notification);
   }
 
@@ -128,6 +116,9 @@
     if (_closed.isCompleted) {
       return;
     }
+
+    ensureMessageCanBeJsonSerialized(request);
+
     _serverToClient.add(request);
   }
 
@@ -141,7 +132,9 @@
     if (_closed.isCompleted) {
       throw new Exception('sendLspRequest after connection closed');
     }
+
     request = _convertJson(request, lsp.RequestMessage.fromJson);
+
     // Wrap send request in future to simulate WebSocket.
     new Future(() => _clientToServer.add(request));
     return waitForResponse(request);
@@ -153,6 +146,9 @@
     if (_closed.isCompleted) {
       return;
     }
+
+    ensureMessageCanBeJsonSerialized(response);
+
     // Wrap send response in future to simulate WebSocket.
     new Future(() => _serverToClient.add(response));
   }
@@ -162,7 +158,9 @@
     if (_closed.isCompleted) {
       return;
     }
+
     response = _convertJson(response, lsp.ResponseMessage.fromJson);
+
     _clientToServer.add(response);
   }
 
@@ -201,15 +199,6 @@
       lsp.ToJsonable message, T Function(Map<String, dynamic>) constructor) {
     return constructor(jsonDecode(jsonEncode(message.toJson())));
   }
-
-  /// Checks whether a notification is likely an error from the server (for
-  /// example a window/showMessage). This is useful for tests that want to
-  /// ensure no errors come from the server in response to notifications (which
-  /// don't have their own responses).
-  bool _isErrorNotification(lsp.NotificationMessage notification) {
-    return notification.method == Method.window_logMessage ||
-        notification.method == Method.window_showMessage;
-  }
 }
 
 /**
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 cedde60..9d9a40d 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
@@ -41,23 +41,6 @@
     expect(suggestion.selectionLength, selectionLength);
   }
 
-  void assertSuggestArgumentList(
-      List<String> paramNames, List<String> paramTypes) {
-    // DEPRECATED... argument lists are no longer suggested.
-    // See https://github.com/dart-lang/sdk/issues/25197
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-
-    // CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
-    // CompletionSuggestion cs = getSuggest(csKind: csKind);
-    // if (cs == null) {
-    //   failedCompletion('expected completion $csKind', suggestions);
-    // }
-    // assertSuggestArgumentList_params(
-    //     paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
-    // expect(cs.relevance, DART_RELEVANCE_HIGH);
-    // assertNoOtherSuggestions([cs]);
-  }
-
   void assertSuggestArgumentList_params(
       List<String> expectedNames,
       List<String> expectedTypes,
@@ -531,54 +514,6 @@
     assertNoSuggestions();
   }
 
-  test_ArgumentList_imported_function_1() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'a.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg'], ['String']);
-  }
-
-  test_ArgumentList_imported_function_2() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'a.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']);
-  }
-
-  test_ArgumentList_imported_function_3() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(String arg1, int arg2, {bool arg3}) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'a.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg1', 'arg2'], ['String', 'int']);
-  }
-
   test_ArgumentList_imported_function_3a() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
@@ -901,39 +836,6 @@
         requiredParamIndices: [1]);
   }
 
-  test_ArgumentList_local_function_1() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      expect(arg) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg'], ['dynamic']);
-  }
-
-  test_ArgumentList_local_function_2() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      expect(arg1, int arg2) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']);
-  }
-
-  test_ArgumentList_local_function_3() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      expect(arg1, int arg2) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg1', 'arg2'], ['dynamic', 'int']);
-  }
-
   test_ArgumentList_local_function_3a() async {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('''
@@ -1032,20 +934,4 @@
     await computeSuggestions();
     assertNoSuggestions();
   }
-
-  test_ArgumentList_local_method_2() async {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource('/home/test/lib/a.dart', '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'a.dart'
-      class B {
-        expect(arg, int blat) { }
-        void foo() {expect(^)}}
-      String bar() => true;''');
-    await computeSuggestions();
-    assertSuggestArgumentList(['arg', 'blat'], ['dynamic', 'int']);
-  }
 }
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 a1ba82c..82d9e55 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
@@ -86,7 +86,7 @@
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     newFile('/project/bin/myLib.dart',
         content:
-            'library L; part "${convertAbsolutePathToUri(testFile)}"; class A {static int s2;}');
+            'library L; part "${toUriStr(testFile)}"; class A {static int s2;}');
     addTestFile('part of L; foo() {A.^}');
     await getSuggestionsWith({
       'L.A': ['s2']
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 6e09724..6c5a310 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,7 +10,6 @@
 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/task/dart.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -52,8 +51,7 @@
         new CompletionPerformance());
     Completer<DartCompletionRequest> requestCompleter =
         new Completer<DartCompletionRequest>();
-    DartCompletionRequestImpl.from(baseRequest,
-            resultDescriptor: RESOLVED_UNIT1)
+    DartCompletionRequestImpl.from(baseRequest)
         .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 0a1300f..0c2b22f 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
@@ -43,8 +43,9 @@
 void main() {f^}''');
     await computeSuggestions();
 
-    assertSuggestFunction('foo', 'bool',
+    CompletionSuggestion cs = assertSuggestFunction('foo', 'bool',
         defaultArgListString: 'bar, baz: null');
+    expect(cs.elementUri, equals('package:test/b.dart'));
   }
 
   test_ArgumentList() async {
@@ -62,7 +63,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool');
     assertSuggestFunction('identical', 'bool');
@@ -89,7 +89,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool');
     assertSuggestFunction('identical', 'bool');
@@ -117,7 +116,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool',
         kind: CompletionSuggestionKind.IDENTIFIER);
@@ -149,7 +147,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool',
         kind: CompletionSuggestionKind.IDENTIFIER);
@@ -179,7 +176,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool');
     assertSuggestFunction('identical', 'bool');
@@ -206,7 +202,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool');
     assertSuggestFunction('identical', 'bool');
@@ -234,7 +229,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertSuggestFunction('hasLength', 'bool',
         kind: CompletionSuggestionKind.IDENTIFIER);
@@ -264,7 +258,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('hasLength', 'bool',
         kind: CompletionSuggestionKind.IDENTIFIER);
     assertSuggestFunction('identical', 'bool',
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index e13ad70..af3d4f8 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -26,7 +27,8 @@
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
     addTestSource('import "dart:async" as bar; foo() {bar.^}');
     await computeSuggestions();
-    assertSuggestClass('Future');
+    CompletionSuggestion cs = assertSuggestClass('Future');
+    expect(cs.elementUri, equals('dart:async'));
     assertNotSuggested('loadLibrary');
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
index 36a37e9..b0e10ba 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
@@ -87,7 +87,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -118,7 +117,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -150,7 +148,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -184,7 +181,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -216,7 +212,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -247,7 +242,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -279,7 +273,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -311,7 +304,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
     if (suggestConstructorsWithoutNew) {
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index 8e5f942..f38def7 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -4,6 +4,7 @@
 
 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:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -42,7 +43,8 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertSuggestConstructor('A');
+    CompletionSuggestion cs = assertSuggestConstructor('A');
+    expect(cs.elementUri, 'package:test/a.dart');
     // Suggested by LocalConstructorContributor
     assertNotSuggested('B.bar');
     // Suggested by ImportedReferenceContributor
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 ffa3f3a..3844a66 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
@@ -57,6 +57,20 @@
     return cs;
   }
 
+  CompletionSuggestion assertSuggestTypeParameter(String name,
+      {int relevance: DART_RELEVANCE_TYPE_PARAMETER}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.IDENTIFIER, relevance: relevance);
+    expect(cs.returnType, isNull);
+    Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(ElementKind.TYPE_PARAMETER));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, isNull);
+    return cs;
+  }
+
   @override
   DartCompletionContributor createContributor() {
     return new LocalReferenceContributor();
@@ -68,10 +82,11 @@
 void main() {h^}''');
     await computeSuggestions();
 
-    assertSuggestFunction('hasLength', 'bool',
+    CompletionSuggestion cs = assertSuggestFunction('hasLength', 'bool',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION,
         defaultArgListString: 'a, b',
         defaultArgumentListTextRanges: [0, 1, 3, 1]);
+    expect(cs.elementUri, equals(convertPath('/home/test/lib/test.dart')));
   }
 
   test_ArgDefaults_function_none() async {
@@ -150,7 +165,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
     assertNotSuggested('hasLength');
@@ -178,7 +192,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
     assertNotSuggested('hasLength');
@@ -207,7 +220,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
@@ -239,7 +251,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
@@ -269,7 +280,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
     assertNotSuggested('hasLength');
@@ -297,7 +307,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
     assertNotSuggested('hasLength');
@@ -326,7 +335,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance: DART_RELEVANCE_LOCAL_FUNCTION);
@@ -360,7 +368,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertSuggestFunction('bar', 'String',
         kind: CompletionSuggestionKind.IDENTIFIER,
         relevance:
@@ -395,7 +402,6 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
     assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
@@ -2300,6 +2306,108 @@
     assertSuggestEnumConst('F.four');
   }
 
+  test_expression_localVariable() async {
+    addTestSource('''
+void f() {
+  var v = 0;
+  ^
+}
+''');
+    await computeSuggestions();
+    assertSuggestLocalVariable('v', 'int');
+  }
+
+  test_expression_parameter() async {
+    addTestSource('''
+void f(int a) {
+  ^
+}
+''');
+    await computeSuggestions();
+    assertSuggestParameter('a', 'int');
+  }
+
+  test_expression_typeParameter_classDeclaration() async {
+    addTestSource('''
+class A<T> {
+  void m() {
+    ^
+  }
+}
+class B<U> {}
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('U');
+  }
+
+  test_expression_typeParameter_classTypeAlias() async {
+    addTestSource('''
+class A<U> {}
+class B<T> = A<^>;
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('U');
+  }
+
+  test_expression_typeParameter_functionDeclaration() async {
+    addTestSource('''
+void f<T>() {
+  ^
+}
+void g<U>() {}
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('U');
+  }
+
+  test_expression_typeParameter_functionDeclaration_local() async {
+    addTestSource('''
+void f() {
+  void g2<U>() {}
+  void g<T>() {
+    ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('U');
+  }
+
+  test_expression_typeParameter_functionTypeAlias() async {
+    addTestSource('''
+typedef void F<T>(^);
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+  }
+
+  test_expression_typeParameter_genericTypeAlias() async {
+    addTestSource('''
+typedef F<T> = void Function<U>(^);
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+    assertSuggestTypeParameter('U');
+  }
+
+  test_expression_typeParameter_methodDeclaration() async {
+    addTestSource('''
+class A {
+  void m<T>() {
+    ^
+  }
+  void m2<U>() {}
+}
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+    assertNotSuggested('U');
+  }
+
   test_ExpressionStatement_identifier() async {
     // SimpleIdentifier  ExpressionStatement  Block
     addSource('/home/test/lib/a.dart', '''
@@ -4599,6 +4707,16 @@
     assertNoSuggestions();
   }
 
+  test_type_typeParameter_classDeclaration() async {
+    addTestSource('''
+class A<T> {
+  ^ m() {}
+}
+''');
+    await computeSuggestions();
+    assertSuggestTypeParameter('T');
+  }
+
   test_TypeArgumentList() async {
     // SimpleIdentifier  BinaryExpression  ExpressionStatement
     addSource('/home/test/lib/a.dart', '''
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index 49a5e34..da7ec8f 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
@@ -21,6 +21,22 @@
     return new OverrideContributor();
   }
 
+  test_alreadyOverridden() async {
+    addTestSource('''
+class A {
+  void foo() {}
+  void bar() {}
+}
+
+class B implements A {
+  void bar() {}
+  f^
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('bar');
+  }
+
   test_fromMultipleSuperclasses() async {
     addTestSource(r'''
 class A {
@@ -152,6 +168,61 @@
         selectionLength: 27);
   }
 
+  test_inClass_of_interface() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B implements A {
+  f^
+}
+''');
+    await computeSuggestions();
+    _assertOverride('''
+@override
+  void foo() {
+    // TODO: implement foo
+  }''', displayText: 'foo() { … }', selectionOffset: 51, selectionLength: 0);
+  }
+
+  test_inMixin_of_interface() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+mixin M implements A {
+  f^
+}
+''');
+    await computeSuggestions();
+    _assertOverride('''
+@override
+  void foo() {
+    // TODO: implement foo
+  }''', displayText: 'foo() { … }', selectionOffset: 51, selectionLength: 0);
+  }
+
+  test_inMixin_of_superclassConstraint() async {
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+mixin M on A {
+  f^
+}
+''');
+    await computeSuggestions();
+    _assertOverride('''
+@override
+  void foo() {
+    // TODO: implement foo
+    super.foo();
+  }''', displayText: 'foo() { … }', selectionOffset: 56, selectionLength: 12);
+  }
+
   @failingTest
   test_insideBareClass() async {
     addTestSource('''
@@ -175,6 +246,21 @@
         selectionLength: 22);
   }
 
+  test_outsideOfWorkspace() async {
+    testFile = convertPath('/home/other/lib/a.dart');
+    addTestSource('''
+class A {
+  void foo() {}
+}
+
+class B extends A {
+  f^
+}
+''');
+    await computeSuggestions();
+    _assertNoOverrideContaining('foo');
+  }
+
   test_private_otherLibrary() async {
     addSource('/home/test/lib/a.dart', '''
 class A {
@@ -278,6 +364,14 @@
         selectionLength: 22);
   }
 
+  void _assertNoOverrideContaining(String search) {
+    expect(
+        suggestions.where((c) =>
+            c.kind == CompletionSuggestionKind.OVERRIDE &&
+            c.completion.contains(search)),
+        isEmpty);
+  }
+
   CompletionSuggestion _assertOverride(String completion,
       {String displayText, int selectionOffset, int selectionLength}) {
     CompletionSuggestion cs = getSuggest(
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index 5fd129a..c3712b1 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -125,7 +125,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -151,7 +150,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -178,7 +176,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -207,7 +204,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -234,7 +230,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -260,7 +255,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -287,7 +281,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -314,7 +307,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
     assertNotSuggested('B');
@@ -2914,6 +2906,30 @@
     assertNotSuggested('==');
   }
 
+  test_mixin() async {
+    addTestSource(r'''
+class A {
+  void a() {}
+}
+
+class B {
+  void b() {}
+}
+
+mixin X on A, B {
+  void x() {}
+}
+
+void f(X x) {
+  x.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('a', 'A', 'void');
+    assertSuggestMethod('b', 'B', 'void');
+    assertSuggestMethod('x', 'X', 'void');
+  }
+
   test_new_instance() async {
     addTestSource('import "dart:math"; class A {x() {new Random().^}}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index fa60f61..59f07b6 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -37,7 +37,7 @@
 import '22/c.dart';
 export '333/d.dart';
 part 'a.dart';
-part '${convertAbsolutePathToUri('/absolute/uri.dart')}';
+part '${toUriStr('/absolute/uri.dart')}';
 ''');
     // perform refactoring
     _createRefactoring('/home/test/000/1111/22/new_name.dart');
@@ -51,7 +51,7 @@
 import 'c.dart';
 export '../333/d.dart';
 part '../a.dart';
-part '${convertAbsolutePathToUri('/absolute/uri.dart')}';
+part '${toUriStr('/absolute/uri.dart')}';
 ''');
   }
 
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index 042fdcc..14f3924 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
@@ -488,12 +488,12 @@
     await indexUnit('/home/test/lib/test2.dart', '''
 library test2;
 class A {
-  void foo({int test: 1}) {
+  void foo({int test}) {
     print(test);
   }
 }
 class B extends A {
-  void foo({int test: 2}) {
+  void foo({int test}) {
     print(test);
   }
 }
@@ -506,7 +506,7 @@
   new C().foo(test: 30);
 }
 class C extends A {
-  void foo({int test: 3}) {
+  void foo({int test}) {
     print(test);
   }
 }
@@ -524,7 +524,7 @@
   new C().foo(newName: 30);
 }
 class C extends A {
-  void foo({int newName: 3}) {
+  void foo({int newName}) {
     print(newName);
   }
 }
@@ -532,12 +532,12 @@
     assertFileChangeResult('/home/test/lib/test2.dart', '''
 library test2;
 class A {
-  void foo({int newName: 1}) {
+  void foo({int newName}) {
     print(newName);
   }
 }
 class B extends A {
-  void foo({int newName: 2}) {
+  void foo({int newName}) {
     print(newName);
   }
 }
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
new file mode 100644
index 0000000..ecf6d0cd
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -0,0 +1,257 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'available_suggestions_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AvailableSuggestionSetsTest);
+  });
+}
+
+@reflectiveTest
+class AvailableSuggestionSetsTest extends AvailableSuggestionsBase {
+  test_notifications_whenFileChanges() async {
+    var path = convertPath('/home/test/lib/a.dart');
+    var uriStr = 'package:test/a.dart';
+
+    // No file initially, so no set.
+    expect(uriToSetMap.keys, isNot(contains(uriStr)));
+
+    // Create the file, should get the set.
+    {
+      newFile(path, content: r'''
+class A {}
+''');
+      var set = await waitForSetWithUri(uriStr);
+      expect(set.items.map((d) => d.label), contains('A'));
+    }
+
+    // Update the file, should get the updated set.
+    {
+      newFile(path, content: r'''
+class B {}
+''');
+      removeSet(uriStr);
+      var set = await waitForSetWithUri(uriStr);
+      expect(set.items.map((d) => d.label), contains('B'));
+    }
+
+    // Delete the file, the set should be removed.
+    deleteFile(path);
+    waitForSetWithUriRemoved(uriStr);
+  }
+
+  test_suggestion_class() async {
+    var path = convertPath('/home/test/lib/a.dart');
+    var uriStr = 'package:test/a.dart';
+
+    newFile(path, content: r'''
+class A {}
+''');
+
+    var set = await waitForSetWithUri(uriStr);
+    assertJsonText(_getSuggestion(set, 'A'), '''
+{
+  "label": "A",
+  "element": {
+    "kind": "CLASS",
+    "name": "A",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 6,
+      "length": 0,
+      "startLine": 1,
+      "startColumn": 7
+    },
+    "flags": 0
+  },
+  "relevanceTags": [
+    "package:test/a.dart::A"
+  ]
+}
+''');
+  }
+
+  test_suggestion_enum() async {
+    var path = convertPath('/home/test/lib/a.dart');
+    var uriStr = 'package:test/a.dart';
+
+    newFile(path, content: r'''
+enum MyEnum {
+  aaa,
+  bbb,
+}
+''');
+
+    var set = await waitForSetWithUri(uriStr);
+    assertJsonText(_getSuggestion(set, 'MyEnum'), '''
+{
+  "label": "MyEnum",
+  "element": {
+    "kind": "ENUM",
+    "name": "MyEnum",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 5,
+      "length": 0,
+      "startLine": 1,
+      "startColumn": 6
+    },
+    "flags": 0
+  },
+  "relevanceTags": [
+    "package:test/a.dart::MyEnum"
+  ]
+}
+''');
+    assertJsonText(_getSuggestion(set, 'MyEnum.aaa'), '''
+{
+  "label": "MyEnum.aaa",
+  "element": {
+    "kind": "ENUM_CONSTANT",
+    "name": "aaa",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 16,
+      "length": 0,
+      "startLine": 2,
+      "startColumn": 3
+    },
+    "flags": 0
+  },
+  "relevanceTags": [
+    "package:test/a.dart::MyEnum"
+  ]
+}
+''');
+    assertJsonText(_getSuggestion(set, 'MyEnum.bbb'), '''
+{
+  "label": "MyEnum.bbb",
+  "element": {
+    "kind": "ENUM_CONSTANT",
+    "name": "bbb",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 23,
+      "length": 0,
+      "startLine": 3,
+      "startColumn": 3
+    },
+    "flags": 0
+  },
+  "relevanceTags": [
+    "package:test/a.dart::MyEnum"
+  ]
+}
+''');
+  }
+
+  test_suggestion_topLevelVariable() async {
+    var path = convertPath('/home/test/lib/a.dart');
+    var uriStr = 'package:test/a.dart';
+
+    newFile(path, content: r'''
+var boolV = false;
+var intV = 0;
+var doubleV = 0.1;
+var stringV = 'hi';
+''');
+
+    var set = await waitForSetWithUri(uriStr);
+    assertJsonText(_getSuggestion(set, 'boolV'), '''
+{
+  "label": "boolV",
+  "element": {
+    "kind": "TOP_LEVEL_VARIABLE",
+    "name": "boolV",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 4,
+      "length": 0,
+      "startLine": 1,
+      "startColumn": 5
+    },
+    "flags": 0,
+    "returnType": ""
+  },
+  "relevanceTags": [
+    "dart:core::bool"
+  ]
+}
+''');
+    assertJsonText(_getSuggestion(set, 'intV'), '''
+{
+  "label": "intV",
+  "element": {
+    "kind": "TOP_LEVEL_VARIABLE",
+    "name": "intV",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 23,
+      "length": 0,
+      "startLine": 2,
+      "startColumn": 5
+    },
+    "flags": 0,
+    "returnType": ""
+  },
+  "relevanceTags": [
+    "dart:core::int"
+  ]
+}
+''');
+    assertJsonText(_getSuggestion(set, 'doubleV'), '''
+{
+  "label": "doubleV",
+  "element": {
+    "kind": "TOP_LEVEL_VARIABLE",
+    "name": "doubleV",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 37,
+      "length": 0,
+      "startLine": 3,
+      "startColumn": 5
+    },
+    "flags": 0,
+    "returnType": ""
+  },
+  "relevanceTags": [
+    "dart:core::double"
+  ]
+}
+''');
+    assertJsonText(_getSuggestion(set, 'stringV'), '''
+{
+  "label": "stringV",
+  "element": {
+    "kind": "TOP_LEVEL_VARIABLE",
+    "name": "stringV",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 56,
+      "length": 0,
+      "startLine": 4,
+      "startColumn": 5
+    },
+    "flags": 0,
+    "returnType": ""
+  },
+  "relevanceTags": [
+    "dart:core::String"
+  ]
+}
+''');
+  }
+
+  static AvailableSuggestion _getSuggestion(
+      AvailableSuggestionSet set, String label) {
+    return set.items.singleWhere((s) => s.label == label);
+  }
+}
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.dart
new file mode 100644
index 0000000..97064f5
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestions_base.dart
@@ -0,0 +1,122 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:analysis_server/protocol/protocol.dart';
+import 'package:analysis_server/protocol/protocol_constants.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/domain_completion.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';
+import '../../../constants.dart';
+
+@reflectiveTest
+class AvailableSuggestionsBase extends AbstractAnalysisTest {
+  final Map<int, AvailableSuggestionSet> idToSetMap = {};
+  final Map<String, AvailableSuggestionSet> uriToSetMap = {};
+  final Map<String, CompletionResultsParams> idToSuggestions = {};
+
+  void assertJsonText(Object object, String expected) {
+    expected = expected.trimRight();
+    var actual = JsonEncoder.withIndent('  ').convert(object);
+    if (actual != expected) {
+      print('-----');
+      print(actual);
+      print('-----');
+    }
+    expect(actual, expected);
+  }
+
+  String jsonOfPath(String path) {
+    path = convertPath(path);
+    return json.encode(path);
+  }
+
+  @override
+  void processNotification(Notification notification) {
+    super.processNotification(notification);
+    if (notification.event == COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS) {
+      var params = CompletionAvailableSuggestionsParams.fromNotification(
+        notification,
+      );
+      for (var set in params.changedLibraries) {
+        idToSetMap[set.id] = set;
+        uriToSetMap[set.uri] = set;
+      }
+      for (var id in params.removedLibraries) {
+        var set = idToSetMap.remove(id);
+        uriToSetMap.remove(set?.uri);
+      }
+    } else if (notification.event == COMPLETION_RESULTS) {
+      var params = CompletionResultsParams.fromNotification(notification);
+      idToSuggestions[params.id] = params;
+    }
+  }
+
+  /// Remove the set with the given [uri].
+  /// The set must be already received.
+  void removeSet(String uri) {
+    var set = uriToSetMap.remove(uri);
+    expect(set, isNotNull);
+
+    idToSetMap.remove(set.id);
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    projectPath = convertPath('/home');
+    testFile = convertPath('/home/test/lib/test.dart');
+
+    newFile('/home/test/pubspec.yaml', content: '');
+    newFile('/home/test/.packages', content: '''
+test:${toUri('/home/test/lib')}
+''');
+
+    createProject();
+    handler = server.handlers.whereType<CompletionDomainHandler>().single;
+    _setCompletionSubscriptions([CompletionService.AVAILABLE_SUGGESTION_SETS]);
+  }
+
+  Future<CompletionResultsParams> waitForGetSuggestions(String id) async {
+    while (true) {
+      var result = idToSuggestions[id];
+      if (result != null) {
+        return result;
+      }
+      await Future.delayed(const Duration(milliseconds: 1));
+    }
+  }
+
+  Future<AvailableSuggestionSet> waitForSetWithUri(String uri) async {
+    while (true) {
+      var result = uriToSetMap[uri];
+      if (result != null) {
+        return result;
+      }
+      await Future.delayed(const Duration(milliseconds: 1));
+    }
+  }
+
+  Future<void> waitForSetWithUriRemoved(String uri) async {
+    while (true) {
+      var result = uriToSetMap[uri];
+      if (result == null) {
+        return;
+      }
+      await Future.delayed(const Duration(milliseconds: 1));
+    }
+  }
+
+  void _setCompletionSubscriptions(List<CompletionService> subscriptions) {
+    handleSuccessfulRequest(
+      CompletionSetSubscriptionsParams(subscriptions).toRequest('0'),
+    );
+  }
+}
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
new file mode 100644
index 0000000..84fdccb
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestion_details_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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_generated.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'available_suggestions_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(GetSuggestionDetailsTest);
+  });
+}
+
+@reflectiveTest
+class GetSuggestionDetailsTest extends AvailableSuggestionsBase {
+  test_enum() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+enum MyEnum {
+  aaa, bbb
+}
+''');
+    addTestFile(r'''
+main() {} // ref
+''');
+
+    var set = await waitForSetWithUri('package:test/a.dart');
+    var result = await _getSuggestionDetails(
+      id: set.id,
+      label: 'MyEnum.aaa',
+      offset: testCode.indexOf('} // ref'),
+    );
+
+    expect(result.completion, 'MyEnum.aaa');
+    _assertTestFileChange(result.change, r'''
+import 'package:test/a.dart';
+
+main() {} // ref
+''');
+  }
+
+  test_existingImport() async {
+    addTestFile(r'''
+import 'dart:math';
+
+main() {} // ref
+''');
+
+    var mathSet = await waitForSetWithUri('dart:math');
+    var result = await _getSuggestionDetails(
+      id: mathSet.id,
+      label: 'sin',
+      offset: testCode.indexOf('} // ref'),
+    );
+
+    expect(result.completion, 'sin');
+    _assertEmptyChange(result.change);
+  }
+
+  test_existingImport_prefixed() async {
+    addTestFile(r'''
+import 'dart:math' as math;
+
+main() {} // ref
+''');
+
+    var mathSet = await waitForSetWithUri('dart:math');
+    var result = await _getSuggestionDetails(
+      id: mathSet.id,
+      label: 'sin',
+      offset: testCode.indexOf('} // ref'),
+    );
+
+    expect(result.completion, 'math.sin');
+    _assertEmptyChange(result.change);
+  }
+
+  test_newImport() async {
+    addTestFile(r'''
+main() {} // ref
+''');
+
+    var mathSet = await waitForSetWithUri('dart:math');
+    var result = await _getSuggestionDetails(
+      id: mathSet.id,
+      label: 'sin',
+      offset: testCode.indexOf('} // ref'),
+    );
+
+    expect(result.completion, 'sin');
+    _assertTestFileChange(result.change, r'''
+import 'dart:math';
+
+main() {} // ref
+''');
+  }
+
+  void _assertEmptyChange(SourceChange change) {
+    expect(change.edits, isEmpty);
+  }
+
+  void _assertTestFileChange(SourceChange change, String expected) {
+    var fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+
+    var fileEdit = fileEdits[0];
+    expect(fileEdit.file, testFile);
+
+    var edits = fileEdit.edits;
+    expect(SourceEdit.applySequence(testCode, edits), expected);
+  }
+
+  Future<CompletionGetSuggestionDetailsResult> _getSuggestionDetails({
+    String file,
+    @required int id,
+    @required String label,
+    @required int offset,
+  }) async {
+    file ??= testFile;
+    var response = await waitResponse(
+      CompletionGetSuggestionDetailsParams(
+        file,
+        id,
+        label,
+        offset,
+      ).toRequest('0'),
+    );
+    return CompletionGetSuggestionDetailsResult.fromResponse(response);
+  }
+}
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
new file mode 100644
index 0000000..0de95fdf
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
@@ -0,0 +1,226 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'available_suggestions_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(GetSuggestionAvailableTest);
+  });
+}
+
+@reflectiveTest
+class GetSuggestionAvailableTest extends AvailableSuggestionsBase {
+  test_dart() async {
+    addTestFile('');
+    var mathSet = await waitForSetWithUri('dart:math');
+    var asyncSet = await waitForSetWithUri('dart:async');
+
+    var results = await _getSuggestions(testFile, 0);
+    expect(results.includedSuggestionKinds, isNotEmpty);
+
+    var includedIdSet = results.includedSuggestionSets.map((set) => set.id);
+    expect(includedIdSet, contains(mathSet.id));
+    expect(includedIdSet, contains(asyncSet.id));
+  }
+
+  test_includedSuggestionKinds_type() async {
+    addTestFile(r'''
+class X extends {} // ref
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf('{} // ref'),
+    );
+
+    expect(
+      results.includedSuggestionKinds,
+      unorderedEquals([
+        ElementKind.CLASS,
+        ElementKind.CLASS_TYPE_ALIAS,
+        ElementKind.ENUM,
+        ElementKind.FUNCTION_TYPE_ALIAS,
+        ElementKind.MIXIN,
+      ]),
+    );
+  }
+
+  test_includedSuggestionKinds_value() async {
+    addTestFile(r'''
+main() {
+  print(); // ref
+}
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf('); // ref'),
+    );
+
+    expect(
+      results.includedSuggestionKinds,
+      unorderedEquals([
+        ElementKind.CLASS,
+        ElementKind.CLASS_TYPE_ALIAS,
+        ElementKind.ENUM,
+        ElementKind.ENUM_CONSTANT,
+        ElementKind.FUNCTION,
+        ElementKind.FUNCTION_TYPE_ALIAS,
+        ElementKind.MIXIN,
+        ElementKind.TOP_LEVEL_VARIABLE,
+      ]),
+    );
+  }
+
+  test_inHtml() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+
+    var path = convertPath('/home/test/doc/a.html');
+    newFile(path, content: '<html></html>');
+
+    await waitResponse(
+      CompletionGetSuggestionsParams(path, 0).toRequest('0'),
+    );
+    expect(serverErrors, isEmpty);
+  }
+
+  test_relevanceTags_enum() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+enum MyEnum {
+  aaa, bbb
+}
+''');
+    addTestFile(r'''
+import 'a.dart';
+
+void f(MyEnum e) {
+  e = // ref;
+}
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf(' // ref'),
+    );
+
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
+[
+  {
+    "tag": "package:test/a.dart::MyEnum",
+    "relevanceBoost": 1100
+  }
+]
+''');
+  }
+
+  test_relevanceTags_location_argumentList_named() async {
+    addTestFile(r'''
+void foo({int a, String b}) {}
+
+main() {
+  foo(b: ); // ref
+}
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf('); // ref'),
+    );
+
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
+[
+  {
+    "tag": "dart:core::String",
+    "relevanceBoost": 10
+  }
+]
+''');
+  }
+
+  test_relevanceTags_location_argumentList_positional() async {
+    addTestFile(r'''
+void foo(double a) {}
+
+main() {
+  foo(); // ref
+}
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf('); // ref'),
+    );
+
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
+[
+  {
+    "tag": "dart:core::double",
+    "relevanceBoost": 10
+  }
+]
+''');
+  }
+
+  test_relevanceTags_location_assignment() async {
+    addTestFile(r'''
+main() {
+  int v;
+  v = // ref;
+}
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf(' // ref'),
+    );
+
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
+[
+  {
+    "tag": "dart:core::int",
+    "relevanceBoost": 10
+  }
+]
+''');
+  }
+
+  test_relevanceTags_location_listLiteral() async {
+    addTestFile(r'''
+main() {
+  var v = [0, ]; // ref
+}
+''');
+
+    var results = await _getSuggestions(
+      testFile,
+      testCode.indexOf(']; // ref'),
+    );
+
+    assertJsonText(results.includedSuggestionRelevanceTags, r'''
+[
+  {
+    "tag": "dart:core::int",
+    "relevanceBoost": 10
+  }
+]
+''');
+  }
+
+  Future<CompletionResultsParams> _getSuggestions(
+    String path,
+    int offset,
+  ) async {
+    var response = CompletionGetSuggestionsResult.fromResponse(
+      await waitResponse(
+        CompletionGetSuggestionsParams(path, offset).toRequest('0'),
+      ),
+    );
+    return await waitForGetSuggestions(response.id);
+  }
+}
diff --git a/pkg/analysis_server/test/src/domains/completion/test_all.dart b/pkg/analysis_server/test/src/domains/completion/test_all.dart
new file mode 100644
index 0000000..066f43c
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/completion/test_all.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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'available_suggestion_sets_test.dart' as available_suggestion_sets;
+import 'get_suggestion_details_test.dart' as get_suggestion_details;
+import 'get_suggestions_available_test.dart' as get_suggestions_available;
+
+main() {
+  defineReflectiveSuite(() {
+    available_suggestion_sets.main();
+    get_suggestion_details.main();
+    get_suggestions_available.main();
+  });
+}
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
index 37ff7fa..c3d9f15 100644
--- a/pkg/analysis_server/test/src/domains/execution/completion_test.dart
+++ b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
@@ -60,8 +60,7 @@
     code = code.replaceAll('^', '');
 
     var computer = new RuntimeCompletionComputer(
-        resourceProvider,
-        fileContentOverlay,
+        overlayResourceProvider,
         driver,
         code,
         codeOffset,
diff --git a/pkg/analysis_server/test/src/domains/test_all.dart b/pkg/analysis_server/test/src/domains/test_all.dart
index ea67387..b936c18 100644
--- a/pkg/analysis_server/test/src/domains/test_all.dart
+++ b/pkg/analysis_server/test/src/domains/test_all.dart
@@ -4,10 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'execution/test_all.dart' as execution_test;
+import 'completion/test_all.dart' as completion;
+import 'execution/test_all.dart' as execution;
 
 main() {
   defineReflectiveSuite(() {
-    execution_test.main();
+    completion.main();
+    execution.main();
   });
 }
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
new file mode 100644
index 0000000..88c6a34
--- /dev/null
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.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 'package:analysis_server/src/nullability/conditional_discard.dart';
+import 'package:analysis_server/src/nullability/constraint_gatherer.dart';
+import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
+import 'package:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../abstract_single_unit.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstraintGathererTest);
+    defineReflectiveTests(ConstraintVariableGathererTest);
+  });
+}
+
+@reflectiveTest
+class ConstraintGathererTest extends ConstraintsTestBase {
+  @override
+  final _Constraints constraints = _Constraints();
+
+  /// Checks that a constraint was recorded with a left hand side of
+  /// [conditions] and a right hand side of [consequence].
+  void assertConstraint(
+      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence) {
+    expect(constraints._clauses,
+        contains(_Clause(conditions.toSet(), consequence)));
+  }
+
+  /// Checks that no constraint was recorded with a right hand side of
+  /// [consequence].
+  void assertNoConstraints(ConstraintVariable consequence) {
+    expect(
+        constraints._clauses,
+        isNot(contains(
+            predicate((_Clause clause) => clause.consequence == consequence))));
+  }
+
+  /// Gets the [ExpressionChecks] associated with the expression whose text
+  /// representation is [text], or `null` if the expression has no
+  /// [ExpressionChecks] associated with it.
+  ExpressionChecks checkExpression(String text) {
+    return _variables.checkExpression(findNode.expression(text));
+  }
+
+  /// Gets the [DecoratedType] associated with the expression whose text
+  /// representation is [text], or `null` if the expression has no
+  /// [DecoratedType] associated with it.
+  DecoratedType decoratedExpressionType(String text) {
+    return _variables.decoratedExpressionType(findNode.expression(text));
+  }
+
+  test_always() async {
+    await analyze('');
+
+    // No clause is needed for `always`; it is assigned the value `true` before
+    // solving begins.
+    assertNoConstraints(ConstraintVariable.always);
+    assert(ConstraintVariable.always.value, isTrue);
+  }
+
+  test_assert_demonstrates_non_null_intent() async {
+    await analyze('''
+void f(int i) {
+  assert(i != null);
+}
+''');
+
+    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
+  }
+
+  test_binaryExpression_add_left_check() async {
+    await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+    assertConstraint([decoratedTypeAnnotation('int i').nullable],
+        checkExpression('i +').nullCheck);
+  }
+
+  test_binaryExpression_add_left_check_custom() async {
+    await analyze('''
+class Int {
+  Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j;
+''');
+
+    assertConstraint([decoratedTypeAnnotation('Int i').nullable],
+        checkExpression('i +').nullCheck);
+  }
+
+  test_binaryExpression_add_result_custom() async {
+    await analyze('''
+class Int {
+  Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j;
+''');
+
+    assertConstraint([decoratedTypeAnnotation('Int operator+').nullable],
+        decoratedTypeAnnotation('Int f').nullable);
+  }
+
+  test_binaryExpression_add_result_not_null() async {
+    await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('int f').nullable);
+  }
+
+  test_binaryExpression_add_right_check() async {
+    await analyze('''
+int f(int i, int j) => i + j;
+''');
+
+    assertConstraint([decoratedTypeAnnotation('int j').nullable],
+        checkExpression('j;').nullCheck);
+  }
+
+  test_binaryExpression_add_right_check_custom() async {
+    await analyze('''
+class Int {
+  Int operator+(Int other) => this;
+}
+Int f(Int i, Int j) => i + j;
+''');
+
+    assertConstraint([decoratedTypeAnnotation('Int j').nullable],
+        decoratedTypeAnnotation('Int other').nullable);
+  }
+
+  test_binaryExpression_equal() async {
+    await analyze('''
+bool f(int i, int j) => i == j;
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('bool f').nullable);
+  }
+
+  test_conditionalExpression_condition_check() async {
+    await analyze('''
+int f(bool b, int i, int j) {
+  return (b ? i : j);
+}
+''');
+
+    var nullable_b = decoratedTypeAnnotation('bool b').nullable;
+    var check_b = checkExpression('b ?').nullCheck;
+    assertConstraint([nullable_b], check_b);
+  }
+
+  test_conditionalExpression_general() async {
+    await analyze('''
+int f(bool b, int i, int j) {
+  return (b ? i : j);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i_or_nullable_j = _mockOr(nullable_i, nullable_j);
+    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    assertConstraint([nullable_i], nullable_conditional);
+    assertConstraint([nullable_j], nullable_conditional);
+    assertConstraint([nullable_conditional], nullable_i_or_nullable_j);
+    assertConstraint([nullable_conditional], nullable_return);
+  }
+
+  test_conditionalExpression_left_non_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? (throw i) : i);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    expect(nullable_conditional, same(nullable_i));
+  }
+
+  test_conditionalExpression_left_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? null : i);
+}
+''');
+
+    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    expect(nullable_conditional, same(ConstraintVariable.always));
+  }
+
+  test_conditionalExpression_right_non_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? i : (throw i));
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    expect(nullable_conditional, same(nullable_i));
+  }
+
+  test_conditionalExpression_right_null() async {
+    await analyze('''
+int f(bool b, int i) {
+  return (b ? i : null);
+}
+''');
+
+    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    expect(nullable_conditional, same(ConstraintVariable.always));
+  }
+
+  test_functionDeclaration_expression_body() async {
+    await analyze('''
+int/*1*/ f(int/*2*/ i) => i;
+''');
+
+    assertConstraint([decoratedTypeAnnotation('int/*2*/').nullable],
+        decoratedTypeAnnotation('int/*1*/').nullable);
+  }
+
+  test_functionDeclaration_parameter_named_default_notNull() async {
+    await analyze('''
+void f({int i = 1}) {}
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_named_default_null() async {
+    await analyze('''
+void f({int i = null}) {}
+''');
+
+    assertConstraint(
+        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_named_no_default_assume_nullable() async {
+    await analyze('''
+void f({int i}) {}
+''',
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+
+    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_named_no_default_assume_required() async {
+    await analyze('''
+void f({int i}) {}
+''',
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_named_no_default_required_assume_nullable() async {
+    addMetaPackage();
+    await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+''',
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_named_no_default_required_assume_required() async {
+    addMetaPackage();
+    await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+''',
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
+    await analyze('''
+void f([int i = 1]) {}
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_default_null() async {
+    await analyze('''
+void f([int i = null]) {}
+''');
+
+    assertConstraint(
+        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_no_default() async {
+    await analyze('''
+void f([int i]) {}
+''');
+
+    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionDeclaration_parameter_positionalOptional_no_default_assume_required() async {
+    // Note: the `assumeRequired` behavior shouldn't affect the behavior here
+    // because it only affects named parameters.
+    await analyze('''
+void f([int i]) {}
+''',
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+
+    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionInvocation_parameter_fromLocalParameter() async {
+    await analyze('''
+void f(int/*1*/ i) {}
+void test(int/*2*/ i) {
+  f(i);
+}
+''');
+
+    assertConstraint([decoratedTypeAnnotation('int/*2*/').nullable],
+        decoratedTypeAnnotation('int/*1*/').nullable);
+  }
+
+  test_functionInvocation_parameter_named() async {
+    await analyze('''
+void f({int i: 0}) {}
+void g(int j) {
+  f(i: j);
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    assertConstraint([nullable_j], nullable_i);
+  }
+
+  test_functionInvocation_parameter_named_missing() async {
+    await analyze('''
+void f({int i}) {}
+void g() {
+  f();
+}
+''');
+    var optional_i = possiblyOptionalParameter('int i');
+    assertConstraint([], optional_i);
+  }
+
+  test_functionInvocation_parameter_named_missing_required() async {
+    addMetaPackage();
+    verifyNoTestUnitErrors = false;
+    await analyze('''
+import 'package:meta/meta.dart';
+void f({@required int i}) {}
+void g() {
+  f();
+}
+''');
+    // 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').nullable;
+    assertNoConstraints(nullable_i);
+  }
+
+  test_functionInvocation_parameter_null() async {
+    await analyze('''
+void f(int i) {}
+void test() {
+  f(null);
+}
+''');
+
+    assertConstraint(
+        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_functionInvocation_return() async {
+    await analyze('''
+int/*1*/ f() => 0;
+int/*2*/ g() {
+  return f();
+}
+''');
+
+    assertConstraint([decoratedTypeAnnotation('int/*1*/').nullable],
+        decoratedTypeAnnotation('int/*2*/').nullable);
+  }
+
+  test_if_condition() async {
+    await analyze('''
+void f(bool b) {
+  if (b) {}
+}
+''');
+
+    assertConstraint([(decoratedTypeAnnotation('bool b').nullable)],
+        checkExpression('b) {}').nullCheck);
+  }
+
+  test_if_conditional_control_flow_after() async {
+    // Asserts after ifs don't demonstrate non-null intent.
+    // TODO(paulberry): if both branches complete normally, they should.
+    await analyze('''
+void f(bool b, int i) {
+  if (b) return;
+  assert(i != null);
+}
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent);
+  }
+
+  test_if_conditional_control_flow_within() async {
+    // Asserts inside ifs don't demonstrate non-null intent.
+    await analyze('''
+void f(bool b, int i) {
+  if (b) {
+    assert(i != null);
+  } else {
+    assert(i != null);
+  }
+}
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent);
+  }
+
+  test_if_guard_equals_null() async {
+    await analyze('''
+int f(int i, int j, int k) {
+  if (i == null) {
+    return j;
+  } else {
+    return k;
+  }
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_k = decoratedTypeAnnotation('int k').nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    assertConstraint([nullable_i, nullable_j], nullable_return);
+    assertConstraint([nullable_k], nullable_return);
+    var discard = statementDiscard('if (i == null)');
+    expect(discard.keepTrue, same(nullable_i));
+    expect(discard.keepFalse, same(ConstraintVariable.always));
+    expect(discard.pureCondition, true);
+  }
+
+  test_if_simple() async {
+    await analyze('''
+int f(bool b, int i, int j) {
+  if (b) {
+    return i;
+  } else {
+    return j;
+  }
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    assertConstraint([nullable_i], nullable_return);
+    assertConstraint([nullable_j], nullable_return);
+  }
+
+  test_if_without_else() async {
+    await analyze('''
+int f(bool b, int i) {
+  if (b) {
+    return i;
+  }
+  return 0;
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    assertConstraint([nullable_i], nullable_return);
+  }
+
+  test_intLiteral() async {
+    await analyze('''
+int f() {
+  return 0;
+}
+''');
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_methodInvocation_parameter_contravariant() async {
+    await analyze('''
+class C<T> {
+  void f(T t) {}
+}
+void g(C<int> c, int i) {
+  c.f(i);
+}
+''');
+
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_c_t =
+        decoratedTypeAnnotation('C<int>').typeArguments[0].nullable;
+    var nullable_t = decoratedTypeAnnotation('T t').nullable;
+    var nullable_c_t_or_nullable_t = _mockOr(nullable_c_t, nullable_t);
+    assertConstraint([nullable_i], nullable_c_t_or_nullable_t);
+  }
+
+  test_methodInvocation_parameter_generic() async {
+    await analyze('''
+class C<T> {}
+void f(C<int/*1*/>/*2*/ c) {}
+void g(C<int/*3*/>/*4*/ c) {
+  f(c);
+}
+''');
+
+    assertConstraint([decoratedTypeAnnotation('int/*3*/').nullable],
+        decoratedTypeAnnotation('int/*1*/').nullable);
+    assertConstraint([decoratedTypeAnnotation('C<int/*3*/>/*4*/').nullable],
+        decoratedTypeAnnotation('C<int/*1*/>/*2*/').nullable);
+  }
+
+  test_methodInvocation_parameter_named() async {
+    await analyze('''
+class C {
+  void f({int i: 0}) {}
+}
+void g(C c, int j) {
+  c.f(i: j);
+}
+''');
+    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    assertConstraint([nullable_j], nullable_i);
+  }
+
+  test_methodInvocation_target_check() async {
+    await analyze('''
+class C {
+  void m() {}
+}
+void test(C c) {
+  c.m();
+}
+''');
+
+    assertConstraint([decoratedTypeAnnotation('C c').nullable],
+        checkExpression('c.m').nullCheck);
+  }
+
+  test_parenthesizedExpression() async {
+    await analyze('''
+int f() {
+  return (null);
+}
+''');
+
+    assertConstraint(
+        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_return_implicit_null() async {
+    verifyNoTestUnitErrors = false;
+    await analyze('''
+int f() {
+  return;
+}
+''');
+
+    assertConstraint(
+        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_return_null() async {
+    await analyze('''
+int f() {
+  return null;
+}
+''');
+
+    assertConstraint(
+        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_stringLiteral() async {
+    // TODO(paulberry): also test string interpolations
+    await analyze('''
+String f() {
+  return 'x';
+}
+''');
+    assertNoConstraints(decoratedTypeAnnotation('String').nullable);
+  }
+
+  test_thisExpression() async {
+    await analyze('''
+class C {
+  C f() => this;
+}
+''');
+
+    assertNoConstraints(decoratedTypeAnnotation('C f').nullable);
+  }
+
+  test_throwExpression() async {
+    await analyze('''
+int f() {
+  return throw null;
+}
+''');
+    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+  }
+
+  test_typeName() async {
+    await analyze('''
+Type f() {
+  return int;
+}
+''');
+    assertNoConstraints(decoratedTypeAnnotation('Type').nullable);
+  }
+
+  /// Creates a variable representing the disjunction of [a] and [b] solely for
+  /// the purpose of inspecting constraint equations in unit tests.  No
+  /// additional constraints will be recorded in [_constraints] as a consequence
+  /// of creating this variable.
+  ConstraintVariable _mockOr(ConstraintVariable a, ConstraintVariable b) =>
+      ConstraintVariable.or(_MockConstraints(), a, b);
+}
+
+abstract class ConstraintsTestBase extends MigrationVisitorTestBase {
+  Constraints get constraints;
+
+  /// Analyzes the given source code, producing constraint variables and
+  /// constraints for it.
+  @override
+  Future<CompilationUnit> analyze(String code,
+      {NullabilityMigrationAssumptions assumptions:
+          const NullabilityMigrationAssumptions()}) async {
+    var unit = await super.analyze(code);
+    unit.accept(ConstraintGatherer(
+        typeProvider, _variables, constraints, testSource, false, assumptions));
+    return unit;
+  }
+}
+
+@reflectiveTest
+class ConstraintVariableGathererTest extends MigrationVisitorTestBase {
+  /// Gets the [DecoratedType] associated with the function declaration whose
+  /// name matches [search].
+  DecoratedType decoratedFunctionType(String search) =>
+      _variables.decoratedElementType(
+          findNode.functionDeclaration(search).declaredElement);
+
+  test_interfaceType_nullable() async {
+    await analyze('''
+void f(int? x) {}
+''');
+    var decoratedType = decoratedTypeAnnotation('int?');
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedType));
+    expect(decoratedType.nullable, same(ConstraintVariable.always));
+  }
+
+  test_interfaceType_typeParameter() async {
+    await analyze('''
+void f(List<int> x) {}
+''');
+    var decoratedListType = decoratedTypeAnnotation('List<int>');
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedListType));
+    expect(decoratedListType.nullable, isNotNull);
+    var decoratedIntType = decoratedTypeAnnotation('int');
+    expect(decoratedListType.typeArguments[0], same(decoratedIntType));
+    expect(decoratedIntType.nullable, isNotNull);
+  }
+
+  test_topLevelFunction_parameterType_implicit_dynamic() async {
+    await analyze('''
+void f(x) {}
+''');
+    var decoratedType =
+        _variables.decoratedElementType(findNode.simple('x').staticElement);
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedType));
+    expect(decoratedType.type.isDynamic, isTrue);
+    expect(decoratedType.nullable, same(ConstraintVariable.always));
+  }
+
+  test_topLevelFunction_parameterType_named_no_default() async {
+    await analyze('''
+void f({String s}) {}
+''');
+    var decoratedType = decoratedTypeAnnotation('String');
+    var functionType = decoratedFunctionType('f');
+    expect(functionType.namedParameters['s'], same(decoratedType));
+    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.nullable, isNot(same(ConstraintVariable.always)));
+    expect(functionType.namedParameterOptionalVariables['s'],
+        same(decoratedType.nullable));
+  }
+
+  test_topLevelFunction_parameterType_named_no_default_required() async {
+    addMetaPackage();
+    await analyze('''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+''');
+    var decoratedType = decoratedTypeAnnotation('String');
+    var functionType = decoratedFunctionType('f');
+    expect(functionType.namedParameters['s'], same(decoratedType));
+    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.nullable, isNot(same(ConstraintVariable.always)));
+    expect(functionType.namedParameterOptionalVariables['s'], isNull);
+  }
+
+  test_topLevelFunction_parameterType_named_with_default() async {
+    await analyze('''
+void f({String s: 'x'}) {}
+''');
+    var decoratedType = decoratedTypeAnnotation('String');
+    var functionType = decoratedFunctionType('f');
+    expect(functionType.namedParameters['s'], same(decoratedType));
+    expect(decoratedType.nullable, isNotNull);
+    expect(functionType.namedParameterOptionalVariables['s'],
+        same(ConstraintVariable.always));
+  }
+
+  test_topLevelFunction_parameterType_positionalOptional() async {
+    await analyze('''
+void f([int i]) {}
+''');
+    var decoratedType = decoratedTypeAnnotation('int');
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedType));
+    expect(decoratedType.nullable, isNotNull);
+  }
+
+  test_topLevelFunction_parameterType_simple() async {
+    await analyze('''
+void f(int i) {}
+''');
+    var decoratedType = decoratedTypeAnnotation('int');
+    expect(decoratedFunctionType('f').positionalParameters[0],
+        same(decoratedType));
+    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.nonNullIntent, isNotNull);
+  }
+
+  test_topLevelFunction_returnType_implicit_dynamic() async {
+    await analyze('''
+f() {}
+''');
+    var decoratedType = decoratedFunctionType('f').returnType;
+    expect(decoratedType.type.isDynamic, isTrue);
+    expect(decoratedType.nullable, same(ConstraintVariable.always));
+  }
+
+  test_topLevelFunction_returnType_simple() async {
+    await analyze('''
+int f() => 0;
+''');
+    var decoratedType = decoratedTypeAnnotation('int');
+    expect(decoratedFunctionType('f').returnType, same(decoratedType));
+    expect(decoratedType.nullable, isNotNull);
+  }
+}
+
+class MigrationVisitorTestBase extends AbstractSingleUnitTest {
+  final _variables = _Variables();
+
+  FindNode findNode;
+
+  TypeProvider get typeProvider => testAnalysisResult.typeProvider;
+
+  Future<CompilationUnit> analyze(String code,
+      {NullabilityMigrationAssumptions assumptions:
+          const NullabilityMigrationAssumptions()}) async {
+    await resolveTestUnit(code);
+    testUnit.accept(
+        ConstraintVariableGatherer(_variables, testSource, false, assumptions));
+    findNode = FindNode(code, testUnit);
+    return testUnit;
+  }
+
+  /// Gets the [DecoratedType] associated with the type annotation whose text
+  /// is [text].
+  DecoratedType decoratedTypeAnnotation(String text) {
+    return _variables.decoratedTypeAnnotation(findNode.typeAnnotation(text));
+  }
+
+  ConstraintVariable possiblyOptionalParameter(String text) {
+    return _variables
+        .possiblyOptionalParameter(findNode.defaultParameter(text));
+  }
+
+  @override
+  void setUp() {
+    createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
+    super.setUp();
+  }
+
+  /// Gets the [ConditionalDiscard] information associated with the statement
+  /// whose text is [text].
+  ConditionalDiscard statementDiscard(String text) {
+    return _variables.conditionalDiscard(findNode.statement(text));
+  }
+}
+
+/// Mock representation of a constraint equation that is not connected to a
+/// constraint solver.  We use this to confirm that analysis produces the
+/// correct constraint equations.
+///
+/// [hashCode] and equality are implemented using [toString] for simplicity.
+class _Clause {
+  final Set<ConstraintVariable> conditions;
+  final ConstraintVariable consequence;
+
+  _Clause(this.conditions, this.consequence);
+
+  @override
+  int get hashCode => toString().hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      other is _Clause && toString() == other.toString();
+
+  @override
+  String toString() {
+    String lhs;
+    if (conditions.isNotEmpty) {
+      var sortedConditionStrings = conditions.map((v) => v.toString()).toList()
+        ..sort();
+      lhs = sortedConditionStrings.join(' & ') + ' => ';
+    } else {
+      lhs = '';
+    }
+    String rhs = consequence.toString();
+    return lhs + rhs;
+  }
+}
+
+/// Mock representation of a constraint solver that does not actually do any
+/// solving.  We use this to confirm that analysis produced the correct
+/// constraint equations.
+class _Constraints extends Constraints {
+  final _clauses = <_Clause>[];
+
+  @override
+  void record(
+      Iterable<ConstraintVariable> conditions, ConstraintVariable consequence) {
+    _clauses.add(_Clause(conditions.toSet(), consequence));
+  }
+}
+
+/// Mock implementation of [Constraints] that doesn't record any constraints.
+class _MockConstraints implements Constraints {
+  @override
+  void record(Iterable<ConstraintVariable> conditions,
+      ConstraintVariable consequence) {}
+}
+
+/// Mock representation of constraint variables.
+class _Variables extends Variables {
+  final _conditionalDiscard = <AstNode, ConditionalDiscard>{};
+
+  final _decoratedExpressionTypes = <Expression, DecoratedType>{};
+
+  final _decoratedTypeAnnotations = <TypeAnnotation, DecoratedType>{};
+
+  final _expressionChecks = <Expression, ExpressionChecks>{};
+
+  final _possiblyOptional = <DefaultFormalParameter, ConstraintVariable>{};
+
+  /// Gets the [ExpressionChecks] associated with the given [expression].
+  ExpressionChecks checkExpression(Expression expression) =>
+      _expressionChecks[_normalizeExpression(expression)];
+
+  /// Gets the [conditionalDiscard] associated with the given [expression].
+  ConditionalDiscard conditionalDiscard(AstNode node) =>
+      _conditionalDiscard[node];
+
+  /// Gets the [DecoratedType] associated with the given [expression].
+  DecoratedType decoratedExpressionType(Expression expression) =>
+      _decoratedExpressionTypes[_normalizeExpression(expression)];
+
+  /// Gets the [DecoratedType] associated with the given [typeAnnotation].
+  DecoratedType decoratedTypeAnnotation(TypeAnnotation typeAnnotation) =>
+      _decoratedTypeAnnotations[typeAnnotation];
+
+  /// Gets the [ConstraintVariable] associated with the possibility that
+  /// [parameter] may be optional.
+  ConstraintVariable possiblyOptionalParameter(
+          DefaultFormalParameter parameter) =>
+      _possiblyOptional[parameter];
+
+  @override
+  void recordConditionalDiscard(
+      Source source, AstNode node, ConditionalDiscard conditionalDiscard) {
+    _conditionalDiscard[node] = conditionalDiscard;
+    super.recordConditionalDiscard(source, node, conditionalDiscard);
+  }
+
+  void recordDecoratedExpressionType(Expression node, DecoratedType type) {
+    super.recordDecoratedExpressionType(node, type);
+    _decoratedExpressionTypes[_normalizeExpression(node)] = type;
+  }
+
+  void recordDecoratedTypeAnnotation(TypeAnnotation node, DecoratedType type) {
+    super.recordDecoratedTypeAnnotation(node, type);
+    _decoratedTypeAnnotations[node] = type;
+  }
+
+  @override
+  void recordExpressionChecks(Expression expression, ExpressionChecks checks) {
+    super.recordExpressionChecks(expression, checks);
+    _expressionChecks[_normalizeExpression(expression)] = checks;
+  }
+
+  @override
+  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
+      ConstraintVariable variable) {
+    _possiblyOptional[parameter] = variable;
+    super.recordPossiblyOptional(source, parameter, variable);
+  }
+
+  /// Unwraps any parentheses surrounding [expression].
+  Expression _normalizeExpression(Expression expression) {
+    while (expression is ParenthesizedExpression) {
+      expression = (expression as ParenthesizedExpression).expression;
+    }
+    return expression;
+  }
+}
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
new file mode 100644
index 0000000..8f9f86e
--- /dev/null
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -0,0 +1,611 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/nullability/provisional_api.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../abstract_context.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ProvisionalApiTest);
+    defineReflectiveTests(ProvisionalApiTestPermissive);
+    defineReflectiveTests(ProvisionalApiTestWithReset);
+  });
+}
+
+/// Tests of the provisional API.
+@reflectiveTest
+class ProvisionalApiTest extends ProvisionalApiTestBase
+    with ProvisionalApiTestCases {
+  @override
+  bool get usePermissiveMode => false;
+}
+
+/// Base class for provisional API tests.
+abstract class ProvisionalApiTestBase extends AbstractContextTest {
+  bool get usePermissiveMode;
+
+  /// Hook invoked after calling `prepareInput` on each input.
+  void _afterPrepare() {}
+
+  /// Verifies that migration of the files in [input] produces the output in
+  /// [expectedOutput].
+  Future<void> _checkMultipleFileChanges(
+      Map<String, String> input, Map<String, String> expectedOutput,
+      {NullabilityMigrationAssumptions assumptions:
+          const NullabilityMigrationAssumptions()}) async {
+    for (var path in input.keys) {
+      newFile(path, content: input[path]);
+    }
+    var listener = new TestMigrationListener();
+    var migration = NullabilityMigration(listener,
+        permissive: usePermissiveMode, assumptions: assumptions);
+    for (var path in input.keys) {
+      migration.prepareInput(await session.getResolvedUnit(path));
+    }
+    _afterPrepare();
+    for (var path in input.keys) {
+      migration.processInput(await session.getResolvedUnit(path));
+    }
+    migration.finish();
+    var sourceEdits = <String, List<SourceEdit>>{};
+    for (var fix in listener.fixes) {
+      var path = fix.source.fullName;
+      expect(expectedOutput.keys, contains(path));
+      (sourceEdits[path] ??= []).addAll(fix.sourceEdits);
+    }
+    for (var path in expectedOutput.keys) {
+      var sourceEditsForPath = sourceEdits[path] ?? [];
+      sourceEditsForPath.sort((a, b) => b.offset.compareTo(a.offset));
+      expect(SourceEdit.applySequence(input[path], sourceEditsForPath),
+          expectedOutput[path]);
+    }
+  }
+
+  /// Verifies that migraiton of the single file with the given [content]
+  /// produces the [expected] output.
+  Future<void> _checkSingleFileChanges(String content, String expected,
+      {NullabilityMigrationAssumptions assumptions:
+          const NullabilityMigrationAssumptions()}) async {
+    var sourcePath = convertPath('/home/test/lib/test.dart');
+    await _checkMultipleFileChanges(
+        {sourcePath: content}, {sourcePath: expected},
+        assumptions: assumptions);
+  }
+}
+
+/// Mixin containing test cases for the provisional API.
+mixin ProvisionalApiTestCases on ProvisionalApiTestBase {
+  test_data_flow_generic_inward() async {
+    var content = '''
+class C<T> {
+  void f(T t) {}
+}
+void g(C<int> c, int i) {
+  c.f(i);
+}
+void test(C<int> c) {
+  g(c, null);
+}
+''';
+
+    // Default behavior is to add nullability at the call site.  Rationale: this
+    // is correct in the common case where the generic parameter represents the
+    // type of an item in a container.  Also, if there are many callers that are
+    // largely independent, adding nullability to the callee would likely
+    // propagate to a field in the class, and thence (via return values of other
+    // methods) to most users of the class.  Whereas if we add nullability at
+    // the call site it's possible that other call sites won't need it.
+    //
+    // TODO(paulberry): possible improvement: detect that since C uses T in a
+    // contravariant way, and deduce that test should change to
+    // `void test(C<int?> c)`
+    var expected = '''
+class C<T> {
+  void f(T t) {}
+}
+void g(C<int?> c, int? i) {
+  c.f(i);
+}
+void test(C<int> c) {
+  g(c, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_data_flow_generic_inward_hint() async {
+    var content = '''
+class C<T> {
+  void f(T? t) {}
+}
+void g(C<int> c, int i) {
+  c.f(i);
+}
+void test(C<int> c) {
+  g(c, null);
+}
+''';
+
+    // The user may override the behavior shown in test_data_flow_generic_inward
+    // by explicitly marking f's use of T as nullable.  Since this makes g's
+    // call to f valid regardless of the type of c, c's type will remain
+    // C<int>.
+    var expected = '''
+class C<T> {
+  void f(T? t) {}
+}
+void g(C<int> c, int? i) {
+  c.f(i);
+}
+void test(C<int> c) {
+  g(c, null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_data_flow_inward() async {
+    var content = '''
+int f(int i) => 0;
+int g(int i) => f(i);
+void test() {
+  g(null);
+}
+''';
+
+    var expected = '''
+int f(int? i) => 0;
+int g(int? i) => f(i);
+void test() {
+  g(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_data_flow_inward_missing_type() async {
+    var content = '''
+int f(int i) => 0;
+int g(i) => f(i); // TODO(danrubel): suggest type
+void test() {
+  g(null);
+}
+''';
+
+    var expected = '''
+int f(int? i) => 0;
+int g(i) => f(i); // TODO(danrubel): suggest type
+void test() {
+  g(null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_data_flow_outward() async {
+    var content = '''
+int f(int i) => null;
+int g(int i) => f(i);
+''';
+
+    var expected = '''
+int? f(int i) => null;
+int? g(int i) => f(i);
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_data_flow_outward_missing_type() async {
+    var content = '''
+f(int i) => null; // TODO(danrubel): suggest type
+int g(int i) => f(i);
+''';
+
+    var expected = '''
+f(int i) => null; // TODO(danrubel): suggest type
+int? g(int i) => f(i);
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_discard_simple_condition() async {
+    var content = '''
+int f(int i) {
+  if (i == null) {
+    return null;
+  } else {
+    return i + 1;
+  }
+}
+''';
+
+    var expected = '''
+int f(int i) {
+  /* if (i == null) {
+    return null;
+  } else {
+    */ return i + 1; /*
+  } */
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_named_parameter_no_default_unused_option2_assume_nullable() async {
+    var content = '''
+void f({String s}) {}
+main() {
+  f();
+}
+''';
+    var expected = '''
+void f({String? s}) {}
+main() {
+  f();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
+  test_named_parameter_no_default_unused_option2_assume_required() async {
+    var content = '''
+void f({String s}) {}
+main() {
+  f();
+}
+''';
+    var expected = '''
+void f({String? s}) {}
+main() {
+  f();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
+  test_named_parameter_no_default_unused_required_option2_assume_nullable() async {
+    // The `@required` annotation overrides the assumption of nullability.
+    // The call at `f()` is presumed to be in error.
+    addMetaPackage();
+    var content = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f();
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
+  test_named_parameter_no_default_unused_required_option2_assume_required() async {
+    // Since the `@required` annotation is already present, it is not added
+    // again.
+    // The call at `f()` is presumed to be in error.
+    addMetaPackage();
+    var content = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f();
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
+  test_named_parameter_no_default_used_non_null_option2_assume_nullable() async {
+    var content = '''
+void f({String s}) {}
+main() {
+  f(s: 'x');
+}
+''';
+    var expected = '''
+void f({String? s}) {}
+main() {
+  f(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
+  test_named_parameter_no_default_used_non_null_option2_assume_required() async {
+    var content = '''
+void f({String s}) {}
+main() {
+  f(s: 'x');
+}
+''';
+    var expected = '''
+void f({@required String s}) {}
+main() {
+  f(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
+  test_named_parameter_no_default_used_non_null_required_option2_assume_required() async {
+    // Even if we are using the "assumeRequired" heuristic, we should not add a
+    // duplicate `@required` annotation.
+    addMetaPackage();
+    var content = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f(s: 'x');
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
+  test_named_parameter_no_default_used_null_option2() async {
+    var content = '''
+void f({String s}) {}
+main() {
+  f(s: null);
+}
+''';
+    var expected = '''
+void f({String? s}) {}
+main() {
+  f(s: null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_named_parameter_no_default_used_null_required_option2_assume_nullable() async {
+    // Explicitly passing `null` forces the parameter to be nullable even though
+    // it is required.
+    addMetaPackage();
+    var content = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f(s: null);
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f({@required String? s}) {}
+main() {
+  f(s: null);
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
+  test_named_parameter_no_default_used_null_required_option2_assume_required() async {
+    // Explicitly passing `null` forces the parameter to be nullable even though
+    // it is required.
+    addMetaPackage();
+    var content = '''
+import 'package:meta/meta.dart';
+void f({@required String s}) {}
+main() {
+  f(s: null);
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f({@required String? s}) {}
+main() {
+  f(s: null);
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
+  test_named_parameter_with_non_null_default_unused_option2() async {
+    var content = '''
+void f({String s: 'foo'}) {}
+main() {
+  f();
+}
+''';
+    var expected = '''
+void f({String s: 'foo'}) {}
+main() {
+  f();
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_named_parameter_with_non_null_default_used_non_null_option2() async {
+    var content = '''
+void f({String s: 'foo'}) {}
+main() {
+  f(s: 'bar');
+}
+''';
+    var expected = '''
+void f({String s: 'foo'}) {}
+main() {
+  f(s: 'bar');
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_named_parameter_with_non_null_default_used_null_option2() async {
+    var content = '''
+void f({String s: 'foo'}) {}
+main() {
+  f(s: null);
+}
+''';
+    var expected = '''
+void f({String? s: 'foo'}) {}
+main() {
+  f(s: null);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_named_parameter_with_null_default_unused_option2() async {
+    var content = '''
+void f({String s: null}) {}
+main() {
+  f();
+}
+''';
+    var expected = '''
+void f({String? s: null}) {}
+main() {
+  f();
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_non_null_assertion() async {
+    var content = '''
+int f(int i, [int j]) {
+  if (i == 0) return i;
+  return i + j;
+}
+''';
+
+    var expected = '''
+int f(int i, [int? j]) {
+  if (i == 0) return i;
+  return i + j!;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_single_file_multiple_changes() async {
+    var content = '''
+int f() => null;
+int g() => null;
+''';
+    var expected = '''
+int? f() => null;
+int? g() => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_single_file_single_change() async {
+    var content = '''
+int f() => null;
+''';
+    var expected = '''
+int? f() => null;
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  test_two_files() async {
+    var root = '/home/test/lib';
+    var path1 = convertPath('$root/file1.dart');
+    var file1 = '''
+import 'file2.dart';
+int f() => null;
+int h() => g();
+''';
+    var expected1 = '''
+import 'file2.dart';
+int? f() => null;
+int? h() => g();
+''';
+    var path2 = convertPath('$root/file2.dart');
+    var file2 = '''
+import 'file1.dart';
+int g() => f();
+''';
+    var expected2 = '''
+import 'file1.dart';
+int? g() => f();
+''';
+    await _checkMultipleFileChanges(
+        {path1: file1, path2: file2}, {path1: expected1, path2: expected2});
+  }
+}
+
+@reflectiveTest
+class ProvisionalApiTestPermissive extends ProvisionalApiTestBase
+    with ProvisionalApiTestCases {
+  @override
+  bool get usePermissiveMode => true;
+}
+
+/// Tests of the provisional API, where the driver is reset between calls to
+/// `prepareInput` and `processInput`, ensuring that the migration algorithm
+/// sees different AST and element objects during different phases.
+@reflectiveTest
+class ProvisionalApiTestWithReset extends ProvisionalApiTestBase
+    with ProvisionalApiTestCases {
+  @override
+  bool get usePermissiveMode => false;
+
+  @override
+  void _afterPrepare() {
+    driver.resetUriResolution();
+  }
+}
+
+class TestMigrationListener implements NullabilityMigrationListener {
+  final fixes = <SingleNullabilityFix>[];
+
+  @override
+  void addFix(SingleNullabilityFix fix) {
+    fixes.add(fix);
+  }
+}
diff --git a/pkg/analysis_server/test/src/nullability/test_all.dart b/pkg/analysis_server/test/src/nullability/test_all.dart
new file mode 100644
index 0000000..77b5187
--- /dev/null
+++ b/pkg/analysis_server/test/src/nullability/test_all.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.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'migration_visitor_test.dart' as migration_visitor_test;
+import 'provisional_api_test.dart' as provisional_api_test;
+import 'unit_propagation_test.dart' as unit_propagation_test;
+
+main() {
+  defineReflectiveSuite(() {
+    migration_visitor_test.main();
+    provisional_api_test.main();
+    unit_propagation_test.main();
+  });
+}
diff --git a/pkg/analysis_server/test/src/nullability/unit_propagation_test.dart b/pkg/analysis_server/test/src/nullability/unit_propagation_test.dart
new file mode 100644
index 0000000..d2fcf89
--- /dev/null
+++ b/pkg/analysis_server/test/src/nullability/unit_propagation_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.
+
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnitPropagationTest);
+  });
+}
+
+/// TODO(paulberry): write more tests
+@reflectiveTest
+class UnitPropagationTest {
+  var solver = Solver();
+
+  ConstraintVariable newVar(String name) => _NamedConstraintVariable(name);
+
+  test_record_copies_conditions() {
+    var a = newVar('a');
+    var b = newVar('b');
+    var conditions = [a];
+    solver.record(conditions, b);
+    conditions.removeLast();
+    expect(a.value, false);
+    expect(b.value, false);
+    solver.record([], a);
+    expect(a.value, true);
+    expect(b.value, true);
+  }
+
+  test_record_propagates_true_variables_immediately() {
+    var a = newVar('a');
+    expect(a.value, false);
+    solver.record([], a);
+    expect(a.value, true);
+    var b = newVar('b');
+    expect(b.value, false);
+    solver.record([a], b);
+    expect(b.value, true);
+  }
+}
+
+/// Representation of a constraint variable with a specified name.
+///
+/// This makes test failures easier to comprehend.
+class _NamedConstraintVariable extends ConstraintVariable {
+  final String _name;
+
+  _NamedConstraintVariable(this._name);
+
+  @override
+  String toString() => _name;
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
index 9d1e8fb..7019111 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
@@ -204,7 +204,7 @@
     await assertHasAssist('''
 part of my_app;
 main() {
-  HashMap<String, int> /*caret*/v = getMap();
+  HashMap<String, int> v = getMap();
 }
 ''', additionallyChangedFiles: {
       appPath: [
@@ -521,14 +521,14 @@
   test_privateType_sameLibrary() async {
     await resolveTestUnit('''
 class _A {}
-_A getValue() => new _A();
+_A getValue() => _A();
 main() {
   var v = getValue();
 }
 ''');
     await assertHasAssistAt('var ', '''
 class _A {}
-_A getValue() => new _A();
+_A getValue() => _A();
 main() {
   _A v = getValue();
 }
@@ -540,7 +540,7 @@
 library my_lib;
 class A {}
 class _B extends A {}
-_B getValue() => new _B();
+_B getValue() => _B();
 ''');
     await resolveTestUnit('''
 import 'my_lib.dart';
diff --git a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
index 1ff780c..cf9d0ba 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
@@ -55,7 +55,6 @@
   /// have been applied.
   Future<void> assertHasAssist(String expected,
       {Map<String, List<String>> additionallyChangedFiles}) async {
-    _setSelection();
     Assist assist = await _assertHasAssist();
     _change = assist.change;
     expect(_change.id, kind.id);
@@ -107,7 +106,6 @@
 
   /// Asserts that there is no [Assist] of the given [kind] at [_offset].
   Future<void> assertNoAssist() async {
-    _setSelection();
     List<Assist> assists = await _computeAssists();
     for (Assist assist in assists) {
       if (assist.kind == kind) {
@@ -136,6 +134,32 @@
     }).toList();
   }
 
+  @override
+  Future<void> resolveTestUnit(String code) async {
+    var offset = code.indexOf('/*caret*/');
+    if (offset >= 0) {
+      var endOffset = offset + '/*caret*/'.length;
+      code = code.substring(0, offset) + code.substring(endOffset);
+      _offset = offset;
+      _length = 0;
+    } else {
+      var startOffset = code.indexOf('// start\n');
+      var endOffset = code.indexOf('// end\n');
+      if (startOffset >= 0 && endOffset >= 0) {
+        var startLength = '// start\n'.length;
+        code = code.substring(0, startOffset) +
+            code.substring(startOffset + startLength, endOffset) +
+            code.substring(endOffset + '// end\n'.length);
+        _offset = startOffset;
+        _length = endOffset - startLength - _offset;
+      } else {
+        _offset = 0;
+        _length = 0;
+      }
+    }
+    return super.resolveTestUnit(code);
+  }
+
   /// Computes assists and verifies that there is an assist of the given kind.
   Future<Assist> _assertHasAssist() async {
     List<Assist> assists = await _computeAssists();
@@ -166,21 +190,4 @@
     }
     return positions;
   }
-
-  void _setSelection() {
-    _offset = testCode.indexOf('/*caret*/');
-    if (_offset >= 0) {
-      _offset += '/*caret*/'.length;
-      _length = 0;
-    } else {
-      _offset = testCode.indexOf('// start\n');
-      if (_offset >= 0) {
-        _offset += '// start\n'.length;
-        _length = testCode.indexOf('// end') - _offset;
-      } else {
-        _offset = 0;
-        _length = 0;
-      }
-    }
-  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
index 535bf55..b13e269 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
@@ -109,4 +109,25 @@
 }
 ''');
   }
+
+  test_preserveIndentation() async {
+    await resolveTestUnit('''
+class A {
+  /**
+   * First line.
+   *     Indented line.
+   * Last line.
+   */
+  m() {}
+}
+''');
+    await assertHasAssistAt('Indented', '''
+class A {
+  /// First line.
+  ///     Indented line.
+  /// Last line.
+  m() {}
+}
+''');
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
index 170a3c4..5e430f9 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
@@ -120,11 +120,7 @@
   int m();
 }
 ''');
-    await assertHasAssistAt('m()', '''
-abstract class C {
-  Future<int> m();
-}
-''');
+    await assertNoAssist();
   }
 
   test_method_noReturnType() async {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
new file mode 100644
index 0000000..fda239f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
@@ -0,0 +1,271 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToIfElementTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToIfElementTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_IF_ELEMENT;
+
+  void setUp() {
+    createAnalysisOptionsFile(experiments: [
+      EnableString.control_flow_collections,
+      EnableString.set_literals
+    ]);
+    super.setUp();
+  }
+
+  test_conditional_list() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return ['a', b /*caret*/? 'c' : 'd', 'e'];
+}
+''');
+    await assertHasAssist('''
+f(bool b) {
+  return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+  }
+
+  test_conditional_list_withParentheses() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return ['a', (b /*caret*/? 'c' : 'd'), 'e'];
+}
+''');
+    await assertHasAssist('''
+f(bool b) {
+  return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+  }
+
+  test_conditional_map() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return {'a' : 1, b /*caret*/? 'c' : 'd' : 2, 'e' : 3};
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_conditional_notConditional() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return {'/*caret*/a', b ? 'c' : 'd', 'e'};
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_conditional_notInLiteral() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return b /*caret*/? 'c' : 'd';
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_conditional_set() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return {'a', b /*caret*/? 'c' : 'd', 'e'};
+}
+''');
+    await assertHasAssist('''
+f(bool b) {
+  return {'a', if (b) 'c' else 'd', 'e'};
+}
+''');
+  }
+
+  test_conditional_set_withParentheses() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return {'a', ((b /*caret*/? 'c' : 'd')), 'e'};
+}
+''');
+    await assertHasAssist('''
+f(bool b) {
+  return {'a', if (b) 'c' else 'd', 'e'};
+}
+''');
+  }
+
+  test_mapFromIterable_complexKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) {
+    var result = e * 2;
+    return result;
+  }, value: (e) => e + 3);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_complexValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) {
+    var result = e  + 3;
+    return result;
+  });
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  var k = 3;
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  var k = 3;
+  return { for (var e in i) e * 2 : k };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var k in i) k * 2 : 0 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  var e = 2;
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  var e = 2;
+  return { for (var e1 in i) e1 * e : e1 + e };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var e in i) e * 2 : e + 3 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  int v = 0;
+  return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  int v = 0;
+  return { for (var e in i) v++ : e * 10 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  int index = 0;
+  return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  int index = 0;
+  return { for (var v in i) index++ : v * 10 };
+}
+''');
+  }
+
+  test_mapFromIterable_missingKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, value: (e) => e + 3);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_missingKeyAndValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_missingValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_notMapFromIterable() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
+}
+class A {
+  A.fromIterable(i, {key, value});
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_sameParameterNames() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var e in i) e * 2 : e + 3 };
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
index d76730c..79859c4 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
@@ -24,7 +24,7 @@
 const double myDouble = /*caret*/42.0;
 ''');
     await assertHasAssist('''
-const double myDouble = /*caret*/42;
+const double myDouble = 42;
 ''');
   }
 
@@ -40,7 +40,7 @@
 const double myDouble = /*caret*/4.2e1;
 ''');
     await assertHasAssist('''
-const double myDouble = /*caret*/42;
+const double myDouble = 42;
 ''');
   }
 
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_test.dart
new file mode 100644
index 0000000..a9b106e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_list_literal_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToListLiteralTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToListLiteralTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_LIST_LITERAL;
+
+  test_default_declaredType() async {
+    await resolveTestUnit('''
+List l = Li/*caret*/st();
+''');
+    await assertHasAssist('''
+List l = [];
+''');
+  }
+
+  test_default_minimal() async {
+    await resolveTestUnit('''
+var l = Li/*caret*/st();
+''');
+    await assertHasAssist('''
+var l = [];
+''');
+  }
+
+  test_default_newKeyword() async {
+    await resolveTestUnit('''
+var l = new Li/*caret*/st();
+''');
+    await assertHasAssist('''
+var l = [];
+''');
+  }
+
+  test_default_tooManyArguments() async {
+    await resolveTestUnit('''
+var l = Li/*caret*/st(5);
+''');
+    await assertNoAssist();
+  }
+
+  test_default_typeArg() async {
+    await resolveTestUnit('''
+var l = Li/*caret*/st<int>();
+''');
+    await assertHasAssist('''
+var l = <int>[];
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_test.dart
new file mode 100644
index 0000000..150b545
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_map_literal_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToMapLiteralTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToMapLiteralTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_MAP_LITERAL;
+
+  test_default_declaredType() async {
+    await resolveTestUnit('''
+Map m = Ma/*caret*/p();
+''');
+    await assertHasAssist('''
+Map m = {};
+''');
+  }
+
+  test_default_linkedHashMap() async {
+    await resolveTestUnit('''
+import 'dart:collection';
+var m = LinkedHashMa/*caret*/p();
+''');
+    await assertHasAssist('''
+import 'dart:collection';
+var m = {};
+''');
+  }
+
+  test_default_minimal() async {
+    await resolveTestUnit('''
+var m = Ma/*caret*/p();
+''');
+    await assertHasAssist('''
+var m = {};
+''');
+  }
+
+  test_default_newKeyword() async {
+    await resolveTestUnit('''
+var m = new Ma/*caret*/p();
+''');
+    await assertHasAssist('''
+var m = {};
+''');
+  }
+
+  test_default_typeArg() async {
+    await resolveTestUnit('''
+var m = Ma/*caret*/p<String, int>();
+''');
+    await assertHasAssist('''
+var m = <String, int>{};
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_test.dart
new file mode 100644
index 0000000..f4b1317
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_multiline_string_test.dart
@@ -0,0 +1,180 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToMultilineStringTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToMultilineStringTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_MULTILINE_STRING;
+
+  test_doubleQuoted() async {
+    await resolveTestUnit('''
+main() {
+  print("abc");
+}
+''');
+    await assertHasAssistAt('abc', '''
+main() {
+  print("""
+abc""");
+}
+''');
+  }
+
+  test_doubleQuoted_alreadyMultiline() async {
+    await resolveTestUnit('''
+main() {
+  print("""abc""");
+}
+''');
+    await assertNoAssistAt('abc');
+  }
+
+  test_doubleQuoted_interpolation_expressionElement() async {
+    await resolveTestUnit(r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print("a $b - ${c} d");
+}
+""");
+    await assertNoAssistAt(r'c}');
+  }
+
+  test_doubleQuoted_interpolation_stringElement_begin() async {
+    await resolveTestUnit(r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print("a $b - ${c} d");
+}
+""");
+    await assertHasAssistAt('"a ', r'''
+main() {
+  var b = 'b';
+  var c = 'c';
+  print("""
+a $b - ${c} d""");
+}
+''');
+  }
+
+  test_doubleQuoted_interpolation_stringElement_middle() async {
+    await resolveTestUnit(r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print("a $b - ${c} d");
+}
+""");
+    await assertHasAssistAt('- ', r'''
+main() {
+  var b = 'b';
+  var c = 'c';
+  print("""
+a $b - ${c} d""");
+}
+''');
+  }
+
+  test_doubleQuoted_raw() async {
+    await resolveTestUnit('''
+main() {
+  print(r"abc");
+}
+''');
+    await assertHasAssistAt('abc', '''
+main() {
+  print(r"""
+abc""");
+}
+''');
+  }
+
+  test_singleQuoted() async {
+    await resolveTestUnit('''
+main() {
+  print('abc');
+}
+''');
+    await assertHasAssistAt('abc', """
+main() {
+  print('''
+abc''');
+}
+""");
+  }
+
+  test_singleQuoted_interpolation_expressionElement() async {
+    await resolveTestUnit(r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print('a $b - ${c} d');
+}
+""");
+    await assertNoAssistAt(r'c}');
+  }
+
+  test_singleQuoted_interpolation_stringElement_begin() async {
+    await resolveTestUnit(r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print('a $b - ${c} d');
+}
+""");
+    await assertHasAssistAt("'a ", r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print('''
+a $b - ${c} d''');
+}
+""");
+  }
+
+  test_singleQuoted_interpolation_stringElement_middle() async {
+    await resolveTestUnit(r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print('a $b - ${c} d');
+}
+""");
+    await assertHasAssistAt("- ", r"""
+main() {
+  var b = 'b';
+  var c = 'c';
+  print('''
+a $b - ${c} d''');
+}
+""");
+  }
+
+  test_singleQuoted_raw() async {
+    await resolveTestUnit('''
+main() {
+  print(r'abc');
+}
+''');
+    await assertHasAssistAt('abc', """
+main() {
+  print(r'''
+abc''');
+}
+""");
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_test.dart
new file mode 100644
index 0000000..053bba7
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_set_literal_test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToSetLiteralTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToSetLiteralTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_SET_LITERAL;
+
+  test_default_declaredType() async {
+    await resolveTestUnit('''
+Set s = S/*caret*/et();
+''');
+    await assertHasAssist('''
+Set s = {};
+''');
+  }
+
+  test_default_minimal() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et();
+''');
+    await assertHasAssist('''
+var s = <dynamic>{};
+''');
+  }
+
+  test_default_newKeyword() async {
+    await resolveTestUnit('''
+var s = new S/*caret*/et();
+''');
+    await assertHasAssist('''
+var s = <dynamic>{};
+''');
+  }
+
+  test_default_typeArg() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et<int>();
+''');
+    await assertHasAssist('''
+var s = <int>{};
+''');
+  }
+
+  test_from_empty() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et.from([]);
+''');
+    await assertHasAssist('''
+var s = <dynamic>{};
+''');
+  }
+
+  test_from_newKeyword() async {
+    await resolveTestUnit('''
+var s = new S/*caret*/et.from([2, 3]);
+''');
+    await assertHasAssist('''
+var s = {2, 3};
+''');
+  }
+
+  test_from_noKeyword_declaredType() async {
+    await resolveTestUnit('''
+Set s = S/*caret*/et.from([2, 3]);
+''');
+    await assertHasAssist('''
+Set s = {2, 3};
+''');
+  }
+
+  test_from_noKeyword_typeArg_onConstructor() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et<int>.from([2, 3]);
+''');
+    await assertHasAssist('''
+var s = <int>{2, 3};
+''');
+  }
+
+  test_from_noKeyword_typeArg_onConstructorAndLiteral() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et<int>.from(<num>[2, 3]);
+''');
+    await assertHasAssist('''
+var s = <int>{2, 3};
+''');
+  }
+
+  test_from_noKeyword_typeArg_onLiteral() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et.from(<int>[2, 3]);
+''');
+    await assertHasAssist('''
+var s = <int>{2, 3};
+''');
+  }
+
+  test_from_nonEmpty() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et.from([2, 3]);
+''');
+    await assertHasAssist('''
+var s = {2, 3};
+''');
+  }
+
+  test_from_notALiteral() async {
+    await resolveTestUnit('''
+var l = [1];
+Set s = new S/*caret*/et.from(l);
+''');
+    await assertNoAssist();
+  }
+
+  test_from_trailingComma() async {
+    await resolveTestUnit('''
+var s = S/*caret*/et.from([2, 3,]);
+''');
+    await assertHasAssist('''
+var s = {2, 3,};
+''');
+  }
+
+  test_toSet_empty() async {
+    await resolveTestUnit('''
+var s = [].to/*caret*/Set();
+''');
+    await assertHasAssist('''
+var s = <dynamic>{};
+''');
+  }
+
+  test_toSet_empty_typeArg() async {
+    await resolveTestUnit('''
+var s = <int>[].to/*caret*/Set();
+''');
+    await assertHasAssist('''
+var s = <int>{};
+''');
+  }
+
+  test_toSet_nonEmpty() async {
+    await resolveTestUnit('''
+var s = [2, 3].to/*caret*/Set();
+''');
+    await assertHasAssist('''
+var s = {2, 3};
+''');
+  }
+
+  test_toSet_nonEmpty_typeArg() async {
+    await resolveTestUnit('''
+var s = <int>[2, 3].to/*caret*/Set();
+''');
+    await assertHasAssist('''
+var s = <int>{2, 3};
+''');
+  }
+
+  test_toSet_notALiteral() async {
+    await resolveTestUnit('''
+var l = [];
+var s = l.to/*caret*/Set();
+''');
+    await assertNoAssist();
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
new file mode 100644
index 0000000..648502f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.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:analysis_server/src/services/correction/assist.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';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToSpreadTest);
+    defineReflectiveTests(ConvertToSpreadWithControlFlowTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToSpreadTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_SPREAD;
+
+  void setUp() {
+    createAnalysisOptionsFile(experiments: [EnableString.spread_collections]);
+    super.setUp();
+  }
+
+  test_addAll_expression() async {
+    await resolveTestUnit('''
+f() {
+  var ints = [1, 2, 3];
+  print(['a']..addAl/*caret*/l(ints.map((i) => i.toString()))..addAll(['c']));
+}
+''');
+    await assertHasAssist('''
+f() {
+  var ints = [1, 2, 3];
+  print(['a', ...ints.map((i) => i.toString())]..addAll(['c']));
+}
+''');
+  }
+
+  test_addAll_literal() async {
+    await resolveTestUnit('''
+var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
+''');
+    await assertHasAssist('''
+var l = ['a', ...['b']]..addAll(['c']);
+''');
+  }
+
+  test_addAll_nonLiteralTarget() async {
+    await resolveTestUnit('''
+var l1 = [];
+var l2 = l1..addAl/*caret*/l(['b'])..addAll(['c']);
+''');
+    await assertNoAssist();
+  }
+
+  test_addAll_notFirst() async {
+    await resolveTestUnit('''
+var l = ['a']..addAll(['b'])../*caret*/addAll(['c']);
+''');
+    await assertNoAssist();
+  }
+
+  test_addAll_nullAware_const() async {
+    await resolveTestUnit('''
+var things;
+var l = ['a']..add/*caret*/All(things ?? const []);
+''');
+    await assertHasAssist('''
+var things;
+var l = ['a', ...?things];
+''');
+  }
+
+  test_addAll_nullAware_nonConst() async {
+    await resolveTestUnit('''
+var things;
+var l = ['a']..add/*caret*/All(things ?? []);
+''');
+    await assertHasAssist('''
+var things;
+var l = ['a', ...?things];
+''');
+  }
+}
+
+@reflectiveTest
+class ConvertToSpreadWithControlFlowTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_SPREAD;
+
+  void setUp() {
+    createAnalysisOptionsFile(experiments: [
+      EnableString.control_flow_collections,
+      EnableString.spread_collections
+    ]);
+    super.setUp();
+  }
+
+  test_addAll_condition_const() async {
+    await resolveTestUnit('''
+bool condition;
+var things;
+var l = ['a']..add/*caret*/All(condition ? things : const []);
+''');
+    await assertHasAssist('''
+bool condition;
+var things;
+var l = ['a', if (condition) ...things];
+''');
+  }
+
+  test_addAll_condition_nonConst() async {
+    await resolveTestUnit('''
+bool condition;
+var things;
+var l = ['a']..add/*caret*/All(condition ? things : []);
+''');
+    await assertHasAssist('''
+bool condition;
+var things;
+var l = ['a', if (condition) ...things];
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
index 8d34099..00e8383 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
@@ -25,8 +25,8 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Row(
-    /*caret*/child: new Container()
+  return Row(
+    /*caret*/child: Container()
   );
 }
 ''');
@@ -38,34 +38,30 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-// start
-    body: new Center(
-      /*caret*/child: new Container(
+  return Scaffold(
+    body: Center(
+      /*caret*/child: Container(
         width: 200.0,
         height: 300.0,
       ),
       key: null,
     ),
-// end
   );
 }
 ''');
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-// start
-    body: new Center(
-      /*caret*/children: <Widget>[
-        new Container(
+  return Scaffold(
+    body: Center(
+      children: <Widget>[
+        Container(
           width: 200.0,
           height: 300.0,
         ),
       ],
       key: null,
     ),
-// end
   );
 }
 ''');
@@ -77,35 +73,31 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-// start
-    body: new Center(
+  return Scaffold(
+    body: Center(
       /*caret*/child:
-          new Container(
+          Container(
         width: 200.0,
         height: 300.0,
       ),
       key: null,
     ),
-// end
   );
 }
 ''');
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-// start
-    body: new Center(
-      /*caret*/children: <Widget>[
-        new Container(
+  return Scaffold(
+    body: Center(
+      children: <Widget>[
+        Container(
           width: 200.0,
           height: 300.0,
         ),
       ],
       key: null,
     ),
-// end
   );
 }
 ''');
@@ -116,9 +108,9 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-    body: /*caret*/new Center(
-      child: new Container(),
+  return Scaffold(
+    body: /*caret*/Center(
+      child: Container(),
     ),
   );
 }
@@ -131,26 +123,22 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-// start
-    body: new Center(
-      /*caret*/child: new GestureDetector(),
+  return Scaffold(
+    body: Center(
+      /*caret*/child: GestureDetector(),
       key: null,
     ),
-// end
   );
 }
 ''');
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-// start
-    body: new Center(
-      /*caret*/children: <Widget>[new GestureDetector()],
+  return Scaffold(
+    body: Center(
+      children: <Widget>[GestureDetector()],
       key: null,
     ),
-// end
   );
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
index 977ea72..d3aaded 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
@@ -27,24 +27,22 @@
 class /*caret*/MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Container();
+    return Container();
   }
 }
 ''');
     await assertHasAssist(r'''
 import 'package:flutter/material.dart';
 
-class /*caret*/MyWidget extends StatefulWidget {
+class MyWidget extends StatefulWidget {
   @override
-  MyWidgetState createState() {
-    return new MyWidgetState();
-  }
+  _MyWidgetState createState() => _MyWidgetState();
 }
 
-class MyWidgetState extends State<MyWidget> {
+class _MyWidgetState extends State<MyWidget> {
   @override
   Widget build(BuildContext context) {
-    return new Container();
+    return Container();
   }
 }
 ''');
@@ -72,16 +70,16 @@
   @override
   Widget build(BuildContext context) {
     instanceField4 = instanceField1;
-    return new Row(
+    return Row(
       children: [
-        new Text(instanceField1),
-        new Text(instanceField2),
-        new Text(instanceField3),
-        new Text(instanceField4),
-        new Text(instanceField5),
-        new Text(staticField1),
-        new Text(staticField2),
-        new Text(staticField3),
+        Text(instanceField1),
+        Text(instanceField2),
+        Text(instanceField3),
+        Text(instanceField4),
+        Text(instanceField5),
+        Text(staticField1),
+        Text(staticField2),
+        Text(staticField3),
       ],
     );
   }
@@ -90,7 +88,7 @@
     await assertHasAssist(r'''
 import 'package:flutter/material.dart';
 
-class /*caret*/MyWidget extends StatefulWidget {
+class MyWidget extends StatefulWidget {
   static String staticField1;
   final String instanceField1;
   final String instanceField2;
@@ -103,12 +101,10 @@
   }
 
   @override
-  MyWidgetState createState() {
-    return new MyWidgetState();
-  }
+  _MyWidgetState createState() => _MyWidgetState();
 }
 
-class MyWidgetState extends State<MyWidget> {
+class _MyWidgetState extends State<MyWidget> {
   String instanceField4;
 
   String instanceField5;
@@ -116,16 +112,16 @@
   @override
   Widget build(BuildContext context) {
     instanceField4 = widget.instanceField1;
-    return new Row(
+    return Row(
       children: [
-        new Text(widget.instanceField1),
-        new Text(widget.instanceField2),
-        new Text(widget.instanceField3),
-        new Text(instanceField4),
-        new Text(instanceField5),
-        new Text(MyWidget.staticField1),
-        new Text(MyWidget.staticField2),
-        new Text(MyWidget.staticField3),
+        Text(widget.instanceField1),
+        Text(widget.instanceField2),
+        Text(widget.instanceField3),
+        Text(instanceField4),
+        Text(instanceField5),
+        Text(MyWidget.staticField1),
+        Text(MyWidget.staticField2),
+        Text(MyWidget.staticField3),
       ],
     );
   }
@@ -141,12 +137,12 @@
 class /*caret*/MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Row(
+    return Row(
       children: [
-        new Text(staticGetter1),
-        new Text(staticGetter2),
-        new Text(instanceGetter1),
-        new Text(instanceGetter2),
+        Text(staticGetter1),
+        Text(staticGetter2),
+        Text(instanceGetter1),
+        Text(instanceGetter2),
       ],
     );
   }
@@ -163,26 +159,24 @@
     await assertHasAssist(r'''
 import 'package:flutter/material.dart';
 
-class /*caret*/MyWidget extends StatefulWidget {
+class MyWidget extends StatefulWidget {
   @override
-  MyWidgetState createState() {
-    return new MyWidgetState();
-  }
+  _MyWidgetState createState() => _MyWidgetState();
 
   static String get staticGetter1 => '';
 
   static String get staticGetter2 => '';
 }
 
-class MyWidgetState extends State<MyWidget> {
+class _MyWidgetState extends State<MyWidget> {
   @override
   Widget build(BuildContext context) {
-    return new Row(
+    return Row(
       children: [
-        new Text(MyWidget.staticGetter1),
-        new Text(MyWidget.staticGetter2),
-        new Text(instanceGetter1),
-        new Text(instanceGetter2),
+        Text(MyWidget.staticGetter1),
+        Text(MyWidget.staticGetter2),
+        Text(instanceGetter1),
+        Text(instanceGetter2),
       ],
     );
   }
@@ -208,11 +202,11 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Row(
+    return Row(
       children: [
-        new Text(instanceField1),
-        new Text(instanceField2),
-        new Text(staticField),
+        Text(instanceField1),
+        Text(instanceField2),
+        Text(staticField),
       ],
     );
   }
@@ -239,16 +233,14 @@
     await assertHasAssist(r'''
 import 'package:flutter/material.dart';
 
-class /*caret*/MyWidget extends StatefulWidget {
+class MyWidget extends StatefulWidget {
   static String staticField;
   final String instanceField1;
 
   MyWidget(this.instanceField1);
 
   @override
-  MyWidgetState createState() {
-    return new MyWidgetState();
-  }
+  _MyWidgetState createState() => _MyWidgetState();
 
   static void staticMethod1() {
     print('static 1');
@@ -259,16 +251,16 @@
   }
 }
 
-class MyWidgetState extends State<MyWidget> {
+class _MyWidgetState extends State<MyWidget> {
   String instanceField2;
 
   @override
   Widget build(BuildContext context) {
-    return new Row(
+    return Row(
       children: [
-        new Text(widget.instanceField1),
-        new Text(instanceField2),
-        new Text(MyWidget.staticField),
+        Text(widget.instanceField1),
+        Text(instanceField2),
+        Text(MyWidget.staticField),
       ],
     );
   }
@@ -328,12 +320,12 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Row(
+    return Row(
       children: [
-        new Text(aaa),
-        new Text(bbb),
-        new Text('$aaa'),
-        new Text('${bbb}'),
+        Text(aaa),
+        Text(bbb),
+        Text('$aaa'),
+        Text('${bbb}'),
       ],
     );
   }
@@ -342,27 +334,25 @@
     await assertHasAssist(r'''
 import 'package:flutter/material.dart';
 
-class /*caret*/MyWidget extends StatefulWidget {
+class MyWidget extends StatefulWidget {
   final String aaa;
   final String bbb;
 
   const MyWidget(this.aaa, this.bbb);
 
   @override
-  MyWidgetState createState() {
-    return new MyWidgetState();
-  }
+  _MyWidgetState createState() => _MyWidgetState();
 }
 
-class MyWidgetState extends State<MyWidget> {
+class _MyWidgetState extends State<MyWidget> {
   @override
   Widget build(BuildContext context) {
-    return new Row(
+    return Row(
       children: [
-        new Text(widget.aaa),
-        new Text(widget.bbb),
-        new Text('${widget.aaa}'),
-        new Text('${widget.bbb}'),
+        Text(widget.aaa),
+        Text(widget.bbb),
+        Text('${widget.aaa}'),
+        Text('${widget.bbb}'),
       ],
     );
   }
@@ -378,24 +368,22 @@
 class /*caret*/MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Container();
+    return Container();
   }
 }
 ''');
     await assertHasAssist(r'''
 import 'package:flutter/material.dart';
 
-class /*caret*/MyWidget extends StatefulWidget {
+class MyWidget extends StatefulWidget {
   @override
-  MyWidgetState createState() {
-    return new MyWidgetState();
-  }
+  _MyWidgetState createState() => _MyWidgetState();
 }
 
-class MyWidgetState extends State<MyWidget> {
+class _MyWidgetState extends State<MyWidget> {
   @override
   Widget build(BuildContext context) {
-    return new Container();
+    return Container();
   }
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
index 5885e70..27069f0 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
@@ -24,11 +24,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('aaa'),
-      /*caret*/new Text('bbbbbb'),
-      new Text('ccccccccc'),
+      Text('aaa'),
+      /*caret*/Text('bbbbbb'),
+      Text('ccccccccc'),
     ],
   );
 }
@@ -36,16 +36,16 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('aaa'),
-      /*caret*/new Text('ccccccccc'),
-      new Text('bbbbbb'),
+      Text('aaa'),
+      Text('ccccccccc'),
+      Text('bbbbbb'),
     ],
   );
 }
 ''');
-    assertExitPosition(before: "new Text('bbbbbb')");
+    assertExitPosition(before: "Text('bbbbbb')");
   }
 
   test_last() async {
@@ -53,11 +53,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('aaa'),
-      new Text('bbb'),
-      /*caret*/new Text('ccc'),
+      Text('aaa'),
+      Text('bbb'),
+      /*caret*/Text('ccc'),
     ],
   );
 }
@@ -70,8 +70,8 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Center(
-    child: /*caret*/new Text('aaa'),
+  Center(
+    child: /*caret*/Text('aaa'),
   );
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
index 771bb73..a6b58b6 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
@@ -24,11 +24,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      /*caret*/new Text('aaa'),
-      new Text('bbb'),
-      new Text('ccc'),
+      /*caret*/Text('aaa'),
+      Text('bbb'),
+      Text('ccc'),
     ],
   );
 }
@@ -41,11 +41,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('aaa'),
-      /*caret*/new Text('bbbbbb'),
-      new Text('ccccccccc'),
+      Text('aaa'),
+      /*caret*/Text('bbbbbb'),
+      Text('ccccccccc'),
     ],
   );
 }
@@ -53,16 +53,16 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('bbbbbb'),
-      /*caret*/new Text('aaa'),
-      new Text('ccccccccc'),
+      Text('bbbbbb'),
+      Text('aaa'),
+      Text('ccccccccc'),
     ],
   );
 }
 ''');
-    assertExitPosition(before: "new Text('bbbbbb')");
+    assertExitPosition(before: "Text('bbbbbb')");
   }
 
   test_notInList() async {
@@ -70,8 +70,8 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Center(
-    child: /*caret*/new Text('aaa'),
+  Center(
+    child: /*caret*/Text('aaa'),
   );
 }
 ''');
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 842b191..03f1287 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
@@ -24,14 +24,14 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Center(
-        child: new /*caret*/Padding(
+      Center(
+        child: /*caret*/Padding(
           padding: const EdgeInsets.all(8.0),
-          child: new Center(
+          child: Center(
             heightFactor: 0.5,
-            child: new Text('foo'),
+            child: Text('foo'),
           ),
         ),
       ),
@@ -42,12 +42,12 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Center(
-        child: new Center(
+      Center(
+        child: Center(
           heightFactor: 0.5,
-          child: new Text('foo'),
+          child: Text('foo'),
         ),
       ),
     ],
@@ -61,11 +61,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Padding(
+  Padding(
     padding: const EdgeInsets.all(8.0),
-    child: new /*caret*/Center(
+    child: /*caret*/Center(
       heightFactor: 0.5,
-      child: new Text('foo'),
+      child: Text('foo'),
     ),
   );
 }
@@ -73,9 +73,9 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Padding(
+  Padding(
     padding: const EdgeInsets.all(8.0),
-    child: new Text('foo'),
+    child: Text('foo'),
   );
 }
 ''');
@@ -86,17 +86,17 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('foo'),
-      new /*caret*/Center(
+      Text('foo'),
+      /*caret*/Center(
         heightFactor: 0.5,
-        child: new Padding(
+        child: Padding(
           padding: const EdgeInsets.all(8.0),
-          child: new Text('bar'),
+          child: Text('bar'),
         ),
       ),
-      new Text('baz'),
+      Text('baz'),
     ],
   );
 }
@@ -104,14 +104,14 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('foo'),
-      new Padding(
+      Text('foo'),
+      Padding(
         padding: const EdgeInsets.all(8.0),
-        child: new Text('bar'),
+        child: Text('bar'),
       ),
-      new Text('baz'),
+      Text('baz'),
     ],
   );
 }
@@ -123,11 +123,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Center(
-    child: new /*caret*/Row(
+  Center(
+    child: /*caret*/Row(
       children: [
-        new Text('aaa'),
-        new Text('bbb'),
+        Text('aaa'),
+        Text('bbb'),
       ],
     ),
   );
@@ -141,10 +141,10 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Center(
-    child: /*caret*/new Column(
+  Center(
+    child: /*caret*/Column(
       children: [
-        new Text('foo'),
+        Text('foo'),
       ],
     ),
   );
@@ -153,8 +153,8 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Center(
-    child: /*caret*/new Text('foo'),
+  Center(
+    child: Text('foo'),
   );
 }
 ''');
@@ -165,9 +165,9 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  return /*caret*/new Column(
+  return /*caret*/Column(
     children: [
-      new Text('foo'),
+      Text('foo'),
     ],
   );
 }
@@ -175,7 +175,7 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  return /*caret*/new Text('foo');
+  return Text('foo');
 }
 ''');
   }
@@ -185,26 +185,26 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('aaa'),
-      new /*caret*/Column(
+      Text('aaa'),
+      /*caret*/Column(
         children: [
-          new Row(
+          Row(
             children: [
-              new Text('bbb'),
-              new Text('ccc'),
+              Text('bbb'),
+              Text('ccc'),
             ],
           ),
-          new Row(
+          Row(
             children: [
-              new Text('ddd'),
-              new Text('eee'),
+              Text('ddd'),
+              Text('eee'),
             ],
           ),
         ],
       ),
-      new Text('fff'),
+      Text('fff'),
     ],
   );
 }
@@ -212,22 +212,22 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: <Widget>[
-      new Text('aaa'),
-      new Row(
+      Text('aaa'),
+      Row(
         children: [
-          new Text('bbb'),
-          new Text('ccc'),
+          Text('bbb'),
+          Text('ccc'),
         ],
       ),
-      new Row(
+      Row(
         children: [
-          new Text('ddd'),
-          new Text('eee'),
+          Text('ddd'),
+          Text('eee'),
         ],
       ),
-      new Text('fff'),
+      Text('fff'),
     ],
   );
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
index 03b6f84..7ec4246 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
@@ -24,11 +24,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-    body: new /*caret*/GestureDetector(
+  return Scaffold(
+    body: /*caret*/GestureDetector(
       onTap: () => startResize(),
-      child: new Center(
-        child: new Container(
+      child: Center(
+        child: Container(
           width: 200.0,
           height: 300.0,
         ),
@@ -42,12 +42,12 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-    body: new Center(
+  return Scaffold(
+    body: Center(
       key: null,
-      child: new /*caret*/GestureDetector(
+      child: GestureDetector(
         onTap: () => startResize(),
-        child: new Container(
+        child: Container(
           width: 200.0,
           height: 300.0,
         ),
@@ -66,16 +66,16 @@
 
 class Foo extends StatefulWidget {
   @override
-  _State createState() => new _State();
+  _State createState() => _State();
 }
 
 class _State extends State<Foo> {
   @override
   Widget build(BuildContext context) {
-    return new /*caret*/Expanded(
+    return /*caret*/Expanded(
       flex: 2,
-      child: new GestureDetector(
-        child: new Text(
+      child: GestureDetector(
+        child: Text(
           'foo',
         ), onTap: () {
           print(42);
@@ -89,19 +89,19 @@
 
 class Foo extends StatefulWidget {
   @override
-  _State createState() => new _State();
+  _State createState() => _State();
 }
 
 class _State extends State<Foo> {
   @override
   Widget build(BuildContext context) {
-    return new GestureDetector(
+    return GestureDetector(
       onTap: () {
         print(42);
     },
-      child: new /*caret*/Expanded(
+      child: Expanded(
         flex: 2,
-        child: new Text(
+        child: Text(
           'foo',
         ),
       ),
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
index d5ad1d3..13a88b7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
@@ -24,11 +24,11 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-    body: new Center(
-      child: new /*caret*/GestureDetector(
+  return Scaffold(
+    body: Center(
+      child: /*caret*/GestureDetector(
         onTap: () => startResize(),
-        child: new Container(
+        child: Container(
           width: 200.0,
           height: 300.0,
         ),
@@ -42,12 +42,12 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 build() {
-  return new Scaffold(
-    body: new /*caret*/GestureDetector(
+  return Scaffold(
+    body: GestureDetector(
       onTap: () => startResize(),
-      child: new Center(
+      child: Center(
         key: null,
-        child: new Container(
+        child: Container(
           width: 200.0,
           height: 300.0,
         ),
@@ -66,15 +66,15 @@
 
 class Foo extends StatefulWidget {
   @override
-  _State createState() => new _State();
+  _State createState() => _State();
 }
 
 class _State extends State<Foo> {
   @override
   Widget build(BuildContext context) {
-    return new GestureDetector(
-      child: new /*caret*/Expanded(
-        child: new Text(
+    return GestureDetector(
+      child: /*caret*/Expanded(
+        child: Text(
           'foo',
         ),
         flex: 2,
@@ -89,19 +89,19 @@
 
 class Foo extends StatefulWidget {
   @override
-  _State createState() => new _State();
+  _State createState() => _State();
 }
 
 class _State extends State<Foo> {
   @override
   Widget build(BuildContext context) {
-    return new /*caret*/Expanded(
+    return Expanded(
       flex: 2,
-      child: new GestureDetector(
+      child: GestureDetector(
         onTap: () {
           print(42);
       },
-        child: new Text(
+        child: Text(
           'foo',
         ),
       ),
@@ -115,14 +115,14 @@
     await resolveTestUnit('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: [
-      new Column(
+      Column(
         children: [
-          new Padding(
-            padding: new EdgeInsets.all(16.0),
-            child: new /*caret*/Center(
-              child: new Column(
+          Padding(
+            padding: EdgeInsets.all(16.0),
+            child: /*caret*/Center(
+              child: Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: <Widget>[],
               ),
@@ -137,14 +137,14 @@
     await assertHasAssist('''
 import 'package:flutter/material.dart';
 main() {
-  new Column(
+  Column(
     children: [
-      new Column(
+      Column(
         children: [
-          new /*caret*/Center(
-            child: new Padding(
-              padding: new EdgeInsets.all(16.0),
-              child: new Column(
+          Center(
+            child: Padding(
+              padding: EdgeInsets.all(16.0),
+              child: Column(
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: <Widget>[],
               ),
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
index 4e300e2..f51ffa7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
@@ -25,7 +25,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/new Center();
+    return /*caret*/Center();
   }
 }
 ''');
@@ -38,7 +38,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/new Container();
+    return /*caret*/Container();
   }
 }
 ''');
@@ -46,7 +46,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/Center(child: new Container());
+    return Center(child: Container());
   }
 }
 ''');
@@ -77,7 +77,7 @@
 }
 
 main() {
-  return Center(child: MyWidget./*caret*/named());
+  return Center(child: MyWidget.named());
 }
 ''');
   }
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 cad4036..6e668f3 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
@@ -26,8 +26,8 @@
 
 class FakeFlutter {
   main() {
-    return new Container(
-      child: new /*caret*/Text('aaa'),
+    return Container(
+      child: /*caret*/Text('aaa'),
     );
   }
 }
@@ -37,10 +37,10 @@
 
 class FakeFlutter {
   main() {
-    return new Container(
+    return Container(
       child: Column(
         children: <Widget>[
-          new /*caret*/Text('aaa'),
+          Text('aaa'),
         ],
       ),
     );
@@ -56,13 +56,13 @@
 
 class FakeFlutter {
   main() {
-    return new Row(children: [
-      new Text('aaa'),
+    return Row(children: [
+      Text('aaa'),
 // start
-      new Text('bbb'),
-      new Text('ccc'),
+      Text('bbb'),
+      Text('ccc'),
 // end
-      new Text('ddd'),
+      Text('ddd'),
     ]);
   }
 }
@@ -72,17 +72,15 @@
 
 class FakeFlutter {
   main() {
-    return new Row(children: [
-      new Text('aaa'),
-// start
+    return Row(children: [
+      Text('aaa'),
       Column(
         children: <Widget>[
-          new Text('bbb'),
-          new Text('ccc'),
+          Text('bbb'),
+          Text('ccc'),
         ],
       ),
-// end
-      new Text('ddd'),
+      Text('ddd'),
     ]);
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
index 15f8433..f52a92c 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
@@ -24,7 +24,7 @@
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 main() {
-  return /*caret*/new Container();
+  return /*caret*/Container();
 }
 ''');
     await assertNoAssist();
@@ -35,13 +35,13 @@
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 main() {
-  /*caret*/new Text('a');
+  /*caret*/Text('a');
 }
 ''');
     await assertHasAssist('''
 import 'package:flutter/widgets.dart';
 main() {
-  /*caret*/Container(child: new Text('a'));
+  Container(child: Text('a'));
 }
 ''');
   }
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 30b416b..40983c8 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
@@ -32,15 +32,13 @@
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 build() {
-  return new Container(
-    child: new Row(
-// start
+  return Container(
+    child: Row(
       children: [/*caret*/
-        new Text('111'),
-        new Text('222'),
-        new Container(),
+        Text('111'),
+        Text('222'),
+        Container(),
       ],
-// end
     ),
   );
 }
@@ -48,19 +46,17 @@
     await assertHasAssist('''
 import 'package:flutter/widgets.dart';
 build() {
-  return new Container(
-    child: new Row(
-// start
+  return Container(
+    child: Row(
       children: [
-        new widget(
-          children: [/*caret*/
-            new Text('111'),
-            new Text('222'),
-            new Container(),
+        widget(
+          children: [
+            Text('111'),
+            Text('222'),
+            Container(),
           ],
         ),
       ],
-// end
     ),
   );
 }
@@ -73,13 +69,13 @@
     await resolveTestUnit('''
 import 'package:flutter/widgets.dart';
 build() {
-  return new Container(
-    child: new Row(
+  return Container(
+    child: Row(
       children: [/*caret*/
 // start
-        new Transform(),
-        new Object(),
-        new AspectRatio(),
+        Transform(),
+        Object(),
+        AspectRatio(),
 // end
       ],
     ),
@@ -95,17 +91,15 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return new Container(
-// start
-      child: new /*caret*/DefaultTextStyle(
-        child: new Row(
+    return Container(
+      child: /*caret*/DefaultTextStyle(
+        child: Row(
           children: <Widget>[
-            new Container(
+            Container(
             ),
           ],
         ),
       ),
-// end
     );
   }
 }
@@ -114,19 +108,17 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return new Container(
-// start
+    return Container(
       child: widget(
-        child: new /*caret*/DefaultTextStyle(
-          child: new Row(
+        child: DefaultTextStyle(
+          child: Row(
             children: <Widget>[
-              new Container(
+              Container(
               ),
             ],
           ),
         ),
       ),
-// end
     );
   }
 }
@@ -139,17 +131,15 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {\r
   main() {\r
-    return new Container(\r
-// start\r
-      child: new /*caret*/DefaultTextStyle(\r
-        child: new Row(\r
+    return Container(\r
+      child: /*caret*/DefaultTextStyle(\r
+        child: Row(\r
           children: <Widget>[\r
-            new Container(\r
+            Container(\r
             ),\r
           ],\r
         ),\r
       ),\r
-// end\r
     );\r
   }\r
 }\r
@@ -158,19 +148,17 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {\r
   main() {\r
-    return new Container(\r
-// start\r
+    return Container(\r
       child: widget(\r
-        child: new /*caret*/DefaultTextStyle(\r
-          child: new Row(\r
+        child: DefaultTextStyle(\r
+          child: Row(\r
             children: <Widget>[\r
-              new Container(\r
+              Container(\r
               ),\r
             ],\r
           ),\r
         ),\r
       ),\r
-// end\r
     );\r
   }\r
 }\r
@@ -198,7 +186,7 @@
 }
 
 main(Foo foo) {
-  return widget(child: foo./*caret*/bar);
+  return widget(child: foo.bar);
 }
 ''');
   }
@@ -224,7 +212,7 @@
 }
 
 main(Foo foo) {
-  return /*caret*/widget(child: foo.bar);
+  return widget(child: foo.bar);
 }
 ''');
   }
@@ -236,9 +224,7 @@
 class FakeFlutter {
   main() {
   var obj;
-// start
-    return new Row(children: [/*caret*/ new Container()]);
-// end
+    return Row(children: [/*caret*/ Container()]);
   }
 }
 ''');
@@ -251,9 +237,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-// start
-    return /*caret*/new Container();
-// end
+    return /*caret*/Container();
   }
 }
 ''');
@@ -261,9 +245,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-// start
-    return /*caret*/widget(child: new Container());
-// end
+    return widget(child: Container());
   }
 }
 ''');
@@ -275,7 +257,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return new ClipRect./*caret*/rect();
+    return ClipRect./*caret*/rect();
   }
 }
 ''');
@@ -283,7 +265,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return widget(child: new ClipRect./*caret*/rect());
+    return widget(child: ClipRect.rect());
   }
 }
 ''');
@@ -295,7 +277,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    var container = new Container();
+    var container = Container();
     return /*caret*/container;
   }
 }
@@ -304,8 +286,8 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    var container = new Container();
-    return /*caret*/widget(child: container);
+    var container = Container();
+    return widget(child: container);
   }
 }
 ''');
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
index 50b927b..acc611a 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
@@ -25,7 +25,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/new Container();
+    return /*caret*/Container();
   }
 }
 ''');
@@ -33,9 +33,9 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/Padding(
+    return Padding(
       padding: const EdgeInsets.all(8.0),
-      child: new Container(),
+      child: Container(),
     );
   }
 }
@@ -48,7 +48,7 @@
 import 'package:flutter/widgets.dart';
 class FakeFlutter {
   main() {
-    return /*caret*/new Padding();
+    return /*caret*/Padding();
   }
 }
 ''');
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 c18ac34..32331c2 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
@@ -26,13 +26,13 @@
 
 class FakeFlutter {
   main() {
-    return new Column(children: [
-      new Text('aaa'),
+    return Column(children: [
+      Text('aaa'),
 // start
-      new Text('bbb'),
-      new Text('ccc'),
+      Text('bbb'),
+      Text('ccc'),
 // end
-      new Text('ddd'),
+      Text('ddd'),
     ]);
   }
 }
@@ -42,17 +42,15 @@
 
 class FakeFlutter {
   main() {
-    return new Column(children: [
-      new Text('aaa'),
-// start
+    return Column(children: [
+      Text('aaa'),
       Row(
         children: <Widget>[
-          new Text('bbb'),
-          new Text('ccc'),
+          Text('bbb'),
+          Text('ccc'),
         ],
       ),
-// end
-      new Text('ddd'),
+      Text('ddd'),
     ]);
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
index be7d5c2..c924f7e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
@@ -40,17 +40,17 @@
 import 'package:flutter/widgets.dart';
 
 main() {
-  /*caret*/new Text('a');
+  /*caret*/Text('a');
 }
 ''');
     await assertHasAssist('''
 import 'package:flutter/widgets.dart';
 
 main() {
-  /*caret*/StreamBuilder<Object>(
+  StreamBuilder<Object>(
     stream: null,
     builder: (context, snapshot) {
-      return new Text('a');
+      return Text('a');
     }
   );
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
index f4647be..52f5125 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
@@ -30,12 +30,10 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   {
     print(0);
     print(1);
   }
-// end
 }
 ''');
   }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
index 96fbd14..56d81c3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
@@ -30,12 +30,10 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   do {
     print(0);
     print(1);
   } while (condition);
-// end
 }
 ''');
     assertLinkedGroup(0, ['condition);']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
index c775e1c..6427730 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
@@ -30,12 +30,10 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   for (var item in iterable) {
     print(0);
     print(1);
   }
-// end
 }
 ''');
     assertLinkedGroup(0, ['item']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
index 770684c..095f0ed 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
@@ -30,12 +30,10 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   for (var v = init; condition; increment) {
     print(0);
     print(1);
   }
-// end
 }
 ''');
     assertLinkedGroup(0, ['v =']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
index de8df15..5780cfa 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
@@ -30,12 +30,10 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   if (condition) {
     print(0);
     print(1);
   }
-// end
 }
 ''');
     assertLinkedGroup(0, ['condition']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
index f39a5e0..bf806e9 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
@@ -30,14 +30,12 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   try {
     print(0);
     print(1);
   } on Exception catch (e) {
     // TODO
   }
-// end
 }
 ''');
     assertLinkedGroup(0, ['Exception']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
index 7e9267c..8527cd7 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
@@ -30,14 +30,12 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   try {
     print(0);
     print(1);
   } finally {
     // TODO
   }
-// end
 }
 ''');
     assertLinkedGroup(0, ['// TODO']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
index 939e211..38f0beb 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
@@ -30,12 +30,10 @@
 ''');
     await assertHasAssist('''
 main() {
-// start
   while (condition) {
     print(0);
     print(1);
   }
-// end
 }
 ''');
     assertLinkedGroup(0, ['condition']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index be58fce..86c5872 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -25,10 +25,16 @@
 import 'convert_to_double_quoted_string_test.dart'
     as convert_to_double_quoted_string;
 import 'convert_to_field_parameter_test.dart' as convert_to_field_parameter;
+import 'convert_to_if_element_test.dart' as convert_to_if_element;
 import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
+import 'convert_to_list_literal_test.dart' as convert_to_list_literal;
+import 'convert_to_map_literal_test.dart' as convert_to_map_literal;
+import 'convert_to_multiline_string_test.dart' as convert_to_multiline_string;
 import 'convert_to_normal_parameter_test.dart' as convert_to_normal_parameter;
+import 'convert_to_set_literal_test.dart' as convert_to_set_literal;
 import 'convert_to_single_quoted_string_test.dart'
     as convert_to_single_quoted_string;
+import 'convert_to_spread_test.dart' as convert_to_spread;
 import 'encapsulate_field_test.dart' as encapsulate_field;
 import 'exchange_operands_test.dart' as exchange_operands;
 import 'flutter_convert_to_children_test.dart' as flutter_convert_to_children;
@@ -87,9 +93,15 @@
     convert_part_of_to_uri.main();
     convert_to_double_quoted_string.main();
     convert_to_field_parameter.main();
+    convert_to_if_element.main();
     convert_to_int_literal.main();
+    convert_to_list_literal.main();
+    convert_to_map_literal.main();
+    convert_to_multiline_string.main();
     convert_to_normal_parameter.main();
+    convert_to_set_literal.main();
     convert_to_single_quoted_string.main();
+    convert_to_spread.main();
     encapsulate_field.main();
     exchange_operands.main();
     flutter_convert_to_children.main();
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 20df52c..57ff490 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
@@ -325,6 +325,7 @@
   test(abc: null);
 }
 ''');
+    assertLinkedGroup(change.linkedEditGroups[0], ['null);']);
   }
 
   test_single_normal() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_test.dart
new file mode 100644
index 0000000..1874b6f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_annotation_test.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveAnnotationTest);
+  });
+}
+
+@reflectiveTest
+class RemoveAnnotationTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_ANNOTATION;
+
+  @override
+  void setUp() {
+    super.setUp();
+    addMetaPackage();
+  }
+
+  test_factory() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+@factory
+f() {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f() {}
+''');
+  }
+
+  test_immutable() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+@immutable
+f() {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f() {}
+''');
+  }
+
+  test_literal() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+@literal
+f() {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f() {}
+''');
+  }
+
+  test_override_field() async {
+    await resolveTestUnit('''
+class A {
+  @override
+  String name;
+}
+''');
+    await assertHasFix('''
+class A {
+  String name;
+}
+''');
+  }
+
+  test_override_getter() async {
+    await resolveTestUnit('''
+class A {
+  @override
+  int get zero => 0;
+}
+''');
+    await assertHasFix('''
+class A {
+  int get zero => 0;
+}
+''');
+  }
+
+  test_override_method() async {
+    await resolveTestUnit('''
+class A {
+  @override
+  void m() {}
+}
+''');
+    await assertHasFix('''
+class A {
+  void m() {}
+}
+''');
+  }
+
+  test_override_setter() async {
+    await resolveTestUnit('''
+class A {
+  @override
+  set value(v) {}
+}
+''');
+    await assertHasFix('''
+class A {
+  set value(v) {}
+}
+''');
+  }
+
+  test_required_namedWithDefault() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+f({@required int x = 0}) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f({int x = 0}) {}
+''');
+  }
+
+  test_required_positional() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+f([@required int x]) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f([int x]) {}
+''');
+  }
+
+  test_required_required() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+f(@required int x) {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f(int x) {}
+''');
+  }
+
+  test_sealed() async {
+    await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+@sealed
+f() {}
+''');
+    await assertHasFix('''
+import 'package:meta/meta.dart';
+
+f() {}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
index eec8f7c..7f2fc41 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
@@ -19,6 +19,73 @@
   @override
   FixKind get kind => DartFixKind.REMOVE_DEAD_CODE;
 
+  test_catch_afterCatchAll_catch() async {
+    await resolveTestUnit('''
+main() {
+  try {
+  } catch (e) {
+    print('a');
+  } catch (e) {
+    print('b');
+  }
+}
+''');
+    await assertHasFix('''
+main() {
+  try {
+  } catch (e) {
+    print('a');
+  }
+}
+''');
+  }
+
+  test_catch_afterCatchAll_on() async {
+    await resolveTestUnit('''
+main() {
+  try {
+  } on Object {
+    print('a');
+  } catch (e) {
+    print('b');
+  }
+}
+''');
+    await assertHasFix('''
+main() {
+  try {
+  } on Object {
+    print('a');
+  }
+}
+''');
+  }
+
+  test_catch_subtype() async {
+    await resolveTestUnit('''
+class A {}
+class B extends A {}
+main() {
+  try {
+  } on A {
+    print('a');
+  } on B {
+    print('b');
+  }
+}
+''');
+    await assertHasFix('''
+class A {}
+class B extends A {}
+main() {
+  try {
+  } on A {
+    print('a');
+  }
+}
+''');
+  }
+
   test_condition() async {
     await resolveTestUnit('''
 main(int p) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_test.dart
new file mode 100644
index 0000000..3ed155e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_name_from_combinator_test.dart
@@ -0,0 +1,357 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/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';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveNameFromCombinatorTest);
+  });
+}
+
+@reflectiveTest
+class RemoveNameFromCombinatorTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.REMOVE_NAME_FROM_COMBINATOR;
+
+  test_duplicateHiddenName_last() async {
+    await resolveTestUnit('''
+import 'dart:math' hide cos, sin, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  test_duplicateHiddenName_middle() async {
+    await resolveTestUnit('''
+import 'dart:math' hide cos, cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  @failingTest
+  test_duplicateHiddenName_only_last() async {
+    // It appears that the hint does not detect names that are duplicated across
+    // multiple combinators.
+    await resolveTestUnit('''
+import 'dart:math' hide cos, sin hide sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  @failingTest
+  test_duplicateHiddenName_only_middle() async {
+    // It appears that the hint does not detect names that are duplicated across
+    // multiple combinators.
+    await resolveTestUnit('''
+import 'dart:math' hide cos hide cos hide sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos hide sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  test_duplicateShownName_last() async {
+    await resolveTestUnit(
+      '''
+import 'dart:math' show cos, sin, sin;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''',
+    );
+    await assertHasFix('''
+import 'dart:math' show cos, sin;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+  }
+
+  test_duplicateShownName_middle() async {
+    await resolveTestUnit('''
+import 'dart:math' show cos, cos, sin;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show cos, sin;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+  }
+
+  test_undefinedHiddenName_first() async {
+    await resolveTestUnit('''
+import 'dart:math' hide aaa, sin, tan;
+
+f(x) {
+  print(cos(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide sin, tan;
+
+f(x) {
+  print(cos(x));
+}
+''');
+  }
+
+  test_undefinedHiddenName_last() async {
+    await resolveTestUnit('''
+import 'dart:math' hide cos, sin, xxx;
+
+f(x) {
+  print(tan(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, sin;
+
+f(x) {
+  print(tan(x));
+}
+''');
+  }
+
+  test_undefinedHiddenName_middle() async {
+    await resolveTestUnit('''
+import 'dart:math' hide cos, mmm, tan;
+
+f(x) {
+  print(sin(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, tan;
+
+f(x) {
+  print(sin(x));
+}
+''');
+  }
+
+  test_undefinedHiddenName_only_first() async {
+    await resolveTestUnit('''
+import 'dart:math' hide aaa hide cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  test_undefinedHiddenName_only_last() async {
+    await resolveTestUnit('''
+import 'dart:math' hide cos, sin hide aaa;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos, sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  test_undefinedHiddenName_only_middle() async {
+    await resolveTestUnit('''
+import 'dart:math' hide cos hide aaa hide sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' hide cos hide sin;
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
+  test_undefinedHiddenName_only_only() async {
+    await resolveTestUnit('''
+import 'dart:math' hide aaa;
+var c = sin(0.3);
+''');
+    await assertHasFix('''
+import 'dart:math';
+var c = sin(0.3);
+''');
+  }
+
+  test_undefinedHiddenName_only_only_withAs() async {
+    await resolveTestUnit('''
+import 'dart:math' as math hide aaa;
+var c = math.sin(0.3);
+''');
+    await assertHasFix('''
+import 'dart:math' as math;
+var c = math.sin(0.3);
+''');
+  }
+
+  test_undefinedShownName_first() async {
+    await resolveTestUnit('''
+import 'dart:math' show aaa, sin, tan;
+
+f(x) {
+  print(sin(x) + tan(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show sin, tan;
+
+f(x) {
+  print(sin(x) + tan(x));
+}
+''');
+  }
+
+  test_undefinedShownName_last() async {
+    await resolveTestUnit('''
+import 'dart:math' show cos, sin, xxx;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show cos, sin;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+  }
+
+  test_undefinedShownName_middle() async {
+    await resolveTestUnit('''
+import 'dart:math' show cos, mmm, tan;
+
+f(x) {
+  print(cos(x) + tan(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show cos, tan;
+
+f(x) {
+  print(cos(x) + tan(x));
+}
+''');
+  }
+
+  test_unusedShownName_first() async {
+    await resolveTestUnit('''
+import 'dart:math' show cos, sin, tan;
+
+f(x) {
+  print(sin(x) + tan(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show sin, tan;
+
+f(x) {
+  print(sin(x) + tan(x));
+}
+''');
+  }
+
+  test_unusedShownName_last() async {
+    await resolveTestUnit('''
+import 'dart:math' show cos, sin, tan;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show cos, sin;
+
+f(x) {
+  print(cos(x) + sin(x));
+}
+''');
+  }
+
+  test_unusedShownName_middle() async {
+    await resolveTestUnit('''
+import 'dart:math' show cos, sin, tan;
+
+f(x) {
+  print(cos(x) + tan(x));
+}
+''');
+    await assertHasFix('''
+import 'dart:math' show cos, tan;
+
+f(x) {
+  print(cos(x) + tan(x));
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
index 96ee02f..e7a4db9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
@@ -86,6 +86,24 @@
 ''');
   }
 
+  test_duplicateImport() async {
+    await resolveTestUnit('''
+import 'dart:math';
+import 'dart:math';
+
+main() {
+  print(min(0, 1));
+}
+''');
+    await assertHasFix('''
+import 'dart:math';
+
+main() {
+  print(min(0, 1));
+}
+''');
+  }
+
   test_multipleOfSame_all() async {
     await resolveTestUnit('''
 import 'dart:math';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_literal_test.dart
deleted file mode 100644
index 7ec1088..0000000
--- a/pkg/analysis_server/test/src/services/correction/fix/replace_with_literal_test.dart
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analysis_server/src/services/correction/fix_internal.dart';
-import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'fix_processor.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ReplaceWithLiteralTest);
-  });
-}
-
-@reflectiveTest
-class ReplaceWithLiteralTest extends FixProcessorLintTest {
-  @override
-  FixKind get kind => DartFixKind.REPLACE_WITH_LITERAL;
-
-  @override
-  String get lintCode => LintNames.prefer_collection_literals;
-
-  test_linkedHashMap_withCommentsInGeneric() async {
-    await resolveTestUnit('''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap<int,/*comment*/int>();
-''');
-    await assertHasFix('''
-import 'dart:collection';
-
-final a = /*LINT*/<int,/*comment*/int>{};
-''');
-  }
-
-  test_linkedHashMap_withDynamicGenerics() async {
-    await resolveTestUnit('''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap<dynamic,dynamic>();
-''');
-    await assertHasFix('''
-import 'dart:collection';
-
-final a = /*LINT*/<dynamic,dynamic>{};
-''');
-  }
-
-  test_linkedHashMap_withGeneric() async {
-    await resolveTestUnit('''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap<int,int>();
-''');
-    await assertHasFix('''
-import 'dart:collection';
-
-final a = /*LINT*/<int,int>{};
-''');
-  }
-
-  test_linkedHashMap_withoutGeneric() async {
-    await resolveTestUnit('''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap();
-''');
-    await assertHasFix('''
-import 'dart:collection';
-
-final a = /*LINT*/{};
-''');
-  }
-
-  test_list_withGeneric() async {
-    await resolveTestUnit('''
-final a = /*LINT*/new List<int>();
-''');
-    await assertHasFix('''
-final a = /*LINT*/<int>[];
-''');
-  }
-
-  test_list_withoutGeneric() async {
-    await resolveTestUnit('''
-final a = /*LINT*/new List();
-''');
-    await assertHasFix('''
-final a = /*LINT*/[];
-''');
-  }
-
-  test_map_withGeneric() async {
-    await resolveTestUnit('''
-final a = /*LINT*/new Map<int,int>();
-''');
-    await assertHasFix('''
-final a = /*LINT*/<int,int>{};
-''');
-  }
-
-  test_map_withoutGeneric() async {
-    await resolveTestUnit('''
-final a = /*LINT*/new Map();
-''');
-    await assertHasFix('''
-final a = /*LINT*/{};
-''');
-  }
-}
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 de6f043..6a259e9 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
@@ -54,6 +54,7 @@
 import 'make_field_not_final_test.dart' as make_field_not_final;
 import 'make_final_test.dart' as make_final;
 import 'move_type_arguments_to_class_test.dart' as move_type_arguments_to_class;
+import 'remove_annotation_test.dart' as remove_annotation;
 import 'remove_await_test.dart' as remove_await;
 import 'remove_dead_code_test.dart' as remove_dead_code;
 import 'remove_empty_catch_test.dart' as remove_empty_catch;
@@ -64,6 +65,7 @@
 import 'remove_initializer_test.dart' as remove_initializer;
 import 'remove_interpolation_braces_test.dart' as remove_interpolation_braces;
 import 'remove_method_declaration_test.dart' as remove_method_declaration;
+import 'remove_name_from_combinator_test.dart' as remove_name_from_combinator;
 import 'remove_parameters_in_getter_declaration_test.dart'
     as remove_parameters_in_getter_declaration;
 import 'remove_parentheses_in_getter_invocation_test.dart'
@@ -84,7 +86,6 @@
 import 'replace_with_conditional_assignment_test.dart'
     as replace_with_conditional_assignment;
 import 'replace_with_identifier_test.dart' as replace_with_identifier;
-import 'replace_with_literal_test.dart' as replace_with_literal;
 import 'replace_with_null_aware_test.dart' as replace_with_null_aware;
 import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
 import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
@@ -141,6 +142,7 @@
     make_field_not_final.main();
     make_final.main();
     move_type_arguments_to_class.main();
+    remove_annotation.main();
     remove_await.main();
     remove_dead_code.main();
     remove_empty_catch.main();
@@ -150,6 +152,7 @@
     remove_initializer.main();
     remove_interpolation_braces.main();
     remove_method_declaration.main();
+    remove_name_from_combinator.main();
     remove_parameters_in_getter_declaration.main();
     remove_parentheses_in_getter_invocation.main();
     remove_this_expression.main();
@@ -166,7 +169,6 @@
     replace_var_with_dynamic.main();
     replace_with_brackets.main();
     replace_with_conditional_assignment.main();
-    replace_with_literal.main();
     replace_with_identifier.main();
     replace_with_null_aware.main();
     replace_with_tear_off.main();
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index 6a07ced..51ad9b3 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -8,6 +8,7 @@
 import 'domain_abstract_test.dart' as domain_abstract_test;
 import 'domains/test_all.dart' as domains_all;
 import 'flutter/test_all.dart' as flutter_all;
+import 'nullability/test_all.dart' as nullability_all;
 import 'plugin/test_all.dart' as plugin_all;
 import 'services/test_all.dart' as services_all;
 import 'utilities/test_all.dart' as utilities_all;
@@ -22,6 +23,7 @@
     domain_abstract_test.main();
     domains_all.main();
     flutter_all.main();
+    nullability_all.main();
     plugin_all.main();
     services_all.main();
     utilities_all.main();
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
index abf1791..f100429 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
@@ -102,7 +102,7 @@
 
     test('parses an interface with type args', () {
       final String input = '''
-interface ResponseError<D> {
+interface MyInterface<D> {
 	data?: D;
 }
     ''';
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index fe5bf80..5c0ab08 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -37,9 +37,11 @@
 | telemetry/event | | | | |
 | client/registerCapability | | | | | unused, but should be used for DocumentSelector at least
 | client/unregisterCapability | | | | |
-| workspace/didChangeWatchedFiles | | | | | unused, server does own watching |
+| workspace/workspaceFolders | | | | |
 | workspace/didChangeWorkspaceFolders | ✅ | ✅ | ✅ | ✅ |
-| workspace/symbol | | | | |
+| workspace/configuration | | | | |
+| workspace/didChangeWatchedFiles | | | | | unused, server does own watching |
+| workspace/symbol | ✅ | ✅ | ✅ | ✅ |
 | workspace/executeCommand | ✅ | ✅ | ✅ | ✅ |
 | workspace/applyEdit | ✅ | ✅ | ✅ | ✅ |
 | textDocument/didOpen | ✅ | ✅ | ✅ | ✅ |
@@ -52,6 +54,7 @@
 | completionItem/resolve | | | | | not required |
 | textDocument/hover | ✅ | ✅ | ✅ | ✅ |
 | textDocument/signatureHelp | ✅ | ✅ | ✅ | ✅ | trigger character handling outstanding
+| textDocument/declaration | | | | |
 | textDocument/definition | ✅ | ✅ | ✅ | ✅ |
 | textDocument/typeDefinition | | | | |
 | textDocument/implementation | | | | |
@@ -67,10 +70,13 @@
 | codeLens/resolve | | | | |
 | textDocument/documentLink | | | | |
 | documentLink/resolve | | | | |
+| textDocument/documentColor | | | | |
+| textDocument/colorPresentation | | | | |
 | textDocument/formatting | ✅ | ✅ | ✅ | ✅ |
 | textDocument/rangeFormatting | | | | | requires support from dart_style?
 | textDocument/onTypeFormatting | ✅ | ✅ | ✅ | ✅ |
-| textDocument/rename | ✅ | ✅ | Incomplete! | |
+| textDocument/rename | ✅ | ✅ | ✅ | ✅ |
 | textDocument/prepareRename | | | | |
-| textDocument/foldingRange | | | | |
+| textDocument/foldingRange | ✅ | ✅ | ✅ | ✅ |
+
 
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 6c87b90..839da75 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -24,7 +24,7 @@
   // TODO(dantup): This should return true by default, and allow opt-out for
   // those things we know are not supported. This behaviour matches the old
   // code in order to simplify diffs while migrating.
-  return name == 'ErrorCodes' || name == 'CodeActionKind';
+  return name == 'ErrorCodes' || name == 'CodeActionKind' || name == 'Method';
 }
 
 String generateDartForTypes(List<AstNode> types) {
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index 909a06b..23fb23f 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -7,6 +7,8 @@
 
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:http/http.dart' as http;
+
+import 'package:args/args.dart';
 import 'package:path/path.dart' as path;
 
 import 'codegen_dart.dart';
@@ -14,14 +16,40 @@
 import 'typescript.dart';
 import 'typescript_parser.dart';
 
-main() async {
+const argHelp = 'help';
+const argDownload = 'download';
+
+final argParser = new ArgParser()
+  ..addFlag(argHelp, hide: true)
+  ..addFlag(argDownload,
+      negatable: false,
+      abbr: 'd',
+      help:
+          'Download the latest version of the LSP spec before generating types');
+
+main(List<String> arguments) async {
+  final args = argParser.parse(arguments);
+  if (args[argHelp]) {
+    print(argParser.usage);
+    return;
+  }
+
   final String script = Platform.script.toFilePath();
   // 3x parent = file -> lsp_spec -> tool -> analysis_server.
   final String packageFolder = new File(script).parent.parent.parent.path;
   final String outFolder = path.join(packageFolder, 'lib', 'lsp_protocol');
   new Directory(outFolder).createSync();
 
-  final String spec = await fetchSpec();
+  await writeSpecClasses(args, outFolder);
+  await writeCustomClasses(args, outFolder);
+}
+
+Future writeSpecClasses(ArgResults args, String outFolder) async {
+  if (args[argDownload]) {
+    await downloadSpec();
+  }
+  final String spec = await readSpec();
+
   final List<AstNode> types = extractTypeScriptBlocks(spec)
       .where(shouldIncludeScriptBlock)
       .map(parseString)
@@ -39,7 +67,28 @@
   final String output = generateDartForTypes(types);
 
   new File(path.join(outFolder, 'protocol_generated.dart'))
-      .writeAsStringSync(_generatedFileHeader + output);
+      .writeAsStringSync(generatedFileHeader(2018) + output);
+}
+
+/// Writes classes used by Dart's custom LSP methods.
+Future writeCustomClasses(ArgResults args, String outFolder) async {
+  interface(String name, List<Member> fields) {
+    return new Interface(null, Token.identifier(name), [], [], fields);
+  }
+
+  field(String name, {String type, canBeNull: false, canBeUndefined: false}) {
+    return new Field(null, Token.identifier(name), Type.identifier(type),
+        canBeNull, canBeUndefined);
+  }
+
+  final List<AstNode> customTypes = [
+    interface('DartDiagnosticServer', [field('port', type: 'number')]),
+  ];
+
+  final String output = generateDartForTypes(customTypes);
+
+  new File(path.join(outFolder, 'protocol_custom_generated.dart'))
+      .writeAsStringSync(generatedFileHeader(2019) + output);
 }
 
 Namespace extractMethodsEnum(String spec) {
@@ -68,8 +117,8 @@
       comment, new Token.identifier('Method'), methodConstants);
 }
 
-const _generatedFileHeader = '''
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+String generatedFileHeader(int year) => '''
+// Copyright (c) $year, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -78,13 +127,16 @@
 // "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
 
 // ignore_for_file: deprecated_member_use
+// ignore_for_file: deprecated_member_use_from_same_package
 // ignore_for_file: unnecessary_brace_in_string_interps
+// ignore_for_file: unused_import
 
 import 'dart:core' hide deprecated;
 import 'dart:core' as core show deprecated;
 import 'dart:convert' show JsonEncoder;
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
-import 'package:analysis_server/src/protocol/protocol_internal.dart' show listEqual, mapEqual;
+import 'package:analysis_server/src/protocol/protocol_internal.dart'
+    show listEqual, mapEqual;
 import 'package:analyzer/src/generated/utilities_general.dart';
 
 const jsonEncoder = const JsonEncoder.withIndent('    ');
@@ -93,6 +145,10 @@
 
 final Uri specUri = Uri.parse(
     'https://raw.githubusercontent.com/Microsoft/language-server-protocol/gh-pages/specification.md');
+final Uri specLicenseUri = Uri.parse(
+    'https://raw.githubusercontent.com/Microsoft/language-server-protocol/gh-pages/License.txt');
+final String localSpecPath = path.join(
+    path.dirname(Platform.script.toFilePath()), 'lsp_specification.md');
 
 /// Pattern to extract inline types from the `result: {xx, yy }` notes in the spec.
 /// Doesn't parse past full stops as some of these have english sentences tagged on
@@ -130,11 +186,27 @@
       .toList();
 }
 
-Future<String> fetchSpec() async {
-  final resp = await http.get(specUri);
-  return resp.body;
+Future<void> downloadSpec() async {
+  final specResp = await http.get(specUri);
+  final licenseResp = await http.get(specLicenseUri);
+  final text = [
+    '''
+This is an unmodified copy of the Language Server Protocol Specification,
+downloaded from $specUri. It is the version of the specification that was
+used to generate a portion of the Dart code used to support the protocol.
+
+To regenerate the generated code, run the script in
+"analysis_server/tool/lsp_spec/generate_all.dart" with no arguments. To
+download the latest version of the specification before regenerating the
+code, run the same script with an argument of "--download".''',
+    licenseResp.body,
+    specResp.body
+  ];
+  return new File(localSpecPath).writeAsString(text.join('\n\n---\n\n'));
 }
 
+Future<String> readSpec() => new File(localSpecPath).readAsString();
+
 /// Returns whether a script block should be parsed or not.
 bool shouldIncludeScriptBlock(String input) {
   // We can't parse literal arrays, but this script block is just an example
diff --git a/pkg/analysis_server/tool/lsp_spec/lsp_specification.md b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
new file mode 100644
index 0000000..2bb235d
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/lsp_specification.md
@@ -0,0 +1,4433 @@
+This is an unmodified copy of the Language Server Protocol Specification,
+downloaded from https://raw.githubusercontent.com/Microsoft/language-server-protocol/gh-pages/specification.md. It is the version of the specification that was
+used to generate a portion of the Dart code used to support the protocol.
+
+To regenerate the generated code, run the script in
+"analysis_server/tool/lsp_spec/generate_all.dart" with no arguments. To
+download the latest version of the specification before regenerating the
+code, run the same script with an argument of "--download".
+
+
+---
+
+Copyright (c) Microsoft Corporation.
+ 
+All rights reserved. 
+
+Distributed under the following terms:
+
+1.	Documentation is licensed under the Creative Commons Attribution 3.0 United States License. Code is licensed under the MIT License.
+2. This license does not grant you rights to use any trademarks or logos of Microsoft. For Microsoft’s general trademark guidelines, go to http://go.microsoft.com/fwlink/?LinkID=254653
+
+---
+
+---
+title: Specification
+layout: specification
+sectionid: specification
+toc: true
+---
+# Language Server Protocol Specification
+
+This document describes version 3.x of the language server protocol. An implementation for node of the 3.0 version of the protocol can be found [here](https://github.com/Microsoft/vscode-languageserver-node).
+
+The 2.x version of this document can be found [here](https://github.com/Microsoft/language-server-protocol/blob/master/versions/protocol-2-x.md).
+The 1.x version of this document can be found [here](https://github.com/Microsoft/language-server-protocol/blob/master/versions/protocol-1-x.md).
+
+**Note:** edits to this specification can be made via a pull request against this markdown [document](https://github.com/Microsoft/language-server-protocol/blob/gh-pages/specification.md).
+
+## Base Protocol
+
+The base protocol consists of a header and a content part (comparable to HTTP). The header and content part are
+separated by a '\r\n'.
+
+### Header Part
+
+The header part consists of header fields. Each header field is comprised of a name and a value,
+separated by ': ' (a colon and a space).
+Each header field is terminated by '\r\n'.
+Considering the last header field and the overall header itself are each terminated with '\r\n',
+and that at least one header is mandatory, this means that two '\r\n' sequences always
+immediately precede the content part of a message.
+
+Currently the following header fields are supported:
+
+| Header Field Name | Value Type  | Description |
+|:------------------|:------------|:------------|
+| Content-Length    | number      | The length of the content part in bytes. This header is required. |
+| Content-Type      | string      | The mime type of the content part. Defaults to application/vscode-jsonrpc; charset=utf-8 |
+{: .table .table-bordered .table-responsive}
+
+The header part is encoded using the 'ascii' encoding. This includes the '\r\n' separating the header and content part.
+
+### Content Part
+
+Contains the actual content of the message. The content part of a message uses [JSON-RPC](http://www.jsonrpc.org/) to describe requests, responses and notifications. The content part is encoded using the charset provided in the Content-Type field. It defaults to `utf-8`, which is the only encoding supported right now. If a server or client receives a header with a different encoding then `utf-8` it should respond with an error.
+
+(Prior versions of the protocol used the string constant `utf8` which is not a correct encoding constant according to [specification](http://www.iana.org/assignments/character-sets/character-sets.xhtml).) For backwards compatibility it is highly recommended that a client and a server treats the string `utf8` as `utf-8`.
+
+### Example:
+
+```
+Content-Length: ...\r\n
+\r\n
+{
+	"jsonrpc": "2.0",
+	"id": 1,
+	"method": "textDocument/didOpen",
+	"params": {
+		...
+	}
+}
+```
+### Base Protocol JSON structures
+
+The following TypeScript definitions describe the base [JSON-RPC protocol](http://www.jsonrpc.org/specification):
+
+#### Abstract Message
+
+A general message as defined by JSON-RPC. The language server protocol always uses "2.0" as the `jsonrpc` version.
+
+```typescript
+interface Message {
+	jsonrpc: string;
+}
+```
+#### Request Message
+
+A request message to describe a request between the client and the server. Every processed request must send a response back to the sender of the request.
+
+```typescript
+interface RequestMessage extends Message {
+
+	/**
+	 * The request id.
+	 */
+	id: number | string;
+
+	/**
+	 * The method to be invoked.
+	 */
+	method: string;
+
+	/**
+	 * The method's params.
+	 */
+	params?: Array<any> | object;
+}
+```
+
+#### Response Message
+
+A Response Message sent as a result of a request. If a request doesn't provide a result value the receiver of a request still needs to return a response message to conform to the JSON RPC specification. The result property of the ResponseMessage should be set to `null` in this case to signal a successful request.
+
+```typescript
+interface ResponseMessage extends Message {
+	/**
+	 * The request id.
+	 */
+	id: number | string | null;
+
+	/**
+	 * The result of a request. This can be omitted in
+	 * the case of an error.
+	 */
+	result?: any;
+
+	/**
+	 * The error object in case a request fails.
+	 */
+	error?: ResponseError<any>;
+}
+
+interface ResponseError<D> {
+	/**
+	 * A number indicating the error type that occurred.
+	 */
+	code: number;
+
+	/**
+	 * A string providing a short description of the error.
+	 */
+	message: string;
+
+	/**
+	 * A Primitive or Structured value that contains additional
+	 * information about the error. Can be omitted.
+	 */
+	data?: D;
+}
+
+export namespace ErrorCodes {
+	// Defined by JSON RPC
+	export const ParseError: number = -32700;
+	export const InvalidRequest: number = -32600;
+	export const MethodNotFound: number = -32601;
+	export const InvalidParams: number = -32602;
+	export const InternalError: number = -32603;
+	export const serverErrorStart: number = -32099;
+	export const serverErrorEnd: number = -32000;
+	export const ServerNotInitialized: number = -32002;
+	export const UnknownErrorCode: number = -32001;
+
+	// Defined by the protocol.
+	export const RequestCancelled: number = -32800;
+	export const ContentModified: number = -32801;
+}
+```
+#### Notification Message
+
+A notification message. A processed notification message must not send a response back. They work like events.
+
+```typescript
+interface NotificationMessage extends Message {
+	/**
+	 * The method to be invoked.
+	 */
+	method: string;
+
+	/**
+	 * The notification's params.
+	 */
+	params?: Array<any> | object;
+}
+```
+
+#### $ Notifications and Requests
+
+Notification and requests whose methods start with '$/' are messages which are protocol implementation dependent and might not be implementable in all clients or servers. For example if the server implementation uses a single threaded synchronous programming language then there is little a server can do to react to a '$/cancelRequest' notification. If a server or client receives notifications starting with '$/' it is free to ignore the notification. If a server or client receives a requests starting with '$/' it must error the request with error code `MethodNotFound` (e.g. `-32601`).
+
+#### <a href="#cancelRequest" name="cancelRequest" class="anchor"> Cancellation Support (:arrow_right: :arrow_left:)</a>
+
+The base protocol offers support for request cancellation. To cancel a request, a notification message with the following properties is sent:
+
+_Notification_:
+* method: '$/cancelRequest'
+* params: `CancelParams` defined as follows:
+
+```typescript
+interface CancelParams {
+	/**
+	 * The request id to cancel.
+	 */
+	id: number | string;
+}
+```
+
+A request that got canceled still needs to return from the server and send a response back. It can not be left open / hanging. This is in line with the JSON RPC protocol that requires that every request sends a response back. In addition it allows for returning partial results on cancel. If the request returns an error response on cancellation it is advised to set the error code to `ErrorCodes.RequestCancelled`.
+
+## Language Server Protocol
+
+The language server protocol defines a set of JSON-RPC request, response and notification messages which are exchanged using the above base protocol. This section starts describing the basic JSON structures used in the protocol. The document uses TypeScript interfaces to describe these. Based on the basic JSON structures, the actual requests with their responses and the notifications are described.
+
+In general, the language server protocol supports JSON-RPC messages, however the base protocol defined here uses a convention such that the parameters passed to request/notification messages should be of `object` type (if passed at all). However, this does not disallow using `Array` parameter types in custom messages.
+
+The protocol currently assumes that one server serves one tool. There is currently no support in the protocol to share one server between different tools. Such a sharing would require additional protocol e.g. to lock a document to support concurrent editing.
+
+### Basic JSON Structures
+
+#### URI
+
+URI's are transferred as strings. The URI's format is defined in [http://tools.ietf.org/html/rfc3986](http://tools.ietf.org/html/rfc3986)
+
+```
+  foo://example.com:8042/over/there?name=ferret#nose
+  \_/   \______________/\_________/ \_________/ \__/
+   |           |            |            |        |
+scheme     authority       path        query   fragment
+   |   _____________________|__
+  / \ /                        \
+  urn:example:animal:ferret:nose
+```
+
+We also maintain a node module to parse a string into `scheme`, `authority`, `path`, `query`, and `fragment` URI components. The GitHub repository is [https://github.com/Microsoft/vscode-uri](https://github.com/Microsoft/vscode-uri) the npm module is [https://www.npmjs.com/package/vscode-uri](https://www.npmjs.com/package/vscode-uri).
+
+Many of the interfaces contain fields that correspond to the URI of a document. For clarity, the type of such a field is declared as a `DocumentUri`. Over the wire, it will still be transferred as a string, but this guarantees that the contents of that string can be parsed as a valid URI.
+
+```typescript
+type DocumentUri = string;
+```
+
+#### Text Documents
+
+The current protocol is tailored for textual documents whose content can be represented as a string. There is currently no support for binary documents. A position inside a document (see Position definition below) is expressed as a zero-based line and character offset. The offsets are based on a UTF-16 string representation. So a string of the form `a𐐀b` the character offset of the character `a` is 0, the character offset of `𐐀` is 1 and the character offset of b is 3 since `𐐀` is represented using two code units in UTF-16. To ensure that both client and server split the string into the same line representation the protocol specifies the following end-of-line sequences: '\n', '\r\n' and '\r'.
+
+Positions are line end character agnostic. So you can not specify  a position that denotes `\r|\n` or `\n|` where `|` represents the character offset.
+
+```typescript
+export const EOL: string[] = ['\n', '\r\n', '\r'];
+```
+
+#### Position
+
+Position in a text document expressed as zero-based line and zero-based character offset. A position is between two characters like an 'insert' cursor in a editor.
+
+```typescript
+interface Position {
+	/**
+	 * Line position in a document (zero-based).
+	 */
+	line: number;
+
+	/**
+	 * Character offset on a line in a document (zero-based). Assuming that the line is
+	 * represented as a string, the `character` value represents the gap between the
+	 * `character` and `character + 1`.
+	 *
+	 * If the character value is greater than the line length it defaults back to the
+	 * line length.
+	 */
+	character: number;
+}
+```
+#### Range
+
+A range in a text document expressed as (zero-based) start and end positions. A range is comparable to a selection in an editor. Therefore the end position is exclusive. If you want to specify a range that contains a line including the line ending character(s) then use an end position denoting the start of the next line. For example:
+```typescript
+{
+    start: { line: 5, character: 23 },
+    end : { line 6, character : 0 }
+}
+```
+
+```typescript
+interface Range {
+	/**
+	 * The range's start position.
+	 */
+	start: Position;
+
+	/**
+	 * The range's end position.
+	 */
+	end: Position;
+}
+```
+
+#### Location
+
+Represents a location inside a resource, such as a line inside a text file.
+```typescript
+interface Location {
+	uri: DocumentUri;
+	range: Range;
+}
+```
+
+#### LocationLink
+
+Represents a link between a source and a target location.
+
+```typescript
+interface LocationLink {
+
+	/**
+	 * Span of the origin of this link.
+	 *
+	 * Used as the underlined span for mouse interaction. Defaults to the word range at
+	 * the mouse position.
+	 */
+	originSelectionRange?: Range;
+
+	/**
+	 * The target resource identifier of this link.
+	 */
+	targetUri: string;
+
+	/**
+	 * The full target range of this link. If the target for example is a symbol then target range is the
+	 * range enclosing this symbol not including leading/trailing whitespace but everything else
+	 * like comments. This information is typically used to highlight the range in the editor.
+	 */
+	targetRange: Range;
+
+	/**
+	 * The range that should be selected and revealed when this link is being followed, e.g the name of a function.
+	 * Must be contained by the the `targetRange`. See also `DocumentSymbol#range`
+	 */
+	targetSelectionRange: Range;
+}
+```
+
+#### Diagnostic
+
+Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid in the scope of a resource.
+
+```typescript
+interface Diagnostic {
+	/**
+	 * The range at which the message applies.
+	 */
+	range: Range;
+
+	/**
+	 * The diagnostic's severity. Can be omitted. If omitted it is up to the
+	 * client to interpret diagnostics as error, warning, info or hint.
+	 */
+	severity?: number;
+
+	/**
+	 * The diagnostic's code, which might appear in the user interface.
+	 */
+	code?: number | string;
+
+	/**
+	 * A human-readable string describing the source of this
+	 * diagnostic, e.g. 'typescript' or 'super lint'.
+	 */
+	source?: string;
+
+	/**
+	 * The diagnostic's message.
+	 */
+	message: string;
+
+	/**
+	 * An array of related diagnostic information, e.g. when symbol-names within
+	 * a scope collide all definitions can be marked via this property.
+	 */
+	relatedInformation?: DiagnosticRelatedInformation[];
+}
+```
+
+The protocol currently supports the following diagnostic severities:
+
+```typescript
+namespace DiagnosticSeverity {
+	/**
+	 * Reports an error.
+	 */
+	export const Error = 1;
+	/**
+	 * Reports a warning.
+	 */
+	export const Warning = 2;
+	/**
+	 * Reports an information.
+	 */
+	export const Information = 3;
+	/**
+	 * Reports a hint.
+	 */
+	export const Hint = 4;
+}
+```
+
+```typescript
+/**
+ * Represents a related message and source code location for a diagnostic. This should be
+ * used to point to code locations that cause or related to a diagnostics, e.g when duplicating
+ * a symbol in a scope.
+ */
+export interface DiagnosticRelatedInformation {
+	/**
+	 * The location of this related diagnostic information.
+	 */
+	location: Location;
+
+	/**
+	 * The message of this related diagnostic information.
+	 */
+	message: string;
+}
+```
+
+#### Command
+
+Represents a reference to a command. Provides a title which will be used to represent a command in the UI. Commands are identified by a string identifier. The recommended way to handle commands is to implement their execution on the server side if the client and server provides the corresponding capabilities. Alternatively the tool extension code could handle the command. The protocol currently doesn't specify a set of well-known commands.
+
+```typescript
+interface Command {
+	/**
+	 * Title of the command, like `save`.
+	 */
+	title: string;
+	/**
+	 * The identifier of the actual command handler.
+	 */
+	command: string;
+	/**
+	 * Arguments that the command handler should be
+	 * invoked with.
+	 */
+	arguments?: any[];
+}
+```
+
+#### TextEdit
+
+A textual edit applicable to a text document.
+
+```typescript
+interface TextEdit {
+	/**
+	 * The range of the text document to be manipulated. To insert
+	 * text into a document create a range where start === end.
+	 */
+	range: Range;
+
+	/**
+	 * The string to be inserted. For delete operations use an
+	 * empty string.
+	 */
+	newText: string;
+}
+```
+
+#### TextEdit[]
+
+Complex text manipulations are described with an array of `TextEdit`'s, representing a single change to the document.
+
+All text edits ranges refer to positions in the original document. Text edits ranges must never overlap, that means no part of the original document must be manipulated by more than one edit. However, it is possible that multiple edits have the same start position: multiple inserts, or any number of inserts followed by a single remove or replace edit. If multiple inserts have the same position, the order in the array defines the order in which the inserted strings appear in the resulting text.
+
+#### TextDocumentEdit
+
+Describes textual changes on a single text document. The text document is referred to as a `VersionedTextDocumentIdentifier` to allow clients to check the text document version before an edit is applied. A `TextDocumentEdit` describes all changes on a version Si and after they are applied move the document to version Si+1. So the creator of a `TextDocumentEdit` doesn't need to sort the array or do any kind of ordering. However the edits must be non overlapping.
+
+```typescript
+export interface TextDocumentEdit {
+	/**
+	 * The text document to change.
+	 */
+	textDocument: VersionedTextDocumentIdentifier;
+
+	/**
+	 * The edits to be applied.
+	 */
+	edits: TextEdit[];
+}
+```
+
+### File Resource changes
+
+> New in version 3.13:
+
+File resource changes allow servers to create, rename and delete files and folders via the client. Note that the names talk about files but the operations are supposed to work on files and folders. This is in line with other naming in the Language Server Protocol (see file watchers which can watch files and folders). The corresponding change literals look as follows:
+
+```typescript
+/**
+ * Options to create a file.
+ */
+export interface CreateFileOptions {
+	/**
+	 * Overwrite existing file. Overwrite wins over `ignoreIfExists`
+	 */
+	overwrite?: boolean;
+	/**
+	 * Ignore if exists.
+	 */
+	ignoreIfExists?: boolean;
+}
+
+/**
+ * Create file operation
+ */
+export interface CreateFile {
+	/**
+	 * A create
+	 */
+	kind: 'create';
+	/**
+	 * The resource to create.
+	 */
+	uri: string;
+	/**
+	 * Additional options
+	 */
+	options?: CreateFileOptions;
+}
+
+/**
+ * Rename file options
+ */
+export interface RenameFileOptions {
+	/**
+	 * Overwrite target if existing. Overwrite wins over `ignoreIfExists`
+	 */
+	overwrite?: boolean;
+	/**
+	 * Ignores if target exists.
+	 */
+	ignoreIfExists?: boolean;
+}
+
+/**
+ * Rename file operation
+ */
+export interface RenameFile {
+	/**
+	 * A rename
+	 */
+	kind: 'rename';
+	/**
+	 * The old (existing) location.
+	 */
+	oldUri: string;
+	/**
+	 * The new location.
+	 */
+	newUri: string;
+	/**
+	 * Rename options.
+	 */
+	options?: RenameFileOptions;
+}
+
+/**
+ * Delete file options
+ */
+export interface DeleteFileOptions {
+	/**
+	 * Delete the content recursively if a folder is denoted.
+	 */
+	recursive?: boolean;
+	/**
+	 * Ignore the operation if the file doesn't exist.
+	 */
+	ignoreIfNotExists?: boolean;
+}
+
+/**
+ * Delete file operation
+ */
+export interface DeleteFile {
+	/**
+	 * A delete
+	 */
+	kind: 'delete';
+	/**
+	 * The file to delete.
+	 */
+	uri: string;
+	/**
+	 * Delete options.
+	 */
+	options?: DeleteFileOptions;
+}
+```
+
+#### WorkspaceEdit
+
+A workspace edit represents changes to many resources managed in the workspace. The edit should either provide `changes` or `documentChanges`. If the client can handle versioned document edits and if `documentChange`s are present, the latter are preferred over `changes`.
+
+```typescript
+export interface WorkspaceEdit {
+	/**
+	 * Holds changes to existing resources.
+	 */
+	changes?: { [uri: string]: TextEdit[]; };
+
+	/**
+	 * Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes
+	 * are either an array of `TextDocumentEdit`s to express changes to n different text documents
+	 * where each text document edit addresses a specific version of a text document. Or it can contain
+	 * above `TextDocumentEdit`s mixed with create, rename and delete file / folder operations.
+	 *
+	 * Whether a client supports versioned document edits is expressed via
+	 * `workspace.workspaceEdit.documentChanges` client capability.
+	 *
+	 * If a client neither supports `documentChanges` nor `workspace.workspaceEdit.resourceOperations` then
+	 * only plain `TextEdit`s using the `changes` property are supported.
+	 */
+	documentChanges?: (TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]);
+}
+```
+
+#### TextDocumentIdentifier
+
+Text documents are identified using a URI. On the protocol level, URIs are passed as strings. The corresponding JSON structure looks like this:
+```typescript
+interface TextDocumentIdentifier {
+	/**
+	 * The text document's URI.
+	 */
+	uri: DocumentUri;
+}
+```
+
+#### TextDocumentItem
+
+An item to transfer a text document from the client to the server.
+
+```typescript
+interface TextDocumentItem {
+	/**
+	 * The text document's URI.
+	 */
+	uri: DocumentUri;
+
+	/**
+	 * The text document's language identifier.
+	 */
+	languageId: string;
+
+	/**
+	 * The version number of this document (it will increase after each
+	 * change, including undo/redo).
+	 */
+	version: number;
+
+	/**
+	 * The content of the opened text document.
+	 */
+	text: string;
+}
+```
+
+Text documents have a language identifier to identify a document on the server side when it handles more than one language to avoid re-interpreting the file extension. If a document refers to one of the programming languages listed below it is recommended that clients use those ids.
+
+Language | Identifier
+-------- | ----------
+Windows Bat | `bat`
+BibTeX | `bibtex`
+Clojure | `clojure`
+Coffeescript | `coffeescript`
+C | `c`
+C++ | `cpp`
+C# | `csharp`
+CSS | `css`
+Diff | `diff`
+Dart | `dart`
+Dockerfile | `dockerfile`
+F# | `fsharp`
+Git | `git-commit` and `git-rebase`
+Go | `go`
+Groovy | `groovy`
+Handlebars | `handlebars`
+HTML | `html`
+Ini | `ini`
+Java | `java`
+JavaScript | `javascript`
+JSON | `json`
+LaTeX | `latex`
+Less | `less`
+Lua | `lua`
+Makefile | `makefile`
+Markdown | `markdown`
+Objective-C | `objective-c`
+Objective-C++ | `objective-cpp`
+Perl | `perl` and `perl6`
+PHP | `php`
+Powershell | `powershell`
+Pug | `jade`
+Python | `python`
+R | `r`
+Razor (cshtml) | `razor`
+Ruby | `ruby`
+Rust | `rust`
+Sass | `scss` (syntax using curly brackets), `sass` (indented syntax)
+Scala | `scala`
+ShaderLab | `shaderlab`
+Shell Script (Bash) | `shellscript`
+SQL | `sql`
+Swift | `swift`
+TypeScript | `typescript`
+TeX | `tex`
+Visual Basic | `vb`
+XML | `xml`
+XSL | `xsl`
+YAML | `yaml`
+{: .table .table-bordered .table-responsive}
+
+#### VersionedTextDocumentIdentifier
+
+An identifier to denote a specific version of a text document.
+
+```typescript
+interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
+	/**
+	 * The version number of this document. If a versioned text document identifier
+	 * is sent from the server to the client and the file is not open in the editor
+	 * (the server has not received an open notification before) the server can send
+	 * `null` to indicate that the version is known and the content on disk is the
+	 * truth (as speced with document content ownership).
+	 *
+	 * The version number of a document will increase after each change, including
+	 * undo/redo. The number doesn't need to be consecutive.
+	 */
+	version: number | null;
+}
+```
+
+#### TextDocumentPositionParams
+
+Was `TextDocumentPosition` in 1.0 with inlined parameters.
+
+A parameter literal used in requests to pass a text document and a position inside that document.
+
+```typescript
+interface TextDocumentPositionParams {
+	/**
+	 * The text document.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The position inside the text document.
+	 */
+	position: Position;
+}
+```
+
+#### DocumentFilter
+
+A document filter denotes a document through properties like `language`, `scheme` or `pattern`. An example is a filter that applies to TypeScript files on disk. Another example is a filter the applies to JSON files with name `package.json`:
+```typescript
+{ language: 'typescript', scheme: 'file' }
+{ language: 'json', pattern: '**/package.json' }
+```
+
+```typescript
+export interface DocumentFilter {
+	/**
+	 * A language id, like `typescript`.
+	 */
+	language?: string;
+
+	/**
+	 * A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+	 */
+	scheme?: string;
+
+	/**
+	 * A glob pattern, like `*.{ts,js}`.
+	 *
+	 * Glob patterns can have the following syntax:
+	 * - `*` to match one or more characters in a path segment
+	 * - `?` to match on one character in a path segment
+	 * - `**` to match any number of path segments, including none
+	 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+	 * - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+	 * - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+	 */
+	pattern?: string;
+}
+```
+
+A document selector is the combination of one or more document filters.
+
+```typescript
+export type DocumentSelector = DocumentFilter[];
+```
+
+#### MarkupContent
+
+ A `MarkupContent` literal represents a string value which content can be represented in different formats. Currently `plaintext` and `markdown` are supported formats. A `MarkupContent` is usually used in documentation properties of result literals like `CompletionItem` or `SignatureInformation`.
+
+```typescript
+/**
+ * Describes the content type that a client supports in various
+ * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
+ *
+ * Please note that `MarkupKinds` must not start with a `$`. This kinds
+ * are reserved for internal usage.
+ */
+export namespace MarkupKind {
+	/**
+	 * Plain text is supported as a content format
+	 */
+	export const PlainText: 'plaintext' = 'plaintext';
+
+	/**
+	 * Markdown is supported as a content format
+	 */
+	export const Markdown: 'markdown' = 'markdown';
+}
+export type MarkupKind = 'plaintext' | 'markdown';
+
+/**
+ * A `MarkupContent` literal represents a string value which content is interpreted base on its
+ * kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
+ *
+ * If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
+ * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ *
+ * Here is an example how such a string can be constructed using JavaScript / TypeScript:
+ * ```typescript
+ * let markdown: MarkdownContent = {
+ *  kind: MarkupKind.Markdown,
+ *	value: [
+ *		'# Header',
+ *		'Some text',
+ *		'```typescript',
+ *		'someCode();',
+ *		'```'
+ *	].join('\n')
+ * };
+ * ```
+ *
+ * *Please Note* that clients might sanitize the return markdown. A client could decide to
+ * remove HTML from the markdown to avoid script execution.
+ */
+export interface MarkupContent {
+	/**
+	 * The type of the Markup
+	 */
+	kind: MarkupKind;
+
+	/**
+	 * The content itself
+	 */
+	value: string;
+}
+```
+
+### Actual Protocol
+
+This section documents the actual language server protocol. It uses the following format:
+
+* a header describing the request
+* a _Request_: section describing the format of the request sent. The method is a string identifying the request the params are documented using a TypeScript interface
+* a _Response_: section describing the format of the response. The result item describes the returned data in case of a success. The error.data describes the returned data in case of an error. Please remember that in case of a failure the response already contains an error.code and an error.message field. These fields are only spec'd if the protocol forces the use of certain error codes or messages. In cases where the server can decide on these values freely they aren't listed here.
+* a _Registration Options_ section describing the registration option if the request or notification supports dynamic capability registration.
+
+#### Request, Notification and Response ordering
+
+Responses to requests should be sent in roughly the same order as the requests appear on the server or client side. So for example if a server receives a `textDocument/completion` request and then a `textDocument/signatureHelp` request it will usually first return the response for the `textDocument/completion` and then the response for `textDocument/signatureHelp`.
+
+However, the server may decide to use a parallel execution strategy and may wish to return responses in a different order than the requests were received. The server may do so as long as this reordering doesn't affect the correctness of the responses. For example, reordering the result of `textDocument/completion` and `textDocument/signatureHelp` is allowed, as these each of these requests usually won't affect the output of the other. On the other hand, the server most likely should not reorder `textDocument/definition` and `textDocument/rename` requests, since the executing the latter may affect the result of the former.
+
+#### Server lifetime
+
+The current protocol specification defines that the lifetime of a server is managed by the client (e.g. a tool like VS Code or Emacs). It is up to the client to decide when to start (process-wise) and when to shutdown a server.
+
+#### <a href="#initialize" name="initialize" class="anchor">Initialize Request (:leftwards_arrow_with_hook:)</a>
+
+The initialize request is sent as the first request from the client to the server. If the server receives a request or notification before the `initialize` request it should act as follows:
+
+* For a request the response should be an error with `code: -32002`. The message can be picked by the server.
+* Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request.
+
+Until the server has responded to the `initialize` request with an `InitializeResult`, the client must not send any additional requests or notifications to the server. In addition the server is not allowed to send any requests or notifications to the client until it has responded with an `InitializeResult`, with the exception that during the `initialize` request the server is allowed to send the notifications `window/showMessage`, `window/logMessage` and `telemetry/event` as well as the `window/showMessageRequest` request to the client.
+
+The `initialize` request may only be sent once.
+
+_Request_:
+* method: 'initialize'
+* params: `InitializeParams` defined as follows:
+
+```typescript
+interface InitializeParams {
+	/**
+	 * The process Id of the parent process that started
+	 * the server. Is null if the process has not been started by another process.
+	 * If the parent process is not alive then the server should exit (see exit notification) its process.
+	 */
+	processId: number | null;
+
+	/**
+	 * The rootPath of the workspace. Is null
+	 * if no folder is open.
+	 *
+	 * @deprecated in favour of rootUri.
+	 */
+	rootPath?: string | null;
+
+	/**
+	 * The rootUri of the workspace. Is null if no
+	 * folder is open. If both `rootPath` and `rootUri` are set
+	 * `rootUri` wins.
+	 */
+	rootUri: DocumentUri | null;
+
+	/**
+	 * User provided initialization options.
+	 */
+	initializationOptions?: any;
+
+	/**
+	 * The capabilities provided by the client (editor or tool)
+	 */
+	capabilities: ClientCapabilities;
+
+	/**
+	 * The initial trace setting. If omitted trace is disabled ('off').
+	 */
+	trace?: 'off' | 'messages' | 'verbose';
+
+	/**
+	 * The workspace folders configured in the client when the server starts.
+	 * This property is only available if the client supports workspace folders.
+	 * It can be `null` if the client supports workspace folders but none are
+	 * configured.
+	 *
+	 * Since 3.6.0
+	 */
+	workspaceFolders?: WorkspaceFolder[] | null;
+}
+```
+Where `ClientCapabilities`, `TextDocumentClientCapabilities` and `WorkspaceClientCapabilities` are defined as follows:
+
+##### `WorkspaceClientCapabilities` define capabilities the editor / tool provides on the workspace:
+
+> New in version 3.13: `ResourceOperationKind` and `FailureHandlingKind` and the client capability `workspace.workspaceEdit.resourceOperations` as well as `workspace.workspaceEdit.failureHandling`.
+
+```typescript
+
+/**
+ * The kind of resource operations supported by the client.
+ */
+export type ResourceOperationKind = 'create' | 'rename' | 'delete';
+
+export namespace ResourceOperationKind {
+
+	/**
+	 * Supports creating new files and folders.
+	 */
+	export const Create: ResourceOperationKind = 'create';
+
+	/**
+	 * Supports renaming existing files and folders.
+	 */
+	export const Rename: ResourceOperationKind = 'rename';
+
+	/**
+	 * Supports deleting existing files and folders.
+	 */
+	export const Delete: ResourceOperationKind = 'delete';
+}
+
+export type FailureHandlingKind = 'abort' | 'transactional' | 'undo' | 'textOnlyTransactional';
+
+export namespace FailureHandlingKind {
+
+	/**
+	 * Applying the workspace change is simply aborted if one of the changes provided
+	 * fails. All operations executed before the failing operation stay executed.
+	 */
+	export const Abort: FailureHandlingKind = 'abort';
+
+	/**
+	 * All operations are executed transactional. That means they either all
+	 * succeed or no changes at all are applied to the workspace.
+	 */
+	export const Transactional: FailureHandlingKind = 'transactional';
+
+
+	/**
+	 * If the workspace edit contains only textual file changes they are executed transactional.
+	 * If resource changes (create, rename or delete file) are part of the change the failure
+	 * handling strategy is abort.
+	 */
+	export const TextOnlyTransactional: FailureHandlingKind = 'textOnlyTransactional';
+
+	/**
+	 * The client tries to undo the operations already executed. But there is no
+	 * guarantee that this is succeeding.
+	 */
+	export const Undo: FailureHandlingKind = 'undo';
+}
+
+/**
+ * Workspace specific client capabilities.
+ */
+export interface WorkspaceClientCapabilities {
+	/**
+	 * The client supports applying batch edits to the workspace by supporting
+	 * the request 'workspace/applyEdit'
+	 */
+	applyEdit?: boolean;
+
+	/**
+	 * Capabilities specific to `WorkspaceEdit`s
+	 */
+	workspaceEdit?: {
+		/**
+		 * The client supports versioned document changes in `WorkspaceEdit`s
+		 */
+		documentChanges?: boolean;
+
+		/**
+		 * The resource operations the client supports. Clients should at least
+		 * support 'create', 'rename' and 'delete' files and folders.
+		 */
+		resourceOperations?: ResourceOperationKind[];
+
+		/**
+		 * The failure handling strategy of a client if applying the workspace edit
+		 * fails.
+		 */
+		failureHandling?: FailureHandlingKind;
+	};
+
+	/**
+	 * Capabilities specific to the `workspace/didChangeConfiguration` notification.
+	 */
+	didChangeConfiguration?: {
+		/**
+		 * Did change configuration notification supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
+	 */
+	didChangeWatchedFiles?: {
+		/**
+		 * Did change watched files notification supports dynamic registration. Please note
+		 * that the current protocol doesn't support static configuration for file changes
+		 * from the server side.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `workspace/symbol` request.
+	 */
+	symbol?: {
+		/**
+		 * Symbol request supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
+		 */
+		symbolKind?: {
+			/**
+			 * The symbol kind values the client supports. When this
+			 * property exists the client also guarantees that it will
+			 * handle values outside its set gracefully and falls back
+			 * to a default value when unknown.
+			 *
+			 * If this property is not present the client only supports
+			 * the symbol kinds from `File` to `Array` as defined in
+			 * the initial version of the protocol.
+			 */
+			valueSet?: SymbolKind[];
+		}
+	};
+
+	/**
+	 * Capabilities specific to the `workspace/executeCommand` request.
+	 */
+	executeCommand?: {
+		/**
+		 * Execute command supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * The client has support for workspace folders.
+	 *
+	 * Since 3.6.0
+	 */
+	workspaceFolders?: boolean;
+
+	/**
+	 * The client supports `workspace/configuration` requests.
+	 *
+	 * Since 3.6.0
+	 */
+	configuration?: boolean;
+}
+```
+
+##### `TextDocumentClientCapabilities` define capabilities the editor / tool provides on text documents.
+
+```typescript
+/**
+ * Text document specific client capabilities.
+ */
+export interface TextDocumentClientCapabilities {
+
+	synchronization?: {
+		/**
+		 * Whether text document synchronization supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports sending will save notifications.
+		 */
+		willSave?: boolean;
+
+		/**
+		 * The client supports sending a will save request and
+		 * waits for a response providing text edits which will
+		 * be applied to the document before it is saved.
+		 */
+		willSaveWaitUntil?: boolean;
+
+		/**
+		 * The client supports did save notifications.
+		 */
+		didSave?: boolean;
+	}
+
+	/**
+	 * Capabilities specific to the `textDocument/completion`
+	 */
+	completion?: {
+		/**
+		 * Whether completion supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports the following `CompletionItem` specific
+		 * capabilities.
+		 */
+		completionItem?: {
+			/**
+			 * The client supports snippets as insert text.
+			 *
+			 * A snippet can define tab stops and placeholders with `$1`, `$2`
+			 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+			 * the end of the snippet. Placeholders with equal identifiers are linked,
+			 * that is typing in one will update others too.
+			 */
+			snippetSupport?: boolean;
+
+			/**
+			 * The client supports commit characters on a completion item.
+			 */
+			commitCharactersSupport?: boolean
+
+			/**
+			 * The client supports the following content formats for the documentation
+			 * property. The order describes the preferred format of the client.
+			 */
+			documentationFormat?: MarkupKind[];
+
+			/**
+			 * The client supports the deprecated property on a completion item.
+			 */
+			deprecatedSupport?: boolean;
+
+			/**
+			 * The client supports the preselect property on a completion item.
+			 */
+			preselectSupport?: boolean;
+		}
+
+		completionItemKind?: {
+			/**
+			 * The completion item kind values the client supports. When this
+			 * property exists the client also guarantees that it will
+			 * handle values outside its set gracefully and falls back
+			 * to a default value when unknown.
+			 *
+			 * If this property is not present the client only supports
+			 * the completion items kinds from `Text` to `Reference` as defined in
+			 * the initial version of the protocol.
+			 */
+			valueSet?: CompletionItemKind[];
+		},
+
+		/**
+		 * The client supports to send additional context information for a
+		 * `textDocument/completion` request.
+		 */
+		contextSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/hover`
+	 */
+	hover?: {
+		/**
+		 * Whether hover supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports the follow content formats for the content
+		 * property. The order describes the preferred format of the client.
+		 */
+		contentFormat?: MarkupKind[];
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/signatureHelp`
+	 */
+	signatureHelp?: {
+		/**
+		 * Whether signature help supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports the following `SignatureInformation`
+		 * specific properties.
+		 */
+		signatureInformation?: {
+			/**
+			 * The client supports the follow content formats for the documentation
+			 * property. The order describes the preferred format of the client.
+			 */
+			documentationFormat?: MarkupKind[];
+
+			/**
+			 * Client capabilities specific to parameter information.
+			 */
+			parameterInformation?: {
+				/**
+				 * The client supports processing label offsets instead of a
+				 * simple label string.
+				 *
+				 * Since 3.14.0
+				 */
+				labelOffsetSupport?: boolean;
+			}
+		};
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/references`
+	 */
+	references?: {
+		/**
+		 * Whether references supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/documentHighlight`
+	 */
+	documentHighlight?: {
+		/**
+		 * Whether document highlight supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/documentSymbol`
+	 */
+	documentSymbol?: {
+		/**
+		 * Whether document symbol supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * Specific capabilities for the `SymbolKind`.
+		 */
+		symbolKind?: {
+			/**
+			 * The symbol kind values the client supports. When this
+			 * property exists the client also guarantees that it will
+			 * handle values outside its set gracefully and falls back
+			 * to a default value when unknown.
+			 *
+			 * If this property is not present the client only supports
+			 * the symbol kinds from `File` to `Array` as defined in
+			 * the initial version of the protocol.
+			 */
+			valueSet?: SymbolKind[];
+		}
+
+		/**
+		 * The client supports hierarchical document symbols.
+		 */
+		hierarchicalDocumentSymbolSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/formatting`
+	 */
+	formatting?: {
+		/**
+		 * Whether formatting supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/rangeFormatting`
+	 */
+	rangeFormatting?: {
+		/**
+		 * Whether range formatting supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/onTypeFormatting`
+	 */
+	onTypeFormatting?: {
+		/**
+		 * Whether on type formatting supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+		* Capabilities specific to the `textDocument/declaration`
+		*/
+	declaration?: {
+		/**
+		 * Whether declaration supports dynamic registration. If this is set to `true`
+		 * the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+		 * return value for the corresponding server capability as well.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports additional metadata in the form of declaration links.
+		 *
+		 * Since 3.14.0
+		 */
+		linkSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/definition`.
+	 *
+	 * Since 3.14.0
+	 */
+	definition?: {
+		/**
+		 * Whether definition supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports additional metadata in the form of definition links.
+		 */
+		linkSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/typeDefinition`
+	 *
+	 * Since 3.6.0
+	 */
+	typeDefinition?: {
+		/**
+		 * Whether typeDefinition supports dynamic registration. If this is set to `true`
+		 * the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+		 * return value for the corresponding server capability as well.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports additional metadata in the form of definition links.
+		 *
+		 * Since 3.14.0
+		 */
+		linkSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/implementation`.
+	 *
+	 * Since 3.6.0
+	 */
+	implementation?: {
+		/**
+		 * Whether implementation supports dynamic registration. If this is set to `true`
+		 * the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+		 * return value for the corresponding server capability as well.
+		 */
+		dynamicRegistration?: boolean;
+
+		/**
+		 * The client supports additional metadata in the form of definition links.
+		 *
+		 * Since 3.14.0
+		 */
+		linkSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/codeAction`
+	 */
+	codeAction?: {
+		/**
+		 * Whether code action supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+		/**
+		 * The client support code action literals as a valid
+		 * response of the `textDocument/codeAction` request.
+		 *
+		 * Since 3.8.0
+		 */
+		codeActionLiteralSupport?: {
+			/**
+			 * The code action kind is support with the following value
+			 * set.
+			 */
+			codeActionKind: {
+
+				/**
+				 * The code action kind values the client supports. When this
+				 * property exists the client also guarantees that it will
+				 * handle values outside its set gracefully and falls back
+				 * to a default value when unknown.
+				 */
+				valueSet: CodeActionKind[];
+			};
+		};
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/codeLens`
+	 */
+	codeLens?: {
+		/**
+		 * Whether code lens supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/documentLink`
+	 */
+	documentLink?: {
+		/**
+		 * Whether document link supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to the `textDocument/documentColor` and the
+	 * `textDocument/colorPresentation` request.
+	 *
+	 * Since 3.6.0
+	 */
+	colorProvider?: {
+		/**
+		 * Whether colorProvider supports dynamic registration. If this is set to `true`
+		 * the client supports the new `(ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+		 * return value for the corresponding server capability as well.
+		 */
+		dynamicRegistration?: boolean;
+	}
+
+	/**
+	 * Capabilities specific to the `textDocument/rename`
+	 */
+	rename?: {
+		/**
+		 * Whether rename supports dynamic registration.
+		 */
+		dynamicRegistration?: boolean;
+		/**
+		 * The client supports testing for validity of rename operations
+		 * before execution.
+		 */
+		prepareSupport?: boolean;
+	};
+
+	/**
+	 * Capabilities specific to `textDocument/publishDiagnostics`.
+	 */
+	publishDiagnostics?: {
+		/**
+		 * Whether the clients accepts diagnostics with related information.
+		 */
+		relatedInformation?: boolean;
+	};
+	/**
+	 * Capabilities specific to `textDocument/foldingRange` requests.
+	 *
+	 * Since 3.10.0
+	 */
+	foldingRange?: {
+		/**
+		 * Whether implementation supports dynamic registration for folding range providers. If this is set to `true`
+		 * the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
+		 * return value for the corresponding server capability as well.
+		 */
+		dynamicRegistration?: boolean;
+		/**
+		 * The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
+		 * hint, servers are free to follow the limit.
+		 */
+		rangeLimit?: number;
+		/**
+		 * If set, the client signals that it only supports folding complete lines. If set, client will
+		 * ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
+		 */
+		lineFoldingOnly?: boolean;
+	};
+}
+```
+
+`ClientCapabilities` now define capabilities for dynamic registration, workspace and text document features the client supports. The `experimental` can be used to pass experimental capabilities under development. For future compatibility a `ClientCapabilities` object literal can have more properties set than currently defined. Servers receiving a `ClientCapabilities` object literal with unknown properties should ignore these properties. A missing property should be interpreted as an absence of the capability. If a missing property normally defines sub properties, all missing sub properties should be interpreted as an absence of the corresponding capability.
+
+Client capabilities got introduced with version 3.0 of the protocol. They therefore only describe capabilities that got introduced in 3.x or later. Capabilities that existed in the 2.x version of the protocol are still mandatory for clients. Clients cannot opt out of providing them. So even if a client omits the `ClientCapabilities.textDocument.synchronization` it is still required that the client provides text document synchronization (e.g. open, changed and close notifications).
+
+```typescript
+interface ClientCapabilities {
+	/**
+	 * Workspace specific client capabilities.
+	 */
+	workspace?: WorkspaceClientCapabilities;
+
+	/**
+	 * Text document specific client capabilities.
+	 */
+	textDocument?: TextDocumentClientCapabilities;
+
+	/**
+	 * Experimental client capabilities.
+	 */
+	experimental?: any;
+}
+```
+
+_Response_:
+* result: `InitializeResult` defined as follows:
+
+```typescript
+interface InitializeResult {
+	/**
+	 * The capabilities the language server provides.
+	 */
+	capabilities: ServerCapabilities;
+}
+```
+* error.code:
+
+```typescript
+/**
+ * Known error codes for an `InitializeError`;
+ */
+export namespace InitializeError {
+	/**
+	 * If the protocol version provided by the client can't be handled by the server.
+	 * @deprecated This initialize error got replaced by client capabilities. There is
+	 * no version handshake in version 3.0x
+	 */
+	export const unknownProtocolVersion: number = 1;
+}
+```
+
+* error.data:
+
+```typescript
+interface InitializeError {
+	/**
+	 * Indicates whether the client execute the following retry logic:
+	 * (1) show the message provided by the ResponseError to the user
+	 * (2) user selects retry or cancel
+	 * (3) if user selected retry the initialize method is sent again.
+	 */
+	retry: boolean;
+}
+```
+
+The server can signal the following capabilities:
+
+```typescript
+/**
+ * Defines how the host (editor) should sync document changes to the language server.
+ */
+export namespace TextDocumentSyncKind {
+	/**
+	 * Documents should not be synced at all.
+	 */
+	export const None = 0;
+
+	/**
+	 * Documents are synced by always sending the full content
+	 * of the document.
+	 */
+	export const Full = 1;
+
+	/**
+	 * Documents are synced by sending the full content on open.
+	 * After that only incremental updates to the document are
+	 * send.
+	 */
+	export const Incremental = 2;
+}
+
+/**
+ * Completion options.
+ */
+export interface CompletionOptions {
+	/**
+	 * The server provides support to resolve additional
+	 * information for a completion item.
+	 */
+	resolveProvider?: boolean;
+
+	/**
+	 * The characters that trigger completion automatically.
+	 */
+	triggerCharacters?: string[];
+}
+/**
+ * Signature help options.
+ */
+export interface SignatureHelpOptions {
+	/**
+	 * The characters that trigger signature help
+	 * automatically.
+	 */
+	triggerCharacters?: string[];
+}
+
+/**
+ * Code Action options.
+ */
+export interface CodeActionOptions {
+	/**
+	 * CodeActionKinds that this server may return.
+	 *
+	 * The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server
+	 * may list out every specific kind they provide.
+	 */
+	codeActionKinds?: CodeActionKind[];
+}
+
+/**
+ * Code Lens options.
+ */
+export interface CodeLensOptions {
+	/**
+	 * Code lens has a resolve provider as well.
+	 */
+	resolveProvider?: boolean;
+}
+
+/**
+ * Format document on type options.
+ */
+export interface DocumentOnTypeFormattingOptions {
+	/**
+	 * A character on which formatting should be triggered, like `}`.
+	 */
+	firstTriggerCharacter: string;
+
+	/**
+	 * More trigger characters.
+	 */
+	moreTriggerCharacter?: string[];
+}
+
+/**
+ * Rename options
+ */
+export interface RenameOptions {
+	/**
+	 * Renames should be checked and tested before being executed.
+	 */
+	prepareProvider?: boolean;
+}
+
+/**
+ * Document link options.
+ */
+export interface DocumentLinkOptions {
+	/**
+	 * Document links have a resolve provider as well.
+	 */
+	resolveProvider?: boolean;
+}
+
+/**
+ * Execute command options.
+ */
+export interface ExecuteCommandOptions {
+	/**
+	 * The commands to be executed on the server
+	 */
+	commands: string[]
+}
+
+/**
+ * Save options.
+ */
+export interface SaveOptions {
+	/**
+	 * The client is supposed to include the content on save.
+	 */
+	includeText?: boolean;
+}
+
+/**
+ * Color provider options.
+ */
+export interface ColorProviderOptions {
+}
+
+/**
+ * Folding range provider options.
+ */
+export interface FoldingRangeProviderOptions {
+}
+
+export interface TextDocumentSyncOptions {
+	/**
+	 * Open and close notifications are sent to the server.
+	 */
+	openClose?: boolean;
+	/**
+	 * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+	 * and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
+	 */
+	change?: number;
+	/**
+	 * Will save notifications are sent to the server.
+	 */
+	willSave?: boolean;
+	/**
+	 * Will save wait until requests are sent to the server.
+	 */
+	willSaveWaitUntil?: boolean;
+	/**
+	 * Save notifications are sent to the server.
+	 */
+	save?: SaveOptions;
+}
+
+/**
+ * Static registration options to be returned in the initialize request.
+ */
+interface StaticRegistrationOptions {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again. See also Registration#id.
+	 */
+	id?: string;
+}
+
+interface ServerCapabilities {
+	/**
+	 * Defines how text documents are synced. Is either a detailed structure defining each notification or
+	 * for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
+	 */
+	textDocumentSync?: TextDocumentSyncOptions | number;
+	/**
+	 * The server provides hover support.
+	 */
+	hoverProvider?: boolean;
+	/**
+	 * The server provides completion support.
+	 */
+	completionProvider?: CompletionOptions;
+	/**
+	 * The server provides signature help support.
+	 */
+	signatureHelpProvider?: SignatureHelpOptions;
+	/**
+	 * The server provides goto definition support.
+	 */
+	definitionProvider?: boolean;
+	/**
+	 * The server provides Goto Type Definition support.
+	 *
+	 * Since 3.6.0
+	 */
+	typeDefinitionProvider?: boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions);
+	/**
+	 * The server provides Goto Implementation support.
+	 *
+	 * Since 3.6.0
+	 */
+	implementationProvider?: boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions);
+	/**
+	 * The server provides find references support.
+	 */
+	referencesProvider?: boolean;
+	/**
+	 * The server provides document highlight support.
+	 */
+	documentHighlightProvider?: boolean;
+	/**
+	 * The server provides document symbol support.
+	 */
+	documentSymbolProvider?: boolean;
+	/**
+	 * The server provides workspace symbol support.
+	 */
+	workspaceSymbolProvider?: boolean;
+	/**
+	 * The server provides code actions. The `CodeActionOptions` return type is only
+	 * valid if the client signals code action literal support via the property
+	 * `textDocument.codeAction.codeActionLiteralSupport`.
+	 */
+	codeActionProvider?: boolean | CodeActionOptions;
+	/**
+	 * The server provides code lens.
+	 */
+	codeLensProvider?: CodeLensOptions;
+	/**
+	 * The server provides document formatting.
+	 */
+	documentFormattingProvider?: boolean;
+	/**
+	 * The server provides document range formatting.
+	 */
+	documentRangeFormattingProvider?: boolean;
+	/**
+	 * The server provides document formatting on typing.
+	 */
+	documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions;
+	/**
+	 * The server provides rename support. RenameOptions may only be
+	 * specified if the client states that it supports
+	 * `prepareSupport` in its initial `initialize` request.
+	 */
+	renameProvider?: boolean | RenameOptions;
+	/**
+	 * The server provides document link support.
+	 */
+	documentLinkProvider?: DocumentLinkOptions;
+	/**
+	 * The server provides color provider support.
+	 *
+	 * Since 3.6.0
+	 */
+	colorProvider?: boolean | ColorProviderOptions | (ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions);
+	/**
+	 * The server provides folding provider support.
+	 *
+	 * Since 3.10.0
+	 */
+	foldingRangeProvider?: boolean | FoldingRangeProviderOptions | (FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions);
+	/**
+	 * The server provides execute command support.
+	 */
+	executeCommandProvider?: ExecuteCommandOptions;
+	/**
+	 * Workspace specific server capabilities
+	 */
+	workspace?: {
+		/**
+		 * The server supports workspace folder.
+		 *
+		 * Since 3.6.0
+		 */
+		workspaceFolders?: {
+			/**
+			* The server has support for workspace folders
+			*/
+			supported?: boolean;
+			/**
+			* Whether the server wants to receive workspace folder
+			* change notifications.
+			*
+			* If a strings is provided the string is treated as a ID
+			* under which the notification is registered on the client
+			* side. The ID can be used to unregister for these events
+			* using the `client/unregisterCapability` request.
+			*/
+			changeNotifications?: string | boolean;
+		}
+	}
+	/**
+	 * Experimental server capabilities.
+	 */
+	experimental?: any;
+}
+```
+
+#### <a href="#initialized" name="initialized" class="anchor">Initialized Notification (:arrow_right:)</a>
+
+The initialized notification is sent from the client to the server after the client received the result of the `initialize` request but before the client is sending any other request or notification to the server. The server can use the `initialized` notification for example to dynamically register capabilities. The `initialized` notification may only be sent once.
+
+_Notification_:
+* method: 'initialized'
+* params: `InitializedParams` defined as follows:
+
+```typescript
+interface InitializedParams {
+}
+```
+
+#### <a href="#shutdown" name="shutdown" class="anchor">Shutdown Request (:leftwards_arrow_with_hook:)</a>
+
+The shutdown request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit.
+
+_Request_:
+* method: 'shutdown'
+* params: void
+
+_Response_:
+* result: null
+* error: code and message set in case an exception happens during shutdown request.
+
+#### <a href="#exit" name="exit" class="anchor">Exit Notification (:arrow_right:)</a>
+
+A notification to ask the server to exit its process.
+The server should exit with `success` code 0 if the shutdown request has been received before; otherwise with `error` code 1.
+
+_Notification_:
+* method: 'exit'
+* params: void
+
+#### <a href="#window_showMessage" name="window_showMessage" class="anchor">ShowMessage Notification (:arrow_left:)</a>
+
+The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
+
+_Notification_:
+* method: 'window/showMessage'
+* params: `ShowMessageParams` defined as follows:
+
+```typescript
+interface ShowMessageParams {
+	/**
+	 * The message type. See {@link MessageType}.
+	 */
+	type: number;
+
+	/**
+	 * The actual message.
+	 */
+	message: string;
+}
+```
+
+Where the type is defined as follows:
+
+```typescript
+export namespace MessageType {
+	/**
+	 * An error message.
+	 */
+	export const Error = 1;
+	/**
+	 * A warning message.
+	 */
+	export const Warning = 2;
+	/**
+	 * An information message.
+	 */
+	export const Info = 3;
+	/**
+	 * A log message.
+	 */
+	export const Log = 4;
+}
+```
+
+#### <a href="#window_showMessageRequest" name="window_showMessageRequest" class="anchor">ShowMessage Request (:arrow_right_hook:)</a>
+
+The show message request is sent from a server to a client to ask the client to display a particular message in the user interface. In addition to the show message notification the request allows to pass actions and to wait for an answer from the client.
+
+_Request_:
+* method: 'window/showMessageRequest'
+* params: `ShowMessageRequestParams` defined as follows:
+
+_Response_:
+* result: the selected `MessageActionItem` \| `null` if none got selected.
+* error: code and message set in case an exception happens during showing a message.
+
+```typescript
+interface ShowMessageRequestParams {
+	/**
+	 * The message type. See {@link MessageType}
+	 */
+	type: number;
+
+	/**
+	 * The actual message
+	 */
+	message: string;
+
+	/**
+	 * The message action items to present.
+	 */
+	actions?: MessageActionItem[];
+}
+```
+
+Where the `MessageActionItem` is defined as follows:
+
+```typescript
+interface MessageActionItem {
+	/**
+	 * A short title like 'Retry', 'Open Log' etc.
+	 */
+	title: string;
+}
+```
+
+#### <a href="#window_logMessage" name="window_logMessage" class="anchor">LogMessage Notification (:arrow_left:)</a>
+
+The log message notification is sent from the server to the client to ask the client to log a particular message.
+
+_Notification_:
+* method: 'window/logMessage'
+* params: `LogMessageParams` defined as follows:
+
+```typescript
+interface LogMessageParams {
+	/**
+	 * The message type. See {@link MessageType}
+	 */
+	type: number;
+
+	/**
+	 * The actual message
+	 */
+	message: string;
+}
+```
+
+Where type is defined as above.
+
+#### <a href="#telemetry_event" name="telemetry_event" class="anchor">Telemetry Notification (:arrow_left:)</a>
+
+The telemetry notification is sent from the server to the client to ask the client to log a telemetry event.
+
+_Notification_:
+* method: 'telemetry/event'
+* params: 'any'
+
+#### <a href="#client_registerCapability" name="client_registerCapability" class="anchor">Register Capability (:arrow_right_hook:)</a>
+
+The `client/registerCapability` request is sent from the server to the client to register for a new capability on the client side. Not all clients need to support dynamic capability registration. A client opts in via the `dynamicRegistration` property on the specific client capabilities. A client can even provide dynamic registration for capability A but not for capability B (see `TextDocumentClientCapabilities` as an example).
+
+_Request_:
+* method: 'client/registerCapability'
+* params: `RegistrationParams`
+
+Where `RegistrationParams` are defined as follows:
+
+```typescript
+/**
+ * General parameters to register for a capability.
+ */
+export interface Registration {
+	/**
+	 * The id used to register the request. The id can be used to deregister
+	 * the request again.
+	 */
+	id: string;
+
+	/**
+	 * The method / capability to register for.
+	 */
+	method: string;
+
+	/**
+	 * Options necessary for the registration.
+	 */
+	registerOptions?: any;
+}
+
+export interface RegistrationParams {
+	registrations: Registration[];
+}
+```
+
+Since most of the registration options require to specify a document selector there is a base interface that can be used.
+
+```typescript
+export interface TextDocumentRegistrationOptions {
+	/**
+	 * A document selector to identify the scope of the registration. If set to null
+	 * the document selector provided on the client side will be used.
+	 */
+	documentSelector: DocumentSelector | null;
+}
+```
+
+An example JSON RPC message to register dynamically for the `textDocument/willSaveWaitUntil` feature on the client side is as follows (only details shown):
+
+```json
+{
+	"method": "client/registerCapability",
+	"params": {
+		"registrations": [
+			{
+				"id": "79eee87c-c409-4664-8102-e03263673f6f",
+				"method": "textDocument/willSaveWaitUntil",
+				"registerOptions": {
+					"documentSelector": [
+						{ "language": "javascript" }
+					]
+				}
+			}
+		]
+	}
+}
+```
+
+This message is sent from the server to the client and after the client has successfully executed the request further `textDocument/willSaveWaitUntil` requests for JavaScript text documents are sent from the client to the server.
+
+_Response_:
+* result: void.
+* error: code and message set in case an exception happens during the request.
+
+#### <a href="#client_unregisterCapability" name="client_unregisterCapability" class="anchor">Unregister Capability (:arrow_right_hook:)</a>
+
+The `client/unregisterCapability` request is sent from the server to the client to unregister a previously registered capability.
+
+_Request_:
+* method: 'client/unregisterCapability'
+* params: `UnregistrationParams`
+
+Where `UnregistrationParams` are defined as follows:
+
+```typescript
+/**
+ * General parameters to unregister a capability.
+ */
+export interface Unregistration {
+	/**
+	 * The id used to unregister the request or notification. Usually an id
+	 * provided during the register request.
+	 */
+	id: string;
+
+	/**
+	 * The method / capability to unregister for.
+	 */
+	method: string;
+}
+
+export interface UnregistrationParams {
+	unregisterations: Unregistration[];
+}
+```
+
+An example JSON RPC message to unregister the above registered `textDocument/willSaveWaitUntil` feature looks like this:
+
+```json
+{
+	"method": "client/unregisterCapability",
+	"params": {
+		"unregisterations": [
+			{
+				"id": "79eee87c-c409-4664-8102-e03263673f6f",
+				"method": "textDocument/willSaveWaitUntil"
+			}
+		]
+	}
+}
+```
+_Response_:
+* result: void.
+* error: code and message set in case an exception happens during the request.
+
+##### <a href="#workspace_workspaceFolders" name="workspace_workspaceFolders" class="anchor">Workspace folders request (:arrow_right_hook:)</a>
+
+> *Since version 3.6.0*
+
+Many tools support more than one root folder per workspace. Examples for this are VS Code's multi-root support, Atom's project folder support or Sublime's project support. If a client workspace consists of multiple roots then a server typically needs to know about this. The protocol up to now assumes one root folder which is announced to the server by the `rootUri` property of the `InitializeParams`. If the client supports workspace folders and announces them via the corresponding `workspaceFolders` client capability, the `InitializeParams` contain an additional property `workspaceFolders` with the configured workspace folders when the server starts.
+
+The `workspace/workspaceFolders` request is sent from the server to the client to fetch the current open list of workspace folders. Returns `null` in the response if only a single file is open in the tool. Returns an empty array if a workspace is open but no folders are configured.
+
+_Request_:
+
+* method: 'workspace/workspaceFolders'
+* params: none
+
+_Response_:
+
+* result: `WorkspaceFolder[] | null` defined as follows:
+
+```typescript
+export interface WorkspaceFolder {
+	/**
+	 * The associated URI for this workspace folder.
+	 */
+	uri: string;
+
+	/**
+	 * The name of the workspace folder. Defaults to the
+	 * uri's basename.
+	 */
+	name: string;
+}
+```
+* error: code and message set in case an exception happens during the 'workspace/workspaceFolders' request
+
+##### <a href="#workspace_didChangeWorkspaceFolders" name="workspace_didChangeWorkspaceFolders" class="anchor">DidChangeWorkspaceFolders Notification (:arrow_right:)</a>
+
+> *Since version 3.6.0*
+
+The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server to inform the server about workspace folder configuration changes. The notification is sent by default if both _ServerCapabilities/workspace/workspaceFolders_ and _ClientCapabilities/workspace/workspaceFolders_ are true; or if the server has registered itself to receive this notification. To register for the `workspace/didChangeWorkspaceFolders` send a `client/registerCapability` request from the server to the client. The registration parameter must have a `registrations` item of the following form, where `id` is a unique id used to unregister the capability (the example uses a UUID):
+```ts
+{
+	id: "28c6150c-bd7b-11e7-abc4-cec278b6b50a",
+	method: "workspace/didChangeWorkspaceFolders"
+}
+```
+
+_Notification_:
+
+* method: 'workspace/didChangeWorkspaceFolders'
+* params: `DidChangeWorkspaceFoldersParams` defined as follows:
+
+```typescript
+export interface DidChangeWorkspaceFoldersParams {
+	/**
+	 * The actual workspace folder change event.
+	 */
+	event: WorkspaceFoldersChangeEvent;
+}
+
+/**
+ * The workspace folder change event.
+ */
+export interface WorkspaceFoldersChangeEvent {
+	/**
+	 * The array of added workspace folders
+	 */
+	added: WorkspaceFolder[];
+
+	/**
+	 * The array of the removed workspace folders
+	 */
+	removed: WorkspaceFolder[];
+}
+```
+
+#### <a href="#workspace_didChangeConfiguration" name="workspace_didChangeConfiguration" class="anchor">DidChangeConfiguration Notification (:arrow_right:)</a>
+
+A notification sent from the client to the server to signal the change of configuration settings.
+
+_Notification_:
+* method: 'workspace/didChangeConfiguration',
+* params: `DidChangeConfigurationParams` defined as follows:
+
+```typescript
+interface DidChangeConfigurationParams {
+	/**
+	 * The actual changed settings
+	 */
+	settings: any;
+}
+```
+
+#### <a href="#workspace_configuration" name="workspace_configuration" class="anchor">Configuration Request (:arrow_right_hook:)</a>
+
+> *Since version 3.6.0*
+
+The `workspace/configuration` request is sent from the server to the client to fetch configuration settings from the client. The request can fetch several configuration settings in one roundtrip. The order of the returned configuration settings correspond to the order of the passed `ConfigurationItems` (e.g. the first item in the response is the result for the first configuration item in the params).
+
+A `ConfigurationItem` consists of the configuration section to ask for and an additional scope URI. The configuration section ask for is defined by the server and doesn't necessarily need to correspond to the configuration store used be the client. So a server might ask for a configuration `cpp.formatterOptions` but the client stores the configuration in a XML store layout differently. It is up to the client to do the necessary conversion. If a scope URI is provided the client should return the setting scoped to the provided resource. If the client for example uses [EditorConfig](http://editorconfig.org/) to manage its settings the configuration should be returned for the passed resource URI. If the client can't provide a configuration setting for a given scope then `null` need to be present in the returned array.
+
+_Request_:
+
+* method: 'workspace/configuration'
+* params: `ConfigurationParams` defined as follows
+
+```typescript
+export interface ConfigurationParams {
+	items: ConfigurationItem[];
+}
+
+export interface ConfigurationItem {
+	/**
+	 * The scope to get the configuration section for.
+	 */
+	scopeUri?: string;
+
+	/**
+	 * The configuration section asked for.
+	 */
+	section?: string;
+}
+```
+
+_Response_:
+* result: any[]
+* error: code and message set in case an exception happens during the 'workspace/configuration' request
+
+#### <a href="#workspace_didChangeWatchedFiles" name="workspace_didChangeWatchedFiles" class="anchor">DidChangeWatchedFiles Notification (:arrow_right:)</a>
+
+The watched files notification is sent from the client to the server when the client detects changes to files watched by the language client. It is recommended that servers register for these file events using the registration mechanism. In former implementations clients pushed file events without the server actively asking for it.
+
+Servers are allowed to run their own file watching mechanism and not rely on clients to provide file events. However this is not recommended due to the following reasons:
+
+- to our experience getting file watching on disk right is challenging, especially if it needs to be supported across multiple OSes.
+- file watching is not for free especially if the implementation uses some sort of polling and keeps a file tree in memory to compare time stamps (as for example some node modules do)
+- a client usually starts more than one server. If every server runs its own file watching it can become a CPU or memory problem.
+- in general there are more server than client implementations. So this problem is better solved on the client side.
+
+
+_Notification_:
+* method: 'workspace/didChangeWatchedFiles'
+* params: `DidChangeWatchedFilesParams` defined as follows:
+
+```typescript
+interface DidChangeWatchedFilesParams {
+	/**
+	 * The actual file events.
+	 */
+	changes: FileEvent[];
+}
+```
+
+Where FileEvents are described as follows:
+
+```typescript
+/**
+ * An event describing a file change.
+ */
+interface FileEvent {
+	/**
+	 * The file's URI.
+	 */
+	uri: DocumentUri;
+	/**
+	 * The change type.
+	 */
+	type: number;
+}
+
+/**
+ * The file event type.
+ */
+export namespace FileChangeType {
+	/**
+	 * The file got created.
+	 */
+	export const Created = 1;
+	/**
+	 * The file got changed.
+	 */
+	export const Changed = 2;
+	/**
+	 * The file got deleted.
+	 */
+	export const Deleted = 3;
+}
+```
+
+_Registration Options_: `DidChangeWatchedFilesRegistrationOptions` defined as follows
+
+```typescript
+/**
+ * Describe options to be used when registering for text document change events.
+ */
+export interface DidChangeWatchedFilesRegistrationOptions {
+	/**
+	 * The watchers to register.
+	 */
+	watchers: FileSystemWatcher[];
+}
+
+export interface FileSystemWatcher {
+	/**
+	 * The  glob pattern to watch.
+	 *
+	 * Glob patterns can have the following syntax:
+	 * - `*` to match one or more characters in a path segment
+	 * - `?` to match on one character in a path segment
+	 * - `**` to match any number of path segments, including none
+	 * - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
+	 * - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
+	 * - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
+	 */
+	globPattern: string;
+
+	/**
+	 * The kind of events of interest. If omitted it defaults
+	 * to WatchKind.Create | WatchKind.Change | WatchKind.Delete
+	 * which is 7.
+	 */
+	kind?: number;
+}
+
+export namespace WatchKind {
+	/**
+	 * Interested in create events.
+	 */
+	export const Create = 1;
+
+	/**
+	 * Interested in change events
+	 */
+	export const Change = 2;
+
+	/**
+	 * Interested in delete events
+	 */
+	export const Delete = 4;
+}
+```
+
+#### <a href="#workspace_symbol" name="workspace_symbol" class="anchor">Workspace Symbols Request (:leftwards_arrow_with_hook:)</a>
+
+The workspace symbol request is sent from the client to the server to list project-wide symbols matching the query string.
+
+_Request_:
+* method: 'workspace/symbol'
+* params: `WorkspaceSymbolParams` defined as follows:
+
+```typescript
+/**
+ * The parameters of a Workspace Symbol Request.
+ */
+interface WorkspaceSymbolParams {
+	/**
+	 * A non-empty query string
+	 */
+	query: string;
+}
+```
+
+_Response_:
+* result: `SymbolInformation[]` \| `null` as defined above.
+* error: code and message set in case an exception happens during the workspace symbol request.
+
+_Registration Options_: void
+
+
+#### <a href="#workspace_executeCommand" name="workspace_executeCommand" class="anchor">Execute a command (:leftwards_arrow_with_hook:)</a>
+
+The `workspace/executeCommand` request is sent from the client to the server to trigger command execution on the server. In most cases
+the server creates a `WorkspaceEdit` structure and applies the changes to the workspace using the request `workspace/applyEdit` which is
+sent from the server to the client.
+
+_Request:_
+* method: 'workspace/executeCommand'
+* params: `ExecuteCommandParams` defined as follows:
+
+```typescript
+export interface ExecuteCommandParams {
+
+	/**
+	 * The identifier of the actual command handler.
+	 */
+	command: string;
+	/**
+	 * Arguments that the command should be invoked with.
+	 */
+	arguments?: any[];
+}
+```
+
+The arguments are typically specified when a command is returned from the server to the client. Example requests that return a command are `textDocument/codeAction` or `textDocument/codeLens`.
+
+_Response_:
+* result: `any` \| `null`
+* error: code and message set in case an exception happens during the request.
+
+_Registration Options_: `ExecuteCommandRegistrationOptions` defined as follows:
+
+```typescript
+/**
+ * Execute command registration options.
+ */
+export interface ExecuteCommandRegistrationOptions {
+	/**
+	 * The commands to be executed on the server
+	 */
+	commands: string[]
+}
+```
+
+
+#### <a href="#workspace_applyEdit" name="workspace_applyEdit" class="anchor">Applies a WorkspaceEdit (:arrow_right_hook:)</a>
+
+The `workspace/applyEdit` request is sent from the server to the client to modify resource on the client side.
+
+_Request_:
+* method: 'workspace/applyEdit'
+* params: `ApplyWorkspaceEditParams` defined as follows:
+
+```typescript
+export interface ApplyWorkspaceEditParams {
+	/**
+	 * An optional label of the workspace edit. This label is
+	 * presented in the user interface for example on an undo
+	 * stack to undo the workspace edit.
+	 */
+	label?: string;
+
+	/**
+	 * The edits to apply.
+	 */
+	edit: WorkspaceEdit;
+}
+```
+
+_Response_:
+* result: `ApplyWorkspaceEditResponse` defined as follows:
+
+```typescript
+export interface ApplyWorkspaceEditResponse {
+	/**
+	 * Indicates whether the edit was applied or not.
+	 */
+	applied: boolean;
+}
+```
+* error: code and message set in case an exception happens during the request.
+
+
+#### <a href="#textDocument_didOpen" name="textDocument_didOpen" class="anchor">DidOpenTextDocument Notification (:arrow_right:)</a>
+
+The document open notification is sent from the client to the server to signal newly opened text documents. The document's truth is now managed by the client and the server must not try to read the document's truth using the document's Uri. Open in this sense means it is managed by the client. It doesn't necessarily mean that its content is presented in an editor. An open notification must not be sent more than once without a corresponding close notification send before. This means open and close notification must be balanced and the max open count for a particular textDocument is one. Note that a server's ability to fulfill requests is independent of whether a text document is open or closed.
+
+The `DidOpenTextDocumentParams` contain the language id the document is associated with. If the language Id of a document changes, the client needs to send a `textDocument/didClose` to the server followed by a `textDocument/didOpen` with the new language id if the server handles the new language id as well.
+
+_Notification_:
+* method: 'textDocument/didOpen'
+* params: `DidOpenTextDocumentParams` defined as follows:
+
+```typescript
+interface DidOpenTextDocumentParams {
+	/**
+	 * The document that was opened.
+	 */
+	textDocument: TextDocumentItem;
+}
+```
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+
+#### <a href="#textDocument_didChange" name="textDocument_didChange" class="anchor">DidChangeTextDocument Notification (:arrow_right:)</a>
+
+The document change notification is sent from the client to the server to signal changes to a text document. In 2.0 the shape of the params has changed to include proper version numbers and language ids.
+
+_Notification_:
+* method: 'textDocument/didChange'
+* params: `DidChangeTextDocumentParams` defined as follows:
+
+```typescript
+interface DidChangeTextDocumentParams {
+	/**
+	 * The document that did change. The version number points
+	 * to the version after all provided content changes have
+	 * been applied.
+	 */
+	textDocument: VersionedTextDocumentIdentifier;
+
+	/**
+	 * The actual content changes. The content changes describe single state changes
+	 * to the document. So if there are two content changes c1 and c2 for a document
+	 * in state S then c1 move the document to S' and c2 to S''.
+	 */
+	contentChanges: TextDocumentContentChangeEvent[];
+}
+
+/**
+ * An event describing a change to a text document. If range and rangeLength are omitted
+ * the new text is considered to be the full content of the document.
+ */
+interface TextDocumentContentChangeEvent {
+	/**
+	 * The range of the document that changed.
+	 */
+	range?: Range;
+
+	/**
+	 * The length of the range that got replaced.
+	 */
+	rangeLength?: number;
+
+	/**
+	 * The new text of the range/document.
+	 */
+	text: string;
+}
+```
+
+_Registration Options_: `TextDocumentChangeRegistrationOptions` defined as follows:
+
+```typescript
+/**
+ * Describe options to be used when registering for text document change events.
+ */
+export interface TextDocumentChangeRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * How documents are synced to the server. See TextDocumentSyncKind.Full
+	 * and TextDocumentSyncKind.Incremental.
+	 */
+	syncKind: number;
+}
+```
+
+
+#### <a href="#textDocument_willSave" name="textDocument_willSave" class="anchor">WillSaveTextDocument Notification (:arrow_right:)</a>
+
+The document will save notification is sent from the client to the server before the document is actually saved.
+
+_Notification_:
+* method: 'textDocument/willSave'
+* params: `WillSaveTextDocumentParams` defined as follows:
+
+```typescript
+/**
+ * The parameters send in a will save text document notification.
+ */
+export interface WillSaveTextDocumentParams {
+	/**
+	 * The document that will be saved.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The 'TextDocumentSaveReason'.
+	 */
+	reason: number;
+}
+
+/**
+ * Represents reasons why a text document is saved.
+ */
+export namespace TextDocumentSaveReason {
+
+	/**
+	 * Manually triggered, e.g. by the user pressing save, by starting debugging,
+	 * or by an API call.
+	 */
+	export const Manual = 1;
+
+	/**
+	 * Automatic after a delay.
+	 */
+	export const AfterDelay = 2;
+
+	/**
+	 * When the editor lost focus.
+	 */
+	export const FocusOut = 3;
+}
+```
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+
+#### <a href="#textDocument_willSaveWaitUntil" name="textDocument_willSaveWaitUntil" class="anchor">WillSaveWaitUntilTextDocument Request (:leftwards_arrow_with_hook:)</a>
+
+The document will save request is sent from the client to the server before the document is actually saved. The request can return an array of TextEdits which will be applied to the text document before it is saved. Please note that clients might drop results if computing the text edits took too long or if a server constantly fails on this request. This is done to keep the save fast and reliable.
+
+_Request_:
+* method: 'textDocument/willSaveWaitUntil'
+* params: `WillSaveTextDocumentParams`
+
+_Response_:
+* result:`TextEdit[]` \| `null`
+* error: code and message set in case an exception happens during the `willSaveWaitUntil` request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_didSave" name="textDocument_didSave" class="anchor">DidSaveTextDocument Notification (:arrow_right:)</a>
+
+The document save notification is sent from the client to the server when the document was saved in the client.
+
+* method: 'textDocument/didSave'
+* params: `DidSaveTextDocumentParams` defined as follows:
+
+```typescript
+interface DidSaveTextDocumentParams {
+	/**
+	 * The document that was saved.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * Optional the content when saved. Depends on the includeText value
+	 * when the save notification was requested.
+	 */
+	text?: string;
+}
+```
+
+_Registration Options_: `TextDocumentSaveRegistrationOptions` defined as follows:
+
+```typescript
+export interface TextDocumentSaveRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * The client is supposed to include the content on save.
+	 */
+	includeText?: boolean;
+}
+```
+
+#### <a href="#textDocument_didClose" name="textDocument_didClose" class="anchor">DidCloseTextDocument Notification (:arrow_right:)</a>
+
+The document close notification is sent from the client to the server when the document got closed in the client. The document's truth now exists where the document's Uri points to (e.g. if the document's Uri is a file Uri the truth now exists on disk). As with the open notification the close notification is about managing the document's content. Receiving a close notification doesn't mean that the document was open in an editor before. A close notification requires a previous open notification to be sent. Note that a server's ability to fulfill requests is independent of whether a text document is open or closed.
+
+_Notification_:
+* method: 'textDocument/didClose'
+* params: `DidCloseTextDocumentParams` defined as follows:
+
+```typescript
+interface DidCloseTextDocumentParams {
+	/**
+	 * The document that was closed.
+	 */
+	textDocument: TextDocumentIdentifier;
+}
+```
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+
+#### <a href="#textDocument_publishDiagnostics" name="textDocument_publishDiagnostics" class="anchor">PublishDiagnostics Notification (:arrow_left:)</a>
+
+Diagnostics notification are sent from the server to the client to signal results of validation runs.
+
+Diagnostics are "owned" by the server so it is the server's responsibility to clear them if necessary. The following rule is used for VS Code servers that generate diagnostics:
+
+* if a language is single file only (for example HTML) then diagnostics are cleared by the server when the file is closed.
+* if a language has a project system (for example C#) diagnostics are not cleared when a file closes. When a project is opened all diagnostics for all files are recomputed (or read from a cache).
+
+When a file changes it is the server's responsibility to re-compute diagnostics and push them to the client. If the computed set is empty it has to push the empty array to clear former diagnostics. Newly pushed diagnostics always replace previously pushed diagnostics. There is no merging that happens on the client side.
+
+_Notification_:
+* method: 'textDocument/publishDiagnostics'
+* params: `PublishDiagnosticsParams` defined as follows:
+
+```typescript
+interface PublishDiagnosticsParams {
+	/**
+	 * The URI for which diagnostic information is reported.
+	 */
+	uri: DocumentUri;
+
+	/**
+	 * An array of diagnostic information items.
+	 */
+	diagnostics: Diagnostic[];
+}
+```
+
+#### <a href="#textDocument_completion" name="textDocument_completion" class="anchor">Completion Request (:leftwards_arrow_with_hook:)</a>
+
+The Completion request is sent from the client to the server to compute completion items at a given cursor position. Completion items are presented in the [IntelliSense](https://code.visualstudio.com/docs/editor/editingevolved#_intellisense) user interface. If computing full completion items is expensive, servers can additionally provide a handler for the completion item resolve request ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A typical use case is for example: the 'textDocument/completion' request doesn't fill in the `documentation` property for returned completion items since it is expensive to compute. When the item is selected in the user interface then a 'completionItem/resolve' request is sent with the selected completion item as a parameter. The returned completion item should have the documentation property filled in. The request can delay the computation of the `detail` and `documentation` properties. However, properties that are needed for the initial sorting and filtering, like `sortText`, `filterText`, `insertText`, and `textEdit` must be provided in the `textDocument/completion` response and must not be changed during resolve.
+
+_Request_:
+* method: 'textDocument/completion'
+* params: `CompletionParams` defined as follows:
+
+```typescript
+export interface CompletionParams extends TextDocumentPositionParams {
+
+	/**
+	 * The completion context. This is only available if the client specifies
+	 * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
+	 */
+	context?: CompletionContext;
+}
+
+/**
+ * How a completion was triggered
+ */
+export namespace CompletionTriggerKind {
+	/**
+	 * Completion was triggered by typing an identifier (24x7 code
+	 * complete), manual invocation (e.g Ctrl+Space) or via API.
+	 */
+	export const Invoked: 1 = 1;
+
+	/**
+	 * Completion was triggered by a trigger character specified by
+	 * the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
+	 */
+	export const TriggerCharacter: 2 = 2;
+
+	/**
+	 * Completion was re-triggered as the current completion list is incomplete.
+	 */
+	export const TriggerForIncompleteCompletions: 3 = 3;
+}
+export type CompletionTriggerKind = 1 | 2 | 3;
+
+
+/**
+ * Contains additional information about the context in which a completion request is triggered.
+ */
+export interface CompletionContext {
+	/**
+	 * How the completion was triggered.
+	 */
+	triggerKind: CompletionTriggerKind;
+
+	/**
+	 * The trigger character (a single character) that has trigger code complete.
+	 * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter`
+	 */
+	triggerCharacter?: string;
+}
+```
+
+_Response_:
+* result: `CompletionItem[]` \| `CompletionList` \| `null`. If a `CompletionItem[]` is provided it is interpreted to be complete. So it is the same as `{ isIncomplete: false, items }`
+
+```typescript
+/**
+ * Represents a collection of [completion items](#CompletionItem) to be presented
+ * in the editor.
+ */
+interface CompletionList {
+	/**
+	 * This list it not complete. Further typing should result in recomputing
+	 * this list.
+	 */
+	isIncomplete: boolean;
+
+	/**
+	 * The completion items.
+	 */
+	items: CompletionItem[];
+}
+
+/**
+ * Defines whether the insert text in a completion item should be interpreted as
+ * plain text or a snippet.
+ */
+namespace InsertTextFormat {
+	/**
+	 * The primary text to be inserted is treated as a plain string.
+	 */
+	export const PlainText = 1;
+
+	/**
+	 * The primary text to be inserted is treated as a snippet.
+	 *
+	 * A snippet can define tab stops and placeholders with `$1`, `$2`
+	 * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+	 * the end of the snippet. Placeholders with equal identifiers are linked,
+	 * that is typing in one will update others too.
+	 */
+	export const Snippet = 2;
+}
+
+type InsertTextFormat = 1 | 2;
+
+interface CompletionItem {
+	/**
+	 * The label of this completion item. By default
+	 * also the text that is inserted when selecting
+	 * this completion.
+	 */
+	label: string;
+
+	/**
+	 * The kind of this completion item. Based of the kind
+	 * an icon is chosen by the editor.
+	 */
+	kind?: number;
+
+	/**
+	 * A human-readable string with additional information
+	 * about this item, like type or symbol information.
+	 */
+	detail?: string;
+
+	/**
+	 * A human-readable string that represents a doc-comment.
+	 */
+	documentation?: string | MarkupContent;
+
+	/**
+	 * Indicates if this item is deprecated.
+	 */
+	deprecated?: boolean;
+
+	/**
+	 * Select this item when showing.
+	 *
+	 * *Note* that only one completion item can be selected and that the
+	 * tool / client decides which item that is. The rule is that the *first*
+	 * item of those that match best is selected.
+	 */
+	preselect?: boolean;
+
+	/**
+	 * A string that should be used when comparing this item
+	 * with other items. When `falsy` the label is used.
+	 */
+	sortText?: string;
+
+	/**
+	 * A string that should be used when filtering a set of
+	 * completion items. When `falsy` the label is used.
+	 */
+	filterText?: string;
+
+	/**
+	 * A string that should be inserted into a document when selecting
+	 * this completion. When `falsy` the label is used.
+	 *
+	 * The `insertText` is subject to interpretation by the client side.
+	 * Some tools might not take the string literally. For example
+	 * VS Code when code complete is requested in this example `con<cursor position>`
+	 * and a completion item with an `insertText` of `console` is provided it
+	 * will only insert `sole`. Therefore it is recommended to use `textEdit` instead
+	 * since it avoids additional client side interpretation.
+	 *
+	 * @deprecated Use textEdit instead.
+	 */
+	insertText?: string;
+
+	/**
+	 * The format of the insert text. The format applies to both the `insertText` property
+	 * and the `newText` property of a provided `textEdit`.
+	 */
+	insertTextFormat?: InsertTextFormat;
+
+	/**
+	 * An edit which is applied to a document when selecting this completion. When an edit is provided the value of
+	 * `insertText` is ignored.
+	 *
+	 * *Note:* The range of the edit must be a single line range and it must contain the position at which completion
+	 * has been requested.
+	 */
+	textEdit?: TextEdit;
+
+	/**
+	 * An optional array of additional text edits that are applied when
+	 * selecting this completion. Edits must not overlap (including the same insert position)
+	 * with the main edit nor with themselves.
+	 *
+	 * Additional text edits should be used to change text unrelated to the current cursor position
+	 * (for example adding an import statement at the top of the file if the completion item will
+	 * insert an unqualified type).
+	 */
+	additionalTextEdits?: TextEdit[];
+
+	/**
+	 * An optional set of characters that when pressed while this completion is active will accept it first and
+	 * then type that character. *Note* that all commit characters should have `length=1` and that superfluous
+	 * characters will be ignored.
+	 */
+	commitCharacters?: string[];
+
+	/**
+	 * An optional command that is executed *after* inserting this completion. *Note* that
+	 * additional modifications to the current document should be described with the
+	 * additionalTextEdits-property.
+	 */
+	command?: Command;
+
+	/**
+	 * An data entry field that is preserved on a completion item between
+	 * a completion and a completion resolve request.
+	 */
+	data?: any
+}
+
+/**
+ * The kind of a completion entry.
+ */
+namespace CompletionItemKind {
+	export const Text = 1;
+	export const Method = 2;
+	export const Function = 3;
+	export const Constructor = 4;
+	export const Field = 5;
+	export const Variable = 6;
+	export const Class = 7;
+	export const Interface = 8;
+	export const Module = 9;
+	export const Property = 10;
+	export const Unit = 11;
+	export const Value = 12;
+	export const Enum = 13;
+	export const Keyword = 14;
+	export const Snippet = 15;
+	export const Color = 16;
+	export const File = 17;
+	export const Reference = 18;
+	export const Folder = 19;
+	export const EnumMember = 20;
+	export const Constant = 21;
+	export const Struct = 22;
+	export const Event = 23;
+	export const Operator = 24;
+	export const TypeParameter = 25;
+}
+```
+* error: code and message set in case an exception happens during the completion request.
+
+_Registration Options_: `CompletionRegistrationOptions` options defined as follows:
+
+```typescript
+export interface CompletionRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * Most tools trigger completion request automatically without explicitly requesting
+	 * it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user
+	 * starts to type an identifier. For example if the user types `c` in a JavaScript file
+	 * code complete will automatically pop up present `console` besides others as a
+	 * completion item. Characters that make up identifiers don't need to be listed here.
+	 *
+	 * If code complete should automatically be trigger on characters not being valid inside
+	 * an identifier (for example `.` in JavaScript) list them in `triggerCharacters`.
+	 */
+	triggerCharacters?: string[];
+
+	/**
+	 * The server provides support to resolve additional
+	 * information for a completion item.
+	 */
+	resolveProvider?: boolean;
+}
+```
+
+Completion items support snippets (see `InsertTextFormat.Snippet`). The snippet format is as follows:
+
+##### Snippet Syntax
+
+The `body` of a snippet can use special constructs to control cursors and the text being inserted. The following are supported features and their syntaxes:
+
+##### Tab stops
+
+With tab stops, you can make the editor cursor move inside a snippet. Use `$1`, `$2` to specify cursor locations. The number is the order in which tab stops will be visited, whereas `$0` denotes the final cursor position. Multiple tab stops are linked and updated in sync.
+
+##### Placeholders
+
+Placeholders are tab stops with values, like `${1:foo}`. The placeholder text will be inserted and selected such that it can be easily changed. Placeholders can be nested, like `${1:another ${2:placeholder}}`.
+
+##### Choice
+
+Placeholders can have choices as values. The syntax is a comma separated enumeration of values, enclosed with the pipe-character, for example `${1|one,two,three|}`. When the snippet is inserted and the placeholder selected, choices will prompt the user to pick one of the values.
+
+##### Variables
+
+With `$name` or `${name:default}` you can insert the value of a variable. When a variable isn’t set, its *default* or the empty string is inserted. When a variable is unknown (that is, its name isn’t defined) the name of the variable is inserted and it is transformed into a placeholder.
+
+The following variables can be used:
+
+* `TM_SELECTED_TEXT` The currently selected text or the empty string
+* `TM_CURRENT_LINE` The contents of the current line
+* `TM_CURRENT_WORD` The contents of the word under cursor or the empty string
+* `TM_LINE_INDEX` The zero-index based line number
+* `TM_LINE_NUMBER` The one-index based line number
+* `TM_FILENAME` The filename of the current document
+* `TM_FILENAME_BASE` The filename of the current document without its extensions
+* `TM_DIRECTORY` The directory of the current document
+* `TM_FILEPATH` The full file path of the current document
+
+##### Variable Transforms
+
+Transformations allow you to modify the value of a variable before it is inserted. The definition of a transformation consists of three parts:
+
+1. A regular expression that is matched against the value of a variable, or the empty string when the variable cannot be resolved.
+2. A "format string" that allows to reference matching groups from the regular expression. The format string allows for conditional inserts and simple modifications.
+3. Options that are passed to the regular expression.
+
+The following example inserts the name of the current file without its ending, so from `foo.txt` it makes `foo`.
+
+```
+${TM_FILENAME/(.*)\..+$/$1/}
+  |           |         | |
+  |           |         | |-> no options
+  |           |         |
+  |           |         |-> references the contents of the first
+  |           |             capture group
+  |           |
+  |           |-> regex to capture everything before
+  |               the final `.suffix`
+  |
+  |-> resolves to the filename
+```
+
+##### Grammar
+
+Below is the EBNF ([extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus-Naur_form)) for snippets. With `\` (backslash), you can escape `$`, `}` and `\`. Within choice elements, the backslash also escapes comma and pipe characters.
+
+```
+any         ::= tabstop | placeholder | choice | variable | text
+tabstop     ::= '$' int | '${' int '}'
+placeholder ::= '${' int ':' any '}'
+choice      ::= '${' int '|' text (',' text)* '|}'
+variable    ::= '$' var | '${' var }'
+                | '${' var ':' any '}'
+                | '${' var '/' regex '/' (format | text)+ '/' options '}'
+format      ::= '$' int | '${' int '}'
+                | '${' int ':' '/upcase' | '/downcase' | '/capitalize' '}'
+                | '${' int ':+' if '}'
+                | '${' int ':?' if ':' else '}'
+                | '${' int ':-' else '}' | '${' int ':' else '}'
+regex       ::= JavaScript Regular Expression value (ctor-string)
+options     ::= JavaScript Regular Expression option (ctor-options)
+var         ::= [_a-zA-Z] [_a-zA-Z0-9]*
+int         ::= [0-9]+
+text        ::= .*
+```
+
+#### <a href="#completionItem_resolve" name="completionItem_resolve" class="anchor">Completion Item Resolve Request (:leftwards_arrow_with_hook:)</a>
+
+The request is sent from the client to the server to resolve additional information for a given completion item.
+
+_Request_:
+* method: 'completionItem/resolve'
+* params: `CompletionItem`
+
+_Response_:
+* result: `CompletionItem`
+* error: code and message set in case an exception happens during the completion resolve request.
+
+#### <a href="#textDocument_hover" name="textDocument_hover" class="anchor">Hover Request (:leftwards_arrow_with_hook:)</a>
+
+The hover request is sent from the client to the server to request hover information at a given text document position.
+
+_Request_:
+* method: 'textDocument/hover'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: `Hover` \| `null` defined as follows:
+
+```typescript
+/**
+ * The result of a hover request.
+ */
+interface Hover {
+	/**
+	 * The hover's content
+	 */
+	contents: MarkedString | MarkedString[] | MarkupContent;
+
+	/**
+	 * An optional range is a range inside a text document
+	 * that is used to visualize a hover, e.g. by changing the background color.
+	 */
+	range?: Range;
+}
+```
+
+Where `MarkedString` is defined as follows:
+
+```typescript
+/**
+ * MarkedString can be used to render human readable text. It is either a markdown string
+ * or a code-block that provides a language and a code snippet. The language identifier
+ * is semantically equal to the optional language identifier in fenced code blocks in GitHub
+ * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ *
+ * The pair of a language and a value is an equivalent to markdown:
+ * ```${language}
+ * ${value}
+ * ```
+ *
+ * Note that markdown strings will be sanitized - that means html will be escaped.
+* @deprecated use MarkupContent instead.
+*/
+type MarkedString = string | { language: string; value: string };
+```
+
+* error: code and message set in case an exception happens during the hover request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_signatureHelp" name="textDocument_signatureHelp" class="anchor">Signature Help Request (:leftwards_arrow_with_hook:)</a>
+
+The signature help request is sent from the client to the server to request signature information at a given cursor position.
+
+_Request_:
+* method: 'textDocument/signatureHelp'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: `SignatureHelp` \| `null` defined as follows:
+
+```typescript
+/**
+ * Signature help represents the signature of something
+ * callable. There can be multiple signature but only one
+ * active and only one active parameter.
+ */
+interface SignatureHelp {
+	/**
+	 * One or more signatures.
+	 */
+	signatures: SignatureInformation[];
+
+	/**
+	 * The active signature. If omitted or the value lies outside the
+	 * range of `signatures` the value defaults to zero or is ignored if
+	 * `signatures.length === 0`. Whenever possible implementors should
+	 * make an active decision about the active signature and shouldn't
+	 * rely on a default value.
+	 * In future version of the protocol this property might become
+	 * mandatory to better express this.
+	 */
+	activeSignature?: number;
+
+	/**
+	 * The active parameter of the active signature. If omitted or the value
+	 * lies outside the range of `signatures[activeSignature].parameters`
+	 * defaults to 0 if the active signature has parameters. If
+	 * the active signature has no parameters it is ignored.
+	 * In future version of the protocol this property might become
+	 * mandatory to better express the active parameter if the
+	 * active signature does have any.
+	 */
+	activeParameter?: number;
+}
+
+/**
+ * Represents the signature of something callable. A signature
+ * can have a label, like a function-name, a doc-comment, and
+ * a set of parameters.
+ */
+interface SignatureInformation {
+	/**
+	 * The label of this signature. Will be shown in
+	 * the UI.
+	 */
+	label: string;
+
+	/**
+	 * The human-readable doc-comment of this signature. Will be shown
+	 * in the UI but can be omitted.
+	 */
+	documentation?: string | MarkupContent;
+
+	/**
+	 * The parameters of this signature.
+	 */
+	parameters?: ParameterInformation[];
+}
+
+/**
+ * Represents a parameter of a callable-signature. A parameter can
+ * have a label and a doc-comment.
+ */
+interface ParameterInformation {
+
+	/**
+	 * The label of this parameter information.
+	 *
+	 * Either a string or an inclusive start and exclusive end offsets within its containing
+	 * signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
+	 * string representation as `Position` and `Range` does.
+	 *
+	 * *Note*: a label of type string should be a substring of its containing signature label.
+	 * Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
+	 */
+	label: string | [number, number];
+
+	/**
+	 * The human-readable doc-comment of this parameter. Will be shown
+	 * in the UI but can be omitted.
+	 */
+	documentation?: string | MarkupContent;
+}
+```
+
+* error: code and message set in case an exception happens during the signature help request.
+
+_Registration Options_: `SignatureHelpRegistrationOptions` defined as follows:
+
+```typescript
+export interface SignatureHelpRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * The characters that trigger signature help
+	 * automatically.
+	 */
+	triggerCharacters?: string[];
+}
+```
+#### <a href="#textDocument_declaration" name="textDocument_declaration" class="anchor">Goto Declaration Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.14.0*
+
+The go to declaration request is sent from the client to the server to resolve the declaration location of a symbol at a given text document position.
+
+The result type [`LocationLink`](#locationlink)[] got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.textDocument.declaration.linkSupport`.
+
+_Request_:
+* method: 'textDocument/declaration'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationlink)[] \|`null`
+* error: code and message set in case an exception happens during the declaration request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_definition" name="textDocument_definition" class="anchor">Goto Definition Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.14.0*
+
+The go to definition request is sent from the client to the server to resolve the definition location of a symbol at a given text document position.
+`
+The result type [`LocationLink`](#locationlink)[] got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.textDocument.definition.linkSupport`.
+
+_Request_:
+* method: 'textDocument/definition'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationlink)[] \| `null`
+* error: code and message set in case an exception happens during the definition request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_typeDefinition" name="textDocument_typeDefinition" class="anchor">Goto Type Definition Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.6.0*
+
+The go to type definition request is sent from the client to the server to resolve the type definition location of a symbol at a given text document position.
+
+The result type [`LocationLink`](#locationlink)[] got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.textDocument.typeDefinition.linkSupport`.
+
+_Request_:
+* method: 'textDocument/typeDefinition'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationlink)[] \| `null`
+* error: code and message set in case an exception happens during the definition request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_implementation" name="textDocument_implementation" class="anchor">Goto Implementation Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.6.0*
+
+The go to implementation request is sent from the client to the server to resolve the implementation location of a symbol at a given text document position.
+
+The result type [`LocationLink`](#locationlink)[] got introduce with version 3.14.0 and depends in the corresponding client capability `clientCapabilities.implementation.typeDefinition.linkSupport`.
+
+_Request_:
+* method: 'textDocument/implementation'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: [`Location`](#location) \| [`Location`](#location)[] \| [`LocationLink`](#locationlink)[] \| `null`
+* error: code and message set in case an exception happens during the definition request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_references" name="textDocument_references" class="anchor">Find References Request (:leftwards_arrow_with_hook:)</a>
+
+The references request is sent from the client to the server to resolve project-wide references for the symbol denoted by the given text document position.
+
+_Request_:
+* method: 'textDocument/references'
+* params: `ReferenceParams` defined as follows:
+
+```typescript
+interface ReferenceParams extends TextDocumentPositionParams {
+	context: ReferenceContext
+}
+
+interface ReferenceContext {
+	/**
+	 * Include the declaration of the current symbol.
+	 */
+	includeDeclaration: boolean;
+}
+```
+_Response_:
+* result: [`Location`](#location)[] \| `null`
+* error: code and message set in case an exception happens during the reference request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_documentHighlight" name="textDocument_documentHighlight" class="anchor">Document Highlights Request (:leftwards_arrow_with_hook:)</a>
+
+The document highlight request is sent from the client to the server to resolve a document highlights for a given text document position.
+For programming languages this usually highlights all references to the symbol scoped to this file. However we kept 'textDocument/documentHighlight'
+and 'textDocument/references' separate requests since the first one is allowed to be more fuzzy. Symbol matches usually have a `DocumentHighlightKind`
+of `Read` or `Write` whereas fuzzy or textual matches use `Text`as the kind.
+
+_Request_:
+* method: 'textDocument/documentHighlight'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: `DocumentHighlight[]` \| `null` defined as follows:
+
+```typescript
+/**
+ * A document highlight is a range inside a text document which deserves
+ * special attention. Usually a document highlight is visualized by changing
+ * the background color of its range.
+ *
+ */
+interface DocumentHighlight {
+	/**
+	 * The range this highlight applies to.
+	 */
+	range: Range;
+
+	/**
+	 * The highlight kind, default is DocumentHighlightKind.Text.
+	 */
+	kind?: number;
+}
+
+/**
+ * A document highlight kind.
+ */
+export namespace DocumentHighlightKind {
+	/**
+	 * A textual occurrence.
+	 */
+	export const Text = 1;
+
+	/**
+	 * Read-access of a symbol, like reading a variable.
+	 */
+	export const Read = 2;
+
+	/**
+	 * Write-access of a symbol, like writing to a variable.
+	 */
+	export const Write = 3;
+}
+```
+
+* error: code and message set in case an exception happens during the document highlight request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_documentSymbol" name="textDocument_documentSymbol" class="anchor">Document Symbols Request (:leftwards_arrow_with_hook:)</a>
+
+The document symbol request is sent from the client to the server to return a flat list of all symbols found in a given text document. Neither the symbol's location range nor the symbol's container name should be used to infer a hierarchy.
+
+_Request_:
+* method: 'textDocument/documentSymbol'
+* params: `DocumentSymbolParams` defined as follows:
+
+```typescript
+interface DocumentSymbolParams {
+	/**
+	 * The text document.
+	 */
+	textDocument: TextDocumentIdentifier;
+}
+```
+
+_Response_:
+* result: `DocumentSymbol[]` \| `SymbolInformation[]` \| `null` defined as follows:
+
+```typescript
+/**
+ * A symbol kind.
+ */
+export namespace SymbolKind {
+	export const File = 1;
+	export const Module = 2;
+	export const Namespace = 3;
+	export const Package = 4;
+	export const Class = 5;
+	export const Method = 6;
+	export const Property = 7;
+	export const Field = 8;
+	export const Constructor = 9;
+	export const Enum = 10;
+	export const Interface = 11;
+	export const Function = 12;
+	export const Variable = 13;
+	export const Constant = 14;
+	export const String = 15;
+	export const Number = 16;
+	export const Boolean = 17;
+	export const Array = 18;
+	export const Object = 19;
+	export const Key = 20;
+	export const Null = 21;
+	export const EnumMember = 22;
+	export const Struct = 23;
+	export const Event = 24;
+	export const Operator = 25;
+	export const TypeParameter = 26;
+}
+
+/**
+ * Represents programming constructs like variables, classes, interfaces etc. that appear in a document. Document symbols can be
+ * hierarchical and they have two ranges: one that encloses its definition and one that points to its most interesting range,
+ * e.g. the range of an identifier.
+ */
+export class DocumentSymbol {
+
+	/**
+	 * The name of this symbol. Will be displayed in the user interface and therefore must not be
+	 * an empty string or a string only consisting of white spaces.
+	 */
+	name: string;
+
+	/**
+	 * More detail for this symbol, e.g the signature of a function.
+	 */
+	detail?: string;
+
+	/**
+	 * The kind of this symbol.
+	 */
+	kind: SymbolKind;
+
+	/**
+	 * Indicates if this symbol is deprecated.
+	 */
+	deprecated?: boolean;
+
+	/**
+	 * The range enclosing this symbol not including leading/trailing whitespace but everything else
+	 * like comments. This information is typically used to determine if the clients cursor is
+	 * inside the symbol to reveal in the symbol in the UI.
+	 */
+	range: Range;
+
+	/**
+	 * The range that should be selected and revealed when this symbol is being picked, e.g the name of a function.
+	 * Must be contained by the `range`.
+	 */
+	selectionRange: Range;
+
+	/**
+	 * Children of this symbol, e.g. properties of a class.
+	 */
+	children?: DocumentSymbol[];
+}
+
+/**
+ * Represents information about programming constructs like variables, classes,
+ * interfaces etc.
+ */
+interface SymbolInformation {
+	/**
+	 * The name of this symbol.
+	 */
+	name: string;
+
+	/**
+	 * The kind of this symbol.
+	 */
+	kind: number;
+
+	/**
+	 * Indicates if this symbol is deprecated.
+	 */
+	deprecated?: boolean;
+
+	/**
+	 * The location of this symbol. The location's range is used by a tool
+	 * to reveal the location in the editor. If the symbol is selected in the
+	 * tool the range's start information is used to position the cursor. So
+	 * the range usually spans more then the actual symbol's name and does
+	 * normally include things like visibility modifiers.
+	 *
+	 * The range doesn't have to denote a node range in the sense of a abstract
+	 * syntax tree. It can therefore not be used to re-construct a hierarchy of
+	 * the symbols.
+	 */
+	location: Location;
+
+	/**
+	 * The name of the symbol containing this symbol. This information is for
+	 * user interface purposes (e.g. to render a qualifier in the user interface
+	 * if necessary). It can't be used to re-infer a hierarchy for the document
+	 * symbols.
+	 */
+	containerName?: string;
+}
+
+```
+
+* error: code and message set in case an exception happens during the document symbol request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_codeAction" name="textDocument_codeAction" class="anchor">Code Action Request (:leftwards_arrow_with_hook:)</a>
+
+The code action request is sent from the client to the server to compute commands for a given text document and range. These commands are typically code fixes to either fix problems or to beautify/refactor code. The result of a `textDocument/codeAction` request is an array of `Command` literals which are typically presented in the user interface. To ensure that a server is useful in many clients the commands specified in a code actions should be handled by the server and not by the client (see `workspace/executeCommand` and `ServerCapabilities.executeCommandProvider`). If the client supports providing edits with a code action then the mode should be used.
+
+When the command is selected the server should be contacted again (via the `workspace/executeCommand`) request to execute the command.
+
+> *Since version 3.8.0:* support for CodeAction literals to enable the following scenarios:
+
+- the ability to directly return a workspace edit from the code action request. This avoids having another server roundtrip to execute an actual code action. However server providers should be aware that if the code action is expensive to compute or the edits are huge it might still be beneficial if the result is simply a command and the actual edit is only computed when needed.
+- the ability to group code actions using a kind. Clients are allowed to ignore that information. However it allows them to better group code action for example into corresponding menus (e.g. all refactor code actions into a refactor menu).
+
+Clients need to announce their support for code action literals and code action kinds via the corresponding client capability `textDocument.codeAction.codeActionLiteralSupport`.
+
+_Request_:
+* method: 'textDocument/codeAction'
+* params: `CodeActionParams` defined as follows:
+
+```typescript
+/**
+ * Params for the CodeActionRequest
+ */
+interface CodeActionParams {
+	/**
+	 * The document in which the command was invoked.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The range for which the command was invoked.
+	 */
+	range: Range;
+
+	/**
+	 * Context carrying additional information.
+	 */
+	context: CodeActionContext;
+}
+
+/**
+ * The kind of a code action.
+ *
+ * Kinds are a hierarchical list of identifiers separated by `.`, e.g. `"refactor.extract.function"`.
+ *
+ * The set of kinds is open and client needs to announce the kinds it supports to the server during
+ * initialization.
+ */
+export type CodeActionKind = string;
+
+/**
+ * A set of predefined code action kinds
+ */
+export namespace CodeActionKind {
+	/**
+	 * Base kind for quickfix actions: 'quickfix'
+	 */
+	export const QuickFix: CodeActionKind = 'quickfix';
+
+	/**
+	 * Base kind for refactoring actions: 'refactor'
+	 */
+	export const Refactor: CodeActionKind = 'refactor';
+
+	/**
+	 * Base kind for refactoring extraction actions: 'refactor.extract'
+	 *
+	 * Example extract actions:
+	 *
+	 * - Extract method
+	 * - Extract function
+	 * - Extract variable
+	 * - Extract interface from class
+	 * - ...
+	 */
+	export const RefactorExtract: CodeActionKind = 'refactor.extract';
+
+	/**
+	 * Base kind for refactoring inline actions: 'refactor.inline'
+	 *
+	 * Example inline actions:
+	 *
+	 * - Inline function
+	 * - Inline variable
+	 * - Inline constant
+	 * - ...
+	 */
+	export const RefactorInline: CodeActionKind = 'refactor.inline';
+
+	/**
+	 * Base kind for refactoring rewrite actions: 'refactor.rewrite'
+	 *
+	 * Example rewrite actions:
+	 *
+	 * - Convert JavaScript function to class
+	 * - Add or remove parameter
+	 * - Encapsulate field
+	 * - Make method static
+	 * - Move method to base class
+	 * - ...
+	 */
+	export const RefactorRewrite: CodeActionKind = 'refactor.rewrite';
+
+	/**
+	 * Base kind for source actions: `source`
+	 *
+	 * Source code actions apply to the entire file.
+	 */
+	export const Source: CodeActionKind = 'source';
+
+	/**
+	 * Base kind for an organize imports source action: `source.organizeImports`
+	 */
+	export const SourceOrganizeImports: CodeActionKind = 'source.organizeImports';
+}
+
+/**
+ * Contains additional diagnostic information about the context in which
+ * a code action is run.
+ */
+interface CodeActionContext {
+	/**
+	 * An array of diagnostics.
+	 */
+	diagnostics: Diagnostic[];
+
+	/**
+	 * Requested kind of actions to return.
+	 *
+	 * Actions not of this kind are filtered out by the client before being shown. So servers
+	 * can omit computing them.
+	 */
+	only?: CodeActionKind[];
+}
+```
+
+_Response_:
+* result: `(Command | CodeAction)[]` \| `null` where `CodeAction` is defined as follows:
+
+```typescript
+/**
+ * A code action represents a change that can be performed in code, e.g. to fix a problem or
+ * to refactor code.
+ *
+ * A CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed.
+ */
+export interface CodeAction {
+
+	/**
+	 * A short, human-readable, title for this code action.
+	 */
+	title: string;
+
+	/**
+	 * The kind of the code action.
+	 *
+	 * Used to filter code actions.
+	 */
+	kind?: CodeActionKind;
+
+	/**
+	 * The diagnostics that this code action resolves.
+	 */
+	diagnostics?: Diagnostic[];
+
+	/**
+	 * The workspace edit this code action performs.
+	 */
+	edit?: WorkspaceEdit;
+
+	/**
+	 * A command this code action executes. If a code action
+	 * provides an edit and a command, first the edit is
+	 * executed and then the command.
+	 */
+	command?: Command;
+}
+```
+
+* error: code and message set in case an exception happens during the code action request.
+
+_Registration Options_: `CodeActionRegistrationOptions`  defined as follows:
+
+```typescript
+export interface CodeActionRegistrationOptions extends TextDocumentRegistrationOptions, CodeActionOptions {
+}
+```
+
+
+#### <a href="#textDocument_codeLens" name="textDocument_codeLens" class="anchor">Code Lens Request (:leftwards_arrow_with_hook:)</a>
+
+The code lens request is sent from the client to the server to compute code lenses for a given text document.
+
+_Request_:
+* method: 'textDocument/codeLens'
+* params: `CodeLensParams` defined as follows:
+
+```typescript
+interface CodeLensParams {
+	/**
+	 * The document to request code lens for.
+	 */
+	textDocument: TextDocumentIdentifier;
+}
+```
+
+_Response_:
+* result: `CodeLens[]` \| `null` defined as follows:
+
+```typescript
+/**
+ * A code lens represents a command that should be shown along with
+ * source text, like the number of references, a way to run tests, etc.
+ *
+ * A code lens is _unresolved_ when no command is associated to it. For performance
+ * reasons the creation of a code lens and resolving should be done in two stages.
+ */
+interface CodeLens {
+	/**
+	 * The range in which this code lens is valid. Should only span a single line.
+	 */
+	range: Range;
+
+	/**
+	 * The command this code lens represents.
+	 */
+	command?: Command;
+
+	/**
+	 * A data entry field that is preserved on a code lens item between
+	 * a code lens and a code lens resolve request.
+	 */
+	data?: any
+}
+```
+* error: code and message set in case an exception happens during the code lens request.
+
+_Registration Options_: `CodeLensRegistrationOptions` defined as follows:
+
+```typescript
+export interface CodeLensRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * Code lens has a resolve provider as well.
+	 */
+	resolveProvider?: boolean;
+}
+```
+
+#### <a href="#codeLens_resolve" name="codeLens_resolve" class="anchor">Code Lens Resolve Request (:leftwards_arrow_with_hook:)</a>
+
+The code lens resolve request is sent from the client to the server to resolve the command for a given code lens item.
+
+_Request_:
+* method: 'codeLens/resolve'
+* params: `CodeLens`
+
+_Response_:
+* result: `CodeLens`
+* error: code and message set in case an exception happens during the code lens resolve request.
+
+#### <a href="#textDocument_documentLink" name="textDocument_documentLink" class="anchor">Document Link Request (:leftwards_arrow_with_hook:)</a>
+
+The document links request is sent from the client to the server to request the location of links in a document.
+
+_Request_:
+* method: 'textDocument/documentLink'
+* params: `DocumentLinkParams`, defined as follows:
+
+```typescript
+interface DocumentLinkParams {
+	/**
+	 * The document to provide document links for.
+	 */
+	textDocument: TextDocumentIdentifier;
+}
+```
+
+_Response_:
+* result: An array of `DocumentLink` \| `null`.
+
+```typescript
+/**
+ * A document link is a range in a text document that links to an internal or external resource, like another
+ * text document or a web site.
+ */
+interface DocumentLink {
+	/**
+	 * The range this link applies to.
+	 */
+	range: Range;
+	/**
+	 * The uri this link points to. If missing a resolve request is sent later.
+	 */
+	target?: DocumentUri;
+	/**
+	 * A data entry field that is preserved on a document link between a
+	 * DocumentLinkRequest and a DocumentLinkResolveRequest.
+	 */
+	data?: any;
+}
+```
+* error: code and message set in case an exception happens during the document link request.
+
+_Registration Options_: `DocumentLinkRegistrationOptions` defined as follows:
+
+```typescript
+export interface DocumentLinkRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * Document links have a resolve provider as well.
+	 */
+	resolveProvider?: boolean;
+}
+```
+
+#### <a href="#documentLink_resolve" name="documentLink_resolve" class="anchor">Document Link Resolve Request (:leftwards_arrow_with_hook:)</a>
+
+The document link resolve request is sent from the client to the server to resolve the target of a given document link.
+
+_Request_:
+* method: 'documentLink/resolve'
+* params: `DocumentLink`
+
+_Response_:
+* result: `DocumentLink`
+* error: code and message set in case an exception happens during the document link resolve request.
+
+#### <a href="#textDocument_documentColor" name="textDocument_documentColor" class="anchor">Document Color Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.6.0*
+
+The document color request is sent from the client to the server to list all color references found in a given text document. Along with the range, a color value in RGB is returned.
+
+Clients can use the result to decorate color references in an editor. For example:
+- Color boxes showing the actual color next to the reference
+- Show a color picker when a color reference is edited
+
+_Request_:
+
+* method: 'textDocument/documentColor'
+* params: `DocumentColorParams` defined as follows
+
+```ts
+interface DocumentColorParams {
+	/**
+	 * The text document.
+	 */
+	textDocument: TextDocumentIdentifier;
+}
+```
+
+_Response_:
+* result: `ColorInformation[]` defined as follows:
+
+```typescript
+interface ColorInformation {
+	/**
+	 * The range in the document where this color appears.
+	 */
+	range: Range;
+
+	/**
+	 * The actual color value for this color range.
+	 */
+	color: Color;
+}
+
+/**
+ * Represents a color in RGBA space.
+ */
+interface Color {
+
+	/**
+	 * The red component of this color in the range [0-1].
+	 */
+	readonly red: number;
+
+	/**
+	 * The green component of this color in the range [0-1].
+	 */
+	readonly green: number;
+
+	/**
+	 * The blue component of this color in the range [0-1].
+	 */
+	readonly blue: number;
+
+	/**
+	 * The alpha component of this color in the range [0-1].
+	 */
+	readonly alpha: number;
+}
+```
+* error: code and message set in case an exception happens during the 'textDocument/documentColor' request
+
+#### <a href="#textDocument_colorPresentation" name="textDocument_colorPresentation" class="anchor">Color Presentation Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.6.0*
+
+The color presentation request is sent from the client to the server to obtain a list of presentations for a color value at a given location. Clients can use the result to
+- modify a color reference.
+- show in a color picker and let users pick one of the presentations
+
+
+_Request_:
+
+* method: 'textDocument/colorPresentation'
+* params: `ColorPresentationParams` defined as follows
+
+```typescript
+interface ColorPresentationParams {
+	/**
+	 * The text document.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The color information to request presentations for.
+	 */
+	color: Color;
+
+	/**
+	 * The range where the color would be inserted. Serves as a context.
+	 */
+	range: Range;
+}
+```
+
+_Response_:
+* result: `ColorPresentation[]` defined as follows:
+
+```typescript
+interface ColorPresentation {
+	/**
+	 * The label of this color presentation. It will be shown on the color
+	 * picker header. By default this is also the text that is inserted when selecting
+	 * this color presentation.
+	 */
+	label: string;
+	/**
+	 * An [edit](#TextEdit) which is applied to a document when selecting
+	 * this presentation for the color.  When `falsy` the [label](#ColorPresentation.label)
+	 * is used.
+	 */
+	textEdit?: TextEdit;
+	/**
+	 * An optional array of additional [text edits](#TextEdit) that are applied when
+	 * selecting this color presentation. Edits must not overlap with the main [edit](#ColorPresentation.textEdit) nor with themselves.
+	 */
+	additionalTextEdits?: TextEdit[];
+}
+```
+
+* error: code and message set in case an exception happens during the 'textDocument/colorPresentation' request
+
+#### <a href="#textDocument_formatting" name="textDocument_formatting" class="anchor">Document Formatting Request  (:leftwards_arrow_with_hook:)</a>
+
+The document formatting request is sent from the client to the server to format a whole document.
+
+_Request_:
+* method: 'textDocument/formatting'
+* params: `DocumentFormattingParams` defined as follows
+
+```typescript
+interface DocumentFormattingParams {
+	/**
+	 * The document to format.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The format options.
+	 */
+	options: FormattingOptions;
+}
+
+/**
+ * Value-object describing what options formatting should use.
+ */
+interface FormattingOptions {
+	/**
+	 * Size of a tab in spaces.
+	 */
+	tabSize: number;
+
+	/**
+	 * Prefer spaces over tabs.
+	 */
+	insertSpaces: boolean;
+
+	/**
+	 * Signature for further properties.
+	 */
+	[key: string]: boolean | number | string;
+}
+```
+
+_Response_:
+* result: [`TextEdit[]`](#textedit) \| `null` describing the modification to the document to be formatted.
+* error: code and message set in case an exception happens during the formatting request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_rangeFormatting" name="textDocument_rangeFormatting" class="anchor">Document Range Formatting Request (:leftwards_arrow_with_hook:)</a>
+
+The document range formatting request is sent from the client to the server to format a given range in a document.
+
+_Request_:
+* method: 'textDocument/rangeFormatting',
+* params: `DocumentRangeFormattingParams` defined as follows:
+
+```typescript
+interface DocumentRangeFormattingParams {
+	/**
+	 * The document to format.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The range to format
+	 */
+	range: Range;
+
+	/**
+	 * The format options
+	 */
+	options: FormattingOptions;
+}
+```
+
+_Response_:
+* result: [`TextEdit[]`](#textedit) \| `null` describing the modification to the document to be formatted.
+* error: code and message set in case an exception happens during the range formatting request.
+
+_Registration Options_: `TextDocumentRegistrationOptions`
+
+#### <a href="#textDocument_onTypeFormatting" name="textDocument_onTypeFormatting" class="anchor">Document on Type Formatting Request (:leftwards_arrow_with_hook:)</a>
+
+The document on type formatting request is sent from the client to the server to format parts of the document during typing.
+
+_Request_:
+* method: 'textDocument/onTypeFormatting'
+* params: `DocumentOnTypeFormattingParams` defined as follows:
+
+```typescript
+interface DocumentOnTypeFormattingParams {
+	/**
+	 * The document to format.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The position at which this request was sent.
+	 */
+	position: Position;
+
+	/**
+	 * The character that has been typed.
+	 */
+	ch: string;
+
+	/**
+	 * The format options.
+	 */
+	options: FormattingOptions;
+}
+```
+
+_Response_:
+* result: [`TextEdit[]`](#textedit) \| `null` describing the modification to the document.
+* error: code and message set in case an exception happens during the range formatting request.
+
+_Registration Options_: `DocumentOnTypeFormattingRegistrationOptions` defined as follows:
+
+```typescript
+export interface DocumentOnTypeFormattingRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * A character on which formatting should be triggered, like `}`.
+	 */
+	firstTriggerCharacter: string;
+	/**
+	 * More trigger characters.
+	 */
+	moreTriggerCharacter?: string[]
+}
+```
+#### <a href="#textDocument_rename" name="textDocument_rename" class="anchor">Rename Request (:leftwards_arrow_with_hook:)</a>
+
+The rename request is sent from the client to the server to perform a workspace-wide rename of a symbol.
+
+_Request_:
+* method: 'textDocument/rename'
+* params: `RenameParams` defined as follows
+
+```typescript
+interface RenameParams {
+	/**
+	 * The document to rename.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The position at which this request was sent.
+	 */
+	position: Position;
+
+	/**
+	 * The new name of the symbol. If the given name is not valid the
+	 * request must return a [ResponseError](#ResponseError) with an
+	 * appropriate message set.
+	 */
+	newName: string;
+}
+```
+
+_Response_:
+* result: [`WorkspaceEdit`](#workspaceedit) \| `null` describing the modification to the workspace.
+* error: code and message set in case an exception happens during the rename request.
+
+_Registration Options_: `RenameRegistrationOptions` defined as follows:
+
+```typescript
+export interface RenameRegistrationOptions extends TextDocumentRegistrationOptions {
+	/**
+	 * Renames should be checked and tested for validity before being executed.
+	 */
+	prepareProvider?: boolean;
+}
+```
+
+#### <a href="#textDocument_prepareRename" name="textDocument_prepareRename" class="anchor">Prepare Rename Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.12.0*
+
+The prepare rename request is sent from the client to the server to setup and test the validity of a rename operation at a given location.
+
+_Request_:
+* method: 'textDocument/prepareRename'
+* params: [`TextDocumentPositionParams`](#textdocumentpositionparams)
+
+_Response_:
+* result: [`Range`](#range) \| `{ range: Range, placeholder: string }` \| `null` describing the range of the string to rename and optionally a placeholder text of the string content to be renamed. If `null` is returned then it is deemed that a 'textDocument/rename' request is not valid at the given position.
+* error: code and message set in case an exception happens during the prepare rename request.
+
+#### <a href="#textDocument_foldingRange" name="textDocument_foldingRange" class="anchor">Folding Range Request (:leftwards_arrow_with_hook:)</a>
+
+> *Since version 3.10.0*
+
+The folding range request is sent from the client to the server to return all folding ranges found in a given text document.
+
+_Request_:
+
+* method: 'textDocument/foldingRange'
+* params: `FoldingRangeParams` defined as follows
+
+```typescript
+export interface FoldingRangeParams {
+	/**
+	 * The text document.
+	 */
+	textDocument: TextDocumentIdentifier;
+}
+
+```
+
+_Response_:
+* result: `FoldingRange[] | null` defined as follows:
+
+```typescript
+/**
+ * Enum of known range kinds
+ */
+export enum FoldingRangeKind {
+	/**
+	 * Folding range for a comment
+	 */
+	Comment = 'comment',
+	/**
+	 * Folding range for a imports or includes
+	 */
+	Imports = 'imports',
+	/**
+	 * Folding range for a region (e.g. `#region`)
+	 */
+	Region = 'region'
+}
+
+/**
+ * Represents a folding range.
+ */
+export interface FoldingRange {
+
+	/**
+	 * The zero-based line number from where the folded range starts.
+	 */
+	startLine: number;
+
+	/**
+	 * The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line.
+	 */
+	startCharacter?: number;
+
+	/**
+	 * The zero-based line number where the folded range ends.
+	 */
+	endLine: number;
+
+	/**
+	 * The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line.
+	 */
+	endCharacter?: number;
+
+	/**
+	 * Describes the kind of the folding range such as `comment' or 'region'. The kind
+	 * is used to categorize folding ranges and used by commands like 'Fold all comments'. See
+	 * [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds.
+	 */
+	kind?: string;
+}
+```
+
+* error: code and message set in case an exception happens during the 'textDocument/foldingRange' request
+
+### Implementation considerations
+
+Language servers usually run in a separate process and client communicate with them in an asynchronous fashion. Additionally clients usually allow users to interact with the source code even if request results are pending. We recommend the following implementation pattern to avoid that clients apply outdated response results:
+
+- if a client sends a request to the server and the client state changes in a way that the result will be invalid it should cancel the server request and ignore the result. If necessary it can resend the request to receive an up to date result.
+- if a server detects a state change that invalidates the result of a request in execution the server can error these requests with `ContentModified`. If clients receive a `ContentModified` error, it generally should not show it in the UI for the end-user. Clients can resend the request if appropriate.
+- if servers end up in an inconsistent state they should log this to the client using the `window/logMessage` request. If they can't recover from this the best they can do right now is to exit themselves. We are considering an [extension to the protocol](https://github.com/Microsoft/language-server-protocol/issues/646) that allows servers to request a restart on the client side.
+- if a client notices that a server exists unexpectedly it should try to restart the server. However clients should be careful to not restart a crashing server endlessly. VS Code for example doesn't restart a server if it crashes 5 times in the last 180 seconds.
+
+### <a href="#changeLog" name="changeLog" class="anchor">Change Log</a>
+
+#### <a href="#version_3_14_0" name="version_3_14_0" class="anchor">3.14.0 (12/13/2018)</a>
+
+* Add support for signature label offsets.
+* Add support for location links.
+* Add support for `textDocument/declaration` request.
+
+#### <a href="#version_3_13_0" name="version_3_13_0" class="anchor">3.13.0 (9/11/2018)</a>
+
+* Add support for file and folder operations (create, rename, move) to workspace edits.
+
+#### <a href="#version_3_12_0" name="version_3_12_0" class="anchor">3.12.0 (8/23/2018)</a>
+
+* Add support for `textDocument/prepareRename` request.
+
+#### <a href="#version_3_11_0" name="version_3_11_0" class="anchor">3.11.0 (8/21/2018)</a>
+
+* Add support for CodeActionOptions to allow a server to provide a list of code action it supports.
+
+#### <a href="#version_3_10_0" name="version_3_10_0" class="anchor">3.10.0 (7/23/2018)</a>
+
+* Add support for hierarchical document symbols as a valid response to a `textDocument/documentSymbol` request.
+* Add support for folding ranges as a valid response to a `textDocument/foldingRange` request.
+
+#### <a href="#version_3_9_0" name="version_3_9_0" class="anchor">3.9.0 (7/10/2018)</a>
+
+* Add support for `preselect` property in `CompletionItem`
+
+#### <a href="#version_3_8_0" name="version_3_8_0" class="anchor">3.8.0 (6/11/2018)</a>
+
+* Added support for CodeAction literals to the `textDocument/codeAction` request.
+* ColorServerCapabilities.colorProvider can also be a boolean
+* Corrected ColorPresentationParams.colorInfo to color (as in the `d.ts` and in implementations)
+
+#### <a href="#version_3_7_0" name="version_3_7_0" class="anchor">3.7.0 (4/5/2018)</a>
+
+* Added support for related information to Diagnostics.
+
+#### <a href="#version_3_6_0" name="version_3_6_0" class="anchor">3.6.0 (2/22/2018)</a>
+
+Merge the proposed protocol for workspace folders, configuration, go to type definition, go to implementation and document color provider into the main branch of the specification. For details see:
+
+* [Get Workspace Folders](https://microsoft.github.io/language-server-protocol/specification#workspace_workspaceFolders)
+* [DidChangeWorkspaceFolders Notification](https://microsoft.github.io/language-server-protocol/specification#workspace_didChangeWorkspaceFolders)
+* [Get Configuration](https://microsoft.github.io/language-server-protocol/specification#workspace_configuration)
+* [Go to Type Definition](https://microsoft.github.io/language-server-protocol/specification#textDocument_typeDefinition)
+* [Go to Implementation](https://microsoft.github.io/language-server-protocol/specification#textDocument_implementation)
+* [Document Color](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentColor)
+* [Color Presentation](https://microsoft.github.io/language-server-protocol/specification#textDocument_colorPresentation)
+
+In addition we enhanced the `CompletionTriggerKind` with a new value `TriggerForIncompleteCompletions: 3 = 3` to signal the a completion request got trigger since the last result was incomplete.
+
+#### <a href="#version_3_5_0" name="version_3_5_0" class="anchor">3.5.0</a>
+
+Decided to skip this version to bring the protocol version number in sync the with npm module vscode-languageserver-protocol.
+
+#### <a href="#version_3_4_0" name="version_3_4_0" class="anchor">3.4.0 (11/27/2017)</a>
+
+* [extensible completion item and symbol kinds](https://github.com/Microsoft/language-server-protocol/issues/129)
+
+#### <a href="version_3_3_0" name="version_3_3_0" class="anchor">3.3.0 (11/24/2017)</a>
+
+* Added support for `CompletionContext`
+* Added support for `MarkupContent`
+* Removed old New and Updated markers.
+
+#### <a href="version_3_2_0" name="version_3_2_0" class="anchor">3.2.0 (09/26/2017)</a>
+
+* Added optional `commitCharacters` property to the `CompletionItem`
+
+#### <a href="version_3_1_0" name="version_3_1_0" class="anchor">3.1.0 (02/28/2017)</a>
+
+* Make the `WorkspaceEdit` changes backwards compatible.
+* Updated the specification to correctly describe the breaking changes from 2.x to 3.x around `WorkspaceEdit`and `TextDocumentEdit`.
+
+#### <a href="#version_3_0_0" name="version_3_0_0" class="anchor">3.0 Version</a>
+
+- add support for client feature flags to support that servers can adapt to different client capabilities. An example is the new `textDocument/willSaveWaitUntil` request which not all clients might be able to support. If the feature is disabled in the client capabilities sent on the initialize request, the server can't rely on receiving the request.
+- add support to experiment with new features. The new `ClientCapabilities.experimental` section together with feature flags allow servers to provide experimental feature without the need of ALL clients to adopt them immediately.
+- servers can more dynamically react to client features. Capabilities can now be registered and unregistered after the initialize request using the new `client/registerCapability` and `client/unregisterCapability`. This for example allows servers to react to settings or configuration changes without a restart.
+- add support for `textDocument/willSave` notification and `textDocument/willSaveWaitUntil` request.
+- add support for `textDocument/documentLink` request.
+- add a `rootUri` property to the initializeParams in favor of the `rootPath` property.
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart
index 6ff12a9..afa5b76 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript.dart
@@ -64,6 +64,11 @@
     },
     "ResponseError": {
       "code": "ErrorCodes",
+      // This is dynamic normally, but since this class can be serialised
+      // we will crash if it data is set to something that can't be converted to
+      // JSON (for ex. Uri) so this forces anyone setting this to convert to a
+      // String.
+      "data": "String",
     },
     "NotificationMessage": {
       "method": "Method",
@@ -89,6 +94,21 @@
   return interface != null ? interface[fieldName] : null;
 }
 
+/// Improves comments in generated code to support where types may have been
+/// altered (for ex. with [getImprovedType] above).
+String getImprovedComment(String interfaceName, String fieldName) {
+  const Map<String, Map<String, String>> _improvedComments = {
+    "ResponseError": {
+      "data":
+          "// A string that contains additional information about the error. Can be omitted.",
+    },
+  };
+
+  final interface = _improvedComments[interfaceName];
+
+  return interface != null ? interface[fieldName] : null;
+}
+
 List<String> getSpecialBaseTypes(Interface interface) {
   if (interface.name == 'RequestMessage' ||
       interface.name == 'NotificationMessage') {
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
index bd303e1..2412309 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
@@ -306,6 +306,12 @@
     type = _type(containerName, name.lexeme,
         includeUndefined: canBeUndefined, improveTypes: true);
 
+    // Overwrite comment if we have an improved one.
+    final improvedComment = getImprovedComment(containerName, name.lexeme);
+    leadingComment = improvedComment != null
+        ? new Comment(new Token(TokenType.COMMENT, improvedComment))
+        : leadingComment;
+
     // Some fields have weird comments like this in the spec:
     //     {@link MessageType}
     // These seem to be the correct type of the field, while the field is
diff --git a/pkg/analysis_server/tool/spec/check_all_test.dart b/pkg/analysis_server/tool/spec/check_all_test.dart
index 3aefa25..1388652 100644
--- a/pkg/analysis_server/tool/spec/check_all_test.dart
+++ b/pkg/analysis_server/tool/spec/check_all_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate_all.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
index 75fc69c..d81e94c 100644
--- a/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
+++ b/pkg/analysis_server/tool/spec/codegen_analysis_server.dart
@@ -5,7 +5,7 @@
 /**
  * Code generation for the file "AnalysisServer.java".
  */
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 import 'codegen_java.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
index 45c8f2e..6acbda1 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_notification_handler.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart';
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
index adb57f7..a8692f1 100644
--- a/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analysis_server/tool/spec/codegen_dart_protocol.dart
@@ -4,7 +4,7 @@
 
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:path/path.dart' as path;
 
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index 8fec4fa..924e5c3 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -7,7 +7,7 @@
  */
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart' as path;
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_java.dart b/pkg/analysis_server/tool/spec/codegen_java.dart
index 9956fe1..56bdc8b 100644
--- a/pkg/analysis_server/tool/spec/codegen_java.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java.dart
@@ -5,7 +5,7 @@
 /**
  * Tools for Java code generation.
  */
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 2006405..5a0e443 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -5,7 +5,7 @@
 /**
  * Code generation for the file "AnalysisServer.java".
  */
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index 226c707..bd6c7e1 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -7,7 +7,7 @@
  */
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 import 'from_html.dart';
diff --git a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
index 7530d39..4c45331 100644
--- a/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analysis_server/tool/spec/codegen_protocol_constants.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 import 'codegen_dart.dart';
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index be77a02..f78ad63 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -7,7 +7,7 @@
  */
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/html.dart';
+import 'package:analysis_tool/html.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:html/parser.dart' as parser;
 import 'package:path/path.dart';
@@ -131,8 +131,8 @@
     });
     for (String expectedAttribute in requiredAttributes) {
       if (!attributesFound.contains(expectedAttribute)) {
-        throw new Exception('$context: ${element
-            .localName} must contain attribute $expectedAttribute');
+        throw new Exception(
+            '$context: ${element.localName} must contain attribute $expectedAttribute');
       }
     }
   }
diff --git a/pkg/analysis_server/tool/spec/generate_all.dart b/pkg/analysis_server/tool/spec/generate_all.dart
index c5afd22..000b487 100644
--- a/pkg/analysis_server/tool/spec/generate_all.dart
+++ b/pkg/analysis_server/tool/spec/generate_all.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart';
 
 import 'codegen_analysis_server.dart' as codegen_analysis_server;
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 45f18a6..895f4f4 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -390,6 +390,23 @@
   public void analytics_sendTiming(String event, int millis);
 
   /**
+   * {@code completion.getSuggestionDetails}
+   *
+   * Clients must make this request when the user has selected a completion suggestion from an
+   * AvailableSuggestionSet. Analysis server will respond with the text to insert as well as any
+   * SourceChange that needs to be applied in case the completion requires an additional import to be
+   * added. It is an error if the id is no longer valid, for instance if the library has been removed
+   * after the completion suggestion is accepted.
+   *
+   * @param file The path of the file into which this completion is being inserted.
+   * @param id The identifier of the AvailableSuggestionSet containing the selected label.
+   * @param label The label from the AvailableSuggestionSet with the `id` for which insertion
+   *         information is requested.
+   * @param offset The offset in the file where the completion will be inserted.
+   */
+  public void completion_getSuggestionDetails(String file, int id, String label, int offset, GetSuggestionDetailsConsumer consumer);
+
+  /**
    * {@code completion.getSuggestions}
    *
    * Request that completion suggestions for the given offset in the given file be returned.
@@ -400,6 +417,35 @@
   public void completion_getSuggestions(String file, int offset, GetSuggestionsConsumer consumer);
 
   /**
+   * {@code completion.registerLibraryPaths}
+   *
+   * The client can make this request to express interest in certain libraries to receive completion
+   * suggestions from based on the client path. If this request is received before the client has
+   * used 'completion.setSubscriptions' to subscribe to the AVAILABLE_SUGGESTION_SETS service, then
+   * an error of type NOT_SUBSCRIBED_TO_AVAILABLE_SUGGESTION_SETS will be generated. All previous
+   * paths are replaced by the given set of paths.
+   *
+   * @param paths A list of objects each containing a path and the additional libraries from which
+   *         the client is interested in receiving completion suggestions. If one configured path is
+   *         beneath another, the descendent will override the ancestors' configured libraries of
+   *         interest.
+   */
+  public void completion_registerLibraryPaths(List<LibraryPathSet> paths);
+
+  /**
+   * {@code completion.setSubscriptions}
+   *
+   * Subscribe for completion services. All previous subscriptions are replaced by the given set of
+   * services.
+   *
+   * It is an error if any of the elements in the list are not valid services. If there is an error,
+   * then the current subscriptions will remain unchanged.
+   *
+   * @param subscriptions A list of the services being subscribed to.
+   */
+  public void completion_setSubscriptions(List<String> subscriptions);
+
+  /**
    * {@code diagnostic.getDiagnostics}
    *
    * Return server diagnostics.
@@ -422,14 +468,27 @@
    * those sources. These edits may include changes to sources outside the set of specified sources
    * if a change in a specified source requires it.
    *
+   * If includedFixes is specified, then those fixes will be applied. If includeRequiredFixes is
+   * specified, then "required" fixes will be applied in addition to whatever fixes are specified in
+   * includedFixes if any. If neither includedFixes nor includeRequiredFixes is specified, then all
+   * fixes will be applied. If excludedFixes is specified, then those fixes will not be applied
+   * regardless of whether they are "required" or specified in includedFixes.
+   *
    * @param included A list of the files and directories for which edits should be suggested. If a
    *         request is made with a path that is invalid, e.g. is not absolute and normalized, an
    *         error of type INVALID_FILE_PATH_FORMAT will be generated. If a request is made for a
    *         file which does not exist, or which is not currently subject to analysis (e.g. because
    *         it is not associated with any analysis root specified to analysis.setAnalysisRoots), an
    *         error of type FILE_NOT_ANALYZED will be generated.
+   * @param includedFixes A list of names indicating which fixes should be applied. If a name is
+   *         specified that does not match the name of a known fix, an error of type UNKNOWN_FIX will
+   *         be generated.
+   * @param includeRequiredFixes A flag indicating that "required" fixes should be applied.
+   * @param excludedFixes A list of names indicating which fixes should not be applied. If a name is
+   *         specified that does not match the name of a known fix, an error of type UNKNOWN_FIX will
+   *         be generated.
    */
-  public void edit_dartfix(List<String> included, DartfixConsumer consumer);
+  public void edit_dartfix(List<String> included, List<String> includedFixes, boolean includeRequiredFixes, List<String> excludedFixes, DartfixConsumer consumer);
 
   /**
    * {@code edit.format}
@@ -478,6 +537,14 @@
   public void edit_getAvailableRefactorings(String file, int offset, int length, GetAvailableRefactoringsConsumer consumer);
 
   /**
+   * {@code edit.getDartfixInfo}
+   *
+   * Request information about edit.dartfix such as the list of known fixes that can be specified in
+   * an edit.dartfix request.
+   */
+  public void edit_getDartfixInfo(GetDartfixInfoConsumer consumer);
+
+  /**
    * {@code edit.getFixes}
    *
    * Return the set of fixes that are available for the errors at a given offset in a given file.
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java
new file mode 100644
index 0000000..a25dd89
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestion.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A partial completion suggestion that can be used in combination with info from
+ * completion.results to build completion suggestions for not yet imported library tokens.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class AvailableSuggestion {
+
+  public static final AvailableSuggestion[] EMPTY_ARRAY = new AvailableSuggestion[0];
+
+  public static final List<AvailableSuggestion> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The identifier to present to the user for code completion.
+   */
+  private final String label;
+
+  /**
+   * Information about the element reference being suggested.
+   */
+  private final Element element;
+
+  /**
+   * The Dartdoc associated with the element being suggested. This field is omitted if there is no
+   * Dartdoc associated with the element.
+   */
+  private final String docComplete;
+
+  /**
+   * An abbreviated version of the Dartdoc associated with the element being suggested. This field is
+   * omitted if there is no Dartdoc associated with the element.
+   */
+  private final String docSummary;
+
+  /**
+   * If the element is an executable, the names of the formal parameters of all kinds - required,
+   * optional positional, and optional named. The names of positional parameters are empty strings.
+   * Omitted if the element is not an executable.
+   */
+  private final List<String> parameterNames;
+
+  /**
+   * If the element is an executable, the declared types of the formal parameters of all kinds -
+   * required, optional positional, and optional named. Omitted if the element is not an executable.
+   */
+  private final List<String> parameterTypes;
+
+  /**
+   * This field is set if the relevance of this suggestion might be changed depending on where
+   * completion is requested.
+   */
+  private final List<AvailableSuggestionRelevanceTag> relevanceTags;
+
+  private final Integer requiredParameterCount;
+
+  /**
+   * Constructor for {@link AvailableSuggestion}.
+   */
+  public AvailableSuggestion(String label, Element element, String docComplete, String docSummary, List<String> parameterNames, List<String> parameterTypes, List<AvailableSuggestionRelevanceTag> relevanceTags, Integer requiredParameterCount) {
+    this.label = label;
+    this.element = element;
+    this.docComplete = docComplete;
+    this.docSummary = docSummary;
+    this.parameterNames = parameterNames;
+    this.parameterTypes = parameterTypes;
+    this.relevanceTags = relevanceTags;
+    this.requiredParameterCount = requiredParameterCount;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof AvailableSuggestion) {
+      AvailableSuggestion other = (AvailableSuggestion) obj;
+      return
+        ObjectUtilities.equals(other.label, label) &&
+        ObjectUtilities.equals(other.element, element) &&
+        ObjectUtilities.equals(other.docComplete, docComplete) &&
+        ObjectUtilities.equals(other.docSummary, docSummary) &&
+        ObjectUtilities.equals(other.parameterNames, parameterNames) &&
+        ObjectUtilities.equals(other.parameterTypes, parameterTypes) &&
+        ObjectUtilities.equals(other.relevanceTags, relevanceTags) &&
+        ObjectUtilities.equals(other.requiredParameterCount, requiredParameterCount);
+    }
+    return false;
+  }
+
+  public static AvailableSuggestion fromJson(JsonObject jsonObject) {
+    String label = jsonObject.get("label").getAsString();
+    Element element = Element.fromJson(jsonObject.get("element").getAsJsonObject());
+    String docComplete = jsonObject.get("docComplete") == null ? null : jsonObject.get("docComplete").getAsString();
+    String docSummary = jsonObject.get("docSummary") == null ? null : jsonObject.get("docSummary").getAsString();
+    List<String> parameterNames = jsonObject.get("parameterNames") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("parameterNames").getAsJsonArray());
+    List<String> parameterTypes = jsonObject.get("parameterTypes") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("parameterTypes").getAsJsonArray());
+    List<AvailableSuggestionRelevanceTag> relevanceTags = jsonObject.get("relevanceTags") == null ? null : AvailableSuggestionRelevanceTag.fromJsonArray(jsonObject.get("relevanceTags").getAsJsonArray());
+    Integer requiredParameterCount = jsonObject.get("requiredParameterCount") == null ? null : jsonObject.get("requiredParameterCount").getAsInt();
+    return new AvailableSuggestion(label, element, docComplete, docSummary, parameterNames, parameterTypes, relevanceTags, requiredParameterCount);
+  }
+
+  public static List<AvailableSuggestion> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<AvailableSuggestion> list = new ArrayList<AvailableSuggestion>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The Dartdoc associated with the element being suggested. This field is omitted if there is no
+   * Dartdoc associated with the element.
+   */
+  public String getDocComplete() {
+    return docComplete;
+  }
+
+  /**
+   * An abbreviated version of the Dartdoc associated with the element being suggested. This field is
+   * omitted if there is no Dartdoc associated with the element.
+   */
+  public String getDocSummary() {
+    return docSummary;
+  }
+
+  /**
+   * Information about the element reference being suggested.
+   */
+  public Element getElement() {
+    return element;
+  }
+
+  /**
+   * The identifier to present to the user for code completion.
+   */
+  public String getLabel() {
+    return label;
+  }
+
+  /**
+   * If the element is an executable, the names of the formal parameters of all kinds - required,
+   * optional positional, and optional named. The names of positional parameters are empty strings.
+   * Omitted if the element is not an executable.
+   */
+  public List<String> getParameterNames() {
+    return parameterNames;
+  }
+
+  /**
+   * If the element is an executable, the declared types of the formal parameters of all kinds -
+   * required, optional positional, and optional named. Omitted if the element is not an executable.
+   */
+  public List<String> getParameterTypes() {
+    return parameterTypes;
+  }
+
+  /**
+   * This field is set if the relevance of this suggestion might be changed depending on where
+   * completion is requested.
+   */
+  public List<AvailableSuggestionRelevanceTag> getRelevanceTags() {
+    return relevanceTags;
+  }
+
+  public Integer getRequiredParameterCount() {
+    return requiredParameterCount;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(label);
+    builder.append(element);
+    builder.append(docComplete);
+    builder.append(docSummary);
+    builder.append(parameterNames);
+    builder.append(parameterTypes);
+    builder.append(relevanceTags);
+    builder.append(requiredParameterCount);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("label", label);
+    jsonObject.add("element", element.toJson());
+    if (docComplete != null) {
+      jsonObject.addProperty("docComplete", docComplete);
+    }
+    if (docSummary != null) {
+      jsonObject.addProperty("docSummary", docSummary);
+    }
+    if (parameterNames != null) {
+      JsonArray jsonArrayParameterNames = new JsonArray();
+      for (String elt : parameterNames) {
+        jsonArrayParameterNames.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("parameterNames", jsonArrayParameterNames);
+    }
+    if (parameterTypes != null) {
+      JsonArray jsonArrayParameterTypes = new JsonArray();
+      for (String elt : parameterTypes) {
+        jsonArrayParameterTypes.add(new JsonPrimitive(elt));
+      }
+      jsonObject.add("parameterTypes", jsonArrayParameterTypes);
+    }
+    if (relevanceTags != null) {
+      JsonArray jsonArrayRelevanceTags = new JsonArray();
+      for (AvailableSuggestionRelevanceTag elt : relevanceTags) {
+        jsonArrayRelevanceTags.add(elt.toJson());
+      }
+      jsonObject.add("relevanceTags", jsonArrayRelevanceTags);
+    }
+    if (requiredParameterCount != null) {
+      jsonObject.addProperty("requiredParameterCount", requiredParameterCount);
+    }
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("label=");
+    builder.append(label + ", ");
+    builder.append("element=");
+    builder.append(element + ", ");
+    builder.append("docComplete=");
+    builder.append(docComplete + ", ");
+    builder.append("docSummary=");
+    builder.append(docSummary + ", ");
+    builder.append("parameterNames=");
+    builder.append(StringUtils.join(parameterNames, ", ") + ", ");
+    builder.append("parameterTypes=");
+    builder.append(StringUtils.join(parameterTypes, ", ") + ", ");
+    builder.append("relevanceTags=");
+    builder.append(StringUtils.join(relevanceTags, ", ") + ", ");
+    builder.append("requiredParameterCount=");
+    builder.append(requiredParameterCount);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java
new file mode 100644
index 0000000..570ef61
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AvailableSuggestionSet.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class AvailableSuggestionSet {
+
+  public static final AvailableSuggestionSet[] EMPTY_ARRAY = new AvailableSuggestionSet[0];
+
+  public static final List<AvailableSuggestionSet> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The id associated with the library.
+   */
+  private final int id;
+
+  /**
+   * The URI of the library.
+   */
+  private final String uri;
+
+  private final List<AvailableSuggestion> items;
+
+  /**
+   * Constructor for {@link AvailableSuggestionSet}.
+   */
+  public AvailableSuggestionSet(int id, String uri, List<AvailableSuggestion> items) {
+    this.id = id;
+    this.uri = uri;
+    this.items = items;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof AvailableSuggestionSet) {
+      AvailableSuggestionSet other = (AvailableSuggestionSet) obj;
+      return
+        other.id == id &&
+        ObjectUtilities.equals(other.uri, uri) &&
+        ObjectUtilities.equals(other.items, items);
+    }
+    return false;
+  }
+
+  public static AvailableSuggestionSet fromJson(JsonObject jsonObject) {
+    int id = jsonObject.get("id").getAsInt();
+    String uri = jsonObject.get("uri").getAsString();
+    List<AvailableSuggestion> items = AvailableSuggestion.fromJsonArray(jsonObject.get("items").getAsJsonArray());
+    return new AvailableSuggestionSet(id, uri, items);
+  }
+
+  public static List<AvailableSuggestionSet> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<AvailableSuggestionSet> list = new ArrayList<AvailableSuggestionSet>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The id associated with the library.
+   */
+  public int getId() {
+    return id;
+  }
+
+  public List<AvailableSuggestion> getItems() {
+    return items;
+  }
+
+  /**
+   * The URI of the library.
+   */
+  public String getUri() {
+    return uri;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(id);
+    builder.append(uri);
+    builder.append(items);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("id", id);
+    jsonObject.addProperty("uri", uri);
+    JsonArray jsonArrayItems = new JsonArray();
+    for (AvailableSuggestion elt : items) {
+      jsonArrayItems.add(elt.toJson());
+    }
+    jsonObject.add("items", jsonArrayItems);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("id=");
+    builder.append(id + ", ");
+    builder.append("uri=");
+    builder.append(uri + ", ");
+    builder.append("items=");
+    builder.append(StringUtils.join(items, ", "));
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java
new file mode 100644
index 0000000..d7a0d19
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionService.java
@@ -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.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+/**
+ * An enumeration of the completion services to which a client can subscribe.
+ *
+ * @coverage dart.server.generated.types
+ */
+public class CompletionService {
+
+  /**
+   * The client will receive notifications once subscribed with completion suggestion sets from the
+   * libraries of interest. The client should keep an up-to-date record of these in memory so that it
+   * will be able to union these candidates with other completion suggestions when applicable at
+   * completion time.
+   */
+  public static final String AVAILABLE_SUGGESTION_SETS = "AVAILABLE_SUGGESTION_SETS";
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java b/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
new file mode 100644
index 0000000..b441025
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/DartFix.java
@@ -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.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A "fix" that can be specified in an edit.dartfix request.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class DartFix {
+
+  public static final DartFix[] EMPTY_ARRAY = new DartFix[0];
+
+  public static final List<DartFix> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The name of the fix.
+   */
+  private final String name;
+
+  /**
+   * A human readable description of the fix.
+   */
+  private final String description;
+
+  /**
+   * `true` if the fix is in the "required" fixes group.
+   */
+  private final Boolean isRequired;
+
+  /**
+   * Constructor for {@link DartFix}.
+   */
+  public DartFix(String name, String description, Boolean isRequired) {
+    this.name = name;
+    this.description = description;
+    this.isRequired = isRequired;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof DartFix) {
+      DartFix other = (DartFix) obj;
+      return
+        ObjectUtilities.equals(other.name, name) &&
+        ObjectUtilities.equals(other.description, description) &&
+        ObjectUtilities.equals(other.isRequired, isRequired);
+    }
+    return false;
+  }
+
+  public static DartFix fromJson(JsonObject jsonObject) {
+    String name = jsonObject.get("name").getAsString();
+    String description = jsonObject.get("description") == null ? null : jsonObject.get("description").getAsString();
+    Boolean isRequired = jsonObject.get("isRequired") == null ? null : jsonObject.get("isRequired").getAsBoolean();
+    return new DartFix(name, description, isRequired);
+  }
+
+  public static List<DartFix> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<DartFix> list = new ArrayList<DartFix>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * A human readable description of the fix.
+   */
+  public String getDescription() {
+    return description;
+  }
+
+  /**
+   * `true` if the fix is in the "required" fixes group.
+   */
+  public Boolean getIsRequired() {
+    return isRequired;
+  }
+
+  /**
+   * The name of the fix.
+   */
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(name);
+    builder.append(description);
+    builder.append(isRequired);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("name", name);
+    if (description != null) {
+      jsonObject.addProperty("description", description);
+    }
+    if (isRequired != null) {
+      jsonObject.addProperty("isRequired", isRequired);
+    }
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("name=");
+    builder.append(name + ", ");
+    builder.append("description=");
+    builder.append(description + ", ");
+    builder.append("isRequired=");
+    builder.append(isRequired);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java
new file mode 100644
index 0000000..d079df2
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionRelevanceTag.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Each AvailableSuggestion can specify zero or more tags in the field relevanceTags, so that when
+ * the included tag is equal to one of the relevanceTags, the suggestion is given higher relevance
+ * than the whole IncludedSuggestionSet.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class IncludedSuggestionRelevanceTag {
+
+  public static final IncludedSuggestionRelevanceTag[] EMPTY_ARRAY = new IncludedSuggestionRelevanceTag[0];
+
+  public static final List<IncludedSuggestionRelevanceTag> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The opaque value of the tag.
+   */
+  private final AvailableSuggestionRelevanceTag tag;
+
+  /**
+   * The boost to the relevance of the completion suggestions that match this tag, which is added to
+   * the relevance of the containing IncludedSuggestionSet.
+   */
+  private final int relevanceBoost;
+
+  /**
+   * Constructor for {@link IncludedSuggestionRelevanceTag}.
+   */
+  public IncludedSuggestionRelevanceTag(AvailableSuggestionRelevanceTag tag, int relevanceBoost) {
+    this.tag = tag;
+    this.relevanceBoost = relevanceBoost;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof IncludedSuggestionRelevanceTag) {
+      IncludedSuggestionRelevanceTag other = (IncludedSuggestionRelevanceTag) obj;
+      return
+        ObjectUtilities.equals(other.tag, tag) &&
+        other.relevanceBoost == relevanceBoost;
+    }
+    return false;
+  }
+
+  public static IncludedSuggestionRelevanceTag fromJson(JsonObject jsonObject) {
+    AvailableSuggestionRelevanceTag tag = AvailableSuggestionRelevanceTag.fromJson(jsonObject.get("tag").getAsJsonObject());
+    int relevanceBoost = jsonObject.get("relevanceBoost").getAsInt();
+    return new IncludedSuggestionRelevanceTag(tag, relevanceBoost);
+  }
+
+  public static List<IncludedSuggestionRelevanceTag> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<IncludedSuggestionRelevanceTag> list = new ArrayList<IncludedSuggestionRelevanceTag>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The boost to the relevance of the completion suggestions that match this tag, which is added to
+   * the relevance of the containing IncludedSuggestionSet.
+   */
+  public int getRelevanceBoost() {
+    return relevanceBoost;
+  }
+
+  /**
+   * The opaque value of the tag.
+   */
+  public AvailableSuggestionRelevanceTag getTag() {
+    return tag;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(tag);
+    builder.append(relevanceBoost);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.add("tag", tag.toJson());
+    jsonObject.addProperty("relevanceBoost", relevanceBoost);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("tag=");
+    builder.append(tag + ", ");
+    builder.append("relevanceBoost=");
+    builder.append(relevanceBoost);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java
new file mode 100644
index 0000000..344ac5b
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/IncludedSuggestionSet.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A reference to an AvailableSuggestionSet noting that the library's members which match the kind
+ * of this ref should be presented to the user.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class IncludedSuggestionSet {
+
+  public static final IncludedSuggestionSet[] EMPTY_ARRAY = new IncludedSuggestionSet[0];
+
+  public static final List<IncludedSuggestionSet> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * Clients should use it to access the set of precomputed completions to be displayed to the user.
+   */
+  private final int id;
+
+  /**
+   * The relevance of completion suggestions from this library where a higher number indicates a
+   * higher relevance.
+   */
+  private final int relevance;
+
+  /**
+   * Constructor for {@link IncludedSuggestionSet}.
+   */
+  public IncludedSuggestionSet(int id, int relevance) {
+    this.id = id;
+    this.relevance = relevance;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof IncludedSuggestionSet) {
+      IncludedSuggestionSet other = (IncludedSuggestionSet) obj;
+      return
+        other.id == id &&
+        other.relevance == relevance;
+    }
+    return false;
+  }
+
+  public static IncludedSuggestionSet fromJson(JsonObject jsonObject) {
+    int id = jsonObject.get("id").getAsInt();
+    int relevance = jsonObject.get("relevance").getAsInt();
+    return new IncludedSuggestionSet(id, relevance);
+  }
+
+  public static List<IncludedSuggestionSet> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<IncludedSuggestionSet> list = new ArrayList<IncludedSuggestionSet>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * Clients should use it to access the set of precomputed completions to be displayed to the user.
+   */
+  public int getId() {
+    return id;
+  }
+
+  /**
+   * The relevance of completion suggestions from this library where a higher number indicates a
+   * higher relevance.
+   */
+  public int getRelevance() {
+    return relevance;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(id);
+    builder.append(relevance);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("id", id);
+    jsonObject.addProperty("relevance", relevance);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("id=");
+    builder.append(id + ", ");
+    builder.append("relevance=");
+    builder.append(relevance);
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java b/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java
new file mode 100644
index 0000000..de46030
--- /dev/null
+++ b/pkg/analysis_server/tool/spec/generated/java/types/LibraryPathSet.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */
+package org.dartlang.analysis.server.protocol;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import com.google.common.collect.Lists;
+import com.google.dart.server.utilities.general.JsonUtilities;
+import com.google.dart.server.utilities.general.ObjectUtilities;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * A list of associations between paths and the libraries that should be included for code
+ * completion when editing a file beneath that path.
+ *
+ * @coverage dart.server.generated.types
+ */
+@SuppressWarnings("unused")
+public class LibraryPathSet {
+
+  public static final LibraryPathSet[] EMPTY_ARRAY = new LibraryPathSet[0];
+
+  public static final List<LibraryPathSet> EMPTY_LIST = Lists.newArrayList();
+
+  /**
+   * The filepath for which this request's libraries should be active in completion suggestions. This
+   * object associates filesystem regions to libraries and library directories of interest to the
+   * client.
+   */
+  private final String scope;
+
+  /**
+   * The paths of the libraries of interest to the client for completion suggestions.
+   */
+  private final List<String> libraryPaths;
+
+  /**
+   * Constructor for {@link LibraryPathSet}.
+   */
+  public LibraryPathSet(String scope, List<String> libraryPaths) {
+    this.scope = scope;
+    this.libraryPaths = libraryPaths;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj instanceof LibraryPathSet) {
+      LibraryPathSet other = (LibraryPathSet) obj;
+      return
+        ObjectUtilities.equals(other.scope, scope) &&
+        ObjectUtilities.equals(other.libraryPaths, libraryPaths);
+    }
+    return false;
+  }
+
+  public static LibraryPathSet fromJson(JsonObject jsonObject) {
+    String scope = jsonObject.get("scope").getAsString();
+    List<String> libraryPaths = JsonUtilities.decodeStringList(jsonObject.get("libraryPaths").getAsJsonArray());
+    return new LibraryPathSet(scope, libraryPaths);
+  }
+
+  public static List<LibraryPathSet> fromJsonArray(JsonArray jsonArray) {
+    if (jsonArray == null) {
+      return EMPTY_LIST;
+    }
+    ArrayList<LibraryPathSet> list = new ArrayList<LibraryPathSet>(jsonArray.size());
+    Iterator<JsonElement> iterator = jsonArray.iterator();
+    while (iterator.hasNext()) {
+      list.add(fromJson(iterator.next().getAsJsonObject()));
+    }
+    return list;
+  }
+
+  /**
+   * The paths of the libraries of interest to the client for completion suggestions.
+   */
+  public List<String> getLibraryPaths() {
+    return libraryPaths;
+  }
+
+  /**
+   * The filepath for which this request's libraries should be active in completion suggestions. This
+   * object associates filesystem regions to libraries and library directories of interest to the
+   * client.
+   */
+  public String getScope() {
+    return scope;
+  }
+
+  @Override
+  public int hashCode() {
+    HashCodeBuilder builder = new HashCodeBuilder();
+    builder.append(scope);
+    builder.append(libraryPaths);
+    return builder.toHashCode();
+  }
+
+  public JsonObject toJson() {
+    JsonObject jsonObject = new JsonObject();
+    jsonObject.addProperty("scope", scope);
+    JsonArray jsonArrayLibraryPaths = new JsonArray();
+    for (String elt : libraryPaths) {
+      jsonArrayLibraryPaths.add(new JsonPrimitive(elt));
+    }
+    jsonObject.add("libraryPaths", jsonArrayLibraryPaths);
+    return jsonObject;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append("scope=");
+    builder.append(scope + ", ");
+    builder.append("libraryPaths=");
+    builder.append(StringUtils.join(libraryPaths, ", "));
+    builder.append("]");
+    return builder.toString();
+  }
+
+}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index b212bf7..dbd738a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -165,6 +165,12 @@
   public static final String SORT_MEMBERS_PARSE_ERRORS = "SORT_MEMBERS_PARSE_ERRORS";
 
   /**
+   * A dartfix request was received containing the name of a fix which does not match the name of any
+   * known fixes.
+   */
+  public static final String UNKNOWN_FIX = "UNKNOWN_FIX";
+
+  /**
    * A request was received which the analysis server does not recognize, or cannot handle in its
    * current configuration.
    */
diff --git a/pkg/analysis_server/tool/spec/implied_types.dart b/pkg/analysis_server/tool/spec/implied_types.dart
index 856b2a4..2cf1c8b 100644
--- a/pkg/analysis_server/tool/spec/implied_types.dart
+++ b/pkg/analysis_server/tool/spec/implied_types.dart
@@ -5,7 +5,7 @@
 /**
  * Code for enumerating the set of types implied by the API.
  */
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 2418991..fd11715 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.22.1</version>
+  <version>1.23.0</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -1412,6 +1412,102 @@
       </field>
     </result>
   </request>
+  <request method="setSubscriptions" experimental="true">
+    <p>
+      Subscribe for completion services. All previous subscriptions are
+      replaced by the given set of services.
+    </p>
+    <p>
+      It is an error if any of the elements in the list are not valid
+      services. If there is an error, then the current subscriptions will
+      remain unchanged.
+    </p>
+    <params>
+      <field name="subscriptions">
+        <list>
+          <ref>CompletionService</ref>
+        </list>
+        <p>A list of the services being subscribed to.</p>
+      </field>
+    </params>
+  </request>
+  <request method="registerLibraryPaths" experimental="true">
+    <p>
+      The client can make this request to express interest in certain
+      libraries to receive completion suggestions from based on the client path.
+      If this request is received before the client has used
+      'completion.setSubscriptions' to subscribe to the <tt>AVAILABLE_SUGGESTION_SETS</tt>
+      service, then an error of type <tt>NOT_SUBSCRIBED_TO_AVAILABLE_SUGGESTION_SETS</tt>
+      will be generated. All previous paths are replaced by the given set of paths.
+    </p>
+    <params>
+      <field name="paths">
+        <list>
+          <ref>LibraryPathSet</ref>
+        </list>
+        <p>
+          A list of objects each containing a path and the additional libraries from which
+          the client is interested in receiving completion suggestions.
+          If one configured path is beneath another, the descendent
+          will override the ancestors' configured libraries of interest.
+        </p>
+      </field>
+    </params>
+  </request>
+  <request method="getSuggestionDetails" experimental="true">
+    <p>
+      Clients must make this request when the user has selected a completion
+      suggestion from an <tt>AvailableSuggestionSet</tt>. Analysis server will respond with
+      the text to insert as well as any <tt>SourceChange</tt> that needs to be applied
+      in case the completion requires an additional import to be added. It is an error
+      if the id is no longer valid, for instance if the library has been removed after
+      the completion suggestion is accepted.
+    </p>
+    <params>
+      <field name="file">
+        <ref>FilePath</ref>
+        <p>
+          The path of the file into which this completion is being inserted.
+        </p>
+      </field>
+      <field name="id">
+        <ref>int</ref>
+        <p>
+          The identifier of the <tt>AvailableSuggestionSet</tt> containing
+          the selected label.
+        </p>
+      </field>
+      <field name="label">
+        <ref>String</ref>
+        <p>
+          The label from the <tt>AvailableSuggestionSet</tt> with the `id`
+          for which insertion information is requested.
+        </p>
+      </field>
+      <field name="offset">
+        <ref>int</ref>
+        <p>
+          The offset in the file where the completion will be inserted.
+        </p>
+      </field>
+    </params>
+    <result>
+      <field name="completion">
+        <ref>String</ref>
+        <p>
+          The full text to insert, including any optional import prefix.
+        </p>
+      </field>
+      <field name="change" optional="true">
+        <ref>SourceChange</ref>
+        <p>
+          A change for the client to apply in case the library containing
+          the accepted completion suggestion needs to be imported. The field
+          will be omitted if there are no additional changes that need to be made.
+        </p>
+      </field>
+    </result>
+  </request>
   <notification event="results">
     <p>
       Reports the completion suggestions that should be presented
@@ -1466,6 +1562,83 @@
           returned for the indicated completion.
         </p>
       </field>
+      <field name="includedSuggestionSets" optional="true">
+        <list>
+          <ref>IncludedSuggestionSet</ref>
+        </list>
+        <p>
+          This field is experimental.
+        </p>
+        <p>
+          References to <tt>AvailableSuggestionSet</tt> objects previously sent
+          to the client. The client can include applicable names from the
+          referenced library in code completion suggestions.
+        </p>
+      </field>
+      <field name="includedSuggestionKinds" optional="true">
+        <list>
+          <ref>ElementKind</ref>
+        </list>
+        <p>
+          This field is experimental.
+        </p>
+        <p>
+          The client is expected to check this list against the
+          <tt>ElementKind</tt> sent in <tt>IncludedSuggestionSet</tt> to decide
+          whether or not these symbols should should be presented to the user.
+        </p>
+      </field>
+      <field name="includedSuggestionRelevanceTags" optional="true">
+        <list>
+          <ref>IncludedSuggestionRelevanceTag</ref>
+        </list>
+        <p>
+          This field is experimental.
+        </p>
+        <p>
+          The client is expected to check this list against the values of the
+          field <tt>relevanceTags</tt> of <tt>AvailableSuggestion</tt> to
+          decide if the suggestion should be given a different relevance than
+          the <tt>IncludedSuggestionSet</tt> that contains it. This might be
+          used for example to give higher relevance to suggestions of matching
+          types.
+        </p>
+        <p>
+          If an <tt>AvailableSuggestion</tt> has relevance tags that match more
+          than one <tt>IncludedSuggestionRelevanceTag</tt>, the maximum
+          relevance boost is used.
+        </p>
+      </field>
+    </params>
+  </notification>
+  <notification event="availableSuggestions" experimental="true">
+    <p>
+      Reports the pre-computed, candidate completions from symbols defined
+      in a corresponding library. This notification may be sent multiple times.
+      When a notification is processed, clients should replace any previous
+      information about the libraries in the list of changedLibraries, discard
+      any information about the libraries in the list of removedLibraries, and
+      preserve any previously received information about any libraries that are
+      not included in either list.
+    </p>
+    <params>
+      <field name="changedLibraries" optional="true">
+        <list>
+          <ref>AvailableSuggestionSet</ref>
+        </list>
+        <p>
+          A list of pre-computed, potential completions coming from
+          this set of completion suggestions.
+        </p>
+      </field>
+      <field name="removedLibraries" optional="true">
+        <list>
+          <ref>int</ref>
+        </list>
+        <p>
+          A list of library ids that no longer apply.
+        </p>
+      </field>
     </params>
   </notification>
 </domain>
@@ -1915,6 +2088,26 @@
       </field>
     </result>
   </request>
+  <request method="getDartfixInfo" experimental="true">
+    <p>
+      Request information about edit.dartfix
+      such as the list of known fixes that can be specified
+      in an edit.dartfix request.
+    </p>
+    <params>
+    </params>
+    <result>
+      <field name="fixes">
+        <list>
+          <ref>DartFix</ref>
+        </list>
+        <p>
+          A list of fixes that can be specified
+          in an edit.dartfix request.
+        </p>
+      </field>
+    </result>
+  </request>
   <request method="dartfix" experimental="true">
     <p>
       Analyze the specified sources for recommended changes
@@ -1922,6 +2115,15 @@
       These edits may include changes to sources outside the set
       of specified sources if a change in a specified source requires it.
     </p>
+    <p>
+      If includedFixes is specified, then those fixes will be applied.
+      If includeRequiredFixes is specified, then "required" fixes will be applied
+      in addition to whatever fixes are specified in includedFixes if any.
+      If neither includedFixes nor includeRequiredFixes is specified,
+      then all fixes will be applied.
+      If excludedFixes is specified, then those fixes will not be applied
+      regardless of whether they are "required" or specified in includedFixes.
+    </p>
     <params>
       <field name="included">
         <list>
@@ -1938,6 +2140,36 @@
           an error of type <tt>FILE_NOT_ANALYZED</tt> will be generated.
         </p>
       </field>
+      <field name="includedFixes" optional="true">
+        <list>
+          <ref>String</ref>
+        </list>
+        <p>
+          A list of names indicating which fixes should be applied.
+        </p>
+        <p>
+          If a name is specified that does not match the name of a known fix,
+          an error of type <tt>UNKNOWN_FIX</tt> will be generated.
+        </p>
+      </field>
+      <field name="includeRequiredFixes" optional="true">
+        <ref>bool</ref>
+        <p>
+          A flag indicating that "required" fixes should be applied.
+        </p>
+      </field>
+      <field name="excludedFixes" optional="true">
+        <list>
+          <ref>String</ref>
+        </list>
+        <p>
+          A list of names indicating which fixes should not be applied.
+        </p>
+        <p>
+          If a name is specified that does not match the name of a known fix,
+          an error of type <tt>UNKNOWN_FIX</tt> will be generated.
+        </p>
+      </field>
     </params>
     <result>
       <field name="suggestions">
@@ -3293,6 +3525,188 @@
       The identifier for a execution context.
     </p>
   </type>
+  <type name="AvailableSuggestion" experimental="true">
+    <p>
+      A partial completion suggestion that can be used in combination with
+      info from <tt>completion.results</tt> to build completion suggestions
+      for not yet imported library tokens.
+    </p>
+    <object>
+      <field name="label">
+        <ref>String</ref>
+        <p>
+          The identifier to present to the user for code completion.
+        </p>
+      </field>
+      <field name="element">
+        <ref>Element</ref>
+        <p>
+          Information about the element reference being suggested.
+        </p>
+      </field>
+      <field name="docComplete" optional="true">
+        <ref>String</ref>
+        <p>
+          The Dartdoc associated with the element being suggested. This field
+          is omitted if there is no Dartdoc associated with the element.
+        </p>
+      </field>
+      <field name="docSummary" optional="true">
+        <ref>String</ref>
+        <p>
+          An abbreviated version of the Dartdoc associated with the element being suggested.
+          This field is omitted if there is no Dartdoc associated with the element.
+        </p>
+      </field>
+      <field name="parameterNames" optional="true">
+        <list>
+          <ref>String</ref>
+        </list>
+        <p>
+          If the element is an executable, the names of the formal parameters of
+          all kinds - required, optional positional, and optional named. The
+          names of positional parameters are empty strings. Omitted if the element
+          is not an executable.
+        </p>
+      </field>
+      <field name="parameterTypes" optional="true">
+        <list>
+          <ref>String</ref>
+        </list>
+        <p>
+          If the element is an executable, the declared types of the formal parameters
+          of all kinds - required, optional positional, and optional named.
+          Omitted if the element is not an executable.
+        </p>
+      </field>
+      <field name="relevanceTags" optional="true">
+        <list>
+          <ref>AvailableSuggestionRelevanceTag</ref>
+        </list>
+        <p>
+          This field is set if the relevance of this suggestion might be
+          changed depending on where completion is requested.
+        </p>
+      </field>
+      <field name="requiredParameterCount" optional="true">
+        <ref>int</ref>
+      </field>
+    </object>
+  </type>
+  <type name="AvailableSuggestionRelevanceTag">
+    <ref>String</ref>
+    <p>
+      The opaque tag value.
+    </p>
+  </type>
+  <type name="AvailableSuggestionSet" experimental="true">
+    <object>
+      <field name="id">
+        <ref>int</ref>
+        <p>
+          The id associated with the library.
+        </p>
+      </field>
+      <field name="uri">
+        <ref>String</ref>
+        <p>
+          The URI of the library.
+        </p>
+      </field>
+      <field name="items">
+        <list>
+          <ref>AvailableSuggestion</ref>
+        </list>
+      </field>
+    </object>
+  </type>
+  <type name="IncludedSuggestionSet" experimental="true">
+    <p>
+      A reference to an <tt>AvailableSuggestionSet</tt> noting
+      that the library's members which match the kind of this ref
+      should be presented to the user.
+    </p>
+    <object>
+      <field name="id">
+        <ref>int</ref>
+        <p>
+          Clients should use it to access the set of precomputed completions
+          to be displayed to the user.
+        </p>
+      </field>
+      <field name="relevance">
+        <ref>int</ref>
+        <p>
+          The relevance of completion suggestions from this
+          library where a higher number indicates a higher relevance.
+        </p>
+      </field>
+    </object>
+  </type>
+  <type name="IncludedSuggestionRelevanceTag" experimental="true">
+    <p>
+      Each <tt>AvailableSuggestion</tt> can specify zero or more tags in the
+      field <tt>relevanceTags</tt>, so that when the included tag is equal to
+      one of the <tt>relevanceTags</tt>, the suggestion is given higher
+      relevance than the whole <tt>IncludedSuggestionSet</tt>.
+    </p>
+    <object>
+      <field name="tag">
+        <ref>AvailableSuggestionRelevanceTag</ref>
+        <p>
+          The opaque value of the tag.
+        </p>
+      </field>
+      <field name="relevanceBoost">
+        <ref>int</ref>
+        <p>
+          The boost to the relevance of the completion suggestions that match
+          this tag, which is added to the relevance of the containing
+          <tt>IncludedSuggestionSet</tt>.
+        </p>
+      </field>
+    </object>
+  </type>
+  <type name="CompletionService" experimental="true">
+    <p>
+      An enumeration of the completion services to which a client can subscribe.
+    </p>
+    <enum>
+      <value>
+        <code>AVAILABLE_SUGGESTION_SETS</code>
+        <p>
+          The client will receive notifications once subscribed with completion suggestion sets from
+          the libraries of interest. The client should keep an up-to-date record of these in
+          memory so that it will be able to union these candidates with other
+          completion suggestions when applicable at completion time.
+        </p>
+      </value>
+    </enum>
+  </type>
+  <type name="LibraryPathSet" experimental="true">
+    <p>
+      A list of associations between paths and the libraries that should be
+      included for code completion when editing a file beneath that path.
+    </p>
+    <object>
+      <field name="scope">
+        <ref>FilePath</ref>
+        <p>
+          The filepath for which this request's libraries should be active
+          in completion suggestions. This object associates filesystem regions
+          to libraries and library directories of interest to the client.
+        </p>
+      </field>
+      <field name="libraryPaths">
+        <list>
+          <ref>FilePath</ref>
+        </list>
+        <p>
+          The paths of the libraries of interest to the client for completion suggestions.
+        </p>
+      </field>
+    </object>
+  </type>
   <type name="RuntimeCompletionExpression">
     <p>
       An expression for which we want to know its runtime type.
@@ -4186,6 +4600,13 @@
         </p>
       </value>
       <value>
+        <code>UNKNOWN_FIX</code>
+        <p>
+          A dartfix request was received containing the name of a fix
+          which does not match the name of any known fixes.
+        </p>
+      </value>
+      <value>
         <code>UNKNOWN_REQUEST</code>
         <p>
           A request was received which the analysis server does
@@ -4215,6 +4636,31 @@
       request.
     </p>
   </type>
+  <type name="DartFix" experimental="true">
+    <p>
+      A "fix" that can be specified in an edit.dartfix request.
+    </p>
+    <object>
+      <field name="name">
+        <ref>String</ref>
+        <p>
+          The name of the fix.
+        </p>
+      </field>
+      <field name="description" optional="true">
+        <ref>String</ref>
+        <p>
+          A human readable description of the fix.
+        </p>
+      </field>
+      <field name="isRequired" optional="true">
+        <ref>bool</ref>
+        <p>
+          `true` if the fix is in the "required" fixes group.
+        </p>
+      </field>
+    </object>
+  </type>
   <type name="DartFixSuggestion" experimental="true">
     <p>
       A suggestion from an edit.dartfix request.
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 1683331..820948c 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -9,8 +9,8 @@
  */
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/html.dart';
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/html.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/analysis_server_client/lib/handler/notification_handler.dart b/pkg/analysis_server_client/lib/handler/notification_handler.dart
index 8bdbf14..97ec840 100644
--- a/pkg/analysis_server_client/lib/handler/notification_handler.dart
+++ b/pkg/analysis_server_client/lib/handler/notification_handler.dart
@@ -67,6 +67,11 @@
         onAnalysisOverrides(
             new AnalysisOverridesParams.fromJson(decoder, 'params', params));
         break;
+      case COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS:
+        onCompletionAvailableSuggestions(
+            new CompletionAvailableSuggestionsParams.fromJson(
+                decoder, 'params', params));
+        break;
       case COMPLETION_NOTIFICATION_RESULTS:
         onCompletionResults(
             new CompletionResultsParams.fromJson(decoder, 'params', params));
@@ -206,6 +211,16 @@
   /// request.
   void onAnalysisOverrides(AnalysisOverridesParams params) {}
 
+  /// Reports the pre-computed, candidate completions from symbols defined
+  /// in a corresponding library. This notification may be sent multiple times.
+  /// When a notification is processed, clients should replace any previous
+  /// information about the libraries in the list of changedLibraries, discard
+  /// any information about the libraries in the list of removedLibraries, and
+  /// preserve any previously received information about any libraries that are
+  /// not included in either list.
+  void onCompletionAvailableSuggestions(
+      CompletionAvailableSuggestionsParams params) {}
+
   /// Reports the completion suggestions that should be presented
   /// to the user. The set of suggestions included in the
   /// notification is always a complete list that supersedes any
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index fd21adb..d599adc 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.22.1';
+const String PROTOCOL_VERSION = '1.23.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -110,8 +110,21 @@
 const String ANALYTICS_REQUEST_SEND_TIMING_EVENT = 'event';
 const String ANALYTICS_REQUEST_SEND_TIMING_MILLIS = 'millis';
 const String ANALYTICS_RESPONSE_IS_ENABLED_ENABLED = 'enabled';
+const String COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS =
+    'completion.availableSuggestions';
+const String COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS_CHANGED_LIBRARIES =
+    'changedLibraries';
+const String COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS_REMOVED_LIBRARIES =
+    'removedLibraries';
 const String COMPLETION_NOTIFICATION_RESULTS = 'completion.results';
 const String COMPLETION_NOTIFICATION_RESULTS_ID = 'id';
+const String COMPLETION_NOTIFICATION_RESULTS_INCLUDED_SUGGESTION_KINDS =
+    'includedSuggestionKinds';
+const String
+    COMPLETION_NOTIFICATION_RESULTS_INCLUDED_SUGGESTION_RELEVANCE_TAGS =
+    'includedSuggestionRelevanceTags';
+const String COMPLETION_NOTIFICATION_RESULTS_INCLUDED_SUGGESTION_SETS =
+    'includedSuggestionSets';
 const String COMPLETION_NOTIFICATION_RESULTS_IS_LAST = 'isLast';
 const String COMPLETION_NOTIFICATION_RESULTS_REPLACEMENT_LENGTH =
     'replacementLength';
@@ -121,13 +134,33 @@
 const String COMPLETION_REQUEST_GET_SUGGESTIONS = 'completion.getSuggestions';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file';
 const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS =
+    'completion.getSuggestionDetails';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_FILE = 'file';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_ID = 'id';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_LABEL = 'label';
+const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS_OFFSET = 'offset';
+const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS =
+    'completion.registerLibraryPaths';
+const String COMPLETION_REQUEST_REGISTER_LIBRARY_PATHS_PATHS = 'paths';
+const String COMPLETION_REQUEST_SET_SUBSCRIPTIONS =
+    'completion.setSubscriptions';
+const String COMPLETION_REQUEST_SET_SUBSCRIPTIONS_SUBSCRIPTIONS =
+    'subscriptions';
 const String COMPLETION_RESPONSE_GET_SUGGESTIONS_ID = 'id';
+const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_CHANGE = 'change';
+const String COMPLETION_RESPONSE_GET_SUGGESTION_DETAILS_COMPLETION =
+    'completion';
 const String DIAGNOSTIC_REQUEST_GET_DIAGNOSTICS = 'diagnostic.getDiagnostics';
 const String DIAGNOSTIC_REQUEST_GET_SERVER_PORT = 'diagnostic.getServerPort';
 const String DIAGNOSTIC_RESPONSE_GET_DIAGNOSTICS_CONTEXTS = 'contexts';
 const String DIAGNOSTIC_RESPONSE_GET_SERVER_PORT_PORT = 'port';
 const String EDIT_REQUEST_DARTFIX = 'edit.dartfix';
+const String EDIT_REQUEST_DARTFIX_EXCLUDED_FIXES = 'excludedFixes';
 const String EDIT_REQUEST_DARTFIX_INCLUDED = 'included';
+const String EDIT_REQUEST_DARTFIX_INCLUDED_FIXES = 'includedFixes';
+const String EDIT_REQUEST_DARTFIX_INCLUDE_REQUIRED_FIXES =
+    'includeRequiredFixes';
 const String EDIT_REQUEST_FORMAT = 'edit.format';
 const String EDIT_REQUEST_FORMAT_FILE = 'file';
 const String EDIT_REQUEST_FORMAT_LINE_LENGTH = 'lineLength';
@@ -142,6 +175,7 @@
 const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_FILE = 'file';
 const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_LENGTH = 'length';
 const String EDIT_REQUEST_GET_AVAILABLE_REFACTORINGS_OFFSET = 'offset';
+const String EDIT_REQUEST_GET_DARTFIX_INFO = 'edit.getDartfixInfo';
 const String EDIT_REQUEST_GET_FIXES = 'edit.getFixes';
 const String EDIT_REQUEST_GET_FIXES_FILE = 'file';
 const String EDIT_REQUEST_GET_FIXES_OFFSET = 'offset';
@@ -183,6 +217,7 @@
 const String EDIT_RESPONSE_FORMAT_SELECTION_OFFSET = 'selectionOffset';
 const String EDIT_RESPONSE_GET_ASSISTS_ASSISTS = 'assists';
 const String EDIT_RESPONSE_GET_AVAILABLE_REFACTORINGS_KINDS = 'kinds';
+const String EDIT_RESPONSE_GET_DARTFIX_INFO_FIXES = 'fixes';
 const String EDIT_RESPONSE_GET_FIXES_FIXES = 'fixes';
 const String EDIT_RESPONSE_GET_POSTFIX_COMPLETION_CHANGE = 'change';
 const String EDIT_RESPONSE_GET_REFACTORING_CHANGE = 'change';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index bea5464..6d464ab 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -5071,6 +5071,415 @@
 }
 
 /**
+ * AvailableSuggestion
+ *
+ * {
+ *   "label": String
+ *   "element": Element
+ *   "docComplete": optional String
+ *   "docSummary": optional String
+ *   "parameterNames": optional List<String>
+ *   "parameterTypes": optional List<String>
+ *   "relevanceTags": optional List<AvailableSuggestionRelevanceTag>
+ *   "requiredParameterCount": optional int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class AvailableSuggestion implements HasToJson {
+  String _label;
+
+  Element _element;
+
+  String _docComplete;
+
+  String _docSummary;
+
+  List<String> _parameterNames;
+
+  List<String> _parameterTypes;
+
+  List<String> _relevanceTags;
+
+  int _requiredParameterCount;
+
+  /**
+   * The identifier to present to the user for code completion.
+   */
+  String get label => _label;
+
+  /**
+   * The identifier to present to the user for code completion.
+   */
+  void set label(String value) {
+    assert(value != null);
+    this._label = value;
+  }
+
+  /**
+   * Information about the element reference being suggested.
+   */
+  Element get element => _element;
+
+  /**
+   * Information about the element reference being suggested.
+   */
+  void set element(Element value) {
+    assert(value != null);
+    this._element = value;
+  }
+
+  /**
+   * The Dartdoc associated with the element being suggested. This field is
+   * omitted if there is no Dartdoc associated with the element.
+   */
+  String get docComplete => _docComplete;
+
+  /**
+   * The Dartdoc associated with the element being suggested. This field is
+   * omitted if there is no Dartdoc associated with the element.
+   */
+  void set docComplete(String value) {
+    this._docComplete = value;
+  }
+
+  /**
+   * An abbreviated version of the Dartdoc associated with the element being
+   * suggested. This field is omitted if there is no Dartdoc associated with
+   * the element.
+   */
+  String get docSummary => _docSummary;
+
+  /**
+   * An abbreviated version of the Dartdoc associated with the element being
+   * suggested. This field is omitted if there is no Dartdoc associated with
+   * the element.
+   */
+  void set docSummary(String value) {
+    this._docSummary = value;
+  }
+
+  /**
+   * If the element is an executable, the names of the formal parameters of all
+   * kinds - required, optional positional, and optional named. The names of
+   * positional parameters are empty strings. Omitted if the element is not an
+   * executable.
+   */
+  List<String> get parameterNames => _parameterNames;
+
+  /**
+   * If the element is an executable, the names of the formal parameters of all
+   * kinds - required, optional positional, and optional named. The names of
+   * positional parameters are empty strings. Omitted if the element is not an
+   * executable.
+   */
+  void set parameterNames(List<String> value) {
+    this._parameterNames = value;
+  }
+
+  /**
+   * If the element is an executable, the declared types of the formal
+   * parameters of all kinds - required, optional positional, and optional
+   * named. Omitted if the element is not an executable.
+   */
+  List<String> get parameterTypes => _parameterTypes;
+
+  /**
+   * If the element is an executable, the declared types of the formal
+   * parameters of all kinds - required, optional positional, and optional
+   * named. Omitted if the element is not an executable.
+   */
+  void set parameterTypes(List<String> value) {
+    this._parameterTypes = value;
+  }
+
+  /**
+   * This field is set if the relevance of this suggestion might be changed
+   * depending on where completion is requested.
+   */
+  List<String> get relevanceTags => _relevanceTags;
+
+  /**
+   * This field is set if the relevance of this suggestion might be changed
+   * depending on where completion is requested.
+   */
+  void set relevanceTags(List<String> value) {
+    this._relevanceTags = value;
+  }
+
+  int get requiredParameterCount => _requiredParameterCount;
+
+  void set requiredParameterCount(int value) {
+    this._requiredParameterCount = value;
+  }
+
+  AvailableSuggestion(String label, Element element,
+      {String docComplete,
+      String docSummary,
+      List<String> parameterNames,
+      List<String> parameterTypes,
+      List<String> relevanceTags,
+      int requiredParameterCount}) {
+    this.label = label;
+    this.element = element;
+    this.docComplete = docComplete;
+    this.docSummary = docSummary;
+    this.parameterNames = parameterNames;
+    this.parameterTypes = parameterTypes;
+    this.relevanceTags = relevanceTags;
+    this.requiredParameterCount = requiredParameterCount;
+  }
+
+  factory AvailableSuggestion.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String label;
+      if (json.containsKey("label")) {
+        label = jsonDecoder.decodeString(jsonPath + ".label", json["label"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "label");
+      }
+      Element element;
+      if (json.containsKey("element")) {
+        element = new Element.fromJson(
+            jsonDecoder, jsonPath + ".element", json["element"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "element");
+      }
+      String docComplete;
+      if (json.containsKey("docComplete")) {
+        docComplete = jsonDecoder.decodeString(
+            jsonPath + ".docComplete", json["docComplete"]);
+      }
+      String docSummary;
+      if (json.containsKey("docSummary")) {
+        docSummary = jsonDecoder.decodeString(
+            jsonPath + ".docSummary", json["docSummary"]);
+      }
+      List<String> parameterNames;
+      if (json.containsKey("parameterNames")) {
+        parameterNames = jsonDecoder.decodeList(jsonPath + ".parameterNames",
+            json["parameterNames"], jsonDecoder.decodeString);
+      }
+      List<String> parameterTypes;
+      if (json.containsKey("parameterTypes")) {
+        parameterTypes = jsonDecoder.decodeList(jsonPath + ".parameterTypes",
+            json["parameterTypes"], jsonDecoder.decodeString);
+      }
+      List<String> relevanceTags;
+      if (json.containsKey("relevanceTags")) {
+        relevanceTags = jsonDecoder.decodeList(jsonPath + ".relevanceTags",
+            json["relevanceTags"], jsonDecoder.decodeString);
+      }
+      int requiredParameterCount;
+      if (json.containsKey("requiredParameterCount")) {
+        requiredParameterCount = jsonDecoder.decodeInt(
+            jsonPath + ".requiredParameterCount",
+            json["requiredParameterCount"]);
+      }
+      return new AvailableSuggestion(label, element,
+          docComplete: docComplete,
+          docSummary: docSummary,
+          parameterNames: parameterNames,
+          parameterTypes: parameterTypes,
+          relevanceTags: relevanceTags,
+          requiredParameterCount: requiredParameterCount);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "AvailableSuggestion", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["label"] = label;
+    result["element"] = element.toJson();
+    if (docComplete != null) {
+      result["docComplete"] = docComplete;
+    }
+    if (docSummary != null) {
+      result["docSummary"] = docSummary;
+    }
+    if (parameterNames != null) {
+      result["parameterNames"] = parameterNames;
+    }
+    if (parameterTypes != null) {
+      result["parameterTypes"] = parameterTypes;
+    }
+    if (relevanceTags != null) {
+      result["relevanceTags"] = relevanceTags;
+    }
+    if (requiredParameterCount != null) {
+      result["requiredParameterCount"] = requiredParameterCount;
+    }
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is AvailableSuggestion) {
+      return label == other.label &&
+          element == other.element &&
+          docComplete == other.docComplete &&
+          docSummary == other.docSummary &&
+          listEqual(parameterNames, other.parameterNames,
+              (String a, String b) => a == b) &&
+          listEqual(parameterTypes, other.parameterTypes,
+              (String a, String b) => a == b) &&
+          listEqual(relevanceTags, other.relevanceTags,
+              (String a, String b) => a == b) &&
+          requiredParameterCount == other.requiredParameterCount;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, label.hashCode);
+    hash = JenkinsSmiHash.combine(hash, element.hashCode);
+    hash = JenkinsSmiHash.combine(hash, docComplete.hashCode);
+    hash = JenkinsSmiHash.combine(hash, docSummary.hashCode);
+    hash = JenkinsSmiHash.combine(hash, parameterNames.hashCode);
+    hash = JenkinsSmiHash.combine(hash, parameterTypes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, relevanceTags.hashCode);
+    hash = JenkinsSmiHash.combine(hash, requiredParameterCount.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * AvailableSuggestionSet
+ *
+ * {
+ *   "id": int
+ *   "uri": String
+ *   "items": List<AvailableSuggestion>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class AvailableSuggestionSet implements HasToJson {
+  int _id;
+
+  String _uri;
+
+  List<AvailableSuggestion> _items;
+
+  /**
+   * The id associated with the library.
+   */
+  int get id => _id;
+
+  /**
+   * The id associated with the library.
+   */
+  void set id(int value) {
+    assert(value != null);
+    this._id = value;
+  }
+
+  /**
+   * The URI of the library.
+   */
+  String get uri => _uri;
+
+  /**
+   * The URI of the library.
+   */
+  void set uri(String value) {
+    assert(value != null);
+    this._uri = value;
+  }
+
+  List<AvailableSuggestion> get items => _items;
+
+  void set items(List<AvailableSuggestion> value) {
+    assert(value != null);
+    this._items = value;
+  }
+
+  AvailableSuggestionSet(int id, String uri, List<AvailableSuggestion> items) {
+    this.id = id;
+    this.uri = uri;
+    this.items = items;
+  }
+
+  factory AvailableSuggestionSet.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      int id;
+      if (json.containsKey("id")) {
+        id = jsonDecoder.decodeInt(jsonPath + ".id", json["id"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "id");
+      }
+      String uri;
+      if (json.containsKey("uri")) {
+        uri = jsonDecoder.decodeString(jsonPath + ".uri", json["uri"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "uri");
+      }
+      List<AvailableSuggestion> items;
+      if (json.containsKey("items")) {
+        items = jsonDecoder.decodeList(
+            jsonPath + ".items",
+            json["items"],
+            (String jsonPath, Object json) =>
+                new AvailableSuggestion.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "items");
+      }
+      return new AvailableSuggestionSet(id, uri, items);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "AvailableSuggestionSet", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["id"] = id;
+    result["uri"] = uri;
+    result["items"] =
+        items.map((AvailableSuggestion value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is AvailableSuggestionSet) {
+      return id == other.id &&
+          uri == other.uri &&
+          listEqual(items, other.items,
+              (AvailableSuggestion a, AvailableSuggestion b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, id.hashCode);
+    hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+    hash = JenkinsSmiHash.combine(hash, items.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * ClosingLabel
  *
  * {
@@ -5196,6 +5605,417 @@
 }
 
 /**
+ * completion.availableSuggestions params
+ *
+ * {
+ *   "changedLibraries": optional List<AvailableSuggestionSet>
+ *   "removedLibraries": optional List<int>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionAvailableSuggestionsParams implements HasToJson {
+  List<AvailableSuggestionSet> _changedLibraries;
+
+  List<int> _removedLibraries;
+
+  /**
+   * A list of pre-computed, potential completions coming from this set of
+   * completion suggestions.
+   */
+  List<AvailableSuggestionSet> get changedLibraries => _changedLibraries;
+
+  /**
+   * A list of pre-computed, potential completions coming from this set of
+   * completion suggestions.
+   */
+  void set changedLibraries(List<AvailableSuggestionSet> value) {
+    this._changedLibraries = value;
+  }
+
+  /**
+   * A list of library ids that no longer apply.
+   */
+  List<int> get removedLibraries => _removedLibraries;
+
+  /**
+   * A list of library ids that no longer apply.
+   */
+  void set removedLibraries(List<int> value) {
+    this._removedLibraries = value;
+  }
+
+  CompletionAvailableSuggestionsParams(
+      {List<AvailableSuggestionSet> changedLibraries,
+      List<int> removedLibraries}) {
+    this.changedLibraries = changedLibraries;
+    this.removedLibraries = removedLibraries;
+  }
+
+  factory CompletionAvailableSuggestionsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<AvailableSuggestionSet> changedLibraries;
+      if (json.containsKey("changedLibraries")) {
+        changedLibraries = jsonDecoder.decodeList(
+            jsonPath + ".changedLibraries",
+            json["changedLibraries"],
+            (String jsonPath, Object json) =>
+                new AvailableSuggestionSet.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      List<int> removedLibraries;
+      if (json.containsKey("removedLibraries")) {
+        removedLibraries = jsonDecoder.decodeList(
+            jsonPath + ".removedLibraries",
+            json["removedLibraries"],
+            jsonDecoder.decodeInt);
+      }
+      return new CompletionAvailableSuggestionsParams(
+          changedLibraries: changedLibraries,
+          removedLibraries: removedLibraries);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.availableSuggestions params", json);
+    }
+  }
+
+  factory CompletionAvailableSuggestionsParams.fromNotification(
+      Notification notification) {
+    return new CompletionAvailableSuggestionsParams.fromJson(
+        new ResponseDecoder(null), "params", notification.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    if (changedLibraries != null) {
+      result["changedLibraries"] = changedLibraries
+          .map((AvailableSuggestionSet value) => value.toJson())
+          .toList();
+    }
+    if (removedLibraries != null) {
+      result["removedLibraries"] = removedLibraries;
+    }
+    return result;
+  }
+
+  Notification toNotification() {
+    return new Notification("completion.availableSuggestions", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionAvailableSuggestionsParams) {
+      return listEqual(changedLibraries, other.changedLibraries,
+              (AvailableSuggestionSet a, AvailableSuggestionSet b) => a == b) &&
+          listEqual(removedLibraries, other.removedLibraries,
+              (int a, int b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, changedLibraries.hashCode);
+    hash = JenkinsSmiHash.combine(hash, removedLibraries.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.getSuggestionDetails params
+ *
+ * {
+ *   "file": FilePath
+ *   "id": int
+ *   "label": String
+ *   "offset": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionGetSuggestionDetailsParams implements RequestParams {
+  String _file;
+
+  int _id;
+
+  String _label;
+
+  int _offset;
+
+  /**
+   * The path of the file into which this completion is being inserted.
+   */
+  String get file => _file;
+
+  /**
+   * The path of the file into which this completion is being inserted.
+   */
+  void set file(String value) {
+    assert(value != null);
+    this._file = value;
+  }
+
+  /**
+   * The identifier of the AvailableSuggestionSet containing the selected
+   * label.
+   */
+  int get id => _id;
+
+  /**
+   * The identifier of the AvailableSuggestionSet containing the selected
+   * label.
+   */
+  void set id(int value) {
+    assert(value != null);
+    this._id = value;
+  }
+
+  /**
+   * The label from the AvailableSuggestionSet with the `id` for which
+   * insertion information is requested.
+   */
+  String get label => _label;
+
+  /**
+   * The label from the AvailableSuggestionSet with the `id` for which
+   * insertion information is requested.
+   */
+  void set label(String value) {
+    assert(value != null);
+    this._label = value;
+  }
+
+  /**
+   * The offset in the file where the completion will be inserted.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset in the file where the completion will be inserted.
+   */
+  void set offset(int value) {
+    assert(value != null);
+    this._offset = value;
+  }
+
+  CompletionGetSuggestionDetailsParams(
+      String file, int id, String label, int offset) {
+    this.file = file;
+    this.id = id;
+    this.label = label;
+    this.offset = offset;
+  }
+
+  factory CompletionGetSuggestionDetailsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String file;
+      if (json.containsKey("file")) {
+        file = jsonDecoder.decodeString(jsonPath + ".file", json["file"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "file");
+      }
+      int id;
+      if (json.containsKey("id")) {
+        id = jsonDecoder.decodeInt(jsonPath + ".id", json["id"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "id");
+      }
+      String label;
+      if (json.containsKey("label")) {
+        label = jsonDecoder.decodeString(jsonPath + ".label", json["label"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "label");
+      }
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "offset");
+      }
+      return new CompletionGetSuggestionDetailsParams(file, id, label, offset);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.getSuggestionDetails params", json);
+    }
+  }
+
+  factory CompletionGetSuggestionDetailsParams.fromRequest(Request request) {
+    return new CompletionGetSuggestionDetailsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["file"] = file;
+    result["id"] = id;
+    result["label"] = label;
+    result["offset"] = offset;
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "completion.getSuggestionDetails", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionGetSuggestionDetailsParams) {
+      return file == other.file &&
+          id == other.id &&
+          label == other.label &&
+          offset == other.offset;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, file.hashCode);
+    hash = JenkinsSmiHash.combine(hash, id.hashCode);
+    hash = JenkinsSmiHash.combine(hash, label.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.getSuggestionDetails result
+ *
+ * {
+ *   "completion": String
+ *   "change": optional SourceChange
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionGetSuggestionDetailsResult implements ResponseResult {
+  String _completion;
+
+  SourceChange _change;
+
+  /**
+   * The full text to insert, including any optional import prefix.
+   */
+  String get completion => _completion;
+
+  /**
+   * The full text to insert, including any optional import prefix.
+   */
+  void set completion(String value) {
+    assert(value != null);
+    this._completion = value;
+  }
+
+  /**
+   * A change for the client to apply in case the library containing the
+   * accepted completion suggestion needs to be imported. The field will be
+   * omitted if there are no additional changes that need to be made.
+   */
+  SourceChange get change => _change;
+
+  /**
+   * A change for the client to apply in case the library containing the
+   * accepted completion suggestion needs to be imported. The field will be
+   * omitted if there are no additional changes that need to be made.
+   */
+  void set change(SourceChange value) {
+    this._change = value;
+  }
+
+  CompletionGetSuggestionDetailsResult(String completion,
+      {SourceChange change}) {
+    this.completion = completion;
+    this.change = change;
+  }
+
+  factory CompletionGetSuggestionDetailsResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String completion;
+      if (json.containsKey("completion")) {
+        completion = jsonDecoder.decodeString(
+            jsonPath + ".completion", json["completion"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "completion");
+      }
+      SourceChange change;
+      if (json.containsKey("change")) {
+        change = new SourceChange.fromJson(
+            jsonDecoder, jsonPath + ".change", json["change"]);
+      }
+      return new CompletionGetSuggestionDetailsResult(completion,
+          change: change);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.getSuggestionDetails result", json);
+    }
+  }
+
+  factory CompletionGetSuggestionDetailsResult.fromResponse(Response response) {
+    return new CompletionGetSuggestionDetailsResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        "result",
+        response.result);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["completion"] = completion;
+    if (change != null) {
+      result["change"] = change.toJson();
+    }
+    return result;
+  }
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionGetSuggestionDetailsResult) {
+      return completion == other.completion && change == other.change;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, completion.hashCode);
+    hash = JenkinsSmiHash.combine(hash, change.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * completion.getSuggestions params
  *
  * {
@@ -5391,6 +6211,130 @@
 }
 
 /**
+ * completion.registerLibraryPaths params
+ *
+ * {
+ *   "paths": List<LibraryPathSet>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionRegisterLibraryPathsParams implements RequestParams {
+  List<LibraryPathSet> _paths;
+
+  /**
+   * A list of objects each containing a path and the additional libraries from
+   * which the client is interested in receiving completion suggestions. If one
+   * configured path is beneath another, the descendent will override the
+   * ancestors' configured libraries of interest.
+   */
+  List<LibraryPathSet> get paths => _paths;
+
+  /**
+   * A list of objects each containing a path and the additional libraries from
+   * which the client is interested in receiving completion suggestions. If one
+   * configured path is beneath another, the descendent will override the
+   * ancestors' configured libraries of interest.
+   */
+  void set paths(List<LibraryPathSet> value) {
+    assert(value != null);
+    this._paths = value;
+  }
+
+  CompletionRegisterLibraryPathsParams(List<LibraryPathSet> paths) {
+    this.paths = paths;
+  }
+
+  factory CompletionRegisterLibraryPathsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<LibraryPathSet> paths;
+      if (json.containsKey("paths")) {
+        paths = jsonDecoder.decodeList(
+            jsonPath + ".paths",
+            json["paths"],
+            (String jsonPath, Object json) =>
+                new LibraryPathSet.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "paths");
+      }
+      return new CompletionRegisterLibraryPathsParams(paths);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.registerLibraryPaths params", json);
+    }
+  }
+
+  factory CompletionRegisterLibraryPathsParams.fromRequest(Request request) {
+    return new CompletionRegisterLibraryPathsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["paths"] =
+        paths.map((LibraryPathSet value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "completion.registerLibraryPaths", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionRegisterLibraryPathsParams) {
+      return listEqual(
+          paths, other.paths, (LibraryPathSet a, LibraryPathSet b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, paths.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.registerLibraryPaths result
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionRegisterLibraryPathsResult implements ResponseResult {
+  @override
+  Map<String, dynamic> toJson() => <String, dynamic>{};
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: null);
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionRegisterLibraryPathsResult) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return 104675661;
+  }
+}
+
+/**
  * completion.results params
  *
  * {
@@ -5399,6 +6343,9 @@
  *   "replacementLength": int
  *   "results": List<CompletionSuggestion>
  *   "isLast": bool
+ *   "includedSuggestionSets": optional List<IncludedSuggestionSet>
+ *   "includedSuggestionKinds": optional List<ElementKind>
+ *   "includedSuggestionRelevanceTags": optional List<IncludedSuggestionRelevanceTag>
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -5414,6 +6361,12 @@
 
   bool _isLast;
 
+  List<IncludedSuggestionSet> _includedSuggestionSets;
+
+  List<ElementKind> _includedSuggestionKinds;
+
+  List<IncludedSuggestionRelevanceTag> _includedSuggestionRelevanceTags;
+
   /**
    * The id associated with the completion.
    */
@@ -5499,13 +6452,92 @@
     this._isLast = value;
   }
 
+  /**
+   * This field is experimental.
+   *
+   * References to AvailableSuggestionSet objects previously sent to the
+   * client. The client can include applicable names from the referenced
+   * library in code completion suggestions.
+   */
+  List<IncludedSuggestionSet> get includedSuggestionSets =>
+      _includedSuggestionSets;
+
+  /**
+   * This field is experimental.
+   *
+   * References to AvailableSuggestionSet objects previously sent to the
+   * client. The client can include applicable names from the referenced
+   * library in code completion suggestions.
+   */
+  void set includedSuggestionSets(List<IncludedSuggestionSet> value) {
+    this._includedSuggestionSets = value;
+  }
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the ElementKind sent in
+   * IncludedSuggestionSet to decide whether or not these symbols should should
+   * be presented to the user.
+   */
+  List<ElementKind> get includedSuggestionKinds => _includedSuggestionKinds;
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the ElementKind sent in
+   * IncludedSuggestionSet to decide whether or not these symbols should should
+   * be presented to the user.
+   */
+  void set includedSuggestionKinds(List<ElementKind> value) {
+    this._includedSuggestionKinds = value;
+  }
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the values of the field
+   * relevanceTags of AvailableSuggestion to decide if the suggestion should be
+   * given a different relevance than the IncludedSuggestionSet that contains
+   * it. This might be used for example to give higher relevance to suggestions
+   * of matching types.
+   *
+   * If an AvailableSuggestion has relevance tags that match more than one
+   * IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
+   */
+  List<IncludedSuggestionRelevanceTag> get includedSuggestionRelevanceTags =>
+      _includedSuggestionRelevanceTags;
+
+  /**
+   * This field is experimental.
+   *
+   * The client is expected to check this list against the values of the field
+   * relevanceTags of AvailableSuggestion to decide if the suggestion should be
+   * given a different relevance than the IncludedSuggestionSet that contains
+   * it. This might be used for example to give higher relevance to suggestions
+   * of matching types.
+   *
+   * If an AvailableSuggestion has relevance tags that match more than one
+   * IncludedSuggestionRelevanceTag, the maximum relevance boost is used.
+   */
+  void set includedSuggestionRelevanceTags(
+      List<IncludedSuggestionRelevanceTag> value) {
+    this._includedSuggestionRelevanceTags = value;
+  }
+
   CompletionResultsParams(String id, int replacementOffset,
-      int replacementLength, List<CompletionSuggestion> results, bool isLast) {
+      int replacementLength, List<CompletionSuggestion> results, bool isLast,
+      {List<IncludedSuggestionSet> includedSuggestionSets,
+      List<ElementKind> includedSuggestionKinds,
+      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags}) {
     this.id = id;
     this.replacementOffset = replacementOffset;
     this.replacementLength = replacementLength;
     this.results = results;
     this.isLast = isLast;
+    this.includedSuggestionSets = includedSuggestionSets;
+    this.includedSuggestionKinds = includedSuggestionKinds;
+    this.includedSuggestionRelevanceTags = includedSuggestionRelevanceTags;
   }
 
   factory CompletionResultsParams.fromJson(
@@ -5550,8 +6582,37 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "isLast");
       }
+      List<IncludedSuggestionSet> includedSuggestionSets;
+      if (json.containsKey("includedSuggestionSets")) {
+        includedSuggestionSets = jsonDecoder.decodeList(
+            jsonPath + ".includedSuggestionSets",
+            json["includedSuggestionSets"],
+            (String jsonPath, Object json) =>
+                new IncludedSuggestionSet.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
+      List<ElementKind> includedSuggestionKinds;
+      if (json.containsKey("includedSuggestionKinds")) {
+        includedSuggestionKinds = jsonDecoder.decodeList(
+            jsonPath + ".includedSuggestionKinds",
+            json["includedSuggestionKinds"],
+            (String jsonPath, Object json) =>
+                new ElementKind.fromJson(jsonDecoder, jsonPath, json));
+      }
+      List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
+      if (json.containsKey("includedSuggestionRelevanceTags")) {
+        includedSuggestionRelevanceTags = jsonDecoder.decodeList(
+            jsonPath + ".includedSuggestionRelevanceTags",
+            json["includedSuggestionRelevanceTags"],
+            (String jsonPath, Object json) =>
+                new IncludedSuggestionRelevanceTag.fromJson(
+                    jsonDecoder, jsonPath, json));
+      }
       return new CompletionResultsParams(
-          id, replacementOffset, replacementLength, results, isLast);
+          id, replacementOffset, replacementLength, results, isLast,
+          includedSuggestionSets: includedSuggestionSets,
+          includedSuggestionKinds: includedSuggestionKinds,
+          includedSuggestionRelevanceTags: includedSuggestionRelevanceTags);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "completion.results params", json);
     }
@@ -5571,6 +6632,22 @@
     result["results"] =
         results.map((CompletionSuggestion value) => value.toJson()).toList();
     result["isLast"] = isLast;
+    if (includedSuggestionSets != null) {
+      result["includedSuggestionSets"] = includedSuggestionSets
+          .map((IncludedSuggestionSet value) => value.toJson())
+          .toList();
+    }
+    if (includedSuggestionKinds != null) {
+      result["includedSuggestionKinds"] = includedSuggestionKinds
+          .map((ElementKind value) => value.toJson())
+          .toList();
+    }
+    if (includedSuggestionRelevanceTags != null) {
+      result["includedSuggestionRelevanceTags"] =
+          includedSuggestionRelevanceTags
+              .map((IncludedSuggestionRelevanceTag value) => value.toJson())
+              .toList();
+    }
     return result;
   }
 
@@ -5589,7 +6666,17 @@
           replacementLength == other.replacementLength &&
           listEqual(results, other.results,
               (CompletionSuggestion a, CompletionSuggestion b) => a == b) &&
-          isLast == other.isLast;
+          isLast == other.isLast &&
+          listEqual(includedSuggestionSets, other.includedSuggestionSets,
+              (IncludedSuggestionSet a, IncludedSuggestionSet b) => a == b) &&
+          listEqual(includedSuggestionKinds, other.includedSuggestionKinds,
+              (ElementKind a, ElementKind b) => a == b) &&
+          listEqual(
+              includedSuggestionRelevanceTags,
+              other.includedSuggestionRelevanceTags,
+              (IncludedSuggestionRelevanceTag a,
+                      IncludedSuggestionRelevanceTag b) =>
+                  a == b);
     }
     return false;
   }
@@ -5602,11 +6689,191 @@
     hash = JenkinsSmiHash.combine(hash, replacementLength.hashCode);
     hash = JenkinsSmiHash.combine(hash, results.hashCode);
     hash = JenkinsSmiHash.combine(hash, isLast.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includedSuggestionSets.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includedSuggestionKinds.hashCode);
+    hash =
+        JenkinsSmiHash.combine(hash, includedSuggestionRelevanceTags.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
 
 /**
+ * CompletionService
+ *
+ * enum {
+ *   AVAILABLE_SUGGESTION_SETS
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionService implements Enum {
+  /**
+   * The client will receive notifications once subscribed with completion
+   * suggestion sets from the libraries of interest. The client should keep an
+   * up-to-date record of these in memory so that it will be able to union
+   * these candidates with other completion suggestions when applicable at
+   * completion time.
+   */
+  static const CompletionService AVAILABLE_SUGGESTION_SETS =
+      const CompletionService._("AVAILABLE_SUGGESTION_SETS");
+
+  /**
+   * A list containing all of the enum values that are defined.
+   */
+  static const List<CompletionService> VALUES = const <CompletionService>[
+    AVAILABLE_SUGGESTION_SETS
+  ];
+
+  @override
+  final String name;
+
+  const CompletionService._(this.name);
+
+  factory CompletionService(String name) {
+    switch (name) {
+      case "AVAILABLE_SUGGESTION_SETS":
+        return AVAILABLE_SUGGESTION_SETS;
+    }
+    throw new Exception('Illegal enum value: $name');
+  }
+
+  factory CompletionService.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json is String) {
+      try {
+        return new CompletionService(json);
+      } catch (_) {
+        // Fall through
+      }
+    }
+    throw jsonDecoder.mismatch(jsonPath, "CompletionService", json);
+  }
+
+  @override
+  String toString() => "CompletionService.$name";
+
+  String toJson() => name;
+}
+
+/**
+ * completion.setSubscriptions params
+ *
+ * {
+ *   "subscriptions": List<CompletionService>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionSetSubscriptionsParams implements RequestParams {
+  List<CompletionService> _subscriptions;
+
+  /**
+   * A list of the services being subscribed to.
+   */
+  List<CompletionService> get subscriptions => _subscriptions;
+
+  /**
+   * A list of the services being subscribed to.
+   */
+  void set subscriptions(List<CompletionService> value) {
+    assert(value != null);
+    this._subscriptions = value;
+  }
+
+  CompletionSetSubscriptionsParams(List<CompletionService> subscriptions) {
+    this.subscriptions = subscriptions;
+  }
+
+  factory CompletionSetSubscriptionsParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<CompletionService> subscriptions;
+      if (json.containsKey("subscriptions")) {
+        subscriptions = jsonDecoder.decodeList(
+            jsonPath + ".subscriptions",
+            json["subscriptions"],
+            (String jsonPath, Object json) =>
+                new CompletionService.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "subscriptions");
+      }
+      return new CompletionSetSubscriptionsParams(subscriptions);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "completion.setSubscriptions params", json);
+    }
+  }
+
+  factory CompletionSetSubscriptionsParams.fromRequest(Request request) {
+    return new CompletionSetSubscriptionsParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["subscriptions"] =
+        subscriptions.map((CompletionService value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "completion.setSubscriptions", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionSetSubscriptionsParams) {
+      return listEqual(subscriptions, other.subscriptions,
+          (CompletionService a, CompletionService b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, subscriptions.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * completion.setSubscriptions result
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class CompletionSetSubscriptionsResult implements ResponseResult {
+  @override
+  Map<String, dynamic> toJson() => <String, dynamic>{};
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: null);
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is CompletionSetSubscriptionsResult) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    return 2482770;
+  }
+}
+
+/**
  * ContextData
  *
  * {
@@ -5877,6 +7144,132 @@
 }
 
 /**
+ * DartFix
+ *
+ * {
+ *   "name": String
+ *   "description": optional String
+ *   "isRequired": optional bool
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class DartFix implements HasToJson {
+  String _name;
+
+  String _description;
+
+  bool _isRequired;
+
+  /**
+   * The name of the fix.
+   */
+  String get name => _name;
+
+  /**
+   * The name of the fix.
+   */
+  void set name(String value) {
+    assert(value != null);
+    this._name = value;
+  }
+
+  /**
+   * A human readable description of the fix.
+   */
+  String get description => _description;
+
+  /**
+   * A human readable description of the fix.
+   */
+  void set description(String value) {
+    this._description = value;
+  }
+
+  /**
+   * `true` if the fix is in the "required" fixes group.
+   */
+  bool get isRequired => _isRequired;
+
+  /**
+   * `true` if the fix is in the "required" fixes group.
+   */
+  void set isRequired(bool value) {
+    this._isRequired = value;
+  }
+
+  DartFix(String name, {String description, bool isRequired}) {
+    this.name = name;
+    this.description = description;
+    this.isRequired = isRequired;
+  }
+
+  factory DartFix.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String name;
+      if (json.containsKey("name")) {
+        name = jsonDecoder.decodeString(jsonPath + ".name", json["name"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "name");
+      }
+      String description;
+      if (json.containsKey("description")) {
+        description = jsonDecoder.decodeString(
+            jsonPath + ".description", json["description"]);
+      }
+      bool isRequired;
+      if (json.containsKey("isRequired")) {
+        isRequired = jsonDecoder.decodeBool(
+            jsonPath + ".isRequired", json["isRequired"]);
+      }
+      return new DartFix(name,
+          description: description, isRequired: isRequired);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "DartFix", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["name"] = name;
+    if (description != null) {
+      result["description"] = description;
+    }
+    if (isRequired != null) {
+      result["isRequired"] = isRequired;
+    }
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is DartFix) {
+      return name == other.name &&
+          description == other.description &&
+          isRequired == other.isRequired;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, name.hashCode);
+    hash = JenkinsSmiHash.combine(hash, description.hashCode);
+    hash = JenkinsSmiHash.combine(hash, isRequired.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * DartFixSuggestion
  *
  * {
@@ -6214,6 +7607,9 @@
  *
  * {
  *   "included": List<FilePath>
+ *   "includedFixes": optional List<String>
+ *   "includeRequiredFixes": optional bool
+ *   "excludedFixes": optional List<String>
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -6221,6 +7617,12 @@
 class EditDartfixParams implements RequestParams {
   List<String> _included;
 
+  List<String> _includedFixes;
+
+  bool _includeRequiredFixes;
+
+  List<String> _excludedFixes;
+
   /**
    * A list of the files and directories for which edits should be suggested.
    *
@@ -6248,8 +7650,62 @@
     this._included = value;
   }
 
-  EditDartfixParams(List<String> included) {
+  /**
+   * A list of names indicating which fixes should be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  List<String> get includedFixes => _includedFixes;
+
+  /**
+   * A list of names indicating which fixes should be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  void set includedFixes(List<String> value) {
+    this._includedFixes = value;
+  }
+
+  /**
+   * A flag indicating that "required" fixes should be applied.
+   */
+  bool get includeRequiredFixes => _includeRequiredFixes;
+
+  /**
+   * A flag indicating that "required" fixes should be applied.
+   */
+  void set includeRequiredFixes(bool value) {
+    this._includeRequiredFixes = value;
+  }
+
+  /**
+   * A list of names indicating which fixes should not be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  List<String> get excludedFixes => _excludedFixes;
+
+  /**
+   * A list of names indicating which fixes should not be applied.
+   *
+   * If a name is specified that does not match the name of a known fix, an
+   * error of type UNKNOWN_FIX will be generated.
+   */
+  void set excludedFixes(List<String> value) {
+    this._excludedFixes = value;
+  }
+
+  EditDartfixParams(List<String> included,
+      {List<String> includedFixes,
+      bool includeRequiredFixes,
+      List<String> excludedFixes}) {
     this.included = included;
+    this.includedFixes = includedFixes;
+    this.includeRequiredFixes = includeRequiredFixes;
+    this.excludedFixes = excludedFixes;
   }
 
   factory EditDartfixParams.fromJson(
@@ -6265,7 +7721,25 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "included");
       }
-      return new EditDartfixParams(included);
+      List<String> includedFixes;
+      if (json.containsKey("includedFixes")) {
+        includedFixes = jsonDecoder.decodeList(jsonPath + ".includedFixes",
+            json["includedFixes"], jsonDecoder.decodeString);
+      }
+      bool includeRequiredFixes;
+      if (json.containsKey("includeRequiredFixes")) {
+        includeRequiredFixes = jsonDecoder.decodeBool(
+            jsonPath + ".includeRequiredFixes", json["includeRequiredFixes"]);
+      }
+      List<String> excludedFixes;
+      if (json.containsKey("excludedFixes")) {
+        excludedFixes = jsonDecoder.decodeList(jsonPath + ".excludedFixes",
+            json["excludedFixes"], jsonDecoder.decodeString);
+      }
+      return new EditDartfixParams(included,
+          includedFixes: includedFixes,
+          includeRequiredFixes: includeRequiredFixes,
+          excludedFixes: excludedFixes);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "edit.dartfix params", json);
     }
@@ -6280,6 +7754,15 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["included"] = included;
+    if (includedFixes != null) {
+      result["includedFixes"] = includedFixes;
+    }
+    if (includeRequiredFixes != null) {
+      result["includeRequiredFixes"] = includeRequiredFixes;
+    }
+    if (excludedFixes != null) {
+      result["excludedFixes"] = excludedFixes;
+    }
     return result;
   }
 
@@ -6295,7 +7778,12 @@
   bool operator ==(other) {
     if (other is EditDartfixParams) {
       return listEqual(
-          included, other.included, (String a, String b) => a == b);
+              included, other.included, (String a, String b) => a == b) &&
+          listEqual(includedFixes, other.includedFixes,
+              (String a, String b) => a == b) &&
+          includeRequiredFixes == other.includeRequiredFixes &&
+          listEqual(excludedFixes, other.excludedFixes,
+              (String a, String b) => a == b);
     }
     return false;
   }
@@ -6304,6 +7792,9 @@
   int get hashCode {
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, included.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includedFixes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, includeRequiredFixes.hashCode);
+    hash = JenkinsSmiHash.combine(hash, excludedFixes.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -7267,6 +8758,152 @@
 }
 
 /**
+ * edit.getDartfixInfo params
+ *
+ * {
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class EditGetDartfixInfoParams implements RequestParams {
+  EditGetDartfixInfoParams();
+
+  factory EditGetDartfixInfoParams.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      return new EditGetDartfixInfoParams();
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "edit.getDartfixInfo params", json);
+    }
+  }
+
+  factory EditGetDartfixInfoParams.fromRequest(Request request) {
+    return new EditGetDartfixInfoParams.fromJson(
+        new RequestDecoder(request), "params", request.params);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    return result;
+  }
+
+  @override
+  Request toRequest(String id) {
+    return new Request(id, "edit.getDartfixInfo", toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is EditGetDartfixInfoParams) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * edit.getDartfixInfo result
+ *
+ * {
+ *   "fixes": List<DartFix>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class EditGetDartfixInfoResult implements ResponseResult {
+  List<DartFix> _fixes;
+
+  /**
+   * A list of fixes that can be specified in an edit.dartfix request.
+   */
+  List<DartFix> get fixes => _fixes;
+
+  /**
+   * A list of fixes that can be specified in an edit.dartfix request.
+   */
+  void set fixes(List<DartFix> value) {
+    assert(value != null);
+    this._fixes = value;
+  }
+
+  EditGetDartfixInfoResult(List<DartFix> fixes) {
+    this.fixes = fixes;
+  }
+
+  factory EditGetDartfixInfoResult.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      List<DartFix> fixes;
+      if (json.containsKey("fixes")) {
+        fixes = jsonDecoder.decodeList(
+            jsonPath + ".fixes",
+            json["fixes"],
+            (String jsonPath, Object json) =>
+                new DartFix.fromJson(jsonDecoder, jsonPath, json));
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "fixes");
+      }
+      return new EditGetDartfixInfoResult(fixes);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "edit.getDartfixInfo result", json);
+    }
+  }
+
+  factory EditGetDartfixInfoResult.fromResponse(Response response) {
+    return new EditGetDartfixInfoResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)),
+        "result",
+        response.result);
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["fixes"] = fixes.map((DartFix value) => value.toJson()).toList();
+    return result;
+  }
+
+  @override
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is EditGetDartfixInfoResult) {
+      return listEqual(fixes, other.fixes, (DartFix a, DartFix b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, fixes.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * edit.getFixes params
  *
  * {
@@ -14330,6 +15967,213 @@
 }
 
 /**
+ * IncludedSuggestionRelevanceTag
+ *
+ * {
+ *   "tag": AvailableSuggestionRelevanceTag
+ *   "relevanceBoost": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class IncludedSuggestionRelevanceTag implements HasToJson {
+  String _tag;
+
+  int _relevanceBoost;
+
+  /**
+   * The opaque value of the tag.
+   */
+  String get tag => _tag;
+
+  /**
+   * The opaque value of the tag.
+   */
+  void set tag(String value) {
+    assert(value != null);
+    this._tag = value;
+  }
+
+  /**
+   * The boost to the relevance of the completion suggestions that match this
+   * tag, which is added to the relevance of the containing
+   * IncludedSuggestionSet.
+   */
+  int get relevanceBoost => _relevanceBoost;
+
+  /**
+   * The boost to the relevance of the completion suggestions that match this
+   * tag, which is added to the relevance of the containing
+   * IncludedSuggestionSet.
+   */
+  void set relevanceBoost(int value) {
+    assert(value != null);
+    this._relevanceBoost = value;
+  }
+
+  IncludedSuggestionRelevanceTag(String tag, int relevanceBoost) {
+    this.tag = tag;
+    this.relevanceBoost = relevanceBoost;
+  }
+
+  factory IncludedSuggestionRelevanceTag.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String tag;
+      if (json.containsKey("tag")) {
+        tag = jsonDecoder.decodeString(jsonPath + ".tag", json["tag"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "tag");
+      }
+      int relevanceBoost;
+      if (json.containsKey("relevanceBoost")) {
+        relevanceBoost = jsonDecoder.decodeInt(
+            jsonPath + ".relevanceBoost", json["relevanceBoost"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "relevanceBoost");
+      }
+      return new IncludedSuggestionRelevanceTag(tag, relevanceBoost);
+    } else {
+      throw jsonDecoder.mismatch(
+          jsonPath, "IncludedSuggestionRelevanceTag", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["tag"] = tag;
+    result["relevanceBoost"] = relevanceBoost;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is IncludedSuggestionRelevanceTag) {
+      return tag == other.tag && relevanceBoost == other.relevanceBoost;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, tag.hashCode);
+    hash = JenkinsSmiHash.combine(hash, relevanceBoost.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * IncludedSuggestionSet
+ *
+ * {
+ *   "id": int
+ *   "relevance": int
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class IncludedSuggestionSet implements HasToJson {
+  int _id;
+
+  int _relevance;
+
+  /**
+   * Clients should use it to access the set of precomputed completions to be
+   * displayed to the user.
+   */
+  int get id => _id;
+
+  /**
+   * Clients should use it to access the set of precomputed completions to be
+   * displayed to the user.
+   */
+  void set id(int value) {
+    assert(value != null);
+    this._id = value;
+  }
+
+  /**
+   * The relevance of completion suggestions from this library where a higher
+   * number indicates a higher relevance.
+   */
+  int get relevance => _relevance;
+
+  /**
+   * The relevance of completion suggestions from this library where a higher
+   * number indicates a higher relevance.
+   */
+  void set relevance(int value) {
+    assert(value != null);
+    this._relevance = value;
+  }
+
+  IncludedSuggestionSet(int id, int relevance) {
+    this.id = id;
+    this.relevance = relevance;
+  }
+
+  factory IncludedSuggestionSet.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      int id;
+      if (json.containsKey("id")) {
+        id = jsonDecoder.decodeInt(jsonPath + ".id", json["id"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "id");
+      }
+      int relevance;
+      if (json.containsKey("relevance")) {
+        relevance =
+            jsonDecoder.decodeInt(jsonPath + ".relevance", json["relevance"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "relevance");
+      }
+      return new IncludedSuggestionSet(id, relevance);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "IncludedSuggestionSet", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["id"] = id;
+    result["relevance"] = relevance;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is IncludedSuggestionSet) {
+      return id == other.id && relevance == other.relevance;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, id.hashCode);
+    hash = JenkinsSmiHash.combine(hash, relevance.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * inlineLocalVariable feedback
  *
  * {
@@ -14905,6 +16749,113 @@
 }
 
 /**
+ * LibraryPathSet
+ *
+ * {
+ *   "scope": FilePath
+ *   "libraryPaths": List<FilePath>
+ * }
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class LibraryPathSet implements HasToJson {
+  String _scope;
+
+  List<String> _libraryPaths;
+
+  /**
+   * The filepath for which this request's libraries should be active in
+   * completion suggestions. This object associates filesystem regions to
+   * libraries and library directories of interest to the client.
+   */
+  String get scope => _scope;
+
+  /**
+   * The filepath for which this request's libraries should be active in
+   * completion suggestions. This object associates filesystem regions to
+   * libraries and library directories of interest to the client.
+   */
+  void set scope(String value) {
+    assert(value != null);
+    this._scope = value;
+  }
+
+  /**
+   * The paths of the libraries of interest to the client for completion
+   * suggestions.
+   */
+  List<String> get libraryPaths => _libraryPaths;
+
+  /**
+   * The paths of the libraries of interest to the client for completion
+   * suggestions.
+   */
+  void set libraryPaths(List<String> value) {
+    assert(value != null);
+    this._libraryPaths = value;
+  }
+
+  LibraryPathSet(String scope, List<String> libraryPaths) {
+    this.scope = scope;
+    this.libraryPaths = libraryPaths;
+  }
+
+  factory LibraryPathSet.fromJson(
+      JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String scope;
+      if (json.containsKey("scope")) {
+        scope = jsonDecoder.decodeString(jsonPath + ".scope", json["scope"]);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "scope");
+      }
+      List<String> libraryPaths;
+      if (json.containsKey("libraryPaths")) {
+        libraryPaths = jsonDecoder.decodeList(jsonPath + ".libraryPaths",
+            json["libraryPaths"], jsonDecoder.decodeString);
+      } else {
+        throw jsonDecoder.mismatch(jsonPath, "libraryPaths");
+      }
+      return new LibraryPathSet(scope, libraryPaths);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "LibraryPathSet", json);
+    }
+  }
+
+  @override
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["scope"] = scope;
+    result["libraryPaths"] = libraryPaths;
+    return result;
+  }
+
+  @override
+  String toString() => json.encode(toJson());
+
+  @override
+  bool operator ==(other) {
+    if (other is LibraryPathSet) {
+      return scope == other.scope &&
+          listEqual(
+              libraryPaths, other.libraryPaths, (String a, String b) => a == b);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = JenkinsSmiHash.combine(hash, scope.hashCode);
+    hash = JenkinsSmiHash.combine(hash, libraryPaths.hashCode);
+    return JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * moveFile feedback
  *
  * Clients may not extend, implement or mix-in this class.
@@ -15953,6 +17904,7 @@
  *   SERVER_ERROR
  *   SORT_MEMBERS_INVALID_FILE
  *   SORT_MEMBERS_PARSE_ERRORS
+ *   UNKNOWN_FIX
  *   UNKNOWN_REQUEST
  *   UNSUPPORTED_FEATURE
  * }
@@ -16143,6 +18095,13 @@
       const RequestErrorCode._("SORT_MEMBERS_PARSE_ERRORS");
 
   /**
+   * A dartfix request was received containing the name of a fix which does not
+   * match the name of any known fixes.
+   */
+  static const RequestErrorCode UNKNOWN_FIX =
+      const RequestErrorCode._("UNKNOWN_FIX");
+
+  /**
    * A request was received which the analysis server does not recognize, or
    * cannot handle in its current configuration.
    */
@@ -16189,6 +18148,7 @@
     SERVER_ERROR,
     SORT_MEMBERS_INVALID_FILE,
     SORT_MEMBERS_PARSE_ERRORS,
+    UNKNOWN_FIX,
     UNKNOWN_REQUEST,
     UNSUPPORTED_FEATURE
   ];
@@ -16252,6 +18212,8 @@
         return SORT_MEMBERS_INVALID_FILE;
       case "SORT_MEMBERS_PARSE_ERRORS":
         return SORT_MEMBERS_PARSE_ERRORS;
+      case "UNKNOWN_FIX":
+        return UNKNOWN_FIX;
       case "UNKNOWN_REQUEST":
         return UNKNOWN_REQUEST;
       case "UNSUPPORTED_FEATURE":
diff --git a/pkg/analysis_server_client/pubspec.yaml b/pkg/analysis_server_client/pubspec.yaml
index 9632e84..fc2de5b 100644
--- a/pkg/analysis_server_client/pubspec.yaml
+++ b/pkg/analysis_server_client/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analysis_server_client
-version: 1.1.1
+version: 1.1.2
 author: Dart Team <misc@dartlang.org>
 description:
   A client wrapper over analysis_server.
diff --git a/pkg/analysis_tool/README.md b/pkg/analysis_tool/README.md
new file mode 100644
index 0000000..c94b407
--- /dev/null
+++ b/pkg/analysis_tool/README.md
@@ -0,0 +1,3 @@
+A set of utilities used by the tools in several analyzer-related packages.
+
+Not meant to be published.
diff --git a/pkg/analyzer/lib/src/codegen/html.dart b/pkg/analysis_tool/lib/html.dart
similarity index 100%
rename from pkg/analyzer/lib/src/codegen/html.dart
rename to pkg/analysis_tool/lib/html.dart
diff --git a/pkg/analysis_tool/lib/text_formatter.dart b/pkg/analysis_tool/lib/text_formatter.dart
new file mode 100644
index 0000000..2305910
--- /dev/null
+++ b/pkg/analysis_tool/lib/text_formatter.dart
@@ -0,0 +1,245 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Code for converting HTML into text, for use during code generation of
+ * analyzer and analysis server.
+ */
+
+import 'package:analysis_tool/tools.dart';
+import 'package:html/dom.dart' as dom;
+
+final RegExp whitespace = new RegExp(r'\s');
+
+/**
+ * Convert the HTML in [desc] into text, word wrapping at width [width].
+ *
+ * If [javadocStyle] is true, then the output is compatible with Javadoc,
+ * which understands certain HTML constructs.
+ */
+String nodesToText(List<dom.Node> desc, int width, bool javadocStyle,
+    {bool removeTrailingNewLine: false}) {
+  _TextFormatter formatter = new _TextFormatter(width, javadocStyle);
+  return formatter.collectCode(() {
+    formatter.addAll(desc);
+    formatter.lineBreak(false);
+  }, removeTrailingNewLine: removeTrailingNewLine);
+}
+
+/**
+ * Engine that transforms HTML to text.  The input HTML is processed one
+ * character at a time, gathering characters into words and words into lines.
+ */
+class _TextFormatter extends CodeGenerator {
+  /**
+   * Word-wrapping width.
+   */
+  final int width;
+
+  /**
+   * The word currently being gathered.
+   */
+  String word = '';
+
+  /**
+   * The line currently being gathered.
+   */
+  String line = '';
+
+  /**
+   * True if a blank line should be inserted before the next word.
+   */
+  bool verticalSpaceNeeded = false;
+
+  /**
+   * True if no text has been output yet.  This suppresses blank lines.
+   */
+  bool atStart = true;
+
+  /**
+   * True if we are processing a <pre> element, thus whitespace should be
+   * preserved.
+   */
+  bool preserveSpaces = false;
+
+  /**
+   * True if the output should be Javadoc compatible.
+   */
+  final bool javadocStyle;
+
+  _TextFormatter(this.width, this.javadocStyle);
+
+  /**
+   * Process an HTML node.
+   */
+  void add(dom.Node node) {
+    if (node is dom.Text) {
+      for (String char in node.text.split('')) {
+        if (preserveSpaces) {
+          wordBreak();
+          write(escape(char));
+        } else if (whitespace.hasMatch(char)) {
+          wordBreak();
+        } else {
+          resolveVerticalSpace();
+          word += escape(char);
+        }
+      }
+    } else if (node is dom.Element) {
+      switch (node.localName) {
+        case 'br':
+          lineBreak(false);
+          break;
+        case 'dl':
+        case 'dt':
+        case 'h1':
+        case 'h2':
+        case 'h3':
+        case 'h4':
+        case 'p':
+          lineBreak(true);
+          addAll(node.nodes);
+          lineBreak(true);
+          break;
+        case 'div':
+          lineBreak(false);
+          if (node.classes.contains('hangingIndent')) {
+            resolveVerticalSpace();
+            indentSpecial('', '        ', () {
+              addAll(node.nodes);
+              lineBreak(false);
+            });
+          } else {
+            addAll(node.nodes);
+            lineBreak(false);
+          }
+          break;
+        case 'ul':
+          lineBreak(false);
+          addAll(node.nodes);
+          lineBreak(false);
+          break;
+        case 'li':
+          lineBreak(false);
+          resolveVerticalSpace();
+          indentSpecial('- ', '  ', () {
+            addAll(node.nodes);
+            lineBreak(false);
+          });
+          break;
+        case 'dd':
+          lineBreak(true);
+          indent(() {
+            addAll(node.nodes);
+            lineBreak(true);
+          });
+          break;
+        case 'pre':
+          lineBreak(false);
+          resolveVerticalSpace();
+          if (javadocStyle) {
+            writeln('<pre>');
+          }
+          bool oldPreserveSpaces = preserveSpaces;
+          try {
+            preserveSpaces = true;
+            addAll(node.nodes);
+          } finally {
+            preserveSpaces = oldPreserveSpaces;
+          }
+          writeln();
+          if (javadocStyle) {
+            writeln('</pre>');
+          }
+          lineBreak(false);
+          break;
+        case 'a':
+        case 'b':
+        case 'body':
+        case 'html':
+        case 'i':
+        case 'span':
+        case 'tt':
+          addAll(node.nodes);
+          break;
+        case 'head':
+          break;
+        default:
+          throw new Exception('Unexpected HTML element: ${node.localName}');
+      }
+    } else {
+      throw new Exception('Unexpected HTML: $node');
+    }
+  }
+
+  /**
+   * Process a list of HTML nodes.
+   */
+  void addAll(List<dom.Node> nodes) {
+    for (dom.Node node in nodes) {
+      add(node);
+    }
+  }
+
+  /**
+   * Escape the given character for HTML.
+   */
+  String escape(String char) {
+    if (javadocStyle) {
+      switch (char) {
+        case '<':
+          return '&lt;';
+        case '>':
+          return '&gt;';
+        case '&':
+          return '&amp;';
+      }
+    }
+    return char;
+  }
+
+  /**
+   * Terminate the current word and/or line, if either is in progress.
+   */
+  void lineBreak(bool gap) {
+    wordBreak();
+    if (line.isNotEmpty) {
+      writeln(line);
+      line = '';
+    }
+    if (gap && !atStart) {
+      verticalSpaceNeeded = true;
+    }
+  }
+
+  /**
+   * Insert vertical space if necessary.
+   */
+  void resolveVerticalSpace() {
+    if (verticalSpaceNeeded) {
+      writeln();
+      verticalSpaceNeeded = false;
+    }
+  }
+
+  /**
+   * Terminate the current word, if a word is in progress.
+   */
+  void wordBreak() {
+    if (word.isNotEmpty) {
+      atStart = false;
+      if (line.isNotEmpty) {
+        if (indentWidth + line.length + 1 + word.length <= width) {
+          line += ' $word';
+        } else {
+          writeln(line);
+          line = word;
+        }
+      } else {
+        line = word;
+      }
+      word = '';
+    }
+  }
+}
diff --git a/pkg/analysis_tool/lib/tools.dart b/pkg/analysis_tool/lib/tools.dart
new file mode 100644
index 0000000..0e35b61
--- /dev/null
+++ b/pkg/analysis_tool/lib/tools.dart
@@ -0,0 +1,648 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Tools for generating code in analyzer and analysis server.
+ */
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analysis_tool/html.dart';
+import 'package:analysis_tool/text_formatter.dart';
+import 'package:html/dom.dart' as dom;
+import 'package:path/path.dart';
+
+final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
+final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
+
+/**
+ * Join the given strings using camelCase.  If [doCapitalize] is true, the first
+ * part will be capitalized as well.
+ */
+String camelJoin(List<String> parts, {bool doCapitalize: false}) {
+  List<String> upcasedParts = <String>[];
+  for (int i = 0; i < parts.length; i++) {
+    if (i == 0 && !doCapitalize) {
+      upcasedParts.add(parts[i]);
+    } else {
+      upcasedParts.add(capitalize(parts[i]));
+    }
+  }
+  return upcasedParts.join();
+}
+
+/**
+ * Capitalize and return the passed String.
+ */
+String capitalize(String string) {
+  return string[0].toUpperCase() + string.substring(1);
+}
+
+/**
+ * Type of functions used to compute the contents of a set of generated files.
+ * [pkgPath] is the path to the current package.
+ */
+typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
+    String pkgPath);
+
+/**
+ * Type of functions used to compute the contents of a generated file.
+ * [pkgPath] is the path to the current package.
+ */
+typedef Future<String> FileContentsComputer(String pkgPath);
+
+/**
+ * Mixin class for generating code.
+ */
+class CodeGenerator {
+  _CodeGeneratorState _state;
+
+  /**
+   * Settings that specialize code generation behavior for a given
+   * programming language.
+   */
+  CodeGeneratorSettings codeGeneratorSettings = new CodeGeneratorSettings();
+
+  /**
+   * Measure the width of the current indentation level.
+   */
+  int get indentWidth => _state.nextIndent.length;
+
+  /**
+   * Execute [callback], collecting any code that is output using [write]
+   * or [writeln], and return the result as a string.
+   */
+  String collectCode(void callback(), {bool removeTrailingNewLine: false}) {
+    _CodeGeneratorState oldState = _state;
+    try {
+      _state = new _CodeGeneratorState();
+      callback();
+      var text =
+          _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, '');
+      if (!removeTrailingNewLine) {
+        return text;
+      } else {
+        return text.replaceAll(trailingWhitespaceRegExp, '');
+      }
+    } finally {
+      _state = oldState;
+    }
+  }
+
+  /**
+   * Generate a doc comment based on the HTML in [docs].
+   *
+   * When generating java code, the output is compatible with Javadoc, which
+   * understands certain HTML constructs.
+   */
+  void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
+    if (containsOnlyWhitespace(docs)) return;
+    if (codeGeneratorSettings.docCommentStartMarker != null)
+      writeln(codeGeneratorSettings.docCommentStartMarker);
+    int width = codeGeneratorSettings.commentLineLength;
+    bool javadocStyle = codeGeneratorSettings.languageName == 'java';
+    indentBy(codeGeneratorSettings.docCommentLineLeader, () {
+      write(nodesToText(docs, width - _state.indent.length, javadocStyle,
+          removeTrailingNewLine: removeTrailingNewLine));
+    });
+    if (codeGeneratorSettings.docCommentEndMarker != null)
+      writeln(codeGeneratorSettings.docCommentEndMarker);
+  }
+
+  /**
+   * Execute [callback], indenting any code it outputs.
+   */
+  void indent(void callback()) {
+    indentSpecial(
+        codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback);
+  }
+
+  /**
+   * Execute [callback], using [additionalIndent] to indent any code it outputs.
+   */
+  void indentBy(String additionalIndent, void callback()) =>
+      indentSpecial(additionalIndent, additionalIndent, callback);
+
+  /**
+   * Execute [callback], using [additionalIndent] to indent any code it outputs.
+   * The first line of output is indented by [firstAdditionalIndent] instead of
+   * [additionalIndent].
+   */
+  void indentSpecial(
+      String firstAdditionalIndent, String additionalIndent, void callback()) {
+    String oldNextIndent = _state.nextIndent;
+    String oldIndent = _state.indent;
+    try {
+      _state.nextIndent += firstAdditionalIndent;
+      _state.indent += additionalIndent;
+      callback();
+    } finally {
+      _state.nextIndent = oldNextIndent;
+      _state.indent = oldIndent;
+    }
+  }
+
+  void lineComment(List<dom.Node> docs) {
+    if (containsOnlyWhitespace(docs)) {
+      return;
+    }
+    write(codeGeneratorSettings.lineCommentLineLeader);
+    int width = codeGeneratorSettings.commentLineLength;
+    indentBy(codeGeneratorSettings.lineCommentLineLeader, () {
+      write(nodesToText(docs, width - _state.indent.length, false));
+    });
+  }
+
+  void outputHeader({bool javaStyle: false, String year = null}) {
+    String header;
+    if (codeGeneratorSettings.languageName == 'java') {
+      header = '''
+/*
+ * Copyright (c) ${year ?? '2018'}, the Dart project authors. Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ *
+ * This file has been automatically generated. Please do not edit it manually.
+ * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
+ */''';
+    } else if (codeGeneratorSettings.languageName == 'python') {
+      header = '''
+# Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# This file has been automatically generated. Please do not edit it manually.
+# To regenerate the file, use the script
+# "pkg/analysis_server/tool/spec/generate_files".
+''';
+    } else {
+      header = '''
+// Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This file has been automatically generated. Please do not edit it manually.
+// To regenerate the file, use the script
+// "pkg/analysis_server/tool/spec/generate_files".
+''';
+    }
+    writeln(header.trim());
+  }
+
+  /**
+   * Output text without ending the current line.
+   */
+  void write(Object obj) {
+    _state.write(obj.toString());
+  }
+
+  /**
+   * Output text, ending the current line.
+   */
+  void writeln([Object obj = '']) {
+    _state.write('$obj\n');
+  }
+}
+
+/**
+ * Controls several settings of [CodeGenerator].
+ *
+ * The default settings are valid for generating Java and Dart code.
+ */
+class CodeGeneratorSettings {
+  /**
+   * Name of the language being generated. Lowercase.
+   */
+  String languageName;
+
+  /**
+   * Marker used in line comments.
+   */
+  String lineCommentLineLeader;
+
+  /**
+   * Start marker for doc comments.
+   */
+  String docCommentStartMarker;
+
+  /**
+   * Line leader for body lines in doc comments.
+   */
+  String docCommentLineLeader;
+
+  /**
+   * End marker for doc comments.
+   */
+  String docCommentEndMarker;
+
+  /**
+   * Line length for doc comment lines.
+   */
+  int commentLineLength;
+
+  /**
+   * String used for indenting code.
+   */
+  String indent;
+
+  CodeGeneratorSettings(
+      {this.languageName: 'java',
+      this.lineCommentLineLeader: '// ',
+      this.docCommentStartMarker: '/**',
+      this.docCommentLineLeader: ' * ',
+      this.docCommentEndMarker: ' */',
+      this.commentLineLength: 99,
+      this.indent: '  '});
+}
+
+/**
+ * A utility class for invoking dartfmt.
+ */
+class DartFormat {
+  static String get _dartfmtPath {
+    String binName = Platform.isWindows ? 'dartfmt.bat' : 'dartfmt';
+    for (var loc in [binName, join('dart-sdk', 'bin', binName)]) {
+      var candidatePath = join(dirname(Platform.resolvedExecutable), loc);
+      if (new File(candidatePath).existsSync()) {
+        return candidatePath;
+      }
+    }
+    throw new StateError('Could not find dartfmt executable');
+  }
+
+  static void formatFile(File file) {
+    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
+    if (result.exitCode != 0) throw result.stderr;
+  }
+
+  static String formatText(String text) {
+    File file = new File(join(Directory.systemTemp.path, 'gen.dart'));
+    file.writeAsStringSync(text);
+    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
+    if (result.exitCode != 0) throw result.stderr;
+    return file.readAsStringSync();
+  }
+}
+
+/**
+ * Abstract base class representing behaviors common to generated files and
+ * generated directories.
+ */
+abstract class GeneratedContent {
+  /**
+   * Check whether the [output] has the correct contents, and return true if it
+   * does.  [pkgPath] is the path to the current package.
+   */
+  Future<bool> check(String pkgPath);
+
+  /**
+   * Replace the [output] with the correct contents.  [pkgPath] is the path to
+   * the current package.
+   */
+  Future<void> generate(String pkgPath);
+
+  /**
+   * Get a [FileSystemEntity] representing the output file or directory.
+   * [pkgPath] is the path to the current package.
+   */
+  FileSystemEntity output(String pkgPath);
+
+  /**
+   * Check that all of the [targets] are up to date.  If they are not, print
+   * out a message instructing the user to regenerate them, and exit with a
+   * nonzero error code.
+   *
+   * [pkgPath] is the path to the current package.  [generatorRelPath] is the
+   * path to a .dart script the user may use to regenerate the targets.
+   *
+   * To avoid mistakes when run on Windows, [generatorRelPath] always uses
+   * POSIX directory separators.
+   */
+  static Future<void> checkAll(String pkgPath, String generatorRelPath,
+      Iterable<GeneratedContent> targets) async {
+    bool generateNeeded = false;
+    for (GeneratedContent target in targets) {
+      bool ok = await target.check(pkgPath);
+      if (!ok) {
+        print("${target.output(pkgPath).absolute}"
+            " doesn't have expected contents.");
+        generateNeeded = true;
+      }
+    }
+    if (generateNeeded) {
+      print('Please regenerate using:');
+      String executable = Platform.executable;
+      String packageRoot = '';
+      // ignore: deprecated_member_use
+      if (Platform.packageRoot != null) {
+        // ignore: deprecated_member_use
+        packageRoot = ' --package-root=${Platform.packageRoot}';
+      }
+      String generateScript =
+          join(pkgPath, joinAll(posix.split(generatorRelPath)));
+      print('  $executable$packageRoot $generateScript');
+      exit(1);
+    } else {
+      print('All generated files up to date.');
+    }
+  }
+
+  /**
+   * Regenerate all of the [targets].  [pkgPath] is the path to the current
+   * package.
+   */
+  static Future<void> generateAll(
+      String pkgPath, Iterable<GeneratedContent> targets) async {
+    print("Generating...");
+    for (GeneratedContent target in targets) {
+      await target.generate(pkgPath);
+    }
+  }
+}
+
+/**
+ * Class representing a single output directory (either generated code or
+ * generated HTML). No other content should exist in the directory.
+ */
+class GeneratedDirectory extends GeneratedContent {
+  /**
+   * The path to the directory that will have the generated content.
+   */
+  final String outputDirPath;
+
+  /**
+   * Callback function that computes the directory contents.
+   */
+  final DirectoryContentsComputer directoryContentsComputer;
+
+  GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
+
+  @override
+  Future<bool> check(String pkgPath) async {
+    Directory outputDirectory = output(pkgPath);
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
+    try {
+      for (String file in map.keys) {
+        FileContentsComputer fileContentsComputer = map[file];
+        String expectedContents = await fileContentsComputer(pkgPath);
+        File outputFile = new File(posix.join(outputDirectory.path, file));
+        String actualContents = outputFile.readAsStringSync();
+        // Normalize Windows line endings to Unix line endings so that the
+        // comparison doesn't fail on Windows.
+        actualContents = actualContents.replaceAll('\r\n', '\n');
+        if (expectedContents != actualContents) {
+          return false;
+        }
+      }
+      int nonHiddenFileCount = 0;
+      outputDirectory
+          .listSync(recursive: false, followLinks: false)
+          .forEach((FileSystemEntity fileSystemEntity) {
+        if (fileSystemEntity is File &&
+            !basename(fileSystemEntity.path).startsWith('.')) {
+          nonHiddenFileCount++;
+        }
+      });
+      if (nonHiddenFileCount != map.length) {
+        // The number of files generated doesn't match the number we expected to
+        // generate.
+        return false;
+      }
+    } catch (e) {
+      // There was a problem reading the file (most likely because it didn't
+      // exist).  Treat that the same as if the file doesn't have the expected
+      // contents.
+      return false;
+    }
+    return true;
+  }
+
+  @override
+  Future<void> generate(String pkgPath) async {
+    Directory outputDirectory = output(pkgPath);
+    try {
+      // delete the contents of the directory (and the directory itself)
+      outputDirectory.deleteSync(recursive: true);
+    } catch (e) {
+      // Error caught while trying to delete the directory, this can happen if
+      // it didn't yet exist.
+    }
+    // re-create the empty directory
+    outputDirectory.createSync(recursive: true);
+
+    // generate all of the files in the directory
+    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
+    for (String file in map.keys) {
+      FileContentsComputer fileContentsComputer = map[file];
+      File outputFile = new File(posix.join(outputDirectory.path, file));
+      print('  ${outputFile.path}');
+      String contents = await fileContentsComputer(pkgPath);
+      outputFile.writeAsStringSync(contents);
+    }
+  }
+
+  @override
+  Directory output(String pkgPath) =>
+      new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
+}
+
+/**
+ * Class representing a single output file (either generated code or generated
+ * HTML).
+ */
+class GeneratedFile extends GeneratedContent {
+  /**
+   * The output file to which generated output should be written, relative to
+   * the "tool/spec" directory.  This filename uses the posix path separator
+   * ('/') regardless of the OS.
+   */
+  final String outputPath;
+
+  /**
+   * Callback function which computes the file.
+   */
+  final FileContentsComputer computeContents;
+
+  GeneratedFile(this.outputPath, this.computeContents);
+
+  bool get isDartFile => outputPath.endsWith('.dart');
+
+  @override
+  Future<bool> check(String pkgPath) async {
+    File outputFile = output(pkgPath);
+    String expectedContents = await computeContents(pkgPath);
+    if (isDartFile) {
+      expectedContents = DartFormat.formatText(expectedContents);
+    }
+    try {
+      String actualContents = outputFile.readAsStringSync();
+      // Normalize Windows line endings to Unix line endings so that the
+      // comparison doesn't fail on Windows.
+      actualContents = actualContents.replaceAll('\r\n', '\n');
+      return expectedContents == actualContents;
+    } catch (e) {
+      // There was a problem reading the file (most likely because it didn't
+      // exist).  Treat that the same as if the file doesn't have the expected
+      // contents.
+      return false;
+    }
+  }
+
+  @override
+  Future<void> generate(String pkgPath) async {
+    File outputFile = output(pkgPath);
+    print('  ${outputFile.path}');
+    String contents = await computeContents(pkgPath);
+    outputFile.writeAsStringSync(contents);
+    if (isDartFile) {
+      DartFormat.formatFile(outputFile);
+    }
+  }
+
+  @override
+  File output(String pkgPath) =>
+      new File(join(pkgPath, joinAll(posix.split(outputPath))));
+}
+
+/**
+ * Mixin class for generating HTML representations of code that are suitable
+ * for enclosing inside a <pre> element.
+ */
+abstract class HtmlCodeGenerator {
+  _HtmlCodeGeneratorState _state;
+
+  /**
+   * Add the given [node] to the HTML output.
+   */
+  void add(dom.Node node) {
+    _state.add(node);
+  }
+
+  /**
+   * Add the given [nodes] to the HTML output.
+   */
+  void addAll(Iterable<dom.Node> nodes) {
+    for (dom.Node node in nodes) {
+      _state.add(node);
+    }
+  }
+
+  /**
+   * Execute [callback], collecting any code that is output using [write],
+   * [writeln], [add], or [addAll], and return the result as a list of DOM
+   * nodes.
+   */
+  List<dom.Node> collectHtml(void callback()) {
+    _HtmlCodeGeneratorState oldState = _state;
+    try {
+      _state = new _HtmlCodeGeneratorState();
+      if (callback != null) {
+        callback();
+      }
+      return _state.buffer;
+    } finally {
+      _state = oldState;
+    }
+  }
+
+  /**
+   * Execute [callback], wrapping its output in an element with the given
+   * [name] and [attributes].
+   */
+  void element(String name, Map<dynamic, String> attributes,
+      [void callback()]) {
+    add(makeElement(name, attributes, collectHtml(callback)));
+  }
+
+  /**
+   * Execute [callback], indenting any code it outputs by two spaces.
+   */
+  void indent(void callback()) {
+    String oldIndent = _state.indent;
+    try {
+      _state.indent += '  ';
+      callback();
+    } finally {
+      _state.indent = oldIndent;
+    }
+  }
+
+  /**
+   * Output text without ending the current line.
+   */
+  void write(Object obj) {
+    _state.write(obj.toString());
+  }
+
+  /**
+   * Output text, ending the current line.
+   */
+  void writeln([Object obj = '']) {
+    _state.write('$obj\n');
+  }
+}
+
+/**
+ * State used by [CodeGenerator].
+ */
+class _CodeGeneratorState {
+  StringBuffer buffer = new StringBuffer();
+  String nextIndent = '';
+  String indent = '';
+  bool indentNeeded = true;
+
+  void write(String text) {
+    List<String> lines = text.split('\n');
+    for (int i = 0; i < lines.length; i++) {
+      if (i == lines.length - 1 && lines[i].isEmpty) {
+        break;
+      }
+      if (indentNeeded) {
+        buffer.write(nextIndent);
+        nextIndent = indent;
+      }
+      indentNeeded = false;
+      buffer.write(lines[i]);
+      if (i != lines.length - 1) {
+        buffer.writeln();
+        indentNeeded = true;
+      }
+    }
+  }
+}
+
+/**
+ * State used by [HtmlCodeGenerator].
+ */
+class _HtmlCodeGeneratorState {
+  List<dom.Node> buffer = <dom.Node>[];
+  String indent = '';
+  bool indentNeeded = true;
+
+  void add(dom.Node node) {
+    if (node is dom.Text) {
+      write(node.text);
+    } else {
+      buffer.add(node);
+    }
+  }
+
+  void write(String text) {
+    if (text.isEmpty) {
+      return;
+    }
+    if (indentNeeded) {
+      buffer.add(new dom.Text(indent));
+    }
+    List<String> lines = text.split('\n');
+    if (lines.last.isEmpty) {
+      lines.removeLast();
+      buffer.add(new dom.Text(lines.join('\n$indent') + '\n'));
+      indentNeeded = true;
+    } else {
+      buffer.add(new dom.Text(lines.join('\n$indent')));
+      indentNeeded = false;
+    }
+  }
+}
diff --git a/pkg/analysis_tool/pubspec.yaml b/pkg/analysis_tool/pubspec.yaml
new file mode 100644
index 0000000..57ab3ee
--- /dev/null
+++ b/pkg/analysis_tool/pubspec.yaml
@@ -0,0 +1,9 @@
+name: analysis_tool
+publish_to: none
+
+environment:
+  sdk: '>=2.1.0 <3.0.0'
+
+dependencies:
+  html: any
+  path: any
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 5a574ca..591419d 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,6 +1,60 @@
+## 0.35.1
+* The new "set literals" language feature is now enabled by default.
+* The dev_dependency analysis_tool was created so that clients do not have to
+  depend on code that is used internally in the analyzer at development time.
+* The `InheritanceManager` class is now deprecated.  The new
+  `InheritanceManager2` class now supports accessing inherited interface/class
+  maps.
+* Added quick assists to support set literals.
+* Added the ability for linter tests to drive the analyzer using custom analysis
+  options.
+* Updated support in the AST structure for the control_flow_collections and
+  spread_collections experiments.  The new AST structures are still in
+  development.
+* Bug fixes: #34437, #35127, #35141, #35306, #35621.
+
+## 0.35.0
+* Added support in the AST structure for the control_flow_collections and
+  spread_collections experiments. This includes adding new visitor methods to
+  `AstVisitor`, which will need to be implemented by any classes that implement
+  `AstVisitor` directly. Concrete implementations were added to other visitor
+  classes (such as `RecursiveAstVisitor`) so that clients that extend those
+  other classes will not be impacted.
+* Removed `EMPTY_LIST` constants.  Please use `const <...>[]` instead.
+* Disabled support for the task model.  Please use the new `AnalysisSession`
+  API.
+* Removed `StrongTypeSystemImpl`.  Please use `Dart2TypeSystem` instead.
+* Made ERROR the default severity for StaticWarningCode.  We no longer need to
+  promote warnings to errors in "strong mode" because strong mode is the only
+  mode.
+* Added exact type analysis for set literals (#35742).
+* Bug fixes: #35305, #35750.
+
+## 0.34.3
+* Non-breaking AST changes in support for the control_flow_collections and
+  spread_collections experiments.  Clients who wish to begin adding support for
+  these experiments can depend on this release of the analyzer and begin writing
+  visit methods.  The visit methods won't be added to the AstVisitor base class
+  until 0.35.0.
+* Bug fixes: #35551, #35708, #35723.
+
 ## 0.34.2
 * Removed support for the `@checked` annotation.  Please use the `covariant`
-  keyword instead.
+  keyword instead (#28797).
+* Did additional work on the new set_literals and constant_update_2018 features.
+* Began adding a string representation of initializer expressions to summaries
+  (#35418).
+* Added a pub aware workspace so that pub packages can be handled properly.
+* Added logging in an effort to track down #35551.
+* Split off DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE from DEPRECATED_MEMBER_USE
+  (#30084).
+* Removed the unused hint code INVALID_ASSIGNMENT.
+* Added a hint enforcing the contract of `@literal`:
+  NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR.
+* Added a hint INVALID_LITERAL_ANNOTATION (#34259).
+* Fixed handling of @immutable on mixins.
+* Did work on @sealed annotation for classes and mixins.
+* Bug fixes: #25860, #29394, #33930, #35090, #35441, #35458, #35467, #35548.
 
 ## 0.34.1
 * Added logic to report a hint if a deprecated lint is specified in the user's
diff --git a/pkg/analyzer/README.md b/pkg/analyzer/README.md
index d633684..f2f9b6a 100644
--- a/pkg/analyzer/README.md
+++ b/pkg/analyzer/README.md
@@ -64,6 +64,9 @@
     - camel_case_types
 ```
 
+For more information, see the docs for
+[customizing static analysis][custom_analysis].
+
 ## Who uses this library?
 
 Many tools embed this library, such as:
@@ -104,3 +107,4 @@
 [dartfmt]: https://github.com/dart-lang/dart_style
 [dartdoc]: https://github.com/dart-lang/dartdoc
 [analysis_sever]: https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server
+[custom_analysis]: https://www.dartlang.org/guides/language/analysis-options
diff --git a/pkg/analyzer/lib/dart/analysis/results.dart b/pkg/analyzer/lib/dart/analysis/results.dart
index 55defb7..7f82c94 100644
--- a/pkg/analyzer/lib/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/dart/analysis/results.dart
@@ -89,7 +89,7 @@
 /// those discovered during scanning and parsing.
 ///
 /// Clients may not extend, implement or mix-in this class.
-// ignore: deprecated_member_use
+// ignore: deprecated_member_use_from_same_package
 abstract class ParsedUnitResult implements ParseResult {}
 
 /// The result of parsing of a single file. The errors returned include only
@@ -128,7 +128,7 @@
 /// include both syntactic and semantic errors.
 ///
 /// Clients may not extend, implement or mix-in this class.
-// ignore: deprecated_member_use
+// ignore: deprecated_member_use_from_same_package
 abstract class ResolvedUnitResult implements ResolveResult {}
 
 /// The result of building a resolved AST for a single file. The errors returned
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 2378850..3bf434e 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2,38 +2,36 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/**
- * Defines the AST model. The AST (Abstract Syntax Tree) model describes the
- * syntactic (as opposed to semantic) structure of Dart code. The semantic
- * structure of the code is modeled by the
- * [element model](../dart_element_element/dart_element_element-library.html).
- *
- * An AST consists of nodes (instances of a subclass of [AstNode]). The nodes
- * are organized in a tree structure in which the children of a node are the
- * smaller syntactic units from which the node is composed. For example, a
- * binary expression consists of two sub-expressions (the operands) and an
- * operator. The two expressions are represented as nodes. The operator is not
- * represented as a node.
- *
- * The AST is constructed by the parser based on the sequence of tokens produced
- * by the scanner. Most nodes provide direct access to the tokens used to build
- * the node. For example, the token for the operator in a binary expression can
- * be accessed from the node representing the binary expression.
- *
- * While any node can theoretically be the root of an AST structure, almost all
- * of the AST structures known to the analyzer have a [CompilationUnit] as the
- * root of the structure. A compilation unit represents all of the Dart code in
- * a single file.
- *
- * An AST can be either unresolved or resolved. When an AST is unresolved
- * certain properties will not have been computed and the accessors for those
- * properties will return `null`. The documentation for those getters should
- * describe that this is a possibility.
- *
- * When an AST is resolved, the identifiers in the AST will be associated with
- * the elements that they refer to and every expression in the AST will have a
- * type associated with it.
- */
+/// Defines the AST model. The AST (Abstract Syntax Tree) model describes the
+/// syntactic (as opposed to semantic) structure of Dart code. The semantic
+/// structure of the code is modeled by the
+/// [element model](../dart_element_element/dart_element_element-library.html).
+///
+/// An AST consists of nodes (instances of a subclass of [AstNode]). The nodes
+/// are organized in a tree structure in which the children of a node are the
+/// smaller syntactic units from which the node is composed. For example, a
+/// binary expression consists of two sub-expressions (the operands) and an
+/// operator. The two expressions are represented as nodes. The operator is not
+/// represented as a node.
+///
+/// The AST is constructed by the parser based on the sequence of tokens
+/// produced by the scanner. Most nodes provide direct access to the tokens used
+/// to build the node. For example, the token for the operator in a binary
+/// expression can be accessed from the node representing the binary expression.
+///
+/// While any node can theoretically be the root of an AST structure, almost all
+/// of the AST structures known to the analyzer have a [CompilationUnit] as the
+/// root of the structure. A compilation unit represents all of the Dart code in
+/// a single file.
+///
+/// An AST can be either unresolved or resolved. When an AST is unresolved
+/// certain properties will not have been computed and the accessors for those
+/// properties will return `null`. The documentation for those getters should
+/// describe that this is a possibility.
+///
+/// When an AST is resolved, the identifiers in the AST will be associated with
+/// the elements that they refer to and every expression in the AST will have a
+/// type associated with it.
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -43,455 +41,313 @@
 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
-/**
- * Two or more string literals that are implicitly concatenated because of being
- * adjacent (separated only by whitespace).
- *
- * While the grammar only allows adjacent strings when all of the strings are of
- * the same kind (single line or multi-line), this class doesn't enforce that
- * restriction.
- *
- *    adjacentStrings ::=
- *        [StringLiteral] [StringLiteral]+
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class AdjacentStrings extends StringLiteral {
-  /**
-   * Return the strings that are implicitly concatenated.
-   */
+/// Two or more string literals that are implicitly concatenated because of
+/// being adjacent (separated only by whitespace).
+///
+/// While the grammar only allows adjacent strings when all of the strings are
+/// of the same kind (single line or multi-line), this class doesn't enforce
+/// that restriction.
+///
+///    adjacentStrings ::=
+///        [StringLiteral] [StringLiteral]+
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class AdjacentStrings implements StringLiteral {
+  /// Return the strings that are implicitly concatenated.
   NodeList<StringLiteral> get strings;
 }
 
-/**
- * An AST node that can be annotated with both a documentation comment and a
- * list of annotations.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class AnnotatedNode extends AstNode {
-  /**
-   * Return the documentation comment associated with this node, or `null` if
-   * this node does not have a documentation comment associated with it.
-   */
+/// An AST node that can be annotated with both a documentation comment and a
+/// list of annotations.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class AnnotatedNode implements AstNode {
+  /// Return the documentation comment associated with this node, or `null` if
+  /// this node does not have a documentation comment associated with it.
   Comment get documentationComment;
 
-  /**
-   * Set the documentation comment associated with this node to the given
-   * [comment].
-   */
+  /// Set the documentation comment associated with this node to the given
+  /// [comment].
   void set documentationComment(Comment comment);
 
-  /**
-   * Return the first token following the comment and metadata.
-   */
+  /// Return the first token following the comment and metadata.
   Token get firstTokenAfterCommentAndMetadata;
 
-  /**
-   * Return the annotations associated with this node.
-   */
+  /// Return the annotations associated with this node.
   NodeList<Annotation> get metadata;
 
-  /**
-   * Return a list containing the comment and annotations associated with this
-   * node, sorted in lexical order.
-   */
+  /// Return a list containing the comment and annotations associated with this
+  /// node, sorted in lexical order.
   List<AstNode> get sortedCommentAndAnnotations;
 }
 
-/**
- * An annotation that can be associated with an AST node.
- *
- *    metadata ::=
- *        annotation*
- *
- *    annotation ::=
- *        '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Annotation extends AstNode {
-  /**
-   * Return the arguments to the constructor being invoked, or `null` if this
-   * annotation is not the invocation of a constructor.
-   */
+/// An annotation that can be associated with an AST node.
+///
+///    metadata ::=
+///        annotation*
+///
+///    annotation ::=
+///        '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Annotation implements AstNode {
+  /// Return the arguments to the constructor being invoked, or `null` if this
+  /// annotation is not the invocation of a constructor.
   ArgumentList get arguments;
 
-  /**
-   * Set the arguments to the constructor being invoked to the given [arguments].
-   */
+  /// Set the arguments to the constructor being invoked to the given
+  /// [arguments].
   void set arguments(ArgumentList arguments);
 
-  /**
-   * Return the at sign that introduced the annotation.
-   */
+  /// Return the at sign that introduced the annotation.
   Token get atSign;
 
-  /**
-   * Set the at sign that introduced the annotation to the given [token].
-   */
+  /// Set the at sign that introduced the annotation to the given [token].
   void set atSign(Token token);
 
-  /**
-   * Return the name of the constructor being invoked, or `null` if this
-   * annotation is not the invocation of a named constructor.
-   */
+  /// Return the name of the constructor being invoked, or `null` if this
+  /// annotation is not the invocation of a named constructor.
   SimpleIdentifier get constructorName;
 
-  /**
-   * Set the name of the constructor being invoked to the given [name].
-   */
+  /// Set the name of the constructor being invoked to the given [name].
   void set constructorName(SimpleIdentifier name);
 
-  /**
-   * Return the element associated with this annotation, or `null` if the AST
-   * structure has not been resolved or if this annotation could not be
-   * resolved.
-   */
+  /// Return the element associated with this annotation, or `null` if the AST
+  /// structure has not been resolved or if this annotation could not be
+  /// resolved.
   Element get element;
 
-  /**
-   * Set the element associated with this annotation to the given [element].
-   */
+  /// Set the element associated with this annotation to the given [element].
   void set element(Element element);
 
-  /**
-   * Return the element annotation representing this annotation in the element model.
-   */
+  /// Return the element annotation representing this annotation in the element
+  /// model.
   ElementAnnotation get elementAnnotation;
 
-  /**
-   * Set the element annotation representing this annotation in the element
-   * model to the given [annotation].
-   */
+  /// Set the element annotation representing this annotation in the element
+  /// model to the given [annotation].
   void set elementAnnotation(ElementAnnotation annotation);
 
-  /**
-   * Return the name of the class defining the constructor that is being invoked
-   * or the name of the field that is being referenced.
-   */
+  /// Return the name of the class defining the constructor that is being
+  /// invoked or the name of the field that is being referenced.
   Identifier get name;
 
-  /**
-   * Set the name of the class defining the constructor that is being invoked or
-   * the name of the field that is being referenced to the given [name].
-   */
+  /// Set the name of the class defining the constructor that is being invoked
+  /// or the name of the field that is being referenced to the given [name].
   void set name(Identifier name);
 
-  /**
-   * Return the period before the constructor name, or `null` if this annotation
-   * is not the invocation of a named constructor.
-   */
+  /// Return the period before the constructor name, or `null` if this
+  /// annotation is not the invocation of a named constructor.
   Token get period;
 
-  /**
-   * Set the period before the constructor name to the given [token].
-   */
+  /// Set the period before the constructor name to the given [token].
   void set period(Token token);
 }
 
-/**
- * A list of arguments in the invocation of an executable element (that is, a
- * function, method, or constructor).
- *
- *    argumentList ::=
- *        '(' arguments? ')'
- *
- *    arguments ::=
- *        [NamedExpression] (',' [NamedExpression])*
- *      | [Expression] (',' [Expression])* (',' [NamedExpression])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ArgumentList extends AstNode {
-  /**
-   * Return the expressions producing the values of the arguments. Although the
-   * language requires that positional arguments appear before named arguments,
-   * this class allows them to be intermixed.
-   */
+/// A list of arguments in the invocation of an executable element (that is, a
+/// function, method, or constructor).
+///
+///    argumentList ::=
+///        '(' arguments? ')'
+///
+///    arguments ::=
+///        [NamedExpression] (',' [NamedExpression])*
+///      | [Expression] (',' [Expression])* (',' [NamedExpression])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ArgumentList implements AstNode {
+  /// Return the expressions producing the values of the arguments. Although the
+  /// language requires that positional arguments appear before named arguments,
+  /// this class allows them to be intermixed.
   NodeList<Expression> get arguments;
 
-  /**
-   * Set the parameter elements corresponding to each of the arguments in this
-   * list to the given list of [parameters]. The list of parameters must be the
-   * same length as the number of arguments, but can contain `null` entries if a
-   * given argument does not correspond to a formal parameter.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [correspondingStaticParameters] instead.
-   */
+  /// Set the parameter elements corresponding to each of the arguments in this
+  /// list to the given list of [parameters]. The list of parameters must be the
+  /// same length as the number of arguments, but can contain `null` entries if
+  /// a given argument does not correspond to a formal parameter.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [correspondingStaticParameters] instead.
   @deprecated
   void set correspondingPropagatedParameters(List<ParameterElement> parameters);
 
-  /**
-   * Set the parameter elements corresponding to each of the arguments in this
-   * list to the given list of [parameters]. The list of parameters must be the
-   * same length as the number of arguments, but can contain `null` entries if a
-   * given argument does not correspond to a formal parameter.
-   */
+  /// Set the parameter elements corresponding to each of the arguments in this
+  /// list to the given list of [parameters]. The list of parameters must be the
+  /// same length as the number of arguments, but can contain `null` entries if
+  /// a given argument does not correspond to a formal parameter.
   void set correspondingStaticParameters(List<ParameterElement> parameters);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 }
 
-/**
- * An as expression.
- *
- *    asExpression ::=
- *        [Expression] 'as' [TypeAnnotation]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class AsExpression extends Expression {
-  /**
-   * Return the 'as' operator.
-   */
+/// An as expression.
+///
+///    asExpression ::=
+///        [Expression] 'as' [TypeAnnotation]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class AsExpression implements Expression {
+  /// Return the 'as' operator.
   Token get asOperator;
 
-  /**
-   * Set the 'as' operator to the given [token].
-   */
+  /// Set the 'as' operator to the given [token].
   void set asOperator(Token token);
 
-  /**
-   * Return the expression used to compute the value being cast.
-   */
+  /// Return the expression used to compute the value being cast.
   Expression get expression;
 
-  /**
-   * Set the expression used to compute the value being cast to the given
-   * [expression].
-   */
+  /// Set the expression used to compute the value being cast to the given
+  /// [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the type being cast to.
-   */
+  /// Return the type being cast to.
   TypeAnnotation get type;
 
-  /**
-   * Set the type being cast to to the given [type].
-   */
+  /// Set the type being cast to to the given [type].
   void set type(TypeAnnotation type);
 }
 
-/**
- * An assert in the initializer list of a constructor.
- *
- *    assertInitializer ::=
- *        'assert' '(' [Expression] (',' [Expression])? ')'
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// An assert in the initializer list of a constructor.
+///
+///    assertInitializer ::=
+///        'assert' '(' [Expression] (',' [Expression])? ')'
+///
+/// Clients may not extend, implement or mix-in this class.
 abstract class AssertInitializer implements Assertion, ConstructorInitializer {}
 
-/**
- * An assertion, either in a block or in the initializer list of a constructor.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// An assertion, either in a block or in the initializer list of a constructor.
+///
+/// Clients may not extend, implement or mix-in this class.
 abstract class Assertion implements AstNode {
-  /**
-   * Return the token representing the 'assert' keyword.
-   */
+  /// Return the token representing the 'assert' keyword.
   Token get assertKeyword;
 
-  /**
-   * Set the token representing the 'assert' keyword to the given [token].
-   */
+  /// Set the token representing the 'assert' keyword to the given [token].
   void set assertKeyword(Token token);
 
-  /**
-   * Return the comma between the [condition] and the [message], or `null` if no
-   * message was supplied.
-   */
+  /// Return the comma between the [condition] and the [message], or `null` if
+  /// no message was supplied.
   Token get comma;
 
-  /**
-   * Set the comma between the [condition] and the [message] to the given
-   * [token].
-   */
+  /// Set the comma between the [condition] and the [message] to the given
+  /// [token].
   void set comma(Token token);
 
-  /**
-   * Return the condition that is being asserted to be `true`.
-   */
+  /// Return the condition that is being asserted to be `true`.
   Expression get condition;
 
-  /**
-   * Set the condition that is being asserted to be `true` to the given
-   * [condition].
-   */
+  /// Set the condition that is being asserted to be `true` to the given
+  /// [condition].
   void set condition(Expression condition);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the message to report if the assertion fails, or `null` if no
-   * message was supplied.
-   */
+  /// Return the message to report if the assertion fails, or `null` if no
+  /// message was supplied.
   Expression get message;
 
-  /**
-   * Set the message to report if the assertion fails to the given
-   * [expression].
-   */
+  /// Set the message to report if the assertion fails to the given
+  /// [expression].
   void set message(Expression expression);
 
-  /**
-   *  Return the right parenthesis.
-   */
+  ///  Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   *  Set the right parenthesis to the given [token].
-   */
+  ///  Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 }
 
-/**
- * An assert statement.
- *
- *    assertStatement ::=
- *        'assert' '(' [Expression] (',' [Expression])? ')' ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// An assert statement.
+///
+///    assertStatement ::=
+///        'assert' '(' [Expression] (',' [Expression])? ')' ';'
+///
+/// Clients may not extend, implement or mix-in this class.
 abstract class AssertStatement implements Assertion, Statement {
-  /**
-   * Return the semicolon terminating the statement.
-   */
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * An assignment expression.
- *
- *    assignmentExpression ::=
- *        [Expression] operator [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class AssignmentExpression extends Expression
-    implements MethodReferenceExpression {
-  /**
-   * Return the expression used to compute the left hand side.
-   */
+/// An assignment expression.
+///
+///    assignmentExpression ::=
+///        [Expression] operator [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class AssignmentExpression
+    implements Expression, MethodReferenceExpression {
+  /// Return the expression used to compute the left hand side.
   Expression get leftHandSide;
 
-  /**
-   * Return the expression used to compute the left hand side.
-   */
+  /// Return the expression used to compute the left hand side.
   void set leftHandSide(Expression expression);
 
-  /**
-   * Return the assignment operator being applied.
-   */
+  /// Return the assignment operator being applied.
   Token get operator;
 
-  /**
-   * Set the assignment operator being applied to the given [token].
-   */
+  /// Set the assignment operator being applied to the given [token].
   void set operator(Token token);
 
-  /**
-   * Return the expression used to compute the right hand side.
-   */
+  /// Return the expression used to compute the right hand side.
   Expression get rightHandSide;
 
-  /**
-   * Set the expression used to compute the left hand side to the given
-   * [expression].
-   */
+  /// Set the expression used to compute the left hand side to the given
+  /// [expression].
   void set rightHandSide(Expression expression);
 }
 
-/**
- * A node in the AST structure for a Dart program.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// A node in the AST structure for a Dart program.
+///
+/// Clients may not extend, implement or mix-in this class.
 abstract class AstNode implements SyntacticEntity {
-  /**
-   * An empty list of AST nodes.
-   */
-  @deprecated
-  static const List<AstNode> EMPTY_LIST = const <AstNode>[];
-
-  /**
-   * A comparator that can be used to sort AST nodes in lexical order. In other
-   * words, `compare` will return a negative value if the offset of the first
-   * node is less than the offset of the second node, zero (0) if the nodes have
-   * the same offset, and a positive value if the offset of the first node is
-   * greater than the offset of the second node.
-   */
+  /// A comparator that can be used to sort AST nodes in lexical order. In other
+  /// words, `compare` will return a negative value if the offset of the first
+  /// node is less than the offset of the second node, zero (0) if the nodes
+  /// have the same offset, and a positive value if the offset of the first node
+  /// is greater than the offset of the second node.
   static Comparator<AstNode> LEXICAL_ORDER =
       (AstNode first, AstNode second) => first.offset - second.offset;
 
-  /**
-   * Return the first token included in this node's source range.
-   */
+  /// Return the first token included in this node's source range.
   Token get beginToken;
 
-  /**
-   * Return an iterator that can be used to iterate through all the entities
-   * (either AST nodes or tokens) that make up the contents of this node,
-   * including doc comments but excluding other comments.
-   */
+  /// Return an iterator that can be used to iterate through all the entities
+  /// (either AST nodes or tokens) that make up the contents of this node,
+  /// including doc comments but excluding other comments.
   Iterable<SyntacticEntity> get childEntities;
 
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this node's source range. This is equivalent to
-   * `node.getOffset() + node.getLength()`. For a compilation unit this will be
-   * equal to the length of the unit's source. For synthetic nodes this will be
-   * equivalent to the node's offset (because the length is zero (0) by
-   * definition).
-   */
+  /// Return the offset of the character immediately following the last
+  /// character of this node's source range. This is equivalent to
+  /// `node.getOffset() + node.getLength()`. For a compilation unit this will be
+  /// equal to the length of the unit's source. For synthetic nodes this will be
+  /// equivalent to the node's offset (because the length is zero (0) by
+  /// definition).
   @override
   int get end;
 
-  /**
-   * Return the last token included in this node's source range.
-   */
+  /// Return the last token included in this node's source range.
   Token get endToken;
 
-  /**
-   * Return `true` if this node is a synthetic node. A synthetic node is a node
-   * that was introduced by the parser in order to recover from an error in the
-   * code. Synthetic nodes always have a length of zero (`0`).
-   */
+  /// Return `true` if this node is a synthetic node. A synthetic node is a node
+  /// that was introduced by the parser in order to recover from an error in the
+  /// code. Synthetic nodes always have a length of zero (`0`).
   bool get isSynthetic;
 
   @override
@@ -500,91 +356,68 @@
   @override
   int get offset;
 
-  /**
-   * Return this node's parent node, or `null` if this node is the root of an
-   * AST structure.
-   *
-   * Note that the relationship between an AST node and its parent node may
-   * change over the lifetime of a node.
-   */
+  /// Return this node's parent node, or `null` if this node is the root of an
+  /// AST structure.
+  ///
+  /// Note that the relationship between an AST node and its parent node may
+  /// change over the lifetime of a node.
   AstNode get parent;
 
-  /**
-   * Return the node at the root of this node's AST structure. Note that this
-   * method's performance is linear with respect to the depth of the node in the
-   * AST structure (O(depth)).
-   */
+  /// Return the node at the root of this node's AST structure. Note that this
+  /// method's performance is linear with respect to the depth of the node in
+  /// the AST structure (O(depth)).
   AstNode get root;
 
-  /**
-   * Use the given [visitor] to visit this node. Return the value returned by
-   * the visitor as a result of visiting this node.
-   */
+  /// Use the given [visitor] to visit this node. Return the value returned by
+  /// the visitor as a result of visiting this node.
   E accept<E>(AstVisitor<E> visitor);
 
-  /**
-   * Return the token before [target] or `null` if it cannot be found.
-   */
+  /// Return the token before [target] or `null` if it cannot be found.
   Token findPrevious(Token target);
 
-  /**
-   * Return the most immediate ancestor of this node for which the [predicate]
-   * returns `true`, or `null` if there is no such ancestor. Note that this node
-   * will never be returned.
-   */
+  /// Return the most immediate ancestor of this node for which the [predicate]
+  /// returns `true`, or `null` if there is no such ancestor. Note that this
+  /// node will never be returned.
   @deprecated
   E getAncestor<E extends AstNode>(Predicate<AstNode> predicate);
 
-  /**
-   * Return the value of the property with the given [name], or `null` if this
-   * node does not have a property with the given name.
-   */
+  /// Return the value of the property with the given [name], or `null` if this
+  /// node does not have a property with the given name.
   E getProperty<E>(String name);
 
-  /**
-   * Set the value of the property with the given [name] to the given [value].
-   * If the value is `null`, the property will effectively be removed.
-   */
+  /// Set the value of the property with the given [name] to the given [value].
+  /// If the value is `null`, the property will effectively be removed.
   void setProperty(String name, Object value);
 
-  /**
-   * Return either this node or the most immediate ancestor of this node for
-   * which the [predicate] returns `true`, or `null` if there is no such node.
-   */
+  /// Return either this node or the most immediate ancestor of this node for
+  /// which the [predicate] returns `true`, or `null` if there is no such node.
   E thisOrAncestorMatching<E extends AstNode>(Predicate<AstNode> predicate);
 
-  /**
-   * Return either this node or the most immediate ancestor of this node that
-   * has the given type, or `null` if there is no such node.
-   */
+  /// Return either this node or the most immediate ancestor of this node that
+  /// has the given type, or `null` if there is no such node.
   T thisOrAncestorOfType<T extends AstNode>();
 
-  /**
-   * Return a textual description of this node in a form approximating valid
-   * source. The returned string will not be valid source primarily in the case
-   * where the node itself is not well-formed.
-   */
+  /// Return a textual description of this node in a form approximating valid
+  /// source. The returned string will not be valid source primarily in the case
+  /// where the node itself is not well-formed.
   String toSource();
 
-  /**
-   * Use the given [visitor] to visit all of the children of this node. The
-   * children will be visited in lexical order.
-   */
+  /// Use the given [visitor] to visit all of the children of this node. The
+  /// children will be visited in lexical order.
   void visitChildren(AstVisitor visitor);
 }
 
-/**
- * An object that can be used to visit an AST structure.
- *
- * Clients may not extend, implement or mix-in this class. There are classes
- * that implement this interface that provide useful default behaviors in
- * `package:analyzer/dart/ast/visitor.dart`. A couple of the most useful include
- * * SimpleAstVisitor which implements every visit method by doing nothing,
- * * RecursiveAstVisitor which will cause every node in a structure to be
- *   visited, and
- * * ThrowingAstVisitor which implements every visit method by throwing an
- *   exception.
- */
+/// An object that can be used to visit an AST structure.
+///
+/// Clients may not extend, implement or mix-in this class. There are classes
+/// that implement this interface that provide useful default behaviors in
+/// `package:analyzer/dart/ast/visitor.dart`. A couple of the most useful
+/// include
+/// * SimpleAstVisitor which implements every visit method by doing nothing,
+/// * RecursiveAstVisitor which will cause every node in a structure to be
+///   visited, and
+/// * ThrowingAstVisitor which implements every visit method by throwing an
+///   exception.
 abstract class AstVisitor<R> {
   R visitAdjacentStrings(AdjacentStrings node);
 
@@ -668,12 +501,24 @@
 
   R visitFieldFormalParameter(FieldFormalParameter node);
 
+  R visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node);
+
+  R visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node);
+
   R visitForEachStatement(ForEachStatement node);
 
+  R visitForElement(ForElement node);
+
   R visitFormalParameterList(FormalParameterList node);
 
+  R visitForPartsWithDeclarations(ForPartsWithDeclarations node);
+
+  R visitForPartsWithExpression(ForPartsWithExpression node);
+
   R visitForStatement(ForStatement node);
 
+  R visitForStatement2(ForStatement2 node);
+
   R visitFunctionDeclaration(FunctionDeclaration node);
 
   R visitFunctionDeclarationStatement(FunctionDeclarationStatement node);
@@ -692,6 +537,8 @@
 
   R visitHideCombinator(HideCombinator node);
 
+  R visitIfElement(IfElement node);
+
   R visitIfStatement(IfStatement node);
 
   R visitImplementsClause(ImplementsClause node);
@@ -720,8 +567,12 @@
 
   R visitListLiteral(ListLiteral node);
 
+  R visitListLiteral2(ListLiteral2 node);
+
   R visitMapLiteral(MapLiteral node);
 
+  R visitMapLiteral2(MapLiteral2 node);
+
   R visitMapLiteralEntry(MapLiteralEntry node);
 
   R visitMethodDeclaration(MethodDeclaration node);
@@ -765,6 +616,8 @@
 
   R visitSetLiteral(SetLiteral node);
 
+  R visitSetLiteral2(SetLiteral2 node);
+
   R visitShowCombinator(ShowCombinator node);
 
   R visitSimpleFormalParameter(SimpleFormalParameter node);
@@ -773,6 +626,8 @@
 
   R visitSimpleStringLiteral(SimpleStringLiteral node);
 
+  R visitSpreadElement(SpreadElement node);
+
   R visitStringInterpolation(StringInterpolation node);
 
   R visitSuperConstructorInvocation(SuperConstructorInvocation node);
@@ -816,1069 +671,758 @@
   R visitYieldStatement(YieldStatement node);
 }
 
-/**
- * An await expression.
- *
- *    awaitExpression ::=
- *        'await' [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class AwaitExpression extends Expression {
-  /**
-   * Return the 'await' keyword.
-   */
+/// An await expression.
+///
+///    awaitExpression ::=
+///        'await' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class AwaitExpression implements Expression {
+  /// Return the 'await' keyword.
   Token get awaitKeyword;
 
-  /**
-   * Set the 'await' keyword to the given [token].
-   */
+  /// Set the 'await' keyword to the given [token].
   void set awaitKeyword(Token token);
 
-  /**
-   * Return the expression whose value is being waited on.
-   */
+  /// Return the expression whose value is being waited on.
   Expression get expression;
 
-  /**
-   * Set the expression whose value is being waited on to the given [expression].
-   */
+  /// Set the expression whose value is being waited on to the given
+  /// [expression].
   void set expression(Expression expression);
 }
 
-/**
- * A binary (infix) expression.
- *
- *    binaryExpression ::=
- *        [Expression] [Token] [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class BinaryExpression extends Expression
-    implements MethodReferenceExpression {
-  /**
-   * Return the expression used to compute the left operand.
-   */
+/// A binary (infix) expression.
+///
+///    binaryExpression ::=
+///        [Expression] [Token] [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class BinaryExpression
+    implements Expression, MethodReferenceExpression {
+  /// Return the expression used to compute the left operand.
   Expression get leftOperand;
 
-  /**
-   * Set the expression used to compute the left operand to the given
-   * [expression].
-   */
+  /// Set the expression used to compute the left operand to the given
+  /// [expression].
   void set leftOperand(Expression expression);
 
-  /**
-   * Return the binary operator being applied.
-   */
+  /// Return the binary operator being applied.
   Token get operator;
 
-  /**
-   * Set the binary operator being applied to the given [token].
-   */
+  /// Set the binary operator being applied to the given [token].
   void set operator(Token token);
 
-  /**
-   * Return the expression used to compute the right operand.
-   */
+  /// Return the expression used to compute the right operand.
   Expression get rightOperand;
 
-  /**
-   * Set the expression used to compute the right operand to the given
-   * [expression].
-   */
+  /// Set the expression used to compute the right operand to the given
+  /// [expression].
   void set rightOperand(Expression expression);
 
-  /**
-   * The function type of the invocation, or `null` if the AST structure has
-   * not been resolved, or if the invocation could not be resolved.
-   */
+  /// The function type of the invocation, or `null` if the AST structure has
+  /// not been resolved, or if the invocation could not be resolved.
   FunctionType get staticInvokeType;
 
-  /**
-   * Sets the function type of the invocation.
-   */
+  /// Sets the function type of the invocation.
   void set staticInvokeType(FunctionType value);
 }
 
-/**
- * A sequence of statements.
- *
- *    block ::=
- *        '{' statement* '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Block extends Statement {
-  /**
-   * Return the left curly bracket.
-   */
+/// A sequence of statements.
+///
+///    block ::=
+///        '{' statement* '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Block implements Statement {
+  /// Return the left curly bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left curly bracket to the given [token].
-   */
+  /// Set the left curly bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right curly bracket.
-   */
+  /// Return the right curly bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 
-  /**
-   * Return the statements contained in the block.
-   */
+  /// Return the statements contained in the block.
   NodeList<Statement> get statements;
 }
 
-/**
- * A function body that consists of a block of statements.
- *
- *    blockFunctionBody ::=
- *        ('async' | 'async' '*' | 'sync' '*')? [Block]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class BlockFunctionBody extends FunctionBody {
-  /**
-   * Return the block representing the body of the function.
-   */
+/// A function body that consists of a block of statements.
+///
+///    blockFunctionBody ::=
+///        ('async' | 'async' '*' | 'sync' '*')? [Block]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class BlockFunctionBody implements FunctionBody {
+  /// Return the block representing the body of the function.
   Block get block;
 
-  /**
-   * Set the block representing the body of the function to the given [block].
-   */
+  /// Set the block representing the body of the function to the given [block].
   void set block(Block block);
 
-  /**
-   * Set token representing the 'async' or 'sync' keyword to the given [token].
-   */
+  /// Set token representing the 'async' or 'sync' keyword to the given [token].
   void set keyword(Token token);
 
-  /**
-   * Set the star following the 'async' or 'sync' keyword to the given [token].
-   */
+  /// Set the star following the 'async' or 'sync' keyword to the given [token].
   void set star(Token token);
 }
 
-/**
- * A boolean literal expression.
- *
- *    booleanLiteral ::=
- *        'false' | 'true'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class BooleanLiteral extends Literal {
-  /**
-   * Return the token representing the literal.
-   */
+/// A boolean literal expression.
+///
+///    booleanLiteral ::=
+///        'false' | 'true'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class BooleanLiteral implements Literal {
+  /// Return the token representing the literal.
   Token get literal;
 
-  /**
-   * Set the token representing the literal to the given [token].
-   */
+  /// Set the token representing the literal to the given [token].
   void set literal(Token token);
 
-  /**
-   * Return the value of the literal.
-   */
+  /// Return the value of the literal.
   bool get value;
 }
 
-/**
- * A break statement.
- *
- *    breakStatement ::=
- *        'break' [SimpleIdentifier]? ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class BreakStatement extends Statement {
-  /**
-   * Return the token representing the 'break' keyword.
-   */
+/// A break statement.
+///
+///    breakStatement ::=
+///        'break' [SimpleIdentifier]? ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class BreakStatement implements Statement {
+  /// Return the token representing the 'break' keyword.
   Token get breakKeyword;
 
-  /**
-   * Set the token representing the 'break' keyword to the given [token].
-   */
+  /// Set the token representing the 'break' keyword to the given [token].
   void set breakKeyword(Token token);
 
-  /**
-   * Return the label associated with the statement, or `null` if there is no
-   * label.
-   */
+  /// Return the label associated with the statement, or `null` if there is no
+  /// label.
   SimpleIdentifier get label;
 
-  /**
-   * Set the label associated with the statement to the given [identifier].
-   */
+  /// Set the label associated with the statement to the given [identifier].
   void set label(SimpleIdentifier identifier);
 
-  /**
-   * Return the semicolon terminating the statement.
-   */
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the node from which this break statement is breaking. This will be
-   * either a [Statement] (in the case of breaking out of a loop), a
-   * [SwitchMember] (in the case of a labeled break statement whose label
-   * matches a label on a switch case in an enclosing switch statement), or
-   * `null` if the AST has not yet been resolved or if the target could not be
-   * resolved. Note that if the source code has errors, the target might be
-   * invalid (e.g. trying to break to a switch case).
-   */
+  /// Return the node from which this break statement is breaking. This will be
+  /// either a [Statement] (in the case of breaking out of a loop), a
+  /// [SwitchMember] (in the case of a labeled break statement whose label
+  /// matches a label on a switch case in an enclosing switch statement), or
+  /// `null` if the AST has not yet been resolved or if the target could not be
+  /// resolved. Note that if the source code has errors, the target might be
+  /// invalid (e.g. trying to break to a switch case).
   AstNode get target;
 
-  /**
-   * Set the node from which this break statement is breaking to the given
-   * [node].
-   */
+  /// Set the node from which this break statement is breaking to the given
+  /// [node].
   void set target(AstNode node);
 }
 
-/**
- * A sequence of cascaded expressions: expressions that share a common target.
- * There are three kinds of expressions that can be used in a cascade
- * expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].
- *
- *    cascadeExpression ::=
- *        [Expression] cascadeSection*
- *
- *    cascadeSection ::=
- *        '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*
- *        (assignmentOperator expressionWithoutCascade)?
- *
- *    cascadeSelector ::=
- *        '[ ' expression '] '
- *      | identifier
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class CascadeExpression extends Expression {
-  /**
-   * Return the cascade sections sharing the common target.
-   */
+/// A sequence of cascaded expressions: expressions that share a common target.
+/// There are three kinds of expressions that can be used in a cascade
+/// expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].
+///
+///    cascadeExpression ::=
+///        [Expression] cascadeSection*
+///
+///    cascadeSection ::=
+///        '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*
+///        (assignmentOperator expressionWithoutCascade)?
+///
+///    cascadeSelector ::=
+///        '[ ' expression '] '
+///      | identifier
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class CascadeExpression implements Expression {
+  /// Return the cascade sections sharing the common target.
   NodeList<Expression> get cascadeSections;
 
-  /**
-   * Return the target of the cascade sections.
-   */
+  /// Return the target of the cascade sections.
   Expression get target;
 
-  /**
-   * Set the target of the cascade sections to the given [target].
-   */
+  /// Set the target of the cascade sections to the given [target].
   void set target(Expression target);
 }
 
-/**
- * A catch clause within a try statement.
- *
- *    onPart ::=
- *        catchPart [Block]
- *      | 'on' type catchPart? [Block]
- *
- *    catchPart ::=
- *        'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class CatchClause extends AstNode {
-  /**
-   * Return the body of the catch block.
-   */
+/// A catch clause within a try statement.
+///
+///    onPart ::=
+///        catchPart [Block]
+///      | 'on' type catchPart? [Block]
+///
+///    catchPart ::=
+///        'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class CatchClause implements AstNode {
+  /// Return the body of the catch block.
   Block get body;
 
-  /**
-   * Set the body of the catch block to the given [block].
-   */
+  /// Set the body of the catch block to the given [block].
   void set body(Block block);
 
-  /**
-   * Return the token representing the 'catch' keyword, or `null` if there is no
-   * 'catch' keyword.
-   */
+  /// Return the token representing the 'catch' keyword, or `null` if there is
+  /// no 'catch' keyword.
   Token get catchKeyword;
 
-  /**
-   * Set the token representing the 'catch' keyword to the given [token].
-   */
+  /// Set the token representing the 'catch' keyword to the given [token].
   void set catchKeyword(Token token);
 
-  /**
-   * Return the comma separating the exception parameter from the stack trace
-   * parameter, or `null` if there is no stack trace parameter.
-   */
+  /// Return the comma separating the exception parameter from the stack trace
+  /// parameter, or `null` if there is no stack trace parameter.
   Token get comma;
 
-  /**
-   * Set the comma separating the exception parameter from the stack trace
-   * parameter to the given [token].
-   */
+  /// Set the comma separating the exception parameter from the stack trace
+  /// parameter to the given [token].
   void set comma(Token token);
 
-  /**
-   * Return the parameter whose value will be the exception that was thrown, or
-   * `null` if there is no 'catch' keyword.
-   */
+  /// Return the parameter whose value will be the exception that was thrown, or
+  /// `null` if there is no 'catch' keyword.
   SimpleIdentifier get exceptionParameter;
 
-  /**
-   * Set the parameter whose value will be the exception that was thrown to the
-   * given [parameter].
-   */
+  /// Set the parameter whose value will be the exception that was thrown to the
+  /// given [parameter].
   void set exceptionParameter(SimpleIdentifier parameter);
 
-  /**
-   * Return the type of exceptions caught by this catch clause, or `null` if
-   * this catch clause catches every type of exception.
-   */
+  /// Return the type of exceptions caught by this catch clause, or `null` if
+  /// this catch clause catches every type of exception.
   TypeAnnotation get exceptionType;
 
-  /**
-   * Set the type of exceptions caught by this catch clause to the given
-   * [exceptionType].
-   */
+  /// Set the type of exceptions caught by this catch clause to the given
+  /// [exceptionType].
   void set exceptionType(TypeAnnotation exceptionType);
 
-  /**
-   * Return the left parenthesis, or `null` if there is no 'catch' keyword.
-   */
+  /// Return the left parenthesis, or `null` if there is no 'catch' keyword.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the token representing the 'on' keyword, or `null` if there is no 'on'
-   * keyword.
-   */
+  /// Return the token representing the 'on' keyword, or `null` if there is no
+  /// 'on' keyword.
   Token get onKeyword;
 
-  /**
-   * Set the token representing the 'on' keyword to the given [token].
-   */
+  /// Set the token representing the 'on' keyword to the given [token].
   void set onKeyword(Token token);
 
-  /**
-   * Return the right parenthesis, or `null` if there is no 'catch' keyword.
-   */
+  /// Return the right parenthesis, or `null` if there is no 'catch' keyword.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 
-  /**
-   * Return the parameter whose value will be the stack trace associated with
-   * the exception, or `null` if there is no stack trace parameter.
-   */
+  /// Return the parameter whose value will be the stack trace associated with
+  /// the exception, or `null` if there is no stack trace parameter.
   SimpleIdentifier get stackTraceParameter;
 
-  /**
-   * Set the parameter whose value will be the stack trace associated with the
-   * exception to the given [parameter].
-   */
+  /// Set the parameter whose value will be the stack trace associated with the
+  /// exception to the given [parameter].
   void set stackTraceParameter(SimpleIdentifier parameter);
 }
 
-/**
- * The declaration of a class.
- *
- *    classDeclaration ::=
- *        'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?
- *        ([ExtendsClause] [WithClause]?)?
- *        [ImplementsClause]?
- *        '{' [ClassMember]* '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ClassDeclaration extends ClassOrMixinDeclaration {
-  /**
-   * Return the 'abstract' keyword, or `null` if the keyword was absent.
-   */
+/// The declaration of a class.
+///
+///    classDeclaration ::=
+///        'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?
+///        ([ExtendsClause] [WithClause]?)?
+///        [ImplementsClause]?
+///        '{' [ClassMember]* '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ClassDeclaration implements ClassOrMixinDeclaration {
+  /// Return the 'abstract' keyword, or `null` if the keyword was absent.
   Token get abstractKeyword;
 
-  /**
-   * Set the 'abstract' keyword to the given [token].
-   */
+  /// Set the 'abstract' keyword to the given [token].
   void set abstractKeyword(Token token);
 
-  /**
-   * Return the token representing the 'class' keyword.
-   */
+  /// Return the token representing the 'class' keyword.
   Token get classKeyword;
 
-  /**
-   * Set the token representing the 'class' keyword.
-   */
+  /// Set the token representing the 'class' keyword.
   void set classKeyword(Token token);
 
   @deprecated
   @override
   ClassElement get element;
 
-  /**
-   * Return the extends clause for this class, or `null` if the class does not
-   * extend any other class.
-   */
+  /// Return the extends clause for this class, or `null` if the class does not
+  /// extend any other class.
   ExtendsClause get extendsClause;
 
-  /**
-   * Set the extends clause for this class to the given [extendsClause].
-   */
+  /// Set the extends clause for this class to the given [extendsClause].
   void set extendsClause(ExtendsClause extendsClause);
 
-  /**
-   * Set the implements clause for the class to the given [implementsClause].
-   */
+  /// Set the implements clause for the class to the given [implementsClause].
   void set implementsClause(ImplementsClause implementsClause);
 
-  /**
-   * Return `true` if this class is declared to be an abstract class.
-   */
+  /// Return `true` if this class is declared to be an abstract class.
   bool get isAbstract;
 
-  /**
-   * Set the left curly bracket to the given [token].
-   */
+  /// Set the left curly bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the native clause for this class, or `null` if the class does not
-   * have a native clause.
-   */
+  /// Return the native clause for this class, or `null` if the class does not
+  /// have a native clause.
   NativeClause get nativeClause;
 
-  /**
-   * Set the native clause for this class to the given [nativeClause].
-   */
+  /// Set the native clause for this class to the given [nativeClause].
   void set nativeClause(NativeClause nativeClause);
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 
-  /**
-   * Set the type parameters for the class to the given list of [typeParameters].
-   */
+  /// Set the type parameters for the class to the given list of
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 
-  /**
-   * Return the with clause for the class, or `null` if the class does not have
-   * a with clause.
-   */
+  /// Return the with clause for the class, or `null` if the class does not have
+  /// a with clause.
   WithClause get withClause;
 
-  /**
-   * Set the with clause for the class to the given [withClause].
-   */
+  /// Set the with clause for the class to the given [withClause].
   void set withClause(WithClause withClause);
 
-  /**
-   * Return the constructor declared in the class with the given [name], or
-   * `null` if there is no such constructor. If the [name] is `null` then the
-   * default constructor will be searched for.
-   */
+  /// Return the constructor declared in the class with the given [name], or
+  /// `null` if there is no such constructor. If the [name] is `null` then the
+  /// default constructor will be searched for.
   ConstructorDeclaration getConstructor(String name);
 }
 
-/**
- * A node that declares a name within the scope of a class.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ClassMember extends Declaration {}
+/// A node that declares a name within the scope of a class.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ClassMember implements Declaration {}
 
-/**
- * The declaration of a class or mixin.
- */
-abstract class ClassOrMixinDeclaration extends NamedCompilationUnitMember {
+/// The declaration of a class or mixin.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ClassOrMixinDeclaration implements NamedCompilationUnitMember {
   @override
   ClassElement get declaredElement;
 
-  /**
-   * Returns the implements clause for the class/mixin, or `null` if the
-   * class/mixin does not implement any interfaces.
-   */
+  /// Returns the implements clause for the class/mixin, or `null` if the
+  /// class/mixin does not implement any interfaces.
   ImplementsClause get implementsClause;
 
-  /**
-   * Returns the left curly bracket.
-   */
+  /// Returns the left curly bracket.
   Token get leftBracket;
 
-  /**
-   * Returns the members defined by the class/mixin.
-   */
+  /// Returns the members defined by the class/mixin.
   NodeList<ClassMember> get members;
 
-  /**
-   * Returns the right curly bracket.
-   */
+  /// Returns the right curly bracket.
   Token get rightBracket;
 
-  /**
-   * Returns the type parameters for the class/mixin, or `null` if the
-   * class/mixin does not have any type parameters.
-   */
+  /// Returns the type parameters for the class/mixin, or `null` if the
+  /// class/mixin does not have any type parameters.
   TypeParameterList get typeParameters;
 
-  /**
-   * Returns the field declared in the class/mixin with the given [name], or
-   * `null` if there is no such field.
-   */
+  /// Returns the field declared in the class/mixin with the given [name], or
+  /// `null` if there is no such field.
   VariableDeclaration getField(String name);
 
-  /**
-   * Returns the method declared in the class/mixin with the given [name], or
-   * `null` if there is no such method.
-   */
+  /// Returns the method declared in the class/mixin with the given [name], or
+  /// `null` if there is no such method.
   MethodDeclaration getMethod(String name);
 }
 
-/**
- * A class type alias.
- *
- *    classTypeAlias ::=
- *        [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication
- *
- *    mixinApplication ::=
- *        [TypeName] [WithClause] [ImplementsClause]? ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ClassTypeAlias extends TypeAlias {
-  /**
-   * Return the token for the 'abstract' keyword, or `null` if this is not
-   * defining an abstract class.
-   */
+/// A class type alias.
+///
+///    classTypeAlias ::=
+///        [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication
+///
+///    mixinApplication ::=
+///        [TypeName] [WithClause] [ImplementsClause]? ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ClassTypeAlias implements TypeAlias {
+  /// Return the token for the 'abstract' keyword, or `null` if this is not
+  /// defining an abstract class.
   Token get abstractKeyword;
 
-  /**
-   * Set the token for the 'abstract' keyword to the given [token].
-   */
+  /// Set the token for the 'abstract' keyword to the given [token].
   void set abstractKeyword(Token token);
 
-  /**
-   * Return the token for the '=' separating the name from the definition.
-   */
+  /// Return the token for the '=' separating the name from the definition.
   Token get equals;
 
-  /**
-   * Set the token for the '=' separating the name from the definition to the
-   * given [token].
-   */
+  /// Set the token for the '=' separating the name from the definition to the
+  /// given [token].
   void set equals(Token token);
 
-  /**
-   * Return the implements clause for this class, or `null` if there is no
-   * implements clause.
-   */
+  /// Return the implements clause for this class, or `null` if there is no
+  /// implements clause.
   ImplementsClause get implementsClause;
 
-  /**
-   * Set the implements clause for this class to the given [implementsClause].
-   */
+  /// Set the implements clause for this class to the given [implementsClause].
   void set implementsClause(ImplementsClause implementsClause);
 
-  /**
-   * Return `true` if this class is declared to be an abstract class.
-   */
+  /// Return `true` if this class is declared to be an abstract class.
   bool get isAbstract;
 
-  /**
-   * Return the name of the superclass of the class being declared.
-   */
+  /// Return the name of the superclass of the class being declared.
   TypeName get superclass;
 
-  /**
-   * Set the name of the superclass of the class being declared to the given
-   * [superclass] name.
-   */
+  /// Set the name of the superclass of the class being declared to the given
+  /// [superclass] name.
   void set superclass(TypeName superclass);
 
-  /**
-   * Return the type parameters for the class, or `null` if the class does not
-   * have any type parameters.
-   */
+  /// Return the type parameters for the class, or `null` if the class does not
+  /// have any type parameters.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters for the class to the given list of [typeParameters].
-   */
+  /// Set the type parameters for the class to the given list of
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 
-  /**
-   * Return the with clause for this class.
-   */
+  /// Return the with clause for this class.
   WithClause get withClause;
 
-  /**
-   * Set the with clause for this class to the given with [withClause].
-   */
+  /// Set the with clause for this class to the given with [withClause].
   void set withClause(WithClause withClause);
 }
 
-/**
- * A combinator associated with an import or export directive.
- *
- *    combinator ::=
- *        [HideCombinator]
- *      | [ShowCombinator]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Combinator extends AstNode {
-  /**
-   * Return the 'hide' or 'show' keyword specifying what kind of processing is
-   * to be done on the names.
-   */
+/// An element in a list, map or set literal.
+///
+///    collectionElement ::=
+///        [Expression]
+///      | [IfElement]
+///      | [ForElement]
+///      | [MapLiteralEntry]
+///      | [SpreadElement]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class CollectionElement implements AstNode {}
+
+/// A combinator associated with an import or export directive.
+///
+///    combinator ::=
+///        [HideCombinator]
+///      | [ShowCombinator]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Combinator implements AstNode {
+  /// Return the 'hide' or 'show' keyword specifying what kind of processing is
+  /// to be done on the names.
   Token get keyword;
 
-  /**
-   * Set the 'hide' or 'show' keyword specifying what kind of processing is
-   * to be done on the names to the given [token].
-   */
+  /// Set the 'hide' or 'show' keyword specifying what kind of processing is
+  /// to be done on the names to the given [token].
   void set keyword(Token token);
 }
 
-/**
- * A comment within the source code.
- *
- *    comment ::=
- *        endOfLineComment
- *      | blockComment
- *      | documentationComment
- *
- *    endOfLineComment ::=
- *        '//' (CHARACTER - EOL)* EOL
- *
- *    blockComment ::=
- *        '/ *' CHARACTER* '&#42;/'
- *
- *    documentationComment ::=
- *        '/ **' (CHARACTER | [CommentReference])* '&#42;/'
- *      | ('///' (CHARACTER - EOL)* EOL)+
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Comment extends AstNode {
-  /**
-   * Return `true` if this is a block comment.
-   */
+/// A comment within the source code.
+///
+///    comment ::=
+///        endOfLineComment
+///      | blockComment
+///      | documentationComment
+///
+///    endOfLineComment ::=
+///        '//' (CHARACTER - EOL)* EOL
+///
+///    blockComment ::=
+///        '/ *' CHARACTER* '&#42;/'
+///
+///    documentationComment ::=
+///        '/ **' (CHARACTER | [CommentReference])* '&#42;/'
+///      | ('///' (CHARACTER - EOL)* EOL)+
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Comment implements AstNode {
+  /// Return `true` if this is a block comment.
   bool get isBlock;
 
-  /**
-   * Return `true` if this is a documentation comment.
-   */
+  /// Return `true` if this is a documentation comment.
   bool get isDocumentation;
 
-  /**
-   * Return `true` if this is an end-of-line comment.
-   */
+  /// Return `true` if this is an end-of-line comment.
   bool get isEndOfLine;
 
-  /**
-   * Return the references embedded within the documentation comment.
-   */
+  /// Return the references embedded within the documentation comment.
   NodeList<CommentReference> get references;
 
-  /**
-   * Return the tokens representing the comment.
-   */
+  /// Return the tokens representing the comment.
   List<Token> get tokens;
 }
 
-/**
- * A reference to a Dart element that is found within a documentation comment.
- *
- *    commentReference ::=
- *        '[' 'new'? [Identifier] ']'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class CommentReference extends AstNode {
-  /**
-   * Return the identifier being referenced.
-   */
+/// A reference to a Dart element that is found within a documentation comment.
+///
+///    commentReference ::=
+///        '[' 'new'? [Identifier] ']'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class CommentReference implements AstNode {
+  /// Return the identifier being referenced.
   Identifier get identifier;
 
-  /**
-   * Set the identifier being referenced to the given [identifier].
-   */
+  /// Set the identifier being referenced to the given [identifier].
   void set identifier(Identifier identifier);
 
-  /**
-   * Return the token representing the 'new' keyword, or `null` if there was no
-   * 'new' keyword.
-   */
+  /// Return the token representing the 'new' keyword, or `null` if there was no
+  /// 'new' keyword.
   Token get newKeyword;
 
-  /**
-   * Set the token representing the 'new' keyword to the given [token].
-   */
+  /// Set the token representing the 'new' keyword to the given [token].
   void set newKeyword(Token token);
 }
 
-/**
- * A compilation unit.
- *
- * While the grammar restricts the order of the directives and declarations
- * within a compilation unit, this class does not enforce those restrictions.
- * In particular, the children of a compilation unit will be visited in lexical
- * order even if lexical order does not conform to the restrictions of the
- * grammar.
- *
- *    compilationUnit ::=
- *        directives declarations
- *
- *    directives ::=
- *        [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*
- *      | [PartOfDirective]
- *
- *    namespaceDirective ::=
- *        [ImportDirective]
- *      | [ExportDirective]
- *
- *    declarations ::=
- *        [CompilationUnitMember]*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class CompilationUnit extends AstNode {
-  /**
-   * Set the first token included in this node's source range to the given
-   * [token].
-   */
+/// A compilation unit.
+///
+/// While the grammar restricts the order of the directives and declarations
+/// within a compilation unit, this class does not enforce those restrictions.
+/// In particular, the children of a compilation unit will be visited in lexical
+/// order even if lexical order does not conform to the restrictions of the
+/// grammar.
+///
+///    compilationUnit ::=
+///        directives declarations
+///
+///    directives ::=
+///        [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*
+///      | [PartOfDirective]
+///
+///    namespaceDirective ::=
+///        [ImportDirective]
+///      | [ExportDirective]
+///
+///    declarations ::=
+///        [CompilationUnitMember]*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class CompilationUnit implements AstNode {
+  /// Set the first token included in this node's source range to the given
+  /// [token].
   void set beginToken(Token token);
 
-  /**
-   * Return the declarations contained in this compilation unit.
-   */
+  /// Return the declarations contained in this compilation unit.
   NodeList<CompilationUnitMember> get declarations;
 
-  /**
-   * Return the element associated with this compilation unit, or `null` if the
-   * AST structure has not been resolved.
-   */
+  /// Return the element associated with this compilation unit, or `null` if the
+  /// AST structure has not been resolved.
   CompilationUnitElement get declaredElement;
 
-  /**
-   * Return the directives contained in this compilation unit.
-   */
+  /// Return the directives contained in this compilation unit.
   NodeList<Directive> get directives;
 
-  /**
-   * Return the element associated with this compilation unit, or `null` if the
-   * AST structure has not been resolved.
-   */
+  /// Return the element associated with this compilation unit, or `null` if the
+  /// AST structure has not been resolved.
   @deprecated
   CompilationUnitElement get element;
 
-  /**
-   * Set the element associated with this compilation unit to the given
-   * [element].
-   */
+  /// Set the element associated with this compilation unit to the given
+  /// [element].
   void set element(CompilationUnitElement element);
 
-  /**
-   * Set the last token included in this node's source range to the given
-   * [token].
-   */
+  /// Set the last token included in this node's source range to the given
+  /// [token].
   void set endToken(Token token);
 
-  /**
-   * Return the line information for this compilation unit.
-   */
+  /// Return the line information for this compilation unit.
   LineInfo get lineInfo;
 
-  /**
-   * Set the line information for this compilation unit to the given [info].
-   */
+  /// Set the line information for this compilation unit to the given [info].
   void set lineInfo(LineInfo info);
 
-  /**
-   * Return the script tag at the beginning of the compilation unit, or `null`
-   * if there is no script tag in this compilation unit.
-   */
+  /// Return the script tag at the beginning of the compilation unit, or `null`
+  /// if there is no script tag in this compilation unit.
   ScriptTag get scriptTag;
 
-  /**
-   * Set the script tag at the beginning of the compilation unit to the given
-   * [scriptTag].
-   */
+  /// Set the script tag at the beginning of the compilation unit to the given
+  /// [scriptTag].
   void set scriptTag(ScriptTag scriptTag);
 
-  /**
-   * Return a list containing all of the directives and declarations in this
-   * compilation unit, sorted in lexical order.
-   */
+  /// Return a list containing all of the directives and declarations in this
+  /// compilation unit, sorted in lexical order.
   List<AstNode> get sortedDirectivesAndDeclarations;
 }
 
-/**
- * A node that declares one or more names within the scope of a compilation
- * unit.
- *
- *    compilationUnitMember ::=
- *        [ClassDeclaration]
- *      | [TypeAlias]
- *      | [FunctionDeclaration]
- *      | [MethodDeclaration]
- *      | [VariableDeclaration]
- *      | [VariableDeclaration]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class CompilationUnitMember extends Declaration {}
+/// A node that declares one or more names within the scope of a compilation
+/// unit.
+///
+///    compilationUnitMember ::=
+///        [ClassDeclaration]
+///      | [TypeAlias]
+///      | [FunctionDeclaration]
+///      | [MethodDeclaration]
+///      | [VariableDeclaration]
+///      | [VariableDeclaration]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class CompilationUnitMember implements Declaration {}
 
-/**
- * A conditional expression.
- *
- *    conditionalExpression ::=
- *        [Expression] '?' [Expression] ':' [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ConditionalExpression extends Expression {
-  /**
-   * Return the token used to separate the then expression from the else
-   * expression.
-   */
+/// A conditional expression.
+///
+///    conditionalExpression ::=
+///        [Expression] '?' [Expression] ':' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ConditionalExpression implements Expression {
+  /// Return the token used to separate the then expression from the else
+  /// expression.
   Token get colon;
 
-  /**
-   * Set the token used to separate the then expression from the else expression
-   * to the given [token].
-   */
+  /// Set the token used to separate the then expression from the else
+  /// expression to the given [token].
   void set colon(Token token);
 
-  /**
-   * Return the condition used to determine which of the expressions is executed
-   * next.
-   */
+  /// Return the condition used to determine which of the expressions is
+  /// executed next.
   Expression get condition;
 
-  /**
-   * Set the condition used to determine which of the expressions is executed
-   * next to the given [expression].
-   */
+  /// Set the condition used to determine which of the expressions is executed
+  /// next to the given [expression].
   void set condition(Expression expression);
 
-  /**
-   * Return the expression that is executed if the condition evaluates to
-   * `false`.
-   */
+  /// Return the expression that is executed if the condition evaluates to
+  /// `false`.
   Expression get elseExpression;
 
-  /**
-   * Set the expression that is executed if the condition evaluates to `false`
-   * to the given [expression].
-   */
+  /// Set the expression that is executed if the condition evaluates to `false`
+  /// to the given [expression].
   void set elseExpression(Expression expression);
 
-  /**
-   * Return the token used to separate the condition from the then expression.
-   */
+  /// Return the token used to separate the condition from the then expression.
   Token get question;
 
-  /**
-   * Set the token used to separate the condition from the then expression to
-   * the given [token].
-   */
+  /// Set the token used to separate the condition from the then expression to
+  /// the given [token].
   void set question(Token token);
 
-  /**
-   * Return the expression that is executed if the condition evaluates to
-   * `true`.
-   */
+  /// Return the expression that is executed if the condition evaluates to
+  /// `true`.
   Expression get thenExpression;
 
-  /**
-   * Set the expression that is executed if the condition evaluates to `true` to
-   * the given [expression].
-   */
+  /// Set the expression that is executed if the condition evaluates to `true`
+  /// to the given [expression].
   void set thenExpression(Expression expression);
 }
 
-/**
- * A configuration in either an import or export directive.
- *
- *    configuration ::=
- *        'if' '(' test ')' uri
- *
- *    test ::=
- *        dottedName ('==' stringLiteral)?
- *
- *    dottedName ::=
- *        identifier ('.' identifier)*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Configuration extends AstNode {
-  /**
-   * Return the token for the equal operator, or `null` if the condition does
-   * not include an equality test.
-   */
+/// A configuration in either an import or export directive.
+///
+///    configuration ::=
+///        'if' '(' test ')' uri
+///
+///    test ::=
+///        dottedName ('==' stringLiteral)?
+///
+///    dottedName ::=
+///        identifier ('.' identifier)*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Configuration implements AstNode {
+  /// Return the token for the equal operator, or `null` if the condition does
+  /// not include an equality test.
   Token get equalToken;
 
-  /**
-   * Set the token for the equal operator to the given [token].
-   */
+  /// Set the token for the equal operator to the given [token].
   void set equalToken(Token token);
 
-  /**
-   * Return the token for the 'if' keyword.
-   */
+  /// Return the token for the 'if' keyword.
   Token get ifKeyword;
 
-  /**
-   * Set the token for the 'if' keyword to the given [token].
-   */
+  /// Set the token for the 'if' keyword to the given [token].
   void set ifKeyword(Token token);
 
-  /**
-   * Return the token for the left parenthesis.
-   */
+  /// Return the token for the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the token for the left parenthesis to the given [token].
-   */
+  /// Set the token for the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the URI of the implementation library to be used if the condition is
-   * true.
-   */
+  /// Return the URI of the implementation library to be used if the condition
+  /// is true.
   @deprecated
   StringLiteral get libraryUri;
 
-  /**
-   * Set the URI of the implementation library to be used if the condition is
-   * true to the given [uri].
-   */
+  /// Set the URI of the implementation library to be used if the condition is
+  /// true to the given [uri].
   @deprecated
   void set libraryUri(StringLiteral uri);
 
-  /**
-   * Return the name of the declared variable whose value is being used in the
-   * condition.
-   */
+  /// Return the name of the declared variable whose value is being used in the
+  /// condition.
   DottedName get name;
 
-  /**
-   * Set the name of the declared variable whose value is being used in the
-   * condition to the given [name].
-   */
+  /// Set the name of the declared variable whose value is being used in the
+  /// condition to the given [name].
   void set name(DottedName name);
 
-  /**
-   * Return the token for the right parenthesis.
-   */
+  /// Return the token for the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the token for the right parenthesis to the given [token].
-   */
+  /// Set the token for the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 
-  /**
-   * Return the URI of the implementation library to be used if the condition is
-   * true.
-   */
+  /// Return the URI of the implementation library to be used if the condition
+  /// is true.
   StringLiteral get uri;
 
-  /**
-   * Set the URI of the implementation library to be used if the condition is
-   * true to the given [uri].
-   */
+  /// Set the URI of the implementation library to be used if the condition is
+  /// true to the given [uri].
   void set uri(StringLiteral uri);
 
-  /**
-   * Return the source to which the [uri] was resolved.
-   */
+  /// Return the source to which the [uri] was resolved.
   Source get uriSource;
 
-  /**
-   * Set the source to which the [uri] was resolved to the given [source].
-   */
+  /// Set the source to which the [uri] was resolved to the given [source].
   void set uriSource(Source source);
 
-  /**
-   * Return the value to which the value of the declared variable will be
-   * compared, or `null` if the condition does not include an equality test.
-   */
+  /// Return the value to which the value of the declared variable will be
+  /// compared, or `null` if the condition does not include an equality test.
   StringLiteral get value;
 
-  /**
-   * Set the value to which the value of the declared variable will be
-   * compared to the given [value].
-   */
+  /// Set the value to which the value of the declared variable will be
+  /// compared to the given [value].
   void set value(StringLiteral value);
 }
 
-/**
- * A constructor declaration.
- *
- *    constructorDeclaration ::=
- *        constructorSignature [FunctionBody]?
- *      | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments
- *
- *    constructorSignature ::=
- *        'external'? constructorName formalParameterList initializerList?
- *      | 'external'? 'factory' factoryName formalParameterList initializerList?
- *      | 'external'? 'const'  constructorName formalParameterList initializerList?
- *
- *    constructorName ::=
- *        [SimpleIdentifier] ('.' [SimpleIdentifier])?
- *
- *    factoryName ::=
- *        [Identifier] ('.' [SimpleIdentifier])?
- *
- *    initializerList ::=
- *        ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ConstructorDeclaration extends ClassMember {
-  /**
-   * Return the body of the constructor, or `null` if the constructor does not
-   * have a body.
-   */
+/// A constructor declaration.
+///
+///    constructorDeclaration ::=
+///        constructorSignature [FunctionBody]?
+///      | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments
+///
+///    constructorSignature ::=
+///        'external'? constructorName formalParameterList initializerList?
+///      | 'external'? 'factory' factoryName formalParameterList initializerList?
+///      | 'external'? 'const'  constructorName formalParameterList initializerList?
+///
+///    constructorName ::=
+///        [SimpleIdentifier] ('.' [SimpleIdentifier])?
+///
+///    factoryName ::=
+///        [Identifier] ('.' [SimpleIdentifier])?
+///
+///    initializerList ::=
+///        ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ConstructorDeclaration implements ClassMember {
+  /// Return the body of the constructor, or `null` if the constructor does not
+  /// have a body.
   FunctionBody get body;
 
-  /**
-   * Set the body of the constructor to the given [functionBody].
-   */
+  /// Set the body of the constructor to the given [functionBody].
   void set body(FunctionBody functionBody);
 
-  /**
-   * Return the token for the 'const' keyword, or `null` if the constructor is
-   * not a const constructor.
-   */
+  /// Return the token for the 'const' keyword, or `null` if the constructor is
+  /// not a const constructor.
   Token get constKeyword;
 
-  /**
-   * Set the token for the 'const' keyword to the given [token].
-   */
+  /// Set the token for the 'const' keyword to the given [token].
   void set constKeyword(Token token);
 
   @override
@@ -1888,340 +1432,235 @@
   @deprecated
   ConstructorElement get element;
 
-  /**
-   * Set the element associated with this constructor to the given [element].
-   */
+  /// Set the element associated with this constructor to the given [element].
   void set element(ConstructorElement element);
 
-  /**
-   * Return the token for the 'external' keyword to the given [token].
-   */
+  /// Return the token for the 'external' keyword to the given [token].
   Token get externalKeyword;
 
-  /**
-   * Set the token for the 'external' keyword, or `null` if the constructor
-   * is not external.
-   */
+  /// Set the token for the 'external' keyword, or `null` if the constructor
+  /// is not external.
   void set externalKeyword(Token token);
 
-  /**
-   * Return the token for the 'factory' keyword, or `null` if the constructor is
-   * not a factory constructor.
-   */
+  /// Return the token for the 'factory' keyword, or `null` if the constructor
+  /// is not a factory constructor.
   Token get factoryKeyword;
 
-  /**
-   * Set the token for the 'factory' keyword to the given [token].
-   */
+  /// Set the token for the 'factory' keyword to the given [token].
   void set factoryKeyword(Token token);
 
-  /**
-   * Return the initializers associated with the constructor.
-   */
+  /// Return the initializers associated with the constructor.
   NodeList<ConstructorInitializer> get initializers;
 
-  /**
-   * Return the name of the constructor, or `null` if the constructor being
-   * declared is unnamed.
-   */
+  /// Return the name of the constructor, or `null` if the constructor being
+  /// declared is unnamed.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the constructor to the given [identifier].
-   */
+  /// Set the name of the constructor to the given [identifier].
   void set name(SimpleIdentifier identifier);
 
-  /**
-   * Return the parameters associated with the constructor.
-   */
+  /// Return the parameters associated with the constructor.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters associated with the constructor to the given list of
-   * [parameters].
-   */
+  /// Set the parameters associated with the constructor to the given list of
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * Return the token for the period before the constructor name, or `null` if
-   * the constructor being declared is unnamed.
-   */
+  /// Return the token for the period before the constructor name, or `null` if
+  /// the constructor being declared is unnamed.
   Token get period;
 
-  /**
-   * Set the token for the period before the constructor name to the given
-   * [token].
-   */
+  /// Set the token for the period before the constructor name to the given
+  /// [token].
   void set period(Token token);
 
-  /**
-   * Return the name of the constructor to which this constructor will be
-   * redirected, or `null` if this is not a redirecting factory constructor.
-   */
+  /// Return the name of the constructor to which this constructor will be
+  /// redirected, or `null` if this is not a redirecting factory constructor.
   ConstructorName get redirectedConstructor;
 
-  /**
-   * Set the name of the constructor to which this constructor will be
-   * redirected to the given [redirectedConstructor] name.
-   */
+  /// Set the name of the constructor to which this constructor will be
+  /// redirected to the given [redirectedConstructor] name.
   void set redirectedConstructor(ConstructorName redirectedConstructor);
 
-  /**
-   * Return the type of object being created. This can be different than the
-   * type in which the constructor is being declared if the constructor is the
-   * implementation of a factory constructor.
-   */
+  /// Return the type of object being created. This can be different than the
+  /// type in which the constructor is being declared if the constructor is the
+  /// implementation of a factory constructor.
   Identifier get returnType;
 
-  /**
-   * Set the type of object being created to the given [typeName].
-   */
+  /// Set the type of object being created to the given [typeName].
   void set returnType(Identifier typeName);
 
-  /**
-   * Return the token for the separator (colon or equals) before the initializer
-   * list or redirection, or `null` if there are no initializers.
-   */
+  /// Return the token for the separator (colon or equals) before the
+  /// initializer list or redirection, or `null` if there are no initializers.
   Token get separator;
 
-  /**
-   * Set the token for the separator (colon or equals) before the initializer
-   * list or redirection to the given [token].
-   */
+  /// Set the token for the separator (colon or equals) before the initializer
+  /// list or redirection to the given [token].
   void set separator(Token token);
 }
 
-/**
- * The initialization of a field within a constructor's initialization list.
- *
- *    fieldInitializer ::=
- *        ('this' '.')? [SimpleIdentifier] '=' [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ConstructorFieldInitializer extends ConstructorInitializer {
-  /**
-   * Return the token for the equal sign between the field name and the
-   * expression.
-   */
+/// The initialization of a field within a constructor's initialization list.
+///
+///    fieldInitializer ::=
+///        ('this' '.')? [SimpleIdentifier] '=' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ConstructorFieldInitializer implements ConstructorInitializer {
+  /// Return the token for the equal sign between the field name and the
+  /// expression.
   Token get equals;
 
-  /**
-   * Set the token for the equal sign between the field name and the
-   * expression to the given [token].
-   */
+  /// Set the token for the equal sign between the field name and the
+  /// expression to the given [token].
   void set equals(Token token);
 
-  /**
-   * Return the expression computing the value to which the field will be
-   * initialized.
-   */
+  /// Return the expression computing the value to which the field will be
+  /// initialized.
   Expression get expression;
 
-  /**
-   * Set the expression computing the value to which the field will be
-   * initialized to the given [expression].
-   */
+  /// Set the expression computing the value to which the field will be
+  /// initialized to the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the name of the field being initialized.
-   */
+  /// Return the name of the field being initialized.
   SimpleIdentifier get fieldName;
 
-  /**
-   * Set the name of the field being initialized to the given [identifier].
-   */
+  /// Set the name of the field being initialized to the given [identifier].
   void set fieldName(SimpleIdentifier identifier);
 
-  /**
-   * Return the token for the period after the 'this' keyword, or `null` if
-   * there is no 'this' keyword.
-   */
+  /// Return the token for the period after the 'this' keyword, or `null` if
+  /// there is no 'this' keyword.
   Token get period;
 
-  /**
-   * Set the token for the period after the 'this' keyword to the given [token].
-   */
+  /// Set the token for the period after the 'this' keyword to the given
+  /// [token].
   void set period(Token token);
 
-  /**
-   * Return the token for the 'this' keyword, or `null` if there is no 'this'
-   * keyword.
-   */
+  /// Return the token for the 'this' keyword, or `null` if there is no 'this'
+  /// keyword.
   Token get thisKeyword;
 
-  /**
-   * Set the token for the 'this' keyword to the given [token].
-   */
+  /// Set the token for the 'this' keyword to the given [token].
   void set thisKeyword(Token token);
 }
 
-/**
- * A node that can occur in the initializer list of a constructor declaration.
- *
- *    constructorInitializer ::=
- *        [SuperConstructorInvocation]
- *      | [ConstructorFieldInitializer]
- *      | [RedirectingConstructorInvocation]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ConstructorInitializer extends AstNode {}
+/// A node that can occur in the initializer list of a constructor declaration.
+///
+///    constructorInitializer ::=
+///        [SuperConstructorInvocation]
+///      | [ConstructorFieldInitializer]
+///      | [RedirectingConstructorInvocation]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ConstructorInitializer implements AstNode {}
 
-/**
- * The name of a constructor.
- *
- *    constructorName ::=
- *        type ('.' identifier)?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ConstructorName extends AstNode
-    implements ConstructorReferenceNode {
-  /**
-   * Return the name of the constructor, or `null` if the specified constructor
-   * is the unnamed constructor.
-   */
+/// The name of a constructor.
+///
+///    constructorName ::=
+///        type ('.' identifier)?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ConstructorName implements AstNode, ConstructorReferenceNode {
+  /// Return the name of the constructor, or `null` if the specified constructor
+  /// is the unnamed constructor.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the constructor to the given [name].
-   */
+  /// Set the name of the constructor to the given [name].
   void set name(SimpleIdentifier name);
 
-  /**
-   * Return the token for the period before the constructor name, or `null` if
-   * the specified constructor is the unnamed constructor.
-   */
+  /// Return the token for the period before the constructor name, or `null` if
+  /// the specified constructor is the unnamed constructor.
   Token get period;
 
-  /**
-   * Set the token for the period before the constructor name to the given
-   * [token].
-   */
+  /// Set the token for the period before the constructor name to the given
+  /// [token].
   void set period(Token token);
 
-  /**
-   * Return the name of the type defining the constructor.
-   */
+  /// Return the name of the type defining the constructor.
   TypeName get type;
 
-  /**
-   * Set the name of the type defining the constructor to the given [type] name.
-   */
+  /// Set the name of the type defining the constructor to the given [type]
+  /// name.
   void set type(TypeName type);
 }
 
-/**
- * An AST node that makes reference to a constructor.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ConstructorReferenceNode {
-  /**
-   * Return the element associated with the referenced constructor based on
-   * static type information, or `null` if the AST structure has not been
-   * resolved or if the constructor could not be resolved.
-   */
+/// An AST node that makes reference to a constructor.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ConstructorReferenceNode implements AstNode {
+  /// Return the element associated with the referenced constructor based on
+  /// static type information, or `null` if the AST structure has not been
+  /// resolved or if the constructor could not be resolved.
   ConstructorElement get staticElement;
 
-  /**
-   * Set the element associated with the referenced constructor based on static
-   * type information to the given [element].
-   */
+  /// Set the element associated with the referenced constructor based on static
+  /// type information to the given [element].
   void set staticElement(ConstructorElement element);
 }
 
-/**
- * A continue statement.
- *
- *    continueStatement ::=
- *        'continue' [SimpleIdentifier]? ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ContinueStatement extends Statement {
-  /**
-   * Return the token representing the 'continue' keyword.
-   */
+/// A continue statement.
+///
+///    continueStatement ::=
+///        'continue' [SimpleIdentifier]? ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ContinueStatement implements Statement {
+  /// Return the token representing the 'continue' keyword.
   Token get continueKeyword;
 
-  /**
-   * Set the token representing the 'continue' keyword to the given [token].
-   */
+  /// Set the token representing the 'continue' keyword to the given [token].
   void set continueKeyword(Token token);
 
-  /**
-   * Return the label associated with the statement, or `null` if there is no
-   * label.
-   */
+  /// Return the label associated with the statement, or `null` if there is no
+  /// label.
   SimpleIdentifier get label;
 
-  /**
-   * Set the label associated with the statement to the given [identifier].
-   */
+  /// Set the label associated with the statement to the given [identifier].
   void set label(SimpleIdentifier identifier);
 
-  /**
-   * Return the semicolon terminating the statement.
-   */
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the node to which this continue statement is continuing. This will
-   * be either a [Statement] (in the case of continuing a loop), a
-   * [SwitchMember] (in the case of continuing from one switch case to another),
-   * or `null` if the AST has not yet been resolved or if the target could not
-   * be resolved. Note that if the source code has errors, the target might be
-   * invalid (e.g. the target may be in an enclosing function).
-   */
+  /// Return the node to which this continue statement is continuing. This will
+  /// be either a [Statement] (in the case of continuing a loop), a
+  /// [SwitchMember] (in the case of continuing from one switch case to
+  /// another), or `null` if the AST has not yet been resolved or if the target
+  /// could not be resolved. Note that if the source code has errors, the target
+  /// might be invalid (e.g. the target may be in an enclosing function).
   AstNode get target;
 
-  /**
-   * Set the node to which this continue statement is continuing to the given
-   * [node].
-   */
+  /// Set the node to which this continue statement is continuing to the given
+  /// [node].
   void set target(AstNode node);
 }
 
-/**
- * A node that represents the declaration of one or more names. Each declared
- * name is visible within a name scope.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Declaration extends AnnotatedNode {
-  /**
-   * Return the element associated with this declaration, or `null` if either
-   * this node corresponds to a list of declarations or if the AST structure has
-   * not been resolved.
-   */
+/// A node that represents the declaration of one or more names. Each declared
+/// name is visible within a name scope.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Declaration implements AnnotatedNode {
+  /// Return the element associated with this declaration, or `null` if either
+  /// this node corresponds to a list of declarations or if the AST structure
+  /// has not been resolved.
   Element get declaredElement;
 
-  /**
-   * Return the element associated with this declaration, or `null` if either
-   * this node corresponds to a list of declarations or if the AST structure has
-   * not been resolved.
-   */
+  /// Return the element associated with this declaration, or `null` if either
+  /// this node corresponds to a list of declarations or if the AST structure
+  /// has not been resolved.
   @deprecated
   Element get element;
 }
 
-/**
- * The declaration of a single identifier.
- *
- *    declaredIdentifier ::=
- *        [Annotation] finalConstVarOrType [SimpleIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DeclaredIdentifier extends Declaration {
+/// The declaration of a single identifier.
+///
+///    declaredIdentifier ::=
+///        [Annotation] finalConstVarOrType [SimpleIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class DeclaredIdentifier implements Declaration {
   @override
   LocalVariableElement get declaredElement;
 
@@ -2229,340 +1668,235 @@
   @override
   LocalVariableElement get element;
 
-  /**
-   * Return the name of the variable being declared.
-   */
+  /// Return the name of the variable being declared.
   SimpleIdentifier get identifier;
 
-  /**
-   * Set the name of the variable being declared to the given [identifier].
-   */
+  /// Set the name of the variable being declared to the given [identifier].
   void set identifier(SimpleIdentifier identifier);
 
-  /**
-   * Return `true` if this variable was declared with the 'const' modifier.
-   */
+  /// Return `true` if this variable was declared with the 'const' modifier.
   bool get isConst;
 
-  /**
-   * Return `true` if this variable was declared with the 'final' modifier.
-   * Variables that are declared with the 'const' modifier will return `false`
-   * even though they are implicitly final.
-   */
+  /// Return `true` if this variable was declared with the 'final' modifier.
+  /// Variables that are declared with the 'const' modifier will return `false`
+  /// even though they are implicitly final.
   bool get isFinal;
 
-  /**
-   * Return the token representing either the 'final', 'const' or 'var' keyword,
-   * or `null` if no keyword was used.
-   */
+  /// Return the token representing either the 'final', 'const' or 'var'
+  /// keyword, or `null` if no keyword was used.
   Token get keyword;
 
-  /**
-   * Set the token representing either the 'final', 'const' or 'var' keyword to
-   * the given [token].
-   */
+  /// Set the token representing either the 'final', 'const' or 'var' keyword to
+  /// the given [token].
   void set keyword(Token token);
 
-  /**
-   * Return the name of the declared type of the parameter, or `null` if the
-   * parameter does not have a declared type.
-   */
+  /// Return the name of the declared type of the parameter, or `null` if the
+  /// parameter does not have a declared type.
   TypeAnnotation get type;
 
-  /**
-   * Set the declared type of the parameter to the given [type].
-   */
+  /// Set the declared type of the parameter to the given [type].
   void set type(TypeAnnotation type);
 }
 
-/**
- * A formal parameter with a default value. There are two kinds of parameters
- * that are both represented by this class: named formal parameters and
- * positional formal parameters.
- *
- *    defaultFormalParameter ::=
- *        [NormalFormalParameter] ('=' [Expression])?
- *
- *    defaultNamedParameter ::=
- *        [NormalFormalParameter] (':' [Expression])?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DefaultFormalParameter extends FormalParameter {
-  /**
-   * Return the expression computing the default value for the parameter, or
-   * `null` if there is no default value.
-   */
+/// A formal parameter with a default value. There are two kinds of parameters
+/// that are both represented by this class: named formal parameters and
+/// positional formal parameters.
+///
+///    defaultFormalParameter ::=
+///        [NormalFormalParameter] ('=' [Expression])?
+///
+///    defaultNamedParameter ::=
+///        [NormalFormalParameter] (':' [Expression])?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class DefaultFormalParameter implements FormalParameter {
+  /// Return the expression computing the default value for the parameter, or
+  /// `null` if there is no default value.
   Expression get defaultValue;
 
-  /**
-   * Set the expression computing the default value for the parameter to the
-   * given [expression].
-   */
+  /// Set the expression computing the default value for the parameter to the
+  /// given [expression].
   void set defaultValue(Expression expression);
 
-  /**
-   * Set the kind of this parameter to the given [kind].
-   */
+  /// Set the kind of this parameter to the given [kind].
   void set kind(ParameterKind kind);
 
-  /**
-   * Return the formal parameter with which the default value is associated.
-   */
+  /// Return the formal parameter with which the default value is associated.
   NormalFormalParameter get parameter;
 
-  /**
-   * Set the formal parameter with which the default value is associated to the
-   * given [formalParameter].
-   */
+  /// Set the formal parameter with which the default value is associated to the
+  /// given [formalParameter].
   void set parameter(NormalFormalParameter formalParameter);
 
-  /**
-   * Return the token separating the parameter from the default value, or `null`
-   * if there is no default value.
-   */
+  /// Return the token separating the parameter from the default value, or
+  /// `null` if there is no default value.
   Token get separator;
 
-  /**
-   * Set the token separating the parameter from the default value to the given
-   * [token].
-   */
+  /// Set the token separating the parameter from the default value to the given
+  /// [token].
   void set separator(Token token);
 }
 
-/**
- * A node that represents a directive.
- *
- *    directive ::=
- *        [ExportDirective]
- *      | [ImportDirective]
- *      | [LibraryDirective]
- *      | [PartDirective]
- *      | [PartOfDirective]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Directive extends AnnotatedNode {
-  /**
-   * Return the element associated with this directive, or `null` if the AST
-   * structure has not been resolved or if this directive could not be resolved.
-   */
+/// A node that represents a directive.
+///
+///    directive ::=
+///        [ExportDirective]
+///      | [ImportDirective]
+///      | [LibraryDirective]
+///      | [PartDirective]
+///      | [PartOfDirective]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Directive implements AnnotatedNode {
+  /// Return the element associated with this directive, or `null` if the AST
+  /// structure has not been resolved or if this directive could not be
+  /// resolved.
   Element get element;
 
-  /**
-   * Set the element associated with this directive to the given [element].
-   */
+  /// Set the element associated with this directive to the given [element].
   void set element(Element element);
 
-  /**
-   * Return the token representing the keyword that introduces this directive
-   * ('import', 'export', 'library' or 'part').
-   */
+  /// Return the token representing the keyword that introduces this directive
+  /// ('import', 'export', 'library' or 'part').
   Token get keyword;
 }
 
-/**
- * A do statement.
- *
- *    doStatement ::=
- *        'do' [Statement] 'while' '(' [Expression] ')' ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DoStatement extends Statement {
-  /**
-   * Return the body of the loop.
-   */
+/// A do statement.
+///
+///    doStatement ::=
+///        'do' [Statement] 'while' '(' [Expression] ')' ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class DoStatement implements Statement {
+  /// Return the body of the loop.
   Statement get body;
 
-  /**
-   * Set the body of the loop to the given [statement].
-   */
+  /// Set the body of the loop to the given [statement].
   void set body(Statement statement);
 
-  /**
-   * Return the condition that determines when the loop will terminate.
-   */
+  /// Return the condition that determines when the loop will terminate.
   Expression get condition;
 
-  /**
-   * Set the condition that determines when the loop will terminate to the given
-   * [expression].
-   */
+  /// Set the condition that determines when the loop will terminate to the
+  /// given [expression].
   void set condition(Expression expression);
 
-  /**
-   * Return the token representing the 'do' keyword.
-   */
+  /// Return the token representing the 'do' keyword.
   Token get doKeyword;
 
-  /**
-   * Set the token representing the 'do' keyword to the given [token].
-   */
+  /// Set the token representing the 'do' keyword to the given [token].
   void set doKeyword(Token token);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 
-  /**
-   * Return the semicolon terminating the statement.
-   */
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the token representing the 'while' keyword.
-   */
+  /// Return the token representing the 'while' keyword.
   Token get whileKeyword;
 
-  /**
-   * Set the token representing the 'while' keyword to the given [token].
-   */
+  /// Set the token representing the 'while' keyword to the given [token].
   void set whileKeyword(Token token);
 }
 
-/**
- * A dotted name, used in a configuration within an import or export directive.
- *
- *    dottedName ::=
- *        [SimpleIdentifier] ('.' [SimpleIdentifier])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DottedName extends AstNode {
-  /**
-   * Return the components of the identifier.
-   */
+/// A dotted name, used in a configuration within an import or export directive.
+///
+///    dottedName ::=
+///        [SimpleIdentifier] ('.' [SimpleIdentifier])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class DottedName implements AstNode {
+  /// Return the components of the identifier.
   NodeList<SimpleIdentifier> get components;
 }
 
-/**
- * A floating point literal expression.
- *
- *    doubleLiteral ::=
- *        decimalDigit+ ('.' decimalDigit*)? exponent?
- *      | '.' decimalDigit+ exponent?
- *
- *    exponent ::=
- *        ('e' | 'E') ('+' | '-')? decimalDigit+
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class DoubleLiteral extends Literal {
-  /**
-   * Return the token representing the literal.
-   */
+/// A floating point literal expression.
+///
+///    doubleLiteral ::=
+///        decimalDigit+ ('.' decimalDigit*)? exponent?
+///      | '.' decimalDigit+ exponent?
+///
+///    exponent ::=
+///        ('e' | 'E') ('+' | '-')? decimalDigit+
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class DoubleLiteral implements Literal {
+  /// Return the token representing the literal.
   Token get literal;
 
-  /**
-   * Set the token representing the literal to the given [token].
-   */
+  /// Set the token representing the literal to the given [token].
   void set literal(Token token);
 
-  /**
-   * Return the value of the literal.
-   */
+  /// Return the value of the literal.
   double get value;
 
-  /**
-   * Set the value of the literal to the given [value].
-   */
+  /// Set the value of the literal to the given [value].
   void set value(double value);
 }
 
-/**
- * An empty function body, which can only appear in constructors or abstract
- * methods.
- *
- *    emptyFunctionBody ::=
- *        ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class EmptyFunctionBody extends FunctionBody {
-  /**
-   * Return the token representing the semicolon that marks the end of the
-   * function body.
-   */
+/// An empty function body, which can only appear in constructors or abstract
+/// methods.
+///
+///    emptyFunctionBody ::=
+///        ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class EmptyFunctionBody implements FunctionBody {
+  /// Return the token representing the semicolon that marks the end of the
+  /// function body.
   Token get semicolon;
 
-  /**
-   * Set the token representing the semicolon that marks the end of the
-   * function body to the given [token].
-   */
+  /// Set the token representing the semicolon that marks the end of the
+  /// function body to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * An empty statement.
- *
- *    emptyStatement ::=
- *        ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class EmptyStatement extends Statement {
-  /**
-   * Return the semicolon terminating the statement.
-   */
+/// An empty statement.
+///
+///    emptyStatement ::=
+///        ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class EmptyStatement implements Statement {
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * The declaration of an enum constant.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class EnumConstantDeclaration extends Declaration {
-  /**
-   * Return the name of the constant.
-   */
+/// The declaration of an enum constant.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class EnumConstantDeclaration implements Declaration {
+  /// Return the name of the constant.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the constant to the given [name].
-   */
+  /// Set the name of the constant to the given [name].
   void set name(SimpleIdentifier name);
 }
 
-/**
- * The declaration of an enumeration.
- *
- *    enumType ::=
- *        metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class EnumDeclaration extends NamedCompilationUnitMember {
-  /**
-   * Return the enumeration constants being declared.
-   */
+/// The declaration of an enumeration.
+///
+///    enumType ::=
+///        metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class EnumDeclaration implements NamedCompilationUnitMember {
+  /// Return the enumeration constants being declared.
   NodeList<EnumConstantDeclaration> get constants;
 
   @override
@@ -2572,894 +1906,792 @@
   @override
   ClassElement get element;
 
-  /**
-   * Return the 'enum' keyword.
-   */
+  /// Return the 'enum' keyword.
   Token get enumKeyword;
 
-  /**
-   * Set the 'enum' keyword to the given [token].
-   */
+  /// Set the 'enum' keyword to the given [token].
   void set enumKeyword(Token token);
 
-  /**
-   * Return the left curly bracket.
-   */
+  /// Return the left curly bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left curly bracket to the given [token].
-   */
+  /// Set the left curly bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right curly bracket.
-   */
+  /// Return the right curly bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 }
 
-/**
- * An export directive.
- *
- *    exportDirective ::=
- *        [Annotation] 'export' [StringLiteral] [Combinator]* ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ExportDirective extends NamespaceDirective {}
+/// An export directive.
+///
+///    exportDirective ::=
+///        [Annotation] 'export' [StringLiteral] [Combinator]* ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExportDirective implements NamespaceDirective {}
 
-/**
- * A node that represents an expression.
- *
- *    expression ::=
- *        [AssignmentExpression]
- *      | [ConditionalExpression] cascadeSection*
- *      | [ThrowExpression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Expression extends AstNode {
-  /**
-   * An empty list of expressions.
-   */
-  @deprecated
-  static const List<Expression> EMPTY_LIST = const <Expression>[];
-
-  /**
-   * Return the best parameter element information available for this
-   * expression. If type propagation was able to find a better parameter element
-   * than static analysis, that type will be returned. Otherwise, the result of
-   * static analysis will be returned.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticParameterElement] instead.
-   */
+/// A node that represents an expression.
+///
+///    expression ::=
+///        [AssignmentExpression]
+///      | [ConditionalExpression] cascadeSection*
+///      | [ThrowExpression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Expression implements CollectionElement {
+  /// Return the best parameter element information available for this
+  /// expression. If type propagation was able to find a better parameter
+  /// element than static analysis, that type will be returned. Otherwise, the
+  /// result of static analysis will be returned.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticParameterElement] instead.
   @deprecated
   ParameterElement get bestParameterElement;
 
-  /**
-   * Return the best type information available for this expression. If type
-   * propagation was able to find a better type than static analysis, that type
-   * will be returned. Otherwise, the result of static analysis will be
-   * returned. If no type analysis has been performed, then the type 'dynamic'
-   * will be returned.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticType] instead, but be aware that [staticType] will return `null`
-   * under some circumstances, while [bestType] did not.
-   */
+  /// Return the best type information available for this expression. If type
+  /// propagation was able to find a better type than static analysis, that type
+  /// will be returned. Otherwise, the result of static analysis will be
+  /// returned. If no type analysis has been performed, then the type 'dynamic'
+  /// will be returned.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticType] instead, but be aware that [staticType] will return
+  /// `null` under some circumstances, while [bestType] did not.
   @deprecated
   DartType get bestType;
 
-  /**
-   * Return `true` if this expression is syntactically valid for the LHS of an
-   * [AssignmentExpression].
-   */
+  /// Return `true` if this expression is syntactically valid for the LHS of an
+  /// [AssignmentExpression].
   bool get isAssignable;
 
-  /**
-   * Return the precedence of this expression. The precedence is a positive
-   * integer value that defines how the source code is parsed into an AST. For
-   * example `a * b + c` is parsed as `(a * b) + c` because the precedence of
-   * `*` is greater than the precedence of `+`.
-   *
-   * Clients should not assume that returned values will stay the same, they
-   * might change as result of specification change. Only relative order should
-   * be used.
-   */
+  /// Return the precedence of this expression. The precedence is a positive
+  /// integer value that defines how the source code is parsed into an AST. For
+  /// example `a * b + c` is parsed as `(a * b) + c` because the precedence of
+  /// `*` is greater than the precedence of `+`.
+  ///
+  /// Clients should not assume that returned values will stay the same, they
+  /// might change as result of specification change. Only relative order should
+  /// be used.
   int get precedence;
 
-  /**
-   * If this expression is an argument to an invocation, and the AST structure
-   * has been resolved, and the function being invoked is known based on
-   * propagated type information, and this expression corresponds to one of the
-   * parameters of the function being invoked, then return the parameter element
-   * representing the parameter to which the value of this expression will be
-   * bound. Otherwise, return `null`.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticParameterElement] instead.
-   */
+  /// If this expression is an argument to an invocation, and the AST structure
+  /// has been resolved, and the function being invoked is known based on
+  /// propagated type information, and this expression corresponds to one of the
+  /// parameters of the function being invoked, then return the parameter
+  /// element representing the parameter to which the value of this expression
+  /// will be bound. Otherwise, return `null`.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticParameterElement] instead.
   @deprecated
   ParameterElement get propagatedParameterElement;
 
-  /**
-   * Return the propagated type of this expression, or `null` if type
-   * propagation has not been performed on the AST structure.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticType] instead.
-   */
+  /// Return the propagated type of this expression, or `null` if type
+  /// propagation has not been performed on the AST structure.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticType] instead.
   @deprecated
   DartType get propagatedType;
 
-  /**
-   * Set the propagated type of this expression to the given [type].
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticType] instead.
-   */
+  /// Set the propagated type of this expression to the given [type].
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticType] instead.
   @deprecated
   void set propagatedType(DartType type);
 
-  /**
-   * If this expression is an argument to an invocation, and the AST structure
-   * has been resolved, and the function being invoked is known based on static
-   * type information, and this expression corresponds to one of the parameters
-   * of the function being invoked, then return the parameter element
-   * representing the parameter to which the value of this expression will be
-   * bound. Otherwise, return `null`.
-   */
+  /// If this expression is an argument to an invocation, and the AST structure
+  /// has been resolved, and the function being invoked is known based on static
+  /// type information, and this expression corresponds to one of the parameters
+  /// of the function being invoked, then return the parameter element
+  /// representing the parameter to which the value of this expression will be
+  /// bound. Otherwise, return `null`.
   ParameterElement get staticParameterElement;
 
-  /**
-   * Return the static type of this expression, or `null` if the AST structure
-   * has not been resolved.
-   */
+  /// Return the static type of this expression, or `null` if the AST structure
+  /// has not been resolved.
   DartType get staticType;
 
-  /**
-   * Set the static type of this expression to the given [type].
-   */
+  /// Set the static type of this expression to the given [type].
   void set staticType(DartType type);
 
-  /**
-   * If this expression is a parenthesized expression, return the result of
-   * unwrapping the expression inside the parentheses. Otherwise, return this
-   * expression.
-   */
+  /// If this expression is a parenthesized expression, return the result of
+  /// unwrapping the expression inside the parentheses. Otherwise, return this
+  /// expression.
   Expression get unParenthesized;
 }
 
-/**
- * A function body consisting of a single expression.
- *
- *    expressionFunctionBody ::=
- *        'async'? '=>' [Expression] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ExpressionFunctionBody extends FunctionBody {
-  /**
-   * Return the expression representing the body of the function.
-   */
+/// A function body consisting of a single expression.
+///
+///    expressionFunctionBody ::=
+///        'async'? '=>' [Expression] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExpressionFunctionBody implements FunctionBody {
+  /// Return the expression representing the body of the function.
   Expression get expression;
 
-  /**
-   * Set the expression representing the body of the function to the given
-   * [expression].
-   */
+  /// Set the expression representing the body of the function to the given
+  /// [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the token introducing the expression that represents the body of the
-   * function.
-   */
+  /// Return the token introducing the expression that represents the body of the
+  /// function.
   Token get functionDefinition;
 
-  /**
-   * Set the token introducing the expression that represents the body of the
-   * function to the given [token].
-   */
+  /// Set the token introducing the expression that represents the body of the
+  /// function to the given [token].
   void set functionDefinition(Token token);
 
-  /**
-   * Set token representing the 'async' or 'sync' keyword to the given [token].
-   */
+  /// Set token representing the 'async' or 'sync' keyword to the given [token].
   void set keyword(Token token);
 
-  /**
-   * Return the semicolon terminating the statement.
-   */
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * An expression used as a statement.
- *
- *    expressionStatement ::=
- *        [Expression]? ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ExpressionStatement extends Statement {
-  /**
-   * Return the expression that comprises the statement.
-   */
+/// An expression used as a statement.
+///
+///    expressionStatement ::=
+///        [Expression]? ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExpressionStatement implements Statement {
+  /// Return the expression that comprises the statement.
   Expression get expression;
 
-  /**
-   * Set the expression that comprises the statement to the given [expression].
-   */
+  /// Set the expression that comprises the statement to the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the semicolon terminating the statement, or `null` if the expression is a
-   * function expression and therefore isn't followed by a semicolon.
-   */
+  /// Return the semicolon terminating the statement, or `null` if the
+  /// expression is a function expression and therefore isn't followed by a
+  /// semicolon.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * The "extends" clause in a class declaration.
- *
- *    extendsClause ::=
- *        'extends' [TypeName]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ExtendsClause extends AstNode {
-  /**
-   * Return the token representing the 'extends' keyword.
-   */
+/// The "extends" clause in a class declaration.
+///
+///    extendsClause ::=
+///        'extends' [TypeName]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ExtendsClause implements AstNode {
+  /// Return the token representing the 'extends' keyword.
   Token get extendsKeyword;
 
-  /**
-   * Set the token representing the 'extends' keyword to the given [token].
-   */
+  /// Set the token representing the 'extends' keyword to the given [token].
   void set extendsKeyword(Token token);
 
-  /**
-   * Return the name of the class that is being extended.
-   */
+  /// Return the name of the class that is being extended.
   TypeName get superclass;
 
-  /**
-   * Set the name of the class that is being extended to the given [name].
-   */
+  /// Set the name of the class that is being extended to the given [name].
   void set superclass(TypeName name);
 }
 
-/**
- * The declaration of one or more fields of the same type.
- *
- *    fieldDeclaration ::=
- *        'static'? [VariableDeclarationList] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FieldDeclaration extends ClassMember {
-  /**
-   * The 'covariant' keyword, or `null` if the keyword was not used.
-   */
+/// The declaration of one or more fields of the same type.
+///
+///    fieldDeclaration ::=
+///        'static'? [VariableDeclarationList] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FieldDeclaration implements ClassMember {
+  /// The 'covariant' keyword, or `null` if the keyword was not used.
   Token get covariantKeyword;
 
-  /**
-   * Set the token for the 'covariant' keyword to the given [token].
-   */
+  /// Set the token for the 'covariant' keyword to the given [token].
   void set covariantKeyword(Token token);
 
-  /**
-   * Return the fields being declared.
-   */
+  /// Return the fields being declared.
   VariableDeclarationList get fields;
 
-  /**
-   * Set the fields being declared to the given list of [fields].
-   */
+  /// Set the fields being declared to the given list of [fields].
   void set fields(VariableDeclarationList fields);
 
-  /**
-   * Return `true` if the fields are declared to be static.
-   */
+  /// Return `true` if the fields are declared to be static.
   bool get isStatic;
 
-  /**
-   * Return the semicolon terminating the declaration.
-   */
+  /// Return the semicolon terminating the declaration.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the declaration to the given [token].
-   */
+  /// Set the semicolon terminating the declaration to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the token representing the 'static' keyword, or `null` if the fields
-   * are not static.
-   */
+  /// Return the token representing the 'static' keyword, or `null` if the
+  /// fields are not static.
   Token get staticKeyword;
 
-  /**
-   * Set the token representing the 'static' keyword to the given [token].
-   */
+  /// Set the token representing the 'static' keyword to the given [token].
   void set staticKeyword(Token token);
 }
 
-/**
- * A field formal parameter.
- *
- *    fieldFormalParameter ::=
- *        ('final' [TypeAnnotation] | 'const' [TypeAnnotation] | 'var' | [TypeAnnotation])?
- *        'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FieldFormalParameter extends NormalFormalParameter {
-  /**
-   * Return the token representing either the 'final', 'const' or 'var' keyword,
-   * or `null` if no keyword was used.
-   */
+/// A field formal parameter.
+///
+///    fieldFormalParameter ::=
+///        ('final' [TypeAnnotation] | 'const' [TypeAnnotation] | 'var' | [TypeAnnotation])?
+///        'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FieldFormalParameter implements NormalFormalParameter {
+  /// Return the token representing either the 'final', 'const' or 'var'
+  /// keyword, or `null` if no keyword was used.
   Token get keyword;
 
-  /**
-   * Set the token representing either the 'final', 'const' or 'var' keyword to
-   * the given [token].
-   */
+  /// Set the token representing either the 'final', 'const' or 'var' keyword to
+  /// the given [token].
   void set keyword(Token token);
 
-  /**
-   * Return the parameters of the function-typed parameter, or `null` if this is
-   * not a function-typed field formal parameter.
-   */
+  /// Return the parameters of the function-typed parameter, or `null` if this
+  /// is not a function-typed field formal parameter.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters of the function-typed parameter to the given
-   * [parameters].
-   */
+  /// Set the parameters of the function-typed parameter to the given
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * Return the token representing the period.
-   */
+  /// Return the token representing the period.
   Token get period;
 
-  /**
-   * Set the token representing the period to the given [token].
-   */
+  /// Set the token representing the period to the given [token].
   void set period(Token token);
 
-  /**
-   * Return the token representing the 'this' keyword.
-   */
+  /// Return the token representing the 'this' keyword.
   Token get thisKeyword;
 
-  /**
-   * Set the token representing the 'this' keyword to the given [token].
-   */
+  /// Set the token representing the 'this' keyword to the given [token].
   void set thisKeyword(Token token);
 
-  /**
-   * Return the declared type of the parameter, or `null` if the parameter does
-   * not have a declared type. Note that if this is a function-typed field
-   * formal parameter this is the return type of the function.
-   */
+  /// Return the declared type of the parameter, or `null` if the parameter does
+  /// not have a declared type. Note that if this is a function-typed field
+  /// formal parameter this is the return type of the function.
   TypeAnnotation get type;
 
-  /**
-   * Set the declared type of the parameter to the given [type].
-   */
+  /// Set the declared type of the parameter to the given [type].
   void set type(TypeAnnotation type);
 
-  /**
-   * Return the type parameters associated with this method, or `null` if this
-   * method is not a generic method.
-   */
+  /// Return the type parameters associated with this method, or `null` if this
+  /// method is not a generic method.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
+  /// Set the type parameters associated with this method to the given
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * A for-each statement.
- *
- *    forEachStatement ::=
- *        'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
- *      | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ForEachStatement extends Statement {
-  /**
-   * Return the token representing the 'await' keyword, or `null` if there is no
-   * 'await' keyword.
-   */
-  Token get awaitKeyword;
-
-  /**
-   * Set the token representing the 'await' keyword to the given [token].
-   */
-  void set awaitKeyword(Token token);
-
-  /**
-   * Return the body of the loop.
-   */
-  Statement get body;
-
-  /**
-   * Set the body of the loop to the given [statement].
-   */
-  void set body(Statement statement);
-
-  /**
-   * Return the token representing the 'for' keyword.
-   */
-  Token get forKeyword;
-
-  /**
-   * Set the token representing the 'for' keyword to the given [token].
-   */
-  void set forKeyword(Token token);
-
-  /**
-   * Return the loop variable, or `null` if the loop variable is declared in the
-   * 'for'.
-   */
-  SimpleIdentifier get identifier;
-
-  /**
-   * Set the loop variable to the given [identifier].
-   */
-  void set identifier(SimpleIdentifier identifier);
-
-  /**
-   * Return the token representing the 'in' keyword.
-   */
+/// The parts of a for-each loop that control the iteration.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForEachParts implements ForLoopParts {
+  /// Return the token representing the 'in' keyword.
   Token get inKeyword;
 
-  /**
-   * Set the token representing the 'in' keyword to the given [token].
-   */
+  /// Return the expression evaluated to produce the iterator.
+  Expression get iterable;
+}
+
+/// The parts of a for-each loop that control the iteration when the loop
+/// variable is declared as part of the for loop.
+///
+///   forLoopParts ::=
+///       [DeclaredIdentifier] 'in' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForEachPartsWithDeclaration implements ForEachParts {
+  /// Return the declaration of the loop variable.
+  DeclaredIdentifier get loopVariable;
+}
+
+/// The parts of a for-each loop that control the iteration when the loop
+/// variable is declared outside of the for loop.
+///
+///   forLoopParts ::=
+///       [SimpleIdentifier] 'in' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForEachPartsWithIdentifier implements ForEachParts {
+  /// Return the loop variable.
+  SimpleIdentifier get identifier;
+}
+
+/// A for-each statement.
+///
+///    forEachStatement ::=
+///        'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
+///      | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
+///
+/// This is the class that is used to represent a for-each loop when neither the
+/// 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+/// If either of those experiments are enabled, then [ForStatement2] will be
+/// used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForEachStatement implements Statement {
+  /// Return the token representing the 'await' keyword, or `null` if there is
+  /// no 'await' keyword.
+  Token get awaitKeyword;
+
+  /// Set the token representing the 'await' keyword to the given [token].
+  void set awaitKeyword(Token token);
+
+  /// Return the body of the loop.
+  Statement get body;
+
+  /// Set the body of the loop to the given [statement].
+  void set body(Statement statement);
+
+  /// Return the token representing the 'for' keyword.
+  Token get forKeyword;
+
+  /// Set the token representing the 'for' keyword to the given [token].
+  void set forKeyword(Token token);
+
+  /// Return the loop variable, or `null` if the loop variable is declared in
+  /// the 'for'.
+  SimpleIdentifier get identifier;
+
+  /// Set the loop variable to the given [identifier].
+  void set identifier(SimpleIdentifier identifier);
+
+  /// Return the token representing the 'in' keyword.
+  Token get inKeyword;
+
+  /// Set the token representing the 'in' keyword to the given [token].
   void set inKeyword(Token token);
 
-  /**
-   * Return the expression evaluated to produce the iterator.
-   */
+  /// Return the expression evaluated to produce the iterator.
   Expression get iterable;
 
-  /**
-   * Set the expression evaluated to produce the iterator to the given
-   * [expression].
-   */
+  /// Set the expression evaluated to produce the iterator to the given
+  /// [expression].
   void set iterable(Expression expression);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the declaration of the loop variable, or `null` if the loop variable
-   * is a simple identifier.
-   */
+  /// Return the declaration of the loop variable, or `null` if the loop
+  /// variable is a simple identifier.
   DeclaredIdentifier get loopVariable;
 
-  /**
-   * Set the declaration of the loop variable to the given [variable].
-   */
+  /// Set the declaration of the loop variable to the given [variable].
   void set loopVariable(DeclaredIdentifier variable);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 }
 
-/**
- * A node representing a parameter to a function.
- *
- *    formalParameter ::=
- *        [NormalFormalParameter]
- *      | [DefaultFormalParameter]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FormalParameter extends AstNode {
-  /**
-   * The 'covariant' keyword, or `null` if the keyword was not used.
-   */
+/// The basic structure of a for element.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForElement implements CollectionElement {
+  /// Return the token representing the 'await' keyword, or `null` if there was
+  /// no 'await' keyword.
+  Token get awaitKeyword;
+
+  /// Return the body of the loop.
+  CollectionElement get body;
+
+  /// Return the token representing the 'for' keyword.
+  Token get forKeyword;
+
+  /// Return the parts of the for element that control the iteration.
+  ForLoopParts get forLoopParts;
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+}
+
+/// The parts of a for or for-each loop that control the iteration.
+///
+///   forLoopParts ::=
+///       [VariableDeclaration] ';' [Expression]? ';' expressionList?
+///     | [Expression]? ';' [Expression]? ';' expressionList?
+///     | [DeclaredIdentifier] 'in' [Expression]
+///     | [SimpleIdentifier] 'in' [Expression]
+///
+///   expressionList ::=
+///       [Expression] (',' [Expression])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForLoopParts implements AstNode {}
+
+/// A node representing a parameter to a function.
+///
+///    formalParameter ::=
+///        [NormalFormalParameter]
+///      | [DefaultFormalParameter]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FormalParameter implements AstNode {
+  /// The 'covariant' keyword, or `null` if the keyword was not used.
   Token get covariantKeyword;
 
-  /**
-   * Return the element representing this parameter, or `null` if this parameter
-   * has not been resolved.
-   */
+  /// Return the element representing this parameter, or `null` if this
+  /// parameter has not been resolved.
   ParameterElement get declaredElement;
 
-  /**
-   * Return the element representing this parameter, or `null` if this parameter
-   * has not been resolved.
-   */
+  /// Return the element representing this parameter, or `null` if this
+  /// parameter has not been resolved.
   @deprecated
   ParameterElement get element;
 
-  /**
-   * Return the name of the parameter being declared.
-   */
+  /// Return the name of the parameter being declared.
   SimpleIdentifier get identifier;
 
-  /**
-   * Return `true` if this parameter was declared with the 'const' modifier.
-   */
+  /// Return `true` if this parameter was declared with the 'const' modifier.
   bool get isConst;
 
-  /**
-   * Return `true` if this parameter was declared with the 'final' modifier.
-   * Parameters that are declared with the 'const' modifier will return `false`
-   * even though they are implicitly final.
-   */
+  /// Return `true` if this parameter was declared with the 'final' modifier.
+  /// Parameters that are declared with the 'const' modifier will return `false`
+  /// even though they are implicitly final.
   bool get isFinal;
 
-  /**
-   * Return `true` if this parameter is a named parameter. Named parameters are
-   * always optional, even when they are annotated with the `@required`
-   * annotation.
-   */
+  /// Return `true` if this parameter is a named parameter. Named parameters are
+  /// always optional, even when they are annotated with the `@required`
+  /// annotation.
   bool get isNamed;
 
-  /**
-   * Return `true` if this parameter is an optional parameter. Optional
-   * parameters can either be positional or named.
-   */
+  /// Return `true` if this parameter is an optional parameter. Optional
+  /// parameters can either be positional or named.
   bool get isOptional;
 
-  /**
-   * Return `true` if this parameter is both an optional and positional
-   * parameter.
-   */
+  /// Return `true` if this parameter is both an optional and positional
+  /// parameter.
   bool get isOptionalPositional;
 
-  /**
-   * Return `true` if this parameter is a positional parameter. Positional
-   * parameters can either be required or optional.
-   */
+  /// Return `true` if this parameter is a positional parameter. Positional
+  /// parameters can either be required or optional.
   bool get isPositional;
 
-  /**
-   * Return `true` if this parameter is a required parameter. Required
-   * parameters are always positional.
-   *
-   * Note: this will return `false` for a named parameter that is annotated with
-   * the `@required` annotation.
-   */
+  /// Return `true` if this parameter is a required parameter. Required
+  /// parameters are always positional.
+  ///
+  /// Note: this will return `false` for a named parameter that is annotated with
+  /// the `@required` annotation.
   bool get isRequired;
 
-  /**
-   * Return the kind of this parameter.
-   */
+  /// Return the kind of this parameter.
   @deprecated
   ParameterKind get kind;
 
-  /**
-   * Return the annotations associated with this parameter.
-   */
+  /// Return the annotations associated with this parameter.
   NodeList<Annotation> get metadata;
 }
 
-/**
- * The formal parameter list of a method declaration, function declaration, or
- * function type alias.
- *
- * While the grammar requires all optional formal parameters to follow all of
- * the normal formal parameters and at most one grouping of optional formal
- * parameters, this class does not enforce those constraints. All parameters are
- * flattened into a single list, which can have any or all kinds of parameters
- * (normal, named, and positional) in any order.
- *
- *    formalParameterList ::=
- *        '(' ')'
- *      | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
- *      | '(' optionalFormalParameters ')'
- *
- *    normalFormalParameters ::=
- *        [NormalFormalParameter] (',' [NormalFormalParameter])*
- *
- *    optionalFormalParameters ::=
- *        optionalPositionalFormalParameters
- *      | namedFormalParameters
- *
- *    optionalPositionalFormalParameters ::=
- *        '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'
- *
- *    namedFormalParameters ::=
- *        '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FormalParameterList extends AstNode {
-  /**
-   * Return the left square bracket ('[') or left curly brace ('{') introducing
-   * the optional parameters, or `null` if there are no optional parameters.
-   */
+/// The formal parameter list of a method declaration, function declaration, or
+/// function type alias.
+///
+/// While the grammar requires all optional formal parameters to follow all of
+/// the normal formal parameters and at most one grouping of optional formal
+/// parameters, this class does not enforce those constraints. All parameters
+/// are flattened into a single list, which can have any or all kinds of
+/// parameters (normal, named, and positional) in any order.
+///
+///    formalParameterList ::=
+///        '(' ')'
+///      | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+///      | '(' optionalFormalParameters ')'
+///
+///    normalFormalParameters ::=
+///        [NormalFormalParameter] (',' [NormalFormalParameter])*
+///
+///    optionalFormalParameters ::=
+///        optionalPositionalFormalParameters
+///      | namedFormalParameters
+///
+///    optionalPositionalFormalParameters ::=
+///        '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'
+///
+///    namedFormalParameters ::=
+///        '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FormalParameterList implements AstNode {
+  /// Return the left square bracket ('[') or left curly brace ('{') introducing
+  /// the optional parameters, or `null` if there are no optional parameters.
   Token get leftDelimiter;
 
-  /**
-   * Set the left square bracket ('[') or left curly brace ('{') introducing
-   * the optional parameters to the given [token].
-   */
+  /// Set the left square bracket ('[') or left curly brace ('{') introducing
+  /// the optional parameters to the given [token].
   void set leftDelimiter(Token token);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return a list containing the elements representing the parameters in this
-   * list. The list will contain `null`s if the parameters in this list have not
-   * been resolved.
-   */
+  /// Return a list containing the elements representing the parameters in this
+  /// list. The list will contain `null`s if the parameters in this list have
+  /// not been resolved.
   List<ParameterElement> get parameterElements;
 
-  /**
-   * Return the parameters associated with the method.
-   */
+  /// Return the parameters associated with the method.
   NodeList<FormalParameter> get parameters;
 
-  /**
-   * Return the right square bracket (']') or right curly brace ('}') terminating the
-   * optional parameters, or `null` if there are no optional parameters.
-   */
+  /// Return the right square bracket (']') or right curly brace ('}')
+  /// terminating the optional parameters, or `null` if there are no optional
+  /// parameters.
   Token get rightDelimiter;
 
-  /**
-   * Set the right square bracket (']') or right curly brace ('}') terminating the
-   * optional parameters to the given [token].
-   */
+  /// Set the right square bracket (']') or right curly brace ('}') terminating
+  /// the optional parameters to the given [token].
   void set rightDelimiter(Token token);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 }
 
-/**
- * A for statement.
- *
- *    forStatement ::=
- *        'for' '(' forLoopParts ')' [Statement]
- *
- *    forLoopParts ::=
- *        forInitializerStatement ';' [Expression]? ';' [Expression]?
- *
- *    forInitializerStatement ::=
- *        [DefaultFormalParameter]
- *      | [Expression]?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ForStatement extends Statement {
-  /**
-   * Return the body of the loop.
-   */
-  Statement get body;
-
-  /**
-   * Set the body of the loop to the given [statement].
-   */
-  void set body(Statement statement);
-
-  /**
-   * Return the condition used to determine when to terminate the loop, or
-   * `null` if there is no condition.
-   */
+/// The parts of a for loop that control the iteration.
+///
+///   forLoopParts ::=
+///       [VariableDeclaration] ';' [Expression]? ';' expressionList?
+///     | [Expression]? ';' [Expression]? ';' expressionList?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForParts implements ForLoopParts {
+  /// Return the condition used to determine when to terminate the loop, or
+  /// `null` if there is no condition.
   Expression get condition;
 
-  /**
-   * Set the condition used to determine when to terminate the loop to the given
-   * [expression].
-   */
-  void set condition(Expression expression);
-
-  /**
-   * Return the token representing the 'for' keyword.
-   */
-  Token get forKeyword;
-
-  /**
-   * Set the token representing the 'for' keyword to the given [token].
-   */
-  void set forKeyword(Token token);
-
-  /**
-   * Return the initialization expression, or `null` if there is no
-   * initialization expression.
-   */
-  Expression get initialization;
-
-  /**
-   * Set the initialization expression to the given [expression].
-   */
-  void set initialization(Expression initialization);
-
-  /**
-   * Return the left parenthesis.
-   */
-  Token get leftParenthesis;
-
-  /**
-   * Set the left parenthesis to the given [token].
-   */
-  void set leftParenthesis(Token token);
-
-  /**
-   * Return the semicolon separating the initializer and the condition.
-   */
+  /// Return the semicolon separating the initializer and the condition.
   Token get leftSeparator;
 
-  /**
-   * Set the semicolon separating the initializer and the condition to the given
-   * [token].
-   */
-  void set leftSeparator(Token token);
-
-  /**
-   * Return the right parenthesis.
-   */
-  Token get rightParenthesis;
-
-  /**
-   * Set the right parenthesis to the given [token].
-   */
-  void set rightParenthesis(Token token);
-
-  /**
-   * Return the semicolon separating the condition and the updater.
-   */
+  /// Return the semicolon separating the condition and the updater.
   Token get rightSeparator;
 
-  /**
-   * Set the semicolon separating the condition and the updater to the given
-   * [token].
-   */
+  /// Return the list of expressions run after each execution of the loop body.
+  NodeList<Expression> get updaters;
+}
+
+/// The parts of a for loop that control the iteration when there are one or
+/// more variable declarations as part of the for loop.
+///
+///   forLoopParts ::=
+///       [VariableDeclarationList] ';' [Expression]? ';' expressionList?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForPartsWithDeclarations implements ForParts {
+  /// Return the declaration of the loop variables.
+  VariableDeclarationList get variables;
+}
+
+/// The parts of a for loop that control the iteration when there are no
+/// variable declarations as part of the for loop.
+///
+///   forLoopParts ::=
+///       [Expression]? ';' [Expression]? ';' expressionList?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForPartsWithExpression implements ForParts {
+  /// Return the initialization expression, or `null` if there is no
+  /// initialization expression.
+  Expression get initialization;
+}
+
+/// A for statement.
+///
+///    forStatement ::=
+///        'for' '(' forLoopParts ')' [Statement]
+///
+///    forLoopParts ::=
+///        forInitializerStatement ';' [Expression]? ';' [Expression]?
+///
+///    forInitializerStatement ::=
+///        [DefaultFormalParameter]
+///      | [Expression]?
+///
+/// This is the class that is used to represent a for loop when neither the
+/// 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+/// If either of those experiments are enabled, then [ForStatement2] will be
+/// used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForStatement implements Statement {
+  /// Return the body of the loop.
+  Statement get body;
+
+  /// Set the body of the loop to the given [statement].
+  void set body(Statement statement);
+
+  /// Return the condition used to determine when to terminate the loop, or
+  /// `null` if there is no condition.
+  Expression get condition;
+
+  /// Set the condition used to determine when to terminate the loop to the
+  /// given [expression].
+  void set condition(Expression expression);
+
+  /// Return the token representing the 'for' keyword.
+  Token get forKeyword;
+
+  /// Set the token representing the 'for' keyword to the given [token].
+  void set forKeyword(Token token);
+
+  /// Return the initialization expression, or `null` if there is no
+  /// initialization expression.
+  Expression get initialization;
+
+  /// Set the initialization expression to the given [expression].
+  void set initialization(Expression initialization);
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Set the left parenthesis to the given [token].
+  void set leftParenthesis(Token token);
+
+  /// Return the semicolon separating the initializer and the condition.
+  Token get leftSeparator;
+
+  /// Set the semicolon separating the initializer and the condition to the
+  /// given [token].
+  void set leftSeparator(Token token);
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+
+  /// Set the right parenthesis to the given [token].
+  void set rightParenthesis(Token token);
+
+  /// Return the semicolon separating the condition and the updater.
+  Token get rightSeparator;
+
+  /// Set the semicolon separating the condition and the updater to the given
+  /// [token].
   void set rightSeparator(Token token);
 
-  /**
-   * Return the list of expressions run after each execution of the loop body.
-   */
+  /// Return the list of expressions run after each execution of the loop body.
   NodeList<Expression> get updaters;
 
-  /**
-   * Return the declaration of the loop variables, or `null` if there are no
-   * variables.
-   */
+  /// Return the declaration of the loop variables, or `null` if there are no
+  /// variables.
   VariableDeclarationList get variables;
 
-  /**
-   * Set the declaration of the loop variables to the given [variableList].
-   */
+  /// Set the declaration of the loop variables to the given [variableList].
   void set variables(VariableDeclarationList variableList);
 }
 
-/**
- * A node representing the body of a function or method.
- *
- *    functionBody ::=
- *        [BlockFunctionBody]
- *      | [EmptyFunctionBody]
- *      | [ExpressionFunctionBody]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionBody extends AstNode {
-  /**
-   * Return `true` if this function body is asynchronous.
-   */
+/// A for or for-each statement.
+///
+///    forStatement ::=
+///        'for' '(' forLoopParts ')' [Statement]
+///
+///    forLoopParts ::=
+///       [VariableDeclaration] ';' [Expression]? ';' expressionList?
+///     | [Expression]? ';' [Expression]? ';' expressionList?
+///     | [DeclaredIdentifier] 'in' [Expression]
+///     | [SimpleIdentifier] 'in' [Expression]
+///
+/// This is the class that is used to represent a for loop when either the
+/// 'control-flow-collections' or 'spread-collections' experiments are enabled.
+/// If neither of those experiments are enabled, then either [ForStatement] or
+/// [ForEachStatement] will be used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ForStatement2 implements Statement {
+  /// Return the token representing the 'await' keyword, or `null` if there is
+  /// no 'await' keyword.
+  Token get awaitKeyword;
+
+  /// Return the body of the loop.
+  Statement get body;
+
+  /// Return the token representing the 'for' keyword.
+  Token get forKeyword;
+
+  /// Return the parts of the for element that control the iteration.
+  ForLoopParts get forLoopParts;
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+}
+
+/// A node representing the body of a function or method.
+///
+///    functionBody ::=
+///        [BlockFunctionBody]
+///      | [EmptyFunctionBody]
+///      | [ExpressionFunctionBody]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionBody implements AstNode {
+  /// Return `true` if this function body is asynchronous.
   bool get isAsynchronous;
 
-  /**
-   * Return `true` if this function body is a generator.
-   */
+  /// Return `true` if this function body is a generator.
   bool get isGenerator;
 
-  /**
-   * Return `true` if this function body is synchronous.
-   */
+  /// Return `true` if this function body is synchronous.
   bool get isSynchronous;
 
-  /**
-   * Return the token representing the 'async' or 'sync' keyword, or `null` if
-   * there is no such keyword.
-   */
+  /// Return the token representing the 'async' or 'sync' keyword, or `null` if
+  /// there is no such keyword.
   Token get keyword;
 
-  /**
-   * Return the star following the 'async' or 'sync' keyword, or `null` if there
-   * is no star.
-   */
+  /// Return the star following the 'async' or 'sync' keyword, or `null` if
+  /// there is no star.
   Token get star;
 
-  /**
-   * If [variable] is a local variable or parameter declared anywhere within
-   * the top level function or method containing this [FunctionBody], return a
-   * boolean indicating whether [variable] is potentially mutated within a
-   * local function other than the function in which it is declared.
-   *
-   * If [variable] is not a local variable or parameter declared within the top
-   * level function or method containing this [FunctionBody], return `false`.
-   *
-   * Throws an exception if resolution has not yet been performed.
-   */
+  /// If [variable] is a local variable or parameter declared anywhere within
+  /// the top level function or method containing this [FunctionBody], return a
+  /// boolean indicating whether [variable] is potentially mutated within a
+  /// local function other than the function in which it is declared.
+  ///
+  /// If [variable] is not a local variable or parameter declared within the top
+  /// level function or method containing this [FunctionBody], return `false`.
+  ///
+  /// Throws an exception if resolution has not yet been performed.
   bool isPotentiallyMutatedInClosure(VariableElement variable);
 
-  /**
-   * If [variable] is a local variable or parameter declared anywhere within
-   * the top level function or method containing this [FunctionBody], return a
-   * boolean indicating whether [variable] is potentially mutated within the
-   * scope of its declaration.
-   *
-   * If [variable] is not a local variable or parameter declared within the top
-   * level function or method containing this [FunctionBody], return `false`.
-   *
-   * Throws an exception if resolution has not yet been performed.
-   */
+  /// If [variable] is a local variable or parameter declared anywhere within
+  /// the top level function or method containing this [FunctionBody], return a
+  /// boolean indicating whether [variable] is potentially mutated within the
+  /// scope of its declaration.
+  ///
+  /// If [variable] is not a local variable or parameter declared within the top
+  /// level function or method containing this [FunctionBody], return `false`.
+  ///
+  /// Throws an exception if resolution has not yet been performed.
   bool isPotentiallyMutatedInScope(VariableElement variable);
 }
 
-/**
- * A top-level declaration.
- *
- *    functionDeclaration ::=
- *        'external' functionSignature
- *      | functionSignature [FunctionBody]
- *
- *    functionSignature ::=
- *        [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionDeclaration extends NamedCompilationUnitMember {
+/// A top-level function declaration.
+///
+///    functionDeclaration ::=
+///        'external' functionSignature
+///      | functionSignature [FunctionBody]
+///
+///    functionSignature ::=
+///        [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionDeclaration implements NamedCompilationUnitMember {
   @override
   ExecutableElement get declaredElement;
 
@@ -3467,643 +2699,487 @@
   @override
   ExecutableElement get element;
 
-  /**
-   * Return the token representing the 'external' keyword, or `null` if this is
-   * not an external function.
-   */
+  /// Return the token representing the 'external' keyword, or `null` if this is
+  /// not an external function.
   Token get externalKeyword;
 
-  /**
-   * Set the token representing the 'external' keyword to the given [token].
-   */
+  /// Set the token representing the 'external' keyword to the given [token].
   void set externalKeyword(Token token);
 
-  /**
-   * Return the function expression being wrapped.
-   */
+  /// Return the function expression being wrapped.
   FunctionExpression get functionExpression;
 
-  /**
-   * Set the function expression being wrapped to the given
-   * [functionExpression].
-   */
+  /// Set the function expression being wrapped to the given
+  /// [functionExpression].
   void set functionExpression(FunctionExpression functionExpression);
 
-  /**
-   * Return `true` if this function declares a getter.
-   */
+  /// Return `true` if this function declares a getter.
   bool get isGetter;
 
-  /**
-   * Return `true` if this function declares a setter.
-   */
+  /// Return `true` if this function declares a setter.
   bool get isSetter;
 
-  /**
-   * Return the token representing the 'get' or 'set' keyword, or `null` if this
-   * is a function declaration rather than a property declaration.
-   */
+  /// Return the token representing the 'get' or 'set' keyword, or `null` if
+  /// this is a function declaration rather than a property declaration.
   Token get propertyKeyword;
 
-  /**
-   * Set the token representing the 'get' or 'set' keyword to the given [token].
-   */
+  /// Set the token representing the 'get' or 'set' keyword to the given
+  /// [token].
   void set propertyKeyword(Token token);
 
-  /**
-   * Return the return type of the function, or `null` if no return type was
-   * declared.
-   */
+  /// Return the return type of the function, or `null` if no return type was
+  /// declared.
   TypeAnnotation get returnType;
 
-  /**
-   * Set the return type of the function to the given [type].
-   */
+  /// Set the return type of the function to the given [type].
   void set returnType(TypeAnnotation type);
 }
 
-/**
- * A [FunctionDeclaration] used as a statement.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionDeclarationStatement extends Statement {
-  /**
-   * Return the function declaration being wrapped.
-   */
+/// A [FunctionDeclaration] used as a statement.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionDeclarationStatement implements Statement {
+  /// Return the function declaration being wrapped.
   FunctionDeclaration get functionDeclaration;
 
-  /**
-   * Set the function declaration being wrapped to the given
-   * [functionDeclaration].
-   */
+  /// Set the function declaration being wrapped to the given
+  /// [functionDeclaration].
   void set functionDeclaration(FunctionDeclaration functionDeclaration);
 }
 
-/**
- * A function expression.
- *
- *    functionExpression ::=
- *        [TypeParameterList]? [FormalParameterList] [FunctionBody]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionExpression extends Expression {
-  /**
-   * Return the body of the function, or `null` if this is an external function.
-   */
+/// A function expression.
+///
+///    functionExpression ::=
+///        [TypeParameterList]? [FormalParameterList] [FunctionBody]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionExpression implements Expression {
+  /// Return the body of the function, or `null` if this is an external
+  /// function.
   FunctionBody get body;
 
-  /**
-   * Set the body of the function to the given [functionBody].
-   */
+  /// Set the body of the function to the given [functionBody].
   void set body(FunctionBody functionBody);
 
-  /**
-   * Return the element associated with the function, or `null` if the AST
-   * structure has not been resolved.
-   */
+  /// Return the element associated with the function, or `null` if the AST
+  /// structure has not been resolved.
   ExecutableElement get declaredElement;
 
-  /**
-   * Return the element associated with the function, or `null` if the AST
-   * structure has not been resolved.
-   */
+  /// Return the element associated with the function, or `null` if the AST
+  /// structure has not been resolved.
   @deprecated
   ExecutableElement get element;
 
-  /**
-   * Set the element associated with the function to the given [element].
-   */
+  /// Set the element associated with the function to the given [element].
   void set element(ExecutableElement element);
 
-  /**
-   * Return the parameters associated with the function.
-   */
+  /// Return the parameters associated with the function.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters associated with the function to the given list of
-   * [parameters].
-   */
+  /// Set the parameters associated with the function to the given list of
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * Return the type parameters associated with this method, or `null` if this
-   * method is not a generic method.
-   */
+  /// Return the type parameters associated with this method, or `null` if this
+  /// method is not a generic method.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
+  /// Set the type parameters associated with this method to the given
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * The invocation of a function resulting from evaluating an expression.
- * Invocations of methods and other forms of functions are represented by
- * [MethodInvocation] nodes. Invocations of getters and setters are represented
- * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
- *
- *    functionExpressionInvocation ::=
- *        [Expression] [TypeArgumentList]? [ArgumentList]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionExpressionInvocation extends InvocationExpression {
-  /**
-   * Set the list of arguments to the method to the given [argumentList].
-   */
+/// The invocation of a function resulting from evaluating an expression.
+/// Invocations of methods and other forms of functions are represented by
+/// [MethodInvocation] nodes. Invocations of getters and setters are represented
+/// by either [PrefixedIdentifier] or [PropertyAccess] nodes.
+///
+///    functionExpressionInvocation ::=
+///        [Expression] [TypeArgumentList]? [ArgumentList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionExpressionInvocation implements InvocationExpression {
+  /// Set the list of arguments to the method to the given [argumentList].
   void set argumentList(ArgumentList argumentList);
 
-  /**
-   * Return the best element available for the function being invoked. If
-   * resolution was able to find a better element based on type propagation,
-   * that element will be returned. Otherwise, the element found using the
-   * result of static analysis will be returned. If resolution has not been
-   * performed, then `null` will be returned.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Return the best element available for the function being invoked. If
+  /// resolution was able to find a better element based on type propagation,
+  /// that element will be returned. Otherwise, the element found using the
+  /// result of static analysis will be returned. If resolution has not been
+  /// performed, then `null` will be returned.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   ExecutableElement get bestElement;
 
-  /**
-   * Return the expression producing the function being invoked.
-   */
+  /// Return the expression producing the function being invoked.
   @override
   Expression get function;
 
-  /**
-   * Set the expression producing the function being invoked to the given
-   * [expression].
-   */
+  /// Set the expression producing the function being invoked to the given
+  /// [expression].
   void set function(Expression expression);
 
-  /**
-   * Return the element associated with the function being invoked based on
-   * propagated type information, or `null` if the AST structure has not been
-   * resolved or the function could not be resolved.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Return the element associated with the function being invoked based on
+  /// propagated type information, or `null` if the AST structure has not been
+  /// resolved or the function could not be resolved.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   ExecutableElement get propagatedElement;
 
-  /**
-   * Set the element associated with the function being invoked based on
-   * propagated type information to the given [element].
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Set the element associated with the function being invoked based on
+  /// propagated type information to the given [element].
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   void set propagatedElement(ExecutableElement element);
 
-  /**
-   * Return the element associated with the function being invoked based on
-   * static type information, or `null` if the AST structure has not been
-   * resolved or the function could not be resolved.
-   */
+  /// Return the element associated with the function being invoked based on
+  /// static type information, or `null` if the AST structure has not been
+  /// resolved or the function could not be resolved.
   ExecutableElement get staticElement;
 
-  /**
-   * Set the element associated with the function being invoked based on static
-   * type information to the given [element].
-   */
+  /// Set the element associated with the function being invoked based on static
+  /// type information to the given [element].
   void set staticElement(ExecutableElement element);
 
-  /**
-   * Set the type arguments to be applied to the method being invoked to the
-   * given [typeArguments].
-   */
+  /// Set the type arguments to be applied to the method being invoked to the
+  /// given [typeArguments].
   void set typeArguments(TypeArgumentList typeArguments);
 }
 
-/**
- * A function type alias.
- *
- *    functionTypeAlias ::=
- *        functionPrefix [TypeParameterList]? [FormalParameterList] ';'
- *
- *    functionPrefix ::=
- *        [TypeAnnotation]? [SimpleIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionTypeAlias extends TypeAlias {
-  /**
-   * Return the parameters associated with the function type.
-   */
+/// A function type alias.
+///
+///    functionTypeAlias ::=
+///        functionPrefix [TypeParameterList]? [FormalParameterList] ';'
+///
+///    functionPrefix ::=
+///        [TypeAnnotation]? [SimpleIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionTypeAlias implements TypeAlias {
+  /// Return the parameters associated with the function type.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters associated with the function type to the given list of
-   * [parameters].
-   */
+  /// Set the parameters associated with the function type to the given list of
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * Return the return type of the function type being defined, or `null` if no
-   * return type was given.
-   */
+  /// Return the return type of the function type being defined, or `null` if no
+  /// return type was given.
   TypeAnnotation get returnType;
 
-  /**
-   * Set the return type of the function type being defined to the given [type].
-   */
+  /// Set the return type of the function type being defined to the given
+  /// [type].
   void set returnType(TypeAnnotation type);
 
-  /**
-   * Return the type parameters for the function type, or `null` if the function
-   * type does not have any type parameters.
-   */
+  /// Return the type parameters for the function type, or `null` if the
+  /// function type does not have any type parameters.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters for the function type to the given list of
-   * [typeParameters].
-   */
+  /// Set the type parameters for the function type to the given list of
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * A function-typed formal parameter.
- *
- *    functionSignature ::=
- *        [TypeAnnotation]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class FunctionTypedFormalParameter extends NormalFormalParameter {
-  /**
-   * Return the parameters of the function-typed parameter.
-   */
+/// A function-typed formal parameter.
+///
+///    functionSignature ::=
+///        [TypeAnnotation]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class FunctionTypedFormalParameter implements NormalFormalParameter {
+  /// Return the parameters of the function-typed parameter.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters of the function-typed parameter to the given
-   * [parameters].
-   */
+  /// Set the parameters of the function-typed parameter to the given
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * Return the return type of the function, or `null` if the function does not
-   * have a return type.
-   */
+  /// Return the return type of the function, or `null` if the function does not
+  /// have a return type.
   TypeAnnotation get returnType;
 
-  /**
-   * Set the return type of the function to the given [type].
-   */
+  /// Set the return type of the function to the given [type].
   void set returnType(TypeAnnotation type);
 
-  /**
-   * Return the type parameters associated with this function, or `null` if
-   * this function is not a generic function.
-   */
+  /// Return the type parameters associated with this function, or `null` if
+  /// this function is not a generic function.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
+  /// Set the type parameters associated with this method to the given
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * An anonymous function type.
- *
- *    functionType ::=
- *        [TypeAnnotation]? 'Function' [TypeParameterList]?
- *        [FormalParameterList] '?'?
- *
- * where the FormalParameterList is being used to represent the following
- * grammar, despite the fact that FormalParameterList can represent a much
- * larger grammar than the one below. This is done in order to simplify the
- * implementation.
- *
- *    parameterTypeList ::=
- *        () |
- *        ( normalParameterTypes ,? ) |
- *        ( normalParameterTypes , optionalParameterTypes ) |
- *        ( optionalParameterTypes )
- *    namedParameterTypes ::=
- *        { namedParameterType (, namedParameterType)* ,? }
- *    namedParameterType ::=
- *        [TypeAnnotation]? [SimpleIdentifier]
- *    normalParameterTypes ::=
- *        normalParameterType (, normalParameterType)*
- *    normalParameterType ::=
- *        [TypeAnnotation] [SimpleIdentifier]?
- *    optionalParameterTypes ::=
- *        optionalPositionalParameterTypes | namedParameterTypes
- *    optionalPositionalParameterTypes ::=
- *        [ normalParameterTypes ,? ]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class GenericFunctionType extends TypeAnnotation {
-  /**
-   * Return the keyword 'Function'.
-   */
+/// An anonymous function type.
+///
+///    functionType ::=
+///        [TypeAnnotation]? 'Function' [TypeParameterList]?
+///        [FormalParameterList] '?'?
+///
+/// where the FormalParameterList is being used to represent the following
+/// grammar, despite the fact that FormalParameterList can represent a much
+/// larger grammar than the one below. This is done in order to simplify the
+/// implementation.
+///
+///    parameterTypeList ::=
+///        () |
+///        ( normalParameterTypes ,? ) |
+///        ( normalParameterTypes , optionalParameterTypes ) |
+///        ( optionalParameterTypes )
+///    namedParameterTypes ::=
+///        { namedParameterType (, namedParameterType)* ,? }
+///    namedParameterType ::=
+///        [TypeAnnotation]? [SimpleIdentifier]
+///    normalParameterTypes ::=
+///        normalParameterType (, normalParameterType)*
+///    normalParameterType ::=
+///        [TypeAnnotation] [SimpleIdentifier]?
+///    optionalParameterTypes ::=
+///        optionalPositionalParameterTypes | namedParameterTypes
+///    optionalPositionalParameterTypes ::=
+///        [ normalParameterTypes ,? ]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class GenericFunctionType implements TypeAnnotation {
+  /// Return the keyword 'Function'.
   Token get functionKeyword;
 
-  /**
-   * Set the keyword 'Function' to the given [token].
-   */
+  /// Set the keyword 'Function' to the given [token].
   void set functionKeyword(Token token);
 
-  /**
-   * Return the parameters associated with the function type.
-   */
+  /// Return the parameters associated with the function type.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters associated with the function type to the given list of
-   * [parameters].
-   */
+  /// Set the parameters associated with the function type to the given list of
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * The question mark indicating that the type is nullable, or `null` if there
-   * is no question mark.
-   */
-  Token get question;
-
-  /**
-   * Set the question mark indicating that the type is nullable to the given
-   * [token].
-   */
+  /// Set the question mark indicating that the type is nullable to the given
+  /// [token].
   void set question(Token token);
 
-  /**
-   * Return the return type of the function type being defined, or `null` if
-   * no return type was given.
-   */
+  /// Return the return type of the function type being defined, or `null` if
+  /// no return type was given.
   TypeAnnotation get returnType;
 
-  /**
-   * Set the return type of the function type being defined to the given[type].
-   */
+  /// Set the return type of the function type being defined to the given[type].
   void set returnType(TypeAnnotation type);
 
-  /**
-   * Return the type parameters for the function type, or `null` if the function
-   * type does not have any type parameters.
-   */
+  /// Return the type parameters for the function type, or `null` if the
+  /// function type does not have any type parameters.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters for the function type to the given list of
-   * [typeParameters].
-   */
+  /// Set the type parameters for the function type to the given list of
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * A generic type alias.
- *
- *    functionTypeAlias ::=
- *        metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? = [FunctionType] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class GenericTypeAlias extends TypeAlias {
-  /**
-     * Return the equal sign separating the name being defined from the function
-     * type.
-     */
+/// A generic type alias.
+///
+///    functionTypeAlias ::=
+///        metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? = [FunctionType] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class GenericTypeAlias implements TypeAlias {
+  /// Return the equal sign separating the name being defined from the function
+  /// type.
   Token get equals;
 
-  /**
-     * Set the equal sign separating the name being defined from the function type
-     * to the given [token].
-     */
+  /// Set the equal sign separating the name being defined from the function
+  /// type to the given [token].
   void set equals(Token token);
 
-  /**
-     * Return the type of function being defined by the alias.
-     */
+  /// Return the type of function being defined by the alias.
   GenericFunctionType get functionType;
 
-  /**
-     * Set the type of function being defined by the alias to the given
-     * [functionType].
-     */
+  /// Set the type of function being defined by the alias to the given
+  /// [functionType].
   void set functionType(GenericFunctionType functionType);
 
-  /**
-     * Return the type parameters for the function type, or `null` if the function
-     * type does not have any type parameters.
-     */
+  /// Return the type parameters for the function type, or `null` if the
+  /// function type does not have any type parameters.
   TypeParameterList get typeParameters;
 
-  /**
-     * Set the type parameters for the function type to the given list of
-     * [typeParameters].
-     */
+  /// Set the type parameters for the function type to the given list of
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * A combinator that restricts the names being imported to those that are not in
- * a given list.
- *
- *    hideCombinator ::=
- *        'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class HideCombinator extends Combinator {
-  /**
-   * Return the list of names from the library that are hidden by this
-   * combinator.
-   */
+/// A combinator that restricts the names being imported to those that are not
+/// in a given list.
+///
+///    hideCombinator ::=
+///        'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class HideCombinator implements Combinator {
+  /// Return the list of names from the library that are hidden by this
+  /// combinator.
   NodeList<SimpleIdentifier> get hiddenNames;
 }
 
-/**
- * A node that represents an identifier.
- *
- *    identifier ::=
- *        [SimpleIdentifier]
- *      | [PrefixedIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Identifier extends Expression {
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+/// A node that represents an identifier.
+///
+///    identifier ::=
+///        [SimpleIdentifier]
+///      | [PrefixedIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Identifier implements Expression {
+  /// Return the best element available for this operator. If resolution was
+  /// able to find a better element based on type propagation, that element will
+  /// be returned. Otherwise, the element found using the result of static
+  /// analysis will be returned. If resolution has not been performed, then
+  /// `null` will be returned.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   Element get bestElement;
 
-  /**
-   * Return the lexical representation of the identifier.
-   */
+  /// Return the lexical representation of the identifier.
   String get name;
 
-  /**
-   * Return the element associated with this identifier based on propagated type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this identifier could not be resolved. One example of the latter case is an
-   * identifier that is not defined within the scope in which it appears.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Return the element associated with this identifier based on propagated
+  /// type information, or `null` if the AST structure has not been resolved or
+  /// if this identifier could not be resolved. One example of the latter case
+  /// is an identifier that is not defined within the scope in which it appears.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   Element get propagatedElement;
 
-  /**
-   * Return the element associated with this identifier based on static type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this identifier could not be resolved. One example of the latter case is an
-   * identifier that is not defined within the scope in which it appears
-   */
+  /// Return the element associated with this identifier based on static type
+  /// information, or `null` if the AST structure has not been resolved or if
+  /// this identifier could not be resolved. One example of the latter case is
+  /// an identifier that is not defined within the scope in which it appears.
   Element get staticElement;
 
-  /**
-   * Return `true` if the given [name] is visible only within the library in
-   * which it is declared.
-   */
+  /// Return `true` if the given [name] is visible only within the library in
+  /// which it is declared.
   static bool isPrivateName(String name) =>
       StringUtilities.startsWithChar(name, 0x5F); // '_'
 }
 
-/**
- * An if statement.
- *
- *    ifStatement ::=
- *        'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class IfStatement extends Statement {
-  /**
-   * Return the condition used to determine which of the statements is executed
-   * next.
-   */
+/// The basic structure of an if element.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class IfElement implements CollectionElement {
+  /// Return the condition used to determine which of the statements is executed
+  /// next.
   Expression get condition;
 
-  /**
-   * Set the condition used to determine which of the statements is executed
-   * next to the given [expression].
-   */
-  void set condition(Expression expression);
+  /// Return the statement that is executed if the condition evaluates to
+  /// `false`, or `null` if there is no else statement.
+  CollectionElement get elseElement;
 
-  /**
-   * Return the token representing the 'else' keyword, or `null` if there is no
-   * else statement.
-   */
+  /// Return the token representing the 'else' keyword, or `null` if there is no
+  /// else statement.
   Token get elseKeyword;
 
-  /**
-   * Set the token representing the 'else' keyword to the given [token].
-   */
-  void set elseKeyword(Token token);
-
-  /**
-   * Return the statement that is executed if the condition evaluates to
-   * `false`, or `null` if there is no else statement.
-   */
-  Statement get elseStatement;
-
-  /**
-   * Set the statement that is executed if the condition evaluates to `false`
-   * to the given [statement].
-   */
-  void set elseStatement(Statement statement);
-
-  /**
-   * Return the token representing the 'if' keyword.
-   */
+  /// Return the token representing the 'if' keyword.
   Token get ifKeyword;
 
-  /**
-   * Set the token representing the 'if' keyword to the given [token].
-   */
-  void set ifKeyword(Token token);
-
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
-  void set leftParenthesis(Token token);
-
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Return the statement that is executed if the condition evaluates to
+  /// `true`.
+  CollectionElement get thenElement;
+}
+
+/// An if statement.
+///
+///    ifStatement ::=
+///        'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class IfStatement implements Statement {
+  /// Return the condition used to determine which of the statements is executed
+  /// next.
+  Expression get condition;
+
+  /// Set the condition used to determine which of the statements is executed
+  /// next to the given [expression].
+  void set condition(Expression expression);
+
+  /// Return the token representing the 'else' keyword, or `null` if there is no
+  /// else statement.
+  Token get elseKeyword;
+
+  /// Set the token representing the 'else' keyword to the given [token].
+  void set elseKeyword(Token token);
+
+  /// Return the statement that is executed if the condition evaluates to
+  /// `false`, or `null` if there is no else statement.
+  Statement get elseStatement;
+
+  /// Set the statement that is executed if the condition evaluates to `false`
+  /// to the given [statement].
+  void set elseStatement(Statement statement);
+
+  /// Return the token representing the 'if' keyword.
+  Token get ifKeyword;
+
+  /// Set the token representing the 'if' keyword to the given [token].
+  void set ifKeyword(Token token);
+
+  /// Return the left parenthesis.
+  Token get leftParenthesis;
+
+  /// Set the left parenthesis to the given [token].
+  void set leftParenthesis(Token token);
+
+  /// Return the right parenthesis.
+  Token get rightParenthesis;
+
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 
-  /**
-   * Return the statement that is executed if the condition evaluates to `true`.
-   */
+  /// Return the statement that is executed if the condition evaluates to
+  /// `true`.
   Statement get thenStatement;
 
-  /**
-   * Set the statement that is executed if the condition evaluates to `true` to
-   * the given [statement].
-   */
+  /// Set the statement that is executed if the condition evaluates to `true` to
+  /// the given [statement].
   void set thenStatement(Statement statement);
 }
 
-/**
- * The "implements" clause in an class declaration.
- *
- *    implementsClause ::=
- *        'implements' [TypeName] (',' [TypeName])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ImplementsClause extends AstNode {
-  /**
-   * Return the token representing the 'implements' keyword.
-   */
+/// The "implements" clause in an class declaration.
+///
+///    implementsClause ::=
+///        'implements' [TypeName] (',' [TypeName])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ImplementsClause implements AstNode {
+  /// Return the token representing the 'implements' keyword.
   Token get implementsKeyword;
 
-  /**
-   * Set the token representing the 'implements' keyword to the given [token].
-   */
+  /// Set the token representing the 'implements' keyword to the given [token].
   void set implementsKeyword(Token token);
 
-  /**
-   * Return the list of the interfaces that are being implemented.
-   */
+  /// Return the list of the interfaces that are being implemented.
   NodeList<TypeName> get interfaces;
 }
 
-/**
- * An import directive.
- *
- *    importDirective ::=
- *        [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
- *      | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ImportDirective extends NamespaceDirective {
+/// An import directive.
+///
+///    importDirective ::=
+///        [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
+///      | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ImportDirective implements NamespaceDirective {
   static Comparator<ImportDirective> COMPARATOR =
       (ImportDirective import1, ImportDirective import2) {
     //
@@ -4209,738 +3285,592 @@
     }
     return 0;
   };
-  /**
-   * Return the token representing the 'as' keyword, or `null` if the imported
-   * names are not prefixed.
-   */
+
+  /// Return the token representing the 'as' keyword, or `null` if the imported
+  /// names are not prefixed.
   Token get asKeyword;
 
-  /**
-   * Set the token representing the 'as' keyword to the given [token].
-   */
+  /// Set the token representing the 'as' keyword to the given [token].
   void set asKeyword(Token token);
 
-  /**
-   * Return the token representing the 'deferred' keyword, or `null` if the
-   * imported URI is not deferred.
-   */
+  /// Return the token representing the 'deferred' keyword, or `null` if the
+  /// imported URI is not deferred.
   Token get deferredKeyword;
 
-  /**
-   * Set the token representing the 'deferred' keyword to the given [token].
-   */
+  /// Set the token representing the 'deferred' keyword to the given [token].
   void set deferredKeyword(Token token);
 
-  /**
-   * Return the prefix to be used with the imported names, or `null` if the
-   * imported names are not prefixed.
-   */
+  /// Return the prefix to be used with the imported names, or `null` if the
+  /// imported names are not prefixed.
   SimpleIdentifier get prefix;
 
-  /**
-   * Set the prefix to be used with the imported names to the given [identifier].
-   */
+  /// Set the prefix to be used with the imported names to the given
+  /// [identifier].
   void set prefix(SimpleIdentifier identifier);
 }
 
-/**
- * An index expression.
- *
- *    indexExpression ::=
- *        [Expression] '[' [Expression] ']'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class IndexExpression extends Expression
-    implements MethodReferenceExpression {
-  /**
-   * Return the auxiliary elements associated with this identifier, or `null` if
-   * this identifier is not in both a getter and setter context. The auxiliary
-   * elements hold the static and propagated elements associated with the getter
-   * context.
-   */
+/// An index expression.
+///
+///    indexExpression ::=
+///        [Expression] '[' [Expression] ']'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class IndexExpression
+    implements Expression, MethodReferenceExpression {
+  /// Return the auxiliary elements associated with this identifier, or `null`
+  /// if this identifier is not in both a getter and setter context. The
+  /// auxiliary elements hold the static and propagated elements associated with
+  /// the getter context.
   // TODO(brianwilkerson) Replace this API.
   AuxiliaryElements get auxiliaryElements;
 
-  /**
-   * Set the auxiliary elements associated with this identifier to the given
-   * [elements].
-   */
+  /// Set the auxiliary elements associated with this identifier to the given
+  /// [elements].
   // TODO(brianwilkerson) Replace this API.
   void set auxiliaryElements(AuxiliaryElements elements);
 
-  /**
-   * Return the expression used to compute the index.
-   */
+  /// Return the expression used to compute the index.
   Expression get index;
 
-  /**
-   * Set the expression used to compute the index to the given [expression].
-   */
+  /// Set the expression used to compute the index to the given [expression].
   void set index(Expression expression);
 
-  /**
-   * Return `true` if this expression is cascaded. If it is, then the target of
-   * this expression is not stored locally but is stored in the nearest ancestor
-   * that is a [CascadeExpression].
-   */
+  /// Return `true` if this expression is cascaded. If it is, then the target of
+  /// this expression is not stored locally but is stored in the nearest
+  /// ancestor that is a [CascadeExpression].
   bool get isCascaded;
 
-  /**
-   * Return the left square bracket.
-   */
+  /// Return the left square bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left square bracket to the given [token].
-   */
+  /// Set the left square bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the period ("..") before a cascaded index expression, or `null` if
-   * this index expression is not part of a cascade expression.
-   */
+  /// Return the period ("..") before a cascaded index expression, or `null` if
+  /// this index expression is not part of a cascade expression.
   Token get period;
 
-  /**
-   * Set the period ("..") before a cascaded index expression to the given
-   * [token].
-   */
+  /// Set the period ("..") before a cascaded index expression to the given
+  /// [token].
   void set period(Token token);
 
-  /**
-   * Return the expression used to compute the object being indexed. If this
-   * index expression is not part of a cascade expression, then this is the same
-   * as [target]. If this index expression is part of a cascade expression, then
-   * the target expression stored with the cascade expression is returned.
-   */
+  /// Return the expression used to compute the object being indexed. If this
+  /// index expression is not part of a cascade expression, then this is the
+  /// same as [target]. If this index expression is part of a cascade
+  /// expression, then the target expression stored with the cascade expression
+  /// is returned.
   Expression get realTarget;
 
-  /**
-   * Return the right square bracket.
-   */
+  /// Return the right square bracket.
   Token get rightBracket;
 
-  /**
-   * Return the expression used to compute the object being indexed, or `null`
-   * if this index expression is part of a cascade expression.
-   *
-   * Use [realTarget] to get the target independent of whether this is part of a
-   * cascade expression.
-   */
+  /// Return the expression used to compute the object being indexed, or `null`
+  /// if this index expression is part of a cascade expression.
+  ///
+  /// Use [realTarget] to get the target independent of whether this is part of
+  /// a cascade expression.
   Expression get target;
 
-  /**
-   * Set the expression used to compute the object being indexed to the given
-   * [expression].
-   */
+  /// Set the expression used to compute the object being indexed to the given
+  /// [expression].
   void set target(Expression expression);
 
-  /**
-   * Return `true` if this expression is computing a right-hand value (that is,
-   * if this expression is in a context where the operator '[]' will be
-   * invoked).
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
+  /// Return `true` if this expression is computing a right-hand value (that is,
+  /// if this expression is in a context where the operator '[]' will be
+  /// invoked).
+  ///
+  /// Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+  /// are they mutually exclusive. In other words, it is possible for both
+  /// methods to return `true` when invoked on the same node.
   // TODO(brianwilkerson) Convert this to a getter.
   bool inGetterContext();
 
-  /**
-   * Return `true` if this expression is computing a left-hand value (that is,
-   * if this expression is in a context where the operator '[]=' will be
-   * invoked).
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
+  /// Return `true` if this expression is computing a left-hand value (that is,
+  /// if this expression is in a context where the operator '[]=' will be
+  /// invoked).
+  ///
+  /// Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+  /// are they mutually exclusive. In other words, it is possible for both
+  /// methods to return `true` when invoked on the same node.
   // TODO(brianwilkerson) Convert this to a getter.
   bool inSetterContext();
 }
 
-/**
- * An instance creation expression.
- *
- *    newExpression ::=
- *        ('new' | 'const')? [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class InstanceCreationExpression extends Expression
-    implements ConstructorReferenceNode {
-  /**
-   * Return the list of arguments to the constructor.
-   */
+/// An instance creation expression.
+///
+///    newExpression ::=
+///        ('new' | 'const')? [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class InstanceCreationExpression
+    implements Expression, ConstructorReferenceNode {
+  /// Return the list of arguments to the constructor.
   ArgumentList get argumentList;
 
-  /**
-   * Set the list of arguments to the constructor to the given [argumentList].
-   */
+  /// Set the list of arguments to the constructor to the given [argumentList].
   void set argumentList(ArgumentList argumentList);
 
-  /**
-   * Return the name of the constructor to be invoked.
-   */
+  /// Return the name of the constructor to be invoked.
   ConstructorName get constructorName;
 
-  /**
-   * Set the name of the constructor to be invoked to the given [name].
-   */
+  /// Set the name of the constructor to be invoked to the given [name].
   void set constructorName(ConstructorName name);
 
-  /**
-   * Return `true` if this creation expression is used to invoke a constant
-   * constructor, either because the keyword `const` was explicitly provided or
-   * because no keyword was provided and this expression is in a constant
-   * context.
-   */
+  /// Return `true` if this creation expression is used to invoke a constant
+  /// constructor, either because the keyword `const` was explicitly provided or
+  /// because no keyword was provided and this expression is in a constant
+  /// context.
   bool get isConst;
 
-  /**
-   * Return the 'new' or 'const' keyword used to indicate how an object should
-   * be created, or `null` if the keyword was not explicitly provided.
-   */
+  /// Return the 'new' or 'const' keyword used to indicate how an object should
+  /// be created, or `null` if the keyword was not explicitly provided.
   Token get keyword;
 
-  /**
-   * Set the 'new' or 'const' keyword used to indicate how an object should be
-   * created to the given [token].
-   */
+  /// Set the 'new' or 'const' keyword used to indicate how an object should be
+  /// created to the given [token].
   void set keyword(Token token);
 }
 
-/**
- * An integer literal expression.
- *
- *    integerLiteral ::=
- *        decimalIntegerLiteral
- *      | hexadecimalIntegerLiteral
- *
- *    decimalIntegerLiteral ::=
- *        decimalDigit+
- *
- *    hexadecimalIntegerLiteral ::=
- *        '0x' hexadecimalDigit+
- *      | '0X' hexadecimalDigit+
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class IntegerLiteral extends Literal {
-  /**
-   * Return the token representing the literal.
-   */
+/// An integer literal expression.
+///
+///    integerLiteral ::=
+///        decimalIntegerLiteral
+///      | hexadecimalIntegerLiteral
+///
+///    decimalIntegerLiteral ::=
+///        decimalDigit+
+///
+///    hexadecimalIntegerLiteral ::=
+///        '0x' hexadecimalDigit+
+///      | '0X' hexadecimalDigit+
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class IntegerLiteral implements Literal {
+  /// Return the token representing the literal.
   Token get literal;
 
-  /**
-   * Set the token representing the literal to the given [token].
-   */
+  /// Set the token representing the literal to the given [token].
   void set literal(Token token);
 
-  /**
-   * Return the value of the literal.
-   */
+  /// Return the value of the literal.
   int get value;
 
-  /**
-   * Set the value of the literal to the given [value].
-   */
+  /// Set the value of the literal to the given [value].
   void set value(int value);
 }
 
-/**
- * A node within a [StringInterpolation].
- *
- *    interpolationElement ::=
- *        [InterpolationExpression]
- *      | [InterpolationString]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class InterpolationElement extends AstNode {}
+/// A node within a [StringInterpolation].
+///
+///    interpolationElement ::=
+///        [InterpolationExpression]
+///      | [InterpolationString]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class InterpolationElement implements AstNode {}
 
-/**
- * An expression embedded in a string interpolation.
- *
- *    interpolationExpression ::=
- *        '$' [SimpleIdentifier]
- *      | '$' '{' [Expression] '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class InterpolationExpression extends InterpolationElement {
-  /**
-   * Return the expression to be evaluated for the value to be converted into a
-   * string.
-   */
+/// An expression embedded in a string interpolation.
+///
+///    interpolationExpression ::=
+///        '$' [SimpleIdentifier]
+///      | '$' '{' [Expression] '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class InterpolationExpression implements InterpolationElement {
+  /// Return the expression to be evaluated for the value to be converted into a
+  /// string.
   Expression get expression;
 
-  /**
-   * Set the expression to be evaluated for the value to be converted into a
-   * string to the given [expression].
-   */
+  /// Set the expression to be evaluated for the value to be converted into a
+  /// string to the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the token used to introduce the interpolation expression; either '$'
-   * if the expression is a simple identifier or '${' if the expression is a
-   * full expression.
-   */
+  /// Return the token used to introduce the interpolation expression; either
+  /// '$' if the expression is a simple identifier or '${' if the expression is
+  /// a full expression.
   Token get leftBracket;
 
-  /**
-   * Set the token used to introduce the interpolation expression; either '$'
-   * if the expression is a simple identifier or '${' if the expression is a
-   * full expression to the given [token].
-   */
+  /// Set the token used to introduce the interpolation expression; either '$'
+  /// if the expression is a simple identifier or '${' if the expression is a
+  /// full expression to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right curly bracket, or `null` if the expression is an
-   * identifier without brackets.
-   */
+  /// Return the right curly bracket, or `null` if the expression is an
+  /// identifier without brackets.
   Token get rightBracket;
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 }
 
-/**
- * A non-empty substring of an interpolated string.
- *
- *    interpolationString ::=
- *        characters
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class InterpolationString extends InterpolationElement {
-  /**
-   * Return the characters that will be added to the string.
-   */
+/// A non-empty substring of an interpolated string.
+///
+///    interpolationString ::=
+///        characters
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class InterpolationString implements InterpolationElement {
+  /// Return the characters that will be added to the string.
   Token get contents;
 
-  /**
-   * Set the characters that will be added to the string to the given [token].
-   */
+  /// Set the characters that will be added to the string to the given [token].
   void set contents(Token token);
 
-  /**
-   * Return the offset of the after-last contents character.
-   */
+  /// Return the offset of the after-last contents character.
   int get contentsEnd;
 
-  /**
-   * Return the offset of the first contents character.
-   */
+  /// Return the offset of the first contents character.
   int get contentsOffset;
 
-  /**
-   * Return the value of the literal.
-   */
+  /// Return the value of the literal.
   String get value;
 
-  /**
-   * Set the value of the literal to the given [value].
-   */
+  /// Set the value of the literal to the given [value].
   void set value(String value);
 }
 
-/**
- * The invocation of a function or method; either a
- * [FunctionExpressionInvocation] or a [MethodInvocation].
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class InvocationExpression extends Expression {
-  /**
-   * Return the list of arguments to the method.
-   */
+/// The invocation of a function or method; either a
+/// [FunctionExpressionInvocation] or a [MethodInvocation].
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class InvocationExpression implements Expression {
+  /// Return the list of arguments to the method.
   ArgumentList get argumentList;
 
-  /**
-   * The expression that identifies the function or method being invoked.
-   * For example:
-   *
-   *     (o.m)<TArgs>(args); // target will be `o.m`
-   *     o.m<TArgs>(args);   // target will be `m`
-   *
-   * In either case, the [function.staticType] will be the
-   * [staticInvokeType] before applying type arguments `TArgs`.
-   */
+  /// The expression that identifies the function or method being invoked.
+  /// For example:
+  ///
+  ///     (o.m)<TArgs>(args); // target will be `o.m`
+  ///     o.m<TArgs>(args);   // target will be `m`
+  ///
+  /// In either case, the [function.staticType] will be the
+  /// [staticInvokeType] before applying type arguments `TArgs`.
   Expression get function;
 
-  /**
-   * Return the function type of the invocation based on the propagated type
-   * information, or `null` if the AST structure has not been resolved, or if
-   * the invoke could not be resolved.
-   *
-   * This will usually be a [FunctionType], but it can also be an
-   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
-   * interface type that implements `Function`.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticInvokeType] instead.
-   */
+  /// Return the function type of the invocation based on the propagated type
+  /// information, or `null` if the AST structure has not been resolved, or if
+  /// the invoke could not be resolved.
+  ///
+  /// This will usually be a [FunctionType], but it can also be an
+  /// [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+  /// interface type that implements `Function`.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticInvokeType] instead.
   @deprecated
   DartType get propagatedInvokeType;
 
-  /**
-   * Sets the function type of the invocation based on the propagated type
-   * information.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticInvokeType] instead.
-   */
+  /// Sets the function type of the invocation based on the propagated type
+  /// information.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticInvokeType] instead.
   @deprecated
   void set propagatedInvokeType(DartType value);
 
-  /**
-   * Return the function type of the invocation based on the static type
-   * information, or `null` if the AST structure has not been resolved, or if
-   * the invoke could not be resolved.
-   *
-   * This will usually be a [FunctionType], but it can also be `dynamic` or
-   * `Function`. In the case of interface types that have a `call` method, we
-   * store the type of that `call` method here as parameterized.
-   */
+  /// Return the function type of the invocation based on the static type
+  /// information, or `null` if the AST structure has not been resolved, or if
+  /// the invoke could not be resolved.
+  ///
+  /// This will usually be a [FunctionType], but it can also be `dynamic` or
+  /// `Function`. In the case of interface types that have a `call` method, we
+  /// store the type of that `call` method here as parameterized.
   DartType get staticInvokeType;
 
-  /**
-   * Sets the function type of the invocation based on the static type
-   * information.
-   */
+  /// Sets the function type of the invocation based on the static type
+  /// information.
   void set staticInvokeType(DartType value);
 
-  /**
-   * Return the type arguments to be applied to the method being invoked, or
-   * `null` if no type arguments were provided.
-   */
+  /// Return the type arguments to be applied to the method being invoked, or
+  /// `null` if no type arguments were provided.
   TypeArgumentList get typeArguments;
 }
 
-/**
- * An is expression.
- *
- *    isExpression ::=
- *        [Expression] 'is' '!'? [TypeAnnotation]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class IsExpression extends Expression {
-  /**
-   * Return the expression used to compute the value whose type is being tested.
-   */
+/// An is expression.
+///
+///    isExpression ::=
+///        [Expression] 'is' '!'? [TypeAnnotation]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class IsExpression implements Expression {
+  /// Return the expression used to compute the value whose type is being
+  /// tested.
   Expression get expression;
 
-  /**
-   * Set the expression used to compute the value whose type is being tested to
-   * the given [expression].
-   */
+  /// Set the expression used to compute the value whose type is being tested to
+  /// the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the is operator.
-   */
+  /// Return the is operator.
   Token get isOperator;
 
-  /**
-   * Set the is operator to the given [token].
-   */
+  /// Set the is operator to the given [token].
   void set isOperator(Token token);
 
-  /**
-   * Return the not operator, or `null` if the sense of the test is not negated.
-   */
+  /// Return the not operator, or `null` if the sense of the test is not
+  /// negated.
   Token get notOperator;
 
-  /**
-   * Set the not operator to the given [token].
-   */
+  /// Set the not operator to the given [token].
   void set notOperator(Token token);
 
-  /**
-   * Return the type being tested for.
-   */
+  /// Return the type being tested for.
   TypeAnnotation get type;
 
-  /**
-   * Set the type being tested for to the given [type].
-   */
+  /// Set the type being tested for to the given [type].
   void set type(TypeAnnotation type);
 }
 
-/**
- * A label on either a [LabeledStatement] or a [NamedExpression].
- *
- *    label ::=
- *        [SimpleIdentifier] ':'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Label extends AstNode {
-  /**
-   * Return the colon that separates the label from the statement.
-   */
+/// A label on either a [LabeledStatement] or a [NamedExpression].
+///
+///    label ::=
+///        [SimpleIdentifier] ':'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Label implements AstNode {
+  /// Return the colon that separates the label from the statement.
   Token get colon;
 
-  /**
-   * Set the colon that separates the label from the statement to the given
-   * [token].
-   */
+  /// Set the colon that separates the label from the statement to the given
+  /// [token].
   void set colon(Token token);
 
-  /**
-   * Return the label being associated with the statement.
-   */
+  /// Return the label being associated with the statement.
   SimpleIdentifier get label;
 
-  /**
-   * Set the label being associated with the statement to the given [label].
-   */
+  /// Set the label being associated with the statement to the given [label].
   void set label(SimpleIdentifier label);
 }
 
-/**
- * A statement that has a label associated with them.
- *
- *    labeledStatement ::=
- *       [Label]+ [Statement]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class LabeledStatement extends Statement {
-  /**
-   * Return the labels being associated with the statement.
-   */
+/// A statement that has a label associated with them.
+///
+///    labeledStatement ::=
+///       [Label]+ [Statement]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class LabeledStatement implements Statement {
+  /// Return the labels being associated with the statement.
   NodeList<Label> get labels;
 
-  /**
-   * Return the statement with which the labels are being associated.
-   */
+  /// Return the statement with which the labels are being associated.
   Statement get statement;
 
-  /**
-   * Set the statement with which the labels are being associated to the given
-   * [statement].
-   */
+  /// Set the statement with which the labels are being associated to the given
+  /// [statement].
   void set statement(Statement statement);
 }
 
-/**
- * A library directive.
- *
- *    libraryDirective ::=
- *        [Annotation] 'library' [Identifier] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class LibraryDirective extends Directive {
-  /**
-   * Return the token representing the 'library' keyword.
-   */
+/// A library directive.
+///
+///    libraryDirective ::=
+///        [Annotation] 'library' [Identifier] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class LibraryDirective implements Directive {
+  /// Return the token representing the 'library' keyword.
   Token get libraryKeyword;
 
-  /**
-   * Set the token representing the 'library' keyword to the given [token].
-   */
+  /// Set the token representing the 'library' keyword to the given [token].
   void set libraryKeyword(Token token);
 
-  /**
-   * Return the name of the library being defined.
-   */
+  /// Return the name of the library being defined.
   LibraryIdentifier get name;
 
-  /**
-   * Set the name of the library being defined to the given [name].
-   */
+  /// Set the name of the library being defined to the given [name].
   void set name(LibraryIdentifier name);
 
-  /**
-   * Return the semicolon terminating the directive.
-   */
+  /// Return the semicolon terminating the directive.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the directive to the given [token].
-   */
+  /// Set the semicolon terminating the directive to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * The identifier for a library.
- *
- *    libraryIdentifier ::=
- *        [SimpleIdentifier] ('.' [SimpleIdentifier])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class LibraryIdentifier extends Identifier {
-  /**
-   * Return the components of the identifier.
-   */
+/// The identifier for a library.
+///
+///    libraryIdentifier ::=
+///        [SimpleIdentifier] ('.' [SimpleIdentifier])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class LibraryIdentifier implements Identifier {
+  /// Return the components of the identifier.
   NodeList<SimpleIdentifier> get components;
 }
 
-/**
- * A list literal.
- *
- *    listLiteral ::=
- *        'const'? ('<' [TypeAnnotation] '>')? '[' ([Expression] ','?)? ']'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ListLiteral extends TypedLiteral {
-  /**
-   * Return the expressions used to compute the elements of the list.
-   */
+/// A list literal.
+///
+///    listLiteral ::=
+///        'const'? ('<' [TypeAnnotation] '>')? '[' ([Expression] ','?)? ']'
+///
+/// This is the class that is used to represent a list literal when neither the
+/// 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+/// If either of those experiments are enabled, then [ListLiteral2] will be
+/// used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ListLiteral implements TypedLiteral {
+  /// Return the expressions used to compute the elements of the list.
   NodeList<Expression> get elements;
 
-  /**
-   * Return the left square bracket.
-   */
+  /// Return the left square bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left square bracket to the given [token].
-   */
+  /// Set the left square bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right square bracket.
-   */
+  /// Return the right square bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right square bracket to the given [token].
-   */
+  /// Set the right square bracket to the given [token].
   void set rightBracket(Token token);
 }
 
-/**
- * A node that represents a literal expression.
- *
- *    literal ::=
- *        [BooleanLiteral]
- *      | [DoubleLiteral]
- *      | [IntegerLiteral]
- *      | [ListLiteral]
- *      | [MapLiteral]
- *      | [NullLiteral]
- *      | [StringLiteral]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Literal extends Expression {}
+/// A list literal.
+///
+///    listLiteral ::=
+///        'const'? ('<' [TypeAnnotation] '>')?
+///        '[' ([CollectionElement] ','?)? ']'
+///
+/// This is the class that is used to represent a list literal when either the
+/// 'control-flow-collections' or 'spread-collections' experiments are enabled.
+/// If neither of those experiments are enabled, then [ListLiteral] will be used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ListLiteral2 implements TypedLiteral {
+  /// Return the expressions used to compute the elements of the list.
+  NodeList<CollectionElement> get elements;
 
-/**
- * A literal map.
- *
- *    mapLiteral ::=
- *        'const'? ('<' [TypeAnnotation] (',' [TypeAnnotation])* '>')?
- *        '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class MapLiteral extends TypedLiteral {
-  /**
-   * Return the entries in the map.
-   */
+  /// Return the left square bracket.
+  Token get leftBracket;
+
+  /// Set the left square bracket to the given [token].
+  void set leftBracket(Token token);
+
+  /// Return the right square bracket.
+  Token get rightBracket;
+
+  /// Set the right square bracket to the given [token].
+  void set rightBracket(Token token);
+}
+
+/// A node that represents a literal expression.
+///
+///    literal ::=
+///        [BooleanLiteral]
+///      | [DoubleLiteral]
+///      | [IntegerLiteral]
+///      | [ListLiteral]
+///      | [MapLiteral]
+///      | [NullLiteral]
+///      | [StringLiteral]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Literal implements Expression {}
+
+/// A literal map.
+///
+///    mapLiteral ::=
+///        'const'? ('<' [TypeAnnotation] (',' [TypeAnnotation])* '>')?
+///        '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'
+///
+/// This is the class that is used to represent a map literal when neither the
+/// 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+/// If either of those experiments are enabled, then [MapLiteral2] will be used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MapLiteral implements TypedLiteral {
+  /// Return the entries in the map.
   NodeList<MapLiteralEntry> get entries;
 
-  /**
-   * Return the left curly bracket.
-   */
+  /// Return the left curly bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left curly bracket to the given [token].
-   */
+  /// Set the left curly bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right curly bracket.
-   */
+  /// Return the right curly bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 }
 
-/**
- * A single key/value pair in a map literal.
- *
- *    mapLiteralEntry ::=
- *        [Expression] ':' [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class MapLiteralEntry extends AstNode {
-  /**
-   * Return the expression computing the key with which the value will be
-   * associated.
-   */
+/// A literal map.
+///
+///    mapLiteral ::=
+///        'const'? ('<' [TypeAnnotation] (',' [TypeAnnotation])* '>')?
+///        '{' ([MapElement] (',' [MapElement])* ','?)? '}'
+///
+/// This is the class that is used to represent a map literal when either the
+/// 'control-flow-collections' or 'spread-collections' experiments are enabled.
+/// If neither of those experiments are enabled, then [MapLiteral] will be used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MapLiteral2 implements TypedLiteral {
+  /// Return the entries in the map.
+  NodeList<CollectionElement> get entries;
+
+  /// Return the left curly bracket.
+  Token get leftBracket;
+
+  /// Set the left curly bracket to the given [token].
+  void set leftBracket(Token token);
+
+  /// Return the right curly bracket.
+  Token get rightBracket;
+
+  /// Set the right curly bracket to the given [token].
+  void set rightBracket(Token token);
+}
+
+/// A single key/value pair in a map literal.
+///
+///    mapLiteralEntry ::=
+///        [Expression] ':' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MapLiteralEntry implements CollectionElement {
+  /// Return the expression computing the key with which the value will be
+  /// associated.
   Expression get key;
 
-  /**
-   * Set the expression computing the key with which the value will be
-   * associated to the given [string].
-   */
+  /// Set the expression computing the key with which the value will be
+  /// associated to the given [string].
   void set key(Expression string);
 
-  /**
-   * Return the colon that separates the key from the value.
-   */
+  /// Return the colon that separates the key from the value.
   Token get separator;
 
-  /**
-   * Set the colon that separates the key from the value to the given [token].
-   */
+  /// Set the colon that separates the key from the value to the given [token].
   void set separator(Token token);
 
-  /**
-   * Return the expression computing the value that will be associated with the
-   * key.
-   */
+  /// Return the expression computing the value that will be associated with the
+  /// key.
   Expression get value;
 
-  /**
-   * Set the expression computing the value that will be associated with the key
-   * to the given [expression].
-   */
+  /// Set the expression computing the value that will be associated with the
+  /// key to the given [expression].
   void set value(Expression expression);
 }
 
-/**
- * A method declaration.
- *
- *    methodDeclaration ::=
- *        methodSignature [FunctionBody]
- *
- *    methodSignature ::=
- *        'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
- *        methodName [TypeParameterList] [FormalParameterList]
- *
- *    methodName ::=
- *        [SimpleIdentifier]
- *      | 'operator' [SimpleIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class MethodDeclaration extends ClassMember {
-  /**
-   * Return the body of the method.
-   */
+/// A method declaration.
+///
+///    methodDeclaration ::=
+///        methodSignature [FunctionBody]
+///
+///    methodSignature ::=
+///        'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
+///        methodName [TypeParameterList] [FormalParameterList]
+///
+///    methodName ::=
+///        [SimpleIdentifier]
+///      | 'operator' [SimpleIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MethodDeclaration implements ClassMember {
+  /// Return the body of the method.
   FunctionBody get body;
 
-  /**
-   * Set the body of the method to the given [functionBody].
-   */
+  /// Set the body of the method to the given [functionBody].
   void set body(FunctionBody functionBody);
 
   @override
@@ -4950,2115 +3880,1530 @@
   @override
   ExecutableElement get element;
 
-  /**
-   * Return the token for the 'external' keyword, or `null` if the constructor
-   * is not external.
-   */
+  /// Return the token for the 'external' keyword, or `null` if the constructor
+  /// is not external.
   Token get externalKeyword;
 
-  /**
-   * Set the token for the 'external' keyword to the given [token].
-   */
+  /// Set the token for the 'external' keyword to the given [token].
   void set externalKeyword(Token token);
 
-  /**
-   * Return `true` if this method is declared to be an abstract method.
-   */
+  /// Return `true` if this method is declared to be an abstract method.
   bool get isAbstract;
 
-  /**
-   * Return `true` if this method declares a getter.
-   */
+  /// Return `true` if this method declares a getter.
   bool get isGetter;
 
-  /**
-   * Return `true` if this method declares an operator.
-   */
+  /// Return `true` if this method declares an operator.
   bool get isOperator;
 
-  /**
-   * Return `true` if this method declares a setter.
-   */
+  /// Return `true` if this method declares a setter.
   bool get isSetter;
 
-  /**
-   * Return `true` if this method is declared to be a static method.
-   */
+  /// Return `true` if this method is declared to be a static method.
   bool get isStatic;
 
-  /**
-   * Return the token representing the 'abstract' or 'static' keyword, or `null`
-   * if neither modifier was specified.
-   */
+  /// Return the token representing the 'abstract' or 'static' keyword, or
+  /// `null` if neither modifier was specified.
   Token get modifierKeyword;
 
-  /**
-   * Set the token representing the 'abstract' or 'static' keyword to the given
-   * [token].
-   */
+  /// Set the token representing the 'abstract' or 'static' keyword to the given
+  /// [token].
   void set modifierKeyword(Token token);
 
-  /**
-   * Return the name of the method.
-   */
+  /// Return the name of the method.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the method to the given [identifier].
-   */
+  /// Set the name of the method to the given [identifier].
   void set name(SimpleIdentifier identifier);
 
-  /**
-   * Return the token representing the 'operator' keyword, or `null` if this
-   * method does not declare an operator.
-   */
+  /// Return the token representing the 'operator' keyword, or `null` if this
+  /// method does not declare an operator.
   Token get operatorKeyword;
 
-  /**
-   * Set the token representing the 'operator' keyword to the given [token].
-   */
+  /// Set the token representing the 'operator' keyword to the given [token].
   void set operatorKeyword(Token token);
 
-  /**
-   * Return the parameters associated with the method, or `null` if this method
-   * declares a getter.
-   */
+  /// Return the parameters associated with the method, or `null` if this method
+  /// declares a getter.
   FormalParameterList get parameters;
 
-  /**
-   * Set the parameters associated with the method to the given list of
-   * [parameters].
-   */
+  /// Set the parameters associated with the method to the given list of
+  /// [parameters].
   void set parameters(FormalParameterList parameters);
 
-  /**
-   * Return the token representing the 'get' or 'set' keyword, or `null` if this
-   * is a method declaration rather than a property declaration.
-   */
+  /// Return the token representing the 'get' or 'set' keyword, or `null` if
+  /// this is a method declaration rather than a property declaration.
   Token get propertyKeyword;
 
-  /**
-   * Set the token representing the 'get' or 'set' keyword to the given [token].
-   */
+  /// Set the token representing the 'get' or 'set' keyword to the given
+  /// [token].
   void set propertyKeyword(Token token);
 
-  /**
-   * Return the return type of the method, or `null` if no return type was
-   * declared.
-   */
+  /// Return the return type of the method, or `null` if no return type was
+  /// declared.
   TypeAnnotation get returnType;
 
-  /**
-   * Set the return type of the method to the given [type].
-   */
+  /// Set the return type of the method to the given [type].
   void set returnType(TypeAnnotation type);
 
-  /**
-   * Return the type parameters associated with this method, or `null` if this
-   * method is not a generic method.
-   */
+  /// Return the type parameters associated with this method, or `null` if this
+  /// method is not a generic method.
   TypeParameterList get typeParameters;
 
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
+  /// Set the type parameters associated with this method to the given
+  /// [typeParameters].
   void set typeParameters(TypeParameterList typeParameters);
 }
 
-/**
- * The invocation of either a function or a method. Invocations of functions
- * resulting from evaluating an expression are represented by
- * [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
- * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
- *
- *    methodInvocation ::=
- *        ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class MethodInvocation extends InvocationExpression {
-  /**
-   * Set the list of arguments to the method to the given [argumentList].
-   */
+/// The invocation of either a function or a method. Invocations of functions
+/// resulting from evaluating an expression are represented by
+/// [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
+/// represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
+///
+///    methodInvocation ::=
+///        ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MethodInvocation implements InvocationExpression {
+  /// Set the list of arguments to the method to the given [argumentList].
   void set argumentList(ArgumentList argumentList);
 
-  /**
-   * Return `true` if this expression is cascaded. If it is, then the target of
-   * this expression is not stored locally but is stored in the nearest ancestor
-   * that is a [CascadeExpression].
-   */
+  /// Return `true` if this expression is cascaded. If it is, then the target of
+  /// this expression is not stored locally but is stored in the nearest
+  /// ancestor that is a [CascadeExpression].
   bool get isCascaded;
 
-  /**
-   * Return the name of the method being invoked.
-   */
+  /// Return the name of the method being invoked.
   SimpleIdentifier get methodName;
 
-  /**
-   * Set the name of the method being invoked to the given [identifier].
-   */
+  /// Set the name of the method being invoked to the given [identifier].
   void set methodName(SimpleIdentifier identifier);
 
-  /**
-   * Return the operator that separates the target from the method name, or
-   * `null` if there is no target. In an ordinary method invocation this will be
-   *  * period ('.'). In a cascade section this will be the cascade operator
-   * ('..').
-   */
+  /// Return the operator that separates the target from the method name, or
+  /// `null` if there is no target. In an ordinary method invocation this will
+  /// be period ('.'). In a cascade section this will be the cascade operator
+  /// ('..').
   Token get operator;
 
-  /**
-   * Set the operator that separates the target from the method name to the
-   * given [token].
-   */
+  /// Set the operator that separates the target from the method name to the
+  /// given [token].
   void set operator(Token token);
 
-  /**
-   * Return the expression used to compute the receiver of the invocation. If
-   * this invocation is not part of a cascade expression, then this is the same
-   * as [target]. If this invocation is part of a cascade expression, then the
-   * target stored with the cascade expression is returned.
-   */
+  /// Return the expression used to compute the receiver of the invocation. If
+  /// this invocation is not part of a cascade expression, then this is the same
+  /// as [target]. If this invocation is part of a cascade expression, then the
+  /// target stored with the cascade expression is returned.
   Expression get realTarget;
 
-  /**
-   * Return the expression producing the object on which the method is defined,
-   * or `null` if there is no target (that is, the target is implicitly `this`)
-   * or if this method invocation is part of a cascade expression.
-   *
-   * Use [realTarget] to get the target independent of whether this is part of a
-   * cascade expression.
-   */
+  /// Return the expression producing the object on which the method is defined,
+  /// or `null` if there is no target (that is, the target is implicitly `this`)
+  /// or if this method invocation is part of a cascade expression.
+  ///
+  /// Use [realTarget] to get the target independent of whether this is part of
+  /// a cascade expression.
   Expression get target;
 
-  /**
-   * Set the expression producing the object on which the method is defined to
-   * the given [expression].
-   */
+  /// Set the expression producing the object on which the method is defined to
+  /// the given [expression].
   void set target(Expression expression);
 
-  /**
-   * Set the type arguments to be applied to the method being invoked to the
-   * given [typeArguments].
-   */
+  /// Set the type arguments to be applied to the method being invoked to the
+  /// given [typeArguments].
   void set typeArguments(TypeArgumentList typeArguments);
 }
 
-/**
- * An expression that implicitly makes reference to a method.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class MethodReferenceExpression {
-  /**
-   * Return the best element available for this expression. If resolution was
-   * able to find a better element based on type propagation, that element will
-   * be returned. Otherwise, the element found using the result of static
-   * analysis will be returned. If resolution has not been performed, then
-   * `null` will be returned.
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+/// An expression that implicitly makes reference to a method.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MethodReferenceExpression implements AstNode {
+  /// Return the best element available for this expression. If resolution was
+  /// able to find a better element based on type propagation, that element will
+  /// be returned. Otherwise, the element found using the result of static
+  /// analysis will be returned. If resolution has not been performed, then
+  /// `null` will be returned.
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   MethodElement get bestElement;
 
-  /**
-   * Return the element associated with the expression based on propagated
-   * types, or `null` if the AST structure has not been resolved, or there is
-   * no meaningful propagated element to return (e.g. because this is a
-   * non-compound assignment expression, or because the method referred to could
-   * not be resolved).
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Return the element associated with the expression based on propagated
+  /// types, or `null` if the AST structure has not been resolved, or there is
+  /// no meaningful propagated element to return (e.g. because this is a
+  /// non-compound assignment expression, or because the method referred to
+  /// could not be resolved).
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   MethodElement get propagatedElement;
 
-  /**
-   * Set the element associated with the expression based on propagated types to
-   * the given [element].
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Set the element associated with the expression based on propagated types
+  /// to the given [element].
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   void set propagatedElement(MethodElement element);
 
-  /**
-   * Return the element associated with the expression based on the static
-   * types, or `null` if the AST structure has not been resolved, or there is no
-   * meaningful static element to return (e.g. because this is a non-compound
-   * assignment expression, or because the method referred to could not be
-   * resolved).
-   */
+  /// Return the element associated with the expression based on the static
+  /// types, or `null` if the AST structure has not been resolved, or there is
+  /// no meaningful static element to return (e.g. because this is a
+  /// non-compound assignment expression, or because the method referred to
+  /// could not be resolved).
   MethodElement get staticElement;
 
-  /**
-   * Set the element associated with the expression based on static types to the
-   * given [element].
-   */
+  /// Set the element associated with the expression based on static types to
+  /// the given [element].
   void set staticElement(MethodElement element);
 }
 
-/**
- * The declaration of a mixin.
- *
- *    mixinDeclaration ::=
- *        metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
- *        [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class MixinDeclaration extends ClassOrMixinDeclaration {
-  /**
-   * Return the token representing the 'mixin' keyword.
-   */
+/// The declaration of a mixin.
+///
+///    mixinDeclaration ::=
+///        metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
+///        [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MixinDeclaration implements ClassOrMixinDeclaration {
+  /// Return the token representing the 'mixin' keyword.
   Token get mixinKeyword;
 
-  /**
-   * Return the on clause for the mixin, or `null` if the mixin does not have
-   * any superclass constraints.
-   */
+  /// Return the on clause for the mixin, or `null` if the mixin does not have
+  /// any superclass constraints.
   OnClause get onClause;
 }
 
-/**
- * A node that declares a single name within the scope of a compilation unit.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NamedCompilationUnitMember extends CompilationUnitMember {
-  /**
-   * Return the name of the member being declared.
-   */
+/// A node that declares a single name within the scope of a compilation unit.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NamedCompilationUnitMember implements CompilationUnitMember {
+  /// Return the name of the member being declared.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the member being declared to the given [identifier].
-   */
+  /// Set the name of the member being declared to the given [identifier].
   void set name(SimpleIdentifier identifier);
 }
 
-/**
- * An expression that has a name associated with it. They are used in method
- * invocations when there are named parameters.
- *
- *    namedExpression ::=
- *        [Label] [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NamedExpression extends Expression {
-  /**
-   * Return the element representing the parameter being named by this
-   * expression, or `null` if the AST structure has not been resolved or if
-   * there is no parameter with the same name as this expression.
-   */
+/// An expression that has a name associated with it. They are used in method
+/// invocations when there are named parameters.
+///
+///    namedExpression ::=
+///        [Label] [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NamedExpression implements Expression {
+  /// Return the element representing the parameter being named by this
+  /// expression, or `null` if the AST structure has not been resolved or if
+  /// there is no parameter with the same name as this expression.
   ParameterElement get element;
 
-  /**
-   * Return the expression with which the name is associated.
-   */
+  /// Return the expression with which the name is associated.
   Expression get expression;
 
-  /**
-   * Set the expression with which the name is associated to the given
-   * [expression].
-   */
+  /// Set the expression with which the name is associated to the given
+  /// [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the name associated with the expression.
-   */
+  /// Return the name associated with the expression.
   Label get name;
 
-  /**
-   * Set the name associated with the expression to the given [identifier].
-   */
+  /// Set the name associated with the expression to the given [identifier].
   void set name(Label identifier);
 }
 
-/**
- * A named type, which can optionally include type arguments.
- *
- *    namedType ::=
- *        [Identifier] typeArguments?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NamedType extends TypeAnnotation {
-  /**
-   * Return `true` if this type is a deferred type.
-   *
-   * 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
-   * </i>p.T</i> where <i>p</i> is a deferred prefix.
-   */
+/// A named type, which can optionally include type arguments.
+///
+///    namedType ::=
+///        [Identifier] typeArguments?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NamedType implements TypeAnnotation {
+  /// Return `true` if this type is a deferred type.
+  ///
+  /// 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
+  /// </i>p.T</i> where <i>p</i> is a deferred prefix.
   bool get isDeferred;
 
-  /**
-   * Return the name of the type.
-   */
+  /// Return the name of the type.
   Identifier get name;
 
-  /**
-   * Set the name of the type to the given [identifier].
-   */
+  /// Set the name of the type to the given [identifier].
   void set name(Identifier identifier);
 
-  /**
-   * The question mark indicating that the type is nullable, or `null` if there
-   * is no question mark.
-   */
-  Token get question;
-
-  /**
-   * Set the question mark indicating that the type is nullable to the given
-   * [token].
-   */
+  /// Set the question mark indicating that the type is nullable to the given
+  /// [token].
   void set question(Token token);
 
-  /**
-   * Set the type being named to the given [type].
-   */
+  /// Set the type being named to the given [type].
   void set type(DartType type);
 
-  /**
-   * Return the type arguments associated with the type, or `null` if there are
-   * no type arguments.
-   */
+  /// Return the type arguments associated with the type, or `null` if there are
+  /// no type arguments.
   TypeArgumentList get typeArguments;
 
-  /**
-   * Set the type arguments associated with the type to the given
-   * [typeArguments].
-   */
+  /// Set the type arguments associated with the type to the given
+  /// [typeArguments].
   void set typeArguments(TypeArgumentList typeArguments);
 }
 
-/**
- * A node that represents a directive that impacts the namespace of a library.
- *
- *    directive ::=
- *        [ExportDirective]
- *      | [ImportDirective]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NamespaceDirective extends UriBasedDirective {
-  /**
-   * Return the combinators used to control how names are imported or exported.
-   */
+/// A node that represents a directive that impacts the namespace of a library.
+///
+///    directive ::=
+///        [ExportDirective]
+///      | [ImportDirective]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NamespaceDirective implements UriBasedDirective {
+  /// Return the combinators used to control how names are imported or exported.
   NodeList<Combinator> get combinators;
 
-  /**
-   * Return the configurations used to control which library will actually be
-   * loaded at run-time.
-   */
+  /// Return the configurations used to control which library will actually be
+  /// loaded at run-time.
   NodeList<Configuration> get configurations;
 
-  /**
-   * Set the token representing the keyword that introduces this directive
-   * ('import', 'export', 'library' or 'part') to the given [token].
-   */
+  /// Set the token representing the keyword that introduces this directive
+  /// ('import', 'export', 'library' or 'part') to the given [token].
   void set keyword(Token token);
 
-  /**
-   * Return the source that was selected based on the declared variables. This
-   * will be the source from the first configuration whose condition is true, or
-   * the [uriSource] if either there are no configurations or if there are no
-   * configurations whose condition is true.
-   */
+  /// Return the source that was selected based on the declared variables. This
+  /// will be the source from the first configuration whose condition is true,
+  /// or the [uriSource] if either there are no configurations or if there are
+  /// no configurations whose condition is true.
   Source get selectedSource;
 
-  /**
-   * Return the content of the URI that was selected based on the declared
-   * variables. This will be the URI from the first configuration whose
-   * condition is true, or the [uriContent] if either there are no
-   * configurations or if there are no configurations whose condition is true.
-   */
+  /// Return the content of the URI that was selected based on the declared
+  /// variables. This will be the URI from the first configuration whose
+  /// condition is true, or the [uriContent] if either there are no
+  /// configurations or if there are no configurations whose condition is true.
   String get selectedUriContent;
 
-  /**
-   * Return the semicolon terminating the directive.
-   */
+  /// Return the semicolon terminating the directive.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the directive to the given [token].
-   */
+  /// Set the semicolon terminating the directive to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * The "native" clause in an class declaration.
- *
- *    nativeClause ::=
- *        'native' [StringLiteral]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NativeClause extends AstNode {
-  /**
-   * Return the name of the native object that implements the class.
-   */
+/// The "native" clause in an class declaration.
+///
+///    nativeClause ::=
+///        'native' [StringLiteral]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NativeClause implements AstNode {
+  /// Return the name of the native object that implements the class.
   StringLiteral get name;
 
-  /**
-   * Set the name of the native object that implements the class to the given
-   * [name].
-   */
+  /// Set the name of the native object that implements the class to the given
+  /// [name].
   void set name(StringLiteral name);
 
-  /**
-   * Return the token representing the 'native' keyword.
-   */
+  /// Return the token representing the 'native' keyword.
   Token get nativeKeyword;
 
-  /**
-   * Set the token representing the 'native' keyword to the given [token].
-   */
+  /// Set the token representing the 'native' keyword to the given [token].
   void set nativeKeyword(Token token);
 }
 
-/**
- * A function body that consists of a native keyword followed by a string
- * literal.
- *
- *    nativeFunctionBody ::=
- *        'native' [SimpleStringLiteral] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NativeFunctionBody extends FunctionBody {
-  /**
-   * Return the token representing 'native' that marks the start of the function
-   * body.
-   */
+/// A function body that consists of a native keyword followed by a string
+/// literal.
+///
+///    nativeFunctionBody ::=
+///        'native' [SimpleStringLiteral] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NativeFunctionBody implements FunctionBody {
+  /// Return the token representing 'native' that marks the start of the
+  /// function body.
   Token get nativeKeyword;
 
-  /**
-   * Set the token representing 'native' that marks the start of the function
-   * body to the given [token].
-   */
+  /// Set the token representing 'native' that marks the start of the function
+  /// body to the given [token].
   void set nativeKeyword(Token token);
 
-  /**
-   * Return the token representing the semicolon that marks the end of the
-   * function body.
-   */
+  /// Return the token representing the semicolon that marks the end of the
+  /// function body.
   Token get semicolon;
 
-  /**
-   * Set the token representing the semicolon that marks the end of the
-   * function body to the given [token].
-   */
+  /// Set the token representing the semicolon that marks the end of the
+  /// function body to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the string literal representing the string after the 'native' token.
-   */
+  /// Return the string literal representing the string after the 'native'
+  /// token.
   StringLiteral get stringLiteral;
 
-  /**
-   * Set the string literal representing the string after the 'native' token to
-   * the given [stringLiteral].
-   */
+  /// Set the string literal representing the string after the 'native' token to
+  /// the given [stringLiteral].
   void set stringLiteral(StringLiteral stringLiteral);
 }
 
-/**
- * A list of AST nodes that have a common parent.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// A list of AST nodes that have a common parent.
+///
+/// Clients may not extend, implement or mix-in this class.
 abstract class NodeList<E extends AstNode> implements List<E> {
-  /**
-   * Return the first token included in this node list's source range, or `null`
-   * if the list is empty.
-   */
+  /// Return the first token included in this node list's source range, or
+  /// `null` if the list is empty.
   Token get beginToken;
 
-  /**
-   * Return the last token included in this node list's source range, or `null`
-   * if the list is empty.
-   */
+  /// Return the last token included in this node list's source range, or `null`
+  /// if the list is empty.
   Token get endToken;
 
-  /**
-   * Return the node that is the parent of each of the elements in the list.
-   */
+  /// Return the node that is the parent of each of the elements in the list.
   AstNode get owner;
 
-  /**
-   * Set the node that is the parent of each of the elements in the list to the
-   * given [node].
-   */
+  /// Set the node that is the parent of each of the elements in the list to the
+  /// given [node].
   @deprecated // Never intended for public use.
   void set owner(AstNode node);
 
-  /**
-   * Return the node at the given [index] in the list or throw a [RangeError] if
-   * [index] is out of bounds.
-   */
+  /// Return the node at the given [index] in the list or throw a [RangeError]
+  /// if [index] is out of bounds.
   @override
   E operator [](int index);
 
-  /**
-   * Set the node at the given [index] in the list to the given [node] or throw
-   * a [RangeError] if [index] is out of bounds.
-   */
+  /// Set the node at the given [index] in the list to the given [node] or throw
+  /// a [RangeError] if [index] is out of bounds.
   @override
   void operator []=(int index, E node);
 
-  /**
-   * Use the given [visitor] to visit each of the nodes in this list.
-   */
+  /// Use the given [visitor] to visit each of the nodes in this list.
   accept(AstVisitor visitor);
 }
 
-/**
- * A formal parameter that is required (is not optional).
- *
- *    normalFormalParameter ::=
- *        [FunctionTypedFormalParameter]
- *      | [FieldFormalParameter]
- *      | [SimpleFormalParameter]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NormalFormalParameter extends FormalParameter {
-  /**
-   * Set the token for the 'covariant' keyword to the given [token].
-   */
+/// A formal parameter that is required (is not optional).
+///
+///    normalFormalParameter ::=
+///        [FunctionTypedFormalParameter]
+///      | [FieldFormalParameter]
+///      | [SimpleFormalParameter]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NormalFormalParameter implements FormalParameter {
+  /// Set the token for the 'covariant' keyword to the given [token].
   void set covariantKeyword(Token token);
 
-  /**
-   * Return the documentation comment associated with this parameter, or `null`
-   * if this parameter does not have a documentation comment associated with it.
-   */
+  /// Return the documentation comment associated with this parameter, or `null`
+  /// if this parameter does not have a documentation comment associated with
+  /// it.
   Comment get documentationComment;
 
-  /**
-   * Set the documentation comment associated with this parameter to the given
-   * [comment].
-   */
+  /// Set the documentation comment associated with this parameter to the given
+  /// [comment].
   void set documentationComment(Comment comment);
 
-  /**
-   * Set the name of the parameter being declared to the given [identifier].
-   */
+  /// Set the name of the parameter being declared to the given [identifier].
   void set identifier(SimpleIdentifier identifier);
 
-  /**
-   * Set the metadata associated with this node to the given [metadata].
-   */
+  /// Set the metadata associated with this node to the given [metadata].
   void set metadata(List<Annotation> metadata);
 
-  /**
-   * Return a list containing the comment and annotations associated with this
-   * parameter, sorted in lexical order.
-   */
+  /// Return a list containing the comment and annotations associated with this
+  /// parameter, sorted in lexical order.
   List<AstNode> get sortedCommentAndAnnotations;
 }
 
-/**
- * A null literal expression.
- *
- *    nullLiteral ::=
- *        'null'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class NullLiteral extends Literal {
-  /**
-   * Return the token representing the literal.
-   */
+/// A null literal expression.
+///
+///    nullLiteral ::=
+///        'null'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class NullLiteral implements Literal {
+  /// Return the token representing the literal.
   Token get literal;
 
-  /**
-   * Set the token representing the literal to the given [token].
-   */
+  /// Set the token representing the literal to the given [token].
   void set literal(Token token);
 }
 
-/**
- * The "on" clause in a mixin declaration.
- *
- *    onClause ::=
- *        'on' [TypeName] (',' [TypeName])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class OnClause extends AstNode {
-  /**
-   * Return the token representing the 'on' keyword.
-   */
+/// The "on" clause in a mixin declaration.
+///
+///    onClause ::=
+///        'on' [TypeName] (',' [TypeName])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class OnClause implements AstNode {
+  /// Return the token representing the 'on' keyword.
   Token get onKeyword;
 
-  /**
-   * Return the list of the classes are superclass constraints for the mixin.
-   */
+  /// Return the list of the classes are superclass constraints for the mixin.
   NodeList<TypeName> get superclassConstraints;
 }
 
-/**
- * A parenthesized expression.
- *
- *    parenthesizedExpression ::=
- *        '(' [Expression] ')'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ParenthesizedExpression extends Expression {
-  /**
-   * Return the expression within the parentheses.
-   */
+/// A parenthesized expression.
+///
+///    parenthesizedExpression ::=
+///        '(' [Expression] ')'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ParenthesizedExpression implements Expression {
+  /// Return the expression within the parentheses.
   Expression get expression;
 
-  /**
-   * Set the expression within the parentheses to the given [expression].
-   */
+  /// Set the expression within the parentheses to the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 }
 
-/**
- * A part directive.
- *
- *    partDirective ::=
- *        [Annotation] 'part' [StringLiteral] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class PartDirective extends UriBasedDirective {
-  /**
-   * Return the token representing the 'part' keyword.
-   */
+/// A part directive.
+///
+///    partDirective ::=
+///        [Annotation] 'part' [StringLiteral] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PartDirective implements UriBasedDirective {
+  /// Return the token representing the 'part' keyword.
   Token get partKeyword;
 
-  /**
-   * Set the token representing the 'part' keyword to the given [token].
-   */
+  /// Set the token representing the 'part' keyword to the given [token].
   void set partKeyword(Token token);
 
-  /**
-   * Return the semicolon terminating the directive.
-   */
+  /// Return the semicolon terminating the directive.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the directive to the given [token].
-   */
+  /// Set the semicolon terminating the directive to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * A part-of directive.
- *
- *    partOfDirective ::=
- *        [Annotation] 'part' 'of' [Identifier] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class PartOfDirective extends Directive {
-  /**
-   * Return the name of the library that the containing compilation unit is part
-   * of.
-   */
+/// A part-of directive.
+///
+///    partOfDirective ::=
+///        [Annotation] 'part' 'of' [Identifier] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PartOfDirective implements Directive {
+  /// Return the name of the library that the containing compilation unit is
+  /// part of.
   LibraryIdentifier get libraryName;
 
-  /**
-   * Set the name of the library that the containing compilation unit is part of
-   * to the given [libraryName].
-   */
+  /// Set the name of the library that the containing compilation unit is part
+  /// of to the given [libraryName].
   void set libraryName(LibraryIdentifier libraryName);
 
-  /**
-   * Return the token representing the 'of' keyword.
-   */
+  /// Return the token representing the 'of' keyword.
   Token get ofKeyword;
 
-  /**
-   * Set the token representing the 'of' keyword to the given [token].
-   */
+  /// Set the token representing the 'of' keyword to the given [token].
   void set ofKeyword(Token token);
 
-  /**
-   * Return the token representing the 'part' keyword.
-   */
+  /// Return the token representing the 'part' keyword.
   Token get partKeyword;
 
-  /**
-   * Set the token representing the 'part' keyword to the given [token].
-   */
+  /// Set the token representing the 'part' keyword to the given [token].
   void set partKeyword(Token token);
 
-  /**
-   * Return the semicolon terminating the directive.
-   */
+  /// Return the semicolon terminating the directive.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the directive to the given [token].
-   */
+  /// Set the semicolon terminating the directive to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the URI of the library that the containing compilation unit is part
-   * of, or `null` if no URI was given (typically because a library name was
-   * provided).
-   */
+  /// Return the URI of the library that the containing compilation unit is part
+  /// of, or `null` if no URI was given (typically because a library name was
+  /// provided).
   StringLiteral get uri;
 
-  /**
-   * Return the URI of the library that the containing compilation unit is part
-   * of, or `null` if no URI was given (typically because a library name was
-   * provided).
-   */
+  /// Return the URI of the library that the containing compilation unit is part
+  /// of, or `null` if no URI was given (typically because a library name was
+  /// provided).
   void set uri(StringLiteral uri);
 }
 
-/**
- * A postfix unary expression.
- *
- *    postfixExpression ::=
- *        [Expression] [Token]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class PostfixExpression extends Expression
-    implements MethodReferenceExpression {
-  /**
-   * Return the expression computing the operand for the operator.
-   */
+/// A postfix unary expression.
+///
+///    postfixExpression ::=
+///        [Expression] [Token]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PostfixExpression
+    implements Expression, MethodReferenceExpression {
+  /// Return the expression computing the operand for the operator.
   Expression get operand;
 
-  /**
-   * Set the expression computing the operand for the operator to the given
-   * [expression].
-   */
+  /// Set the expression computing the operand for the operator to the given
+  /// [expression].
   void set operand(Expression expression);
 
-  /**
-   * Return the postfix operator being applied to the operand.
-   */
+  /// Return the postfix operator being applied to the operand.
   Token get operator;
 
-  /**
-   * Set the postfix operator being applied to the operand to the given [token].
-   */
+  /// Set the postfix operator being applied to the operand to the given
+  /// [token].
   void set operator(Token token);
 }
 
-/**
- * An identifier that is prefixed or an access to an object property where the
- * target of the property access is a simple identifier.
- *
- *    prefixedIdentifier ::=
- *        [SimpleIdentifier] '.' [SimpleIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class PrefixedIdentifier extends Identifier {
-  /**
-   * Return the identifier being prefixed.
-   */
+/// An identifier that is prefixed or an access to an object property where the
+/// target of the property access is a simple identifier.
+///
+///    prefixedIdentifier ::=
+///        [SimpleIdentifier] '.' [SimpleIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PrefixedIdentifier implements Identifier {
+  /// Return the identifier being prefixed.
   SimpleIdentifier get identifier;
 
-  /**
-   * Set the identifier being prefixed to the given [identifier].
-   */
+  /// Set the identifier being prefixed to the given [identifier].
   void set identifier(SimpleIdentifier identifier);
 
-  /**
-   * Return `true` if this type is a deferred type. If the AST structure has not
-   * been resolved, then return `false`.
-   *
-   * 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
-   * </i>p.T</i> where <i>p</i> is a deferred prefix.
-   */
+  /// Return `true` if this type is a deferred type. If the AST structure has
+  /// not been resolved, then return `false`.
+  ///
+  /// 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
+  /// </i>p.T</i> where <i>p</i> is a deferred prefix.
   bool get isDeferred;
 
-  /**
-   * Return the period used to separate the prefix from the identifier.
-   */
+  /// Return the period used to separate the prefix from the identifier.
   Token get period;
 
-  /**
-   * Set the period used to separate the prefix from the identifier to the given
-   * [token].
-   */
+  /// Set the period used to separate the prefix from the identifier to the
+  /// given [token].
   void set period(Token token);
 
-  /**
-   * Return the prefix associated with the library in which the identifier is
-   * defined.
-   */
+  /// Return the prefix associated with the library in which the identifier is
+  /// defined.
   SimpleIdentifier get prefix;
 
-  /**
-   * Set the prefix associated with the library in which the identifier is
-   * defined to the given [identifier].
-   */
+  /// Set the prefix associated with the library in which the identifier is
+  /// defined to the given [identifier].
   void set prefix(SimpleIdentifier identifier);
 }
 
-/**
- * A prefix unary expression.
- *
- *    prefixExpression ::=
- *        [Token] [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class PrefixExpression extends Expression
-    implements MethodReferenceExpression {
-  /**
-   * Return the expression computing the operand for the operator.
-   */
+/// A prefix unary expression.
+///
+///    prefixExpression ::=
+///        [Token] [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PrefixExpression
+    implements Expression, MethodReferenceExpression {
+  /// Return the expression computing the operand for the operator.
   Expression get operand;
 
-  /**
-   * Set the expression computing the operand for the operator to the given
-   * [expression].
-   */
+  /// Set the expression computing the operand for the operator to the given
+  /// [expression].
   void set operand(Expression expression);
 
-  /**
-   * Return the prefix operator being applied to the operand.
-   */
+  /// Return the prefix operator being applied to the operand.
   Token get operator;
 
-  /**
-   * Set the prefix operator being applied to the operand to the given [token].
-   */
+  /// Set the prefix operator being applied to the operand to the given [token].
   void set operator(Token token);
 }
 
-/**
- * The access of a property of an object.
- *
- * Note, however, that accesses to properties of objects can also be represented
- * as [PrefixedIdentifier] nodes in cases where the target is also a simple
- * identifier.
- *
- *    propertyAccess ::=
- *        [Expression] '.' [SimpleIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class PropertyAccess extends Expression {
-  /**
-   * Return `true` if this expression is cascaded. If it is, then the target of
-   * this expression is not stored locally but is stored in the nearest ancestor
-   * that is a [CascadeExpression].
-   */
+/// The access of a property of an object.
+///
+/// Note, however, that accesses to properties of objects can also be
+/// represented as [PrefixedIdentifier] nodes in cases where the target is also
+/// a simple identifier.
+///
+///    propertyAccess ::=
+///        [Expression] '.' [SimpleIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class PropertyAccess implements Expression {
+  /// Return `true` if this expression is cascaded. If it is, then the target of
+  /// this expression is not stored locally but is stored in the nearest
+  /// ancestor that is a [CascadeExpression].
   bool get isCascaded;
 
-  /**
-   * Return the property access operator.
-   */
+  /// Return the property access operator.
   Token get operator;
 
-  /**
-   * Set the property access operator to the given [token].
-   */
+  /// Set the property access operator to the given [token].
   void set operator(Token token);
 
-  /**
-   * Return the name of the property being accessed.
-   */
+  /// Return the name of the property being accessed.
   SimpleIdentifier get propertyName;
 
-  /**
-   * Set the name of the property being accessed to the given [identifier].
-   */
+  /// Set the name of the property being accessed to the given [identifier].
   void set propertyName(SimpleIdentifier identifier);
 
-  /**
-   * Return the expression used to compute the receiver of the invocation. If
-   * this invocation is not part of a cascade expression, then this is the same
-   * as [target]. If this invocation is part of a cascade expression, then the
-   * target stored with the cascade expression is returned.
-   */
+  /// Return the expression used to compute the receiver of the invocation. If
+  /// this invocation is not part of a cascade expression, then this is the same
+  /// as [target]. If this invocation is part of a cascade expression, then the
+  /// target stored with the cascade expression is returned.
   Expression get realTarget;
 
-  /**
-   * Return the expression computing the object defining the property being
-   * accessed, or `null` if this property access is part of a cascade expression.
-   *
-   * Use [realTarget] to get the target independent of whether this is part of a
-   * cascade expression.
-   */
+  /// Return the expression computing the object defining the property being
+  /// accessed, or `null` if this property access is part of a cascade
+  /// expression.
+  ///
+  /// Use [realTarget] to get the target independent of whether this is part of
+  /// a cascade expression.
   Expression get target;
 
-  /**
-   * Set the expression computing the object defining the property being
-   * accessed to the given [expression].
-   */
+  /// Set the expression computing the object defining the property being
+  /// accessed to the given [expression].
   void set target(Expression expression);
 }
 
-/**
- * The invocation of a constructor in the same class from within a constructor's
- * initialization list.
- *
- *    redirectingConstructorInvocation ::=
- *        'this' ('.' identifier)? arguments
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class RedirectingConstructorInvocation extends ConstructorInitializer
-    implements ConstructorReferenceNode {
-  /**
-   * Return the list of arguments to the constructor.
-   */
+/// The invocation of a constructor in the same class from within a
+/// constructor's initialization list.
+///
+///    redirectingConstructorInvocation ::=
+///        'this' ('.' identifier)? arguments
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class RedirectingConstructorInvocation
+    implements ConstructorInitializer, ConstructorReferenceNode {
+  /// Return the list of arguments to the constructor.
   ArgumentList get argumentList;
 
-  /**
-   * Set the list of arguments to the constructor to the given [argumentList].
-   */
+  /// Set the list of arguments to the constructor to the given [argumentList].
   void set argumentList(ArgumentList argumentList);
 
-  /**
-   * Return the name of the constructor that is being invoked, or `null` if the
-   * unnamed constructor is being invoked.
-   */
+  /// Return the name of the constructor that is being invoked, or `null` if the
+  /// unnamed constructor is being invoked.
   SimpleIdentifier get constructorName;
 
-  /**
-   * Set the name of the constructor that is being invoked to the given
-   * [identifier].
-   */
+  /// Set the name of the constructor that is being invoked to the given
+  /// [identifier].
   void set constructorName(SimpleIdentifier identifier);
 
-  /**
-   * Return the token for the period before the name of the constructor that is
-   * being invoked, or `null` if the unnamed constructor is being invoked.
-   */
+  /// Return the token for the period before the name of the constructor that is
+  /// being invoked, or `null` if the unnamed constructor is being invoked.
   Token get period;
 
-  /**
-   * Set the token for the period before the name of the constructor that is
-   * being invoked to the given [token].
-   */
+  /// Set the token for the period before the name of the constructor that is
+  /// being invoked to the given [token].
   void set period(Token token);
 
-  /**
-   * Return the token for the 'this' keyword.
-   */
+  /// Return the token for the 'this' keyword.
   Token get thisKeyword;
 
-  /**
-   * Set the token for the 'this' keyword to the given [token].
-   */
+  /// Set the token for the 'this' keyword to the given [token].
   void set thisKeyword(Token token);
 }
 
-/**
- * A rethrow expression.
- *
- *    rethrowExpression ::=
- *        'rethrow'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class RethrowExpression extends Expression {
-  /**
-   * Return the token representing the 'rethrow' keyword.
-   */
+/// A rethrow expression.
+///
+///    rethrowExpression ::=
+///        'rethrow'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class RethrowExpression implements Expression {
+  /// Return the token representing the 'rethrow' keyword.
   Token get rethrowKeyword;
 
-  /**
-   * Set the token representing the 'rethrow' keyword to the given [token].
-   */
+  /// Set the token representing the 'rethrow' keyword to the given [token].
   void set rethrowKeyword(Token token);
 }
 
-/**
- * A return statement.
- *
- *    returnStatement ::=
- *        'return' [Expression]? ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ReturnStatement extends Statement {
-  /**
-   * Return the expression computing the value to be returned, or `null` if no
-   * explicit value was provided.
-   */
+/// A return statement.
+///
+///    returnStatement ::=
+///        'return' [Expression]? ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ReturnStatement implements Statement {
+  /// Return the expression computing the value to be returned, or `null` if no
+  /// explicit value was provided.
   Expression get expression;
 
-  /**
-   * Set the expression computing the value to be returned to the given
-   * [expression].
-   */
+  /// Set the expression computing the value to be returned to the given
+  /// [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the token representing the 'return' keyword.
-   */
+  /// Return the token representing the 'return' keyword.
   Token get returnKeyword;
 
-  /**
-   * Set the token representing the 'return' keyword to the given [token].
-   */
+  /// Set the token representing the 'return' keyword to the given [token].
   void set returnKeyword(Token token);
 
-  /**
-   * Return the semicolon terminating the statement.
-   */
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 }
 
-/**
- * A script tag that can optionally occur at the beginning of a compilation unit.
- *
- *    scriptTag ::=
- *        '#!' (~NEWLINE)* NEWLINE
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ScriptTag extends AstNode {
-  /**
-   * Return the token representing this script tag.
-   */
+/// A script tag that can optionally occur at the beginning of a compilation
+/// unit.
+///
+///    scriptTag ::=
+///        '#!' (~NEWLINE)* NEWLINE
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ScriptTag implements AstNode {
+  /// Return the token representing this script tag.
   Token get scriptTag;
 
-  /**
-   * Set the token representing this script tag to the given [token].
-   */
+  /// Set the token representing this script tag to the given [token].
   void set scriptTag(Token token);
 }
 
-/**
- * A literal set.
- *
- *    setLiteral ::=
- *        'const'? ('<' [TypeAnnotation] '>')?
- *        '{' [Expression] (',' [Expression])* ','? '}'
- *      | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SetLiteral extends TypedLiteral {
-  /**
-   * Return the expressions used to compute the elements of the set.
-   */
+/// A literal set.
+///
+///    setLiteral ::=
+///        'const'? ('<' [TypeAnnotation] '>')?
+///        '{' [Expression] (',' [Expression])* ','? '}'
+///      | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
+///
+/// This is the class that is used to represent a set literal when neither the
+/// 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+/// If either of those experiments are enabled, then [SetLiteral2] will be used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SetLiteral implements TypedLiteral {
+  /// Return the expressions used to compute the elements of the set.
   NodeList<Expression> get elements;
 
-  /**
-   * Return the left curly bracket.
-   */
+  /// Return the left curly bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left curly bracket to the given [token].
-   */
+  /// Set the left curly bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right curly bracket.
-   */
+  /// Return the right curly bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 }
 
-/**
- * A combinator that restricts the names being imported to those in a given list.
- *
- *    showCombinator ::=
- *        'show' [SimpleIdentifier] (',' [SimpleIdentifier])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ShowCombinator extends Combinator {
-  /**
-   * Return the list of names from the library that are made visible by this
-   * combinator.
-   */
+/// A literal set.
+///
+///    setLiteral ::=
+///        'const'? ('<' [TypeAnnotation] '>')?
+///        '{' [CollectionElement] (',' [CollectionElement])* ','? '}'
+///      | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
+///
+/// This is the class that is used to represent a set literal when either the
+/// 'control-flow-collections' or 'spread-collections' experiments are enabled.
+/// If neither of those experiments are enabled, then [SetLiteral] will be used.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SetLiteral2 implements TypedLiteral {
+  /// Return the expressions used to compute the elements of the set.
+  NodeList<CollectionElement> get elements;
+
+  /// Return the left curly bracket.
+  Token get leftBracket;
+
+  /// Set the left curly bracket to the given [token].
+  void set leftBracket(Token token);
+
+  /// Return the right curly bracket.
+  Token get rightBracket;
+
+  /// Set the right curly bracket to the given [token].
+  void set rightBracket(Token token);
+}
+
+/// A combinator that restricts the names being imported to those in a given list.
+///
+///    showCombinator ::=
+///        'show' [SimpleIdentifier] (',' [SimpleIdentifier])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ShowCombinator implements Combinator {
+  /// Return the list of names from the library that are made visible by this
+  /// combinator.
   NodeList<SimpleIdentifier> get shownNames;
 }
 
-/**
- * A simple formal parameter.
- *
- *    simpleFormalParameter ::=
- *        ('final' [TypeAnnotation] | 'var' | [TypeAnnotation])? [SimpleIdentifier]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SimpleFormalParameter extends NormalFormalParameter {
-  /**
-   * Return the token representing either the 'final', 'const' or 'var' keyword,
-   * or `null` if no keyword was used.
-   */
+/// A simple formal parameter.
+///
+///    simpleFormalParameter ::=
+///        ('final' [TypeAnnotation] | 'var' | [TypeAnnotation])? [SimpleIdentifier]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SimpleFormalParameter implements NormalFormalParameter {
+  /// Return the token representing either the 'final', 'const' or 'var'
+  /// keyword, or `null` if no keyword was used.
   Token get keyword;
 
-  /**
-   * Set the token representing either the 'final', 'const' or 'var' keyword to
-   * the given [token].
-   */
+  /// Set the token representing either the 'final', 'const' or 'var' keyword to
+  /// the given [token].
   void set keyword(Token token);
 
-  /**
-   * Return the declared type of the parameter, or `null` if the parameter does
-   * not have a declared type.
-   */
+  /// Return the declared type of the parameter, or `null` if the parameter does
+  /// not have a declared type.
   TypeAnnotation get type;
 
-  /**
-   * Set the declared type of the parameter to the given [type].
-   */
+  /// Set the declared type of the parameter to the given [type].
   void set type(TypeAnnotation type);
 }
 
-/**
- * A simple identifier.
- *
- *    simpleIdentifier ::=
- *        initialCharacter internalCharacter*
- *
- *    initialCharacter ::= '_' | '$' | letter
- *
- *    internalCharacter ::= '_' | '$' | letter | digit
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SimpleIdentifier extends Identifier {
-  /**
-   * Return the auxiliary elements associated with this identifier, or `null` if
-   * this identifier is not in both a getter and setter context. The auxiliary
-   * elements hold the static and propagated elements associated with the getter
-   * context.
-   */
+/// A simple identifier.
+///
+///    simpleIdentifier ::=
+///        initialCharacter internalCharacter*
+///
+///    initialCharacter ::= '_' | '$' | letter
+///
+///    internalCharacter ::= '_' | '$' | letter | digit
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SimpleIdentifier implements Identifier {
+  /// Return the auxiliary elements associated with this identifier, or `null`
+  /// if this identifier is not in both a getter and setter context. The
+  /// auxiliary elements hold the static and propagated elements associated with
+  /// the getter context.
   // TODO(brianwilkerson) Replace this API.
   AuxiliaryElements get auxiliaryElements;
 
-  /**
-   * Set the auxiliary elements associated with this identifier to the given
-   * [elements].
-   */
+  /// Set the auxiliary elements associated with this identifier to the given
+  /// [elements].
   // TODO(brianwilkerson) Replace this API.
   void set auxiliaryElements(AuxiliaryElements elements);
 
-  /**
-   * Return `true` if this identifier is the "name" part of a prefixed
-   * identifier or a method invocation.
-   */
+  /// Return `true` if this identifier is the "name" part of a prefixed
+  /// identifier or a method invocation.
   bool get isQualified;
 
-  /**
-   * Set the element associated with this identifier based on propagated type
-   * information to the given [element].
-   *
-   * Deprecated: The analyzer no longer computes propagated type information.
-   * Use [staticElement] instead.
-   */
+  /// Set the element associated with this identifier based on propagated type
+  /// information to the given [element].
+  ///
+  /// Deprecated: The analyzer no longer computes propagated type information.
+  /// Use [staticElement] instead.
   @deprecated
   void set propagatedElement(Element element);
 
-  /**
-   * Set the element associated with this identifier based on static type
-   * information to the given [element].
-   */
+  /// Set the element associated with this identifier based on static type
+  /// information to the given [element].
   void set staticElement(Element element);
 
-  /**
-   * Return the token representing the identifier.
-   */
+  /// Return the token representing the identifier.
   Token get token;
 
-  /**
-   * Set the token representing the identifier to the given [token].
-   */
+  /// Set the token representing the identifier to the given [token].
   void set token(Token token);
 
-  /**
-   * Return `true` if this identifier is the name being declared in a
-   * declaration.
-   */
+  /// Return `true` if this identifier is the name being declared in a
+  /// declaration.
   // TODO(brianwilkerson) Convert this to a getter.
   bool inDeclarationContext();
 
-  /**
-   * Return `true` if this expression is computing a right-hand value.
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
+  /// Return `true` if this expression is computing a right-hand value.
+  ///
+  /// Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+  /// are they mutually exclusive. In other words, it is possible for both
+  /// methods to return `true` when invoked on the same node.
   // TODO(brianwilkerson) Convert this to a getter.
   bool inGetterContext();
 
-  /**
-   * Return `true` if this expression is computing a left-hand value.
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
+  /// Return `true` if this expression is computing a left-hand value.
+  ///
+  /// Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+  /// are they mutually exclusive. In other words, it is possible for both
+  /// methods to return `true` when invoked on the same node.
   // TODO(brianwilkerson) Convert this to a getter.
   bool inSetterContext();
 }
 
-/**
- * A string literal expression that does not contain any interpolations.
- *
- *    simpleStringLiteral ::=
- *        rawStringLiteral
- *      | basicStringLiteral
- *
- *    rawStringLiteral ::=
- *        'r' basicStringLiteral
- *
- *    simpleStringLiteral ::=
- *        multiLineStringLiteral
- *      | singleLineStringLiteral
- *
- *    multiLineStringLiteral ::=
- *        "'''" characters "'''"
- *      | '"""' characters '"""'
- *
- *    singleLineStringLiteral ::=
- *        "'" characters "'"
- *      | '"' characters '"'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SimpleStringLiteral extends SingleStringLiteral {
-  /**
-   * Return the token representing the literal.
-   */
+/// A string literal expression that does not contain any interpolations.
+///
+///    simpleStringLiteral ::=
+///        rawStringLiteral
+///      | basicStringLiteral
+///
+///    rawStringLiteral ::=
+///        'r' basicStringLiteral
+///
+///    simpleStringLiteral ::=
+///        multiLineStringLiteral
+///      | singleLineStringLiteral
+///
+///    multiLineStringLiteral ::=
+///        "'''" characters "'''"
+///      | '"""' characters '"""'
+///
+///    singleLineStringLiteral ::=
+///        "'" characters "'"
+///      | '"' characters '"'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SimpleStringLiteral implements SingleStringLiteral {
+  /// Return the token representing the literal.
   Token get literal;
 
-  /**
-   * Set the token representing the literal to the given [token].
-   */
+  /// Set the token representing the literal to the given [token].
   void set literal(Token token);
 
-  /**
-   * Return the value of the literal.
-   */
+  /// Return the value of the literal.
   String get value;
 
-  /**
-   * Set the value of the literal to the given [string].
-   */
+  /// Set the value of the literal to the given [string].
   void set value(String string);
 }
 
-/**
- * A single string literal expression.
- *
- *    singleStringLiteral ::=
- *        [SimpleStringLiteral]
- *      | [StringInterpolation]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SingleStringLiteral extends StringLiteral {
-  /**
-   * Return the offset of the after-last contents character.
-   */
+/// A single string literal expression.
+///
+///    singleStringLiteral ::=
+///        [SimpleStringLiteral]
+///      | [StringInterpolation]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SingleStringLiteral implements StringLiteral {
+  /// Return the offset of the after-last contents character.
   int get contentsEnd;
 
-  /**
-   * Return the offset of the first contents character.
-   * If the string is multiline, then leading whitespaces are skipped.
-   */
+  /// Return the offset of the first contents character. If the string is
+  /// multiline, then leading whitespaces are skipped.
   int get contentsOffset;
 
-  /**
-   * Return `true` if this string literal is a multi-line string.
-   */
+  /// Return `true` if this string literal is a multi-line string.
   bool get isMultiline;
 
-  /**
-   * Return `true` if this string literal is a raw string.
-   */
+  /// Return `true` if this string literal is a raw string.
   bool get isRaw;
 
-  /**
-   * Return `true` if this string literal uses single quotes (' or ''').
-   * Return `false` if this string literal uses double quotes (" or """).
-   */
+  /// Return `true` if this string literal uses single quotes (' or '''), or
+  /// `false` if this string literal uses double quotes (" or """).
   bool get isSingleQuoted;
 }
 
-/**
- * A node that represents a statement.
- *
- *    statement ::=
- *        [Block]
- *      | [VariableDeclarationStatement]
- *      | [ForStatement]
- *      | [ForEachStatement]
- *      | [WhileStatement]
- *      | [DoStatement]
- *      | [SwitchStatement]
- *      | [IfStatement]
- *      | [TryStatement]
- *      | [BreakStatement]
- *      | [ContinueStatement]
- *      | [ReturnStatement]
- *      | [ExpressionStatement]
- *      | [FunctionDeclarationStatement]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class Statement extends AstNode {
-  /**
-   * If this is a labeled statement, return the unlabeled portion of the
-   * statement, otherwise return the statement itself.
-   */
+/// A spread element.
+///
+///    spreadElement:
+///        ( '...' | '...?' ) [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SpreadElement implements CollectionElement {
+  /// The expression used to compute the collection being spread.
+  Expression get expression;
+
+  /// The spread operator, either '...' or '...?'.
+  Token get spreadOperator;
+}
+
+/// A node that represents a statement.
+///
+///    statement ::=
+///        [Block]
+///      | [VariableDeclarationStatement]
+///      | [ForStatement]
+///      | [ForEachStatement]
+///      | [WhileStatement]
+///      | [DoStatement]
+///      | [SwitchStatement]
+///      | [IfStatement]
+///      | [TryStatement]
+///      | [BreakStatement]
+///      | [ContinueStatement]
+///      | [ReturnStatement]
+///      | [ExpressionStatement]
+///      | [FunctionDeclarationStatement]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class Statement implements AstNode {
+  /// If this is a labeled statement, return the unlabeled portion of the
+  /// statement, otherwise return the statement itself.
   Statement get unlabeled;
 }
 
-/**
- * A string interpolation literal.
- *
- *    stringInterpolation ::=
- *        ''' [InterpolationElement]* '''
- *      | '"' [InterpolationElement]* '"'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class StringInterpolation extends SingleStringLiteral {
-  /**
-   * Return the elements that will be composed to produce the resulting string.
-   */
+/// A string interpolation literal.
+///
+///    stringInterpolation ::=
+///        ''' [InterpolationElement]* '''
+///      | '"' [InterpolationElement]* '"'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class StringInterpolation implements SingleStringLiteral {
+  /// Return the elements that will be composed to produce the resulting string.
   NodeList<InterpolationElement> get elements;
 }
 
-/**
- * A string literal expression.
- *
- *    stringLiteral ::=
- *        [SimpleStringLiteral]
- *      | [AdjacentStrings]
- *      | [StringInterpolation]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class StringLiteral extends Literal {
-  /**
-   * Return the value of the string literal, or `null` if the string is not a
-   * constant string without any string interpolation.
-   */
+/// A string literal expression.
+///
+///    stringLiteral ::=
+///        [SimpleStringLiteral]
+///      | [AdjacentStrings]
+///      | [StringInterpolation]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class StringLiteral implements Literal {
+  /// Return the value of the string literal, or `null` if the string is not a
+  /// constant string without any string interpolation.
   String get stringValue;
 }
 
-/**
- * The invocation of a superclass' constructor from within a constructor's
- * initialization list.
- *
- *    superInvocation ::=
- *        'super' ('.' [SimpleIdentifier])? [ArgumentList]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SuperConstructorInvocation extends ConstructorInitializer
-    implements ConstructorReferenceNode {
-  /**
-   * Return the list of arguments to the constructor.
-   */
+/// The invocation of a superclass' constructor from within a constructor's
+/// initialization list.
+///
+///    superInvocation ::=
+///        'super' ('.' [SimpleIdentifier])? [ArgumentList]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SuperConstructorInvocation
+    implements ConstructorInitializer, ConstructorReferenceNode {
+  /// Return the list of arguments to the constructor.
   ArgumentList get argumentList;
 
-  /**
-   * Set the list of arguments to the constructor to the given [argumentList].
-   */
+  /// Set the list of arguments to the constructor to the given [argumentList].
   void set argumentList(ArgumentList argumentList);
 
-  /**
-   * Return the name of the constructor that is being invoked, or `null` if the
-   * unnamed constructor is being invoked.
-   */
+  /// Return the name of the constructor that is being invoked, or `null` if the
+  /// unnamed constructor is being invoked.
   SimpleIdentifier get constructorName;
 
-  /**
-   * Set the name of the constructor that is being invoked to the given
-   * [identifier].
-   */
+  /// Set the name of the constructor that is being invoked to the given
+  /// [identifier].
   void set constructorName(SimpleIdentifier identifier);
 
-  /**
-   * Return the token for the period before the name of the constructor that is
-   * being invoked, or `null` if the unnamed constructor is being invoked.
-   */
+  /// Return the token for the period before the name of the constructor that is
+  /// being invoked, or `null` if the unnamed constructor is being invoked.
   Token get period;
 
-  /**
-   * Set the token for the period before the name of the constructor that is
-   * being invoked to the given [token].
-   */
+  /// Set the token for the period before the name of the constructor that is
+  /// being invoked to the given [token].
   void set period(Token token);
 
-  /**
-   * Return the token for the 'super' keyword.
-   */
+  /// Return the token for the 'super' keyword.
   Token get superKeyword;
 
-  /**
-   * Set the token for the 'super' keyword to the given [token].
-   */
+  /// Set the token for the 'super' keyword to the given [token].
   void set superKeyword(Token token);
 }
 
-/**
- * A super expression.
- *
- *    superExpression ::=
- *        'super'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SuperExpression extends Expression {
-  /**
-   * Return the token representing the 'super' keyword.
-   */
+/// A super expression.
+///
+///    superExpression ::=
+///        'super'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SuperExpression implements Expression {
+  /// Return the token representing the 'super' keyword.
   Token get superKeyword;
 
-  /**
-   * Set the token representing the 'super' keyword to the given [token].
-   */
+  /// Set the token representing the 'super' keyword to the given [token].
   void set superKeyword(Token token);
 }
 
-/**
- * A case in a switch statement.
- *
- *    switchCase ::=
- *        [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SwitchCase extends SwitchMember {
-  /**
-   * Return the expression controlling whether the statements will be executed.
-   */
+/// A case in a switch statement.
+///
+///    switchCase ::=
+///        [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SwitchCase implements SwitchMember {
+  /// Return the expression controlling whether the statements will be executed.
   Expression get expression;
 
-  /**
-   * Set the expression controlling whether the statements will be executed to
-   * the given [expression].
-   */
+  /// Set the expression controlling whether the statements will be executed to
+  /// the given [expression].
   void set expression(Expression expression);
 }
 
-/**
- * The default case in a switch statement.
- *
- *    switchDefault ::=
- *        [SimpleIdentifier]* 'default' ':' [Statement]*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SwitchDefault extends SwitchMember {}
+/// The default case in a switch statement.
+///
+///    switchDefault ::=
+///        [SimpleIdentifier]* 'default' ':' [Statement]*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SwitchDefault implements SwitchMember {}
 
-/**
- * An element within a switch statement.
- *
- *    switchMember ::=
- *        switchCase
- *      | switchDefault
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SwitchMember extends AstNode {
-  /**
-   * Return the colon separating the keyword or the expression from the
-   * statements.
-   */
+/// An element within a switch statement.
+///
+///    switchMember ::=
+///        switchCase
+///      | switchDefault
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SwitchMember implements AstNode {
+  /// Return the colon separating the keyword or the expression from the
+  /// statements.
   Token get colon;
 
-  /**
-   * Set the colon separating the keyword or the expression from the
-   * statements to the given [token].
-   */
+  /// Set the colon separating the keyword or the expression from the
+  /// statements to the given [token].
   void set colon(Token token);
 
-  /**
-   * Return the token representing the 'case' or 'default' keyword.
-   */
+  /// Return the token representing the 'case' or 'default' keyword.
   Token get keyword;
 
-  /**
-   * Set the token representing the 'case' or 'default' keyword to the given
-   * [token].
-   */
+  /// Set the token representing the 'case' or 'default' keyword to the given
+  /// [token].
   void set keyword(Token token);
 
-  /**
-   * Return the labels associated with the switch member.
-   */
+  /// Return the labels associated with the switch member.
   NodeList<Label> get labels;
 
-  /**
-   * Return the statements that will be executed if this switch member is
-   * selected.
-   */
+  /// Return the statements that will be executed if this switch member is
+  /// selected.
   NodeList<Statement> get statements;
 }
 
-/**
- * A switch statement.
- *
- *    switchStatement ::=
- *        'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SwitchStatement extends Statement {
-  /**
-   * Return the expression used to determine which of the switch members will be
-   * selected.
-   */
+/// A switch statement.
+///
+///    switchStatement ::=
+///        'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SwitchStatement implements Statement {
+  /// Return the expression used to determine which of the switch members will
+  /// be selected.
   Expression get expression;
 
-  /**
-   * Set the expression used to determine which of the switch members will be
-   * selected to the given [expression].
-   */
+  /// Set the expression used to determine which of the switch members will be
+  /// selected to the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the left curly bracket.
-   */
+  /// Return the left curly bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left curly bracket to the given [token].
-   */
+  /// Set the left curly bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the switch members that can be selected by the expression.
-   */
+  /// Return the switch members that can be selected by the expression.
   NodeList<SwitchMember> get members;
 
-  /**
-   * Return the right curly bracket.
-   */
+  /// Return the right curly bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right curly bracket to the given [token].
-   */
+  /// Set the right curly bracket to the given [token].
   void set rightBracket(Token token);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 
-  /**
-   * Return the token representing the 'switch' keyword.
-   */
+  /// Return the token representing the 'switch' keyword.
   Token get switchKeyword;
 
-  /**
-   * Set the token representing the 'switch' keyword to the given [token].
-   */
+  /// Set the token representing the 'switch' keyword to the given [token].
   void set switchKeyword(Token token);
 }
 
-/**
- * A symbol literal expression.
- *
- *    symbolLiteral ::=
- *        '#' (operator | (identifier ('.' identifier)*))
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class SymbolLiteral extends Literal {
-  /**
-   * Return the components of the literal.
-   */
+/// A symbol literal expression.
+///
+///    symbolLiteral ::=
+///        '#' (operator | (identifier ('.' identifier)*))
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class SymbolLiteral implements Literal {
+  /// Return the components of the literal.
   List<Token> get components;
 
-  /**
-   * Return the token introducing the literal.
-   */
+  /// Return the token introducing the literal.
   Token get poundSign;
 
-  /**
-   * Set the token introducing the literal to the given [token].
-   */
+  /// Set the token introducing the literal to the given [token].
   void set poundSign(Token token);
 }
 
-/**
- * A this expression.
- *
- *    thisExpression ::=
- *        'this'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ThisExpression extends Expression {
-  /**
-   * Return the token representing the 'this' keyword.
-   */
+/// A this expression.
+///
+///    thisExpression ::=
+///        'this'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ThisExpression implements Expression {
+  /// Return the token representing the 'this' keyword.
   Token get thisKeyword;
 
-  /**
-   * Set the token representing the 'this' keyword to the given [token].
-   */
+  /// Set the token representing the 'this' keyword to the given [token].
   void set thisKeyword(Token token);
 }
 
-/**
- * A throw expression.
- *
- *    throwExpression ::=
- *        'throw' [Expression]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class ThrowExpression extends Expression {
-  /**
-   * Return the expression computing the exception to be thrown.
-   */
+/// A throw expression.
+///
+///    throwExpression ::=
+///        'throw' [Expression]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class ThrowExpression implements Expression {
+  /// Return the expression computing the exception to be thrown.
   Expression get expression;
 
-  /**
-   * Set the expression computing the exception to be thrown to the given
-   * [expression].
-   */
+  /// Set the expression computing the exception to be thrown to the given
+  /// [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the token representing the 'throw' keyword.
-   */
+  /// Return the token representing the 'throw' keyword.
   Token get throwKeyword;
 
-  /**
-   * Set the token representing the 'throw' keyword to the given [token].
-   */
+  /// Set the token representing the 'throw' keyword to the given [token].
   void set throwKeyword(Token token);
 }
 
-/**
- * The declaration of one or more top-level variables of the same type.
- *
- *    topLevelVariableDeclaration ::=
- *        ('final' | 'const') type? staticFinalDeclarationList ';'
- *      | variableDeclaration ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TopLevelVariableDeclaration extends CompilationUnitMember {
-  /**
-   * Return the semicolon terminating the declaration.
-   */
+/// The declaration of one or more top-level variables of the same type.
+///
+///    topLevelVariableDeclaration ::=
+///        ('final' | 'const') type? staticFinalDeclarationList ';'
+///      | variableDeclaration ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TopLevelVariableDeclaration implements CompilationUnitMember {
+  /// Return the semicolon terminating the declaration.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the declaration to the given [token].
-   */
+  /// Set the semicolon terminating the declaration to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the top-level variables being declared.
-   */
+  /// Return the top-level variables being declared.
   VariableDeclarationList get variables;
 
-  /**
-   * Set the top-level variables being declared to the given list of
-   * [variables].
-   */
+  /// Set the top-level variables being declared to the given list of
+  /// [variables].
   void set variables(VariableDeclarationList variables);
 }
 
-/**
- * A try statement.
- *
- *    tryStatement ::=
- *        'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)
- *
- *    finallyClause ::=
- *        'finally' [Block]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TryStatement extends Statement {
-  /**
-   * Return the body of the statement.
-   */
+/// A try statement.
+///
+///    tryStatement ::=
+///        'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)
+///
+///    finallyClause ::=
+///        'finally' [Block]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TryStatement implements Statement {
+  /// Return the body of the statement.
   Block get body;
 
-  /**
-   * Set the body of the statement to the given [block].
-   */
+  /// Set the body of the statement to the given [block].
   void set body(Block block);
 
-  /**
-   * Return the catch clauses contained in the try statement.
-   */
+  /// Return the catch clauses contained in the try statement.
   NodeList<CatchClause> get catchClauses;
 
-  /**
-   * Return the finally block contained in the try statement, or `null` if the
-   * statement does not contain a finally clause.
-   */
+  /// Return the finally block contained in the try statement, or `null` if the
+  /// statement does not contain a finally clause.
   Block get finallyBlock;
 
-  /**
-   * Set the finally block contained in the try statement to the given [block].
-   */
+  /// Set the finally block contained in the try statement to the given [block].
   void set finallyBlock(Block block);
 
-  /**
-   * Return the token representing the 'finally' keyword, or `null` if the
-   * statement does not contain a finally clause.
-   */
+  /// Return the token representing the 'finally' keyword, or `null` if the
+  /// statement does not contain a finally clause.
   Token get finallyKeyword;
 
-  /**
-   * Set the token representing the 'finally' keyword to the given [token].
-   */
+  /// Set the token representing the 'finally' keyword to the given [token].
   void set finallyKeyword(Token token);
 
-  /**
-   * Return the token representing the 'try' keyword.
-   */
+  /// Return the token representing the 'try' keyword.
   Token get tryKeyword;
 
-  /**
-   * Set the token representing the 'try' keyword to the given [token].
-   */
+  /// Set the token representing the 'try' keyword to the given [token].
   void set tryKeyword(Token token);
 }
 
-/**
- * The declaration of a type alias.
- *
- *    typeAlias ::=
- *        'typedef' typeAliasBody
- *
- *    typeAliasBody ::=
- *        classTypeAlias
- *      | functionTypeAlias
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypeAlias extends NamedCompilationUnitMember {
-  /**
-   * Return the semicolon terminating the declaration.
-   */
+/// The declaration of a type alias.
+///
+///    typeAlias ::=
+///        'typedef' typeAliasBody
+///
+///    typeAliasBody ::=
+///        classTypeAlias
+///      | functionTypeAlias
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypeAlias implements NamedCompilationUnitMember {
+  /// Return the semicolon terminating the declaration.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the declaration to the given [token].
-   */
+  /// Set the semicolon terminating the declaration to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the token representing the 'typedef' keyword.
-   */
+  /// Return the token representing the 'typedef' keyword.
   Token get typedefKeyword;
 
-  /**
-   * Set the token representing the 'typedef' keyword to the given [token].
-   */
+  /// Set the token representing the 'typedef' keyword to the given [token].
   void set typedefKeyword(Token token);
 }
 
-/**
- * A type annotation.
- *
- *    type ::=
- *        [NamedType]
- *      | [GenericFunctionType]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypeAnnotation extends AstNode {
-  /**
-   * Return the type being named, or `null` if the AST structure has not been
-   * resolved.
-   */
+/// A type annotation.
+///
+///    type ::=
+///        [NamedType]
+///      | [GenericFunctionType]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypeAnnotation implements AstNode {
+  /// The question mark indicating that the type is nullable, or `null` if there
+  /// is no question mark.
+  Token get question;
+
+  /// Return the type being named, or `null` if the AST structure has not been
+  /// resolved.
   DartType get type;
 }
 
-/**
- * A list of type arguments.
- *
- *    typeArguments ::=
- *        '<' typeName (',' typeName)* '>'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypeArgumentList extends AstNode {
-  /**
-   * Return the type arguments associated with the type.
-   */
+/// A list of type arguments.
+///
+///    typeArguments ::=
+///        '<' typeName (',' typeName)* '>'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypeArgumentList implements AstNode {
+  /// Return the type arguments associated with the type.
   NodeList<TypeAnnotation> get arguments;
 
-  /**
-   * Return the left bracket.
-   */
+  /// Return the left bracket.
   Token get leftBracket;
 
-  /**
-   * Set the left bracket to the given [token].
-   */
+  /// Set the left bracket to the given [token].
   void set leftBracket(Token token);
 
-  /**
-   * Return the right bracket.
-   */
+  /// Return the right bracket.
   Token get rightBracket;
 
-  /**
-   * Set the right bracket to the given [token].
-   */
+  /// Set the right bracket to the given [token].
   void set rightBracket(Token token);
 }
 
-/**
- * A literal that has a type associated with it.
- *
- *    typedLiteral ::=
- *        [ListLiteral]
- *      | [MapLiteral]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypedLiteral extends Literal {
-  /**
-   * Return the token representing the 'const' keyword, or `null` if the literal
-   * is not a constant.
-   */
+/// A literal that has a type associated with it.
+///
+///    typedLiteral ::=
+///        [ListLiteral]
+///      | [MapLiteral]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypedLiteral implements Literal {
+  /// Return the token representing the 'const' keyword, or `null` if the
+  /// literal is not a constant.
   Token get constKeyword;
 
-  /**
-   * Set the token representing the 'const' keyword to the given [token].
-   */
+  /// Set the token representing the 'const' keyword to the given [token].
   void set constKeyword(Token token);
 
-  /**
-   * Return `true` if this literal is a constant expression, either because the
-   * keyword `const` was explicitly provided or because no keyword was provided
-   * and this expression is in a constant context.
-   */
+  /// Return `true` if this literal is a constant expression, either because the
+  /// keyword `const` was explicitly provided or because no keyword was provided
+  /// and this expression is in a constant context.
   bool get isConst;
 
-  /**
-   * Return the type argument associated with this literal, or `null` if no type
-   * arguments were declared.
-   */
+  /// Return the type argument associated with this literal, or `null` if no
+  /// type arguments were declared.
   TypeArgumentList get typeArguments;
 
-  /**
-   * Set the type argument associated with this literal to the given
-   * [typeArguments].
-   */
+  /// Set the type argument associated with this literal to the given
+  /// [typeArguments].
   void set typeArguments(TypeArgumentList typeArguments);
 }
 
-/**
- * The name of a type, which can optionally include type arguments.
- *
- *    typeName ::=
- *        [Identifier] typeArguments?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypeName extends NamedType {}
+/// The name of a type, which can optionally include type arguments.
+///
+///    typeName ::=
+///        [Identifier] typeArguments?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypeName implements NamedType {}
 
-/**
- * A type parameter.
- *
- *    typeParameter ::=
- *        [SimpleIdentifier] ('extends' [TypeAnnotation])?
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypeParameter extends Declaration {
-  /**
-   * Return the upper bound for legal arguments, or `null` if there is no
-   * explicit upper bound.
-   */
+/// A type parameter.
+///
+///    typeParameter ::=
+///        [SimpleIdentifier] ('extends' [TypeAnnotation])?
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypeParameter implements Declaration {
+  /// Return the upper bound for legal arguments, or `null` if there is no
+  /// explicit upper bound.
   TypeAnnotation get bound;
 
-  /**
-   * Set the upper bound for legal arguments to the given [type].
-   */
+  /// Set the upper bound for legal arguments to the given [type].
   void set bound(TypeAnnotation type);
 
-  /**
-   * Return the token representing the 'extends' keyword, or `null` if there is
-   * no explicit upper bound.
-   */
+  /// Return the token representing the 'extends' keyword, or `null` if there is
+  /// no explicit upper bound.
   Token get extendsKeyword;
 
-  /**
-   * Set the token representing the 'extends' keyword to the given [token].
-   */
+  /// Set the token representing the 'extends' keyword to the given [token].
   void set extendsKeyword(Token token);
 
-  /**
-   * Return the name of the type parameter.
-   */
+  /// Return the name of the type parameter.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the type parameter to the given [identifier].
-   */
+  /// Set the name of the type parameter to the given [identifier].
   void set name(SimpleIdentifier identifier);
 }
 
-/**
- * Type parameters within a declaration.
- *
- *    typeParameterList ::=
- *        '<' [TypeParameter] (',' [TypeParameter])* '>'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class TypeParameterList extends AstNode {
-  /**
-   * Return the left angle bracket.
-   */
+/// Type parameters within a declaration.
+///
+///    typeParameterList ::=
+///        '<' [TypeParameter] (',' [TypeParameter])* '>'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class TypeParameterList implements AstNode {
+  /// Return the left angle bracket.
   Token get leftBracket;
 
-  /**
-   * Return the right angle bracket.
-   */
+  /// Return the right angle bracket.
   Token get rightBracket;
 
-  /**
-   * Return the type parameters for the type.
-   */
+  /// Return the type parameters for the type.
   NodeList<TypeParameter> get typeParameters;
 }
 
-/**
- * A directive that references a URI.
- *
- *    uriBasedDirective ::=
- *        [ExportDirective]
- *      | [ImportDirective]
- *      | [PartDirective]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class UriBasedDirective extends Directive {
-  /**
-   * Return the source to which the URI was resolved.
-   */
+/// A directive that references a URI.
+///
+///    uriBasedDirective ::=
+///        [ExportDirective]
+///      | [ImportDirective]
+///      | [PartDirective]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class UriBasedDirective implements Directive {
+  /// Return the source to which the URI was resolved.
   @deprecated
   Source get source;
 
-  /**
-   * Set the source to which the URI was resolved to the given [source].
-   */
+  /// Set the source to which the URI was resolved to the given [source].
   @deprecated
   void set source(Source source);
 
-  /**
-   * Return the URI referenced by this directive.
-   */
+  /// Return the URI referenced by this directive.
   StringLiteral get uri;
 
-  /**
-   * Set the URI referenced by this directive to the given [uri].
-   */
+  /// Set the URI referenced by this directive to the given [uri].
   void set uri(StringLiteral uri);
 
-  /**
-   * Return the content of the [uri].
-   */
+  /// Return the content of the [uri].
   String get uriContent;
 
-  /**
-   * Set the content of the [uri] to the given [content].
-   */
+  /// Set the content of the [uri] to the given [content].
   void set uriContent(String content);
 
-  /**
-   * Return the element associated with the [uri] of this directive, or `null`
-   * if the AST structure has not been resolved or if the URI could not be
-   * resolved. Examples of the latter case include a directive that contains an
-   * invalid URL or a URL that does not exist.
-   */
+  /// Return the element associated with the [uri] of this directive, or `null`
+  /// if the AST structure has not been resolved or if the URI could not be
+  /// resolved. Examples of the latter case include a directive that contains an
+  /// invalid URL or a URL that does not exist.
   Element get uriElement;
 
-  /**
-   * Return the source to which the [uri] was resolved.
-   */
+  /// Return the source to which the [uri] was resolved.
   Source get uriSource;
 
-  /**
-   * Set the source to which the [uri] was resolved to the given [source].
-   */
+  /// Set the source to which the [uri] was resolved to the given [source].
   void set uriSource(Source source);
 }
 
-/**
- * An identifier that has an initial value associated with it. Instances of this
- * class are always children of the class [VariableDeclarationList].
- *
- *    variableDeclaration ::=
- *        [SimpleIdentifier] ('=' [Expression])?
- *
- * TODO(paulberry): the grammar does not allow metadata to be associated with
- * a VariableDeclaration, and currently we don't record comments for it either.
- * Consider changing the class hierarchy so that [VariableDeclaration] does not
- * extend [Declaration].
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class VariableDeclaration extends Declaration {
+/// An identifier that has an initial value associated with it. Instances of
+/// this class are always children of the class [VariableDeclarationList].
+///
+///    variableDeclaration ::=
+///        [SimpleIdentifier] ('=' [Expression])?
+///
+/// TODO(paulberry): the grammar does not allow metadata to be associated with
+/// a VariableDeclaration, and currently we don't record comments for it either.
+/// Consider changing the class hierarchy so that [VariableDeclaration] does not
+/// extend [Declaration].
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class VariableDeclaration implements Declaration {
   @override
   VariableElement get declaredElement;
 
@@ -7066,275 +5411,186 @@
   @override
   VariableElement get element;
 
-  /**
-   * Return the equal sign separating the variable name from the initial value,
-   * or `null` if the initial value was not specified.
-   */
+  /// Return the equal sign separating the variable name from the initial value,
+  /// or `null` if the initial value was not specified.
   Token get equals;
 
-  /**
-   * Set the equal sign separating the variable name from the initial value to
-   * the given [token].
-   */
+  /// Set the equal sign separating the variable name from the initial value to
+  /// the given [token].
   void set equals(Token token);
 
-  /**
-   * Return the expression used to compute the initial value for the variable,
-   * or `null` if the initial value was not specified.
-   */
+  /// Return the expression used to compute the initial value for the variable,
+  /// or `null` if the initial value was not specified.
   Expression get initializer;
 
-  /**
-   * Set the expression used to compute the initial value for the variable to
-   * the given [expression].
-   */
+  /// Set the expression used to compute the initial value for the variable to
+  /// the given [expression].
   void set initializer(Expression expression);
 
-  /**
-   * Return `true` if this variable was declared with the 'const' modifier.
-   */
+  /// Return `true` if this variable was declared with the 'const' modifier.
   bool get isConst;
 
-  /**
-   * Return `true` if this variable was declared with the 'final' modifier.
-   * Variables that are declared with the 'const' modifier will return `false`
-   * even though they are implicitly final.
-   */
+  /// Return `true` if this variable was declared with the 'final' modifier.
+  /// Variables that are declared with the 'const' modifier will return `false`
+  /// even though they are implicitly final.
   bool get isFinal;
 
-  /**
-   * Return the name of the variable being declared.
-   */
+  /// Return the name of the variable being declared.
   SimpleIdentifier get name;
 
-  /**
-   * Set the name of the variable being declared to the given [identifier].
-   */
+  /// Set the name of the variable being declared to the given [identifier].
   void set name(SimpleIdentifier identifier);
 }
 
-/**
- * The declaration of one or more variables of the same type.
- *
- *    variableDeclarationList ::=
- *        finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*
- *
- *    finalConstVarOrType ::=
- *      | 'final' [TypeAnnotation]?
- *      | 'const' [TypeAnnotation]?
- *      | 'var'
- *      | [TypeAnnotation]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class VariableDeclarationList extends AnnotatedNode {
-  /**
-   * Return `true` if the variables in this list were declared with the 'const'
-   * modifier.
-   */
+/// The declaration of one or more variables of the same type.
+///
+///    variableDeclarationList ::=
+///        finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*
+///
+///    finalConstVarOrType ::=
+///      | 'final' [TypeAnnotation]?
+///      | 'const' [TypeAnnotation]?
+///      | 'var'
+///      | [TypeAnnotation]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class VariableDeclarationList implements AnnotatedNode {
+  /// Return `true` if the variables in this list were declared with the 'const'
+  /// modifier.
   bool get isConst;
 
-  /**
-   * Return `true` if the variables in this list were declared with the 'final'
-   * modifier. Variables that are declared with the 'const' modifier will return
-   * `false` even though they are implicitly final. (In other words, this is a
-   * syntactic check rather than a semantic check.)
-   */
+  /// Return `true` if the variables in this list were declared with the 'final'
+  /// modifier. Variables that are declared with the 'const' modifier will
+  /// return `false` even though they are implicitly final. (In other words,
+  /// this is a syntactic check rather than a semantic check.)
   bool get isFinal;
 
-  /**
-   * Return the token representing the 'final', 'const' or 'var' keyword, or
-   * `null` if no keyword was included.
-   */
+  /// Return the token representing the 'final', 'const' or 'var' keyword, or
+  /// `null` if no keyword was included.
   Token get keyword;
 
-  /**
-   * Set the token representing the 'final', 'const' or 'var' keyword to the
-   * given [token].
-   */
+  /// Set the token representing the 'final', 'const' or 'var' keyword to the
+  /// given [token].
   void set keyword(Token token);
 
-  /**
-   * Return the type of the variables being declared, or `null` if no type was
-   * provided.
-   */
+  /// Return the type of the variables being declared, or `null` if no type was
+  /// provided.
   TypeAnnotation get type;
 
-  /**
-   * Set the type of the variables being declared to the given [type].
-   */
+  /// Set the type of the variables being declared to the given [type].
   void set type(TypeAnnotation type);
 
-  /**
-   * Return a list containing the individual variables being declared.
-   */
+  /// Return a list containing the individual variables being declared.
   NodeList<VariableDeclaration> get variables;
 }
 
-/**
- * A list of variables that are being declared in a context where a statement is
- * required.
- *
- *    variableDeclarationStatement ::=
- *        [VariableDeclarationList] ';'
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class VariableDeclarationStatement extends Statement {
-  /**
-   * Return the semicolon terminating the statement.
-   */
+/// A list of variables that are being declared in a context where a statement
+/// is required.
+///
+///    variableDeclarationStatement ::=
+///        [VariableDeclarationList] ';'
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class VariableDeclarationStatement implements Statement {
+  /// Return the semicolon terminating the statement.
   Token get semicolon;
 
-  /**
-   * Set the semicolon terminating the statement to the given [token].
-   */
+  /// Set the semicolon terminating the statement to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the variables being declared.
-   */
+  /// Return the variables being declared.
   VariableDeclarationList get variables;
 
-  /**
-   * Set the variables being declared to the given list of [variables].
-   */
+  /// Set the variables being declared to the given list of [variables].
   void set variables(VariableDeclarationList variables);
 }
 
-/**
- * A while statement.
- *
- *    whileStatement ::=
- *        'while' '(' [Expression] ')' [Statement]
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class WhileStatement extends Statement {
-  /**
-   * Return the body of the loop.
-   */
+/// A while statement.
+///
+///    whileStatement ::=
+///        'while' '(' [Expression] ')' [Statement]
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class WhileStatement implements Statement {
+  /// Return the body of the loop.
   Statement get body;
 
-  /**
-   * Set the body of the loop to the given [statement].
-   */
+  /// Set the body of the loop to the given [statement].
   void set body(Statement statement);
 
-  /**
-   * Return the expression used to determine whether to execute the body of the
-   * loop.
-   */
+  /// Return the expression used to determine whether to execute the body of the
+  /// loop.
   Expression get condition;
 
-  /**
-   * Set the expression used to determine whether to execute the body of the
-   * loop to the given [expression].
-   */
+  /// Set the expression used to determine whether to execute the body of the
+  /// loop to the given [expression].
   void set condition(Expression expression);
 
-  /**
-   * Return the left parenthesis.
-   */
+  /// Return the left parenthesis.
   Token get leftParenthesis;
 
-  /**
-   * Set the left parenthesis to the given [token].
-   */
+  /// Set the left parenthesis to the given [token].
   void set leftParenthesis(Token token);
 
-  /**
-   * Return the right parenthesis.
-   */
+  /// Return the right parenthesis.
   Token get rightParenthesis;
 
-  /**
-   * Set the right parenthesis to the given [token].
-   */
+  /// Set the right parenthesis to the given [token].
   void set rightParenthesis(Token token);
 
-  /**
-   * Return the token representing the 'while' keyword.
-   */
+  /// Return the token representing the 'while' keyword.
   Token get whileKeyword;
 
-  /**
-   * Set the token representing the 'while' keyword to the given [token].
-   */
+  /// Set the token representing the 'while' keyword to the given [token].
   void set whileKeyword(Token token);
 }
 
-/**
- * The with clause in a class declaration.
- *
- *    withClause ::=
- *        'with' [TypeName] (',' [TypeName])*
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class WithClause extends AstNode {
-  /**
-   * Return the names of the mixins that were specified.
-   */
+/// The with clause in a class declaration.
+///
+///    withClause ::=
+///        'with' [TypeName] (',' [TypeName])*
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class WithClause implements AstNode {
+  /// Return the names of the mixins that were specified.
   NodeList<TypeName> get mixinTypes;
 
-  /**
-   * Return the token representing the 'with' keyword.
-   */
+  /// Return the token representing the 'with' keyword.
   Token get withKeyword;
 
-  /**
-   * Set the token representing the 'with' keyword to the given [token].
-   */
+  /// Set the token representing the 'with' keyword to the given [token].
   void set withKeyword(Token token);
 }
 
-/**
- * A yield statement.
- *
- *    yieldStatement ::=
- *        'yield' '*'? [Expression] ‘;’
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class YieldStatement extends Statement {
-  /**
-   * Return the expression whose value will be yielded.
-   */
+/// A yield statement.
+///
+///    yieldStatement ::=
+///        'yield' '*'? [Expression] ‘;’
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class YieldStatement implements Statement {
+  /// Return the expression whose value will be yielded.
   Expression get expression;
 
-  /**
-   * Set the expression whose value will be yielded to the given [expression].
-   */
+  /// Set the expression whose value will be yielded to the given [expression].
   void set expression(Expression expression);
 
-  /**
-   * Return the semicolon following the expression.
-   */
+  /// Return the semicolon following the expression.
   Token get semicolon;
 
-  /**
-   * Return the semicolon following the expression to the given [token].
-   */
+  /// Return the semicolon following the expression to the given [token].
   void set semicolon(Token token);
 
-  /**
-   * Return the star optionally following the 'yield' keyword.
-   */
+  /// Return the star optionally following the 'yield' keyword.
   Token get star;
 
-  /**
-   * Return the star optionally following the 'yield' keyword to the given [token].
-   */
+  /// Return the star optionally following the 'yield' keyword to the given
+  /// [token].
   void set star(Token token);
 
-  /**
-   * Return the 'yield' keyword.
-   */
+  /// Return the 'yield' keyword.
   Token get yieldKeyword;
 
-  /**
-   * Return the 'yield' keyword to the given [token].
-   */
+  /// Return the 'yield' keyword to the given [token].
   void set yieldKeyword(Token token);
 }
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 1a49333..c888aac 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -384,6 +384,7 @@
       List<Configuration> configurations,
       List<Combinator> combinators,
       Token semicolon);
+
   /**
    * Returns a newly created function body consisting of a block of
    * statements. The [keyword] can be `null` if the function body is not an
@@ -474,6 +475,19 @@
       FormalParameterList parameters});
 
   /**
+   * Returns a newly created for each part that includes a declaration.
+   */
+  ForEachPartsWithDeclaration forEachPartsWithDeclaration(
+      {DeclaredIdentifier loopVariable, Token inKeyword, Expression iterable});
+
+  /**
+   * Returns a newly created for each part that includes an identifier that is
+   * declared outside of the loop.
+   */
+  ForEachPartsWithIdentifier forEachPartsWithIdentifier(
+      {SimpleIdentifier identifier, Token inKeyword, Expression iterable});
+
+  /**
    * Returns a newly created for-each statement whose loop control variable
    * is declared internally (in the for-loop part). The [awaitKeyword] can be
    * `null` if this is not an asynchronous for loop.
@@ -504,6 +518,18 @@
       Statement body);
 
   /**
+   * Returns a newly created for element that can be part of a list, map or set
+   * literal.
+   */
+  ForElement forElement(
+      {Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopParts forLoopParts,
+      Token rightParenthesis,
+      CollectionElement body});
+
+  /**
    * Returns a newly created parameter list. The list of [parameters] can be
    * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
    * can be `null` if there are no optional parameters.
@@ -516,6 +542,26 @@
       Token rightParenthesis);
 
   /**
+   * Returns a newly created for part that includes a declaration.
+   */
+  ForPartsWithDeclarations forPartsWithDeclarations(
+      {VariableDeclarationList variables,
+      Token leftSeparator,
+      Expression condition,
+      Token rightSeparator,
+      List<Expression> updaters});
+
+  /**
+   * Returns a newly created for part that includes an expression.
+   */
+  ForPartsWithExpression forPartsWithExpression(
+      {Expression initialization,
+      Token leftSeparator,
+      Expression condition,
+      Token rightSeparator,
+      List<Expression> updaters});
+
+  /**
    * Returns a newly created for statement. Either the [variableList] or the
    * [initialization] must be `null`. Either the [condition] and the list of
    * [updaters] can be `null` if the loop does not have the corresponding
@@ -534,6 +580,17 @@
       Statement body);
 
   /**
+   * Returns a newly created for statement.
+   */
+  ForStatement2 forStatement2(
+      {Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopParts forLoopParts,
+      Token rightParenthesis,
+      Statement body});
+
+  /**
    * Returns a newly created function declaration. Either or both of the
    * [comment] and [metadata] can be `null` if the function does not have the
    * corresponding attribute. The [externalKeyword] can be `null` if the
@@ -650,6 +707,19 @@
       Token keyword, List<SimpleIdentifier> hiddenNames);
 
   /**
+   * Returns a newly created if element that can be part of a list, map or set
+   * literal.
+   */
+  IfElement ifElement(
+      {Token ifKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      CollectionElement thenElement,
+      Token elseKeyword,
+      CollectionElement elseElement});
+
+  /**
    * Returns a newly created if statement. The [elseKeyword] and
    * [elseStatement] can be `null` if there is no else clause.
    */
@@ -764,6 +834,16 @@
       Token leftBracket, List<Expression> elements, Token rightBracket);
 
   /**
+   * Returns a newly created list literal.
+   */
+  ListLiteral2 listLiteral2(
+      {Token constKeyword,
+      TypeArgumentList typeArguments,
+      Token leftBracket,
+      List<CollectionElement> elements,
+      Token rightBracket});
+
+  /**
    * Returns a newly created map literal. The [constKeyword] can be `null` if
    * the literal is not a constant. The [typeArguments] can be `null` if no type
    * arguments were declared. The [entries] can be `null` if the map is empty.
@@ -772,6 +852,16 @@
       Token leftBracket, List<MapLiteralEntry> entries, Token rightBracket);
 
   /**
+   * Returns a newly created map literal.
+   */
+  MapLiteral2 mapLiteral2(
+      {Token constKeyword,
+      TypeArgumentList typeArguments,
+      Token leftBracket,
+      List<CollectionElement> entries,
+      Token rightBracket});
+
+  /**
    * Returns a newly created map literal entry.
    */
   MapLiteralEntry mapLiteralEntry(
@@ -949,6 +1039,16 @@
       Token leftBracket, List<Expression> elements, Token rightBracket);
 
   /**
+   * Returns a newly created set literal.
+   */
+  SetLiteral2 setLiteral2(
+      {Token constKeyword,
+      TypeArgumentList typeArguments,
+      Token leftBracket,
+      List<CollectionElement> elements,
+      Token rightBracket});
+
+  /**
    * Returns a newly created import show combinator.
    */
   ShowCombinator showCombinator(
@@ -995,6 +1095,11 @@
   SimpleStringLiteral simpleStringLiteral(Token literal, String value);
 
   /**
+   * Returns a newly created spread element.
+   */
+  SpreadElement spreadElement({Token spreadOperator, Expression expression});
+
+  /**
    * Returns a newly created string interpolation expression.
    */
   StringInterpolation stringInterpolation(List<InterpolationElement> elements);
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 53ff333..4c599e8 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -205,6 +205,8 @@
   @override
   R visitClassTypeAlias(ClassTypeAlias node) => visitTypeAlias(node);
 
+  R visitCollectionElement(CollectionElement node) => visitNode(node);
+
   R visitCombinator(Combinator node) => visitNode(node);
 
   @override
@@ -279,7 +281,7 @@
   @override
   R visitExportDirective(ExportDirective node) => visitNamespaceDirective(node);
 
-  R visitExpression(Expression node) => visitNode(node);
+  R visitExpression(Expression node) => visitCollectionElement(node);
 
   @override
   R visitExpressionFunctionBody(ExpressionFunctionBody node) =>
@@ -298,17 +300,43 @@
   R visitFieldFormalParameter(FieldFormalParameter node) =>
       visitNormalFormalParameter(node);
 
+  R visitForEachParts(ForEachParts node) => visitNode(node);
+
+  @override
+  R visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) =>
+      visitForEachParts(node);
+
+  @override
+  R visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) =>
+      visitForEachParts(node);
+
   @override
   R visitForEachStatement(ForEachStatement node) => visitStatement(node);
 
+  @override
+  R visitForElement(ForElement node) => visitCollectionElement(node);
+
   R visitFormalParameter(FormalParameter node) => visitNode(node);
 
   @override
   R visitFormalParameterList(FormalParameterList node) => visitNode(node);
 
+  R visitForParts(ForParts node) => visitNode(node);
+
+  @override
+  R visitForPartsWithDeclarations(ForPartsWithDeclarations node) =>
+      visitForParts(node);
+
+  @override
+  R visitForPartsWithExpression(ForPartsWithExpression node) =>
+      visitForParts(node);
+
   @override
   R visitForStatement(ForStatement node) => visitStatement(node);
 
+  @override
+  R visitForStatement2(ForStatement2 node) => visitStatement(node);
+
   R visitFunctionBody(FunctionBody node) => visitNode(node);
 
   @override
@@ -346,6 +374,9 @@
   R visitIdentifier(Identifier node) => visitExpression(node);
 
   @override
+  R visitIfElement(IfElement node) => visitCollectionElement(node);
+
+  @override
   R visitIfStatement(IfStatement node) => visitStatement(node);
 
   @override
@@ -395,13 +426,19 @@
   @override
   R visitListLiteral(ListLiteral node) => visitTypedLiteral(node);
 
+  @override
+  R visitListLiteral2(ListLiteral2 node) => visitTypedLiteral(node);
+
   R visitLiteral(Literal node) => visitExpression(node);
 
   @override
   R visitMapLiteral(MapLiteral node) => visitTypedLiteral(node);
 
   @override
-  R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
+  R visitMapLiteral2(MapLiteral2 node) => visitTypedLiteral(node);
+
+  @override
+  R visitMapLiteralEntry(MapLiteralEntry node) => visitCollectionElement(node);
 
   @override
   R visitMethodDeclaration(MethodDeclaration node) => visitClassMember(node);
@@ -483,6 +520,9 @@
   R visitSetLiteral(SetLiteral node) => visitTypedLiteral(node);
 
   @override
+  R visitSetLiteral2(SetLiteral2 node) => visitTypedLiteral(node);
+
+  @override
   R visitShowCombinator(ShowCombinator node) => visitCombinator(node);
 
   @override
@@ -499,6 +539,9 @@
   R visitSingleStringLiteral(SingleStringLiteral node) =>
       visitStringLiteral(node);
 
+  @override
+  R visitSpreadElement(SpreadElement node) => visitCollectionElement(node);
+
   R visitStatement(Statement node) => visitNode(node);
 
   @override
@@ -843,24 +886,60 @@
   }
 
   @override
+  R visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitForEachStatement(ForEachStatement node) {
     node.visitChildren(this);
     return null;
   }
 
   @override
+  R visitForElement(ForElement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitFormalParameterList(FormalParameterList node) {
     node.visitChildren(this);
     return null;
   }
 
   @override
+  R visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitForPartsWithExpression(ForPartsWithExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitForStatement(ForStatement node) {
     node.visitChildren(this);
     return null;
   }
 
   @override
+  R visitForStatement2(ForStatement2 node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitFunctionDeclaration(FunctionDeclaration node) {
     node.visitChildren(this);
     return null;
@@ -915,6 +994,12 @@
   }
 
   @override
+  R visitIfElement(IfElement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitIfStatement(IfStatement node) {
     node.visitChildren(this);
     return null;
@@ -999,12 +1084,24 @@
   }
 
   @override
+  R visitListLiteral2(ListLiteral2 node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitMapLiteral(MapLiteral node) {
     node.visitChildren(this);
     return null;
   }
 
   @override
+  R visitMapLiteral2(MapLiteral2 node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitMapLiteralEntry(MapLiteralEntry node) {
     node.visitChildren(this);
     return null;
@@ -1132,6 +1229,12 @@
   }
 
   @override
+  R visitSetLiteral2(SetLiteral2 node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitShowCombinator(ShowCombinator node) {
     node.visitChildren(this);
     return null;
@@ -1156,6 +1259,12 @@
   }
 
   @override
+  R visitSpreadElement(SpreadElement node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitStringInterpolation(StringInterpolation node) {
     node.visitChildren(this);
     return null;
@@ -1415,15 +1524,33 @@
   R visitFieldFormalParameter(FieldFormalParameter node) => null;
 
   @override
+  R visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) => null;
+
+  @override
+  R visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) => null;
+
+  @override
   R visitForEachStatement(ForEachStatement node) => null;
 
   @override
+  R visitForElement(ForElement node) => null;
+
+  @override
   R visitFormalParameterList(FormalParameterList node) => null;
 
   @override
+  R visitForPartsWithDeclarations(ForPartsWithDeclarations node) => null;
+
+  @override
+  R visitForPartsWithExpression(ForPartsWithExpression node) => null;
+
+  @override
   R visitForStatement(ForStatement node) => null;
 
   @override
+  R visitForStatement2(ForStatement2 node) => null;
+
+  @override
   R visitFunctionDeclaration(FunctionDeclaration node) => null;
 
   @override
@@ -1454,6 +1581,9 @@
   R visitHideCombinator(HideCombinator node) => null;
 
   @override
+  R visitIfElement(IfElement node) => null;
+
+  @override
   R visitIfStatement(IfStatement node) => null;
 
   @override
@@ -1496,9 +1626,15 @@
   R visitListLiteral(ListLiteral node) => null;
 
   @override
+  R visitListLiteral2(ListLiteral2 node) => null;
+
+  @override
   R visitMapLiteral(MapLiteral node) => null;
 
   @override
+  R visitMapLiteral2(MapLiteral2 node) => null;
+
+  @override
   R visitMapLiteralEntry(MapLiteralEntry node) => null;
 
   @override
@@ -1564,6 +1700,9 @@
   R visitSetLiteral(SetLiteral node) => null;
 
   @override
+  R visitSetLiteral2(SetLiteral2 node) => null;
+
+  @override
   R visitShowCombinator(ShowCombinator node) => null;
 
   @override
@@ -1576,6 +1715,9 @@
   R visitSimpleStringLiteral(SimpleStringLiteral node) => null;
 
   @override
+  R visitSpreadElement(SpreadElement node) => null;
+
+  @override
   R visitStringInterpolation(StringInterpolation node) => null;
 
   @override
@@ -1775,15 +1917,36 @@
   R visitFieldFormalParameter(FieldFormalParameter node) => _throw(node);
 
   @override
+  R visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) =>
+      _throw(node);
+
+  @override
+  R visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) =>
+      _throw(node);
+
+  @override
   R visitForEachStatement(ForEachStatement node) => _throw(node);
 
   @override
+  R visitForElement(ForElement node) => _throw(node);
+
+  @override
   R visitFormalParameterList(FormalParameterList node) => _throw(node);
 
   @override
+  R visitForPartsWithDeclarations(ForPartsWithDeclarations node) =>
+      _throw(node);
+
+  @override
+  R visitForPartsWithExpression(ForPartsWithExpression node) => _throw(node);
+
+  @override
   R visitForStatement(ForStatement node) => _throw(node);
 
   @override
+  R visitForStatement2(ForStatement2 node) => _throw(node);
+
+  @override
   R visitFunctionDeclaration(FunctionDeclaration node) => _throw(node);
 
   @override
@@ -1814,6 +1977,9 @@
   R visitHideCombinator(HideCombinator node) => _throw(node);
 
   @override
+  R visitIfElement(IfElement node) => _throw(node);
+
+  @override
   R visitIfStatement(IfStatement node) => _throw(node);
 
   @override
@@ -1857,9 +2023,15 @@
   R visitListLiteral(ListLiteral node) => _throw(node);
 
   @override
+  R visitListLiteral2(ListLiteral2 node) => _throw(node);
+
+  @override
   R visitMapLiteral(MapLiteral node) => _throw(node);
 
   @override
+  R visitMapLiteral2(MapLiteral2 node) => _throw(node);
+
+  @override
   R visitMapLiteralEntry(MapLiteralEntry node) => _throw(node);
 
   @override
@@ -1925,6 +2097,9 @@
   R visitSetLiteral(SetLiteral node) => _throw(node);
 
   @override
+  R visitSetLiteral2(SetLiteral2 node) => _throw(node);
+
+  @override
   R visitShowCombinator(ShowCombinator node) => _throw(node);
 
   @override
@@ -1937,6 +2112,9 @@
   R visitSimpleStringLiteral(SimpleStringLiteral node) => _throw(node);
 
   @override
+  R visitSpreadElement(SpreadElement node) => _throw(node);
+
+  @override
   R visitStringInterpolation(StringInterpolation node) => _throw(node);
 
   @override
@@ -2358,6 +2536,22 @@
   }
 
   @override
+  T visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForEachPartsWithDeclaration(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForEachPartsWithIdentifier(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitForEachStatement(ForEachStatement node) {
     stopwatch.start();
     T result = _baseVisitor.visitForEachStatement(node);
@@ -2366,6 +2560,14 @@
   }
 
   @override
+  T visitForElement(ForElement node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForElement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitFormalParameterList(FormalParameterList node) {
     stopwatch.start();
     T result = _baseVisitor.visitFormalParameterList(node);
@@ -2374,6 +2576,22 @@
   }
 
   @override
+  T visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForPartsWithDeclarations(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
+  T visitForPartsWithExpression(ForPartsWithExpression node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForPartsWithExpression(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitForStatement(ForStatement node) {
     stopwatch.start();
     T result = _baseVisitor.visitForStatement(node);
@@ -2382,6 +2600,14 @@
   }
 
   @override
+  T visitForStatement2(ForStatement2 node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitForStatement2(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitFunctionDeclaration(FunctionDeclaration node) {
     stopwatch.start();
     T result = _baseVisitor.visitFunctionDeclaration(node);
@@ -2454,6 +2680,14 @@
   }
 
   @override
+  T visitIfElement(IfElement node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitIfElement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitIfStatement(IfStatement node) {
     stopwatch.start();
     T result = _baseVisitor.visitIfStatement(node);
@@ -2566,6 +2800,14 @@
   }
 
   @override
+  T visitListLiteral2(ListLiteral2 node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitListLiteral2(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitMapLiteral(MapLiteral node) {
     stopwatch.start();
     T result = _baseVisitor.visitMapLiteral(node);
@@ -2574,6 +2816,14 @@
   }
 
   @override
+  T visitMapLiteral2(MapLiteral2 node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitMapLiteral2(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitMapLiteralEntry(MapLiteralEntry node) {
     stopwatch.start();
     T result = _baseVisitor.visitMapLiteralEntry(node);
@@ -2743,6 +2993,14 @@
   }
 
   @override
+  T visitSetLiteral2(SetLiteral2 node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitSetLiteral2(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitShowCombinator(ShowCombinator node) {
     stopwatch.start();
     T result = _baseVisitor.visitShowCombinator(node);
@@ -2775,6 +3033,14 @@
   }
 
   @override
+  T visitSpreadElement(SpreadElement node) {
+    stopwatch.start();
+    T result = _baseVisitor.visitSpreadElement(node);
+    stopwatch.stop();
+    return result;
+  }
+
+  @override
   T visitStringInterpolation(StringInterpolation node) {
     stopwatch.start();
     T result = _baseVisitor.visitStringInterpolation(node);
@@ -3082,15 +3348,36 @@
   R visitFieldFormalParameter(FieldFormalParameter node) => visitNode(node);
 
   @override
+  R visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) =>
+      visitNode(node);
+
+  @override
+  R visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) =>
+      visitNode(node);
+
+  @override
   R visitForEachStatement(ForEachStatement node) => visitNode(node);
 
   @override
+  R visitForElement(ForElement node) => visitNode(node);
+
+  @override
   R visitFormalParameterList(FormalParameterList node) => visitNode(node);
 
   @override
+  R visitForPartsWithDeclarations(ForPartsWithDeclarations node) =>
+      visitNode(node);
+
+  @override
+  R visitForPartsWithExpression(ForPartsWithExpression node) => visitNode(node);
+
+  @override
   R visitForStatement(ForStatement node) => visitNode(node);
 
   @override
+  R visitForStatement2(ForStatement2 node) => visitNode(node);
+
+  @override
   R visitFunctionDeclaration(FunctionDeclaration node) => visitNode(node);
 
   @override
@@ -3121,6 +3408,9 @@
   R visitHideCombinator(HideCombinator node) => visitNode(node);
 
   @override
+  R visitIfElement(IfElement node) => visitNode(node);
+
+  @override
   R visitIfStatement(IfStatement node) => visitNode(node);
 
   @override
@@ -3165,9 +3455,15 @@
   R visitListLiteral(ListLiteral node) => visitNode(node);
 
   @override
+  R visitListLiteral2(ListLiteral2 node) => visitNode(node);
+
+  @override
   R visitMapLiteral(MapLiteral node) => visitNode(node);
 
   @override
+  R visitMapLiteral2(MapLiteral2 node) => visitNode(node);
+
+  @override
   R visitMapLiteralEntry(MapLiteralEntry node) => visitNode(node);
 
   @override
@@ -3239,6 +3535,9 @@
   R visitSetLiteral(SetLiteral node) => visitNode(node);
 
   @override
+  R visitSetLiteral2(SetLiteral2 node) => visitNode(node);
+
+  @override
   R visitShowCombinator(ShowCombinator node) => visitNode(node);
 
   @override
@@ -3251,6 +3550,9 @@
   R visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
 
   @override
+  R visitSpreadElement(SpreadElement node) => visitNode(node);
+
+  @override
   R visitStringInterpolation(StringInterpolation node) => visitNode(node);
 
   @override
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 0260c07..f4ce6d91 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -54,10 +54,6 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class ClassElement
     implements TypeDefiningElement, TypeParameterizedElement {
-  /// An empty list of class elements.
-  @deprecated
-  static const List<ClassElement> EMPTY_LIST = const <ClassElement>[];
-
   /// Return a list containing all of the accessors (getters and setters)
   /// declared in this class.
   List<PropertyAccessorElement> get accessors;
@@ -365,11 +361,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class CompilationUnitElement implements Element, UriReferencedElement {
-  /// An empty list of compilation unit elements.
-  @deprecated
-  static const List<CompilationUnitElement> EMPTY_LIST =
-      const <CompilationUnitElement>[];
-
   /// Return a list containing all of the top-level accessors (getters and
   /// setters) contained in this compilation unit.
   List<PropertyAccessorElement> get accessors;
@@ -429,11 +420,6 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class ConstructorElement
     implements ClassMemberElement, ExecutableElement, ConstantEvaluationTarget {
-  /// An empty list of constructor elements.
-  @deprecated
-  static const List<ConstructorElement> EMPTY_LIST =
-      const <ConstructorElement>[];
-
   /// Return `true` if this constructor is a const constructor.
   bool get isConst;
 
@@ -712,10 +698,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ElementAnnotation implements ConstantEvaluationTarget {
-  /// An empty list of annotations.
-  @deprecated
-  static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
-
   /// Return the errors that were produced while computing a value for this
   /// annotation, or `null` if no value has been computed. If a value has been
   /// produced but no errors were generated, then the list will be empty.
@@ -998,10 +980,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ExecutableElement implements FunctionTypedElement {
-  /// An empty list of executable elements.
-  @deprecated
-  static const List<ExecutableElement> EMPTY_LIST = const <ExecutableElement>[];
-
   /// Return `true` if this executable element did not have an explicit return
   /// type specified for it in the original source. Note that if there was no
   /// explicit return type, and if the element model is fully populated, then
@@ -1044,10 +1022,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ExportElement implements Element, UriReferencedElement {
-  /// An empty list of export elements.
-  @deprecated
-  static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
-
   /// Return a list containing the combinators that were specified as part of
   /// the export directive in the order in which they were specified.
   List<NamespaceCombinator> get combinators;
@@ -1062,10 +1036,6 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class FieldElement
     implements ClassMemberElement, PropertyInducingElement {
-  /// An empty list of field elements.
-  @deprecated
-  static const List<FieldElement> EMPTY_LIST = const <FieldElement>[];
-
   /// Return `true` if this field was explicitly marked as being covariant.
   bool get isCovariant;
 
@@ -1096,10 +1066,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionElement implements ExecutableElement, LocalElement {
-  /// An empty list of function elements.
-  @deprecated
-  static const List<FunctionElement> EMPTY_LIST = const <FunctionElement>[];
-
   /// The name of the method that can be implemented by a class to allow its
   /// instances to be invoked as if they were a function.
   static final String CALL_METHOD_NAME = "call";
@@ -1129,11 +1095,6 @@
 /// Clients may not extend, implement or mix-in this class.
 abstract class FunctionTypeAliasElement
     implements FunctionTypedElement, TypeDefiningElement {
-  /// An empty array of type alias elements.
-  @deprecated
-  static List<FunctionTypeAliasElement> EMPTY_LIST =
-      new List<FunctionTypeAliasElement>(0);
-
   @override
   CompilationUnitElement get enclosingElement;
 
@@ -1201,10 +1162,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ImportElement implements Element, UriReferencedElement {
-  /// An empty list of import elements.
-  @deprecated
-  static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
-
   /// Return a list containing the combinators that were specified as part of
   /// the import directive in the order in which they were specified.
   List<NamespaceCombinator> get combinators;
@@ -1233,10 +1190,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class LabelElement implements Element {
-  /// An empty list of label elements.
-  @deprecated
-  static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
-
   @override
   ExecutableElement get enclosingElement;
 }
@@ -1245,10 +1198,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class LibraryElement implements Element {
-  /// An empty list of library elements.
-  @deprecated
-  static const List<LibraryElement> EMPTY_LIST = const <LibraryElement>[];
-
   /// Return the compilation unit that defines this library.
   CompilationUnitElement get definingCompilationUnit;
 
@@ -1367,21 +1316,12 @@
 /// A local variable.
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class LocalVariableElement implements LocalElement, VariableElement {
-  /// An empty list of field elements.
-  @deprecated
-  static const List<LocalVariableElement> EMPTY_LIST =
-      const <LocalVariableElement>[];
-}
+abstract class LocalVariableElement implements LocalElement, VariableElement {}
 
 /// An element that represents a method defined within a type.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
-  /// An empty list of method elements.
-  @deprecated
-  static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
-
   @deprecated
   @override
   MethodDeclaration computeNode();
@@ -1424,22 +1364,13 @@
 /// An object that controls how namespaces are combined.
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class NamespaceCombinator {
-  /// An empty list of namespace combinators.
-  @deprecated
-  static const List<NamespaceCombinator> EMPTY_LIST =
-      const <NamespaceCombinator>[];
-}
+abstract class NamespaceCombinator {}
 
 /// A parameter defined within an executable element.
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class ParameterElement
     implements LocalElement, VariableElement, ConstantEvaluationTarget {
-  /// An empty list of parameter elements.
-  @deprecated
-  static const List<ParameterElement> EMPTY_LIST = const <ParameterElement>[];
-
   /// Return the Dart code of the default value, or `null` if no default value.
   String get defaultValueCode;
 
@@ -1502,10 +1433,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class PrefixElement implements Element {
-  /// An empty list of prefix elements.
-  @deprecated
-  static const List<PrefixElement> EMPTY_LIST = const <PrefixElement>[];
-
   @override
   LibraryElement get enclosingElement;
 
@@ -1532,11 +1459,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class PropertyAccessorElement implements ExecutableElement {
-  /// An empty list of property accessor elements.
-  @deprecated
-  static const List<PropertyAccessorElement> EMPTY_LIST =
-      const <PropertyAccessorElement>[];
-
   /// Return the accessor representing the getter that corresponds to (has the
   /// same name as) this setter, or `null` if this accessor is not a setter or
   /// if there is no corresponding getter.
@@ -1577,11 +1499,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class PropertyInducingElement implements VariableElement {
-  /// An empty list of elements.
-  @deprecated
-  static const List<PropertyInducingElement> EMPTY_LIST =
-      const <PropertyInducingElement>[];
-
   /// Return the getter associated with this variable. If this variable was
   /// explicitly defined (is not synthetic) then the getter associated with it
   /// will be synthetic.
@@ -1623,11 +1540,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class TopLevelVariableElement implements PropertyInducingElement {
-  /// An empty list of top-level variable elements.
-  @deprecated
-  static const List<TopLevelVariableElement> EMPTY_LIST =
-      const <TopLevelVariableElement>[];
-
   @deprecated
   @override
   VariableDeclaration computeNode();
@@ -1645,11 +1557,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class TypeParameterElement implements TypeDefiningElement {
-  /// An empty list of type parameter elements.
-  @deprecated
-  static const List<TypeParameterElement> EMPTY_LIST =
-      const <TypeParameterElement>[];
-
   /// Return the type representing the bound associated with this parameter, or
   /// `null` if this parameter does not have an explicit bound.
   DartType get bound;
@@ -1709,10 +1616,6 @@
 ///
 /// Clients may not extend, implement or mix-in this class.
 abstract class VariableElement implements Element, ConstantEvaluationTarget {
-  /// An empty list of variable elements.
-  @deprecated
-  static const List<VariableElement> EMPTY_LIST = const <VariableElement>[];
-
   /// Return a representation of the value of this variable.
   ///
   /// Return `null` if either this variable was not declared with the 'const'
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index f2ddef8..19c217d 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -32,12 +32,6 @@
  */
 abstract class DartType {
   /**
-   * An empty list of types.
-   */
-  @deprecated
-  static const List<DartType> EMPTY_LIST = const <DartType>[];
-
-  /**
    * Return the name of this type as it should appear when presented to users in
    * contexts such as error messages.
    */
@@ -69,6 +63,12 @@
   bool get isDartAsyncFutureOr;
 
   /**
+   * Return `true` if this type represents the type 'bool' defined in the
+   * dart:core library.
+   */
+  bool get isDartCoreBool;
+
+  /**
    * Return `true` if this type represents the type 'Function' defined in the
    * dart:core library.
    */
@@ -356,12 +356,6 @@
  */
 abstract class InterfaceType implements ParameterizedType {
   /**
-   * An empty list of types.
-   */
-  @deprecated
-  static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
-
-  /**
    * Return a list containing all of the accessors (getters and setters)
    * declared in this type.
    */
@@ -730,12 +724,6 @@
  */
 abstract class TypeParameterType implements DartType {
   /**
-   * An empty list of type parameter types.
-   */
-  @deprecated
-  static const List<TypeParameterType> EMPTY_LIST = const <TypeParameterType>[];
-
-  /**
    * Return the type representing the bound associated with this parameter,
    * or `dynamic` if there was no explicit bound.
    */
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index fdaed1b..22efc18 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -299,6 +299,7 @@
   HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
   HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER,
   HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER,
+  HintCode.INVALID_VISIBILITY_ANNOTATION,
   HintCode.IS_DOUBLE,
   HintCode.IS_INT,
   HintCode.IS_NOT_DOUBLE,
@@ -648,6 +649,7 @@
   StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT,
   StaticWarningCode.UNDEFINED_NAMED_PARAMETER,
   StaticWarningCode.USE_OF_VOID_RESULT,
+  StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE,
   StrongModeCode.ASSIGNMENT_CAST,
   StrongModeCode.COULD_NOT_INFER,
   StrongModeCode.DOWN_CAST_COMPOSITE,
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
index b1cf472..3391264 100644
--- a/pkg/analyzer/lib/source/error_processor.dart
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/task/options.dart';
@@ -99,33 +98,7 @@
 
     // Add the strong mode processor.
     processors = processors.toList();
-    processors.add(_StrongModeTypeErrorProcessor.instance);
     return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
         orElse: () => null);
   }
 }
-
-/// In strong mode, this upgrades static type warnings to errors.
-class _StrongModeTypeErrorProcessor implements ErrorProcessor {
-  static final instance = new _StrongModeTypeErrorProcessor();
-
-  // TODO(rnystrom): As far as I know, this is only used to implement
-  // appliesTo(). Consider making it private in ErrorProcessor if possible.
-  String get code => throw new UnsupportedError(
-      "_StrongModeTypeErrorProcessor is not specific to an error code.");
-
-  @override
-  String get description => 'allStrongWarnings -> ERROR';
-
-  /// In strong mode, type warnings are upgraded to errors.
-  ErrorSeverity get severity => ErrorSeverity.ERROR;
-
-  /// Check if this processor applies to the given [error].
-  bool appliesTo(AnalysisError error) {
-    ErrorCode errorCode = error.errorCode;
-    if (errorCode is StaticWarningCode) {
-      return true;
-    }
-    return false;
-  }
-}
diff --git a/pkg/analyzer/lib/source/line_info.dart b/pkg/analyzer/lib/source/line_info.dart
index 5d0dee9..5d5be56 100644
--- a/pkg/analyzer/lib/source/line_info.dart
+++ b/pkg/analyzer/lib/source/line_info.dart
@@ -8,7 +8,7 @@
 /**
  * The location of a character represented as a line and column pair.
  */
-// ignore: deprecated_member_use
+// ignore: deprecated_member_use_from_same_package
 class CharacterLocation extends LineInfo_Location {
   // TODO(brianwilkerson) Replace the body of this class with the body of
   // LineInfo_Location and remove LineInfo_Location.
@@ -64,10 +64,10 @@
    * Return the location information for the character at the given [offset].
    *
    * A future version of this API will return a [CharacterLocation] rather than
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
    * a [LineInfo_Location].
    */
-  // ignore: deprecated_member_use
+  // ignore: deprecated_member_use_from_same_package
   LineInfo_Location getLocation(int offset) {
     var min = 0;
     var max = lineStarts.length - 1;
diff --git a/pkg/analyzer/lib/src/codegen/text_formatter.dart b/pkg/analyzer/lib/src/codegen/text_formatter.dart
deleted file mode 100644
index 0ffad91..0000000
--- a/pkg/analyzer/lib/src/codegen/text_formatter.dart
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Code for converting HTML into text, for use during code generation of
- * analyzer and analysis server.
- */
-import 'package:analyzer/src/codegen/tools.dart';
-import 'package:html/dom.dart' as dom;
-
-final RegExp whitespace = new RegExp(r'\s');
-
-/**
- * Convert the HTML in [desc] into text, word wrapping at width [width].
- *
- * If [javadocStyle] is true, then the output is compatible with Javadoc,
- * which understands certain HTML constructs.
- */
-String nodesToText(List<dom.Node> desc, int width, bool javadocStyle,
-    {bool removeTrailingNewLine: false}) {
-  _TextFormatter formatter = new _TextFormatter(width, javadocStyle);
-  return formatter.collectCode(() {
-    formatter.addAll(desc);
-    formatter.lineBreak(false);
-  }, removeTrailingNewLine: removeTrailingNewLine);
-}
-
-/**
- * Engine that transforms HTML to text.  The input HTML is processed one
- * character at a time, gathering characters into words and words into lines.
- */
-class _TextFormatter extends CodeGenerator {
-  /**
-   * Word-wrapping width.
-   */
-  final int width;
-
-  /**
-   * The word currently being gathered.
-   */
-  String word = '';
-
-  /**
-   * The line currently being gathered.
-   */
-  String line = '';
-
-  /**
-   * True if a blank line should be inserted before the next word.
-   */
-  bool verticalSpaceNeeded = false;
-
-  /**
-   * True if no text has been output yet.  This suppresses blank lines.
-   */
-  bool atStart = true;
-
-  /**
-   * True if we are processing a <pre> element, thus whitespace should be
-   * preserved.
-   */
-  bool preserveSpaces = false;
-
-  /**
-   * True if the output should be Javadoc compatible.
-   */
-  final bool javadocStyle;
-
-  _TextFormatter(this.width, this.javadocStyle);
-
-  /**
-   * Process an HTML node.
-   */
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      for (String char in node.text.split('')) {
-        if (preserveSpaces) {
-          wordBreak();
-          write(escape(char));
-        } else if (whitespace.hasMatch(char)) {
-          wordBreak();
-        } else {
-          resolveVerticalSpace();
-          word += escape(char);
-        }
-      }
-    } else if (node is dom.Element) {
-      switch (node.localName) {
-        case 'br':
-          lineBreak(false);
-          break;
-        case 'dl':
-        case 'dt':
-        case 'h1':
-        case 'h2':
-        case 'h3':
-        case 'h4':
-        case 'p':
-          lineBreak(true);
-          addAll(node.nodes);
-          lineBreak(true);
-          break;
-        case 'div':
-          lineBreak(false);
-          if (node.classes.contains('hangingIndent')) {
-            resolveVerticalSpace();
-            indentSpecial('', '        ', () {
-              addAll(node.nodes);
-              lineBreak(false);
-            });
-          } else {
-            addAll(node.nodes);
-            lineBreak(false);
-          }
-          break;
-        case 'ul':
-          lineBreak(false);
-          addAll(node.nodes);
-          lineBreak(false);
-          break;
-        case 'li':
-          lineBreak(false);
-          resolveVerticalSpace();
-          indentSpecial('- ', '  ', () {
-            addAll(node.nodes);
-            lineBreak(false);
-          });
-          break;
-        case 'dd':
-          lineBreak(true);
-          indent(() {
-            addAll(node.nodes);
-            lineBreak(true);
-          });
-          break;
-        case 'pre':
-          lineBreak(false);
-          resolveVerticalSpace();
-          if (javadocStyle) {
-            writeln('<pre>');
-          }
-          bool oldPreserveSpaces = preserveSpaces;
-          try {
-            preserveSpaces = true;
-            addAll(node.nodes);
-          } finally {
-            preserveSpaces = oldPreserveSpaces;
-          }
-          writeln();
-          if (javadocStyle) {
-            writeln('</pre>');
-          }
-          lineBreak(false);
-          break;
-        case 'a':
-        case 'b':
-        case 'body':
-        case 'html':
-        case 'i':
-        case 'span':
-        case 'tt':
-          addAll(node.nodes);
-          break;
-        case 'head':
-          break;
-        default:
-          throw new Exception('Unexpected HTML element: ${node.localName}');
-      }
-    } else {
-      throw new Exception('Unexpected HTML: $node');
-    }
-  }
-
-  /**
-   * Process a list of HTML nodes.
-   */
-  void addAll(List<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      add(node);
-    }
-  }
-
-  /**
-   * Escape the given character for HTML.
-   */
-  String escape(String char) {
-    if (javadocStyle) {
-      switch (char) {
-        case '<':
-          return '&lt;';
-        case '>':
-          return '&gt;';
-        case '&':
-          return '&amp;';
-      }
-    }
-    return char;
-  }
-
-  /**
-   * Terminate the current word and/or line, if either is in progress.
-   */
-  void lineBreak(bool gap) {
-    wordBreak();
-    if (line.isNotEmpty) {
-      writeln(line);
-      line = '';
-    }
-    if (gap && !atStart) {
-      verticalSpaceNeeded = true;
-    }
-  }
-
-  /**
-   * Insert vertical space if necessary.
-   */
-  void resolveVerticalSpace() {
-    if (verticalSpaceNeeded) {
-      writeln();
-      verticalSpaceNeeded = false;
-    }
-  }
-
-  /**
-   * Terminate the current word, if a word is in progress.
-   */
-  void wordBreak() {
-    if (word.isNotEmpty) {
-      atStart = false;
-      if (line.isNotEmpty) {
-        if (indentWidth + line.length + 1 + word.length <= width) {
-          line += ' $word';
-        } else {
-          writeln(line);
-          line = word;
-        }
-      } else {
-        line = word;
-      }
-      word = '';
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
deleted file mode 100644
index 8b4e96d..0000000
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ /dev/null
@@ -1,648 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * Tools for generating code in analyzer and analysis server.
- */
-import 'dart:async';
-import 'dart:io';
-
-import 'package:analyzer/src/codegen/html.dart';
-import 'package:analyzer/src/codegen/text_formatter.dart';
-import 'package:html/dom.dart' as dom;
-import 'package:path/path.dart';
-
-final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
-final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
-
-/**
- * Join the given strings using camelCase.  If [doCapitalize] is true, the first
- * part will be capitalized as well.
- */
-String camelJoin(List<String> parts, {bool doCapitalize: false}) {
-  List<String> upcasedParts = <String>[];
-  for (int i = 0; i < parts.length; i++) {
-    if (i == 0 && !doCapitalize) {
-      upcasedParts.add(parts[i]);
-    } else {
-      upcasedParts.add(capitalize(parts[i]));
-    }
-  }
-  return upcasedParts.join();
-}
-
-/**
- * Capitalize and return the passed String.
- */
-String capitalize(String string) {
-  return string[0].toUpperCase() + string.substring(1);
-}
-
-/**
- * Type of functions used to compute the contents of a set of generated files.
- * [pkgPath] is the path to the current package.
- */
-typedef Map<String, FileContentsComputer> DirectoryContentsComputer(
-    String pkgPath);
-
-/**
- * Type of functions used to compute the contents of a generated file.
- * [pkgPath] is the path to the current package.
- */
-typedef Future<String> FileContentsComputer(String pkgPath);
-
-/**
- * Mixin class for generating code.
- */
-class CodeGenerator {
-  _CodeGeneratorState _state;
-
-  /**
-   * Settings that specialize code generation behavior for a given
-   * programming language.
-   */
-  CodeGeneratorSettings codeGeneratorSettings = new CodeGeneratorSettings();
-
-  /**
-   * Measure the width of the current indentation level.
-   */
-  int get indentWidth => _state.nextIndent.length;
-
-  /**
-   * Execute [callback], collecting any code that is output using [write]
-   * or [writeln], and return the result as a string.
-   */
-  String collectCode(void callback(), {bool removeTrailingNewLine: false}) {
-    _CodeGeneratorState oldState = _state;
-    try {
-      _state = new _CodeGeneratorState();
-      callback();
-      var text =
-          _state.buffer.toString().replaceAll(trailingSpacesInLineRegExp, '');
-      if (!removeTrailingNewLine) {
-        return text;
-      } else {
-        return text.replaceAll(trailingWhitespaceRegExp, '');
-      }
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Generate a doc comment based on the HTML in [docs].
-   *
-   * When generating java code, the output is compatible with Javadoc, which
-   * understands certain HTML constructs.
-   */
-  void docComment(List<dom.Node> docs, {bool removeTrailingNewLine: false}) {
-    if (containsOnlyWhitespace(docs)) return;
-    if (codeGeneratorSettings.docCommentStartMarker != null)
-      writeln(codeGeneratorSettings.docCommentStartMarker);
-    int width = codeGeneratorSettings.commentLineLength;
-    bool javadocStyle = codeGeneratorSettings.languageName == 'java';
-    indentBy(codeGeneratorSettings.docCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, javadocStyle,
-          removeTrailingNewLine: removeTrailingNewLine));
-    });
-    if (codeGeneratorSettings.docCommentEndMarker != null)
-      writeln(codeGeneratorSettings.docCommentEndMarker);
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs.
-   */
-  void indent(void callback()) {
-    indentSpecial(
-        codeGeneratorSettings.indent, codeGeneratorSettings.indent, callback);
-  }
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   */
-  void indentBy(String additionalIndent, void callback()) =>
-      indentSpecial(additionalIndent, additionalIndent, callback);
-
-  /**
-   * Execute [callback], using [additionalIndent] to indent any code it outputs.
-   * The first line of output is indented by [firstAdditionalIndent] instead of
-   * [additionalIndent].
-   */
-  void indentSpecial(
-      String firstAdditionalIndent, String additionalIndent, void callback()) {
-    String oldNextIndent = _state.nextIndent;
-    String oldIndent = _state.indent;
-    try {
-      _state.nextIndent += firstAdditionalIndent;
-      _state.indent += additionalIndent;
-      callback();
-    } finally {
-      _state.nextIndent = oldNextIndent;
-      _state.indent = oldIndent;
-    }
-  }
-
-  void lineComment(List<dom.Node> docs) {
-    if (containsOnlyWhitespace(docs)) {
-      return;
-    }
-    write(codeGeneratorSettings.lineCommentLineLeader);
-    int width = codeGeneratorSettings.commentLineLength;
-    indentBy(codeGeneratorSettings.lineCommentLineLeader, () {
-      write(nodesToText(docs, width - _state.indent.length, false));
-    });
-  }
-
-  void outputHeader({bool javaStyle: false, String year = null}) {
-    String header;
-    if (codeGeneratorSettings.languageName == 'java') {
-      header = '''
-/*
- * Copyright (c) ${year ?? '2018'}, the Dart project authors. Please see the AUTHORS file
- * for details. All rights reserved. Use of this source code is governed by a
- * BSD-style license that can be found in the LICENSE file.
- *
- * This file has been automatically generated. Please do not edit it manually.
- * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
- */''';
-    } else if (codeGeneratorSettings.languageName == 'python') {
-      header = '''
-# Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-#
-# This file has been automatically generated. Please do not edit it manually.
-# To regenerate the file, use the script
-# "pkg/analysis_server/tool/spec/generate_files".
-''';
-    } else {
-      header = '''
-// Copyright (c) ${year ?? '2014'}, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-//
-// This file has been automatically generated. Please do not edit it manually.
-// To regenerate the file, use the script
-// "pkg/analysis_server/tool/spec/generate_files".
-''';
-    }
-    writeln(header.trim());
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * Controls several settings of [CodeGenerator].
- *
- * The default settings are valid for generating Java and Dart code.
- */
-class CodeGeneratorSettings {
-  /**
-   * Name of the language being generated. Lowercase.
-   */
-  String languageName;
-
-  /**
-   * Marker used in line comments.
-   */
-  String lineCommentLineLeader;
-
-  /**
-   * Start marker for doc comments.
-   */
-  String docCommentStartMarker;
-
-  /**
-   * Line leader for body lines in doc comments.
-   */
-  String docCommentLineLeader;
-
-  /**
-   * End marker for doc comments.
-   */
-  String docCommentEndMarker;
-
-  /**
-   * Line length for doc comment lines.
-   */
-  int commentLineLength;
-
-  /**
-   * String used for indenting code.
-   */
-  String indent;
-
-  CodeGeneratorSettings(
-      {this.languageName: 'java',
-      this.lineCommentLineLeader: '// ',
-      this.docCommentStartMarker: '/**',
-      this.docCommentLineLeader: ' * ',
-      this.docCommentEndMarker: ' */',
-      this.commentLineLength: 99,
-      this.indent: '  '});
-}
-
-/**
- * A utility class for invoking dartfmt.
- */
-class DartFormat {
-  static String get _dartfmtPath {
-    String binName = Platform.isWindows ? 'dartfmt.bat' : 'dartfmt';
-    for (var loc in [binName, join('dart-sdk', 'bin', binName)]) {
-      var candidatePath = join(dirname(Platform.resolvedExecutable), loc);
-      if (new File(candidatePath).existsSync()) {
-        return candidatePath;
-      }
-    }
-    throw new StateError('Could not find dartfmt executable');
-  }
-
-  static void formatFile(File file) {
-    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
-    if (result.exitCode != 0) throw result.stderr;
-  }
-
-  static String formatText(String text) {
-    File file = new File(join(Directory.systemTemp.path, 'gen.dart'));
-    file.writeAsStringSync(text);
-    ProcessResult result = Process.runSync(_dartfmtPath, ['-w', file.path]);
-    if (result.exitCode != 0) throw result.stderr;
-    return file.readAsStringSync();
-  }
-}
-
-/**
- * Abstract base class representing behaviors common to generated files and
- * generated directories.
- */
-abstract class GeneratedContent {
-  /**
-   * Check whether the [output] has the correct contents, and return true if it
-   * does.  [pkgPath] is the path to the current package.
-   */
-  Future<bool> check(String pkgPath);
-
-  /**
-   * Replace the [output] with the correct contents.  [pkgPath] is the path to
-   * the current package.
-   */
-  Future<void> generate(String pkgPath);
-
-  /**
-   * Get a [FileSystemEntity] representing the output file or directory.
-   * [pkgPath] is the path to the current package.
-   */
-  FileSystemEntity output(String pkgPath);
-
-  /**
-   * Check that all of the [targets] are up to date.  If they are not, print
-   * out a message instructing the user to regenerate them, and exit with a
-   * nonzero error code.
-   *
-   * [pkgPath] is the path to the current package.  [generatorRelPath] is the
-   * path to a .dart script the user may use to regenerate the targets.
-   *
-   * To avoid mistakes when run on Windows, [generatorRelPath] always uses
-   * POSIX directory separators.
-   */
-  static Future<void> checkAll(String pkgPath, String generatorRelPath,
-      Iterable<GeneratedContent> targets) async {
-    bool generateNeeded = false;
-    for (GeneratedContent target in targets) {
-      bool ok = await target.check(pkgPath);
-      if (!ok) {
-        print("${target.output(pkgPath).absolute}"
-            " doesn't have expected contents.");
-        generateNeeded = true;
-      }
-    }
-    if (generateNeeded) {
-      print('Please regenerate using:');
-      String executable = Platform.executable;
-      String packageRoot = '';
-      // ignore: deprecated_member_use
-      if (Platform.packageRoot != null) {
-        // ignore: deprecated_member_use
-        packageRoot = ' --package-root=${Platform.packageRoot}';
-      }
-      String generateScript =
-          join(pkgPath, joinAll(posix.split(generatorRelPath)));
-      print('  $executable$packageRoot $generateScript');
-      exit(1);
-    } else {
-      print('All generated files up to date.');
-    }
-  }
-
-  /**
-   * Regenerate all of the [targets].  [pkgPath] is the path to the current
-   * package.
-   */
-  static Future<void> generateAll(
-      String pkgPath, Iterable<GeneratedContent> targets) async {
-    print("Generating...");
-    for (GeneratedContent target in targets) {
-      await target.generate(pkgPath);
-    }
-  }
-}
-
-/**
- * Class representing a single output directory (either generated code or
- * generated HTML). No other content should exist in the directory.
- */
-class GeneratedDirectory extends GeneratedContent {
-  /**
-   * The path to the directory that will have the generated content.
-   */
-  final String outputDirPath;
-
-  /**
-   * Callback function that computes the directory contents.
-   */
-  final DirectoryContentsComputer directoryContentsComputer;
-
-  GeneratedDirectory(this.outputDirPath, this.directoryContentsComputer);
-
-  @override
-  Future<bool> check(String pkgPath) async {
-    Directory outputDirectory = output(pkgPath);
-    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
-    try {
-      for (String file in map.keys) {
-        FileContentsComputer fileContentsComputer = map[file];
-        String expectedContents = await fileContentsComputer(pkgPath);
-        File outputFile = new File(posix.join(outputDirectory.path, file));
-        String actualContents = outputFile.readAsStringSync();
-        // Normalize Windows line endings to Unix line endings so that the
-        // comparison doesn't fail on Windows.
-        actualContents = actualContents.replaceAll('\r\n', '\n');
-        if (expectedContents != actualContents) {
-          return false;
-        }
-      }
-      int nonHiddenFileCount = 0;
-      outputDirectory
-          .listSync(recursive: false, followLinks: false)
-          .forEach((FileSystemEntity fileSystemEntity) {
-        if (fileSystemEntity is File &&
-            !basename(fileSystemEntity.path).startsWith('.')) {
-          nonHiddenFileCount++;
-        }
-      });
-      if (nonHiddenFileCount != map.length) {
-        // The number of files generated doesn't match the number we expected to
-        // generate.
-        return false;
-      }
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-    return true;
-  }
-
-  @override
-  Future<void> generate(String pkgPath) async {
-    Directory outputDirectory = output(pkgPath);
-    try {
-      // delete the contents of the directory (and the directory itself)
-      outputDirectory.deleteSync(recursive: true);
-    } catch (e) {
-      // Error caught while trying to delete the directory, this can happen if
-      // it didn't yet exist.
-    }
-    // re-create the empty directory
-    outputDirectory.createSync(recursive: true);
-
-    // generate all of the files in the directory
-    Map<String, FileContentsComputer> map = directoryContentsComputer(pkgPath);
-    for (String file in map.keys) {
-      FileContentsComputer fileContentsComputer = map[file];
-      File outputFile = new File(posix.join(outputDirectory.path, file));
-      print('  ${outputFile.path}');
-      String contents = await fileContentsComputer(pkgPath);
-      outputFile.writeAsStringSync(contents);
-    }
-  }
-
-  @override
-  Directory output(String pkgPath) =>
-      new Directory(join(pkgPath, joinAll(posix.split(outputDirPath))));
-}
-
-/**
- * Class representing a single output file (either generated code or generated
- * HTML).
- */
-class GeneratedFile extends GeneratedContent {
-  /**
-   * The output file to which generated output should be written, relative to
-   * the "tool/spec" directory.  This filename uses the posix path separator
-   * ('/') regardless of the OS.
-   */
-  final String outputPath;
-
-  /**
-   * Callback function which computes the file.
-   */
-  final FileContentsComputer computeContents;
-
-  GeneratedFile(this.outputPath, this.computeContents);
-
-  bool get isDartFile => outputPath.endsWith('.dart');
-
-  @override
-  Future<bool> check(String pkgPath) async {
-    File outputFile = output(pkgPath);
-    String expectedContents = await computeContents(pkgPath);
-    if (isDartFile) {
-      expectedContents = DartFormat.formatText(expectedContents);
-    }
-    try {
-      String actualContents = outputFile.readAsStringSync();
-      // Normalize Windows line endings to Unix line endings so that the
-      // comparison doesn't fail on Windows.
-      actualContents = actualContents.replaceAll('\r\n', '\n');
-      return expectedContents == actualContents;
-    } catch (e) {
-      // There was a problem reading the file (most likely because it didn't
-      // exist).  Treat that the same as if the file doesn't have the expected
-      // contents.
-      return false;
-    }
-  }
-
-  @override
-  Future<void> generate(String pkgPath) async {
-    File outputFile = output(pkgPath);
-    print('  ${outputFile.path}');
-    String contents = await computeContents(pkgPath);
-    outputFile.writeAsStringSync(contents);
-    if (isDartFile) {
-      DartFormat.formatFile(outputFile);
-    }
-  }
-
-  @override
-  File output(String pkgPath) =>
-      new File(join(pkgPath, joinAll(posix.split(outputPath))));
-}
-
-/**
- * Mixin class for generating HTML representations of code that are suitable
- * for enclosing inside a <pre> element.
- */
-abstract class HtmlCodeGenerator {
-  _HtmlCodeGeneratorState _state;
-
-  /**
-   * Add the given [node] to the HTML output.
-   */
-  void add(dom.Node node) {
-    _state.add(node);
-  }
-
-  /**
-   * Add the given [nodes] to the HTML output.
-   */
-  void addAll(Iterable<dom.Node> nodes) {
-    for (dom.Node node in nodes) {
-      _state.add(node);
-    }
-  }
-
-  /**
-   * Execute [callback], collecting any code that is output using [write],
-   * [writeln], [add], or [addAll], and return the result as a list of DOM
-   * nodes.
-   */
-  List<dom.Node> collectHtml(void callback()) {
-    _HtmlCodeGeneratorState oldState = _state;
-    try {
-      _state = new _HtmlCodeGeneratorState();
-      if (callback != null) {
-        callback();
-      }
-      return _state.buffer;
-    } finally {
-      _state = oldState;
-    }
-  }
-
-  /**
-   * Execute [callback], wrapping its output in an element with the given
-   * [name] and [attributes].
-   */
-  void element(String name, Map<dynamic, String> attributes,
-      [void callback()]) {
-    add(makeElement(name, attributes, collectHtml(callback)));
-  }
-
-  /**
-   * Execute [callback], indenting any code it outputs by two spaces.
-   */
-  void indent(void callback()) {
-    String oldIndent = _state.indent;
-    try {
-      _state.indent += '  ';
-      callback();
-    } finally {
-      _state.indent = oldIndent;
-    }
-  }
-
-  /**
-   * Output text without ending the current line.
-   */
-  void write(Object obj) {
-    _state.write(obj.toString());
-  }
-
-  /**
-   * Output text, ending the current line.
-   */
-  void writeln([Object obj = '']) {
-    _state.write('$obj\n');
-  }
-}
-
-/**
- * State used by [CodeGenerator].
- */
-class _CodeGeneratorState {
-  StringBuffer buffer = new StringBuffer();
-  String nextIndent = '';
-  String indent = '';
-  bool indentNeeded = true;
-
-  void write(String text) {
-    List<String> lines = text.split('\n');
-    for (int i = 0; i < lines.length; i++) {
-      if (i == lines.length - 1 && lines[i].isEmpty) {
-        break;
-      }
-      if (indentNeeded) {
-        buffer.write(nextIndent);
-        nextIndent = indent;
-      }
-      indentNeeded = false;
-      buffer.write(lines[i]);
-      if (i != lines.length - 1) {
-        buffer.writeln();
-        indentNeeded = true;
-      }
-    }
-  }
-}
-
-/**
- * State used by [HtmlCodeGenerator].
- */
-class _HtmlCodeGeneratorState {
-  List<dom.Node> buffer = <dom.Node>[];
-  String indent = '';
-  bool indentNeeded = true;
-
-  void add(dom.Node node) {
-    if (node is dom.Text) {
-      write(node.text);
-    } else {
-      buffer.add(node);
-    }
-  }
-
-  void write(String text) {
-    if (text.isEmpty) {
-      return;
-    }
-    if (indentNeeded) {
-      buffer.add(new dom.Text(indent));
-    }
-    List<String> lines = text.split('\n');
-    if (lines.last.isEmpty) {
-      lines.removeLast();
-      buffer.add(new dom.Text(lines.join('\n$indent') + '\n'));
-      indentNeeded = true;
-    } else {
-      buffer.add(new dom.Text(lines.join('\n$indent')));
-      indentNeeded = false;
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 960c862..86cdd07 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -30,7 +30,6 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/hint/sdk_constraint_extractor.dart';
-import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/plugin/resolver_provider.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
@@ -483,11 +482,6 @@
       if (builderOptions.argResults != null) {
         applyAnalysisOptionFlags(options, builderOptions.argResults,
             verbosePrint: verbosePrint);
-        // If lints turned on but none specified, then enable default lints
-        if (options.lint && options.lintRules.isEmpty) {
-          options.lintRules = Registry.ruleRegistry.defaultRules;
-          verbose('Using default lint rules');
-        }
       }
     } else {
       verbose('Using default analysis options');
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 220e865..52a6a24 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -75,7 +75,7 @@
   @override
   List<AnalysisContext> locateContexts(
       {@required List<String> includedPaths,
-      List<String> excludedPaths: null,
+      List<String> excludedPaths: const <String>[],
       String optionsFile: null,
       String packagesFile: null,
       String sdkPath: null}) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index e8c9902..3081077 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -94,7 +94,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 76;
+  static const int DATA_VERSION = 78;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
@@ -344,6 +344,13 @@
   LibraryContext _libraryContext;
 
   /**
+   * This function is invoked when the current session is about to be discarded.
+   * The argument represents the path of the resource causing the session
+   * to be discarded or `null` if there are multiple or this is unknown.
+   */
+  void Function(String) onCurrentSessionAboutToBeDiscarded;
+
+  /**
    * Create a new instance of [AnalysisDriver].
    *
    * The given [SourceFactory] is cloned to ensure that it does not contain a
@@ -364,7 +371,7 @@
       : _logger = logger,
         _sourceFactory = sourceFactory.clone(),
         _externalSummaries = externalSummaries {
-    _createNewSession();
+    _createNewSession(null);
     _onResults = _resultController.stream.asBroadcastStream();
     _testView = new AnalysisDriverTestView(this);
     _createFileTracker();
@@ -1329,7 +1336,7 @@
   void resetUriResolution() {
     _fsState.resetUriResolution();
     _fileTracker.scheduleAllAddedFiles();
-    _changeHook();
+    _changeHook(null);
   }
 
   /**
@@ -1345,8 +1352,8 @@
    * Handles a notification from the [FileTracker] that there has been a change
    * of state.
    */
-  void _changeHook() {
-    _createNewSession();
+  void _changeHook(String path) {
+    _createNewSession(path);
     _libraryContext = null;
     _priorityResults.clear();
     _scheduler.notify(this);
@@ -1622,7 +1629,10 @@
   /**
    * Create a new analysis session, so invalidating the current one.
    */
-  void _createNewSession() {
+  void _createNewSession(String path) {
+    if (onCurrentSessionAboutToBeDiscarded != null) {
+      onCurrentSessionAboutToBeDiscarded(path);
+    }
     _currentSession = new AnalysisSessionImpl(this);
   }
 
@@ -1989,6 +1999,14 @@
 
   bool _started = false;
 
+  /**
+   * The optional worker that is invoked when its work priority is higher
+   * than work priorities in drivers.
+   *
+   * Don't use outside of Analyzer and Analysis Server.
+   */
+  SchedulerWorker outOfBandWorker;
+
   AnalysisDriverScheduler(this._logger, {this.driverWatcher});
 
   /**
@@ -2100,6 +2118,17 @@
         }
       }
 
+      if (outOfBandWorker != null) {
+        var workerPriority = outOfBandWorker.workPriority;
+        if (workerPriority != AnalysisDriverPriority.nothing) {
+          if (workerPriority.index > bestPriority.index) {
+            await outOfBandWorker.performWork();
+            _hasWork.notify();
+            continue;
+          }
+        }
+      }
+
       // Transition to idle if no files to analyze.
       if (!_hasFilesToAnalyze) {
         _statusSupport.transitionToIdle();
@@ -2262,6 +2291,15 @@
   ExceptionResult(this.path, this.exception, this.contextKey);
 }
 
+/// Worker in [AnalysisDriverScheduler].
+abstract class SchedulerWorker {
+  /// Return the priority of work that this worker needs to perform.
+  AnalysisDriverPriority get workPriority;
+
+  /// Perform a single chunk of work.
+  Future<void> performWork();
+}
+
 /**
  * Task that discovers all files that are available to the driver, and makes
  * them known.
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
index 4a016fa..5bf37c7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -70,30 +70,30 @@
         IsEnabledByDefault.constant_update_2018,
         IsExpired.constant_update_2018,
         'Q4 2018 Constant Update'),
-    EnableString.set_literals: const ExperimentalFeature(
-        1,
-        EnableString.set_literals,
-        IsEnabledByDefault.set_literals,
-        IsExpired.set_literals,
-        'Set Literals'),
     EnableString.non_nullable: const ExperimentalFeature(
-        2,
+        1,
         EnableString.non_nullable,
         IsEnabledByDefault.non_nullable,
         IsExpired.non_nullable,
         'Non Nullable'),
     EnableString.control_flow_collections: const ExperimentalFeature(
-        3,
+        2,
         EnableString.control_flow_collections,
         IsEnabledByDefault.control_flow_collections,
         IsExpired.control_flow_collections,
         'Control Flow Collections'),
     EnableString.spread_collections: const ExperimentalFeature(
-        4,
+        3,
         EnableString.spread_collections,
         IsEnabledByDefault.spread_collections,
         IsExpired.spread_collections,
         'Spread Collections'),
+    EnableString.set_literals: const ExperimentalFeature(
+        null,
+        EnableString.set_literals,
+        IsEnabledByDefault.set_literals,
+        IsExpired.set_literals,
+        'Set Literals'),
     EnableString.bogus_disabled: const ExperimentalFeature(
         null,
         EnableString.bogus_disabled,
@@ -113,11 +113,17 @@
   /// Initializes a newly created set of experiments based on optional
   /// arguments.
   ExperimentStatus(
-      {bool constant_update_2018, bool set_literals, bool non_nullable})
+      {bool constant_update_2018,
+      bool control_flow_collections,
+      bool non_nullable,
+      bool set_literals,
+      bool spread_collections})
       : _enableFlags = <bool>[
           constant_update_2018 ?? IsEnabledByDefault.constant_update_2018,
-          set_literals ?? IsEnabledByDefault.set_literals,
           non_nullable ?? IsEnabledByDefault.non_nullable,
+          control_flow_collections ??
+              IsEnabledByDefault.control_flow_collections,
+          spread_collections ?? IsEnabledByDefault.spread_collections,
         ];
 
   /// Decodes the strings given in [flags] into a representation of the set of
@@ -139,11 +145,17 @@
   /// Current state for the flag "constant-update-2018"
   bool get constant_update_2018 => _enableFlags[0];
 
+  /// Current state for the flag "control_flow_collections"
+  bool get control_flow_collections => _enableFlags[2];
+
   /// Current state for the flag "non-nullable"
-  bool get non_nullable => _enableFlags[2];
+  bool get non_nullable => _enableFlags[1];
 
   /// Current state for the flag "set-literals"
-  bool get set_literals => _enableFlags[1];
+  bool get set_literals => true;
+
+  /// Current state for the flag "spread_collections"
+  bool get spread_collections => _enableFlags[3];
 
   /// Queries whether the given [feature] is enabled or disabled.
   bool isEnabled(ExperimentalFeature feature) => feature.isExpired
@@ -168,7 +180,7 @@
   static const bool non_nullable = false;
 
   /// Default state of the experiment "set-literals"
-  static const bool set_literals = false;
+  static const bool set_literals = true;
 
   /// Default state of the experiment "spread-collections"
   static const bool spread_collections = false;
@@ -194,7 +206,7 @@
   static const bool non_nullable = false;
 
   /// Expiration status of the experiment "set-literals"
-  static const bool set_literals = false;
+  static const bool set_literals = true;
 
   /// Expiration status of the experiment "spread-collections"
   static const bool spread_collections = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index e9526b0..8655536 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -382,13 +382,6 @@
    * transitive closure of imported / exported files.
    */
   String get transitiveSignature {
-    if (isPart) {
-      var library = this.library;
-      if (library != null) {
-        return library.transitiveSignature;
-      }
-    }
-
     this.libraryCycle; // sets _transitiveSignature
     return _transitiveSignature;
   }
@@ -711,6 +704,9 @@
     parser.enableOptionalNewAndConst = true;
     parser.enableSetLiterals = experimentStatus.set_literals;
     parser.enableNonNullable = experimentStatus.non_nullable;
+    parser.enableSpreadCollections = experimentStatus.spread_collections;
+    parser.enableControlFlowCollections =
+        experimentStatus.control_flow_collections;
     CompilationUnit unit = parser.parseCompilationUnit(token);
     unit.lineInfo = lineInfo;
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
index f355cc9..1e34697 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_tracker.dart
@@ -10,8 +10,10 @@
 /**
  * Callback used by [FileTracker] to report to its client that files have been
  * added, changed, or removed, and therefore more analysis may be necessary.
+ * [path] is the path of the file that was added, changed, or removed,
+ * or `null` if multiple files were added, changed, or removed.
  */
-typedef void FileTrackerChangeHook();
+typedef void FileTrackerChangeHook(String path);
 
 /**
  * Maintains the file system state needed by the analysis driver, as well as
@@ -147,7 +149,7 @@
     _fsState.markFileForReading(path);
     addedFiles.add(path);
     _pendingFiles.add(path);
-    _changeHook();
+    _changeHook(path);
   }
 
   /**
@@ -156,7 +158,7 @@
   void addFiles(Iterable<String> paths) {
     addedFiles.addAll(paths);
     _pendingFiles.addAll(paths);
-    _changeHook();
+    _changeHook(null);
   }
 
   /**
@@ -168,7 +170,7 @@
       _pendingChangedFiles.add(path);
     }
     _fsState.markFileForReading(path);
-    _changeHook();
+    _changeHook(path);
   }
 
   /**
@@ -207,7 +209,7 @@
     // files seems extreme.
     _fsState.removeFile(path);
     _pendingFiles.addAll(addedFiles);
-    _changeHook();
+    _changeHook(path);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 8624f12..cb200cb 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -213,7 +213,9 @@
 
     unit.accept(new BestPracticesVerifier(
         errorReporter, _typeProvider, _libraryElement,
-        typeSystem: _context.typeSystem, resourceProvider: _resourceProvider));
+        typeSystem: _context.typeSystem,
+        resourceProvider: _resourceProvider,
+        analysisOptions: _context.analysisOptions));
 
     unit.accept(new OverrideVerifier(
       _inheritance,
@@ -266,8 +268,8 @@
 
     var nodeRegistry = new NodeLintRegistry(_analysisOptions.enableTiming);
     var visitors = <AstVisitor>[];
-    var context = LinterContextImpl(
-        allUnits, currentUnit, _declaredVariables, _typeProvider, _typeSystem);
+    var context = LinterContextImpl(allUnits, currentUnit, _declaredVariables,
+        _typeProvider, _typeSystem, _analysisOptions);
     for (Linter linter in _analysisOptions.lintRules) {
       linter.reporter = errorReporter;
       if (linter is NodeLintRule) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart b/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
index d1fe93b..9148fef 100644
--- a/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
@@ -45,6 +45,9 @@
       _addSubtypedName(declaration.superclass);
       _addSubtypedNames(declaration.withClause?.mixinTypes);
       _addSubtypedNames(declaration.implementsClause?.interfaces);
+    } else if (declaration is MixinDeclaration) {
+      _addSubtypedNames(declaration.onClause?.superclassConstraints);
+      _addSubtypedNames(declaration.implementsClause?.interfaces);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index caa227a..908cc96 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
@@ -33,6 +34,7 @@
  */
 class Declaration {
   final int fileIndex;
+  final LineInfo lineInfo;
   final String name;
   final DeclarationKind kind;
   final int offset;
@@ -46,6 +48,7 @@
 
   Declaration(
       this.fileIndex,
+      this.lineInfo,
       this.name,
       this.kind,
       this.offset,
@@ -188,6 +191,7 @@
           var location = file.lineInfo.getLocation(offset);
           declarations.add(new Declaration(
               fileIndex,
+              file.lineInfo,
               name,
               kind,
               offset,
diff --git a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
index da33b5a..a05c39c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
@@ -43,5 +43,5 @@
   }
 
   @override
-  String uriToPath(Uri uri) => driver.sourceFactory.forUri2(uri).fullName;
+  String uriToPath(Uri uri) => driver.sourceFactory.forUri2(uri)?.fullName;
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 749f864..93bfdfd 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2056,6 +2056,9 @@
   }
 }
 
+abstract class CollectionElementImpl extends AstNodeImpl
+    implements CollectionElement {}
+
 /**
  * A combinator associated with an import or export directive.
  *
@@ -4074,7 +4077,8 @@
  *      | [ConditionalExpression] cascadeSection*
  *      | [ThrowExpression]
  */
-abstract class ExpressionImpl extends AstNodeImpl implements Expression {
+abstract class ExpressionImpl extends AstNodeImpl
+    implements CollectionElementImpl, Expression {
   /**
    * The static type of this expression, or `null` if the AST structure has not
    * been resolved.
@@ -4121,7 +4125,10 @@
     AstNode child = this;
     while (child is Expression ||
         child is ArgumentList ||
-        child is MapLiteralEntry) {
+        child is MapLiteralEntry ||
+        child is SpreadElement ||
+        child is IfElement ||
+        child is ForElement) {
       AstNode parent = child.parent;
       if (parent is TypedLiteralImpl && parent.constKeyword != null) {
         // Inside an explicitly `const` list or map literal.
@@ -4549,6 +4556,134 @@
   }
 }
 
+abstract class ForEachPartsImpl extends ForLoopPartsImpl
+    implements ForEachParts {
+  @override
+  Token inKeyword;
+
+  /**
+   * The expression evaluated to produce the iterator.
+   */
+  ExpressionImpl _iterable;
+
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared internally (in the for-loop part). The [awaitKeyword] can be
+   * `null` if this is not an asynchronous for loop.
+   */
+  ForEachPartsImpl(this.inKeyword, ExpressionImpl iterator) {
+    _iterable = _becomeParentOf(iterator);
+  }
+
+  @override
+  Token get beginToken => inKeyword;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities =>
+      new ChildEntities()..add(inKeyword)..add(_iterable);
+
+  @override
+  Token get endToken => _iterable.endToken;
+
+  @override
+  Expression get iterable => _iterable;
+
+  void set iterable(Expression expression) {
+    _iterable = _becomeParentOf(expression as ExpressionImpl);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _iterable?.accept(visitor);
+  }
+}
+
+class ForEachPartsWithDeclarationImpl extends ForEachPartsImpl
+    implements ForEachPartsWithDeclaration {
+  /**
+   * The declaration of the loop variable.
+   */
+  DeclaredIdentifierImpl _loopVariable;
+
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared internally (inside the for-loop part).
+   */
+  ForEachPartsWithDeclarationImpl(DeclaredIdentifierImpl loopVariable,
+      Token inKeyword, ExpressionImpl iterator)
+      : super(inKeyword, iterator) {
+    _loopVariable = _becomeParentOf(loopVariable);
+  }
+
+  @override
+  Token get beginToken => _loopVariable.beginToken;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(_loopVariable)
+    ..addAll(super.childEntities);
+
+  @override
+  DeclaredIdentifier get loopVariable => _loopVariable;
+
+  void set loopVariable(DeclaredIdentifier variable) {
+    _loopVariable = _becomeParentOf(variable as DeclaredIdentifierImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitForEachPartsWithDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _loopVariable?.accept(visitor);
+    super.visitChildren(visitor);
+  }
+}
+
+class ForEachPartsWithIdentifierImpl extends ForEachPartsImpl
+    implements ForEachPartsWithIdentifier {
+  /**
+   * The loop variable.
+   */
+  SimpleIdentifierImpl _identifier;
+
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared externally (outside the for-loop part).
+   */
+  ForEachPartsWithIdentifierImpl(
+      SimpleIdentifierImpl identifier, Token inKeyword, ExpressionImpl iterator)
+      : super(inKeyword, iterator) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  Token get beginToken => _identifier.beginToken;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(_identifier)
+    ..addAll(super.childEntities);
+
+  @override
+  SimpleIdentifier get identifier => _identifier;
+
+  void set identifier(SimpleIdentifier identifier) {
+    _identifier = _becomeParentOf(identifier as SimpleIdentifierImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitForEachPartsWithIdentifier(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _identifier?.accept(visitor);
+    _iterable?.accept(visitor);
+  }
+}
+
 /**
  * A for-each statement.
  *
@@ -4648,7 +4783,7 @@
   }
 
   @override
-  Token get beginToken => forKeyword;
+  Token get beginToken => awaitKeyword ?? forKeyword;
 
   @override
   Statement get body => _body;
@@ -4709,6 +4844,59 @@
   }
 }
 
+class ForElementImpl extends CollectionElementImpl
+    with ForMixin
+    implements ForElement {
+  /**
+   * The body of the loop.
+   */
+  CollectionElementImpl _body;
+
+  /**
+   * Initialize a newly created for element.
+   */
+  ForElementImpl(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopPartsImpl forLoopParts,
+      Token rightParenthesis,
+      CollectionElementImpl body) {
+    this.awaitKeyword = awaitKeyword;
+    this.forKeyword = forKeyword;
+    this.leftParenthesis = leftParenthesis;
+    _forLoopParts = _becomeParentOf(forLoopParts);
+    this.rightParenthesis = rightParenthesis;
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  CollectionElement get body => _body;
+
+  void set body(CollectionElement statement) {
+    _body = _becomeParentOf(statement as CollectionElementImpl);
+  }
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..addAll(super.childEntities)
+    ..add(_body);
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitForElement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _forLoopParts?.accept(visitor);
+    _body?.accept(visitor);
+  }
+}
+
+abstract class ForLoopPartsImpl extends AstNodeImpl implements ForLoopParts {}
+
 /**
  * A node representing a parameter to a function.
  *
@@ -4873,6 +5061,243 @@
   }
 }
 
+mixin ForMixin on AstNodeImpl {
+  Token awaitKeyword;
+
+  Token forKeyword;
+
+  Token leftParenthesis;
+
+  ForLoopPartsImpl _forLoopParts;
+
+  Token rightParenthesis;
+
+  @override
+  Token get beginToken => awaitKeyword ?? forKeyword;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(awaitKeyword)
+    ..add(forKeyword)
+    ..add(leftParenthesis)
+    ..add(_forLoopParts)
+    ..add(rightParenthesis);
+
+  ForLoopParts get forLoopParts => _forLoopParts;
+
+  void set forLoopParts(ForLoopParts forLoopParts) {
+    _forLoopParts = _becomeParentOf(forLoopParts as ForLoopPartsImpl);
+  }
+}
+
+abstract class ForPartsImpl extends ForLoopPartsImpl implements ForParts {
+  @override
+  Token leftSeparator;
+
+  /**
+   * The condition used to determine when to terminate the loop, or `null` if
+   * there is no condition.
+   */
+  ExpressionImpl _condition;
+
+  @override
+  Token rightSeparator;
+
+  /**
+   * The list of expressions run after each execution of the loop body.
+   */
+  NodeList<Expression> _updaters;
+
+  /**
+   * Initialize a newly created for statement. Either the [variableList] or the
+   * [initialization] must be `null`. Either the [condition] and the list of
+   * [updaters] can be `null` if the loop does not have the corresponding
+   * attribute.
+   */
+  ForPartsImpl(this.leftSeparator, ExpressionImpl condition,
+      this.rightSeparator, List<Expression> updaters) {
+    _condition = _becomeParentOf(condition);
+    _updaters = new NodeListImpl<Expression>(this, updaters);
+  }
+
+  @override
+  Token get beginToken => leftSeparator;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(leftSeparator)
+    ..add(_condition)
+    ..add(rightSeparator)
+    ..addAll(_updaters);
+
+  @override
+  Expression get condition => _condition;
+
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression as ExpressionImpl);
+  }
+
+  @override
+  Token get endToken => _updaters?.endToken ?? rightSeparator;
+
+  @override
+  NodeList<Expression> get updaters => _updaters;
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _condition?.accept(visitor);
+    _updaters.accept(visitor);
+  }
+}
+
+class ForPartsWithDeclarationsImpl extends ForPartsImpl
+    implements ForPartsWithDeclarations {
+  /**
+   * The declaration of the loop variables, or `null` if there are no variables.
+   * Note that a for statement cannot have both a variable list and an
+   * initialization expression, but can validly have neither.
+   */
+  VariableDeclarationListImpl _variableList;
+
+  /**
+   * Initialize a newly created for statement. Both the [condition] and the list
+   * of [updaters] can be `null` if the loop does not have the corresponding
+   * attribute.
+   */
+  ForPartsWithDeclarationsImpl(
+      VariableDeclarationListImpl variableList,
+      Token leftSeparator,
+      ExpressionImpl condition,
+      Token rightSeparator,
+      List<Expression> updaters)
+      : super(leftSeparator, condition, rightSeparator, updaters) {
+    _variableList = _becomeParentOf(variableList);
+  }
+
+  @override
+  Token get beginToken => _variableList?.beginToken ?? super.beginToken;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(_variableList)
+    ..addAll(super.childEntities);
+
+  @override
+  VariableDeclarationList get variables => _variableList;
+
+  void set variables(VariableDeclarationList variableList) {
+    _variableList =
+        _becomeParentOf(variableList as VariableDeclarationListImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitForPartsWithDeclarations(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _variableList?.accept(visitor);
+    super.visitChildren(visitor);
+  }
+}
+
+class ForPartsWithExpressionImpl extends ForPartsImpl
+    implements ForPartsWithExpression {
+  /**
+   * The initialization expression, or `null` if there is no initialization
+   * expression. Note that a for statement cannot have both a variable list and
+   * an initialization expression, but can validly have neither.
+   */
+  ExpressionImpl _initialization;
+
+  /**
+   * Initialize a newly created for statement. Both the [condition] and the list
+   * of [updaters] can be `null` if the loop does not have the corresponding
+   * attribute.
+   */
+  ForPartsWithExpressionImpl(ExpressionImpl initialization, Token leftSeparator,
+      ExpressionImpl condition, Token rightSeparator, List<Expression> updaters)
+      : super(leftSeparator, condition, rightSeparator, updaters) {
+    _initialization = _becomeParentOf(initialization);
+  }
+
+  @override
+  Token get beginToken => initialization?.beginToken ?? super.beginToken;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(_initialization)
+    ..addAll(super.childEntities);
+
+  @override
+  Expression get initialization => _initialization;
+
+  void set initialization(Expression initialization) {
+    _initialization = _becomeParentOf(initialization as ExpressionImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) =>
+      visitor.visitForPartsWithExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _initialization?.accept(visitor);
+    super.visitChildren(visitor);
+  }
+}
+
+class ForStatement2Impl extends StatementImpl
+    with ForMixin
+    implements ForStatement2 {
+  /**
+   * The body of the loop.
+   */
+  StatementImpl _body;
+
+  /**
+   * Initialize a newly created for statement.
+   */
+  ForStatement2Impl(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      ForLoopPartsImpl forLoopParts,
+      Token rightParenthesis,
+      StatementImpl body) {
+    this.awaitKeyword = awaitKeyword;
+    this.forKeyword = forKeyword;
+    this.leftParenthesis = leftParenthesis;
+    _forLoopParts = _becomeParentOf(forLoopParts);
+    this.rightParenthesis = rightParenthesis;
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  Statement get body => _body;
+
+  void set body(Statement statement) {
+    _body = _becomeParentOf(statement as StatementImpl);
+  }
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..addAll(super.childEntities)
+    ..add(_body);
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitForStatement2(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _forLoopParts?.accept(visitor);
+    _body?.accept(visitor);
+  }
+}
+
 /**
  * A for statement.
  *
@@ -5952,6 +6377,111 @@
   bool get isAssignable => true;
 }
 
+class IfElementImpl extends CollectionElementImpl
+    with IfMixin
+    implements IfElement {
+  /**
+   * The element to be executed if the condition is `true`.
+   */
+  CollectionElementImpl _thenElement;
+
+  /**
+   * The element to be executed if the condition is `false`, or `null` if there
+   * is no such element.
+   */
+  CollectionElementImpl _elseElement;
+
+  /**
+   * Initialize a newly created for element.
+   */
+  IfElementImpl(
+      Token ifKeyword,
+      Token leftParenthesis,
+      ExpressionImpl condition,
+      Token rightParenthesis,
+      CollectionElementImpl thenElement,
+      Token elseKeyword,
+      CollectionElementImpl elseElement) {
+    this.ifKeyword = ifKeyword;
+    this.leftParenthesis = leftParenthesis;
+    _condition = _becomeParentOf(condition);
+    this.rightParenthesis = rightParenthesis;
+    _thenElement = _becomeParentOf(thenElement);
+    this.elseKeyword = elseKeyword;
+    _elseElement = _becomeParentOf(elseElement);
+  }
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..addAll(super.childEntities)
+    ..add(_thenElement)
+    ..add(_elseElement);
+
+  @override
+  CollectionElement get elseElement => _elseElement;
+
+  set elseElement(CollectionElement element) {
+    _elseElement = _becomeParentOf(element as CollectionElementImpl);
+  }
+
+  @override
+  Token get endToken => _elseElement?.endToken ?? _thenElement.endToken;
+
+  @override
+  CollectionElement get thenElement => _thenElement;
+
+  set thenElement(CollectionElement element) {
+    _thenElement = _becomeParentOf(element as CollectionElementImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitIfElement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _thenElement?.accept(visitor);
+    _elseElement?.accept(visitor);
+  }
+}
+
+mixin IfMixin on AstNodeImpl {
+  Token ifKeyword;
+
+  Token leftParenthesis;
+
+  /**
+   * The condition used to determine which of the branches is executed next.
+   */
+  ExpressionImpl _condition;
+
+  Token rightParenthesis;
+
+  Token elseKeyword;
+
+  @override
+  Token get beginToken => ifKeyword;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities => new ChildEntities()
+    ..add(ifKeyword)
+    ..add(leftParenthesis)
+    ..add(_condition)
+    ..add(rightParenthesis)
+    ..add(elseKeyword);
+
+  Expression get condition => _condition;
+
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression as ExpressionImpl);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _condition?.accept(visitor);
+  }
+}
+
 /**
  * An if statement.
  *
@@ -7277,7 +7807,81 @@
  * A list literal.
  *
  *    listLiteral ::=
+ *        'const'? ('<' [TypeAnnotation] '>')?
+ *        '[' ([CollectionLiteralElement] ','?)? ']'
+ *
+ * This is the class that is used to represent a list literal when either the
+ * 'control-flow-collections' or 'spread-collections' experiments are enabled.
+ * If neither of those experiments are enabled, then [ListLiteral] will be used.
+ */
+class ListLiteral2Impl extends TypedLiteralImpl implements ListLiteral2 {
+  @override
+  Token leftBracket;
+
+  /**
+   * The elements used to compute the elements of the list.
+   */
+  NodeList<CollectionElement> _elements;
+
+  @override
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created list literal. The [constKeyword] can be `null`
+   * if the literal is not a constant. The [typeArguments] can be `null` if no
+   * type arguments were declared. The list of [elements] can be `null` if the
+   * list is empty.
+   */
+  ListLiteral2Impl(Token constKeyword, TypeArgumentListImpl typeArguments,
+      this.leftBracket, List<CollectionElement> elements, this.rightBracket)
+      : super(constKeyword, typeArguments) {
+    _elements = new NodeListImpl<CollectionElement>(this, elements);
+  }
+
+  @override
+  Token get beginToken {
+    if (constKeyword != null) {
+      return constKeyword;
+    }
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
+    }
+    return leftBracket;
+  }
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable<SyntacticEntity> get childEntities => super._childEntities
+    ..add(leftBracket)
+    ..addAll(_elements)
+    ..add(rightBracket);
+
+  @override
+  NodeList<CollectionElement> get elements => _elements;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitListLiteral2(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _elements.accept(visitor);
+  }
+}
+
+/**
+ * A list literal.
+ *
+ *    listLiteral ::=
  *        'const'? ('<' [TypeName] '>')? '[' ([Expression] ','?)? ']'
+ *
+ * This is the class that is used to represent a list literal when neither the
+ * 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+ * If either of those experiments are enabled, then [ListLiteral2] will be used.
  */
 class ListLiteralImpl extends TypedLiteralImpl implements ListLiteral {
   /**
@@ -7382,12 +7986,82 @@
 }
 
 /**
+ * A literal map.
+ *
+ *    mapLiteral ::=
+ *        'const'? ('<' [TypeAnnotation] (',' [TypeAnnotation])* '>')?
+ *        '{' ([MapElement] (',' [MapElement])* ','?)? '}'
+ *
+ * This is the class that is used to represent a map literal when either the
+ * 'control-flow-collections' or 'spread-collections' experiments are enabled.
+ * If neither of those experiments are enabled, then [MapLiteral] will be used.
+ */
+class MapLiteral2Impl extends TypedLiteralImpl implements MapLiteral2 {
+  @override
+  Token leftBracket;
+
+  /**
+   * The entries in the map.
+   */
+  NodeList<CollectionElement> _entries;
+
+  @override
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created map literal. The [constKeyword] can be `null` if
+   * the literal is not a constant. The [typeArguments] can be `null` if no type
+   * arguments were declared. The [entries] can be `null` if the map is empty.
+   */
+  MapLiteral2Impl(Token constKeyword, TypeArgumentListImpl typeArguments,
+      this.leftBracket, List<CollectionElement> entries, this.rightBracket)
+      : super(constKeyword, typeArguments) {
+    _entries = new NodeListImpl<CollectionElement>(this, entries);
+  }
+
+  @override
+  Token get beginToken {
+    if (constKeyword != null) {
+      return constKeyword;
+    }
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
+    }
+    return leftBracket;
+  }
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable<SyntacticEntity> get childEntities => super._childEntities
+    ..add(leftBracket)
+    ..addAll(entries)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  NodeList<CollectionElement> get entries => _entries;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitMapLiteral2(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _entries.accept(visitor);
+  }
+}
+
+/**
  * A single key/value pair in a map literal.
  *
  *    mapLiteralEntry ::=
  *        [Expression] ':' [Expression]
  */
-class MapLiteralEntryImpl extends AstNodeImpl implements MapLiteralEntry {
+class MapLiteralEntryImpl extends CollectionElementImpl
+    implements MapLiteralEntry {
   /**
    * The expression computing the key with which the value will be associated.
    */
@@ -9507,8 +10181,82 @@
  *
  *    setLiteral ::=
  *        'const'? ('<' [TypeAnnotation] '>')?
+ *        '{' [CollectionElement] (',' [Expression])* ','? '}'
+ *      | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
+ *
+ * This is the class that is used to represent a set literal when either the
+ * 'control-flow-collections' or 'spread-collections' experiments are enabled.
+ * If neither of those experiments are enabled, then [SetLiteral] will be used.
+ */
+class SetLiteral2Impl extends TypedLiteralImpl implements SetLiteral2 {
+  @override
+  Token leftBracket;
+
+  /**
+   * The elements in the set.
+   */
+  NodeList<CollectionElement> _elements;
+
+  @override
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created set literal. The [constKeyword] can be `null` if
+   * the literal is not a constant. The [typeArguments] can be `null` if no type
+   * arguments were declared. The [elements] can be `null` if the set is empty.
+   */
+  SetLiteral2Impl(Token constKeyword, TypeArgumentListImpl typeArguments,
+      this.leftBracket, List<CollectionElement> elements, this.rightBracket)
+      : super(constKeyword, typeArguments) {
+    _elements = new NodeListImpl<CollectionElement>(this, elements);
+  }
+
+  @override
+  Token get beginToken {
+    if (constKeyword != null) {
+      return constKeyword;
+    }
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
+    }
+    return leftBracket;
+  }
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable<SyntacticEntity> get childEntities => super._childEntities
+    ..add(leftBracket)
+    ..addAll(elements)
+    ..add(rightBracket);
+
+  @override
+  NodeList<CollectionElement> get elements => _elements;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) => visitor.visitSetLiteral2(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _elements.accept(visitor);
+  }
+}
+
+/**
+ * A literal set.
+ *
+ *    setLiteral ::=
+ *        'const'? ('<' [TypeAnnotation] '>')?
  *        '{' [Expression] (',' [Expression])* ','? '}'
  *      | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
+ *
+ * This is the class that is used to represent a set literal when neither the
+ * 'control-flow-collections' nor 'spread-collections' experiments are enabled.
+ * If either of those experiments are enabled, then [SetLiteral2] will be used.
  */
 class SetLiteralImpl extends TypedLiteralImpl implements SetLiteral {
   /**
@@ -9999,6 +10747,44 @@
 abstract class SingleStringLiteralImpl extends StringLiteralImpl
     implements SingleStringLiteral {}
 
+class SpreadElementImpl extends AstNodeImpl
+    implements CollectionElementImpl, SpreadElement {
+  Token spreadOperator;
+
+  ExpressionImpl _expression;
+
+  SpreadElementImpl(this.spreadOperator, ExpressionImpl expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => spreadOperator;
+
+  @override
+  Iterable<SyntacticEntity> get childEntities =>
+      new ChildEntities()..add(spreadOperator)..add(_expression);
+
+  @override
+  Token get endToken => _expression.endToken;
+
+  @override
+  Expression get expression => _expression;
+
+  set expression(Expression expression) {
+    _expression = _becomeParentOf(expression as ExpressionImpl);
+  }
+
+  @override
+  E accept<E>(AstVisitor<E> visitor) {
+    return visitor.visitSpreadElement(this);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _expression?.accept(visitor);
+  }
+}
+
 /**
  * A node that represents a statement.
  *
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index cc7023a..4e04999 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -338,6 +338,7 @@
           Token semicolon) =>
       new ExportDirectiveImpl(comment, metadata, keyword, libraryUri,
           configurations, combinators, semicolon);
+
   @override
   ExpressionFunctionBody expressionFunctionBody(Token keyword,
           Token functionDefinition, Expression expression, Token semicolon) =>
@@ -404,6 +405,20 @@
           type, thisKeyword, period, identifier, typeParameters, parameters);
 
   @override
+  ForEachPartsWithDeclaration forEachPartsWithDeclaration(
+          {DeclaredIdentifier loopVariable,
+          Token inKeyword,
+          Expression iterable}) =>
+      new ForEachPartsWithDeclarationImpl(loopVariable, inKeyword, iterable);
+
+  @override
+  ForEachPartsWithIdentifier forEachPartsWithIdentifier(
+          {SimpleIdentifier identifier,
+          Token inKeyword,
+          Expression iterable}) =>
+      new ForEachPartsWithIdentifierImpl(identifier, inKeyword, iterable);
+
+  @override
   ForEachStatement forEachStatementWithDeclaration(
           Token awaitKeyword,
           Token forKeyword,
@@ -444,6 +459,17 @@
           body);
 
   @override
+  ForElement forElement(
+          {Token awaitKeyword,
+          Token forKeyword,
+          Token leftParenthesis,
+          ForLoopParts forLoopParts,
+          Token rightParenthesis,
+          CollectionElement body}) =>
+      new ForElementImpl(awaitKeyword, forKeyword, leftParenthesis,
+          forLoopParts, rightParenthesis, body);
+
+  @override
   FormalParameterList formalParameterList(
           Token leftParenthesis,
           List<FormalParameter> parameters,
@@ -454,6 +480,26 @@
           rightDelimiter, rightParenthesis);
 
   @override
+  ForPartsWithDeclarations forPartsWithDeclarations(
+          {VariableDeclarationList variables,
+          Token leftSeparator,
+          Expression condition,
+          Token rightSeparator,
+          List<Expression> updaters}) =>
+      new ForPartsWithDeclarationsImpl(
+          variables, leftSeparator, condition, rightSeparator, updaters);
+
+  @override
+  ForPartsWithExpression forPartsWithExpression(
+          {Expression initialization,
+          Token leftSeparator,
+          Expression condition,
+          Token rightSeparator,
+          List<Expression> updaters}) =>
+      new ForPartsWithExpressionImpl(
+          initialization, leftSeparator, condition, rightSeparator, updaters);
+
+  @override
   ForStatement forStatement(
           Token forKeyword,
           Token leftParenthesis,
@@ -478,6 +524,17 @@
           body);
 
   @override
+  ForStatement2 forStatement2(
+          {Token awaitKeyword,
+          Token forKeyword,
+          Token leftParenthesis,
+          ForLoopParts forLoopParts,
+          Token rightParenthesis,
+          Statement body}) =>
+      new ForStatement2Impl(awaitKeyword, forKeyword, leftParenthesis,
+          forLoopParts, rightParenthesis, body);
+
+  @override
   FunctionDeclaration functionDeclaration(
           Comment comment,
           List<Annotation> metadata,
@@ -571,6 +628,18 @@
       new HideCombinatorImpl(keyword, hiddenNames);
 
   @override
+  IfElement ifElement(
+          {Token ifKeyword,
+          Token leftParenthesis,
+          Expression condition,
+          Token rightParenthesis,
+          CollectionElement thenElement,
+          Token elseKeyword,
+          CollectionElement elseElement}) =>
+      new IfElementImpl(ifKeyword, leftParenthesis, condition, rightParenthesis,
+          thenElement, elseKeyword, elseElement);
+
+  @override
   IfStatement ifStatement(
           Token ifKeyword,
           Token leftParenthesis,
@@ -673,6 +742,16 @@
           constKeyword, typeArguments, leftBracket, elements, rightBracket);
 
   @override
+  ListLiteral2 listLiteral2(
+          {Token constKeyword,
+          TypeArgumentList typeArguments,
+          Token leftBracket,
+          List<CollectionElement> elements,
+          Token rightBracket}) =>
+      new ListLiteral2Impl(
+          constKeyword, typeArguments, leftBracket, elements, rightBracket);
+
+  @override
   MapLiteral mapLiteral(
           Token constKeyword,
           TypeArgumentList typeArguments,
@@ -683,6 +762,16 @@
           constKeyword, typeArguments, leftBracket, entries, rightBracket);
 
   @override
+  MapLiteral2 mapLiteral2(
+          {Token constKeyword,
+          TypeArgumentList typeArguments,
+          Token leftBracket,
+          List<CollectionElement> entries,
+          Token rightBracket}) =>
+      new MapLiteral2Impl(
+          constKeyword, typeArguments, leftBracket, entries, rightBracket);
+
+  @override
   MapLiteralEntry mapLiteralEntry(
           Expression key, Token separator, Expression value) =>
       new MapLiteralEntryImpl(key, separator, value);
@@ -840,6 +929,16 @@
           constKeyword, typeArguments, leftBracket, elements, rightBracket);
 
   @override
+  SetLiteral2 setLiteral2(
+          {Token constKeyword,
+          TypeArgumentList typeArguments,
+          Token leftBracket,
+          List<CollectionElement> elements,
+          Token rightBracket}) =>
+      new SetLiteral2Impl(
+          constKeyword, typeArguments, leftBracket, elements, rightBracket);
+
+  @override
   ShowCombinator showCombinator(
           Token keyword, List<SimpleIdentifier> shownNames) =>
       new ShowCombinatorImpl(keyword, shownNames);
@@ -878,6 +977,10 @@
       new SimpleStringLiteralImpl(literal, value);
 
   @override
+  SpreadElement spreadElement({Token spreadOperator, Expression expression}) =>
+      new SpreadElementImpl(spreadOperator, expression);
+
+  @override
   StringInterpolation stringInterpolation(
           List<InterpolationElement> elements) =>
       new StringInterpolationImpl(elements);
diff --git a/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart b/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart
new file mode 100644
index 0000000..052c2fe
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/ast/constant_evaluator.dart
@@ -0,0 +1,390 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+/**
+ * Instances of the class [ConstantEvaluator] evaluate constant expressions to
+ * produce their compile-time value.
+ *
+ * According to the Dart Language Specification:
+ *
+ * > A constant expression is one of the following:
+ * >
+ * > * A literal number.
+ * > * A literal boolean.
+ * > * A literal string where any interpolated expression is a compile-time
+ * >   constant that evaluates to a numeric, string or boolean value or to
+ * >   **null**.
+ * > * A literal symbol.
+ * > * **null**.
+ * > * A qualified reference to a static constant variable.
+ * > * An identifier expression that denotes a constant variable, class or type
+ * >   alias.
+ * > * A constant constructor invocation.
+ * > * A constant list literal.
+ * > * A constant map literal.
+ * > * A simple or qualified identifier denoting a top-level function or a
+ * >   static method.
+ * > * A parenthesized expression _(e)_ where _e_ is a constant expression.
+ * > * <span>
+ * >   An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
+ * >   where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * >   expressions and <i>identical()</i> is statically bound to the predefined
+ * >   dart function <i>identical()</i> discussed above.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i>
+ * >   or <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
+ * >   <i>e<sub>2</sub></i> are constant expressions that evaluate to a
+ * >   numeric, string or boolean value.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
+ * >   e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where
+ * >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * >   expressions that evaluate to a boolean value.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
+ * >   e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
+ * >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ * >   expressions that evaluate to an integer value or to <b>null</b>.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub>
+ * >   -e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub> ~/
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &gt; e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or
+ * >   <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>,
+ * >   <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
+ * >   that evaluate to a numeric value or to <b>null</b>.
+ * >   </span>
+ * > * <span>
+ * >   An expression of one the form <i>e<sub>1</sub> + e<sub>2</sub></i>,
+ * >   <i>e<sub>1</sub> -e<sub>2</sub></i> where <i>e<sub>1</sub> and
+ * >   e<sub>2</sub></i> are constant expressions that evaluate to a numeric or
+ * >   string value or to <b>null</b>.
+ * >   </span>
+ * > * <span>
+ * >   An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
+ * >   e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
+ * >   <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
+ * >   evaluates to a boolean value.
+ * >   </span>
+ *
+ * However, this comment is now at least a little bit out of sync with the spec.
+ *
+ * The values returned by instances of this class are therefore `null` and
+ * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
+ * `DartObject`.
+ *
+ * In addition, this class defines several values that can be returned to
+ * indicate various conditions encountered during evaluation. These are
+ * documented with the static fields that define those values.
+ */
+class ConstantEvaluator extends GeneralizingAstVisitor<Object> {
+  /**
+   * The value returned for expressions (or non-expression nodes) that are not
+   * compile-time constant expressions.
+   */
+  static Object NOT_A_CONSTANT = new Object();
+
+  @override
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    StringBuffer buffer = new StringBuffer();
+    for (StringLiteral string in node.strings) {
+      Object value = string.accept(this);
+      if (identical(value, NOT_A_CONSTANT)) {
+        return value;
+      }
+      buffer.write(value);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  Object visitBinaryExpression(BinaryExpression node) {
+    Object leftOperand = node.leftOperand.accept(this);
+    if (identical(leftOperand, NOT_A_CONSTANT)) {
+      return leftOperand;
+    }
+    Object rightOperand = node.rightOperand.accept(this);
+    if (identical(rightOperand, NOT_A_CONSTANT)) {
+      return rightOperand;
+    }
+    while (true) {
+      if (node.operator.type == TokenType.AMPERSAND) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand & rightOperand;
+        }
+      } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
+        // boolean or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand && rightOperand;
+        }
+      } else if (node.operator.type == TokenType.BANG_EQ) {
+        // numeric, string, boolean, or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand != rightOperand;
+        } else if (leftOperand is num && rightOperand is num) {
+          return leftOperand != rightOperand;
+        } else if (leftOperand is String && rightOperand is String) {
+          return leftOperand != rightOperand;
+        }
+      } else if (node.operator.type == TokenType.BAR) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand | rightOperand;
+        }
+      } else if (node.operator.type == TokenType.BAR_BAR) {
+        // boolean or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand || rightOperand;
+        }
+      } else if (node.operator.type == TokenType.CARET) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand ^ rightOperand;
+        }
+      } else if (node.operator.type == TokenType.EQ_EQ) {
+        // numeric, string, boolean, or {@code null}
+        if (leftOperand is bool && rightOperand is bool) {
+          return leftOperand == rightOperand;
+        } else if (leftOperand is num && rightOperand is num) {
+          return leftOperand == rightOperand;
+        } else if (leftOperand is String && rightOperand is String) {
+          return leftOperand == rightOperand;
+        }
+      } else if (node.operator.type == TokenType.GT) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) > 0;
+        }
+      } else if (node.operator.type == TokenType.GT_EQ) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) >= 0;
+        }
+      } else if (node.operator.type == TokenType.GT_GT) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand >> rightOperand;
+        }
+      } else if (node.operator.type == TokenType.LT) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) < 0;
+        }
+      } else if (node.operator.type == TokenType.LT_EQ) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.compareTo(rightOperand) <= 0;
+        }
+      } else if (node.operator.type == TokenType.LT_LT) {
+        // integer or {@code null}
+        if (leftOperand is int && rightOperand is int) {
+          return leftOperand << rightOperand;
+        }
+      } else if (node.operator.type == TokenType.MINUS) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand - rightOperand;
+        }
+      } else if (node.operator.type == TokenType.PERCENT) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand.remainder(rightOperand);
+        }
+      } else if (node.operator.type == TokenType.PLUS) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand + rightOperand;
+        }
+        if (leftOperand is String && rightOperand is String) {
+          return leftOperand + rightOperand;
+        }
+      } else if (node.operator.type == TokenType.STAR) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand * rightOperand;
+        }
+      } else if (node.operator.type == TokenType.SLASH) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand / rightOperand;
+        }
+      } else if (node.operator.type == TokenType.TILDE_SLASH) {
+        // numeric or {@code null}
+        if (leftOperand is num && rightOperand is num) {
+          return leftOperand ~/ rightOperand;
+        }
+      }
+      break;
+    }
+    // TODO(brianwilkerson) This doesn't handle numeric conversions.
+    return visitExpression(node);
+  }
+
+  @override
+  Object visitBooleanLiteral(BooleanLiteral node) => node.value ? true : false;
+
+  @override
+  Object visitDoubleLiteral(DoubleLiteral node) => node.value;
+
+  @override
+  Object visitIntegerLiteral(IntegerLiteral node) => node.value;
+
+  @override
+  Object visitInterpolationExpression(InterpolationExpression node) {
+    Object value = node.expression.accept(this);
+    if (value == null || value is bool || value is String || value is num) {
+      return value;
+    }
+    return NOT_A_CONSTANT;
+  }
+
+  @override
+  Object visitInterpolationString(InterpolationString node) => node.value;
+
+  @override
+  Object visitListLiteral(ListLiteral node) {
+    List<Object> list = new List<Object>();
+    for (Expression element in node.elements) {
+      Object value = element.accept(this);
+      if (identical(value, NOT_A_CONSTANT)) {
+        return value;
+      }
+      list.add(value);
+    }
+    return list;
+  }
+
+  @override
+  Object visitMapLiteral(MapLiteral node) {
+    Map<String, Object> map = new HashMap<String, Object>();
+    for (MapLiteralEntry entry in node.entries) {
+      Object key = entry.key.accept(this);
+      Object value = entry.value.accept(this);
+      if (key is String && !identical(value, NOT_A_CONSTANT)) {
+        map[key] = value;
+      } else {
+        return NOT_A_CONSTANT;
+      }
+    }
+    return map;
+  }
+
+  @override
+  Object visitMethodInvocation(MethodInvocation node) => visitNode(node);
+
+  @override
+  Object visitNode(AstNode node) => NOT_A_CONSTANT;
+
+  @override
+  Object visitNullLiteral(NullLiteral node) => null;
+
+  @override
+  Object visitParenthesizedExpression(ParenthesizedExpression node) =>
+      node.expression.accept(this);
+
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) =>
+      _getConstantValue(null);
+
+  @override
+  Object visitPrefixExpression(PrefixExpression node) {
+    Object operand = node.operand.accept(this);
+    if (identical(operand, NOT_A_CONSTANT)) {
+      return operand;
+    }
+    while (true) {
+      if (node.operator.type == TokenType.BANG) {
+        if (identical(operand, true)) {
+          return false;
+        } else if (identical(operand, false)) {
+          return true;
+        }
+      } else if (node.operator.type == TokenType.TILDE) {
+        if (operand is int) {
+          return ~operand;
+        }
+      } else if (node.operator.type == TokenType.MINUS) {
+        if (operand == null) {
+          return null;
+        } else if (operand is num) {
+          return -operand;
+        }
+      } else {}
+      break;
+    }
+    return NOT_A_CONSTANT;
+  }
+
+  @override
+  Object visitPropertyAccess(PropertyAccess node) => _getConstantValue(null);
+
+  @override
+  Object visitSimpleIdentifier(SimpleIdentifier node) =>
+      _getConstantValue(null);
+
+  @override
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
+
+  @override
+  Object visitStringInterpolation(StringInterpolation node) {
+    StringBuffer buffer = new StringBuffer();
+    for (InterpolationElement element in node.elements) {
+      Object value = element.accept(this);
+      if (identical(value, NOT_A_CONSTANT)) {
+        return value;
+      }
+      buffer.write(value);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  Object visitSymbolLiteral(SymbolLiteral node) {
+    // TODO(brianwilkerson) This isn't optimal because a Symbol is not a String.
+    StringBuffer buffer = new StringBuffer();
+    for (Token component in node.components) {
+      if (buffer.length > 0) {
+        buffer.writeCharCode(0x2E);
+      }
+      buffer.write(component.lexeme);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Return the constant value of the static constant represented by the given
+   * [element].
+   */
+  Object _getConstantValue(Element element) {
+    // TODO(brianwilkerson) Implement this
+//    if (element is FieldElement) {
+//      FieldElement field = element;
+//      if (field.isStatic && field.isConst) {
+//        //field.getConstantValue();
+//      }
+//      //    } else if (element instanceof VariableElement) {
+//      //      VariableElement variable = (VariableElement) element;
+//      //      if (variable.isStatic() && variable.isConst()) {
+//      //        //variable.getConstantValue();
+//      //      }
+//    }
+    return NOT_A_CONSTANT;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/element_locator.dart b/pkg/analyzer/lib/src/dart/ast/element_locator.dart
new file mode 100644
index 0000000..9761144
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/ast/element_locator.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.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+/// An object used to locate the [Element] associated with a given [AstNode].
+class ElementLocator {
+  /// Return the element associated with the given [node], or `null` if there
+  /// is no element associated with the node.
+  static Element locate(AstNode node) {
+    if (node == null) return null;
+
+    var mapper = new _ElementMapper();
+    return node.accept(mapper);
+  }
+}
+
+/// Visitor that maps nodes to elements.
+class _ElementMapper extends GeneralizingAstVisitor<Element> {
+  @override
+  Element visitAnnotation(Annotation node) {
+    return node.element;
+  }
+
+  @override
+  Element visitAssignmentExpression(AssignmentExpression node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitBinaryExpression(BinaryExpression node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitClassDeclaration(ClassDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
+  Element visitCompilationUnit(CompilationUnit node) {
+    return node.declaredElement;
+  }
+
+  @override
+  Element visitConstructorDeclaration(ConstructorDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
+  Element visitExportDirective(ExportDirective node) {
+    return node.element;
+  }
+
+  @override
+  Element visitFunctionDeclaration(FunctionDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
+  Element visitIdentifier(Identifier node) {
+    var parent = node.parent;
+    if (parent is Annotation) {
+      // Type name in Annotation
+      if (identical(parent.name, node) && parent.constructorName == null) {
+        return parent.element;
+      }
+    } else if (parent is ConstructorDeclaration) {
+      // Extra work to map Constructor Declarations to their associated
+      // Constructor Elements
+      var returnType = parent.returnType;
+      if (identical(returnType, node)) {
+        var name = parent.name;
+        if (name != null) {
+          return name.staticElement;
+        }
+        var element = node.staticElement;
+        if (element is ClassElement) {
+          return element.unnamedConstructor;
+        }
+      }
+    } else if (parent is LibraryIdentifier) {
+      var grandParent = parent.parent;
+      if (grandParent is PartOfDirective) {
+        var element = grandParent.element;
+        if (element is LibraryElement) {
+          return element.definingCompilationUnit;
+        }
+      } else if (grandParent is LibraryDirective) {
+        return grandParent.element;
+      }
+    }
+    return node.staticElement;
+  }
+
+  @override
+  Element visitImportDirective(ImportDirective node) {
+    return node.element;
+  }
+
+  @override
+  Element visitIndexExpression(IndexExpression node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitInstanceCreationExpression(InstanceCreationExpression node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitLibraryDirective(LibraryDirective node) {
+    return node.element;
+  }
+
+  @override
+  Element visitMethodDeclaration(MethodDeclaration node) {
+    return node.declaredElement;
+  }
+
+  @override
+  Element visitMethodInvocation(MethodInvocation node) {
+    return node.methodName.staticElement;
+  }
+
+  @override
+  Element visitPartOfDirective(PartOfDirective node) {
+    return node.element;
+  }
+
+  @override
+  Element visitPostfixExpression(PostfixExpression node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitPrefixedIdentifier(PrefixedIdentifier node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitPrefixExpression(PrefixExpression node) {
+    return node.staticElement;
+  }
+
+  @override
+  Element visitStringLiteral(StringLiteral node) {
+    var parent = node.parent;
+    if (parent is UriBasedDirective) {
+      return parent.uriElement;
+    }
+    return null;
+  }
+
+  @override
+  Element visitVariableDeclaration(VariableDeclaration node) {
+    return node.declaredElement;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 051fa2b..59cec6b 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/dart/ast/standard_ast_factory.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/exception/exception.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
@@ -17,6 +16,8 @@
 import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
 import 'package:meta/meta.dart';
 
+export 'package:analyzer/src/dart/ast/constant_evaluator.dart';
+
 /**
  * A function used to handle exceptions that are thrown by delegates while using
  * an [ExceptionHandlingDelegatingAstVisitor].
@@ -363,7 +364,7 @@
   @override
   DefaultFormalParameter visitDefaultFormalParameter(
           DefaultFormalParameter node) =>
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       astFactory.defaultFormalParameter(cloneNode(node.parameter), node.kind,
           cloneToken(node.separator), cloneNode(node.defaultValue));
 
@@ -470,6 +471,22 @@
           parameters: cloneNode(node.parameters));
 
   @override
+  ForEachPartsWithDeclaration visitForEachPartsWithDeclaration(
+          ForEachPartsWithDeclaration node) =>
+      astFactory.forEachPartsWithDeclaration(
+          loopVariable: cloneNode(node.loopVariable),
+          inKeyword: cloneToken(node.inKeyword),
+          iterable: cloneNode(node.iterable));
+
+  @override
+  ForEachPartsWithIdentifier visitForEachPartsWithIdentifier(
+          ForEachPartsWithIdentifier node) =>
+      astFactory.forEachPartsWithIdentifier(
+          identifier: cloneNode(node.identifier),
+          inKeyword: cloneToken(node.inKeyword),
+          iterable: cloneNode(node.iterable));
+
+  @override
   ForEachStatement visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (loopVariable == null) {
@@ -495,6 +512,14 @@
   }
 
   @override
+  ForElement visitForElement(ForElement node) => astFactory.forElement(
+      forKeyword: cloneToken(node.forKeyword),
+      leftParenthesis: cloneToken(node.leftParenthesis),
+      forLoopParts: cloneNode(node.forLoopParts),
+      rightParenthesis: cloneToken(node.rightParenthesis),
+      body: cloneNode(node.body));
+
+  @override
   FormalParameterList visitFormalParameterList(FormalParameterList node) =>
       astFactory.formalParameterList(
           cloneToken(node.leftParenthesis),
@@ -504,6 +529,26 @@
           cloneToken(node.rightParenthesis));
 
   @override
+  ForPartsWithDeclarations visitForPartsWithDeclarations(
+          ForPartsWithDeclarations node) =>
+      astFactory.forPartsWithDeclarations(
+          variables: cloneNode(node.variables),
+          leftSeparator: cloneToken(node.leftSeparator),
+          condition: cloneNode(node.condition),
+          rightSeparator: cloneToken(node.rightSeparator),
+          updaters: cloneNodeList(node.updaters));
+
+  @override
+  ForPartsWithExpression visitForPartsWithExpression(
+          ForPartsWithExpression node) =>
+      astFactory.forPartsWithExpression(
+          initialization: cloneNode(node.initialization),
+          leftSeparator: cloneToken(node.leftSeparator),
+          condition: cloneNode(node.condition),
+          rightSeparator: cloneToken(node.rightSeparator),
+          updaters: cloneNodeList(node.updaters));
+
+  @override
   ForStatement visitForStatement(ForStatement node) => astFactory.forStatement(
       cloneToken(node.forKeyword),
       cloneToken(node.leftParenthesis),
@@ -517,6 +562,15 @@
       cloneNode(node.body));
 
   @override
+  ForStatement2 visitForStatement2(ForStatement2 node) =>
+      astFactory.forStatement2(
+          forKeyword: cloneToken(node.forKeyword),
+          leftParenthesis: cloneToken(node.leftParenthesis),
+          forLoopParts: cloneNode(node.forLoopParts),
+          rightParenthesis: cloneToken(node.rightParenthesis),
+          body: cloneNode(node.body));
+
+  @override
   FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
       astFactory.functionDeclaration(
           cloneNode(node.documentationComment),
@@ -595,6 +649,16 @@
           cloneToken(node.keyword), cloneNodeList(node.hiddenNames));
 
   @override
+  IfElement visitIfElement(IfElement node) => astFactory.ifElement(
+      ifKeyword: cloneToken(node.ifKeyword),
+      leftParenthesis: cloneToken(node.leftParenthesis),
+      condition: cloneNode(node.condition),
+      rightParenthesis: cloneToken(node.rightParenthesis),
+      thenElement: cloneNode(node.thenElement),
+      elseKeyword: cloneToken(node.elseKeyword),
+      elseElement: cloneNode(node.elseElement));
+
+  @override
   IfStatement visitIfStatement(IfStatement node) => astFactory.ifStatement(
       cloneToken(node.ifKeyword),
       cloneToken(node.leftParenthesis),
@@ -704,6 +768,14 @@
       cloneToken(node.rightBracket));
 
   @override
+  ListLiteral2 visitListLiteral2(ListLiteral2 node) => astFactory.listLiteral2(
+      constKeyword: cloneToken(node.constKeyword),
+      typeArguments: cloneNode(node.typeArguments),
+      leftBracket: cloneToken(node.leftBracket),
+      elements: cloneNodeList(node.elements),
+      rightBracket: cloneToken(node.rightBracket));
+
+  @override
   MapLiteral visitMapLiteral(MapLiteral node) => astFactory.mapLiteral(
       cloneToken(node.constKeyword),
       cloneNode(node.typeArguments),
@@ -712,6 +784,14 @@
       cloneToken(node.rightBracket));
 
   @override
+  MapLiteral2 visitMapLiteral2(MapLiteral2 node) => astFactory.mapLiteral2(
+      constKeyword: cloneToken(node.constKeyword),
+      typeArguments: cloneNode(node.typeArguments),
+      leftBracket: cloneToken(node.leftBracket),
+      entries: cloneNodeList(node.entries),
+      rightBracket: cloneToken(node.rightBracket));
+
+  @override
   MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
       astFactory.mapLiteralEntry(cloneNode(node.key),
           cloneToken(node.separator), cloneNode(node.value));
@@ -854,6 +934,14 @@
       cloneToken(node.rightBracket));
 
   @override
+  SetLiteral2 visitSetLiteral2(SetLiteral2 node) => astFactory.setLiteral2(
+      constKeyword: cloneToken(node.constKeyword),
+      typeArguments: cloneNode(node.typeArguments),
+      leftBracket: cloneToken(node.leftBracket),
+      elements: cloneNodeList(node.elements),
+      rightBracket: cloneToken(node.rightBracket));
+
+  @override
   ShowCombinator visitShowCombinator(ShowCombinator node) => astFactory
       .showCombinator(cloneToken(node.keyword), cloneNodeList(node.shownNames));
 
@@ -878,6 +966,12 @@
       astFactory.simpleStringLiteral(cloneToken(node.literal), node.value);
 
   @override
+  SpreadElement visitSpreadElement(SpreadElement node) =>
+      astFactory.spreadElement(
+          spreadOperator: cloneToken(node.spreadOperator),
+          expression: cloneNode(node.expression));
+
+  @override
   StringInterpolation visitStringInterpolation(StringInterpolation node) =>
       astFactory.stringInterpolation(cloneNodeList(node.elements));
 
@@ -1439,7 +1533,7 @@
   bool visitDefaultFormalParameter(DefaultFormalParameter node) {
     DefaultFormalParameter other = _other as DefaultFormalParameter;
     return isEqualNodes(node.parameter, other.parameter) &&
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
         node.kind == other.kind &&
         isEqualTokens(node.separator, other.separator) &&
         isEqualNodes(node.defaultValue, other.defaultValue);
@@ -1563,6 +1657,22 @@
   }
 
   @override
+  bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    ForEachPartsWithDeclaration other = _other as ForEachPartsWithDeclaration;
+    return isEqualNodes(node.loopVariable, other.loopVariable) &&
+        isEqualTokens(node.inKeyword, other.inKeyword) &&
+        isEqualNodes(node.iterable, other.iterable);
+  }
+
+  @override
+  bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    ForEachPartsWithIdentifier other = _other as ForEachPartsWithIdentifier;
+    return isEqualNodes(node.identifier, other.identifier) &&
+        isEqualTokens(node.inKeyword, other.inKeyword) &&
+        isEqualNodes(node.iterable, other.iterable);
+  }
+
+  @override
   bool visitForEachStatement(ForEachStatement node) {
     ForEachStatement other = _other as ForEachStatement;
     return isEqualTokens(node.forKeyword, other.forKeyword) &&
@@ -1575,6 +1685,16 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    ForElement other = _other as ForElement;
+    return isEqualTokens(node.forKeyword, other.forKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.forLoopParts, other.forLoopParts) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
   bool visitFormalParameterList(FormalParameterList node) {
     FormalParameterList other = _other as FormalParameterList;
     return isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
@@ -1585,6 +1705,26 @@
   }
 
   @override
+  bool visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    ForPartsWithDeclarations other = _other as ForPartsWithDeclarations;
+    return isEqualNodes(node.variables, other.variables) &&
+        isEqualTokens(node.leftSeparator, other.leftSeparator) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightSeparator, other.rightSeparator) &&
+        _isEqualNodeLists(node.updaters, other.updaters);
+  }
+
+  @override
+  bool visitForPartsWithExpression(ForPartsWithExpression node) {
+    ForPartsWithExpression other = _other as ForPartsWithExpression;
+    return isEqualNodes(node.initialization, other.initialization) &&
+        isEqualTokens(node.leftSeparator, other.leftSeparator) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightSeparator, other.rightSeparator) &&
+        _isEqualNodeLists(node.updaters, other.updaters);
+  }
+
+  @override
   bool visitForStatement(ForStatement node) {
     ForStatement other = _other as ForStatement;
     return isEqualTokens(node.forKeyword, other.forKeyword) &&
@@ -1600,6 +1740,16 @@
   }
 
   @override
+  bool visitForStatement2(ForStatement2 node) {
+    ForStatement2 other = _other as ForStatement2;
+    return isEqualTokens(node.forKeyword, other.forKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.forLoopParts, other.forLoopParts) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.body, other.body);
+  }
+
+  @override
   bool visitFunctionDeclaration(FunctionDeclaration node) {
     FunctionDeclaration other = _other as FunctionDeclaration;
     return isEqualNodes(
@@ -1688,6 +1838,18 @@
   }
 
   @override
+  bool visitIfElement(IfElement node) {
+    IfElement other = _other as IfElement;
+    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.thenElement, other.thenElement) &&
+        isEqualTokens(node.elseKeyword, other.elseKeyword) &&
+        isEqualNodes(node.elseElement, other.elseElement);
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     IfStatement other = _other as IfStatement;
     return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
@@ -1812,6 +1974,16 @@
   }
 
   @override
+  bool visitListLiteral2(ListLiteral2 node) {
+    ListLiteral2 other = _other as ListLiteral2;
+    return isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.elements, other.elements) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
   bool visitMapLiteral(MapLiteral node) {
     MapLiteral other = _other as MapLiteral;
     return isEqualTokens(node.constKeyword, other.constKeyword) &&
@@ -1822,6 +1994,16 @@
   }
 
   @override
+  bool visitMapLiteral2(MapLiteral2 node) {
+    MapLiteral2 other = _other as MapLiteral2;
+    return isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.entries, other.entries) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
   bool visitMapLiteralEntry(MapLiteralEntry node) {
     MapLiteralEntry other = _other as MapLiteralEntry;
     return isEqualNodes(node.key, other.key) &&
@@ -2009,6 +2191,16 @@
   }
 
   @override
+  bool visitSetLiteral2(SetLiteral2 node) {
+    SetLiteral2 other = _other as SetLiteral2;
+    return isEqualTokens(node.constKeyword, other.constKeyword) &&
+        isEqualNodes(node.typeArguments, other.typeArguments) &&
+        isEqualTokens(node.leftBracket, other.leftBracket) &&
+        _isEqualNodeLists(node.elements, other.elements) &&
+        isEqualTokens(node.rightBracket, other.rightBracket);
+  }
+
+  @override
   bool visitShowCombinator(ShowCombinator node) {
     ShowCombinator other = _other as ShowCombinator;
     return isEqualTokens(node.keyword, other.keyword) &&
@@ -2040,6 +2232,13 @@
   }
 
   @override
+  bool visitSpreadElement(SpreadElement node) {
+    SpreadElement other = _other as SpreadElement;
+    return isEqualTokens(node.spreadOperator, other.spreadOperator) &&
+        isEqualNodes(node.expression, other.expression);
+  }
+
+  @override
   bool visitStringInterpolation(StringInterpolation node) {
     StringInterpolation other = _other as StringInterpolation;
     return _isEqualNodeLists(node.elements, other.elements);
@@ -2269,386 +2468,6 @@
 }
 
 /**
- * Instances of the class [ConstantEvaluator] evaluate constant expressions to
- * produce their compile-time value.
- *
- * According to the Dart Language Specification:
- *
- * > A constant expression is one of the following:
- * >
- * > * A literal number.
- * > * A literal boolean.
- * > * A literal string where any interpolated expression is a compile-time
- * >   constant that evaluates to a numeric, string or boolean value or to
- * >   **null**.
- * > * A literal symbol.
- * > * **null**.
- * > * A qualified reference to a static constant variable.
- * > * An identifier expression that denotes a constant variable, class or type
- * >   alias.
- * > * A constant constructor invocation.
- * > * A constant list literal.
- * > * A constant map literal.
- * > * A simple or qualified identifier denoting a top-level function or a
- * >   static method.
- * > * A parenthesized expression _(e)_ where _e_ is a constant expression.
- * > * <span>
- * >   An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
- * >   where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
- * >   expressions and <i>identical()</i> is statically bound to the predefined
- * >   dart function <i>identical()</i> discussed above.
- * >   </span>
- * > * <span>
- * >   An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i>
- * >   or <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
- * >   <i>e<sub>2</sub></i> are constant expressions that evaluate to a
- * >   numeric, string or boolean value.
- * >   </span>
- * > * <span>
- * >   An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
- * >   e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where
- * >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
- * >   expressions that evaluate to a boolean value.
- * >   </span>
- * > * <span>
- * >   An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
- * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
- * >   <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
- * >   e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
- * >   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
- * >   expressions that evaluate to an integer value or to <b>null</b>.
- * >   </span>
- * > * <span>
- * >   An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub>
- * >   -e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>,
- * >   <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub> ~/
- * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &gt; e<sub>2</sub></i>,
- * >   <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
- * >   e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or
- * >   <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>,
- * >   <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
- * >   that evaluate to a numeric value or to <b>null</b>.
- * >   </span>
- * > * <span>
- * >   An expression of one the form <i>e<sub>1</sub> + e<sub>2</sub></i>,
- * >   <i>e<sub>1</sub> -e<sub>2</sub></i> where <i>e<sub>1</sub> and
- * >   e<sub>2</sub></i> are constant expressions that evaluate to a numeric or
- * >   string value or to <b>null</b>.
- * >   </span>
- * > * <span>
- * >   An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
- * >   e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
- * >   <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
- * >   evaluates to a boolean value.
- * >   </span>
- *
- * However, this comment is now at least a little bit out of sync with the spec.
- *
- * The values returned by instances of this class are therefore `null` and
- * instances of the classes `Boolean`, `BigInteger`, `Double`, `String`, and
- * `DartObject`.
- *
- * In addition, this class defines several values that can be returned to
- * indicate various conditions encountered during evaluation. These are
- * documented with the static fields that define those values.
- */
-class ConstantEvaluator extends GeneralizingAstVisitor<Object> {
-  /**
-   * The value returned for expressions (or non-expression nodes) that are not
-   * compile-time constant expressions.
-   */
-  static Object NOT_A_CONSTANT = new Object();
-
-  @override
-  Object visitAdjacentStrings(AdjacentStrings node) {
-    StringBuffer buffer = new StringBuffer();
-    for (StringLiteral string in node.strings) {
-      Object value = string.accept(this);
-      if (identical(value, NOT_A_CONSTANT)) {
-        return value;
-      }
-      buffer.write(value);
-    }
-    return buffer.toString();
-  }
-
-  @override
-  Object visitBinaryExpression(BinaryExpression node) {
-    Object leftOperand = node.leftOperand.accept(this);
-    if (identical(leftOperand, NOT_A_CONSTANT)) {
-      return leftOperand;
-    }
-    Object rightOperand = node.rightOperand.accept(this);
-    if (identical(rightOperand, NOT_A_CONSTANT)) {
-      return rightOperand;
-    }
-    while (true) {
-      if (node.operator.type == TokenType.AMPERSAND) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand & rightOperand;
-        }
-      } else if (node.operator.type == TokenType.AMPERSAND_AMPERSAND) {
-        // boolean or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand && rightOperand;
-        }
-      } else if (node.operator.type == TokenType.BANG_EQ) {
-        // numeric, string, boolean, or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand != rightOperand;
-        } else if (leftOperand is num && rightOperand is num) {
-          return leftOperand != rightOperand;
-        } else if (leftOperand is String && rightOperand is String) {
-          return leftOperand != rightOperand;
-        }
-      } else if (node.operator.type == TokenType.BAR) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand | rightOperand;
-        }
-      } else if (node.operator.type == TokenType.BAR_BAR) {
-        // boolean or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand || rightOperand;
-        }
-      } else if (node.operator.type == TokenType.CARET) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand ^ rightOperand;
-        }
-      } else if (node.operator.type == TokenType.EQ_EQ) {
-        // numeric, string, boolean, or {@code null}
-        if (leftOperand is bool && rightOperand is bool) {
-          return leftOperand == rightOperand;
-        } else if (leftOperand is num && rightOperand is num) {
-          return leftOperand == rightOperand;
-        } else if (leftOperand is String && rightOperand is String) {
-          return leftOperand == rightOperand;
-        }
-      } else if (node.operator.type == TokenType.GT) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) > 0;
-        }
-      } else if (node.operator.type == TokenType.GT_EQ) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) >= 0;
-        }
-      } else if (node.operator.type == TokenType.GT_GT) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand >> rightOperand;
-        }
-      } else if (node.operator.type == TokenType.LT) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) < 0;
-        }
-      } else if (node.operator.type == TokenType.LT_EQ) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.compareTo(rightOperand) <= 0;
-        }
-      } else if (node.operator.type == TokenType.LT_LT) {
-        // integer or {@code null}
-        if (leftOperand is int && rightOperand is int) {
-          return leftOperand << rightOperand;
-        }
-      } else if (node.operator.type == TokenType.MINUS) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand - rightOperand;
-        }
-      } else if (node.operator.type == TokenType.PERCENT) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand.remainder(rightOperand);
-        }
-      } else if (node.operator.type == TokenType.PLUS) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand + rightOperand;
-        }
-        if (leftOperand is String && rightOperand is String) {
-          return leftOperand + rightOperand;
-        }
-      } else if (node.operator.type == TokenType.STAR) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand * rightOperand;
-        }
-      } else if (node.operator.type == TokenType.SLASH) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand / rightOperand;
-        }
-      } else if (node.operator.type == TokenType.TILDE_SLASH) {
-        // numeric or {@code null}
-        if (leftOperand is num && rightOperand is num) {
-          return leftOperand ~/ rightOperand;
-        }
-      }
-      break;
-    }
-    // TODO(brianwilkerson) This doesn't handle numeric conversions.
-    return visitExpression(node);
-  }
-
-  @override
-  Object visitBooleanLiteral(BooleanLiteral node) => node.value ? true : false;
-
-  @override
-  Object visitDoubleLiteral(DoubleLiteral node) => node.value;
-
-  @override
-  Object visitIntegerLiteral(IntegerLiteral node) => node.value;
-
-  @override
-  Object visitInterpolationExpression(InterpolationExpression node) {
-    Object value = node.expression.accept(this);
-    if (value == null || value is bool || value is String || value is num) {
-      return value;
-    }
-    return NOT_A_CONSTANT;
-  }
-
-  @override
-  Object visitInterpolationString(InterpolationString node) => node.value;
-
-  @override
-  Object visitListLiteral(ListLiteral node) {
-    List<Object> list = new List<Object>();
-    for (Expression element in node.elements) {
-      Object value = element.accept(this);
-      if (identical(value, NOT_A_CONSTANT)) {
-        return value;
-      }
-      list.add(value);
-    }
-    return list;
-  }
-
-  @override
-  Object visitMapLiteral(MapLiteral node) {
-    Map<String, Object> map = new HashMap<String, Object>();
-    for (MapLiteralEntry entry in node.entries) {
-      Object key = entry.key.accept(this);
-      Object value = entry.value.accept(this);
-      if (key is String && !identical(value, NOT_A_CONSTANT)) {
-        map[key] = value;
-      } else {
-        return NOT_A_CONSTANT;
-      }
-    }
-    return map;
-  }
-
-  @override
-  Object visitMethodInvocation(MethodInvocation node) => visitNode(node);
-
-  @override
-  Object visitNode(AstNode node) => NOT_A_CONSTANT;
-
-  @override
-  Object visitNullLiteral(NullLiteral node) => null;
-
-  @override
-  Object visitParenthesizedExpression(ParenthesizedExpression node) =>
-      node.expression.accept(this);
-
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) =>
-      _getConstantValue(null);
-
-  @override
-  Object visitPrefixExpression(PrefixExpression node) {
-    Object operand = node.operand.accept(this);
-    if (identical(operand, NOT_A_CONSTANT)) {
-      return operand;
-    }
-    while (true) {
-      if (node.operator.type == TokenType.BANG) {
-        if (identical(operand, true)) {
-          return false;
-        } else if (identical(operand, false)) {
-          return true;
-        }
-      } else if (node.operator.type == TokenType.TILDE) {
-        if (operand is int) {
-          return ~operand;
-        }
-      } else if (node.operator.type == TokenType.MINUS) {
-        if (operand == null) {
-          return null;
-        } else if (operand is num) {
-          return -operand;
-        }
-      } else {}
-      break;
-    }
-    return NOT_A_CONSTANT;
-  }
-
-  @override
-  Object visitPropertyAccess(PropertyAccess node) => _getConstantValue(null);
-
-  @override
-  Object visitSimpleIdentifier(SimpleIdentifier node) =>
-      _getConstantValue(null);
-
-  @override
-  Object visitSimpleStringLiteral(SimpleStringLiteral node) => node.value;
-
-  @override
-  Object visitStringInterpolation(StringInterpolation node) {
-    StringBuffer buffer = new StringBuffer();
-    for (InterpolationElement element in node.elements) {
-      Object value = element.accept(this);
-      if (identical(value, NOT_A_CONSTANT)) {
-        return value;
-      }
-      buffer.write(value);
-    }
-    return buffer.toString();
-  }
-
-  @override
-  Object visitSymbolLiteral(SymbolLiteral node) {
-    // TODO(brianwilkerson) This isn't optimal because a Symbol is not a String.
-    StringBuffer buffer = new StringBuffer();
-    for (Token component in node.components) {
-      if (buffer.length > 0) {
-        buffer.writeCharCode(0x2E);
-      }
-      buffer.write(component.lexeme);
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * Return the constant value of the static constant represented by the given
-   * [element].
-   */
-  Object _getConstantValue(Element element) {
-    // TODO(brianwilkerson) Implement this
-//    if (element is FieldElement) {
-//      FieldElement field = element;
-//      if (field.isStatic && field.isConst) {
-//        //field.getConstantValue();
-//      }
-//      //    } else if (element instanceof VariableElement) {
-//      //      VariableElement variable = (VariableElement) element;
-//      //      if (variable.isStatic() && variable.isConst()) {
-//      //        //variable.getConstantValue();
-//      //      }
-//    }
-    return NOT_A_CONSTANT;
-  }
-}
-
-/**
  * A recursive AST visitor that is used to run over [Expression]s to determine
  * whether the expression is composed by at least one deferred
  * [PrefixedIdentifier].
@@ -2679,138 +2498,6 @@
 }
 
 /**
- * An object used to locate the [Element] associated with a given [AstNode].
- */
-class ElementLocator {
-  /**
-   * Return the element associated with the given [node], or `null` if there is
-   * no element associated with the node.
-   */
-  static Element locate(AstNode node) {
-    if (node == null) {
-      return null;
-    }
-    ElementLocator_ElementMapper mapper = new ElementLocator_ElementMapper();
-    return node.accept(mapper);
-  }
-}
-
-/**
- * Visitor that maps nodes to elements.
- */
-class ElementLocator_ElementMapper extends GeneralizingAstVisitor<Element> {
-  @override
-  Element visitAnnotation(Annotation node) => node.element;
-
-  @override
-  Element visitAssignmentExpression(AssignmentExpression node) =>
-      node.staticElement;
-
-  @override
-  Element visitBinaryExpression(BinaryExpression node) => node.staticElement;
-
-  @override
-  Element visitClassDeclaration(ClassDeclaration node) => node.declaredElement;
-
-  @override
-  Element visitCompilationUnit(CompilationUnit node) => node.declaredElement;
-
-  @override
-  Element visitConstructorDeclaration(ConstructorDeclaration node) =>
-      node.declaredElement;
-
-  @override
-  Element visitExportDirective(ExportDirective node) => node.element;
-
-  @override
-  Element visitFunctionDeclaration(FunctionDeclaration node) =>
-      node.declaredElement;
-
-  @override
-  Element visitIdentifier(Identifier node) {
-    AstNode parent = node.parent;
-    if (parent is Annotation) {
-      // Type name in Annotation
-      if (identical(parent.name, node) && parent.constructorName == null) {
-        return parent.element;
-      }
-    } else if (parent is ConstructorDeclaration) {
-      // Extra work to map Constructor Declarations to their associated
-      // Constructor Elements
-      Identifier returnType = parent.returnType;
-      if (identical(returnType, node)) {
-        SimpleIdentifier name = parent.name;
-        if (name != null) {
-          return name.staticElement;
-        }
-        Element element = node.staticElement;
-        if (element is ClassElement) {
-          return element.unnamedConstructor;
-        }
-      }
-    } else if (parent is LibraryIdentifier) {
-      AstNode grandParent = parent.parent;
-      if (grandParent is PartOfDirective) {
-        Element element = grandParent.element;
-        if (element is LibraryElement) {
-          return element.definingCompilationUnit;
-        }
-      } else if (grandParent is LibraryDirective) {
-        return grandParent.element;
-      }
-    }
-    return node.staticElement;
-  }
-
-  @override
-  Element visitImportDirective(ImportDirective node) => node.element;
-
-  @override
-  Element visitIndexExpression(IndexExpression node) => node.staticElement;
-
-  @override
-  Element visitInstanceCreationExpression(InstanceCreationExpression node) =>
-      node.staticElement;
-
-  @override
-  Element visitLibraryDirective(LibraryDirective node) => node.element;
-
-  @override
-  Element visitMethodDeclaration(MethodDeclaration node) =>
-      node.declaredElement;
-
-  @override
-  Element visitMethodInvocation(MethodInvocation node) =>
-      node.methodName.staticElement;
-
-  @override
-  Element visitPartOfDirective(PartOfDirective node) => node.element;
-
-  @override
-  Element visitPostfixExpression(PostfixExpression node) => node.staticElement;
-
-  @override
-  Element visitPrefixedIdentifier(PrefixedIdentifier node) =>
-      node.staticElement;
-
-  @override
-  Element visitPrefixExpression(PrefixExpression node) => node.staticElement;
-
-  @override
-  Element visitStringLiteral(StringLiteral node) {
-    AstNode parent = node.parent;
-    if (parent is UriBasedDirective) {
-      return parent.uriElement;
-    }
-    return null;
-  }
-
-  @override
-  Element visitVariableDeclaration(VariableDeclaration node) =>
-      node.declaredElement;
-}
-
-/**
  * A [DelegatingAstVisitor] that will additionally catch all exceptions from the
  * delegates without stopping the visiting. A function must be provided that
  * will be invoked for each such exception.
@@ -3272,6 +2959,22 @@
           parameters: _cloneNode(node.parameters));
 
   @override
+  ForEachPartsWithDeclaration visitForEachPartsWithDeclaration(
+          ForEachPartsWithDeclaration node) =>
+      astFactory.forEachPartsWithDeclaration(
+          loopVariable: _cloneNode(node.loopVariable),
+          inKeyword: _mapToken(node.inKeyword),
+          iterable: _cloneNode(node.iterable));
+
+  @override
+  ForEachPartsWithIdentifier visitForEachPartsWithIdentifier(
+          ForEachPartsWithIdentifier node) =>
+      astFactory.forEachPartsWithIdentifier(
+          identifier: _cloneNode(node.identifier),
+          inKeyword: _mapToken(node.inKeyword),
+          iterable: _cloneNode(node.iterable));
+
+  @override
   ForEachStatement visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (loopVariable == null) {
@@ -3297,6 +3000,14 @@
   }
 
   @override
+  ForElement visitForElement(ForElement node) => astFactory.forElement(
+      forKeyword: _mapToken(node.forKeyword),
+      leftParenthesis: _mapToken(node.leftParenthesis),
+      forLoopParts: _cloneNode(node.forLoopParts),
+      rightParenthesis: _mapToken(node.rightParenthesis),
+      body: _cloneNode(node.body));
+
+  @override
   FormalParameterList visitFormalParameterList(FormalParameterList node) =>
       astFactory.formalParameterList(
           _mapToken(node.leftParenthesis),
@@ -3306,6 +3017,26 @@
           _mapToken(node.rightParenthesis));
 
   @override
+  ForPartsWithDeclarations visitForPartsWithDeclarations(
+          ForPartsWithDeclarations node) =>
+      astFactory.forPartsWithDeclarations(
+          variables: _cloneNode(node.variables),
+          leftSeparator: _mapToken(node.leftSeparator),
+          condition: _cloneNode(node.condition),
+          rightSeparator: _mapToken(node.rightSeparator),
+          updaters: _cloneNodeList(node.updaters));
+
+  @override
+  ForPartsWithExpression visitForPartsWithExpression(
+          ForPartsWithExpression node) =>
+      astFactory.forPartsWithExpression(
+          initialization: _cloneNode(node.initialization),
+          leftSeparator: _mapToken(node.leftSeparator),
+          condition: _cloneNode(node.condition),
+          rightSeparator: _mapToken(node.rightSeparator),
+          updaters: _cloneNodeList(node.updaters));
+
+  @override
   ForStatement visitForStatement(ForStatement node) => astFactory.forStatement(
       _mapToken(node.forKeyword),
       _mapToken(node.leftParenthesis),
@@ -3319,6 +3050,15 @@
       _cloneNode(node.body));
 
   @override
+  ForStatement2 visitForStatement2(ForStatement2 node) =>
+      astFactory.forStatement2(
+          forKeyword: _mapToken(node.forKeyword),
+          leftParenthesis: _mapToken(node.leftParenthesis),
+          forLoopParts: _cloneNode(node.forLoopParts),
+          rightParenthesis: _mapToken(node.rightParenthesis),
+          body: _cloneNode(node.body));
+
+  @override
   FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) =>
       astFactory.functionDeclaration(
           _cloneNode(node.documentationComment),
@@ -3409,6 +3149,16 @@
           _mapToken(node.keyword), _cloneNodeList(node.hiddenNames));
 
   @override
+  IfElement visitIfElement(IfElement node) => astFactory.ifElement(
+      ifKeyword: _mapToken(node.ifKeyword),
+      leftParenthesis: _mapToken(node.leftParenthesis),
+      condition: _cloneNode(node.condition),
+      rightParenthesis: _mapToken(node.rightParenthesis),
+      thenElement: _cloneNode(node.thenElement),
+      elseKeyword: _mapToken(node.elseKeyword),
+      elseElement: _cloneNode(node.elseElement));
+
+  @override
   IfStatement visitIfStatement(IfStatement node) => astFactory.ifStatement(
       _mapToken(node.ifKeyword),
       _mapToken(node.leftParenthesis),
@@ -3546,6 +3296,14 @@
   }
 
   @override
+  ListLiteral2 visitListLiteral2(ListLiteral2 node) => astFactory.listLiteral2(
+      constKeyword: _mapToken(node.constKeyword),
+      typeArguments: _cloneNode(node.typeArguments),
+      leftBracket: _mapToken(node.leftBracket),
+      elements: _cloneNodeList(node.elements),
+      rightBracket: _mapToken(node.rightBracket));
+
+  @override
   MapLiteral visitMapLiteral(MapLiteral node) {
     MapLiteral copy = astFactory.mapLiteral(
         _mapToken(node.constKeyword),
@@ -3558,6 +3316,14 @@
   }
 
   @override
+  MapLiteral2 visitMapLiteral2(MapLiteral2 node) => astFactory.mapLiteral2(
+      constKeyword: _mapToken(node.constKeyword),
+      typeArguments: _cloneNode(node.typeArguments),
+      leftBracket: _mapToken(node.leftBracket),
+      entries: _cloneNodeList(node.entries),
+      rightBracket: _mapToken(node.rightBracket));
+
+  @override
   MapLiteralEntry visitMapLiteralEntry(MapLiteralEntry node) =>
       astFactory.mapLiteralEntry(_cloneNode(node.key),
           _mapToken(node.separator), _cloneNode(node.value));
@@ -3747,6 +3513,14 @@
   }
 
   @override
+  SetLiteral2 visitSetLiteral2(SetLiteral2 node) => astFactory.setLiteral2(
+      constKeyword: _mapToken(node.constKeyword),
+      typeArguments: _cloneNode(node.typeArguments),
+      leftBracket: _mapToken(node.leftBracket),
+      elements: _cloneNodeList(node.elements),
+      rightBracket: _mapToken(node.rightBracket));
+
+  @override
   ShowCombinator visitShowCombinator(ShowCombinator node) => astFactory
       .showCombinator(_mapToken(node.keyword), _cloneNodeList(node.shownNames));
 
@@ -3789,6 +3563,12 @@
   }
 
   @override
+  SpreadElement visitSpreadElement(SpreadElement node) =>
+      astFactory.spreadElement(
+          spreadOperator: _mapToken(node.spreadOperator),
+          expression: _cloneNode(node.expression));
+
+  @override
   StringInterpolation visitStringInterpolation(StringInterpolation node) {
     StringInterpolation copy =
         astFactory.stringInterpolation(_cloneNodeList(node.elements));
@@ -4663,6 +4443,34 @@
   }
 
   @override
+  bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    if (identical(node.loopVariable, _oldNode)) {
+      (node as ForEachPartsWithDeclarationImpl).loopVariable =
+          _newNode as DeclaredIdentifier;
+      return true;
+    } else if (identical(node.iterable, _oldNode)) {
+      (node as ForEachPartsWithDeclarationImpl).iterable =
+          _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    if (identical(node.identifier, _oldNode)) {
+      (node as ForEachPartsWithIdentifierImpl).identifier =
+          _newNode as SimpleIdentifier;
+      return true;
+    } else if (identical(node.iterable, _oldNode)) {
+      (node as ForEachPartsWithIdentifierImpl).iterable =
+          _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitForEachStatement(ForEachStatement node) {
     if (identical(node.loopVariable, _oldNode)) {
       node.loopVariable = _newNode as DeclaredIdentifier;
@@ -4681,6 +4489,18 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    if (identical(node.forLoopParts, _oldNode)) {
+      (node as ForElementImpl).forLoopParts = _newNode as ForLoopParts;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      (node as ForElementImpl).body = _newNode as CollectionElement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitFormalParameterList(FormalParameterList node) {
     if (_replaceInList(node.parameters)) {
       return true;
@@ -4689,6 +4509,36 @@
   }
 
   @override
+  bool visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    if (identical(node.variables, _oldNode)) {
+      (node as ForPartsWithDeclarationsImpl).variables =
+          _newNode as VariableDeclarationList;
+      return true;
+    } else if (identical(node.condition, _oldNode)) {
+      (node as ForPartsWithDeclarationsImpl).condition = _newNode as Expression;
+      return true;
+    } else if (_replaceInList(node.updaters)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
+  bool visitForPartsWithExpression(ForPartsWithExpression node) {
+    if (identical(node.initialization, _oldNode)) {
+      (node as ForPartsWithExpressionImpl).initialization =
+          _newNode as Expression;
+      return true;
+    } else if (identical(node.condition, _oldNode)) {
+      (node as ForPartsWithExpressionImpl).condition = _newNode as Expression;
+      return true;
+    } else if (_replaceInList(node.updaters)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitForStatement(ForStatement node) {
     if (identical(node.variables, _oldNode)) {
       node.variables = _newNode as VariableDeclarationList;
@@ -4709,6 +4559,18 @@
   }
 
   @override
+  bool visitForStatement2(ForStatement2 node) {
+    if (identical(node.forLoopParts, _oldNode)) {
+      (node as ForStatement2Impl).forLoopParts = _newNode as ForLoopParts;
+      return true;
+    } else if (identical(node.body, _oldNode)) {
+      (node as ForStatement2Impl).body = _newNode as Statement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitFunctionDeclaration(FunctionDeclaration node) {
     if (identical(node.returnType, _oldNode)) {
       node.returnType = _newNode as TypeAnnotation;
@@ -4827,6 +4689,21 @@
   }
 
   @override
+  bool visitIfElement(IfElement node) {
+    if (identical(node.condition, _oldNode)) {
+      (node as IfElementImpl).condition = _newNode as Expression;
+      return true;
+    } else if (identical(node.thenElement, _oldNode)) {
+      (node as IfElementImpl).thenElement = _newNode as CollectionElement;
+      return true;
+    } else if (identical(node.elseElement, _oldNode)) {
+      (node as IfElementImpl).elseElement = _newNode as CollectionElement;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     if (identical(node.condition, _oldNode)) {
       node.condition = _newNode as Expression;
@@ -4955,6 +4832,17 @@
   }
 
   @override
+  bool visitListLiteral2(ListLiteral2 node) {
+    if (identical(node.typeArguments, _oldNode)) {
+      (node as ListLiteral2Impl).typeArguments = _newNode as TypeArgumentList;
+      return true;
+    } else if (_replaceInList(node.elements)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitMapLiteral(MapLiteral node) {
     if (_replaceInList(node.entries)) {
       return true;
@@ -4963,6 +4851,17 @@
   }
 
   @override
+  bool visitMapLiteral2(MapLiteral2 node) {
+    if (identical(node.typeArguments, _oldNode)) {
+      (node as MapLiteral2Impl).typeArguments = _newNode as TypeArgumentList;
+      return true;
+    } else if (_replaceInList(node.entries)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitMapLiteralEntry(MapLiteralEntry node) {
     if (identical(node.key, _oldNode)) {
       node.key = _newNode as Expression;
@@ -5199,6 +5098,17 @@
   }
 
   @override
+  bool visitSetLiteral2(SetLiteral2 node) {
+    if (identical(node.typeArguments, _oldNode)) {
+      (node as SetLiteral2Impl).typeArguments = _newNode as TypeArgumentList;
+      return true;
+    } else if (_replaceInList(node.elements)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitShowCombinator(ShowCombinator node) {
     if (_replaceInList(node.shownNames)) {
       return true;
@@ -5222,6 +5132,15 @@
   bool visitSimpleStringLiteral(SimpleStringLiteral node) => visitNode(node);
 
   @override
+  bool visitSpreadElement(SpreadElement node) {
+    if (identical(node.expression, _oldNode)) {
+      (node as SpreadElementImpl).expression = _newNode as Expression;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitStringInterpolation(StringInterpolation node) {
     if (_replaceInList(node.elements)) {
       return true;
@@ -5824,7 +5743,7 @@
     DefaultFormalParameter toNode = this._toNode as DefaultFormalParameter;
     return _and(
         _isEqualNodes(node.parameter, toNode.parameter),
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
         node.kind == toNode.kind,
         _isEqualTokens(node.separator, toNode.separator),
         _isEqualNodes(node.defaultValue, toNode.defaultValue));
@@ -5958,6 +5877,26 @@
   }
 
   @override
+  bool visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    ForEachPartsWithDeclaration toNode =
+        this._toNode as ForEachPartsWithDeclaration;
+    return _and(
+        _isEqualNodes(node.loopVariable, toNode.loopVariable),
+        _isEqualTokens(node.inKeyword, toNode.inKeyword),
+        _isEqualNodes(node.iterable, toNode.iterable));
+  }
+
+  @override
+  bool visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    ForEachPartsWithIdentifier toNode =
+        this._toNode as ForEachPartsWithIdentifier;
+    return _and(
+        _isEqualNodes(node.identifier, toNode.identifier),
+        _isEqualTokens(node.inKeyword, toNode.inKeyword),
+        _isEqualNodes(node.iterable, toNode.iterable));
+  }
+
+  @override
   bool visitForEachStatement(ForEachStatement node) {
     ForEachStatement toNode = this._toNode as ForEachStatement;
     return _and(
@@ -5972,6 +5911,17 @@
   }
 
   @override
+  bool visitForElement(ForElement node) {
+    ForElement toNode = this._toNode as ForElement;
+    return _and(
+        _isEqualTokens(node.forKeyword, toNode.forKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.body, toNode.body));
+  }
+
+  @override
   bool visitFormalParameterList(FormalParameterList node) {
     FormalParameterList toNode = this._toNode as FormalParameterList;
     return _and(
@@ -5983,6 +5933,28 @@
   }
 
   @override
+  bool visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    ForPartsWithDeclarations toNode = this._toNode as ForPartsWithDeclarations;
+    return _and(
+        _isEqualNodes(node.variables, toNode.variables),
+        _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
+        _isEqualNodes(node.condition, toNode.condition),
+        _isEqualTokens(node.rightSeparator, toNode.rightSeparator),
+        _isEqualNodeLists(node.updaters, toNode.updaters));
+  }
+
+  @override
+  bool visitForPartsWithExpression(ForPartsWithExpression node) {
+    ForPartsWithExpression toNode = this._toNode as ForPartsWithExpression;
+    return _and(
+        _isEqualNodes(node.initialization, toNode.initialization),
+        _isEqualTokens(node.leftSeparator, toNode.leftSeparator),
+        _isEqualNodes(node.condition, toNode.condition),
+        _isEqualTokens(node.rightSeparator, toNode.rightSeparator),
+        _isEqualNodeLists(node.updaters, toNode.updaters));
+  }
+
+  @override
   bool visitForStatement(ForStatement node) {
     ForStatement toNode = this._toNode as ForStatement;
     return _and(
@@ -5999,6 +5971,17 @@
   }
 
   @override
+  bool visitForStatement2(ForStatement2 node) {
+    ForStatement2 toNode = this._toNode as ForStatement2;
+    return _and(
+        _isEqualTokens(node.forKeyword, toNode.forKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.forLoopParts, toNode.forLoopParts),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.body, toNode.body));
+  }
+
+  @override
   bool visitFunctionDeclaration(FunctionDeclaration node) {
     FunctionDeclaration toNode = this._toNode as FunctionDeclaration;
     return _and(
@@ -6112,6 +6095,19 @@
   }
 
   @override
+  bool visitIfElement(IfElement node) {
+    IfElement toNode = this._toNode as IfElement;
+    return _and(
+        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.condition, toNode.condition),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.thenElement, toNode.thenElement),
+        _isEqualTokens(node.elseKeyword, toNode.elseKeyword),
+        _isEqualNodes(node.elseElement, toNode.elseElement));
+  }
+
+  @override
   bool visitIfStatement(IfStatement node) {
     IfStatement toNode = this._toNode as IfStatement;
     return _and(
@@ -6277,6 +6273,21 @@
   }
 
   @override
+  bool visitListLiteral2(ListLiteral2 node) {
+    ListLiteral2 toNode = this._toNode as ListLiteral2;
+    if (_and(
+        _isEqualTokens(node.constKeyword, toNode.constKeyword),
+        _isEqualNodes(node.typeArguments, toNode.typeArguments),
+        _isEqualTokens(node.leftBracket, toNode.leftBracket),
+        _isEqualNodeLists(node.elements, toNode.elements),
+        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+      toNode.staticType = node.staticType;
+      return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitMapLiteral(MapLiteral node) {
     MapLiteral toNode = this._toNode as MapLiteral;
     if (_and(
@@ -6292,6 +6303,21 @@
   }
 
   @override
+  bool visitMapLiteral2(MapLiteral2 node) {
+    MapLiteral2 toNode = this._toNode as MapLiteral2;
+    if (_and(
+        _isEqualTokens(node.constKeyword, toNode.constKeyword),
+        _isEqualNodes(node.typeArguments, toNode.typeArguments),
+        _isEqualTokens(node.leftBracket, toNode.leftBracket),
+        _isEqualNodeLists(node.entries, toNode.entries),
+        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+      toNode.staticType = node.staticType;
+      return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitMapLiteralEntry(MapLiteralEntry node) {
     MapLiteralEntry toNode = this._toNode as MapLiteralEntry;
     return _and(
@@ -6545,6 +6571,21 @@
   }
 
   @override
+  bool visitSetLiteral2(SetLiteral2 node) {
+    SetLiteral2 toNode = this._toNode as SetLiteral2;
+    if (_and(
+        _isEqualTokens(node.constKeyword, toNode.constKeyword),
+        _isEqualNodes(node.typeArguments, toNode.typeArguments),
+        _isEqualTokens(node.leftBracket, toNode.leftBracket),
+        _isEqualNodeLists(node.elements, toNode.elements),
+        _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+      toNode.staticType = node.staticType;
+      return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitShowCombinator(ShowCombinator node) {
     ShowCombinator toNode = this._toNode as ShowCombinator;
     return _and(_isEqualTokens(node.keyword, toNode.keyword),
@@ -6591,6 +6632,13 @@
   }
 
   @override
+  bool visitSpreadElement(SpreadElement node) {
+    SpreadElement toNode = this._toNode as SpreadElement;
+    return _and(_isEqualTokens(node.spreadOperator, toNode.spreadOperator),
+        _isEqualNodes(node.expression, toNode.expression));
+  }
+
+  @override
   bool visitStringInterpolation(StringInterpolation node) {
     StringInterpolation toNode = this._toNode as StringInterpolation;
     if (_isEqualNodeLists(node.elements, toNode.elements)) {
@@ -6991,6 +7039,12 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _addToScope(node.loopVariable.identifier);
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (loopVariable != null) {
@@ -7000,6 +7054,12 @@
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _addVariables(node.variables.variables);
+    super.visitForPartsWithDeclarations(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     if (!identical(_immediateChild, node.variables) && node.variables != null) {
       _addVariables(node.variables.variables);
@@ -7483,6 +7543,20 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _visitNode(node.loopVariable);
+    _writer.print(' in ');
+    _visitNode(node.iterable);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    _visitNode(node.identifier);
+    _writer.print(' in ');
+    _visitNode(node.iterable);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (node.awaitKeyword != null) {
@@ -7501,6 +7575,14 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    _writer.print('for (');
+    _visitNode(node.forLoopParts);
+    _writer.print(') ');
+    _visitNode(node.body);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     String groupEnd = null;
     _writer.print('(');
@@ -7529,6 +7611,24 @@
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _visitNode(node.variables);
+    _writer.print(';');
+    _visitNodeWithPrefix(' ', node.condition);
+    _writer.print(';');
+    _visitNodeListWithSeparatorAndPrefix(' ', node.updaters, ', ');
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    _visitNode(node.initialization);
+    _writer.print(';');
+    _visitNodeWithPrefix(' ', node.condition);
+    _writer.print(';');
+    _visitNodeListWithSeparatorAndPrefix(" ", node.updaters, ', ');
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     Expression initialization = node.initialization;
     _writer.print("for (");
@@ -7546,6 +7646,14 @@
   }
 
   @override
+  void visitForStatement2(ForStatement2 node) {
+    _writer.print('for (');
+    _visitNode(node.forLoopParts);
+    _writer.print(') ');
+    _visitNode(node.body);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
     _visitTokenWithSuffix(node.externalKeyword, " ");
@@ -7626,6 +7734,15 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    _writer.print('if (');
+    _visitNode(node.condition);
+    _writer.print(') ');
+    _visitNode(node.thenElement);
+    _visitNodeWithPrefix(' else ', node.elseElement);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     _writer.print("if (");
     _visitNode(node.condition);
@@ -7743,6 +7860,15 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    _visitTokenWithSuffix(node.constKeyword, ' ');
+    _visitNode(node.typeArguments);
+    _writer.print('[');
+    _visitNodeListWithSeparator(node.elements, ', ');
+    _writer.print(']');
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     if (node.constKeyword != null) {
       _writer.print(node.constKeyword.lexeme);
@@ -7755,6 +7881,15 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    _visitTokenWithSuffix(node.constKeyword, ' ');
+    _visitNode(node.typeArguments);
+    _writer.print('{');
+    _visitNodeListWithSeparator(node.entries, ', ');
+    _writer.print('}');
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     _visitNode(node.key);
     _writer.print(" : ");
@@ -7931,6 +8066,15 @@
   }
 
   @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    _visitTokenWithSuffix(node.constKeyword, ' ');
+    _visitNode(node.typeArguments);
+    _writer.print('{');
+    _visitNodeListWithSeparator(node.elements, ', ');
+    _writer.print('}');
+  }
+
+  @override
   void visitShowCombinator(ShowCombinator node) {
     _writer.print("show ");
     _visitNodeListWithSeparator(node.shownNames, ", ");
@@ -7959,6 +8103,12 @@
   }
 
   @override
+  void visitSpreadElement(SpreadElement node) {
+    _writer.print(node.spreadOperator.lexeme);
+    _visitNode(node.expression);
+  }
+
+  @override
   void visitStringInterpolation(StringInterpolation node) {
     _visitNodeList(node.elements);
   }
@@ -8720,6 +8870,20 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    safelyVisitNode(node.loopVariable);
+    sink.write(' in ');
+    safelyVisitNode(node.iterable);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    safelyVisitNode(node.identifier);
+    sink.write(' in ');
+    safelyVisitNode(node.iterable);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (node.awaitKeyword != null) {
@@ -8738,6 +8902,14 @@
   }
 
   @override
+  void visitForElement(ForElement node) {
+    sink.write('for (');
+    safelyVisitNode(node.forLoopParts);
+    sink.write(') ');
+    safelyVisitNode(node.body);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     String groupEnd = null;
     sink.write('(');
@@ -8766,6 +8938,24 @@
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    safelyVisitNode(node.variables);
+    sink.write(';');
+    safelyVisitNodeWithPrefix(' ', node.condition);
+    sink.write(';');
+    safelyVisitNodeListWithSeparatorAndPrefix(' ', node.updaters, ', ');
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    safelyVisitNode(node.initialization);
+    sink.write(';');
+    safelyVisitNodeWithPrefix(' ', node.condition);
+    sink.write(';');
+    safelyVisitNodeListWithSeparatorAndPrefix(" ", node.updaters, ', ');
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     Expression initialization = node.initialization;
     sink.write("for (");
@@ -8783,6 +8973,14 @@
   }
 
   @override
+  void visitForStatement2(ForStatement2 node) {
+    sink.write('for (');
+    safelyVisitNode(node.forLoopParts);
+    sink.write(') ');
+    safelyVisitNode(node.body);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
     safelyVisitTokenWithSuffix(node.externalKeyword, " ");
@@ -8863,6 +9061,15 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    sink.write('if (');
+    safelyVisitNode(node.condition);
+    sink.write(') ');
+    safelyVisitNode(node.thenElement);
+    safelyVisitNodeWithPrefix(' else ', node.elseElement);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     sink.write("if (");
     safelyVisitNode(node.condition);
@@ -8969,10 +9176,7 @@
 
   @override
   void visitListLiteral(ListLiteral node) {
-    if (node.constKeyword != null) {
-      sink.write(node.constKeyword.lexeme);
-      sink.write(' ');
-    }
+    safelyVisitTokenWithSuffix(node.constKeyword, ' ');
     safelyVisitNodeWithSuffix(node.typeArguments, " ");
     sink.write("[");
     safelyVisitNodeListWithSeparator(node.elements, ", ");
@@ -8980,11 +9184,17 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    safelyVisitTokenWithSuffix(node.constKeyword, ' ');
+    safelyVisitNode(node.typeArguments);
+    sink.write('[');
+    safelyVisitNodeListWithSeparator(node.elements, ', ');
+    sink.write(']');
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
-    if (node.constKeyword != null) {
-      sink.write(node.constKeyword.lexeme);
-      sink.write(' ');
-    }
+    safelyVisitTokenWithSuffix(node.constKeyword, ' ');
     safelyVisitNodeWithSuffix(node.typeArguments, " ");
     sink.write("{");
     safelyVisitNodeListWithSeparator(node.entries, ", ");
@@ -8992,6 +9202,15 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    safelyVisitTokenWithSuffix(node.constKeyword, ' ');
+    safelyVisitNode(node.typeArguments);
+    sink.write('{');
+    safelyVisitNodeListWithSeparator(node.entries, ', ');
+    sink.write('}');
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     safelyVisitNode(node.key);
     sink.write(" : ");
@@ -9157,10 +9376,7 @@
 
   @override
   void visitSetLiteral(SetLiteral node) {
-    if (node.constKeyword != null) {
-      sink.write(node.constKeyword.lexeme);
-      sink.write(' ');
-    }
+    safelyVisitTokenWithSuffix(node.constKeyword, ' ');
     safelyVisitNodeWithSuffix(node.typeArguments, " ");
     sink.write("{");
     safelyVisitNodeListWithSeparator(node.elements, ", ");
@@ -9168,6 +9384,15 @@
   }
 
   @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    safelyVisitTokenWithSuffix(node.constKeyword, ' ');
+    safelyVisitNode(node.typeArguments);
+    sink.write('{');
+    safelyVisitNodeListWithSeparator(node.elements, ', ');
+    sink.write('}');
+  }
+
+  @override
   void visitShowCombinator(ShowCombinator node) {
     sink.write("show ");
     safelyVisitNodeListWithSeparator(node.shownNames, ", ");
@@ -9196,6 +9421,12 @@
   }
 
   @override
+  void visitSpreadElement(SpreadElement node) {
+    sink.write(node.spreadOperator.lexeme);
+    safelyVisitNode(node.expression);
+  }
+
+  @override
   void visitStringInterpolation(StringInterpolation node) {
     safelyVisitNodeList(node.elements);
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 453c439..024eca2 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -103,7 +103,7 @@
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     if (node.constKeyword != null) {
       _validateConstructorInitializers(node);
-      _validateFieldInitializers(node.parent as ClassDeclaration, node);
+      _validateFieldInitializers(node.parent, node);
     }
     _validateDefaultValues(node.parameters);
     super.visitConstructorDeclaration(node);
@@ -548,8 +548,8 @@
   ///
   /// @param classDeclaration the class which should be validated
   /// @param errorSite the site at which errors should be reported.
-  void _validateFieldInitializers(
-      ClassDeclaration classDeclaration, ConstructorDeclaration errorSite) {
+  void _validateFieldInitializers(ClassOrMixinDeclaration classDeclaration,
+      ConstructorDeclaration errorSite) {
     NodeList<ClassMember> members = classDeclaration.members;
     for (ClassMember member in members) {
       if (member is FieldDeclaration && !member.isStatic) {
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 545cd6c..ee9cc60 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1360,6 +1360,30 @@
   }
 
   @override
+  DartObjectImpl visitListLiteral2(ListLiteral2 node) {
+    if (!node.isConst) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL, node);
+      return null;
+    }
+    bool errorOccurred = false;
+    List<DartObjectImpl> list = [];
+    for (CollectionElement element in node.elements) {
+      errorOccurred = errorOccurred | _addElementsToList(list, element);
+    }
+    if (errorOccurred) {
+      return null;
+    }
+    DartType nodeType = node.staticType;
+    DartType elementType =
+        nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
+            ? nodeType.typeArguments[0]
+            : _typeProvider.dynamicType;
+    InterfaceType listType = _typeProvider.listType.instantiate([elementType]);
+    return new DartObjectImpl(listType, new ListState(list));
+  }
+
+  @override
   DartObjectImpl visitMapLiteral(MapLiteral node) {
     if (!node.isConst) {
       _errorReporter.reportErrorForNode(
@@ -1397,6 +1421,36 @@
   }
 
   @override
+  DartObjectImpl visitMapLiteral2(MapLiteral2 node) {
+    if (!node.isConst) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL, node);
+      return null;
+    }
+    Map<DartObjectImpl, DartObjectImpl> map = {};
+    bool errorOccurred = false;
+    for (CollectionElement element in node.entries) {
+      errorOccurred = errorOccurred | _addElementsToMap(map, element);
+    }
+    if (errorOccurred) {
+      return null;
+    }
+    DartType keyType = _typeProvider.dynamicType;
+    DartType valueType = _typeProvider.dynamicType;
+    DartType nodeType = node.staticType;
+    if (nodeType is InterfaceType) {
+      var typeArguments = nodeType.typeArguments;
+      if (typeArguments.length >= 2) {
+        keyType = typeArguments[0];
+        valueType = typeArguments[1];
+      }
+    }
+    InterfaceType mapType =
+        _typeProvider.mapType.instantiate([keyType, valueType]);
+    return new DartObjectImpl(mapType, new MapState(map));
+  }
+
+  @override
   DartObjectImpl visitMethodInvocation(MethodInvocation node) {
     Element element = node.methodName.staticElement;
     if (element is FunctionElement) {
@@ -1523,6 +1577,30 @@
   }
 
   @override
+  DartObjectImpl visitSetLiteral2(SetLiteral2 node) {
+    if (!node.isConst) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL, node);
+      return null;
+    }
+    bool errorOccurred = false;
+    Set<DartObjectImpl> set = new Set<DartObjectImpl>();
+    for (CollectionElement element in node.elements) {
+      errorOccurred = errorOccurred | _addElementsToSet(set, element);
+    }
+    if (errorOccurred) {
+      return null;
+    }
+    DartType nodeType = node.staticType;
+    DartType elementType =
+        nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
+            ? nodeType.typeArguments[0]
+            : _typeProvider.dynamicType;
+    InterfaceType setType = _typeProvider.setType.instantiate([elementType]);
+    return new DartObjectImpl(setType, new SetState(set));
+  }
+
+  @override
   DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
     if (_lexicalEnvironment != null &&
         _lexicalEnvironment.containsKey(node.name)) {
@@ -1577,6 +1655,119 @@
   DartObjectImpl visitTypeName(TypeName node) => visitTypeAnnotation(node);
 
   /**
+   * Add the entries produced by evaluating the given collection [element] to
+   * the given [list]. Return `true` if the evaluation of one or more of the
+   * elements failed.
+   */
+  bool _addElementsToList(List<DartObject> list, CollectionElement element) {
+    if (element is IfElement) {
+      DartObjectImpl conditionResult = element.condition.accept(this);
+      bool conditionValue = conditionResult?.toBoolValue();
+      if (conditionValue == null) {
+        return true;
+      } else if (conditionValue) {
+        return _addElementsToList(list, element.thenElement);
+      } else if (element.elseElement != null) {
+        return _addElementsToList(list, element.elseElement);
+      }
+      return false;
+    } else if (element is Expression) {
+      DartObjectImpl value = element.accept(this);
+      if (value == null) {
+        return true;
+      }
+      list.add(value);
+      return false;
+    } else if (element is SpreadElement) {
+      DartObjectImpl elementResult = element.expression.accept(this);
+      List<DartObject> value = elementResult?.toListValue();
+      if (value == null) {
+        return true;
+      }
+      list.addAll(value);
+      return false;
+    }
+    // This error should have been reported elsewhere.
+    return true;
+  }
+
+  /**
+   * Add the entries produced by evaluating the given map [element] to the given
+   * [map]. Return `true` if the evaluation of one or more of the entries
+   * failed.
+   */
+  bool _addElementsToMap(
+      Map<DartObjectImpl, DartObjectImpl> map, CollectionElement element) {
+    if (element is IfElement) {
+      DartObjectImpl conditionResult = element.condition.accept(this);
+      bool conditionValue = conditionResult?.toBoolValue();
+      if (conditionValue == null) {
+        return true;
+      } else if (conditionValue) {
+        return _addElementsToMap(map, element.thenElement);
+      } else if (element.elseElement != null) {
+        return _addElementsToMap(map, element.elseElement);
+      }
+      return false;
+    } else if (element is MapLiteralEntry) {
+      DartObjectImpl keyResult = element.key.accept(this);
+      DartObjectImpl valueResult = element.value.accept(this);
+      if (keyResult == null || valueResult == null) {
+        return true;
+      }
+      map[keyResult] = valueResult;
+      return false;
+    } else if (element is SpreadElement) {
+      DartObjectImpl elementResult = element.expression.accept(this);
+      Map<DartObject, DartObject> value = elementResult?.toMapValue();
+      if (value == null) {
+        return true;
+      }
+      map.addAll(value);
+      return false;
+    }
+    // This error should have been reported elsewhere.
+    return true;
+  }
+
+  /**
+   * Add the entries produced by evaluating the given collection [element] to
+   * the given [set]. Return `true` if the evaluation of one or more of the
+   * elements failed.
+   */
+  bool _addElementsToSet(Set<DartObject> set, CollectionElement element) {
+    if (element is IfElement) {
+      DartObjectImpl conditionResult = element.condition.accept(this);
+      bool conditionValue = conditionResult?.toBoolValue();
+      if (conditionValue == null) {
+        return true;
+      } else if (conditionValue) {
+        return _addElementsToSet(set, element.thenElement);
+      } else if (element.elseElement != null) {
+        return _addElementsToSet(set, element.elseElement);
+      }
+      return false;
+    } else if (element is Expression) {
+      DartObjectImpl value = element.accept(this);
+      if (value == null) {
+        return true;
+      }
+      set.add(value);
+      return false;
+    } else if (element is SpreadElement) {
+      DartObjectImpl elementResult = element.expression.accept(this);
+      Set<DartObject> value = elementResult?.toSetValue();
+      if (value == null) {
+        return true;
+      }
+      set.addAll(value);
+      return false;
+    }
+    // This error should have been reported elsewhere.
+    return true;
+  }
+
+  /**
    * Create an error associated with the given [node]. The error will have the
    * given error [code].
    */
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 6a806c3..95223de 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -95,6 +95,16 @@
   }
 
   @override
+  ListLiteral2 visitListLiteral2(ListLiteral2 node) {
+    ListLiteral2 literal = super.visitListLiteral2(node);
+    literal.staticType = node.staticType;
+    if (node.constKeyword == null && node.isConst) {
+      literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
+    }
+    return literal;
+  }
+
+  @override
   MapLiteral visitMapLiteral(MapLiteral node) {
     MapLiteral literal = super.visitMapLiteral(node);
     literal.staticType = node.staticType;
@@ -105,6 +115,16 @@
   }
 
   @override
+  MapLiteral2 visitMapLiteral2(MapLiteral2 node) {
+    MapLiteral2 literal = super.visitMapLiteral2(node);
+    literal.staticType = node.staticType;
+    if (node.constKeyword == null && node.isConst) {
+      literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
+    }
+    return literal;
+  }
+
+  @override
   RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
       RedirectingConstructorInvocation node) {
     RedirectingConstructorInvocation invocation =
@@ -124,6 +144,16 @@
   }
 
   @override
+  SetLiteral2 visitSetLiteral2(SetLiteral2 node) {
+    SetLiteral2 literal = super.visitSetLiteral2(node);
+    literal.staticType = node.staticType;
+    if (node.constKeyword == null && node.isConst) {
+      literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
+    }
+    return literal;
+  }
+
+  @override
   SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
     SimpleIdentifier identifier = super.visitSimpleIdentifier(node);
     identifier.staticElement = node.staticElement;
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 4666351..c95889d 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -171,12 +171,6 @@
  * A representation of an instance of a Dart class.
  */
 class DartObjectImpl implements DartObject {
-  /**
-   * An empty list of objects.
-   */
-  @deprecated
-  static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[];
-
   @override
   final ParameterizedType type;
 
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 5d439ae..e213e85 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -1179,8 +1179,16 @@
         new LocalVariableElementImpl.forNode(variableName);
     _setCodeRange(element, node);
     element.metadata = _createElementAnnotations(node.metadata);
-    ForEachStatement statement = node.parent as ForEachStatement;
-    element.setVisibleRange(statement.offset, statement.length);
+
+    var parent = node.parent;
+    if (parent is ForEachStatement) {
+      var statement = parent;
+      element.setVisibleRange(statement.offset, statement.length);
+    } else if (parent is ForEachPartsWithDeclaration) {
+      var statement = parent.parent;
+      element.setVisibleRange(statement.offset, statement.length);
+    }
+
     element.isConst = node.isConst;
     element.isFinal = node.isFinal;
     if (node.type == null) {
@@ -1432,7 +1440,7 @@
     parameter.isConst = node.isConst;
     parameter.isExplicitlyCovariant = node.parameter.covariantKeyword != null;
     parameter.isFinal = node.isFinal;
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     parameter.parameterKind = node.kind;
     // visible range
     _setParameterVisibleRange(node, parameter);
@@ -1459,7 +1467,7 @@
       parameter.isConst = node.isConst;
       parameter.isExplicitlyCovariant = node.covariantKeyword != null;
       parameter.isFinal = node.isFinal;
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       parameter.parameterKind = node.kind;
       _currentHolder.addParameter(parameter);
       parameterName.staticElement = parameter;
@@ -1488,7 +1496,7 @@
       parameter.isConst = node.isConst;
       parameter.isExplicitlyCovariant = node.covariantKeyword != null;
       parameter.isFinal = node.isFinal;
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       parameter.parameterKind = node.kind;
       _setParameterVisibleRange(node, parameter);
       _currentHolder.addParameter(parameter);
@@ -1531,7 +1539,7 @@
       parameter.isConst = node.isConst;
       parameter.isExplicitlyCovariant = node.covariantKeyword != null;
       parameter.isFinal = node.isFinal;
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       parameter.parameterKind = node.kind;
       _setParameterVisibleRange(node, parameter);
       if (node.type == null) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index f764d36..56e2f2a 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1133,7 +1133,7 @@
           }
           implicitParameter.isConst = superParameter.isConst;
           implicitParameter.isFinal = superParameter.isFinal;
-          // ignore: deprecated_member_use
+          // ignore: deprecated_member_use_from_same_package
           implicitParameter.parameterKind = superParameter.parameterKind;
           implicitParameter.isSynthetic = true;
           implicitParameter.type =
@@ -3868,7 +3868,7 @@
           buffer.write(", ");
         }
         ParameterElement parameter = parameters[i];
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
         ParameterKind parameterKind = parameter.parameterKind;
         if (parameterKind != kind) {
           if (closing != null) {
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
index 799dbc8..b2fb92f 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
@@ -43,10 +43,37 @@
 
   InheritanceManager2(this._typeSystem);
 
-  /// Return the member with the given [name] that the [type] inherits from the
-  /// mixins, superclasses, or interfaces; or `null` if no member is inherited.
+  /// Return the most specific signature of the member with the given [name]
+  /// that the [type] inherits from the mixins, superclasses, or interfaces;
+  /// or `null` if no member is inherited because the member is not declared
+  /// at all, or because there is no the most specific signature.
+  ///
+  /// This is equivalent to `getInheritedMap(type)[name]`.
   FunctionType getInherited(InterfaceType type, Name name) {
-    return getOverridden(type, name)?.last;
+    return getInheritedMap(type)[name];
+  }
+
+  /// Return signatures of all concrete members that the given [type] inherits
+  /// from the superclasses and mixins.
+  Map<Name, FunctionType> getInheritedConcreteMap(InterfaceType type) {
+    var interface = getInterface(type);
+    return interface._superImplemented.last;
+  }
+
+  /// Return the mapping from names to most specific signatures of members
+  /// inherited from the super-interfaces (superclasses, mixins, and
+  /// interfaces).  If there is no most specific signature for a name, the
+  /// corresponding name will not be included.
+  Map<Name, FunctionType> getInheritedMap(InterfaceType type) {
+    var interface = getInterface(type);
+    if (interface._inheritedMap == null) {
+      interface._inheritedMap = {};
+      _findMostSpecificFromNamedCandidates(
+        interface._inheritedMap,
+        interface._overridden,
+      );
+    }
+    return interface._inheritedMap;
   }
 
   /// Return the interface of the given [type].  It might include private
@@ -84,8 +111,10 @@
       }
 
       if (classElement.isMixin) {
+        var superClassCandidates = <Name, List<FunctionType>>{};
         for (var constraint in type.superclassConstraints) {
           var interfaceObj = getInterface(constraint);
+          _addCandidates(superClassCandidates, interfaceObj);
           _addCandidates(namedCandidates, interfaceObj);
         }
 
@@ -93,9 +122,9 @@
 
         // `mixin M on S1, S2 {}` can call using `super` any instance member
         // from its superclass constraints, whether it is abstract or concrete.
-        Map<Name, FunctionType> mixinSuperClass = {};
-        _findMostSpecificFromNamedCandidates(mixinSuperClass, namedCandidates);
-        superImplemented.add(mixinSuperClass);
+        var superClass = <Name, FunctionType>{};
+        _findMostSpecificFromNamedCandidates(superClass, superClassCandidates);
+        superImplemented.add(superClass);
       } else {
         if (type.superclass != null) {
           superInterface = getInterface(type.superclass);
@@ -114,9 +143,9 @@
 
           implemented = <Name, FunctionType>{}
             ..addAll(implemented)
-            ..addAll(interfaceObj.implementedForMixing);
+            ..addAll(interfaceObj._implementedForMixing);
           superImplemented.add(implemented);
-          implementedForMixing.addAll(interfaceObj.implementedForMixing);
+          implementedForMixing.addAll(interfaceObj._implementedForMixing);
         }
       }
     } finally {
@@ -150,12 +179,12 @@
     var noSuchMethodForwarders = Set<Name>();
     if (classElement.isAbstract) {
       if (superInterface != null) {
-        noSuchMethodForwarders = superInterface.noSuchMethodForwarders;
+        noSuchMethodForwarders = superInterface._noSuchMethodForwarders;
       }
     } else {
       var noSuchMethod = implemented[_noSuchMethodName]?.element;
       if (noSuchMethod != null && !_isDeclaredInObject(noSuchMethod)) {
-        var superForwarders = superInterface?.noSuchMethodForwarders;
+        var superForwarders = superInterface?._noSuchMethodForwarders;
         for (var name in map.keys) {
           if (!implemented.containsKey(name) ||
               superForwarders != null && superForwarders.contains(name)) {
@@ -417,11 +446,11 @@
   final Map<Name, FunctionType> implemented;
 
   /// The set of names that are `noSuchMethod` forwarders in [implemented].
-  final Set<Name> noSuchMethodForwarders;
+  final Set<Name> _noSuchMethodForwarders;
 
   /// The map of names to their concrete implementations that can be mixed
   /// when this type is used as a mixin.
-  final Map<Name, FunctionType> implementedForMixing;
+  final Map<Name, FunctionType> _implementedForMixing;
 
   /// The map of names to their signatures from the mixins, superclasses,
   /// or interfaces.
@@ -438,16 +467,25 @@
   /// members of the class.
   final List<Conflict> conflicts;
 
+  /// The map of names to the most specific signatures from the mixins,
+  /// superclasses, or interfaces.
+  Map<Name, FunctionType> _inheritedMap;
+
   Interface._(
     this.map,
     this.declared,
     this.implemented,
-    this.noSuchMethodForwarders,
-    this.implementedForMixing,
+    this._noSuchMethodForwarders,
+    this._implementedForMixing,
     this._overridden,
     this._superImplemented,
     this.conflicts,
   );
+
+  /// Return `true` if the [name] is implemented in the supertype.
+  bool isSuperImplemented(Name name) {
+    return _superImplemented.last.containsKey(name);
+  }
 }
 
 /// A public name, or a private name qualified by a library URI.
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 484458a..845d59d 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -636,7 +636,7 @@
         buffer.write(", ");
       }
       ParameterElement parameter = parameters[i];
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       ParameterKind parameterKind = parameter.parameterKind;
       if (parameterKind != kind) {
         if (closing != null) {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 6b7d311..85712c3 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -920,7 +920,7 @@
       return new ParameterElementImpl.synthetic(
           p.name,
           newType,
-          // ignore: deprecated_member_use
+          // ignore: deprecated_member_use_from_same_package
           p.parameterKind);
     }
 
@@ -1496,6 +1496,15 @@
   }
 
   @override
+  bool get isDartCoreBool {
+    ClassElement element = this.element;
+    if (element == null) {
+      return false;
+    }
+    return element.name == "bool" && element.library.isDartCore;
+  }
+
+  @override
   bool get isDartCoreFunction {
     ClassElement element = this.element;
     if (element == null) {
@@ -2735,6 +2744,9 @@
   bool get isDartAsyncFutureOr => false;
 
   @override
+  bool get isDartCoreBool => false;
+
+  @override
   bool get isDartCoreFunction => false;
 
   @override
@@ -3717,7 +3729,7 @@
     int length = parameters.length;
     for (int i = 0; i < length; i++) {
       ParameterElement parameter = parameters[i];
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       if (parameter.parameterKind == kind) {
         TypeImpl type = parameter.type ?? DynamicTypeImpl.instance;
         if (typeArguments.length != 0 &&
@@ -3798,7 +3810,7 @@
       return new ParameterElementImpl.synthetic(
           p.name,
           newType,
-          // ignore: deprecated_member_use
+          // ignore: deprecated_member_use_from_same_package
           p.parameterKind);
     }
 
@@ -3853,7 +3865,7 @@
       return new ParameterElementImpl.synthetic(
           p.name,
           newType,
-          // ignore: deprecated_member_use
+          // ignore: deprecated_member_use_from_same_package
           p.parameterKind);
     }
 
@@ -3880,7 +3892,7 @@
   void _forEachParameterType(
       ParameterKind kind, Function(String name, DartType type) callback) {
     for (var parameter in parameters) {
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       if (parameter.parameterKind == kind) {
         callback(parameter.name, parameter.type);
       }
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 3c6f7f1..10c3f75 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -185,7 +185,7 @@
 
   @override
   String computeDocumentationComment() => wrappedUnit
-      .computeDocumentationComment(); // ignore: deprecated_member_use
+      .computeDocumentationComment(); // ignore: deprecated_member_use_from_same_package
 
   @deprecated
   @override
@@ -377,7 +377,7 @@
 
   @override
   String computeDocumentationComment() => wrappedImport
-      .computeDocumentationComment(); // ignore: deprecated_member_use
+      .computeDocumentationComment(); // ignore: deprecated_member_use_from_same_package
 
   @deprecated
   @override
@@ -599,8 +599,8 @@
   T accept<T>(ElementVisitor<T> visitor) => wrappedLib.accept(visitor);
 
   @override
-  String computeDocumentationComment() =>
-      wrappedLib.computeDocumentationComment(); // ignore: deprecated_member_use
+  String computeDocumentationComment() => wrappedLib
+      .computeDocumentationComment(); // ignore: deprecated_member_use_from_same_package
 
   @deprecated
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 62c6a8a..185e224 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -280,6 +280,17 @@
       const HintCode('INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER',
           "The member '{0}' can only be used within '{1}' or a test.");
 
+  /// This hint is generated anywhere where a private declaration is annotated
+  /// with `@visibleForTemplate` or `@visibleForTesting`.
+  ///
+  /// Parameters:
+  /// 0: the name of the member
+  /// 1: the name of the annotation
+  static const HintCode INVALID_VISIBILITY_ANNOTATION = const HintCode(
+      'INVALID_VISIBILITY_ANNOTATION',
+      "The member '{0}' is annotated with '{1}', but this annotation is only "
+      "meaningful on declarations of public members.");
+
   /**
    * Hint for the `x is double` type checks.
    */
diff --git a/pkg/analyzer/lib/src/dart/resolver/definite_assignment.dart b/pkg/analyzer/lib/src/dart/resolver/definite_assignment.dart
index 0b1cd1d..8edf986 100644
--- a/pkg/analyzer/lib/src/dart/resolver/definite_assignment.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/definite_assignment.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -546,6 +546,12 @@
     _statementToStackIndex[statement] = _stack.length;
   }
 
+  void beginForStatement2(ForStatement2 statement) {
+    // Not strongly necessary, because we discard everything anyway.
+    // Just for consistency, so that `break` is handled without `null`.
+    _statementToStackIndex[statement] = _stack.length;
+  }
+
   void beginForStatementBody() {
     _stack.add(_current); // break set
     _stack.add(_ElementSet.empty); // continue set
diff --git a/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
new file mode 100644
index 0000000..2f558cf
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/exit_detector.dart
@@ -0,0 +1,724 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+/// Instances of the class `ExitDetector` determine whether the visited AST node
+/// is guaranteed to terminate by executing a `return` statement, `throw`
+/// expression, `rethrow` expression, or simple infinite loop such as
+/// `while(true)`.
+class ExitDetector extends GeneralizingAstVisitor<bool> {
+  /// Set to `true` when a `break` is encountered, and reset to `false` when a
+  /// `do`, `while`, `for` or `switch` block is entered.
+  bool _enclosingBlockContainsBreak = false;
+
+  /// Set to `true` when a `continue` is encountered, and reset to `false` when
+  /// a `do`, `while`, `for` or `switch` block is entered.
+  bool _enclosingBlockContainsContinue = false;
+
+  /// Add node when a labelled `break` is encountered.
+  Set<AstNode> _enclosingBlockBreaksLabel = new Set<AstNode>();
+
+  @override
+  bool visitArgumentList(ArgumentList node) =>
+      _visitExpressions(node.arguments);
+
+  @override
+  bool visitAsExpression(AsExpression node) => _nodeExits(node.expression);
+
+  @override
+  bool visitAssertInitializer(AssertInitializer node) => false;
+
+  @override
+  bool visitAssertStatement(AssertStatement node) => false;
+
+  @override
+  bool visitAssignmentExpression(AssignmentExpression node) {
+    Expression leftHandSide = node.leftHandSide;
+    if (_nodeExits(leftHandSide)) {
+      return true;
+    }
+    TokenType operatorType = node.operator.type;
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
+        operatorType == TokenType.BAR_BAR_EQ ||
+        operatorType == TokenType.QUESTION_QUESTION_EQ) {
+      return false;
+    }
+    if (leftHandSide is PropertyAccess &&
+        leftHandSide.operator.type == TokenType.QUESTION_PERIOD) {
+      return false;
+    }
+    return _nodeExits(node.rightHandSide);
+  }
+
+  @override
+  bool visitAwaitExpression(AwaitExpression node) =>
+      _nodeExits(node.expression);
+
+  @override
+  bool visitBinaryExpression(BinaryExpression node) {
+    Expression lhsExpression = node.leftOperand;
+    Expression rhsExpression = node.rightOperand;
+    TokenType operatorType = node.operator.type;
+    // If the operator is ||, then only consider the RHS of the binary
+    // expression if the left hand side is the false literal.
+    // TODO(jwren) Do we want to take constant expressions into account,
+    // evaluate if(false) {} differently than if(<condition>), when <condition>
+    // evaluates to a constant false value?
+    if (operatorType == TokenType.BAR_BAR) {
+      if (lhsExpression is BooleanLiteral) {
+        if (!lhsExpression.value) {
+          return _nodeExits(rhsExpression);
+        }
+      }
+      return _nodeExits(lhsExpression);
+    }
+    // If the operator is &&, then only consider the RHS of the binary
+    // expression if the left hand side is the true literal.
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
+      if (lhsExpression is BooleanLiteral) {
+        if (lhsExpression.value) {
+          return _nodeExits(rhsExpression);
+        }
+      }
+      return _nodeExits(lhsExpression);
+    }
+    // If the operator is ??, then don't consider the RHS of the binary
+    // expression.
+    if (operatorType == TokenType.QUESTION_QUESTION) {
+      return _nodeExits(lhsExpression);
+    }
+    return _nodeExits(lhsExpression) || _nodeExits(rhsExpression);
+  }
+
+  @override
+  bool visitBlock(Block node) => _visitStatements(node.statements);
+
+  @override
+  bool visitBlockFunctionBody(BlockFunctionBody node) => _nodeExits(node.block);
+
+  @override
+  bool visitBreakStatement(BreakStatement node) {
+    _enclosingBlockContainsBreak = true;
+    if (node.label != null) {
+      _enclosingBlockBreaksLabel.add(node.target);
+    }
+    return false;
+  }
+
+  @override
+  bool visitCascadeExpression(CascadeExpression node) =>
+      _nodeExits(node.target) || _visitExpressions(node.cascadeSections);
+
+  @override
+  bool visitConditionalExpression(ConditionalExpression node) {
+    Expression conditionExpression = node.condition;
+    Expression thenStatement = node.thenExpression;
+    Expression elseStatement = node.elseExpression;
+    // TODO(jwren) Do we want to take constant expressions into account,
+    // evaluate if(false) {} differently than if(<condition>), when <condition>
+    // evaluates to a constant false value?
+    if (_nodeExits(conditionExpression)) {
+      return true;
+    }
+    if (thenStatement == null || elseStatement == null) {
+      return false;
+    }
+    return thenStatement.accept(this) && elseStatement.accept(this);
+  }
+
+  @override
+  bool visitContinueStatement(ContinueStatement node) {
+    _enclosingBlockContainsContinue = true;
+    return false;
+  }
+
+  @override
+  bool visitDoStatement(DoStatement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    bool outerContinueValue = _enclosingBlockContainsContinue;
+    _enclosingBlockContainsBreak = false;
+    _enclosingBlockContainsContinue = false;
+    try {
+      bool bodyExits = _nodeExits(node.body);
+      bool containsBreakOrContinue =
+          _enclosingBlockContainsBreak || _enclosingBlockContainsContinue;
+      // Even if we determine that the body "exits", there might be break or
+      // continue statements that actually mean it _doesn't_ always exit.
+      if (bodyExits && !containsBreakOrContinue) {
+        return true;
+      }
+      Expression conditionExpression = node.condition;
+      if (_nodeExits(conditionExpression)) {
+        return true;
+      }
+      // TODO(jwren) Do we want to take all constant expressions into account?
+      if (conditionExpression is BooleanLiteral) {
+        // If do {} while (true), and the body doesn't break, then return true.
+        if (conditionExpression.value && !_enclosingBlockContainsBreak) {
+          return true;
+        }
+      }
+      return false;
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+      _enclosingBlockContainsContinue = outerContinueValue;
+    }
+  }
+
+  @override
+  bool visitEmptyStatement(EmptyStatement node) => false;
+
+  @override
+  bool visitExpressionStatement(ExpressionStatement node) =>
+      _nodeExits(node.expression);
+
+  @override
+  bool visitForEachStatement(ForEachStatement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    try {
+      bool iterableExits = _nodeExits(node.iterable);
+      // Discard whether the for-each body exits; since the for-each iterable
+      // may be empty, execution may never enter the body, so it doesn't matter
+      // if it exits or not.  We still must visit the body, to accurately
+      // manage `_enclosingBlockBreaksLabel`.
+      _nodeExits(node.body);
+      return iterableExits;
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+  }
+
+  @override
+  bool visitForElement(ForElement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    try {
+      ForLoopParts forLoopParts = node.forLoopParts;
+      if (forLoopParts is ForParts) {
+        if (forLoopParts is ForPartsWithDeclarations) {
+          if (forLoopParts.variables != null &&
+              _visitVariableDeclarations(forLoopParts.variables.variables)) {
+            return true;
+          }
+        } else if (forLoopParts is ForPartsWithExpression) {
+          if (forLoopParts.initialization != null &&
+              _nodeExits(forLoopParts.initialization)) {
+            return true;
+          }
+        }
+        Expression conditionExpression = forLoopParts.condition;
+        if (conditionExpression != null && _nodeExits(conditionExpression)) {
+          return true;
+        }
+        if (_visitExpressions(forLoopParts.updaters)) {
+          return true;
+        }
+        bool blockReturns = _nodeExits(node.body);
+        // TODO(jwren) Do we want to take all constant expressions into account?
+        // If for(; true; ) (or for(;;)), and the body doesn't return or the body
+        // doesn't have a break, then return true.
+        bool implicitOrExplictTrue = conditionExpression == null ||
+            (conditionExpression is BooleanLiteral &&
+                conditionExpression.value);
+        if (implicitOrExplictTrue) {
+          if (blockReturns || !_enclosingBlockContainsBreak) {
+            return true;
+          }
+        }
+        return false;
+      } else if (forLoopParts is ForEachParts) {
+        bool iterableExits = _nodeExits(forLoopParts.iterable);
+        // Discard whether the for-each body exits; since the for-each iterable
+        // may be empty, execution may never enter the body, so it doesn't matter
+        // if it exits or not.  We still must visit the body, to accurately
+        // manage `_enclosingBlockBreaksLabel`.
+        _nodeExits(node.body);
+        return iterableExits;
+      }
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+    return false;
+  }
+
+  @override
+  bool visitForStatement(ForStatement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    try {
+      if (node.variables != null &&
+          _visitVariableDeclarations(node.variables.variables)) {
+        return true;
+      }
+      if (node.initialization != null && _nodeExits(node.initialization)) {
+        return true;
+      }
+      Expression conditionExpression = node.condition;
+      if (conditionExpression != null && _nodeExits(conditionExpression)) {
+        return true;
+      }
+      if (_visitExpressions(node.updaters)) {
+        return true;
+      }
+      bool blockReturns = _nodeExits(node.body);
+      // TODO(jwren) Do we want to take all constant expressions into account?
+      // If for(; true; ) (or for(;;)), and the body doesn't return or the body
+      // doesn't have a break, then return true.
+      bool implicitOrExplictTrue = conditionExpression == null ||
+          (conditionExpression is BooleanLiteral && conditionExpression.value);
+      if (implicitOrExplictTrue) {
+        if (blockReturns || !_enclosingBlockContainsBreak) {
+          return true;
+        }
+      }
+      return false;
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+  }
+
+  @override
+  bool visitForStatement2(ForStatement2 node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    ForLoopParts parts = node.forLoopParts;
+    try {
+      if (parts is ForEachParts) {
+        bool iterableExits = _nodeExits(parts.iterable);
+        // Discard whether the for-each body exits; since the for-each iterable
+        // may be empty, execution may never enter the body, so it doesn't matter
+        // if it exits or not.  We still must visit the body, to accurately
+        // manage `_enclosingBlockBreaksLabel`.
+        _nodeExits(node.body);
+        return iterableExits;
+      }
+      VariableDeclarationList variables;
+      Expression initialization;
+      Expression condition;
+      NodeList<Expression> updaters;
+      if (parts is ForPartsWithDeclarations) {
+        variables = parts.variables;
+        condition = parts.condition;
+        updaters = parts.updaters;
+      } else if (parts is ForPartsWithExpression) {
+        initialization = parts.initialization;
+        condition = parts.condition;
+        updaters = parts.updaters;
+      }
+      if (variables != null &&
+          _visitVariableDeclarations(variables.variables)) {
+        return true;
+      }
+      if (initialization != null && _nodeExits(initialization)) {
+        return true;
+      }
+      if (condition != null && _nodeExits(condition)) {
+        return true;
+      }
+      if (_visitExpressions(updaters)) {
+        return true;
+      }
+      bool blockReturns = _nodeExits(node.body);
+      // TODO(jwren) Do we want to take all constant expressions into account?
+      // If for(; true; ) (or for(;;)), and the body doesn't return or the body
+      // doesn't have a break, then return true.
+      bool implicitOrExplictTrue =
+          condition == null || (condition is BooleanLiteral && condition.value);
+      if (implicitOrExplictTrue) {
+        if (blockReturns || !_enclosingBlockContainsBreak) {
+          return true;
+        }
+      }
+      return false;
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+  }
+
+  @override
+  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
+      false;
+
+  @override
+  bool visitFunctionExpression(FunctionExpression node) => false;
+
+  @override
+  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    if (_nodeExits(node.function)) {
+      return true;
+    }
+    return node.argumentList.accept(this);
+  }
+
+  @override
+  bool visitGenericFunctionType(GenericFunctionType node) => false;
+
+  @override
+  bool visitIdentifier(Identifier node) => false;
+
+  @override
+  bool visitIfElement(IfElement node) {
+    Expression conditionExpression = node.condition;
+    CollectionElement thenElement = node.thenElement;
+    CollectionElement elseElement = node.elseElement;
+    if (_nodeExits(conditionExpression)) {
+      return true;
+    }
+
+    bool conditionValue = _knownConditionValue(conditionExpression);
+    if (conditionValue == true) {
+      return _nodeExits(thenElement);
+    } else if (conditionValue == false && elseElement != null) {
+      return _nodeExits(elseElement);
+    }
+
+    bool thenExits = _nodeExits(thenElement);
+    bool elseExits = _nodeExits(elseElement);
+    if (thenElement == null || elseElement == null) {
+      return false;
+    }
+    return thenExits && elseExits;
+  }
+
+  @override
+  bool visitIfStatement(IfStatement node) {
+    Expression conditionExpression = node.condition;
+    Statement thenStatement = node.thenStatement;
+    Statement elseStatement = node.elseStatement;
+    if (_nodeExits(conditionExpression)) {
+      return true;
+    }
+
+    bool conditionValue = _knownConditionValue(conditionExpression);
+    if (conditionValue == true) {
+      return _nodeExits(thenStatement);
+    } else if (conditionValue == false && elseStatement != null) {
+      return _nodeExits(elseStatement);
+    }
+
+    bool thenExits = _nodeExits(thenStatement);
+    bool elseExits = _nodeExits(elseStatement);
+    if (thenStatement == null || elseStatement == null) {
+      return false;
+    }
+    return thenExits && elseExits;
+  }
+
+  @override
+  bool visitIndexExpression(IndexExpression node) {
+    Expression target = node.realTarget;
+    if (_nodeExits(target)) {
+      return true;
+    }
+    if (_nodeExits(node.index)) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  bool visitInstanceCreationExpression(InstanceCreationExpression node) =>
+      _nodeExits(node.argumentList);
+
+  @override
+  bool visitIsExpression(IsExpression node) => node.expression.accept(this);
+
+  @override
+  bool visitLabel(Label node) => false;
+
+  @override
+  bool visitLabeledStatement(LabeledStatement node) {
+    try {
+      bool statementExits = _nodeExits(node.statement);
+      bool neverBrokeFromLabel =
+          !_enclosingBlockBreaksLabel.contains(node.statement);
+      return statementExits && neverBrokeFromLabel;
+    } finally {
+      _enclosingBlockBreaksLabel.remove(node.statement);
+    }
+  }
+
+  @override
+  bool visitListLiteral2(ListLiteral2 node) {
+    for (CollectionElement element in node.elements) {
+      if (_nodeExits(element)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool visitLiteral(Literal node) => false;
+
+  @override
+  bool visitMapLiteral2(MapLiteral2 node) {
+    for (CollectionElement entry in node.entries) {
+      if (_nodeExits(entry)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool visitMapLiteralEntry(MapLiteralEntry node) {
+    return _nodeExits(node.key) || _nodeExits(node.value);
+  }
+
+  @override
+  bool visitMethodInvocation(MethodInvocation node) {
+    Expression target = node.realTarget;
+    if (target != null) {
+      if (target.accept(this)) {
+        return true;
+      }
+      if (node.operator.type == TokenType.QUESTION_PERIOD) {
+        return false;
+      }
+    }
+    Element element = node.methodName.staticElement;
+    if (element != null && element.hasAlwaysThrows) {
+      return true;
+    }
+    return _nodeExits(node.argumentList);
+  }
+
+  @override
+  bool visitNamedExpression(NamedExpression node) =>
+      node.expression.accept(this);
+
+  @override
+  bool visitNode(AstNode node) {
+    throw new StateError(
+        'Missing a visit method for a node of type ${node.runtimeType}');
+  }
+
+  @override
+  bool visitParenthesizedExpression(ParenthesizedExpression node) =>
+      node.expression.accept(this);
+
+  @override
+  bool visitPostfixExpression(PostfixExpression node) => false;
+
+  @override
+  bool visitPrefixExpression(PrefixExpression node) => false;
+
+  @override
+  bool visitPropertyAccess(PropertyAccess node) {
+    Expression target = node.realTarget;
+    if (target != null && target.accept(this)) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  bool visitRethrowExpression(RethrowExpression node) => true;
+
+  @override
+  bool visitReturnStatement(ReturnStatement node) => true;
+
+  @override
+  bool visitSetLiteral2(SetLiteral2 node) {
+    for (CollectionElement element in node.elements) {
+      if (_nodeExits(element)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool visitSpreadElement(SpreadElement node) {
+    return _nodeExits(node.expression);
+  }
+
+  @override
+  bool visitSuperExpression(SuperExpression node) => false;
+
+  @override
+  bool visitSwitchCase(SwitchCase node) => _visitStatements(node.statements);
+
+  @override
+  bool visitSwitchDefault(SwitchDefault node) =>
+      _visitStatements(node.statements);
+
+  @override
+  bool visitSwitchStatement(SwitchStatement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    try {
+      bool hasDefault = false;
+      bool hasNonExitingCase = false;
+      List<SwitchMember> members = node.members;
+      for (int i = 0; i < members.length; i++) {
+        SwitchMember switchMember = members[i];
+        if (switchMember is SwitchDefault) {
+          hasDefault = true;
+          // If this is the last member and there are no statements, then it
+          // does not exit.
+          if (switchMember.statements.isEmpty && i + 1 == members.length) {
+            hasNonExitingCase = true;
+            continue;
+          }
+        }
+        // For switch members with no statements, don't visit the children.
+        // Otherwise, if there children statements don't exit, mark this as a
+        // non-exiting case.
+        if (!switchMember.statements.isEmpty && !switchMember.accept(this)) {
+          hasNonExitingCase = true;
+        }
+      }
+      if (hasNonExitingCase) {
+        return false;
+      }
+      // As all cases exit, return whether that list includes `default`.
+      return hasDefault;
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+  }
+
+  @override
+  bool visitThisExpression(ThisExpression node) => false;
+
+  @override
+  bool visitThrowExpression(ThrowExpression node) => true;
+
+  @override
+  bool visitTryStatement(TryStatement node) {
+    if (_nodeExits(node.finallyBlock)) {
+      return true;
+    }
+    if (!_nodeExits(node.body)) {
+      return false;
+    }
+    for (CatchClause c in node.catchClauses) {
+      if (!_nodeExits(c.body)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  bool visitTypeName(TypeName node) => false;
+
+  @override
+  bool visitVariableDeclaration(VariableDeclaration node) {
+    Expression initializer = node.initializer;
+    if (initializer != null) {
+      return initializer.accept(this);
+    }
+    return false;
+  }
+
+  @override
+  bool visitVariableDeclarationList(VariableDeclarationList node) =>
+      _visitVariableDeclarations(node.variables);
+
+  @override
+  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    NodeList<VariableDeclaration> variables = node.variables.variables;
+    for (int i = 0; i < variables.length; i++) {
+      if (variables[i].accept(this)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool visitWhileStatement(WhileStatement node) {
+    bool outerBreakValue = _enclosingBlockContainsBreak;
+    _enclosingBlockContainsBreak = false;
+    try {
+      Expression conditionExpression = node.condition;
+      if (conditionExpression.accept(this)) {
+        return true;
+      }
+      node.body.accept(this);
+      // TODO(jwren) Do we want to take all constant expressions into account?
+      if (conditionExpression is BooleanLiteral) {
+        // If while(true), and the body doesn't have a break, then return true.
+        // The body might be found to exit, but if there are any break
+        // statements, then it is a faulty finding. In other words:
+        //
+        // * If the body exits, and does not contain a break statement, then
+        //   it exits.
+        // * If the body does not exit, and does not contain a break statement,
+        //   then it loops infinitely (also an exit).
+        //
+        // As both conditions forbid any break statements to be found, the logic
+        // just boils down to checking [_enclosingBlockContainsBreak].
+        if (conditionExpression.value && !_enclosingBlockContainsBreak) {
+          return true;
+        }
+      }
+      return false;
+    } finally {
+      _enclosingBlockContainsBreak = outerBreakValue;
+    }
+  }
+
+  @override
+  bool visitYieldStatement(YieldStatement node) => _nodeExits(node.expression);
+
+  /// If the given [expression] has a known Boolean value, return the known
+  /// value, otherwise return `null`.
+  bool _knownConditionValue(Expression conditionExpression) {
+    // TODO(jwren) Do we want to take all constant expressions into account?
+    if (conditionExpression is BooleanLiteral) {
+      return conditionExpression.value;
+    }
+    return null;
+  }
+
+  /// Return `true` if the given [node] exits.
+  bool _nodeExits(AstNode node) {
+    if (node == null) {
+      return false;
+    }
+    return node.accept(this);
+  }
+
+  bool _visitExpressions(NodeList<Expression> expressions) {
+    for (int i = expressions.length - 1; i >= 0; i--) {
+      if (expressions[i].accept(this)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool _visitStatements(NodeList<Statement> statements) {
+    for (int i = 0; i < statements.length; i++) {
+      if (statements[i].accept(this)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool _visitVariableDeclarations(
+      NodeList<VariableDeclaration> variableDeclarations) {
+    for (int i = variableDeclarations.length - 1; i >= 0; i--) {
+      if (variableDeclarations[i].accept(this)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Return `true` if the given [node] exits.
+  static bool exits(AstNode node) {
+    return new ExitDetector()._nodeExits(node);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
new file mode 100644
index 0000000..1c8dc31
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis.dart
@@ -0,0 +1,1012 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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';
+
+/// Sets of variables that are potentially assigned in a node.
+class AssignedVariables {
+  static final emptySet = Set<VariableElement>();
+
+  /// Mapping from a loop [AstNode] to the set of variables that are
+  /// potentially assigned in this loop.
+  final Map<AstNode, Set<VariableElement>> _map = {};
+
+  /// The stack of nested loops.
+  final List<Set<VariableElement>> _stack = [];
+
+  /// Return the set of variables that are potentially assigned in the [loop].
+  Set<VariableElement> operator [](AstNode loop) {
+    return _map[loop] ?? emptySet;
+  }
+
+  void beginLoop() {
+    var set = Set<VariableElement>.identity();
+    _stack.add(set);
+  }
+
+  void endLoop(AstNode loop) {
+    _map[loop] = _stack.removeLast();
+  }
+
+  void write(VariableElement variable) {
+    for (var i = 0; i < _stack.length; ++i) {
+      _stack[i].add(variable);
+    }
+  }
+}
+
+class FlowAnalysis<T> {
+  final _identity = _State<T>(
+    false,
+    _ElementSet.empty,
+    _ElementSet.empty,
+    _ElementSet.empty,
+    const {},
+  );
+
+  /// The output list of variables that were read before they were written.
+  /// TODO(scheglov) use _ElementSet?
+  final List<LocalVariableElement> readBeforeWritten = [];
+
+  /// The [TypeOperations], used to access types, and check subtyping.
+  final TypeOperations<T> typeOperations;
+
+  /// The enclosing [FunctionBody], used to check for potential mutations.
+  final FunctionBody functionBody;
+
+  /// The stack of states of variables that are not definitely assigned.
+  final List<_State> _stack = [];
+
+  /// The mapping from labeled [Statement]s to the index in the [_stack]
+  /// where the first related element is located.  The number of elements
+  /// is statement specific.  Loops have two elements: `break` and `continue`
+  /// states.
+  final Map<Statement, int> _statementToStackIndex = {};
+
+  /// The list of all variables.
+  final List<VariableElement> _variables = [];
+
+  _State<T> _current;
+
+  /// The last boolean condition, for [_conditionTrue] and [_conditionFalse].
+  Expression _condition;
+
+  /// The state when [_condition] evaluates to `true`.
+  _State<T> _conditionTrue;
+
+  /// The state when [_condition] evaluates to `false`.
+  _State<T> _conditionFalse;
+
+  FlowAnalysis(this.typeOperations, this.functionBody) {
+    _current = _State<T>(
+      true,
+      _ElementSet.empty,
+      _ElementSet.empty,
+      _ElementSet.empty,
+      const {},
+    );
+  }
+
+  /// Return `true` if the current state is reachable.
+  bool get isReachable => _current.reachable;
+
+  /// Add a new [variable], which might be already [assigned].
+  void add(VariableElement variable, {bool assigned: false}) {
+    _variables.add(variable);
+    _current = _current.add(variable, assigned: assigned);
+  }
+
+  void conditional_elseBegin(ConditionalExpression node, bool isBool) {
+    var afterThen = _current;
+    var falseCondition = _stack.removeLast();
+
+    if (isBool) {
+      _conditionalEnd(node.thenExpression);
+      // Tail of the stack: falseThen, trueThen
+    }
+
+    _stack.add(afterThen);
+    _current = falseCondition;
+  }
+
+  void conditional_end(ConditionalExpression node, bool isBool) {
+    var afterThen = _stack.removeLast();
+    var afterElse = _current;
+
+    if (isBool) {
+      _conditionalEnd(node.elseExpression);
+      // Tail of the stack: falseThen, trueThen, falseElse, trueElse
+
+      var trueElse = _stack.removeLast();
+      var falseElse = _stack.removeLast();
+
+      var trueThen = _stack.removeLast();
+      var falseThen = _stack.removeLast();
+
+      var trueResult = _join(trueThen, trueElse);
+      var falseResult = _join(falseThen, falseElse);
+
+      _condition = node;
+      _conditionTrue = trueResult;
+      _conditionFalse = falseResult;
+    }
+
+    _current = _join(afterThen, afterElse);
+  }
+
+  void conditional_thenBegin(ConditionalExpression node) {
+    _conditionalEnd(node.condition);
+    // Tail of the stack: falseCondition, trueCondition
+
+    var trueCondition = _stack.removeLast();
+    _current = trueCondition;
+  }
+
+  /// The [node] checks that the [variable] is equal to `null`.
+  void conditionEqNull(BinaryExpression node, VariableElement variable) {
+    if (functionBody.isPotentiallyMutatedInClosure(variable)) {
+      return;
+    }
+
+    _condition = node;
+    _conditionTrue = _current.markNullable(variable);
+    _conditionFalse = _current.markNonNullable(variable);
+  }
+
+  /// The [node] checks that the [variable] is not equal to `null`.
+  void conditionNotEqNull(BinaryExpression node, VariableElement variable) {
+    if (functionBody.isPotentiallyMutatedInClosure(variable)) {
+      return;
+    }
+
+    _condition = node;
+    _conditionTrue = _current.markNonNullable(variable);
+    _conditionFalse = _current.markNullable(variable);
+  }
+
+  void doStatement_bodyBegin(
+      DoStatement node, Set<VariableElement> loopAssigned) {
+    _current = _current.removePromotedAll(loopAssigned);
+
+    _statementToStackIndex[node] = _stack.length;
+    _stack.add(_identity); // break
+    _stack.add(_identity); // continue
+  }
+
+  void doStatement_conditionBegin() {
+    // Tail of the stack: break, continue
+
+    var continueState = _stack.removeLast();
+    _current = _join(_current, continueState);
+  }
+
+  void doStatement_end(DoStatement node) {
+    _conditionalEnd(node.condition);
+    // Tail of the stack:  break, falseCondition, trueCondition
+
+    _stack.removeLast(); // trueCondition
+    var falseCondition = _stack.removeLast();
+    var breakState = _stack.removeLast();
+
+    _current = _join(falseCondition, breakState);
+  }
+
+  void falseLiteral(BooleanLiteral expression) {
+    _condition = expression;
+    _conditionTrue = _identity;
+    _conditionFalse = _current;
+  }
+
+  void forEachStatement_bodyBegin(Set<VariableElement> loopAssigned) {
+    _stack.add(_current);
+    _current = _current.removePromotedAll(loopAssigned);
+  }
+
+  void forEachStatement_end() {
+    var afterIterable = _stack.removeLast();
+    _current = _join(_current, afterIterable);
+  }
+
+  void forStatement_bodyBegin(Statement node, Expression condition) {
+    _conditionalEnd(condition);
+    // Tail of the stack: falseCondition, trueCondition
+
+    var trueCondition = _stack.removeLast();
+
+    _statementToStackIndex[node] = _stack.length;
+    _stack.add(_identity); // break
+    _stack.add(_identity); // continue
+
+    _current = trueCondition;
+  }
+
+  void forStatement_conditionBegin(Set<VariableElement> loopAssigned) {
+    _current = _current.removePromotedAll(loopAssigned);
+  }
+
+  void forStatement_end() {
+    // Tail of the stack: falseCondition, break
+    var breakState = _stack.removeLast();
+    var falseCondition = _stack.removeLast();
+
+    _current = _join(falseCondition, breakState);
+  }
+
+  void forStatement_updaterBegin() {
+    // Tail of the stack: falseCondition, break, continue
+    var afterBody = _current;
+    var continueState = _stack.removeLast();
+
+    _current = _join(afterBody, continueState);
+  }
+
+  void functionExpression_begin() {
+    _stack.add(_current);
+
+    Set<VariableElement> notPromoted = null;
+    for (var variable in _current.promoted.keys) {
+      if (functionBody.isPotentiallyMutatedInScope(variable)) {
+        notPromoted ??= Set<VariableElement>.identity();
+        notPromoted.add(variable);
+      }
+    }
+
+    if (notPromoted != null) {
+      _current = _current.removePromotedAll(notPromoted);
+    }
+  }
+
+  void functionExpression_end() {
+    _current = _stack.removeLast();
+  }
+
+  void handleBreak(AstNode target) {
+    var breakIndex = _statementToStackIndex[target];
+    if (breakIndex != null) {
+      _stack[breakIndex] = _join(_stack[breakIndex], _current);
+    }
+    _current = _current.exit();
+  }
+
+  void handleContinue(AstNode target) {
+    var breakIndex = _statementToStackIndex[target];
+    if (breakIndex != null) {
+      var continueIndex = breakIndex + 1;
+      _stack[continueIndex] = _join(_stack[continueIndex], _current);
+    }
+    _current = _current.exit();
+  }
+
+  /// Register the fact that the current state definitely exists, e.g. returns
+  /// from the body, throws an exception, etc.
+  void handleExit() {
+    _current = _current.exit();
+  }
+
+  void ifNullExpression_end() {
+    var afterLeft = _stack.removeLast();
+    _current = _join(_current, afterLeft);
+  }
+
+  void ifNullExpression_rightBegin() {
+    _stack.add(_current); // afterLeft
+  }
+
+  void ifStatement_elseBegin() {
+    var afterThen = _current;
+    var falseCondition = _stack.removeLast();
+    _stack.add(afterThen);
+    _current = falseCondition;
+  }
+
+  void ifStatement_end(bool hasElse) {
+    _State<T> afterThen;
+    _State<T> afterElse;
+    if (hasElse) {
+      afterThen = _stack.removeLast();
+      afterElse = _current;
+    } else {
+      afterThen = _current; // no `else`, so `then` is still current
+      afterElse = _stack.removeLast(); // `falseCond` is still on the stack
+    }
+    _current = _join(afterThen, afterElse);
+  }
+
+  void ifStatement_thenBegin(IfStatement ifStatement) {
+    _conditionalEnd(ifStatement.condition);
+    // Tail of the stack:  falseCondition, trueCondition
+
+    var trueCondition = _stack.removeLast();
+    _current = trueCondition;
+  }
+
+  void isExpression_end(
+      IsExpression isExpression, VariableElement variable, T type) {
+    if (functionBody.isPotentiallyMutatedInClosure(variable)) {
+      return;
+    }
+
+    _condition = isExpression;
+    if (isExpression.notOperator == null) {
+      _conditionTrue = _current.promote(typeOperations, variable, type);
+      _conditionFalse = _current;
+    } else {
+      _conditionTrue = _current;
+      _conditionFalse = _current.promote(typeOperations, variable, type);
+    }
+  }
+
+  /// Return `true` if the [variable] is known to be be nullable.
+  bool isNonNullable(VariableElement variable) {
+    return !_current.notNonNullable.contains(variable);
+  }
+
+  /// Return `true` if the [variable] is known to be be non-nullable.
+  bool isNullable(VariableElement variable) {
+    return !_current.notNullable.contains(variable);
+  }
+
+  void logicalAnd_end(BinaryExpression andExpression) {
+    _conditionalEnd(andExpression.rightOperand);
+    // Tail of the stack: falseLeft, trueLeft, falseRight, trueRight
+
+    var trueRight = _stack.removeLast();
+    var falseRight = _stack.removeLast();
+
+    _stack.removeLast(); // trueLeft is not used
+    var falseLeft = _stack.removeLast();
+
+    var trueResult = trueRight;
+    var falseResult = _join(falseLeft, falseRight);
+    var afterResult = _join(trueResult, falseResult);
+
+    _condition = andExpression;
+    _conditionTrue = trueResult;
+    _conditionFalse = falseResult;
+
+    _current = afterResult;
+  }
+
+  void logicalAnd_rightBegin(BinaryExpression andExpression) {
+    _conditionalEnd(andExpression.leftOperand);
+    // Tail of the stack: falseLeft, trueLeft
+
+    var trueLeft = _stack.last;
+    _current = trueLeft;
+  }
+
+  void logicalNot_end(PrefixExpression notExpression) {
+    _conditionalEnd(notExpression.operand);
+    var trueExpr = _stack.removeLast();
+    var falseExpr = _stack.removeLast();
+
+    _condition = notExpression;
+    _conditionTrue = falseExpr;
+    _conditionFalse = trueExpr;
+  }
+
+  void logicalOr_end(BinaryExpression orExpression) {
+    _conditionalEnd(orExpression.rightOperand);
+    // Tail of the stack: falseLeft, trueLeft, falseRight, trueRight
+
+    var trueRight = _stack.removeLast();
+    var falseRight = _stack.removeLast();
+
+    var trueLeft = _stack.removeLast();
+    _stack.removeLast(); // falseLeft is not used
+
+    var trueResult = _join(trueLeft, trueRight);
+    var falseResult = falseRight;
+    var afterResult = _join(trueResult, falseResult);
+
+    _condition = orExpression;
+    _conditionTrue = trueResult;
+    _conditionFalse = falseResult;
+
+    _current = afterResult;
+  }
+
+  void logicalOr_rightBegin(BinaryExpression orExpression) {
+    _conditionalEnd(orExpression.leftOperand);
+    // Tail of the stack: falseLeft, trueLeft
+
+    var falseLeft = _stack[_stack.length - 2];
+    _current = falseLeft;
+  }
+
+  /// Retrieves the type that the [variable] is promoted to, if the [variable]
+  /// is currently promoted.  Otherwise returns `null`.
+  T promotedType(VariableElement variable) {
+    return _current.promoted[variable];
+  }
+
+  /// Register read of the given [variable] in the current state.
+  void read(LocalVariableElement variable) {
+    if (_current.notAssigned.contains(variable)) {
+      // Add to the list of violating variables, if not there yet.
+      for (var i = 0; i < readBeforeWritten.length; ++i) {
+        var violatingVariable = readBeforeWritten[i];
+        if (identical(violatingVariable, variable)) {
+          return;
+        }
+      }
+      readBeforeWritten.add(variable);
+    }
+  }
+
+  /// The [notPromoted] set contains all variables that are potentially
+  /// assigned in other cases that might target this with `continue`, so
+  /// these variables might have different types and are "un-promoted" from
+  /// the "afterExpression" state.
+  void switchStatement_beginCase(Set<VariableElement> notPromoted) {
+    _current = _stack.last.removePromotedAll(notPromoted);
+  }
+
+  void switchStatement_end(SwitchStatement node, bool hasDefault) {
+    // Tail of the stack: break, continue, afterExpression
+    var afterExpression = _current = _stack.removeLast();
+    _stack.removeLast(); // continue
+    var breakState = _stack.removeLast();
+
+    if (hasDefault) {
+      _current = breakState;
+    } else {
+      _current = _join(breakState, afterExpression);
+    }
+  }
+
+  void switchStatement_expressionEnd(SwitchStatement node) {
+    _statementToStackIndex[node] = _stack.length;
+    _stack.add(_identity); // break
+    _stack.add(_identity); // continue
+    _stack.add(_current); // afterExpression
+  }
+
+  void trueLiteral(BooleanLiteral expression) {
+    _condition = expression;
+    _conditionTrue = _current;
+    _conditionFalse = _identity;
+  }
+
+  void tryCatchStatement_bodyBegin() {
+    _stack.add(_current);
+    // Tail of the stack: beforeBody
+  }
+
+  void tryCatchStatement_bodyEnd(Set<VariableElement> assignedInBody) {
+    var beforeBody = _stack.removeLast();
+    var beforeCatch = beforeBody.removePromotedAll(assignedInBody);
+    _stack.add(beforeCatch);
+    _stack.add(_current); // afterBodyAndCatches
+    // Tail of the stack: beforeCatch, afterBodyAndCatches
+  }
+
+  void tryCatchStatement_catchBegin() {
+    var beforeCatch = _stack[_stack.length - 2];
+    _current = beforeCatch;
+  }
+
+  void tryCatchStatement_catchEnd() {
+    var afterBodyAndCatches = _stack.last;
+    _stack.last = _join(afterBodyAndCatches, _current);
+  }
+
+  void tryCatchStatement_end() {
+    var afterBodyAndCatches = _stack.removeLast();
+    _stack.removeLast(); // beforeCatch
+    _current = afterBodyAndCatches;
+  }
+
+  void tryFinallyStatement_bodyBegin() {
+    _stack.add(_current); // beforeTry
+  }
+
+  void tryFinallyStatement_end(Set<VariableElement> assignedInFinally) {
+    var afterBody = _stack.removeLast();
+    _current = _current.restrict(typeOperations, afterBody, assignedInFinally);
+  }
+
+  void tryFinallyStatement_finallyBegin(Set<VariableElement> assignedInBody) {
+    var beforeTry = _stack.removeLast();
+    var afterBody = _current;
+    _stack.add(afterBody);
+    _current = _join(afterBody, beforeTry.removePromotedAll(assignedInBody));
+  }
+
+  void verifyStackEmpty() {
+    assert(_stack.isEmpty);
+  }
+
+  void whileStatement_bodyBegin(WhileStatement node) {
+    _conditionalEnd(node.condition);
+    // Tail of the stack: falseCondition, trueCondition
+
+    var trueCondition = _stack.removeLast();
+
+    _statementToStackIndex[node] = _stack.length;
+    _stack.add(_identity); // break
+    _stack.add(_identity); // continue
+
+    _current = trueCondition;
+  }
+
+  void whileStatement_conditionBegin(Set<VariableElement> loopAssigned) {
+    _current = _current.removePromotedAll(loopAssigned);
+  }
+
+  void whileStatement_end() {
+    _stack.removeLast(); // continue
+    var breakState = _stack.removeLast();
+    var falseCondition = _stack.removeLast();
+
+    _current = _join(falseCondition, breakState);
+  }
+
+  /// Register write of the given [variable] in the current state.
+  void write(
+    VariableElement variable, {
+    bool isNull = false,
+    bool isNonNull = false,
+  }) {
+    _current = _current.write(variable, isNull: isNull, isNonNull: isNonNull);
+  }
+
+  void _conditionalEnd(Expression condition) {
+    while (condition is ParenthesizedExpression) {
+      condition = (condition as ParenthesizedExpression).expression;
+    }
+    if (identical(condition, _condition)) {
+      _stack.add(_conditionFalse);
+      _stack.add(_conditionTrue);
+    } else {
+      _stack.add(_current);
+      _stack.add(_current);
+    }
+  }
+
+  _State<T> _join(_State<T> first, _State<T> second) {
+    if (identical(first, _identity)) return second;
+    if (identical(second, _identity)) return first;
+
+    if (first.reachable && !second.reachable) return first;
+    if (!first.reachable && second.reachable) return second;
+
+    var newReachable = first.reachable || second.reachable;
+    var newNotAssigned = first.notAssigned.union(second.notAssigned);
+    var newNotNullable = first.notNullable.union(second.notNullable);
+    var newNotNonNullable = first.notNonNullable.union(second.notNonNullable);
+    var newPromoted = _joinPromoted(first.promoted, second.promoted);
+
+    return _State._identicalOrNew(
+      first,
+      second,
+      newReachable,
+      newNotAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      newPromoted,
+    );
+  }
+
+  Map<VariableElement, T> _joinPromoted(
+    Map<VariableElement, T> first,
+    Map<VariableElement, T> second,
+  ) {
+    if (identical(first, second)) return first;
+    if (first.isEmpty || second.isEmpty) return const {};
+
+    var result = <VariableElement, T>{};
+    var alwaysFirst = true;
+    var alwaysSecond = true;
+    for (var element in first.keys) {
+      var firstType = first[element];
+      var secondType = second[element];
+      if (firstType != null && secondType != null) {
+        if (typeOperations.isSubtypeOf(firstType, secondType)) {
+          result[element] = secondType;
+          alwaysFirst = false;
+        } else if (typeOperations.isSubtypeOf(secondType, firstType)) {
+          result[element] = firstType;
+          alwaysSecond = false;
+        } else {
+          alwaysFirst = false;
+          alwaysSecond = false;
+        }
+      } else {
+        alwaysFirst = false;
+        alwaysSecond = false;
+      }
+    }
+
+    if (alwaysFirst) return first;
+    if (alwaysSecond) return second;
+    if (result.isEmpty) return const {};
+    return result;
+  }
+}
+
+/// Operations on types, abstracted from concrete type interfaces.
+abstract class TypeOperations<T> {
+  /// Return the static type of with the given [element].
+  T elementType(VariableElement element);
+
+  /// Return `true` if the [leftType] is a subtype of the [rightType].
+  bool isSubtypeOf(T leftType, T rightType);
+}
+
+/// List based immutable set of elements.
+class _ElementSet {
+  static final empty = _ElementSet._(
+    List<VariableElement>(0),
+  );
+
+  final List<VariableElement> elements;
+
+  _ElementSet._(this.elements);
+
+  _ElementSet add(VariableElement addedElement) {
+    if (contains(addedElement)) {
+      return this;
+    }
+
+    var length = elements.length;
+    var newElements = List<VariableElement>(length + 1);
+    for (var i = 0; i < length; ++i) {
+      newElements[i] = elements[i];
+    }
+    newElements[length] = addedElement;
+    return _ElementSet._(newElements);
+  }
+
+  _ElementSet addAll(Iterable<VariableElement> elements) {
+    var result = this;
+    for (var element in elements) {
+      result = result.add(element);
+    }
+    return result;
+  }
+
+  bool contains(VariableElement element) {
+    var length = elements.length;
+    for (var i = 0; i < length; ++i) {
+      if (identical(elements[i], element)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  _ElementSet intersect(_ElementSet other) {
+    if (identical(other, empty)) return empty;
+
+    // TODO(scheglov) optimize
+    var newElements =
+        elements.toSet().intersection(other.elements.toSet()).toList();
+
+    if (newElements.isEmpty) return empty;
+    return _ElementSet._(newElements);
+  }
+
+  _ElementSet remove(VariableElement removedElement) {
+    if (!contains(removedElement)) {
+      return this;
+    }
+
+    var length = elements.length;
+    if (length == 1) {
+      return empty;
+    }
+
+    var newElements = List<VariableElement>(length - 1);
+    var newIndex = 0;
+    for (var i = 0; i < length; ++i) {
+      var element = elements[i];
+      if (!identical(element, removedElement)) {
+        newElements[newIndex++] = element;
+      }
+    }
+
+    return _ElementSet._(newElements);
+  }
+
+  _ElementSet union(_ElementSet other) {
+    if (other.elements.isEmpty) {
+      return this;
+    }
+
+    var result = this;
+    var otherElements = other.elements;
+    for (var i = 0; i < otherElements.length; ++i) {
+      var otherElement = otherElements[i];
+      result = result.add(otherElement);
+    }
+    return result;
+  }
+}
+
+class _State<T> {
+  final bool reachable;
+  final _ElementSet notAssigned;
+  final _ElementSet notNullable;
+  final _ElementSet notNonNullable;
+  final Map<VariableElement, T> promoted;
+
+  _State(
+    this.reachable,
+    this.notAssigned,
+    this.notNullable,
+    this.notNonNullable,
+    this.promoted,
+  );
+
+  /// Add a new [variable] to track definite assignment.
+  _State<T> add(VariableElement variable, {bool assigned: false}) {
+    var newNotAssigned = assigned ? notAssigned : notAssigned.add(variable);
+    var newNotNullable = notNullable.add(variable);
+    var newNotNonNullable = notNonNullable.add(variable);
+
+    if (identical(newNotAssigned, notAssigned) &&
+        identical(newNotNullable, notNullable) &&
+        identical(newNotNonNullable, notNonNullable)) {
+      return this;
+    }
+
+    return _State<T>(
+      reachable,
+      newNotAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      promoted,
+    );
+  }
+
+  _State<T> exit() {
+    return _State<T>(false, notAssigned, notNullable, notNonNullable, promoted);
+  }
+
+  _State<T> markNonNullable(VariableElement variable) {
+    var newNotNullable = notNullable.add(variable);
+    var newNotNonNullable = notNonNullable.remove(variable);
+
+    if (identical(newNotNullable, notNullable) &&
+        identical(newNotNonNullable, notNonNullable)) {
+      return this;
+    }
+
+    return _State<T>(
+      reachable,
+      notAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      promoted,
+    );
+  }
+
+  _State<T> markNullable(VariableElement variable) {
+    var newNotNullable = notNullable.remove(variable);
+    var newNotNonNullable = notNonNullable.add(variable);
+
+    if (identical(newNotNullable, notNullable) &&
+        identical(newNotNonNullable, notNonNullable)) {
+      return this;
+    }
+
+    return _State<T>(
+      reachable,
+      notAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      promoted,
+    );
+  }
+
+  _State<T> promote(
+    TypeOperations<T> typeOperations,
+    VariableElement variable,
+    T type,
+  ) {
+    var previousType = promoted[variable];
+    previousType ??= typeOperations.elementType(variable);
+
+    if (typeOperations.isSubtypeOf(type, previousType) &&
+        type != previousType) {
+      var newPromoted = <VariableElement, T>{}..addAll(promoted);
+      newPromoted[variable] = type;
+      return _State<T>(
+        reachable,
+        notAssigned,
+        notNullable,
+        notNonNullable,
+        newPromoted,
+      );
+    }
+
+    return this;
+  }
+
+  _State<T> removePromotedAll(Set<VariableElement> variables) {
+    var newNotNullable = notNullable.addAll(variables);
+    var newNotNonNullable = notNonNullable.addAll(variables);
+    var newPromoted = _removePromotedAll(promoted, variables);
+
+    if (identical(newNotNullable, notNullable) &&
+        identical(newNotNonNullable, notNonNullable) &&
+        identical(newPromoted, promoted)) return this;
+
+    return _State<T>(
+      reachable,
+      notAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      newPromoted,
+    );
+  }
+
+  _State<T> restrict(
+    TypeOperations<T> typeOperations,
+    _State<T> other,
+    Set<VariableElement> unsafe,
+  ) {
+    var newReachable = reachable && other.reachable;
+    var newNotAssigned = notAssigned.intersect(other.notAssigned);
+
+    var newNotNullable = _ElementSet.empty;
+    for (var variable in notNullable.elements) {
+      if (unsafe.contains(variable) || other.notNullable.contains(variable)) {
+        newNotNullable = newNotNullable.add(variable);
+      }
+    }
+
+    var newNotNonNullable = _ElementSet.empty;
+    for (var variable in notNonNullable.elements) {
+      if (unsafe.contains(variable) ||
+          other.notNonNullable.contains(variable)) {
+        newNotNonNullable = newNotNonNullable.add(variable);
+      }
+    }
+
+    var newPromoted = <VariableElement, T>{};
+    for (var variable in promoted.keys) {
+      var thisType = promoted[variable];
+      if (!unsafe.contains(variable)) {
+        var otherType = other.promoted[variable];
+        if (otherType != null &&
+            typeOperations.isSubtypeOf(otherType, thisType)) {
+          newPromoted[variable] = otherType;
+          continue;
+        }
+      }
+      newPromoted[variable] = thisType;
+    }
+
+    return _identicalOrNew(
+      this,
+      other,
+      newReachable,
+      newNotAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      newPromoted,
+    );
+  }
+
+  _State<T> setReachable(bool reachable) {
+    if (this.reachable == reachable) return this;
+
+    return _State<T>(
+      reachable,
+      notAssigned,
+      notNullable,
+      notNonNullable,
+      promoted,
+    );
+  }
+
+  _State<T> write(
+    VariableElement variable, {
+    bool isNull = false,
+    bool isNonNull = false,
+  }) {
+    var newNotAssigned = variable is LocalVariableElement
+        ? notAssigned.remove(variable)
+        : notAssigned;
+
+    var newNotNullable =
+        isNull ? notNullable.remove(variable) : notNullable.add(variable);
+
+    var newNotNonNullable = isNonNull
+        ? notNonNullable.remove(variable)
+        : notNonNullable.add(variable);
+
+    var newPromoted = _removePromoted(promoted, variable);
+
+    if (identical(newNotAssigned, notAssigned) &&
+        identical(newNotNullable, notNullable) &&
+        identical(newNotNonNullable, notNonNullable) &&
+        identical(newPromoted, promoted)) {
+      return this;
+    }
+
+    return _State<T>(
+      reachable,
+      newNotAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      newPromoted,
+    );
+  }
+
+  Map<VariableElement, T> _removePromoted(
+    Map<VariableElement, T> map,
+    VariableElement variable,
+  ) {
+    if (map.isEmpty) return const {};
+
+    var result = <VariableElement, T>{};
+    for (var key in map.keys) {
+      if (!identical(key, variable)) {
+        result[key] = map[key];
+      }
+    }
+
+    if (result.isEmpty) return const {};
+    return result;
+  }
+
+  Map<VariableElement, T> _removePromotedAll(
+    Map<VariableElement, T> map,
+    Set<VariableElement> variables,
+  ) {
+    if (map.isEmpty) return const {};
+    if (variables.isEmpty) return map;
+
+    var result = <VariableElement, T>{};
+    var noChanges = true;
+    for (var key in map.keys) {
+      if (variables.contains(key)) {
+        noChanges = false;
+      } else {
+        result[key] = map[key];
+      }
+    }
+
+    if (noChanges) return map;
+    if (result.isEmpty) return const {};
+    return result;
+  }
+
+  static _State<T> _identicalOrNew<T>(
+    _State<T> first,
+    _State<T> second,
+    bool newReachable,
+    _ElementSet newNotAssigned,
+    _ElementSet newNotNullable,
+    _ElementSet newNotNonNullable,
+    Map<VariableElement, T> newPromoted,
+  ) {
+    if (first.reachable == newReachable &&
+        identical(first.notAssigned, newNotAssigned) &&
+        identical(first.notNullable, newNotNullable) &&
+        identical(first.notNonNullable, newNotNonNullable) &&
+        identical(first.promoted, newPromoted)) {
+      return first;
+    }
+    if (second.reachable == newReachable &&
+        identical(second.notAssigned, newNotAssigned) &&
+        identical(second.notNullable, newNotNullable) &&
+        identical(second.notNonNullable, newNotNonNullable) &&
+        identical(second.promoted, newPromoted)) {
+      return second;
+    }
+
+    return _State<T>(
+      newReachable,
+      newNotAssigned,
+      newNotNullable,
+      newNotNonNullable,
+      newPromoted,
+    );
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 846de52..9e54c4c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -21,6 +21,7 @@
  * Instances of the class `InheritanceManager` manage the knowledge of where class members
  * (methods, getters & setters) are inherited from.
  */
+@Deprecated('Use InheritanceManager2 instead.')
 class InheritanceManager {
   /**
    * The [LibraryElement] that is managed by this manager.
@@ -76,7 +77,7 @@
    * @return a mapping between the set of all members inherited from the passed [ClassElement]
    *         superclass hierarchy, and the associated [ExecutableElement]
    */
-  @deprecated
+  @Deprecated('Use InheritanceManager2.getInheritedConcreteMap() instead.')
   MemberMap getMapOfMembersInheritedFromClasses(ClassElement classElt) =>
       new MemberMap.fromMap(
           _computeClassChainLookupMap(classElt, new HashSet<ClassElement>()));
@@ -89,7 +90,7 @@
    * @return a mapping between the set of all string names of the members inherited from the passed
    *         [ClassElement] interface hierarchy, and the associated [ExecutableElement].
    */
-  @deprecated
+  @Deprecated('Use InheritanceManager2.getInheritedMap() instead.')
   MemberMap getMapOfMembersInheritedFromInterfaces(ClassElement classElt) =>
       new MemberMap.fromMap(
           _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>()));
@@ -125,7 +126,7 @@
    * @return the inherited executable element with the member name, or `null` if no such
    *         member exists
    */
-  @deprecated
+  @Deprecated('Use InheritanceManager2.getInherited() instead.')
   ExecutableElement lookupInheritance(
       ClassElement classElt, String memberName) {
     if (memberName == null || memberName.isEmpty) {
@@ -150,7 +151,7 @@
    * @return the inherited executable element with the member name, or `null` if no such
    *         member exists
    */
-  @deprecated
+  @Deprecated('Use InheritanceManager2.getMember() instead.')
   ExecutableElement lookupMember(ClassElement classElt, String memberName) {
     ExecutableElement element = _lookupMemberInClass(classElt, memberName);
     if (element != null) {
@@ -169,7 +170,7 @@
    * @param memberName the name of the class member to query
    * @return a list of overridden methods
    */
-  @deprecated
+  @Deprecated('Use InheritanceManager2.getOverridden() instead.')
   List<ExecutableElement> lookupOverrides(
       ClassElement classElt, String memberName) {
     List<ExecutableElement> result = new List<ExecutableElement>();
@@ -798,7 +799,7 @@
     List<ParameterElement> parameters = executableElement.parameters;
     for (int i = 0; i < parameters.length; i++) {
       ParameterElement parameterElement = parameters[i];
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       if (parameterElement.parameterKind == parameterKind) {
         parameterCount++;
       }
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 10e01f6..6471484 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -496,13 +495,6 @@
       var calleeType = _getCalleeType(node, targetType);
       _setResolution(node, calleeType);
 
-      ClassElementImpl receiverSuperClass = AbstractClassElementImpl.getImpl(
-        receiverType.element.supertype.element,
-      );
-      if (receiverSuperClass.hasNoSuchMethod) {
-        return;
-      }
-
       _resolver.errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
           nameNode,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index bd26015..81dcb16 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -3899,7 +3899,8 @@
           'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
           "Parameters can't override default values, "
           "this method overrides '{0}.{1}' where '{2}' has a different value.",
-          correction: "Try using the same default value in both methods.");
+          correction: "Try using the same default value in both methods.",
+          errorSeverity: ErrorSeverity.WARNING);
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3914,7 +3915,8 @@
           'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
           "Parameters can't override default values, this method overrides "
           "'{0}.{1}' where this positional parameter has a different value.",
-          correction: "Try using the same default value in both methods.");
+          correction: "Try using the same default value in both methods.",
+          errorSeverity: ErrorSeverity.WARNING);
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4597,6 +4599,19 @@
               "defining a new parameter with this name.");
 
   /**
+   * For the purposes of experimenting with potential non-null type semantics.
+   *
+   * Parameters: none
+   */
+  static const StaticWarningCode UNCHECKED_USE_OF_NULLABLE_VALUE =
+      const StaticWarningCode(
+          'UNCHECKED_USE_OF_NULLABLE_VALUE',
+          'The expression is nullable and must be null-checked before it can be'
+          ' used.',
+          correction:
+              'Try casting or check the value is not null before using it.');
+
+  /**
    * It is a static warning to assign void to any non-void type in dart.
    * compile-time error). Report that error specially for a better user
    * experience.
@@ -4611,6 +4626,9 @@
           " call that returns void you didn't expect. Also check type parameters"
           ' and variables which, in rare cases, may be void as well.');
 
+  @override
+  final ErrorSeverity errorSeverity;
+
   /**
    * Initialize a newly created error code to have the given [name]. The message
    * associated with the error will be created from the given [message]
@@ -4618,15 +4636,14 @@
    * given [correction] template.
    */
   const StaticWarningCode(String name, String message,
-      {String correction, bool isUnresolvedIdentifier: false})
+      {String correction,
+      this.errorSeverity: ErrorSeverity.ERROR,
+      bool isUnresolvedIdentifier: false})
       : super.temporary(name, message,
             correction: correction,
             isUnresolvedIdentifier: isUnresolvedIdentifier);
 
   @override
-  ErrorSeverity get errorSeverity => ErrorType.STATIC_WARNING.severity;
-
-  @override
   ErrorType get type => ErrorType.STATIC_WARNING;
 }
 
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 20ecec0..a5f1196 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -164,7 +164,8 @@
           _checkDeclaredMember(fieldList, libraryUri, fieldElement.setter);
         }
       } else if (member is MethodDeclaration) {
-        _checkDeclaredMember(member, libraryUri, member.declaredElement);
+        _checkDeclaredMember(member, libraryUri, member.declaredElement,
+            methodParameterNodes: member.parameters?.parameters);
       }
     }
 
@@ -248,8 +249,9 @@
   void _checkDeclaredMember(
     AstNode node,
     Uri libraryUri,
-    ExecutableElement member,
-  ) {
+    ExecutableElement member, {
+    List<AstNode> methodParameterNodes,
+  }) {
     if (member == null) return;
     if (member.isStatic) return;
 
@@ -276,6 +278,13 @@
             ],
           );
         }
+        if (methodParameterNodes != null) {
+          _checkForOptionalParametersDifferentDefaultValues(
+            superMemberType.element,
+            member,
+            methodParameterNodes,
+          );
+        }
       }
     }
   }
@@ -406,6 +415,84 @@
     }
   }
 
+  void _checkForOptionalParametersDifferentDefaultValues(
+    ExecutableElement baseExecutable,
+    ExecutableElement derivedExecutable,
+    List<AstNode> derivedParameterNodes,
+  ) {
+    var derivedOptionalNodes = <AstNode>[];
+    var derivedOptionalElements = <ParameterElementImpl>[];
+    var derivedParameterElements = derivedExecutable.parameters;
+    for (var i = 0; i < derivedParameterElements.length; i++) {
+      var parameterElement = derivedParameterElements[i];
+      if (parameterElement.isOptional) {
+        derivedOptionalNodes.add(derivedParameterNodes[i]);
+        derivedOptionalElements.add(parameterElement);
+      }
+    }
+
+    var baseOptionalElements = <ParameterElementImpl>[];
+    var baseParameterElements = baseExecutable.parameters;
+    for (var i = 0; i < baseParameterElements.length; ++i) {
+      var baseParameter = baseParameterElements[i];
+      if (baseParameter.isOptional) {
+        baseOptionalElements.add(baseParameter);
+      }
+    }
+
+    // Stop if no optional parameters.
+    if (baseOptionalElements.isEmpty || derivedOptionalElements.isEmpty) {
+      return;
+    }
+
+    if (derivedOptionalElements[0].isNamed) {
+      for (int i = 0; i < derivedOptionalElements.length; i++) {
+        var derivedElement = derivedOptionalElements[i];
+        var name = derivedElement.name;
+        for (var j = 0; j < baseOptionalElements.length; j++) {
+          var baseParameter = baseOptionalElements[j];
+          if (name == baseParameter.name && baseParameter.initializer != null) {
+            var baseValue = baseParameter.computeConstantValue();
+            var derivedResult = derivedElement.evaluationResult;
+            if (derivedResult.value != baseValue) {
+              reporter.reportErrorForNode(
+                StaticWarningCode
+                    .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+                derivedOptionalNodes[i],
+                [
+                  baseExecutable.enclosingElement.displayName,
+                  baseExecutable.displayName,
+                  name
+                ],
+              );
+            }
+          }
+        }
+      }
+    } else {
+      for (var i = 0;
+          i < derivedOptionalElements.length && i < baseOptionalElements.length;
+          i++) {
+        var baseElement = baseOptionalElements[i];
+        if (baseElement.initializer != null) {
+          var baseValue = baseElement.computeConstantValue();
+          var derivedResult = derivedOptionalElements[i].evaluationResult;
+          if (derivedResult.value != baseValue) {
+            reporter.reportErrorForNode(
+              StaticWarningCode
+                  .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+              derivedOptionalNodes[i],
+              [
+                baseExecutable.enclosingElement.displayName,
+                baseExecutable.displayName
+              ],
+            );
+          }
+        }
+      }
+    }
+  }
+
   /// Check that [classElement] is not a superinterface to itself.
   /// The [path] is a list containing the potentially cyclic implements path.
   ///
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 94a0fbe..edbcf3c 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -46,7 +46,8 @@
         messageStaticConstructor,
         messageTypedefNotFunction,
         templateDuplicateLabelInSwitchStatement,
-        templateExpectedIdentifier;
+        templateExpectedIdentifier,
+        templateUnexpectedToken;
 import 'package:front_end/src/fasta/quote.dart';
 import 'package:front_end/src/fasta/scanner/token_constants.dart';
 import 'package:front_end/src/fasta/source/stack_listener.dart'
@@ -99,6 +100,12 @@
   /// `true` if non-nullable behavior is enabled
   bool enableNonNullable = false;
 
+  /// `true` if spread-collections behavior is enabled
+  bool enableSpreadCollections = false;
+
+  /// `true` if control-flow-collections behavior is enabled
+  bool enableControlFlowCollections = false;
+
   /// Is `true` if [enableNonNullable] is enabled, and the library directive
   /// is annotated with `@pragma('analyzer:non-nullable')`.
   bool hasPragmaAnalyzerNonNullable = false;
@@ -270,6 +277,67 @@
     scriptTag = ast.scriptTag(token);
   }
 
+  void beginIfControlFlow(Token ifToken) {
+    push(ifToken);
+  }
+
+  @override
+  void handleElseControlFlow(Token elseToken) {
+    push(elseToken);
+  }
+
+  @override
+  void endIfControlFlow(Token token) {
+    CollectionElement thenElement = pop();
+    ParenthesizedExpression condition = pop();
+    Token ifToken = pop();
+    pushIfControlFlowInfo(ifToken, condition, thenElement, null, null);
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    CollectionElement elseElement = pop();
+    Token elseToken = pop();
+    CollectionElement thenElement = pop();
+    ParenthesizedExpression condition = pop();
+    Token ifToken = pop();
+    pushIfControlFlowInfo(
+        ifToken, condition, thenElement, elseToken, elseElement);
+  }
+
+  void pushIfControlFlowInfo(
+      Token ifToken,
+      ParenthesizedExpression condition,
+      CollectionElement thenElement,
+      Token elseToken,
+      CollectionElement elseElement) {
+    if (enableControlFlowCollections) {
+      push(ast.ifElement(
+        ifKeyword: ifToken,
+        leftParenthesis: condition.leftParenthesis,
+        condition: condition.expression,
+        rightParenthesis: condition.rightParenthesis,
+        thenElement: thenElement,
+        elseKeyword: elseToken,
+        elseElement: elseElement,
+      ));
+    } else {
+      handleRecoverableError(
+          templateUnexpectedToken.withArguments(ifToken), ifToken, ifToken);
+      push(thenElement);
+    }
+  }
+
+  @override
+  void handleSpreadExpression(Token spreadToken) {
+    if (enableSpreadCollections) {
+      push(ast.spreadElement(spreadOperator: spreadToken, expression: pop()));
+    } else {
+      handleRecoverableError(templateUnexpectedToken.withArguments(spreadToken),
+          spreadToken, spreadToken);
+    }
+  }
+
   void handleStringJuxtaposition(int literalCount) {
     debugEvent("StringJuxtaposition");
 
@@ -802,26 +870,17 @@
   }
 
   @override
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
     assert(optional('for', forKeyword));
     assert(optional('(', leftParen));
     assert(optional(';', leftSeparator));
-    debugEvent("ForStatement");
+    assert(updateExpressionCount >= 0);
 
-    Statement body = pop();
     List<Expression> updates = popTypedList(updateExpressionCount);
     Statement conditionStatement = pop();
     Object initializerPart = pop();
 
-    VariableDeclarationList variableList;
-    Expression initializer;
-    if (initializerPart is VariableDeclarationStatement) {
-      variableList = initializerPart.variables;
-    } else {
-      initializer = initializerPart as Expression;
-    }
-
     Expression condition;
     Token rightSeparator;
     if (conditionStatement is ExpressionStatement) {
@@ -831,17 +890,95 @@
       rightSeparator = (conditionStatement as EmptyStatement).semicolon;
     }
 
-    push(ast.forStatement(
-        forKeyword,
-        leftParen,
-        variableList,
-        initializer,
-        leftSeparator,
-        condition,
-        rightSeparator,
-        updates,
-        leftParen?.endGroup,
-        body));
+    ForParts forLoopParts;
+    if (initializerPart is VariableDeclarationStatement) {
+      forLoopParts = ast.forPartsWithDeclarations(
+        variables: initializerPart.variables,
+        leftSeparator: leftSeparator,
+        condition: condition,
+        rightSeparator: rightSeparator,
+        updaters: updates,
+      );
+    } else {
+      forLoopParts = ast.forPartsWithExpression(
+        initialization: initializerPart as Expression,
+        leftSeparator: leftSeparator,
+        condition: condition,
+        rightSeparator: rightSeparator,
+        updaters: updates,
+      );
+    }
+
+    push(forKeyword);
+    push(leftParen);
+    push(forLoopParts);
+  }
+
+  @override
+  void endForControlFlow(Token token) {
+    debugEvent("endForControlFlow");
+    var entry = pop();
+    ForParts forLoopParts = pop();
+    Token leftParen = pop();
+    Token forToken = pop();
+
+    pushForControlFlowInfo(null, forToken, leftParen, forLoopParts, entry);
+  }
+
+  void pushForControlFlowInfo(Token awaitToken, Token forToken,
+      Token leftParenthesis, ForLoopParts forLoopParts, Object entry) {
+    if (enableControlFlowCollections) {
+      push(ast.forElement(
+        awaitKeyword: awaitToken,
+        forKeyword: forToken,
+        leftParenthesis: leftParenthesis,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParenthesis.endGroup,
+        body: entry as CollectionElement,
+      ));
+    } else {
+      handleRecoverableError(
+          templateUnexpectedToken.withArguments(forToken), forToken, forToken);
+      push(entry);
+    }
+  }
+
+  @override
+  void endForStatement(Token endToken) {
+    debugEvent("ForStatement");
+    Statement body = pop();
+    ForParts forLoopParts = pop();
+    Token leftParen = pop();
+    Token forToken = pop();
+
+    if (enableControlFlowCollections || enableSpreadCollections) {
+      push(ast.forStatement2(
+        forKeyword: forToken,
+        leftParenthesis: leftParen,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParen.endGroup,
+        body: body,
+      ));
+    } else {
+      VariableDeclarationList variableList;
+      Expression initializer;
+      if (forLoopParts is ForPartsWithDeclarations) {
+        variableList = forLoopParts.variables;
+      } else {
+        initializer = (forLoopParts as ForPartsWithExpression).initialization;
+      }
+      push(ast.forStatement(
+          forToken,
+          leftParen,
+          variableList,
+          initializer,
+          forLoopParts.leftSeparator,
+          forLoopParts.condition,
+          forLoopParts.rightSeparator,
+          forLoopParts.updaters,
+          leftParen?.endGroup,
+          body));
+    }
   }
 
   void handleLiteralList(
@@ -851,10 +988,23 @@
     assert(optional(']', rightBracket));
     debugEvent("LiteralList");
 
-    List<Expression> expressions = popTypedList(count);
-    TypeArgumentList typeArguments = pop();
-    push(ast.listLiteral(
-        constKeyword, typeArguments, leftBracket, expressions, rightBracket));
+    if (enableControlFlowCollections || enableSpreadCollections) {
+      List<CollectionElement> elements = popCollectionElements(count);
+
+      TypeArgumentList typeArguments = pop();
+      push(ast.listLiteral2(
+        constKeyword: constKeyword,
+        typeArguments: typeArguments,
+        leftBracket: leftBracket,
+        elements: elements,
+        rightBracket: rightBracket,
+      ));
+    } else {
+      List<Expression> expressions = popTypedList(count);
+      TypeArgumentList typeArguments = pop();
+      push(ast.listLiteral(
+          constKeyword, typeArguments, leftBracket, expressions, rightBracket));
+    }
   }
 
   void handleAsyncModifier(Token asyncToken, Token starToken) {
@@ -898,13 +1048,12 @@
   }
 
   @override
-  void handleEmptyLiteralSetOrMap(
-      Token leftBrace, Token constKeyword, Token rightBrace) {
+  void handleLiteralSetOrMap(
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
     // TODO(danrubel): From a type resolution standpoint, this could be either
     // a set literal or a map literal depending upon the context
     // in which this expression occurs.
-    // For now, generate a map literal.
-    handleLiteralMap(0, leftBrace, constKeyword, rightBrace);
+    handleLiteralMap(count, leftBrace, constKeyword, rightBrace);
   }
 
   void handleLiteralSet(
@@ -914,10 +1063,23 @@
     assert(optional('}', rightBracket));
     debugEvent("LiteralSet");
 
-    List<Expression> entries = popTypedList(count) ?? <Expression>[];
-    TypeArgumentList typeArguments = pop();
-    push(ast.setLiteral(
-        constKeyword, typeArguments, leftBracket, entries, rightBracket));
+    if (enableControlFlowCollections || enableSpreadCollections) {
+      List<CollectionElement> elements = popCollectionElements(count);
+
+      TypeArgumentList typeArguments = pop();
+      push(ast.setLiteral2(
+        constKeyword: constKeyword,
+        typeArguments: typeArguments,
+        leftBracket: leftBracket,
+        elements: elements,
+        rightBracket: rightBracket,
+      ));
+    } else {
+      List<Expression> entries = popTypedList(count) ?? <Expression>[];
+      TypeArgumentList typeArguments = pop();
+      push(ast.setLiteral(
+          constKeyword, typeArguments, leftBracket, entries, rightBracket));
+    }
   }
 
   void handleLiteralMap(
@@ -927,10 +1089,28 @@
     assert(optional('}', rightBracket));
     debugEvent("LiteralMap");
 
-    List<MapLiteralEntry> entries = popTypedList(count) ?? <MapLiteralEntry>[];
-    TypeArgumentList typeArguments = pop();
-    push(ast.mapLiteral(
-        constKeyword, typeArguments, leftBracket, entries, rightBracket));
+    if (enableControlFlowCollections || enableSpreadCollections) {
+      List<CollectionElement> entries = popCollectionElements(count);
+      TypeArgumentList typeArguments = pop();
+      push(ast.mapLiteral2(
+        constKeyword: constKeyword,
+        typeArguments: typeArguments,
+        leftBracket: leftBracket,
+        entries: entries,
+        rightBracket: rightBracket,
+      ));
+    } else {
+      List<MapLiteralEntry> entries = <MapLiteralEntry>[];
+      popTypedList(count)?.forEach((entry) {
+        if (entry is MapLiteralEntry) {
+          entries.add(entry);
+        }
+      });
+
+      TypeArgumentList typeArguments = pop();
+      push(ast.mapLiteral(
+          constKeyword, typeArguments, leftBracket, entries, rightBracket));
+    }
   }
 
   void handleLiteralMapEntry(Token colon, Token endToken) {
@@ -1154,33 +1334,29 @@
   }
 
   @override
-  void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
-      Token inKeyword, Token endToken) {
+  void handleForInLoopParts(Token awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {
     assert(optionalOrNull('await', awaitToken));
     assert(optional('for', forToken));
     assert(optional('(', leftParenthesis));
     assert(optional('in', inKeyword) || optional(':', inKeyword));
-    debugEvent("ForInExpression");
 
-    Statement body = pop();
     Expression iterator = pop();
     Object variableOrDeclaration = pop();
+
+    ForEachParts forLoopParts;
     if (variableOrDeclaration is VariableDeclarationStatement) {
       VariableDeclarationList variableList = variableOrDeclaration.variables;
-      push(ast.forEachStatementWithDeclaration(
-          awaitToken,
-          forToken,
-          leftParenthesis,
-          ast.declaredIdentifier(
-              variableList.documentationComment,
-              variableList.metadata,
-              variableList.keyword,
-              variableList.type,
-              variableList.variables.first.name),
-          inKeyword,
-          iterator,
-          leftParenthesis?.endGroup,
-          body));
+      forLoopParts = ast.forEachPartsWithDeclaration(
+        loopVariable: ast.declaredIdentifier(
+            variableList.documentationComment,
+            variableList.metadata,
+            variableList.keyword,
+            variableList.type,
+            variableList.variables.first.name),
+        inKeyword: inKeyword,
+        iterable: iterator,
+      );
     } else {
       if (variableOrDeclaration is! SimpleIdentifier) {
         // Parser has already reported the error.
@@ -1192,13 +1368,70 @@
         }
         variableOrDeclaration = ast.simpleIdentifier(leftParenthesis.next);
       }
+      forLoopParts = ast.forEachPartsWithIdentifier(
+        identifier: variableOrDeclaration,
+        inKeyword: inKeyword,
+        iterable: iterator,
+      );
+    }
+
+    push(awaitToken ?? NullValue.AwaitToken);
+    push(forToken);
+    push(leftParenthesis);
+    push(forLoopParts);
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    debugEvent("endForInControlFlow");
+
+    var entry = pop();
+    ForEachParts forLoopParts = pop();
+    Token leftParenthesis = pop();
+    Token forToken = pop();
+    Token awaitToken = pop(NullValue.AwaitToken);
+
+    pushForControlFlowInfo(
+        awaitToken, forToken, leftParenthesis, forLoopParts, entry);
+  }
+
+  @override
+  void endForIn(Token endToken) {
+    debugEvent("ForInExpression");
+
+    Statement body = pop();
+    ForEachParts forLoopParts = pop();
+    Token leftParenthesis = pop();
+    Token forToken = pop();
+    Token awaitToken = pop(NullValue.AwaitToken);
+
+    if (enableControlFlowCollections || enableSpreadCollections) {
+      push(ast.forStatement2(
+        awaitKeyword: awaitToken,
+        forKeyword: forToken,
+        leftParenthesis: leftParenthesis,
+        forLoopParts: forLoopParts,
+        rightParenthesis: leftParenthesis.endGroup,
+        body: body,
+      ));
+    } else if (forLoopParts is ForEachPartsWithDeclaration) {
+      push(ast.forEachStatementWithDeclaration(
+          awaitToken,
+          forToken,
+          leftParenthesis,
+          forLoopParts.loopVariable,
+          forLoopParts.inKeyword,
+          forLoopParts.iterable,
+          leftParenthesis?.endGroup,
+          body));
+    } else {
       push(ast.forEachStatementWithReference(
           awaitToken,
           forToken,
           leftParenthesis,
-          variableOrDeclaration,
-          inKeyword,
-          iterator,
+          (forLoopParts as ForEachPartsWithIdentifier).identifier,
+          forLoopParts.inKeyword,
+          forLoopParts.iterable,
           leftParenthesis?.endGroup,
           body));
     }
@@ -2915,6 +3148,15 @@
     debugEvent("endElseStatement");
   }
 
+  List<CollectionElement> popCollectionElements(int count) {
+    final elements = new List<CollectionElement>()..length = count;
+    for (int index = count - 1; index >= 0; --index) {
+      var element = pop();
+      elements[index] = element as CollectionElement;
+    }
+    return elements;
+  }
+
   List popList(int n, List list) {
     if (n == 0) return null;
     return stack.popList(n, list, null);
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index dbb487e..b86cd55 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -145,14 +145,14 @@
     Expression leftHandSide = node.leftHandSide;
     DartType staticType = _getStaticType(leftHandSide, read: true);
 
-    // For any compound assignments to a void variable, report bad void usage.
+    // For any compound assignments to a void or nullable variable, report it.
     // Example: `y += voidFn()`, not allowed.
-    if (operatorType != TokenType.EQ &&
-        staticType != null &&
-        staticType.isVoid) {
-      _recordUndefinedToken(
-          null, StaticWarningCode.USE_OF_VOID_RESULT, operator, []);
-      return;
+    if (operatorType != TokenType.EQ) {
+      if (staticType != null && staticType.isVoid) {
+        _recordUndefinedToken(
+            null, StaticWarningCode.USE_OF_VOID_RESULT, operator, []);
+        return;
+      }
     }
 
     if (operatorType != TokenType.AMPERSAND_AMPERSAND_EQ &&
@@ -165,7 +165,7 @@
         MethodElement staticMethod =
             _lookUpMethod(leftHandSide, staticType, methodName);
         node.staticElement = staticMethod;
-        if (_shouldReportMissingMember(staticType, staticMethod)) {
+        if (_shouldReportInvalidMember(staticType, staticMethod)) {
           _recordUndefinedToken(
               staticType.element,
               StaticTypeWarningCode.UNDEFINED_METHOD,
@@ -533,7 +533,7 @@
     DartType staticType = _getStaticType(operand);
     MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
     node.staticElement = staticMethod;
-    if (_shouldReportMissingMember(staticType, staticMethod)) {
+    if (_shouldReportInvalidMember(staticType, staticMethod)) {
       if (operand is SuperExpression) {
         _recordUndefinedToken(
             staticType.element,
@@ -646,7 +646,7 @@
       MethodElement staticMethod =
           _lookUpMethod(operand, staticType, methodName);
       node.staticElement = staticMethod;
-      if (_shouldReportMissingMember(staticType, staticMethod)) {
+      if (_shouldReportInvalidMember(staticType, staticMethod)) {
         if (operand is SuperExpression) {
           _recordUndefinedToken(
               staticType.element,
@@ -891,7 +891,7 @@
       String methodName,
       MethodElement staticMethod,
       DartType staticType) {
-    if (_shouldReportMissingMember(staticType, staticMethod)) {
+    if (_shouldReportInvalidMember(staticType, staticMethod)) {
       Token leftBracket = expression.leftBracket;
       Token rightBracket = expression.rightBracket;
       ErrorCode errorCode;
@@ -1443,7 +1443,7 @@
       var invokeElement = invokeType?.element;
       node.staticElement = invokeElement;
       node.staticInvokeType = invokeType;
-      if (_shouldReportMissingMember(leftType, invokeElement)) {
+      if (_shouldReportInvalidMember(leftType, invokeElement)) {
         if (isSuper) {
           _recordUndefinedToken(
               leftType.element,
@@ -1608,7 +1608,7 @@
       return;
     }
     propertyName.staticElement = staticElement;
-    if (_shouldReportMissingMember(staticType, staticElement)) {
+    if (_shouldReportInvalidMember(staticType, staticElement)) {
       Element staticOrPropagatedEnclosingElt = staticType.element;
       bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt);
       // Special getter cases.
@@ -1731,12 +1731,12 @@
       type?.resolveToBound(_resolver.typeProvider.objectType);
 
   /**
-   * Return `true` if we should report an error as a result of looking up a
-   * [member] in the given [type] and not finding any member.
+   * Return `true` if we should report an error for a [member] lookup that found
+   * no match on the given [type], or accessing a [member] on a nullable type.
    */
-  bool _shouldReportMissingMember(DartType type, Element member) {
-    return member == null &&
-        type != null &&
+  bool _shouldReportInvalidMember(DartType type, Element member) {
+    return type != null &&
+        member == null &&
         !type.isDynamic &&
         !type.isDartCoreNull;
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 527f2ed..3b581fa 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -95,12 +95,6 @@
  */
 abstract class AnalysisContext {
   /**
-   * An empty list of contexts.
-   */
-  @deprecated
-  static const List<AnalysisContext> EMPTY_LIST = const <AnalysisContext>[];
-
-  /**
    * The file resolver provider used to override the way file URI's are
    * resolved in some contexts.
    */
@@ -2058,12 +2052,6 @@
  */
 class ChangeNoticeImpl implements ChangeNotice {
   /**
-   * An empty list of change notices.
-   */
-  @deprecated
-  static const List<ChangeNoticeImpl> EMPTY_LIST = const <ChangeNoticeImpl>[];
-
-  /**
    * The source for which the result is being reported.
    */
   @override
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 5283d92..55f766e 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -369,6 +369,7 @@
     } else {
       _checkForInvalidCompoundAssignment(node, lhs, rhs);
       _checkForArgumentTypeNotAssignableForArgument(rhs);
+      _checkForNullableDereference(lhs);
     }
     _checkForAssignmentToFinal(lhs);
     super.visitAssignmentExpression(node);
@@ -394,10 +395,17 @@
       _checkForAssignability(node.rightOperand, _boolType,
           StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
       _checkForUseOfVoidResult(node.rightOperand);
+      _checkForNullableDereference(node.leftOperand);
+      _checkForNullableDereference(node.rightOperand);
+    } else if (type != TokenType.EQ_EQ && type != TokenType.BANG_EQ) {
+      _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
+      _checkForNullableDereference(node.leftOperand);
     } else {
       _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
     }
+
     _checkForUseOfVoidResult(node.leftOperand);
+
     super.visitBinaryExpression(node);
   }
 
@@ -448,6 +456,11 @@
     }
   }
 
+  void visitCascadeExpression(CascadeExpression node) {
+    _checkForNullableDereference(node.target);
+    super.visitCascadeExpression(node);
+  }
+
   @override
   void visitCatchClause(CatchClause node) {
     _checkDuplicateDefinitionInCatchClause(node);
@@ -532,9 +545,6 @@
   @override
   void visitConditionalExpression(ConditionalExpression node) {
     _checkForNonBoolCondition(node.condition);
-    // TODO(mfairhurst) Enable this and get code compliant.
-    //_checkForUseOfVoidResult(node.thenExpression);
-    //_checkForUseOfVoidResult(node.elseExpression);
     super.visitConditionalExpression(node);
   }
 
@@ -691,6 +701,39 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+    if (loopVariable == null) {
+      // Ignore malformed for statements.
+      return;
+    }
+    if (_checkForEachParts(node, loopVariable.identifier)) {
+      if (loopVariable.isConst) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, loopVariable);
+      }
+    }
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    SimpleIdentifier identifier = node.identifier;
+    if (identifier == null) {
+      // Ignore malformed for statements.
+      return;
+    }
+    if (_checkForEachParts(node, identifier)) {
+      Element variableElement = identifier.staticElement;
+      if (variableElement is VariableElement && variableElement.isConst) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, identifier);
+      }
+    }
+    super.visitForEachPartsWithIdentifier(node);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     _checkForInIterable(node);
     super.visitForEachStatement(node);
@@ -704,6 +747,25 @@
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    if (node.condition != null) {
+      _checkForNonBoolCondition(node.condition);
+    }
+    if (node.variables != null) {
+      _checkDuplicateVariables(node.variables);
+    }
+    super.visitForPartsWithDeclarations(node);
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    if (node.condition != null) {
+      _checkForNonBoolCondition(node.condition);
+    }
+    super.visitForPartsWithExpression(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     if (node.condition != null) {
       _checkForNonBoolCondition(node.condition);
@@ -775,7 +837,8 @@
   void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     Expression functionExpression = node.function;
     DartType expressionType = functionExpression.staticType;
-    if (!_checkForUseOfVoidResult(functionExpression) &&
+    if (!_checkForNullableDereference(functionExpression) &&
+        !_checkForUseOfVoidResult(functionExpression) &&
         !_isFunctionType(expressionType)) {
       _errorReporter.reportErrorForNode(
           StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION,
@@ -784,6 +847,7 @@
       _checkTypeArguments(node);
     }
     _checkForImplicitDynamicInvoke(node);
+    _checkForNullableDereference(node.function);
     super.visitFunctionExpressionInvocation(node);
   }
 
@@ -869,6 +933,7 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     _checkForArgumentTypeNotAssignableForArgument(node.index);
+    _checkForNullableDereference(node.target);
     super.visitIndexExpression(node);
   }
 
@@ -930,7 +995,8 @@
               CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
         }
       }
-      _checkForExpectedOneListTypeArgument(node, typeArguments);
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
     }
     _checkForImplicitDynamicTypedLiteral(node);
     _checkForListElementTypeNotAssignable(node);
@@ -939,6 +1005,26 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+        if (arguments.isNotEmpty) {
+          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
+              CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
+        }
+      }
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+    _checkForListElementTypeNotAssignable2(node);
+
+    super.visitListLiteral2(node);
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     TypeArgumentList typeArguments = node.typeArguments;
     if (typeArguments != null) {
@@ -949,7 +1035,8 @@
               CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
         }
       }
-      _checkExpectedTwoMapTypeArguments(typeArguments);
+      _checkTypeArgumentCount(typeArguments, 2,
+          StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
     }
     _checkForImplicitDynamicTypedLiteral(node);
     _checkForMapTypeNotAssignable(node);
@@ -958,6 +1045,26 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+      if (arguments.isNotEmpty) {
+        if (node.isConst) {
+          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
+              CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
+        }
+      }
+      _checkTypeArgumentCount(typeArguments, 2,
+          StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+    _checkForMapTypeNotAssignable2(node);
+    _checkForNonConstMapAsExpressionStatement2(node);
+    super.visitMapLiteral2(node);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement previousFunction = _enclosingFunction;
     try {
@@ -995,9 +1102,15 @@
       _checkForInstanceAccessToStaticMember(typeReference, methodName);
     } else {
       _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
+      _checkForNullableDereference(node.function);
     }
     _checkTypeArguments(node);
     _checkForImplicitDynamicInvoke(node);
+    if (node.operator?.type != TokenType.QUESTION_PERIOD &&
+        methodName.name != 'toString' &&
+        methodName.name != 'noSuchMethod') {
+      _checkForNullableDereference(target);
+    }
     super.visitMethodInvocation(node);
   }
 
@@ -1025,7 +1138,7 @@
 
       _initializeInitialFieldElementsMap(_enclosingClass.fields);
       _checkForFinalNotInitializedInClass(members);
-//      _checkForBadFunctionUse(node);
+      //      _checkForBadFunctionUse(node);
       super.visitMixinDeclaration(node);
     } finally {
       _initialFieldElementsMap = null;
@@ -1054,6 +1167,7 @@
   void visitPostfixExpression(PostfixExpression node) {
     _checkForAssignmentToFinal(node.operand);
     _checkForIntNotAssignable(node.operand);
+    _checkForNullableDereference(node.operand);
     super.visitPostfixExpression(node);
   }
 
@@ -1066,6 +1180,12 @@
       _checkForStaticAccessToInstanceMember(typeReference, name);
       _checkForInstanceAccessToStaticMember(typeReference, name);
     }
+    String property = node.identifier.name;
+    if (node.staticElement is ExecutableElement &&
+        property != 'hashCode' &&
+        property != 'runtimeType') {
+      _checkForNullableDereference(node.prefix);
+    }
     super.visitPrefixedIdentifier(node);
   }
 
@@ -1079,6 +1199,7 @@
       _checkForAssignmentToFinal(operand);
     }
     _checkForIntNotAssignable(operand);
+    _checkForNullableDereference(operand);
     _checkForUseOfVoidResult(operand);
     super.visitPrefixExpression(node);
   }
@@ -1090,6 +1211,11 @@
     SimpleIdentifier propertyName = node.propertyName;
     _checkForStaticAccessToInstanceMember(typeReference, propertyName);
     _checkForInstanceAccessToStaticMember(typeReference, propertyName);
+    if (node.operator?.type != TokenType.QUESTION_PERIOD &&
+        propertyName.name != 'hashCode' &&
+        propertyName.name != 'runtimeType') {
+      _checkForNullableDereference(node.target);
+    }
     super.visitPropertyAccess(node);
   }
 
@@ -1132,7 +1258,8 @@
               CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET);
         }
       }
-      _checkForExpectedOneSetTypeArgument(node, typeArguments);
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
     }
     _checkForImplicitDynamicTypedLiteral(node);
     _checkForSetElementTypeNotAssignable(node);
@@ -1141,6 +1268,26 @@
   }
 
   @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.isConst) {
+        NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+        if (arguments.isNotEmpty) {
+          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
+              CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET);
+        }
+      }
+      _checkTypeArgumentCount(typeArguments, 1,
+          StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS);
+    }
+    _checkForImplicitDynamicTypedLiteral(node);
+    _checkForSetElementTypeNotAssignable2(node);
+
+    super.visitSetLiteral2(node);
+  }
+
+  @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     _checkForConstFormalParameter(node);
     _checkForPrivateOptionalParameter(node);
@@ -1208,6 +1355,7 @@
   @override
   void visitThrowExpression(ThrowExpression node) {
     _checkForConstEvalThrowsException(node);
+    _checkForNullableDereference(node.expression);
     _checkForUseOfVoidResult(node.expression);
     super.visitThrowExpression(node);
   }
@@ -1312,6 +1460,9 @@
   void visitYieldStatement(YieldStatement node) {
     if (_inGenerator) {
       _checkForYieldOfInvalidType(node.expression, node.star != null);
+      if (node.star != null) {
+        _checkForNullableDereference(node.expression);
+      }
     } else {
       CompileTimeErrorCode errorCode;
       if (node.star != null) {
@@ -1706,22 +1857,6 @@
   }
 
   /**
-   * Verify that the given list of [typeArguments] contains exactly two
-   * elements.
-   *
-   * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS].
-   */
-  void _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) {
-    int num = typeArguments.arguments.length;
-    if (num != 2) {
-      _errorReporter.reportErrorForNode(
-          StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS,
-          typeArguments,
-          [num]);
-    }
-  }
-
-  /**
    * Check that return statements without expressions are not in a generative
    * constructor and the return type is not assignable to `null`; that is, we
    * don't have `return;` if the enclosing method has a non-void containing
@@ -2423,6 +2558,34 @@
   }
 
   /**
+   * Verify that the given [element] can be assigned to the [elementType] of the
+   * enclosing list or set literal. Report an error with the given [errorCode]
+   * if not.
+   *
+   * This method corresponds to
+   * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes].
+   */
+  void _checkForCollectionElementTypeNotAssignableWithElementType(
+      CollectionElement element, DartType elementType, ErrorCode errorCode) {
+    if (element is ForElement) {
+      _checkForCollectionElementTypeNotAssignableWithElementType(
+          element.body, elementType, errorCode);
+    } else if (element is IfElement) {
+      _checkForCollectionElementTypeNotAssignableWithElementType(
+          element.thenElement, elementType, errorCode);
+      _checkForCollectionElementTypeNotAssignableWithElementType(
+          element.elseElement, elementType, errorCode);
+    } else if (element is Expression) {
+      _checkForArgumentTypeNotAssignable(
+          element, elementType, getStaticType(element), errorCode);
+    } else if (element is SpreadElement) {
+      Expression expression = element.expression;
+      _checkForArgumentTypeNotAssignable(
+          expression, elementType, getStaticType(expression), errorCode);
+    }
+  }
+
+  /**
    * Verify that the [_enclosingClass] does not have a method and getter pair
    * with the same name on, via inheritance.
    *
@@ -2892,39 +3055,67 @@
   }
 
   /**
-   * Verify that if the given list [literal] has type arguments then there is
-   * exactly one. The [typeArguments] are the type arguments.
-   *
-   * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS].
+   * Return `true` if the caller should continue checking the rest of the
+   * information in the for-each part.
    */
-  void _checkForExpectedOneListTypeArgument(
-      ListLiteral literal, TypeArgumentList typeArguments) {
-    // check number of type arguments
-    int num = typeArguments.arguments.length;
-    if (num != 1) {
-      _errorReporter.reportErrorForNode(
-          StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
-          typeArguments,
-          [num]);
+  bool _checkForEachParts(ForEachParts node, SimpleIdentifier variable) {
+    if (_checkForNullableDereference(node.iterable)) {
+      return false;
     }
-  }
 
-  /**
-   * Verify that if the given set [literal] has type arguments then there is
-   * exactly one. The [typeArguments] are the type arguments.
-   *
-   * See [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS].
-   */
-  void _checkForExpectedOneSetTypeArgument(
-      SetLiteral literal, TypeArgumentList typeArguments) {
-    // check number of type arguments
-    int count = typeArguments.arguments.length;
-    if (count != 1) {
-      _errorReporter.reportErrorForNode(
-          StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS,
-          typeArguments,
-          [count]);
+    if (_checkForUseOfVoidResult(node.iterable)) {
+      return false;
     }
+
+    DartType iterableType = getStaticType(node.iterable);
+    if (iterableType.isDynamic) {
+      return false;
+    }
+
+    // The type of the loop variable.
+    DartType variableType = getStaticType(variable);
+
+    AstNode parent = node.parent;
+    Token awaitKeyword;
+    if (parent is ForStatement2) {
+      awaitKeyword = parent.awaitKeyword;
+    } else if (parent is ForElement) {
+      awaitKeyword = parent.awaitKeyword;
+    }
+    DartType loopType = awaitKeyword != null
+        ? _typeProvider.streamType
+        : _typeProvider.iterableType;
+
+    // Use an explicit string instead of [loopType] to remove the "<E>".
+    String loopTypeName = awaitKeyword != null ? "Stream" : "Iterable";
+
+    // The object being iterated has to implement Iterable<T> for some T that
+    // is assignable to the variable's type.
+    // TODO(rnystrom): Move this into mostSpecificTypeArgument()?
+    iterableType = iterableType.resolveToBound(_typeProvider.objectType);
+    DartType bestIterableType =
+        _typeSystem.mostSpecificTypeArgument(iterableType, loopType);
+
+    // Allow it to be a supertype of Iterable<T> (basically just Object) and do
+    // an implicit downcast to Iterable<dynamic>.
+    if (bestIterableType == null) {
+      if (_typeSystem.isSubtypeOf(loopType, iterableType)) {
+        bestIterableType = DynamicTypeImpl.instance;
+      }
+    }
+
+    if (bestIterableType == null) {
+      _errorReporter.reportTypeErrorForNode(
+          StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
+          node.iterable,
+          [iterableType, loopTypeName]);
+    } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) {
+      _errorReporter.reportTypeErrorForNode(
+          StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
+          node.iterable,
+          [iterableType, loopTypeName, variableType]);
+    }
+    return true;
   }
 
   /**
@@ -3432,6 +3623,7 @@
     DartType type = node.staticType;
     // It's an error if either the key or value was inferred as dynamic.
     if (type is InterfaceType && type.typeArguments.any((t) => t.isDynamic)) {
+      // TODO(brianwilkerson) Add StrongModeCode.IMPLICIT_DYNAMIC_SET_LITERAL
       ErrorCode errorCode = node is ListLiteral
           ? StrongModeCode.IMPLICIT_DYNAMIC_LIST_LITERAL
           : StrongModeCode.IMPLICIT_DYNAMIC_MAP_LITERAL;
@@ -3586,6 +3778,10 @@
       return;
     }
 
+    if (_checkForNullableDereference(node.iterable)) {
+      return;
+    }
+
     if (_checkForUseOfVoidResult(node.iterable)) {
       return;
     }
@@ -3599,9 +3795,6 @@
     SimpleIdentifier variable = node.identifier ?? loopVariable.identifier;
     DartType variableType = getStaticType(variable);
 
-    // TODO(mfairhurst) Check and guard against `for(void x in _)`?
-    //_checkForUseOfVoidResult(variable);
-
     DartType loopType = node.awaitKeyword != null
         ? _typeProvider.streamType
         : _typeProvider.iterableType;
@@ -3827,8 +4020,8 @@
   }
 
   /**
-   * Verify that the elements given list [literal] are subtypes of the list's
-   * static type.
+   * Verify that the elements of the given list [literal] are subtypes of the
+   * list's static type.
    *
    * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and
    * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE].
@@ -3863,6 +4056,92 @@
   }
 
   /**
+   * Verify that the elements of the given list [literal] are subtypes of the
+   * list's static type.
+   */
+  void _checkForListElementTypeNotAssignable2(ListLiteral2 literal) {
+    // Determine the list's element type. We base this on the static type and
+    // not the literal's type arguments because in strong mode, the type
+    // arguments may be inferred.
+    DartType listType = literal.staticType;
+    assert(listType is InterfaceTypeImpl);
+
+    List<DartType> typeArguments =
+        (listType as InterfaceTypeImpl).typeArguments;
+    assert(typeArguments.length == 1);
+
+    DartType listElementType = typeArguments[0];
+
+    // Check every list element.
+    bool isConst = literal.isConst;
+    for (CollectionElement element in literal.elements) {
+      if (isConst) {
+        // TODO(paulberry): this error should be based on the actual type of the
+        // list element, not the static type.  See dartbug.com/21119.
+        _checkForCollectionElementTypeNotAssignableWithElementType(
+            element,
+            listElementType,
+            CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE);
+      } else {
+        _checkForCollectionElementTypeNotAssignableWithElementType(
+            element,
+            listElementType,
+            StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE);
+      }
+    }
+  }
+
+  /**
+   * Verify that the given [element] can be assigned to the [elementType] of the
+   * enclosing list or set literal. Report an error with the given [errorCode]
+   * if not.
+   *
+   * This method corresponds to
+   * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes].
+   */
+  void _checkForMapElementTypeNotAssignableWithKeyOrValueType(
+      CollectionElement element,
+      DartType keyType,
+      DartType valueType,
+      ErrorCode keyErrorCode,
+      ErrorCode valueErrorCode) {
+    if (element is ForElement) {
+      _checkForMapElementTypeNotAssignableWithKeyOrValueType(
+          element.body, keyType, valueType, keyErrorCode, valueErrorCode);
+    } else if (element is IfElement) {
+      _checkForMapElementTypeNotAssignableWithKeyOrValueType(
+          element.thenElement,
+          keyType,
+          valueType,
+          keyErrorCode,
+          valueErrorCode);
+      _checkForMapElementTypeNotAssignableWithKeyOrValueType(
+          element.elseElement,
+          keyType,
+          valueType,
+          keyErrorCode,
+          valueErrorCode);
+    } else if (element is MapLiteralEntry) {
+      _checkForArgumentTypeNotAssignableWithExpectedTypes(
+          element.key, keyType, keyErrorCode);
+      _checkForArgumentTypeNotAssignableWithExpectedTypes(
+          element.value, valueType, valueErrorCode);
+    } else if (element is SpreadElement) {
+      Expression expression = element.expression;
+      DartType expressionType = getStaticType(expression);
+      if (expressionType is ParameterizedType) {
+        List<DartType> typeArguments = expressionType.typeArguments;
+        if (typeArguments.length == 2) {
+          _checkForArgumentTypeNotAssignable(
+              expression, keyType, typeArguments[0], keyErrorCode);
+          _checkForArgumentTypeNotAssignable(
+              expression, valueType, typeArguments[1], valueErrorCode);
+        }
+      }
+    }
+  }
+
+  /**
    * Verify that the key/value of entries of the given map [literal] are
    * subtypes of the map's static type.
    *
@@ -3909,6 +4188,55 @@
   }
 
   /**
+   * Verify that the key/value of entries of the given map [literal] are
+   * subtypes of the map's static type.
+   *
+   * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
+   * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
+   * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
+   * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
+   */
+  void _checkForMapTypeNotAssignable2(MapLiteral2 literal) {
+    // Determine the map's key and value types. We base this on the static type
+    // and not the literal's type arguments because in strong mode, the type
+    // arguments may be inferred.
+    DartType mapType = literal.staticType;
+    if (mapType == null) {
+      // This is known to happen when the literal is the default value in an
+      // optional parameter in a generic function type alias.
+      return;
+    }
+    assert(mapType is InterfaceTypeImpl);
+
+    List<DartType> typeArguments = (mapType as InterfaceTypeImpl).typeArguments;
+    assert(typeArguments.length == 2);
+    DartType keyType = typeArguments[0];
+    DartType valueType = typeArguments[1];
+
+    bool isConst = literal.isConst;
+    NodeList<CollectionElement> entries = literal.entries;
+    for (CollectionElement entry in entries) {
+      if (isConst) {
+        // TODO(paulberry): this error should be based on the actual type of the
+        // list element, not the static type.  See dartbug.com/21119.
+        _checkForMapElementTypeNotAssignableWithKeyOrValueType(
+            entry,
+            keyType,
+            valueType,
+            CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+            CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE);
+      } else {
+        _checkForMapElementTypeNotAssignableWithKeyOrValueType(
+            entry,
+            keyType,
+            valueType,
+            StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+            StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE);
+      }
+    }
+  }
+
+  /**
    * Verify that the [_enclosingClass] does not define members with the same name
    * as the enclosing class.
    *
@@ -4423,7 +4751,8 @@
    */
   void _checkForNonBoolCondition(Expression condition) {
     DartType conditionType = getStaticType(condition);
-    if (!_checkForUseOfVoidResult(condition) &&
+    if (!_checkForNullableDereference(condition) &&
+        !_checkForUseOfVoidResult(condition) &&
         conditionType != null &&
         !_typeSystem.isAssignableTo(conditionType, _boolType)) {
       _errorReporter.reportErrorForNode(
@@ -4497,6 +4826,37 @@
   }
 
   /**
+   * Verify the given map [literal] either:
+   * * has `const modifier`
+   * * has explicit type arguments
+   * * is not start of the statement
+   *
+   * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT].
+   */
+  void _checkForNonConstMapAsExpressionStatement2(MapLiteral2 literal) {
+    // "const"
+    if (literal.constKeyword != null) {
+      return;
+    }
+    // has type arguments
+    if (literal.typeArguments != null) {
+      return;
+    }
+    // prepare statement
+    Statement statement = literal.thisOrAncestorOfType<ExpressionStatement>();
+    if (statement == null) {
+      return;
+    }
+    // OK, statement does not start with map
+    if (!identical(statement.beginToken, literal.beginToken)) {
+      return;
+    }
+
+    _errorReporter.reportErrorForNode(
+        CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal);
+  }
+
+  /**
    * Verify that the given method [declaration] of operator `[]=`, has `void`
    * return type.
    *
@@ -4536,6 +4896,34 @@
   }
 
   /**
+   * Check for illegal derefences of nullables, ie, "unchecked" usages of
+   * nullable values. Note that *any* usage of a null value is an "unchecked"
+   * usage, because proper checks will promote the type to a non-nullable value.
+   *
+   * See [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]
+   */
+  bool _checkForNullableDereference(Expression expression) {
+    if (expression == null ||
+        !_options.experimentStatus.non_nullable ||
+        expression.staticType == null ||
+        (expression.staticType as TypeImpl).nullability !=
+            Nullability.nullable) {
+      return false;
+    }
+
+    StaticWarningCode code = StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE;
+
+    if (expression is MethodInvocation) {
+      SimpleIdentifier methodName = expression.methodName;
+      _errorReporter.reportErrorForNode(code, methodName, []);
+    } else {
+      _errorReporter.reportErrorForNode(code, expression, []);
+    }
+
+    return true;
+  }
+
+  /**
    * Verify that all classes of the given [onClause] are valid.
    *
    * See [CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS],
@@ -5015,6 +5403,42 @@
   }
 
   /**
+   * Verify that the elements in the given set [literal] are subtypes of the
+   * set's static type.
+   *
+   * See [CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE], and
+   * [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE].
+   */
+  void _checkForSetElementTypeNotAssignable2(SetLiteral2 literal) {
+    // Determine the list's element type. We base this on the static type and
+    // not the literal's type arguments because in strong mode, the type
+    // arguments may be inferred.
+    DartType setType = literal.staticType;
+    assert(setType is InterfaceTypeImpl);
+
+    List<DartType> typeArguments = (setType as InterfaceTypeImpl).typeArguments;
+    assert(typeArguments.length == 1);
+
+    DartType setElementType = typeArguments[0];
+
+    // Check every list element.
+    bool isConst = literal.isConst;
+    for (CollectionElement element in literal.elements) {
+      if (isConst) {
+        // TODO(paulberry): this error should be based on the actual type of the
+        // element, not the static type.  See dartbug.com/21119.
+        _checkForCollectionElementTypeNotAssignableWithElementType(
+            element,
+            setElementType,
+            CheckedModeCompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE);
+      } else {
+        _checkForCollectionElementTypeNotAssignableWithElementType(element,
+            setElementType, StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE);
+      }
+    }
+  }
+
+  /**
    * Check the given [typeReference] and that the [name] is not a reference to
    * an instance member.
    *
@@ -5644,6 +6068,20 @@
   }
 
   /**
+   * Verify that the given list of [typeArguments] contains exactly the
+   * [expectedCount] of elements, reporting an error with the given [errorCode]
+   * if not.
+   */
+  void _checkTypeArgumentCount(
+      TypeArgumentList typeArguments, int expectedCount, ErrorCode errorCode) {
+    int actualCount = typeArguments.arguments.length;
+    if (actualCount != expectedCount) {
+      _errorReporter
+          .reportErrorForNode(errorCode, typeArguments, [actualCount]);
+    }
+  }
+
+  /**
    * Verify that the given [typeArguments] are all within their bounds, as
    * defined by the given [element].
    *
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index b75defe..9ea56c4 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -251,6 +251,22 @@
     }
   }
 
+  /// Enables or disables parsing of spread collections.
+  void set enableSpreadCollections(bool value) {
+    if (value) {
+      throw new UnimplementedError(
+          'spread_collections experiment not supported by analyzer parser');
+    }
+  }
+
+  /// Enables or disables parsing of control flow collections.
+  void set enableControlFlowCollections(bool value) {
+    if (value) {
+      throw new UnimplementedError('control_flow_collections experiment'
+          ' not supported by analyzer parser');
+    }
+  }
+
   /// Return `true` if the parser is to allow URI's in part-of directives.
   @deprecated
   bool get enableUriInPartOf => true;
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index 389c230..62e616e 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -63,6 +63,26 @@
   }
 
   @override
+  void set enableSpreadCollections(bool value) {
+    if (IsExpired.spread_collections &&
+        value != IsEnabledByDefault.spread_collections) {
+      throw new StateError('spread_collections may only be set'
+          ' to ${IsEnabledByDefault.spread_collections}');
+    }
+    astBuilder.enableSpreadCollections = value;
+  }
+
+  @override
+  void set enableControlFlowCollections(bool value) {
+    if (IsExpired.control_flow_collections &&
+        value != IsEnabledByDefault.control_flow_collections) {
+      throw new StateError('control_flow_collections may only be set'
+          ' to ${IsEnabledByDefault.control_flow_collections}');
+    }
+    astBuilder.enableControlFlowCollections = value;
+  }
+
+  @override
   void set parseFunctionBodies(bool parseFunctionBodies) {
     astBuilder.parseFunctionBodies = parseFunctionBodies;
   }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9dc3ff1..e10c1fd 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/exit_detector.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/constant.dart';
@@ -38,6 +39,7 @@
 import 'package:path/path.dart' as path;
 
 export 'package:analyzer/src/dart/constant/constant_verifier.dart';
+export 'package:analyzer/src/dart/resolver/exit_detector.dart';
 export 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
 export 'package:analyzer/src/dart/resolver/scope.dart';
 export 'package:analyzer/src/generated/type_system.dart';
@@ -299,6 +301,7 @@
     TypeSystem typeSystem,
     ResourceProvider resourceProvider,
     DeclaredVariables declaredVariables,
+    AnalysisOptions analysisOptions,
   })  : _nullType = typeProvider.nullType,
         _futureNullType = typeProvider.futureNullType,
         _typeSystem = typeSystem ?? new Dart2TypeSystem(typeProvider),
@@ -306,11 +309,18 @@
             new _InvalidAccessVerifier(_errorReporter, _currentLibrary) {
     _inDeprecatedMember = _currentLibrary.hasDeprecated;
     String libraryPath = _currentLibrary.source.fullName;
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, libraryPath, null /* ContextBuilder */);
+    ContextBuilder builder = new ContextBuilder(
+        resourceProvider, null /* sdkManager */, null /* contentCache */);
+    Workspace workspace =
+        ContextBuilder.createWorkspace(resourceProvider, libraryPath, builder);
     _workspacePackage = workspace.findPackageFor(libraryPath);
-    _linterContext = LinterContextImpl(null /* allUnits */,
-        null /* currentUnit */, declaredVariables, typeProvider, _typeSystem);
+    _linterContext = LinterContextImpl(
+        null /* allUnits */,
+        null /* currentUnit */,
+        declaredVariables,
+        typeProvider,
+        _typeSystem,
+        analysisOptions);
   }
 
   @override
@@ -338,10 +348,42 @@
       }
     } else if (element?.isSealed == true) {
       if (!(parent is ClassDeclaration || parent is ClassTypeAlias)) {
-        _errorReporter.reportErrorForNode(HintCode.INVALID_SEALED_ANNOTATION,
-            node.parent, [node.element.name]);
+        _errorReporter.reportErrorForNode(
+            HintCode.INVALID_SEALED_ANNOTATION, node, [node.element.name]);
+      }
+    } else if (element?.isVisibleForTemplate == true ||
+        element?.isVisibleForTesting == true) {
+      if (parent is Declaration) {
+        reportInvalidAnnotation(Element declaredElement) {
+          _errorReporter.reportErrorForNode(
+              HintCode.INVALID_VISIBILITY_ANNOTATION,
+              node,
+              [declaredElement.name, node.name.name]);
+        }
+
+        if (parent is TopLevelVariableDeclaration) {
+          for (VariableDeclaration variable in parent.variables.variables) {
+            if (Identifier.isPrivateName(variable.declaredElement.name)) {
+              reportInvalidAnnotation(variable.declaredElement);
+            }
+          }
+        } else if (parent is FieldDeclaration) {
+          for (VariableDeclaration variable in parent.fields.variables) {
+            if (Identifier.isPrivateName(variable.declaredElement.name)) {
+              reportInvalidAnnotation(variable.declaredElement);
+            }
+          }
+        } else if (parent.declaredElement != null &&
+            Identifier.isPrivateName(parent.declaredElement.name)) {
+          reportInvalidAnnotation(parent.declaredElement);
+        }
+      } else {
+        // Something other than a declaration was annotated. Whatever this is,
+        // it probably warrants a Hint, but this has not been specified on
+        // visibleForTemplate or visibleForTesting, so leave it alone for now.
       }
     }
+
     super.visitAnnotation(node);
   }
 
@@ -700,6 +742,15 @@
       return false;
     }
 
+    bool isLibraryInWorkspacePackage(LibraryElement library) {
+      if (_workspacePackage == null || library == null) {
+        // Better to not make a big claim that they _are_ in the same package,
+        // if we were unable to determine what package [_currentLibrary] is in.
+        return false;
+      }
+      return _workspacePackage.contains(library.source.fullName);
+    }
+
     if (!_inDeprecatedMember &&
         element != null &&
         isDeprecated(element) &&
@@ -722,7 +773,7 @@
       }
       LibraryElement library =
           element is LibraryElement ? element : element.library;
-      HintCode hintCode = _workspacePackage.contains(library.source.fullName)
+      HintCode hintCode = isLibraryInWorkspacePackage(library)
           ? HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE
           : HintCode.DEPRECATED_MEMBER_USE;
       _errorReporter.reportErrorForNode(hintCode, node, [displayName]);
@@ -1539,6 +1590,34 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    Expression conditionExpression = node.condition;
+    conditionExpression?.accept(this);
+    if (!_isDebugConstant(conditionExpression)) {
+      EvaluationResultImpl result =
+          _getConstantBooleanValue(conditionExpression);
+      if (result != null) {
+        if (result.value.toBoolValue() == true) {
+          // Report error on else block: if(true) {} else {!}
+          CollectionElement elseElement = node.elseElement;
+          if (elseElement != null) {
+            _errorReporter.reportErrorForNode(HintCode.DEAD_CODE, elseElement);
+            node.thenElement?.accept(this);
+            return;
+          }
+        } else {
+          // Report error on if block: if (false) {!} else {}
+          _errorReporter.reportErrorForNode(
+              HintCode.DEAD_CODE, node.thenElement);
+          node.elseElement?.accept(this);
+          return;
+        }
+      }
+    }
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     Expression conditionExpression = node.condition;
     conditionExpression?.accept(this);
@@ -2390,536 +2469,6 @@
   }
 }
 
-/// Instances of the class `ExitDetector` determine whether the visited AST node
-/// is guaranteed to terminate by executing a `return` statement, `throw`
-/// expression, `rethrow` expression, or simple infinite loop such as
-/// `while(true)`.
-class ExitDetector extends GeneralizingAstVisitor<bool> {
-  /// Set to `true` when a `break` is encountered, and reset to `false` when a
-  /// `do`, `while`, `for` or `switch` block is entered.
-  bool _enclosingBlockContainsBreak = false;
-
-  /// Set to `true` when a `continue` is encountered, and reset to `false` when
-  /// a `do`, `while`, `for` or `switch` block is entered.
-  bool _enclosingBlockContainsContinue = false;
-
-  /// Add node when a labelled `break` is encountered.
-  Set<AstNode> _enclosingBlockBreaksLabel = new Set<AstNode>();
-
-  @override
-  bool visitArgumentList(ArgumentList node) =>
-      _visitExpressions(node.arguments);
-
-  @override
-  bool visitAsExpression(AsExpression node) => _nodeExits(node.expression);
-
-  @override
-  bool visitAssertInitializer(AssertInitializer node) => false;
-
-  @override
-  bool visitAssertStatement(AssertStatement node) => false;
-
-  @override
-  bool visitAssignmentExpression(AssignmentExpression node) {
-    Expression leftHandSide = node.leftHandSide;
-    if (_nodeExits(leftHandSide)) {
-      return true;
-    }
-    TokenType operatorType = node.operator.type;
-    if (operatorType == TokenType.AMPERSAND_AMPERSAND_EQ ||
-        operatorType == TokenType.BAR_BAR_EQ ||
-        operatorType == TokenType.QUESTION_QUESTION_EQ) {
-      return false;
-    }
-    if (leftHandSide is PropertyAccess &&
-        leftHandSide.operator.type == TokenType.QUESTION_PERIOD) {
-      return false;
-    }
-    return _nodeExits(node.rightHandSide);
-  }
-
-  @override
-  bool visitAwaitExpression(AwaitExpression node) =>
-      _nodeExits(node.expression);
-
-  @override
-  bool visitBinaryExpression(BinaryExpression node) {
-    Expression lhsExpression = node.leftOperand;
-    Expression rhsExpression = node.rightOperand;
-    TokenType operatorType = node.operator.type;
-    // If the operator is ||, then only consider the RHS of the binary
-    // expression if the left hand side is the false literal.
-    // TODO(jwren) Do we want to take constant expressions into account,
-    // evaluate if(false) {} differently than if(<condition>), when <condition>
-    // evaluates to a constant false value?
-    if (operatorType == TokenType.BAR_BAR) {
-      if (lhsExpression is BooleanLiteral) {
-        if (!lhsExpression.value) {
-          return _nodeExits(rhsExpression);
-        }
-      }
-      return _nodeExits(lhsExpression);
-    }
-    // If the operator is &&, then only consider the RHS of the binary
-    // expression if the left hand side is the true literal.
-    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
-      if (lhsExpression is BooleanLiteral) {
-        if (lhsExpression.value) {
-          return _nodeExits(rhsExpression);
-        }
-      }
-      return _nodeExits(lhsExpression);
-    }
-    // If the operator is ??, then don't consider the RHS of the binary
-    // expression.
-    if (operatorType == TokenType.QUESTION_QUESTION) {
-      return _nodeExits(lhsExpression);
-    }
-    return _nodeExits(lhsExpression) || _nodeExits(rhsExpression);
-  }
-
-  @override
-  bool visitBlock(Block node) => _visitStatements(node.statements);
-
-  @override
-  bool visitBlockFunctionBody(BlockFunctionBody node) => _nodeExits(node.block);
-
-  @override
-  bool visitBreakStatement(BreakStatement node) {
-    _enclosingBlockContainsBreak = true;
-    if (node.label != null) {
-      _enclosingBlockBreaksLabel.add(node.target);
-    }
-    return false;
-  }
-
-  @override
-  bool visitCascadeExpression(CascadeExpression node) =>
-      _nodeExits(node.target) || _visitExpressions(node.cascadeSections);
-
-  @override
-  bool visitConditionalExpression(ConditionalExpression node) {
-    Expression conditionExpression = node.condition;
-    Expression thenStatement = node.thenExpression;
-    Expression elseStatement = node.elseExpression;
-    // TODO(jwren) Do we want to take constant expressions into account,
-    // evaluate if(false) {} differently than if(<condition>), when <condition>
-    // evaluates to a constant false value?
-    if (_nodeExits(conditionExpression)) {
-      return true;
-    }
-    if (thenStatement == null || elseStatement == null) {
-      return false;
-    }
-    return thenStatement.accept(this) && elseStatement.accept(this);
-  }
-
-  @override
-  bool visitContinueStatement(ContinueStatement node) {
-    _enclosingBlockContainsContinue = true;
-    return false;
-  }
-
-  @override
-  bool visitDoStatement(DoStatement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    bool outerContinueValue = _enclosingBlockContainsContinue;
-    _enclosingBlockContainsBreak = false;
-    _enclosingBlockContainsContinue = false;
-    try {
-      bool bodyExits = _nodeExits(node.body);
-      bool containsBreakOrContinue =
-          _enclosingBlockContainsBreak || _enclosingBlockContainsContinue;
-      // Even if we determine that the body "exits", there might be break or
-      // continue statements that actually mean it _doesn't_ always exit.
-      if (bodyExits && !containsBreakOrContinue) {
-        return true;
-      }
-      Expression conditionExpression = node.condition;
-      if (_nodeExits(conditionExpression)) {
-        return true;
-      }
-      // TODO(jwren) Do we want to take all constant expressions into account?
-      if (conditionExpression is BooleanLiteral) {
-        // If do {} while (true), and the body doesn't break, then return true.
-        if (conditionExpression.value && !_enclosingBlockContainsBreak) {
-          return true;
-        }
-      }
-      return false;
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-      _enclosingBlockContainsContinue = outerContinueValue;
-    }
-  }
-
-  @override
-  bool visitEmptyStatement(EmptyStatement node) => false;
-
-  @override
-  bool visitExpressionStatement(ExpressionStatement node) =>
-      _nodeExits(node.expression);
-
-  @override
-  bool visitForEachStatement(ForEachStatement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    _enclosingBlockContainsBreak = false;
-    try {
-      bool iterableExits = _nodeExits(node.iterable);
-      // Discard whether the for-each body exits; since the for-each iterable
-      // may be empty, execution may never enter the body, so it doesn't matter
-      // if it exits or not.  We still must visit the body, to accurately
-      // manage `_enclosingBlockBreaksLabel`.
-      _nodeExits(node.body);
-      return iterableExits;
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-    }
-  }
-
-  @override
-  bool visitForStatement(ForStatement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    _enclosingBlockContainsBreak = false;
-    try {
-      if (node.variables != null &&
-          _visitVariableDeclarations(node.variables.variables)) {
-        return true;
-      }
-      if (node.initialization != null && _nodeExits(node.initialization)) {
-        return true;
-      }
-      Expression conditionExpression = node.condition;
-      if (conditionExpression != null && _nodeExits(conditionExpression)) {
-        return true;
-      }
-      if (_visitExpressions(node.updaters)) {
-        return true;
-      }
-      bool blockReturns = _nodeExits(node.body);
-      // TODO(jwren) Do we want to take all constant expressions into account?
-      // If for(; true; ) (or for(;;)), and the body doesn't return or the body
-      // doesn't have a break, then return true.
-      bool implicitOrExplictTrue = conditionExpression == null ||
-          (conditionExpression is BooleanLiteral && conditionExpression.value);
-      if (implicitOrExplictTrue) {
-        if (blockReturns || !_enclosingBlockContainsBreak) {
-          return true;
-        }
-      }
-      return false;
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-    }
-  }
-
-  @override
-  bool visitFunctionDeclarationStatement(FunctionDeclarationStatement node) =>
-      false;
-
-  @override
-  bool visitFunctionExpression(FunctionExpression node) => false;
-
-  @override
-  bool visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    if (_nodeExits(node.function)) {
-      return true;
-    }
-    return node.argumentList.accept(this);
-  }
-
-  @override
-  bool visitGenericFunctionType(GenericFunctionType node) => false;
-
-  @override
-  bool visitIdentifier(Identifier node) => false;
-
-  @override
-  bool visitIfStatement(IfStatement node) {
-    Expression conditionExpression = node.condition;
-    Statement thenStatement = node.thenStatement;
-    Statement elseStatement = node.elseStatement;
-    if (_nodeExits(conditionExpression)) {
-      return true;
-    }
-    // TODO(jwren) Do we want to take all constant expressions into account?
-    if (conditionExpression is BooleanLiteral) {
-      if (conditionExpression.value) {
-        // if (true) ...
-        return _nodeExits(thenStatement);
-      } else if (elseStatement != null) {
-        // if (false) ...
-        return _nodeExits(elseStatement);
-      }
-    }
-    bool thenExits = _nodeExits(thenStatement);
-    bool elseExits = _nodeExits(elseStatement);
-    if (thenStatement == null || elseStatement == null) {
-      return false;
-    }
-    return thenExits && elseExits;
-  }
-
-  @override
-  bool visitIndexExpression(IndexExpression node) {
-    Expression target = node.realTarget;
-    if (_nodeExits(target)) {
-      return true;
-    }
-    if (_nodeExits(node.index)) {
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitInstanceCreationExpression(InstanceCreationExpression node) =>
-      _nodeExits(node.argumentList);
-
-  @override
-  bool visitIsExpression(IsExpression node) => node.expression.accept(this);
-
-  @override
-  bool visitLabel(Label node) => false;
-
-  @override
-  bool visitLabeledStatement(LabeledStatement node) {
-    try {
-      bool statementExits = _nodeExits(node.statement);
-      bool neverBrokeFromLabel =
-          !_enclosingBlockBreaksLabel.contains(node.statement);
-      return statementExits && neverBrokeFromLabel;
-    } finally {
-      _enclosingBlockBreaksLabel.remove(node.statement);
-    }
-  }
-
-  @override
-  bool visitLiteral(Literal node) => false;
-
-  @override
-  bool visitMethodInvocation(MethodInvocation node) {
-    Expression target = node.realTarget;
-    if (target != null) {
-      if (target.accept(this)) {
-        return true;
-      }
-      if (node.operator.type == TokenType.QUESTION_PERIOD) {
-        return false;
-      }
-    }
-    Element element = node.methodName.staticElement;
-    if (element != null && element.hasAlwaysThrows) {
-      return true;
-    }
-    return _nodeExits(node.argumentList);
-  }
-
-  @override
-  bool visitNamedExpression(NamedExpression node) =>
-      node.expression.accept(this);
-
-  @override
-  bool visitParenthesizedExpression(ParenthesizedExpression node) =>
-      node.expression.accept(this);
-
-  @override
-  bool visitPostfixExpression(PostfixExpression node) => false;
-
-  @override
-  bool visitPrefixExpression(PrefixExpression node) => false;
-
-  @override
-  bool visitPropertyAccess(PropertyAccess node) {
-    Expression target = node.realTarget;
-    if (target != null && target.accept(this)) {
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  bool visitRethrowExpression(RethrowExpression node) => true;
-
-  @override
-  bool visitReturnStatement(ReturnStatement node) => true;
-
-  @override
-  bool visitSuperExpression(SuperExpression node) => false;
-
-  @override
-  bool visitSwitchCase(SwitchCase node) => _visitStatements(node.statements);
-
-  @override
-  bool visitSwitchDefault(SwitchDefault node) =>
-      _visitStatements(node.statements);
-
-  @override
-  bool visitSwitchStatement(SwitchStatement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    _enclosingBlockContainsBreak = false;
-    try {
-      bool hasDefault = false;
-      bool hasNonExitingCase = false;
-      List<SwitchMember> members = node.members;
-      for (int i = 0; i < members.length; i++) {
-        SwitchMember switchMember = members[i];
-        if (switchMember is SwitchDefault) {
-          hasDefault = true;
-          // If this is the last member and there are no statements, then it
-          // does not exit.
-          if (switchMember.statements.isEmpty && i + 1 == members.length) {
-            hasNonExitingCase = true;
-            continue;
-          }
-        }
-        // For switch members with no statements, don't visit the children.
-        // Otherwise, if there children statements don't exit, mark this as a
-        // non-exiting case.
-        if (!switchMember.statements.isEmpty && !switchMember.accept(this)) {
-          hasNonExitingCase = true;
-        }
-      }
-      if (hasNonExitingCase) {
-        return false;
-      }
-      // As all cases exit, return whether that list includes `default`.
-      return hasDefault;
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-    }
-  }
-
-  @override
-  bool visitThisExpression(ThisExpression node) => false;
-
-  @override
-  bool visitThrowExpression(ThrowExpression node) => true;
-
-  @override
-  bool visitTryStatement(TryStatement node) {
-    if (_nodeExits(node.finallyBlock)) {
-      return true;
-    }
-    if (!_nodeExits(node.body)) {
-      return false;
-    }
-    for (CatchClause c in node.catchClauses) {
-      if (!_nodeExits(c.body)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
-  bool visitTypeName(TypeName node) => false;
-
-  @override
-  bool visitVariableDeclaration(VariableDeclaration node) {
-    Expression initializer = node.initializer;
-    if (initializer != null) {
-      return initializer.accept(this);
-    }
-    return false;
-  }
-
-  @override
-  bool visitVariableDeclarationList(VariableDeclarationList node) =>
-      _visitVariableDeclarations(node.variables);
-
-  @override
-  bool visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    NodeList<VariableDeclaration> variables = node.variables.variables;
-    for (int i = 0; i < variables.length; i++) {
-      if (variables[i].accept(this)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool visitWhileStatement(WhileStatement node) {
-    bool outerBreakValue = _enclosingBlockContainsBreak;
-    _enclosingBlockContainsBreak = false;
-    try {
-      Expression conditionExpression = node.condition;
-      if (conditionExpression.accept(this)) {
-        return true;
-      }
-      node.body.accept(this);
-      // TODO(jwren) Do we want to take all constant expressions into account?
-      if (conditionExpression is BooleanLiteral) {
-        // If while(true), and the body doesn't have a break, then return true.
-        // The body might be found to exit, but if there are any break
-        // statements, then it is a faulty finding. In other words:
-        //
-        // * If the body exits, and does not contain a break statement, then
-        //   it exits.
-        // * If the body does not exit, and does not contain a break statement,
-        //   then it loops infinitely (also an exit).
-        //
-        // As both conditions forbid any break statements to be found, the logic
-        // just boils down to checking [_enclosingBlockContainsBreak].
-        if (conditionExpression.value && !_enclosingBlockContainsBreak) {
-          return true;
-        }
-      }
-      return false;
-    } finally {
-      _enclosingBlockContainsBreak = outerBreakValue;
-    }
-  }
-
-  @override
-  bool visitYieldStatement(YieldStatement node) => _nodeExits(node.expression);
-
-  /// Return `true` if the given node exits.
-  ///
-  /// @param node the node being tested
-  /// @return `true` if the given node exits
-  bool _nodeExits(AstNode node) {
-    if (node == null) {
-      return false;
-    }
-    return node.accept(this);
-  }
-
-  bool _visitExpressions(NodeList<Expression> expressions) {
-    for (int i = expressions.length - 1; i >= 0; i--) {
-      if (expressions[i].accept(this)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool _visitStatements(NodeList<Statement> statements) {
-    for (int i = 0; i < statements.length; i++) {
-      if (statements[i].accept(this)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool _visitVariableDeclarations(
-      NodeList<VariableDeclaration> variableDeclarations) {
-    for (int i = variableDeclarations.length - 1; i >= 0; i--) {
-      if (variableDeclarations[i].accept(this)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// Return `true` if the given [node] exits.
-  static bool exits(AstNode node) {
-    return new ExitDetector()._nodeExits(node);
-  }
-}
-
 /// A visitor that visits ASTs and fills [UsedImportedElements].
 class GatherUsedImportedElementsVisitor extends RecursiveAstVisitor {
   final LibraryElement library;
@@ -3382,26 +2931,31 @@
     }
   }
 
-  /// Report an [HintCode.UNUSED_SHOWN_NAME] hint for each unused shown name.
+  /// Use the error [reporter] to report an [HintCode.UNUSED_SHOWN_NAME] hint
+  /// for each unused shown name.
   ///
-  /// Only call this method after all of the compilation units have been visited
-  /// by this visitor.
-  ///
-  /// @param errorReporter the error reporter used to report the set of
-  ///        [HintCode.UNUSED_SHOWN_NAME] hints
+  /// This method should only be invoked after all of the compilation units have
+  /// been visited by this visitor.
   void generateUnusedShownNameHints(ErrorReporter reporter) {
     _unusedShownNamesMap.forEach(
         (ImportDirective importDirective, List<SimpleIdentifier> identifiers) {
       if (_unusedImports.contains(importDirective)) {
-        // This import is actually wholly unused, not just one or more shown names from it.
-        // This is then an "unused import", rather than unused shown names.
+        // The whole import is unused, not just one or more shown names from it,
+        // so an "unused_import" hint will be generated, making it unnecessary
+        // to generate hints for the individual names.
         return;
       }
       int length = identifiers.length;
       for (int i = 0; i < length; i++) {
         Identifier identifier = identifiers[i];
-        reporter.reportErrorForNode(
-            HintCode.UNUSED_SHOWN_NAME, identifier, [identifier.name]);
+        List<SimpleIdentifier> duplicateNames =
+            _duplicateShownNamesMap[importDirective];
+        if (duplicateNames == null || !duplicateNames.contains(identifier)) {
+          // Only generate a hint if we won't also generate a
+          // "duplicate_shown_name" hint for the same identifier.
+          reporter.reportErrorForNode(
+              HintCode.UNUSED_SHOWN_NAME, identifier, [identifier.name]);
+        }
       }
     });
   }
@@ -3755,18 +3309,13 @@
 
   /// Resolve the instance fields in the given compilation unit [node].
   void resolveCompilationUnit(CompilationUnit node) {
-    _overrideManager.enterScope();
-    try {
-      NodeList<CompilationUnitMember> declarations = node.declarations;
-      int declarationCount = declarations.length;
-      for (int i = 0; i < declarationCount; i++) {
-        CompilationUnitMember declaration = declarations[i];
-        if (declaration is ClassDeclaration) {
-          _resolveClassDeclaration(declaration);
-        }
+    NodeList<CompilationUnitMember> declarations = node.declarations;
+    int declarationCount = declarations.length;
+    for (int i = 0; i < declarationCount; i++) {
+      CompilationUnitMember declaration = declarations[i];
+      if (declaration is ClassDeclaration) {
+        _resolveClassDeclaration(declaration);
       }
-    } finally {
-      _overrideManager.exitScope();
     }
   }
 
@@ -4119,10 +3668,6 @@
 
   InferenceContext inferenceContext = null;
 
-  /// The object keeping track of which elements have had their types
-  /// overridden.
-  TypeOverrideManager _overrideManager = new TypeOverrideManager();
-
   /// The object keeping track of which elements have had their types promoted.
   TypePromotionManager _promoteManager = new TypePromotionManager();
 
@@ -4183,13 +3728,6 @@
   ExecutableElement get enclosingFunction => _enclosingFunction;
 
   /// Return the object keeping track of which elements have had their types
-  /// overridden.
-  ///
-  /// @return the object keeping track of which elements have had their types
-  ///         overridden
-  TypeOverrideManager get overrideManager => _overrideManager;
-
-  /// Return the object keeping track of which elements have had their types
   /// promoted.
   ///
   /// @return the object keeping track of which elements have had their types
@@ -4235,11 +3773,6 @@
     return null;
   }
 
-  /// Prepares this [ResolverVisitor] to using it for incremental resolution.
-  void initForIncrementalResolution() {
-    _overrideManager.enterScope();
-  }
-
   /// Given a downward inference type [fnType], and the declared
   /// [typeParameterList] for a function expression, determines if we can enable
   /// downward inference and if so, returns the function type to use for
@@ -4296,66 +3829,6 @@
     // TODO(brianwilkerson) Remove this method.
   }
 
-  /// If it is appropriate to do so, override the current type of the given
-  /// element with the given type.
-  ///
-  /// @param element the element whose type might be overridden
-  /// @param potentialType the potential type of the element
-  /// @param allowPrecisionLoss true if `potentialType` is allowed to be less
-  ///        precise than the current best type
-  ///
-  /// Return a new better [DartType], or `null` if [potentialType] is not better
-  /// than the current [element] type.
-  DartType overrideVariable(VariableElement element, DartType potentialType,
-      bool allowPrecisionLoss) {
-    // TODO(scheglov) type propagation for instance/top-level fields
-    // was disabled because it depends on the order or visiting.
-    // If both field and its client are in the same unit, and we visit
-    // the client before the field, then propagated type is not set yet.
-    if (element is PropertyInducingElement) {
-      return null;
-    }
-
-    if (potentialType == null ||
-        potentialType.isBottom ||
-        potentialType.isDartCoreNull) {
-      return null;
-    }
-    DartType currentType = _overrideManager.getBestType(element);
-
-    if (potentialType == currentType) {
-      return null;
-    }
-
-    // If we aren't allowing precision loss then the third and fourth conditions
-    // check that we aren't losing precision.
-    //
-    // Let [C] be the current type and [P] be the potential type.  When we
-    // aren't allowing precision loss -- which is the case for is-checks -- we
-    // check that [! (C << P)] or  [P << C]. The second check, that [P << C], is
-    // analogous to part of the Dart Language Spec rule for type promotion under
-    // is-checks (in the analogy [T] is [P] and [S] is [C]):
-    //
-    //   An is-expression of the form [v is T] shows that [v] has type [T] iff
-    //   [T] is more specific than the type [S] of the expression [v] and both
-    //   [T != dynamic] and [S != dynamic].
-    //
-    // It also covers an important case that is not applicable in the spec:
-    // for union types, we want an is-check to promote from an union type to
-    // (a subtype of) any of its members.
-    //
-    // The first check, that [! (C << P)], covers the case where [P] and [C] are
-    // unrelated types; This case is not addressed in the spec for static types.
-    if (currentType == null ||
-        allowPrecisionLoss ||
-        !currentType.isMoreSpecificThan(potentialType) ||
-        potentialType.isMoreSpecificThan(currentType)) {
-      _overrideManager.setType(element, potentialType);
-      return potentialType;
-    }
-    return null;
-  }
-
   /// A client is about to resolve a member in the given class declaration.
   void prepareToResolveMembersInClass(ClassDeclaration node) {
     _enclosingClassDeclaration = node;
@@ -4450,7 +3923,6 @@
   void visitAssertStatement(AssertStatement node) {
     InferenceContext.setType(node.condition, typeProvider.boolType);
     super.visitAssertStatement(node);
-    _propagateTrueState(node.condition);
   }
 
   @override
@@ -4487,24 +3959,18 @@
       InferenceContext.setType(rightOperand, typeProvider.boolType);
       leftOperand?.accept(this);
       if (rightOperand != null) {
-        _overrideManager.enterScope();
+        _promoteManager.enterScope();
         try {
-          _promoteManager.enterScope();
-          try {
-            _propagateTrueState(leftOperand);
-            // Type promotion.
-            _promoteTypes(leftOperand);
-            _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
-            _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
-            _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-                rightOperand);
-            // Visit right operand.
-            rightOperand.accept(this);
-          } finally {
-            _promoteManager.exitScope();
-          }
+          // Type promotion.
+          _promoteTypes(leftOperand);
+          _clearTypePromotionsIfPotentiallyMutatedIn(leftOperand);
+          _clearTypePromotionsIfPotentiallyMutatedIn(rightOperand);
+          _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
+              rightOperand);
+          // Visit right operand.
+          rightOperand.accept(this);
         } finally {
-          _overrideManager.exitScope();
+          _promoteManager.exitScope();
         }
       }
       node.accept(elementResolver);
@@ -4513,13 +3979,7 @@
       InferenceContext.setType(rightOperand, typeProvider.boolType);
       leftOperand?.accept(this);
       if (rightOperand != null) {
-        _overrideManager.enterScope();
-        try {
-          _propagateFalseState(leftOperand);
-          rightOperand.accept(this);
-        } finally {
-          _overrideManager.exitScope();
-        }
+        rightOperand.accept(this);
       }
       node.accept(elementResolver);
     } else {
@@ -4557,12 +4017,10 @@
 
   @override
   void visitBlockFunctionBody(BlockFunctionBody node) {
-    _overrideManager.enterScope();
     try {
       inferenceContext.pushReturnContext(node);
       super.visitBlockFunctionBody(node);
     } finally {
-      _overrideManager.exitScope();
       inferenceContext.popReturnContext(node);
     }
   }
@@ -4648,20 +4106,15 @@
 
   @override
   void visitCompilationUnit(CompilationUnit node) {
-    _overrideManager.enterScope();
-    try {
-      NodeList<Directive> directives = node.directives;
-      int directiveCount = directives.length;
-      for (int i = 0; i < directiveCount; i++) {
-        directives[i].accept(this);
-      }
-      NodeList<CompilationUnitMember> declarations = node.declarations;
-      int declarationCount = declarations.length;
-      for (int i = 0; i < declarationCount; i++) {
-        declarations[i].accept(this);
-      }
-    } finally {
-      _overrideManager.exitScope();
+    NodeList<Directive> directives = node.directives;
+    int directiveCount = directives.length;
+    for (int i = 0; i < directiveCount; i++) {
+      directives[i].accept(this);
+    }
+    NodeList<CompilationUnitMember> declarations = node.declarations;
+    int declarationCount = declarations.length;
+    for (int i = 0; i < declarationCount; i++) {
+      declarations[i].accept(this);
     }
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
@@ -4673,48 +4126,27 @@
     condition?.accept(this);
     Expression thenExpression = node.thenExpression;
     if (thenExpression != null) {
-      _overrideManager.enterScope();
+      _promoteManager.enterScope();
       try {
-        _promoteManager.enterScope();
-        try {
-          _propagateTrueState(condition);
-          // Type promotion.
-          _promoteTypes(condition);
-          _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
-          _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-              thenExpression);
-          // Visit "then" expression.
-          InferenceContext.setTypeFromNode(thenExpression, node);
-          thenExpression.accept(this);
-        } finally {
-          _promoteManager.exitScope();
-        }
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenExpression);
+        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
+            thenExpression);
+        // Visit "then" expression.
+        InferenceContext.setTypeFromNode(thenExpression, node);
+        thenExpression.accept(this);
       } finally {
-        _overrideManager.exitScope();
+        _promoteManager.exitScope();
       }
     }
     Expression elseExpression = node.elseExpression;
     if (elseExpression != null) {
-      _overrideManager.enterScope();
-      try {
-        _propagateFalseState(condition);
-        InferenceContext.setTypeFromNode(elseExpression, node);
-        elseExpression.accept(this);
-      } finally {
-        _overrideManager.exitScope();
-      }
+      InferenceContext.setTypeFromNode(elseExpression, node);
+      elseExpression.accept(this);
     }
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
-    bool thenIsAbrupt = _isAbruptTerminationExpression(thenExpression);
-    bool elseIsAbrupt = _isAbruptTerminationExpression(elseExpression);
-    if (elseIsAbrupt && !thenIsAbrupt) {
-      _propagateTrueState(condition);
-      _propagateState(thenExpression);
-    } else if (thenIsAbrupt && !elseIsAbrupt) {
-      _propagateFalseState(condition);
-      _propagateState(elseExpression);
-    }
   }
 
   @override
@@ -4803,15 +4235,8 @@
 
   @override
   void visitDoStatement(DoStatement node) {
-    _overrideManager.enterScope();
-    try {
-      InferenceContext.setType(node.condition, typeProvider.boolType);
-      super.visitDoStatement(node);
-    } finally {
-      _overrideManager.exitScope();
-    }
-    // TODO(brianwilkerson) If the loop can only be exited because the condition
-    // is false, then propagateFalseState(node.getCondition());
+    InferenceContext.setType(node.condition, typeProvider.boolType);
+    super.visitDoStatement(node);
   }
 
   @override
@@ -4855,7 +4280,6 @@
     if (resolveOnlyCommentInFunctionBody) {
       return;
     }
-    _overrideManager.enterScope();
     try {
       InferenceContext.setTypeFromNode(node.expression, node);
       inferenceContext.pushReturnContext(node);
@@ -4869,35 +4293,11 @@
         inferenceContext.addReturnOrYieldType(type);
       }
     } finally {
-      _overrideManager.exitScope();
       inferenceContext.popReturnContext(node);
     }
   }
 
   @override
-  void visitFieldDeclaration(FieldDeclaration node) {
-    _overrideManager.enterScope();
-    try {
-      super.visitFieldDeclaration(node);
-    } finally {
-      Map<VariableElement, DartType> overrides =
-          _overrideManager.captureOverrides(node.fields);
-      _overrideManager.exitScope();
-      _overrideManager.applyOverrides(overrides);
-    }
-  }
-
-  @override
-  void visitForEachStatement(ForEachStatement node) {
-    _overrideManager.enterScope();
-    try {
-      super.visitForEachStatement(node);
-    } finally {
-      _overrideManager.exitScope();
-    }
-  }
-
-  @override
   void visitForEachStatementInScope(ForEachStatement node) {
     Expression iterable = node.iterable;
     DeclaredIdentifier loopVariable = node.loopVariable;
@@ -4935,44 +4335,121 @@
     loopVariable?.accept(this);
     Statement body = node.body;
     if (body != null) {
-      _overrideManager.enterScope();
-      try {
-        if (loopVariable != null && iterable != null) {
-          LocalVariableElement loopElement = loopVariable.declaredElement;
-          if (loopElement != null) {
-            DartType propagatedType = null;
-            if (node.awaitKeyword == null) {
-              propagatedType = _getIteratorElementType(iterable);
-            } else {
-              propagatedType = _getStreamElementType(iterable);
-            }
-            if (propagatedType != null) {
-              overrideVariable(loopElement, propagatedType, true);
-            }
-          }
-        } else if (identifier != null && iterable != null) {
-          Element identifierElement = identifier.staticElement;
-          if (identifierElement is VariableElement) {
-            DartType iteratorElementType = _getIteratorElementType(iterable);
-            overrideVariable(identifierElement, iteratorElementType, true);
-          }
-        }
-        visitStatementInScope(body);
-      } finally {
-        _overrideManager.exitScope();
-      }
+      visitStatementInScope(body);
     }
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
 
   @override
-  void visitForStatement(ForStatement node) {
-    _overrideManager.enterScope();
-    try {
-      super.visitForStatement(node);
-    } finally {
-      _overrideManager.exitScope();
+  void visitForElement(ForElement node) {
+    ForLoopParts forLoopParts = node.forLoopParts;
+    if (forLoopParts is ForParts) {
+      if (forLoopParts is ForPartsWithDeclarations) {
+        forLoopParts.variables?.accept(this);
+      } else if (forLoopParts is ForPartsWithExpression) {
+        forLoopParts.initialization?.accept(this);
+      }
+      InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
+      forLoopParts.condition?.accept(this);
+      node.body?.accept(this);
+      forLoopParts.updaters.accept(this);
+    } else if (forLoopParts is ForEachParts) {
+      Expression iterable = forLoopParts.iterable;
+      DeclaredIdentifier loopVariable;
+      DartType valueType;
+      if (forLoopParts is ForEachPartsWithDeclaration) {
+        loopVariable = forLoopParts.loopVariable;
+        valueType = loopVariable?.type?.type ?? UnknownInferredType.instance;
+      } else if (forLoopParts is ForEachPartsWithIdentifier) {
+        SimpleIdentifier identifier = forLoopParts.identifier;
+        identifier?.accept(this);
+        Element element = identifier?.staticElement;
+        if (element is VariableElement) {
+          valueType = element.type;
+        } else if (element is PropertyAccessorElement) {
+          if (element.parameters.isNotEmpty) {
+            valueType = element.parameters[0].type;
+          }
+        }
+      }
+
+      if (valueType != null) {
+        InterfaceType targetType = (node.awaitKeyword == null)
+            ? typeProvider.iterableType
+            : typeProvider.streamType;
+        InferenceContext.setType(iterable, targetType.instantiate([valueType]));
+      }
+      //
+      // We visit the iterator before the loop variable because the loop
+      // variable cannot be in scope while visiting the iterator.
+      //
+      iterable?.accept(this);
+      loopVariable?.accept(this);
+      node.body?.accept(this);
+
+      node.accept(elementResolver);
+      node.accept(typeAnalyzer);
+    }
+  }
+
+  @override
+  void visitForStatement2InScope(ForStatement2 node) {
+    ForLoopParts forLoopParts = node.forLoopParts;
+    if (forLoopParts is ForParts) {
+      if (forLoopParts is ForPartsWithDeclarations) {
+        forLoopParts.variables?.accept(this);
+      } else if (forLoopParts is ForPartsWithExpression) {
+        forLoopParts.initialization?.accept(this);
+      }
+      InferenceContext.setType(forLoopParts.condition, typeProvider.boolType);
+      forLoopParts.condition?.accept(this);
+      visitStatementInScope(node.body);
+      forLoopParts.updaters.accept(this);
+    } else if (forLoopParts is ForEachParts) {
+      Expression iterable = forLoopParts.iterable;
+      DeclaredIdentifier loopVariable;
+      SimpleIdentifier identifier;
+      if (forLoopParts is ForEachPartsWithDeclaration) {
+        loopVariable = forLoopParts.loopVariable;
+      } else if (forLoopParts is ForEachPartsWithIdentifier) {
+        identifier = forLoopParts.identifier;
+        identifier?.accept(this);
+      }
+
+      DartType valueType;
+      if (loopVariable != null) {
+        TypeAnnotation typeAnnotation = loopVariable.type;
+        valueType = typeAnnotation?.type ?? UnknownInferredType.instance;
+      }
+      if (identifier != null) {
+        Element element = identifier.staticElement;
+        if (element is VariableElement) {
+          valueType = element.type;
+        } else if (element is PropertyAccessorElement) {
+          if (element.parameters.isNotEmpty) {
+            valueType = element.parameters[0].type;
+          }
+        }
+      }
+      if (valueType != null) {
+        InterfaceType targetType = (node.awaitKeyword == null)
+            ? typeProvider.iterableType
+            : typeProvider.streamType;
+        InferenceContext.setType(iterable, targetType.instantiate([valueType]));
+      }
+      //
+      // We visit the iterator before the loop variable because the loop variable
+      // cannot be in scope while visiting the iterator.
+      //
+      iterable?.accept(this);
+      loopVariable?.accept(this);
+      Statement body = node.body;
+      if (body != null) {
+        visitStatementInScope(body);
+      }
+      node.accept(elementResolver);
+      node.accept(typeAnalyzer);
     }
   }
 
@@ -4982,16 +4459,8 @@
     node.initialization?.accept(this);
     InferenceContext.setType(node.condition, typeProvider.boolType);
     node.condition?.accept(this);
-    _overrideManager.enterScope();
-    try {
-      _propagateTrueState(node.condition);
-      visitStatementInScope(node.body);
-      node.updaters.accept(this);
-    } finally {
-      _overrideManager.exitScope();
-    }
-    // TODO(brianwilkerson) If the loop can only be exited because the condition
-    // is false, then propagateFalseState(condition);
+    visitStatementInScope(node.body);
+    node.updaters.accept(this);
   }
 
   @override
@@ -5024,22 +4493,17 @@
     try {
       _currentFunctionBody = node.body;
       _enclosingFunction = node.declaredElement;
-      _overrideManager.enterScope();
-      try {
-        DartType functionType = InferenceContext.getContext(node);
+      DartType functionType = InferenceContext.getContext(node);
+      if (functionType is FunctionType) {
+        functionType =
+            matchFunctionTypeParameters(node.typeParameters, functionType);
         if (functionType is FunctionType) {
-          functionType =
-              matchFunctionTypeParameters(node.typeParameters, functionType);
-          if (functionType is FunctionType) {
-            _inferFormalParameterList(node.parameters, functionType);
-            InferenceContext.setType(
-                node.body, _computeReturnOrYieldType(functionType.returnType));
-          }
+          _inferFormalParameterList(node.parameters, functionType);
+          InferenceContext.setType(
+              node.body, _computeReturnOrYieldType(functionType.returnType));
         }
-        super.visitFunctionExpression(node);
-      } finally {
-        _overrideManager.exitScope();
       }
+      super.visitFunctionExpression(node);
     } finally {
       _currentFunctionBody = outerFunctionBody;
       _enclosingFunction = outerFunction;
@@ -5089,65 +4553,57 @@
   void visitHideCombinator(HideCombinator node) {}
 
   @override
+  void visitIfElement(IfElement node) {
+    Expression condition = node.condition;
+    InferenceContext.setType(condition, typeProvider.boolType);
+    condition?.accept(this);
+    CollectionElement thenElement = node.thenElement;
+    if (thenElement != null) {
+      _promoteManager.enterScope();
+      try {
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenElement);
+        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
+            thenElement);
+        // Visit "then".
+        thenElement.accept(this);
+      } finally {
+        _promoteManager.exitScope();
+      }
+    }
+    node.elseElement?.accept(this);
+
+    node.accept(elementResolver);
+    node.accept(typeAnalyzer);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     Expression condition = node.condition;
     InferenceContext.setType(condition, typeProvider.boolType);
     condition?.accept(this);
-    Map<VariableElement, DartType> thenOverrides =
-        const <VariableElement, DartType>{};
     Statement thenStatement = node.thenStatement;
     if (thenStatement != null) {
-      _overrideManager.enterScope();
+      _promoteManager.enterScope();
       try {
-        _promoteManager.enterScope();
-        try {
-          _propagateTrueState(condition);
-          // Type promotion.
-          _promoteTypes(condition);
-          _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
-          _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
-              thenStatement);
-          // Visit "then".
-          visitStatementInScope(thenStatement);
-        } finally {
-          _promoteManager.exitScope();
-        }
+        // Type promotion.
+        _promoteTypes(condition);
+        _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement);
+        _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
+            thenStatement);
+        // Visit "then".
+        visitStatementInScope(thenStatement);
       } finally {
-        thenOverrides = _overrideManager.captureLocalOverrides();
-        _overrideManager.exitScope();
+        _promoteManager.exitScope();
       }
     }
-    Map<VariableElement, DartType> elseOverrides =
-        const <VariableElement, DartType>{};
     Statement elseStatement = node.elseStatement;
     if (elseStatement != null) {
-      _overrideManager.enterScope();
-      try {
-        _propagateFalseState(condition);
-        visitStatementInScope(elseStatement);
-      } finally {
-        elseOverrides = _overrideManager.captureLocalOverrides();
-        _overrideManager.exitScope();
-      }
+      visitStatementInScope(elseStatement);
     }
     node.accept(elementResolver);
     node.accept(typeAnalyzer);
-    // Join overrides.
-    bool thenIsAbrupt = _isAbruptTerminationStatement(thenStatement);
-    bool elseIsAbrupt = _isAbruptTerminationStatement(elseStatement);
-    if (elseIsAbrupt && !thenIsAbrupt) {
-      _propagateTrueState(condition);
-      _overrideManager.applyOverrides(thenOverrides);
-    } else if (thenIsAbrupt && !elseIsAbrupt) {
-      _propagateFalseState(condition);
-      _overrideManager.applyOverrides(elseOverrides);
-    } else if (!thenIsAbrupt && !elseIsAbrupt) {
-      List<Map<VariableElement, DartType>> perBranchOverrides =
-          <Map<VariableElement, DartType>>[];
-      perBranchOverrides.add(thenOverrides);
-      perBranchOverrides.add(elseOverrides);
-      _overrideManager.mergeOverrides(perBranchOverrides);
-    }
   }
 
   @override
@@ -5203,6 +4659,29 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    InterfaceType listT;
+
+    if (node.typeArguments != null) {
+      var targs = node.typeArguments.arguments.map((t) => t.type).toList();
+      if (targs.length == 1 && !targs[0].isDynamic) {
+        listT = typeProvider.listType.instantiate([targs[0]]);
+      }
+    } else {
+      listT = typeAnalyzer.inferListType2(node, downwards: true);
+    }
+    if (listT != null) {
+      for (CollectionElement element in node.elements) {
+        _pushCollectionTypesDown(element, listT);
+      }
+      InferenceContext.setType(node, listT);
+    } else {
+      InferenceContext.clearType(node);
+    }
+    super.visitListLiteral2(node);
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     InterfaceType mapT;
     if (node.typeArguments != null) {
@@ -5237,6 +4716,54 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    InterfaceType mapT;
+    if (node.typeArguments != null) {
+      var targs = node.typeArguments.arguments.map((t) => t.type).toList();
+      if (targs.length == 2 && targs.any((t) => !t.isDynamic)) {
+        mapT = typeProvider.mapType.instantiate([targs[0], targs[1]]);
+      }
+    } else {
+      mapT = typeAnalyzer.inferMapType2(node, downwards: true);
+      if (mapT != null &&
+          node.typeArguments == null &&
+          node.entries.isEmpty &&
+          typeSystem.isAssignableTo(typeProvider.iterableObjectType, mapT) &&
+          !typeSystem.isAssignableTo(typeProvider.mapObjectObjectType, mapT)) {
+        // The node is really an empty set literal with no type arguments, so
+        // don't try to visit the replaced map literal.
+        return;
+      }
+    }
+    if (mapT != null) {
+      DartType kType = mapT.typeArguments[0];
+      DartType vType = mapT.typeArguments[1];
+
+      void pushTypesDown(CollectionElement element) {
+        if (element is ForElement) {
+          pushTypesDown(element.body);
+        } else if (element is IfElement) {
+          pushTypesDown(element.thenElement);
+          pushTypesDown(element.elseElement);
+        } else if (element is MapLiteralEntry) {
+          InferenceContext.setType(element.key, kType);
+          InferenceContext.setType(element.value, vType);
+        } else if (element is SpreadElement) {
+          InferenceContext.setType(element.expression, mapT);
+        }
+      }
+
+      for (CollectionElement element in node.entries) {
+        pushTypesDown(element);
+      }
+      InferenceContext.setType(node, mapT);
+    } else {
+      InferenceContext.clearType(node);
+    }
+    super.visitMapLiteral2(node);
+  }
+
+  @override
   void visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
     FunctionBody outerFunctionBody = _currentFunctionBody;
@@ -5397,6 +4924,32 @@
   }
 
   @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    InterfaceType setT;
+
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (typeArguments.length == 1) {
+        DartType elementType = typeArguments.arguments[0].type;
+        if (!elementType.isDynamic) {
+          setT = typeProvider.setType.instantiate([elementType]);
+        }
+      }
+    } else {
+      setT = typeAnalyzer.inferSetType2(node, downwards: true);
+    }
+    if (setT != null) {
+      for (CollectionElement element in node.elements) {
+        _pushCollectionTypesDown(element, setT);
+      }
+      InferenceContext.setType(node, setT);
+    } else {
+      InferenceContext.clearType(node);
+    }
+    super.visitSetLiteral2(node);
+  }
+
+  @override
   void visitShowCombinator(ShowCombinator node) {}
 
   @override
@@ -5415,24 +4968,9 @@
 
   @override
   void visitSwitchCase(SwitchCase node) {
-    _overrideManager.enterScope();
-    try {
-      InferenceContext.setType(
-          node.expression, _enclosingSwitchStatementExpressionType);
-      super.visitSwitchCase(node);
-    } finally {
-      _overrideManager.exitScope();
-    }
-  }
-
-  @override
-  void visitSwitchDefault(SwitchDefault node) {
-    _overrideManager.enterScope();
-    try {
-      super.visitSwitchDefault(node);
-    } finally {
-      _overrideManager.exitScope();
-    }
+    InferenceContext.setType(
+        node.expression, _enclosingSwitchStatementExpressionType);
+    super.visitSwitchCase(node);
   }
 
   @override
@@ -5448,19 +4986,6 @@
   }
 
   @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _overrideManager.enterScope();
-    try {
-      super.visitTopLevelVariableDeclaration(node);
-    } finally {
-      Map<VariableElement, DartType> overrides =
-          _overrideManager.captureOverrides(node.variables);
-      _overrideManager.exitScope();
-      _overrideManager.applyOverrides(overrides);
-    }
-  }
-
-  @override
   void visitTypeName(TypeName node) {}
 
   @override
@@ -5504,13 +5029,7 @@
       condition?.accept(this);
       Statement body = node.body;
       if (body != null) {
-        _overrideManager.enterScope();
-        try {
-          _propagateTrueState(condition);
-          visitStatementInScope(body);
-        } finally {
-          _overrideManager.exitScope();
-        }
+        visitStatementInScope(body);
       }
     } finally {
       _implicitLabelScope = outerImplicitScope;
@@ -5636,62 +5155,6 @@
     return typeProvider.futureOrType.instantiate([type]);
   }
 
-  /// The given expression is the expression used to compute the iterator for a
-  /// for-each statement. Attempt to compute the type of objects that will be
-  /// assigned to the loop variable and return that type. Return `null` if the
-  /// type could not be determined. The [iteratorExpression] is the expression
-  /// that will return the Iterable being iterated over.
-  DartType _getIteratorElementType(Expression iteratorExpression) {
-    DartType expressionType = iteratorExpression.staticType;
-    if (expressionType is InterfaceType) {
-      PropertyAccessorElement iteratorFunction =
-          expressionType.lookUpInheritedGetter("iterator");
-      if (iteratorFunction == null) {
-        // TODO(brianwilkerson) Should we report this error?
-        return null;
-      }
-      DartType iteratorType = iteratorFunction.returnType;
-      if (iteratorType is InterfaceType) {
-        PropertyAccessorElement currentFunction =
-            iteratorType.lookUpInheritedGetter("current");
-        if (currentFunction == null) {
-          // TODO(brianwilkerson) Should we report this error?
-          return null;
-        }
-        return currentFunction.returnType;
-      }
-    }
-    return null;
-  }
-
-  /// The given expression is the expression used to compute the stream for an
-  /// asynchronous for-each statement. Attempt to compute the type of objects
-  /// that will be assigned to the loop variable and return that type.
-  /// Return `null` if the type could not be determined. The [streamExpression]
-  /// is the expression that will return the stream being iterated over.
-  DartType _getStreamElementType(Expression streamExpression) {
-    DartType streamType = streamExpression.staticType;
-    if (streamType is InterfaceType) {
-      MethodElement listenFunction = streamType.lookUpInheritedMethod("listen");
-      if (listenFunction == null) {
-        return null;
-      }
-      List<ParameterElement> listenParameters = listenFunction.parameters;
-      if (listenParameters == null || listenParameters.length < 1) {
-        return null;
-      }
-      DartType onDataType = listenParameters[0].type;
-      if (onDataType is FunctionType) {
-        List<ParameterElement> onDataParameters = onDataType.parameters;
-        if (onDataParameters == null || onDataParameters.isEmpty) {
-          return null;
-        }
-        return onDataParameters[0].type;
-      }
-    }
-    return null;
-  }
-
   /// Return `true` if the given [parameter] element of the AST being resolved
   /// is resynthesized and is an API-level, not local, so has its initializer
   /// serialized.
@@ -5818,71 +5281,6 @@
     }
   }
 
-  /// Return `true` if the given expression terminates abruptly (that is, if any
-  /// expression following the given expression will not be reached).
-  ///
-  /// @param expression the expression being tested
-  /// @return `true` if the given expression terminates abruptly
-  bool _isAbruptTerminationExpression(Expression expression) {
-    // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
-    // would eventually turn this into a method on Expression that returns a
-    // termination indication (normal, abrupt with no exception, abrupt with an
-    // exception).
-    expression = expression?.unParenthesized;
-    return expression is ThrowExpression || expression is RethrowExpression;
-  }
-
-  /// Return `true` if the given statement terminates abruptly (that is, if any
-  /// statement following the given statement will not be reached).
-  ///
-  /// @param statement the statement being tested
-  /// @return `true` if the given statement terminates abruptly
-  bool _isAbruptTerminationStatement(Statement statement) {
-    // TODO(brianwilkerson) This needs to be significantly improved. Ideally we
-    // would eventually turn this into a method on Statement that returns a
-    // termination indication (normal, abrupt with no exception, abrupt with an
-    // exception).
-    //
-    // collinsn: it is unsound to assume that [break] and [continue] are
-    // "abrupt". See: https://code.google.com/p/dart/issues/detail?id=19929#c4
-    // (tests are included in TypePropagationTest.java).
-    // In general, the difficulty is loopy control flow.
-    //
-    // In the presence of exceptions things become much more complicated, but
-    // while we only use this to propagate at [if]-statement join points,
-    // checking for [return] may work well enough in the common case.
-    if (statement is ReturnStatement) {
-      return true;
-    } else if (statement is ExpressionStatement) {
-      return _isAbruptTerminationExpression(statement.expression);
-    } else if (statement is Block) {
-      NodeList<Statement> statements = statement.statements;
-      int size = statements.length;
-      if (size == 0) {
-        return false;
-      }
-
-      // This last-statement-is-return heuristic is unsound for adversarial
-      // code, but probably works well in the common case:
-      //
-      //   var x = 123;
-      //   var c = true;
-      //   L: if (c) {
-      //     x = "hello";
-      //     c = false;
-      //     break L;
-      //     return;
-      //   }
-      //   print(x);
-      //
-      // Unsound to assume that [x = "hello";] never executed after the
-      // if-statement. Of course, a dead-code analysis could point out that
-      // [return] here is dead.
-      return _isAbruptTerminationStatement(statements[size - 1]);
-    }
-    return false;
-  }
-
   /// Return `true` if the given variable is accessed within a closure in the
   /// given [AstNode] and also mutated somewhere in variable scope. This
   /// information is only available for local variables (including parameters).
@@ -5963,50 +5361,17 @@
     }
   }
 
-  /// Propagate any type information that results from knowing that the given
-  /// condition will have been evaluated to 'false'.
-  ///
-  /// @param condition the condition that will have evaluated to 'false'
-  void _propagateFalseState(Expression condition) {
-    if (condition is BinaryExpression) {
-      if (condition.operator.type == TokenType.BAR_BAR) {
-        _propagateFalseState(condition.leftOperand);
-        _propagateFalseState(condition.rightOperand);
-      }
-    } else if (condition is PrefixExpression) {
-      if (condition.operator.type == TokenType.BANG) {
-        _propagateTrueState(condition.operand);
-      }
-    } else if (condition is ParenthesizedExpression) {
-      _propagateFalseState(condition.expression);
-    }
-  }
-
-  /// Propagate any type information that results from knowing that the given
-  /// expression will have been evaluated without altering the flow of
-  /// execution.
-  ///
-  /// @param expression the expression that will have been evaluated
-  void _propagateState(Expression expression) {
-    // TODO(brianwilkerson) Implement this.
-  }
-
-  /// Propagate any type information that results from knowing that the given
-  /// condition will have been evaluated to 'true'.
-  ///
-  /// @param condition the condition that will have evaluated to 'true'
-  void _propagateTrueState(Expression condition) {
-    if (condition is BinaryExpression) {
-      if (condition.operator.type == TokenType.AMPERSAND_AMPERSAND) {
-        _propagateTrueState(condition.leftOperand);
-        _propagateTrueState(condition.rightOperand);
-      }
-    } else if (condition is PrefixExpression) {
-      if (condition.operator.type == TokenType.BANG) {
-        _propagateFalseState(condition.operand);
-      }
-    } else if (condition is ParenthesizedExpression) {
-      _propagateTrueState(condition.expression);
+  void _pushCollectionTypesDown(
+      CollectionElement element, ParameterizedType collectionType) {
+    if (element is ForElement) {
+      _pushCollectionTypesDown(element.body, collectionType);
+    } else if (element is IfElement) {
+      _pushCollectionTypesDown(element.thenElement, collectionType);
+      _pushCollectionTypesDown(element.elseElement, collectionType);
+    } else if (element is Expression) {
+      InferenceContext.setType(element, collectionType.typeArguments[0]);
+    } else if (element is SpreadElement) {
+      InferenceContext.setType(element.expression, collectionType);
     }
   }
 
@@ -6457,6 +5822,30 @@
     }
   }
 
+  @override
+  void visitForStatement2(ForStatement2 node) {
+    Scope outerNameScope = nameScope;
+    ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
+    try {
+      nameScope = new EnclosedScope(nameScope);
+      _implicitLabelScope = _implicitLabelScope.nest(node);
+      visitForStatement2InScope(node);
+    } finally {
+      nameScope = outerNameScope;
+      _implicitLabelScope = outerImplicitScope;
+    }
+  }
+
+  /// Visit the given [node] after it's scope has been created. This replaces
+  /// the normal call to the inherited visit method so that ResolverVisitor can
+  /// intervene when type propagation is enabled.
+  void visitForStatement2InScope(ForStatement2 node) {
+    // TODO(brianwilkerson) Investigate the possibility of removing the
+    //  visit...InScope methods now that type propagation is no longer done.
+    node.forLoopParts?.accept(this);
+    visitStatementInScope(node.body);
+  }
+
   /// Visit the given statement after it's scope has been created. This replaces
   /// the normal call to the inherited visit method so that ResolverVisitor can
   /// intervene when type propagation is enabled.
@@ -7512,191 +6901,6 @@
   }
 }
 
-/// Instances of the class `TypeOverrideManager` manage the ability to override
-/// the type of an element within a given context.
-class TypeOverrideManager {
-  /// The current override scope, or `null` if no scope has been entered.
-  TypeOverrideManager_TypeOverrideScope currentScope;
-
-  /// Apply a set of overrides that were previously captured.
-  ///
-  /// @param overrides the overrides to be applied
-  void applyOverrides(Map<VariableElement, DartType> overrides) {
-    if (currentScope == null) {
-      throw new StateError("Cannot apply overrides without a scope");
-    }
-    currentScope.applyOverrides(overrides);
-  }
-
-  /// Return a table mapping the elements whose type is overridden in the
-  /// current scope to the overriding type.
-  ///
-  /// @return the overrides in the current scope
-  Map<VariableElement, DartType> captureLocalOverrides() {
-    if (currentScope == null) {
-      throw new StateError("Cannot capture local overrides without a scope");
-    }
-    return currentScope.captureLocalOverrides();
-  }
-
-  /// Return a map from the elements for the variables in the given list that
-  /// have their types overridden to the overriding type.
-  ///
-  /// @param variableList the list of variables whose overriding types are to be
-  ///        captured
-  /// @return a table mapping elements to their overriding types
-  Map<VariableElement, DartType> captureOverrides(
-      VariableDeclarationList variableList) {
-    if (currentScope == null) {
-      throw new StateError("Cannot capture overrides without a scope");
-    }
-    return currentScope.captureOverrides(variableList);
-  }
-
-  /// Enter a new override scope.
-  void enterScope() {
-    currentScope = new TypeOverrideManager_TypeOverrideScope(currentScope);
-  }
-
-  /// Exit the current override scope.
-  void exitScope() {
-    if (currentScope == null) {
-      throw new StateError("No scope to exit");
-    }
-    currentScope = currentScope._outerScope;
-  }
-
-  /// Return the best type information available for the given element. If the
-  /// type of the element has been overridden, then return the overriding type.
-  /// Otherwise, return the static type.
-  ///
-  /// @param element the element for which type information is to be returned
-  /// @return the best type information available for the given element
-  DartType getBestType(VariableElement element) {
-    DartType bestType = getType(element);
-    return bestType ?? element.type;
-  }
-
-  /// Return the overridden type of the given element, or `null` if the type of
-  /// the element has not been overridden.
-  ///
-  /// @param element the element whose type might have been overridden
-  /// @return the overridden type of the given element
-  DartType getType(Element element) {
-    if (currentScope == null) {
-      return null;
-    }
-    return currentScope.getType(element);
-  }
-
-  /// Update overrides assuming [perBranchOverrides] is the collection of
-  /// per-branch overrides for *all* branches flowing into a join point.
-  void mergeOverrides(List<Map<VariableElement, DartType>> perBranchOverrides) {
-    int length = perBranchOverrides.length;
-    for (int i = 0; i < length; i++) {
-      Map<VariableElement, DartType> branch = perBranchOverrides[i];
-      branch.forEach((VariableElement variable, DartType branchType) {
-        DartType currentType = currentScope.getType(variable);
-        if (currentType != branchType) {
-          currentScope.resetType(variable);
-        }
-      });
-    }
-  }
-
-  /// Set the overridden type of the given element to the given type
-  ///
-  /// @param element the element whose type might have been overridden
-  /// @param type the overridden type of the given element
-  void setType(VariableElement element, DartType type) {
-    if (currentScope == null) {
-      throw new StateError("Cannot override without a scope");
-    }
-    currentScope.setType(element, type);
-  }
-}
-
-/// Instances of the class `TypeOverrideScope` represent a scope in which the
-/// types of elements can be overridden.
-class TypeOverrideManager_TypeOverrideScope {
-  /// The outer scope in which types might be overridden.
-  final TypeOverrideManager_TypeOverrideScope _outerScope;
-
-  /// A table mapping elements to the overridden type of that element.
-  Map<VariableElement, DartType> _overriddenTypes =
-      new HashMap<VariableElement, DartType>();
-
-  /// Initialize a newly created scope to be an empty child of the given scope.
-  ///
-  /// @param outerScope the outer scope in which types might be overridden
-  TypeOverrideManager_TypeOverrideScope(this._outerScope);
-
-  /// Apply a set of overrides that were previously captured.
-  ///
-  /// @param overrides the overrides to be applied
-  void applyOverrides(Map<VariableElement, DartType> overrides) {
-    _overriddenTypes.addAll(overrides);
-  }
-
-  /// Return a table mapping the elements whose type is overridden in the
-  /// current scope to the overriding type.
-  ///
-  /// @return the overrides in the current scope
-  Map<VariableElement, DartType> captureLocalOverrides() => _overriddenTypes;
-
-  /// Return a map from the elements for the variables in the given list that
-  /// have their types overridden to the overriding type.
-  ///
-  /// @param variableList the list of variables whose overriding types are to be
-  ///        captured
-  /// @return a table mapping elements to their overriding types
-  Map<VariableElement, DartType> captureOverrides(
-      VariableDeclarationList variableList) {
-    Map<VariableElement, DartType> overrides =
-        new HashMap<VariableElement, DartType>();
-    if (variableList.isConst || variableList.isFinal) {
-      for (VariableDeclaration variable in variableList.variables) {
-        VariableElement element = variable.declaredElement;
-        if (element != null) {
-          DartType type = _overriddenTypes[element];
-          if (type != null) {
-            overrides[element] = type;
-          }
-        }
-      }
-    }
-    return overrides;
-  }
-
-  /// Return the overridden type of the given element, or `null` if the type of
-  /// the element has not been overridden.
-  ///
-  /// @param element the element whose type might have been overridden
-  /// @return the overridden type of the given element
-  DartType getType(Element element) {
-    Element nonAccessor =
-        element is PropertyAccessorElement ? element.variable : element;
-    DartType type = _overriddenTypes[nonAccessor];
-    if (_overriddenTypes.containsKey(nonAccessor)) {
-      return type;
-    }
-    return type ?? _outerScope?.getType(element);
-  }
-
-  /// Clears the overridden type of the given [element].
-  void resetType(VariableElement element) {
-    _overriddenTypes[element] = null;
-  }
-
-  /// Set the overridden type of the given element to the given type
-  ///
-  /// @param element the element whose type might have been overridden
-  /// @param type the overridden type of the given element
-  void setType(VariableElement element, DartType type) {
-    _overriddenTypes[element] = type;
-  }
-}
-
 /// This class resolves bounds of type parameters of classes, class and function
 /// type aliases.
 class TypeParameterBoundsResolver {
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 9b1d4e7..f2d604f 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -370,12 +370,6 @@
  */
 abstract class Source implements AnalysisTarget {
   /**
-   * An empty list of sources.
-   */
-  @deprecated
-  static const List<Source> EMPTY_LIST = const <Source>[];
-
-  /**
    * Get the contents and timestamp of this source.
    *
    * Clients should consider using the method [AnalysisContext.getContents]
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 88f8f3b..23871b8 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -182,6 +182,40 @@
     return inferred;
   }
 
+  DartType inferListType2(ListLiteral2 node, {bool downwards: false}) {
+    DartType contextType = InferenceContext.getContext(node);
+
+    var ts = _typeSystem as Dart2TypeSystem;
+    List<DartType> elementTypes;
+    List<ParameterElement> parameters;
+
+    if (downwards) {
+      if (contextType == null) {
+        return null;
+      }
+      elementTypes = [];
+      parameters = [];
+    } else {
+      // Also use upwards information to infer the type.
+      elementTypes = node.elements
+          .map((element) => _computeElementType(element))
+          .where((t) => t != null)
+          .toList();
+      TypeParameterType listTypeParam =
+          _typeProvider.listType.typeParameters[0].type;
+      ParameterElementImpl syntheticParamElement =
+          new ParameterElementImpl.synthetic(
+              'element', listTypeParam, ParameterKind.POSITIONAL);
+      parameters = new List.filled(elementTypes.length, syntheticParamElement);
+    }
+    InterfaceType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
+        _typeProvider.listType, parameters, elementTypes, contextType,
+        downwards: downwards,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
+    return inferred;
+  }
+
   ParameterizedType inferMapType(MapLiteral node, {bool downwards: false}) {
     DartType contextType = InferenceContext.getContext(node);
     if (contextType != null && _experimentStatus.set_literals) {
@@ -247,6 +281,73 @@
     return inferred;
   }
 
+  ParameterizedType inferMapType2(MapLiteral2 node, {bool downwards: false}) {
+    DartType contextType = InferenceContext.getContext(node);
+    if (contextType != null && _experimentStatus.set_literals) {
+      DartType unwrap(DartType type) {
+        if (type is InterfaceType &&
+            type.isDartAsyncFutureOr &&
+            type.typeArguments.length == 1) {
+          return unwrap(type.typeArguments[0]);
+        }
+        return type;
+      }
+
+      DartType unwrappedContextType = unwrap(contextType);
+      if (node.typeArguments == null &&
+          node.entries.isEmpty &&
+          _typeSystem.isAssignableTo(
+              _typeProvider.iterableObjectType, unwrappedContextType) &&
+          !_typeSystem.isAssignableTo(
+              _typeProvider.mapObjectObjectType, unwrappedContextType)) {
+        // The node is really an empty set literal with no type arguments.
+        // Rewrite the AST and infer the type of the set as appropriate.
+        SetLiteral setLiteral = new AstFactoryImpl().setLiteral(
+            node.constKeyword, null, node.leftBracket, null, node.rightBracket);
+        InferenceContext.setType(setLiteral, contextType);
+        NodeReplacer.replace(node, setLiteral);
+        DartType type = inferSetType(setLiteral, downwards: downwards);
+        setLiteral.staticType = type;
+        return type;
+      }
+    }
+    List<DartType> elementTypes;
+    List<ParameterElement> parameters;
+    if (downwards) {
+      if (contextType == null) {
+        return null;
+      }
+      elementTypes = [];
+      parameters = [];
+    } else {
+      var keyTypes = node.entries
+          .map((entry) => _computeKeyType(entry))
+          .where((t) => t != null);
+      var valueTypes = node.entries
+          .map((entry) => _computeValueType(entry))
+          .where((t) => t != null);
+      var keyTypeParam = _typeProvider.mapType.typeParameters[0].type;
+      var valueTypeParam = _typeProvider.mapType.typeParameters[1].type;
+      var syntheticKeyParameter = new ParameterElementImpl.synthetic(
+          'key', keyTypeParam, ParameterKind.POSITIONAL);
+      var syntheticValueParameter = new ParameterElementImpl.synthetic(
+          'value', valueTypeParam, ParameterKind.POSITIONAL);
+      parameters = new List.filled(keyTypes.length, syntheticKeyParameter,
+          growable: true)
+        ..addAll(new List.filled(valueTypes.length, syntheticValueParameter));
+      elementTypes = new List<DartType>.from(keyTypes)..addAll(valueTypes);
+    }
+
+    // Use both downwards and upwards information to infer the type.
+    var ts = _typeSystem as Dart2TypeSystem;
+    ParameterizedType inferred = ts.inferGenericFunctionOrType(
+        _typeProvider.mapType, parameters, elementTypes, contextType,
+        downwards: downwards,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
+    return inferred;
+  }
+
   DartType inferSetType(SetLiteral node, {bool downwards: false}) {
     DartType contextType = InferenceContext.getContext(node);
 
@@ -280,6 +381,41 @@
     return inferred;
   }
 
+  DartType inferSetType2(SetLiteral2 node, {bool downwards: false}) {
+    DartType contextType = InferenceContext.getContext(node);
+
+    var ts = _typeSystem as Dart2TypeSystem;
+    List<DartType> elementTypes;
+    List<ParameterElement> parameters;
+
+    if (downwards) {
+      if (contextType == null) {
+        return null;
+      }
+
+      elementTypes = [];
+      parameters = [];
+    } else {
+      // Also use upwards information to infer the type.
+      elementTypes = node.elements
+          .map((element) => _computeElementType(element))
+          .where((t) => t != null)
+          .toList();
+      TypeParameterType setTypeParam =
+          _typeProvider.setType.typeParameters[0].type;
+      ParameterElementImpl syntheticParamElement =
+          new ParameterElementImpl.synthetic(
+              'element', setTypeParam, ParameterKind.POSITIONAL);
+      parameters = new List.filled(elementTypes.length, syntheticParamElement);
+    }
+    DartType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
+        _typeProvider.setType, parameters, elementTypes, contextType,
+        downwards: downwards,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
+    return inferred;
+  }
+
   /**
    * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
    * `String`.</blockquote>
@@ -694,6 +830,45 @@
     _recordStaticType(node, listDynamicType);
   }
 
+  @override
+  void visitListLiteral2(ListLiteral2 node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+
+    // If we have explicit arguments, use them
+    if (typeArguments != null) {
+      DartType staticType = _dynamicType;
+      NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+      if (arguments != null && arguments.length == 1) {
+        DartType argumentType = _getType(arguments[0]);
+        if (argumentType != null) {
+          staticType = argumentType;
+        }
+      }
+      _recordStaticType(
+          node, _typeProvider.listType.instantiate(<DartType>[staticType]));
+      return;
+    }
+
+    DartType listDynamicType =
+        _typeProvider.listType.instantiate(<DartType>[_dynamicType]);
+
+    // If there are no type arguments, try to infer some arguments.
+    DartType inferred = inferListType2(node);
+
+    if (inferred != listDynamicType) {
+      // TODO(jmesserly): this results in an "inferred" message even when we
+      // in fact had an error above, because it will still attempt to return
+      // a type. Perhaps we should record inference from TypeSystem if
+      // everything was successful?
+      _resolver.inferenceContext.recordInference(node, inferred);
+      _recordStaticType(node, inferred);
+      return;
+    }
+
+    // If we have no type arguments and couldn't infer any, use dynamic.
+    _recordStaticType(node, listDynamicType);
+  }
+
   /**
    * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
    * <i><b>const</b> &lt;K, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
@@ -752,6 +927,52 @@
     _recordStaticType(node, mapDynamicType);
   }
 
+  @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+
+    // If we have type arguments, use them
+    if (typeArguments != null) {
+      DartType staticKeyType = _dynamicType;
+      DartType staticValueType = _dynamicType;
+      NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+      if (arguments != null && arguments.length == 2) {
+        DartType entryKeyType = _getType(arguments[0]);
+        if (entryKeyType != null) {
+          staticKeyType = entryKeyType;
+        }
+        DartType entryValueType = _getType(arguments[1]);
+        if (entryValueType != null) {
+          staticValueType = entryValueType;
+        }
+      }
+      _recordStaticType(
+          node,
+          _typeProvider.mapType
+              .instantiate(<DartType>[staticKeyType, staticValueType]));
+      return;
+    }
+
+    DartType mapDynamicType = _typeProvider.mapType
+        .instantiate(<DartType>[_dynamicType, _dynamicType]);
+
+    // If we have no explicit type arguments, try to infer type arguments.
+    ParameterizedType inferred = inferMapType2(node);
+
+    if (inferred != mapDynamicType) {
+      // TODO(jmesserly): this results in an "inferred" message even when we
+      // in fact had an error above, because it will still attempt to return
+      // a type. Perhaps we should record inference from TypeSystem if
+      // everything was successful?
+      _resolver.inferenceContext.recordInference(node, inferred);
+      _recordStaticType(node, inferred);
+      return;
+    }
+
+    // If no type arguments and no inference, use dynamic
+    _recordStaticType(node, mapDynamicType);
+  }
+
   /**
    * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
    * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
@@ -1038,6 +1259,45 @@
     _recordStaticType(node, setDynamicType);
   }
 
+  @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+
+    // If we have type arguments, use them
+    if (typeArguments != null) {
+      DartType elementType = _dynamicType;
+      NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+      if (arguments != null && arguments.length == 1) {
+        DartType type = _getType(arguments[0]);
+        if (type != null) {
+          elementType = type;
+        }
+      }
+      _recordStaticType(
+          node, _typeProvider.setType.instantiate(<DartType>[elementType]));
+      return;
+    }
+
+    DartType setDynamicType =
+        _typeProvider.setType.instantiate(<DartType>[_dynamicType]);
+
+    // If we have no explicit type arguments, try to infer type arguments.
+    ParameterizedType inferred = inferSetType2(node);
+
+    if (inferred != setDynamicType) {
+      // TODO(jmesserly): this results in an "inferred" message even when we
+      // in fact had an error above, because it will still attempt to return
+      // a type. Perhaps we should record inference from TypeSystem if
+      // everything was successful?
+      _resolver.inferenceContext.recordInference(node, inferred);
+      _recordStaticType(node, inferred);
+      return;
+    }
+
+    // If no type arguments and no inference, use dynamic
+    _recordStaticType(node, setDynamicType);
+  }
+
   /**
    * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
    * <i>e</i> of the form <i>id</i> proceeds as follows:
@@ -1179,16 +1439,7 @@
 
   @override
   void visitVariableDeclaration(VariableDeclaration node) {
-    Expression initializer = node.initializer;
-    _inferLocalVariableType(node, initializer);
-    if (initializer != null) {
-      DartType rightType = initializer.staticType;
-      SimpleIdentifier name = node.name;
-      VariableElement element = name.staticElement as VariableElement;
-      if (element != null) {
-        _resolver.overrideVariable(element, rightType, true);
-      }
-    }
+    _inferLocalVariableType(node, node.initializer);
   }
 
   /**
@@ -1246,6 +1497,30 @@
     return _dynamicType;
   }
 
+  DartType _computeElementType(CollectionElement element) {
+    if (element is ForElement) {
+      return _computeElementType(element.body);
+    } else if (element is IfElement) {
+      DartType thenType = _computeElementType(element.thenElement);
+      if (element.elseElement == null) {
+        return thenType;
+      }
+      DartType elseType = _computeElementType(element.elseElement);
+      return _typeSystem.leastUpperBound(thenType, elseType);
+    } else if (element is Expression) {
+      return element.staticType;
+    } else if (element is SpreadElement) {
+      DartType collectionType = element.expression.staticType;
+      if (collectionType is ParameterizedType) {
+        List<DartType> typeArguments = collectionType.typeArguments;
+        if (typeArguments.length == 1) {
+          return typeArguments[0];
+        }
+      }
+    }
+    return null;
+  }
+
   /**
    * Compute the return type of the method or function represented by the given
    * type that is being invoked.
@@ -1261,6 +1536,30 @@
     return _dynamicType;
   }
 
+  DartType _computeKeyType(CollectionElement element) {
+    if (element is ForElement) {
+      return _computeKeyType(element.body);
+    } else if (element is IfElement) {
+      DartType thenType = _computeKeyType(element.thenElement);
+      if (element.elseElement == null) {
+        return thenType;
+      }
+      DartType elseType = _computeKeyType(element.elseElement);
+      return _typeSystem.leastUpperBound(thenType, elseType);
+    } else if (element is MapLiteralEntry) {
+      return element.key.staticType;
+    } else if (element is SpreadElement) {
+      DartType collectionType = element.expression.staticType;
+      if (collectionType is ParameterizedType) {
+        List<DartType> typeArguments = collectionType.typeArguments;
+        if (typeArguments.length == 2) {
+          return typeArguments[0];
+        }
+      }
+    }
+    return null;
+  }
+
   /**
    * Given a function body and its return type, compute the return type of
    * the entire function, taking into account whether the function body
@@ -1327,6 +1626,30 @@
     return returnType.type;
   }
 
+  DartType _computeValueType(CollectionElement element) {
+    if (element is ForElement) {
+      return _computeValueType(element.body);
+    } else if (element is IfElement) {
+      DartType thenType = _computeValueType(element.thenElement);
+      if (element.elseElement == null) {
+        return thenType;
+      }
+      DartType elseType = _computeValueType(element.elseElement);
+      return _typeSystem.leastUpperBound(thenType, elseType);
+    } else if (element is MapLiteralEntry) {
+      return element.value.staticType;
+    } else if (element is SpreadElement) {
+      DartType collectionType = element.expression.staticType;
+      if (collectionType is ParameterizedType) {
+        List<DartType> typeArguments = collectionType.typeArguments;
+        if (typeArguments.length == 2) {
+          return typeArguments[1];
+        }
+      }
+    }
+    return null;
+  }
+
   DartType _findIteratedType(DartType type, DartType targetType) {
     // TODO(vsm): Use leafp's matchType here?
     // Set by _find if match is found
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 824767b..b6f7ccd 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -842,6 +842,10 @@
       astFactory.mapLiteralEntry(
           key, TokenFactory.tokenFromType(TokenType.COLON), value);
 
+  static MapLiteralEntry mapLiteralEntry3(String key, String value) =>
+      astFactory.mapLiteralEntry(string2(key),
+          TokenFactory.tokenFromType(TokenType.COLON), string2(value));
+
   static MethodDeclaration methodDeclaration(
           Keyword modifier,
           TypeAnnotation returnType,
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 6a4ffba..30b2925 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -67,7 +67,10 @@
  * A type system that implements the type semantics for Dart 2.0.
  */
 class Dart2TypeSystem extends TypeSystem {
-  static bool _comparingTypeParameterBounds = false;
+  /// Track types currently being compared via type parameter bounds so that we
+  /// can detect recursion.
+  static Set<TypeComparison> _typeParameterBoundsComparisons =
+      new HashSet<TypeComparison>();
 
   /**
    * True if implicit casts should be allowed, otherwise false.
@@ -625,7 +628,7 @@
     // For a type parameter `T extends U`, allow promoting the upper bound
     // `U` to `S` where `S <: U`, yielding a type parameter `T extends S`.
     if (from is TypeParameterType) {
-      if (isSubtypeOf(to, from.resolveToBound(DynamicTypeImpl.instance))) {
+      if (isSubtypeOf(to, from.bound ?? DynamicTypeImpl.instance)) {
         return new TypeParameterMember(from.element, null, to).type;
       }
     }
@@ -908,10 +911,9 @@
         var newType =
             _substituteForUnknownType(p.type, lowerBound: !lowerBound);
         return new ParameterElementImpl.synthetic(
-            // ignore: deprecated_member_use
             p.name,
             newType,
-            // ignore: deprecated_member_use
+            // ignore: deprecated_member_use_from_same_package
             p.parameterKind);
       });
       // Return type is covariant.
@@ -931,14 +933,15 @@
 
   bool _typeParameterBoundsSubtype(
       DartType t1, DartType t2, bool recursionValue) {
-    if (_comparingTypeParameterBounds) {
+    TypeComparison comparison = TypeComparison(t1, t2);
+    if (_typeParameterBoundsComparisons.contains(comparison)) {
       return recursionValue;
     }
-    _comparingTypeParameterBounds = true;
+    _typeParameterBoundsComparisons.add(comparison);
     try {
       return isSubtypeOf(t1, t2);
     } finally {
-      _comparingTypeParameterBounds = false;
+      _typeParameterBoundsComparisons.remove(comparison);
     }
   }
 
@@ -1662,12 +1665,27 @@
   }
 }
 
-/**
- * A type system that implements the type semantics for strong mode.
- */
-@deprecated
-class StrongTypeSystemImpl extends Dart2TypeSystem {
-  StrongTypeSystemImpl(TypeProvider typeProvider) : super(typeProvider);
+/// 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";
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index 65fde36..c9abd60 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/file_system/file_system.dart'
     show File, Folder, ResourceProvider, ResourceUriResolver;
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -27,6 +28,7 @@
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/util/sdk.dart';
 import 'package:package_config/packages.dart' show Packages;
 import 'package:package_config/packages_file.dart' as pkgfile show parse;
@@ -34,6 +36,9 @@
 import 'package:path/path.dart' as p;
 import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
+import 'package:yaml/yaml.dart';
+
+AnalysisOptionsProvider _optionsProvider = new AnalysisOptionsProvider();
 
 Source createSource(Uri sourceUri) {
   return PhysicalResourceProvider.INSTANCE
@@ -49,6 +54,12 @@
 
 AnalysisOptions _buildAnalyzerOptions(LinterOptions options) {
   AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
+  if (options.analysisOptions != null) {
+    YamlMap map =
+        _optionsProvider.getOptionsFromString(options.analysisOptions);
+    applyToAnalysisOptions(analysisOptions, map);
+  }
+
   analysisOptions.hint = false;
   analysisOptions.lint = options.enableLints;
   analysisOptions.generateSdkErrors = options.showSdkWarnings;
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 348322f..c60b97d1 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -16,7 +16,7 @@
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/error/lint_codes.dart';
 import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisErrorInfo, AnalysisErrorInfoImpl, Logger;
+    show AnalysisErrorInfo, AnalysisErrorInfoImpl, AnalysisOptions, Logger;
 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart' show LineInfo;
@@ -199,6 +199,8 @@
 abstract class LinterContext {
   List<LinterContextUnit> get allUnits;
 
+  AnalysisOptions get analysisOptions;
+
   LinterContextUnit get currentUnit;
 
   DeclaredVariables get declaredVariables;
@@ -224,6 +226,9 @@
   final List<LinterContextUnit> allUnits;
 
   @override
+  final AnalysisOptions analysisOptions;
+
+  @override
   final LinterContextUnit currentUnit;
 
   @override
@@ -236,7 +241,7 @@
   final TypeSystem typeSystem;
 
   LinterContextImpl(this.allUnits, this.currentUnit, this.declaredVariables,
-      this.typeProvider, this.typeSystem);
+      this.typeProvider, this.typeSystem, this.analysisOptions);
 
   @override
   bool canBeConst(InstanceCreationExpression expression) {
@@ -291,13 +296,14 @@
 /// Linter options.
 class LinterOptions extends DriverOptions {
   Iterable<LintRule> enabledLints;
+  String analysisOptions;
   LintFilter filter;
   file_system.ResourceProvider resourceProvider;
-  LinterOptions([this.enabledLints]) {
+  // todo (pq): consider migrating to named params (but note Linter dep).
+  LinterOptions([this.enabledLints, this.analysisOptions]) {
     enabledLints ??= Registry.ruleRegistry;
   }
   void configure(LintConfig config) {
-    // TODO(pquitslund): revisit these default-to-on semantics.
     enabledLints = Registry.ruleRegistry.where((LintRule rule) =>
         !config.ruleConfigs.any((rc) => rc.disables(rule.name)));
     filter = new FileGlobFilter(config.fileIncludes, config.fileExcludes);
diff --git a/pkg/analyzer/lib/src/lint/linter_visitor.dart b/pkg/analyzer/lib/src/lint/linter_visitor.dart
index 7b2374e..98ba52c 100644
--- a/pkg/analyzer/lib/src/lint/linter_visitor.dart
+++ b/pkg/analyzer/lib/src/lint/linter_visitor.dart
@@ -253,24 +253,60 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _runSubscriptions(node, registry._forForEachPartsWithDeclaration);
+    super.visitForEachPartsWithDeclaration(node);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    _runSubscriptions(node, registry._forForEachPartsWithIdentifier);
+    super.visitForEachPartsWithIdentifier(node);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     _runSubscriptions(node, registry._forForEachStatement);
     super.visitForEachStatement(node);
   }
 
   @override
+  void visitForElement(ForElement node) {
+    _runSubscriptions(node, registry._forForElement);
+    super.visitForElement(node);
+  }
+
+  @override
   void visitFormalParameterList(FormalParameterList node) {
     _runSubscriptions(node, registry._forFormalParameterList);
     super.visitFormalParameterList(node);
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    _runSubscriptions(node, registry._forForPartsWithDeclarations);
+    super.visitForPartsWithDeclarations(node);
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    _runSubscriptions(node, registry._forForPartsWithExpression);
+    super.visitForPartsWithExpression(node);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     _runSubscriptions(node, registry._forForStatement);
     super.visitForStatement(node);
   }
 
   @override
+  void visitForStatement2(ForStatement2 node) {
+    _runSubscriptions(node, registry._forForStatement2);
+    super.visitForStatement2(node);
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     _runSubscriptions(node, registry._forFunctionDeclaration);
     super.visitFunctionDeclaration(node);
@@ -325,6 +361,12 @@
   }
 
   @override
+  void visitIfElement(IfElement node) {
+    _runSubscriptions(node, registry._forIfElement);
+    super.visitIfElement(node);
+  }
+
+  @override
   void visitIfStatement(IfStatement node) {
     _runSubscriptions(node, registry._forIfStatement);
     super.visitIfStatement(node);
@@ -409,12 +451,24 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    _runSubscriptions(node, registry._forListLiteral2);
+    super.visitListLiteral2(node);
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     _runSubscriptions(node, registry._forMapLiteral);
     super.visitMapLiteral(node);
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    _runSubscriptions(node, registry._forMapLiteral2);
+    super.visitMapLiteral2(node);
+  }
+
+  @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
     _runSubscriptions(node, registry._forMapLiteralEntry);
     super.visitMapLiteralEntry(node);
@@ -518,6 +572,12 @@
   }
 
   @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    _runSubscriptions(node, registry._forSetLiteral2);
+    super.visitSetLiteral2(node);
+  }
+
+  @override
   void visitShowCombinator(ShowCombinator node) {
     _runSubscriptions(node, registry._forShowCombinator);
     super.visitShowCombinator(node);
@@ -542,6 +602,12 @@
   }
 
   @override
+  void visitSpreadElement(SpreadElement node) {
+    _runSubscriptions(node, registry._forSpreadElement);
+    super.visitSpreadElement(node);
+  }
+
+  @override
   void visitStringInterpolation(StringInterpolation node) {
     _runSubscriptions(node, registry._forStringInterpolation);
     super.visitStringInterpolation(node);
@@ -731,9 +797,19 @@
   final List<_Subscription<ExtendsClause>> _forExtendsClause = [];
   final List<_Subscription<FieldDeclaration>> _forFieldDeclaration = [];
   final List<_Subscription<FieldFormalParameter>> _forFieldFormalParameter = [];
+  final List<_Subscription<ForEachPartsWithDeclaration>>
+      _forForEachPartsWithDeclaration = [];
+  final List<_Subscription<ForEachPartsWithIdentifier>>
+      _forForEachPartsWithIdentifier = [];
   final List<_Subscription<ForEachStatement>> _forForEachStatement = [];
+  final List<_Subscription<ForElement>> _forForElement = [];
   final List<_Subscription<FormalParameterList>> _forFormalParameterList = [];
+  final List<_Subscription<ForPartsWithDeclarations>>
+      _forForPartsWithDeclarations = [];
+  final List<_Subscription<ForPartsWithExpression>> _forForPartsWithExpression =
+      [];
   final List<_Subscription<ForStatement>> _forForStatement = [];
+  final List<_Subscription<ForStatement2>> _forForStatement2 = [];
   final List<_Subscription<FunctionDeclaration>> _forFunctionDeclaration = [];
   final List<_Subscription<FunctionDeclarationStatement>>
       _forFunctionDeclarationStatement = [];
@@ -746,6 +822,7 @@
   final List<_Subscription<GenericFunctionType>> _forGenericFunctionType = [];
   final List<_Subscription<GenericTypeAlias>> _forGenericTypeAlias = [];
   final List<_Subscription<HideCombinator>> _forHideCombinator = [];
+  final List<_Subscription<IfElement>> _forIfElement = [];
   final List<_Subscription<IfStatement>> _forIfStatement = [];
   final List<_Subscription<ImplementsClause>> _forImplementsClause = [];
   final List<_Subscription<ImportDirective>> _forImportDirective = [];
@@ -762,7 +839,9 @@
   final List<_Subscription<LibraryDirective>> _forLibraryDirective = [];
   final List<_Subscription<LibraryIdentifier>> _forLibraryIdentifier = [];
   final List<_Subscription<ListLiteral>> _forListLiteral = [];
+  final List<_Subscription<ListLiteral2>> _forListLiteral2 = [];
   final List<_Subscription<MapLiteral>> _forMapLiteral = [];
+  final List<_Subscription<MapLiteral2>> _forMapLiteral2 = [];
   final List<_Subscription<MapLiteralEntry>> _forMapLiteralEntry = [];
   final List<_Subscription<MethodDeclaration>> _forMethodDeclaration = [];
   final List<_Subscription<MethodInvocation>> _forMethodInvocation = [];
@@ -782,11 +861,13 @@
       _forRedirectingConstructorInvocation = [];
   final List<_Subscription<RethrowExpression>> _forRethrowExpression = [];
   final List<_Subscription<ReturnStatement>> _forReturnStatement = [];
+  final List<_Subscription<SetLiteral2>> _forSetLiteral2 = [];
   final List<_Subscription<ShowCombinator>> _forShowCombinator = [];
   final List<_Subscription<SimpleFormalParameter>> _forSimpleFormalParameter =
       [];
   final List<_Subscription<SimpleIdentifier>> _forSimpleIdentifier = [];
   final List<_Subscription<SimpleStringLiteral>> _forSimpleStringLiteral = [];
+  final List<_Subscription<SpreadElement>> _forSpreadElement = [];
   final List<_Subscription<StringInterpolation>> _forStringInterpolation = [];
   final List<_Subscription<SuperConstructorInvocation>>
       _forSuperConstructorInvocation = [];
@@ -1003,20 +1084,49 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForEachPartsWithDeclaration(LintRule linter, AstVisitor visitor) {
+    _forForEachPartsWithDeclaration
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addForEachPartsWithIdentifier(LintRule linter, AstVisitor visitor) {
+    _forForEachPartsWithIdentifier
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addForEachStatement(LintRule linter, AstVisitor visitor) {
     _forForEachStatement
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForElement(LintRule linter, AstVisitor visitor) {
+    _forForElement.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addFormalParameterList(LintRule linter, AstVisitor visitor) {
     _forFormalParameterList
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForPartsWithDeclarations(LintRule linter, AstVisitor visitor) {
+    _forForPartsWithDeclarations
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
+  void addForPartsWithExpression(LintRule linter, AstVisitor visitor) {
+    _forForPartsWithExpression
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addForStatement(LintRule linter, AstVisitor visitor) {
     _forForStatement.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addForStatement2(LintRule linter, AstVisitor visitor) {
+    _forForStatement2
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addFunctionDeclaration(LintRule linter, AstVisitor visitor) {
     _forFunctionDeclaration
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
@@ -1062,6 +1172,10 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addIfElement(LintRule linter, AstVisitor visitor) {
+    _forIfElement.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addIfStatement(LintRule linter, AstVisitor visitor) {
     _forIfStatement.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
@@ -1128,10 +1242,18 @@
     _forListLiteral.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addListLiteral2(LintRule linter, AstVisitor visitor) {
+    _forListLiteral2.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addMapLiteral(LintRule linter, AstVisitor visitor) {
     _forMapLiteral.add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addMapLiteral2(LintRule linter, AstVisitor visitor) {
+    _forMapLiteral2.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addMapLiteralEntry(LintRule linter, AstVisitor visitor) {
     _forMapLiteralEntry
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
@@ -1216,6 +1338,10 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addSetLiteral2(LintRule linter, AstVisitor visitor) {
+    _forSetLiteral2.add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addShowCombinator(LintRule linter, AstVisitor visitor) {
     _forShowCombinator
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
@@ -1236,6 +1362,11 @@
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
   }
 
+  void addSpreadElement(LintRule linter, AstVisitor visitor) {
+    _forSpreadElement
+        .add(new _Subscription(linter, visitor, _getTimer(linter)));
+  }
+
   void addStringInterpolation(LintRule linter, AstVisitor visitor) {
     _forStringInterpolation
         .add(new _Subscription(linter, visitor, _getTimer(linter)));
diff --git a/pkg/analyzer/lib/src/lint/registry.dart b/pkg/analyzer/lib/src/lint/registry.dart
index 4e02ac7..e72f804 100644
--- a/pkg/analyzer/lib/src/lint/registry.dart
+++ b/pkg/analyzer/lib/src/lint/registry.dart
@@ -21,16 +21,6 @@
    */
   Map<String, LintRule> _ruleMap = <String, LintRule>{};
 
-  /**
-   * A list of the default lint rules.
-   */
-  List<LintRule> _defaultRules = <LintRule>[];
-
-  /**
-   * Return a list of the default lint rules.
-   */
-  List<LintRule> get defaultRules => _defaultRules;
-
   @override
   Iterator<LintRule> get iterator => _ruleMap.values.iterator;
 
@@ -69,12 +59,9 @@
     _ruleMap[rule.name] = rule;
   }
 
-  /**
-   * Add the given lint [rule] to this registry and mark it as being a default
-   * lint (one that will be run if lints are requested but no rules are enabled.
-   */
+  // todo (pq): remove once linter-0.1.79 is in DEPS.
+  @deprecated
   void registerDefault(LintRule rule) {
     register(rule);
-    _defaultRules.add(rule);
   }
 }
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
new file mode 100644
index 0000000..a9056f4
--- /dev/null
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -0,0 +1,1544 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:collection';
+
+import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/string_source.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+import 'package:analyzer/src/summary/format.dart' as idl;
+import 'package:analyzer/src/summary/idl.dart' as idl;
+import 'package:analyzer/src/summary/link.dart' as graph
+    show DependencyWalker, Node;
+import 'package:analyzer/src/util/comment.dart';
+import 'package:convert/convert.dart';
+import 'package:meta/meta.dart';
+import 'package:yaml/yaml.dart';
+
+/// A top-level public declaration.
+class Declaration {
+  final String docComplete;
+  final String docSummary;
+  final bool isAbstract;
+  final bool isConst;
+  final bool isDeprecated;
+  final bool isFinal;
+  final DeclarationKind kind;
+  final int locationOffset;
+  final String locationPath;
+  final int locationStartColumn;
+  final int locationStartLine;
+  final String name;
+  final String name2;
+  final String parameters;
+  final List<String> parameterNames;
+  final List<String> parameterTypes;
+  final int requiredParameterCount;
+  final String returnType;
+  final String typeParameters;
+
+  List<String> _relevanceTags;
+
+  Declaration({
+    @required this.docComplete,
+    @required this.docSummary,
+    @required this.isAbstract,
+    @required this.isConst,
+    @required this.isDeprecated,
+    @required this.isFinal,
+    @required this.kind,
+    @required this.locationOffset,
+    @required this.locationPath,
+    @required this.locationStartColumn,
+    @required this.locationStartLine,
+    @required this.name,
+    @required this.name2,
+    @required this.parameters,
+    @required this.parameterNames,
+    @required this.parameterTypes,
+    @required List<String> relevanceTags,
+    @required this.requiredParameterCount,
+    @required this.returnType,
+    @required this.typeParameters,
+  }) : _relevanceTags = relevanceTags;
+
+  List<String> get relevanceTags => _relevanceTags;
+
+  @override
+  String toString() {
+    if (name2 == null) {
+      return '($kind, $name)';
+    } else {
+      return '($kind, $name, $name2)';
+    }
+  }
+}
+
+/// A kind of a top-level declaration.
+enum DeclarationKind {
+  CLASS,
+  CLASS_TYPE_ALIAS,
+  ENUM,
+  ENUM_CONSTANT,
+  FUNCTION,
+  FUNCTION_TYPE_ALIAS,
+  GETTER,
+  MIXIN,
+  SETTER,
+  VARIABLE
+}
+
+/// The context in which completions happens, so declarations are collected.
+class DeclarationsContext {
+  final DeclarationsTracker _tracker;
+
+  /// The analysis context for this context.  Declarations from all files in
+  /// the root are included into completion, even in 'lib/src' folders.
+  final AnalysisContext _analysisContext;
+
+  /// Packages in the analysis context.
+  ///
+  /// Packages are sorted so that inner packages are before outer.
+  final List<_Package> _packages = [];
+
+  /// The list of paths of all files inside the context.
+  final List<String> _contextPathList = [];
+
+  /// The list of paths of all SDK libraries.
+  final List<String> _sdkLibraryPathList = [];
+
+  /// Map of path prefixes to lists of paths of files from dependencies
+  /// (both libraries and parts, we don't know at the time when we fill this
+  /// map) that libraries with paths starting with these prefixes can access.
+  ///
+  /// The path prefix keys are sorted so that the longest keys are first.
+  final Map<String, List<String>> _pathPrefixToDependencyPathList = {};
+
+  DeclarationsContext(this._tracker, this._analysisContext);
+
+  /// Return libraries that are available to the file with the given [path].
+  ///
+  /// With `Pub`, files below the `pubspec.yaml` file can access libraries
+  /// of packages listed as `dependencies`, and files in the `test` directory
+  /// can in addition access libraries of packages listed as `dev_dependencies`.
+  ///
+  /// With `Bazel` sets of accessible libraries are specified explicitly by
+  /// the client using [setDependencies].
+  Libraries getLibraries(String path) {
+    var sdkLibraries = <Library>[];
+    _addLibrariesWithPaths(sdkLibraries, _sdkLibraryPathList);
+
+    var dependencyLibraries = <Library>[];
+    for (var pathPrefix in _pathPrefixToDependencyPathList.keys) {
+      if (path.startsWith(pathPrefix)) {
+        var pathList = _pathPrefixToDependencyPathList[pathPrefix];
+        _addLibrariesWithPaths(dependencyLibraries, pathList);
+        break;
+      }
+    }
+
+    _Package package;
+    for (var candidatePackage in _packages) {
+      if (candidatePackage.contains(path)) {
+        package = candidatePackage;
+        break;
+      }
+    }
+
+    var contextPathList = <String>[];
+    if (package != null) {
+      var containingFolder = package.folderInRootContaining(path);
+      if (containingFolder != null) {
+        for (var contextPath in _contextPathList) {
+          // `lib/` can see only libraries in `lib/`.
+          // `test/` can see libraries in `lib/` and in `test/`.
+          if (package.containsInLib(contextPath) ||
+              containingFolder.contains(contextPath)) {
+            contextPathList.add(contextPath);
+          }
+        }
+      }
+    } else {
+      // Not in a package, include all libraries of the context.
+      contextPathList = _contextPathList;
+    }
+
+    var contextLibraries = <Library>[];
+    _addLibrariesWithPaths(
+      contextLibraries,
+      contextPathList,
+      excludingLibraryOfPath: path,
+    );
+
+    return Libraries(sdkLibraries, dependencyLibraries, contextLibraries);
+  }
+
+  /// Set dependencies for path prefixes in this context.
+  ///
+  /// The map [pathPrefixToPathList] specifies the list of paths of libraries
+  /// and directories with libraries that are accessible to the files with
+  /// paths that start with the path that is the key in the map.  The longest
+  /// (so most specific) key will be used, each list of paths is complete, and
+  /// is not combined with any enclosing locations.
+  ///
+  /// For `Pub` packages this method is invoked automatically, because their
+  /// dependencies, described in `pubspec.yaml` files, and can be automatically
+  /// included.  This method is useful for `Bazel` contexts, where dependencies
+  /// are specified externally, in form of `BUILD` files.
+  ///
+  /// New dependencies will replace any previously set dependencies for this
+  /// context.
+  ///
+  /// Every path in the list must be absolute and normalized.
+  void setDependencies(Map<String, List<String>> pathPrefixToPathList) {
+    var rootFolder = _analysisContext.contextRoot.root;
+    _pathPrefixToDependencyPathList.removeWhere((pathPrefix, _) {
+      return rootFolder.isOrContains(pathPrefix);
+    });
+
+    var sortedPrefixes = pathPrefixToPathList.keys.toList();
+    sortedPrefixes.sort((a, b) {
+      return b.compareTo(a);
+    });
+
+    for (var pathPrefix in sortedPrefixes) {
+      var pathList = pathPrefixToPathList[pathPrefix];
+      var files = <String>[];
+      for (var path in pathList) {
+        var resource = _tracker._resourceProvider.getResource(path);
+        _scheduleDependencyResource(files, resource);
+      }
+      _pathPrefixToDependencyPathList[pathPrefix] = files;
+    }
+  }
+
+  void _addContextFile(String path) {
+    if (!_contextPathList.contains(path)) {
+      _contextPathList.add(path);
+    }
+  }
+
+  void _addLibrariesWithPaths(List<Library> libraries, List<String> pathList,
+      {String excludingLibraryOfPath}) {
+    var excludedFile = _tracker._pathToFile[excludingLibraryOfPath];
+    var excludedLibraryPath = (excludedFile?.library ?? excludedFile)?.path;
+
+    for (var path in pathList) {
+      if (path == excludedLibraryPath) continue;
+
+      var file = _tracker._pathToFile[path];
+      if (file != null && file.isLibrary) {
+        var library = _tracker._idToLibrary[file.id];
+        if (library != null) {
+          libraries.add(library);
+        }
+      }
+    }
+  }
+
+  /// Traverse the folders of this context and fill [_packages];  use
+  /// `pubspec.yaml` files to set `Pub` dependencies.
+  void _findPackages() {
+    var pathContext = _tracker._resourceProvider.pathContext;
+    var pubPathPrefixToPathList = <String, List<String>>{};
+
+    void visitFolder(Folder folder) {
+      var buildFile = folder.getChildAssumingFile('BUILD');
+      var pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
+      if (buildFile.exists) {
+        _packages.add(_Package(folder));
+      } else if (pubspecFile.exists) {
+        var dependencies = _parsePubspecDependencies(pubspecFile);
+        var libPaths = _resolvePackageNamesToLibPaths(dependencies.lib);
+        var devPaths = _resolvePackageNamesToLibPaths(dependencies.dev);
+
+        var packagePath = folder.path;
+        pubPathPrefixToPathList[packagePath] = <String>[]
+          ..addAll(libPaths)
+          ..addAll(devPaths);
+
+        var libPath = pathContext.join(packagePath, 'lib');
+        pubPathPrefixToPathList[libPath] = libPaths;
+
+        _packages.add(_Package(folder));
+      }
+
+      try {
+        for (var resource in folder.getChildren()) {
+          if (resource is Folder) {
+            visitFolder(resource);
+          }
+        }
+      } on FileSystemException {}
+    }
+
+    visitFolder(_analysisContext.contextRoot.root);
+    setDependencies(pubPathPrefixToPathList);
+
+    _packages.sort((a, b) {
+      var aRoot = a.root.path;
+      var bRoot = b.root.path;
+      return bRoot.compareTo(aRoot);
+    });
+  }
+
+  bool _isLibSrcPath(String path) {
+    var parts = _tracker._resourceProvider.pathContext.split(path);
+    for (var i = 0; i < parts.length - 1; ++i) {
+      if (parts[i] == 'lib' && parts[i + 1] == 'src') return true;
+    }
+    return false;
+  }
+
+  List<String> _resolvePackageNamesToLibPaths(List<String> packageNames) {
+    return packageNames
+        .map(_resolvePackageNameToLibPath)
+        .where((path) => path != null)
+        .toList();
+  }
+
+  String _resolvePackageNameToLibPath(String packageName) {
+    try {
+      var uri = Uri.parse('package:$packageName/ref.dart');
+
+      var path = _resolveUri(uri);
+      if (path == null) return null;
+
+      return _tracker._resourceProvider.pathContext.dirname(path);
+    } on FormatException {
+      return null;
+    }
+  }
+
+  String _resolveUri(Uri uri) {
+    var uriConverter = _analysisContext.currentSession.uriConverter;
+    return uriConverter.uriToPath(uri);
+  }
+
+  Uri _restoreUri(String path) {
+    var uriConverter = _analysisContext.currentSession.uriConverter;
+    return uriConverter.pathToUri(path);
+  }
+
+  void _scheduleContextFiles() {
+    var contextFiles = _analysisContext.contextRoot.analyzedFiles();
+    for (var path in contextFiles) {
+      _contextPathList.add(path);
+      _tracker._addFile(this, path);
+    }
+  }
+
+  void _scheduleDependencyFolder(List<String> files, Folder folder) {
+    if (_isLibSrcPath(folder.path)) return;
+    try {
+      for (var resource in folder.getChildren()) {
+        _scheduleDependencyResource(files, resource);
+      }
+    } on FileSystemException catch (_) {}
+  }
+
+  void _scheduleDependencyResource(List<String> files, Resource resource) {
+    if (resource is File) {
+      files.add(resource.path);
+      _tracker._addFile(this, resource.path);
+    } else if (resource is Folder) {
+      _scheduleDependencyFolder(files, resource);
+    }
+  }
+
+  void _scheduleSdkLibraries() {
+    // ignore: deprecated_member_use_from_same_package
+    var sdk = _analysisContext.currentSession.sourceFactory.dartSdk;
+    for (var uriStr in sdk.uris) {
+      if (!uriStr.startsWith('dart:_')) {
+        var uri = Uri.parse(uriStr);
+        var path = _resolveUri(uri);
+        if (path != null) {
+          _sdkLibraryPathList.add(path);
+          _tracker._addFile(this, path);
+        }
+      }
+    }
+  }
+
+  static _PubspecDependencies _parsePubspecDependencies(File pubspecFile) {
+    var dependencies = <String>[];
+    var devDependencies = <String>[];
+    try {
+      var fileContent = pubspecFile.readAsStringSync();
+      var document = loadYamlDocument(fileContent);
+      var contents = document.contents;
+      if (contents is YamlMap) {
+        var dependenciesNode = contents.nodes['dependencies'];
+        if (dependenciesNode is YamlMap) {
+          dependencies = dependenciesNode.keys.whereType<String>().toList();
+        }
+
+        var devDependenciesNode = contents.nodes['dev_dependencies'];
+        if (devDependenciesNode is YamlMap) {
+          devDependencies =
+              devDependenciesNode.keys.whereType<String>().toList();
+        }
+      }
+    } catch (e) {}
+    return _PubspecDependencies(dependencies, devDependencies);
+  }
+}
+
+/// Tracker for top-level declarations across multiple analysis contexts
+/// and their dependencies.
+class DeclarationsTracker {
+  final ByteStore _byteStore;
+  final ResourceProvider _resourceProvider;
+
+  final Map<AnalysisContext, DeclarationsContext> _contexts = {};
+  final Map<String, _File> _pathToFile = {};
+  final Map<Uri, _File> _uriToFile = {};
+  final Map<int, Library> _idToLibrary = {};
+
+  final _changesController = _StreamController<LibraryChange>();
+
+  /// The list of changed file paths.
+  final List<String> _changedPaths = [];
+
+  /// The list of files scheduled for processing.  It may include parts and
+  /// libraries, but parts are ignored when we detect them.
+  final List<_ScheduledFile> _scheduledFiles = [];
+
+  DeclarationsTracker(this._byteStore, this._resourceProvider);
+
+  /// The stream of changes to the set of libraries used by the added contexts.
+  Stream<LibraryChange> get changes => _changesController.stream;
+
+  /// Return `true` if there is scheduled work to do, as a result of adding
+  /// new contexts, or changes to files.
+  bool get hasWork {
+    return _changedPaths.isNotEmpty || _scheduledFiles.isNotEmpty;
+  }
+
+  /// Add the [analysisContext], so that its libraries are reported via the
+  /// [changes] stream, and return the [DeclarationsContext] that can be used
+  /// to set additional dependencies and request libraries available to this
+  /// context.
+  DeclarationsContext addContext(AnalysisContext analysisContext) {
+    if (_contexts.containsKey(analysisContext)) {
+      throw StateError('The analysis context has already been added.');
+    }
+
+    var declarationsContext = DeclarationsContext(this, analysisContext);
+    _contexts[analysisContext] = declarationsContext;
+
+    declarationsContext._scheduleContextFiles();
+    declarationsContext._scheduleSdkLibraries();
+    declarationsContext._findPackages();
+    return declarationsContext;
+  }
+
+  /// The file with the given [path] was changed - added, updated, or removed.
+  ///
+  /// The [path] must be absolute and normalized.
+  ///
+  /// Usually causes [hasWork] to return `true`, so that [doWork] should
+  /// be invoked to send updates to [changes] that reflect changes to the
+  /// library of the file, and other libraries that export it.
+  void changeFile(String path) {
+    if (!path.endsWith('.dart')) return;
+
+    _changedPaths.add(path);
+  }
+
+  /// Discard all contexts and libraries, notify the [changes] stream that
+  /// these libraries are removed.
+  void discardContexts() {
+    var libraryIdList = _idToLibrary.keys.toList();
+    _changesController.add(LibraryChange._([], libraryIdList));
+
+    _contexts.clear();
+    _pathToFile.clear();
+    _uriToFile.clear();
+    _idToLibrary.clear();
+    _changedPaths.clear();
+    _scheduledFiles.clear();
+  }
+
+  /// Do a single piece of work.
+  ///
+  /// The client should call this method until [hasWork] returns `false`.
+  /// This would mean that all previous changes have been processed, and
+  /// updates scheduled to be delivered via the [changes] stream.
+  void doWork() {
+    if (_changedPaths.isNotEmpty) {
+      var path = _changedPaths.removeLast();
+      _performChangeFile(path);
+      return;
+    }
+
+    if (_scheduledFiles.isNotEmpty) {
+      var scheduledFile = _scheduledFiles.removeLast();
+      var file = _getFileByPath(scheduledFile.context, scheduledFile.path);
+
+      if (!file.isLibrary) return;
+
+      if (file.isSent) {
+        return;
+      } else {
+        file.isSent = true;
+      }
+
+      if (file.exportedDeclarations == null) {
+        new _LibraryWalker().walkLibrary(file);
+        assert(file.exportedDeclarations != null);
+      }
+
+      var library = Library._(
+        file.id,
+        file.path,
+        file.uri,
+        file.isLibraryDeprecated,
+        file.exportedDeclarations,
+      );
+      _idToLibrary[file.id] = library;
+      _changesController.add(
+        LibraryChange._([library], []),
+      );
+    }
+  }
+
+  /// Return the context associated with the given [analysisContext], or `null`
+  /// if there is none.
+  DeclarationsContext getContext(AnalysisContext analysisContext) {
+    return _contexts[analysisContext];
+  }
+
+  /// Return the library with the given [id], or `null` if there is none.
+  Library getLibrary(int id) {
+    return _idToLibrary[id];
+  }
+
+  void _addFile(DeclarationsContext context, String path) {
+    if (path.endsWith('.dart')) {
+      _scheduledFiles.add(_ScheduledFile(context, path));
+    }
+  }
+
+  /// Compute exported declarations for the given [libraries].
+  void _computeExportedDeclarations(Set<_File> libraries) {
+    var walker = new _LibraryWalker();
+    for (var library in libraries) {
+      if (library.isLibrary && library.exportedDeclarations == null) {
+        walker.walkLibrary(library);
+        assert(library.exportedDeclarations != null);
+      }
+    }
+  }
+
+  DeclarationsContext _findContextOfPath(String path) {
+    // Prefer the context in which the path is analyzed.
+    for (var context in _contexts.values) {
+      if (context._analysisContext.contextRoot.isAnalyzed(path)) {
+        context._addContextFile(path);
+        return context;
+      }
+    }
+
+    // The path must have the URI with one of the supported URI schemes.
+    for (var context in _contexts.values) {
+      var uri = context._restoreUri(path);
+      if (uri != null) {
+        if (uri.isScheme('dart') || uri.isScheme('package')) {
+          return context;
+        }
+      }
+    }
+
+    return null;
+  }
+
+  _File _getFileByPath(DeclarationsContext context, String path) {
+    var file = _pathToFile[path];
+    if (file == null) {
+      var uri = context._restoreUri(path);
+      if (uri != null) {
+        file = _File(this, path, uri);
+        _pathToFile[path] = file;
+        _uriToFile[uri] = file;
+        file.refresh(context);
+      }
+    }
+    return file;
+  }
+
+  _File _getFileByUri(DeclarationsContext context, Uri uri) {
+    var file = _uriToFile[uri];
+    if (file == null) {
+      var path = context._resolveUri(uri);
+      if (path != null) {
+        file = _File(this, path, uri);
+        _pathToFile[path] = file;
+        _uriToFile[uri] = file;
+        file.refresh(context);
+      }
+    }
+    return file;
+  }
+
+  /// Recursively invalidate exported declarations of the given [library]
+  /// and libraries that export it.
+  void _invalidateExportedDeclarations(Set<_File> libraries, _File library) {
+    if (libraries.add(library)) {
+      library.exportedDeclarations = null;
+      for (var exporter in library.directExporters) {
+        _invalidateExportedDeclarations(libraries, exporter);
+      }
+    }
+  }
+
+  void _performChangeFile(String path) {
+    var containingContext = _findContextOfPath(path);
+    if (containingContext == null) return;
+
+    var file = _getFileByPath(containingContext, path);
+    if (file == null) return;
+
+    var isLibrary = file.isLibrary;
+    var library = isLibrary ? file : file.library;
+
+    if (isLibrary) {
+      file.refresh(containingContext);
+    } else {
+      file.refresh(containingContext);
+      library.refresh(containingContext);
+    }
+
+    var invalidatedLibraries = Set<_File>();
+    _invalidateExportedDeclarations(invalidatedLibraries, library);
+    _computeExportedDeclarations(invalidatedLibraries);
+
+    var changedLibraries = <Library>[];
+    var removedLibraries = <int>[];
+    for (var libraryFile in invalidatedLibraries) {
+      if (libraryFile.exists) {
+        var library = Library._(
+          libraryFile.id,
+          libraryFile.path,
+          libraryFile.uri,
+          libraryFile.isLibraryDeprecated,
+          libraryFile.exportedDeclarations,
+        );
+        _idToLibrary[library.id] = library;
+        changedLibraries.add(library);
+      } else {
+        _idToLibrary.remove(libraryFile.id);
+        removedLibraries.add(libraryFile.id);
+      }
+    }
+    _changesController.add(
+      LibraryChange._(changedLibraries, removedLibraries),
+    );
+  }
+}
+
+class Libraries {
+  final List<Library> sdk;
+  final List<Library> dependencies;
+  final List<Library> context;
+
+  Libraries(this.sdk, this.dependencies, this.context);
+}
+
+/// A library with declarations.
+class Library {
+  /// The unique identifier of a library with the given [path].
+  final int id;
+
+  /// The path to the file that defines this library.
+  final String path;
+
+  /// The URI of the library.
+  final Uri uri;
+
+  /// Is `true` if the library has `@deprecated` annotation, so it probably
+  /// deprecated.  But we don't actually resolve the annotation, so it might be
+  /// a false positive.
+  final bool isDeprecated;
+
+  /// All public declaration that the library declares or (re)exports.
+  final List<Declaration> declarations;
+
+  Library._(this.id, this.path, this.uri, this.isDeprecated, this.declarations);
+
+  String get uriStr => '$uri';
+
+  @override
+  String toString() {
+    return '(id: $id, uri: $uri, path: $path)';
+  }
+}
+
+/// A change to the set of libraries and their declarations.
+class LibraryChange {
+  /// The list of new or changed libraries.
+  final List<Library> changed;
+
+  /// The list of identifier of libraries that are removed, either because
+  /// the corresponding files were removed, or because none of the contexts
+  /// has these libraries as dependencies, so that they cannot be used anymore.
+  final List<int> removed;
+
+  LibraryChange._(this.changed, this.removed);
+}
+
+class RelevanceTags {
+  static List<String> _forDeclaration(String uriStr, Declaration declaration) {
+    switch (declaration.kind) {
+      case DeclarationKind.CLASS:
+      case DeclarationKind.CLASS_TYPE_ALIAS:
+      case DeclarationKind.ENUM:
+      case DeclarationKind.MIXIN:
+      case DeclarationKind.FUNCTION_TYPE_ALIAS:
+        var name = declaration.name;
+        return <String>['$uriStr::$name'];
+      case DeclarationKind.ENUM_CONSTANT:
+        var name2 = declaration.name2;
+        return <String>['$uriStr::$name2'];
+      default:
+        return null;
+    }
+  }
+
+  static List<String> _forExpression(Expression expression) {
+    if (expression is BooleanLiteral) return const ['dart:core::bool'];
+    if (expression is DoubleLiteral) return const ['dart:core::double'];
+    if (expression is IntegerLiteral) return const ['dart:core::int'];
+    if (expression is StringLiteral) return const ['dart:core::String'];
+
+    if (expression is ListLiteral || expression is ListLiteral2) {
+      return const ['dart:core::List'];
+    }
+    if (expression is MapLiteral || expression is MapLiteral2) {
+      return const ['dart:core::Map'];
+    }
+    if (expression is SetLiteral || expression is SetLiteral2) {
+      return const ['dart:core::Set'];
+    }
+
+    return null;
+  }
+}
+
+class _DeclarationStorage {
+  static const fieldDocMask = 1 << 0;
+  static const fieldName2Mask = 1 << 1;
+  static const fieldParametersMask = 1 << 2;
+  static const fieldReturnTypeMask = 1 << 3;
+  static const fieldTypeParametersMask = 1 << 4;
+
+  static Declaration fromIdl(String path, idl.AvailableDeclaration d) {
+    var fieldMask = d.fieldMask;
+    var hasDoc = fieldMask & fieldDocMask != 0;
+    var hasName2 = fieldMask & fieldName2Mask != 0;
+    var hasParameters = fieldMask & fieldParametersMask != 0;
+    var hasReturnType = fieldMask & fieldReturnTypeMask != 0;
+    var hasTypeParameters = fieldMask & fieldTypeParametersMask != 0;
+
+    var kind = kindFromIdl(d.kind);
+
+    var relevanceTags = d.relevanceTags.toList();
+    if (relevanceTags.isEmpty) {
+      relevanceTags = null;
+    }
+
+    return Declaration(
+      docComplete: hasDoc ? d.docComplete : null,
+      docSummary: hasDoc ? d.docSummary : null,
+      isAbstract: d.isAbstract,
+      isConst: d.isConst,
+      isDeprecated: d.isDeprecated,
+      isFinal: d.isFinal,
+      kind: kind,
+      locationOffset: d.locationOffset,
+      locationPath: path,
+      locationStartColumn: d.locationStartColumn,
+      locationStartLine: d.locationStartLine,
+      name: d.name,
+      name2: hasName2 ? d.name2 : null,
+      parameters: hasParameters ? d.parameters : null,
+      parameterNames: hasParameters ? d.parameterNames : null,
+      parameterTypes: hasParameters ? d.parameterTypes.toList() : null,
+      relevanceTags: relevanceTags,
+      requiredParameterCount: hasParameters ? d.requiredParameterCount : null,
+      returnType: hasReturnType ? d.returnType : null,
+      typeParameters: hasTypeParameters ? d.typeParameters : null,
+    );
+  }
+
+  static DeclarationKind kindFromIdl(idl.AvailableDeclarationKind kind) {
+    switch (kind) {
+      case idl.AvailableDeclarationKind.CLASS:
+        return DeclarationKind.CLASS;
+      case idl.AvailableDeclarationKind.CLASS_TYPE_ALIAS:
+        return DeclarationKind.CLASS_TYPE_ALIAS;
+      case idl.AvailableDeclarationKind.ENUM:
+        return DeclarationKind.ENUM;
+      case idl.AvailableDeclarationKind.ENUM_CONSTANT:
+        return DeclarationKind.ENUM_CONSTANT;
+      case idl.AvailableDeclarationKind.FUNCTION:
+        return DeclarationKind.FUNCTION;
+      case idl.AvailableDeclarationKind.FUNCTION_TYPE_ALIAS:
+        return DeclarationKind.FUNCTION_TYPE_ALIAS;
+      case idl.AvailableDeclarationKind.GETTER:
+        return DeclarationKind.GETTER;
+      case idl.AvailableDeclarationKind.MIXIN:
+        return DeclarationKind.MIXIN;
+      case idl.AvailableDeclarationKind.SETTER:
+        return DeclarationKind.SETTER;
+      case idl.AvailableDeclarationKind.VARIABLE:
+        return DeclarationKind.VARIABLE;
+      default:
+        throw StateError('Unknown kind: $kind');
+    }
+  }
+
+  static idl.AvailableDeclarationKind kindToIdl(DeclarationKind kind) {
+    switch (kind) {
+      case DeclarationKind.CLASS:
+        return idl.AvailableDeclarationKind.CLASS;
+      case DeclarationKind.CLASS_TYPE_ALIAS:
+        return idl.AvailableDeclarationKind.CLASS_TYPE_ALIAS;
+      case DeclarationKind.ENUM:
+        return idl.AvailableDeclarationKind.ENUM;
+      case DeclarationKind.ENUM_CONSTANT:
+        return idl.AvailableDeclarationKind.ENUM_CONSTANT;
+      case DeclarationKind.FUNCTION:
+        return idl.AvailableDeclarationKind.FUNCTION;
+      case DeclarationKind.FUNCTION_TYPE_ALIAS:
+        return idl.AvailableDeclarationKind.FUNCTION_TYPE_ALIAS;
+      case DeclarationKind.GETTER:
+        return idl.AvailableDeclarationKind.GETTER;
+      case DeclarationKind.MIXIN:
+        return idl.AvailableDeclarationKind.MIXIN;
+      case DeclarationKind.SETTER:
+        return idl.AvailableDeclarationKind.SETTER;
+      case DeclarationKind.VARIABLE:
+        return idl.AvailableDeclarationKind.VARIABLE;
+      default:
+        throw StateError('Unknown kind: $kind');
+    }
+  }
+
+  static idl.AvailableDeclarationBuilder toIdl(Declaration d) {
+    var fieldMask = 0;
+    if (d.docComplete != null) {
+      fieldMask |= fieldDocMask;
+    }
+    if (d.name2 != null) {
+      fieldMask |= fieldName2Mask;
+    }
+    if (d.parameters != null) {
+      fieldMask |= fieldParametersMask;
+    }
+    if (d.returnType != null) {
+      fieldMask |= fieldReturnTypeMask;
+    }
+    if (d.typeParameters != null) {
+      fieldMask |= fieldTypeParametersMask;
+    }
+
+    var idlKind = kindToIdl(d.kind);
+    return idl.AvailableDeclarationBuilder(
+      docComplete: d.docComplete,
+      docSummary: d.docSummary,
+      fieldMask: fieldMask,
+      isAbstract: d.isAbstract,
+      isConst: d.isConst,
+      isDeprecated: d.isDeprecated,
+      isFinal: d.isFinal,
+      kind: idlKind,
+      locationOffset: d.locationOffset,
+      locationStartColumn: d.locationStartColumn,
+      locationStartLine: d.locationStartLine,
+      name: d.name,
+      name2: d.name2,
+      parameters: d.parameters,
+      parameterNames: d.parameterNames,
+      parameterTypes: d.parameterTypes,
+      relevanceTags: d.relevanceTags,
+      requiredParameterCount: d.requiredParameterCount,
+      returnType: d.returnType,
+      typeParameters: d.typeParameters,
+    );
+  }
+}
+
+class _Export {
+  final Uri uri;
+  final List<_ExportCombinator> combinators;
+
+  _File file;
+
+  _Export(this.uri, this.combinators);
+
+  Iterable<Declaration> filter(List<Declaration> declarations) {
+    return declarations.where((d) {
+      var name = d.name2 ?? d.name;
+      for (var combinator in combinators) {
+        if (combinator.shows.isNotEmpty) {
+          if (!combinator.shows.contains(name)) return false;
+        }
+        if (combinator.hides.isNotEmpty) {
+          if (combinator.hides.contains(name)) return false;
+        }
+      }
+      return true;
+    });
+  }
+}
+
+class _ExportCombinator {
+  final List<String> shows;
+  final List<String> hides;
+
+  _ExportCombinator(this.shows, this.hides);
+}
+
+class _File {
+  /// The version of data format, should be incremented on every format change.
+  static const int DATA_VERSION = 5;
+
+  /// The next value for [id].
+  static int _nextId = 0;
+
+  final DeclarationsTracker tracker;
+
+  final int id = _nextId++;
+  final String path;
+  final Uri uri;
+
+  bool exists = false;
+  bool isLibrary = false;
+  bool isLibraryDeprecated = false;
+  List<_Export> exports = [];
+  List<_Part> parts = [];
+
+  /// If this file is a part, the containing library.
+  _File library;
+
+  /// If this file is a library, libraries that export it.
+  List<_File> directExporters = [];
+
+  List<Declaration> fileDeclarations = [];
+  List<Declaration> libraryDeclarations = [];
+  List<Declaration> exportedDeclarations;
+
+  /// If `true`, then this library has already been sent to the client.
+  bool isSent = false;
+
+  _File(this.tracker, this.path, this.uri);
+
+  String get uriStr => uri.toString();
+
+  void refresh(DeclarationsContext context) {
+    var resource = tracker._resourceProvider.getFile(path);
+
+    int modificationStamp;
+    try {
+      modificationStamp = resource.modificationStamp;
+      exists = true;
+    } catch (e) {
+      modificationStamp = -1;
+      exists = false;
+    }
+
+    // When a file changes, its modification stamp changes.
+    String pathKey;
+    {
+      var pathKeyBuilder = ApiSignature();
+      pathKeyBuilder.addInt(DATA_VERSION);
+      pathKeyBuilder.addString(path);
+      pathKeyBuilder.addInt(modificationStamp);
+      pathKey = pathKeyBuilder.toHex() + '.declarations_content';
+    }
+
+    // With Bazel multiple workspaces might be copies of the same workspace,
+    // and have files with the same content, but with different paths.
+    // So, we use the content hash to reuse their declarations without parsing.
+    String content;
+    String contentKey;
+    {
+      var contentHashBytes = tracker._byteStore.get(pathKey);
+      if (contentHashBytes == null) {
+        content = _readContent(resource);
+
+        var contentHashBuilder = ApiSignature();
+        contentHashBuilder.addInt(DATA_VERSION);
+        contentHashBuilder.addString(content);
+        contentHashBytes = contentHashBuilder.toByteList();
+
+        tracker._byteStore.put(pathKey, contentHashBytes);
+      }
+
+      contentKey = hex.encode(contentHashBytes) + '.declarations';
+    }
+
+    var bytes = tracker._byteStore.get(contentKey);
+    if (bytes == null) {
+      content ??= _readContent(resource);
+
+      CompilationUnit unit = _parse(content);
+      _buildFileDeclarations(unit);
+      _putFileDeclarationsToByteStore(contentKey);
+    } else {
+      _readFileDeclarationsFromBytes(bytes);
+    }
+
+    // Resolve exports and parts.
+    for (var export in exports) {
+      export.file = _fileForRelativeUri(context, export.uri);
+    }
+    for (var part in parts) {
+      part.file = _fileForRelativeUri(context, part.uri);
+    }
+    exports.removeWhere((e) => e.file == null);
+    parts.removeWhere((e) => e.file == null);
+
+    // Set back pointers.
+    for (var export in exports) {
+      export.file.directExporters.add(this);
+    }
+    for (var part in parts) {
+      part.file.library = this;
+      part.file.isLibrary = false;
+    }
+
+    // Compute library declarations.
+    if (isLibrary) {
+      libraryDeclarations = <Declaration>[];
+      libraryDeclarations.addAll(fileDeclarations);
+      for (var part in parts) {
+        libraryDeclarations.addAll(part.file.fileDeclarations);
+      }
+      _computeRelevanceTagsForLibraryDeclarations();
+    }
+  }
+
+  void _buildFileDeclarations(CompilationUnit unit) {
+    isLibrary = true;
+    exports = [];
+    fileDeclarations = [];
+    libraryDeclarations = null;
+    exportedDeclarations = null;
+
+    for (var astDirective in unit.directives) {
+      if (astDirective is ExportDirective) {
+        var uri = _uriFromAst(astDirective.uri);
+        if (uri == null) continue;
+
+        var combinators = <_ExportCombinator>[];
+        for (var astCombinator in astDirective.combinators) {
+          if (astCombinator is ShowCombinator) {
+            combinators.add(_ExportCombinator(
+              astCombinator.shownNames.map((id) => id.name).toList(),
+              const [],
+            ));
+          } else if (astCombinator is HideCombinator) {
+            combinators.add(_ExportCombinator(
+              const [],
+              astCombinator.hiddenNames.map((id) => id.name).toList(),
+            ));
+          }
+        }
+
+        exports.add(_Export(uri, combinators));
+      } else if (astDirective is LibraryDirective) {
+        isLibraryDeprecated = _hasDeprecatedAnnotation(astDirective);
+      } else if (astDirective is PartDirective) {
+        var uri = _uriFromAst(astDirective.uri);
+        if (uri == null) continue;
+
+        parts.add(_Part(uri));
+      } else if (astDirective is PartOfDirective) {
+        isLibrary = false;
+      }
+    }
+
+    var lineInfo = unit.lineInfo;
+
+    String docComplete = null;
+    String docSummary = null;
+
+    void setDartDoc(AnnotatedNode node) {
+      if (node.documentationComment != null) {
+        var rawText = getCommentNodeRawText(node.documentationComment);
+        docComplete = getDartDocPlainText(rawText);
+        docSummary = getDartDocSummary(docComplete);
+      } else {
+        docComplete = null;
+        docSummary = null;
+      }
+    }
+
+    void addDeclaration({
+      bool isAbstract = false,
+      bool isConst = false,
+      bool isDeprecated = false,
+      bool isFinal = false,
+      @required DeclarationKind kind,
+      @required Identifier name,
+      Identifier name2,
+      String parameters,
+      List<String> parameterNames,
+      List<String> parameterTypes,
+      List<String> relevanceTags,
+      int requiredParameterCount,
+      String returnType,
+      String typeParameters,
+    }) {
+      if (!Identifier.isPrivateName(name.name)) {
+        var locationOffset = name.offset;
+        var lineLocation = lineInfo.getLocation(locationOffset);
+        fileDeclarations.add(Declaration(
+          docComplete: docComplete,
+          docSummary: docSummary,
+          isAbstract: isAbstract,
+          isConst: isConst,
+          isDeprecated: isDeprecated,
+          isFinal: isFinal,
+          kind: kind,
+          locationOffset: locationOffset,
+          locationPath: path,
+          name: name.name,
+          name2: name2?.name,
+          locationStartColumn: lineLocation.columnNumber,
+          locationStartLine: lineLocation.lineNumber,
+          parameters: parameters,
+          parameterNames: parameterNames,
+          parameterTypes: parameterTypes,
+          relevanceTags: relevanceTags,
+          requiredParameterCount: requiredParameterCount,
+          returnType: returnType,
+          typeParameters: typeParameters,
+        ));
+      }
+    }
+
+    for (var node in unit.declarations) {
+      setDartDoc(node);
+      var isDeprecated = _hasDeprecatedAnnotation(node);
+
+      if (node is ClassDeclaration) {
+        addDeclaration(
+          isAbstract: node.isAbstract,
+          isDeprecated: isDeprecated,
+          kind: DeclarationKind.CLASS,
+          name: node.name,
+        );
+      } else if (node is ClassTypeAlias) {
+        addDeclaration(
+          isDeprecated: isDeprecated,
+          kind: DeclarationKind.CLASS_TYPE_ALIAS,
+          name: node.name,
+        );
+      } else if (node is EnumDeclaration) {
+        addDeclaration(
+          isDeprecated: isDeprecated,
+          kind: DeclarationKind.ENUM,
+          name: node.name,
+        );
+        for (var constant in node.constants) {
+          setDartDoc(constant);
+          var isDeprecated = _hasDeprecatedAnnotation(constant);
+          addDeclaration(
+            isDeprecated: isDeprecated,
+            kind: DeclarationKind.ENUM_CONSTANT,
+            name: constant.name,
+            name2: node.name,
+          );
+        }
+      } else if (node is FunctionDeclaration) {
+        var functionExpression = node.functionExpression;
+        var parameters = functionExpression.parameters;
+        if (node.isGetter) {
+          addDeclaration(
+            isDeprecated: isDeprecated,
+            kind: DeclarationKind.GETTER,
+            name: node.name,
+            returnType: _getTypeAnnotationString(node.returnType),
+          );
+        } else if (node.isSetter) {
+          addDeclaration(
+            isDeprecated: isDeprecated,
+            kind: DeclarationKind.SETTER,
+            name: node.name,
+            parameters: parameters.toSource(),
+            parameterNames: _getFormalParameterNames(parameters),
+            parameterTypes: _getFormalParameterTypes(parameters),
+            requiredParameterCount:
+                _getFormalParameterRequiredCount(parameters),
+          );
+        } else {
+          addDeclaration(
+            isDeprecated: isDeprecated,
+            kind: DeclarationKind.FUNCTION,
+            name: node.name,
+            parameters: parameters.toSource(),
+            parameterNames: _getFormalParameterNames(parameters),
+            parameterTypes: _getFormalParameterTypes(parameters),
+            requiredParameterCount:
+                _getFormalParameterRequiredCount(parameters),
+            returnType: _getTypeAnnotationString(node.returnType),
+            typeParameters: functionExpression.typeParameters?.toSource(),
+          );
+        }
+      } else if (node is GenericTypeAlias) {
+        var functionType = node.functionType;
+        var parameters = functionType.parameters;
+        addDeclaration(
+          isDeprecated: isDeprecated,
+          kind: DeclarationKind.FUNCTION_TYPE_ALIAS,
+          name: node.name,
+          parameters: parameters.toSource(),
+          parameterNames: _getFormalParameterNames(parameters),
+          parameterTypes: _getFormalParameterTypes(parameters),
+          requiredParameterCount: _getFormalParameterRequiredCount(parameters),
+          returnType: _getTypeAnnotationString(functionType.returnType),
+          typeParameters: functionType.typeParameters?.toSource(),
+        );
+      } else if (node is MixinDeclaration) {
+        addDeclaration(
+          isDeprecated: isDeprecated,
+          kind: DeclarationKind.MIXIN,
+          name: node.name,
+        );
+      } else if (node is TopLevelVariableDeclaration) {
+        var isConst = node.variables.isConst;
+        var isFinal = node.variables.isFinal;
+        for (var variable in node.variables.variables) {
+          addDeclaration(
+            isConst: isConst,
+            isDeprecated: isDeprecated,
+            isFinal: isFinal,
+            kind: DeclarationKind.VARIABLE,
+            name: variable.name,
+            relevanceTags: RelevanceTags._forExpression(variable.initializer),
+            returnType: _getTypeAnnotationString(node.variables.type),
+          );
+        }
+      }
+    }
+  }
+
+  void _computeRelevanceTagsForLibraryDeclarations() {
+    for (var declaration in libraryDeclarations) {
+      declaration._relevanceTags ??=
+          RelevanceTags._forDeclaration(uriStr, declaration);
+    }
+  }
+
+  /// Return the [_File] for the given [relative] URI, maybe `null`.
+  _File _fileForRelativeUri(DeclarationsContext context, Uri relative) {
+    var absoluteUri = resolveRelativeUri(uri, relative);
+    return tracker._getFileByUri(context, absoluteUri);
+  }
+
+  void _putFileDeclarationsToByteStore(String contentKey) {
+    var builder = idl.AvailableFileBuilder(
+      isLibrary: isLibrary,
+      isLibraryDeprecated: isLibraryDeprecated,
+      exports: exports.map((e) {
+        return idl.AvailableFileExportBuilder(
+          uri: e.uri.toString(),
+          combinators: e.combinators.map((c) {
+            return idl.AvailableFileExportCombinatorBuilder(
+                shows: c.shows, hides: c.hides);
+          }).toList(),
+        );
+      }).toList(),
+      parts: parts.map((p) => p.uri.toString()).toList(),
+      declarations: fileDeclarations.map((d) {
+        return _DeclarationStorage.toIdl(d);
+      }).toList(),
+    );
+    var bytes = builder.toBuffer();
+    tracker._byteStore.put(contentKey, bytes);
+  }
+
+  void _readFileDeclarationsFromBytes(List<int> bytes) {
+    var idlFile = idl.AvailableFile.fromBuffer(bytes);
+
+    isLibrary = idlFile.isLibrary;
+    isLibraryDeprecated = idlFile.isLibraryDeprecated;
+
+    exports = idlFile.exports.map((e) {
+      return _Export(
+        Uri.parse(e.uri),
+        e.combinators.map((c) {
+          return _ExportCombinator(c.shows.toList(), c.hides.toList());
+        }).toList(),
+      );
+    }).toList();
+
+    parts = idlFile.parts.map((e) {
+      var uri = Uri.parse(e);
+      return _Part(uri);
+    }).toList();
+
+    fileDeclarations = idlFile.declarations.map((e) {
+      return _DeclarationStorage.fromIdl(path, e);
+    }).toList();
+  }
+
+  static List<String> _getFormalParameterNames(FormalParameterList parameters) {
+    if (parameters == null) return const <String>[];
+
+    var names = <String>[];
+    for (var parameter in parameters.parameters) {
+      var name = parameter.identifier?.name ?? '';
+      names.add(name);
+    }
+    return names;
+  }
+
+  static int _getFormalParameterRequiredCount(FormalParameterList parameters) {
+    if (parameters == null) return null;
+
+    return parameters.parameters
+        .takeWhile((parameter) => parameter.isRequired)
+        .length;
+  }
+
+  static String _getFormalParameterType(FormalParameter parameter) {
+    if (parameter is DefaultFormalParameter) {
+      DefaultFormalParameter defaultFormalParameter = parameter;
+      parameter = defaultFormalParameter.parameter;
+    }
+    if (parameter is SimpleFormalParameter) {
+      return _getTypeAnnotationString(parameter.type);
+    }
+    return '';
+  }
+
+  static List<String> _getFormalParameterTypes(FormalParameterList parameters) {
+    if (parameters == null) return null;
+
+    var types = <String>[];
+    for (var parameter in parameters.parameters) {
+      var type = _getFormalParameterType(parameter);
+      types.add(type);
+    }
+    return types;
+  }
+
+  static String _getTypeAnnotationString(TypeAnnotation typeAnnotation) {
+    return typeAnnotation?.toSource() ?? '';
+  }
+
+  /// Return `true` if the [node] is probably deprecated.
+  static bool _hasDeprecatedAnnotation(AnnotatedNode node) {
+    for (var annotation in node.metadata) {
+      var name = annotation.name;
+      if (name is SimpleIdentifier) {
+        if (name.name == 'deprecated' || name.name == 'Deprecated') {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  static CompilationUnit _parse(String content) {
+    var errorListener = AnalysisErrorListener.NULL_LISTENER;
+    var source = StringSource(content, '');
+
+    var reader = new CharSequenceReader(content);
+    var scanner = new Scanner(null, reader, errorListener);
+    var token = scanner.tokenize();
+
+    var parser = new Parser(source, errorListener, useFasta: true);
+    var unit = parser.parseCompilationUnit(token);
+    unit.lineInfo = LineInfo(scanner.lineStarts);
+
+    return unit;
+  }
+
+  static String _readContent(File resource) {
+    try {
+      return resource.readAsStringSync();
+    } catch (e) {
+      return '';
+    }
+  }
+
+  static Uri _uriFromAst(StringLiteral astUri) {
+    if (astUri is SimpleStringLiteral) {
+      var uriStr = astUri.value.trim();
+      if (uriStr.isEmpty) return null;
+      try {
+        return Uri.parse(uriStr);
+      } catch (_) {}
+    }
+    return null;
+  }
+}
+
+class _LibraryNode extends graph.Node<_LibraryNode> {
+  final _LibraryWalker walker;
+  final _File file;
+
+  _LibraryNode(this.walker, this.file);
+
+  @override
+  bool get isEvaluated => file.exportedDeclarations != null;
+
+  @override
+  List<_LibraryNode> computeDependencies() {
+    return file.exports.map((e) => e.file).map(walker.getNode).toList();
+  }
+}
+
+class _LibraryWalker extends graph.DependencyWalker<_LibraryNode> {
+  final Map<_File, _LibraryNode> nodesOfFiles = {};
+
+  @override
+  void evaluate(_LibraryNode node) {
+    var file = node.file;
+    var resultSet = _newDeclarationSet();
+    resultSet.addAll(file.libraryDeclarations);
+
+    for (var export in file.exports) {
+      var exportedDeclarations = export.file.exportedDeclarations;
+      resultSet.addAll(export.filter(exportedDeclarations));
+    }
+
+    file.exportedDeclarations = resultSet.toList();
+  }
+
+  @override
+  void evaluateScc(List<_LibraryNode> scc) {
+    for (var node in scc) {
+      var visitedFiles = Set<_File>();
+
+      List<Declaration> computeExported(_File file) {
+        if (file.exportedDeclarations != null) {
+          return file.exportedDeclarations;
+        }
+
+        if (!visitedFiles.add(file)) {
+          return const [];
+        }
+
+        var resultSet = _newDeclarationSet();
+        resultSet.addAll(file.libraryDeclarations);
+
+        for (var export in file.exports) {
+          var exportedDeclarations = computeExported(export.file);
+          resultSet.addAll(export.filter(exportedDeclarations));
+        }
+
+        return resultSet.toList();
+      }
+
+      var file = node.file;
+      file.exportedDeclarations = computeExported(file);
+    }
+  }
+
+  _LibraryNode getNode(_File file) {
+    return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file));
+  }
+
+  void walkLibrary(_File file) {
+    var node = getNode(file);
+    walk(node);
+  }
+
+  static Set<Declaration> _newDeclarationSet() {
+    return HashSet<Declaration>(
+      hashCode: (e) => e.name.hashCode,
+      equals: (a, b) => a.name == b.name && a.name2 == b.name2,
+    );
+  }
+}
+
+/// Information about a package: `Pub` or `Bazel`.
+class _Package {
+  final Folder root;
+  final Folder lib;
+
+  _Package(this.root) : lib = root.getChildAssumingFolder('lib');
+
+  /// Return `true` if the [path] is anywhere in the [root] of the package.
+  ///
+  /// Note, that this method does not check if the are nested packages, that
+  /// might actually contain the [path].
+  bool contains(String path) {
+    return root.contains(path);
+  }
+
+  /// Return `true` if the [path] is in the `lib` folder of this package.
+  bool containsInLib(String path) {
+    return lib.contains(path);
+  }
+
+  /// Return the direct child folder of the root, that contains the [path].
+  ///
+  /// So, we can know if the [path] is in `lib/`, or `test/`, or `bin/`.
+  Folder folderInRootContaining(String path) {
+    try {
+      var children = root.getChildren();
+      for (var folder in children) {
+        if (folder is Folder && folder.contains(path)) {
+          return folder;
+        }
+      }
+    } on FileSystemException {}
+    return null;
+  }
+}
+
+class _Part {
+  final Uri uri;
+
+  _File file;
+
+  _Part(this.uri);
+}
+
+/// Normal and dev dependencies specified in a `pubspec.yaml` file.
+class _PubspecDependencies {
+  final List<String> lib;
+  final List<String> dev;
+
+  _PubspecDependencies(this.lib, this.dev);
+}
+
+class _ScheduledFile {
+  final DeclarationsContext context;
+  final String path;
+
+  _ScheduledFile(this.context, this.path);
+}
+
+/// Wrapper for a [StreamController] and its unique [Stream] instance.
+class _StreamController<T> {
+  final StreamController<T> controller = StreamController<T>();
+  Stream<T> stream;
+
+  _StreamController() {
+    stream = controller.stream;
+  }
+
+  void add(T event) {
+    controller.add(event);
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 3c8019c..7f866ae 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -14,6 +14,22 @@
 
 import 'idl.dart' as idl;
 
+class _AvailableDeclarationKindReader
+    extends fb.Reader<idl.AvailableDeclarationKind> {
+  const _AvailableDeclarationKindReader() : super();
+
+  @override
+  int get size => 1;
+
+  @override
+  idl.AvailableDeclarationKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
+    return index < idl.AvailableDeclarationKind.values.length
+        ? idl.AvailableDeclarationKind.values[index]
+        : idl.AvailableDeclarationKind.CLASS;
+  }
+}
+
 class _EntityRefKindReader extends fb.Reader<idl.EntityRefKind> {
   const _EntityRefKindReader() : super();
 
@@ -2095,6 +2111,1111 @@
   String toString() => convert.json.encode(toJson());
 }
 
+class AvailableDeclarationBuilder extends Object
+    with _AvailableDeclarationMixin
+    implements idl.AvailableDeclaration {
+  String _docComplete;
+  String _docSummary;
+  int _fieldMask;
+  idl.AvailableDeclarationKind _kind;
+  bool _isAbstract;
+  bool _isConst;
+  bool _isDeprecated;
+  bool _isFinal;
+  String _name;
+  String _name2;
+  int _locationOffset;
+  int _locationStartColumn;
+  int _locationStartLine;
+  List<String> _parameterNames;
+  String _parameters;
+  List<String> _parameterTypes;
+  int _requiredParameterCount;
+  List<String> _relevanceTags;
+  String _returnType;
+  String _typeParameters;
+
+  @override
+  String get docComplete => _docComplete ??= '';
+
+  void set docComplete(String value) {
+    this._docComplete = value;
+  }
+
+  @override
+  String get docSummary => _docSummary ??= '';
+
+  void set docSummary(String value) {
+    this._docSummary = value;
+  }
+
+  @override
+  int get fieldMask => _fieldMask ??= 0;
+
+  void set fieldMask(int value) {
+    assert(value == null || value >= 0);
+    this._fieldMask = value;
+  }
+
+  @override
+  idl.AvailableDeclarationKind get kind =>
+      _kind ??= idl.AvailableDeclarationKind.CLASS;
+
+  /// The kind of the declaration.
+  void set kind(idl.AvailableDeclarationKind value) {
+    this._kind = value;
+  }
+
+  @override
+  bool get isAbstract => _isAbstract ??= false;
+
+  void set isAbstract(bool value) {
+    this._isAbstract = value;
+  }
+
+  @override
+  bool get isConst => _isConst ??= false;
+
+  void set isConst(bool value) {
+    this._isConst = value;
+  }
+
+  @override
+  bool get isDeprecated => _isDeprecated ??= false;
+
+  void set isDeprecated(bool value) {
+    this._isDeprecated = value;
+  }
+
+  @override
+  bool get isFinal => _isFinal ??= false;
+
+  void set isFinal(bool value) {
+    this._isFinal = value;
+  }
+
+  @override
+  String get name => _name ??= '';
+
+  /// The first part of the declaration name, usually the only one, for example
+  /// the name of a class like `MyClass`, or a function like `myFunction`.
+  void set name(String value) {
+    this._name = value;
+  }
+
+  @override
+  String get name2 => _name2 ??= '';
+
+  /// The second, optional, part of the declaration name.  For example enum
+  /// constants all have the same [name], but their own [name2].
+  void set name2(String value) {
+    this._name2 = value;
+  }
+
+  @override
+  int get locationOffset => _locationOffset ??= 0;
+
+  void set locationOffset(int value) {
+    assert(value == null || value >= 0);
+    this._locationOffset = value;
+  }
+
+  @override
+  int get locationStartColumn => _locationStartColumn ??= 0;
+
+  void set locationStartColumn(int value) {
+    assert(value == null || value >= 0);
+    this._locationStartColumn = value;
+  }
+
+  @override
+  int get locationStartLine => _locationStartLine ??= 0;
+
+  void set locationStartLine(int value) {
+    assert(value == null || value >= 0);
+    this._locationStartLine = value;
+  }
+
+  @override
+  List<String> get parameterNames => _parameterNames ??= <String>[];
+
+  void set parameterNames(List<String> value) {
+    this._parameterNames = value;
+  }
+
+  @override
+  String get parameters => _parameters ??= '';
+
+  void set parameters(String value) {
+    this._parameters = value;
+  }
+
+  @override
+  List<String> get parameterTypes => _parameterTypes ??= <String>[];
+
+  void set parameterTypes(List<String> value) {
+    this._parameterTypes = value;
+  }
+
+  @override
+  int get requiredParameterCount => _requiredParameterCount ??= 0;
+
+  void set requiredParameterCount(int value) {
+    assert(value == null || value >= 0);
+    this._requiredParameterCount = value;
+  }
+
+  @override
+  List<String> get relevanceTags => _relevanceTags ??= <String>[];
+
+  /// The partial list of relevance tags.  Not every declaration has one (for
+  /// example, function do not currently), and not every declaration has to
+  /// store one (for classes it can be computed when we know the library that
+  /// includes this file).
+  void set relevanceTags(List<String> value) {
+    this._relevanceTags = value;
+  }
+
+  @override
+  String get returnType => _returnType ??= '';
+
+  void set returnType(String value) {
+    this._returnType = value;
+  }
+
+  @override
+  String get typeParameters => _typeParameters ??= '';
+
+  void set typeParameters(String value) {
+    this._typeParameters = value;
+  }
+
+  AvailableDeclarationBuilder(
+      {String docComplete,
+      String docSummary,
+      int fieldMask,
+      idl.AvailableDeclarationKind kind,
+      bool isAbstract,
+      bool isConst,
+      bool isDeprecated,
+      bool isFinal,
+      String name,
+      String name2,
+      int locationOffset,
+      int locationStartColumn,
+      int locationStartLine,
+      List<String> parameterNames,
+      String parameters,
+      List<String> parameterTypes,
+      int requiredParameterCount,
+      List<String> relevanceTags,
+      String returnType,
+      String typeParameters})
+      : _docComplete = docComplete,
+        _docSummary = docSummary,
+        _fieldMask = fieldMask,
+        _kind = kind,
+        _isAbstract = isAbstract,
+        _isConst = isConst,
+        _isDeprecated = isDeprecated,
+        _isFinal = isFinal,
+        _name = name,
+        _name2 = name2,
+        _locationOffset = locationOffset,
+        _locationStartColumn = locationStartColumn,
+        _locationStartLine = locationStartLine,
+        _parameterNames = parameterNames,
+        _parameters = parameters,
+        _parameterTypes = parameterTypes,
+        _requiredParameterCount = requiredParameterCount,
+        _relevanceTags = relevanceTags,
+        _returnType = returnType,
+        _typeParameters = typeParameters;
+
+  /**
+   * Flush [informative] data recursively.
+   */
+  void flushInformative() {}
+
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._docComplete ?? '');
+    signature.addString(this._docSummary ?? '');
+    signature.addInt(this._fieldMask ?? 0);
+    signature.addInt(this._kind == null ? 0 : this._kind.index);
+    signature.addBool(this._isAbstract == true);
+    signature.addBool(this._isConst == true);
+    signature.addBool(this._isDeprecated == true);
+    signature.addBool(this._isFinal == true);
+    signature.addString(this._name ?? '');
+    signature.addString(this._name2 ?? '');
+    signature.addInt(this._locationOffset ?? 0);
+    signature.addInt(this._locationStartColumn ?? 0);
+    signature.addInt(this._locationStartLine ?? 0);
+    if (this._parameterNames == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parameterNames.length);
+      for (var x in this._parameterNames) {
+        signature.addString(x);
+      }
+    }
+    signature.addString(this._parameters ?? '');
+    if (this._parameterTypes == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parameterTypes.length);
+      for (var x in this._parameterTypes) {
+        signature.addString(x);
+      }
+    }
+    signature.addInt(this._requiredParameterCount ?? 0);
+    if (this._relevanceTags == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._relevanceTags.length);
+      for (var x in this._relevanceTags) {
+        signature.addString(x);
+      }
+    }
+    signature.addString(this._returnType ?? '');
+    signature.addString(this._typeParameters ?? '');
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_docComplete;
+    fb.Offset offset_docSummary;
+    fb.Offset offset_name;
+    fb.Offset offset_name2;
+    fb.Offset offset_parameterNames;
+    fb.Offset offset_parameters;
+    fb.Offset offset_parameterTypes;
+    fb.Offset offset_relevanceTags;
+    fb.Offset offset_returnType;
+    fb.Offset offset_typeParameters;
+    if (_docComplete != null) {
+      offset_docComplete = fbBuilder.writeString(_docComplete);
+    }
+    if (_docSummary != null) {
+      offset_docSummary = fbBuilder.writeString(_docSummary);
+    }
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    if (_name2 != null) {
+      offset_name2 = fbBuilder.writeString(_name2);
+    }
+    if (!(_parameterNames == null || _parameterNames.isEmpty)) {
+      offset_parameterNames = fbBuilder.writeList(
+          _parameterNames.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (_parameters != null) {
+      offset_parameters = fbBuilder.writeString(_parameters);
+    }
+    if (!(_parameterTypes == null || _parameterTypes.isEmpty)) {
+      offset_parameterTypes = fbBuilder.writeList(
+          _parameterTypes.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_relevanceTags == null || _relevanceTags.isEmpty)) {
+      offset_relevanceTags = fbBuilder.writeList(
+          _relevanceTags.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (_returnType != null) {
+      offset_returnType = fbBuilder.writeString(_returnType);
+    }
+    if (_typeParameters != null) {
+      offset_typeParameters = fbBuilder.writeString(_typeParameters);
+    }
+    fbBuilder.startTable();
+    if (offset_docComplete != null) {
+      fbBuilder.addOffset(0, offset_docComplete);
+    }
+    if (offset_docSummary != null) {
+      fbBuilder.addOffset(1, offset_docSummary);
+    }
+    if (_fieldMask != null && _fieldMask != 0) {
+      fbBuilder.addUint32(2, _fieldMask);
+    }
+    if (_kind != null && _kind != idl.AvailableDeclarationKind.CLASS) {
+      fbBuilder.addUint8(3, _kind.index);
+    }
+    if (_isAbstract == true) {
+      fbBuilder.addBool(4, true);
+    }
+    if (_isConst == true) {
+      fbBuilder.addBool(5, true);
+    }
+    if (_isDeprecated == true) {
+      fbBuilder.addBool(6, true);
+    }
+    if (_isFinal == true) {
+      fbBuilder.addBool(7, true);
+    }
+    if (offset_name != null) {
+      fbBuilder.addOffset(8, offset_name);
+    }
+    if (offset_name2 != null) {
+      fbBuilder.addOffset(9, offset_name2);
+    }
+    if (_locationOffset != null && _locationOffset != 0) {
+      fbBuilder.addUint32(10, _locationOffset);
+    }
+    if (_locationStartColumn != null && _locationStartColumn != 0) {
+      fbBuilder.addUint32(11, _locationStartColumn);
+    }
+    if (_locationStartLine != null && _locationStartLine != 0) {
+      fbBuilder.addUint32(12, _locationStartLine);
+    }
+    if (offset_parameterNames != null) {
+      fbBuilder.addOffset(13, offset_parameterNames);
+    }
+    if (offset_parameters != null) {
+      fbBuilder.addOffset(14, offset_parameters);
+    }
+    if (offset_parameterTypes != null) {
+      fbBuilder.addOffset(15, offset_parameterTypes);
+    }
+    if (_requiredParameterCount != null && _requiredParameterCount != 0) {
+      fbBuilder.addUint32(16, _requiredParameterCount);
+    }
+    if (offset_relevanceTags != null) {
+      fbBuilder.addOffset(17, offset_relevanceTags);
+    }
+    if (offset_returnType != null) {
+      fbBuilder.addOffset(18, offset_returnType);
+    }
+    if (offset_typeParameters != null) {
+      fbBuilder.addOffset(19, offset_typeParameters);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _AvailableDeclarationReader
+    extends fb.TableReader<_AvailableDeclarationImpl> {
+  const _AvailableDeclarationReader();
+
+  @override
+  _AvailableDeclarationImpl createObject(fb.BufferContext bc, int offset) =>
+      new _AvailableDeclarationImpl(bc, offset);
+}
+
+class _AvailableDeclarationImpl extends Object
+    with _AvailableDeclarationMixin
+    implements idl.AvailableDeclaration {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _AvailableDeclarationImpl(this._bc, this._bcOffset);
+
+  String _docComplete;
+  String _docSummary;
+  int _fieldMask;
+  idl.AvailableDeclarationKind _kind;
+  bool _isAbstract;
+  bool _isConst;
+  bool _isDeprecated;
+  bool _isFinal;
+  String _name;
+  String _name2;
+  int _locationOffset;
+  int _locationStartColumn;
+  int _locationStartLine;
+  List<String> _parameterNames;
+  String _parameters;
+  List<String> _parameterTypes;
+  int _requiredParameterCount;
+  List<String> _relevanceTags;
+  String _returnType;
+  String _typeParameters;
+
+  @override
+  String get docComplete {
+    _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+    return _docComplete;
+  }
+
+  @override
+  String get docSummary {
+    _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
+    return _docSummary;
+  }
+
+  @override
+  int get fieldMask {
+    _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
+    return _fieldMask;
+  }
+
+  @override
+  idl.AvailableDeclarationKind get kind {
+    _kind ??= const _AvailableDeclarationKindReader()
+        .vTableGet(_bc, _bcOffset, 3, idl.AvailableDeclarationKind.CLASS);
+    return _kind;
+  }
+
+  @override
+  bool get isAbstract {
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 4, false);
+    return _isAbstract;
+  }
+
+  @override
+  bool get isConst {
+    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
+    return _isConst;
+  }
+
+  @override
+  bool get isDeprecated {
+    _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
+    return _isDeprecated;
+  }
+
+  @override
+  bool get isFinal {
+    _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false);
+    return _isFinal;
+  }
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 8, '');
+    return _name;
+  }
+
+  @override
+  String get name2 {
+    _name2 ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 9, '');
+    return _name2;
+  }
+
+  @override
+  int get locationOffset {
+    _locationOffset ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0);
+    return _locationOffset;
+  }
+
+  @override
+  int get locationStartColumn {
+    _locationStartColumn ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
+    return _locationStartColumn;
+  }
+
+  @override
+  int get locationStartLine {
+    _locationStartLine ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
+    return _locationStartLine;
+  }
+
+  @override
+  List<String> get parameterNames {
+    _parameterNames ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 13, const <String>[]);
+    return _parameterNames;
+  }
+
+  @override
+  String get parameters {
+    _parameters ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, '');
+    return _parameters;
+  }
+
+  @override
+  List<String> get parameterTypes {
+    _parameterTypes ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 15, const <String>[]);
+    return _parameterTypes;
+  }
+
+  @override
+  int get requiredParameterCount {
+    _requiredParameterCount ??=
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 16, 0);
+    return _requiredParameterCount;
+  }
+
+  @override
+  List<String> get relevanceTags {
+    _relevanceTags ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 17, const <String>[]);
+    return _relevanceTags;
+  }
+
+  @override
+  String get returnType {
+    _returnType ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 18, '');
+    return _returnType;
+  }
+
+  @override
+  String get typeParameters {
+    _typeParameters ??=
+        const fb.StringReader().vTableGet(_bc, _bcOffset, 19, '');
+    return _typeParameters;
+  }
+}
+
+abstract class _AvailableDeclarationMixin implements idl.AvailableDeclaration {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (docComplete != '') _result["docComplete"] = docComplete;
+    if (docSummary != '') _result["docSummary"] = docSummary;
+    if (fieldMask != 0) _result["fieldMask"] = fieldMask;
+    if (kind != idl.AvailableDeclarationKind.CLASS)
+      _result["kind"] = kind.toString().split('.')[1];
+    if (isAbstract != false) _result["isAbstract"] = isAbstract;
+    if (isConst != false) _result["isConst"] = isConst;
+    if (isDeprecated != false) _result["isDeprecated"] = isDeprecated;
+    if (isFinal != false) _result["isFinal"] = isFinal;
+    if (name != '') _result["name"] = name;
+    if (name2 != '') _result["name2"] = name2;
+    if (locationOffset != 0) _result["locationOffset"] = locationOffset;
+    if (locationStartColumn != 0)
+      _result["locationStartColumn"] = locationStartColumn;
+    if (locationStartLine != 0)
+      _result["locationStartLine"] = locationStartLine;
+    if (parameterNames.isNotEmpty) _result["parameterNames"] = parameterNames;
+    if (parameters != '') _result["parameters"] = parameters;
+    if (parameterTypes.isNotEmpty) _result["parameterTypes"] = parameterTypes;
+    if (requiredParameterCount != 0)
+      _result["requiredParameterCount"] = requiredParameterCount;
+    if (relevanceTags.isNotEmpty) _result["relevanceTags"] = relevanceTags;
+    if (returnType != '') _result["returnType"] = returnType;
+    if (typeParameters != '') _result["typeParameters"] = typeParameters;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "docComplete": docComplete,
+        "docSummary": docSummary,
+        "fieldMask": fieldMask,
+        "kind": kind,
+        "isAbstract": isAbstract,
+        "isConst": isConst,
+        "isDeprecated": isDeprecated,
+        "isFinal": isFinal,
+        "name": name,
+        "name2": name2,
+        "locationOffset": locationOffset,
+        "locationStartColumn": locationStartColumn,
+        "locationStartLine": locationStartLine,
+        "parameterNames": parameterNames,
+        "parameters": parameters,
+        "parameterTypes": parameterTypes,
+        "requiredParameterCount": requiredParameterCount,
+        "relevanceTags": relevanceTags,
+        "returnType": returnType,
+        "typeParameters": typeParameters,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
+class AvailableFileBuilder extends Object
+    with _AvailableFileMixin
+    implements idl.AvailableFile {
+  List<AvailableDeclarationBuilder> _declarations;
+  List<AvailableFileExportBuilder> _exports;
+  bool _isLibrary;
+  bool _isLibraryDeprecated;
+  List<String> _parts;
+
+  @override
+  List<AvailableDeclarationBuilder> get declarations =>
+      _declarations ??= <AvailableDeclarationBuilder>[];
+
+  /// Declarations of the file.
+  void set declarations(List<AvailableDeclarationBuilder> value) {
+    this._declarations = value;
+  }
+
+  @override
+  List<AvailableFileExportBuilder> get exports =>
+      _exports ??= <AvailableFileExportBuilder>[];
+
+  /// Exports directives of the file.
+  void set exports(List<AvailableFileExportBuilder> value) {
+    this._exports = value;
+  }
+
+  @override
+  bool get isLibrary => _isLibrary ??= false;
+
+  /// Is `true` if this file is a library.
+  void set isLibrary(bool value) {
+    this._isLibrary = value;
+  }
+
+  @override
+  bool get isLibraryDeprecated => _isLibraryDeprecated ??= false;
+
+  /// Is `true` if this file is a library, and it is deprecated.
+  void set isLibraryDeprecated(bool value) {
+    this._isLibraryDeprecated = value;
+  }
+
+  @override
+  List<String> get parts => _parts ??= <String>[];
+
+  /// URIs of `part` directives.
+  void set parts(List<String> value) {
+    this._parts = value;
+  }
+
+  AvailableFileBuilder(
+      {List<AvailableDeclarationBuilder> declarations,
+      List<AvailableFileExportBuilder> exports,
+      bool isLibrary,
+      bool isLibraryDeprecated,
+      List<String> parts})
+      : _declarations = declarations,
+        _exports = exports,
+        _isLibrary = isLibrary,
+        _isLibraryDeprecated = isLibraryDeprecated,
+        _parts = parts;
+
+  /**
+   * Flush [informative] data recursively.
+   */
+  void flushInformative() {
+    _declarations?.forEach((b) => b.flushInformative());
+    _exports?.forEach((b) => b.flushInformative());
+  }
+
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._declarations == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._declarations.length);
+      for (var x in this._declarations) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    if (this._exports == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._exports.length);
+      for (var x in this._exports) {
+        x?.collectApiSignature(signature);
+      }
+    }
+    signature.addBool(this._isLibrary == true);
+    signature.addBool(this._isLibraryDeprecated == true);
+    if (this._parts == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._parts.length);
+      for (var x in this._parts) {
+        signature.addString(x);
+      }
+    }
+  }
+
+  List<int> toBuffer() {
+    fb.Builder fbBuilder = new fb.Builder();
+    return fbBuilder.finish(finish(fbBuilder), "UICF");
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_declarations;
+    fb.Offset offset_exports;
+    fb.Offset offset_parts;
+    if (!(_declarations == null || _declarations.isEmpty)) {
+      offset_declarations = fbBuilder
+          .writeList(_declarations.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_exports == null || _exports.isEmpty)) {
+      offset_exports = fbBuilder
+          .writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (!(_parts == null || _parts.isEmpty)) {
+      offset_parts = fbBuilder
+          .writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_declarations != null) {
+      fbBuilder.addOffset(0, offset_declarations);
+    }
+    if (offset_exports != null) {
+      fbBuilder.addOffset(1, offset_exports);
+    }
+    if (_isLibrary == true) {
+      fbBuilder.addBool(2, true);
+    }
+    if (_isLibraryDeprecated == true) {
+      fbBuilder.addBool(3, true);
+    }
+    if (offset_parts != null) {
+      fbBuilder.addOffset(4, offset_parts);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+idl.AvailableFile readAvailableFile(List<int> buffer) {
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _AvailableFileReader().read(rootRef, 0);
+}
+
+class _AvailableFileReader extends fb.TableReader<_AvailableFileImpl> {
+  const _AvailableFileReader();
+
+  @override
+  _AvailableFileImpl createObject(fb.BufferContext bc, int offset) =>
+      new _AvailableFileImpl(bc, offset);
+}
+
+class _AvailableFileImpl extends Object
+    with _AvailableFileMixin
+    implements idl.AvailableFile {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _AvailableFileImpl(this._bc, this._bcOffset);
+
+  List<idl.AvailableDeclaration> _declarations;
+  List<idl.AvailableFileExport> _exports;
+  bool _isLibrary;
+  bool _isLibraryDeprecated;
+  List<String> _parts;
+
+  @override
+  List<idl.AvailableDeclaration> get declarations {
+    _declarations ??= const fb.ListReader<idl.AvailableDeclaration>(
+            const _AvailableDeclarationReader())
+        .vTableGet(_bc, _bcOffset, 0, const <idl.AvailableDeclaration>[]);
+    return _declarations;
+  }
+
+  @override
+  List<idl.AvailableFileExport> get exports {
+    _exports ??= const fb.ListReader<idl.AvailableFileExport>(
+            const _AvailableFileExportReader())
+        .vTableGet(_bc, _bcOffset, 1, const <idl.AvailableFileExport>[]);
+    return _exports;
+  }
+
+  @override
+  bool get isLibrary {
+    _isLibrary ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
+    return _isLibrary;
+  }
+
+  @override
+  bool get isLibraryDeprecated {
+    _isLibraryDeprecated ??=
+        const fb.BoolReader().vTableGet(_bc, _bcOffset, 3, false);
+    return _isLibraryDeprecated;
+  }
+
+  @override
+  List<String> get parts {
+    _parts ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 4, const <String>[]);
+    return _parts;
+  }
+}
+
+abstract class _AvailableFileMixin implements idl.AvailableFile {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (declarations.isNotEmpty)
+      _result["declarations"] =
+          declarations.map((_value) => _value.toJson()).toList();
+    if (exports.isNotEmpty)
+      _result["exports"] = exports.map((_value) => _value.toJson()).toList();
+    if (isLibrary != false) _result["isLibrary"] = isLibrary;
+    if (isLibraryDeprecated != false)
+      _result["isLibraryDeprecated"] = isLibraryDeprecated;
+    if (parts.isNotEmpty) _result["parts"] = parts;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "declarations": declarations,
+        "exports": exports,
+        "isLibrary": isLibrary,
+        "isLibraryDeprecated": isLibraryDeprecated,
+        "parts": parts,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
+class AvailableFileExportBuilder extends Object
+    with _AvailableFileExportMixin
+    implements idl.AvailableFileExport {
+  List<AvailableFileExportCombinatorBuilder> _combinators;
+  String _uri;
+
+  @override
+  List<AvailableFileExportCombinatorBuilder> get combinators =>
+      _combinators ??= <AvailableFileExportCombinatorBuilder>[];
+
+  /// Combinators contained in this export directive.
+  void set combinators(List<AvailableFileExportCombinatorBuilder> value) {
+    this._combinators = value;
+  }
+
+  @override
+  String get uri => _uri ??= '';
+
+  /// URI of the exported library.
+  void set uri(String value) {
+    this._uri = value;
+  }
+
+  AvailableFileExportBuilder(
+      {List<AvailableFileExportCombinatorBuilder> combinators, String uri})
+      : _combinators = combinators,
+        _uri = uri;
+
+  /**
+   * Flush [informative] data recursively.
+   */
+  void flushInformative() {
+    _combinators?.forEach((b) => b.flushInformative());
+  }
+
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    signature.addString(this._uri ?? '');
+    if (this._combinators == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._combinators.length);
+      for (var x in this._combinators) {
+        x?.collectApiSignature(signature);
+      }
+    }
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_combinators;
+    fb.Offset offset_uri;
+    if (!(_combinators == null || _combinators.isEmpty)) {
+      offset_combinators = fbBuilder
+          .writeList(_combinators.map((b) => b.finish(fbBuilder)).toList());
+    }
+    if (_uri != null) {
+      offset_uri = fbBuilder.writeString(_uri);
+    }
+    fbBuilder.startTable();
+    if (offset_combinators != null) {
+      fbBuilder.addOffset(1, offset_combinators);
+    }
+    if (offset_uri != null) {
+      fbBuilder.addOffset(0, offset_uri);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _AvailableFileExportReader
+    extends fb.TableReader<_AvailableFileExportImpl> {
+  const _AvailableFileExportReader();
+
+  @override
+  _AvailableFileExportImpl createObject(fb.BufferContext bc, int offset) =>
+      new _AvailableFileExportImpl(bc, offset);
+}
+
+class _AvailableFileExportImpl extends Object
+    with _AvailableFileExportMixin
+    implements idl.AvailableFileExport {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _AvailableFileExportImpl(this._bc, this._bcOffset);
+
+  List<idl.AvailableFileExportCombinator> _combinators;
+  String _uri;
+
+  @override
+  List<idl.AvailableFileExportCombinator> get combinators {
+    _combinators ??= const fb.ListReader<idl.AvailableFileExportCombinator>(
+            const _AvailableFileExportCombinatorReader())
+        .vTableGet(
+            _bc, _bcOffset, 1, const <idl.AvailableFileExportCombinator>[]);
+    return _combinators;
+  }
+
+  @override
+  String get uri {
+    _uri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+    return _uri;
+  }
+}
+
+abstract class _AvailableFileExportMixin implements idl.AvailableFileExport {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (combinators.isNotEmpty)
+      _result["combinators"] =
+          combinators.map((_value) => _value.toJson()).toList();
+    if (uri != '') _result["uri"] = uri;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "combinators": combinators,
+        "uri": uri,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
+class AvailableFileExportCombinatorBuilder extends Object
+    with _AvailableFileExportCombinatorMixin
+    implements idl.AvailableFileExportCombinator {
+  List<String> _hides;
+  List<String> _shows;
+
+  @override
+  List<String> get hides => _hides ??= <String>[];
+
+  /// List of names which are hidden.  Empty if this is a `show` combinator.
+  void set hides(List<String> value) {
+    this._hides = value;
+  }
+
+  @override
+  List<String> get shows => _shows ??= <String>[];
+
+  /// List of names which are shown.  Empty if this is a `hide` combinator.
+  void set shows(List<String> value) {
+    this._shows = value;
+  }
+
+  AvailableFileExportCombinatorBuilder({List<String> hides, List<String> shows})
+      : _hides = hides,
+        _shows = shows;
+
+  /**
+   * Flush [informative] data recursively.
+   */
+  void flushInformative() {}
+
+  /**
+   * Accumulate non-[informative] data into [signature].
+   */
+  void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._shows == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._shows.length);
+      for (var x in this._shows) {
+        signature.addString(x);
+      }
+    }
+    if (this._hides == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._hides.length);
+      for (var x in this._hides) {
+        signature.addString(x);
+      }
+    }
+  }
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_hides;
+    fb.Offset offset_shows;
+    if (!(_hides == null || _hides.isEmpty)) {
+      offset_hides = fbBuilder
+          .writeList(_hides.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_shows == null || _shows.isEmpty)) {
+      offset_shows = fbBuilder
+          .writeList(_shows.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_hides != null) {
+      fbBuilder.addOffset(1, offset_hides);
+    }
+    if (offset_shows != null) {
+      fbBuilder.addOffset(0, offset_shows);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _AvailableFileExportCombinatorReader
+    extends fb.TableReader<_AvailableFileExportCombinatorImpl> {
+  const _AvailableFileExportCombinatorReader();
+
+  @override
+  _AvailableFileExportCombinatorImpl createObject(
+          fb.BufferContext bc, int offset) =>
+      new _AvailableFileExportCombinatorImpl(bc, offset);
+}
+
+class _AvailableFileExportCombinatorImpl extends Object
+    with _AvailableFileExportCombinatorMixin
+    implements idl.AvailableFileExportCombinator {
+  final fb.BufferContext _bc;
+  final int _bcOffset;
+
+  _AvailableFileExportCombinatorImpl(this._bc, this._bcOffset);
+
+  List<String> _hides;
+  List<String> _shows;
+
+  @override
+  List<String> get hides {
+    _hides ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 1, const <String>[]);
+    return _hides;
+  }
+
+  @override
+  List<String> get shows {
+    _shows ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 0, const <String>[]);
+    return _shows;
+  }
+}
+
+abstract class _AvailableFileExportCombinatorMixin
+    implements idl.AvailableFileExportCombinator {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (hides.isNotEmpty) _result["hides"] = hides;
+    if (shows.isNotEmpty) _result["shows"] = shows;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+        "hides": hides,
+        "shows": shows,
+      };
+
+  @override
+  String toString() => convert.json.encode(toJson());
+}
+
 class CodeRangeBuilder extends Object
     with _CodeRangeMixin
     implements idl.CodeRange {
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 5d328ce..640b861 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -6,6 +6,29 @@
 // To regenerate the file, use the script "pkg/analyzer/tool/generate_files".
 
 
+/// Enum of declaration kinds in available files.
+enum AvailableDeclarationKind : byte {
+  CLASS,
+
+  CLASS_TYPE_ALIAS,
+
+  ENUM,
+
+  ENUM_CONSTANT,
+
+  FUNCTION,
+
+  FUNCTION_TYPE_ALIAS,
+
+  GETTER,
+
+  MIXIN,
+
+  SETTER,
+
+  VARIABLE
+}
+
 /// Enum used to indicate the kind of an entity reference.
 enum EntityRefKind : byte {
   /// The entity represents a named type.
@@ -845,6 +868,94 @@
   unit:UnlinkedUnit (id: 1);
 }
 
+/// Information about a single declaration.
+table AvailableDeclaration {
+  docComplete:string (id: 0);
+
+  docSummary:string (id: 1);
+
+  fieldMask:uint (id: 2);
+
+  /// The kind of the declaration.
+  kind:AvailableDeclarationKind (id: 3);
+
+  isAbstract:bool (id: 4);
+
+  isConst:bool (id: 5);
+
+  isDeprecated:bool (id: 6);
+
+  isFinal:bool (id: 7);
+
+  /// The first part of the declaration name, usually the only one, for example
+  /// the name of a class like `MyClass`, or a function like `myFunction`.
+  name:string (id: 8);
+
+  /// The second, optional, part of the declaration name.  For example enum
+  /// constants all have the same [name], but their own [name2].
+  name2:string (id: 9);
+
+  locationOffset:uint (id: 10);
+
+  locationStartColumn:uint (id: 11);
+
+  locationStartLine:uint (id: 12);
+
+  parameterNames:[string] (id: 13);
+
+  parameters:string (id: 14);
+
+  parameterTypes:[string] (id: 15);
+
+  requiredParameterCount:uint (id: 16);
+
+  /// The partial list of relevance tags.  Not every declaration has one (for
+  /// example, function do not currently), and not every declaration has to
+  /// store one (for classes it can be computed when we know the library that
+  /// includes this file).
+  relevanceTags:[string] (id: 17);
+
+  returnType:string (id: 18);
+
+  typeParameters:string (id: 19);
+}
+
+/// Information about an available, even if not yet imported file.
+table AvailableFile {
+  /// Declarations of the file.
+  declarations:[AvailableDeclaration] (id: 0);
+
+  /// Exports directives of the file.
+  exports:[AvailableFileExport] (id: 1);
+
+  /// Is `true` if this file is a library.
+  isLibrary:bool (id: 2);
+
+  /// Is `true` if this file is a library, and it is deprecated.
+  isLibraryDeprecated:bool (id: 3);
+
+  /// URIs of `part` directives.
+  parts:[string] (id: 4);
+}
+
+/// Information about an export directive.
+table AvailableFileExport {
+  /// Combinators contained in this export directive.
+  combinators:[AvailableFileExportCombinator] (id: 1);
+
+  /// URI of the exported library.
+  uri:string (id: 0);
+}
+
+/// Information about a `show` or `hide` combinator in an export directive.
+table AvailableFileExportCombinator {
+  /// List of names which are hidden.  Empty if this is a `show` combinator.
+  hides:[string] (id: 1);
+
+  /// List of names which are shown.  Empty if this is a `hide` combinator.
+  shows:[string] (id: 0);
+}
+
 /// Information about an element code range.
 table CodeRange {
   /// Length of the element code.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index d3dff59..6e3a1d8 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -283,6 +283,141 @@
   UnlinkedUnit get unit;
 }
 
+/// Information about a single declaration.
+abstract class AvailableDeclaration extends base.SummaryClass {
+  @Id(0)
+  String get docComplete;
+
+  @Id(1)
+  String get docSummary;
+
+  @Id(2)
+  int get fieldMask;
+
+  /// The kind of the declaration.
+  @Id(3)
+  AvailableDeclarationKind get kind;
+
+  @Id(4)
+  bool get isAbstract;
+
+  @Id(5)
+  bool get isConst;
+
+  @Id(6)
+  bool get isDeprecated;
+
+  @Id(7)
+  bool get isFinal;
+
+  /// The first part of the declaration name, usually the only one, for example
+  /// the name of a class like `MyClass`, or a function like `myFunction`.
+  @Id(8)
+  String get name;
+
+  /// The second, optional, part of the declaration name.  For example enum
+  /// constants all have the same [name], but their own [name2].
+  @Id(9)
+  String get name2;
+
+  @Id(10)
+  int get locationOffset;
+
+  @Id(11)
+  int get locationStartColumn;
+
+  @Id(12)
+  int get locationStartLine;
+
+  @Id(13)
+  List<String> get parameterNames;
+
+  @Id(14)
+  String get parameters;
+
+  @Id(15)
+  List<String> get parameterTypes;
+
+  @Id(16)
+  int get requiredParameterCount;
+
+  /// The partial list of relevance tags.  Not every declaration has one (for
+  /// example, function do not currently), and not every declaration has to
+  /// store one (for classes it can be computed when we know the library that
+  /// includes this file).
+  @Id(17)
+  List<String> get relevanceTags;
+
+  @Id(18)
+  String get returnType;
+
+  @Id(19)
+  String get typeParameters;
+}
+
+/// Enum of declaration kinds in available files.
+enum AvailableDeclarationKind {
+  CLASS,
+  CLASS_TYPE_ALIAS,
+  ENUM,
+  ENUM_CONSTANT,
+  FUNCTION,
+  FUNCTION_TYPE_ALIAS,
+  GETTER,
+  MIXIN,
+  SETTER,
+  VARIABLE
+}
+
+/// Information about an available, even if not yet imported file.
+@TopLevel('UICF')
+abstract class AvailableFile extends base.SummaryClass {
+  factory AvailableFile.fromBuffer(List<int> buffer) =>
+      generated.readAvailableFile(buffer);
+
+  /// Declarations of the file.
+  @Id(0)
+  List<AvailableDeclaration> get declarations;
+
+  /// Exports directives of the file.
+  @Id(1)
+  List<AvailableFileExport> get exports;
+
+  /// Is `true` if this file is a library.
+  @Id(2)
+  bool get isLibrary;
+
+  /// Is `true` if this file is a library, and it is deprecated.
+  @Id(3)
+  bool get isLibraryDeprecated;
+
+  /// URIs of `part` directives.
+  @Id(4)
+  List<String> get parts;
+}
+
+/// Information about an export directive.
+abstract class AvailableFileExport extends base.SummaryClass {
+  /// Combinators contained in this export directive.
+  @Id(1)
+  List<AvailableFileExportCombinator> get combinators;
+
+  /// URI of the exported library.
+  @Id(0)
+  String get uri;
+}
+
+/// Information about a `show` or `hide` combinator in an export directive.
+abstract class AvailableFileExportCombinator extends base.SummaryClass {
+  /// List of names which are hidden.  Empty if this is a `show` combinator.
+  @Id(1)
+  List<String> get hides;
+
+  /// List of names which are shown.  Empty if this is a `hide` combinator.
+  @Id(0)
+  List<String> get shows;
+}
+
 /// Information about an element code range.
 abstract class CodeRange extends base.SummaryClass {
   /// Length of the element code.
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index df89a01..1f05586 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -817,7 +817,7 @@
     } else if (node.isNamed) {
       b.kind = UnlinkedParamKind.named;
     } else {
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       throw new StateError('Unexpected parameter kind: ${node.kind}');
     }
     return b;
diff --git a/pkg/analyzer/lib/src/task/api/dart.dart b/pkg/analyzer/lib/src/task/api/dart.dart
index d8f28ff..f1f19e6 100644
--- a/pkg/analyzer/lib/src/task/api/dart.dart
+++ b/pkg/analyzer/lib/src/task/api/dart.dart
@@ -140,10 +140,6 @@
  * change if a single part is included in more than one library.
  */
 class LibrarySpecificUnit implements AnalysisTarget {
-  @deprecated
-  static const List<LibrarySpecificUnit> EMPTY_LIST =
-      const <LibrarySpecificUnit>[];
-
   /**
    * The defining compilation unit of the library in which the [unit]
    * is analyzed.
diff --git a/pkg/analyzer/lib/src/task/api/model.dart b/pkg/analyzer/lib/src/task/api/model.dart
index fbfadff..fe0edef 100644
--- a/pkg/analyzer/lib/src/task/api/model.dart
+++ b/pkg/analyzer/lib/src/task/api/model.dart
@@ -526,12 +526,6 @@
  */
 class TargetedResult {
   /**
-   * An empty list of results.
-   */
-  @deprecated
-  static final List<TargetedResult> EMPTY_LIST = const <TargetedResult>[];
-
-  /**
    * The target with which the result is associated.
    */
   final AnalysisTarget target;
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 81198ab..50e3992 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -2867,7 +2867,9 @@
 
     unit.accept(new BestPracticesVerifier(
         errorReporter, typeProvider, libraryElement,
-        typeSystem: typeSystem, resourceProvider: resourceProvider));
+        typeSystem: typeSystem,
+        resourceProvider: resourceProvider,
+        analysisOptions: context.analysisOptions));
     unit.accept(new OverrideVerifier(
       inheritanceManager2,
       libraryElement,
@@ -3432,7 +3434,6 @@
         visitor.prepareToResolveMembersInClass(
             resolutionContext.enclosingClassDeclaration);
       }
-      visitor.initForIncrementalResolution();
       initializer.accept(visitor);
       DartType newType = initializer.staticType;
       if (newType == null || newType.isBottom || newType.isDartCoreNull) {
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index 66eba45..c7f12e2 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -178,7 +178,7 @@
     }
     try {
       WorkItem workItem =
-          new WorkItem(context, target, taskDescriptor, result, 0, null);
+          new WorkItem._(context, target, taskDescriptor, result, 0, null);
       return new WorkOrder(taskManager, workItem);
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -645,8 +645,9 @@
    * Initialize a newly created work item to compute the inputs for the task
    * described by the given descriptor.
    */
-  WorkItem(this.context, this.target, this.descriptor, this.spawningResult,
+  WorkItem._(this.context, this.target, this.descriptor, this.spawningResult,
       this.level, this.workOrder) {
+    _checkInternalUseOfTaskModel();
     AnalysisTarget actualTarget =
         identical(target, AnalysisContextTarget.request)
             ? new AnalysisContextTarget(context)
@@ -762,8 +763,8 @@
               // inputs.
               builder.currentValueNotAvailable();
             } else {
-              return new WorkItem(context, inputTarget, descriptor, inputResult,
-                  level + 1, workOrder);
+              return new WorkItem._(context, inputTarget, descriptor,
+                  inputResult, level + 1, workOrder);
             }
           } on AnalysisException catch (exception, stackTrace) {
             this.exception = new CaughtException(exception, stackTrace);
@@ -791,6 +792,13 @@
 
   @override
   String toString() => 'Run $descriptor on $target';
+
+  static void _checkInternalUseOfTaskModel() {
+    if (!StackTrace.current.toString().contains('/analyzer/test/')) {
+      throw new StateError(
+          'The analyzer task model is no longer supported.  Please use the AnalysisSession API.');
+    }
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index c72d99f..502db66 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -37,12 +37,6 @@
  */
 class DartScript implements Source {
   /**
-   * An empty list of scripts.
-   */
-  @deprecated
-  static final List<DartScript> EMPTY_LIST = const <DartScript>[];
-
-  /**
    * The source containing this script.
    */
   final Source source;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3583fb3..da18f90 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -164,6 +164,22 @@
   void checkBoolean(Expression expr) =>
       checkAssignment(expr, typeProvider.boolType);
 
+  void checkCollectionElement(
+      CollectionElement element, DartType expectedType) {
+    if (element is ForElement) {
+      checkCollectionElement(element.body, expectedType);
+    } else if (element is IfElement) {
+      checkCollectionElement(element.thenElement, expectedType);
+      checkCollectionElement(element.elseElement, expectedType);
+    } else if (element is Expression) {
+      checkAssignment(element, expectedType);
+    } else if (element is SpreadElement) {
+      DartType iterableType =
+          typeProvider.iterableType.instantiate([expectedType]);
+      checkAssignment(element.expression, iterableType);
+    }
+  }
+
   void checkForCast(Expression expr, DartType type) {
     if (expr is ParenthesizedExpression) {
       checkForCast(expr.expression, type);
@@ -172,6 +188,23 @@
     }
   }
 
+  void checkMapElement(CollectionElement element, DartType expectedKeyType,
+      DartType expectedValueType) {
+    if (element is ForElement) {
+      checkMapElement(element.body, expectedKeyType, expectedValueType);
+    } else if (element is IfElement) {
+      checkMapElement(element.thenElement, expectedKeyType, expectedValueType);
+      checkMapElement(element.elseElement, expectedKeyType, expectedValueType);
+    } else if (element is MapLiteralEntry) {
+      checkAssignment(element.key, expectedKeyType);
+      checkAssignment(element.value, expectedValueType);
+    } else if (element is SpreadElement) {
+      DartType mapType = typeProvider.mapType
+          .instantiate([expectedKeyType, expectedValueType]);
+      checkAssignment(element.expression, mapType);
+    }
+  }
+
   DartType getAnnotatedType(TypeAnnotation type) {
     return type?.type ?? DynamicTypeImpl.instance;
   }
@@ -344,6 +377,18 @@
   }
 
   @override
+  void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
+    _visitForEachParts(node, node.loopVariable?.identifier);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
+    _visitForEachParts(node, node.identifier);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitForEachStatement(ForEachStatement node) {
     var loopVariable = node.identifier ?? node.loopVariable?.identifier;
 
@@ -384,6 +429,22 @@
   }
 
   @override
+  void visitForPartsWithDeclarations(ForPartsWithDeclarations node) {
+    if (node.condition != null) {
+      checkBoolean(node.condition);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitForPartsWithExpression(ForPartsWithExpression node) {
+    if (node.condition != null) {
+      checkBoolean(node.condition);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
   void visitForStatement(ForStatement node) {
     if (node.condition != null) {
       checkBoolean(node.condition);
@@ -464,6 +525,30 @@
   }
 
   @override
+  void visitListLiteral2(ListLiteral2 node) {
+    DartType type = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      NodeList<TypeAnnotation> targs = node.typeArguments.arguments;
+      if (targs.length > 0) {
+        type = targs[0].type;
+      }
+    } else {
+      DartType staticType = node.staticType;
+      if (staticType is InterfaceType) {
+        List<DartType> targs = staticType.typeArguments;
+        if (targs != null && targs.length > 0) {
+          type = targs[0];
+        }
+      }
+    }
+    NodeList<CollectionElement> elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      checkCollectionElement(elements[i], type);
+    }
+    super.visitListLiteral2(node);
+  }
+
+  @override
   void visitMapLiteral(MapLiteral node) {
     DartType ktype = DynamicTypeImpl.instance;
     DartType vtype = DynamicTypeImpl.instance;
@@ -499,6 +584,39 @@
   }
 
   @override
+  void visitMapLiteral2(MapLiteral2 node) {
+    DartType keyType = DynamicTypeImpl.instance;
+    DartType valueType = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      NodeList<TypeAnnotation> typeArguments = node.typeArguments.arguments;
+      if (typeArguments.length > 0) {
+        keyType = typeArguments[0].type;
+      }
+      if (typeArguments.length > 1) {
+        valueType = typeArguments[1].type;
+      }
+    } else {
+      DartType staticType = node.staticType;
+      if (staticType is InterfaceType) {
+        List<DartType> typeArguments = staticType.typeArguments;
+        if (typeArguments != null) {
+          if (typeArguments.length > 0) {
+            keyType = typeArguments[0];
+          }
+          if (typeArguments.length > 1) {
+            valueType = typeArguments[1];
+          }
+        }
+      }
+    }
+    NodeList<CollectionElement> entries = node.entries;
+    for (int i = 0; i < entries.length; i++) {
+      checkMapElement(entries[i], keyType, valueType);
+    }
+    super.visitMapLiteral2(node);
+  }
+
+  @override
   visitMethodInvocation(MethodInvocation node) {
     var target = node.realTarget;
     var element = node.methodName.staticElement;
@@ -579,6 +697,54 @@
   }
 
   @override
+  void visitSetLiteral(SetLiteral node) {
+    DartType type = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      NodeList<TypeAnnotation> targs = node.typeArguments.arguments;
+      if (targs.length > 0) {
+        type = targs[0].type;
+      }
+    } else {
+      DartType staticType = node.staticType;
+      if (staticType is InterfaceType) {
+        List<DartType> typeArguments = staticType.typeArguments;
+        if (typeArguments != null && typeArguments.length > 0) {
+          type = typeArguments[0];
+        }
+      }
+    }
+    NodeList<Expression> elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      checkArgument(elements[i], type);
+    }
+    super.visitSetLiteral(node);
+  }
+
+  @override
+  void visitSetLiteral2(SetLiteral2 node) {
+    DartType type = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      NodeList<TypeAnnotation> targs = node.typeArguments.arguments;
+      if (targs.length > 0) {
+        type = targs[0].type;
+      }
+    } else {
+      DartType staticType = node.staticType;
+      if (staticType is InterfaceType) {
+        List<DartType> typeArguments = staticType.typeArguments;
+        if (typeArguments != null && typeArguments.length > 0) {
+          type = typeArguments[0];
+        }
+      }
+    }
+    NodeList<CollectionElement> elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      checkCollectionElement(elements[i], type);
+    }
+    super.visitSetLiteral2(node);
+  }
+
+  @override
   void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
     var element = node.staticElement;
     if (element != null) {
@@ -1212,6 +1378,51 @@
   void _validateTopLevelInitializer(String name, Expression n) {
     n.accept(new _TopLevelInitializerValidator(this, name));
   }
+
+  void _visitForEachParts(ForEachParts node, SimpleIdentifier loopVariable) {
+    // Safely handle malformed statements.
+    if (loopVariable == null) {
+      return;
+    }
+    Token awaitKeyword;
+    AstNode parent = node.parent;
+    if (parent is ForStatement2) {
+      awaitKeyword = parent.awaitKeyword;
+    } else if (parent is ForElement) {
+      awaitKeyword = parent.awaitKeyword;
+    } else {
+      throw new StateError(
+          'Unexpected parent of ForEachParts: ${parent.runtimeType}');
+    }
+    // Find the element type of the sequence.
+    var sequenceInterface = awaitKeyword != null
+        ? typeProvider.streamType
+        : typeProvider.iterableType;
+    var iterableType = _getExpressionType(node.iterable);
+    var elementType =
+        rules.mostSpecificTypeArgument(iterableType, sequenceInterface);
+
+    // If the sequence is not an Iterable (or Stream for await for) but is a
+    // supertype of it, do an implicit downcast to Iterable<dynamic>. Then
+    // we'll do a separate cast of the dynamic element to the variable's type.
+    if (elementType == null) {
+      var sequenceType =
+          sequenceInterface.instantiate([DynamicTypeImpl.instance]);
+
+      if (rules.isSubtypeOf(sequenceType, iterableType)) {
+        _recordImplicitCast(node.iterable, sequenceType, from: iterableType);
+        elementType = DynamicTypeImpl.instance;
+      }
+    }
+    // If the sequence doesn't implement the interface at all, [ErrorVerifier]
+    // will report the error, so ignore it here.
+    if (elementType != null) {
+      // Insert a cast from the sequence's element type to the loop variable's
+      // if needed.
+      _checkImplicitCast(loopVariable, _getExpressionType(loopVariable),
+          from: elementType);
+    }
+  }
 }
 
 /// Checks for overriding declarations of fields and methods. This is used to
@@ -1702,6 +1913,13 @@
   }
 
   @override
+  visitListLiteral2(ListLiteral2 node) {
+    if (node.typeArguments == null) {
+      super.visitListLiteral2(node);
+    }
+  }
+
+  @override
   visitMapLiteral(MapLiteral node) {
     if (node.typeArguments == null) {
       super.visitMapLiteral(node);
@@ -1709,6 +1927,13 @@
   }
 
   @override
+  visitMapLiteral2(MapLiteral2 node) {
+    if (node.typeArguments == null) {
+      super.visitMapLiteral2(node);
+    }
+  }
+
+  @override
   visitMethodInvocation(MethodInvocation node) {
     node.target?.accept(this);
     var method = node.methodName.staticElement;
@@ -1745,6 +1970,20 @@
   }
 
   @override
+  visitSetLiteral(SetLiteral node) {
+    if (node.typeArguments == null) {
+      super.visitSetLiteral(node);
+    }
+  }
+
+  @override
+  visitSetLiteral2(SetLiteral2 node) {
+    if (node.typeArguments == null) {
+      super.visitSetLiteral2(node);
+    }
+  }
+
+  @override
   visitSimpleIdentifier(SimpleIdentifier node) {
     validateIdentifierElement(node, node.staticElement);
   }
diff --git a/pkg/analyzer/lib/src/test_utilities/find_element.dart b/pkg/analyzer/lib/src/test_utilities/find_element.dart
new file mode 100644
index 0000000..86b3e1f
--- /dev/null
+++ b/pkg/analyzer/lib/src/test_utilities/find_element.dart
@@ -0,0 +1,501 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/test_utilities/function_ast_visitor.dart';
+
+/// Helper for finding elements declared in the resolved [unit].
+class FindElement {
+  final CompilationUnit unit;
+
+  FindElement(this.unit);
+
+  CompilationUnitElement get unitElement => unit.declaredElement;
+
+  ClassElement class_(String name) {
+    for (var class_ in unitElement.types) {
+      if (class_.name == name) {
+        return class_;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ClassElement classOrMixin(String name) {
+    for (var class_ in unitElement.types) {
+      if (class_.name == name) {
+        return class_;
+      }
+    }
+    for (var mixin in unitElement.mixins) {
+      if (mixin.name == name) {
+        return mixin;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ConstructorElement constructor(String name, {String of}) {
+    assert(name != '');
+    ConstructorElement result;
+    for (var class_ in unitElement.types) {
+      if (of == null || class_.name == of) {
+        for (var constructor in class_.constructors) {
+          if (constructor.name == name) {
+            if (result != null) {
+              throw StateError('Not unique: $name');
+            }
+            result = constructor;
+          }
+        }
+      }
+    }
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ClassElement enum_(String name) {
+    for (var enum_ in unitElement.enums) {
+      if (enum_.name == name) {
+        return enum_;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ExportElement export(String targetUri) {
+    ExportElement result;
+
+    for (var export in unitElement.library.exports) {
+      var exportedUri = export.exportedLibrary.source.uri.toString();
+      if (exportedUri == targetUri) {
+        if (result != null) {
+          throw StateError('Not unique: $targetUri');
+        }
+        result = export;
+      }
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $targetUri');
+  }
+
+  FieldElement field(String name, {String of}) {
+    FieldElement result;
+
+    void findIn(List<FieldElement> fields) {
+      for (var field in fields) {
+        if (field.name == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = field;
+        }
+      }
+    }
+
+    for (var enum_ in unitElement.enums) {
+      if (of != null && enum_.name != of) {
+        continue;
+      }
+      findIn(enum_.fields);
+    }
+
+    for (var class_ in unitElement.types) {
+      if (of != null && class_.name != of) {
+        continue;
+      }
+      findIn(class_.fields);
+    }
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.fields);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  FieldFormalParameterElement fieldFormalParameter(String name) {
+    return parameter(name) as FieldFormalParameterElement;
+  }
+
+  FunctionElement function(String name) {
+    for (var function in unitElement.functions) {
+      if (function.name == name) {
+        return function;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  GenericTypeAliasElement genericTypeAlias(String name) {
+    for (var element in unitElement.functionTypeAliases) {
+      if (element is GenericTypeAliasElement && element.name == name) {
+        return element;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  PropertyAccessorElement getter(String name, {String of}) {
+    PropertyAccessorElement result;
+
+    void findIn(List<PropertyAccessorElement> accessors) {
+      for (var accessor in accessors) {
+        if (accessor.isGetter && accessor.displayName == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = accessor;
+        }
+      }
+    }
+
+    for (var enum_ in unitElement.enums) {
+      if (of != null && enum_.name != of) {
+        continue;
+      }
+      findIn(enum_.accessors);
+    }
+
+    for (var class_ in unitElement.types) {
+      if (of != null && class_.name != of) {
+        continue;
+      }
+      findIn(class_.accessors);
+    }
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.accessors);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ImportElement import(String targetUri) {
+    ImportElement importElement;
+
+    for (var import in unitElement.library.imports) {
+      var importedUri = import.importedLibrary.source.uri.toString();
+      if (importedUri == targetUri) {
+        if (importElement != null) {
+          throw StateError('Not unique: $targetUri');
+        }
+        importElement = import;
+      }
+    }
+
+    if (importElement != null) {
+      return importElement;
+    }
+    throw StateError('Not found: $targetUri');
+  }
+
+  ImportFindElement importFind(String targetUri) {
+    var import = this.import(targetUri);
+    return ImportFindElement(import);
+  }
+
+  InterfaceType interfaceType(String name) {
+    return class_(name).type;
+  }
+
+  FunctionElement localFunction(String name) {
+    FunctionElement result;
+
+    unit.accept(new FunctionAstVisitor(
+      functionDeclarationStatement: (node) {
+        var element = node.functionDeclaration.declaredElement;
+        if (element is FunctionElement) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = element;
+        }
+      },
+    ));
+
+    if (result == null) {
+      throw StateError('Not found: $name');
+    }
+    return result;
+  }
+
+  LocalVariableElement localVar(String name) {
+    LocalVariableElement result;
+
+    unit.accept(new FunctionAstVisitor(
+      variableDeclaration: (node) {
+        var element = node.declaredElement;
+        if (element is LocalVariableElement && element.name == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = element;
+        }
+      },
+    ));
+
+    if (result == null) {
+      throw StateError('Not found: $name');
+    }
+    return result;
+  }
+
+  MethodElement method(String name, {String of}) {
+    MethodElement result;
+
+    void findIn(List<MethodElement> methods) {
+      for (var method in methods) {
+        if (method.name == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = method;
+        }
+      }
+    }
+
+    for (var class_ in unitElement.types) {
+      if (of != null && class_.name != of) {
+        continue;
+      }
+      findIn(class_.methods);
+    }
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.methods);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ClassElement mixin(String name) {
+    for (var mixin in unitElement.mixins) {
+      if (mixin.name == name) {
+        return mixin;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ParameterElement parameter(String name) {
+    ParameterElement result;
+
+    void findIn(List<ParameterElement> parameters) {
+      for (var parameter in parameters) {
+        if (parameter.name == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = parameter;
+        }
+      }
+    }
+
+    for (var accessor in unitElement.accessors) {
+      findIn(accessor.parameters);
+    }
+
+    for (var function in unitElement.functions) {
+      findIn(function.parameters);
+    }
+
+    for (var function in unitElement.functionTypeAliases) {
+      findIn(function.parameters);
+    }
+
+    for (var class_ in unitElement.types) {
+      for (var constructor in class_.constructors) {
+        findIn(constructor.parameters);
+      }
+      for (var method in class_.methods) {
+        findIn(method.parameters);
+      }
+      for (var accessor in class_.accessors) {
+        findIn(accessor.parameters);
+      }
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  PrefixElement prefix(String name) {
+    for (var import_ in unitElement.library.imports) {
+      var prefix = import_.prefix;
+      if (prefix?.name == name) {
+        return prefix;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  PropertyAccessorElement setter(String name, {String of}) {
+    PropertyAccessorElement result;
+
+    void findIn(List<PropertyAccessorElement> accessors) {
+      for (var accessor in accessors) {
+        if (accessor.isSetter && accessor.displayName == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = accessor;
+        }
+      }
+    }
+
+    for (var class_ in unitElement.types) {
+      if (of != null && class_.name != of) {
+        continue;
+      }
+      findIn(class_.accessors);
+    }
+
+    for (var mixin in unitElement.mixins) {
+      if (of != null && mixin.name != of) {
+        continue;
+      }
+      findIn(mixin.accessors);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  FunctionElement topFunction(String name) {
+    for (var function in unitElement.functions) {
+      if (function.name == name) {
+        return function;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  PropertyAccessorElement topGet(String name) {
+    return topVar(name).getter;
+  }
+
+  PropertyAccessorElement topSet(String name) {
+    return topVar(name).setter;
+  }
+
+  TopLevelVariableElement topVar(String name) {
+    for (var variable in unitElement.topLevelVariables) {
+      if (variable.name == name) {
+        return variable;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  TypeParameterElement typeParameter(String name) {
+    TypeParameterElement result;
+
+    void findIn(List<TypeParameterElement> typeParameters) {
+      for (var typeParameter in typeParameters) {
+        if (typeParameter.name == name) {
+          if (result != null) {
+            throw StateError('Not unique: $name');
+          }
+          result = typeParameter;
+        }
+      }
+    }
+
+    for (var type in unitElement.functionTypeAliases) {
+      findIn(type.typeParameters);
+      if (type is GenericTypeAliasElement) {
+        findIn(type.function.typeParameters);
+      }
+    }
+
+    for (var class_ in unitElement.types) {
+      findIn(class_.typeParameters);
+    }
+
+    for (var mixin in unitElement.mixins) {
+      findIn(mixin.typeParameters);
+    }
+
+    if (result != null) {
+      return result;
+    }
+    throw StateError('Not found: $name');
+  }
+
+  ConstructorElement unnamedConstructor(String name) {
+    return class_(name).unnamedConstructor;
+  }
+}
+
+/// Helper for searching imported elements.
+class ImportFindElement {
+  final ImportElement import;
+
+  ImportFindElement(this.import);
+
+  CompilationUnitElement get definingUnit {
+    return importedLibrary.definingCompilationUnit;
+  }
+
+  LibraryElement get importedLibrary => import.importedLibrary;
+
+  PrefixElement get prefix => import.prefix;
+
+  ClassElement class_(String name) {
+    for (var class_ in definingUnit.types) {
+      if (class_.name == name) {
+        return class_;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  FunctionElement topFunction(String name) {
+    for (var function in definingUnit.functions) {
+      if (function.name == name) {
+        return function;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+
+  PropertyAccessorElement topGetter(String name) {
+    for (var accessor in definingUnit.accessors) {
+      if (accessor.name == name && accessor.isGetter) {
+        return accessor;
+      }
+    }
+    throw StateError('Not found: $name');
+  }
+}
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
new file mode 100644
index 0000000..9bf696b
--- /dev/null
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -0,0 +1,285 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+
+class FindNode {
+  final String content;
+  final CompilationUnit unit;
+
+  FindNode(this.content, this.unit);
+
+  LibraryDirective get libraryDirective {
+    return unit.directives.singleWhere((d) => d is LibraryDirective);
+  }
+
+  Annotation annotation(String search) {
+    return _node(search, (n) => n is Annotation);
+  }
+
+  AstNode any(String search) {
+    return _node(search, (n) => true);
+  }
+
+  AssignmentExpression assignment(String search) {
+    return _node(search, (n) => n is AssignmentExpression);
+  }
+
+  BinaryExpression binary(String search) {
+    return _node(search, (n) => n is BinaryExpression);
+  }
+
+  Block block(String search) {
+    return _node(search, (n) => n is Block);
+  }
+
+  BreakStatement breakStatement(String search) {
+    return _node(search, (n) => n is BreakStatement);
+  }
+
+  CascadeExpression cascade(String search) {
+    return _node(search, (n) => n is CascadeExpression);
+  }
+
+  ClassDeclaration classDeclaration(String search) {
+    return _node(search, (n) => n is ClassDeclaration);
+  }
+
+  CommentReference commentReference(String search) {
+    return _node(search, (n) => n is CommentReference);
+  }
+
+  ConditionalExpression conditionalExpression(String search) {
+    return _node(search, (n) => n is ConditionalExpression);
+  }
+
+  ConstructorDeclaration constructor(String search) {
+    return _node(search, (n) => n is ConstructorDeclaration);
+  }
+
+  ConstructorFieldInitializer constructorFieldInitializer(String search) {
+    return _node(search, (n) => n is ConstructorFieldInitializer);
+  }
+
+  ContinueStatement continueStatement(String search) {
+    return _node(search, (n) => n is ContinueStatement);
+  }
+
+  DefaultFormalParameter defaultParameter(String search) {
+    return _node(search, (n) => n is DefaultFormalParameter);
+  }
+
+  DoStatement doStatement(String search) {
+    return _node(search, (n) => n is DoStatement);
+  }
+
+  ExportDirective export(String search) {
+    return _node(search, (n) => n is ExportDirective);
+  }
+
+  Expression expression(String search) {
+    return _node(search, (n) => n is Expression);
+  }
+
+  ExpressionStatement expressionStatement(String search) {
+    return _node(search, (n) => n is ExpressionStatement);
+  }
+
+  FieldFormalParameter fieldFormalParameter(String search) {
+    return _node(search, (n) => n is FieldFormalParameter);
+  }
+
+  ForEachStatement forEachStatement(String search) {
+    return _node(search, (n) => n is ForEachStatement);
+  }
+
+  ForStatement forStatement(String search) {
+    return _node(search, (n) => n is ForStatement);
+  }
+
+  FunctionBody functionBody(String search) {
+    return _node(search, (n) => n is FunctionBody);
+  }
+
+  FunctionDeclaration functionDeclaration(String search) {
+    return _node(search, (n) => n is FunctionDeclaration);
+  }
+
+  FunctionExpression functionExpression(String search) {
+    return _node(search, (n) => n is FunctionExpression);
+  }
+
+  FunctionTypeAlias functionTypeAlias(String search) {
+    return _node(search, (n) => n is FunctionTypeAlias);
+  }
+
+  GenericFunctionType genericFunctionType(String search) {
+    return _node(search, (n) => n is GenericFunctionType);
+  }
+
+  ImportDirective import(String search) {
+    return _node(search, (n) => n is ImportDirective);
+  }
+
+  IndexExpression index(String search) {
+    return _node(search, (n) => n is IndexExpression);
+  }
+
+  InstanceCreationExpression instanceCreation(String search) {
+    return _node(search, (n) => n is InstanceCreationExpression);
+  }
+
+  LibraryDirective library(String search) {
+    return _node(search, (n) => n is LibraryDirective);
+  }
+
+  ListLiteral listLiteral(String search) {
+    return _node(search, (n) => n is ListLiteral);
+  }
+
+  MapLiteral mapLiteral(String search) {
+    return _node(search, (n) => n is MapLiteral);
+  }
+
+  MethodDeclaration methodDeclaration(String search) {
+    return _node(search, (n) => n is MethodDeclaration);
+  }
+
+  MethodInvocation methodInvocation(String search) {
+    return _node(search, (n) => n is MethodInvocation);
+  }
+
+  MixinDeclaration mixin(String search) {
+    return _node(search, (n) => n is MixinDeclaration);
+  }
+
+  ParenthesizedExpression parenthesized(String search) {
+    return _node(search, (n) => n is ParenthesizedExpression);
+  }
+
+  PartDirective part(String search) {
+    return _node(search, (n) => n is PartDirective);
+  }
+
+  PartOfDirective partOf(String search) {
+    return _node(search, (n) => n is PartOfDirective);
+  }
+
+  PostfixExpression postfix(String search) {
+    return _node(search, (n) => n is PostfixExpression);
+  }
+
+  PrefixExpression prefix(String search) {
+    return _node(search, (n) => n is PrefixExpression);
+  }
+
+  PrefixedIdentifier prefixed(String search) {
+    return _node(search, (n) => n is PrefixedIdentifier);
+  }
+
+  PropertyAccess propertyAccess(String search) {
+    return _node(search, (n) => n is PropertyAccess);
+  }
+
+  RethrowExpression rethrow_(String search) {
+    return _node(search, (n) => n is RethrowExpression);
+  }
+
+  SetLiteral setLiteral(String search) {
+    return _node(search, (n) => n is SetLiteral);
+  }
+
+  SimpleIdentifier simple(String search) {
+    return _node(search, (_) => true);
+  }
+
+  SimpleFormalParameter simpleParameter(String search) {
+    return _node(search, (n) => n is SimpleFormalParameter);
+  }
+
+  Statement statement(String search) {
+    return _node(search, (n) => n is Statement);
+  }
+
+  StringLiteral stringLiteral(String search) {
+    return _node(search, (n) => n is StringLiteral);
+  }
+
+  SuperExpression super_(String search) {
+    return _node(search, (n) => n is SuperExpression);
+  }
+
+  SwitchStatement switchStatement(String search) {
+    return _node(search, (n) => n is SwitchStatement);
+  }
+
+  ThisExpression this_(String search) {
+    return _node(search, (n) => n is ThisExpression);
+  }
+
+  ThrowExpression throw_(String search) {
+    return _node(search, (n) => n is ThrowExpression);
+  }
+
+  TopLevelVariableDeclaration topLevelVariableDeclaration(String search) {
+    return _node(search, (n) => n is TopLevelVariableDeclaration);
+  }
+
+  VariableDeclaration topVariableDeclarationByName(String name) {
+    for (var declaration in unit.declarations) {
+      if (declaration is TopLevelVariableDeclaration) {
+        for (var variable in declaration.variables.variables) {
+          if (variable.name.name == name) {
+            return variable;
+          }
+        }
+      }
+    }
+    throw StateError('$name');
+  }
+
+  TypeAnnotation typeAnnotation(String search) {
+    return _node(search, (n) => n is TypeAnnotation);
+  }
+
+  TypeName typeName(String search) {
+    return _node(search, (n) => n is TypeName);
+  }
+
+  TypeParameter typeParameter(String search) {
+    return _node(search, (n) => n is TypeParameter);
+  }
+
+  VariableDeclaration variableDeclaration(String search) {
+    return _node(search, (n) => n is VariableDeclaration);
+  }
+
+  WhileStatement whileStatement(String search) {
+    return _node(search, (n) => n is WhileStatement);
+  }
+
+  AstNode _node(String search, bool Function(AstNode) predicate) {
+    var index = content.indexOf(search);
+    if (content.indexOf(search, index + 1) != -1) {
+      throw new StateError('The pattern |$search| is not unique in:\n$content');
+    }
+    if (index < 0) {
+      throw new StateError('The pattern |$search| is not found in:\n$content');
+    }
+
+    var node = new NodeLocator2(index).searchWithin(unit);
+    if (node == null) {
+      throw new StateError(
+          'The pattern |$search| had no corresponding node in:\n$content');
+    }
+
+    var result = node.thisOrAncestorMatching(predicate);
+    if (result == null) {
+      throw new StateError(
+          'The node for |$search| had no matching ancestor in:\n$content');
+    }
+    return result;
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/function_ast_visitor.dart b/pkg/analyzer/lib/src/test_utilities/function_ast_visitor.dart
similarity index 100%
rename from pkg/analyzer/test/src/dart/resolution/function_ast_visitor.dart
rename to pkg/analyzer/lib/src/test_utilities/function_ast_visitor.dart
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index b68d13e..94f6ed8 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -105,7 +105,12 @@
 library dart.collection;
 
 abstract class HashMap<K, V> implements Map<K, V> {}
-abstract class LinkedHashMap<K, V> implements Map<K, V> {}
+abstract class LinkedHashMap<K, V> implements Map<K, V> {
+  factory LinkedHashMap(
+      {bool equals(K key1, K key2),
+      int hashCode(K key),
+      bool isValidKey(potentialKey)}) => null;
+}
 abstract class HashSet<E> implements Set<E> {}
 abstract class LinkedHashSet<E> implements Set<E> {}
 ''');
@@ -235,6 +240,8 @@
 
   List<E> toList();
 
+  Set<E> toSet();
+
   Iterable<E> where(bool test(E element));
 }
 
@@ -259,6 +266,9 @@
 }
 
 class Map<K, V> {
+  factory Map() => {}
+  factory Map.fromIterable(Iterable iterable,
+      {K key(element), V value(element)}) => {}
   Iterable<K> get keys => null;
   int get length => 0;
   Iterable<V> get values => null;
@@ -312,6 +322,10 @@
 }
 
 abstract class Set<E> implements Iterable<E> {
+  factory Set() => null;
+  factory Set.identity() => null;
+  factory Set.from(Iterable elements) => null;
+  factory Set.of(Iterable<E> elements) => null;
   Set<R> cast<R>();
 }
 
@@ -435,6 +449,7 @@
 external double cos(num radians);
 external double sin(num radians);
 external double sqrt(num radians);
+external double tan(num radians);
 class Random {
   bool nextBool() => true;
   double nextDouble() => 2.0;
diff --git a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
index 4eba2df..8f20457 100644
--- a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
+++ b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:io' hide File;
-
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/dart/analysis/context_locator.dart';
@@ -16,26 +14,6 @@
 mixin ResourceProviderMixin {
   MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
 
-  /// Convert the given [path] to be a valid import uri for this provider's path context.
-  /// The URI will use forward slashes on all platforms and absolute paths on Windows
-  /// will be formatted as /X:/path/file.dart
-  String convertAbsolutePathToUri(String path) {
-    path = convertPath(path);
-
-    // On Windows, absolute import paths are not quite the same as a normal fs path.
-    // C:\test.dart must be imported as one of:
-    //   import "file:///C:/test.dart"
-    //   import "/C:/test.dart"
-    if (Platform.isWindows && resourceProvider.pathContext.isAbsolute(path)) {
-      // The .path on a file Uri is in the form "/C:/test.dart"
-      path = new Uri.file(path).path;
-    }
-
-    // Since this returns a URI for imports, it should always be forward slashes
-    // even for relative paths on Windows.
-    return path.replaceAll(r'\', '/');
-  }
-
   String convertPath(String path) => resourceProvider.convertPath(path);
 
   void deleteFile(String path) {
@@ -103,4 +81,8 @@
     path = convertPath(path);
     return resourceProvider.pathContext.toUri(path);
   }
+
+  String toUriStr(String path) {
+    return toUri(path).toString();
+  }
 }
diff --git a/pkg/analyzer/lib/src/util/comment.dart b/pkg/analyzer/lib/src/util/comment.dart
new file mode 100644
index 0000000..8e61774
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/comment.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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';
+
+/// Return the raw text of the given comment node.
+String getCommentNodeRawText(Comment node) {
+  if (node == null) return null;
+
+  return node.tokens
+      .map((token) => token.lexeme)
+      .join('\n')
+      .replaceAll('\r\n', '\n');
+}
+
+/// Return the plain text from the given DartDoc [rawText], without delimiters.
+String getDartDocPlainText(String rawText) {
+  if (rawText == null) return null;
+
+  // Remove /** */.
+  if (rawText.startsWith('/**')) {
+    rawText = rawText.substring(3);
+  }
+  if (rawText.endsWith('*/')) {
+    rawText = rawText.substring(0, rawText.length - 2);
+  }
+  rawText = rawText.trim();
+
+  // Remove leading '* ' and '/// '.
+  var result = new StringBuffer();
+  var lines = rawText.split('\n');
+  for (var line in lines) {
+    line = line.trim();
+    if (line.startsWith('*')) {
+      line = line.substring(1);
+      if (line.startsWith(' ')) {
+        line = line.substring(1);
+      }
+    } else if (line.startsWith('///')) {
+      line = line.substring(3);
+      if (line.startsWith(' ')) {
+        line = line.substring(1);
+      }
+    }
+    if (result.isNotEmpty) {
+      result.write('\n');
+    }
+    result.write(line);
+  }
+
+  return result.toString();
+}
+
+/// Return the DartDoc summary, i.e. the portion before the first empty line.
+String getDartDocSummary(String completeText) {
+  if (completeText == null) return null;
+
+  var result = new StringBuffer();
+  var lines = completeText.split('\n');
+  for (var line in lines) {
+    if (result.isNotEmpty) {
+      if (line.isEmpty) {
+        return result.toString();
+      }
+      result.write('\n');
+    }
+    result.write(line);
+  }
+  return result.toString();
+}
diff --git a/pkg/analyzer/lib/src/workspace/basic.dart b/pkg/analyzer/lib/src/workspace/basic.dart
index 89b270f..0b177f0 100644
--- a/pkg/analyzer/lib/src/workspace/basic.dart
+++ b/pkg/analyzer/lib/src/workspace/basic.dart
@@ -4,10 +4,6 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/builder.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/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/workspace/simple.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:package_config/packages.dart';
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index d33e17a..c5c74673 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -37,6 +37,10 @@
       return null;
     }
     String filePath = fileUriToNormalizedPath(provider.pathContext, uri);
+    Resource resource = provider.getResource(filePath);
+    if (resource is! File) {
+      return null;
+    }
     File file = workspace.findFile(filePath);
     if (file != null) {
       return file.createSource(actualUri ?? uri);
@@ -213,8 +217,8 @@
       return null;
     }
     path.Context context = provider.pathContext;
-    String fullBuiltPath = context.join(
-        root, _dartToolRootName, 'build', 'generated', packageName, builtPath);
+    String fullBuiltPath = context.normalize(context.join(
+        root, _dartToolRootName, 'build', 'generated', packageName, builtPath));
     return provider.getFile(fullBuiltPath);
   }
 
@@ -247,18 +251,19 @@
   }
 
   /**
-   * Return the file with the given [filePath], looking first into directories for
-   * source files, and then in the generated directory
-   * `.dart_tool/build/generated/$projectPackageName/$FILE`. The file in the
-   * workspace root is returned even if it does not exist. Return `null` if the
-   * given [filePath] is not in the workspace [root].
+   * Return the file with the given [filePath], looking first in the generated
+   * directory `.dart_tool/build/generated/$projectPackageName/`, then in
+   * source directories.
+   *
+   * The file in the workspace [root] is returned even if it does not exist.
+   * Return `null` if the given [filePath] is not in the workspace root.
    */
   File findFile(String filePath) {
     path.Context context = provider.pathContext;
     assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
     try {
-      final String builtPath = context.relative(filePath, from: root);
-      final File file = builtFile(builtPath, projectPackageName);
+      final String relativePath = context.relative(filePath, from: root);
+      final File file = builtFile(relativePath, projectPackageName);
 
       if (file.exists) {
         return file;
@@ -332,10 +337,11 @@
   PackageBuildWorkspacePackage(this.root, this.workspace);
 
   @override
-  bool contains(String path) {
+  bool contains(String filePath) {
     // There is a 1-1 relationship between PackageBuildWorkspaces and
     // PackageBuildWorkspacePackages. If a file is in a package's workspace,
     // then it is in the package as well.
-    return workspace.findFile(path) != null;
+    return workspace.provider.pathContext.isWithin(workspace.root, filePath) &&
+        workspace.findFile(filePath) != null;
   }
 }
diff --git a/pkg/analyzer/lib/src/workspace/pub.dart b/pkg/analyzer/lib/src/workspace/pub.dart
index f89937c..3cfbe59 100644
--- a/pkg/analyzer/lib/src/workspace/pub.dart
+++ b/pkg/analyzer/lib/src/workspace/pub.dart
@@ -4,10 +4,6 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/builder.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/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/workspace/simple.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
 import 'package:package_config/packages.dart';
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 33c10f2..38d06b9 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.34.2-dev
+version: 0.35.1
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.8
+  front_end: 0.1.11
   glob: ^1.0.3
   html: '>=0.12.0 <1.14.0'
-  kernel: 0.3.8
+  kernel: 0.3.11
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
@@ -24,5 +24,7 @@
   watcher: '>=0.9.6 <0.10.0'
   yaml: ^2.1.2
 dev_dependencies:
+  analysis_tool:
+    path: ../analysis_tool
   test: ^1.0.0
   test_reflective_loader: ^0.1.8
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index b476b61..ca9248f 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -23,6 +23,7 @@
 
 import '../../generated/parser_test.dart';
 import '../../generated/test_support.dart';
+import '../../util/element_type_matchers.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -878,7 +879,7 @@
     FunctionElement initializerElement = fieldElement.initializer;
     expect(initializerElement, isNotNull);
     expect(initializerElement.hasImplicitReturnType, isTrue);
-    expect(initializer.declaredElement, new TypeMatcher<FunctionElement>());
+    expect(initializer.declaredElement, isFunctionElement);
     LocalVariableElement variableElement = variable.declaredElement;
     expect(variableElement.hasImplicitType, isTrue);
     expect(variableElement.isConst, isFalse);
diff --git a/pkg/analyzer/test/error/error_reporter_test.dart b/pkg/analyzer/test/error/error_reporter_test.dart
new file mode 100644
index 0000000..eeb2468
--- /dev/null
+++ b/pkg/analyzer/test/error/error_reporter_test.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:source_span/source_span.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../generated/test_support.dart';
+import '../src/dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ErrorReporterTest);
+  });
+}
+
+@reflectiveTest
+class ErrorReporterTest extends DriverResolutionTest {
+  var listener = GatheringErrorListener();
+
+  test_creation() async {
+    var source = TestSource();
+    expect(ErrorReporter(listener, source), isNotNull);
+  }
+
+  test_reportErrorForElement_named() async {
+    addTestFile('class A {}');
+    await resolveTestFile();
+
+    var element = findElement.class_('A');
+    var reporter = ErrorReporter(listener, element.source);
+    reporter.reportErrorForElement(
+      StaticWarningCode.CAST_TO_NON_TYPE,
+      element,
+      ['A'],
+    );
+
+    var error = listener.errors[0];
+    expect(error.offset, element.nameOffset);
+  }
+
+  test_reportErrorForElement_unnamed() async {
+    addTestFile(r'''
+import 'dart:async';
+import 'dart:math';
+''');
+    await resolveTestFile();
+
+    var element = findElement.import('dart:math');
+
+    var reporter = ErrorReporter(listener, element.source);
+    reporter.reportErrorForElement(
+      StaticWarningCode.CAST_TO_NON_TYPE,
+      element,
+      ['A'],
+    );
+
+    var error = listener.errors[0];
+    expect(error.offset, element.nameOffset);
+  }
+
+  test_reportErrorForSpan() async {
+    var source = TestSource();
+    var reporter = ErrorReporter(listener, source);
+
+    var text = '''
+foo: bar
+zap: baz
+''';
+
+    var offset = text.indexOf('baz');
+    var length = 'baz'.length;
+
+    var span = SourceSpanBase(
+      SourceLocation(offset),
+      SourceLocation(offset + length),
+      'baz',
+    );
+
+    reporter.reportErrorForSpan(
+      AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
+      span,
+      ['test', 'zip', 'zap'],
+    );
+    expect(listener.errors, hasLength(1));
+    expect(listener.errors.first.offset, offset);
+    expect(listener.errors.first.length, length);
+  }
+
+  test_reportTypeErrorForNode_differentNames() async {
+    newFile('/test/lib/a.dart', content: 'class A {}');
+    newFile('/test/lib/b.dart', content: 'class B {}');
+    addTestFile(r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+main() {
+  x;
+}
+''');
+    await resolveTestFile();
+
+    var aImport = findElement.importFind('package:test/a.dart');
+    var bImport = findElement.importFind('package:test/b.dart');
+
+    var firstType = aImport.class_('A').type;
+    var secondType = bImport.class_('B').type;
+
+    var reporter = ErrorReporter(listener, firstType.element.source);
+
+    reporter.reportTypeErrorForNode(
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      findNode.simple('x'),
+      [firstType, secondType],
+    );
+
+    var error = listener.errors[0];
+    expect(error.message, isNot(contains('(')));
+  }
+
+  test_reportTypeErrorForNode_sameName() async {
+    newFile('/test/lib/a.dart', content: 'class A {}');
+    newFile('/test/lib/b.dart', content: 'class A {}');
+    addTestFile(r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+main() {
+  x;
+}
+''');
+    await resolveTestFile();
+
+    var aImport = findElement.importFind('package:test/a.dart');
+    var bImport = findElement.importFind('package:test/b.dart');
+
+    var firstType = aImport.class_('A').type;
+    var secondType = bImport.class_('A').type;
+
+    var reporter = ErrorReporter(listener, firstType.element.source);
+    reporter.reportTypeErrorForNode(
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      findNode.simple('x'),
+      [firstType, secondType],
+    );
+
+    var error = listener.errors[0];
+    expect(error.message, contains('('));
+  }
+
+  test_reportTypeErrorForNode_sameName_functionType() async {
+    newFile('/test/lib/a.dart', content: 'class A{}');
+    newFile('/test/lib/b.dart', content: 'class A{}');
+    addTestFile(r'''
+import 'a.dart' as a;
+import 'b.dart' as b;
+
+a.A Function() fa;
+b.A Function() fb;
+
+main() {
+  x;
+}
+''');
+    await resolveTestFile();
+
+    var fa = findNode.topLevelVariableDeclaration('fa');
+    var fb = findNode.topLevelVariableDeclaration('fb');
+
+    var source = result.unit.declaredElement.source;
+    var reporter = ErrorReporter(listener, source);
+    reporter.reportTypeErrorForNode(
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      findNode.simple('x'),
+      [fa.variables.type.type, fb.variables.type.type],
+    );
+
+    var error = listener.errors[0];
+    expect(error.message, contains('a.dart'));
+    expect(error.message, contains('b.dart'));
+  }
+
+  test_reportTypeErrorForNode_sameName_nested() async {
+    newFile('/test/lib/a.dart', content: 'class A{}');
+    newFile('/test/lib/b.dart', content: 'class A{}');
+    addTestFile(r'''
+import 'a.dart' as a;
+import 'b.dart' as b;
+
+B<a.A> ba;
+B<b.A> bb;
+class B<T> {}
+
+main() {
+  x;
+}
+''');
+    await resolveTestFile();
+
+    var ba = findNode.topLevelVariableDeclaration('ba');
+    var bb = findNode.topLevelVariableDeclaration('bb');
+
+    var source = result.unit.declaredElement.source;
+    var reporter = ErrorReporter(listener, source);
+    reporter.reportTypeErrorForNode(
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      findNode.simple('x'),
+      [ba.variables.type.type, bb.variables.type.type],
+    );
+
+    var error = listener.errors[0];
+    expect(error.message, contains('a.dart'));
+    expect(error.message, contains('b.dart'));
+  }
+}
diff --git a/pkg/analyzer/test/error/test_all.dart b/pkg/analyzer/test/error/test_all.dart
index bf82c24..aeadc12 100644
--- a/pkg/analyzer/test/error/test_all.dart
+++ b/pkg/analyzer/test/error/test_all.dart
@@ -4,10 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'error_reporter_test.dart' as error_reporter;
 import 'error_test.dart' as error_test;
 
 main() {
   defineReflectiveSuite(() {
+    error_reporter.main();
     error_test.main();
   }, name: 'error');
 }
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 0c87fa9..a860794 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -2,62 +2,43 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart' hide ConstantEvaluator;
 import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader;
-import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart'; // ignore: deprecated_member_use
+import 'package:analyzer/src/generated/sdk_io.dart'; // ignore: deprecated_member_use_from_same_package
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:path/path.dart' as path;
-import 'package:source_span/source_span.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../util/element_type_matchers.dart';
-import 'parser_test.dart';
-import 'resolver_test_case.dart';
 import 'test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ContentCacheTest);
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     defineReflectiveTests(CustomUriResolverTest);
     defineReflectiveTests(DartUriResolverTest);
-    defineReflectiveTests(ElementLocatorTest);
     defineReflectiveTests(EnumMemberBuilderTest);
-    defineReflectiveTests(ErrorReporterTest);
-    defineReflectiveTests(ErrorReporterTest2);
     defineReflectiveTests(ErrorSeverityTest);
-    defineReflectiveTests(ExitDetectorTest);
-    defineReflectiveTests(ExitDetectorTest2);
     defineReflectiveTests(FileBasedSourceTest);
     defineReflectiveTests(ResolveRelativeUriTest);
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     defineReflectiveTests(SDKLibrariesReaderTest);
     defineReflectiveTests(UriKindTest);
   });
@@ -166,383 +147,6 @@
 }
 
 @reflectiveTest
-class ElementLocatorTest extends ResolverTestCase {
-  void fail_locate_Identifier_partOfDirective() {
-    // Can't resolve the library element without the library declaration.
-    //    AstNode id = findNodeIn("foo", "part of foo.bar;");
-    //    Element element = ElementLocator.locate(id);
-    //    assertInstanceOf(LibraryElement.class, element);
-    fail("Test this case");
-  }
-
-  @override
-  void reset() {
-    AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
-    analysisOptions.hint = false;
-    resetWith(options: analysisOptions);
-  }
-
-  test_locate_AssignmentExpression() async {
-    AstNode id = await _findNodeIn("+=", r'''
-int x = 0;
-void main() {
-  x += 1;
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_BinaryExpression() async {
-    AstNode id = await _findNodeIn("+", "var x = 3 + 4;");
-    Element element = ElementLocator.locate(id);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_ClassDeclaration() async {
-    AstNode id = await _findNodeIn("class", "class A { }");
-    Element element = ElementLocator.locate(id);
-    expect(element, isClassElement);
-  }
-
-  test_locate_CompilationUnit() async {
-    CompilationUnit cu = await _resolveContents("// only comment");
-    expect(cu.declaredElement, isNotNull);
-    Element element = ElementLocator.locate(cu);
-    expect(element, same(cu.declaredElement));
-  }
-
-  test_locate_ConstructorDeclaration() async {
-    AstNode id = await _findNodeIndexedIn("bar", 0, r'''
-class A {
-  A.bar() {}
-}''');
-    ConstructorDeclaration declaration =
-        id.thisOrAncestorOfType<ConstructorDeclaration>();
-    Element element = ElementLocator.locate(declaration);
-    expect(element, isConstructorElement);
-  }
-
-  test_locate_ExportDirective() async {
-    AstNode id = await _findNodeIn("export", "export 'dart:core';");
-    Element element = ElementLocator.locate(id);
-    expect(element, isExportElement);
-  }
-
-  test_locate_FunctionDeclaration() async {
-    AstNode id = await _findNodeIn("f", "int f() => 3;");
-    FunctionDeclaration declaration =
-        id.thisOrAncestorOfType<FunctionDeclaration>();
-    Element element = ElementLocator.locate(declaration);
-    expect(element, isFunctionElement);
-  }
-
-  test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalParameter() async {
-    AstNode id = await _findNodeIndexedIn("Class", 2, r'''
-class Class {
-  const Class.name();
-}
-void main(@Class.name() parameter) {
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isClassElement);
-  }
-
-  test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalParameter() async {
-    AstNode id = await _findNodeIndexedIn("Class", 2, r'''
-class Class {
-  const Class();
-}
-void main(@Class() parameter) {
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isConstructorElement);
-  }
-
-  test_locate_Identifier_className() async {
-    AstNode id = await _findNodeIn("A", "class A { }");
-    Element element = ElementLocator.locate(id);
-    expect(element, isClassElement);
-  }
-
-  test_locate_Identifier_constructor_named() async {
-    AstNode id = await _findNodeIndexedIn("bar", 0, r'''
-class A {
-  A.bar() {}
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isConstructorElement);
-  }
-
-  test_locate_Identifier_constructor_unnamed() async {
-    AstNode id = await _findNodeIndexedIn("A", 1, r'''
-class A {
-  A() {}
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isConstructorElement);
-  }
-
-  test_locate_Identifier_fieldName() async {
-    AstNode id = await _findNodeIn("x", "class A { var x; }");
-    Element element = ElementLocator.locate(id);
-    expect(element, isFieldElement);
-  }
-
-  test_locate_Identifier_libraryDirective() async {
-    AstNode id = await _findNodeIn("foo", "library foo.bar;");
-    Element element = ElementLocator.locate(id);
-    expect(element, isLibraryElement);
-  }
-
-  test_locate_Identifier_propertyAccess() async {
-    AstNode id = await _findNodeIn("length", r'''
-void main() {
- int x = 'foo'.length;
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isPropertyAccessorElement);
-  }
-
-  test_locate_ImportDirective() async {
-    AstNode id = await _findNodeIn("import", "import 'dart:core';");
-    Element element = ElementLocator.locate(id);
-    expect(element, isImportElement);
-  }
-
-  test_locate_IndexExpression() async {
-    AstNode id = await _findNodeIndexedIn("\\[", 1, r'''
-void main() {
-  List x = [1, 2];
-  var y = x[0];
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_InstanceCreationExpression() async {
-    AstNode node = await _findNodeIndexedIn("A(", 0, r'''
-class A {}
-void main() {
- new A();
-}''');
-    Element element = ElementLocator.locate(node);
-    expect(element, isConstructorElement);
-  }
-
-  test_locate_InstanceCreationExpression_type_prefixedIdentifier() async {
-    // prepare: new pref.A()
-    SimpleIdentifier identifier = AstTestFactory.identifier3("A");
-    PrefixedIdentifier prefixedIdentifier =
-        AstTestFactory.identifier4("pref", identifier);
-    InstanceCreationExpression creation =
-        AstTestFactory.instanceCreationExpression2(
-            Keyword.NEW, AstTestFactory.typeName3(prefixedIdentifier));
-    // set ClassElement
-    ClassElement classElement = ElementFactory.classElement2("A");
-    identifier.staticElement = classElement;
-    // set ConstructorElement
-    ConstructorElement constructorElement =
-        ElementFactory.constructorElement2(classElement, null);
-    creation.constructorName.staticElement = constructorElement;
-    // verify that "A" is resolved to ConstructorElement
-    Element element = ElementLocator.locate(identifier);
-    expect(element, same(classElement));
-  }
-
-  test_locate_InstanceCreationExpression_type_simpleIdentifier() async {
-    // prepare: new A()
-    SimpleIdentifier identifier = AstTestFactory.identifier3("A");
-    InstanceCreationExpression creation =
-        AstTestFactory.instanceCreationExpression2(
-            Keyword.NEW, AstTestFactory.typeName3(identifier));
-    // set ClassElement
-    ClassElement classElement = ElementFactory.classElement2("A");
-    identifier.staticElement = classElement;
-    // set ConstructorElement
-    ConstructorElement constructorElement =
-        ElementFactory.constructorElement2(classElement, null);
-    creation.constructorName.staticElement = constructorElement;
-    // verify that "A" is resolved to ConstructorElement
-    Element element = ElementLocator.locate(identifier);
-    expect(element, same(classElement));
-  }
-
-  test_locate_LibraryDirective() async {
-    AstNode id = await _findNodeIn("library", "library foo;");
-    Element element = ElementLocator.locate(id);
-    expect(element, isLibraryElement);
-  }
-
-  test_locate_MethodDeclaration() async {
-    AstNode id = await _findNodeIn("m", r'''
-class A {
-  void m() {}
-}''');
-    MethodDeclaration declaration =
-        id.thisOrAncestorOfType<MethodDeclaration>();
-    Element element = ElementLocator.locate(declaration);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_MethodInvocation_method() async {
-    AstNode id = await _findNodeIndexedIn("bar", 1, r'''
-class A {
-  int bar() => 42;
-}
-void main() {
- var f = new A().bar();
-}''');
-    Element element = ElementLocator.locate(id);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_MethodInvocation_topLevel() async {
-    String code = r'''
-foo(x) {}
-void main() {
- foo(0);
-}''';
-    CompilationUnit cu = await _resolveContents(code);
-    int offset = code.indexOf('foo(0)');
-    AstNode node = new NodeLocator(offset).searchWithin(cu);
-    MethodInvocation invocation = node.thisOrAncestorOfType<MethodInvocation>();
-    Element element = ElementLocator.locate(invocation);
-    expect(element, isFunctionElement);
-  }
-
-  test_locate_PartOfDirective() async {
-    Source librarySource = addNamedSource('/lib.dart', '''
-library my.lib;
-part 'part.dart';
-''');
-    Source unitSource = addNamedSource('/part.dart', '''
-part of my.lib;
-''');
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit2(unitSource, librarySource);
-    PartOfDirective partOf = unit.directives.first;
-    Element element = ElementLocator.locate(partOf);
-    expect(element, isLibraryElement);
-  }
-
-  test_locate_PostfixExpression() async {
-    AstNode id = await _findNodeIn("++", "int addOne(int x) => x++;");
-    Element element = ElementLocator.locate(id);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_PrefixedIdentifier() async {
-    AstNode id = await _findNodeIn("int", r'''
-import 'dart:core' as core;
-core.int value;''');
-    PrefixedIdentifier identifier =
-        id.thisOrAncestorOfType<PrefixedIdentifier>();
-    Element element = ElementLocator.locate(identifier);
-    expect(element, isClassElement);
-  }
-
-  test_locate_PrefixExpression() async {
-    AstNode id = await _findNodeIn("++", "int addOne(int x) => ++x;");
-    Element element = ElementLocator.locate(id);
-    expect(element, isMethodElement);
-  }
-
-  test_locate_StringLiteral_exportUri() async {
-    addNamedSource("/foo.dart", "library foo;");
-    AstNode id = await _findNodeIn("'foo.dart'", "export 'foo.dart';");
-    Element element = ElementLocator.locate(id);
-    expect(element, isLibraryElement);
-  }
-
-  test_locate_StringLiteral_expression() async {
-    AstNode id = await _findNodeIn("abc", "var x = 'abc';");
-    Element element = ElementLocator.locate(id);
-    expect(element, isNull);
-  }
-
-  test_locate_StringLiteral_importUri() async {
-    addNamedSource("/foo.dart", "library foo; class A {}");
-    AstNode id = await _findNodeIn(
-        "'foo.dart'", "import 'foo.dart'; class B extends A {}");
-    Element element = ElementLocator.locate(id);
-    expect(element, isLibraryElement);
-  }
-
-  test_locate_StringLiteral_partUri() async {
-    addNamedSource("/foo.dart", "part of app;");
-    AstNode id =
-        await _findNodeIn("'foo.dart'", "library app; part 'foo.dart';");
-    Element element = ElementLocator.locate(id);
-    expect(element, isCompilationUnitElement);
-  }
-
-  test_locate_VariableDeclaration() async {
-    AstNode id = await _findNodeIn("x", "var x = 'abc';");
-    VariableDeclaration declaration =
-        id.thisOrAncestorOfType<VariableDeclaration>();
-    Element element = ElementLocator.locate(declaration);
-    expect(element, isTopLevelVariableElement);
-  }
-
-  /**
-   * Find the first AST node matching a pattern in the resolved AST for the given source.
-   *
-   * [nodePattern] the (unique) pattern used to identify the node of interest.
-   * [code] the code to resolve.
-   * Returns the matched node in the resolved AST for the given source lines.
-   */
-  Future<AstNode> _findNodeIn(String nodePattern, String code) async {
-    return await _findNodeIndexedIn(nodePattern, 0, code);
-  }
-
-  /**
-   * Find the AST node matching the given indexed occurrence of a pattern in the resolved AST for
-   * the given source.
-   *
-   * [nodePattern] the pattern used to identify the node of interest.
-   * [index] the index of the pattern match of interest.
-   * [code] the code to resolve.
-   * Returns the matched node in the resolved AST for the given source lines
-   */
-  Future<AstNode> _findNodeIndexedIn(
-      String nodePattern, int index, String code) async {
-    CompilationUnit cu = await _resolveContents(code);
-    int start = _getOffsetOfMatch(code, nodePattern, index);
-    int end = start + nodePattern.length;
-    return new NodeLocator(start, end).searchWithin(cu);
-  }
-
-  int _getOffsetOfMatch(String contents, String pattern, int matchIndex) {
-    if (matchIndex == 0) {
-      return contents.indexOf(pattern);
-    }
-    Iterable<Match> matches = new RegExp(pattern).allMatches(contents);
-    Match match = matches.toList()[matchIndex];
-    return match.start;
-  }
-
-  /**
-   * Parse, resolve and verify the given source lines to produce a fully
-   * resolved AST.
-   *
-   * [code] the code to resolve.
-   *
-   * Returns the result of resolving the AST structure representing the content
-   * of the source.
-   *
-   * Throws if source cannot be verified.
-   */
-  Future<CompilationUnit> _resolveContents(String code) async {
-    Source source = addSource(code);
-    LibraryElement library = resolve2(source);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    return analysisContext.resolveCompilationUnit(source, library);
-  }
-}
-
-@reflectiveTest
 class EnumMemberBuilderTest extends EngineTestCase {
   test_visitEnumDeclaration_multiple() async {
     String firstName = "ONE";
@@ -637,166 +241,6 @@
 }
 
 @reflectiveTest
-class ErrorReporterTest extends EngineTestCase {
-  /**
-   * Return a newly created interface type with the given [typeName] in a
-   * compilation unit with the given [fileName].
-   */
-  InterfaceType createType(String fileName, String typeName) {
-    CompilationUnitElementImpl unit = ElementFactory.compilationUnit(fileName);
-    ClassElementImpl element = ElementFactory.classElement2(typeName);
-    unit.types = <ClassElement>[element];
-    return element.type;
-  }
-
-  test_creation() async {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    TestSource source = new TestSource();
-    expect(new ErrorReporter(listener, source), isNotNull);
-  }
-
-  test_reportErrorForElement_named() async {
-    DartType type = createType("/test1.dart", "A");
-    ClassElement element = type.element;
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter = new ErrorReporter(listener, element.source);
-    reporter.reportErrorForElement(
-        StaticWarningCode.CAST_TO_NON_TYPE, element, ['A']);
-    AnalysisError error = listener.errors[0];
-    expect(error.offset, element.nameOffset);
-  }
-
-  test_reportErrorForElement_unnamed() async {
-    ImportElementImpl element =
-        ElementFactory.importFor(ElementFactory.library(null, ''), null);
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter = new ErrorReporter(
-        listener,
-        new NonExistingSource(
-            '/test.dart', path.toUri('/test.dart'), UriKind.FILE_URI));
-    reporter.reportErrorForElement(
-        StaticWarningCode.CAST_TO_NON_TYPE, element, ['A']);
-    AnalysisError error = listener.errors[0];
-    expect(error.offset, element.nameOffset);
-  }
-
-  test_reportErrorForSpan() async {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter = new ErrorReporter(listener, new TestSource());
-
-    var src = '''
-foo: bar
-zap: baz
-''';
-
-    int offset = src.indexOf('baz');
-    int length = 'baz'.length;
-
-    SourceSpan span = new SourceSpanBase(
-        new SourceLocation(offset), new SourceLocation(offset + length), 'baz');
-
-    reporter.reportErrorForSpan(
-        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
-        span,
-        ['test', 'zip', 'zap']);
-    expect(listener.errors, hasLength(1));
-    expect(listener.errors.first.offset, offset);
-    expect(listener.errors.first.length, length);
-  }
-
-  test_reportTypeErrorForNode_differentNames() async {
-    DartType firstType = createType("/test1.dart", "A");
-    DartType secondType = createType("/test2.dart", "B");
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter =
-        new ErrorReporter(listener, firstType.element.source);
-    reporter.reportTypeErrorForNode(
-        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-        AstTestFactory.identifier3("x"),
-        [firstType, secondType]);
-    AnalysisError error = listener.errors[0];
-    expect(error.message.contains("("), isFalse);
-  }
-
-  test_reportTypeErrorForNode_sameName() async {
-    String typeName = "A";
-    DartType firstType = createType("/test1.dart", typeName);
-    DartType secondType = createType("/test2.dart", typeName);
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter =
-        new ErrorReporter(listener, firstType.element.source);
-    reporter.reportTypeErrorForNode(
-        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-        AstTestFactory.identifier3("x"),
-        [firstType, secondType]);
-    AnalysisError error = listener.errors[0];
-    expect(error.message.contains("("), isTrue);
-  }
-}
-
-@reflectiveTest
-class ErrorReporterTest2 extends ResolverTestCase {
-  test_reportTypeErrorForNode_sameName_functionType() async {
-    addNamedSource('/a.dart', '''
-class A {}
-''');
-    addNamedSource('/b.dart', '''
-class A {}
-''');
-    CompilationUnit unit = await resolveSource('''
-import 'a.dart' as a;
-import 'b.dart' as b;
-
-a.A Function() fa;
-b.A Function() fb;
-''');
-
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter =
-        new ErrorReporter(listener, unit.declaredElement.source);
-    TopLevelVariableDeclaration fa = unit.declarations[0];
-    TopLevelVariableDeclaration fb = unit.declarations[1];
-    reporter.reportTypeErrorForNode(
-        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-        AstTestFactory.identifier3('x'),
-        [fa.variables.type.type, fb.variables.type.type]);
-    AnalysisError error = listener.errors[0];
-    expect(error.message.contains('a.dart'), isTrue);
-    expect(error.message.contains('b.dart'), isTrue);
-  }
-
-  test_reportTypeErrorForNode_sameName_nested() async {
-    addNamedSource('/a.dart', '''
-class A {}
-''');
-    addNamedSource('/b.dart', '''
-class A {}
-''');
-    CompilationUnit unit = await resolveSource('''
-import 'a.dart' as a;
-import 'b.dart' as b;
-
-B<a.A> ba;
-B<b.A> bb;
-class B<T> {}
-''');
-
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ErrorReporter reporter =
-        new ErrorReporter(listener, unit.declaredElement.source);
-    TopLevelVariableDeclaration fa = unit.declarations[0];
-    TopLevelVariableDeclaration fb = unit.declarations[1];
-    reporter.reportTypeErrorForNode(
-        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-        AstTestFactory.identifier3('x'),
-        [fa.variables.type.type, fb.variables.type.type]);
-    AnalysisError error = listener.errors[0];
-    expect(error.message.contains('a.dart'), isTrue);
-    expect(error.message.contains('b.dart'), isTrue);
-  }
-}
-
-@reflectiveTest
 class ErrorSeverityTest extends EngineTestCase {
   test_max_error_error() async {
     expect(ErrorSeverity.ERROR.max(ErrorSeverity.ERROR),
@@ -844,922 +288,6 @@
   }
 }
 
-/**
- * Tests for the [ExitDetector] that do not require that the AST be resolved.
- *
- * See [ExitDetectorTest2] for tests that require the AST to be resolved.
- */
-@reflectiveTest
-class ExitDetectorTest extends ParserTestCase {
-  test_asExpression() async {
-    _assertFalse("a as Object;");
-  }
-
-  test_asExpression_throw() async {
-    _assertTrue("throw '' as Object;");
-  }
-
-  test_assertStatement() async {
-    _assertFalse("assert(a);");
-  }
-
-  test_assertStatement_throw() async {
-    _assertFalse("assert((throw 0));");
-  }
-
-  test_assignmentExpression() async {
-    _assertFalse("v = 1;");
-  }
-
-  test_assignmentExpression_compound_lazy() async {
-    enableLazyAssignmentOperators = true;
-    _assertFalse("v ||= false;");
-  }
-
-  test_assignmentExpression_lhs_throw() async {
-    _assertTrue("a[throw ''] = 0;");
-  }
-
-  test_assignmentExpression_rhs_throw() async {
-    _assertTrue("v = throw '';");
-  }
-
-  test_await_false() async {
-    _assertFalse("await x;");
-  }
-
-  test_await_throw_true() async {
-    _assertTrue("bool b = await (throw '' || true);");
-  }
-
-  test_binaryExpression_and() async {
-    _assertFalse("a && b;");
-  }
-
-  test_binaryExpression_and_lhs() async {
-    _assertTrue("throw '' && b;");
-  }
-
-  test_binaryExpression_and_rhs() async {
-    _assertFalse("a && (throw '');");
-  }
-
-  test_binaryExpression_and_rhs2() async {
-    _assertFalse("false && (throw '');");
-  }
-
-  test_binaryExpression_and_rhs3() async {
-    _assertTrue("true && (throw '');");
-  }
-
-  test_binaryExpression_ifNull() async {
-    _assertFalse("a ?? b;");
-  }
-
-  test_binaryExpression_ifNull_lhs() async {
-    _assertTrue("throw '' ?? b;");
-  }
-
-  test_binaryExpression_ifNull_rhs() async {
-    _assertFalse("a ?? (throw '');");
-  }
-
-  test_binaryExpression_ifNull_rhs2() async {
-    _assertFalse("null ?? (throw '');");
-  }
-
-  test_binaryExpression_or() async {
-    _assertFalse("a || b;");
-  }
-
-  test_binaryExpression_or_lhs() async {
-    _assertTrue("throw '' || b;");
-  }
-
-  test_binaryExpression_or_rhs() async {
-    _assertFalse("a || (throw '');");
-  }
-
-  test_binaryExpression_or_rhs2() async {
-    _assertFalse("true || (throw '');");
-  }
-
-  test_binaryExpression_or_rhs3() async {
-    _assertTrue("false || (throw '');");
-  }
-
-  test_block_empty() async {
-    _assertFalse("{}");
-  }
-
-  test_block_noReturn() async {
-    _assertFalse("{ int i = 0; }");
-  }
-
-  test_block_return() async {
-    _assertTrue("{ return 0; }");
-  }
-
-  test_block_returnNotLast() async {
-    _assertTrue("{ return 0; throw 'a'; }");
-  }
-
-  test_block_throwNotLast() async {
-    _assertTrue("{ throw 0; x = null; }");
-  }
-
-  test_cascadeExpression_argument() async {
-    _assertTrue("a..b(throw '');");
-  }
-
-  test_cascadeExpression_index() async {
-    _assertTrue("a..[throw ''];");
-  }
-
-  test_cascadeExpression_target() async {
-    _assertTrue("throw ''..b();");
-  }
-
-  test_conditional_ifElse_bothThrows() async {
-    _assertTrue("c ? throw '' : throw '';");
-  }
-
-  test_conditional_ifElse_elseThrows() async {
-    _assertFalse("c ? i : throw '';");
-  }
-
-  test_conditional_ifElse_noThrow() async {
-    _assertFalse("c ? i : j;");
-  }
-
-  test_conditional_ifElse_thenThrow() async {
-    _assertFalse("c ? throw '' : j;");
-  }
-
-  test_conditionalAccess() async {
-    _assertFalse("a?.b;");
-  }
-
-  test_conditionalAccess_lhs() async {
-    _assertTrue("(throw '')?.b;");
-  }
-
-  test_conditionalAccessAssign() async {
-    _assertFalse("a?.b = c;");
-  }
-
-  test_conditionalAccessAssign_lhs() async {
-    _assertTrue("(throw '')?.b = c;");
-  }
-
-  test_conditionalAccessAssign_rhs() async {
-    _assertFalse("a?.b = throw '';");
-  }
-
-  test_conditionalAccessAssign_rhs2() async {
-    _assertFalse("null?.b = throw '';");
-  }
-
-  test_conditionalAccessIfNullAssign() async {
-    _assertFalse("a?.b ??= c;");
-  }
-
-  test_conditionalAccessIfNullAssign_lhs() async {
-    _assertTrue("(throw '')?.b ??= c;");
-  }
-
-  test_conditionalAccessIfNullAssign_rhs() async {
-    _assertFalse("a?.b ??= throw '';");
-  }
-
-  test_conditionalAccessIfNullAssign_rhs2() async {
-    _assertFalse("null?.b ??= throw '';");
-  }
-
-  test_conditionalCall() async {
-    _assertFalse("a?.b(c);");
-  }
-
-  test_conditionalCall_lhs() async {
-    _assertTrue("(throw '')?.b(c);");
-  }
-
-  test_conditionalCall_rhs() async {
-    _assertFalse("a?.b(throw '');");
-  }
-
-  test_conditionalCall_rhs2() async {
-    _assertFalse("null?.b(throw '');");
-  }
-
-  test_creation() async {
-    expect(new ExitDetector(), isNotNull);
-  }
-
-  test_doStatement_break_and_throw() async {
-    _assertFalse("{ do { if (1==1) break; throw 'T'; } while (0==1); }");
-  }
-
-  test_doStatement_continue_and_throw() async {
-    _assertFalse("{ do { if (1==1) continue; throw 'T'; } while (0==1); }");
-  }
-
-  test_doStatement_continueDoInSwitch_and_throw() async {
-    _assertFalse('''
-{
-  D: do {
-    switch (1) {
-      L: case 0: continue D;
-      M: case 1: break;
-    }
-    throw 'T';
-  } while (0 == 1);
-}''');
-  }
-
-  test_doStatement_continueInSwitch_and_throw() async {
-    _assertFalse('''
-{
-  do {
-    switch (1) {
-      L: case 0: continue;
-      M: case 1: break;
-    }
-    throw 'T';
-  } while (0 == 1);
-}''');
-  }
-
-  test_doStatement_return() async {
-    _assertTrue("{ do { return null; } while (1 == 2); }");
-  }
-
-  test_doStatement_throwCondition() async {
-    _assertTrue("{ do {} while (throw ''); }");
-  }
-
-  test_doStatement_true_break() async {
-    _assertFalse("{ do { break; } while (true); }");
-  }
-
-  test_doStatement_true_continue() async {
-    _assertTrue("{ do { continue; } while (true); }");
-  }
-
-  test_doStatement_true_continueWithLabel() async {
-    _assertTrue("{ x: do { continue x; } while (true); }");
-  }
-
-  test_doStatement_true_if_return() async {
-    _assertTrue("{ do { if (true) {return null;} } while (true); }");
-  }
-
-  test_doStatement_true_noBreak() async {
-    _assertTrue("{ do {} while (true); }");
-  }
-
-  test_doStatement_true_return() async {
-    _assertTrue("{ do { return null; } while (true);  }");
-  }
-
-  test_emptyStatement() async {
-    _assertFalse(";");
-  }
-
-  test_forEachStatement() async {
-    _assertFalse("for (element in list) {}");
-  }
-
-  test_forEachStatement_throw() async {
-    _assertTrue("for (element in throw '') {}");
-  }
-
-  test_forStatement_condition() async {
-    _assertTrue("for (; throw 0;) {}");
-  }
-
-  test_forStatement_implicitTrue() async {
-    _assertTrue("for (;;) {}");
-  }
-
-  test_forStatement_implicitTrue_break() async {
-    _assertFalse("for (;;) { break; }");
-  }
-
-  test_forStatement_implicitTrue_if_break() async {
-    _assertFalse("{ for (;;) { if (1==2) { var a = 1; } else { break; } } }");
-  }
-
-  test_forStatement_initialization() async {
-    _assertTrue("for (i = throw 0;;) {}");
-  }
-
-  test_forStatement_true() async {
-    _assertTrue("for (; true; ) {}");
-  }
-
-  test_forStatement_true_break() async {
-    _assertFalse("{ for (; true; ) { break; } }");
-  }
-
-  test_forStatement_true_continue() async {
-    _assertTrue("{ for (; true; ) { continue; } }");
-  }
-
-  test_forStatement_true_if_return() async {
-    _assertTrue("{ for (; true; ) { if (true) {return null;} } }");
-  }
-
-  test_forStatement_true_noBreak() async {
-    _assertTrue("{ for (; true; ) {} }");
-  }
-
-  test_forStatement_updaters() async {
-    _assertTrue("for (;; i++, throw 0) {}");
-  }
-
-  test_forStatement_variableDeclaration() async {
-    _assertTrue("for (int i = throw 0;;) {}");
-  }
-
-  test_functionExpression() async {
-    _assertFalse("(){};");
-  }
-
-  test_functionExpression_bodyThrows() async {
-    _assertFalse("(int i) => throw '';");
-  }
-
-  test_functionExpressionInvocation() async {
-    _assertFalse("f(g);");
-  }
-
-  test_functionExpressionInvocation_argumentThrows() async {
-    _assertTrue("f(throw '');");
-  }
-
-  test_functionExpressionInvocation_targetThrows() async {
-    _assertTrue("throw ''(g);");
-  }
-
-  test_identifier_prefixedIdentifier() async {
-    _assertFalse("a.b;");
-  }
-
-  test_identifier_simpleIdentifier() async {
-    _assertFalse("a;");
-  }
-
-  test_if_false_else_return() async {
-    _assertTrue("if (false) {} else { return 0; }");
-  }
-
-  test_if_false_noReturn() async {
-    _assertFalse("if (false) {}");
-  }
-
-  test_if_false_return() async {
-    _assertFalse("if (false) { return 0; }");
-  }
-
-  test_if_noReturn() async {
-    _assertFalse("if (c) i++;");
-  }
-
-  test_if_return() async {
-    _assertFalse("if (c) return 0;");
-  }
-
-  test_if_true_noReturn() async {
-    _assertFalse("if (true) {}");
-  }
-
-  test_if_true_return() async {
-    _assertTrue("if (true) { return 0; }");
-  }
-
-  test_ifElse_bothReturn() async {
-    _assertTrue("if (c) return 0; else return 1;");
-  }
-
-  test_ifElse_elseReturn() async {
-    _assertFalse("if (c) i++; else return 1;");
-  }
-
-  test_ifElse_noReturn() async {
-    _assertFalse("if (c) i++; else j++;");
-  }
-
-  test_ifElse_thenReturn() async {
-    _assertFalse("if (c) return 0; else j++;");
-  }
-
-  test_ifNullAssign() async {
-    _assertFalse("a ??= b;");
-  }
-
-  test_ifNullAssign_rhs() async {
-    _assertFalse("a ??= throw '';");
-  }
-
-  test_indexExpression() async {
-    _assertFalse("a[b];");
-  }
-
-  test_indexExpression_index() async {
-    _assertTrue("a[throw ''];");
-  }
-
-  test_indexExpression_target() async {
-    _assertTrue("throw ''[b];");
-  }
-
-  test_instanceCreationExpression() async {
-    _assertFalse("new A(b);");
-  }
-
-  test_instanceCreationExpression_argumentThrows() async {
-    _assertTrue("new A(throw '');");
-  }
-
-  test_isExpression() async {
-    _assertFalse("A is B;");
-  }
-
-  test_isExpression_throws() async {
-    _assertTrue("throw '' is B;");
-  }
-
-  test_labeledStatement() async {
-    _assertFalse("label: a;");
-  }
-
-  test_labeledStatement_throws() async {
-    _assertTrue("label: throw '';");
-  }
-
-  test_literal_boolean() async {
-    _assertFalse("true;");
-  }
-
-  test_literal_double() async {
-    _assertFalse("1.1;");
-  }
-
-  test_literal_integer() async {
-    _assertFalse("1;");
-  }
-
-  test_literal_null() async {
-    _assertFalse("null;");
-  }
-
-  test_literal_String() async {
-    _assertFalse("'str';");
-  }
-
-  test_methodInvocation() async {
-    _assertFalse("a.b(c);");
-  }
-
-  test_methodInvocation_argument() async {
-    _assertTrue("a.b(throw '');");
-  }
-
-  test_methodInvocation_target() async {
-    _assertTrue("throw ''.b(c);");
-  }
-
-  test_parenthesizedExpression() async {
-    _assertFalse("(a);");
-  }
-
-  test_parenthesizedExpression_throw() async {
-    _assertTrue("(throw '');");
-  }
-
-  test_propertyAccess() async {
-    _assertFalse("new Object().a;");
-  }
-
-  test_propertyAccess_throws() async {
-    _assertTrue("(throw '').a;");
-  }
-
-  test_rethrow() async {
-    _assertTrue("rethrow;");
-  }
-
-  test_return() async {
-    _assertTrue("return 0;");
-  }
-
-  test_superExpression() async {
-    _assertFalse("super.a;");
-  }
-
-  test_switch_allReturn() async {
-    _assertTrue("switch (i) { case 0: return 0; default: return 1; }");
-  }
-
-  test_switch_defaultWithNoStatements() async {
-    _assertFalse("switch (i) { case 0: return 0; default: }");
-  }
-
-  test_switch_fallThroughToNotReturn() async {
-    _assertFalse("switch (i) { case 0: case 1: break; default: return 1; }");
-  }
-
-  test_switch_fallThroughToReturn() async {
-    _assertTrue("switch (i) { case 0: case 1: return 0; default: return 1; }");
-  }
-
-  // The ExitDetector could conceivably follow switch continue labels and
-  // determine that `case 0` exits, `case 1` continues to an exiting case, and
-  // `default` exits, so the switch exits.
-  @failingTest
-  test_switch_includesContinue() async {
-    _assertTrue('''
-switch (i) {
-  zero: case 0: return 0;
-  case 1: continue zero;
-  default: return 1;
-}''');
-  }
-
-  test_switch_noDefault() async {
-    _assertFalse("switch (i) { case 0: return 0; }");
-  }
-
-  test_switch_nonReturn() async {
-    _assertFalse("switch (i) { case 0: i++; default: return 1; }");
-  }
-
-  test_thisExpression() async {
-    _assertFalse("this.a;");
-  }
-
-  test_throwExpression() async {
-    _assertTrue("throw new Object();");
-  }
-
-  test_tryStatement_noReturn() async {
-    _assertFalse("try {} catch (e, s) {} finally {}");
-  }
-
-  test_tryStatement_noReturn_noFinally() async {
-    _assertFalse("try {} catch (e, s) {}");
-  }
-
-  test_tryStatement_return_catch() async {
-    _assertFalse("try {} catch (e, s) { return 1; } finally {}");
-  }
-
-  test_tryStatement_return_catch_noFinally() async {
-    _assertFalse("try {} catch (e, s) { return 1; }");
-  }
-
-  test_tryStatement_return_finally() async {
-    _assertTrue("try {} catch (e, s) {} finally { return 1; }");
-  }
-
-  test_tryStatement_return_try_noCatch() async {
-    _assertTrue("try { return 1; } finally {}");
-  }
-
-  test_tryStatement_return_try_oneCatchDoesNotExit() async {
-    _assertFalse("try { return 1; } catch (e, s) {} finally {}");
-  }
-
-  test_tryStatement_return_try_oneCatchDoesNotExit_noFinally() async {
-    _assertFalse("try { return 1; } catch (e, s) {}");
-  }
-
-  test_tryStatement_return_try_oneCatchExits() async {
-    _assertTrue("try { return 1; } catch (e, s) { return 1; } finally {}");
-  }
-
-  test_tryStatement_return_try_oneCatchExits_noFinally() async {
-    _assertTrue("try { return 1; } catch (e, s) { return 1; }");
-  }
-
-  test_tryStatement_return_try_twoCatchesDoExit() async {
-    _assertTrue('''
-try { return 1; }
-on int catch (e, s) { return 1; }
-on String catch (e, s) { return 1; }
-finally {}''');
-  }
-
-  test_tryStatement_return_try_twoCatchesDoExit_noFinally() async {
-    _assertTrue('''
-try { return 1; }
-on int catch (e, s) { return 1; }
-on String catch (e, s) { return 1; }''');
-  }
-
-  test_tryStatement_return_try_twoCatchesDoNotExit() async {
-    _assertFalse('''
-try { return 1; }
-on int catch (e, s) {}
-on String catch (e, s) {}
-finally {}''');
-  }
-
-  test_tryStatement_return_try_twoCatchesDoNotExit_noFinally() async {
-    _assertFalse('''
-try { return 1; }
-on int catch (e, s) {}
-on String catch (e, s) {}''');
-  }
-
-  test_tryStatement_return_try_twoCatchesMixed() async {
-    _assertFalse('''
-try { return 1; }
-on int catch (e, s) {}
-on String catch (e, s) { return 1; }
-finally {}''');
-  }
-
-  test_tryStatement_return_try_twoCatchesMixed_noFinally() async {
-    _assertFalse('''
-try { return 1; }
-on int catch (e, s) {}
-on String catch (e, s) { return 1; }''');
-  }
-
-  test_variableDeclarationStatement_noInitializer() async {
-    _assertFalse("int i;");
-  }
-
-  test_variableDeclarationStatement_noThrow() async {
-    _assertFalse("int i = 0;");
-  }
-
-  test_variableDeclarationStatement_throw() async {
-    _assertTrue("int i = throw new Object();");
-  }
-
-  test_whileStatement_false_nonReturn() async {
-    _assertFalse("{ while (false) {} }");
-  }
-
-  test_whileStatement_throwCondition() async {
-    _assertTrue("{ while (throw '') {} }");
-  }
-
-  test_whileStatement_true_break() async {
-    _assertFalse("{ while (true) { break; } }");
-  }
-
-  test_whileStatement_true_break_and_throw() async {
-    _assertFalse("{ while (true) { if (1==1) break; throw 'T'; } }");
-  }
-
-  test_whileStatement_true_continue() async {
-    _assertTrue("{ while (true) { continue; } }");
-  }
-
-  test_whileStatement_true_continueWithLabel() async {
-    _assertTrue("{ x: while (true) { continue x; } }");
-  }
-
-  test_whileStatement_true_doStatement_scopeRequired() async {
-    _assertTrue("{ while (true) { x: do { continue x; } while (true); } }");
-  }
-
-  test_whileStatement_true_if_return() async {
-    _assertTrue("{ while (true) { if (true) {return null;} } }");
-  }
-
-  test_whileStatement_true_noBreak() async {
-    _assertTrue("{ while (true) {} }");
-  }
-
-  test_whileStatement_true_return() async {
-    _assertTrue("{ while (true) { return null; } }");
-  }
-
-  test_whileStatement_true_throw() async {
-    _assertTrue("{ while (true) { throw ''; } }");
-  }
-
-  void _assertFalse(String source) {
-    _assertHasReturn(false, source);
-  }
-
-  void _assertHasReturn(bool expectedResult, String source) {
-    Statement statement = parseStatement(source,
-        enableLazyAssignmentOperators: enableLazyAssignmentOperators);
-    expect(ExitDetector.exits(statement), expectedResult);
-  }
-
-  void _assertTrue(String source) {
-    _assertHasReturn(true, source);
-  }
-}
-
-/**
- * Tests for the [ExitDetector] that require that the AST be resolved.
- *
- * See [ExitDetectorTest] for tests that do not require the AST to be resolved.
- */
-@reflectiveTest
-class ExitDetectorTest2 extends ResolverTestCase {
-  test_forStatement_implicitTrue_breakWithLabel() async {
-    Source source = addSource(r'''
-void f() {
-  x: for (;;) {
-    if (1 < 2) {
-      break x;
-    }
-    return;
-  }
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
-  test_switch_withEnum_false_noDefault() async {
-    Source source = addSource(r'''
-enum E { A, B }
-String f(E e) {
-  var x;
-  switch (e) {
-    case A:
-      x = 'A';
-    case B:
-      x = 'B';
-  }
-  return x;
-}
-''');
-    _assertNthStatementDoesNotExit(source, 1);
-  }
-
-  test_switch_withEnum_false_withDefault() async {
-    Source source = addSource(r'''
-enum E { A, B }
-String f(E e) {
-  var x;
-  switch (e) {
-    case A:
-      x = 'A';
-    default:
-      x = '?';
-  }
-  return x;
-}
-''');
-    _assertNthStatementDoesNotExit(source, 1);
-  }
-
-  test_switch_withEnum_true_noDefault() async {
-    Source source = addSource(r'''
-enum E { A, B }
-String f(E e) {
-  switch (e) {
-    case A:
-      return 'A';
-    case B:
-      return 'B';
-  }
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
-  test_switch_withEnum_true_withExitingDefault() async {
-    Source source = addSource(r'''
-enum E { A, B }
-String f(E e) {
-  switch (e) {
-    case A:
-      return 'A';
-    default:
-      return '?';
-  }
-}
-''');
-    _assertNthStatementExits(source, 0);
-  }
-
-  test_switch_withEnum_true_withNonExitingDefault() async {
-    Source source = addSource(r'''
-enum E { A, B }
-String f(E e) {
-  var x;
-  switch (e) {
-    case A:
-      return 'A';
-    default:
-      x = '?';
-  }
-}
-''');
-    _assertNthStatementDoesNotExit(source, 1);
-  }
-
-  test_whileStatement_breakWithLabel() async {
-    Source source = addSource(r'''
-void f() {
-  x: while (true) {
-    if (1 < 2) {
-      break x;
-    }
-    return;
-  }
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
-  test_whileStatement_breakWithLabel_afterExiting() async {
-    Source source = addSource(r'''
-void f() {
-  x: while (true) {
-    return;
-    if (1 < 2) {
-      break x;
-    }
-  }
-}
-''');
-    _assertNthStatementExits(source, 0);
-  }
-
-  test_whileStatement_switchWithBreakWithLabel() async {
-    Source source = addSource(r'''
-void f() {
-  x: while (true) {
-    switch (true) {
-      case false: break;
-      case true: break x;
-    }
-  }
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
-  test_yieldStatement_plain() async {
-    Source source = addSource(r'''
-void f() sync* {
-  yield 1;
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
-  test_yieldStatement_star_plain() async {
-    Source source = addSource(r'''
-void f() sync* {
-  yield* 1;
-}
-''');
-    _assertNthStatementDoesNotExit(source, 0);
-  }
-
-  test_yieldStatement_star_throw() async {
-    Source source = addSource(r'''
-void f() sync* {
-  yield* throw '';
-}
-''');
-    _assertNthStatementExits(source, 0);
-  }
-
-  test_yieldStatement_throw() async {
-    Source source = addSource(r'''
-void f() sync* {
-  yield throw '';
-}
-''');
-    _assertNthStatementExits(source, 0);
-  }
-
-  void _assertHasReturn(bool expectedResult, Source source, int n) {
-    LibraryElement element = resolve2(source);
-    CompilationUnit unit = resolveCompilationUnit(source, element);
-    FunctionDeclaration function = unit.declarations.last;
-    BlockFunctionBody body = function.functionExpression.body;
-    Statement statement = body.block.statements[n];
-    expect(ExitDetector.exits(statement), expectedResult);
-  }
-
-  // Assert that the [n]th statement in the last function declaration of
-  // [source] exits.
-  void _assertNthStatementDoesNotExit(Source source, int n) {
-    _assertHasReturn(false, source, n);
-  }
-
-  // Assert that the [n]th statement in the last function declaration of
-  // [source] does not exit.
-  void _assertNthStatementExits(Source source, int n) {
-    _assertHasReturn(true, source, n);
-  }
-}
-
 @reflectiveTest
 class FileBasedSourceTest {
   test_equals_false_differentFiles() async {
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code.dart
new file mode 100644
index 0000000..a666f7a
--- /dev/null
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code.dart
@@ -0,0 +1,683 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All 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:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+
+import 'resolver_test_case.dart';
+
+abstract class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
+  @override
+  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
+
+  test_assertion_throws() async {
+    Source source = addSource(r'''
+class A {
+  const A(int x, int y) : assert(x < y);
+}
+var v = const A(3, 2);
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_extends() async {
+    // According to checked-mode type checking rules, a value of type B is
+    // assignable to a field of type A, because B extends A (and hence is a
+    // subtype of A).
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+class C {
+  final A a;
+  const C(this.a);
+}
+var v = const C(const B());''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() async {
+    // Null always passes runtime type checks, even when the type is
+    // unresolved.
+    Source source = addSource(r'''
+class A {
+  final Unresolved x;
+  const A(String this.x);
+}
+var v = const A(null);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_implements() async {
+    // According to checked-mode type checking rules, a value of type B is
+    // assignable to a field of type A, because B implements A (and hence is a
+    // subtype of A).
+    Source source = addSource(r'''
+class A {}
+class B implements A {
+  const B();
+}
+class C {
+  final A a;
+  const C(this.a);
+}
+var v = const C(const B());''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_list_dynamic() async {
+    // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
+    Source source = addSource(r'''
+class A {
+  const A(List<int> x);
+}
+var x = const A(const [1, 2, 3]);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_list_nonDynamic() async {
+    // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
+    Source source = addSource(r'''
+class A {
+  const A(List<num> x);
+}
+var x = const A(const <int>[1, 2, 3]);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_map_dynamic() async {
+    // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
+    // Map<int, int>.
+    Source source = addSource(r'''
+class A {
+  const A(Map<int, int> x);
+}
+var x = const A(const {1: 2});''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_map_keyDifferent() async {
+    // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
+    // Map<num, int>.
+    Source source = addSource(r'''
+class A {
+  const A(Map<num, int> x);
+}
+var x = const A(const <int, int>{1: 2});''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_map_valueDifferent() async {
+    // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
+    // Map<int, num>.
+    Source source = addSource(r'''
+class A {
+  const A(Map<int, num> x);
+}
+var x = const A(const <int, int>{1: 2});''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_notype() async {
+    // If a field is declared without a type, then any value may be assigned to
+    // it.
+    Source source = addSource(r'''
+class A {
+  final x;
+  const A(this.x);
+}
+var v = const A(5);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_null() async {
+    // Null is assignable to anything.
+    Source source = addSource(r'''
+class A {
+  final int x;
+  const A(this.x);
+}
+var v = const A(null);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_typedef() async {
+    // foo has the runtime type dynamic -> dynamic, so it is not assignable
+    // to A.f.
+    Source source = addSource(r'''
+typedef String Int2String(int x);
+class A {
+  final Int2String f;
+  const A(this.f);
+}
+foo(x) => 1;
+var v = const A(foo);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterAssignableToField_typeSubstitution() async {
+    // foo has the runtime type dynamic -> dynamic, so it should be assignable
+    // to A.f.
+    Source source = addSource(r'''
+class A<T> {
+  final T x;
+  const A(this.x);
+}
+var v = const A<int>(3);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  const A(this.x);
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_extends() async {
+    // According to checked-mode type checking rules, a value of type A is not
+    // assignable to a field of type B, because B extends A (the subtyping
+    // relationship is in the wrong direction).
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+class C {
+  final B b;
+  const C(this.b);
+}
+const A u = const A();
+var v = const C(u);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_fieldType() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  const A(this.x);
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() async {
+    Source source = addSource(r'''
+class A {
+  final Unresolved x;
+  const A(String this.x);
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.UNDEFINED_CLASS
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_implements() async {
+    // According to checked-mode type checking rules, a value of type A is not
+    // assignable to a field of type B, because B implements A (the subtyping
+    // relationship is in the wrong direction).
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B implements A {}
+class C {
+  final B b;
+  const C(this.b);
+}
+const A u = const A();
+var v = const C(u);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_list() async {
+    // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
+    Source source = addSource(r'''
+class A {
+  const A(List<int> x);
+}
+const dynamic w = const <num>[1, 2, 3];
+var x = const A(w);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_map_keyMismatch() async {
+    // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
+    // Map<int, int>.
+    Source source = addSource(r'''
+class A {
+  const A(Map<int, int> x);
+}
+const dynamic w = const <num, int>{1: 2};
+var x = const A(w);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_map_valueMismatch() async {
+    // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
+    // Map<int, int>.
+    Source source = addSource(r'''
+class A {
+  const A(Map<int, int> x);
+}
+const dynamic w = const <int, num>{1: 2};
+var x = const A(w);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_optional() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  const A([this.x = 'foo']);
+}
+var v = const A();''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticTypeWarningCode.INVALID_ASSIGNMENT
+    ]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameterNotAssignableToField_typedef() async {
+    // foo has the runtime type String -> int, so it should not be assignable
+    // to A.f (A.f requires it to be int -> String).
+    Source source = addSource(r'''
+typedef String Int2String(int x);
+class A {
+  final Int2String f;
+  const A(this.f);
+}
+int foo(String x) => 1;
+var v = const A(foo);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_fieldInitializerNotAssignable() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  const A() : x = '';
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+      StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_fieldTypeMismatch() async {
+    Source source = addSource(r'''
+class A {
+  const A(x) : y = x;
+  final int y;
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
+    ]);
+    verify([source]);
+  }
+
+  test_fieldTypeMismatch_generic() async {
+    Source source = addSource(r'''
+class C<T> {
+  final T x = y;
+  const C();
+}
+const int y = 1;
+var v = const C<String>();
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+      source,
+      [
+        CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+        StaticTypeWarningCode.INVALID_ASSIGNMENT
+      ],
+    );
+    verify([source]);
+  }
+
+  test_fieldTypeMismatch_unresolved() async {
+    Source source = addSource(r'''
+class A {
+  const A(x) : y = x;
+  final Unresolved y;
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+      StaticWarningCode.UNDEFINED_CLASS
+    ]);
+    verify([source]);
+  }
+
+  test_fieldTypeOk_generic() async {
+    Source source = addSource(r'''
+class C<T> {
+  final T x = y;
+  const C();
+}
+const int y = 1;
+var v = const C<int>();
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+      source,
+      [StaticTypeWarningCode.INVALID_ASSIGNMENT],
+    );
+    verify([source]);
+  }
+
+  test_fieldTypeOk_null() async {
+    Source source = addSource(r'''
+class A {
+  const A(x) : y = x;
+  final int y;
+}
+var v = const A(null);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldTypeOk_unresolved_null() async {
+    // Null always passes runtime type checks, even when the type is
+    // unresolved.
+    Source source = addSource(r'''
+class A {
+  const A(x) : y = x;
+  final Unresolved y;
+}
+var v = const A(null);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+    verify([source]);
+  }
+
+  test_listElementTypeNotAssignable() async {
+    Source source = addSource("var v = const <String> [42];");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+      StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_listLiteral_inferredElementType() async {
+    Source source = addSource('''
+const Object x = [1];
+const List<String> y = x;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+    verify([source]);
+  }
+
+  test_mapKeyTypeNotAssignable() async {
+    Source source = addSource("var v = const <String, int > {1 : 2};");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+      StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_mapLiteral_inferredKeyType() async {
+    Source source = addSource('''
+const Object x = {1: 1};
+const Map<String, dynamic> y = x;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+    verify([source]);
+  }
+
+  test_mapLiteral_inferredValueType() async {
+    Source source = addSource('''
+const Object x = {1: 1};
+const Map<dynamic, String> y = x;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
+    verify([source]);
+  }
+
+  test_mapValueTypeNotAssignable() async {
+    Source source = addSource("var v = const <String, String> {'a' : 2};");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+      StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_parameterAssignable_null() async {
+    // Null is assignable to anything.
+    Source source = addSource(r'''
+class A {
+  const A(int x);
+}
+var v = const A(null);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_parameterAssignable_typeSubstitution() async {
+    Source source = addSource(r'''
+class A<T> {
+  const A(T x);
+}
+var v = const A<int>(3);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_parameterAssignable_undefined_null() async {
+    // Null always passes runtime type checks, even when the type is
+    // unresolved.
+    Source source = addSource(r'''
+class A {
+  const A(Unresolved x);
+}
+var v = const A(null);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+    verify([source]);
+  }
+
+  test_parameterNotAssignable() async {
+    Source source = addSource(r'''
+class A {
+  const A(int x);
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_parameterNotAssignable_typeSubstitution() async {
+    Source source = addSource(r'''
+class A<T> {
+  const A(T x);
+}
+var v = const A<int>('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_parameterNotAssignable_undefined() async {
+    Source source = addSource(r'''
+class A {
+  const A(Unresolved x);
+}
+var v = const A('foo');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+      StaticWarningCode.UNDEFINED_CLASS
+    ]);
+    verify([source]);
+  }
+
+  test_redirectingConstructor_paramTypeMismatch() async {
+    Source source = addSource(r'''
+class A {
+  const A.a1(x) : this.a2(x);
+  const A.a2(String x);
+}
+var v = const A.a1(0);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    verify([source]);
+  }
+
+  test_superConstructor_paramTypeMismatch() async {
+    Source source = addSource(r'''
+class C {
+  final double d;
+  const C(this.d);
+}
+class D extends C {
+  const D(d) : super(d);
+}
+const f = const D('0.0');
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    verify([source]);
+  }
+
+  test_topLevelVarAssignable_null() async {
+    Source source = addSource("const int x = null;");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_topLevelVarAssignable_undefined_null() async {
+    // Null always passes runtime type checks, even when the type is
+    // unresolved.
+    Source source = addSource("const Unresolved x = null;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+    verify([source]);
+  }
+
+  test_topLevelVarNotAssignable() async {
+    Source source = addSource("const int x = 'foo';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+      StaticTypeWarningCode.INVALID_ASSIGNMENT
+    ]);
+    verify([source]);
+  }
+
+  test_topLevelVarNotAssignable_undefined() async {
+    Source source = addSource("const Unresolved x = 'foo';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
+      StaticWarningCode.UNDEFINED_CLASS
+    ]);
+    verify([source]);
+  }
+}
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart
index 2a3d968..f8d85f2 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart
@@ -7,7 +7,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'checked_mode_compile_time_error_code_test.dart';
+import 'checked_mode_compile_time_error_code.dart';
 import 'resolver_test_case.dart';
 
 main() {
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
deleted file mode 100644
index 6bfb23d..0000000
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ /dev/null
@@ -1,691 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
-  });
-}
-
-@reflectiveTest
-class CheckedModeCompileTimeErrorCodeTest extends ResolverTestCase {
-  @override
-  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
-
-  test_assertion_throws() async {
-    Source source = addSource(r'''
-class A {
-  const A(int x, int y) : assert(x < y);
-}
-var v = const A(3, 2);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_extends() async {
-    // According to checked-mode type checking rules, a value of type B is
-    // assignable to a field of type A, because B extends A (and hence is a
-    // subtype of A).
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-class C {
-  final A a;
-  const C(this.a);
-}
-var v = const C(const B());''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    Source source = addSource(r'''
-class A {
-  final Unresolved x;
-  const A(String this.x);
-}
-var v = const A(null);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_implements() async {
-    // According to checked-mode type checking rules, a value of type B is
-    // assignable to a field of type A, because B implements A (and hence is a
-    // subtype of A).
-    Source source = addSource(r'''
-class A {}
-class B implements A {
-  const B();
-}
-class C {
-  final A a;
-  const C(this.a);
-}
-var v = const C(const B());''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_list_dynamic() async {
-    // [1, 2, 3] has type List<dynamic>, which is a subtype of List<int>.
-    Source source = addSource(r'''
-class A {
-  const A(List<int> x);
-}
-var x = const A(const [1, 2, 3]);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_list_nonDynamic() async {
-    // <int>[1, 2, 3] has type List<int>, which is a subtype of List<num>.
-    Source source = addSource(r'''
-class A {
-  const A(List<num> x);
-}
-var x = const A(const <int>[1, 2, 3]);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_map_dynamic() async {
-    // {1: 2} has type Map<dynamic, dynamic>, which is a subtype of
-    // Map<int, int>.
-    Source source = addSource(r'''
-class A {
-  const A(Map<int, int> x);
-}
-var x = const A(const {1: 2});''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_map_keyDifferent() async {
-    // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
-    // Map<num, int>.
-    Source source = addSource(r'''
-class A {
-  const A(Map<num, int> x);
-}
-var x = const A(const <int, int>{1: 2});''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_map_valueDifferent() async {
-    // <int, int>{1: 2} has type Map<int, int>, which is a subtype of
-    // Map<int, num>.
-    Source source = addSource(r'''
-class A {
-  const A(Map<int, num> x);
-}
-var x = const A(const <int, int>{1: 2});''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_notype() async {
-    // If a field is declared without a type, then any value may be assigned to
-    // it.
-    Source source = addSource(r'''
-class A {
-  final x;
-  const A(this.x);
-}
-var v = const A(5);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_null() async {
-    // Null is assignable to anything.
-    Source source = addSource(r'''
-class A {
-  final int x;
-  const A(this.x);
-}
-var v = const A(null);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_typedef() async {
-    // foo has the runtime type dynamic -> dynamic, so it is not assignable
-    // to A.f.
-    Source source = addSource(r'''
-typedef String Int2String(int x);
-class A {
-  final Int2String f;
-  const A(this.f);
-}
-foo(x) => 1;
-var v = const A(foo);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterAssignableToField_typeSubstitution() async {
-    // foo has the runtime type dynamic -> dynamic, so it should be assignable
-    // to A.f.
-    Source source = addSource(r'''
-class A<T> {
-  final T x;
-  const A(this.x);
-}
-var v = const A<int>(3);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  const A(this.x);
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_extends() async {
-    // According to checked-mode type checking rules, a value of type A is not
-    // assignable to a field of type B, because B extends A (the subtyping
-    // relationship is in the wrong direction).
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-class C {
-  final B b;
-  const C(this.b);
-}
-const A u = const A();
-var v = const C(u);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_fieldType() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  const A(this.x);
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() async {
-    Source source = addSource(r'''
-class A {
-  final Unresolved x;
-  const A(String this.x);
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.UNDEFINED_CLASS
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_implements() async {
-    // According to checked-mode type checking rules, a value of type A is not
-    // assignable to a field of type B, because B implements A (the subtyping
-    // relationship is in the wrong direction).
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B implements A {}
-class C {
-  final B b;
-  const C(this.b);
-}
-const A u = const A();
-var v = const C(u);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_list() async {
-    // <num>[1, 2, 3] has type List<num>, which is not a subtype of List<int>.
-    Source source = addSource(r'''
-class A {
-  const A(List<int> x);
-}
-const dynamic w = const <num>[1, 2, 3];
-var x = const A(w);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_map_keyMismatch() async {
-    // <num, int>{1: 2} has type Map<num, int>, which is not a subtype of
-    // Map<int, int>.
-    Source source = addSource(r'''
-class A {
-  const A(Map<int, int> x);
-}
-const dynamic w = const <num, int>{1: 2};
-var x = const A(w);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_map_valueMismatch() async {
-    // <int, num>{1: 2} has type Map<int, num>, which is not a subtype of
-    // Map<int, int>.
-    Source source = addSource(r'''
-class A {
-  const A(Map<int, int> x);
-}
-const dynamic w = const <int, num>{1: 2};
-var x = const A(w);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_optional() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  const A([this.x = 'foo']);
-}
-var v = const A();''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticTypeWarningCode.INVALID_ASSIGNMENT
-    ]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameterNotAssignableToField_typedef() async {
-    // foo has the runtime type String -> int, so it should not be assignable
-    // to A.f (A.f requires it to be int -> String).
-    Source source = addSource(r'''
-typedef String Int2String(int x);
-class A {
-  final Int2String f;
-  const A(this.f);
-}
-int foo(String x) => 1;
-var v = const A(foo);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_fieldInitializerNotAssignable() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  const A() : x = '';
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
-      StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_fieldTypeMismatch() async {
-    Source source = addSource(r'''
-class A {
-  const A(x) : y = x;
-  final int y;
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH
-    ]);
-    verify([source]);
-  }
-
-  test_fieldTypeMismatch_generic() async {
-    Source source = addSource(r'''
-class C<T> {
-  final T x = y;
-  const C();
-}
-const int y = 1;
-var v = const C<String>();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
-      [
-        CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
-        StaticTypeWarningCode.INVALID_ASSIGNMENT
-      ],
-    );
-    verify([source]);
-  }
-
-  test_fieldTypeMismatch_unresolved() async {
-    Source source = addSource(r'''
-class A {
-  const A(x) : y = x;
-  final Unresolved y;
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
-      StaticWarningCode.UNDEFINED_CLASS
-    ]);
-    verify([source]);
-  }
-
-  test_fieldTypeOk_generic() async {
-    Source source = addSource(r'''
-class C<T> {
-  final T x = y;
-  const C();
-}
-const int y = 1;
-var v = const C<int>();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
-      [StaticTypeWarningCode.INVALID_ASSIGNMENT],
-    );
-    verify([source]);
-  }
-
-  test_fieldTypeOk_null() async {
-    Source source = addSource(r'''
-class A {
-  const A(x) : y = x;
-  final int y;
-}
-var v = const A(null);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldTypeOk_unresolved_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    Source source = addSource(r'''
-class A {
-  const A(x) : y = x;
-  final Unresolved y;
-}
-var v = const A(null);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
-    verify([source]);
-  }
-
-  test_listElementTypeNotAssignable() async {
-    Source source = addSource("var v = const <String> [42];");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
-      StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_listLiteral_inferredElementType() async {
-    Source source = addSource('''
-const Object x = [1];
-const List<String> y = x;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
-    verify([source]);
-  }
-
-  test_mapKeyTypeNotAssignable() async {
-    Source source = addSource("var v = const <String, int > {1 : 2};");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
-      StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_mapLiteral_inferredKeyType() async {
-    Source source = addSource('''
-const Object x = {1: 1};
-const Map<String, dynamic> y = x;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
-    verify([source]);
-  }
-
-  test_mapLiteral_inferredValueType() async {
-    Source source = addSource('''
-const Object x = {1: 1};
-const Map<dynamic, String> y = x;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH]);
-    verify([source]);
-  }
-
-  test_mapValueTypeNotAssignable() async {
-    Source source = addSource("var v = const <String, String> {'a' : 2};");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
-      StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_parameterAssignable_null() async {
-    // Null is assignable to anything.
-    Source source = addSource(r'''
-class A {
-  const A(int x);
-}
-var v = const A(null);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_parameterAssignable_typeSubstitution() async {
-    Source source = addSource(r'''
-class A<T> {
-  const A(T x);
-}
-var v = const A<int>(3);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_parameterAssignable_undefined_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    Source source = addSource(r'''
-class A {
-  const A(Unresolved x);
-}
-var v = const A(null);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
-    verify([source]);
-  }
-
-  test_parameterNotAssignable() async {
-    Source source = addSource(r'''
-class A {
-  const A(int x);
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_parameterNotAssignable_typeSubstitution() async {
-    Source source = addSource(r'''
-class A<T> {
-  const A(T x);
-}
-var v = const A<int>('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_parameterNotAssignable_undefined() async {
-    Source source = addSource(r'''
-class A {
-  const A(Unresolved x);
-}
-var v = const A('foo');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
-      StaticWarningCode.UNDEFINED_CLASS
-    ]);
-    verify([source]);
-  }
-
-  test_redirectingConstructor_paramTypeMismatch() async {
-    Source source = addSource(r'''
-class A {
-  const A.a1(x) : this.a2(x);
-  const A.a2(String x);
-}
-var v = const A.a1(0);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    verify([source]);
-  }
-
-  test_superConstructor_paramTypeMismatch() async {
-    Source source = addSource(r'''
-class C {
-  final double d;
-  const C(this.d);
-}
-class D extends C {
-  const D(d) : super(d);
-}
-const f = const D('0.0');
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    verify([source]);
-  }
-
-  test_topLevelVarAssignable_null() async {
-    Source source = addSource("const int x = null;");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_topLevelVarAssignable_undefined_null() async {
-    // Null always passes runtime type checks, even when the type is
-    // unresolved.
-    Source source = addSource("const Unresolved x = null;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
-    verify([source]);
-  }
-
-  test_topLevelVarNotAssignable() async {
-    Source source = addSource("const int x = 'foo';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
-      StaticTypeWarningCode.INVALID_ASSIGNMENT
-    ]);
-    verify([source]);
-  }
-
-  test_topLevelVarNotAssignable_undefined() async {
-    Source source = addSource("const Unresolved x = 'foo';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
-      StaticWarningCode.UNDEFINED_CLASS
-    ]);
-    verify([source]);
-  }
-}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
new file mode 100644
index 0000000..b14a030
--- /dev/null
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -0,0 +1,6464 @@
+// 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:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart' show expect;
+
+import 'resolver_test_case.dart';
+
+class CompileTimeErrorCodeTestBase extends ResolverTestCase {
+  disabled_test_conflictingGenericInterfaces_hierarchyLoop_infinite() async {
+    // There is an interface conflict here due to a loop in the class
+    // hierarchy leading to an infinite set of implemented types; this loop
+    // shouldn't cause non-termination.
+
+    // TODO(paulberry): this test is currently disabled due to non-termination
+    // bugs elsewhere in the analyzer.
+    Source source = addSource('''
+class A<T> implements B<List<T>> {}
+class B<T> implements A<List<T>> {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
+  }
+
+  test_accessPrivateEnumField() async {
+    Source source = addSource(r'''
+enum E { ONE }
+String name(E e) {
+  return e._name;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD]);
+    // Cannot verify because "_name" cannot be resolved.
+  }
+
+  test_ambiguousExport() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';
+export 'lib2.dart';''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class N {}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+class N {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.AMBIGUOUS_EXPORT]);
+    verify([source]);
+  }
+
+  test_annotationWithNotClass() async {
+    Source source = addSource('''
+class Property {
+  final int value;
+  const Property(this.value);
+}
+
+const Property property = const Property(42);
+
+@property(123)
+main() {
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_annotationWithNotClass_prefixed() async {
+    addNamedSource("/annotations.dart", r'''
+class Property {
+  final int value;
+  const Property(this.value);
+}
+
+const Property property = const Property(42);
+''');
+    Source source = addSource('''
+import 'annotations.dart' as pref;
+@pref.property(123)
+main() {
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_annotation() async {
+    Source source = addSource('''
+const int async = 0;
+f() async {
+  g(@async x) {}
+  g(0);
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_argument_label() async {
+    Source source = addSource('''
+f(c) async {
+  c.g(async: 0);
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_async_method() async {
+    Source source = addSource('''
+f() async {
+  var async = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_async_star_method() async {
+    Source source = addSource('''
+f() async* {
+  var async = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_break_statement() async {
+    Source source = addSource('''
+f() async {
+  while (true) {
+    break async;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
+      CompileTimeErrorCode.LABEL_UNDEFINED
+    ]);
+    // Note: we don't call verify([source]) because the reference to the
+    // "async" label is unresolved.
+  }
+
+  test_async_used_as_identifier_in_cascaded_invocation() async {
+    Source source = addSource('''
+class C {
+  int async() => 1;
+}
+f() async {
+  return new C()..async();
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_cascaded_setter_invocation() async {
+    Source source = addSource('''
+class C {
+  void set async(int i) {}
+}
+f() async {
+  return new C()..async = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_catch_exception_argument() async {
+    Source source = addSource('''
+g() {}
+f() async {
+  try {
+    g();
+  } catch (async) { }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_catch_stacktrace_argument() async {
+    Source source = addSource('''
+g() {}
+f() async {
+  try {
+    g();
+  } catch (e, async) { }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_continue_statement() async {
+    Source source = addSource('''
+f() async {
+  while (true) {
+    continue async;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
+      CompileTimeErrorCode.LABEL_UNDEFINED
+    ]);
+    // Note: we don't call verify([source]) because the reference to the
+    // "async" label is unresolved.
+  }
+
+  test_async_used_as_identifier_in_for_statement() async {
+    Source source = addSource('''
+var async;
+f() async {
+  for (async in []) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_formal_parameter_name() async {
+    Source source = addSource('''
+f() async {
+  g(int async) {}
+  g(0);
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_getter_name() async {
+    Source source = addSource('''
+class C {
+  int get async => 1;
+}
+f() async {
+  return new C().async;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_invocation() async {
+    Source source = addSource('''
+class C {
+  int async() => 1;
+}
+f() async {
+  return new C().async();
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_local_function_name() async {
+    Source source = addSource('''
+f() async {
+  int async() => null;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_prefix() async {
+    Source source = addSource('''
+import 'dart:async' as async;
+f() async {
+  return new async.Future.value(0);
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_setter_name() async {
+    Source source = addSource('''
+class C {
+  void set async(int i) {}
+}
+f() async {
+  new C().async = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_statement_label() async {
+    Source source = addSource('''
+f() async {
+  async: g();
+}
+g() {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
+      HintCode.UNUSED_LABEL
+    ]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_string_interpolation() async {
+    Source source = addSource(r'''
+int async = 1;
+f() async {
+  return "$async";
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_suffix() async {
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+int async;
+''');
+    Source source = addSource('''
+import 'lib1.dart' as l;
+f() async {
+  return l.async;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_switch_label() async {
+    Source source = addSource('''
+f() async {
+  switch (0) {
+    async: case 0: break;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
+      HintCode.UNUSED_LABEL
+    ]);
+    verify([source]);
+  }
+
+  test_async_used_as_identifier_in_sync_star_method() async {
+    Source source = addSource('''
+f() sync* {
+  var async = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_asyncForInWrongContext() async {
+    Source source = addSource(r'''
+f(list) {
+  await for (var e in list) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT]);
+    verify([source]);
+  }
+
+  test_await_used_as_identifier_in_async_method() async {
+    Source source = addSource('''
+f() async {
+  var await = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_await_used_as_identifier_in_async_star_method() async {
+    Source source = addSource('''
+f() async* {
+  var await = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_await_used_as_identifier_in_sync_star_method() async {
+    Source source = addSource('''
+f() sync* {
+  var await = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_awaitInWrongContext_sync() async {
+    // This test requires better error recovery than we currently have. In
+    // particular, we need to be able to distinguish between an await expression
+    // in the wrong context, and the use of 'await' as an identifier.
+    Source source = addSource(r'''
+f(x) {
+  return await x;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT]);
+    verify([source]);
+  }
+
+  test_awaitInWrongContext_syncStar() async {
+    // This test requires better error recovery than we currently have. In
+    // particular, we need to be able to distinguish between an await expression
+    // in the wrong context, and the use of 'await' as an identifier.
+    Source source = addSource(r'''
+f(x) sync* {
+  yield await x;
+}''');
+    await computeAnalysisResult(source);
+    if (usingFastaParser) {
+      assertErrors(source, [CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT]);
+    }
+    verify([source]);
+  }
+
+  test_bug_23176() async {
+    Source source = addSource('''
+class A {
+  const A([x]);
+}
+class B {
+  dynamic @A(const A()) x;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+                ParserErrorCode.EXPECTED_TOKEN
+              ]
+            : [
+                ParserErrorCode.EXPECTED_CLASS_MEMBER,
+                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
+              ]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsMixinName_classTypeAlias() async {
+    Source source = addSource(r'''
+class A {}
+class B {}
+class as = A with B;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsPrefixName() async {
+    Source source = addSource("import 'dart:async' as abstract;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_PREFIX_NAME,
+      HintCode.UNUSED_IMPORT
+    ]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsType_dynamicMissingPrefix() async {
+    Source source = addSource(r"""
+import 'dart:core' as core;
+
+dynamic x;
+""");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
+  }
+
+  test_builtInIdentifierAsType_formalParameter_field() async {
+    Source source = addSource(r'''
+class A {
+  var x;
+  A(static this.x);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [ParserErrorCode.EXTRANEOUS_MODIFIER]
+            : [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsType_formalParameter_simple() async {
+    Source source = addSource(r'''
+f(static x) {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [ParserErrorCode.EXTRANEOUS_MODIFIER]
+            : [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsType_variableDeclaration() async {
+    Source source = addSource(r'''
+f() {
+  typedef x;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                StaticWarningCode.UNDEFINED_IDENTIFIER,
+                StaticWarningCode.UNDEFINED_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
+              ]
+            : [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsTypedefName_functionTypeAlias() async {
+    Source source = addSource("typedef bool as();");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsTypeName() async {
+    Source source = addSource("class as {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsTypeParameterName() async {
+    Source source = addSource("class A<as> {}");
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]);
+    verify([source]);
+  }
+
+  test_caseExpressionTypeImplementsEquals() async {
+    Source source = addSource(r'''
+class IntWrapper {
+  final int value;
+  const IntWrapper(this.value);
+  bool operator ==(Object x) {
+    return x is IntWrapper && x.value == value;
+  }
+  get hashCode => value;
+}
+
+f(var a) {
+  switch(a) {
+    case(const IntWrapper(1)) : return 1;
+    default: return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_conflictingGenericInterfaces_hierarchyLoop() async {
+    // There is no interface conflict here, but there is a loop in the class
+    // hierarchy leading to a finite set of implemented types; this loop
+    // shouldn't cause non-termination.
+    Source source = addSource('''
+class A<T> implements B<T> {}
+class B<T> implements A<T> {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+  }
+
+  test_conflictingGenericInterfaces_noConflict() async {
+    Source source = addSource('''
+class I<T> {}
+class A implements I<int> {}
+class B implements I<int> {}
+class C extends A implements B {}
+    ''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_conflictingTypeVariableAndClass() async {
+    Source source = addSource(r'''
+class T<T> {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS]);
+    verify([source]);
+  }
+
+  test_conflictingTypeVariableAndMember_field() async {
+    Source source = addSource(r'''
+class A<T> {
+  var T;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
+    verify([source]);
+  }
+
+  test_conflictingTypeVariableAndMember_getter() async {
+    Source source = addSource(r'''
+class A<T> {
+  get T => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
+    verify([source]);
+  }
+
+  test_conflictingTypeVariableAndMember_method() async {
+    Source source = addSource(r'''
+class A<T> {
+  T() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
+    verify([source]);
+  }
+
+  test_conflictingTypeVariableAndMember_method_static() async {
+    Source source = addSource(r'''
+class A<T> {
+  static T() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
+    verify([source]);
+  }
+
+  test_conflictingTypeVariableAndMember_setter() async {
+    Source source = addSource(r'''
+class A<T> {
+  set T(x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
+    verify([source]);
+  }
+
+  test_consistentCaseExpressionTypes_dynamic() async {
+    // Even though A.S and S have a static type of "dynamic", we should see
+    // that they match 'abc', because they are constant strings.
+    Source source = addSource(r'''
+class A {
+  static const S = 'A.S';
+}
+
+const S = 'S';
+
+foo(var p) {
+  switch (p) {
+    case S:
+      break;
+    case A.S:
+      break;
+    case 'abc':
+      break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_const_invalid_constructorFieldInitializer_fromLibrary() async {
+    addNamedSource('/lib.dart', r'''
+class A<T> {
+  final int f;
+  const A() : f = T.foo;
+}
+''');
+    Source source = addSource(r'''
+import 'lib.dart';
+const a = const A();
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+  }
+
+  test_constConstructor_redirect_generic() async {
+    Source source = addSource(r'''
+class A<T> {
+  const A(T value) : this._(value);
+  const A._(T value) : value = value;
+  final T value;
+}
+
+void main(){
+  const A<int>(1);
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithFieldInitializedByNonConst() async {
+    Source source = addSource(r'''
+class A {
+  final int i = f();
+  const A();
+}
+int f() {
+  return 3;
+}''');
+    // TODO(paulberry): the error CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE is
+    // redundant and ought to be suppressed.
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode
+          .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
+      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+    ]);
+    verify([source]);
+  }
+
+  test_constConstructorWithFieldInitializedByNonConst_static() async {
+    Source source = addSource(r'''
+class A {
+  static final int i = f();
+  const A();
+}
+int f() {
+  return 3;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonConstSuper_explicit() async {
+    Source source = addSource(r'''
+class A {
+  A();
+}
+class B extends A {
+  const B(): super();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonConstSuper_implicit() async {
+    Source source = addSource(r'''
+class A {
+  A();
+}
+class B extends A {
+  const B();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonFinalField_mixin() async {
+    Source source = addSource(r'''
+class A {
+  var a;
+}
+class B extends Object with A {
+  const B();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
+      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
+    ]);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonFinalField_super() async {
+    Source source = addSource(r'''
+class A {
+  var a;
+}
+class B extends A {
+  const B();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
+      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
+    ]);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonFinalField_this() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
+    verify([source]);
+  }
+
+  test_constDeferredClass() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {
+  const A();
+}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+main() {
+  const a.A();
+}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.CONST_DEFERRED_CLASS
+    ]);
+  }
+
+  test_constDeferredClass_namedConstructor() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {
+  const A.b();
+}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+main() {
+  const a.A.b();
+}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.CONST_DEFERRED_CLASS
+    ]);
+  }
+
+  test_constEval_newInstance_constConstructor() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+const a = new A();''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+    verify([source]);
+  }
+
+  test_constEval_newInstance_externalFactoryConstConstructor() async {
+    // We can't evaluate "const A()" because its constructor is external.  But
+    // the code is correct--we shouldn't report an error.
+    Source source = addSource(r'''
+class A {
+  external const factory A();
+}
+const x = const A();''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEval_nonStaticField_inGenericClass() async {
+    Source source = addSource('''
+class C<T> {
+  const C();
+  T get t => null;
+}
+
+const x = const C().t;''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+    verify([source]);
+  }
+
+  test_constEval_propertyExtraction_targetNotConst() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  int m() => 0;
+}
+final a = const A();
+const C = a.m;''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+    verify([source]);
+  }
+
+  test_constEvalThrowsException() async {
+    Source source = addSource(r'''
+class C {
+  const C();
+}
+f() { return const C(); }''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]);
+    verify([source]);
+  }
+
+  test_constEvalThrowsException_binaryMinus_null() async {
+    await _check_constEvalThrowsException_binary_null("null - 5", false);
+    await _check_constEvalThrowsException_binary_null("5 - null", true);
+  }
+
+  test_constEvalThrowsException_binaryPlus_null() async {
+    await _check_constEvalThrowsException_binary_null("null + 5", false);
+    await _check_constEvalThrowsException_binary_null("5 + null", true);
+  }
+
+  test_constEvalThrowsException_divisionByZero() async {
+    Source source = addSource("const C = 1 ~/ 0;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE]);
+    verify([source]);
+  }
+
+  test_constEvalThrowsException_finalAlreadySet_initializer() async {
+    // If a final variable has an initializer at the site of its declaration,
+    // and at the site of the constructor, then invoking that constructor would
+    // produce a runtime error; hence invoking that constructor via the "const"
+    // keyword results in a compile-time error.
+    Source source = addSource('''
+class C {
+  final x = 1;
+  const C() : x = 2;
+}
+var x = const C();
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
+    ]);
+    verify([source]);
+  }
+
+  test_constEvalThrowsException_finalAlreadySet_initializing_formal() async {
+    // If a final variable has an initializer at the site of its declaration,
+    // and it is initialized using an initializing formal at the site of the
+    // constructor, then invoking that constructor would produce a runtime
+    // error; hence invoking that constructor via the "const" keyword results
+    // in a compile-time error.
+    Source source = addSource('''
+class C {
+  final x = 1;
+  const C(this.x);
+}
+var x = const C(2);
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
+    ]);
+    verify([source]);
+  }
+
+  test_constEvalThrowsException_unaryBitNot_null() async {
+    Source source = addSource("const C = ~null;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    // no verify(), '~null' is not resolved
+  }
+
+  test_constEvalThrowsException_unaryNegated_null() async {
+    Source source = addSource("const C = -null;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    // no verify(), '-null' is not resolved
+  }
+
+  test_constEvalThrowsException_unaryNot_null() async {
+    Source source = addSource("const C = !null;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    verify([source]);
+  }
+
+  test_constEvalTypeBool_binary() async {
+    await _check_constEvalTypeBool_withParameter_binary("p && ''");
+    await _check_constEvalTypeBool_withParameter_binary("p || ''");
+  }
+
+  test_constEvalTypeBool_binary_leftTrue() async {
+    Source source = addSource("const C = (true || 0);");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [StaticTypeWarningCode.NON_BOOL_OPERAND, HintCode.DEAD_CODE]);
+    verify([source]);
+  }
+
+  test_constEvalTypeBool_logicalOr_trueLeftOperand() async {
+    Source source = addSource(r'''
+class C {
+  final int x;
+  const C({this.x}) : assert(x == null || x >= 0);
+}
+const c = const C();
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEvalTypeBoolNumString_equal() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B {
+  final a;
+  const B(num p) : a = p == const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
+    verify([source]);
+  }
+
+  test_constEvalTypeBoolNumString_notEqual() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B {
+  final a;
+  const B(String p) : a = p != const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
+    verify([source]);
+  }
+
+  test_constEvalTypeInt_binary() async {
+    await _check_constEvalTypeBoolOrInt_withParameter_binary("p ^ ''");
+    await _check_constEvalTypeBoolOrInt_withParameter_binary("p & ''");
+    await _check_constEvalTypeBoolOrInt_withParameter_binary("p | ''");
+    await _check_constEvalTypeInt_withParameter_binary("p >> ''");
+    await _check_constEvalTypeInt_withParameter_binary("p << ''");
+  }
+
+  test_constEvalTypeNum_binary() async {
+    await _check_constEvalTypeNum_withParameter_binary("p + ''");
+    await _check_constEvalTypeNum_withParameter_binary("p - ''");
+    await _check_constEvalTypeNum_withParameter_binary("p * ''");
+    await _check_constEvalTypeNum_withParameter_binary("p / ''");
+    await _check_constEvalTypeNum_withParameter_binary("p ~/ ''");
+    await _check_constEvalTypeNum_withParameter_binary("p > ''");
+    await _check_constEvalTypeNum_withParameter_binary("p < ''");
+    await _check_constEvalTypeNum_withParameter_binary("p >= ''");
+    await _check_constEvalTypeNum_withParameter_binary("p <= ''");
+    await _check_constEvalTypeNum_withParameter_binary("p % ''");
+  }
+
+  test_constFormalParameter_fieldFormalParameter() async {
+    Source source = addSource(r'''
+class A {
+  var x;
+  A(const this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
+                ParserErrorCode.EXTRANEOUS_MODIFIER
+              ]
+            : [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
+    verify([source]);
+  }
+
+  test_constFormalParameter_simpleFormalParameter() async {
+    Source source = addSource("f(const x) {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
+                ParserErrorCode.EXTRANEOUS_MODIFIER
+              ]
+            : [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
+    verify([source]);
+  }
+
+  test_constInitializedWithNonConstValue() async {
+    Source source = addSource(r'''
+f(p) {
+  const C = p;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
+    verify([source]);
+  }
+
+  test_constInitializedWithNonConstValue_finalField() async {
+    // Regression test for bug #25526 which previously
+    // caused two errors to be reported.
+    Source source = addSource(r'''
+class Foo {
+  final field = 0;
+  foo([int x = field]) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_constInitializedWithNonConstValue_missingConstInListLiteral() async {
+    Source source = addSource("const List L = [0];");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constInitializedWithNonConstValue_missingConstInMapLiteral() async {
+    Source source = addSource("const Map M = {'a' : 0};");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constInitializedWithNonConstValueFromDeferredClass() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const V = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+const B = a.V;'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode
+          .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_constInitializedWithNonConstValueFromDeferredClass_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const V = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+const B = a.V + 1;'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode
+          .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_constInstanceField() async {
+    Source source = addSource(r'''
+class C {
+  const int f = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
+    verify([source]);
+  }
+
+  test_constMapKeyTypeImplementsEquals_direct() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  operator ==(other) => false;
+}
+main() {
+  const {const A() : 0};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_constMapKeyTypeImplementsEquals_dynamic() async {
+    // Note: static type of B.a is "dynamic", but actual type of the const
+    // object is A.  We need to make sure we examine the actual type when
+    // deciding whether there is a problem with operator==.
+    Source source = addSource(r'''
+class A {
+  const A();
+  operator ==(other) => false;
+}
+class B {
+  static const a = const A();
+}
+main() {
+  const {B.a : 0};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_constMapKeyTypeImplementsEquals_factory() async {
+    Source source = addSource(r'''
+class A { const factory A() = B; }
+
+class B implements A {
+  const B();
+
+  operator ==(o) => true;
+}
+
+main() {
+  var m = const { const A(): 42 };
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_constMapKeyTypeImplementsEquals_super() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  operator ==(other) => false;
+}
+class B extends A {
+  const B();
+}
+main() {
+  const {const B() : 0};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_constWithInvalidTypeParameters() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+f() { return const A<A>(); }''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+
+  test_constWithInvalidTypeParameters_tooFew() async {
+    Source source = addSource(r'''
+class A {}
+class C<K, V> {
+  const C();
+}
+f(p) {
+  return const C<A>();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+
+  test_constWithInvalidTypeParameters_tooMany() async {
+    Source source = addSource(r'''
+class A {}
+class C<E> {
+  const C();
+}
+f(p) {
+  return const C<A, A>();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
+    verify([source]);
+  }
+
+  test_constWithNonConst() async {
+    Source source = addSource(r'''
+class T {
+  T(a, b, {c, d}) {}
+}
+f() { return const T(0, 1, c: 2, d: 3); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONST]);
+    verify([source]);
+  }
+
+  test_constWithNonConst_in_const_context() async {
+    Source source = addSource(r'''
+class A {
+  const A(x);
+}
+class B {
+}
+main() {
+  const A(B());
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONST]);
+    verify([source]);
+  }
+
+  test_constWithNonConstantArgument_annotation() async {
+    Source source = addSource(r'''
+class A {
+  const A(int p);
+}
+var v = 42;
+@A(v)
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
+    verify([source]);
+  }
+
+  test_constWithNonConstantArgument_instanceCreation() async {
+    Source source = addSource(r'''
+class A {
+  const A(a);
+}
+f(p) { return const A(p); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
+    ]);
+    verify([source]);
+  }
+
+  test_constWithNonType() async {
+    Source source = addSource(r'''
+int A;
+f() {
+  return const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
+    verify([source]);
+  }
+
+  test_constWithNonType_fromLibrary() async {
+    Source source1 = addNamedSource("/lib.dart", "");
+    Source source2 = addNamedSource("/lib2.dart", r'''
+import 'lib.dart' as lib;
+void f() {
+  const lib.A();
+}''');
+    await computeAnalysisResult(source1);
+    await computeAnalysisResult(source2);
+    assertErrors(source2, [CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
+    verify([source1]);
+  }
+
+  test_constWithTypeParameters_direct() async {
+    Source source = addSource(r'''
+class A<T> {
+  static const V = const A<T>();
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
+      StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC
+    ]);
+    verify([source]);
+  }
+
+  test_constWithTypeParameters_indirect() async {
+    Source source = addSource(r'''
+class A<T> {
+  static const V = const A<List<T>>();
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
+      StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC
+    ]);
+    verify([source]);
+  }
+
+  test_constWithUndefinedConstructor() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+f() {
+  return const A.noSuchConstructor();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
+    // no verify(), 'noSuchConstructor' is not resolved
+  }
+
+  test_constWithUndefinedConstructorDefault() async {
+    Source source = addSource(r'''
+class A {
+  const A.name();
+}
+f() {
+  return const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypeAlias_new_named() async {
+    Source source = addSource('''
+typedef F = int Function({Map<String, String> m: const {}});
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
+      StrongModeCode.INVALID_CAST_LITERAL_MAP
+    ]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypeAlias_new_positional() async {
+    Source source = addSource('''
+typedef F = int Function([Map<String, String> m = const {}]);
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
+      StrongModeCode.INVALID_CAST_LITERAL_MAP
+    ]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypeAlias_old_named() async {
+    Source source = addSource("typedef F([x = 0]);");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
+                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
+              ]
+            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypeAlias_old_positional() async {
+    Source source = addSource("typedef F([x = 0]);");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
+                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
+              ]
+            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypedParameter_named() async {
+    Source source = addSource("f(g({p: null})) {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
+                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
+              ]
+            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypedParameter_optional() async {
+    Source source = addSource("f(g([p = null])) {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
+                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
+              ]
+            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
+    verify([source]);
+  }
+
+  test_defaultValueInRedirectingFactoryConstructor() async {
+    Source source = addSource(r'''
+class A {
+  factory A([int x = 0]) = B;
+}
+
+class B implements A {
+  B([int x = 1]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
+    ]);
+    verify([source]);
+  }
+
+  test_deferredImportWithInvalidUri() async {
+    Source source = addSource(r'''
+import '[invalid uri]' deferred as p;
+main() {
+  p.loadLibrary();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+  }
+
+  test_duplicateDefinition_acrossLibraries() async {
+    Source librarySource = addNamedSource("/lib.dart", r'''
+library lib;
+
+part 'a.dart';
+part 'b.dart';''');
+    Source sourceA = addNamedSource("/a.dart", r'''
+part of lib;
+
+class A {}''');
+    Source sourceB = addNamedSource("/b.dart", r'''
+part of lib;
+
+class A {}''');
+    await computeAnalysisResult(librarySource);
+    await computeAnalysisResult(sourceA);
+    await computeAnalysisResult(sourceB);
+    assertNoErrors(librarySource);
+    assertErrors(sourceB, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([librarySource, sourceA, sourceB]);
+  }
+
+  test_duplicateDefinition_catch() async {
+    Source source = addSource(r'''
+main() {
+  try {} catch (e, e) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_inPart() async {
+    Source librarySource = addNamedSource("/lib.dart", r'''
+library test;
+part 'a.dart';
+class A {}''');
+    Source sourceA = addNamedSource("/a.dart", r'''
+part of test;
+class A {}''');
+    await computeAnalysisResult(librarySource);
+    await computeAnalysisResult(sourceA);
+    assertNoErrors(librarySource);
+    assertErrors(sourceA, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([librarySource, sourceA]);
+  }
+
+  test_duplicateDefinition_locals_inCase() async {
+    Source source = addSource(r'''
+main() {
+  switch(1) {
+    case 1:
+      var a;
+      var a;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_locals_inFunctionBlock() async {
+    Source source = addSource(r'''
+main() {
+  int m = 0;
+  m(a) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_locals_inIf() async {
+    Source source = addSource(r'''
+main(int p) {
+  if (p != 0) {
+    var a;
+    var a;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_locals_inMethodBlock() async {
+    Source source = addSource(r'''
+class A {
+  m() {
+    int a;
+    int a;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_parameters_inConstructor() async {
+    Source source = addSource(r'''
+class A {
+  int a;
+  A(int a, this.a);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_parameters_inFunctionTypeAlias() async {
+    Source source = addSource(r'''
+typedef F(int a, double a);
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_parameters_inLocalFunction() async {
+    Source source = addSource(r'''
+main() {
+  f(int a, double a) {
+  };
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_parameters_inMethod() async {
+    Source source = addSource(r'''
+class A {
+  m(int a, double a) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_parameters_inTopLevelFunction() async {
+    Source source = addSource(r'''
+f(int a, double a) {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_typeParameters() async {
+    Source source = addSource(r'''
+class A<T, T> {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_duplicateNamedArgument() async {
+    Source source = addSource(r'''
+f({a, b}) {}
+main() {
+  f(a: 1, a: 2);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT]);
+    verify([source]);
+  }
+
+  test_duplicatePart_sameSource() async {
+    addNamedSource('/part.dart', 'part of lib;');
+    Source source = addSource(r'''
+library lib;
+part 'part.dart';
+part 'foo/../part.dart';
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_PART]);
+    verify([source]);
+  }
+
+  test_duplicatePart_sameUri() async {
+    addNamedSource('/part.dart', 'part of lib;');
+    Source source = addSource(r'''
+library lib;
+part 'part.dart';
+part 'part.dart';
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_PART]);
+    verify([source]);
+  }
+
+  test_exportInternalLibrary() async {
+    Source source = addSource("export 'dart:_interceptors';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]);
+    verify([source]);
+  }
+
+  test_exportOfNonLibrary() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';''');
+    addNamedSource("/lib1.dart", "part of lib;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
+    verify([source]);
+  }
+
+  test_extendsDeferredClass() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class B extends a.A {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS
+    ]);
+  }
+
+  test_extendsDeferredClass_classTypeAlias() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class M {}
+class C = a.A with M;'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS
+    ]);
+  }
+
+  test_extendsDisallowedClass_class_bool() async {
+    Source source = addSource("class A extends bool {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
+      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+    ]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_class_double() async {
+    Source source = addSource("class A extends double {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_class_int() async {
+    Source source = addSource("class A extends int {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
+      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+    ]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_class_Null() async {
+    Source source = addSource("class A extends Null {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
+      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+    ]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_class_num() async {
+    Source source = addSource("class A extends num {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_class_String() async {
+    Source source = addSource("class A extends String {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
+      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+    ]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_classTypeAlias_bool() async {
+    Source source = addSource(r'''
+class M {}
+class C = bool with M;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_classTypeAlias_double() async {
+    Source source = addSource(r'''
+class M {}
+class C = double with M;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_classTypeAlias_int() async {
+    Source source = addSource(r'''
+class M {}
+class C = int with M;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_classTypeAlias_Null() async {
+    Source source = addSource(r'''
+class M {}
+class C = Null with M;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_classTypeAlias_num() async {
+    Source source = addSource(r'''
+class M {}
+class C = num with M;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extendsDisallowedClass_classTypeAlias_String() async {
+    Source source = addSource(r'''
+class M {}
+class C = String with M;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_extraPositionalArguments_const() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+main() {
+  const A(0);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
+    verify([source]);
+  }
+
+  test_extraPositionalArguments_const_super() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B extends A {
+  const B() : super(0);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
+    verify([source]);
+  }
+
+  test_extraPositionalArgumentsCouldBeNamed_const() async {
+    Source source = addSource(r'''
+class A {
+  const A({int x});
+}
+main() {
+  const A(0);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED]);
+    verify([source]);
+  }
+
+  test_extraPositionalArgumentsCouldBeNamed_const_super() async {
+    Source source = addSource(r'''
+class A {
+  const A({int x});
+}
+class B extends A {
+  const B() : super(0);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED]);
+    verify([source]);
+  }
+
+  test_fieldFormalParameter_assignedInInitializer() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A(this.x) : x = 3 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_fieldInitializedByMultipleInitializers() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A() : x = 0, x = 1 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
+    verify([source]);
+  }
+
+  test_fieldInitializedByMultipleInitializers_multipleInits() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A() : x = 0, x = 1, x = 2 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
+      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS
+    ]);
+    verify([source]);
+  }
+
+  test_fieldInitializedByMultipleInitializers_multipleNames() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  int y;
+  A() : x = 0, x = 1, y = 0, y = 1 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
+      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS
+    ]);
+    verify([source]);
+  }
+
+  test_fieldInitializedInParameterAndInitializer() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A(this.x) : x = 1 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_fieldInitializerFactoryConstructor() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  factory A(this.x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_fieldInitializerOutsideConstructor() async {
+    // TODO(brianwilkerson) Fix the duplicate error messages.
+    Source source = addSource(r'''
+class A {
+  int x;
+  m(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+      CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+    ]);
+    verify([source]);
+  }
+
+  test_fieldInitializerOutsideConstructor_defaultParameter() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  m([this.x]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_fieldInitializerOutsideConstructor_inFunctionTypeParameter() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A(int p(this.x));
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_fieldInitializerRedirectingConstructor_afterRedirection() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A.named() {}
+  A() : this.named(), x = 42;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_fieldInitializerRedirectingConstructor_beforeRedirection() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A.named() {}
+  A() : x = 42, this.named();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_fieldInitializingFormalRedirectingConstructor() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A.named() {}
+  A(this.x) : this.named();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_finalInitializedMultipleTimes_initializers() async {
+    Source source = addSource(r'''
+class A {
+  final x;
+  A() : x = 0, x = 0 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
+    verify([source]);
+  }
+
+  /**
+   * This test doesn't test the FINAL_INITIALIZED_MULTIPLE_TIMES code, but tests the
+   * FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER code instead. It is provided here to show
+   * coverage over all of the permutations of initializers in constructor declarations.
+   *
+   * Note: FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER covers a subset of
+   * FINAL_INITIALIZED_MULTIPLE_TIMES, since it more specific, we use it instead of the broader code
+   */
+  test_finalInitializedMultipleTimes_initializingFormal_initializer() async {
+    Source source = addSource(r'''
+class A {
+  final x;
+  A(this.x) : x = 0 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_finalInitializedMultipleTimes_initializingFormals() async {
+    Source source = addSource(r'''
+class A {
+  final x;
+  A(this.x, this.x) {}
+}''');
+    // TODO(brianwilkerson) There should only be one error here.
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.DUPLICATE_DEFINITION,
+      CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES
+    ]);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_instanceField_const_static() async {
+    Source source = addSource(r'''
+class A {
+  static const F;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_library_const() async {
+    Source source = addSource("const F;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_local_const() async {
+    Source source = addSource(r'''
+f() {
+  const int x;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
+    verify([source]);
+  }
+
+  test_forInWithConstVariable_forEach_identifier() async {
+    Source source = addSource(r'''
+f() {
+  const x = 0;
+  for (x in [0, 1, 2]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+    verify([source]);
+  }
+
+  test_forInWithConstVariable_forEach_loopVariable() async {
+    Source source = addSource(r'''
+f() {
+  for (const x in [0, 1, 2]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+    verify([source]);
+  }
+
+  test_fromEnvironment_bool_badArgs() async {
+    Source source = addSource(r'''
+var b1 = const bool.fromEnvironment(1);
+var b2 = const bool.fromEnvironment('x', defaultValue: 1);''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_fromEnvironment_bool_badDefault_whenDefined() async {
+    // The type of the defaultValue needs to be correct even when the default
+    // value isn't used (because the variable is defined in the environment).
+    if (enableNewAnalysisDriver) {
+      driver.declaredVariables = new DeclaredVariables.fromMap({'x': 'true'});
+    } else {
+      (analysisContext2 as AnalysisContextImpl).declaredVariables =
+          new DeclaredVariables.fromMap({'x': 'true'});
+    }
+    Source source =
+        addSource("var b = const bool.fromEnvironment('x', defaultValue: 1);");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeArgument_inference_function() async {
+    Source source = addSource(r'''
+T f<T>(T t) => null;
+main() { f(<S>(S s) => s); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeArgument_inference_functionType() async {
+    Source source = addSource(r'''
+T Function<T>(T) f;
+main() { f(<S>(S s) => s); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeArgument_inference_method() async {
+    Source source = addSource(r'''
+class C {
+  T f<T>(T t) => null;
+}
+main() { new C().f(<S>(S s) => s); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeAsBound_class() async {
+    Source source = addSource(r'''
+class C<T extends S Function<S>(S)> {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeAsBound_genericFunction() async {
+    Source source = addSource(r'''
+T Function<T extends S Function<S>(S)>(T) fun;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeAsBound_genericFunctionTypedef() async {
+    Source source = addSource(r'''
+typedef foo = T Function<T extends S Function<S>(S)>(T t);
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeAsBound_parameterOfFunction() async {
+    Source source = addSource(r'''
+class C<T extends void Function(S Function<S>(S))> {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeAsBound_typedef() async {
+    Source source = addSource(r'''
+typedef T foo<T extends S Function<S>(S)>(T t);
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypedParameter() async {
+    // Once dartbug.com/28515 is fixed, this syntax should no longer generate an
+    // error.
+    // TODO(paulberry): When dartbug.com/28515 is fixed, convert this into a
+    // NonErrorResolverTest.
+    Source source = addSource('void g(T f<T>(T x)) {}');
+    await computeAnalysisResult(source);
+    var expectedErrorCodes = <ErrorCode>[
+      CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED
+    ];
+    if (enableNewAnalysisDriver) {
+      // Due to dartbug.com/28515, some additional errors appear when using the
+      // new analysis driver.
+      expectedErrorCodes.addAll([
+        StaticWarningCode.UNDEFINED_CLASS,
+        StaticWarningCode.UNDEFINED_CLASS
+      ]);
+    }
+    assertErrors(source, expectedErrorCodes);
+    verify([source]);
+  }
+
+  test_implementsDeferredClass() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class B implements a.A {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS
+    ]);
+  }
+
+  test_implementsDeferredClass_classTypeAlias() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class B {}
+class M {}
+class C = B with M implements a.A;'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS
+    ]);
+  }
+
+  test_implementsDisallowedClass_class_bool() async {
+    Source source = addSource("class A implements bool {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_class_double() async {
+    Source source = addSource("class A implements double {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_class_int() async {
+    Source source = addSource("class A implements int {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_class_Null() async {
+    Source source = addSource("class A implements Null {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_class_num() async {
+    Source source = addSource("class A implements num {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_class_String() async {
+    Source source = addSource("class A implements String {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_class_String_num() async {
+    Source source = addSource("class A implements String, num {}");
+    await computeAnalysisResult(source);
+    if (enableNewAnalysisDriver) {
+      assertErrors(source, [
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
+      ]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
+      ]);
+    }
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_bool() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements bool;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_double() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements double;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_int() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements int;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_Null() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements Null;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_num() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements num;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_String() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements String;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsDisallowedClass_classTypeAlias_String_num() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class C = A with M implements String, num;''');
+    await computeAnalysisResult(source);
+    if (enableNewAnalysisDriver) {
+      assertErrors(source, [
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
+      ]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
+        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
+      ]);
+    }
+    verify([source]);
+  }
+
+  test_implementsNonClass_class() async {
+    Source source = addSource(r'''
+int A;
+class B implements A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsNonClass_dynamic() async {
+    Source source = addSource("class A implements dynamic {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsNonClass_enum() async {
+    Source source = addSource(r'''
+enum E { ONE }
+class A implements E {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsNonClass_typeAlias() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+int B;
+class C = A with M implements B;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsSuperClass() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A implements A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsSuperClass_Object() async {
+    Source source = addSource("class A implements Object {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsSuperClass_Object_typeAlias() async {
+    Source source = addSource(r'''
+class M {}
+class A = Object with M implements Object;
+    ''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
+    verify([source]);
+  }
+
+  test_implementsSuperClass_typeAlias() async {
+    Source source = addSource(r'''
+class A {}
+class M {}
+class B = A with M implements A;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_field() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f;
+  var f;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_field2() async {
+    Source source = addSource(r'''
+class A {
+  final x = 0;
+  final y = x;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+      StrongModeCode.TOP_LEVEL_INSTANCE_GETTER
+    ]);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_invocation() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f();
+  f() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_invocationInStatic() async {
+    Source source = addSource(r'''
+class A {
+  static var F = m();
+  int m() => 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_redirectingConstructorInvocation() async {
+    Source source = addSource(r'''
+class A {
+  A(p) {}
+  A.named() : this(f);
+  var f;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_superConstructorInvocation() async {
+    Source source = addSource(r'''
+class A {
+  A(p) {}
+}
+class B extends A {
+  B() : super(f);
+  var f;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_importInternalLibrary() async {
+    Source source = addSource("import 'dart:_interceptors';");
+    // Note, in these error cases we may generate an UNUSED_IMPORT hint, while
+    // we could prevent the hint from being generated by testing the import
+    // directive for the error, this is such a minor corner case that we don't
+    // think we should add the additional computation time to figure out such
+    // cases.
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, HintCode.UNUSED_IMPORT]);
+    verify([source]);
+  }
+
+  test_importOfNonLibrary() async {
+    Source source = addSource(r'''
+library lib;
+import 'part.dart';
+A a;''');
+    addNamedSource("/part.dart", r'''
+part of lib;
+class A{}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
+    verify([source]);
+  }
+
+  test_inconsistentCaseExpressionTypes() async {
+    Source source = addSource(r'''
+f(var p) {
+  switch (p) {
+    case 1:
+      break;
+    case 'a':
+      break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES]);
+    verify([source]);
+  }
+
+  test_inconsistentCaseExpressionTypes_dynamic() async {
+    // Even though A.S and S have a static type of "dynamic", we should see
+    // that they fail to match 3, because they are constant strings.
+    Source source = addSource(r'''
+class A {
+  static const S = 'A.S';
+}
+
+const S = 'S';
+
+foo(var p) {
+  switch (p) {
+    case 3:
+      break;
+    case S:
+      break;
+    case A.S:
+      break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
+      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES
+    ]);
+    verify([source]);
+  }
+
+  test_inconsistentCaseExpressionTypes_repeated() async {
+    Source source = addSource(r'''
+f(var p) {
+  switch (p) {
+    case 1:
+      break;
+    case 'a':
+      break;
+    case 'b':
+      break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
+      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES
+    ]);
+    verify([source]);
+  }
+
+  test_initializerForNonExistent_const() async {
+    // Check that the absence of a matching field doesn't cause a
+    // crash during constant evaluation.
+    Source source = addSource(r'''
+class A {
+  const A() : x = 'foo';
+}
+A a = const A();''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD]);
+  }
+
+  test_initializerForNonExistent_initializer() async {
+    Source source = addSource(r'''
+class A {
+  A() : x = 0 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD]);
+  }
+
+  test_initializerForStaticField() async {
+    Source source = addSource(r'''
+class A {
+  static int x;
+  A() : x = 0 {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD]);
+    verify([source]);
+  }
+
+  test_initializingFormalForNonExistentField() async {
+    Source source = addSource(r'''
+class A {
+  A(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
+    verify([source]);
+  }
+
+  test_initializingFormalForNonExistentField_notInEnclosingClass() async {
+    Source source = addSource(r'''
+class A {
+int x;
+}
+class B extends A {
+  B(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
+    verify([source]);
+  }
+
+  test_initializingFormalForNonExistentField_optional() async {
+    Source source = addSource(r'''
+class A {
+  A([this.x]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
+    verify([source]);
+  }
+
+  test_initializingFormalForNonExistentField_synthetic() async {
+    Source source = addSource(r'''
+class A {
+  int get x => 1;
+  A(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
+    verify([source]);
+  }
+
+  test_initializingFormalForStaticField() async {
+    Source source = addSource(r'''
+class A {
+  static int x;
+  A([this.x]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD]);
+    verify([source]);
+  }
+
+  test_instanceMemberAccessFromFactory_named() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+  A();
+  factory A.make() {
+    m();
+    return new A();
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY]);
+    verify([source]);
+  }
+
+  test_instanceMemberAccessFromFactory_unnamed() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+  A._();
+  factory A() {
+    m();
+    return new A._();
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY]);
+    verify([source]);
+  }
+
+  test_instanceMemberAccessFromStatic_field() async {
+    Source source = addSource(r'''
+class A {
+  int f;
+  static foo() {
+    f;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
+    verify([source]);
+  }
+
+  test_instanceMemberAccessFromStatic_getter() async {
+    Source source = addSource(r'''
+class A {
+  get g => null;
+  static foo() {
+    g;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
+    verify([source]);
+  }
+
+  test_instanceMemberAccessFromStatic_method() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+  static foo() {
+    m();
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
+    verify([source]);
+  }
+
+  test_instantiate_to_bounds_not_matching_bounds() async {
+    Source source = addSource('''
+class Foo<T> {}
+class Bar<T extends Foo<T>> {}
+class Baz extends Bar {}
+void main() {}
+''');
+    var result = await computeAnalysisResult(source);
+    // Instantiate-to-bounds should have instantiated "Bar" to "Bar<Foo>"
+    expect(result.unit.declaredElement.getType('Baz').supertype.toString(),
+        'Bar<Foo<dynamic>>');
+    // Therefore there should be an error, since Bar's type argument T is Foo,
+    // which doesn't extends Foo<T>.
+    assertErrors(
+        source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_instantiateEnum_const() async {
+    Source source = addSource(r'''
+enum E { ONE }
+E e(String name) {
+  return const E();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INSTANTIATE_ENUM]);
+    verify([source]);
+  }
+
+  test_instantiateEnum_new() async {
+    Source source = addSource(r'''
+enum E { ONE }
+E e(String name) {
+  return new E();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INSTANTIATE_ENUM]);
+    verify([source]);
+  }
+
+  test_integerLiteralAsDoubleOutOfRange_excessiveExponent() async {
+    Source source = addSource(
+        'double x = 0xfffffffffffff80000000000000000000000000000000000000000000'
+        '0000000000000000000000000000000000000000000000000000000000000000000000'
+        '0000000000000000000000000000000000000000000000000000000000000000000000'
+        '000000000000000000000000000000000000000000000000000000000000;');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE]);
+    AnalysisError error = analysisResults[source].errors[0];
+
+    // Check that we suggest the max double instead.
+    expect(
+        true,
+        error.correction.contains(
+            '179769313486231570814527423731704356798070567525844996598917476803'
+            '157260780028538760589558632766878171540458953514382464234321326889'
+            '464182768467546703537516986049910576551282076245490090389328944075'
+            '868508455133942304583236903222948165808559332123348274797826204144'
+            '723168738177180919299881250404026184124858368'));
+  }
+
+  test_integerLiteralAsDoubleOutOfRange_excessiveMantissa() async {
+    Source source = addSource('double x = 9223372036854775809;');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE]);
+    AnalysisError error = analysisResults[source].errors[0];
+    // Check that we suggest a valid double instead.
+    expect(true, error.correction.contains('9223372036854775808'));
+  }
+
+  test_integerLiteralOutOfRange_negative() async {
+    Source source = addSource('int x = -9223372036854775809;');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE]);
+  }
+
+  test_integerLiteralOutOfRange_positive() async {
+    Source source = addSource('int x = 9223372036854775808;');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE]);
+  }
+
+  test_invalidAnnotation_importWithPrefix_notConstantVariable() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+final V = 0;''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.V
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_importWithPrefix_notVariableOrConstructorInvocation() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+typedef V();''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.V
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_notConstantVariable() async {
+    Source source = addSource(r'''
+final V = 0;
+@V
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_notVariableOrConstructorInvocation() async {
+    Source source = addSource(r'''
+typedef V();
+@V
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_staticMethodReference() async {
+    Source source = addSource(r'''
+class A {
+  static f() {}
+}
+@A.f
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
+    verify([source]);
+  }
+
+  test_invalidAnnotationFromDeferredLibrary() async {
+    // See test_invalidAnnotation_notConstantVariable
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class V { const V(); }
+const v = const V();''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+@a.v main () {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_invalidAnnotationFromDeferredLibrary_constructor() async {
+    // See test_invalidAnnotation_notConstantVariable
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class C { const C(); }''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+@a.C() main () {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_invalidAnnotationFromDeferredLibrary_namedConstructor() async {
+    // See test_invalidAnnotation_notConstantVariable
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class C { const C.name(); }''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+@a.C.name() main () {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_invalidAnnotationGetter_getter() async {
+    Source source = addSource(r'''
+get V => 0;
+@V
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION_GETTER]);
+    verify([source]);
+  }
+
+  test_invalidAnnotationGetter_importWithPrefix_getter() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+get V => 0;''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.V
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION_GETTER]);
+    verify([source]);
+  }
+
+  test_invalidConstructorName_notEnclosingClassName_defined() async {
+    Source source = addSource(r'''
+class A {
+  B() : super();
+}
+class B {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
+    // no verify() call, "B" is not resolved
+  }
+
+  test_invalidConstructorName_notEnclosingClassName_undefined() async {
+    Source source = addSource(r'''
+class A {
+  B() : super();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
+    // no verify() call, "B" is not resolved
+  }
+
+  test_invalidFactoryNameNotAClass_notClassName() async {
+    Source source = addSource(r'''
+int B;
+class A {
+  factory B() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
+    verify([source]);
+  }
+
+  test_invalidFactoryNameNotAClass_notEnclosingClassName() async {
+    Source source = addSource(r'''
+class A {
+  factory B() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
+    // no verify() call, "B" is not resolved
+  }
+
+  test_invalidIdentifierInAsync_async() async {
+    // TODO(brianwilkerson) Report this error.
+    Source source = addSource(r'''
+class A {
+  m() async {
+    int async;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC]);
+    verify([source]);
+  }
+
+  test_invalidIdentifierInAsync_await() async {
+    // TODO(brianwilkerson) Report this error.
+    Source source = addSource(r'''
+class A {
+  m() async {
+    int await;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC]);
+    verify([source]);
+  }
+
+  test_invalidIdentifierInAsync_yield() async {
+    // TODO(brianwilkerson) Report this error.
+    Source source = addSource(r'''
+class A {
+  m() async {
+    int yield;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnConstructor_async() async {
+    Source source = addSource(r'''
+class A {
+  A() async {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnConstructor_asyncStar() async {
+    Source source = addSource(r'''
+class A {
+  A() async* {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnConstructor_syncStar() async {
+    Source source = addSource(r'''
+class A {
+  A() sync* {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnSetter_member_async() async {
+    Source source = addSource(r'''
+class A {
+  set x(v) async {}
+}''');
+    await computeAnalysisResult(source);
+    // TODO(danrubel): Investigate why error message is duplicated when
+    // using fasta parser.
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
+              ]
+            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnSetter_member_asyncStar() async {
+    Source source = addSource(r'''
+class A {
+  set x(v) async* {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
+              ]
+            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnSetter_member_syncStar() async {
+    Source source = addSource(r'''
+class A {
+  set x(v) sync* {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
+              ]
+            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnSetter_topLevel_async() async {
+    Source source = addSource("set x(v) async {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
+              ]
+            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnSetter_topLevel_asyncStar() async {
+    Source source = addSource("set x(v) async* {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
+              ]
+            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
+    verify([source]);
+  }
+
+  test_invalidModifierOnSetter_topLevel_syncStar() async {
+    Source source = addSource("set x(v) sync* {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
+                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
+              ]
+            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_factoryConstructor() async {
+    Source source = addSource(r'''
+class A {
+  factory A() { return this; }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_instanceVariableInitializer_inConstructor() async {
+    Source source = addSource(r'''
+class A {
+  var f;
+  A() : f = this;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_instanceVariableInitializer_inDeclaration() async {
+    Source source = addSource(r'''
+class A {
+  var f = this;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_staticMethod() async {
+    Source source = addSource(r'''
+class A {
+  static m() { return this; }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_staticVariableInitializer() async {
+    Source source = addSource(r'''
+class A {
+  static A f = this;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_superInitializer() async {
+    Source source = addSource(r'''
+class A {
+  A(var x) {}
+}
+class B extends A {
+  B() : super(this);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_topLevelFunction() async {
+    Source source = addSource("f() { return this; }");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_variableInitializer() async {
+    Source source = addSource("int x = this;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstList() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return const <E>[];
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST]);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstMap() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return const <String, E>{};
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
+    verify([source]);
+  }
+
+  test_invalidUri_export() async {
+    Source source = addSource("export 'ht:';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
+  }
+
+  test_invalidUri_import() async {
+    Source source = addSource("import 'ht:';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
+  }
+
+  test_invalidUri_part() async {
+    Source source = addSource(r'''
+library lib;
+part 'ht:';''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
+  }
+
+  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.
+    Source source = addSource(r'''
+class Foo<T extends num> {
+  const Foo(x, y);
+}
+const x = const Foo<int>(const Foo<int>(0, 1),
+    const <Foo<String>>[]); // (1)
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+    verify([source]);
+  }
+
+  test_isInInstanceVariableInitializer_restored() async {
+    // If ErrorVerifier._isInInstanceVariableInitializer is not properly
+    // restored on exit from visitVariableDeclaration, the error at (1)
+    // won't be detected.
+    Source source = addSource(r'''
+class Foo {
+  var bar;
+  Map foo = {
+    'bar': () {
+        var _bar;
+    },
+    'bop': _foo // (1)
+  };
+  _foo() {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_labelInOuterScope() async {
+    Source source = addSource(r'''
+class A {
+  void m(int i) {
+    l: while (i > 0) {
+      void f() {
+        break l;
+      };
+    }
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE]);
+    // We cannot verify resolution with unresolvable labels
+  }
+
+  test_labelUndefined_break() async {
+    Source source = addSource(r'''
+f() {
+  x: while (true) {
+    break y;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.LABEL_UNDEFINED, HintCode.UNUSED_LABEL]);
+    // We cannot verify resolution with undefined labels
+  }
+
+  test_labelUndefined_continue() async {
+    Source source = addSource(r'''
+f() {
+  x: while (true) {
+    continue y;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.LABEL_UNDEFINED, HintCode.UNUSED_LABEL]);
+    // We cannot verify resolution with undefined labels
+  }
+
+  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)
+    Source source = addSource("const int i = (1 ? 'alpha' : 'beta').length;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
+      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+      StaticTypeWarningCode.NON_BOOL_CONDITION
+    ]);
+    verify([source]);
+  }
+
+  test_memberWithClassName_field() async {
+    Source source = addSource(r'''
+class A {
+  int A = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+    verify([source]);
+  }
+
+  test_memberWithClassName_field2() async {
+    Source source = addSource(r'''
+class A {
+  int z, A, b = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+    verify([source]);
+  }
+
+  test_memberWithClassName_getter() async {
+    Source source = addSource(r'''
+class A {
+  get A => 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
+    verify([source]);
+  }
+
+  test_memberWithClassName_method() async {
+    // no test because indistinguishable from constructor
+  }
+
+  test_mixinClassDeclaresConstructor_classDeclaration() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+class B extends Object with A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+      source,
+      [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
+    );
+    verify([source]);
+  }
+
+  test_mixinClassDeclaresConstructor_typeAlias() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+class B = Object with A;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+      source,
+      [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
+    );
+    verify([source]);
+  }
+
+  test_mixinDeferredClass() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class B extends Object with a.A {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.MIXIN_DEFERRED_CLASS
+    ]);
+  }
+
+  test_mixinDeferredClass_classTypeAlias() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class B {}
+class C = B with a.A;'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.MIXIN_DEFERRED_CLASS
+    ]);
+  }
+
+  test_mixinInference_matchingClass_inPreviousMixin_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+class B {}
+mixin M1 implements A<B> {}
+mixin M2<T> on A<T> {}
+class C extends Object with M1, M2 {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_mixinInference_matchingClass_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+class B {}
+mixin M<T> on A<T> {}
+class C extends A<int> with M {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_mixinInference_noMatchingClass_namedMixinApplication_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+class B {}
+mixin M<T> on A<T> {}
+class C = Object with M;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
+  }
+
+  test_mixinInference_noMatchingClass_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+class B {}
+mixin M<T> on A<T> {}
+class C extends Object with M {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
+  }
+
+  test_mixinInference_noMatchingClass_noSuperclassConstraint_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+class B {}
+mixin M<T> {}
+class C extends Object with M {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_mixinInference_noMatchingClass_typeParametersSupplied_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+class B {}
+mixin M<T> on A<T> {}
+class C extends Object with M<int> {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
+  }
+
+  test_mixinInference_recursiveSubtypeCheck_new_syntax() async {
+    // See dartbug.com/32353 for a detailed explanation.
+    Source source = addSource('''
+class ioDirectory implements ioFileSystemEntity {}
+
+class ioFileSystemEntity {}
+
+abstract class _LocalDirectory
+    extends _LocalFileSystemEntity<_LocalDirectory, ioDirectory>
+    with ForwardingDirectory, DirectoryAddOnsMixin {}
+
+abstract class _LocalFileSystemEntity<T extends FileSystemEntity,
+  D extends ioFileSystemEntity> extends ForwardingFileSystemEntity<T, D> {}
+
+abstract class FileSystemEntity implements ioFileSystemEntity {}
+
+abstract class ForwardingFileSystemEntity<T extends FileSystemEntity,
+  D extends ioFileSystemEntity> implements FileSystemEntity {}
+
+
+mixin ForwardingDirectory<T extends Directory>
+    on ForwardingFileSystemEntity<T, ioDirectory>
+    implements Directory {}
+
+abstract class Directory implements FileSystemEntity, ioDirectory {}
+
+mixin DirectoryAddOnsMixin implements Directory {}
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    var mixins =
+        analysisResult.unit.declaredElement.getType('_LocalDirectory').mixins;
+    expect(mixins[0].toString(), 'ForwardingDirectory<_LocalDirectory>');
+  }
+
+  test_mixinInheritsFromNotObject_classDeclaration_extends() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C extends Object with B {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verify([source]);
+  }
+
+  test_mixinInheritsFromNotObject_classDeclaration_with() async {
+    Source source = addSource(r'''
+class A {}
+class B extends Object with A {}
+class C extends Object with B {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verify([source]);
+  }
+
+  test_mixinInheritsFromNotObject_typeAlias_extends() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C = Object with B;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verify([source]);
+  }
+
+  test_mixinInheritsFromNotObject_typeAlias_with() async {
+    Source source = addSource(r'''
+class A {}
+class B extends Object with A {}
+class C = Object with B;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_class_bool() async {
+    Source source = addSource("class A extends Object with bool {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_class_double() async {
+    Source source = addSource("class A extends Object with double {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_class_int() async {
+    Source source = addSource("class A extends Object with int {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_class_Null() async {
+    Source source = addSource("class A extends Object with Null {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_class_num() async {
+    Source source = addSource("class A extends Object with num {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_class_String() async {
+    Source source = addSource("class A extends Object with String {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_bool() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with bool;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_double() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with double;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_int() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with int;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_Null() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with Null;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_num() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with num;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_String() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with String;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfDisallowedClass_classTypeAlias_String_num() async {
+    Source source = addSource(r'''
+class A {}
+class C = A with String, num;''');
+    await computeAnalysisResult(source);
+    if (enableNewAnalysisDriver) {
+      assertErrors(source, [
+        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
+        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS
+      ]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
+        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS
+      ]);
+    }
+    verify([source]);
+  }
+
+  test_mixinOfNonClass() async {
+    // TODO(brianwilkerson) Compare with MIXIN_WITH_NON_CLASS_SUPERCLASS.
+    Source source = addSource(r'''
+var A;
+class B extends Object mixin A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfNonClass_class() async {
+    Source source = addSource(r'''
+int A;
+class B extends Object with A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfNonClass_enum() async {
+    Source source = addSource(r'''
+enum E { ONE }
+class A extends Object with E {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinOfNonClass_typeAlias() async {
+    Source source = addSource(r'''
+class A {}
+int B;
+class C = A with B;''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_mixinReferencesSuper() async {
+    Source source = addSource(r'''
+class A {
+  toString() => super.toString();
+}
+class B extends Object with A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+    verify([source]);
+  }
+
+  test_mixinWithNonClassSuperclass_class() async {
+    Source source = addSource(r'''
+int A;
+class B {}
+class C extends A with B {}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
+    verify([source]);
+  }
+
+  test_mixinWithNonClassSuperclass_typeAlias() async {
+    Source source = addSource(r'''
+int A;
+class B {}
+class C = A with B;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
+    verify([source]);
+  }
+
+  test_multipleRedirectingConstructorInvocations() async {
+    Source source = addSource(r'''
+class A {
+  A() : this.a(), this.b();
+  A.a() {}
+  A.b() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS]);
+    verify([source]);
+  }
+
+  test_multipleSuperInitializers() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {
+  B() : super(), super() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS,
+      StrongModeCode.INVALID_SUPER_INVOCATION
+    ]);
+    verify([source]);
+  }
+
+  test_nativeClauseInNonSDKCode() async {
+    // TODO(jwren) Move this test somewhere else: This test verifies a parser
+    // error code is generated through the ErrorVerifier, it is not a
+    // CompileTimeErrorCode.
+    Source source = addSource("class A native 'string' {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
+    verify([source]);
+  }
+
+  test_nativeFunctionBodyInNonSDKCode_function() async {
+    // TODO(jwren) Move this test somewhere else: This test verifies a parser
+    // error code is generated through the ErrorVerifier, it is not a
+    // CompileTimeErrorCode.
+    Source source = addSource("int m(a) native 'string';");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
+    verify([source]);
+  }
+
+  test_nativeFunctionBodyInNonSDKCode_method() async {
+    // TODO(jwren) Move this test somewhere else: This test verifies a parser
+    // error code is generated through the ErrorVerifier, it is not a
+    // CompileTimeErrorCode.
+    Source source = addSource(r'''
+class A{
+  static int m(a) native 'string';
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
+    verify([source]);
+  }
+
+  test_noAnnotationConstructorArguments() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+@A
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS]);
+    verify([source]);
+  }
+
+  test_noDefaultSuperConstructorExplicit() async {
+    Source source = addSource(r'''
+class A {
+  A(p);
+}
+class B extends A {
+  B() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]);
+    verify([source]);
+  }
+
+  test_noDefaultSuperConstructorImplicit_superHasParameters() async {
+    Source source = addSource(r'''
+class A {
+  A(p);
+}
+class B extends A {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
+    verify([source]);
+  }
+
+  test_noDefaultSuperConstructorImplicit_superOnlyNamed() async {
+    Source source = addSource(r'''
+class A { A.named() {} }
+class B extends A {}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
+    verify([source]);
+  }
+
+  test_nonConstantAnnotationConstructor_named() async {
+    Source source = addSource(r'''
+class A {
+  A.fromInt() {}
+}
+@A.fromInt()
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_nonConstantAnnotationConstructor_unnamed() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+@A()
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_function_named() async {
+    Source source = addSource(r'''
+int y;
+f({x : y}) {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_function_positional() async {
+    Source source = addSource(r'''
+int y;
+f([x = y]) {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_inConstructor_named() async {
+    Source source = addSource(r'''
+class A {
+  int y;
+  A({x : y}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_inConstructor_positional() async {
+    Source source = addSource(r'''
+class A {
+  int y;
+  A([x = y]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_method_named() async {
+    Source source = addSource(r'''
+class A {
+  int y;
+  m({x : y}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_method_positional() async {
+    Source source = addSource(r'''
+class A {
+  int y;
+  m([x = y]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValueFromDeferredLibrary() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const V = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f({x : a.V}) {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstantDefaultValueFromDeferredLibrary_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const V = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f({x : a.V + 1}) {}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstCaseExpression() async {
+    Source source = addSource(r'''
+f(int p, int q) {
+  switch (p) {
+    case 3 + q:
+      break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION]);
+    verify([source]);
+  }
+
+  test_nonConstCaseExpressionFromDeferredLibrary() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+main (int p) {
+  switch (p) {
+    case a.c:
+      break;
+  }
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstCaseExpressionFromDeferredLibrary_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+main (int p) {
+  switch (p) {
+    case a.c + 1:
+      break;
+  }
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstListElement() async {
+    Source source = addSource(r'''
+f(a) {
+  return const [a];
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
+    verify([source]);
+  }
+
+  test_nonConstListElementFromDeferredLibrary() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+  return const [a.c];
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstListElementFromDeferredLibrary_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+  return const [a.c + 1];
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstMapAsExpressionStatement_begin() async {
+    Source source = addSource(r'''
+f() {
+  {'a' : 0, 'b' : 1}.length;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                // TODO(danrubel): Consider improving recovery
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.UNEXPECTED_TOKEN,
+                ParserErrorCode.UNEXPECTED_TOKEN,
+                ParserErrorCode.UNEXPECTED_TOKEN,
+              ]
+            : [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+    verify([source]);
+  }
+
+  test_nonConstMapAsExpressionStatement_only() async {
+    Source source = addSource(r'''
+f() {
+  {'a' : 0, 'b' : 1};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.UNEXPECTED_TOKEN,
+                ParserErrorCode.UNEXPECTED_TOKEN,
+                ParserErrorCode.UNEXPECTED_TOKEN,
+              ]
+            : [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+    verify([source]);
+  }
+
+  test_nonConstMapKey() async {
+    Source source = addSource(r'''
+f(a) {
+  return const {a : 0};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
+    verify([source]);
+  }
+
+  test_nonConstMapKeyFromDeferredLibrary() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+  return const {a.c : 0};
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstMapKeyFromDeferredLibrary_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+  return const {a.c + 1 : 0};
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstMapValue() async {
+    Source source = addSource(r'''
+f(a) {
+  return const {'a' : a};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
+    verify([source]);
+  }
+
+  test_nonConstMapValueFromDeferredLibrary() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+  return const {'a' : a.c};
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstMapValueFromDeferredLibrary_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+  return const {'a' : a.c + 1};
+}'''
+    ], [
+      CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstValueInInitializer_assert_condition() async {
+    Source source = addSource(r'''
+class A {
+  const A(int i) : assert(i.isNegative);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_assert_message() async {
+    Source source = addSource(r'''
+class A {
+  const A(int i) : assert(i < 0, 'isNegative = ${i.isNegative}');
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_notBool_left() async {
+    Source source = addSource(r'''
+class A {
+  final bool a;
+  const A(String p) : a = p && true;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+      StaticTypeWarningCode.NON_BOOL_OPERAND
+    ]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_notBool_right() async {
+    Source source = addSource(r'''
+class A {
+  final bool a;
+  const A(String p) : a = true && p;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+      StaticTypeWarningCode.NON_BOOL_OPERAND
+    ]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_notInt() async {
+    Source source = addSource(r'''
+class A {
+  final int a;
+  const A(String p) : a = 5 & p;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_notNum() async {
+    Source source = addSource(r'''
+class A {
+  final int a;
+  const A(String p) : a = 5 + p;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_field() async {
+    Source source = addSource(r'''
+class A {
+  static int C;
+  final int a;
+  const A() : a = C;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_instanceCreation() async {
+    Source source = addSource(r'''
+class A {
+  A();
+}
+class B {
+  const B() : a = new A();
+  final a;
+}
+var b = const B();''');
+    // TODO(scheglov): the error CONST_EVAL_THROWS_EXCEPTION is redundant and
+    // ought to be suppressed. Or not?
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION
+    ]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_instanceCreation_inDifferentFile() async {
+    Source sourceA = addNamedSource('/a.dart', r'''
+import 'b.dart';
+const v = const MyClass();
+''');
+    Source sourceB = addNamedSource('/b.dart', r'''
+class MyClass {
+  const MyClass([p = foo]);
+}
+''');
+    await computeAnalysisResult(sourceA);
+    assertNoErrors(sourceA);
+    await computeAnalysisResult(sourceB);
+    assertErrors(sourceB, [
+      CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE,
+      StaticWarningCode.UNDEFINED_IDENTIFIER
+    ]);
+  }
+
+  test_nonConstValueInInitializer_redirecting() async {
+    Source source = addSource(r'''
+class A {
+  static var C;
+  const A.named(p);
+  const A() : this.named(C);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_super() async {
+    Source source = addSource(r'''
+class A {
+  const A(p);
+}
+class B extends A {
+  static var C;
+  const B() : super(C);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializerFromDeferredLibrary_field() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class A {
+  final int x;
+  const A() : x = a.c;
+}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstValueInInitializerFromDeferredLibrary_field_nested() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class A {
+  final int x;
+  const A() : x = a.c + 1;
+}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstValueInInitializerFromDeferredLibrary_redirecting() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class A {
+  const A.named(p);
+  const A() : this.named(a.c);
+}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonConstValueInInitializerFromDeferredLibrary_super() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+const int c = 1;''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+class A {
+  const A(p);
+}
+class B extends A {
+  const B() : super(a.c);
+}'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+    ]);
+  }
+
+  test_nonGenerativeConstructor_explicit() async {
+    Source source = addSource(r'''
+class A {
+  factory A.named() => null;
+}
+class B extends A {
+  B() : super.named();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_nonGenerativeConstructor_implicit() async {
+    Source source = addSource(r'''
+class A {
+  factory A() => null;
+}
+class B extends A {
+  B();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_nonGenerativeConstructor_implicit2() async {
+    Source source = addSource(r'''
+class A {
+  factory A() => null;
+}
+class B extends A {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_notEnoughRequiredArguments_const() async {
+    Source source = addSource(r'''
+class A {
+  const A(int p);
+}
+main() {
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
+    verify([source]);
+  }
+
+  test_notEnoughRequiredArguments_const_super() async {
+    Source source = addSource(r'''
+class A {
+  const A(int p);
+}
+class B extends A {
+  const B() : super();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
+    verify([source]);
+  }
+
+  test_objectCannotExtendAnotherClass() async {
+    Source source = addSource(r'''
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS]);
+    verify([source]);
+  }
+
+  test_optionalParameterInOperator_named() async {
+    Source source = addSource(r'''
+class A {
+  operator +({p}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
+    verify([source]);
+  }
+
+  test_optionalParameterInOperator_positional() async {
+    Source source = addSource(r'''
+class A {
+  operator +([p]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
+    verify([source]);
+  }
+
+  test_partOfNonPart() async {
+    Source source = addSource(r'''
+library l1;
+part 'l2.dart';''');
+    addNamedSource("/l2.dart", "library l2;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.PART_OF_NON_PART]);
+    verify([source]);
+  }
+
+  test_partOfNonPart_self() async {
+    Source source = addSource(r'''
+library lib;
+part 'test.dart';''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.PART_OF_NON_PART]);
+    verify([source]);
+  }
+
+  test_prefix_assignment_compound_in_method() async {
+    addNamedSource('/lib.dart', 'library lib;');
+    Source source = addSource('''
+import 'lib.dart' as p;
+class C {
+  f() {
+    p += 1;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_assignment_compound_not_in_method() async {
+    addNamedSource('/lib.dart', 'library lib;');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  p += 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_assignment_in_method() async {
+    addNamedSource('/lib.dart', 'library lib;');
+    Source source = addSource('''
+import 'lib.dart' as p;
+class C {
+  f() {
+    p = 1;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_assignment_not_in_method() async {
+    addNamedSource('/lib.dart', 'library lib;');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  p = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_conditionalPropertyAccess_call_loadLibrary() async {
+    addNamedSource('/lib.dart', '''
+library lib;
+''');
+    Source source = addSource('''
+import 'lib.dart' deferred as p;
+f() {
+  p?.loadLibrary();
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_conditionalPropertyAccess_get() async {
+    addNamedSource('/lib.dart', '''
+library lib;
+var x;
+''');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  return p?.x;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_conditionalPropertyAccess_get_loadLibrary() async {
+    addNamedSource('/lib.dart', '''
+library lib;
+''');
+    Source source = addSource('''
+import 'lib.dart' deferred as p;
+f() {
+  return p?.loadLibrary;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_conditionalPropertyAccess_set() async {
+    addNamedSource('/lib.dart', '''
+library lib;
+var x;
+''');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  p?.x = null;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefix_conditionalPropertyAccess_set_loadLibrary() async {
+    addNamedSource('/lib.dart', '''
+library lib;
+''');
+    Source source = addSource('''
+import 'lib.dart' deferred as p;
+f() {
+  p?.loadLibrary = null;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefixCollidesWithTopLevelMembers_functionTypeAlias() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A{}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+typedef p();
+p.A a;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+    verify([source]);
+  }
+
+  test_prefixCollidesWithTopLevelMembers_topLevelFunction() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A{}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+p() {}
+p.A a;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+    verify([source]);
+  }
+
+  test_prefixCollidesWithTopLevelMembers_topLevelVariable() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A{}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+var p = null;
+p.A a;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+    verify([source]);
+  }
+
+  test_prefixCollidesWithTopLevelMembers_type() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A{}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+class p {}
+p.A a;''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
+    verify([source]);
+  }
+
+  test_prefixNotFollowedByDot() async {
+    addNamedSource('/lib.dart', 'library lib;');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  return p;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefixNotFollowedByDot_compoundAssignment() async {
+    addNamedSource('/lib.dart', 'library lib;');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  p += 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_prefixNotFollowedByDot_conditionalMethodInvocation() async {
+    addNamedSource('/lib.dart', '''
+library lib;
+g() {}
+''');
+    Source source = addSource('''
+import 'lib.dart' as p;
+f() {
+  p?.g();
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
+    verify([source]);
+  }
+
+  test_privateCollisionInClassTypeAlias_mixinAndMixin() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C = Object with A, B;
+''');
+  }
+
+  test_privateCollisionInClassTypeAlias_mixinAndMixin_indirect() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C = Object with A;
+class D = C with B;
+''');
+  }
+
+  test_privateCollisionInClassTypeAlias_superclassAndMixin() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C = A with B;
+''');
+  }
+
+  test_privateCollisionInClassTypeAlias_superclassAndMixin_same() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C = A with A;
+''');
+  }
+
+  test_privateCollisionInMixinApplication_mixinAndMixin() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C extends Object with A, B {}
+''');
+  }
+
+  test_privateCollisionInMixinApplication_mixinAndMixin_indirect() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C extends Object with A {}
+class D extends C with B {}
+''');
+  }
+
+  test_privateCollisionInMixinApplication_superclassAndMixin() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C extends A with B {}
+''');
+  }
+
+  test_privateCollisionInMixinApplication_superclassAndMixin_same() {
+    return _privateCollisionInMixinApplicationTest('''
+import 'lib1.dart';
+class C extends A with A {}
+''');
+  }
+
+  test_privateOptionalParameter() async {
+    Source source = addSource("f({var _p}) {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+    verify([source]);
+  }
+
+  test_privateOptionalParameter_fieldFormal() async {
+    Source source = addSource(r'''
+class A {
+  var _p;
+  A({this._p: 0});
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+    verify([source]);
+  }
+
+  test_privateOptionalParameter_withDefaultValue() async {
+    Source source = addSource("f({_p : 0}) {}");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
+    verify([source]);
+  }
+
+  test_recursiveCompileTimeConstant() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  final m = const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
+    verify([source]);
+  }
+
+  test_recursiveCompileTimeConstant_cycle() async {
+    Source source = addSource(r'''
+const x = y + 1;
+const y = x + 1;''');
+    await computeAnalysisResult(source);
+    if (!enableNewAnalysisDriver) {
+      assertErrors(source, [
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+      ]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+        StrongModeCode.TOP_LEVEL_CYCLE,
+        StrongModeCode.TOP_LEVEL_CYCLE,
+      ]);
+    }
+    verify([source]);
+  }
+
+  test_recursiveCompileTimeConstant_fromMapLiteral() async {
+    newFile(
+      '/constants.dart',
+      content: r'''
+const int x = y;
+const int y = x;
+''',
+    );
+    Source source = addSource(r'''
+import 'constants.dart';
+final z = {x: 0, y: 1};
+''');
+    await computeAnalysisResult(source);
+    // No errors, because the cycle is not in this source.
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_recursiveCompileTimeConstant_initializer_after_toplevel_var() async {
+    Source source = addSource('''
+const y = const C();
+class C {
+  const C() : x = y;
+  final x;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
+    verify([source]);
+  }
+
+  test_recursiveCompileTimeConstant_singleVariable() async {
+    Source source = addSource(r'''
+const x = x;
+''');
+    await computeAnalysisResult(source);
+    if (!enableNewAnalysisDriver) {
+      assertErrors(source, [
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+      ]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+        StrongModeCode.TOP_LEVEL_CYCLE
+      ]);
+    }
+    verify([source]);
+  }
+
+  test_recursiveCompileTimeConstant_singleVariable_fromConstList() async {
+    Source source = addSource(r'''
+const elems = const [
+  const [
+    1, elems, 3,
+  ],
+];
+''');
+    await computeAnalysisResult(source);
+    if (!enableNewAnalysisDriver) {
+      assertErrors(source, [
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+      ]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
+        StrongModeCode.TOP_LEVEL_CYCLE,
+      ]);
+    }
+    verify([source]);
+  }
+
+  test_recursiveConstructorRedirect() async {
+    Source source = addSource(r'''
+class A {
+  A.a() : this.b();
+  A.b() : this.a();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT
+    ]);
+    verify([source]);
+  }
+
+  test_recursiveConstructorRedirect_directSelfReference() async {
+    Source source = addSource(r'''
+class A {
+  A() : this();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]);
+    verify([source]);
+  }
+
+  test_recursiveFactoryRedirect() async {
+    Source source = addSource(r'''
+class A implements B {
+  factory A() = C;
+}
+class B implements C {
+  factory B() = A;
+}
+class C implements A {
+  factory C() = B;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+    verify([source]);
+  }
+
+  test_recursiveFactoryRedirect_directSelfReference() async {
+    Source source = addSource(r'''
+class A {
+  factory A() = A;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
+    verify([source]);
+  }
+
+  test_recursiveFactoryRedirect_diverging() async {
+    // Analysis should terminate even though the redirections don't reach a
+    // fixed point.  (C<int> redirects to C<C<int>>, then to C<C<C<int>>>, and
+    // so on).
+    Source source = addSource('''
+class C<T> {
+  const factory C() = C<C<T>>;
+}
+main() {
+  const C<int>();
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
+    verify([source]);
+  }
+
+  test_recursiveFactoryRedirect_generic() async {
+    Source source = addSource(r'''
+class A<T> implements B<T> {
+  factory A() = C;
+}
+class B<T> implements C<T> {
+  factory B() = A;
+}
+class C<T> implements A<T> {
+  factory C() = B;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+    verify([source]);
+  }
+
+  test_recursiveFactoryRedirect_named() async {
+    Source source = addSource(r'''
+class A implements B {
+  factory A.nameA() = C.nameC;
+}
+class B implements C {
+  factory B.nameB() = A.nameA;
+}
+class C implements A {
+  factory C.nameC() = B.nameB;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+    verify([source]);
+  }
+
+  /**
+   * "A" references "C" which has cycle with "B". But we should not report problem for "A" - it is
+   * not the part of a cycle.
+   */
+  test_recursiveFactoryRedirect_outsideCycle() async {
+    Source source = addSource(r'''
+class A {
+  factory A() = C;
+}
+class B implements C {
+  factory B() = C;
+}
+class C implements A, B {
+  factory C() = B;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
+      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
+    ]);
+    verify([source]);
+  }
+
+  test_redirectGenerativeToMissingConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A() : this.noSuchConstructor();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR]);
+  }
+
+  test_redirectGenerativeToNonGenerativeConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A() : this.x();
+  factory A.x() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR
+    ]);
+    verify([source]);
+  }
+
+  test_redirectToMissingConstructor_named() async {
+    Source source = addSource(r'''
+class A implements B{
+  A() {}
+}
+class B {
+  const factory B() = A.name;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
+  }
+
+  test_redirectToMissingConstructor_unnamed() async {
+    Source source = addSource(r'''
+class A implements B{
+  A.name() {}
+}
+class B {
+  const factory B() = A;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
+  }
+
+  test_redirectToNonClass_notAType() async {
+    Source source = addSource(r'''
+int A;
+class B {
+  const factory B() = A;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REDIRECT_TO_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_redirectToNonClass_undefinedIdentifier() async {
+    Source source = addSource(r'''
+class B {
+  const factory B() = A;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REDIRECT_TO_NON_CLASS]);
+    verify([source]);
+  }
+
+  test_redirectToNonConstConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A.a() {}
+  const factory A.b() = A.a;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_referencedBeforeDeclaration_hideInBlock_comment() async {
+    Source source = addSource(r'''
+main() {
+  /// [v] is a variable.
+  var v = 2;
+}
+print(x) {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_referencedBeforeDeclaration_hideInBlock_function() async {
+    Source source = addSource(r'''
+var v = 1;
+main() {
+  print(v);
+  v() {}
+}
+print(x) {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_referencedBeforeDeclaration_hideInBlock_local() async {
+    Source source = addSource(r'''
+var v = 1;
+main() {
+  print(v);
+  var v = 2;
+}
+print(x) {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_referencedBeforeDeclaration_hideInBlock_subBlock() async {
+    Source source = addSource(r'''
+var v = 1;
+main() {
+  {
+    print(v);
+  }
+  var v = 2;
+}
+print(x) {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_referencedBeforeDeclaration_inInitializer_closure() async {
+    Source source = addSource(r'''
+main() {
+  var v = () => v;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_referencedBeforeDeclaration_inInitializer_directly() async {
+    Source source = addSource(r'''
+main() {
+  var v = v;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_referencedBeforeDeclaration_type_localFunction() async {
+    Source source = addSource(r'''
+void testTypeRef() {
+  String s = '';
+  int String(int x) => x + 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_referencedBeforeDeclaration_type_localVariable() async {
+    Source source = addSource(r'''
+void testTypeRef() {
+  String s = '';
+  var String = '';
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
+  }
+
+  test_rethrowOutsideCatch() async {
+    Source source = addSource(r'''
+f() {
+  rethrow;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]);
+    verify([source]);
+  }
+
+  test_returnInGenerativeConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A() { return 0; }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_returnInGenerativeConstructor_expressionFunctionBody() async {
+    Source source = addSource(r'''
+class A {
+  A() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_returnInGenerator_asyncStar() async {
+    Source source = addSource(r'''
+f() async* {
+  return 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.RETURN_IN_GENERATOR,
+                CompileTimeErrorCode.RETURN_IN_GENERATOR
+              ]
+            : [CompileTimeErrorCode.RETURN_IN_GENERATOR]);
+    verify([source]);
+  }
+
+  test_returnInGenerator_syncStar() async {
+    Source source = addSource(r'''
+f() sync* {
+  return 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [
+                CompileTimeErrorCode.RETURN_IN_GENERATOR,
+                CompileTimeErrorCode.RETURN_IN_GENERATOR
+              ]
+            : [CompileTimeErrorCode.RETURN_IN_GENERATOR]);
+    verify([source]);
+  }
+
+  test_sharedDeferredPrefix() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+f1() {}''',
+      r'''
+library lib2;
+f2() {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as lib;
+import 'lib2.dart' as lib;
+main() { lib.f1(); lib.f2(); }'''
+    ], <ErrorCode>[
+      CompileTimeErrorCode.SHARED_DEFERRED_PREFIX
+    ]);
+  }
+
+  test_superInInvalidContext_binaryExpression() async {
+    Source source = addSource("var v = super + 0;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.v' is not resolved
+  }
+
+  test_superInInvalidContext_constructorFieldInitializer() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+class B extends A {
+  var f;
+  B() : f = super.m();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.m' is not resolved
+  }
+
+  test_superInInvalidContext_factoryConstructor() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+class B extends A {
+  factory B() {
+    super.m();
+    return null;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.m' is not resolved
+  }
+
+  test_superInInvalidContext_instanceVariableInitializer() async {
+    Source source = addSource(r'''
+class A {
+  var a;
+}
+class B extends A {
+ var b = super.a;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.a' is not resolved
+  }
+
+  test_superInInvalidContext_staticMethod() async {
+    Source source = addSource(r'''
+class A {
+  static m() {}
+}
+class B extends A {
+  static n() { return super.m(); }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.m' is not resolved
+  }
+
+  test_superInInvalidContext_staticVariableInitializer() async {
+    Source source = addSource(r'''
+class A {
+  static int a = 0;
+}
+class B extends A {
+  static int b = super.a;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.a' is not resolved
+  }
+
+  test_superInInvalidContext_topLevelFunction() async {
+    Source source = addSource(r'''
+f() {
+  super.f();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.f' is not resolved
+  }
+
+  test_superInInvalidContext_topLevelVariableInitializer() async {
+    Source source = addSource("var v = super.y;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    // no verify(), 'super.y' is not resolved
+  }
+
+  test_superInitializerInObject() async {
+    Source source = addSource(r'''
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT]);
+    verify([source]);
+  }
+
+  test_superInRedirectingConstructor_redirectionSuper() async {
+    Source source = addSource(r'''
+class A {}
+class B {
+  B() : this.name(), super();
+  B.name() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  test_superInRedirectingConstructor_superRedirection() async {
+    Source source = addSource(r'''
+class A {}
+class B {
+  B() : super(), this.name();
+  B.name() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
+      StrongModeCode.INVALID_SUPER_INVOCATION
+    ]);
+    verify([source]);
+  }
+
+  test_symbol_constructor_badArgs() async {
+    Source source = addSource(r'''
+var s1 = const Symbol('3');
+var s2 = const Symbol(3);
+var s3 = const Symbol();
+var s4 = const Symbol('x', 'y');
+var s5 = const Symbol('x', foo: 'x');''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
+      CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
+      CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
+    ]);
+    verify([source]);
+  }
+
+  test_test_fieldInitializerOutsideConstructor_topLevelFunction() async {
+    Source source = addSource(r'''
+f(this.x(y)) {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source,
+        usingFastaParser
+            ? [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]
+            : [
+                ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+                CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+              ]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_11987() async {
+    Source source = addSource(r'''
+typedef void F(List<G> l);
+typedef void G(List<F> l);
+main() {
+  F foo(G g) => g;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+    ]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_19459() async {
+    // A complex example involving multiple classes.  This is legal, since
+    // typedef F references itself only via a class.
+    Source source = addSource(r'''
+class A<B, C> {}
+abstract class D {
+  f(E e);
+}
+abstract class E extends A<dynamic, F> {}
+typedef D F();
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_functionTypedParameter_returnType() async {
+    Source source = addSource("typedef A(A b());");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_generic() async {
+    Source source = addSource(r'''
+typedef F = void Function(List<G> l);
+typedef G = void Function(List<F> l);
+main() {
+  F foo(G g) => g;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+    ]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_parameterType_named() async {
+    Source source = addSource("typedef A({A a});");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_parameterType_positional() async {
+    Source source = addSource("typedef A([A a]);");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_parameterType_required() async {
+    Source source = addSource("typedef A(A a);");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_parameterType_typeArgument() async {
+    Source source = addSource("typedef A(List<A> a);");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_returnClass_withTypeAlias() async {
+    // A typedef is allowed to indirectly reference itself via a class.
+    Source source = addSource(r'''
+typedef C A();
+typedef A B();
+class C {
+  B a;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_returnType() async {
+    Source source = addSource("typedef A A();");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_returnType_indirect() async {
+    Source source = addSource(r'''
+typedef B A();
+typedef A B();''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+    ]);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_typeVariableBounds() async {
+    Source source = addSource("typedef A<T extends A<int>>();");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+      StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+    ]);
+    verify([source]);
+  }
+
+  test_typeArgumentNotMatchingBounds_const() async {
+    Source source = addSource(r'''
+class A {}
+class B {}
+class G<E extends A> {
+  const G();
+}
+f() { return const G<B>(); }''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+    verify([source]);
+  }
+
+  test_typedef_infiniteParameterBoundCycle() async {
+    Source source = addSource(r'''
+typedef F<X extends F> = F Function();
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+    ]);
+    verify([source]);
+  }
+
+  test_undefinedAnnotation_unresolved_identifier() async {
+    Source source = addSource(r'''
+@unresolved
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
+  }
+
+  test_undefinedAnnotation_unresolved_invocation() async {
+    Source source = addSource(r'''
+@Unresolved()
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
+  }
+
+  test_undefinedAnnotation_unresolved_prefixedIdentifier() async {
+    Source source = addSource(r'''
+import 'dart:math' as p;
+@p.unresolved
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
+  }
+
+  test_undefinedAnnotation_useLibraryScope() async {
+    Source source = addSource(r'''
+@foo
+class A {
+  static const foo = null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
+  }
+
+  test_undefinedClass_const() async {
+    Source source = addSource(r'''
+f() {
+  return const A();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_explicit_named() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {
+  B() : super.named();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER]);
+    // no verify(), "super.named()" is not resolved
+  }
+
+  test_undefinedConstructorInInitializer_explicit_unnamed() async {
+    Source source = addSource(r'''
+class A {
+  A.named() {}
+}
+class B extends A {
+  B() : super();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_implicit() async {
+    Source source = addSource(r'''
+class A {
+  A.named() {}
+}
+class B extends A {
+  B();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
+    verify([source]);
+  }
+
+  test_undefinedNamedParameter() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+main() {
+  const A(p: 0);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER]);
+    // no verify(), 'p' is not resolved
+  }
+
+  test_uriDoesNotExist_export() async {
+    Source source = addSource("export 'unknown.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+  }
+
+  test_uriDoesNotExist_import() async {
+    Source source = addSource("import 'unknown.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+  }
+
+  test_uriDoesNotExist_import_appears_after_deleting_target() async {
+    Source test = addSource("import 'target.dart';");
+    Source target = addNamedSource("/target.dart", "");
+    await computeAnalysisResult(test);
+    assertErrors(test, [HintCode.UNUSED_IMPORT]);
+
+    // Remove the overlay in the same way as AnalysisServer.
+    deleteFile(target.fullName);
+    if (enableNewAnalysisDriver) {
+      driver.removeFile(target.fullName);
+    } else {
+      analysisContext2.setContents(target, null);
+      ChangeSet changeSet = new ChangeSet()..removedSource(target);
+      analysisContext2.applyChanges(changeSet);
+    }
+
+    await computeAnalysisResult(test);
+    assertErrors(test, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+  }
+
+  test_uriDoesNotExist_import_disappears_when_fixed() async {
+    Source source = addSource("import 'target.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+
+    String targetPath = convertPath('/target.dart');
+    if (enableNewAnalysisDriver) {
+      // Add an overlay in the same way as AnalysisServer.
+      fileContentOverlay[targetPath] = '';
+      driver.changeFile(targetPath);
+    } else {
+      // Check that the file is represented as missing.
+      Source target = analysisContext2.getSourcesWithFullName(targetPath).first;
+      expect(analysisContext2.getModificationStamp(target), -1);
+
+      // Add an overlay in the same way as AnalysisServer.
+      analysisContext2
+        ..setContents(target, "")
+        ..handleContentsChanged(target, null, "", true);
+    }
+
+    // Make sure the error goes away.
+    await computeAnalysisResult(source);
+    assertErrors(source, [HintCode.UNUSED_IMPORT]);
+  }
+
+  test_uriDoesNotExist_part() async {
+    Source source = addSource(r'''
+library lib;
+part 'unknown.dart';''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+  }
+
+  test_uriWithInterpolation_constant() async {
+    Source source = addSource("import 'stuff_\$platform.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.URI_WITH_INTERPOLATION,
+      StaticWarningCode.UNDEFINED_IDENTIFIER
+    ]);
+    // We cannot verify resolution with an unresolvable
+    // URI: 'stuff_$platform.dart'
+  }
+
+  test_uriWithInterpolation_nonConstant() async {
+    Source source = addSource(r'''
+library lib;
+part '${'a'}.dart';''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
+    // We cannot verify resolution with an unresolvable URI: '${'a'}.dart'
+  }
+
+  test_wrongNumberOfParametersForOperator1() async {
+    await _check_wrongNumberOfParametersForOperator1("<");
+    await _check_wrongNumberOfParametersForOperator1(">");
+    await _check_wrongNumberOfParametersForOperator1("<=");
+    await _check_wrongNumberOfParametersForOperator1(">=");
+    await _check_wrongNumberOfParametersForOperator1("+");
+    await _check_wrongNumberOfParametersForOperator1("/");
+    await _check_wrongNumberOfParametersForOperator1("~/");
+    await _check_wrongNumberOfParametersForOperator1("*");
+    await _check_wrongNumberOfParametersForOperator1("%");
+    await _check_wrongNumberOfParametersForOperator1("|");
+    await _check_wrongNumberOfParametersForOperator1("^");
+    await _check_wrongNumberOfParametersForOperator1("&");
+    await _check_wrongNumberOfParametersForOperator1("<<");
+    await _check_wrongNumberOfParametersForOperator1(">>");
+    await _check_wrongNumberOfParametersForOperator1("[]");
+  }
+
+  test_wrongNumberOfParametersForOperator_minus() async {
+    Source source = addSource(r'''
+class A {
+  operator -(a, b) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForOperator_tilde() async {
+    await _check_wrongNumberOfParametersForOperator("~", "a");
+    await _check_wrongNumberOfParametersForOperator("~", "a, b");
+  }
+
+  test_wrongNumberOfParametersForSetter_function_named() async {
+    Source source = addSource("set x({p}) {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_function_optional() async {
+    Source source = addSource("set x([p]) {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_function_tooFew() async {
+    Source source = addSource("set x() {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_function_tooMany() async {
+    Source source = addSource("set x(a, b) {}");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_method_named() async {
+    Source source = addSource(r'''
+class A {
+  set x({p}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_method_optional() async {
+    Source source = addSource(r'''
+class A {
+  set x([p]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_method_tooFew() async {
+    Source source = addSource(r'''
+class A {
+  set x() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForSetter_method_tooMany() async {
+    Source source = addSource(r'''
+class A {
+  set x(a, b) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
+    verify([source]);
+  }
+
+  test_yield_used_as_identifier_in_async_method() async {
+    Source source = addSource('''
+f() async {
+  var yield = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_yield_used_as_identifier_in_async_star_method() async {
+    Source source = addSource('''
+f() async* {
+  var yield = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_yield_used_as_identifier_in_sync_star_method() async {
+    Source source = addSource('''
+f() sync* {
+  var yield = 1;
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
+    verify([source]);
+  }
+
+  test_yieldEachInNonGenerator_async() async {
+    // TODO(brianwilkerson) We are currently parsing the yield statement as a
+    // binary expression.
+    Source source = addSource(r'''
+f() async {
+  yield* 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR]);
+    verify([source]);
+  }
+
+  test_yieldEachInNonGenerator_sync() async {
+    // TODO(brianwilkerson) We are currently parsing the yield statement as a
+    // binary expression.
+    Source source = addSource(r'''
+f() {
+  yield* 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.YIELD_IN_NON_GENERATOR]);
+    verify([source]);
+  }
+
+  test_yieldInNonGenerator_async() async {
+    // TODO(brianwilkerson) We are currently trying to parse the yield statement
+    // as a binary expression.
+    Source source = addSource(r'''
+f() async {
+  yield 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.YIELD_IN_NON_GENERATOR]);
+    verify([source]);
+  }
+
+  test_yieldInNonGenerator_sync() async {
+    // TODO(brianwilkerson) We are currently trying to parse the yield statement
+    // as a binary expression.
+    Source source = addSource(r'''
+f() {
+  yield 0;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR]);
+    verify([source]);
+  }
+
+  Future<void> _check_constEvalThrowsException_binary_null(
+      String expr, bool resolved) async {
+    Source source = addSource("const C = $expr;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    if (resolved) {
+      verify([source]);
+    }
+  }
+
+  Future<void> _check_constEvalTypeBool_withParameter_binary(
+      String expr) async {
+    Source source = addSource('''
+class A {
+  final a;
+  const A(bool p) : a = $expr;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+      StaticTypeWarningCode.NON_BOOL_OPERAND
+    ]);
+    verify([source]);
+  }
+
+  Future<void> _check_constEvalTypeBoolOrInt_withParameter_binary(
+      String expr) async {
+    Source source = addSource('''
+class A {
+  final a;
+  const A(int p) : a = $expr;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  Future<void> _check_constEvalTypeInt_withParameter_binary(String expr) async {
+    Source source = addSource('''
+class A {
+  final a;
+  const A(int p) : a = $expr;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  Future<void> _check_constEvalTypeNum_withParameter_binary(String expr) async {
+    Source source = addSource('''
+class A {
+  final a;
+  const A(num p) : a = $expr;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+  }
+
+  Future<void> _check_wrongNumberOfParametersForOperator(
+      String name, String parameters) async {
+    Source source = addSource('''
+class A {
+  operator $name($parameters) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]);
+    verify([source]);
+  }
+
+  Future<void> _check_wrongNumberOfParametersForOperator1(String name) async {
+    await _check_wrongNumberOfParametersForOperator(name, "");
+    await _check_wrongNumberOfParametersForOperator(name, "a, b");
+  }
+
+  Future<void> _privateCollisionInMixinApplicationTest(String testCode) async {
+    addNamedSource('/lib1.dart', '''
+class A {
+  int _x;
+}
+
+class B {
+  int _x;
+}
+''');
+    Source source = addSource(testCode);
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION]);
+    verify([source]);
+  }
+}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
index 9ff1460..9c33cd5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
@@ -3,17 +3,19 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'compile_time_error_code_test.dart';
+import 'compile_time_error_code.dart';
 import 'resolver_test_case.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CompileTimeErrorCodeTest_Driver);
     defineReflectiveTests(ConstSetElementTypeImplementsEqualsTest);
+    defineReflectiveTests(ControlFlowCollectionsTest);
     defineReflectiveTests(InvalidTypeArgumentInConstSetTest);
     defineReflectiveTests(NonConstSetElementFromDeferredLibraryTest);
     defineReflectiveTests(NonConstSetElementTest);
@@ -202,6 +204,343 @@
 }
 
 @reflectiveTest
+class ControlFlowCollectionsTest extends ResolverTestCase {
+  @override
+  List<String> get enabledExperiments =>
+      [EnableString.control_flow_collections, EnableString.set_literals];
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_awaitForIn_declaredVariableWrongType() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<String> stream;
+  await for (int i in stream) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_awaitForIn_existingVariableWrongType() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<String> stream;
+  int i;
+  await for (i in stream) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_awaitForIn_notStream() async {
+    await assertErrorsInCode('''
+f() async {
+  await for (var i in true) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE]);
+  }
+
+  test_duplicateDefinition_for_initializers() async {
+    Source source = addSource(r'''
+f() {
+  for (int i = 0, i = 0; i < 5;) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    verify([source]);
+  }
+
+  test_expectedOneListTypeArgument() async {
+    await assertErrorsInCode(r'''
+main() {
+  <int, int>[];
+}''', [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]);
+  }
+
+  test_expectedOneSetTypeArgument() async {
+    await assertErrorsInCode(r'''
+main() {
+  <int, int, int>{2, 3};
+}''', [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS]);
+  }
+
+  test_expectedTwoMapTypeArguments_three() async {
+    await assertErrorsInCode(r'''
+main() {
+  <int, int, int>{};
+}''', [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]);
+  }
+
+  test_forIn_declaredVariableWrongType() async {
+    await assertErrorsInCode('''
+f() {
+  for (int i in <String>[]) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_forIn_existingVariableWrongType() async {
+    await assertErrorsInCode('''
+f() {
+  int i;
+  for (i in <String>[]) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_forIn_notIterable() async {
+    await assertErrorsInCode('''
+f() {
+  for (var i in true) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE]);
+  }
+
+  test_forIn_typeBoundBad() async {
+    await assertErrorsInCode('''
+class Foo<T extends Iterable<int>> {
+  void method(T iterable) {
+    for (String i in iterable) {}
+  }
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_forInWithConstVariable_forEach_identifier() async {
+    Source source = addSource(r'''
+f() {
+  const x = 0;
+  for (x in [0, 1, 2]) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+    verify([source]);
+  }
+
+  test_forInWithConstVariable_forEach_loopVariable() async {
+    Source source = addSource(r'''
+f() {
+  for (const x in [0, 1, 2]) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+    verify([source]);
+  }
+
+  test_generalizedVoid_useOfInForeachIterableError() async {
+    Source source = addSource(r'''
+void main() {
+  void x;
+  for (var v in x) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
+  }
+
+  test_generalizedVoid_useOfVoidInForeachVariableError() async {
+    Source source = addSource(r'''
+void main() {
+  void x;
+  var y;
+  for (y in x) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
+  }
+
+  test_invalidTypeArgumentInConstList() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return const <E>[];
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST]);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstMap_key() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return const <E, String>{};
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstMap_value() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return const <String, E>{};
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstSet_class() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return const <E>{};
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET]);
+    verify([source]);
+  }
+
+  test_listElementTypeNotAssignable_const() async {
+    Source source = addSource("var v = const <String>[42];");
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_listElementTypeNotAssignable_nonConst() async {
+    Source source = addSource("var v = <String> [42];");
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_mapKeyTypeNotAssignable_const() async {
+    Source source = addSource("var v = const <String, int >{1 : 2};");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_mapKeyTypeNotAssignable_nonConst() async {
+    Source source = addSource("var v = <String, int >{1 : 2};");
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_mapValueTypeNotAssignable_const() async {
+    Source source = addSource("var v = const <String, String>{'a' : 2};");
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_mapValueTypeNotAssignable_nonConst() async {
+    Source source = addSource("var v = <String, String>{'a' : 2};");
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_nonBoolCondition_for_declaration() async {
+    // https://github.com/dart-lang/sdk/issues/24713
+    await assertErrorsInCode(r'''
+f() {
+  for (int i = 0; 3;) {}
+}
+''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonBoolCondition_for_expression() async {
+    // https://github.com/dart-lang/sdk/issues/24713
+    await assertErrorsInCode(r'''
+f() {
+  int i;
+  for (i = 0; 3;) {}
+}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonConstMapAsExpressionStatement_begin() async {
+    Source source = addSource(r'''
+f() {
+  {'a' : 0, 'b' : 1}.length;
+}''');
+    await computeAnalysisResult(source);
+    // TODO(danrubel) Fasta is not recovering.
+    assertErrors(source, [
+      ParserErrorCode.UNEXPECTED_TOKEN,
+      ParserErrorCode.UNEXPECTED_TOKEN,
+      ParserErrorCode.UNEXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.MISSING_IDENTIFIER
+    ]);
+//    assertErrors(
+//        source, [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+    verify([source]);
+  }
+
+  test_nonConstMapAsExpressionStatement_only() async {
+    Source source = addSource(r'''
+f() {
+  {'a' : 0, 'b' : 1};
+}''');
+    await computeAnalysisResult(source);
+    // TODO(danrubel) Fasta is not recovering.
+    assertErrors(source, [
+      ParserErrorCode.UNEXPECTED_TOKEN,
+      ParserErrorCode.UNEXPECTED_TOKEN,
+      ParserErrorCode.UNEXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.EXPECTED_TOKEN,
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.MISSING_IDENTIFIER
+    ]);
+//    assertErrors(
+//        source, [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
+    verify([source]);
+  }
+
+  test_setElementTypeNotAssignable_const() async {
+    Source source = addSource("var v = const <String>{42};");
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CheckedModeCompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  test_setElementTypeNotAssignable_nonConst() async {
+    Source source = addSource("var v = <String>{42};");
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+}
+
+@reflectiveTest
 class InvalidTypeArgumentInConstSetTest extends ResolverTestCase {
   @override
   List<String> get enabledExperiments => [EnableString.set_literals];
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
deleted file mode 100644
index c266770..0000000
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ /dev/null
@@ -1,6559 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test/test.dart' show expect;
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(CompileTimeErrorCodeTest);
-  });
-}
-
-@reflectiveTest
-class CompileTimeErrorCodeTest extends CompileTimeErrorCodeTestBase {
-  @override
-  @failingTest
-  test_awaitInWrongContext_sync() {
-    return super.test_awaitInWrongContext_sync();
-  }
-
-  @override
-  @failingTest
-  test_constEvalThrowsException() {
-    return super.test_constEvalThrowsException();
-  }
-
-  @override
-  @failingTest
-  test_invalidIdentifierInAsync_async() {
-    return super.test_invalidIdentifierInAsync_async();
-  }
-
-  @override
-  @failingTest
-  test_invalidIdentifierInAsync_await() {
-    return super.test_invalidIdentifierInAsync_await();
-  }
-
-  @override
-  @failingTest
-  test_invalidIdentifierInAsync_yield() {
-    return super.test_invalidIdentifierInAsync_yield();
-  }
-
-  @override
-  @failingTest // Does not work with old task model
-  test_mixinInference_recursiveSubtypeCheck_new_syntax() {
-    return super.test_mixinInference_recursiveSubtypeCheck_new_syntax();
-  }
-
-  @override
-  @failingTest
-  test_mixinOfNonClass() {
-    return super.test_mixinOfNonClass();
-  }
-
-  @override
-  @failingTest
-  test_objectCannotExtendAnotherClass() {
-    return super.test_objectCannotExtendAnotherClass();
-  }
-
-  @override
-  @failingTest
-  test_superInitializerInObject() {
-    return super.test_superInitializerInObject();
-  }
-
-  @override
-  @failingTest
-  test_typedef_infiniteParameterBoundCycle() {
-    // Does not work with the task model.
-    return super.test_typedef_infiniteParameterBoundCycle();
-  }
-
-  @override
-  @failingTest
-  test_yieldEachInNonGenerator_async() {
-    return super.test_yieldEachInNonGenerator_async();
-  }
-
-  @override
-  @failingTest
-  test_yieldEachInNonGenerator_sync() {
-    return super.test_yieldEachInNonGenerator_sync();
-  }
-
-  @override
-  @failingTest
-  test_yieldInNonGenerator_async() {
-    return super.test_yieldInNonGenerator_async();
-  }
-
-  @override
-  @failingTest
-  test_yieldInNonGenerator_sync() {
-    return super.test_yieldInNonGenerator_sync();
-  }
-}
-
-class CompileTimeErrorCodeTestBase extends ResolverTestCase {
-  disabled_test_conflictingGenericInterfaces_hierarchyLoop_infinite() async {
-    // There is an interface conflict here due to a loop in the class
-    // hierarchy leading to an infinite set of implemented types; this loop
-    // shouldn't cause non-termination.
-
-    // TODO(paulberry): this test is currently disabled due to non-termination
-    // bugs elsewhere in the analyzer.
-    Source source = addSource('''
-class A<T> implements B<List<T>> {}
-class B<T> implements A<List<T>> {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES]);
-  }
-
-  test_accessPrivateEnumField() async {
-    Source source = addSource(r'''
-enum E { ONE }
-String name(E e) {
-  return e._name;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD]);
-    // Cannot verify because "_name" cannot be resolved.
-  }
-
-  test_ambiguousExport() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';
-export 'lib2.dart';''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class N {}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-class N {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.AMBIGUOUS_EXPORT]);
-    verify([source]);
-  }
-
-  test_annotationWithNotClass() async {
-    Source source = addSource('''
-class Property {
-  final int value;
-  const Property(this.value);
-}
-
-const Property property = const Property(42);
-
-@property(123)
-main() {
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_annotationWithNotClass_prefixed() async {
-    addNamedSource("/annotations.dart", r'''
-class Property {
-  final int value;
-  const Property(this.value);
-}
-
-const Property property = const Property(42);
-''');
-    Source source = addSource('''
-import 'annotations.dart' as pref;
-@pref.property(123)
-main() {
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_annotation() async {
-    Source source = addSource('''
-const int async = 0;
-f() async {
-  g(@async x) {}
-  g(0);
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_argument_label() async {
-    Source source = addSource('''
-f(c) async {
-  c.g(async: 0);
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_async_method() async {
-    Source source = addSource('''
-f() async {
-  var async = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_async_star_method() async {
-    Source source = addSource('''
-f() async* {
-  var async = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_break_statement() async {
-    Source source = addSource('''
-f() async {
-  while (true) {
-    break async;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
-      CompileTimeErrorCode.LABEL_UNDEFINED
-    ]);
-    // Note: we don't call verify([source]) because the reference to the
-    // "async" label is unresolved.
-  }
-
-  test_async_used_as_identifier_in_cascaded_invocation() async {
-    Source source = addSource('''
-class C {
-  int async() => 1;
-}
-f() async {
-  return new C()..async();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_cascaded_setter_invocation() async {
-    Source source = addSource('''
-class C {
-  void set async(int i) {}
-}
-f() async {
-  return new C()..async = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_catch_exception_argument() async {
-    Source source = addSource('''
-g() {}
-f() async {
-  try {
-    g();
-  } catch (async) { }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_catch_stacktrace_argument() async {
-    Source source = addSource('''
-g() {}
-f() async {
-  try {
-    g();
-  } catch (e, async) { }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_continue_statement() async {
-    Source source = addSource('''
-f() async {
-  while (true) {
-    continue async;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
-      CompileTimeErrorCode.LABEL_UNDEFINED
-    ]);
-    // Note: we don't call verify([source]) because the reference to the
-    // "async" label is unresolved.
-  }
-
-  test_async_used_as_identifier_in_for_statement() async {
-    Source source = addSource('''
-var async;
-f() async {
-  for (async in []) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_formal_parameter_name() async {
-    Source source = addSource('''
-f() async {
-  g(int async) {}
-  g(0);
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_getter_name() async {
-    Source source = addSource('''
-class C {
-  int get async => 1;
-}
-f() async {
-  return new C().async;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_invocation() async {
-    Source source = addSource('''
-class C {
-  int async() => 1;
-}
-f() async {
-  return new C().async();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_local_function_name() async {
-    Source source = addSource('''
-f() async {
-  int async() => null;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_prefix() async {
-    Source source = addSource('''
-import 'dart:async' as async;
-f() async {
-  return new async.Future.value(0);
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_setter_name() async {
-    Source source = addSource('''
-class C {
-  void set async(int i) {}
-}
-f() async {
-  new C().async = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_statement_label() async {
-    Source source = addSource('''
-f() async {
-  async: g();
-}
-g() {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
-      HintCode.UNUSED_LABEL
-    ]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_string_interpolation() async {
-    Source source = addSource(r'''
-int async = 1;
-f() async {
-  return "$async";
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_suffix() async {
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-int async;
-''');
-    Source source = addSource('''
-import 'lib1.dart' as l;
-f() async {
-  return l.async;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_switch_label() async {
-    Source source = addSource('''
-f() async {
-  switch (0) {
-    async: case 0: break;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
-      HintCode.UNUSED_LABEL
-    ]);
-    verify([source]);
-  }
-
-  test_async_used_as_identifier_in_sync_star_method() async {
-    Source source = addSource('''
-f() sync* {
-  var async = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_asyncForInWrongContext() async {
-    Source source = addSource(r'''
-f(list) {
-  await for (var e in list) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT]);
-    verify([source]);
-  }
-
-  test_await_used_as_identifier_in_async_method() async {
-    Source source = addSource('''
-f() async {
-  var await = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_await_used_as_identifier_in_async_star_method() async {
-    Source source = addSource('''
-f() async* {
-  var await = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_await_used_as_identifier_in_sync_star_method() async {
-    Source source = addSource('''
-f() sync* {
-  var await = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_awaitInWrongContext_sync() async {
-    // This test requires better error recovery than we currently have. In
-    // particular, we need to be able to distinguish between an await expression
-    // in the wrong context, and the use of 'await' as an identifier.
-    Source source = addSource(r'''
-f(x) {
-  return await x;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT]);
-    verify([source]);
-  }
-
-  test_awaitInWrongContext_syncStar() async {
-    // This test requires better error recovery than we currently have. In
-    // particular, we need to be able to distinguish between an await expression
-    // in the wrong context, and the use of 'await' as an identifier.
-    Source source = addSource(r'''
-f(x) sync* {
-  yield await x;
-}''');
-    await computeAnalysisResult(source);
-    if (usingFastaParser) {
-      assertErrors(source, [CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT]);
-    }
-    verify([source]);
-  }
-
-  test_bug_23176() async {
-    Source source = addSource('''
-class A {
-  const A([x]);
-}
-class B {
-  dynamic @A(const A()) x;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
-                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
-                ParserErrorCode.EXPECTED_TOKEN
-              ]
-            : [
-                ParserErrorCode.EXPECTED_CLASS_MEMBER,
-                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
-              ]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsMixinName_classTypeAlias() async {
-    Source source = addSource(r'''
-class A {}
-class B {}
-class as = A with B;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsPrefixName() async {
-    Source source = addSource("import 'dart:async' as abstract;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_PREFIX_NAME,
-      HintCode.UNUSED_IMPORT
-    ]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsType_dynamicMissingPrefix() async {
-    Source source = addSource(r"""
-import 'dart:core' as core;
-
-dynamic x;
-""");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
-  }
-
-  test_builtInIdentifierAsType_formalParameter_field() async {
-    Source source = addSource(r'''
-class A {
-  var x;
-  A(static this.x);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [ParserErrorCode.EXTRANEOUS_MODIFIER]
-            : [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsType_formalParameter_simple() async {
-    Source source = addSource(r'''
-f(static x) {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [ParserErrorCode.EXTRANEOUS_MODIFIER]
-            : [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsType_variableDeclaration() async {
-    Source source = addSource(r'''
-f() {
-  typedef x;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                StaticWarningCode.UNDEFINED_IDENTIFIER,
-                StaticWarningCode.UNDEFINED_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ]
-            : [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsTypedefName_functionTypeAlias() async {
-    Source source = addSource("typedef bool as();");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsTypeName() async {
-    Source source = addSource("class as {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME]);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsTypeParameterName() async {
-    Source source = addSource("class A<as> {}");
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME]);
-    verify([source]);
-  }
-
-  test_caseExpressionTypeImplementsEquals() async {
-    Source source = addSource(r'''
-class IntWrapper {
-  final int value;
-  const IntWrapper(this.value);
-  bool operator ==(Object x) {
-    return x is IntWrapper && x.value == value;
-  }
-  get hashCode => value;
-}
-
-f(var a) {
-  switch(a) {
-    case(const IntWrapper(1)) : return 1;
-    default: return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_conflictingGenericInterfaces_hierarchyLoop() async {
-    // There is no interface conflict here, but there is a loop in the class
-    // hierarchy leading to a finite set of implemented types; this loop
-    // shouldn't cause non-termination.
-    Source source = addSource('''
-class A<T> implements B<T> {}
-class B<T> implements A<T> {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-  }
-
-  test_conflictingGenericInterfaces_noConflict() async {
-    Source source = addSource('''
-class I<T> {}
-class A implements I<int> {}
-class B implements I<int> {}
-class C extends A implements B {}
-    ''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_conflictingTypeVariableAndClass() async {
-    Source source = addSource(r'''
-class T<T> {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS]);
-    verify([source]);
-  }
-
-  test_conflictingTypeVariableAndMember_field() async {
-    Source source = addSource(r'''
-class A<T> {
-  var T;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
-    verify([source]);
-  }
-
-  test_conflictingTypeVariableAndMember_getter() async {
-    Source source = addSource(r'''
-class A<T> {
-  get T => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
-    verify([source]);
-  }
-
-  test_conflictingTypeVariableAndMember_method() async {
-    Source source = addSource(r'''
-class A<T> {
-  T() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
-    verify([source]);
-  }
-
-  test_conflictingTypeVariableAndMember_method_static() async {
-    Source source = addSource(r'''
-class A<T> {
-  static T() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
-    verify([source]);
-  }
-
-  test_conflictingTypeVariableAndMember_setter() async {
-    Source source = addSource(r'''
-class A<T> {
-  set T(x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]);
-    verify([source]);
-  }
-
-  test_consistentCaseExpressionTypes_dynamic() async {
-    // Even though A.S and S have a static type of "dynamic", we should see
-    // that they match 'abc', because they are constant strings.
-    Source source = addSource(r'''
-class A {
-  static const S = 'A.S';
-}
-
-const S = 'S';
-
-foo(var p) {
-  switch (p) {
-    case S:
-      break;
-    case A.S:
-      break;
-    case 'abc':
-      break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_const_invalid_constructorFieldInitializer_fromLibrary() async {
-    addNamedSource('/lib.dart', r'''
-class A<T> {
-  final int f;
-  const A() : f = T.foo;
-}
-''');
-    Source source = addSource(r'''
-import 'lib.dart';
-const a = const A();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-  }
-
-  test_constConstructor_redirect_generic() async {
-    Source source = addSource(r'''
-class A<T> {
-  const A(T value) : this._(value);
-  const A._(T value) : value = value;
-  final T value;
-}
-
-void main(){
-  const A<int>(1);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithFieldInitializedByNonConst() async {
-    Source source = addSource(r'''
-class A {
-  final int i = f();
-  const A();
-}
-int f() {
-  return 3;
-}''');
-    // TODO(paulberry): the error CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE is
-    // redundant and ought to be suppressed.
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode
-          .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
-      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-    ]);
-    verify([source]);
-  }
-
-  test_constConstructorWithFieldInitializedByNonConst_static() async {
-    Source source = addSource(r'''
-class A {
-  static final int i = f();
-  const A();
-}
-int f() {
-  return 3;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonConstSuper_explicit() async {
-    Source source = addSource(r'''
-class A {
-  A();
-}
-class B extends A {
-  const B(): super();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonConstSuper_implicit() async {
-    Source source = addSource(r'''
-class A {
-  A();
-}
-class B extends A {
-  const B();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonFinalField_mixin() async {
-    Source source = addSource(r'''
-class A {
-  var a;
-}
-class B extends Object with A {
-  const B();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
-      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
-    ]);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonFinalField_super() async {
-    Source source = addSource(r'''
-class A {
-  var a;
-}
-class B extends A {
-  const B();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
-      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
-    ]);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonFinalField_this() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]);
-    verify([source]);
-  }
-
-  test_constDeferredClass() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {
-  const A();
-}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-main() {
-  const a.A();
-}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.CONST_DEFERRED_CLASS
-    ]);
-  }
-
-  test_constDeferredClass_namedConstructor() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {
-  const A.b();
-}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-main() {
-  const a.A.b();
-}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.CONST_DEFERRED_CLASS
-    ]);
-  }
-
-  test_constEval_newInstance_constConstructor() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-const a = new A();''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
-    verify([source]);
-  }
-
-  test_constEval_newInstance_externalFactoryConstConstructor() async {
-    // We can't evaluate "const A()" because its constructor is external.  But
-    // the code is correct--we shouldn't report an error.
-    Source source = addSource(r'''
-class A {
-  external const factory A();
-}
-const x = const A();''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEval_nonStaticField_inGenericClass() async {
-    Source source = addSource('''
-class C<T> {
-  const C();
-  T get t => null;
-}
-
-const x = const C().t;''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
-    verify([source]);
-  }
-
-  test_constEval_propertyExtraction_targetNotConst() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-  int m() => 0;
-}
-final a = const A();
-const C = a.m;''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
-    verify([source]);
-  }
-
-  test_constEvalThrowsException() async {
-    Source source = addSource(r'''
-class C {
-  const C();
-}
-f() { return const C(); }''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]);
-    verify([source]);
-  }
-
-  test_constEvalThrowsException_binaryMinus_null() async {
-    await _check_constEvalThrowsException_binary_null("null - 5", false);
-    await _check_constEvalThrowsException_binary_null("5 - null", true);
-  }
-
-  test_constEvalThrowsException_binaryPlus_null() async {
-    await _check_constEvalThrowsException_binary_null("null + 5", false);
-    await _check_constEvalThrowsException_binary_null("5 + null", true);
-  }
-
-  test_constEvalThrowsException_divisionByZero() async {
-    Source source = addSource("const C = 1 ~/ 0;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE]);
-    verify([source]);
-  }
-
-  test_constEvalThrowsException_finalAlreadySet_initializer() async {
-    // If a final variable has an initializer at the site of its declaration,
-    // and at the site of the constructor, then invoking that constructor would
-    // produce a runtime error; hence invoking that constructor via the "const"
-    // keyword results in a compile-time error.
-    Source source = addSource('''
-class C {
-  final x = 1;
-  const C() : x = 2;
-}
-var x = const C();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
-    ]);
-    verify([source]);
-  }
-
-  test_constEvalThrowsException_finalAlreadySet_initializing_formal() async {
-    // If a final variable has an initializer at the site of its declaration,
-    // and it is initialized using an initializing formal at the site of the
-    // constructor, then invoking that constructor would produce a runtime
-    // error; hence invoking that constructor via the "const" keyword results
-    // in a compile-time error.
-    Source source = addSource('''
-class C {
-  final x = 1;
-  const C(this.x);
-}
-var x = const C(2);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
-    ]);
-    verify([source]);
-  }
-
-  test_constEvalThrowsException_unaryBitNot_null() async {
-    Source source = addSource("const C = ~null;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    // no verify(), '~null' is not resolved
-  }
-
-  test_constEvalThrowsException_unaryNegated_null() async {
-    Source source = addSource("const C = -null;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    // no verify(), '-null' is not resolved
-  }
-
-  test_constEvalThrowsException_unaryNot_null() async {
-    Source source = addSource("const C = !null;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    verify([source]);
-  }
-
-  test_constEvalTypeBool_binary() async {
-    await _check_constEvalTypeBool_withParameter_binary("p && ''");
-    await _check_constEvalTypeBool_withParameter_binary("p || ''");
-  }
-
-  test_constEvalTypeBool_binary_leftTrue() async {
-    Source source = addSource("const C = (true || 0);");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [StaticTypeWarningCode.NON_BOOL_OPERAND, HintCode.DEAD_CODE]);
-    verify([source]);
-  }
-
-  test_constEvalTypeBool_logicalOr_trueLeftOperand() async {
-    Source source = addSource(r'''
-class C {
-  final int x;
-  const C({this.x}) : assert(x == null || x >= 0);
-}
-const c = const C();
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEvalTypeBoolNumString_equal() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B {
-  final a;
-  const B(num p) : a = p == const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
-    verify([source]);
-  }
-
-  test_constEvalTypeBoolNumString_notEqual() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B {
-  final a;
-  const B(String p) : a = p != const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
-    verify([source]);
-  }
-
-  test_constEvalTypeInt_binary() async {
-    await _check_constEvalTypeBoolOrInt_withParameter_binary("p ^ ''");
-    await _check_constEvalTypeBoolOrInt_withParameter_binary("p & ''");
-    await _check_constEvalTypeBoolOrInt_withParameter_binary("p | ''");
-    await _check_constEvalTypeInt_withParameter_binary("p >> ''");
-    await _check_constEvalTypeInt_withParameter_binary("p << ''");
-  }
-
-  test_constEvalTypeNum_binary() async {
-    await _check_constEvalTypeNum_withParameter_binary("p + ''");
-    await _check_constEvalTypeNum_withParameter_binary("p - ''");
-    await _check_constEvalTypeNum_withParameter_binary("p * ''");
-    await _check_constEvalTypeNum_withParameter_binary("p / ''");
-    await _check_constEvalTypeNum_withParameter_binary("p ~/ ''");
-    await _check_constEvalTypeNum_withParameter_binary("p > ''");
-    await _check_constEvalTypeNum_withParameter_binary("p < ''");
-    await _check_constEvalTypeNum_withParameter_binary("p >= ''");
-    await _check_constEvalTypeNum_withParameter_binary("p <= ''");
-    await _check_constEvalTypeNum_withParameter_binary("p % ''");
-  }
-
-  test_constFormalParameter_fieldFormalParameter() async {
-    Source source = addSource(r'''
-class A {
-  var x;
-  A(const this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
-                ParserErrorCode.EXTRANEOUS_MODIFIER
-              ]
-            : [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
-    verify([source]);
-  }
-
-  test_constFormalParameter_simpleFormalParameter() async {
-    Source source = addSource("f(const x) {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
-                ParserErrorCode.EXTRANEOUS_MODIFIER
-              ]
-            : [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]);
-    verify([source]);
-  }
-
-  test_constInitializedWithNonConstValue() async {
-    Source source = addSource(r'''
-f(p) {
-  const C = p;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE]);
-    verify([source]);
-  }
-
-  test_constInitializedWithNonConstValue_finalField() async {
-    // Regression test for bug #25526 which previously
-    // caused two errors to be reported.
-    Source source = addSource(r'''
-class Foo {
-  final field = 0;
-  foo([int x = field]) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_constInitializedWithNonConstValue_missingConstInListLiteral() async {
-    Source source = addSource("const List L = [0];");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constInitializedWithNonConstValue_missingConstInMapLiteral() async {
-    Source source = addSource("const Map M = {'a' : 0};");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constInitializedWithNonConstValueFromDeferredClass() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const V = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-const B = a.V;'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode
-          .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_constInitializedWithNonConstValueFromDeferredClass_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const V = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-const B = a.V + 1;'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode
-          .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_constInstanceField() async {
-    Source source = addSource(r'''
-class C {
-  const int f = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
-    verify([source]);
-  }
-
-  test_constMapKeyTypeImplementsEquals_direct() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-  operator ==(other) => false;
-}
-main() {
-  const {const A() : 0};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_constMapKeyTypeImplementsEquals_dynamic() async {
-    // Note: static type of B.a is "dynamic", but actual type of the const
-    // object is A.  We need to make sure we examine the actual type when
-    // deciding whether there is a problem with operator==.
-    Source source = addSource(r'''
-class A {
-  const A();
-  operator ==(other) => false;
-}
-class B {
-  static const a = const A();
-}
-main() {
-  const {B.a : 0};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_constMapKeyTypeImplementsEquals_factory() async {
-    Source source = addSource(r'''
-class A { const factory A() = B; }
-
-class B implements A {
-  const B();
-
-  operator ==(o) => true;
-}
-
-main() {
-  var m = const { const A(): 42 };
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_constMapKeyTypeImplementsEquals_super() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-  operator ==(other) => false;
-}
-class B extends A {
-  const B();
-}
-main() {
-  const {const B() : 0};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_constWithInvalidTypeParameters() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-f() { return const A<A>(); }''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
-    verify([source]);
-  }
-
-  test_constWithInvalidTypeParameters_tooFew() async {
-    Source source = addSource(r'''
-class A {}
-class C<K, V> {
-  const C();
-}
-f(p) {
-  return const C<A>();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
-    verify([source]);
-  }
-
-  test_constWithInvalidTypeParameters_tooMany() async {
-    Source source = addSource(r'''
-class A {}
-class C<E> {
-  const C();
-}
-f(p) {
-  return const C<A, A>();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS]);
-    verify([source]);
-  }
-
-  test_constWithNonConst() async {
-    Source source = addSource(r'''
-class T {
-  T(a, b, {c, d}) {}
-}
-f() { return const T(0, 1, c: 2, d: 3); }''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONST]);
-    verify([source]);
-  }
-
-  test_constWithNonConst_in_const_context() async {
-    Source source = addSource(r'''
-class A {
-  const A(x);
-}
-class B {
-}
-main() {
-  const A(B());
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONST]);
-    verify([source]);
-  }
-
-  test_constWithNonConstantArgument_annotation() async {
-    Source source = addSource(r'''
-class A {
-  const A(int p);
-}
-var v = 42;
-@A(v)
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT]);
-    verify([source]);
-  }
-
-  test_constWithNonConstantArgument_instanceCreation() async {
-    Source source = addSource(r'''
-class A {
-  const A(a);
-}
-f(p) { return const A(p); }''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
-    ]);
-    verify([source]);
-  }
-
-  test_constWithNonType() async {
-    Source source = addSource(r'''
-int A;
-f() {
-  return const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
-    verify([source]);
-  }
-
-  test_constWithNonType_fromLibrary() async {
-    Source source1 = addNamedSource("/lib.dart", "");
-    Source source2 = addNamedSource("/lib2.dart", r'''
-import 'lib.dart' as lib;
-void f() {
-  const lib.A();
-}''');
-    await computeAnalysisResult(source1);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [CompileTimeErrorCode.CONST_WITH_NON_TYPE]);
-    verify([source1]);
-  }
-
-  test_constWithTypeParameters_direct() async {
-    Source source = addSource(r'''
-class A<T> {
-  static const V = const A<T>();
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
-      StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC
-    ]);
-    verify([source]);
-  }
-
-  test_constWithTypeParameters_indirect() async {
-    Source source = addSource(r'''
-class A<T> {
-  static const V = const A<List<T>>();
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS,
-      StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC
-    ]);
-    verify([source]);
-  }
-
-  test_constWithUndefinedConstructor() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-f() {
-  return const A.noSuchConstructor();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
-    // no verify(), 'noSuchConstructor' is not resolved
-  }
-
-  test_constWithUndefinedConstructorDefault() async {
-    Source source = addSource(r'''
-class A {
-  const A.name();
-}
-f() {
-  return const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypeAlias_new_named() async {
-    Source source = addSource('''
-typedef F = int Function({Map<String, String> m: const {}});
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
-      StrongModeCode.INVALID_CAST_LITERAL_MAP
-    ]);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypeAlias_new_positional() async {
-    Source source = addSource('''
-typedef F = int Function([Map<String, String> m = const {}]);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
-      StrongModeCode.INVALID_CAST_LITERAL_MAP
-    ]);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypeAlias_old_named() async {
-    Source source = addSource("typedef F([x = 0]);");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
-                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
-              ]
-            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypeAlias_old_positional() async {
-    Source source = addSource("typedef F([x = 0]);");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS,
-                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
-              ]
-            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypedParameter_named() async {
-    Source source = addSource("f(g({p: null})) {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
-                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
-              ]
-            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypedParameter_optional() async {
-    Source source = addSource("f(g([p = null])) {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
-                ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE
-              ]
-            : [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]);
-    verify([source]);
-  }
-
-  test_defaultValueInRedirectingFactoryConstructor() async {
-    Source source = addSource(r'''
-class A {
-  factory A([int x = 0]) = B;
-}
-
-class B implements A {
-  B([int x = 1]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
-    ]);
-    verify([source]);
-  }
-
-  test_deferredImportWithInvalidUri() async {
-    Source source = addSource(r'''
-import '[invalid uri]' deferred as p;
-main() {
-  p.loadLibrary();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  test_duplicateDefinition_acrossLibraries() async {
-    Source librarySource = addNamedSource("/lib.dart", r'''
-library lib;
-
-part 'a.dart';
-part 'b.dart';''');
-    Source sourceA = addNamedSource("/a.dart", r'''
-part of lib;
-
-class A {}''');
-    Source sourceB = addNamedSource("/b.dart", r'''
-part of lib;
-
-class A {}''');
-    await computeAnalysisResult(librarySource);
-    await computeAnalysisResult(sourceA);
-    await computeAnalysisResult(sourceB);
-    assertNoErrors(librarySource);
-    assertErrors(sourceB, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([librarySource, sourceA, sourceB]);
-  }
-
-  test_duplicateDefinition_catch() async {
-    Source source = addSource(r'''
-main() {
-  try {} catch (e, e) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_inPart() async {
-    Source librarySource = addNamedSource("/lib.dart", r'''
-library test;
-part 'a.dart';
-class A {}''');
-    Source sourceA = addNamedSource("/a.dart", r'''
-part of test;
-class A {}''');
-    await computeAnalysisResult(librarySource);
-    await computeAnalysisResult(sourceA);
-    assertNoErrors(librarySource);
-    assertErrors(sourceA, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([librarySource, sourceA]);
-  }
-
-  test_duplicateDefinition_locals_inCase() async {
-    Source source = addSource(r'''
-main() {
-  switch(1) {
-    case 1:
-      var a;
-      var a;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_locals_inFunctionBlock() async {
-    Source source = addSource(r'''
-main() {
-  int m = 0;
-  m(a) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_locals_inIf() async {
-    Source source = addSource(r'''
-main(int p) {
-  if (p != 0) {
-    var a;
-    var a;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_locals_inMethodBlock() async {
-    Source source = addSource(r'''
-class A {
-  m() {
-    int a;
-    int a;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_parameters_inConstructor() async {
-    Source source = addSource(r'''
-class A {
-  int a;
-  A(int a, this.a);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_parameters_inFunctionTypeAlias() async {
-    Source source = addSource(r'''
-typedef F(int a, double a);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_parameters_inLocalFunction() async {
-    Source source = addSource(r'''
-main() {
-  f(int a, double a) {
-  };
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_parameters_inMethod() async {
-    Source source = addSource(r'''
-class A {
-  m(int a, double a) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_parameters_inTopLevelFunction() async {
-    Source source = addSource(r'''
-f(int a, double a) {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_typeParameters() async {
-    Source source = addSource(r'''
-class A<T, T> {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    verify([source]);
-  }
-
-  test_duplicateNamedArgument() async {
-    Source source = addSource(r'''
-f({a, b}) {}
-main() {
-  f(a: 1, a: 2);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT]);
-    verify([source]);
-  }
-
-  test_duplicatePart_sameSource() async {
-    addNamedSource('/part.dart', 'part of lib;');
-    Source source = addSource(r'''
-library lib;
-part 'part.dart';
-part 'foo/../part.dart';
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_PART]);
-    verify([source]);
-  }
-
-  test_duplicatePart_sameUri() async {
-    addNamedSource('/part.dart', 'part of lib;');
-    Source source = addSource(r'''
-library lib;
-part 'part.dart';
-part 'part.dart';
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.DUPLICATE_PART]);
-    verify([source]);
-  }
-
-  test_exportInternalLibrary() async {
-    Source source = addSource("export 'dart:_interceptors';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]);
-    verify([source]);
-  }
-
-  test_exportOfNonLibrary() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';''');
-    addNamedSource("/lib1.dart", "part of lib;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
-    verify([source]);
-  }
-
-  test_extendsDeferredClass() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class B extends a.A {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS
-    ]);
-  }
-
-  test_extendsDeferredClass_classTypeAlias() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class M {}
-class C = a.A with M;'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS
-    ]);
-  }
-
-  test_extendsDisallowedClass_class_bool() async {
-    Source source = addSource("class A extends bool {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
-    ]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_class_double() async {
-    Source source = addSource("class A extends double {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_class_int() async {
-    Source source = addSource("class A extends int {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
-    ]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_class_Null() async {
-    Source source = addSource("class A extends Null {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
-    ]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_class_num() async {
-    Source source = addSource("class A extends num {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_class_String() async {
-    Source source = addSource("class A extends String {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
-    ]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_classTypeAlias_bool() async {
-    Source source = addSource(r'''
-class M {}
-class C = bool with M;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_classTypeAlias_double() async {
-    Source source = addSource(r'''
-class M {}
-class C = double with M;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_classTypeAlias_int() async {
-    Source source = addSource(r'''
-class M {}
-class C = int with M;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_classTypeAlias_Null() async {
-    Source source = addSource(r'''
-class M {}
-class C = Null with M;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_classTypeAlias_num() async {
-    Source source = addSource(r'''
-class M {}
-class C = num with M;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extendsDisallowedClass_classTypeAlias_String() async {
-    Source source = addSource(r'''
-class M {}
-class C = String with M;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_extraPositionalArguments_const() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-main() {
-  const A(0);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
-    verify([source]);
-  }
-
-  test_extraPositionalArguments_const_super() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B extends A {
-  const B() : super(0);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS]);
-    verify([source]);
-  }
-
-  test_extraPositionalArgumentsCouldBeNamed_const() async {
-    Source source = addSource(r'''
-class A {
-  const A({int x});
-}
-main() {
-  const A(0);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED]);
-    verify([source]);
-  }
-
-  test_extraPositionalArgumentsCouldBeNamed_const_super() async {
-    Source source = addSource(r'''
-class A {
-  const A({int x});
-}
-class B extends A {
-  const B() : super(0);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED]);
-    verify([source]);
-  }
-
-  test_fieldFormalParameter_assignedInInitializer() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A(this.x) : x = 3 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_fieldInitializedByMultipleInitializers() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A() : x = 0, x = 1 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
-    verify([source]);
-  }
-
-  test_fieldInitializedByMultipleInitializers_multipleInits() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A() : x = 0, x = 1, x = 2 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
-      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS
-    ]);
-    verify([source]);
-  }
-
-  test_fieldInitializedByMultipleInitializers_multipleNames() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  int y;
-  A() : x = 0, x = 1, y = 0, y = 1 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS,
-      CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS
-    ]);
-    verify([source]);
-  }
-
-  test_fieldInitializedInParameterAndInitializer() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A(this.x) : x = 1 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_fieldInitializerFactoryConstructor() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  factory A(this.x) => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_fieldInitializerOutsideConstructor() async {
-    // TODO(brianwilkerson) Fix the duplicate error messages.
-    Source source = addSource(r'''
-class A {
-  int x;
-  m(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
-      CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
-    ]);
-    verify([source]);
-  }
-
-  test_fieldInitializerOutsideConstructor_defaultParameter() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  m([this.x]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_fieldInitializerOutsideConstructor_inFunctionTypeParameter() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A(int p(this.x));
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_fieldInitializerRedirectingConstructor_afterRedirection() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A.named() {}
-  A() : this.named(), x = 42;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_fieldInitializerRedirectingConstructor_beforeRedirection() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A.named() {}
-  A() : x = 42, this.named();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_fieldInitializingFormalRedirectingConstructor() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A.named() {}
-  A(this.x) : this.named();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_finalInitializedMultipleTimes_initializers() async {
-    Source source = addSource(r'''
-class A {
-  final x;
-  A() : x = 0, x = 0 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS]);
-    verify([source]);
-  }
-
-  /**
-   * This test doesn't test the FINAL_INITIALIZED_MULTIPLE_TIMES code, but tests the
-   * FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER code instead. It is provided here to show
-   * coverage over all of the permutations of initializers in constructor declarations.
-   *
-   * Note: FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER covers a subset of
-   * FINAL_INITIALIZED_MULTIPLE_TIMES, since it more specific, we use it instead of the broader code
-   */
-  test_finalInitializedMultipleTimes_initializingFormal_initializer() async {
-    Source source = addSource(r'''
-class A {
-  final x;
-  A(this.x) : x = 0 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_finalInitializedMultipleTimes_initializingFormals() async {
-    Source source = addSource(r'''
-class A {
-  final x;
-  A(this.x, this.x) {}
-}''');
-    // TODO(brianwilkerson) There should only be one error here.
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.DUPLICATE_DEFINITION,
-      CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES
-    ]);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_instanceField_const_static() async {
-    Source source = addSource(r'''
-class A {
-  static const F;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_library_const() async {
-    Source source = addSource("const F;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_local_const() async {
-    Source source = addSource(r'''
-f() {
-  const int x;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
-    verify([source]);
-  }
-
-  test_forInWithConstVariable_forEach_identifier() async {
-    Source source = addSource(r'''
-f() {
-  const x = 0;
-  for (x in [0, 1, 2]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
-    verify([source]);
-  }
-
-  test_forInWithConstVariable_forEach_loopVariable() async {
-    Source source = addSource(r'''
-f() {
-  for (const x in [0, 1, 2]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
-    verify([source]);
-  }
-
-  test_fromEnvironment_bool_badArgs() async {
-    Source source = addSource(r'''
-var b1 = const bool.fromEnvironment(1);
-var b2 = const bool.fromEnvironment('x', defaultValue: 1);''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_fromEnvironment_bool_badDefault_whenDefined() async {
-    // The type of the defaultValue needs to be correct even when the default
-    // value isn't used (because the variable is defined in the environment).
-    if (enableNewAnalysisDriver) {
-      driver.declaredVariables = new DeclaredVariables.fromMap({'x': 'true'});
-    } else {
-      (analysisContext2 as AnalysisContextImpl).declaredVariables =
-          new DeclaredVariables.fromMap({'x': 'true'});
-    }
-    Source source =
-        addSource("var b = const bool.fromEnvironment('x', defaultValue: 1);");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeArgument_inference_function() async {
-    Source source = addSource(r'''
-T f<T>(T t) => null;
-main() { f(<S>(S s) => s); }''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeArgument_inference_functionType() async {
-    Source source = addSource(r'''
-T Function<T>(T) f;
-main() { f(<S>(S s) => s); }''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeArgument_inference_method() async {
-    Source source = addSource(r'''
-class C {
-  T f<T>(T t) => null;
-}
-main() { new C().f(<S>(S s) => s); }''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeAsBound_class() async {
-    Source source = addSource(r'''
-class C<T extends S Function<S>(S)> {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeAsBound_genericFunction() async {
-    Source source = addSource(r'''
-T Function<T extends S Function<S>(S)>(T) fun;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeAsBound_genericFunctionTypedef() async {
-    Source source = addSource(r'''
-typedef foo = T Function<T extends S Function<S>(S)>(T t);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeAsBound_parameterOfFunction() async {
-    Source source = addSource(r'''
-class C<T extends void Function(S Function<S>(S))> {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericFunctionTypeAsBound_typedef() async {
-    Source source = addSource(r'''
-typedef T foo<T extends S Function<S>(S)>(T t);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND]);
-    verify([source]);
-  }
-
-  test_genericFunctionTypedParameter() async {
-    // Once dartbug.com/28515 is fixed, this syntax should no longer generate an
-    // error.
-    // TODO(paulberry): When dartbug.com/28515 is fixed, convert this into a
-    // NonErrorResolverTest.
-    Source source = addSource('void g(T f<T>(T x)) {}');
-    await computeAnalysisResult(source);
-    var expectedErrorCodes = <ErrorCode>[
-      CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED
-    ];
-    if (enableNewAnalysisDriver) {
-      // Due to dartbug.com/28515, some additional errors appear when using the
-      // new analysis driver.
-      expectedErrorCodes.addAll([
-        StaticWarningCode.UNDEFINED_CLASS,
-        StaticWarningCode.UNDEFINED_CLASS
-      ]);
-    }
-    assertErrors(source, expectedErrorCodes);
-    verify([source]);
-  }
-
-  test_implementsDeferredClass() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class B implements a.A {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS
-    ]);
-  }
-
-  test_implementsDeferredClass_classTypeAlias() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class B {}
-class M {}
-class C = B with M implements a.A;'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS
-    ]);
-  }
-
-  test_implementsDisallowedClass_class_bool() async {
-    Source source = addSource("class A implements bool {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_class_double() async {
-    Source source = addSource("class A implements double {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_class_int() async {
-    Source source = addSource("class A implements int {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_class_Null() async {
-    Source source = addSource("class A implements Null {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_class_num() async {
-    Source source = addSource("class A implements num {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_class_String() async {
-    Source source = addSource("class A implements String {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_class_String_num() async {
-    Source source = addSource("class A implements String, num {}");
-    await computeAnalysisResult(source);
-    if (enableNewAnalysisDriver) {
-      assertErrors(source, [
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
-      ]);
-    } else {
-      assertErrors(source, [
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
-      ]);
-    }
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_bool() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements bool;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_double() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements double;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_int() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements int;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_Null() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements Null;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_num() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements num;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_String() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements String;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsDisallowedClass_classTypeAlias_String_num() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class C = A with M implements String, num;''');
-    await computeAnalysisResult(source);
-    if (enableNewAnalysisDriver) {
-      assertErrors(source, [
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
-      ]);
-    } else {
-      assertErrors(source, [
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
-        CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS
-      ]);
-    }
-    verify([source]);
-  }
-
-  test_implementsNonClass_class() async {
-    Source source = addSource(r'''
-int A;
-class B implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsNonClass_dynamic() async {
-    Source source = addSource("class A implements dynamic {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsNonClass_enum() async {
-    Source source = addSource(r'''
-enum E { ONE }
-class A implements E {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsNonClass_typeAlias() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-int B;
-class C = A with M implements B;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsSuperClass() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A implements A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsSuperClass_Object() async {
-    Source source = addSource("class A implements Object {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsSuperClass_Object_typeAlias() async {
-    Source source = addSource(r'''
-class M {}
-class A = Object with M implements Object;
-    ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
-    verify([source]);
-  }
-
-  test_implementsSuperClass_typeAlias() async {
-    Source source = addSource(r'''
-class A {}
-class M {}
-class B = A with M implements A;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_field() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f;
-  var f;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_field2() async {
-    Source source = addSource(r'''
-class A {
-  final x = 0;
-  final y = x;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
-      StrongModeCode.TOP_LEVEL_INSTANCE_GETTER
-    ]);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_invocation() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f();
-  f() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_invocationInStatic() async {
-    Source source = addSource(r'''
-class A {
-  static var F = m();
-  int m() => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_redirectingConstructorInvocation() async {
-    Source source = addSource(r'''
-class A {
-  A(p) {}
-  A.named() : this(f);
-  var f;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_superConstructorInvocation() async {
-    Source source = addSource(r'''
-class A {
-  A(p) {}
-}
-class B extends A {
-  B() : super(f);
-  var f;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_importInternalLibrary() async {
-    Source source = addSource("import 'dart:_interceptors';");
-    // Note, in these error cases we may generate an UNUSED_IMPORT hint, while
-    // we could prevent the hint from being generated by testing the import
-    // directive for the error, this is such a minor corner case that we don't
-    // think we should add the additional computation time to figure out such
-    // cases.
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, HintCode.UNUSED_IMPORT]);
-    verify([source]);
-  }
-
-  test_importOfNonLibrary() async {
-    Source source = addSource(r'''
-library lib;
-import 'part.dart';
-A a;''');
-    addNamedSource("/part.dart", r'''
-part of lib;
-class A{}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
-    verify([source]);
-  }
-
-  test_inconsistentCaseExpressionTypes() async {
-    Source source = addSource(r'''
-f(var p) {
-  switch (p) {
-    case 1:
-      break;
-    case 'a':
-      break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES]);
-    verify([source]);
-  }
-
-  test_inconsistentCaseExpressionTypes_dynamic() async {
-    // Even though A.S and S have a static type of "dynamic", we should see
-    // that they fail to match 3, because they are constant strings.
-    Source source = addSource(r'''
-class A {
-  static const S = 'A.S';
-}
-
-const S = 'S';
-
-foo(var p) {
-  switch (p) {
-    case 3:
-      break;
-    case S:
-      break;
-    case A.S:
-      break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
-      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES
-    ]);
-    verify([source]);
-  }
-
-  test_inconsistentCaseExpressionTypes_repeated() async {
-    Source source = addSource(r'''
-f(var p) {
-  switch (p) {
-    case 1:
-      break;
-    case 'a':
-      break;
-    case 'b':
-      break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
-      CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES
-    ]);
-    verify([source]);
-  }
-
-  test_initializerForNonExistent_const() async {
-    // Check that the absence of a matching field doesn't cause a
-    // crash during constant evaluation.
-    Source source = addSource(r'''
-class A {
-  const A() : x = 'foo';
-}
-A a = const A();''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD]);
-  }
-
-  test_initializerForNonExistent_initializer() async {
-    Source source = addSource(r'''
-class A {
-  A() : x = 0 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD]);
-  }
-
-  test_initializerForStaticField() async {
-    Source source = addSource(r'''
-class A {
-  static int x;
-  A() : x = 0 {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD]);
-    verify([source]);
-  }
-
-  test_initializingFormalForNonExistentField() async {
-    Source source = addSource(r'''
-class A {
-  A(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
-    verify([source]);
-  }
-
-  test_initializingFormalForNonExistentField_notInEnclosingClass() async {
-    Source source = addSource(r'''
-class A {
-int x;
-}
-class B extends A {
-  B(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
-    verify([source]);
-  }
-
-  test_initializingFormalForNonExistentField_optional() async {
-    Source source = addSource(r'''
-class A {
-  A([this.x]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
-    verify([source]);
-  }
-
-  test_initializingFormalForNonExistentField_synthetic() async {
-    Source source = addSource(r'''
-class A {
-  int get x => 1;
-  A(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD]);
-    verify([source]);
-  }
-
-  test_initializingFormalForStaticField() async {
-    Source source = addSource(r'''
-class A {
-  static int x;
-  A([this.x]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD]);
-    verify([source]);
-  }
-
-  test_instanceMemberAccessFromFactory_named() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-  A();
-  factory A.make() {
-    m();
-    return new A();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY]);
-    verify([source]);
-  }
-
-  test_instanceMemberAccessFromFactory_unnamed() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-  A._();
-  factory A() {
-    m();
-    return new A._();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY]);
-    verify([source]);
-  }
-
-  test_instanceMemberAccessFromStatic_field() async {
-    Source source = addSource(r'''
-class A {
-  int f;
-  static foo() {
-    f;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
-    verify([source]);
-  }
-
-  test_instanceMemberAccessFromStatic_getter() async {
-    Source source = addSource(r'''
-class A {
-  get g => null;
-  static foo() {
-    g;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
-    verify([source]);
-  }
-
-  test_instanceMemberAccessFromStatic_method() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-  static foo() {
-    m();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]);
-    verify([source]);
-  }
-
-  test_instantiate_to_bounds_not_matching_bounds() async {
-    Source source = addSource('''
-class Foo<T> {}
-class Bar<T extends Foo<T>> {}
-class Baz extends Bar {}
-void main() {}
-''');
-    var result = await computeAnalysisResult(source);
-    // Instantiate-to-bounds should have instantiated "Bar" to "Bar<Foo>"
-    expect(result.unit.declaredElement.getType('Baz').supertype.toString(),
-        'Bar<Foo<dynamic>>');
-    // Therefore there should be an error, since Bar's type argument T is Foo,
-    // which doesn't extends Foo<T>.
-    assertErrors(
-        source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_instantiateEnum_const() async {
-    Source source = addSource(r'''
-enum E { ONE }
-E e(String name) {
-  return const E();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INSTANTIATE_ENUM]);
-    verify([source]);
-  }
-
-  test_instantiateEnum_new() async {
-    Source source = addSource(r'''
-enum E { ONE }
-E e(String name) {
-  return new E();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INSTANTIATE_ENUM]);
-    verify([source]);
-  }
-
-  test_integerLiteralAsDoubleOutOfRange_excessiveExponent() async {
-    Source source = addSource(
-        'double x = 0xfffffffffffff80000000000000000000000000000000000000000000'
-        '0000000000000000000000000000000000000000000000000000000000000000000000'
-        '0000000000000000000000000000000000000000000000000000000000000000000000'
-        '000000000000000000000000000000000000000000000000000000000000;');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE]);
-    AnalysisError error = analysisResults[source].errors[0];
-
-    // Check that we suggest the max double instead.
-    expect(
-        true,
-        error.correction.contains(
-            '179769313486231570814527423731704356798070567525844996598917476803'
-            '157260780028538760589558632766878171540458953514382464234321326889'
-            '464182768467546703537516986049910576551282076245490090389328944075'
-            '868508455133942304583236903222948165808559332123348274797826204144'
-            '723168738177180919299881250404026184124858368'));
-  }
-
-  test_integerLiteralAsDoubleOutOfRange_excessiveMantissa() async {
-    Source source = addSource('double x = 9223372036854775809;');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE]);
-    AnalysisError error = analysisResults[source].errors[0];
-    // Check that we suggest a valid double instead.
-    expect(true, error.correction.contains('9223372036854775808'));
-  }
-
-  test_integerLiteralOutOfRange_negative() async {
-    Source source = addSource('int x = -9223372036854775809;');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE]);
-  }
-
-  test_integerLiteralOutOfRange_positive() async {
-    Source source = addSource('int x = 9223372036854775808;');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE]);
-  }
-
-  test_invalidAnnotation_importWithPrefix_notConstantVariable() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-final V = 0;''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.V
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_importWithPrefix_notVariableOrConstructorInvocation() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-typedef V();''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.V
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_notConstantVariable() async {
-    Source source = addSource(r'''
-final V = 0;
-@V
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_notVariableOrConstructorInvocation() async {
-    Source source = addSource(r'''
-typedef V();
-@V
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_staticMethodReference() async {
-    Source source = addSource(r'''
-class A {
-  static f() {}
-}
-@A.f
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION]);
-    verify([source]);
-  }
-
-  test_invalidAnnotationFromDeferredLibrary() async {
-    // See test_invalidAnnotation_notConstantVariable
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class V { const V(); }
-const v = const V();''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-@a.v main () {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_invalidAnnotationFromDeferredLibrary_constructor() async {
-    // See test_invalidAnnotation_notConstantVariable
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class C { const C(); }''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-@a.C() main () {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_invalidAnnotationFromDeferredLibrary_namedConstructor() async {
-    // See test_invalidAnnotation_notConstantVariable
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class C { const C.name(); }''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-@a.C.name() main () {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_invalidAnnotationGetter_getter() async {
-    Source source = addSource(r'''
-get V => 0;
-@V
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION_GETTER]);
-    verify([source]);
-  }
-
-  test_invalidAnnotationGetter_importWithPrefix_getter() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-get V => 0;''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.V
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_ANNOTATION_GETTER]);
-    verify([source]);
-  }
-
-  test_invalidConstructorName_notEnclosingClassName_defined() async {
-    Source source = addSource(r'''
-class A {
-  B() : super();
-}
-class B {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
-    // no verify() call, "B" is not resolved
-  }
-
-  test_invalidConstructorName_notEnclosingClassName_undefined() async {
-    Source source = addSource(r'''
-class A {
-  B() : super();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME]);
-    // no verify() call, "B" is not resolved
-  }
-
-  test_invalidFactoryNameNotAClass_notClassName() async {
-    Source source = addSource(r'''
-int B;
-class A {
-  factory B() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
-    verify([source]);
-  }
-
-  test_invalidFactoryNameNotAClass_notEnclosingClassName() async {
-    Source source = addSource(r'''
-class A {
-  factory B() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS]);
-    // no verify() call, "B" is not resolved
-  }
-
-  test_invalidIdentifierInAsync_async() async {
-    // TODO(brianwilkerson) Report this error.
-    Source source = addSource(r'''
-class A {
-  m() async {
-    int async;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC]);
-    verify([source]);
-  }
-
-  test_invalidIdentifierInAsync_await() async {
-    // TODO(brianwilkerson) Report this error.
-    Source source = addSource(r'''
-class A {
-  m() async {
-    int await;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC]);
-    verify([source]);
-  }
-
-  test_invalidIdentifierInAsync_yield() async {
-    // TODO(brianwilkerson) Report this error.
-    Source source = addSource(r'''
-class A {
-  m() async {
-    int yield;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_IDENTIFIER_IN_ASYNC]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnConstructor_async() async {
-    Source source = addSource(r'''
-class A {
-  A() async {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnConstructor_asyncStar() async {
-    Source source = addSource(r'''
-class A {
-  A() async* {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnConstructor_syncStar() async {
-    Source source = addSource(r'''
-class A {
-  A() sync* {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnSetter_member_async() async {
-    Source source = addSource(r'''
-class A {
-  set x(v) async {}
-}''');
-    await computeAnalysisResult(source);
-    // TODO(danrubel): Investigate why error message is duplicated when
-    // using fasta parser.
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
-              ]
-            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnSetter_member_asyncStar() async {
-    Source source = addSource(r'''
-class A {
-  set x(v) async* {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
-              ]
-            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnSetter_member_syncStar() async {
-    Source source = addSource(r'''
-class A {
-  set x(v) sync* {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
-              ]
-            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnSetter_topLevel_async() async {
-    Source source = addSource("set x(v) async {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
-              ]
-            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnSetter_topLevel_asyncStar() async {
-    Source source = addSource("set x(v) async* {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
-              ]
-            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
-    verify([source]);
-  }
-
-  test_invalidModifierOnSetter_topLevel_syncStar() async {
-    Source source = addSource("set x(v) sync* {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER,
-                CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER
-              ]
-            : [CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_factoryConstructor() async {
-    Source source = addSource(r'''
-class A {
-  factory A() { return this; }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_instanceVariableInitializer_inConstructor() async {
-    Source source = addSource(r'''
-class A {
-  var f;
-  A() : f = this;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_instanceVariableInitializer_inDeclaration() async {
-    Source source = addSource(r'''
-class A {
-  var f = this;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_staticMethod() async {
-    Source source = addSource(r'''
-class A {
-  static m() { return this; }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_staticVariableInitializer() async {
-    Source source = addSource(r'''
-class A {
-  static A f = this;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_superInitializer() async {
-    Source source = addSource(r'''
-class A {
-  A(var x) {}
-}
-class B extends A {
-  B() : super(this);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_topLevelFunction() async {
-    Source source = addSource("f() { return this; }");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_variableInitializer() async {
-    Source source = addSource("int x = this;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]);
-    verify([source]);
-  }
-
-  test_invalidTypeArgumentInConstList() async {
-    Source source = addSource(r'''
-class A<E> {
-  m() {
-    return const <E>[];
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST]);
-    verify([source]);
-  }
-
-  test_invalidTypeArgumentInConstMap() async {
-    Source source = addSource(r'''
-class A<E> {
-  m() {
-    return const <String, E>{};
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]);
-    verify([source]);
-  }
-
-  test_invalidUri_export() async {
-    Source source = addSource("export 'ht:';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
-  }
-
-  test_invalidUri_import() async {
-    Source source = addSource("import 'ht:';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
-  }
-
-  test_invalidUri_part() async {
-    Source source = addSource(r'''
-library lib;
-part 'ht:';''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
-  }
-
-  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.
-    Source source = addSource(r'''
-class Foo<T extends num> {
-  const Foo(x, y);
-}
-const x = const Foo<int>(const Foo<int>(0, 1),
-    const <Foo<String>>[]); // (1)
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-    verify([source]);
-  }
-
-  test_isInInstanceVariableInitializer_restored() async {
-    // If ErrorVerifier._isInInstanceVariableInitializer is not properly
-    // restored on exit from visitVariableDeclaration, the error at (1)
-    // won't be detected.
-    Source source = addSource(r'''
-class Foo {
-  var bar;
-  Map foo = {
-    'bar': () {
-        var _bar;
-    },
-    'bop': _foo // (1)
-  };
-  _foo() {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_labelInOuterScope() async {
-    Source source = addSource(r'''
-class A {
-  void m(int i) {
-    l: while (i > 0) {
-      void f() {
-        break l;
-      };
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE]);
-    // We cannot verify resolution with unresolvable labels
-  }
-
-  test_labelUndefined_break() async {
-    Source source = addSource(r'''
-f() {
-  x: while (true) {
-    break y;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.LABEL_UNDEFINED, HintCode.UNUSED_LABEL]);
-    // We cannot verify resolution with undefined labels
-  }
-
-  test_labelUndefined_continue() async {
-    Source source = addSource(r'''
-f() {
-  x: while (true) {
-    continue y;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.LABEL_UNDEFINED, HintCode.UNUSED_LABEL]);
-    // We cannot verify resolution with undefined labels
-  }
-
-  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)
-    Source source = addSource("const int i = (1 ? 'alpha' : 'beta').length;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
-      StaticTypeWarningCode.NON_BOOL_CONDITION
-    ]);
-    verify([source]);
-  }
-
-  test_memberWithClassName_field() async {
-    Source source = addSource(r'''
-class A {
-  int A = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
-    verify([source]);
-  }
-
-  test_memberWithClassName_field2() async {
-    Source source = addSource(r'''
-class A {
-  int z, A, b = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
-    verify([source]);
-  }
-
-  test_memberWithClassName_getter() async {
-    Source source = addSource(r'''
-class A {
-  get A => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]);
-    verify([source]);
-  }
-
-  test_memberWithClassName_method() async {
-    // no test because indistinguishable from constructor
-  }
-
-  test_mixinClassDeclaresConstructor_classDeclaration() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-class B extends Object with A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
-      [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
-    );
-    verify([source]);
-  }
-
-  test_mixinClassDeclaresConstructor_typeAlias() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-class B = Object with A;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
-      [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
-    );
-    verify([source]);
-  }
-
-  test_mixinDeferredClass() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class B extends Object with a.A {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.MIXIN_DEFERRED_CLASS
-    ]);
-  }
-
-  test_mixinDeferredClass_classTypeAlias() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class B {}
-class C = B with a.A;'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.MIXIN_DEFERRED_CLASS
-    ]);
-  }
-
-  test_mixinInference_matchingClass_inPreviousMixin_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-mixin M1 implements A<B> {}
-mixin M2<T> on A<T> {}
-class C extends Object with M1, M2 {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_mixinInference_matchingClass_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-mixin M<T> on A<T> {}
-class C extends A<int> with M {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_mixinInference_noMatchingClass_namedMixinApplication_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-mixin M<T> on A<T> {}
-class C = Object with M;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
-  }
-
-  test_mixinInference_noMatchingClass_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-mixin M<T> on A<T> {}
-class C extends Object with M {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
-  }
-
-  test_mixinInference_noMatchingClass_noSuperclassConstraint_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-mixin M<T> {}
-class C extends Object with M {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_mixinInference_noMatchingClass_typeParametersSupplied_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-class B {}
-mixin M<T> on A<T> {}
-class C extends Object with M<int> {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
-  }
-
-  test_mixinInference_recursiveSubtypeCheck_new_syntax() async {
-    // See dartbug.com/32353 for a detailed explanation.
-    Source source = addSource('''
-class ioDirectory implements ioFileSystemEntity {}
-
-class ioFileSystemEntity {}
-
-abstract class _LocalDirectory
-    extends _LocalFileSystemEntity<_LocalDirectory, ioDirectory>
-    with ForwardingDirectory, DirectoryAddOnsMixin {}
-
-abstract class _LocalFileSystemEntity<T extends FileSystemEntity,
-  D extends ioFileSystemEntity> extends ForwardingFileSystemEntity<T, D> {}
-
-abstract class FileSystemEntity implements ioFileSystemEntity {}
-
-abstract class ForwardingFileSystemEntity<T extends FileSystemEntity,
-  D extends ioFileSystemEntity> implements FileSystemEntity {}
-
-
-mixin ForwardingDirectory<T extends Directory>
-    on ForwardingFileSystemEntity<T, ioDirectory>
-    implements Directory {}
-
-abstract class Directory implements FileSystemEntity, ioDirectory {}
-
-mixin DirectoryAddOnsMixin implements Directory {}
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    var mixins =
-        analysisResult.unit.declaredElement.getType('_LocalDirectory').mixins;
-    expect(mixins[0].toString(), 'ForwardingDirectory<_LocalDirectory>');
-  }
-
-  test_mixinInheritsFromNotObject_classDeclaration_extends() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C extends Object with B {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
-    verify([source]);
-  }
-
-  test_mixinInheritsFromNotObject_classDeclaration_with() async {
-    Source source = addSource(r'''
-class A {}
-class B extends Object with A {}
-class C extends Object with B {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
-    verify([source]);
-  }
-
-  test_mixinInheritsFromNotObject_typeAlias_extends() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C = Object with B;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
-    verify([source]);
-  }
-
-  test_mixinInheritsFromNotObject_typeAlias_with() async {
-    Source source = addSource(r'''
-class A {}
-class B extends Object with A {}
-class C = Object with B;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_class_bool() async {
-    Source source = addSource("class A extends Object with bool {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_class_double() async {
-    Source source = addSource("class A extends Object with double {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_class_int() async {
-    Source source = addSource("class A extends Object with int {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_class_Null() async {
-    Source source = addSource("class A extends Object with Null {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_class_num() async {
-    Source source = addSource("class A extends Object with num {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_class_String() async {
-    Source source = addSource("class A extends Object with String {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_bool() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with bool;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_double() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with double;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_int() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with int;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_Null() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with Null;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_num() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with num;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_String() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with String;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfDisallowedClass_classTypeAlias_String_num() async {
-    Source source = addSource(r'''
-class A {}
-class C = A with String, num;''');
-    await computeAnalysisResult(source);
-    if (enableNewAnalysisDriver) {
-      assertErrors(source, [
-        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
-        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS
-      ]);
-    } else {
-      assertErrors(source, [
-        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
-        CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS
-      ]);
-    }
-    verify([source]);
-  }
-
-  test_mixinOfNonClass() async {
-    // TODO(brianwilkerson) Compare with MIXIN_WITH_NON_CLASS_SUPERCLASS.
-    Source source = addSource(r'''
-var A;
-class B extends Object mixin A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfNonClass_class() async {
-    Source source = addSource(r'''
-int A;
-class B extends Object with A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfNonClass_enum() async {
-    Source source = addSource(r'''
-enum E { ONE }
-class A extends Object with E {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinOfNonClass_typeAlias() async {
-    Source source = addSource(r'''
-class A {}
-int B;
-class C = A with B;''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_OF_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_mixinReferencesSuper() async {
-    Source source = addSource(r'''
-class A {
-  toString() => super.toString();
-}
-class B extends Object with A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
-    verify([source]);
-  }
-
-  test_mixinWithNonClassSuperclass_class() async {
-    Source source = addSource(r'''
-int A;
-class B {}
-class C extends A with B {}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
-    verify([source]);
-  }
-
-  test_mixinWithNonClassSuperclass_typeAlias() async {
-    Source source = addSource(r'''
-int A;
-class B {}
-class C = A with B;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS]);
-    verify([source]);
-  }
-
-  test_multipleRedirectingConstructorInvocations() async {
-    Source source = addSource(r'''
-class A {
-  A() : this.a(), this.b();
-  A.a() {}
-  A.b() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS]);
-    verify([source]);
-  }
-
-  test_multipleSuperInitializers() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  B() : super(), super() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS,
-      StrongModeCode.INVALID_SUPER_INVOCATION
-    ]);
-    verify([source]);
-  }
-
-  test_nativeClauseInNonSDKCode() async {
-    // TODO(jwren) Move this test somewhere else: This test verifies a parser
-    // error code is generated through the ErrorVerifier, it is not a
-    // CompileTimeErrorCode.
-    Source source = addSource("class A native 'string' {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
-    verify([source]);
-  }
-
-  test_nativeFunctionBodyInNonSDKCode_function() async {
-    // TODO(jwren) Move this test somewhere else: This test verifies a parser
-    // error code is generated through the ErrorVerifier, it is not a
-    // CompileTimeErrorCode.
-    Source source = addSource("int m(a) native 'string';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
-    verify([source]);
-  }
-
-  test_nativeFunctionBodyInNonSDKCode_method() async {
-    // TODO(jwren) Move this test somewhere else: This test verifies a parser
-    // error code is generated through the ErrorVerifier, it is not a
-    // CompileTimeErrorCode.
-    Source source = addSource(r'''
-class A{
-  static int m(a) native 'string';
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]);
-    verify([source]);
-  }
-
-  test_noAnnotationConstructorArguments() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-@A
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS]);
-    verify([source]);
-  }
-
-  test_noDefaultSuperConstructorExplicit() async {
-    Source source = addSource(r'''
-class A {
-  A(p);
-}
-class B extends A {
-  B() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]);
-    verify([source]);
-  }
-
-  test_noDefaultSuperConstructorImplicit_superHasParameters() async {
-    Source source = addSource(r'''
-class A {
-  A(p);
-}
-class B extends A {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
-    verify([source]);
-  }
-
-  test_noDefaultSuperConstructorImplicit_superOnlyNamed() async {
-    Source source = addSource(r'''
-class A { A.named() {} }
-class B extends A {}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]);
-    verify([source]);
-  }
-
-  test_nonConstantAnnotationConstructor_named() async {
-    Source source = addSource(r'''
-class A {
-  A.fromInt() {}
-}
-@A.fromInt()
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_nonConstantAnnotationConstructor_unnamed() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-@A()
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_function_named() async {
-    Source source = addSource(r'''
-int y;
-f({x : y}) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_function_positional() async {
-    Source source = addSource(r'''
-int y;
-f([x = y]) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_inConstructor_named() async {
-    Source source = addSource(r'''
-class A {
-  int y;
-  A({x : y}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_inConstructor_positional() async {
-    Source source = addSource(r'''
-class A {
-  int y;
-  A([x = y]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_method_named() async {
-    Source source = addSource(r'''
-class A {
-  int y;
-  m({x : y}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_method_positional() async {
-    Source source = addSource(r'''
-class A {
-  int y;
-  m([x = y]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValueFromDeferredLibrary() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const V = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f({x : a.V}) {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstantDefaultValueFromDeferredLibrary_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const V = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f({x : a.V + 1}) {}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstCaseExpression() async {
-    Source source = addSource(r'''
-f(int p, int q) {
-  switch (p) {
-    case 3 + q:
-      break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION]);
-    verify([source]);
-  }
-
-  test_nonConstCaseExpressionFromDeferredLibrary() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-main (int p) {
-  switch (p) {
-    case a.c:
-      break;
-  }
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstCaseExpressionFromDeferredLibrary_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-main (int p) {
-  switch (p) {
-    case a.c + 1:
-      break;
-  }
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstListElement() async {
-    Source source = addSource(r'''
-f(a) {
-  return const [a];
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT]);
-    verify([source]);
-  }
-
-  test_nonConstListElementFromDeferredLibrary() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f() {
-  return const [a.c];
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstListElementFromDeferredLibrary_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f() {
-  return const [a.c + 1];
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstMapAsExpressionStatement_begin() async {
-    Source source = addSource(r'''
-f() {
-  {'a' : 0, 'b' : 1}.length;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                // TODO(danrubel): Consider improving recovery
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.UNEXPECTED_TOKEN,
-                ParserErrorCode.UNEXPECTED_TOKEN,
-                ParserErrorCode.UNEXPECTED_TOKEN,
-              ]
-            : [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
-    verify([source]);
-  }
-
-  test_nonConstMapAsExpressionStatement_only() async {
-    Source source = addSource(r'''
-f() {
-  {'a' : 0, 'b' : 1};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.UNEXPECTED_TOKEN,
-                ParserErrorCode.UNEXPECTED_TOKEN,
-                ParserErrorCode.UNEXPECTED_TOKEN,
-              ]
-            : [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]);
-    verify([source]);
-  }
-
-  test_nonConstMapKey() async {
-    Source source = addSource(r'''
-f(a) {
-  return const {a : 0};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_MAP_KEY]);
-    verify([source]);
-  }
-
-  test_nonConstMapKeyFromDeferredLibrary() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f() {
-  return const {a.c : 0};
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstMapKeyFromDeferredLibrary_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f() {
-  return const {a.c + 1 : 0};
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstMapValue() async {
-    Source source = addSource(r'''
-f(a) {
-  return const {'a' : a};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE]);
-    verify([source]);
-  }
-
-  test_nonConstMapValueFromDeferredLibrary() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f() {
-  return const {'a' : a.c};
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstMapValueFromDeferredLibrary_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-f() {
-  return const {'a' : a.c + 1};
-}'''
-    ], [
-      CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstValueInInitializer_assert_condition() async {
-    Source source = addSource(r'''
-class A {
-  const A(int i) : assert(i.isNegative);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_assert_message() async {
-    Source source = addSource(r'''
-class A {
-  const A(int i) : assert(i < 0, 'isNegative = ${i.isNegative}');
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_notBool_left() async {
-    Source source = addSource(r'''
-class A {
-  final bool a;
-  const A(String p) : a = p && true;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
-      StaticTypeWarningCode.NON_BOOL_OPERAND
-    ]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_notBool_right() async {
-    Source source = addSource(r'''
-class A {
-  final bool a;
-  const A(String p) : a = true && p;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
-      StaticTypeWarningCode.NON_BOOL_OPERAND
-    ]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_notInt() async {
-    Source source = addSource(r'''
-class A {
-  final int a;
-  const A(String p) : a = 5 & p;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_notNum() async {
-    Source source = addSource(r'''
-class A {
-  final int a;
-  const A(String p) : a = 5 + p;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_field() async {
-    Source source = addSource(r'''
-class A {
-  static int C;
-  final int a;
-  const A() : a = C;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_instanceCreation() async {
-    Source source = addSource(r'''
-class A {
-  A();
-}
-class B {
-  const B() : a = new A();
-  final a;
-}
-var b = const B();''');
-    // TODO(scheglov): the error CONST_EVAL_THROWS_EXCEPTION is redundant and
-    // ought to be suppressed. Or not?
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION
-    ]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_instanceCreation_inDifferentFile() async {
-    Source sourceA = addNamedSource('/a.dart', r'''
-import 'b.dart';
-const v = const MyClass();
-''');
-    Source sourceB = addNamedSource('/b.dart', r'''
-class MyClass {
-  const MyClass([p = foo]);
-}
-''');
-    await computeAnalysisResult(sourceA);
-    assertNoErrors(sourceA);
-    await computeAnalysisResult(sourceB);
-    assertErrors(sourceB, [
-      CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE,
-      StaticWarningCode.UNDEFINED_IDENTIFIER
-    ]);
-  }
-
-  test_nonConstValueInInitializer_redirecting() async {
-    Source source = addSource(r'''
-class A {
-  static var C;
-  const A.named(p);
-  const A() : this.named(C);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_super() async {
-    Source source = addSource(r'''
-class A {
-  const A(p);
-}
-class B extends A {
-  static var C;
-  const B() : super(C);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializerFromDeferredLibrary_field() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class A {
-  final int x;
-  const A() : x = a.c;
-}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode
-          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstValueInInitializerFromDeferredLibrary_field_nested() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class A {
-  final int x;
-  const A() : x = a.c + 1;
-}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode
-          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstValueInInitializerFromDeferredLibrary_redirecting() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class A {
-  const A.named(p);
-  const A() : this.named(a.c);
-}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode
-          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonConstValueInInitializerFromDeferredLibrary_super() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-const int c = 1;''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-class A {
-  const A(p);
-}
-class B extends A {
-  const B() : super(a.c);
-}'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode
-          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
-    ]);
-  }
-
-  test_nonGenerativeConstructor_explicit() async {
-    Source source = addSource(r'''
-class A {
-  factory A.named() => null;
-}
-class B extends A {
-  B() : super.named();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_nonGenerativeConstructor_implicit() async {
-    Source source = addSource(r'''
-class A {
-  factory A() => null;
-}
-class B extends A {
-  B();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_nonGenerativeConstructor_implicit2() async {
-    Source source = addSource(r'''
-class A {
-  factory A() => null;
-}
-class B extends A {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_notEnoughRequiredArguments_const() async {
-    Source source = addSource(r'''
-class A {
-  const A(int p);
-}
-main() {
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
-    verify([source]);
-  }
-
-  test_notEnoughRequiredArguments_const_super() async {
-    Source source = addSource(r'''
-class A {
-  const A(int p);
-}
-class B extends A {
-  const B() : super();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS]);
-    verify([source]);
-  }
-
-  test_objectCannotExtendAnotherClass() async {
-    Source source = addSource(r'''
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS]);
-    verify([source]);
-  }
-
-  test_optionalParameterInOperator_named() async {
-    Source source = addSource(r'''
-class A {
-  operator +({p}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
-    verify([source]);
-  }
-
-  test_optionalParameterInOperator_positional() async {
-    Source source = addSource(r'''
-class A {
-  operator +([p]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]);
-    verify([source]);
-  }
-
-  test_partOfNonPart() async {
-    Source source = addSource(r'''
-library l1;
-part 'l2.dart';''');
-    addNamedSource("/l2.dart", "library l2;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.PART_OF_NON_PART]);
-    verify([source]);
-  }
-
-  test_partOfNonPart_self() async {
-    Source source = addSource(r'''
-library lib;
-part 'test.dart';''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.PART_OF_NON_PART]);
-    verify([source]);
-  }
-
-  test_prefix_assignment_compound_in_method() async {
-    addNamedSource('/lib.dart', 'library lib;');
-    Source source = addSource('''
-import 'lib.dart' as p;
-class C {
-  f() {
-    p += 1;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_assignment_compound_not_in_method() async {
-    addNamedSource('/lib.dart', 'library lib;');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  p += 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_assignment_in_method() async {
-    addNamedSource('/lib.dart', 'library lib;');
-    Source source = addSource('''
-import 'lib.dart' as p;
-class C {
-  f() {
-    p = 1;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_assignment_not_in_method() async {
-    addNamedSource('/lib.dart', 'library lib;');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  p = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_conditionalPropertyAccess_call_loadLibrary() async {
-    addNamedSource('/lib.dart', '''
-library lib;
-''');
-    Source source = addSource('''
-import 'lib.dart' deferred as p;
-f() {
-  p?.loadLibrary();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_conditionalPropertyAccess_get() async {
-    addNamedSource('/lib.dart', '''
-library lib;
-var x;
-''');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  return p?.x;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_conditionalPropertyAccess_get_loadLibrary() async {
-    addNamedSource('/lib.dart', '''
-library lib;
-''');
-    Source source = addSource('''
-import 'lib.dart' deferred as p;
-f() {
-  return p?.loadLibrary;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_conditionalPropertyAccess_set() async {
-    addNamedSource('/lib.dart', '''
-library lib;
-var x;
-''');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  p?.x = null;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefix_conditionalPropertyAccess_set_loadLibrary() async {
-    addNamedSource('/lib.dart', '''
-library lib;
-''');
-    Source source = addSource('''
-import 'lib.dart' deferred as p;
-f() {
-  p?.loadLibrary = null;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefixCollidesWithTopLevelMembers_functionTypeAlias() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A{}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-typedef p();
-p.A a;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
-    verify([source]);
-  }
-
-  test_prefixCollidesWithTopLevelMembers_topLevelFunction() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A{}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-p() {}
-p.A a;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
-    verify([source]);
-  }
-
-  test_prefixCollidesWithTopLevelMembers_topLevelVariable() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A{}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-var p = null;
-p.A a;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
-    verify([source]);
-  }
-
-  test_prefixCollidesWithTopLevelMembers_type() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A{}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-class p {}
-p.A a;''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER]);
-    verify([source]);
-  }
-
-  test_prefixNotFollowedByDot() async {
-    addNamedSource('/lib.dart', 'library lib;');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  return p;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefixNotFollowedByDot_compoundAssignment() async {
-    addNamedSource('/lib.dart', 'library lib;');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  p += 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_prefixNotFollowedByDot_conditionalMethodInvocation() async {
-    addNamedSource('/lib.dart', '''
-library lib;
-g() {}
-''');
-    Source source = addSource('''
-import 'lib.dart' as p;
-f() {
-  p?.g();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
-    verify([source]);
-  }
-
-  test_privateCollisionInClassTypeAlias_mixinAndMixin() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C = Object with A, B;
-''');
-  }
-
-  test_privateCollisionInClassTypeAlias_mixinAndMixin_indirect() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C = Object with A;
-class D = C with B;
-''');
-  }
-
-  test_privateCollisionInClassTypeAlias_superclassAndMixin() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C = A with B;
-''');
-  }
-
-  test_privateCollisionInClassTypeAlias_superclassAndMixin_same() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C = A with A;
-''');
-  }
-
-  test_privateCollisionInMixinApplication_mixinAndMixin() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C extends Object with A, B {}
-''');
-  }
-
-  test_privateCollisionInMixinApplication_mixinAndMixin_indirect() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C extends Object with A {}
-class D extends C with B {}
-''');
-  }
-
-  test_privateCollisionInMixinApplication_superclassAndMixin() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C extends A with B {}
-''');
-  }
-
-  test_privateCollisionInMixinApplication_superclassAndMixin_same() {
-    return _privateCollisionInMixinApplicationTest('''
-import 'lib1.dart';
-class C extends A with A {}
-''');
-  }
-
-  test_privateOptionalParameter() async {
-    Source source = addSource("f({var _p}) {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
-    verify([source]);
-  }
-
-  test_privateOptionalParameter_fieldFormal() async {
-    Source source = addSource(r'''
-class A {
-  var _p;
-  A({this._p: 0});
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
-    verify([source]);
-  }
-
-  test_privateOptionalParameter_withDefaultValue() async {
-    Source source = addSource("f({_p : 0}) {}");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]);
-    verify([source]);
-  }
-
-  test_recursiveCompileTimeConstant() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-  final m = const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
-    verify([source]);
-  }
-
-  test_recursiveCompileTimeConstant_cycle() async {
-    Source source = addSource(r'''
-const x = y + 1;
-const y = x + 1;''');
-    await computeAnalysisResult(source);
-    if (!enableNewAnalysisDriver) {
-      assertErrors(source, [
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-      ]);
-    } else {
-      assertErrors(source, [
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-        StrongModeCode.TOP_LEVEL_CYCLE,
-        StrongModeCode.TOP_LEVEL_CYCLE,
-      ]);
-    }
-    verify([source]);
-  }
-
-  test_recursiveCompileTimeConstant_fromMapLiteral() async {
-    newFile(
-      '/constants.dart',
-      content: r'''
-const int x = y;
-const int y = x;
-''',
-    );
-    Source source = addSource(r'''
-import 'constants.dart';
-final z = {x: 0, y: 1};
-''');
-    await computeAnalysisResult(source);
-    // No errors, because the cycle is not in this source.
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_recursiveCompileTimeConstant_initializer_after_toplevel_var() async {
-    Source source = addSource('''
-const y = const C();
-class C {
-  const C() : x = y;
-  final x;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT]);
-    verify([source]);
-  }
-
-  test_recursiveCompileTimeConstant_singleVariable() async {
-    Source source = addSource(r'''
-const x = x;
-''');
-    await computeAnalysisResult(source);
-    if (!enableNewAnalysisDriver) {
-      assertErrors(source, [
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-      ]);
-    } else {
-      assertErrors(source, [
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-        StrongModeCode.TOP_LEVEL_CYCLE
-      ]);
-    }
-    verify([source]);
-  }
-
-  test_recursiveCompileTimeConstant_singleVariable_fromConstList() async {
-    Source source = addSource(r'''
-const elems = const [
-  const [
-    1, elems, 3,
-  ],
-];
-''');
-    await computeAnalysisResult(source);
-    if (!enableNewAnalysisDriver) {
-      assertErrors(source, [
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-      ]);
-    } else {
-      assertErrors(source, [
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-        StrongModeCode.TOP_LEVEL_CYCLE,
-      ]);
-    }
-    verify([source]);
-  }
-
-  test_recursiveConstructorRedirect() async {
-    Source source = addSource(r'''
-class A {
-  A.a() : this.b();
-  A.b() : this.a();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveConstructorRedirect_directSelfReference() async {
-    Source source = addSource(r'''
-class A {
-  A() : this();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]);
-    verify([source]);
-  }
-
-  test_recursiveFactoryRedirect() async {
-    Source source = addSource(r'''
-class A implements B {
-  factory A() = C;
-}
-class B implements C {
-  factory B() = A;
-}
-class C implements A {
-  factory C() = B;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveFactoryRedirect_directSelfReference() async {
-    Source source = addSource(r'''
-class A {
-  factory A() = A;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
-    verify([source]);
-  }
-
-  test_recursiveFactoryRedirect_diverging() async {
-    // Analysis should terminate even though the redirections don't reach a
-    // fixed point.  (C<int> redirects to C<C<int>>, then to C<C<C<int>>>, and
-    // so on).
-    Source source = addSource('''
-class C<T> {
-  const factory C() = C<C<T>>;
-}
-main() {
-  const C<int>();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]);
-    verify([source]);
-  }
-
-  test_recursiveFactoryRedirect_generic() async {
-    Source source = addSource(r'''
-class A<T> implements B<T> {
-  factory A() = C;
-}
-class B<T> implements C<T> {
-  factory B() = A;
-}
-class C<T> implements A<T> {
-  factory C() = B;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_recursiveFactoryRedirect_named() async {
-    Source source = addSource(r'''
-class A implements B {
-  factory A.nameA() = C.nameC;
-}
-class B implements C {
-  factory B.nameB() = A.nameA;
-}
-class C implements A {
-  factory C.nameC() = B.nameB;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  /**
-   * "A" references "C" which has cycle with "B". But we should not report problem for "A" - it is
-   * not the part of a cycle.
-   */
-  test_recursiveFactoryRedirect_outsideCycle() async {
-    Source source = addSource(r'''
-class A {
-  factory A() = C;
-}
-class B implements C {
-  factory B() = C;
-}
-class C implements A, B {
-  factory C() = B;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
-      CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE
-    ]);
-    verify([source]);
-  }
-
-  test_redirectGenerativeToMissingConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A() : this.noSuchConstructor();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR]);
-  }
-
-  test_redirectGenerativeToNonGenerativeConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A() : this.x();
-  factory A.x() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR
-    ]);
-    verify([source]);
-  }
-
-  test_redirectToMissingConstructor_named() async {
-    Source source = addSource(r'''
-class A implements B{
-  A() {}
-}
-class B {
-  const factory B() = A.name;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
-  }
-
-  test_redirectToMissingConstructor_unnamed() async {
-    Source source = addSource(r'''
-class A implements B{
-  A.name() {}
-}
-class B {
-  const factory B() = A;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR]);
-  }
-
-  test_redirectToNonClass_notAType() async {
-    Source source = addSource(r'''
-int A;
-class B {
-  const factory B() = A;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REDIRECT_TO_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_redirectToNonClass_undefinedIdentifier() async {
-    Source source = addSource(r'''
-class B {
-  const factory B() = A;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REDIRECT_TO_NON_CLASS]);
-    verify([source]);
-  }
-
-  test_redirectToNonConstConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A.a() {}
-  const factory A.b() = A.a;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_referencedBeforeDeclaration_hideInBlock_comment() async {
-    Source source = addSource(r'''
-main() {
-  /// [v] is a variable.
-  var v = 2;
-}
-print(x) {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_referencedBeforeDeclaration_hideInBlock_function() async {
-    Source source = addSource(r'''
-var v = 1;
-main() {
-  print(v);
-  v() {}
-}
-print(x) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_referencedBeforeDeclaration_hideInBlock_local() async {
-    Source source = addSource(r'''
-var v = 1;
-main() {
-  print(v);
-  var v = 2;
-}
-print(x) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_referencedBeforeDeclaration_hideInBlock_subBlock() async {
-    Source source = addSource(r'''
-var v = 1;
-main() {
-  {
-    print(v);
-  }
-  var v = 2;
-}
-print(x) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_referencedBeforeDeclaration_inInitializer_closure() async {
-    Source source = addSource(r'''
-main() {
-  var v = () => v;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_referencedBeforeDeclaration_inInitializer_directly() async {
-    Source source = addSource(r'''
-main() {
-  var v = v;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_referencedBeforeDeclaration_type_localFunction() async {
-    Source source = addSource(r'''
-void testTypeRef() {
-  String s = '';
-  int String(int x) => x + 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_referencedBeforeDeclaration_type_localVariable() async {
-    Source source = addSource(r'''
-void testTypeRef() {
-  String s = '';
-  var String = '';
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION]);
-  }
-
-  test_rethrowOutsideCatch() async {
-    Source source = addSource(r'''
-f() {
-  rethrow;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]);
-    verify([source]);
-  }
-
-  test_returnInGenerativeConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A() { return 0; }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_returnInGenerativeConstructor_expressionFunctionBody() async {
-    Source source = addSource(r'''
-class A {
-  A() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_returnInGenerator_asyncStar() async {
-    Source source = addSource(r'''
-f() async* {
-  return 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.RETURN_IN_GENERATOR,
-                CompileTimeErrorCode.RETURN_IN_GENERATOR
-              ]
-            : [CompileTimeErrorCode.RETURN_IN_GENERATOR]);
-    verify([source]);
-  }
-
-  test_returnInGenerator_syncStar() async {
-    Source source = addSource(r'''
-f() sync* {
-  return 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [
-                CompileTimeErrorCode.RETURN_IN_GENERATOR,
-                CompileTimeErrorCode.RETURN_IN_GENERATOR
-              ]
-            : [CompileTimeErrorCode.RETURN_IN_GENERATOR]);
-    verify([source]);
-  }
-
-  test_sharedDeferredPrefix() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-f1() {}''',
-      r'''
-library lib2;
-f2() {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as lib;
-import 'lib2.dart' as lib;
-main() { lib.f1(); lib.f2(); }'''
-    ], <ErrorCode>[
-      CompileTimeErrorCode.SHARED_DEFERRED_PREFIX
-    ]);
-  }
-
-  test_superInInvalidContext_binaryExpression() async {
-    Source source = addSource("var v = super + 0;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.v' is not resolved
-  }
-
-  test_superInInvalidContext_constructorFieldInitializer() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  var f;
-  B() : f = super.m();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.m' is not resolved
-  }
-
-  test_superInInvalidContext_factoryConstructor() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  factory B() {
-    super.m();
-    return null;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.m' is not resolved
-  }
-
-  test_superInInvalidContext_instanceVariableInitializer() async {
-    Source source = addSource(r'''
-class A {
-  var a;
-}
-class B extends A {
- var b = super.a;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.a' is not resolved
-  }
-
-  test_superInInvalidContext_staticMethod() async {
-    Source source = addSource(r'''
-class A {
-  static m() {}
-}
-class B extends A {
-  static n() { return super.m(); }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.m' is not resolved
-  }
-
-  test_superInInvalidContext_staticVariableInitializer() async {
-    Source source = addSource(r'''
-class A {
-  static int a = 0;
-}
-class B extends A {
-  static int b = super.a;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.a' is not resolved
-  }
-
-  test_superInInvalidContext_topLevelFunction() async {
-    Source source = addSource(r'''
-f() {
-  super.f();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.f' is not resolved
-  }
-
-  test_superInInvalidContext_topLevelVariableInitializer() async {
-    Source source = addSource("var v = super.y;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
-    // no verify(), 'super.y' is not resolved
-  }
-
-  test_superInitializerInObject() async {
-    Source source = addSource(r'''
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_INITIALIZER_IN_OBJECT]);
-    verify([source]);
-  }
-
-  test_superInRedirectingConstructor_redirectionSuper() async {
-    Source source = addSource(r'''
-class A {}
-class B {
-  B() : this.name(), super();
-  B.name() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR]);
-    verify([source]);
-  }
-
-  test_superInRedirectingConstructor_superRedirection() async {
-    Source source = addSource(r'''
-class A {}
-class B {
-  B() : super(), this.name();
-  B.name() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
-      StrongModeCode.INVALID_SUPER_INVOCATION
-    ]);
-    verify([source]);
-  }
-
-  test_symbol_constructor_badArgs() async {
-    Source source = addSource(r'''
-var s1 = const Symbol('3');
-var s2 = const Symbol(3);
-var s3 = const Symbol();
-var s4 = const Symbol('x', 'y');
-var s5 = const Symbol('x', foo: 'x');''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-      CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
-      CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS,
-      CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
-    ]);
-    verify([source]);
-  }
-
-  test_test_fieldInitializerOutsideConstructor_topLevelFunction() async {
-    Source source = addSource(r'''
-f(this.x(y)) {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source,
-        usingFastaParser
-            ? [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]
-            : [
-                ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
-                CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
-              ]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_11987() async {
-    Source source = addSource(r'''
-typedef void F(List<G> l);
-typedef void G(List<F> l);
-main() {
-  F foo(G g) => g;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
-    ]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_19459() async {
-    // A complex example involving multiple classes.  This is legal, since
-    // typedef F references itself only via a class.
-    Source source = addSource(r'''
-class A<B, C> {}
-abstract class D {
-  f(E e);
-}
-abstract class E extends A<dynamic, F> {}
-typedef D F();
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_functionTypedParameter_returnType() async {
-    Source source = addSource("typedef A(A b());");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_generic() async {
-    Source source = addSource(r'''
-typedef F = void Function(List<G> l);
-typedef G = void Function(List<F> l);
-main() {
-  F foo(G g) => g;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
-    ]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_parameterType_named() async {
-    Source source = addSource("typedef A({A a});");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_parameterType_positional() async {
-    Source source = addSource("typedef A([A a]);");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_parameterType_required() async {
-    Source source = addSource("typedef A(A a);");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_parameterType_typeArgument() async {
-    Source source = addSource("typedef A(List<A> a);");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_returnClass_withTypeAlias() async {
-    // A typedef is allowed to indirectly reference itself via a class.
-    Source source = addSource(r'''
-typedef C A();
-typedef A B();
-class C {
-  B a;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_returnType() async {
-    Source source = addSource("typedef A A();");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_returnType_indirect() async {
-    Source source = addSource(r'''
-typedef B A();
-typedef A B();''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
-    ]);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_typeVariableBounds() async {
-    Source source = addSource("typedef A<T extends A<int>>();");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-      StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
-    ]);
-    verify([source]);
-  }
-
-  test_typeArgumentNotMatchingBounds_const() async {
-    Source source = addSource(r'''
-class A {}
-class B {}
-class G<E extends A> {
-  const G();
-}
-f() { return const G<B>(); }''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-    verify([source]);
-  }
-
-  test_typedef_infiniteParameterBoundCycle() async {
-    Source source = addSource(r'''
-typedef F<X extends F> = F Function();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-    ]);
-    verify([source]);
-  }
-
-  test_undefinedAnnotation_unresolved_identifier() async {
-    Source source = addSource(r'''
-@unresolved
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
-  }
-
-  test_undefinedAnnotation_unresolved_invocation() async {
-    Source source = addSource(r'''
-@Unresolved()
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
-  }
-
-  test_undefinedAnnotation_unresolved_prefixedIdentifier() async {
-    Source source = addSource(r'''
-import 'dart:math' as p;
-@p.unresolved
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
-  }
-
-  test_undefinedAnnotation_useLibraryScope() async {
-    Source source = addSource(r'''
-@foo
-class A {
-  static const foo = null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_ANNOTATION]);
-  }
-
-  test_undefinedClass_const() async {
-    Source source = addSource(r'''
-f() {
-  return const A();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticWarningCode.UNDEFINED_CLASS]);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_explicit_named() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  B() : super.named();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER]);
-    // no verify(), "super.named()" is not resolved
-  }
-
-  test_undefinedConstructorInInitializer_explicit_unnamed() async {
-    Source source = addSource(r'''
-class A {
-  A.named() {}
-}
-class B extends A {
-  B() : super();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_implicit() async {
-    Source source = addSource(r'''
-class A {
-  A.named() {}
-}
-class B extends A {
-  B();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
-    verify([source]);
-  }
-
-  test_undefinedNamedParameter() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-main() {
-  const A(p: 0);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER]);
-    // no verify(), 'p' is not resolved
-  }
-
-  test_uriDoesNotExist_export() async {
-    Source source = addSource("export 'unknown.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  test_uriDoesNotExist_import() async {
-    Source source = addSource("import 'unknown.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  test_uriDoesNotExist_import_appears_after_deleting_target() async {
-    Source test = addSource("import 'target.dart';");
-    Source target = addNamedSource("/target.dart", "");
-    await computeAnalysisResult(test);
-    assertErrors(test, [HintCode.UNUSED_IMPORT]);
-
-    // Remove the overlay in the same way as AnalysisServer.
-    deleteFile(target.fullName);
-    if (enableNewAnalysisDriver) {
-      driver.removeFile(target.fullName);
-    } else {
-      analysisContext2.setContents(target, null);
-      ChangeSet changeSet = new ChangeSet()..removedSource(target);
-      analysisContext2.applyChanges(changeSet);
-    }
-
-    await computeAnalysisResult(test);
-    assertErrors(test, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  test_uriDoesNotExist_import_disappears_when_fixed() async {
-    Source source = addSource("import 'target.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-
-    String targetPath = convertPath('/target.dart');
-    if (enableNewAnalysisDriver) {
-      // Add an overlay in the same way as AnalysisServer.
-      fileContentOverlay[targetPath] = '';
-      driver.changeFile(targetPath);
-    } else {
-      // Check that the file is represented as missing.
-      Source target = analysisContext2.getSourcesWithFullName(targetPath).first;
-      expect(analysisContext2.getModificationStamp(target), -1);
-
-      // Add an overlay in the same way as AnalysisServer.
-      analysisContext2
-        ..setContents(target, "")
-        ..handleContentsChanged(target, null, "", true);
-    }
-
-    // Make sure the error goes away.
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_IMPORT]);
-  }
-
-  test_uriDoesNotExist_part() async {
-    Source source = addSource(r'''
-library lib;
-part 'unknown.dart';''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  test_uriWithInterpolation_constant() async {
-    Source source = addSource("import 'stuff_\$platform.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.URI_WITH_INTERPOLATION,
-      StaticWarningCode.UNDEFINED_IDENTIFIER
-    ]);
-    // We cannot verify resolution with an unresolvable
-    // URI: 'stuff_$platform.dart'
-  }
-
-  test_uriWithInterpolation_nonConstant() async {
-    Source source = addSource(r'''
-library lib;
-part '${'a'}.dart';''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_WITH_INTERPOLATION]);
-    // We cannot verify resolution with an unresolvable URI: '${'a'}.dart'
-  }
-
-  test_wrongNumberOfParametersForOperator1() async {
-    await _check_wrongNumberOfParametersForOperator1("<");
-    await _check_wrongNumberOfParametersForOperator1(">");
-    await _check_wrongNumberOfParametersForOperator1("<=");
-    await _check_wrongNumberOfParametersForOperator1(">=");
-    await _check_wrongNumberOfParametersForOperator1("+");
-    await _check_wrongNumberOfParametersForOperator1("/");
-    await _check_wrongNumberOfParametersForOperator1("~/");
-    await _check_wrongNumberOfParametersForOperator1("*");
-    await _check_wrongNumberOfParametersForOperator1("%");
-    await _check_wrongNumberOfParametersForOperator1("|");
-    await _check_wrongNumberOfParametersForOperator1("^");
-    await _check_wrongNumberOfParametersForOperator1("&");
-    await _check_wrongNumberOfParametersForOperator1("<<");
-    await _check_wrongNumberOfParametersForOperator1(">>");
-    await _check_wrongNumberOfParametersForOperator1("[]");
-  }
-
-  test_wrongNumberOfParametersForOperator_minus() async {
-    Source source = addSource(r'''
-class A {
-  operator -(a, b) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForOperator_tilde() async {
-    await _check_wrongNumberOfParametersForOperator("~", "a");
-    await _check_wrongNumberOfParametersForOperator("~", "a, b");
-  }
-
-  test_wrongNumberOfParametersForSetter_function_named() async {
-    Source source = addSource("set x({p}) {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_function_optional() async {
-    Source source = addSource("set x([p]) {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_function_tooFew() async {
-    Source source = addSource("set x() {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_function_tooMany() async {
-    Source source = addSource("set x(a, b) {}");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_method_named() async {
-    Source source = addSource(r'''
-class A {
-  set x({p}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_method_optional() async {
-    Source source = addSource(r'''
-class A {
-  set x([p]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_method_tooFew() async {
-    Source source = addSource(r'''
-class A {
-  set x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForSetter_method_tooMany() async {
-    Source source = addSource(r'''
-class A {
-  set x(a, b) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER]);
-    verify([source]);
-  }
-
-  test_yield_used_as_identifier_in_async_method() async {
-    Source source = addSource('''
-f() async {
-  var yield = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_yield_used_as_identifier_in_async_star_method() async {
-    Source source = addSource('''
-f() async* {
-  var yield = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_yield_used_as_identifier_in_sync_star_method() async {
-    Source source = addSource('''
-f() sync* {
-  var yield = 1;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER]);
-    verify([source]);
-  }
-
-  test_yieldEachInNonGenerator_async() async {
-    // TODO(brianwilkerson) We are currently parsing the yield statement as a
-    // binary expression.
-    Source source = addSource(r'''
-f() async {
-  yield* 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR]);
-    verify([source]);
-  }
-
-  test_yieldEachInNonGenerator_sync() async {
-    // TODO(brianwilkerson) We are currently parsing the yield statement as a
-    // binary expression.
-    Source source = addSource(r'''
-f() {
-  yield* 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.YIELD_IN_NON_GENERATOR]);
-    verify([source]);
-  }
-
-  test_yieldInNonGenerator_async() async {
-    // TODO(brianwilkerson) We are currently trying to parse the yield statement
-    // as a binary expression.
-    Source source = addSource(r'''
-f() async {
-  yield 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.YIELD_IN_NON_GENERATOR]);
-    verify([source]);
-  }
-
-  test_yieldInNonGenerator_sync() async {
-    // TODO(brianwilkerson) We are currently trying to parse the yield statement
-    // as a binary expression.
-    Source source = addSource(r'''
-f() {
-  yield 0;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR]);
-    verify([source]);
-  }
-
-  Future<void> _check_constEvalThrowsException_binary_null(
-      String expr, bool resolved) async {
-    Source source = addSource("const C = $expr;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
-    if (resolved) {
-      verify([source]);
-    }
-  }
-
-  Future<void> _check_constEvalTypeBool_withParameter_binary(
-      String expr) async {
-    Source source = addSource('''
-class A {
-  final a;
-  const A(bool p) : a = $expr;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
-      StaticTypeWarningCode.NON_BOOL_OPERAND
-    ]);
-    verify([source]);
-  }
-
-  Future<void> _check_constEvalTypeBoolOrInt_withParameter_binary(
-      String expr) async {
-    Source source = addSource('''
-class A {
-  final a;
-  const A(int p) : a = $expr;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  Future<void> _check_constEvalTypeInt_withParameter_binary(String expr) async {
-    Source source = addSource('''
-class A {
-  final a;
-  const A(int p) : a = $expr;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  Future<void> _check_constEvalTypeNum_withParameter_binary(String expr) async {
-    Source source = addSource('''
-class A {
-  final a;
-  const A(num p) : a = $expr;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-  }
-
-  Future<void> _check_wrongNumberOfParametersForOperator(
-      String name, String parameters) async {
-    Source source = addSource('''
-class A {
-  operator $name($parameters) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]);
-    verify([source]);
-  }
-
-  Future<void> _check_wrongNumberOfParametersForOperator1(String name) async {
-    await _check_wrongNumberOfParametersForOperator(name, "");
-    await _check_wrongNumberOfParametersForOperator(name, "a, b");
-  }
-
-  Future<void> _privateCollisionInMixinApplicationTest(String testCode) async {
-    addNamedSource('/lib1.dart', '''
-class A {
-  int _x;
-}
-
-class B {
-  int _x;
-}
-''');
-    Source source = addSource(testCode);
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION]);
-    verify([source]);
-  }
-}
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index 12c9c85..d4e7df3 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -5,16 +5,12 @@
 @deprecated
 library analyzer.test.constant_test;
 
-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/constant.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'resolver_test_case.dart';
+import '../src/dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -23,109 +19,25 @@
 }
 
 @reflectiveTest
-class ConstantEvaluatorTest extends ResolverTestCase {
-  void fail_identifier_class() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
+class ConstantEvaluatorTest extends DriverResolutionTest {
+  test_bitAnd_int_int() async {
+    await _assertValueInt(74 & 42, "74 & 42");
   }
 
-  void fail_identifier_function() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
+  test_bitNot() async {
+    await _assertValueInt(~42, "~42");
   }
 
-  void fail_identifier_static() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
+  test_bitOr_int_int() async {
+    await _assertValueInt(74 | 42, "74 | 42");
   }
 
-  void fail_identifier_staticMethod() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
+  test_bitXor_int_int() async {
+    await _assertValueInt(74 ^ 42, "74 ^ 42");
   }
 
-  void fail_identifier_topLevel() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_typeParameter() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_prefixedIdentifier_invalid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_prefixedIdentifier_valid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_propertyAccess_invalid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_propertyAccess_valid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_simpleIdentifier_invalid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_simpleIdentifier_valid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void test_bitAnd_int_int() {
-    _assertValue3(74 & 42, "74 & 42");
-  }
-
-  void test_bitNot() {
-    _assertValue3(~42, "~42");
-  }
-
-  void test_bitOr_int_int() {
-    _assertValue3(74 | 42, "74 | 42");
-  }
-
-  void test_bitXor_int_int() {
-    _assertValue3(74 ^ 42, "74 ^ 42");
-  }
-
-  void test_constructorInvocation_assert_false() {
-    EvaluationResult result = _getExpressionValue("const C(0)", context: '''
+  test_constructorInvocation_assert_false() async {
+    var result = await _getExpressionValue("const C(0)", context: '''
 class C {
   const C(int x) : assert(x > 0);
 }
@@ -134,8 +46,9 @@
   }
 
   test_constructorInvocation_assert_inherited() async {
-    EvaluationResult result =
-        _getExpressionValue("const Center(name: 'v')", context: '''
+    var result = await _getExpressionValue(
+      "const Center(name: 'v')",
+      context: '''
 class Align {
   final double widthFactor;
   const Align({String name, this.widthFactor})
@@ -145,7 +58,8 @@
   const Center({String name})
     : super(name: name);
 }
-''');
+''',
+    );
     expect(result.isValid, isTrue);
     DartObject value = result.value;
     expect(value, isNotNull);
@@ -156,8 +70,8 @@
     expect(widthFactor.isNull, isTrue);
   }
 
-  void test_constructorInvocation_assert_true() {
-    EvaluationResult result = _getExpressionValue("const C(3)", context: '''
+  test_constructorInvocation_assert_true() async {
+    var result = await _getExpressionValue("const C(3)", context: '''
 class C {
   const C(int x) : assert(x > 0);
 }
@@ -168,8 +82,8 @@
     expect(value.type.name, 'C');
   }
 
-  void test_constructorInvocation_fieldInitializer() {
-    EvaluationResult result = _getExpressionValue("const C(2)", context: '''
+  test_constructorInvocation_fieldInitializer() async {
+    var result = await _getExpressionValue("const C(2)", context: '''
 class C {
   final int x;
   const C(this.x);
@@ -185,25 +99,29 @@
     expect(x.toIntValue(), 2);
   }
 
-  void test_constructorInvocation_noArgs() {
-    EvaluationResult result =
-        _getExpressionValue("const C()", context: 'class C {const C();}');
+  test_constructorInvocation_noArgs() async {
+    var result = await _getExpressionValue(
+      "const C()",
+      context: 'class C {const C();}',
+    );
     expect(result.isValid, isTrue);
     DartObject value = result.value;
     expect(value, isNotNull);
     expect(value.type.name, 'C');
   }
 
-  void test_constructorInvocation_noConstConstructor() {
-    EvaluationResult result =
-        _getExpressionValue("const C()", context: 'class C {}');
+  test_constructorInvocation_noConstConstructor() async {
+    var result = await _getExpressionValue(
+      "const C()",
+      context: 'class C {}',
+    );
     expect(result.isValid, isFalse);
     DartObject value = result.value;
     expect(value, isNull);
   }
 
-  void test_constructorInvocation_simpleArgs() {
-    EvaluationResult result = _getExpressionValue("const C(1)", context: '''
+  test_constructorInvocation_simpleArgs() async {
+    var result = await _getExpressionValue("const C(1)", context: '''
 class C {
   const C(int x);
 }
@@ -214,254 +132,351 @@
     expect(value.type.name, 'C');
   }
 
-  void test_divide_double_double() {
-    _assertValue2(3.2 / 2.3, "3.2 / 2.3");
+  test_divide_double_double() async {
+    await _assertValueDouble(3.2 / 2.3, "3.2 / 2.3");
   }
 
-  void test_divide_double_double_byZero() {
-    EvaluationResult result = _getExpressionValue("3.2 / 0.0");
+  test_divide_double_double_byZero() async {
+    var result = await _getExpressionValue("3.2 / 0.0");
     expect(result.isValid, isTrue);
     DartObject value = result.value;
     expect(value.type.name, "double");
     expect(value.toDoubleValue().isInfinite, isTrue);
   }
 
-  void test_divide_int_int() {
-    _assertValue2(1.5, "3 / 2");
+  test_divide_int_int() async {
+    await _assertValueDouble(1.5, "3 / 2");
   }
 
-  void test_divide_int_int_byZero() {
-    EvaluationResult result = _getExpressionValue("3 / 0");
+  test_divide_int_int_byZero() async {
+    var result = await _getExpressionValue("3 / 0");
     expect(result.isValid, isTrue);
   }
 
-  void test_equal_boolean_boolean() {
-    _assertValue(false, "true == false");
+  test_equal_boolean_boolean() async {
+    await _assertValueBool(false, "true == false");
   }
 
-  void test_equal_int_int() {
-    _assertValue(false, "2 == 3");
+  test_equal_int_int() async {
+    await _assertValueBool(false, "2 == 3");
   }
 
-  void test_equal_invalidLeft() {
-    EvaluationResult result = _getExpressionValue("a == 3");
+  test_equal_invalidLeft() async {
+    var result = await _getExpressionValue("a == 3");
     expect(result.isValid, isFalse);
   }
 
-  void test_equal_invalidRight() {
-    EvaluationResult result = _getExpressionValue("2 == a");
+  test_equal_invalidRight() async {
+    var result = await _getExpressionValue("2 == a");
     expect(result.isValid, isFalse);
   }
 
-  void test_equal_string_string() {
-    _assertValue(false, "'a' == 'b'");
+  test_equal_string_string() async {
+    await _assertValueBool(false, "'a' == 'b'");
   }
 
-  void test_greaterThan_int_int() {
-    _assertValue(false, "2 > 3");
+  test_greaterThan_int_int() async {
+    await _assertValueBool(false, "2 > 3");
   }
 
-  void test_greaterThanOrEqual_int_int() {
-    _assertValue(false, "2 >= 3");
+  test_greaterThanOrEqual_int_int() async {
+    await _assertValueBool(false, "2 >= 3");
   }
 
-  void test_leftShift_int_int() {
-    _assertValue3(64, "16 << 2");
+  @failingTest
+  test_identifier_class() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_lessThan_int_int() {
-    _assertValue(true, "2 < 3");
+  @failingTest
+  test_identifier_function() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_lessThanOrEqual_int_int() {
-    _assertValue(true, "2 <= 3");
+  @failingTest
+  test_identifier_static() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_literal_boolean_false() {
-    _assertValue(false, "false");
+  @failingTest
+  test_identifier_staticMethod() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_literal_boolean_true() {
-    _assertValue(true, "true");
+  @failingTest
+  test_identifier_topLevel() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_literal_list() {
-    EvaluationResult result = _getExpressionValue("const ['a', 'b', 'c']");
+  @failingTest
+  test_identifier_typeParameter() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  test_leftShift_int_int() async {
+    await _assertValueInt(64, "16 << 2");
+  }
+
+  test_lessThan_int_int() async {
+    await _assertValueBool(true, "2 < 3");
+  }
+
+  test_lessThanOrEqual_int_int() async {
+    await _assertValueBool(true, "2 <= 3");
+  }
+
+  test_literal_boolean_false() async {
+    await _assertValueBool(false, "false");
+  }
+
+  test_literal_boolean_true() async {
+    await _assertValueBool(true, "true");
+  }
+
+  test_literal_list() async {
+    var result = await _getExpressionValue("const ['a', 'b', 'c']");
     expect(result.isValid, isTrue);
   }
 
-  void test_literal_map() {
-    EvaluationResult result =
-        _getExpressionValue("const {'a' : 'm', 'b' : 'n', 'c' : 'o'}");
+  test_literal_map() async {
+    var result = await _getExpressionValue(
+      "const {'a' : 'm', 'b' : 'n', 'c' : 'o'}",
+    );
     expect(result.isValid, isTrue);
     Map<DartObject, DartObject> map = result.value.toMapValue();
     expect(map.keys.map((k) => k.toStringValue()), ['a', 'b', 'c']);
   }
 
-  void test_literal_null() {
-    EvaluationResult result = _getExpressionValue("null");
+  test_literal_null() async {
+    var result = await _getExpressionValue("null");
     expect(result.isValid, isTrue);
     DartObject value = result.value;
     expect(value.isNull, isTrue);
   }
 
-  void test_literal_number_double() {
-    _assertValue2(3.45, "3.45");
+  test_literal_number_double() async {
+    await _assertValueDouble(3.45, "3.45");
   }
 
-  void test_literal_number_integer() {
-    _assertValue3(42, "42");
+  test_literal_number_integer() async {
+    await _assertValueInt(42, "42");
   }
 
-  void test_literal_string_adjacent() {
-    _assertValue4("abcdef", "'abc' 'def'");
+  test_literal_string_adjacent() async {
+    await _assertValueString("abcdef", "'abc' 'def'");
   }
 
-  void test_literal_string_interpolation_invalid() {
-    EvaluationResult result = _getExpressionValue("'a\${f()}c'");
+  test_literal_string_interpolation_invalid() async {
+    var result = await _getExpressionValue("'a\${f()}c'");
     expect(result.isValid, isFalse);
   }
 
-  void test_literal_string_interpolation_valid() {
-    _assertValue4("a3c", "'a\${3}c'");
+  test_literal_string_interpolation_valid() async {
+    await _assertValueString("a3c", "'a\${3}c'");
   }
 
-  void test_literal_string_simple() {
-    _assertValue4("abc", "'abc'");
+  test_literal_string_simple() async {
+    await _assertValueString("abc", "'abc'");
   }
 
-  void test_logicalAnd() {
-    _assertValue(false, "true && false");
+  test_logicalAnd() async {
+    await _assertValueBool(false, "true && false");
   }
 
-  void test_logicalNot() {
-    _assertValue(false, "!true");
+  test_logicalNot() async {
+    await _assertValueBool(false, "!true");
   }
 
-  void test_logicalOr() {
-    _assertValue(true, "true || false");
+  test_logicalOr() async {
+    await _assertValueBool(true, "true || false");
   }
 
-  void test_minus_double_double() {
-    _assertValue2(3.2 - 2.3, "3.2 - 2.3");
+  test_minus_double_double() async {
+    await _assertValueDouble(3.2 - 2.3, "3.2 - 2.3");
   }
 
-  void test_minus_int_int() {
-    _assertValue3(1, "3 - 2");
+  test_minus_int_int() async {
+    await _assertValueInt(1, "3 - 2");
   }
 
-  void test_negated_boolean() {
-    EvaluationResult result = _getExpressionValue("-true");
+  test_negated_boolean() async {
+    var result = await _getExpressionValue("-true");
     expect(result.isValid, isFalse);
   }
 
-  void test_negated_double() {
-    _assertValue2(-42.3, "-42.3");
+  test_negated_double() async {
+    await _assertValueDouble(-42.3, "-42.3");
   }
 
-  void test_negated_integer() {
-    _assertValue3(-42, "-42");
+  test_negated_integer() async {
+    await _assertValueInt(-42, "-42");
   }
 
-  void test_notEqual_boolean_boolean() {
-    _assertValue(true, "true != false");
+  test_notEqual_boolean_boolean() async {
+    await _assertValueBool(true, "true != false");
   }
 
-  void test_notEqual_int_int() {
-    _assertValue(true, "2 != 3");
+  test_notEqual_int_int() async {
+    await _assertValueBool(true, "2 != 3");
   }
 
-  void test_notEqual_invalidLeft() {
-    EvaluationResult result = _getExpressionValue("a != 3");
+  test_notEqual_invalidLeft() async {
+    var result = await _getExpressionValue("a != 3");
     expect(result.isValid, isFalse);
   }
 
-  void test_notEqual_invalidRight() {
-    EvaluationResult result = _getExpressionValue("2 != a");
+  test_notEqual_invalidRight() async {
+    var result = await _getExpressionValue("2 != a");
     expect(result.isValid, isFalse);
   }
 
-  void test_notEqual_string_string() {
-    _assertValue(true, "'a' != 'b'");
+  test_notEqual_string_string() async {
+    await _assertValueBool(true, "'a' != 'b'");
   }
 
-  void test_parenthesizedExpression() {
-    _assertValue4("a", "('a')");
+  test_parenthesizedExpression() async {
+    await _assertValueString("a", "('a')");
   }
 
-  void test_plus_double_double() {
-    _assertValue2(2.3 + 3.2, "2.3 + 3.2");
+  test_plus_double_double() async {
+    await _assertValueDouble(2.3 + 3.2, "2.3 + 3.2");
   }
 
-  void test_plus_int_int() {
-    _assertValue3(5, "2 + 3");
+  test_plus_int_int() async {
+    await _assertValueInt(5, "2 + 3");
   }
 
-  void test_plus_string_string() {
-    _assertValue4("ab", "'a' + 'b'");
+  test_plus_string_string() async {
+    await _assertValueString("ab", "'a' + 'b'");
   }
 
-  void test_remainder_double_double() {
-    _assertValue2(3.2 % 2.3, "3.2 % 2.3");
+  @failingTest
+  test_prefixedIdentifier_invalid() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_remainder_int_int() {
-    _assertValue3(2, "8 % 3");
+  @failingTest
+  test_prefixedIdentifier_valid() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_rightShift() {
-    _assertValue3(16, "64 >> 2");
+  @failingTest
+  test_propertyAccess_invalid() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_stringLength_complex() {
-    _assertValue3(6, "('qwe' + 'rty').length");
+  @failingTest
+  test_propertyAccess_valid() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_stringLength_simple() {
-    _assertValue3(6, "'Dvorak'.length");
+  test_remainder_double_double() async {
+    await _assertValueDouble(3.2 % 2.3, "3.2 % 2.3");
   }
 
-  void test_times_double_double() {
-    _assertValue2(2.3 * 3.2, "2.3 * 3.2");
+  test_remainder_int_int() async {
+    await _assertValueInt(2, "8 % 3");
   }
 
-  void test_times_int_int() {
-    _assertValue3(6, "2 * 3");
+  test_rightShift() async {
+    await _assertValueInt(16, "64 >> 2");
   }
 
-  void test_truncatingDivide_double_double() {
-    _assertValue3(1, "3.2 ~/ 2.3");
+  @failingTest
+  test_simpleIdentifier_invalid() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void test_truncatingDivide_int_int() {
-    _assertValue3(3, "10 ~/ 3");
+  @failingTest
+  test_simpleIdentifier_valid() async {
+    var result = await _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
   }
 
-  void _assertValue(bool expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
+  test_stringLength_complex() async {
+    await _assertValueInt(6, "('qwe' + 'rty').length");
+  }
+
+  test_stringLength_simple() async {
+    await _assertValueInt(6, "'Dvorak'.length");
+  }
+
+  test_times_double_double() async {
+    await _assertValueDouble(2.3 * 3.2, "2.3 * 3.2");
+  }
+
+  test_times_int_int() async {
+    await _assertValueInt(6, "2 * 3");
+  }
+
+  test_truncatingDivide_double_double() async {
+    await _assertValueInt(1, "3.2 ~/ 2.3");
+  }
+
+  test_truncatingDivide_int_int() async {
+    await _assertValueInt(3, "10 ~/ 3");
+  }
+
+  Future<void> _assertValueBool(bool expectedValue, String contents) async {
+    var result = await _getExpressionValue(contents);
     DartObject value = result.value;
     expect(value.type.name, "bool");
     expect(value.toBoolValue(), expectedValue);
   }
 
-  void _assertValue2(double expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
+  Future<void> _assertValueDouble(double expectedValue, String contents) async {
+    var result = await _getExpressionValue(contents);
     expect(result.isValid, isTrue);
     DartObject value = result.value;
     expect(value.type.name, "double");
     expect(value.toDoubleValue(), expectedValue);
   }
 
-  void _assertValue3(int expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
+  Future<void> _assertValueInt(int expectedValue, String contents) async {
+    var result = await _getExpressionValue(contents);
     expect(result.isValid, isTrue);
     DartObject value = result.value;
     expect(value.type.name, "int");
     expect(value.toIntValue(), expectedValue);
   }
 
-  void _assertValue4(String expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
+  Future<void> _assertValueString(String expectedValue, String contents) async {
+    var result = await _getExpressionValue(contents);
     DartObject value = result.value;
     expect(value, isNotNull);
     ParameterizedType type = value.type;
@@ -470,19 +485,26 @@
     expect(value.toStringValue(), expectedValue);
   }
 
-  EvaluationResult _getExpressionValue(String contents, {String context: ''}) {
-    Source source = addSource("var x = $contents;$context");
-    LibraryElement library = resolve2(source);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(source, library);
-    expect(unit, isNotNull);
-    NodeList<CompilationUnitMember> declarations = unit.declarations;
-    TopLevelVariableDeclaration declaration = declarations[0];
-    NodeList<VariableDeclaration> variables = declaration.variables.variables;
-    expect(variables, hasLength(1));
-    ConstantEvaluator evaluator = new ConstantEvaluator(
-        source, analysisContext.typeProvider,
-        typeSystem: analysisContext.typeSystem);
-    return evaluator.evaluate(variables[0].initializer);
+  Future<EvaluationResult> _getExpressionValue(String expressionCode,
+      {String context: ''}) async {
+    var path = convertPath('/test/lib/test.dart');
+
+    var file = newFile(path, content: '''
+var x = $expressionCode;
+
+$context
+''');
+
+    await resolveTestFile();
+
+    var expression = findNode.variableDeclaration('x =').initializer;
+
+    var evaluator = ConstantEvaluator(
+      file.createSource(result.uri),
+      result.typeProvider,
+      typeSystem: result.typeSystem,
+    );
+
+    return evaluator.evaluate(expression);
   }
 }
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index 26dd5a1..db29c01 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -10,20 +10,19 @@
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/declaration_resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/api/dart.dart';
-import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'resolver_test_case.dart';
+import '../src/dart/resolution/driver_resolution.dart';
+import '../util/element_type_matchers.dart';
 import 'test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(DeclarationResolverMetadataTest);
     defineReflectiveTests(DeclarationResolverTest);
-    defineReflectiveTests(StrongModeDeclarationResolverTest);
   });
 }
 
@@ -33,14 +32,8 @@
   return clonedUnit;
 }
 
-SimpleIdentifier _findSimpleIdentifier(
-    AstNode root, String code, String search) {
-  return EngineTestCase.findNode(
-      root, code, search, (n) => n is SimpleIdentifier);
-}
-
 @reflectiveTest
-class DeclarationResolverMetadataTest extends ResolverTestCase {
+class DeclarationResolverMetadataTest extends DriverResolutionTest {
   String code;
   CompilationUnit unit;
   CompilationUnit unit2;
@@ -60,53 +53,57 @@
 
   Future<void> setupCode(String code) async {
     this.code = code;
-    unit = await resolveSource(code + ' const a = null;');
+
+    addTestFile(code + ' const a = null;');
+    await resolveTestFile();
+
+    unit = result.unit;
     unit2 = _cloneResolveUnit(unit);
   }
 
-  test_metadata_classDeclaration() async {
+  test_classDeclaration() async {
     await setupCode('@a class C {}');
     checkMetadata('C');
   }
 
-  test_metadata_classTypeAlias() async {
+  test_classTypeAlias() async {
     await setupCode('@a class C = D with E; class D {} class E {}');
     checkMetadata('C');
   }
 
-  test_metadata_constructorDeclaration_named() async {
+  test_constructorDeclaration_named() async {
     await setupCode('class C { @a C.x(); }');
     checkMetadata('x');
   }
 
-  test_metadata_constructorDeclaration_unnamed() async {
+  test_constructorDeclaration_unnamed() async {
     await setupCode('class C { @a C(); }');
     checkMetadata('C()');
   }
 
-  test_metadata_declaredIdentifier() async {
+  test_declaredIdentifier() async {
     await setupCode('f(x, y) { for (@a var x in y) {} }');
     checkMetadata('var', expectDifferent: true);
   }
 
-  test_metadata_enumDeclaration() async {
+  test_enumDeclaration() async {
     await setupCode('@a enum E { v }');
     checkMetadata('E');
   }
 
-  test_metadata_enumDeclaration_constant() async {
+  test_enumDeclaration_constant() async {
     await setupCode('enum E { @a v }');
     checkMetadata('v');
   }
 
-  test_metadata_exportDirective() async {
-    addNamedSource('/foo.dart', 'class C {}');
+  test_exportDirective() async {
+    newFile('/test/lib/foo.dart', content: 'class C {}');
     await setupCode('@a export "foo.dart";');
     checkMetadata('export');
   }
 
-  test_metadata_exportDirective_resynthesized() async {
-    CompilationUnit unit = await resolveSource(r'''
+  test_exportDirective_resynthesized() async {
+    addTestFile(r'''
 @a
 export "dart:async";
 
@@ -116,15 +113,20 @@
 const a = null;
 const b = null;
 ''');
+    await resolveTestFile();
+    unit = result.unit;
+
     expect(unit.directives[0].metadata.single.name.name, 'a');
     expect(unit.directives[1].metadata.single.name.name, 'b');
     var unitElement = unit.declaredElement as CompilationUnitElementImpl;
+
     // Damage the unit element - as if "setAnnotations" were not called.
     // The ExportElement(s) still have the metadata, we should use it.
     unitElement.setAnnotations(unit.directives[0].offset, []);
     unitElement.setAnnotations(unit.directives[1].offset, []);
     expect(unitElement.library.exports[0].metadata, hasLength(1));
     expect(unitElement.library.exports[1].metadata, hasLength(1));
+
     // DeclarationResolver on the clone should succeed.
     CompilationUnit clonedUnit = AstCloner.clone(unit);
     new DeclarationResolver().resolve(clonedUnit, unit.declaredElement);
@@ -132,70 +134,59 @@
     expect(unit.directives[1].metadata.single.name.name, 'b');
   }
 
-  test_metadata_fieldDeclaration() async {
+  test_fieldDeclaration() async {
     await setupCode('class C { @a int x; }');
     checkMetadata('x');
   }
 
-  test_metadata_fieldFormalParameter() async {
+  test_fieldFormalParameter() async {
     await setupCode('class C { var x; C(@a this.x); }');
     checkMetadata('this');
   }
 
-  test_metadata_fieldFormalParameter_withDefault() async {
+  test_fieldFormalParameter_withDefault() async {
     await setupCode('class C { var x; C([@a this.x = null]); }');
     checkMetadata('this');
   }
 
-  test_metadata_functionDeclaration_function() async {
+  test_functionDeclaration_function() async {
     await setupCode('@a f() {}');
     checkMetadata('f');
   }
 
-  test_metadata_functionDeclaration_getter() async {
+  test_functionDeclaration_getter() async {
     await setupCode('@a get f() => null;');
     checkMetadata('f');
   }
 
-  test_metadata_functionDeclaration_setter() async {
+  test_functionDeclaration_setter() async {
     await setupCode('@a set f(value) {}');
     checkMetadata('f');
   }
 
-  test_metadata_functionTypeAlias() async {
+  test_functionTypeAlias() async {
     await setupCode('@a typedef F();');
     checkMetadata('F');
   }
 
-  test_metadata_functionTypedFormalParameter() async {
+  test_functionTypedFormalParameter() async {
     await setupCode('f(@a g()) {}');
     checkMetadata('g');
   }
 
-  test_metadata_functionTypedFormalParameter_withDefault() async {
+  test_functionTypedFormalParameter_withDefault() async {
     await setupCode('f([@a g() = null]) {}');
     checkMetadata('g');
   }
 
-  test_metadata_importDirective() async {
-    addNamedSource('/foo.dart', 'class C {}');
+  test_importDirective() async {
+    newFile('/test/lib/foo.dart', content: 'class C {}');
     await setupCode('@a import "foo.dart";');
     checkMetadata('import');
   }
 
-  test_metadata_importDirective_partiallyResolved() async {
-    addNamedSource('/foo.dart', 'class C {}');
-    this.code = 'const a = null; @a import "foo.dart";';
-    Source source = addNamedSource('/test.dart', code);
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    analysisContext.computeResult(source, LIBRARY_ELEMENT1);
-    unit = analysisContext.computeResult(target, RESOLVED_UNIT1);
-    unit2 = _cloneResolveUnit(unit);
-    checkMetadata('import');
-  }
-
-  test_metadata_importDirective_resynthesized() async {
-    CompilationUnit unit = await resolveSource(r'''
+  test_importDirective_resynthesized() async {
+    addTestFile(r'''
 @a
 import "dart:async";
 
@@ -205,15 +196,20 @@
 const a = null;
 const b = null;
 ''');
+    await resolveTestFile();
+    unit = result.unit;
+
     expect(unit.directives[0].metadata.single.name.name, 'a');
     expect(unit.directives[1].metadata.single.name.name, 'b');
     var unitElement = unit.declaredElement as CompilationUnitElementImpl;
+
     // Damage the unit element - as if "setAnnotations" were not called.
     // The ImportElement(s) still have the metadata, we should use it.
     unitElement.setAnnotations(unit.directives[0].offset, []);
     unitElement.setAnnotations(unit.directives[1].offset, []);
     expect(unitElement.library.imports[0].metadata, hasLength(1));
     expect(unitElement.library.imports[1].metadata, hasLength(1));
+
     // DeclarationResolver on the clone should succeed.
     CompilationUnit clonedUnit = AstCloner.clone(unit);
     new DeclarationResolver().resolve(clonedUnit, unit.declaredElement);
@@ -221,70 +217,75 @@
     expect(unit.directives[1].metadata.single.name.name, 'b');
   }
 
-  test_metadata_libraryDirective() async {
+  test_libraryDirective() async {
     await setupCode('@a library L;');
     checkMetadata('L');
   }
 
-  test_metadata_libraryDirective_resynthesized() async {
-    CompilationUnit unit = await resolveSource('@a library L; const a = null;');
+  test_libraryDirective_resynthesized() async {
+    addTestFile('@a library L; const a = null;');
+    await resolveTestFile();
+    unit = result.unit;
+
     expect(unit.directives.single.metadata.single.name.name, 'a');
     var unitElement = unit.declaredElement as CompilationUnitElementImpl;
+
     // Damage the unit element - as if "setAnnotations" were not called.
     // The LibraryElement still has the metadata, we should use it.
     unitElement.setAnnotations(unit.directives.single.offset, []);
     expect(unitElement.library.metadata, hasLength(1));
+
     // DeclarationResolver on the clone should succeed.
     CompilationUnit clonedUnit = AstCloner.clone(unit);
     new DeclarationResolver().resolve(clonedUnit, unit.declaredElement);
     expect(clonedUnit.directives.single.metadata.single.name.name, 'a');
   }
 
-  test_metadata_localFunctionDeclaration() async {
+  test_localFunctionDeclaration() async {
     await setupCode('f() { @a g() {} }');
     // Note: metadata on local function declarations is ignored by the
     // analyzer.  TODO(paulberry): is this a bug?
     FunctionDeclaration node = EngineTestCase.findNode(
         unit, code, 'g', (AstNode n) => n is FunctionDeclaration);
     NodeList<Annotation> metadata = (node as FunctionDeclarationImpl).metadata;
-    if (usingFastaParser) {
+    if (Parser.useFasta) {
       expect(metadata, hasLength(1));
     } else {
       expect(metadata, isEmpty);
     }
   }
 
-  test_metadata_localVariableDeclaration() async {
+  test_localVariableDeclaration() async {
     await setupCode('f() { @a int x; }');
     checkMetadata('x', expectDifferent: true);
   }
 
-  test_metadata_methodDeclaration_getter() async {
+  test_methodDeclaration_getter() async {
     await setupCode('class C { @a get m => null; }');
     checkMetadata('m');
   }
 
-  test_metadata_methodDeclaration_method() async {
+  test_methodDeclaration_method() async {
     await setupCode('class C { @a m() {} }');
     checkMetadata('m');
   }
 
-  test_metadata_methodDeclaration_setter() async {
+  test_methodDeclaration_setter() async {
     await setupCode('class C { @a set m(value) {} }');
     checkMetadata('m');
   }
 
-  test_metadata_partDirective() async {
-    addNamedSource('/foo.dart', 'part of L;');
+  test_partDirective() async {
+    newFile('/test/lib/foo.dart', content: 'part of L;');
     await setupCode('library L; @a part "foo.dart";');
     checkMetadata('part');
   }
 
-  test_metadata_partDirective_resynthesized() async {
-    addNamedSource('/part_a.dart', 'part of L;');
-    addNamedSource('/part_b.dart', 'part of L;');
+  test_partDirective_resynthesized() async {
+    newFile('/test/lib/part_a.dart', content: 'part of L;');
+    newFile('/test/lib/part_b.dart', content: 'part of L;');
 
-    CompilationUnit unit = await resolveSource(r'''
+    addTestFile(r'''
 library L;
 
 @a
@@ -296,15 +297,20 @@
 const a = null;
 const b = null;
 ''');
+    await resolveTestFile();
+    unit = result.unit;
+
     expect(unit.directives[1].metadata.single.name.name, 'a');
     expect(unit.directives[2].metadata.single.name.name, 'b');
     var unitElement = unit.declaredElement as CompilationUnitElementImpl;
+
     // Damage the unit element - as if "setAnnotations" were not called.
     // The ImportElement(s) still have the metadata, we should use it.
     unitElement.setAnnotations(unit.directives[1].offset, []);
     unitElement.setAnnotations(unit.directives[2].offset, []);
     expect(unitElement.library.parts[0].metadata, hasLength(1));
     expect(unitElement.library.parts[1].metadata, hasLength(1));
+
     // DeclarationResolver on the clone should succeed.
     CompilationUnit clonedUnit = AstCloner.clone(unit);
     new DeclarationResolver().resolve(clonedUnit, unit.declaredElement);
@@ -312,37 +318,37 @@
     expect(unit.directives[2].metadata.single.name.name, 'b');
   }
 
-  test_metadata_simpleFormalParameter() async {
+  test_simpleFormalParameter() async {
     await setupCode('f(@a x) {}) {}');
     checkMetadata('x');
   }
 
-  test_metadata_simpleFormalParameter_withDefault() async {
+  test_simpleFormalParameter_withDefault() async {
     await setupCode('f([@a x = null]) {}');
     checkMetadata('x');
   }
 
-  test_metadata_topLevelVariableDeclaration() async {
+  test_topLevelVariableDeclaration() async {
     await setupCode('@a int x;');
     checkMetadata('x');
   }
 
-  test_metadata_typeParameter_ofClass() async {
+  test_typeParameter_ofClass() async {
     await setupCode('class C<@a T> {}');
     checkMetadata('T');
   }
 
-  test_metadata_typeParameter_ofClassTypeAlias() async {
+  test_typeParameter_ofClassTypeAlias() async {
     await setupCode('class C<@a T> = D with E; class D {} class E {}');
     checkMetadata('T');
   }
 
-  test_metadata_typeParameter_ofFunction() async {
+  test_typeParameter_ofFunction() async {
     await setupCode('f<@a T>() {}');
     checkMetadata('T');
   }
 
-  test_metadata_typeParameter_ofTypedef() async {
+  test_typeParameter_ofTypedef() async {
     await setupCode('typedef F<@a T>();');
     checkMetadata('T');
   }
@@ -364,29 +370,24 @@
 }
 
 @reflectiveTest
-class DeclarationResolverTest extends ResolverTestCase {
-  @override
-  void setUp() {
-    super.setUp();
-  }
-
+class DeclarationResolverTest extends DriverResolutionTest {
   test_closure_inside_catch_block() async {
-    String code = '''
+    addTestFile('''
 f() {
   try {
   } catch (e) {
     return () => null;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_closure_inside_labeled_statement() async {
-    String code = '''
+    addTestFile('''
 f(b) {
   foo: while (true) {
     if (b) {
@@ -395,15 +396,15 @@
     return () => null;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_closure_inside_switch_case() async {
-    String code = '''
+    addTestFile('''
 void f(k, m) {
   switch (k) {
     case 0:
@@ -411,15 +412,15 @@
     break;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_closure_inside_switch_default() async {
-    String code = '''
+    addTestFile('''
 void f(k, m) {
   switch (k) {
     default:
@@ -427,142 +428,132 @@
     break;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
-  test_enumConstant_partiallyResolved() async {
-    String code = r'''
-enum Fruit {apple, pear}
-''';
-    Source source = addNamedSource('/test.dart', code);
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    analysisContext.computeResult(source, LIBRARY_ELEMENT1);
-    CompilationUnit unit =
-        analysisContext.computeResult(target, RESOLVED_UNIT1);
-    _cloneResolveUnit(unit);
-  }
-
   test_functionDeclaration_getter() async {
-    String code = r'''
+    addTestFile(r'''
 int get zzz => 42;
-''';
-    CompilationUnit unit = await resolveSource(code);
-    PropertyAccessorElement getterElement =
-        _findSimpleIdentifier(unit, code, 'zzz =>').staticElement;
+''');
+    await resolveTestFile();
+
+    var getterElement = findElement.topGet('zzz');
     expect(getterElement.isGetter, isTrue);
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var getterName = FindNode(result.content, unit2).simple('zzz =>');
     expect(getterName.staticElement, same(getterElement));
   }
 
   test_functionDeclaration_setter() async {
-    String code = r'''
+    addTestFile(r'''
 void set zzz(_) {}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    PropertyAccessorElement setterElement =
-        _findSimpleIdentifier(unit, code, 'zzz(_)').staticElement;
+''');
+    await resolveTestFile();
+
+    var setterElement = findElement.topSet('zzz');
     expect(setterElement.isSetter, isTrue);
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz(_)');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var getterName = FindNode(result.content, unit2).simple('zzz(_)');
     expect(getterName.staticElement, same(setterElement));
   }
 
   test_genericFunction_asFunctionReturnType() async {
-    String code = r'''
+    addTestFile(r'''
 Function(int, String) f() => null;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asGenericFunctionReturnType() async {
-    String code = r'''
+    addTestFile(r'''
 typedef F<T> = int Function(T t, S s) Function<S>(int);
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asMethodReturnType() async {
-    String code = r'''
+    addTestFile(r'''
 class C {
   Function(int, String) m() => null;
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asParameterReturnType() async {
-    String code = r'''
+    addTestFile(r'''
 f(Function(int, String) p) => null;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asTopLevelVariableType() async {
-    String code = r'''
+    addTestFile(r'''
 int Function(int, String) v;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asTypeArgument() async {
-    String code = r'''
+    addTestFile(r'''
 List<Function(int)> v;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asTypeArgument_lessNodes() async {
-    String code = r'''
+    addTestFile(r'''
 Map<Function<int>> v;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asTypeArgument_moreNodes() async {
-    String code = r'''
+    addTestFile(r'''
 List<Function<int>, Function<String>> v;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_genericFunction_asTypeArgument_noNodes() async {
-    String code = r'''
+    addTestFile(r'''
 List v;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
@@ -570,300 +561,253 @@
     String code = r'''
 var v = <Function(int)>[];
 ''';
-    CompilationUnit unit = await resolveSource(code);
-    CompilationUnit newUnit = _cloneResolveUnit(unit);
-    var v = newUnit.declarations[0] as TopLevelVariableDeclaration;
-    var initializer = v.variables.variables[0].initializer as ListLiteral;
+    addTestFile(code);
+    await resolveTestFile();
+
+    var newUnit = _cloneResolveUnit(result.unit);
+    var initializer = FindNode(result.content, newUnit).listLiteral('>[]');
     expect(initializer.typeArguments.arguments[0].type, isNotNull);
   }
 
   test_genericFunction_invalid_missingParameterName() async {
-    String code = r'''
+    addTestFile(r'''
 typedef F = Function({int});
-''';
-    CompilationUnit unit = await resolveSource(code);
-    _cloneResolveUnit(unit);
+''');
+    await resolveTestFile();
+    // re-resolve
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_invalid_functionDeclaration_getter_inFunction() async {
-    String code = r'''
+    addTestFile(r'''
 var v = (() {
   main() {
     int get zzz => 42;
   }
 });
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'zzz =>');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var getterName = FindNode(result.content, unit2).simple('zzz =>');
+
     // Local getters are not allowed, so a FunctionElement is created.
-    expect(getterName.staticElement, new TypeMatcher<FunctionElement>());
+    expect(getterName.staticElement, isFunctionElement);
   }
 
   test_invalid_functionDeclaration_setter_inFunction() async {
-    String code = r'''
+    addTestFile(r'''
 var v = (() {
   main() {
     set zzz(x) {}
   }
 });
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var setterName = FindNode(result.content, unit2).simple('zzz(x)');
+
     // Local getters are not allowed, so a FunctionElement is created.
-    expect(setterName.staticElement, new TypeMatcher<FunctionElement>());
+    expect(setterName.staticElement, isFunctionElement);
   }
 
   test_visitExportDirective_notExistingSource() async {
-    String code = r'''
+    addTestFile(r'''
 export 'foo.dart';
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitExportDirective_unresolvedUri() async {
-    String code = r'''
+    addTestFile(r'''
 export 'package:foo/bar.dart';
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitFunctionExpression() async {
-    String code = r'''
+    addTestFile(r'''
 main(List<String> items) {
   items.forEach((item) {});
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitGenericTypeAlias_0() async {
-    String code = r'''
+    addTestFile(r'''
 typedef F<T> = Function<S>(List<S> list, Function<A>(A), T);
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitGenericTypeAlias_1() async {
-    String code = r'''
+    addTestFile(r'''
 typedef F = Function({int});
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitGenericTypeAlias_2() async {
-    String code = r'''
+    addTestFile(r'''
 typedef F = int;
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitImportDirective_notExistingSource() async {
-    String code = r'''
+    addTestFile(r'''
 import 'foo.dart';
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitImportDirective_unresolvedUri() async {
-    String code = r'''
+    addTestFile(r'''
 import 'package:foo/bar.dart';
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitMethodDeclaration_getter_duplicate() async {
-    String code = r'''
+    addTestFile(r'''
 class C {
   int get zzz => 1;
   String get zzz => null;
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
-    PropertyAccessorElement firstElement =
-        _findSimpleIdentifier(unit, code, 'zzz => 1').staticElement;
-    PropertyAccessorElement secondElement =
-        _findSimpleIdentifier(unit, code, 'zzz => null').staticElement;
+''');
+    await resolveTestFile();
+
+    var firstElement = findNode.simple('zzz => 1').staticElement;
+    var secondElement = findNode.simple('zzz => null').staticElement;
+    expect(firstElement, isNot(same(secondElement)));
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz => 1');
-    SimpleIdentifier secondName =
-        _findSimpleIdentifier(unit2, code, 'zzz => null');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var findNode2 = FindNode(result.content, unit2);
+    var firstName = findNode2.simple('zzz => 1');
+    var secondName = findNode2.simple('zzz => null');
     expect(firstName.staticElement, same(firstElement));
     expect(secondName.staticElement, same(secondElement));
   }
 
   test_visitMethodDeclaration_getterSetter() async {
-    String code = r'''
+    addTestFile(r'''
 class C {
   int _field = 0;
   int get field => _field;
   void set field(value) {_field = value;}
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
-    FieldElement getterElement =
-        _findSimpleIdentifier(unit, code, 'field =').staticElement;
-    PropertyAccessorElement setterElement =
-        _findSimpleIdentifier(unit, code, 'field(').staticElement;
+''');
+    await resolveTestFile();
+
+    var getterElement = findElement.getter('field');
+    var setterElement = findElement.setter('field');
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier getterName = _findSimpleIdentifier(unit2, code, 'field =');
-    SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'field(');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var findNode2 = FindNode(result.content, unit2);
+    var getterName = findNode2.simple('field =>');
+    var setterName = findNode2.simple('field(value)');
     expect(getterName.staticElement, same(getterElement));
     expect(setterName.staticElement, same(setterElement));
   }
 
   test_visitMethodDeclaration_method_duplicate() async {
-    String code = r'''
+    addTestFile(r'''
 class C {
   void zzz(x) {}
   void zzz(y) {}
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
-    MethodElement firstElement =
-        _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement;
-    MethodElement secondElement =
-        _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement;
+''');
+    await resolveTestFile();
+
+    MethodElement firstElement = findNode.simple('zzz(x)').staticElement;
+    MethodElement secondElement = findNode.simple('zzz(y)').staticElement;
+    expect(firstElement, isNot(same(secondElement)));
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
-    SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var findNode2 = FindNode(result.content, unit2);
+    var firstName = findNode2.simple('zzz(x)');
+    var secondName = findNode2.simple('zzz(y)');
     expect(firstName.staticElement, same(firstElement));
     expect(secondName.staticElement, same(secondElement));
   }
 
   test_visitMethodDeclaration_setter_duplicate() async {
     // https://github.com/dart-lang/sdk/issues/25601
-    String code = r'''
+    addTestFile(r'''
 class C {
   set zzz(x) {}
   set zzz(y) {}
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
+
     PropertyAccessorElement firstElement =
-        _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement;
+        findNode.simple('zzz(x)').staticElement;
     PropertyAccessorElement secondElement =
-        _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement;
+        findNode.simple('zzz(y)').staticElement;
+    expect(firstElement, isNot(same(secondElement)));
+
     // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
-    SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)');
+    var unit2 = _cloneResolveUnit(result.unit);
+    var findNode2 = FindNode(result.content, unit2);
+    var firstName = findNode2.simple('zzz(x)');
+    var secondName = findNode2.simple('zzz(y)');
     expect(firstName.staticElement, same(firstElement));
     expect(secondName.staticElement, same(secondElement));
   }
 
   test_visitMethodDeclaration_unaryMinus() async {
-    String code = r'''
+    addTestFile(r'''
 class C {
   C operator -() => null;
   C operator -(C other) => null;
 }
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 
   test_visitPartDirective_notExistingSource() async {
-    String code = r'''
+    addTestFile(r'''
 part 'foo.bar';
-''';
-    CompilationUnit unit = await resolveSource(code);
+''');
+    await resolveTestFile();
     // re-resolve
-    _cloneResolveUnit(unit);
+    _cloneResolveUnit(result.unit);
     // no other validations than built into DeclarationResolver
   }
 }
-
-/**
- * Strong mode DeclarationResolver tests
- */
-@reflectiveTest
-class StrongModeDeclarationResolverTest extends ResolverTestCase {
-  @override
-  void setUp() {
-    reset();
-  }
-
-  test_genericFunction_typeParameter() async {
-    // Fasta ignores generic type comments
-    if (usingFastaParser) return;
-    String code = r'''
-/*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null;
-''';
-    CompilationUnit unit = await resolveSource(code);
-    FunctionDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent;
-    TypeParameter t = node.functionExpression.typeParameters.typeParameters[0];
-
-    FunctionElement element = node.name.staticElement;
-    TypeParameterElement tElement = element.typeParameters[0];
-    expect(tElement, isNotNull);
-    expect(element.typeParameters.toString(), "[T]");
-    expect(element.type.toString(), "<T>(T, T) → T");
-    expect(t.declaredElement, same(tElement));
-
-    // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    node = _findSimpleIdentifier(unit2, code, 'max').parent;
-    t = node.functionExpression.typeParameters.typeParameters[0];
-    expect(t.declaredElement, same(tElement));
-  }
-
-  test_genericMethod_typeParameter() async {
-    // Fasta ignores generic type comments
-    if (usingFastaParser) return;
-    String code = r'''
-class C {
-  /*=T*/ max/*<T>*/(/*=T*/ x, /*=T*/ y) => null;
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    MethodDeclaration node = _findSimpleIdentifier(unit, code, 'max').parent;
-    TypeParameter t = node.typeParameters.typeParameters[0];
-
-    MethodElement element = node.name.staticElement;
-    TypeParameterElement tElement = element.typeParameters[0];
-    expect(tElement, isNotNull);
-    expect(element.typeParameters.toString(), "[T]");
-    expect(element.type.toString(), "<T>(T, T) → T");
-    expect(t.declaredElement, same(tElement));
-
-    // re-resolve
-    CompilationUnit unit2 = _cloneResolveUnit(unit);
-    node = _findSimpleIdentifier(unit2, code, 'max').parent;
-    t = node.typeParameters.typeParameters[0];
-    expect(t.declaredElement, same(tElement));
-  }
-}
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 58c0a5c..4808365 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -23,6 +23,8 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../src/dart/resolution/driver_resolution.dart';
+import '../util/element_type_matchers.dart';
 import '../utils.dart';
 import 'analysis_context_factory.dart';
 import 'resolver_test_case.dart';
@@ -30,16 +32,12 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ElementResolverCodeTest);
+    defineReflectiveTests(AnnotationElementResolverTest);
     defineReflectiveTests(ElementResolverTest);
     defineReflectiveTests(PreviewDart2Test);
   });
 }
 
-const _isClassElement = const TypeMatcher<ClassElement>();
-
-const _isConstructorElement = const TypeMatcher<ConstructorElement>();
-
 /// Wrapper around the test package's `fail` function.
 ///
 /// Unlike the test package's `fail` function, this function is not annotated
@@ -50,9 +48,9 @@
 }
 
 @reflectiveTest
-class ElementResolverCodeTest extends ResolverTestCase {
-  test_annotation_class_namedConstructor() async {
-    addNamedSource('/a.dart', r'''
+class AnnotationElementResolverTest extends DriverResolutionTest {
+  test_class_namedConstructor() async {
+    newFile('/test/lib/a.dart', content: r'''
 class A {
   const A.named();
 }
@@ -62,10 +60,10 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<ClassElement>());
+      expect(name1.staticElement, isClassElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'A');
       expect(name2, isNotNull);
-      expect(name2.staticElement, new TypeMatcher<ConstructorElement>());
+      expect(name2.staticElement, isConstructorElement);
       expect(
           resolutionMap.staticElementForIdentifier(name2).displayName, 'named');
       expect(name3, isNull);
@@ -81,8 +79,8 @@
     });
   }
 
-  test_annotation_class_prefixed_namedConstructor() async {
-    addNamedSource('/a.dart', r'''
+  test_class_prefixed_namedConstructor() async {
+    newFile('/test/lib/a.dart', content: r'''
 class A {
   const A.named();
 }
@@ -92,13 +90,13 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<PrefixElement>());
+      expect(name1.staticElement, isPrefixElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
       expect(name2, isNotNull);
-      expect(name2.staticElement, new TypeMatcher<ClassElement>());
+      expect(name2.staticElement, isClassElement);
       expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'A');
       expect(name3, isNotNull);
-      expect(name3.staticElement, new TypeMatcher<ConstructorElement>());
+      expect(name3.staticElement, isConstructorElement);
       expect(
           resolutionMap.staticElementForIdentifier(name3).displayName, 'named');
       if (annotationElement is ConstructorElement) {
@@ -113,8 +111,8 @@
     });
   }
 
-  test_annotation_class_prefixed_staticConstField() async {
-    addNamedSource('/a.dart', r'''
+  test_class_prefixed_staticConstField() async {
+    newFile('/test/lib/a.dart', content: r'''
 class A {
   static const V = 0;
 }
@@ -124,13 +122,13 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<PrefixElement>());
+      expect(name1.staticElement, isPrefixElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
       expect(name2, isNotNull);
-      expect(name2.staticElement, new TypeMatcher<ClassElement>());
+      expect(name2.staticElement, isClassElement);
       expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'A');
       expect(name3, isNotNull);
-      expect(name3.staticElement, new TypeMatcher<PropertyAccessorElement>());
+      expect(name3.staticElement, isPropertyAccessorElement);
       expect(resolutionMap.staticElementForIdentifier(name3).displayName, 'V');
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name3.staticElement));
@@ -143,8 +141,8 @@
     });
   }
 
-  test_annotation_class_prefixed_unnamedConstructor() async {
-    addNamedSource('/a.dart', r'''
+  test_class_prefixed_unnamedConstructor() async {
+    newFile('/test/lib/a.dart', content: r'''
 class A {
   const A();
 }
@@ -154,10 +152,10 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<PrefixElement>());
+      expect(name1.staticElement, isPrefixElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
       expect(name2, isNotNull);
-      expect(name2.staticElement, new TypeMatcher<ClassElement>());
+      expect(name2.staticElement, isClassElement);
       expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'A');
       expect(name3, isNull);
       if (annotationElement is ConstructorElement) {
@@ -171,8 +169,8 @@
     });
   }
 
-  test_annotation_class_staticConstField() async {
-    addNamedSource('/a.dart', r'''
+  test_class_staticConstField() async {
+    newFile('/test/lib/a.dart', content: r'''
 class A {
   static const V = 0;
 }
@@ -182,10 +180,10 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<ClassElement>());
+      expect(name1.staticElement, isClassElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'A');
       expect(name2, isNotNull);
-      expect(name2.staticElement, new TypeMatcher<PropertyAccessorElement>());
+      expect(name2.staticElement, isPropertyAccessorElement);
       expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'V');
       expect(name3, isNull);
       if (annotationElement is PropertyAccessorElement) {
@@ -199,8 +197,8 @@
     });
   }
 
-  test_annotation_class_unnamedConstructor() async {
-    addNamedSource('/a.dart', r'''
+  test_class_unnamedConstructor() async {
+    newFile('/test/lib/a.dart', content: r'''
 class A {
   const A();
 }
@@ -210,7 +208,7 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<ClassElement>());
+      expect(name1.staticElement, isClassElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'A');
       expect(name2, isNull);
       expect(name3, isNull);
@@ -225,8 +223,8 @@
     });
   }
 
-  test_annotation_topLevelVariable() async {
-    addNamedSource('/a.dart', r'''
+  test_topLevelVariable() async {
+    newFile('/test/lib/a.dart', content: r'''
 const V = 0;
 ''');
     await _validateAnnotation('', '@V', (SimpleIdentifier name1,
@@ -234,14 +232,13 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<PropertyAccessorElement>());
+      expect(name1.staticElement, isPropertyAccessorElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'V');
       expect(name2, isNull);
       expect(name3, isNull);
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name1.staticElement));
-        expect(annotationElement.enclosingElement,
-            new TypeMatcher<CompilationUnitElement>());
+        expect(annotationElement.enclosingElement, isCompilationUnitElement);
         expect(annotationElement.displayName, 'V');
       } else {
         fail('Expected "annotationElement" is PropertyAccessorElement, '
@@ -250,8 +247,8 @@
     });
   }
 
-  test_annotation_topLevelVariable_prefixed() async {
-    addNamedSource('/a.dart', r'''
+  test_topLevelVariable_prefixed() async {
+    newFile('/test/lib/a.dart', content: r'''
 const V = 0;
 ''');
     await _validateAnnotation('as p', '@p.V', (SimpleIdentifier name1,
@@ -259,16 +256,15 @@
         SimpleIdentifier name3,
         Element annotationElement) {
       expect(name1, isNotNull);
-      expect(name1.staticElement, new TypeMatcher<PrefixElement>());
+      expect(name1.staticElement, isPrefixElement);
       expect(resolutionMap.staticElementForIdentifier(name1).displayName, 'p');
       expect(name2, isNotNull);
-      expect(name2.staticElement, new TypeMatcher<PropertyAccessorElement>());
+      expect(name2.staticElement, isPropertyAccessorElement);
       expect(resolutionMap.staticElementForIdentifier(name2).displayName, 'V');
       expect(name3, isNull);
       if (annotationElement is PropertyAccessorElement) {
         expect(annotationElement, same(name2.staticElement));
-        expect(annotationElement.enclosingElement,
-            new TypeMatcher<CompilationUnitElement>());
+        expect(annotationElement.enclosingElement, isCompilationUnitElement);
         expect(annotationElement.displayName, 'V');
       } else {
         fail('Expected "annotationElement" is PropertyAccessorElement, '
@@ -282,12 +278,14 @@
       String annotationText,
       validator(SimpleIdentifier name1, SimpleIdentifier name2,
           SimpleIdentifier name3, Element annotationElement)) async {
-    CompilationUnit unit = await resolveSource('''
+    addTestFile('''
 import 'a.dart' $annotationPrefix;
 $annotationText
 class C {}
 ''');
-    var clazz = unit.declarations.single as ClassDeclaration;
+    await resolveTestFile();
+
+    var clazz = findNode.classDeclaration('C');
     Annotation annotation = clazz.metadata.single;
     Identifier name = annotation.name;
     Element annotationElement = annotation.element;
@@ -1287,13 +1285,13 @@
     ExpressionStatement statement = statements[0];
     InstanceCreationExpression creation = statement.expression;
 
-    expect(creation.staticElement, _isConstructorElement);
+    expect(creation.staticElement, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
-    expect(creation.constructorName.staticElement, _isConstructorElement);
+    expect(creation.constructorName.staticElement, isConstructorElement);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name, isNull);
   }
@@ -1321,13 +1319,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name, isNull);
 
@@ -1359,13 +1357,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name, isNull);
 
@@ -1395,13 +1393,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name.staticElement, constructor);
   }
@@ -1433,13 +1431,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name, isNull);
   }
@@ -1470,13 +1468,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name.staticElement, constructor);
 
@@ -1515,13 +1513,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name, isNull);
   }
@@ -1550,13 +1548,13 @@
     InstanceCreationExpression creation = statement.expression;
     ConstructorElement constructor = creation.staticElement;
 
-    expect(constructor, _isConstructorElement);
+    expect(constructor, isConstructorElement);
     expect(creation.staticType, isNotNull);
 
     expect(creation.constructorName.staticElement, constructor);
 
     expect(creation.constructorName.type.type, isNotNull);
-    expect(creation.constructorName.type.name.staticElement, _isClassElement);
+    expect(creation.constructorName.type.name.staticElement, isClassElement);
 
     expect(creation.constructorName.name, isNull);
   }
@@ -1575,7 +1573,7 @@
     MethodInvocation invocation = statement.expression;
 
     SimpleIdentifier prefix = invocation.target;
-    expect(prefix.staticElement, new TypeMatcher<PrefixElement>());
+    expect(prefix.staticElement, isPrefixElement);
 
     expect(invocation.methodName.name, 'max');
   }
diff --git a/pkg/analyzer/test/generated/error_suppression.dart b/pkg/analyzer/test/generated/error_suppression.dart
new file mode 100644
index 0000000..80027a4
--- /dev/null
+++ b/pkg/analyzer/test/generated/error_suppression.dart
@@ -0,0 +1,229 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+
+import 'resolver_test_case.dart';
+
+abstract class ErrorSuppressionTest extends ResolverTestCase {
+  String get ignoredCode => 'const_initialized_with_non_constant_value';
+
+  List<ErrorCode> get reportedCodes => [
+        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
+      ];
+
+  List<ErrorCode> get reportedCodesWithAssignment => [
+        StaticTypeWarningCode.INVALID_ASSIGNMENT,
+        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
+      ];
+
+  test_error_code_mismatch() async {
+    Source source = addSource('''
+// ignore: $ignoredCode
+int x = '';
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodesWithAssignment);
+  }
+
+  test_ignore_first() async {
+    Source source = addSource('''
+// ignore: invalid_assignment
+int x = '';
+// ... but no ignore here ...
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodes);
+  }
+
+  test_ignore_first_trailing() async {
+    Source source = addSource('''
+int x = ''; // ignore: invalid_assignment
+// ... but no ignore here ...
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodes);
+  }
+
+  test_ignore_for_file() async {
+    Source source = addSource('''
+int x = '';  //INVALID_ASSIGNMENT
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// ignore_for_file: invalid_assignment
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodes);
+  }
+
+  test_ignore_for_file_whitespace_variant() async {
+    Source source = addSource('''
+//ignore_for_file:   $ignoredCode , invalid_assignment
+int x = '';  //INVALID_ASSIGNMENT
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_ignore_only_trailing() async {
+    Source source = addSource('''
+int x = ''; // ignore: invalid_assignment
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_ignore_second() async {
+    Source source = addSource('''
+//INVALID_ASSIGNMENT
+int x = '';
+// ignore: $ignoredCode
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_ignore_second_trailing() async {
+    Source source = addSource('''
+//INVALID_ASSIGNMENT
+int x = '';
+const y = x; // ignore: $ignoredCode
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_ignore_upper_case() async {
+    Source source = addSource('''
+int x = ''; // ignore: INVALID_ASSIGNMENT
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_invalid_error_code() async {
+    Source source = addSource('''
+// ignore: right_format_wrong_code
+int x = '';
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodesWithAssignment);
+  }
+
+  test_missing_error_codes() async {
+    Source source = addSource('''
+    int x = 3;
+// ignore:
+const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodesWithAssignment);
+  }
+
+  test_missing_metadata_suffix() async {
+    Source source = addSource('''
+// ignore invalid_assignment
+String y = 3; //INVALID_ASSIGNMENT
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_multiple_comments() async {
+    Source source = addSource('''
+int x = ''; //This is the first comment...
+// ignore: $ignoredCode
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_multiple_ignore_for_files() async {
+    Source source = addSource('''
+int x = '';  //INVALID_ASSIGNMENT
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+// ignore_for_file: invalid_assignment,$ignoredCode
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_multiple_ignores() async {
+    Source source = addSource('''
+int x = 3;
+// ignore: invalid_assignment, $ignoredCode
+const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_multiple_ignores_trailing() async {
+    Source source = addSource('''
+int x = 3;
+const String y = x; // ignore: invalid_assignment, $ignoredCode
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_multiple_ignores_whitespace_variant_1() async {
+    Source source = addSource('''
+int x = 3;
+//ignore:invalid_assignment,$ignoredCode
+const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_multiple_ignores_whitespace_variant_2() async {
+    Source source = addSource('''
+int x = 3;
+//ignore: invalid_assignment,$ignoredCode
+const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_multiple_ignores_whitespace_variant_3() async {
+    Source source = addSource('''
+int x = 3;
+// ignore: invalid_assignment,$ignoredCode
+const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, []);
+  }
+
+  test_no_ignores() async {
+    Source source = addSource('''
+int x = '';  //INVALID_ASSIGNMENT
+const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, reportedCodesWithAssignment);
+  }
+
+  test_trailing_not_above() async {
+    Source source = addSource('''
+int x = ''; // ignore: invalid_assignment
+int y = '';
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      StaticTypeWarningCode.INVALID_ASSIGNMENT,
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/generated/error_suppression_driver_test.dart b/pkg/analyzer/test/generated/error_suppression_driver_test.dart
index 9bc552e..77e0f57 100644
--- a/pkg/analyzer/test/generated/error_suppression_driver_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_driver_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'error_suppression_test.dart';
+import 'error_suppression.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
deleted file mode 100644
index 0e5d6106..0000000
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ErrorSuppressionTest);
-  });
-}
-
-@reflectiveTest
-class ErrorSuppressionTest extends ResolverTestCase {
-  String get ignoredCode => 'const_initialized_with_non_constant_value';
-
-  List<ErrorCode> get reportedCodes => [
-        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      ];
-
-  List<ErrorCode> get reportedCodesWithAssignment => [
-        StaticTypeWarningCode.INVALID_ASSIGNMENT,
-        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      ];
-
-  test_error_code_mismatch() async {
-    Source source = addSource('''
-// ignore: $ignoredCode
-int x = '';
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
-  }
-
-  test_ignore_first() async {
-    Source source = addSource('''
-// ignore: invalid_assignment
-int x = '';
-// ... but no ignore here ...
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
-  }
-
-  test_ignore_first_trailing() async {
-    Source source = addSource('''
-int x = ''; // ignore: invalid_assignment
-// ... but no ignore here ...
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
-  }
-
-  test_ignore_for_file() async {
-    Source source = addSource('''
-int x = '';  //INVALID_ASSIGNMENT
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-// ignore_for_file: invalid_assignment
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
-  }
-
-  test_ignore_for_file_whitespace_variant() async {
-    Source source = addSource('''
-//ignore_for_file:   $ignoredCode , invalid_assignment
-int x = '';  //INVALID_ASSIGNMENT
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_ignore_only_trailing() async {
-    Source source = addSource('''
-int x = ''; // ignore: invalid_assignment
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_ignore_second() async {
-    Source source = addSource('''
-//INVALID_ASSIGNMENT
-int x = '';
-// ignore: $ignoredCode
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_ignore_second_trailing() async {
-    Source source = addSource('''
-//INVALID_ASSIGNMENT
-int x = '';
-const y = x; // ignore: $ignoredCode
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_ignore_upper_case() async {
-    Source source = addSource('''
-int x = ''; // ignore: INVALID_ASSIGNMENT
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_invalid_error_code() async {
-    Source source = addSource('''
-// ignore: right_format_wrong_code
-int x = '';
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
-  }
-
-  test_missing_error_codes() async {
-    Source source = addSource('''
-    int x = 3;
-// ignore:
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
-  }
-
-  test_missing_metadata_suffix() async {
-    Source source = addSource('''
-// ignore invalid_assignment
-String y = 3; //INVALID_ASSIGNMENT
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_multiple_comments() async {
-    Source source = addSource('''
-int x = ''; //This is the first comment...
-// ignore: $ignoredCode
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_multiple_ignore_for_files() async {
-    Source source = addSource('''
-int x = '';  //INVALID_ASSIGNMENT
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-// ignore_for_file: invalid_assignment,$ignoredCode
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_multiple_ignores() async {
-    Source source = addSource('''
-int x = 3;
-// ignore: invalid_assignment, $ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_multiple_ignores_trailing() async {
-    Source source = addSource('''
-int x = 3;
-const String y = x; // ignore: invalid_assignment, $ignoredCode
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_multiple_ignores_whitespace_variant_1() async {
-    Source source = addSource('''
-int x = 3;
-//ignore:invalid_assignment,$ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_multiple_ignores_whitespace_variant_2() async {
-    Source source = addSource('''
-int x = 3;
-//ignore: invalid_assignment,$ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_multiple_ignores_whitespace_variant_3() async {
-    Source source = addSource('''
-int x = 3;
-// ignore: invalid_assignment,$ignoredCode
-const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
-  }
-
-  test_no_ignores() async {
-    Source source = addSource('''
-int x = '';  //INVALID_ASSIGNMENT
-const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
-  }
-
-  test_trailing_not_above() async {
-    Source source = addSource('''
-int x = ''; // ignore: invalid_assignment
-int y = '';
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.INVALID_ASSIGNMENT,
-    ]);
-  }
-}
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index e33ea7d..6695ba9 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -2,14 +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:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/options.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/util/yaml_test.dart';
@@ -18,7 +16,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CrossPackageHintCodeTest);
-    defineReflectiveTests(HintCodeTest);
   });
 }
 
@@ -3121,1800 +3118,4 @@
     assertErrors(source, [StrongModeCode.DOWN_CAST_COMPOSITE]);
     verify([source]);
   }
-
-  test_strongMode_topLevelInstanceGetter() async {
-    Source source = addSource('''
-class A {
-  int get g => 0;
-}
-var b = new A().g;
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    TopLevelVariableDeclaration b = analysisResult.unit.declarations[1];
-    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_call() async {
-    Source source = addSource('''
-class A {
-  int Function() get g => () => 0;
-}
-var a = new A();
-var b = a.g();
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
-    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_field() async {
-    Source source = addSource('''
-class A {
-  int g;
-}
-var b = new A().g;
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    TopLevelVariableDeclaration b = analysisResult.unit.declarations[1];
-    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_field_call() async {
-    Source source = addSource('''
-class A {
-  int Function() g;
-}
-var a = new A();
-var b = a.g();
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
-    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_field_prefixedIdentifier() async {
-    Source source = addSource('''
-class A {
-  int g;
-}
-var a = new A();
-var b = a.g;
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
-    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped() async {
-    Source source = addSource('''
-class A {
-  get g => 0;
-}
-var b = new A().g;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_call() async {
-    Source source = addSource('''
-class A {
-  get g => () => 0;
-}
-var a = new A();
-var b = a.g();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_field() async {
-    Source source = addSource('''
-class A {
-  var g = 0;
-}
-var b = new A().g;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_field_call() async {
-    Source source = addSource('''
-class A {
-  var g = () => 0;
-}
-var a = new A();
-var b = a.g();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_field_prefixedIdentifier() async {
-    Source source = addSource('''
-class A {
-  var g = 0;
-}
-var a = new A();
-var b = a.g;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_fn() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-int f<T>(x) => 0;
-var a = new A();
-var b = f(a.x);
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
-    // generic, so the type of a.x might affect the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_fn_explicit_type_params() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-int f<T>(x) => 0;
-var a = new A();
-var b = f<int>(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_fn_not_generic() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-int f(x) => 0;
-var a = new A();
-var b = f(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_indexExpression() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-  int operator[](int value) => 0;
-}
-var a = new A();
-var b = a[a.x];
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-var a = new A();
-var b = (<T>(y) => 0)(a.x);
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the
-    // closure is generic, so the type of a.x might affect the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke_explicit_type_params() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-var a = new A();
-var b = (<T>(y) => 0)<int>(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke_not_generic() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-var a = new A();
-var b = ((y) => 0)(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_method() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-  int f<T>(int x) => 0;
-}
-var a = new A();
-var b = a.f(a.x);
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
-    // generic, so the type of a.x might affect the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_method_explicit_type_params() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-  int f<T>(x) => 0;
-}
-var a = new A();
-var b = a.f<int>(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_method_not_generic() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-  int f(x) => 0;
-}
-var a = new A();
-var b = a.f(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-class B<T> {
-  B(x);
-}
-var a = new A();
-var b = new B(a.x);
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
-    // generic, so the type of a.x might affect the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_explicit_type_params() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-class B<T> {
-  B(x);
-}
-var a = new A();
-var b = new B<int>(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_explicit_type_params_named() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-class B<T> {
-  B.named(x);
-}
-var a = new A();
-var b = new B<int>.named(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_explicit_type_params_prefixed() async {
-    addNamedSource('/lib1.dart', '''
-class B<T> {
-  B(x);
-}
-''');
-    Source source = addSource('''
-import 'lib1.dart' as foo;
-class A {
-  var x = 0;
-}
-var a = new A();
-var b = new foo.B<int>(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_named() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-class B<T> {
-  B.named(x);
-}
-var a = new A();
-var b = new B.named(a.x);
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
-    // generic, so the type of a.x might affect the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_not_generic() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-class B {
-  B(x);
-}
-var a = new A();
-var b = new B(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_not_generic_named() async {
-    Source source = addSource('''
-class A {
-  var x = 0;
-}
-class B {
-  B.named(x);
-}
-var a = new A();
-var b = new B.named(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_not_generic_prefixed() async {
-    addNamedSource('/lib1.dart', '''
-class B {
-  B(x);
-}
-''');
-    Source source = addSource('''
-import 'lib1.dart' as foo;
-class A {
-  var x = 0;
-}
-var a = new A();
-var b = new foo.B(a.x);
-''');
-    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
-    // it can't possibly affect the type of b.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_new_prefixed() async {
-    addNamedSource('/lib1.dart', '''
-class B<T> {
-  B(x);
-}
-''');
-    Source source = addSource('''
-import 'lib1.dart' as foo;
-class A {
-  var x = 0;
-}
-var a = new A();
-var b = new foo.B(a.x);
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
-    // generic, so the type of a.x might affect the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_prefixedIdentifier() async {
-    Source source = addSource('''
-class A {
-  get g => 0;
-}
-var a = new A();
-var b = a.g;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_implicitlyTyped_propertyAccessLhs() async {
-    Source source = addSource('''
-class A {
-  var x = new B();
-  int operator[](int value) => 0;
-}
-class B {
-  int y;
-}
-var a = new A();
-var b = (a.x).y;
-''');
-    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the type
-    // of a.x affects the lookup of y, which in turn affects the type of b.
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceGetter_prefixedIdentifier() async {
-    Source source = addSource('''
-class A {
-  int get g => 0;
-}
-var a = new A();
-var b = a.g;
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
-    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod() async {
-    Source source = addSource('''
-class A {
-  f() => 0;
-}
-var x = new A().f();
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_parameter() async {
-    Source source = addSource('''
-class A {
-  int f(v) => 0;
-}
-var x = new A().f(0);
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_parameter_generic() async {
-    Source source = addSource('''
-class A {
-  int f<T>(v) => 0;
-}
-var x = new A().f(0);
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_parameter_generic_explicit() async {
-    Source source = addSource('''
-class A {
-  int f<T>(v) => 0;
-}
-var x = new A().f<int>(0);
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_static() async {
-    Source source = addSource('''
-class A {
-  static f() => 0;
-}
-var x = A.f();
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_tearoff() async {
-    Source source = addSource('''
-class A {
-  f() => 0;
-}
-var x = new A().f;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_tearoff_parameter() async {
-    Source source = addSource('''
-class A {
-  int f(v) => 0;
-}
-var x = new A().f;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
-    verify([source]);
-  }
-
-  test_strongMode_topLevelInstanceMethod_tearoff_static() async {
-    Source source = addSource('''
-class A {
-  static f() => 0;
-}
-var x = A.f;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeCheck_type_is_Null() async {
-    Source source = addSource(r'''
-m(i) {
-  bool b = i is Null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.TYPE_CHECK_IS_NULL]);
-    verify([source]);
-  }
-
-  test_typeCheck_type_not_Null() async {
-    Source source = addSource(r'''
-m(i) {
-  bool b = i is! Null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.TYPE_CHECK_IS_NOT_NULL]);
-    verify([source]);
-  }
-
-  test_undefinedGetter() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    return a.m;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedIdentifier_exportHide() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart' hide a;''');
-    addNamedSource("/lib1.dart", "library lib1;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNDEFINED_HIDDEN_NAME]);
-    verify([source]);
-  }
-
-  test_undefinedIdentifier_exportShow() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart' show a;''');
-    addNamedSource("/lib1.dart", "library lib1;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNDEFINED_SHOWN_NAME]);
-    verify([source]);
-  }
-
-  test_undefinedIdentifier_importHide() async {
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart' hide a;''');
-    addNamedSource("/lib1.dart", "library lib1;");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_HIDDEN_NAME]);
-    verify([source]);
-  }
-
-  test_undefinedIdentifier_importShow() async {
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart' show a;''');
-    addNamedSource("/lib1.dart", "library lib1;");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_SHOWN_NAME]);
-    verify([source]);
-  }
-
-  test_undefinedOperator_binaryExpression() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    a + 1;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_indexBoth() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    a[0]++;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.UNDEFINED_OPERATOR,
-      StaticTypeWarningCode.UNDEFINED_OPERATOR,
-    ]);
-  }
-
-  test_undefinedOperator_indexGetter() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    a[0];
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_indexSetter() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    a[0] = 1;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_postfixExpression() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    a++;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedOperator_prefixExpression() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    ++a;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedSetter() async {
-    Source source = addSource(r'''
-class A {}
-f(var a) {
-  if(a is A) {
-    a.m = 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
-  }
-
-  test_unnecessaryNoSuchMethod_blockBody() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
-  mmm();
-  noSuchMethod(y) {
-    return super.noSuchMethod(y);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
-    verify([source]);
-  }
-
-  test_unnecessaryNoSuchMethod_expressionBody() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
-  mmm();
-  noSuchMethod(y) => super.noSuchMethod(y);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
-    verify([source]);
-  }
-
-  test_unnecessaryTypeCheck_null_is_Null() async {
-    Source source = addSource("bool b = null is Null;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
-    verify([source]);
-  }
-
-  test_unnecessaryTypeCheck_null_not_Null() async {
-    Source source = addSource("bool b = null is! Null;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
-    verify([source]);
-  }
-
-  test_unnecessaryTypeCheck_type_is_dynamic() async {
-    Source source = addSource(r'''
-m(i) {
-  bool b = i is dynamic;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
-    verify([source]);
-  }
-
-  test_unnecessaryTypeCheck_type_is_object() async {
-    Source source = addSource(r'''
-m(i) {
-  bool b = i is Object;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
-    verify([source]);
-  }
-
-  test_unnecessaryTypeCheck_type_not_dynamic() async {
-    Source source = addSource(r'''
-m(i) {
-  bool b = i is! dynamic;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
-    verify([source]);
-  }
-
-  test_unnecessaryTypeCheck_type_not_object() async {
-    Source source = addSource(r'''
-m(i) {
-  bool b = i is! Object;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_extends() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-class B extends _A {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_fieldDeclaration() async {
-    enableUnusedElement = true;
-    var src = r'''
-class Foo {
-  _Bar x;
-}
-
-class _Bar {
-}
-''';
-    Source source = addSource(src);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_implements() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-class B implements _A {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_instanceCreation() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-main() {
-  new _A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_staticFieldAccess() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {
-  static const F = 42;
-}
-main() {
-  _A.F;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_staticMethodInvocation() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {
-  static m() {}
-}
-main() {
-  _A.m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_isUsed_typeArgument() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-main() {
-  var v = new List<_A>();
-  print(v);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_class_notUsed_inClassMember() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {
-  static staticMethod() {
-    new _A();
-  }
-  instanceMethod() {
-    new _A();
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_class_notUsed_inConstructorName() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {
-  _A() {}
-  _A.named() {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_class_notUsed_isExpression() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-main(p) {
-  if (p is _A) {
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_class_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_class_notUsed_variableDeclaration() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class _A {}
-main() {
-  _A v;
-  print(v);
-}
-print(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_enum_isUsed_fieldReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-enum _MyEnum {A, B, C}
-main() {
-  print(_MyEnum.B);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_enum_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-enum _MyEnum {A, B, C}
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_functionLocal_isUsed_closure() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-main() {
-  print(() {});
-}
-print(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionLocal_isUsed_invocation() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-main() {
-  f() {}
-  f();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionLocal_isUsed_reference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-main() {
-  f() {}
-  print(f);
-}
-print(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionLocal_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-main() {
-  f() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_functionLocal_notUsed_referenceFromItself() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-main() {
-  _f(int p) {
-    _f(p - 1);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTop_isUsed_invocation() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-_f() {}
-main() {
-  _f();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTop_isUsed_reference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-_f() {}
-main() {
-  print(_f);
-}
-print(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTop_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-_f() {}
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTop_notUsed_referenceFromItself() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-_f(int p) {
-  _f(p - 1);
-}
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTypeAlias_isUsed_isExpression() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-typedef _F(a, b);
-main(f) {
-  if (f is _F) {
-    print('F');
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTypeAlias_isUsed_reference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-typedef _F(a, b);
-main(_F f) {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTypeAlias_isUsed_typeArgument() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-typedef _F(a, b);
-main() {
-  var v = new List<_F>();
-  print(v);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTypeAlias_isUsed_variableDeclaration() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-typedef _F(a, b);
-class A {
-  _F f;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_functionTypeAlias_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-typedef _F(a, b);
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_getter_isUsed_invocation_implicitThis() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  get _g => null;
-  useGetter() {
-    var v = _g;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_getter_isUsed_invocation_PrefixedIdentifier() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  get _g => null;
-}
-main(A a) {
-  var v = a._g;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_getter_isUsed_invocation_PropertyAccess() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  get _g => null;
-}
-main() {
-  var v = new A()._g;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_getter_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  get _g => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_getter_notUsed_referenceFromItself() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  get _g {
-    return _g;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_hasReference_implicitThis() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-  useMethod() {
-    print(_m);
-  }
-}
-print(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_hasReference_implicitThis_subclass() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-  useMethod() {
-    print(_m);
-  }
-}
-class B extends A {
-  _m() {}
-}
-print(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_hasReference_PrefixedIdentifier() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-}
-main(A a) {
-  a._m;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_hasReference_PropertyAccess() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-}
-main() {
-  new A()._m;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_invocation_implicitThis() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-  useMethod() {
-    _m();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_invocation_implicitThis_subclass() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-  useMethod() {
-    _m();
-  }
-}
-class B extends A {
-  _m() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_invocation_MemberElement() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A<T> {
-  _m(T t) {}
-}
-main(A<int> a) {
-  a._m(0);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_invocation_propagated() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-}
-main() {
-  var a = new A();
-  a._m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_invocation_static() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-}
-main() {
-  A a = new A();
-  a._m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_invocation_subclass() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  _m() {}
-}
-class B extends A {
-  _m() {}
-}
-main(A a) {
-  a._m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_notPrivate() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_isUsed_staticInvocation() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  static _m() {}
-}
-main() {
-  A._m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_method_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  static _m() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_method_notUsed_referenceFromItself() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  static _m(int p) {
-    _m(p - 1);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_setter_isUsed_invocation_implicitThis() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  set _s(x) {}
-  useSetter() {
-    _s = 42;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_setter_isUsed_invocation_PrefixedIdentifier() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  set _s(x) {}
-}
-main(A a) {
-  a._s = 42;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_setter_isUsed_invocation_PropertyAccess() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  set _s(x) {}
-}
-main() {
-  new A()._s = 42;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_setter_notUsed_noReference() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  set _s(x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_setter_notUsed_referenceFromItself() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-class A {
-  set _s(int x) {
-    if (x > 5) {
-      _s = x - 1;
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedElement_topLevelVariable_isUsed() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-int _a = 1;
-main() {
-  _a;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_topLevelVariable_isUsed_plusPlus() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-int _a = 0;
-main() {
-  var b = _a++;
-  b;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedElement_topLevelVariable_notUsed() async {
-    enableUnusedElement = true;
-    Source source = addSource(r'''
-int _a = 1;
-main() {
-  _a = 2;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_ELEMENT]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inCatch_exception() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  try {
-  } on String catch (exception) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inCatch_exception_hasStack() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  try {
-  } catch (exception, stack) {
-    print(stack);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inCatch_exception_noOnClause() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  try {
-  } catch (exception) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inCatch_stackTrace() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  try {
-  } catch (exception, stackTrace) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inCatch_stackTrace_used() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  try {
-  } catch (exception, stackTrace) {
-    print('exception at $stackTrace');
-  }
-}
-print(x) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inFor_underscore_ignored() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  for (var _ in [1,2,3]) {
-    for (var __ in [4,5,6]) {
-      // do something
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inFunction() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  var v = 1;
-  v = 2;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_inMethod() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-class A {
-  foo() {
-    var v = 1;
-    v = 2;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isInvoked() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-typedef Foo();
-main() {
-  Foo foo;
-  foo();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isNullAssigned() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-typedef Foo();
-main() {
-  var v;
-  v ??= doSomething();
-}
-doSomething() => 42;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isRead_notUsed_compoundAssign() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  var v = 1;
-  v += 2;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isRead_notUsed_postfixExpr() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  var v = 1;
-  v++;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isRead_notUsed_prefixExpr() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  var v = 1;
-  ++v;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isRead_usedArgument() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-main() {
-  var v = 1;
-  print(++v);
-}
-print(x) {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
-
-  test_unusedLocalVariable_isRead_usedInvocationTarget() async {
-    enableUnusedLocalVariable = true;
-    Source source = addSource(r'''
-class A {
-  foo() {}
-}
-main() {
-  var a = new A();
-  a.foo();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
 }
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index d6def33..8673c9e 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -42,6 +42,7 @@
   /**
    * The inheritance manager being tested.
    */
+  @deprecated
   InheritanceManager _inheritanceManager;
 
   /**
@@ -49,6 +50,7 @@
    */
   int _numOfMembersInObject = 0;
 
+  @deprecated
   void setUp() {
     _typeProvider = new TestTypeProvider();
     _inheritanceManager = _createInheritanceManager();
@@ -1106,6 +1108,7 @@
    *
    * @return the inheritance manager that was created
    */
+  @deprecated
   InheritanceManager _createInheritanceManager() {
     AnalysisContext context = AnalysisContextFactory.contextWithCore(
         resourceProvider: resourceProvider);
diff --git a/pkg/analyzer/test/generated/invalid_code.dart b/pkg/analyzer/test/generated/invalid_code.dart
new file mode 100644
index 0000000..b7e6944
--- /dev/null
+++ b/pkg/analyzer/test/generated/invalid_code.dart
@@ -0,0 +1,48 @@
+// 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 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
+
+import 'resolver_test_case.dart';
+
+/**
+ * Tests for various end-to-end cases when invalid code caused exceptions
+ * in one or another Analyzer subsystem. We are not interested not in specific
+ * errors generated, but we want to make sure that there is at least one,
+ * and analysis finishes without exceptions.
+ */
+abstract class InvalidCodeTest extends ResolverTestCase {
+  @override
+  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
+
+  /**
+   * This code results in a method with the empty name, and the default
+   * constructor, which also has the empty name. The `Map` in `f` initializer
+   * references the empty name.
+   */
+  test_constructorAndMethodNameCollision() async {
+    await _assertCanBeAnalyzed('''
+class C {
+  var f = { : };
+  @ ();
+}
+''');
+  }
+
+  test_genericFunction_asTypeArgument_ofUnresolvedClass() async {
+    await _assertCanBeAnalyzed(r'''
+C<int Function()> c;
+''');
+  }
+
+  Future<void> _assertCanBeAnalyzed(String text) async {
+    Source source = addSource(text);
+    var analysisResult = await computeAnalysisResult(source);
+    expect(analysisResult.errors, isNotEmpty);
+  }
+}
diff --git a/pkg/analyzer/test/generated/invalid_code_driver_test.dart b/pkg/analyzer/test/generated/invalid_code_driver_test.dart
index cdccd25..b457f67 100644
--- a/pkg/analyzer/test/generated/invalid_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_driver_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'invalid_code_test.dart';
+import 'invalid_code.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
deleted file mode 100644
index 3d24f99..0000000
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(InvalidCodeTest);
-  });
-}
-
-/**
- * Tests for various end-to-end cases when invalid code caused exceptions
- * in one or another Analyzer subsystem. We are not interested not in specific
- * errors generated, but we want to make sure that there is at least one,
- * and analysis finishes without exceptions.
- */
-@reflectiveTest
-class InvalidCodeTest extends ResolverTestCase {
-  @override
-  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
-
-  /**
-   * This code results in a method with the empty name, and the default
-   * constructor, which also has the empty name. The `Map` in `f` initializer
-   * references the empty name.
-   */
-  test_constructorAndMethodNameCollision() async {
-    await _assertCanBeAnalyzed('''
-class C {
-  var f = { : };
-  @ ();
-}
-''');
-  }
-
-  test_genericFunction_asTypeArgument_ofUnresolvedClass() async {
-    await _assertCanBeAnalyzed(r'''
-C<int Function()> c;
-''');
-  }
-
-  Future<void> _assertCanBeAnalyzed(String text) async {
-    Source source = addSource(text);
-    var analysisResult = await computeAnalysisResult(source);
-    expect(analysisResult.errors, isNotEmpty);
-  }
-}
diff --git a/pkg/analyzer/test/generated/non_error_resolver.dart b/pkg/analyzer/test/generated/non_error_resolver.dart
new file mode 100644
index 0000000..3d06cd2
--- /dev/null
+++ b/pkg/analyzer/test/generated/non_error_resolver.dart
@@ -0,0 +1,6028 @@
+// 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_resolution_map.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
+
+import 'resolver_test_case.dart';
+
+class NonErrorResolverTestBase extends ResolverTestCase {
+  @override
+  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
+
+  fail_undefinedEnumConstant() async {
+    Source source = addSource(r'''
+enum E { ONE }
+E e() {
+  return E.TWO;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_ambiguousExport() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';
+export 'lib2.dart';''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class M {}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+class N {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_ambiguousExport_combinators_hide() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';
+export 'lib2.dart' hide B;''');
+    addNamedSource("/lib1.dart", r'''
+library L1;
+class A {}
+class B {}''');
+    addNamedSource("/lib2.dart", r'''
+library L2;
+class B {}
+class C {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_ambiguousExport_combinators_show() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';
+export 'lib2.dart' show C;''');
+    addNamedSource("/lib1.dart", r'''
+library L1;
+class A {}
+class B {}''');
+    addNamedSource("/lib2.dart", r'''
+library L2;
+class B {}
+class C {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_ambiguousExport_sameDeclaration() async {
+    Source source = addSource(r'''
+library L;
+export 'lib.dart';
+export 'lib.dart';''');
+    addNamedSource("/lib.dart", r'''
+library lib;
+class N {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_ambiguousImport_dart_implicitHide() async {
+    Source source = addSource(r'''
+import 'dart:async';
+import 'lib.dart';
+main() {
+  print(Future.zero);
+}
+''');
+    addNamedSource('/lib.dart', r'''
+class Future {
+  static const zero = 0;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_ambiguousImport_hideCombinator() async {
+    Source source = addSource(r'''
+import 'lib1.dart';
+import 'lib2.dart';
+import 'lib3.dart' hide N;
+main() {
+  new N1();
+  new N2();
+  new N3();
+}''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class N {}
+class N1 {}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+class N {}
+class N2 {}''');
+    addNamedSource("/lib3.dart", r'''
+library lib3;
+class N {}
+class N3 {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_ambiguousImport_showCombinator() async {
+    Source source = addSource(r'''
+import 'lib1.dart';
+import 'lib2.dart' show N, N2;
+main() {
+  new N1();
+  new N2();
+}''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class N {}
+class N1 {}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+class N {}
+class N2 {}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
+  }
+
+  test_annotated_partOfDeclaration() async {
+    Source source = addSource('library L; part "part.dart";');
+    addNamedSource('/part.dart', '@deprecated part of L;');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_classWithCall_Function() async {
+    Source source = addSource(r'''
+  caller(Function callee) {
+    callee();
+  }
+
+  class CallMeBack {
+    call() => 0;
+  }
+
+  main() {
+    caller(new CallMeBack());
+  }''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_fieldFormalParameterElement_member() async {
+    Source source = addSource(r'''
+class ObjectSink<T> {
+  void sink(T object) {
+    new TimestampedObject<T>(object);
+  }
+}
+class TimestampedObject<E> {
+  E object2;
+  TimestampedObject(this.object2);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_invocation_functionParameter_generic() async {
+    Source source = addSource(r'''
+class A<K> {
+  m(f(K k), K v) {
+    f(v);
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_invocation_typedef_generic() async {
+    Source source = addSource(r'''
+typedef A<T>(T p);
+f(A<int> a) {
+  a(1);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_Object_Function() async {
+    Source source = addSource(r'''
+main() {
+  process(() {});
+}
+process(Object x) {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_optionalNew() async {
+    resetWith(options: new AnalysisOptionsImpl());
+    Source source = addSource(r'''
+class Widget { }
+
+class MaterialPageRoute {
+  final Widget Function() builder;
+  const MaterialPageRoute({this.builder});
+}
+
+void main() {
+  print(MaterialPageRoute(
+      builder: () { return Widget(); }
+  ));
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_typedef_local() async {
+    Source source = addSource(r'''
+typedef A(int p1, String p2);
+A getA() => null;
+f() {
+  A a = getA();
+  a(1, '2');
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_argumentTypeNotAssignable_typedef_parameter() async {
+    Source source = addSource(r'''
+typedef A(int p1, String p2);
+f(A a) {
+  a(1, '2');
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assert_with_message_await() async {
+    Source source = addSource('''
+import 'dart:async';
+f() async {
+  assert(false, await g());
+}
+Future<String> g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assert_with_message_dynamic() async {
+    Source source = addSource('''
+f() {
+  assert(false, g());
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assert_with_message_non_string() async {
+    Source source = addSource('''
+f() {
+  assert(false, 3);
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assert_with_message_null() async {
+    Source source = addSource('''
+f() {
+  assert(false, null);
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assert_with_message_string() async {
+    Source source = addSource('''
+f() {
+  assert(false, 'message');
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assert_with_message_suppresses_unused_var_hint() async {
+    Source source = addSource('''
+f() {
+  String message = 'msg';
+  assert(true, message);
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assignability_function_expr_rettype_from_typedef_cls() async {
+    // In the code below, the type of (() => f()) has a return type which is
+    // a class, and that class is inferred from the return type of the typedef
+    // F.
+    Source source = addSource('''
+class C {}
+typedef C F();
+F f;
+main() {
+  F f2 = (() => f());
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assignability_function_expr_rettype_from_typedef_typedef() async {
+    // In the code below, the type of (() => f()) has a return type which is
+    // a typedef, and that typedef is inferred from the return type of the
+    // typedef F.
+    Source source = addSource('''
+typedef G F();
+typedef G();
+F f;
+main() {
+  F f2 = (() => f());
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assignmentToFinal_prefixNegate() async {
+    Source source = addSource(r'''
+f() {
+  final x = 0;
+  -x;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assignmentToFinalNoSetter_prefixedIdentifier() async {
+    Source source = addSource(r'''
+class A {
+  int get x => 0;
+  set x(v) {}
+}
+main() {
+  A a = new A();
+  a.x = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assignmentToFinalNoSetter_propertyAccess() async {
+    Source source = addSource(r'''
+class A {
+  int get x => 0;
+  set x(v) {}
+}
+class B {
+  static A a;
+}
+main() {
+  B.a.x = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_assignmentToFinals_importWithPrefix() async {
+    Source source = addSource(r'''
+library lib;
+import 'lib1.dart' as foo;
+main() {
+  foo.x = true;
+}''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+bool x = false;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_dynamic_with_return() async {
+    Source source = addSource('''
+dynamic f() async {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_dynamic_with_return_value() async {
+    Source source = addSource('''
+dynamic f() async {
+  return 5;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_dynamic_without_return() async {
+    Source source = addSource('''
+dynamic f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_expression_function_type() async {
+    Source source = addSource('''
+import 'dart:async';
+typedef Future<int> F(int i);
+main() {
+  F f = (int i) async => i;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_flattened() async {
+    Source source = addSource('''
+import 'dart:async';
+typedef Future<int> CreatesFutureInt();
+main() {
+  CreatesFutureInt createFutureInt = () async => f();
+  Future<int> futureInt = createFutureInt();
+  futureInt.then((int i) => print(i));
+}
+Future<int> f() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_dynamic_with_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<dynamic> f() async {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_dynamic_with_return_value() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<dynamic> f() async {
+  return 5;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_dynamic_without_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<dynamic> f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_int_with_return_future_int() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<int> f() async {
+  return new Future<int>.value(5);
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_int_with_return_value() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<int> f() async {
+  return 5;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_null_with_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<Null> f() async {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_null_without_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<Null> f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_object_with_return_value() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<Object> f() async {
+  return 5;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_with_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future f() async {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_with_return_value() async {
+    Source source = addSource('''
+import 'dart:async';
+Future f() async {
+  return 5;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_future_without_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_with_return() async {
+    Source source = addSource('''
+f() async {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_with_return_value() async {
+    Source source = addSource('''
+f() async {
+  return 5;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_async_without_return() async {
+    Source source = addSource('''
+f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_asyncForInWrongContext_async() async {
+    Source source = addSource(r'''
+f(list) async {
+  await for (var e in list) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_asyncForInWrongContext_asyncStar() async {
+    Source source = addSource(r'''
+f(list) async* {
+  await for (var e in list) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_await_flattened() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<Future<int>> ffi() => null;
+f() async {
+  Future<int> b = await ffi();
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_await_simple() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<int> fi() => null;
+f() async {
+  int a = await fi();
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_awaitInWrongContext_async() async {
+    Source source = addSource(r'''
+f(x, y) async {
+  return await x + await y;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_awaitInWrongContext_asyncStar() async {
+    Source source = addSource(r'''
+f(x, y) async* {
+  yield await x + await y;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_breakWithoutLabelInSwitch() async {
+    Source source = addSource(r'''
+class A {
+  void m(int i) {
+    switch (i) {
+      case 0:
+        break;
+    }
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_bug_24539_getter() async {
+    Source source = addSource('''
+class C<T> {
+  List<Foo> get x => null;
+}
+
+typedef Foo(param);
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_bug_24539_setter() async {
+    Source source = addSource('''
+class C<T> {
+  void set x(List<Foo> value) {}
+}
+
+typedef Foo(param);
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_builtInIdentifierAsType_dynamic() async {
+    Source source = addSource(r'''
+f() {
+  dynamic x;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_caseBlockNotTerminated() async {
+    Source source = addSource(r'''
+f(int p) {
+  for (int i = 0; i < 10; i++) {
+    switch (p) {
+      case 0:
+        break;
+      case 1:
+        continue;
+      case 2:
+        return;
+      case 3:
+        throw new Object();
+      case 4:
+      case 5:
+        return;
+      case 6:
+      default:
+        return;
+    }
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_caseBlockNotTerminated_lastCase() async {
+    Source source = addSource(r'''
+f(int p) {
+  switch (p) {
+    case 0:
+      p = p + 1;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_caseExpressionTypeImplementsEquals() async {
+    Source source = addSource(r'''
+print(p) {}
+
+abstract class B {
+  final id;
+  const B(this.id);
+  String toString() => 'C($id)';
+  /** Equality is identity equality, the id isn't used. */
+  bool operator==(Object other);
+  }
+
+class C extends B {
+  const C(id) : super(id);
+}
+
+void doSwitch(c) {
+  switch (c) {
+  case const C(0): print('Switch: 0'); break;
+  case const C(1): print('Switch: 1'); break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_caseExpressionTypeImplementsEquals_int() async {
+    Source source = addSource(r'''
+f(int i) {
+  switch(i) {
+    case(1) : return 1;
+    default: return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_caseExpressionTypeImplementsEquals_Object() async {
+    Source source = addSource(r'''
+class IntWrapper {
+  final int value;
+  const IntWrapper(this.value);
+}
+
+f(IntWrapper intWrapper) {
+  switch(intWrapper) {
+    case(const IntWrapper(1)) : return 1;
+    default: return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_caseExpressionTypeImplementsEquals_String() async {
+    Source source = addSource(r'''
+f(String s) {
+  switch(s) {
+    case('1') : return 1;
+    default: return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_class_type_alias_documentationComment() async {
+    Source source = addSource('''
+/**
+ * Documentation
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    ClassElement classC =
+        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+    expect(classC.documentationComment, isNotNull);
+  }
+
+  test_concreteClassWithAbstractMember() async {
+    Source source = addSource(r'''
+abstract class A {
+  m();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_concreteClassWithAbstractMember_inherited() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+class B extends A {
+  m();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_conflictingConstructorNameAndMember_setter() async {
+    Source source = addSource(r'''
+class A {
+A.x() {}
+set x(_) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_conflictingStaticGetterAndInstanceSetter_thisClass() async {
+    Source source = addSource(r'''
+class A {
+  static get x => 0;
+  static set x(int p) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_const_constructor_with_named_generic_parameter() async {
+    Source source = addSource('''
+class C<T> {
+  const C({T t});
+}
+const c = const C(t: 1);
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_const_dynamic() async {
+    Source source = addSource('''
+const Type d = dynamic;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_const_imported_defaultParameterValue_withImportPrefix() async {
+    Source source = addNamedSource("/a.dart", r'''
+import 'b.dart';
+const b = const B();
+''');
+    addNamedSource("/b.dart", r'''
+import 'c.dart' as ccc;
+class B {
+  const B([p = ccc.value]);
+}
+''');
+    addNamedSource("/c.dart", r'''
+const int value = 12345;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonConstSuper_explicit() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+class B extends A {
+  const B(): super();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonConstSuper_redirectingFactory() async {
+    Source source = addSource(r'''
+class A {
+  A();
+}
+class B implements C {
+  const B();
+}
+class C extends A {
+  const factory C() = B;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonConstSuper_unresolved() async {
+    Source source = addSource(r'''
+class A {
+  A.a();
+}
+class B extends A {
+  const B(): super();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonFinalField_finalInstanceVar() async {
+    Source source = addSource(r'''
+class A {
+  final int x = 0;
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonFinalField_static() async {
+    Source source = addSource(r'''
+class A {
+  static int x;
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constConstructorWithNonFinalField_syntheticField() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  set x(value) {}
+  get x {return 0;}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constDeferredClass_new() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+class A {
+  const A.b();
+}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as a;
+main() {
+  new a.A.b();
+}'''
+    ], <ErrorCode>[]);
+  }
+
+  test_constEval_functionTypeLiteral() async {
+    Source source = addSource(r'''
+typedef F();
+const C = F;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEval_propertyExtraction_fieldStatic_targetType() async {
+    addNamedSource("/math.dart", r'''
+library math;
+const PI = 3.14;''');
+    Source source = addSource(r'''
+import 'math.dart' as math;
+const C = math.PI;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEval_propertyExtraction_methodStatic_targetType() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  static m() {}
+}
+const C = A.m;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEval_symbol() async {
+    addNamedSource("/math.dart", r'''
+library math;
+const PI = 3.14;''');
+    Source source = addSource(r'''
+const C = #foo;
+foo() {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEvalTypeBoolNumString_equal() async {
+    Source source = addSource(r'''
+class B {
+  final v;
+  const B.a1(bool p) : v = p == true;
+  const B.a2(bool p) : v = p == false;
+  const B.a3(bool p) : v = p == 0;
+  const B.a4(bool p) : v = p == 0.0;
+  const B.a5(bool p) : v = p == '';
+  const B.b1(int p) : v = p == true;
+  const B.b2(int p) : v = p == false;
+  const B.b3(int p) : v = p == 0;
+  const B.b4(int p) : v = p == 0.0;
+  const B.b5(int p) : v = p == '';
+  const B.c1(String p) : v = p == true;
+  const B.c2(String p) : v = p == false;
+  const B.c3(String p) : v = p == 0;
+  const B.c4(String p) : v = p == 0.0;
+  const B.c5(String p) : v = p == '';
+  const B.n1(num p) : v = p == null;
+  const B.n2(num p) : v = null == p;
+  const B.n3(Object p) : v = p == null;
+  const B.n4(Object p) : v = null == p;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_constEvalTypeBoolNumString_notEqual() async {
+    Source source = addSource(r'''
+class B {
+  final v;
+  const B.a1(bool p) : v = p != true;
+  const B.a2(bool p) : v = p != false;
+  const B.a3(bool p) : v = p != 0;
+  const B.a4(bool p) : v = p != 0.0;
+  const B.a5(bool p) : v = p != '';
+  const B.b1(int p) : v = p != true;
+  const B.b2(int p) : v = p != false;
+  const B.b3(int p) : v = p != 0;
+  const B.b4(int p) : v = p != 0.0;
+  const B.b5(int p) : v = p != '';
+  const B.c1(String p) : v = p != true;
+  const B.c2(String p) : v = p != false;
+  const B.c3(String p) : v = p != 0;
+  const B.c4(String p) : v = p != 0.0;
+  const B.c5(String p) : v = p != '';
+  const B.n1(num p) : v = p != null;
+  const B.n2(num p) : v = null != p;
+  const B.n3(Object p) : v = p != null;
+  const B.n4(Object p) : v = null != p;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constEvAlTypeNum_String() async {
+    Source source = addSource(r'''
+const String A = 'a';
+const String B = A + 'b';
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constMapKeyExpressionTypeImplementsEquals_abstract() async {
+    Source source = addSource(r'''
+abstract class B {
+  final id;
+  const B(this.id);
+  String toString() => 'C($id)';
+  /** Equality is identity equality, the id isn't used. */
+  bool operator==(Object other);
+  }
+
+class C extends B {
+  const C(id) : super(id);
+}
+
+Map getMap() {
+  return const { const C(0): 'Map: 0' };
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constNotInitialized_field() async {
+    Source source = addSource(r'''
+class A {
+  static const int x = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constNotInitialized_local() async {
+    Source source = addSource(r'''
+main() {
+  const int x = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constRedirectSkipsSupertype() async {
+    // Since C redirects to C.named, it doesn't implicitly refer to B's
+    // unnamed constructor.  Therefore there is no cycle.
+    Source source = addSource('''
+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();
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constructorDeclaration_scope_signature() async {
+    Source source = addSource(r'''
+const app = 0;
+class A {
+  A(@app int app) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constWithNonConstantArgument_constField() async {
+    Source source = addSource(r'''
+class A {
+  const A(x);
+}
+main() {
+  const A(double.INFINITY);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constWithNonConstantArgument_literals() async {
+    Source source = addSource(r'''
+class A {
+  const A(a, b, c, d);
+}
+f() { return const A(true, 0, 1.0, '2'); }''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constWithTypeParameters_direct() async {
+    Source source = addSource(r'''
+class A<T> {
+  static const V = const A<int>();
+  const A();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constWithUndefinedConstructor() async {
+    Source source = addSource(r'''
+class A {
+  const A.name();
+}
+f() {
+  return const A.name();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_constWithUndefinedConstructorDefault() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+}
+f() {
+  return const A();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypeAlias() async {
+    Source source = addSource("typedef F([x]);");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypedParameter_named() async {
+    Source source = addSource("f(g({p})) {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypedParameter_optional() async {
+    Source source = addSource("f(g([p])) {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deprecatedMemberUse_hide() async {
+    Source source = addSource(r'''
+library lib;
+import 'lib1.dart' hide B;
+A a = new A();''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class A {}
+@deprecated
+class B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_emptyName() async {
+    // Note: This code has two FunctionElements '() {}' with an empty name,
+    // this tests that the empty string is not put into the scope
+    // (more than once).
+    Source source = addSource(r'''
+Map _globalMap = {
+  'a' : () {},
+  'b' : () {}
+};''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_duplicateDefinition_getter() async {
+    Source source = addSource("bool get a => true;");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_duplicatePart() async {
+    addNamedSource('/part1.dart', 'part of lib;');
+    addNamedSource('/part2.dart', 'part of lib;');
+    Source source = addSource(r'''
+library lib;
+part 'part1.dart';
+part 'part2.dart';
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_dynamicIdentifier() async {
+    Source source = addSource(r'''
+main() {
+  var v = dynamic;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_empty_generator_async() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream<int> f() async* {
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_empty_generator_sync() async {
+    Source source = addSource('''
+Iterable<int> f() sync* {
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_expectedOneListTypeArgument() async {
+    Source source = addSource(r'''
+main() {
+  <int> [];
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_expectedTwoMapTypeArguments() async {
+    Source source = addSource(r'''
+main() {
+  <int, int> {};
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_exportDuplicatedLibraryUnnamed() async {
+    Source source = addSource(r'''
+library test;
+export 'lib1.dart';
+export 'lib2.dart';''');
+    addNamedSource("/lib1.dart", "");
+    addNamedSource("/lib2.dart", "");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_exportOfNonLibrary_libraryDeclared() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';''');
+    addNamedSource("/lib1.dart", "library lib1;");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_exportOfNonLibrary_libraryNotDeclared() async {
+    Source source = addSource(r'''
+library L;
+export 'lib1.dart';''');
+    addNamedSource("/lib1.dart", "");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_extraPositionalArguments_function() async {
+    Source source = addSource(r'''
+f(p1, p2) {}
+main() {
+  f(1, 2);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_extraPositionalArguments_Function() async {
+    Source source = addSource(r'''
+f(Function a) {
+  a(1, 2);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_extraPositionalArguments_typedef_local() async {
+    Source source = addSource(r'''
+typedef A(p1, p2);
+A getA() => null;
+f() {
+  A a = getA();
+  a(1, 2);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_extraPositionalArguments_typedef_parameter() async {
+    Source source = addSource(r'''
+typedef A(p1, p2);
+f(A a) {
+  a(1, 2);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameter_functionTyped_named() async {
+    Source source = addSource(r'''
+class C {
+  final Function field;
+
+  C({String this.field(int value)});
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameter_genericFunctionTyped() async {
+    Source source = addSource(r'''
+class C {
+  final Object Function(int, double) field;
+
+  C(String Function(num, Object) this.field);
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldFormalParameter_genericFunctionTyped_named() async {
+    Source source = addSource(r'''
+class C {
+  final Object Function(int, double) field;
+
+  C({String Function(num, Object) this.field});
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldInitializedByMultipleInitializers() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  int y;
+  A() : x = 0, y = 0 {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal() async {
+    Source source = addSource(r'''
+class A {
+  int x = 0;
+  A() : x = 1 {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldInitializedInInitializerAndDeclaration_finalFieldNotSet() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  A() : x = 1 {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldInitializerOutsideConstructor() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldInitializerOutsideConstructor_defaultParameters() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A([this.x]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_fieldInitializerRedirectingConstructor_super() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+class B extends A {
+  int x;
+  B(this.x) : super();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalInitializedInDeclarationAndConstructor_initializer() async {
+    Source source = addSource(r'''
+class A {
+  final x;
+  A() : x = 1 {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalInitializedInDeclarationAndConstructor_initializingFormal() async {
+    Source source = addSource(r'''
+class A {
+  final x;
+  A(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_atDeclaration() async {
+    Source source = addSource(r'''
+class A {
+  final int x = 0;
+  A() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_fieldFormal() async {
+    Source source = addSource(r'''
+class A {
+  final int x = 0;
+  A() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_functionTypedFieldFormal() async {
+    Source source = addSource(r'''
+class A {
+  final Function x;
+  A(int this.x(int p)) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_hasNativeClause_hasConstructor() async {
+    Source source = addSource(r'''
+class A native 'something' {
+  final int x;
+  A() {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_hasNativeClause_noConstructor() async {
+    Source source = addSource(r'''
+class A native 'something' {
+  final int x;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_initializer() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  A() : x = 0 {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_finalNotInitialized_redirectingConstructor() async {
+    Source source = addSource(r'''
+class A {
+  final int x;
+  A(this.x);
+  A.named() : this (42);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_forEach_genericFunctionType() async {
+    Source source = addSource(r'''
+main() {
+  for (Null Function<T>(T, Null) e in <dynamic>[]) {
+    e;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionDeclaration_scope_returnType() async {
+    Source source = addSource("int f(int) { return 0; }");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionDeclaration_scope_signature() async {
+    Source source = addSource(r'''
+const app = 0;
+f(@app int app) {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionTypeAlias_scope_returnType() async {
+    Source source = addSource("typedef int f(int);");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionTypeAlias_scope_signature() async {
+    Source source = addSource(r'''
+const app = 0;
+typedef int f(@app int app);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionWithoutCall() async {
+    Source source = addSource(r'''
+abstract class A implements Function {
+}
+class B implements A {
+  void call() {}
+}
+class C extends A {
+  void call() {}
+}
+class D extends C {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionWithoutCall_doesNotImplementFunction() async {
+    Source source = addSource("class A {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionWithoutCall_staticCallMethod() async {
+    Source source = addSource(r'''
+class A { }
+class B extends A {
+  static call() { }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionWithoutCall_withNoSuchMethod() async {
+    // 16078
+    Source source = addSource(r'''
+class A implements Function {
+  noSuchMethod(inv) {
+    return 42;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionWithoutCall_withNoSuchMethod_mixin() async {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(inv) {}
+}
+class B extends Object with A implements Function {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_functionWithoutCall_withNoSuchMethod_superclass() async {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(inv) {}
+}
+class B extends A implements Function {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_castsAndTypeChecks_hasTypeParameters() async {
+    Source source = addSource('''
+typedef Foo<S> = S Function<T>(T x);
+
+main(Object p) {
+  (p as Foo)<int>(3);
+  if (p is Foo) {
+    p<int>(3);
+  }
+  (p as Foo<String>)<int>(3);
+  if (p is Foo<String>) {
+    p<int>(3);
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_castsAndTypeChecks_noTypeParameters() async {
+    Source source = addSource('''
+typedef Foo = T Function<T>(T x);
+
+main(Object p) {
+  (p as Foo)<int>(3);
+  if (p is Foo) {
+    p<int>(3);
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_fieldAndReturnType_noTypeParameters() async {
+    Source source = addSource(r'''
+typedef Foo = int Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo bar() => foo;
+void test1() {
+  bar()<String>("hello");
+}
+
+class A {
+  Foo f;
+  void test() {
+    f<String>("hello");
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
+    Source source = addSource(r'''
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo<int> bar() => foo;
+void test1() {
+  bar()<String>("hello");
+}
+
+class A {
+  Foo<int> f;
+  void test() {
+    f<String>("hello");
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
+    Source source = addSource(r'''
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo bar() => foo;
+void test1() {
+  bar()<String>("hello");
+}
+
+class A {
+  Foo f;
+  void test() {
+    f<String>("hello");
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_invalidGenericFunctionType() async {
+    Source source = addSource('''
+typedef F = int;
+main(p) {
+  p is F;
+}
+''');
+    await computeAnalysisResult(source);
+    // There is a parse error, but no crashes.
+    assertErrors(source, [ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE]);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_noTypeParameters() async {
+    Source source = addSource(r'''
+typedef Foo = int Function<T>(T x);
+int foo<T>(T x) => 3;
+void test1() {
+  Foo y = foo;
+  // These two should be equivalent
+  foo<String>("hello");
+  y<String>("hello");
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericTypeAlias_typeParameters() async {
+    Source source = addSource(r'''
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+void test1() {
+  Foo<int> y = foo;
+  // These two should be equivalent
+  foo<String>("hello");
+  y<String>("hello");
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_constructorName() async {
+    Source source = addSource(r'''
+class A {
+  A.named() {}
+}
+class B {
+  var v;
+  B() : v = new A.named();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_prefixedIdentifier() async {
+    Source source = addSource(r'''
+class A {
+  var f;
+}
+class B {
+  var v;
+  B(A a) : v = a.f;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_qualifiedMethodInvocation() async {
+    Source source = addSource(r'''
+class A {
+  f() {}
+}
+class B {
+  var v;
+  B() : v = new A().f();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_qualifiedPropertyAccess() async {
+    Source source = addSource(r'''
+class A {
+  var f;
+}
+class B {
+  var v;
+  B() : v = new A().f;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_staticField_thisClass() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f;
+  static var f;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_staticGetter() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f;
+  static get f => 42;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_staticMethod() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f();
+  static f() => 42;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_topLevelField() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f;
+}
+var f = 42;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_topLevelFunction() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f();
+}
+f() => 42;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_topLevelGetter() async {
+    Source source = addSource(r'''
+class A {
+  var v;
+  A() : v = f;
+}
+get f => 42;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_implicitThisReferenceInInitializer_typeParameter() async {
+    Source source = addSource(r'''
+class A<T> {
+  var v;
+  A(p) : v = (p is T);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_importDuplicatedLibraryName() async {
+    Source source = addSource(r'''
+library test;
+import 'lib.dart';
+import 'lib.dart';''');
+    addNamedSource("/lib.dart", "library lib;");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      HintCode.UNUSED_IMPORT,
+      HintCode.UNUSED_IMPORT,
+      HintCode.DUPLICATE_IMPORT
+    ]);
+    verify([source]);
+  }
+
+  test_importDuplicatedLibraryUnnamed() async {
+    Source source = addSource(r'''
+library test;
+import 'lib1.dart';
+import 'lib2.dart';''');
+    addNamedSource("/lib1.dart", "");
+    addNamedSource("/lib2.dart", "");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      // No warning on duplicate import (https://github.com/dart-lang/sdk/issues/24156)
+      HintCode.UNUSED_IMPORT,
+      HintCode.UNUSED_IMPORT
+    ]);
+    verify([source]);
+  }
+
+  test_importOfNonLibrary_libraryDeclared() async {
+    Source source = addSource(r'''
+library lib;
+import 'part.dart';
+A a;''');
+    addNamedSource("/part.dart", r'''
+library lib1;
+class A {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_importOfNonLibrary_libraryNotDeclared() async {
+    Source source = addSource(r'''
+library lib;
+import 'part.dart';
+A a;''');
+    addNamedSource("/part.dart", "class A {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_importPrefixes_withFirstLetterDifference() async {
+    Source source = addSource(r'''
+library L;
+import 'lib1.dart' as math;
+import 'lib2.dart' as path;
+main() {
+  math.test1();
+  path.test2();
+}''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+test1() {}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+test2() {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentCaseExpressionTypes() async {
+    Source source = addSource(r'''
+f(var p) {
+  switch (p) {
+    case 1:
+      break;
+    case 2:
+      break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentMethodInheritance_accessors_typeParameter2() async {
+    Source source = addSource(r'''
+abstract class A<E> {
+  E get x {return null;}
+}
+class B<E> {
+  E get x {return null;}
+}
+class C<E> extends A<E> implements B<E> {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentMethodInheritance_accessors_typeParameters1() async {
+    Source source = addSource(r'''
+abstract class A<E> {
+  E get x;
+}
+abstract class B<E> {
+  E get x;
+}
+class C<E> implements A<E>, B<E> {
+  E get x => null;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentMethodInheritance_accessors_typeParameters_diamond() async {
+    Source source = addSource(r'''
+abstract class F<E> extends B<E> {}
+class D<E> extends F<E> {
+  external E get g;
+}
+abstract class C<E> {
+  E get g;
+}
+abstract class B<E> implements C<E> {
+  E get g { return null; }
+}
+class A<E> extends B<E> implements D<E> {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentMethodInheritance_methods_typeParameter2() async {
+    Source source = addSource(r'''
+class A<E> {
+  x(E e) {}
+}
+class B<E> {
+  x(E e) {}
+}
+class C<E> extends A<E> implements B<E> {
+  x(E e) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentMethodInheritance_methods_typeParameters1() async {
+    Source source = addSource(r'''
+class A<E> {
+  x(E e) {}
+}
+class B<E> {
+  x(E e) {}
+}
+class C<E> implements A<E>, B<E> {
+  x(E e) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inconsistentMethodInheritance_simple() async {
+    Source source = addSource(r'''
+abstract class A {
+  x();
+}
+abstract class B {
+  x();
+}
+class C implements A, B {
+  x() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_infer_mixin_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+
+class B {}
+
+mixin M<T> on A<T> {}
+
+class C extends A<B> with M {}
+''');
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    ClassElement classC =
+        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+    expect(classC.mixins, hasLength(1));
+    expect(classC.mixins[0].toString(), 'M<B>');
+  }
+
+  test_infer_mixin_with_substitution_functionType_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+
+class B {}
+
+mixin M<T, U> on A<T Function(U)> {}
+
+class C extends A<int Function(String)> with M {}
+''');
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    CompilationUnit unit = analysisResult.unit;
+    ClassElement classC =
+        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+    expect(classC.mixins, hasLength(1));
+    expect(classC.mixins[0].toString(), 'M<int, String>');
+  }
+
+  test_infer_mixin_with_substitution_new_syntax() async {
+    Source source = addSource('''
+abstract class A<T> {}
+
+class B {}
+
+mixin M<T> on A<List<T>> {}
+
+class C extends A<List<B>> with M {}
+''');
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    ClassElement classC =
+        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+    expect(classC.mixins, hasLength(1));
+    expect(classC.mixins[0].toString(), 'M<B>');
+  }
+
+  test_initializingFormalForNonExistentField() async {
+    Source source = addSource(r'''
+class A {
+  int x;
+  A(this.x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_instance_creation_inside_annotation() async {
+    Source source = addSource('''
+class C {
+  const C();
+}
+class D {
+  final C c;
+  const D(this.c);
+}
+@D(const C())
+f() {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_instanceAccessToStaticMember_fromComment() async {
+    Source source = addSource(r'''
+class A {
+  static m() {}
+}
+/// [A.m]
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_instanceAccessToStaticMember_topLevel() async {
+    Source source = addSource(r'''
+m() {}
+main() {
+  m();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_instanceMemberAccessFromStatic_fromComment() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+  /// [m]
+  static foo() {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_instanceMethodNameCollidesWithSuperclassStatic_field() async {
+    Source source = addSource(r'''
+import 'lib.dart';
+class B extends A {
+  _m() {}
+}''');
+    addNamedSource("/lib.dart", r'''
+library L;
+class A {
+  static var _m;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_instanceMethodNameCollidesWithSuperclassStatic_method() async {
+    Source source = addSource(r'''
+import 'lib.dart';
+class B extends A {
+  _m() {}
+}''');
+    addNamedSource("/lib.dart", r'''
+library L;
+class A {
+  static _m() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_integerLiteralOutOfRange_negative_leadingZeros() async {
+    Source source = addSource('int x = -000923372036854775809;');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_integerLiteralOutOfRange_negative_small() async {
+    Source source = addSource('int x = -42;');
+    await computeAnalysisResult(source);
+    assertErrors(source);
+  }
+
+  test_integerLiteralOutOfRange_negative_valid() async {
+    Source source = addSource('int x = -9223372036854775808;');
+    await computeAnalysisResult(source);
+    assertErrors(source);
+  }
+
+  test_integerLiteralOutOfRange_positive_leadingZeros() async {
+    Source source = addSource('int x = 000923372036854775808;');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_integerLiteralOutOfRange_positive_valid() async {
+    Source source = addSource('int x = 9223372036854775807;');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_integerLiteralOutOfRange_positive_zero() async {
+    Source source = addSource('int x = 0;');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_intLiteralInDoubleContext() async {
+    Source source = addSource(r'''
+void takeDouble(double x) {}
+void main() {
+  takeDouble(0);
+  takeDouble(-0);
+  takeDouble(0x0);
+  takeDouble(-0x0);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_intLiteralInDoubleContext_const() async {
+    Source source = addSource(r'''
+class C {
+  const C(double x)
+    : assert((x + 3) / 2 == 1.5)
+    , assert(x == 0.0);
+}
+@C(0)
+@C(-0)
+@C(0x0)
+@C(-0x0)
+void main() {
+  const C(0);
+  const C(-0);
+  const C(0x0);
+  const C(-0x0);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_constantVariable_field() async {
+    Source source = addSource(r'''
+@A.C
+class A {
+  static const C = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_constantVariable_field_importWithPrefix() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A {
+  static const C = 0;
+}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.A.C
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_constantVariable_topLevel() async {
+    Source source = addSource(r'''
+const C = 0;
+@C
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_constantVariable_topLevel_importWithPrefix() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+const C = 0;''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.C
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_constConstructor_importWithPrefix() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A {
+  const A(int p);
+}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.A(42)
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAnnotation_constConstructor_named_importWithPrefix() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A {
+  const A.named(int p);
+}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+@p.A.named(42)
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment() async {
+    Source source = addSource(r'''
+f() {
+  var x;
+  var y;
+  x = y;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_compoundAssignment() async {
+    Source source = addSource(r'''
+class byte {
+  int _value;
+  byte(this._value);
+  byte operator +(int val) { return this; }
+}
+
+void main() {
+  byte b = new byte(52);
+  b += 3;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_defaultValue_named() async {
+    Source source = addSource(r'''
+f({String x: '0'}) {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_defaultValue_optional() async {
+    Source source = addSource(r'''
+f([String x = '0']) {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_ifNullAssignment_compatibleType() async {
+    Source source = addSource('''
+void f(int i) {
+  num n;
+  n ??= i;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_ifNullAssignment_sameType() async {
+    Source source = addSource('''
+void f(int i) {
+  int j;
+  j ??= i;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_1() async {
+    // 18341
+    //
+    // This test and
+    // 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()'
+    // are closely related: here we see that 'I' checks as a subtype of
+    // 'IntToInt'.
+    Source source = addSource(r'''
+class I {
+  int call(int x) => 0;
+}
+class C implements I {
+  noSuchMethod(_) => null;
+}
+typedef int IntToInt(int x);
+IntToInt f = new I();''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_2() async {
+    // 18341
+    //
+    // Here 'C' checks as a subtype of 'I', but 'C' does not
+    // check as a subtype of 'IntToInt'. Together with
+    // 'test_invalidAssignment_implicitlyImplementFunctionViaCall_1()' we see
+    // that subtyping is not transitive here.
+    Source source = addSource(r'''
+class I {
+  int call(int x) => 0;
+}
+class C implements I {
+  noSuchMethod(_) => null;
+}
+typedef int IntToInt(int x);
+IntToInt f = new C();''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_3() async {
+    // 18341
+    //
+    // Like 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
+    // but uses type 'Function' instead of more precise type 'IntToInt' for 'f'.
+    Source source = addSource(r'''
+class I {
+  int call(int x) => 0;
+}
+class C implements I {
+  noSuchMethod(_) => null;
+}
+typedef int IntToInt(int x);
+Function f = new C();''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_4() async {
+    // 18341
+    //
+    // Like 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
+    // but uses type 'VoidToInt' instead of more precise type 'IntToInt' for
+    // 'f'.
+    //
+    // Here 'C <: IntToInt <: VoidToInt', but the spec gives no transitivity
+    // rule for '<:'. However, many of the :/tools/test.py tests assume this
+    // transitivity for 'JsBuilder' objects, assigning them to
+    // '(String) -> dynamic'. The declared type of 'JsBuilder.call' is
+    // '(String, [dynamic]) -> Expression'.
+    Source source = addSource(r'''
+class I {
+  int call([int x]) => 0;
+}
+class C implements I {
+  noSuchMethod(_) => null;
+}
+typedef int VoidToInt();
+VoidToInt f = new C();''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_postfixExpression_localVariable() async {
+    Source source = addSource(r'''
+class A {
+  A operator+(_) => this;
+}
+
+f(A a) {
+  a++;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_postfixExpression_property() async {
+    Source source = addSource(r'''
+class A {
+  A operator+(_) => this;
+}
+
+class C {
+  A a;
+}
+
+f(C c) {
+  c.a++;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_prefixExpression_localVariable() async {
+    Source source = addSource(r'''
+class A {
+  A operator+(_) => this;
+}
+
+f(A a) {
+  ++a;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_prefixExpression_property() async {
+    Source source = addSource(r'''
+class A {
+  A operator+(_) => this;
+}
+
+class C {
+  A a;
+}
+
+f(C c) {
+  ++c.a;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidAssignment_toDynamic() async {
+    Source source = addSource(r'''
+f() {
+  var g;
+  g = () => 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidFactoryNameNotAClass() async {
+    Source source = addSource(r'''
+class A {
+  factory A() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidIdentifierInAsync() async {
+    Source source = addSource(r'''
+class A {
+  m() {
+    int async;
+    int await;
+    int yield;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidMethodOverrideNamedParamType() async {
+    Source source = addSource(r'''
+class A {
+  m({int a}) {}
+}
+class B implements A {
+  m({int a, int b}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideNamed_unorderedNamedParameter() async {
+    Source source = addSource(r'''
+class A {
+  m({a, b}) {}
+}
+class B extends A {
+  m({b, a}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideRequired_less() async {
+    Source source = addSource(r'''
+class A {
+  m(a, b) {}
+}
+class B extends A {
+  m(a, [b]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideRequired_same() async {
+    Source source = addSource(r'''
+class A {
+  m(a) {}
+}
+class B extends A {
+  m(a) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_interface() async {
+    Source source = addNamedSource("/test.dart", r'''
+abstract class A {
+  num m();
+}
+class B implements A {
+  int m() { return 1; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_interface2() async {
+    Source source = addNamedSource("/test.dart", r'''
+abstract class A {
+  num m();
+}
+abstract class B implements A {
+}
+class C implements B {
+  int m() { return 1; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_mixin() async {
+    Source source = addNamedSource("/test.dart", r'''
+class A {
+  num m() { return 0; }
+}
+class B extends Object with A {
+  int m() { return 1; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_parameterizedTypes() async {
+    Source source = addSource(r'''
+abstract class A<E> {
+  List<E> m();
+}
+class B extends A<dynamic> {
+  List<dynamic> m() { return new List<dynamic>(); }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_sameType() async {
+    Source source = addNamedSource("/test.dart", r'''
+class A {
+  int m() { return 0; }
+}
+class B extends A {
+  int m() { return 1; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_superclass() async {
+    Source source = addNamedSource("/test.dart", r'''
+class A {
+  num m() { return 0; }
+}
+class B extends A {
+  int m() { return 1; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_superclass2() async {
+    Source source = addNamedSource("/test.dart", r'''
+class A {
+  num m() { return 0; }
+}
+class B extends A {
+}
+class C extends B {
+  int m() { return 1; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidOverrideReturnType_returnType_void() async {
+    Source source = addSource(r'''
+class A {
+  void m() {}
+}
+class B extends A {
+  int m() { return 0; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_constructor() async {
+    Source source = addSource(r'''
+class A {
+  A() {
+    var v = this;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidReferenceToThis_instanceMethod() async {
+    Source source = addSource(r'''
+class A {
+  m() {
+    var v = this;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentForKey() async {
+    Source source = addSource(r'''
+class A {
+  m() {
+    return const <int, int>{};
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstList() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return <E>[];
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidTypeArgumentInConstMap() async {
+    Source source = addSource(r'''
+class A<E> {
+  m() {
+    return <String, E>{};
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  Future test_issue32114() async {
+    addNamedSource('/a.dart', '''
+class O {}
+
+typedef T Func<T extends O>(T e);
+''');
+    addNamedSource('/b.dart', '''
+import 'a.dart';
+export 'a.dart' show Func;
+
+abstract class A<T extends O> {
+  Func<T> get func;
+}
+''');
+    final Source source = addSource('''
+import 'b.dart';
+
+class B extends A {
+  Func get func => (x) => x;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_issue_24191() async {
+    Source source = addSource('''
+import 'dart:async';
+
+abstract class S extends Stream {}
+f(S s) async {
+  await for (var v in s) {
+    print(v);
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_issue_32394() async {
+    Source source = addSource('''
+var x = y.map((a) => a.toString());
+var y = [3];
+var z = x.toList();
+
+void main() {
+  String p = z;
+}
+''');
+    var result = await computeAnalysisResult(source);
+    var z = result.unit.declaredElement.topLevelVariables
+        .where((e) => e.name == 'z')
+        .single;
+    expect(z.type.toString(), 'List<String>');
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
+  test_issue_35320_lists() async {
+    addNamedSource('/lib.dart', '''
+const x = const <String>['a'];
+''');
+    Source source = addSource('''
+import 'lib.dart';
+const y = const <String>['b'];
+int f(v) {
+  switch(v) {
+    case x:
+      return 0;
+    case y:
+      return 1;
+    default:
+      return 2;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_issue_35320_maps() async {
+    addNamedSource('/lib.dart', '''
+const x = const <String, String>{'a': 'b'};
+''');
+    Source source = addSource('''
+import 'lib.dart';
+const y = const <String, String>{'c': 'd'};
+int f(v) {
+  switch(v) {
+    case x:
+      return 0;
+    case y:
+      return 1;
+    default:
+      return 2;
+  }
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_listElementTypeNotAssignable() async {
+    Source source = addSource(r'''
+var v1 = <int> [42];
+var v2 = const <int> [42];''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_loadLibraryDefined() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+foo() => 22;''',
+      r'''
+import 'lib1.dart' deferred as other;
+main() {
+  other.loadLibrary().then((_) => other.foo());
+}'''
+    ], <ErrorCode>[]);
+  }
+
+  test_local_generator_async() async {
+    Source source = addSource('''
+f() {
+  return () async* { yield 0; };
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_local_generator_sync() async {
+    Source source = addSource('''
+f() {
+  return () sync* { yield 0; };
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mapKeyTypeNotAssignable() async {
+    Source source = addSource("var v = <String, int > {'a' : 1};");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_metadata_enumConstantDeclaration() async {
+    Source source = addSource(r'''
+const x = 1;
+enum E {
+  aaa,
+  @x
+  bbb
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_methodDeclaration_scope_signature() async {
+    Source source = addSource(r'''
+const app = 0;
+class A {
+  foo(@app int app) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_misMatchedGetterAndSetterTypes_instance_sameTypes() async {
+    Source source = addSource(r'''
+class C {
+  int get x => 0;
+  set x(int v) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_misMatchedGetterAndSetterTypes_instance_unspecifiedGetter() async {
+    Source source = addSource(r'''
+class C {
+  get x => 0;
+  set x(String v) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_misMatchedGetterAndSetterTypes_instance_unspecifiedSetter() async {
+    Source source = addSource(r'''
+class C {
+  int get x => 0;
+  set x(v) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_misMatchedGetterAndSetterTypes_topLevel_sameTypes() async {
+    Source source = addSource(r'''
+int get x => 0;
+set x(int v) {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedGetter() async {
+    Source source = addSource(r'''
+get x => 0;
+set x(String v) {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedSetter() async {
+    Source source = addSource(r'''
+int get x => 0;
+set x(v) {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingEnumConstantInSwitch_all() async {
+    Source source = addSource(r'''
+enum E { A, B, C }
+
+f(E e) {
+  switch (e) {
+    case E.A: break;
+    case E.B: break;
+    case E.C: break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingEnumConstantInSwitch_default() async {
+    Source source = addSource(r'''
+enum E { A, B, C }
+
+f(E e) {
+  switch (e) {
+    case E.B: break;
+    default: break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixedReturnTypes_differentScopes() async {
+    Source source = addSource(r'''
+class C {
+  m(int x) {
+    f(int y) {
+      return;
+    }
+    f(x);
+    return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixedReturnTypes_ignoreImplicit() async {
+    Source source = addSource(r'''
+f(bool p) {
+  if (p) return 42;
+  // implicit 'return;' is ignored
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixedReturnTypes_ignoreImplicit2() async {
+    Source source = addSource(r'''
+f(bool p) {
+  if (p) {
+    return 42;
+  } else {
+    return 42;
+  }
+  // implicit 'return;' is ignored
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixedReturnTypes_sameKind() async {
+    Source source = addSource(r'''
+class C {
+  m(int x) {
+    if (x < 0) {
+      return 1;
+    }
+    return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixin_of_mixin_type_argument_inference() async {
+    // In the code below, B's superclass constraints don't include A, because
+    // superclass constraints are determined from the mixin's superclass, and
+    // B's superclass is Object.  So no mixin type inference is attempted, and
+    // "with B" is interpreted as "with B<dynamic>".
+    Source source = addSource('''
+class A<T> {}
+class B<T> = Object with A<T>;
+class C = Object with B;
+''');
+    var result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var bReference = result.unit.declaredElement.getType('C').mixins[0];
+    expect(bReference.typeArguments[0].toString(), 'dynamic');
+  }
+
+  test_mixin_of_mixin_type_argument_inference_cascaded_mixin() async {
+    // In the code below, B has a single superclass constraint, A1, because
+    // superclass constraints are determined from the mixin's superclass, and
+    // B's superclass is "Object with A1<T>".  So mixin type inference succeeds
+    // (since C's base class implements A1<int>), and "with B" is interpreted as
+    // "with B<int>".
+    Source source = addSource('''
+class A1<T> {}
+class A2<T> {}
+class B<T> = Object with A1<T>, A2<T>;
+class Base implements A1<int> {}
+class C = Base with B;
+''');
+    var result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var bReference = result.unit.declaredElement.getType('C').mixins[0];
+    expect(bReference.typeArguments[0].toString(), 'int');
+  }
+
+  test_mixinDeclaresConstructor() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+class B extends Object with A {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixinDeclaresConstructor_factory() async {
+    Source source = addSource(r'''
+class A {
+  factory A() => null;
+}
+class B extends Object with A {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixinInference_with_actual_mixins() async {
+    Source source = addSource('''
+class I<X> {}
+
+mixin M0<T> on I<T> {}
+
+mixin M1<T> on I<T> {
+  T foo() => null;
+}
+
+class A = I<int> with M0, M1;
+
+void main () {
+  var x = new A().foo();
+}
+''');
+    var result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var main = result.unit.declarations.last as FunctionDeclaration;
+    var mainBody = main.functionExpression.body as BlockFunctionBody;
+    var xDecl = mainBody.block.statements[0] as VariableDeclarationStatement;
+    var xElem = xDecl.variables.variables[0].declaredElement;
+    expect(xElem.type.toString(), 'int');
+  }
+
+  test_mixinInheritsFromNotObject_classDeclaration_extends_new_syntax() async {
+    Source source = addSource(r'''
+class A {}
+mixin B on A {}
+class C extends A with B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixinInheritsFromNotObject_classDeclaration_mixTypeAlias() async {
+    Source source = addSource(r'''
+class A {}
+class B = Object with A;
+class C extends Object with B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixinInheritsFromNotObject_typeAlias_extends_new_syntax() async {
+    Source source = addSource(r'''
+class A {}
+mixin B on A {}
+class C = A with B;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixinInheritsFromNotObject_typedef_mixTypeAlias() async {
+    Source source = addSource(r'''
+class A {}
+class B = Object with A;
+class C = Object with B;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_mixinReferencesSuper_new_syntax() async {
+    Source source = addSource(r'''
+mixin A {
+  toString() => super.toString();
+}
+class B extends Object with A {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_multipleSuperInitializers_no() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {
+  B() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_multipleSuperInitializers_single() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {
+  B() : super() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nativeConstConstructor() async {
+    Source source = addSource(r'''
+import 'dart-ext:x';
+class Foo {
+  const Foo() native 'Foo_Foo';
+  const factory Foo.foo() native 'Foo_Foo_foo';
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY]);
+    // Cannot verify the AST because the import's URI cannot be resolved.
+  }
+
+  test_nativeFunctionBodyInNonSDKCode_function() async {
+    Source source = addSource(r'''
+import 'dart-ext:x';
+int m(a) native 'string';''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    // Cannot verify the AST because the import's URI cannot be resolved.
+  }
+
+  test_newWithAbstractClass_factory() async {
+    Source source = addSource(r'''
+abstract class A {
+  factory A() { return new B(); }
+}
+class B implements A {
+  B() {}
+}
+A f() {
+  return new A();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_newWithUndefinedConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A.name() {}
+}
+f() {
+  new A.name();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_newWithUndefinedConstructorDefault() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+f() {
+  new A();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_getter() async {
+    Source source = addSource(r'''
+class A {
+  int get g => 0;
+}
+abstract class B extends A {
+  int get g;
+}
+class C extends B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_method() async {
+    Source source = addSource(r'''
+class A {
+  m(p) {}
+}
+abstract class B extends A {
+  m(p);
+}
+class C extends B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter() async {
+    Source source = addSource(r'''
+class A {
+  set s(v) {}
+}
+abstract class B extends A {
+  set s(v);
+}
+class C extends B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() async {
+    // 15979
+    Source source = addSource(r'''
+abstract class M {}
+abstract class A {}
+abstract class I {
+  m();
+}
+abstract class B = A with M implements I;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin() async {
+    // 15979
+    Source source = addSource(r'''
+abstract class M {
+  m();
+}
+abstract class A {}
+abstract class B = A with M;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() async {
+    // 15979
+    Source source = addSource(r'''
+class M {}
+abstract class A {
+  m();
+}
+abstract class B = A with M;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter() async {
+    // 17034
+    Source source = addSource(r'''
+class A {
+  var a;
+}
+abstract class M {
+  get a;
+}
+class B extends A with M {}
+class C extends B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_mixin_method() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+abstract class M {
+  m();
+}
+class B extends A with M {}
+class C extends B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter() async {
+    Source source = addSource(r'''
+class A {
+  var a;
+}
+abstract class M {
+  set a(dynamic v);
+}
+class B extends A with M {}
+class C extends B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor() async {
+    Source source = addSource(r'''
+abstract class A {
+  int get g;
+}
+class B extends A {
+  noSuchMethod(v) => '';
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_method() async {
+    Source source = addSource(r'''
+abstract class A {
+  m(p);
+}
+class B extends A {
+  noSuchMethod(v) => '';
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_mixin() async {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(v) => '';
+}
+class B extends Object with A {
+  m(p);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_superclass() async {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(v) => '';
+}
+class B extends A {
+  m(p);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() async {
+    Source source = addSource(r'''
+class A {
+  String toString([String prefix = '']) => '${prefix}Hello';
+}
+class C {}
+class B extends A with C {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolExpression_interfaceType() async {
+    Source source = addSource(r'''
+f() {
+  assert(true);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolNegationExpression() async {
+    Source source = addSource(r'''
+f(bool pb, pd) {
+  !true;
+  !false;
+  !pb;
+  !pd;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolNegationExpression_dynamic() async {
+    Source source = addSource(r'''
+f1(bool dynamic) {
+  !dynamic;
+}
+f2() {
+  bool dynamic = true;
+  !dynamic;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolOperand_and_bool() async {
+    Source source = addSource(r'''
+bool f(bool left, bool right) {
+  return left && right;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolOperand_and_dynamic() async {
+    Source source = addSource(r'''
+bool f(left, dynamic right) {
+  return left && right;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolOperand_or_bool() async {
+    Source source = addSource(r'''
+bool f(bool left, bool right) {
+  return left || right;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonBoolOperand_or_dynamic() async {
+    Source source = addSource(r'''
+bool f(dynamic left, right) {
+  return left || right;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_constField() async {
+    Source source = addSource(r'''
+f([a = double.INFINITY]) {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_function_named() async {
+    Source source = addSource("f({x : 2 + 3}) {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_function_positional() async {
+    Source source = addSource("f([x = 2 + 3]) {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_inConstructor_named() async {
+    Source source = addSource(r'''
+class A {
+  A({x : 2 + 3}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_inConstructor_positional() async {
+    Source source = addSource(r'''
+class A {
+  A([x = 2 + 3]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_method_named() async {
+    Source source = addSource(r'''
+class A {
+  m({x : 2 + 3}) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_method_positional() async {
+    Source source = addSource(r'''
+class A {
+  m([x = 2 + 3]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantDefaultValue_typedConstList() async {
+    Source source = addSource(r'''
+class A {
+  m([p111 = const <String>[]]) {}
+}
+class B extends A {
+  m([p222 = const <String>[]]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstantValueInInitializer_namedArgument() async {
+    Source source = addSource(r'''
+class A {
+  final a;
+  const A({this.a});
+}
+class B extends A {
+  const B({b}) : super(a: b);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstCaseExpression_constField() async {
+    Source source = addSource(r'''
+f(double p) {
+  switch (p) {
+    case double.INFINITY:
+      return true;
+    default:
+      return false;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_nonConstCaseExpression_typeLiteral() async {
+    Source source = addSource(r'''
+f(Type t) {
+  switch (t) {
+    case bool:
+    case int:
+      return true;
+    default:
+      return false;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstListElement_constField() async {
+    Source source = addSource(r'''
+main() {
+  const [double.INFINITY];
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstMapAsExpressionStatement_const() async {
+    Source source = addSource(r'''
+f() {
+  const {'a' : 0, 'b' : 1};
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstMapAsExpressionStatement_notExpressionStatement() async {
+    Source source = addSource(r'''
+f() {
+  var m = {'a' : 0, 'b' : 1};
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstMapAsExpressionStatement_typeArguments() async {
+    Source source = addSource(r'''
+f() {
+  <String, int> {'a' : 0, 'b' : 1};
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstMapKey_constField() async {
+    Source source = addSource(r'''
+main() {
+  const {double.INFINITY: 0};
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_nonConstMapValue_constField() async {
+    Source source = addSource(r'''
+main() {
+  const {0: double.INFINITY};
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_bool() async {
+    Source source = addSource(r'''
+class A {
+  final v;
+  const A.a1(bool p) : v = p && true;
+  const A.a2(bool p) : v = true && p;
+  const A.b1(bool p) : v = p || true;
+  const A.b2(bool p) : v = true || p;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [HintCode.DEAD_CODE]);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_dynamic() async {
+    Source source = addSource(r'''
+class A {
+  final v;
+  const A.a1(p) : v = p + 5;
+  const A.a2(p) : v = 5 + p;
+  const A.b1(p) : v = p - 5;
+  const A.b2(p) : v = 5 - p;
+  const A.c1(p) : v = p * 5;
+  const A.c2(p) : v = 5 * p;
+  const A.d1(p) : v = p / 5;
+  const A.d2(p) : v = 5 / p;
+  const A.e1(p) : v = p ~/ 5;
+  const A.e2(p) : v = 5 ~/ p;
+  const A.f1(p) : v = p > 5;
+  const A.f2(p) : v = 5 > p;
+  const A.g1(p) : v = p < 5;
+  const A.g2(p) : v = 5 < p;
+  const A.h1(p) : v = p >= 5;
+  const A.h2(p) : v = 5 >= p;
+  const A.i1(p) : v = p <= 5;
+  const A.i2(p) : v = 5 <= p;
+  const A.j1(p) : v = p % 5;
+  const A.j2(p) : v = 5 % p;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    // operations on "p" are not resolved
+  }
+
+  test_nonConstValueInInitializer_binary_int() async {
+    Source source = addSource(r'''
+class A {
+  final v;
+  const A.a1(int p) : v = p ^ 5;
+  const A.a2(int p) : v = 5 ^ p;
+  const A.b1(int p) : v = p & 5;
+  const A.b2(int p) : v = 5 & p;
+  const A.c1(int p) : v = p | 5;
+  const A.c2(int p) : v = 5 | p;
+  const A.d1(int p) : v = p >> 5;
+  const A.d2(int p) : v = 5 >> p;
+  const A.e1(int p) : v = p << 5;
+  const A.e2(int p) : v = 5 << p;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_binary_num() async {
+    Source source = addSource(r'''
+class A {
+  final v;
+  const A.a1(num p) : v = p + 5;
+  const A.a2(num p) : v = 5 + p;
+  const A.b1(num p) : v = p - 5;
+  const A.b2(num p) : v = 5 - p;
+  const A.c1(num p) : v = p * 5;
+  const A.c2(num p) : v = 5 * p;
+  const A.d1(num p) : v = p / 5;
+  const A.d2(num p) : v = 5 / p;
+  const A.e1(num p) : v = p ~/ 5;
+  const A.e2(num p) : v = 5 ~/ p;
+  const A.f1(num p) : v = p > 5;
+  const A.f2(num p) : v = 5 > p;
+  const A.g1(num p) : v = p < 5;
+  const A.g2(num p) : v = 5 < p;
+  const A.h1(num p) : v = p >= 5;
+  const A.h2(num p) : v = 5 >= p;
+  const A.i1(num p) : v = p <= 5;
+  const A.i2(num p) : v = 5 <= p;
+  const A.j1(num p) : v = p % 5;
+  const A.j2(num p) : v = 5 % p;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_field() async {
+    Source source = addSource(r'''
+class A {
+  final int a;
+  const A() : a = 5;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_redirecting() async {
+    Source source = addSource(r'''
+class A {
+  const A.named(p);
+  const A() : this.named(42);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_super() async {
+    Source source = addSource(r'''
+class A {
+  const A(p);
+}
+class B extends A {
+  const B() : super(42);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstValueInInitializer_unary() async {
+    Source source = addSource(r'''
+class A {
+  final v;
+  const A.a(bool p) : v = !p;
+  const A.b(int p) : v = ~p;
+  const A.c(num p) : v = -p;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonGenerativeConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A.named() {}
+  factory A() => null;
+}
+class B extends A {
+  B() : super.named();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonTypeInCatchClause_isClass() async {
+    Source source = addSource(r'''
+f() {
+  try {
+  } on String catch (e) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonTypeInCatchClause_isFunctionTypeAlias() async {
+    Source source = addSource(r'''
+typedef F();
+f() {
+  try {
+  } on F catch (e) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonTypeInCatchClause_isTypeParameter() async {
+    Source source = addSource(r'''
+class A<T> {
+  f() {
+    try {
+    } on T catch (e) {
+    }
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonTypeInCatchClause_noType() async {
+    Source source = addSource(r'''
+f() {
+  try {
+  } catch (e) {
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonVoidReturnForOperator_no() async {
+    Source source = addSource(r'''
+class A {
+  operator []=(a, b) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonVoidReturnForOperator_void() async {
+    Source source = addSource(r'''
+class A {
+  void operator []=(a, b) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonVoidReturnForSetter_function_no() async {
+    Source source = addSource("set x(v) {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonVoidReturnForSetter_function_void() async {
+    Source source = addSource("void set x(v) {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonVoidReturnForSetter_method_no() async {
+    Source source = addSource(r'''
+class A {
+  set x(v) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonVoidReturnForSetter_method_void() async {
+    Source source = addSource(r'''
+class A {
+  void set x(v) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_null_callOperator() async {
+    Source source = addSource(r'''
+main() {
+  null + 5;
+  null == 5;
+  null[0];
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      StaticTypeWarningCode.UNDEFINED_METHOD,
+      StaticTypeWarningCode.UNDEFINED_METHOD
+    ]);
+  }
+
+  test_optionalNew_rewrite() async {
+    resetWith(options: new AnalysisOptionsImpl());
+    Source source = addSource(r'''
+import 'b.dart';
+main() {
+  const B.named1();
+  const B.named2();
+  const B.named3();
+  const B.named4();
+}
+''');
+    addNamedSource("/a.dart", r'''
+class A {
+  const A();
+  const A.named();
+}
+''');
+    addNamedSource("/b.dart", r'''
+import 'a.dart';
+import 'a.dart' as p;
+
+const _a1 = A();
+const _a2 = A.named();
+const _a3 = p.A();
+const _a4 = p.A.named();
+
+class B {
+  const B.named1({this.a: _a1}) : assert(a != null);
+  const B.named2({this.a: _a2}) : assert(a != null);
+  const B.named3({this.a: _a3}) : assert(a != null);
+  const B.named4({this.a: _a4}) : assert(a != null);
+
+  final A a;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_optionalNew_rewrite_instantiatesToBounds() async {
+    resetWith(options: new AnalysisOptionsImpl());
+    Source source = addSource(r'''
+import 'b.dart';
+
+@B.named1()
+@B.named2()
+@B.named3()
+@B.named4()
+@B.named5()
+@B.named6()
+@B.named7()
+@B.named8()
+main() {}
+''');
+    addNamedSource("/a.dart", r'''
+class Unbounded<T> {
+  const Unbounded();
+  const Unbounded.named();
+}
+class Bounded<T extends String> {
+  const Bounded();
+  const Bounded.named();
+}
+''');
+    addNamedSource("/b.dart", r'''
+import 'a.dart';
+import 'a.dart' as p;
+
+const unbounded1 = Unbounded();
+const unbounded2 = Unbounded.named();
+const unbounded3 = p.Unbounded();
+const unbounded4 = p.Unbounded.named();
+const bounded1 = Bounded();
+const bounded2 = Bounded.named();
+const bounded3 = p.Bounded();
+const bounded4 = p.Bounded.named();
+
+class B {
+  const B.named1({this.unbounded: unbounded1}) : bounded = null;
+  const B.named2({this.unbounded: unbounded2}) : bounded = null;
+  const B.named3({this.unbounded: unbounded3}) : bounded = null;
+  const B.named4({this.unbounded: unbounded4}) : bounded = null;
+  const B.named5({this.bounded: bounded1}) : unbounded = null;
+  const B.named6({this.bounded: bounded2}) : unbounded = null;
+  const B.named7({this.bounded: bounded3}) : unbounded = null;
+  const B.named8({this.bounded: bounded4}) : unbounded = null;
+
+  final Unbounded unbounded;
+  final Bounded bounded;
+}
+''');
+    final result = await computeAnalysisResult(source);
+    expect(result.unit.declarations, hasLength(1));
+    final mainDecl = result.unit.declarations[0];
+    expect(mainDecl.metadata, hasLength(8));
+    mainDecl.metadata.forEach((metadata) {
+      final value = metadata.elementAnnotation.computeConstantValue();
+      expect(value, isNotNull);
+      expect(value.type.toString(), 'B');
+      final unbounded = value.getField('unbounded');
+      final bounded = value.getField('bounded');
+      if (!unbounded.isNull) {
+        expect(bounded.isNull, true);
+        expect(unbounded.type.name, 'Unbounded');
+        expect(unbounded.type.typeArguments, hasLength(1));
+        expect(unbounded.type.typeArguments[0].isDynamic, isTrue);
+      } else {
+        expect(unbounded.isNull, true);
+        expect(bounded.type.name, 'Bounded');
+        expect(bounded.type.typeArguments, hasLength(1));
+        expect(bounded.type.typeArguments[0].name, 'String');
+      }
+    });
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_optionalParameterInOperator_required() async {
+    Source source = addSource(r'''
+class A {
+  operator +(p) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_parameterScope_local() async {
+    // Parameter names shouldn't conflict with the name of the function they
+    // are enclosed in.
+    Source source = addSource(r'''
+f() {
+  g(g) {
+    h(g);
+  }
+}
+h(x) {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_parameterScope_method() async {
+    // Parameter names shouldn't conflict with the name of the function they
+    // are enclosed in.
+    Source source = addSource(r'''
+class C {
+  g(g) {
+    h(g);
+  }
+}
+h(x) {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_parameterScope_topLevel() async {
+    // Parameter names shouldn't conflict with the name of the function they
+    // are enclosed in.
+    Source source = addSource(r'''
+g(g) {
+  h(g);
+}
+h(x) {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_parametricCallFunction() async {
+    Source source = addSource(r'''
+f() {
+  var c = new C();
+  c<String>().codeUnits;
+}
+
+class C {
+  T call<T>() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_prefixCollidesWithTopLevelMembers() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class A {}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+typedef P();
+p2() {}
+var p3;
+class p4 {}
+p.A a;''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_propagateTypeArgs_intoBounds() async {
+    Source source = addSource(r'''
+abstract class A<E> {}
+abstract class B<F> implements A<F>{}
+abstract class C<G, H extends A<G>> {}
+class D<I> extends C<I, B<I>> {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_propagateTypeArgs_intoSupertype() async {
+    Source source = addSource(r'''
+class A<T> {
+  A(T p);
+  A.named(T p);
+}
+class B<S> extends A<S> {
+  B(S p) : super(p);
+  B.named(S p) : super.named(p);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_recursiveConstructorRedirect() async {
+    Source source = addSource(r'''
+class A {
+  A.a() : this.b();
+  A.b() : this.c();
+  A.c() {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_recursiveFactoryRedirect() async {
+    Source source = addSource(r'''
+class A {
+  factory A() = B;
+}
+class B implements A {
+  factory B() = C;
+}
+class C implements B {
+  factory C() => null;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_redirectToInvalidFunctionType() async {
+    Source source = addSource(r'''
+class A implements B {
+  A(int p) {}
+}
+class B {
+  factory B(int p) = A;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_redirectToNonConstConstructor() async {
+    Source source = addSource(r'''
+class A {
+  const A.a();
+  const factory A.b() = A.a;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_referencedBeforeDeclaration_cascade() async {
+    Source source = addSource(r'''
+testRequestHandler() {}
+
+main() {
+  var s1 = null;
+  testRequestHandler()
+    ..stream(s1);
+  var stream = 123;
+  print(stream);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_referenceToDeclaredVariableInInitializer_constructorName() async {
+    Source source = addSource(r'''
+class A {
+  A.x() {}
+}
+f() {
+  var x = new A.x();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_referenceToDeclaredVariableInInitializer_methodName() async {
+    Source source = addSource(r'''
+class A {
+  x() {}
+}
+f(A a) {
+  var x = a.x();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_referenceToDeclaredVariableInInitializer_propertyName() async {
+    Source source = addSource(r'''
+class A {
+  var x;
+}
+f(A a) {
+  var x = a.x;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_regress34906() async {
+    Source source = addSource(r'''
+typedef G<X, Y extends Function(X)> = X Function(Function(Y));
+G<dynamic, Function(Null)> superBoundedG;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_rethrowOutsideCatch() async {
+    Source source = addSource(r'''
+class A {
+  void m() {
+    try {} catch (e) {rethrow;}
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_return_in_generator_async() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream<int> f() async* {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_return_in_generator_sync() async {
+    Source source = addSource('''
+Iterable<int> f() sync* {
+  return;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnInGenerativeConstructor() async {
+    Source source = addSource(r'''
+class A {
+  A() { return; }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnInGenerator_async() async {
+    Source source = addSource(r'''
+f() async {
+  return 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnInGenerator_sync() async {
+    Source source = addSource(r'''
+f() {
+  return 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnOfInvalidType_async() async {
+    Source source = addSource(r'''
+import 'dart:async';
+class A {
+  Future<int> m() async {
+    return 0;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnOfInvalidType_dynamic() async {
+    Source source = addSource(r'''
+class TypeError {}
+class A {
+  static void testLogicalOp() {
+    testOr(a, b, onTypeError) {
+      try {
+        return a || b;
+      } on TypeError catch (t) {
+        return onTypeError;
+      }
+    }
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnOfInvalidType_subtype() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+A f(B b) { return b; }''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnOfInvalidType_supertype() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+B f(A a) { return a; }''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnOfInvalidType_typeParameter_18468() async {
+    // https://code.google.com/p/dart/issues/detail?id=18468
+    //
+    // This test verifies that the type of T is more specific than Type,
+    // where T is a type parameter and Type is the type Type from
+    // core, this particular test case comes from issue 18468.
+    //
+    // A test cannot be added to TypeParameterTypeImplTest since the types
+    // returned out of the TestTypeProvider don't have a mock 'dart.core'
+    // enclosing library element.
+    // See TypeParameterTypeImpl.isMoreSpecificThan().
+    Source source = addSource(r'''
+class Foo<T> {
+  Type get t => T;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source);
+    verify([source]);
+  }
+
+  test_returnOfInvalidType_void() async {
+    Source source = addSource(r'''
+void f1() {}
+void f2() { return; }
+void f3() { return null; }
+void f4() { return g1(); }
+void f5() { return g2(); }
+void f6() => throw 42;
+g1() {}
+void g2() {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnWithoutValue_noReturnType() async {
+    Source source = addSource("f() { return; }");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_returnWithoutValue_void() async {
+    Source source = addSource("void f() { return; }");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_reversedTypeArguments() async {
+    Source source = addSource(r'''
+class Codec<S1, T1> {
+  Codec<T1, S1> get inverted => new _InvertedCodec<T1, S1>(this);
+}
+class _InvertedCodec<T2, S2> extends Codec<T2, S2> {
+  _InvertedCodec(Codec<S2, T2> codec);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_sharedDeferredPrefix() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+f1() {}''',
+      r'''
+library lib2;
+f2() {}''',
+      r'''
+library lib3;
+f3() {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as lib1;
+import 'lib2.dart' as lib;
+import 'lib3.dart' as lib;
+main() { lib1.f1(); lib.f2(); lib.f3(); }'''
+    ], <ErrorCode>[]);
+  }
+
+  test_staticAccessToInstanceMember_annotation() async {
+    Source source = addSource(r'''
+class A {
+  const A.name();
+}
+@A.name()
+main() {
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_staticAccessToInstanceMember_method() async {
+    Source source = addSource(r'''
+class A {
+  static m() {}
+}
+main() {
+  A.m;
+  A.m();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_staticAccessToInstanceMember_propertyAccess_field() async {
+    Source source = addSource(r'''
+class A {
+  static var f;
+}
+main() {
+  A.f;
+  A.f = 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_staticAccessToInstanceMember_propertyAccess_propertyAccessor() async {
+    Source source = addSource(r'''
+class A {
+  static get f => 42;
+  static set f(x) {}
+}
+main() {
+  A.f;
+  A.f = 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_superInInvalidContext() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+class B extends A {
+  B() {
+    var v = super.m();
+  }
+  n() {
+    var v = super.m();
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeAliasCannotReferenceItself_returnClass_withTypeAlias() async {
+    Source source = addSource(r'''
+typedef B A();
+class B {
+  A a;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeArgument_boundToFunctionType() async {
+    Source source = addSource("class A<T extends void Function(T)>{}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeArgumentNotMatchingBounds_const() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class G<E extends A> {
+  const G();
+}
+f() { return const G<B>(); }''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeArgumentNotMatchingBounds_new() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class G<E extends A> {}
+f() { return new G<B>(); }''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+typedef F<T extends A>();
+F<A> fa;
+F<B> fb;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound2() async {
+    Source source = addSource(r'''
+class MyClass<T> {}
+typedef MyFunction<T, P extends MyClass<T>>();
+class A<T, P extends MyClass<T>> {
+  MyFunction<T, P> f;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_noBound() async {
+    Source source = addSource(r'''
+typedef F<T>();
+F<int> f1;
+F<String> f2;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_booleanAnd_useInRight() async {
+    Source source = addSource(r'''
+main(Object p) {
+  p is String && p.length != 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() async {
+    Source source = addSource(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  (p is String) && callMe(() { p.length; });
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_conditional_issue14655() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C extends B {
+  mc() {}
+}
+print(_) {}
+main(A p) {
+  (p is C) && (print(() => p) && (p is B)) ? p.mc() : p = null;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_conditional_useInThen() async {
+    Source source = addSource(r'''
+main(Object p) {
+  p is String ? p.length : 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() async {
+    Source source = addSource(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  p is String ? callMe(() { p.length; }) : 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_functionType_arg_ignoreIfNotMoreSpecific() async {
+    Source source = addSource(r'''
+typedef FuncB(B b);
+typedef FuncA(A a);
+class A {}
+class B {}
+main(FuncA f) {
+  if (f is FuncB) {
+    f(new A());
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_functionType_return_ignoreIfNotMoreSpecific() async {
+    Source source = addSource(r'''
+class A {}
+typedef FuncAtoDyn(A a);
+typedef FuncDynToDyn(x);
+main(FuncAtoDyn f) {
+  if (f is FuncDynToDyn) {
+    A a = f(new A());
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_functionType_return_voidToDynamic() async {
+    Source source = addSource(r'''
+typedef FuncDynToDyn(x);
+typedef void FuncDynToVoid(x);
+class A {}
+main(FuncDynToVoid f) {
+  if (f is FuncDynToDyn) {
+    A a = f(null);
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_accessedInClosure_noAssignment() async {
+    Source source = addSource(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  if (p is String) {
+    callMe(() {
+      p.length;
+    });
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_extends_moreSpecific() async {
+    Source source = addSource(r'''
+class V {}
+class VP extends V {}
+class A<T> {}
+class B<S> extends A<S> {
+  var b;
+}
+
+main(A<V> p) {
+  if (p is B<VP>) {
+    p.b;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_hasAssignment_outsideAfter() async {
+    Source source = addSource(r'''
+main(Object p) {
+  if (p is String) {
+    p.length;
+  }
+  p = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_hasAssignment_outsideBefore() async {
+    Source source = addSource(r'''
+main(Object p, Object p2) {
+  p = p2;
+  if (p is String) {
+    p.length;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_implements_moreSpecific() async {
+    Source source = addSource(r'''
+class V {}
+class VP extends V {}
+class A<T> {}
+class B<S> implements A<S> {
+  var b;
+}
+
+main(A<V> p) {
+  if (p is B<VP>) {
+    p.b;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_inClosure_assignedAfter_inSameFunction() async {
+    Source source = addSource(r'''
+main() {
+  f(Object p) {
+    if (p is String) {
+      p.length;
+    }
+    p = 0;
+  };
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_is_and_left() async {
+    Source source = addSource(r'''
+bool tt() => true;
+main(Object p) {
+  if (p is String && tt()) {
+    p.length;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_is_and_right() async {
+    Source source = addSource(r'''
+bool tt() => true;
+main(Object p) {
+  if (tt() && p is String) {
+    p.length;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_is_and_subThenSuper() async {
+    Source source = addSource(r'''
+class A {
+  var a;
+}
+class B extends A {
+  var b;
+}
+main(Object p) {
+  if (p is B && p is A) {
+    p.a;
+    p.b;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_is_parenthesized() async {
+    Source source = addSource(r'''
+main(Object p) {
+  if ((p is String)) {
+    p.length;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_if_is_single() async {
+    Source source = addSource(r'''
+main(Object p) {
+  if (p is String) {
+    p.length;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typePromotion_parentheses() async {
+    Source source = addSource(r'''
+main(Object p) {
+  (p is String) ? p.length : 0;
+  (p) is String ? p.length : 0;
+  ((p)) is String ? p.length : 0;
+  ((p) is String) ? p.length : 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeType_class() async {
+    Source source = addSource(r'''
+class C {}
+f(Type t) {}
+main() {
+  f(C);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeType_class_prefixed() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+class C {}''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+f(Type t) {}
+main() {
+  f(p.C);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeType_functionTypeAlias() async {
+    Source source = addSource(r'''
+typedef F();
+f(Type t) {}
+main() {
+  f(F);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_typeType_functionTypeAlias_prefixed() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+typedef F();''');
+    Source source = addSource(r'''
+import 'lib.dart' as p;
+f(Type t) {}
+main() {
+  f(p.F);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_explicit_named() async {
+    Source source = addSource(r'''
+class A {
+  A.named() {}
+}
+class B extends A {
+  B() : super.named();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_explicit_unnamed() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+class B extends A {
+  B() : super();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_hasOptionalParameters() async {
+    Source source = addSource(r'''
+class A {
+  A([p]) {}
+}
+class B extends A {
+  B();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_implicit() async {
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+class B extends A {
+  B();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedConstructorInInitializer_redirecting() async {
+    Source source = addSource(r'''
+class Foo {
+  Foo.ctor();
+}
+class Bar extends Foo {
+  Bar() : this.ctor();
+  Bar.ctor() : super.ctor();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedGetter_static_conditionalAccess() async {
+    // The conditional access operator '?.' can be used to access static
+    // fields.
+    Source source = addSource('''
+class A {
+  static var x;
+}
+var a = A?.x;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedGetter_typeSubstitution() async {
+    Source source = addSource(r'''
+class A<E> {
+  E element;
+}
+class B extends A<List> {
+  m() {
+    element.last;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedIdentifier_synthetic_whenExpression() async {
+    Source source = addSource(r'''
+print(x) {}
+main() {
+  print(is String);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [ParserErrorCode.MISSING_IDENTIFIER]);
+  }
+
+  test_undefinedIdentifier_synthetic_whenMethodName() async {
+    Source source = addSource(r'''
+print(x) {}
+main(int p) {
+  p.();
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.MISSING_IDENTIFIER,
+      StaticTypeWarningCode.UNDEFINED_GETTER
+    ]);
+  }
+
+  test_undefinedMethod_functionExpression_callMethod() async {
+    Source source = addSource(r'''
+main() {
+  (() => null).call();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    // A call to verify(source) fails as '.call()' isn't resolved.
+  }
+
+  test_undefinedMethod_functionExpression_directCall() async {
+    Source source = addSource(r'''
+main() {
+  (() => null)();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    // A call to verify(source) fails as '(() => null)()' isn't resolved.
+  }
+
+  test_undefinedMethod_static_conditionalAccess() async {
+    // The conditional access operator '?.' can be used to access static
+    // methods.
+    Source source = addSource('''
+class A {
+  static void m() {}
+}
+f() { A?.m(); }
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedOperator_index() async {
+    Source source = addSource(r'''
+class A {
+  operator [](a) {}
+  operator []=(a, b) {}
+}
+f(A a) {
+  a[0];
+  a[0] = 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedOperator_tilde() async {
+    Source source = addSource(r'''
+const A = 3;
+const B = ~((1 << A) - 1);''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedSetter_importWithPrefix() async {
+    addNamedSource("/lib.dart", r'''
+library lib;
+set y(int value) {}''');
+    Source source = addSource(r'''
+import 'lib.dart' as x;
+main() {
+  x.y = 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedSetter_static_conditionalAccess() async {
+    // The conditional access operator '?.' can be used to access static
+    // fields.
+    Source source = addSource('''
+class A {
+  static var x;
+}
+f() { A?.x = 1; }
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedSuperMethod_field() async {
+    Source source = addSource(r'''
+class A {
+  var m;
+}
+class B extends A {
+  f() {
+    super.m();
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_undefinedSuperMethod_method() async {
+    Source source = addSource(r'''
+class A {
+  m() {}
+}
+class B extends A {
+  f() {
+    super.m();
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_unusedShownName_unresolved() async {
+    Source source = addSource(r'''
+import 'dart:math' show max, FooBar;
+main() {
+  print(max(1, 2));
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [HintCode.UNDEFINED_SHOWN_NAME]);
+  }
+
+  test_uriDoesNotExist_dll() async {
+    addNamedSource("/lib.dll", "");
+    Source source = addSource("import 'dart-ext:lib';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_uriDoesNotExist_dylib() async {
+    addNamedSource("/lib.dylib", "");
+    Source source = addSource("import 'dart-ext:lib';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_uriDoesNotExist_so() async {
+    addNamedSource("/lib.so", "");
+    Source source = addSource("import 'dart-ext:lib';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  Future test_useDynamicWithPrefix() async {
+    final Source source = addSource('''
+import 'dart:core' as core;
+
+core.dynamic dynamicVariable;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForOperator1() async {
+    await _check_wrongNumberOfParametersForOperator1("<");
+    await _check_wrongNumberOfParametersForOperator1(">");
+    await _check_wrongNumberOfParametersForOperator1("<=");
+    await _check_wrongNumberOfParametersForOperator1(">=");
+    await _check_wrongNumberOfParametersForOperator1("+");
+    await _check_wrongNumberOfParametersForOperator1("/");
+    await _check_wrongNumberOfParametersForOperator1("~/");
+    await _check_wrongNumberOfParametersForOperator1("*");
+    await _check_wrongNumberOfParametersForOperator1("%");
+    await _check_wrongNumberOfParametersForOperator1("|");
+    await _check_wrongNumberOfParametersForOperator1("^");
+    await _check_wrongNumberOfParametersForOperator1("&");
+    await _check_wrongNumberOfParametersForOperator1("<<");
+    await _check_wrongNumberOfParametersForOperator1(">>");
+    await _check_wrongNumberOfParametersForOperator1("[]");
+  }
+
+  test_wrongNumberOfParametersForOperator_index() async {
+    Source source = addSource(r'''
+class A {
+  operator []=(a, b) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_wrongNumberOfParametersForOperator_minus() async {
+    await _check_wrongNumberOfParametersForOperator("-", "");
+    await _check_wrongNumberOfParametersForOperator("-", "a");
+  }
+
+  test_wrongNumberOfParametersForSetter() async {
+    Source source = addSource(r'''
+class A {
+  set x(a) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_async_to_dynamic_type() async {
+    Source source = addSource('''
+dynamic f() async* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_async_to_generic_type() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream f() async* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_async_to_parameterized_type() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream<int> f() async* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_async_to_untyped() async {
+    Source source = addSource('''
+f() async* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_async_dynamic_to_dynamic() async {
+    Source source = addSource('''
+f() async* {
+  yield* g();
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_async_dynamic_to_stream() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream f() async* {
+  yield* g();
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_async_dynamic_to_typed_stream() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream<int> f() async* {
+  yield* g();
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_async_stream_to_dynamic() async {
+    Source source = addSource('''
+import 'dart:async';
+f() async* {
+  yield* g();
+}
+Stream g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_async_typed_stream_to_dynamic() async {
+    Source source = addSource('''
+import 'dart:async';
+f() async* {
+  yield* g();
+}
+Stream<int> g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_async_typed_stream_to_typed_stream() async {
+    Source source = addSource('''
+import 'dart:async';
+Stream<int> f() async* {
+  yield* g();
+}
+Stream<int> g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_sync_dynamic_to_dynamic() async {
+    Source source = addSource('''
+f() sync* {
+  yield* g();
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_sync_dynamic_to_iterable() async {
+    Source source = addSource('''
+Iterable f() sync* {
+  yield* g();
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_sync_dynamic_to_typed_iterable() async {
+    Source source = addSource('''
+Iterable<int> f() sync* {
+  yield* g();
+}
+g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_sync_iterable_to_dynamic() async {
+    Source source = addSource('''
+f() sync* {
+  yield* g();
+}
+Iterable g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_sync_typed_iterable_to_dynamic() async {
+    Source source = addSource('''
+f() sync* {
+  yield* g();
+}
+Iterable<int> g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_each_sync_typed_iterable_to_typed_iterable() async {
+    Source source = addSource('''
+Iterable<int> f() sync* {
+  yield* g();
+}
+Iterable<int> g() => null;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_sync_to_dynamic_type() async {
+    Source source = addSource('''
+dynamic f() sync* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_sync_to_generic_type() async {
+    Source source = addSource('''
+Iterable f() sync* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_sync_to_parameterized_type() async {
+    Source source = addSource('''
+Iterable<int> f() sync* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yield_sync_to_untyped() async {
+    Source source = addSource('''
+f() sync* {
+  yield 3;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yieldInNonGenerator_asyncStar() async {
+    Source source = addSource(r'''
+f() async* {
+  yield 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_yieldInNonGenerator_syncStar() async {
+    Source source = addSource(r'''
+f() sync* {
+  yield 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  Future<void> _check_wrongNumberOfParametersForOperator(
+      String name, String parameters) async {
+    Source source = addSource("""
+class A {
+  operator $name($parameters) {}
+}""");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  Future<void> _check_wrongNumberOfParametersForOperator1(String name) async {
+    await _check_wrongNumberOfParametersForOperator(name, "a");
+  }
+}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
index 300cae8..0e14cfb 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
@@ -6,7 +6,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'non_error_resolver_test.dart';
+import 'non_error_resolver.dart';
 import 'resolver_test_case.dart';
 
 main() {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
deleted file mode 100644
index 12a26e8..0000000
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ /dev/null
@@ -1,6147 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(NonErrorResolverTest);
-  });
-}
-
-@reflectiveTest
-class NonErrorResolverTest extends NonErrorResolverTestBase {
-  @override
-  @failingTest // Does not work with old task model
-  test_infer_mixin_new_syntax() {
-    return super.test_infer_mixin_new_syntax();
-  }
-
-  @override
-  @failingTest
-  test_infer_mixin_with_substitution_functionType_new_syntax() {
-    return super.test_infer_mixin_with_substitution_functionType_new_syntax();
-  }
-
-  @override
-  @failingTest // Does not work with old task model
-  test_infer_mixin_with_substitution_new_syntax() {
-    return super.test_infer_mixin_with_substitution_new_syntax();
-  }
-
-  @override
-  @failingTest // Fails with the old task model
-  test_issue_32394() {
-    return super.test_issue_32394();
-  }
-
-  @override
-  @failingTest // Does not work with old task model
-  test_mixin_of_mixin_type_argument_inference_cascaded_mixin() {
-    return super.test_mixin_of_mixin_type_argument_inference_cascaded_mixin();
-  }
-
-  @override
-  @failingTest // Does not work with old task model
-  test_mixinInference_with_actual_mixins() {
-    return super.test_mixinInference_with_actual_mixins();
-  }
-
-  @override
-  @failingTest
-  test_null_callOperator() {
-    return super.test_null_callOperator();
-  }
-}
-
-class NonErrorResolverTestBase extends ResolverTestCase {
-  @override
-  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
-
-  fail_undefinedEnumConstant() async {
-    Source source = addSource(r'''
-enum E { ONE }
-E e() {
-  return E.TWO;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_ambiguousExport() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';
-export 'lib2.dart';''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class M {}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-class N {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_ambiguousExport_combinators_hide() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';
-export 'lib2.dart' hide B;''');
-    addNamedSource("/lib1.dart", r'''
-library L1;
-class A {}
-class B {}''');
-    addNamedSource("/lib2.dart", r'''
-library L2;
-class B {}
-class C {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_ambiguousExport_combinators_show() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';
-export 'lib2.dart' show C;''');
-    addNamedSource("/lib1.dart", r'''
-library L1;
-class A {}
-class B {}''');
-    addNamedSource("/lib2.dart", r'''
-library L2;
-class B {}
-class C {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_ambiguousExport_sameDeclaration() async {
-    Source source = addSource(r'''
-library L;
-export 'lib.dart';
-export 'lib.dart';''');
-    addNamedSource("/lib.dart", r'''
-library lib;
-class N {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_ambiguousImport_dart_implicitHide() async {
-    Source source = addSource(r'''
-import 'dart:async';
-import 'lib.dart';
-main() {
-  print(Future.zero);
-}
-''');
-    addNamedSource('/lib.dart', r'''
-class Future {
-  static const zero = 0;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_ambiguousImport_hideCombinator() async {
-    Source source = addSource(r'''
-import 'lib1.dart';
-import 'lib2.dart';
-import 'lib3.dart' hide N;
-main() {
-  new N1();
-  new N2();
-  new N3();
-}''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class N {}
-class N1 {}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-class N {}
-class N2 {}''');
-    addNamedSource("/lib3.dart", r'''
-library lib3;
-class N {}
-class N3 {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_ambiguousImport_showCombinator() async {
-    Source source = addSource(r'''
-import 'lib1.dart';
-import 'lib2.dart' show N, N2;
-main() {
-  new N1();
-  new N2();
-}''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class N {}
-class N1 {}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-class N {}
-class N2 {}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNUSED_SHOWN_NAME]);
-  }
-
-  test_annotated_partOfDeclaration() async {
-    Source source = addSource('library L; part "part.dart";');
-    addNamedSource('/part.dart', '@deprecated part of L;');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_classWithCall_Function() async {
-    Source source = addSource(r'''
-  caller(Function callee) {
-    callee();
-  }
-
-  class CallMeBack {
-    call() => 0;
-  }
-
-  main() {
-    caller(new CallMeBack());
-  }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_fieldFormalParameterElement_member() async {
-    Source source = addSource(r'''
-class ObjectSink<T> {
-  void sink(T object) {
-    new TimestampedObject<T>(object);
-  }
-}
-class TimestampedObject<E> {
-  E object2;
-  TimestampedObject(this.object2);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_invocation_functionParameter_generic() async {
-    Source source = addSource(r'''
-class A<K> {
-  m(f(K k), K v) {
-    f(v);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_invocation_typedef_generic() async {
-    Source source = addSource(r'''
-typedef A<T>(T p);
-f(A<int> a) {
-  a(1);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_Object_Function() async {
-    Source source = addSource(r'''
-main() {
-  process(() {});
-}
-process(Object x) {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_optionalNew() async {
-    resetWith(options: new AnalysisOptionsImpl());
-    Source source = addSource(r'''
-class Widget { }
-
-class MaterialPageRoute {
-  final Widget Function() builder;
-  const MaterialPageRoute({this.builder});
-}
-
-void main() {
-  print(MaterialPageRoute(
-      builder: () { return Widget(); }
-  ));
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_typedef_local() async {
-    Source source = addSource(r'''
-typedef A(int p1, String p2);
-A getA() => null;
-f() {
-  A a = getA();
-  a(1, '2');
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_argumentTypeNotAssignable_typedef_parameter() async {
-    Source source = addSource(r'''
-typedef A(int p1, String p2);
-f(A a) {
-  a(1, '2');
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assert_with_message_await() async {
-    Source source = addSource('''
-import 'dart:async';
-f() async {
-  assert(false, await g());
-}
-Future<String> g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assert_with_message_dynamic() async {
-    Source source = addSource('''
-f() {
-  assert(false, g());
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assert_with_message_non_string() async {
-    Source source = addSource('''
-f() {
-  assert(false, 3);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assert_with_message_null() async {
-    Source source = addSource('''
-f() {
-  assert(false, null);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assert_with_message_string() async {
-    Source source = addSource('''
-f() {
-  assert(false, 'message');
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assert_with_message_suppresses_unused_var_hint() async {
-    Source source = addSource('''
-f() {
-  String message = 'msg';
-  assert(true, message);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assignability_function_expr_rettype_from_typedef_cls() async {
-    // In the code below, the type of (() => f()) has a return type which is
-    // a class, and that class is inferred from the return type of the typedef
-    // F.
-    Source source = addSource('''
-class C {}
-typedef C F();
-F f;
-main() {
-  F f2 = (() => f());
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assignability_function_expr_rettype_from_typedef_typedef() async {
-    // In the code below, the type of (() => f()) has a return type which is
-    // a typedef, and that typedef is inferred from the return type of the
-    // typedef F.
-    Source source = addSource('''
-typedef G F();
-typedef G();
-F f;
-main() {
-  F f2 = (() => f());
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assignmentToFinal_prefixNegate() async {
-    Source source = addSource(r'''
-f() {
-  final x = 0;
-  -x;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assignmentToFinalNoSetter_prefixedIdentifier() async {
-    Source source = addSource(r'''
-class A {
-  int get x => 0;
-  set x(v) {}
-}
-main() {
-  A a = new A();
-  a.x = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assignmentToFinalNoSetter_propertyAccess() async {
-    Source source = addSource(r'''
-class A {
-  int get x => 0;
-  set x(v) {}
-}
-class B {
-  static A a;
-}
-main() {
-  B.a.x = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_assignmentToFinals_importWithPrefix() async {
-    Source source = addSource(r'''
-library lib;
-import 'lib1.dart' as foo;
-main() {
-  foo.x = true;
-}''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-bool x = false;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_dynamic_with_return() async {
-    Source source = addSource('''
-dynamic f() async {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_dynamic_with_return_value() async {
-    Source source = addSource('''
-dynamic f() async {
-  return 5;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_dynamic_without_return() async {
-    Source source = addSource('''
-dynamic f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_expression_function_type() async {
-    Source source = addSource('''
-import 'dart:async';
-typedef Future<int> F(int i);
-main() {
-  F f = (int i) async => i;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_flattened() async {
-    Source source = addSource('''
-import 'dart:async';
-typedef Future<int> CreatesFutureInt();
-main() {
-  CreatesFutureInt createFutureInt = () async => f();
-  Future<int> futureInt = createFutureInt();
-  futureInt.then((int i) => print(i));
-}
-Future<int> f() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_dynamic_with_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<dynamic> f() async {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_dynamic_with_return_value() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<dynamic> f() async {
-  return 5;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_dynamic_without_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<dynamic> f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_int_with_return_future_int() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<int> f() async {
-  return new Future<int>.value(5);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_int_with_return_value() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<int> f() async {
-  return 5;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_null_with_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<Null> f() async {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_null_without_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<Null> f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_object_with_return_value() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<Object> f() async {
-  return 5;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_with_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future f() async {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_with_return_value() async {
-    Source source = addSource('''
-import 'dart:async';
-Future f() async {
-  return 5;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_future_without_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_with_return() async {
-    Source source = addSource('''
-f() async {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_with_return_value() async {
-    Source source = addSource('''
-f() async {
-  return 5;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_async_without_return() async {
-    Source source = addSource('''
-f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_asyncForInWrongContext_async() async {
-    Source source = addSource(r'''
-f(list) async {
-  await for (var e in list) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_asyncForInWrongContext_asyncStar() async {
-    Source source = addSource(r'''
-f(list) async* {
-  await for (var e in list) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_await_flattened() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<Future<int>> ffi() => null;
-f() async {
-  Future<int> b = await ffi();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_await_simple() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<int> fi() => null;
-f() async {
-  int a = await fi();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_awaitInWrongContext_async() async {
-    Source source = addSource(r'''
-f(x, y) async {
-  return await x + await y;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_awaitInWrongContext_asyncStar() async {
-    Source source = addSource(r'''
-f(x, y) async* {
-  yield await x + await y;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_breakWithoutLabelInSwitch() async {
-    Source source = addSource(r'''
-class A {
-  void m(int i) {
-    switch (i) {
-      case 0:
-        break;
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_bug_24539_getter() async {
-    Source source = addSource('''
-class C<T> {
-  List<Foo> get x => null;
-}
-
-typedef Foo(param);
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_bug_24539_setter() async {
-    Source source = addSource('''
-class C<T> {
-  void set x(List<Foo> value) {}
-}
-
-typedef Foo(param);
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_builtInIdentifierAsType_dynamic() async {
-    Source source = addSource(r'''
-f() {
-  dynamic x;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_caseBlockNotTerminated() async {
-    Source source = addSource(r'''
-f(int p) {
-  for (int i = 0; i < 10; i++) {
-    switch (p) {
-      case 0:
-        break;
-      case 1:
-        continue;
-      case 2:
-        return;
-      case 3:
-        throw new Object();
-      case 4:
-      case 5:
-        return;
-      case 6:
-      default:
-        return;
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_caseBlockNotTerminated_lastCase() async {
-    Source source = addSource(r'''
-f(int p) {
-  switch (p) {
-    case 0:
-      p = p + 1;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_caseExpressionTypeImplementsEquals() async {
-    Source source = addSource(r'''
-print(p) {}
-
-abstract class B {
-  final id;
-  const B(this.id);
-  String toString() => 'C($id)';
-  /** Equality is identity equality, the id isn't used. */
-  bool operator==(Object other);
-  }
-
-class C extends B {
-  const C(id) : super(id);
-}
-
-void doSwitch(c) {
-  switch (c) {
-  case const C(0): print('Switch: 0'); break;
-  case const C(1): print('Switch: 1'); break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_caseExpressionTypeImplementsEquals_int() async {
-    Source source = addSource(r'''
-f(int i) {
-  switch(i) {
-    case(1) : return 1;
-    default: return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_caseExpressionTypeImplementsEquals_Object() async {
-    Source source = addSource(r'''
-class IntWrapper {
-  final int value;
-  const IntWrapper(this.value);
-}
-
-f(IntWrapper intWrapper) {
-  switch(intWrapper) {
-    case(const IntWrapper(1)) : return 1;
-    default: return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_caseExpressionTypeImplementsEquals_String() async {
-    Source source = addSource(r'''
-f(String s) {
-  switch(s) {
-    case('1') : return 1;
-    default: return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_class_type_alias_documentationComment() async {
-    Source source = addSource('''
-/**
- * Documentation
- */
-class C = D with E;
-
-class D {}
-class E {}''');
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    ClassElement classC =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
-    expect(classC.documentationComment, isNotNull);
-  }
-
-  test_concreteClassWithAbstractMember() async {
-    Source source = addSource(r'''
-abstract class A {
-  m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_concreteClassWithAbstractMember_inherited() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_conflictingConstructorNameAndMember_setter() async {
-    Source source = addSource(r'''
-class A {
-A.x() {}
-set x(_) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_conflictingStaticGetterAndInstanceSetter_thisClass() async {
-    Source source = addSource(r'''
-class A {
-  static get x => 0;
-  static set x(int p) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_const_constructor_with_named_generic_parameter() async {
-    Source source = addSource('''
-class C<T> {
-  const C({T t});
-}
-const c = const C(t: 1);
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_const_dynamic() async {
-    Source source = addSource('''
-const Type d = dynamic;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_const_imported_defaultParameterValue_withImportPrefix() async {
-    Source source = addNamedSource("/a.dart", r'''
-import 'b.dart';
-const b = const B();
-''');
-    addNamedSource("/b.dart", r'''
-import 'c.dart' as ccc;
-class B {
-  const B([p = ccc.value]);
-}
-''');
-    addNamedSource("/c.dart", r'''
-const int value = 12345;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonConstSuper_explicit() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-class B extends A {
-  const B(): super();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonConstSuper_redirectingFactory() async {
-    Source source = addSource(r'''
-class A {
-  A();
-}
-class B implements C {
-  const B();
-}
-class C extends A {
-  const factory C() = B;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonConstSuper_unresolved() async {
-    Source source = addSource(r'''
-class A {
-  A.a();
-}
-class B extends A {
-  const B(): super();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonFinalField_finalInstanceVar() async {
-    Source source = addSource(r'''
-class A {
-  final int x = 0;
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonFinalField_static() async {
-    Source source = addSource(r'''
-class A {
-  static int x;
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constConstructorWithNonFinalField_syntheticField() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-  set x(value) {}
-  get x {return 0;}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constDeferredClass_new() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-class A {
-  const A.b();
-}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as a;
-main() {
-  new a.A.b();
-}'''
-    ], <ErrorCode>[]);
-  }
-
-  test_constEval_functionTypeLiteral() async {
-    Source source = addSource(r'''
-typedef F();
-const C = F;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEval_propertyExtraction_fieldStatic_targetType() async {
-    addNamedSource("/math.dart", r'''
-library math;
-const PI = 3.14;''');
-    Source source = addSource(r'''
-import 'math.dart' as math;
-const C = math.PI;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEval_propertyExtraction_methodStatic_targetType() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-  static m() {}
-}
-const C = A.m;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEval_symbol() async {
-    addNamedSource("/math.dart", r'''
-library math;
-const PI = 3.14;''');
-    Source source = addSource(r'''
-const C = #foo;
-foo() {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEvalTypeBoolNumString_equal() async {
-    Source source = addSource(r'''
-class B {
-  final v;
-  const B.a1(bool p) : v = p == true;
-  const B.a2(bool p) : v = p == false;
-  const B.a3(bool p) : v = p == 0;
-  const B.a4(bool p) : v = p == 0.0;
-  const B.a5(bool p) : v = p == '';
-  const B.b1(int p) : v = p == true;
-  const B.b2(int p) : v = p == false;
-  const B.b3(int p) : v = p == 0;
-  const B.b4(int p) : v = p == 0.0;
-  const B.b5(int p) : v = p == '';
-  const B.c1(String p) : v = p == true;
-  const B.c2(String p) : v = p == false;
-  const B.c3(String p) : v = p == 0;
-  const B.c4(String p) : v = p == 0.0;
-  const B.c5(String p) : v = p == '';
-  const B.n1(num p) : v = p == null;
-  const B.n2(num p) : v = null == p;
-  const B.n3(Object p) : v = p == null;
-  const B.n4(Object p) : v = null == p;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_constEvalTypeBoolNumString_notEqual() async {
-    Source source = addSource(r'''
-class B {
-  final v;
-  const B.a1(bool p) : v = p != true;
-  const B.a2(bool p) : v = p != false;
-  const B.a3(bool p) : v = p != 0;
-  const B.a4(bool p) : v = p != 0.0;
-  const B.a5(bool p) : v = p != '';
-  const B.b1(int p) : v = p != true;
-  const B.b2(int p) : v = p != false;
-  const B.b3(int p) : v = p != 0;
-  const B.b4(int p) : v = p != 0.0;
-  const B.b5(int p) : v = p != '';
-  const B.c1(String p) : v = p != true;
-  const B.c2(String p) : v = p != false;
-  const B.c3(String p) : v = p != 0;
-  const B.c4(String p) : v = p != 0.0;
-  const B.c5(String p) : v = p != '';
-  const B.n1(num p) : v = p != null;
-  const B.n2(num p) : v = null != p;
-  const B.n3(Object p) : v = p != null;
-  const B.n4(Object p) : v = null != p;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constEvAlTypeNum_String() async {
-    Source source = addSource(r'''
-const String A = 'a';
-const String B = A + 'b';
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constMapKeyExpressionTypeImplementsEquals_abstract() async {
-    Source source = addSource(r'''
-abstract class B {
-  final id;
-  const B(this.id);
-  String toString() => 'C($id)';
-  /** Equality is identity equality, the id isn't used. */
-  bool operator==(Object other);
-  }
-
-class C extends B {
-  const C(id) : super(id);
-}
-
-Map getMap() {
-  return const { const C(0): 'Map: 0' };
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constNotInitialized_field() async {
-    Source source = addSource(r'''
-class A {
-  static const int x = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constNotInitialized_local() async {
-    Source source = addSource(r'''
-main() {
-  const int x = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constRedirectSkipsSupertype() async {
-    // Since C redirects to C.named, it doesn't implicitly refer to B's
-    // unnamed constructor.  Therefore there is no cycle.
-    Source source = addSource('''
-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();
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constructorDeclaration_scope_signature() async {
-    Source source = addSource(r'''
-const app = 0;
-class A {
-  A(@app int app) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constWithNonConstantArgument_constField() async {
-    Source source = addSource(r'''
-class A {
-  const A(x);
-}
-main() {
-  const A(double.INFINITY);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constWithNonConstantArgument_literals() async {
-    Source source = addSource(r'''
-class A {
-  const A(a, b, c, d);
-}
-f() { return const A(true, 0, 1.0, '2'); }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constWithTypeParameters_direct() async {
-    Source source = addSource(r'''
-class A<T> {
-  static const V = const A<int>();
-  const A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constWithUndefinedConstructor() async {
-    Source source = addSource(r'''
-class A {
-  const A.name();
-}
-f() {
-  return const A.name();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_constWithUndefinedConstructorDefault() async {
-    Source source = addSource(r'''
-class A {
-  const A();
-}
-f() {
-  return const A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypeAlias() async {
-    Source source = addSource("typedef F([x]);");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypedParameter_named() async {
-    Source source = addSource("f(g({p})) {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_defaultValueInFunctionTypedParameter_optional() async {
-    Source source = addSource("f(g([p])) {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deprecatedMemberUse_hide() async {
-    Source source = addSource(r'''
-library lib;
-import 'lib1.dart' hide B;
-A a = new A();''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class A {}
-@deprecated
-class B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_emptyName() async {
-    // Note: This code has two FunctionElements '() {}' with an empty name,
-    // this tests that the empty string is not put into the scope
-    // (more than once).
-    Source source = addSource(r'''
-Map _globalMap = {
-  'a' : () {},
-  'b' : () {}
-};''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_duplicateDefinition_getter() async {
-    Source source = addSource("bool get a => true;");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_duplicatePart() async {
-    addNamedSource('/part1.dart', 'part of lib;');
-    addNamedSource('/part2.dart', 'part of lib;');
-    Source source = addSource(r'''
-library lib;
-part 'part1.dart';
-part 'part2.dart';
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_dynamicIdentifier() async {
-    Source source = addSource(r'''
-main() {
-  var v = dynamic;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_empty_generator_async() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream<int> f() async* {
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_empty_generator_sync() async {
-    Source source = addSource('''
-Iterable<int> f() sync* {
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_expectedOneListTypeArgument() async {
-    Source source = addSource(r'''
-main() {
-  <int> [];
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_expectedTwoMapTypeArguments() async {
-    Source source = addSource(r'''
-main() {
-  <int, int> {};
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_exportDuplicatedLibraryUnnamed() async {
-    Source source = addSource(r'''
-library test;
-export 'lib1.dart';
-export 'lib2.dart';''');
-    addNamedSource("/lib1.dart", "");
-    addNamedSource("/lib2.dart", "");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_exportOfNonLibrary_libraryDeclared() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';''');
-    addNamedSource("/lib1.dart", "library lib1;");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_exportOfNonLibrary_libraryNotDeclared() async {
-    Source source = addSource(r'''
-library L;
-export 'lib1.dart';''');
-    addNamedSource("/lib1.dart", "");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_extraPositionalArguments_function() async {
-    Source source = addSource(r'''
-f(p1, p2) {}
-main() {
-  f(1, 2);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_extraPositionalArguments_Function() async {
-    Source source = addSource(r'''
-f(Function a) {
-  a(1, 2);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_extraPositionalArguments_typedef_local() async {
-    Source source = addSource(r'''
-typedef A(p1, p2);
-A getA() => null;
-f() {
-  A a = getA();
-  a(1, 2);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_extraPositionalArguments_typedef_parameter() async {
-    Source source = addSource(r'''
-typedef A(p1, p2);
-f(A a) {
-  a(1, 2);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameter_functionTyped_named() async {
-    Source source = addSource(r'''
-class C {
-  final Function field;
-
-  C({String this.field(int value)});
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameter_genericFunctionTyped() async {
-    Source source = addSource(r'''
-class C {
-  final Object Function(int, double) field;
-
-  C(String Function(num, Object) this.field);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldFormalParameter_genericFunctionTyped_named() async {
-    Source source = addSource(r'''
-class C {
-  final Object Function(int, double) field;
-
-  C({String Function(num, Object) this.field});
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldInitializedByMultipleInitializers() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  int y;
-  A() : x = 0, y = 0 {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal() async {
-    Source source = addSource(r'''
-class A {
-  int x = 0;
-  A() : x = 1 {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldInitializedInInitializerAndDeclaration_finalFieldNotSet() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  A() : x = 1 {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldInitializerOutsideConstructor() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldInitializerOutsideConstructor_defaultParameters() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A([this.x]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_fieldInitializerRedirectingConstructor_super() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-class B extends A {
-  int x;
-  B(this.x) : super();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalInitializedInDeclarationAndConstructor_initializer() async {
-    Source source = addSource(r'''
-class A {
-  final x;
-  A() : x = 1 {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalInitializedInDeclarationAndConstructor_initializingFormal() async {
-    Source source = addSource(r'''
-class A {
-  final x;
-  A(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_atDeclaration() async {
-    Source source = addSource(r'''
-class A {
-  final int x = 0;
-  A() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_fieldFormal() async {
-    Source source = addSource(r'''
-class A {
-  final int x = 0;
-  A() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_functionTypedFieldFormal() async {
-    Source source = addSource(r'''
-class A {
-  final Function x;
-  A(int this.x(int p)) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_hasNativeClause_hasConstructor() async {
-    Source source = addSource(r'''
-class A native 'something' {
-  final int x;
-  A() {}
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_hasNativeClause_noConstructor() async {
-    Source source = addSource(r'''
-class A native 'something' {
-  final int x;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE]);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_initializer() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  A() : x = 0 {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_finalNotInitialized_redirectingConstructor() async {
-    Source source = addSource(r'''
-class A {
-  final int x;
-  A(this.x);
-  A.named() : this (42);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_forEach_genericFunctionType() async {
-    Source source = addSource(r'''
-main() {
-  for (Null Function<T>(T, Null) e in <dynamic>[]) {
-    e;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionDeclaration_scope_returnType() async {
-    Source source = addSource("int f(int) { return 0; }");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionDeclaration_scope_signature() async {
-    Source source = addSource(r'''
-const app = 0;
-f(@app int app) {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionTypeAlias_scope_returnType() async {
-    Source source = addSource("typedef int f(int);");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionTypeAlias_scope_signature() async {
-    Source source = addSource(r'''
-const app = 0;
-typedef int f(@app int app);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionWithoutCall() async {
-    Source source = addSource(r'''
-abstract class A implements Function {
-}
-class B implements A {
-  void call() {}
-}
-class C extends A {
-  void call() {}
-}
-class D extends C {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionWithoutCall_doesNotImplementFunction() async {
-    Source source = addSource("class A {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionWithoutCall_staticCallMethod() async {
-    Source source = addSource(r'''
-class A { }
-class B extends A {
-  static call() { }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionWithoutCall_withNoSuchMethod() async {
-    // 16078
-    Source source = addSource(r'''
-class A implements Function {
-  noSuchMethod(inv) {
-    return 42;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionWithoutCall_withNoSuchMethod_mixin() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(inv) {}
-}
-class B extends Object with A implements Function {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_functionWithoutCall_withNoSuchMethod_superclass() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(inv) {}
-}
-class B extends A implements Function {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_castsAndTypeChecks_hasTypeParameters() async {
-    Source source = addSource('''
-typedef Foo<S> = S Function<T>(T x);
-
-main(Object p) {
-  (p as Foo)<int>(3);
-  if (p is Foo) {
-    p<int>(3);
-  }
-  (p as Foo<String>)<int>(3);
-  if (p is Foo<String>) {
-    p<int>(3);
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_castsAndTypeChecks_noTypeParameters() async {
-    Source source = addSource('''
-typedef Foo = T Function<T>(T x);
-
-main(Object p) {
-  (p as Foo)<int>(3);
-  if (p is Foo) {
-    p<int>(3);
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_fieldAndReturnType_noTypeParameters() async {
-    Source source = addSource(r'''
-typedef Foo = int Function<T>(T x);
-int foo<T>(T x) => 3;
-Foo bar() => foo;
-void test1() {
-  bar()<String>("hello");
-}
-
-class A {
-  Foo f;
-  void test() {
-    f<String>("hello");
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
-    Source source = addSource(r'''
-typedef Foo<S> = S Function<T>(T x);
-int foo<T>(T x) => 3;
-Foo<int> bar() => foo;
-void test1() {
-  bar()<String>("hello");
-}
-
-class A {
-  Foo<int> f;
-  void test() {
-    f<String>("hello");
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
-    Source source = addSource(r'''
-typedef Foo<S> = S Function<T>(T x);
-int foo<T>(T x) => 3;
-Foo bar() => foo;
-void test1() {
-  bar()<String>("hello");
-}
-
-class A {
-  Foo f;
-  void test() {
-    f<String>("hello");
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_invalidGenericFunctionType() async {
-    Source source = addSource('''
-typedef F = int;
-main(p) {
-  p is F;
-}
-''');
-    await computeAnalysisResult(source);
-    // There is a parse error, but no crashes.
-    assertErrors(source, [ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE]);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_noTypeParameters() async {
-    Source source = addSource(r'''
-typedef Foo = int Function<T>(T x);
-int foo<T>(T x) => 3;
-void test1() {
-  Foo y = foo;
-  // These two should be equivalent
-  foo<String>("hello");
-  y<String>("hello");
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericTypeAlias_typeParameters() async {
-    Source source = addSource(r'''
-typedef Foo<S> = S Function<T>(T x);
-int foo<T>(T x) => 3;
-void test1() {
-  Foo<int> y = foo;
-  // These two should be equivalent
-  foo<String>("hello");
-  y<String>("hello");
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_constructorName() async {
-    Source source = addSource(r'''
-class A {
-  A.named() {}
-}
-class B {
-  var v;
-  B() : v = new A.named();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_prefixedIdentifier() async {
-    Source source = addSource(r'''
-class A {
-  var f;
-}
-class B {
-  var v;
-  B(A a) : v = a.f;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_qualifiedMethodInvocation() async {
-    Source source = addSource(r'''
-class A {
-  f() {}
-}
-class B {
-  var v;
-  B() : v = new A().f();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_qualifiedPropertyAccess() async {
-    Source source = addSource(r'''
-class A {
-  var f;
-}
-class B {
-  var v;
-  B() : v = new A().f;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_staticField_thisClass() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f;
-  static var f;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_staticGetter() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f;
-  static get f => 42;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_staticMethod() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f();
-  static f() => 42;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_topLevelField() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f;
-}
-var f = 42;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_topLevelFunction() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f();
-}
-f() => 42;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_topLevelGetter() async {
-    Source source = addSource(r'''
-class A {
-  var v;
-  A() : v = f;
-}
-get f => 42;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_implicitThisReferenceInInitializer_typeParameter() async {
-    Source source = addSource(r'''
-class A<T> {
-  var v;
-  A(p) : v = (p is T);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_importDuplicatedLibraryName() async {
-    Source source = addSource(r'''
-library test;
-import 'lib.dart';
-import 'lib.dart';''');
-    addNamedSource("/lib.dart", "library lib;");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      HintCode.UNUSED_IMPORT,
-      HintCode.UNUSED_IMPORT,
-      HintCode.DUPLICATE_IMPORT
-    ]);
-    verify([source]);
-  }
-
-  test_importDuplicatedLibraryUnnamed() async {
-    Source source = addSource(r'''
-library test;
-import 'lib1.dart';
-import 'lib2.dart';''');
-    addNamedSource("/lib1.dart", "");
-    addNamedSource("/lib2.dart", "");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      // No warning on duplicate import (https://github.com/dart-lang/sdk/issues/24156)
-      HintCode.UNUSED_IMPORT,
-      HintCode.UNUSED_IMPORT
-    ]);
-    verify([source]);
-  }
-
-  test_importOfNonLibrary_libraryDeclared() async {
-    Source source = addSource(r'''
-library lib;
-import 'part.dart';
-A a;''');
-    addNamedSource("/part.dart", r'''
-library lib1;
-class A {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_importOfNonLibrary_libraryNotDeclared() async {
-    Source source = addSource(r'''
-library lib;
-import 'part.dart';
-A a;''');
-    addNamedSource("/part.dart", "class A {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_importPrefixes_withFirstLetterDifference() async {
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart' as math;
-import 'lib2.dart' as path;
-main() {
-  math.test1();
-  path.test2();
-}''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-test1() {}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-test2() {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentCaseExpressionTypes() async {
-    Source source = addSource(r'''
-f(var p) {
-  switch (p) {
-    case 1:
-      break;
-    case 2:
-      break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentMethodInheritance_accessors_typeParameter2() async {
-    Source source = addSource(r'''
-abstract class A<E> {
-  E get x {return null;}
-}
-class B<E> {
-  E get x {return null;}
-}
-class C<E> extends A<E> implements B<E> {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentMethodInheritance_accessors_typeParameters1() async {
-    Source source = addSource(r'''
-abstract class A<E> {
-  E get x;
-}
-abstract class B<E> {
-  E get x;
-}
-class C<E> implements A<E>, B<E> {
-  E get x => null;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentMethodInheritance_accessors_typeParameters_diamond() async {
-    Source source = addSource(r'''
-abstract class F<E> extends B<E> {}
-class D<E> extends F<E> {
-  external E get g;
-}
-abstract class C<E> {
-  E get g;
-}
-abstract class B<E> implements C<E> {
-  E get g { return null; }
-}
-class A<E> extends B<E> implements D<E> {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentMethodInheritance_methods_typeParameter2() async {
-    Source source = addSource(r'''
-class A<E> {
-  x(E e) {}
-}
-class B<E> {
-  x(E e) {}
-}
-class C<E> extends A<E> implements B<E> {
-  x(E e) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentMethodInheritance_methods_typeParameters1() async {
-    Source source = addSource(r'''
-class A<E> {
-  x(E e) {}
-}
-class B<E> {
-  x(E e) {}
-}
-class C<E> implements A<E>, B<E> {
-  x(E e) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inconsistentMethodInheritance_simple() async {
-    Source source = addSource(r'''
-abstract class A {
-  x();
-}
-abstract class B {
-  x();
-}
-class C implements A, B {
-  x() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_infer_mixin_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-
-class B {}
-
-mixin M<T> on A<T> {}
-
-class C extends A<B> with M {}
-''');
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    ClassElement classC =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
-    expect(classC.mixins, hasLength(1));
-    expect(classC.mixins[0].toString(), 'M<B>');
-  }
-
-  test_infer_mixin_with_substitution_functionType_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-
-class B {}
-
-mixin M<T, U> on A<T Function(U)> {}
-
-class C extends A<int Function(String)> with M {}
-''');
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    CompilationUnit unit = analysisResult.unit;
-    ClassElement classC =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
-    expect(classC.mixins, hasLength(1));
-    expect(classC.mixins[0].toString(), 'M<int, String>');
-  }
-
-  test_infer_mixin_with_substitution_new_syntax() async {
-    Source source = addSource('''
-abstract class A<T> {}
-
-class B {}
-
-mixin M<T> on A<List<T>> {}
-
-class C extends A<List<B>> with M {}
-''');
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    ClassElement classC =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
-    expect(classC.mixins, hasLength(1));
-    expect(classC.mixins[0].toString(), 'M<B>');
-  }
-
-  test_initializingFormalForNonExistentField() async {
-    Source source = addSource(r'''
-class A {
-  int x;
-  A(this.x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_instance_creation_inside_annotation() async {
-    Source source = addSource('''
-class C {
-  const C();
-}
-class D {
-  final C c;
-  const D(this.c);
-}
-@D(const C())
-f() {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_instanceAccessToStaticMember_fromComment() async {
-    Source source = addSource(r'''
-class A {
-  static m() {}
-}
-/// [A.m]
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_instanceAccessToStaticMember_topLevel() async {
-    Source source = addSource(r'''
-m() {}
-main() {
-  m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_instanceMemberAccessFromStatic_fromComment() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-  /// [m]
-  static foo() {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_instanceMethodNameCollidesWithSuperclassStatic_field() async {
-    Source source = addSource(r'''
-import 'lib.dart';
-class B extends A {
-  _m() {}
-}''');
-    addNamedSource("/lib.dart", r'''
-library L;
-class A {
-  static var _m;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_instanceMethodNameCollidesWithSuperclassStatic_method() async {
-    Source source = addSource(r'''
-import 'lib.dart';
-class B extends A {
-  _m() {}
-}''');
-    addNamedSource("/lib.dart", r'''
-library L;
-class A {
-  static _m() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_integerLiteralOutOfRange_negative_leadingZeros() async {
-    Source source = addSource('int x = -000923372036854775809;');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_integerLiteralOutOfRange_negative_small() async {
-    Source source = addSource('int x = -42;');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-  }
-
-  test_integerLiteralOutOfRange_negative_valid() async {
-    Source source = addSource('int x = -9223372036854775808;');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-  }
-
-  test_integerLiteralOutOfRange_positive_leadingZeros() async {
-    Source source = addSource('int x = 000923372036854775808;');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_integerLiteralOutOfRange_positive_valid() async {
-    Source source = addSource('int x = 9223372036854775807;');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_integerLiteralOutOfRange_positive_zero() async {
-    Source source = addSource('int x = 0;');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_intLiteralInDoubleContext() async {
-    Source source = addSource(r'''
-void takeDouble(double x) {}
-void main() {
-  takeDouble(0);
-  takeDouble(-0);
-  takeDouble(0x0);
-  takeDouble(-0x0);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_intLiteralInDoubleContext_const() async {
-    Source source = addSource(r'''
-class C {
-  const C(double x)
-    : assert((x + 3) / 2 == 1.5)
-    , assert(x == 0.0);
-}
-@C(0)
-@C(-0)
-@C(0x0)
-@C(-0x0)
-void main() {
-  const C(0);
-  const C(-0);
-  const C(0x0);
-  const C(-0x0);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_constantVariable_field() async {
-    Source source = addSource(r'''
-@A.C
-class A {
-  static const C = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_constantVariable_field_importWithPrefix() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A {
-  static const C = 0;
-}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.A.C
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_constantVariable_topLevel() async {
-    Source source = addSource(r'''
-const C = 0;
-@C
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_constantVariable_topLevel_importWithPrefix() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-const C = 0;''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.C
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_constConstructor_importWithPrefix() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A {
-  const A(int p);
-}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.A(42)
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAnnotation_constConstructor_named_importWithPrefix() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A {
-  const A.named(int p);
-}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-@p.A.named(42)
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment() async {
-    Source source = addSource(r'''
-f() {
-  var x;
-  var y;
-  x = y;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_compoundAssignment() async {
-    Source source = addSource(r'''
-class byte {
-  int _value;
-  byte(this._value);
-  byte operator +(int val) { return this; }
-}
-
-void main() {
-  byte b = new byte(52);
-  b += 3;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_defaultValue_named() async {
-    Source source = addSource(r'''
-f({String x: '0'}) {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_defaultValue_optional() async {
-    Source source = addSource(r'''
-f([String x = '0']) {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_ifNullAssignment_compatibleType() async {
-    Source source = addSource('''
-void f(int i) {
-  num n;
-  n ??= i;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_ifNullAssignment_sameType() async {
-    Source source = addSource('''
-void f(int i) {
-  int j;
-  j ??= i;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_implicitlyImplementFunctionViaCall_1() async {
-    // 18341
-    //
-    // This test and
-    // 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()'
-    // are closely related: here we see that 'I' checks as a subtype of
-    // 'IntToInt'.
-    Source source = addSource(r'''
-class I {
-  int call(int x) => 0;
-}
-class C implements I {
-  noSuchMethod(_) => null;
-}
-typedef int IntToInt(int x);
-IntToInt f = new I();''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_implicitlyImplementFunctionViaCall_2() async {
-    // 18341
-    //
-    // Here 'C' checks as a subtype of 'I', but 'C' does not
-    // check as a subtype of 'IntToInt'. Together with
-    // 'test_invalidAssignment_implicitlyImplementFunctionViaCall_1()' we see
-    // that subtyping is not transitive here.
-    Source source = addSource(r'''
-class I {
-  int call(int x) => 0;
-}
-class C implements I {
-  noSuchMethod(_) => null;
-}
-typedef int IntToInt(int x);
-IntToInt f = new C();''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_implicitlyImplementFunctionViaCall_3() async {
-    // 18341
-    //
-    // Like 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
-    // but uses type 'Function' instead of more precise type 'IntToInt' for 'f'.
-    Source source = addSource(r'''
-class I {
-  int call(int x) => 0;
-}
-class C implements I {
-  noSuchMethod(_) => null;
-}
-typedef int IntToInt(int x);
-Function f = new C();''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_implicitlyImplementFunctionViaCall_4() async {
-    // 18341
-    //
-    // Like 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
-    // but uses type 'VoidToInt' instead of more precise type 'IntToInt' for
-    // 'f'.
-    //
-    // Here 'C <: IntToInt <: VoidToInt', but the spec gives no transitivity
-    // rule for '<:'. However, many of the :/tools/test.py tests assume this
-    // transitivity for 'JsBuilder' objects, assigning them to
-    // '(String) -> dynamic'. The declared type of 'JsBuilder.call' is
-    // '(String, [dynamic]) -> Expression'.
-    Source source = addSource(r'''
-class I {
-  int call([int x]) => 0;
-}
-class C implements I {
-  noSuchMethod(_) => null;
-}
-typedef int VoidToInt();
-VoidToInt f = new C();''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_postfixExpression_localVariable() async {
-    Source source = addSource(r'''
-class A {
-  A operator+(_) => this;
-}
-
-f(A a) {
-  a++;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_postfixExpression_property() async {
-    Source source = addSource(r'''
-class A {
-  A operator+(_) => this;
-}
-
-class C {
-  A a;
-}
-
-f(C c) {
-  c.a++;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_prefixExpression_localVariable() async {
-    Source source = addSource(r'''
-class A {
-  A operator+(_) => this;
-}
-
-f(A a) {
-  ++a;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_prefixExpression_property() async {
-    Source source = addSource(r'''
-class A {
-  A operator+(_) => this;
-}
-
-class C {
-  A a;
-}
-
-f(C c) {
-  ++c.a;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidAssignment_toDynamic() async {
-    Source source = addSource(r'''
-f() {
-  var g;
-  g = () => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidFactoryNameNotAClass() async {
-    Source source = addSource(r'''
-class A {
-  factory A() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidIdentifierInAsync() async {
-    Source source = addSource(r'''
-class A {
-  m() {
-    int async;
-    int await;
-    int yield;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidMethodOverrideNamedParamType() async {
-    Source source = addSource(r'''
-class A {
-  m({int a}) {}
-}
-class B implements A {
-  m({int a, int b}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_named() async {
-    Source source = addSource(r'''
-class A {
-  m({int p : 0}) {}
-}
-class B extends A {
-  m({int p : 0}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_named_function() async {
-    Source source = addSource(r'''
-nothing() => 'nothing';
-class A {
-  thing(String a, {orElse : nothing}) {}
-}
-class B extends A {
-  thing(String a, {orElse : nothing}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_positional() async {
-    Source source = addSource(r'''
-class A {
-  m([int p = 0]) {}
-}
-class B extends A {
-  m([int p = 0]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_positional_changedOrder() async {
-    Source source = addSource(r'''
-class A {
-  m([int a = 0, String b = '0']) {}
-}
-class B extends A {
-  m([int b = 0, String a = '0']) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_positional_function() async {
-    Source source = addSource(r'''
-nothing() => 'nothing';
-class A {
-  thing(String a, [orElse = nothing]) {}
-}
-class B extends A {
-  thing(String a, [orElse = nothing]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideNamed_unorderedNamedParameter() async {
-    Source source = addSource(r'''
-class A {
-  m({a, b}) {}
-}
-class B extends A {
-  m({b, a}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideRequired_less() async {
-    Source source = addSource(r'''
-class A {
-  m(a, b) {}
-}
-class B extends A {
-  m(a, [b]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideRequired_same() async {
-    Source source = addSource(r'''
-class A {
-  m(a) {}
-}
-class B extends A {
-  m(a) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_interface() async {
-    Source source = addNamedSource("/test.dart", r'''
-abstract class A {
-  num m();
-}
-class B implements A {
-  int m() { return 1; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_interface2() async {
-    Source source = addNamedSource("/test.dart", r'''
-abstract class A {
-  num m();
-}
-abstract class B implements A {
-}
-class C implements B {
-  int m() { return 1; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_mixin() async {
-    Source source = addNamedSource("/test.dart", r'''
-class A {
-  num m() { return 0; }
-}
-class B extends Object with A {
-  int m() { return 1; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_parameterizedTypes() async {
-    Source source = addSource(r'''
-abstract class A<E> {
-  List<E> m();
-}
-class B extends A<dynamic> {
-  List<dynamic> m() { return new List<dynamic>(); }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_sameType() async {
-    Source source = addNamedSource("/test.dart", r'''
-class A {
-  int m() { return 0; }
-}
-class B extends A {
-  int m() { return 1; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_superclass() async {
-    Source source = addNamedSource("/test.dart", r'''
-class A {
-  num m() { return 0; }
-}
-class B extends A {
-  int m() { return 1; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_superclass2() async {
-    Source source = addNamedSource("/test.dart", r'''
-class A {
-  num m() { return 0; }
-}
-class B extends A {
-}
-class C extends B {
-  int m() { return 1; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideReturnType_returnType_void() async {
-    Source source = addSource(r'''
-class A {
-  void m() {}
-}
-class B extends A {
-  int m() { return 0; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_constructor() async {
-    Source source = addSource(r'''
-class A {
-  A() {
-    var v = this;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidReferenceToThis_instanceMethod() async {
-    Source source = addSource(r'''
-class A {
-  m() {
-    var v = this;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidTypeArgumentForKey() async {
-    Source source = addSource(r'''
-class A {
-  m() {
-    return const <int, int>{};
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidTypeArgumentInConstList() async {
-    Source source = addSource(r'''
-class A<E> {
-  m() {
-    return <E>[];
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidTypeArgumentInConstMap() async {
-    Source source = addSource(r'''
-class A<E> {
-  m() {
-    return <String, E>{};
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  Future test_issue32114() async {
-    addNamedSource('/a.dart', '''
-class O {}
-
-typedef T Func<T extends O>(T e);
-''');
-    addNamedSource('/b.dart', '''
-import 'a.dart';
-export 'a.dart' show Func;
-
-abstract class A<T extends O> {
-  Func<T> get func;
-}
-''');
-    final Source source = addSource('''
-import 'b.dart';
-
-class B extends A {
-  Func get func => (x) => x;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_issue_24191() async {
-    Source source = addSource('''
-import 'dart:async';
-
-abstract class S extends Stream {}
-f(S s) async {
-  await for (var v in s) {
-    print(v);
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_issue_32394() async {
-    Source source = addSource('''
-var x = y.map((a) => a.toString());
-var y = [3];
-var z = x.toList();
-
-void main() {
-  String p = z;
-}
-''');
-    var result = await computeAnalysisResult(source);
-    var z = result.unit.declaredElement.topLevelVariables
-        .where((e) => e.name == 'z')
-        .single;
-    expect(z.type.toString(), 'List<String>');
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-    verify([source]);
-  }
-
-  test_issue_35320_lists() async {
-    addNamedSource('/lib.dart', '''
-const x = const <String>['a'];
-''');
-    Source source = addSource('''
-import 'lib.dart';
-const y = const <String>['b'];
-int f(v) {
-  switch(v) {
-    case x:
-      return 0;
-    case y:
-      return 1;
-    default:
-      return 2;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_issue_35320_maps() async {
-    addNamedSource('/lib.dart', '''
-const x = const <String, String>{'a': 'b'};
-''');
-    Source source = addSource('''
-import 'lib.dart';
-const y = const <String, String>{'c': 'd'};
-int f(v) {
-  switch(v) {
-    case x:
-      return 0;
-    case y:
-      return 1;
-    default:
-      return 2;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_listElementTypeNotAssignable() async {
-    Source source = addSource(r'''
-var v1 = <int> [42];
-var v2 = const <int> [42];''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_loadLibraryDefined() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-foo() => 22;''',
-      r'''
-import 'lib1.dart' deferred as other;
-main() {
-  other.loadLibrary().then((_) => other.foo());
-}'''
-    ], <ErrorCode>[]);
-  }
-
-  test_local_generator_async() async {
-    Source source = addSource('''
-f() {
-  return () async* { yield 0; };
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_local_generator_sync() async {
-    Source source = addSource('''
-f() {
-  return () sync* { yield 0; };
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mapKeyTypeNotAssignable() async {
-    Source source = addSource("var v = <String, int > {'a' : 1};");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_metadata_enumConstantDeclaration() async {
-    Source source = addSource(r'''
-const x = 1;
-enum E {
-  aaa,
-  @x
-  bbb
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_methodDeclaration_scope_signature() async {
-    Source source = addSource(r'''
-const app = 0;
-class A {
-  foo(@app int app) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_misMatchedGetterAndSetterTypes_instance_sameTypes() async {
-    Source source = addSource(r'''
-class C {
-  int get x => 0;
-  set x(int v) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_misMatchedGetterAndSetterTypes_instance_unspecifiedGetter() async {
-    Source source = addSource(r'''
-class C {
-  get x => 0;
-  set x(String v) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_misMatchedGetterAndSetterTypes_instance_unspecifiedSetter() async {
-    Source source = addSource(r'''
-class C {
-  int get x => 0;
-  set x(v) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_misMatchedGetterAndSetterTypes_topLevel_sameTypes() async {
-    Source source = addSource(r'''
-int get x => 0;
-set x(int v) {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedGetter() async {
-    Source source = addSource(r'''
-get x => 0;
-set x(String v) {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_misMatchedGetterAndSetterTypes_topLevel_unspecifiedSetter() async {
-    Source source = addSource(r'''
-int get x => 0;
-set x(v) {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingEnumConstantInSwitch_all() async {
-    Source source = addSource(r'''
-enum E { A, B, C }
-
-f(E e) {
-  switch (e) {
-    case E.A: break;
-    case E.B: break;
-    case E.C: break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingEnumConstantInSwitch_default() async {
-    Source source = addSource(r'''
-enum E { A, B, C }
-
-f(E e) {
-  switch (e) {
-    case E.B: break;
-    default: break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixedReturnTypes_differentScopes() async {
-    Source source = addSource(r'''
-class C {
-  m(int x) {
-    f(int y) {
-      return;
-    }
-    f(x);
-    return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixedReturnTypes_ignoreImplicit() async {
-    Source source = addSource(r'''
-f(bool p) {
-  if (p) return 42;
-  // implicit 'return;' is ignored
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixedReturnTypes_ignoreImplicit2() async {
-    Source source = addSource(r'''
-f(bool p) {
-  if (p) {
-    return 42;
-  } else {
-    return 42;
-  }
-  // implicit 'return;' is ignored
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixedReturnTypes_sameKind() async {
-    Source source = addSource(r'''
-class C {
-  m(int x) {
-    if (x < 0) {
-      return 1;
-    }
-    return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixin_of_mixin_type_argument_inference() async {
-    // In the code below, B's superclass constraints don't include A, because
-    // superclass constraints are determined from the mixin's superclass, and
-    // B's superclass is Object.  So no mixin type inference is attempted, and
-    // "with B" is interpreted as "with B<dynamic>".
-    Source source = addSource('''
-class A<T> {}
-class B<T> = Object with A<T>;
-class C = Object with B;
-''');
-    var result = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var bReference = result.unit.declaredElement.getType('C').mixins[0];
-    expect(bReference.typeArguments[0].toString(), 'dynamic');
-  }
-
-  test_mixin_of_mixin_type_argument_inference_cascaded_mixin() async {
-    // In the code below, B has a single superclass constraint, A1, because
-    // superclass constraints are determined from the mixin's superclass, and
-    // B's superclass is "Object with A1<T>".  So mixin type inference succeeds
-    // (since C's base class implements A1<int>), and "with B" is interpreted as
-    // "with B<int>".
-    Source source = addSource('''
-class A1<T> {}
-class A2<T> {}
-class B<T> = Object with A1<T>, A2<T>;
-class Base implements A1<int> {}
-class C = Base with B;
-''');
-    var result = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var bReference = result.unit.declaredElement.getType('C').mixins[0];
-    expect(bReference.typeArguments[0].toString(), 'int');
-  }
-
-  test_mixinDeclaresConstructor() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends Object with A {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixinDeclaresConstructor_factory() async {
-    Source source = addSource(r'''
-class A {
-  factory A() => null;
-}
-class B extends Object with A {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixinInference_with_actual_mixins() async {
-    Source source = addSource('''
-class I<X> {}
-
-mixin M0<T> on I<T> {}
-
-mixin M1<T> on I<T> {
-  T foo() => null;
-}
-
-class A = I<int> with M0, M1;
-
-void main () {
-  var x = new A().foo();
-}
-''');
-    var result = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var main = result.unit.declarations.last as FunctionDeclaration;
-    var mainBody = main.functionExpression.body as BlockFunctionBody;
-    var xDecl = mainBody.block.statements[0] as VariableDeclarationStatement;
-    var xElem = xDecl.variables.variables[0].declaredElement;
-    expect(xElem.type.toString(), 'int');
-  }
-
-  test_mixinInheritsFromNotObject_classDeclaration_extends_new_syntax() async {
-    Source source = addSource(r'''
-class A {}
-mixin B on A {}
-class C extends A with B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixinInheritsFromNotObject_classDeclaration_mixTypeAlias() async {
-    Source source = addSource(r'''
-class A {}
-class B = Object with A;
-class C extends Object with B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixinInheritsFromNotObject_typeAlias_extends_new_syntax() async {
-    Source source = addSource(r'''
-class A {}
-mixin B on A {}
-class C = A with B;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixinInheritsFromNotObject_typedef_mixTypeAlias() async {
-    Source source = addSource(r'''
-class A {}
-class B = Object with A;
-class C = Object with B;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_mixinReferencesSuper_new_syntax() async {
-    Source source = addSource(r'''
-mixin A {
-  toString() => super.toString();
-}
-class B extends Object with A {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_multipleSuperInitializers_no() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  B() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_multipleSuperInitializers_single() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  B() : super() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nativeConstConstructor() async {
-    Source source = addSource(r'''
-import 'dart-ext:x';
-class Foo {
-  const Foo() native 'Foo_Foo';
-  const factory Foo.foo() native 'Foo_Foo_foo';
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY]);
-    // Cannot verify the AST because the import's URI cannot be resolved.
-  }
-
-  test_nativeFunctionBodyInNonSDKCode_function() async {
-    Source source = addSource(r'''
-import 'dart-ext:x';
-int m(a) native 'string';''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    // Cannot verify the AST because the import's URI cannot be resolved.
-  }
-
-  test_newWithAbstractClass_factory() async {
-    Source source = addSource(r'''
-abstract class A {
-  factory A() { return new B(); }
-}
-class B implements A {
-  B() {}
-}
-A f() {
-  return new A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_newWithUndefinedConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A.name() {}
-}
-f() {
-  new A.name();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_newWithUndefinedConstructorDefault() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-f() {
-  new A();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_getter() async {
-    Source source = addSource(r'''
-class A {
-  int get g => 0;
-}
-abstract class B extends A {
-  int get g;
-}
-class C extends B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_method() async {
-    Source source = addSource(r'''
-class A {
-  m(p) {}
-}
-abstract class B extends A {
-  m(p);
-}
-class C extends B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter() async {
-    Source source = addSource(r'''
-class A {
-  set s(v) {}
-}
-abstract class B extends A {
-  set s(v);
-}
-class C extends B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() async {
-    // 15979
-    Source source = addSource(r'''
-abstract class M {}
-abstract class A {}
-abstract class I {
-  m();
-}
-abstract class B = A with M implements I;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin() async {
-    // 15979
-    Source source = addSource(r'''
-abstract class M {
-  m();
-}
-abstract class A {}
-abstract class B = A with M;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() async {
-    // 15979
-    Source source = addSource(r'''
-class M {}
-abstract class A {
-  m();
-}
-abstract class B = A with M;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter() async {
-    // 17034
-    Source source = addSource(r'''
-class A {
-  var a;
-}
-abstract class M {
-  get a;
-}
-class B extends A with M {}
-class C extends B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_mixin_method() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-abstract class M {
-  m();
-}
-class B extends A with M {}
-class C extends B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter() async {
-    Source source = addSource(r'''
-class A {
-  var a;
-}
-abstract class M {
-  set a(dynamic v);
-}
-class B extends A with M {}
-class C extends B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_accessor() async {
-    Source source = addSource(r'''
-abstract class A {
-  int get g;
-}
-class B extends A {
-  noSuchMethod(v) => '';
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_method() async {
-    Source source = addSource(r'''
-abstract class A {
-  m(p);
-}
-class B extends A {
-  noSuchMethod(v) => '';
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_mixin() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(v) => '';
-}
-class B extends Object with A {
-  m(p);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_superclass() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(v) => '';
-}
-class B extends A {
-  m(p);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() async {
-    Source source = addSource(r'''
-class A {
-  String toString([String prefix = '']) => '${prefix}Hello';
-}
-class C {}
-class B extends A with C {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolExpression_interfaceType() async {
-    Source source = addSource(r'''
-f() {
-  assert(true);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolNegationExpression() async {
-    Source source = addSource(r'''
-f(bool pb, pd) {
-  !true;
-  !false;
-  !pb;
-  !pd;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolNegationExpression_dynamic() async {
-    Source source = addSource(r'''
-f1(bool dynamic) {
-  !dynamic;
-}
-f2() {
-  bool dynamic = true;
-  !dynamic;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolOperand_and_bool() async {
-    Source source = addSource(r'''
-bool f(bool left, bool right) {
-  return left && right;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolOperand_and_dynamic() async {
-    Source source = addSource(r'''
-bool f(left, dynamic right) {
-  return left && right;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolOperand_or_bool() async {
-    Source source = addSource(r'''
-bool f(bool left, bool right) {
-  return left || right;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonBoolOperand_or_dynamic() async {
-    Source source = addSource(r'''
-bool f(dynamic left, right) {
-  return left || right;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_constField() async {
-    Source source = addSource(r'''
-f([a = double.INFINITY]) {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_function_named() async {
-    Source source = addSource("f({x : 2 + 3}) {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_function_positional() async {
-    Source source = addSource("f([x = 2 + 3]) {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_inConstructor_named() async {
-    Source source = addSource(r'''
-class A {
-  A({x : 2 + 3}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_inConstructor_positional() async {
-    Source source = addSource(r'''
-class A {
-  A([x = 2 + 3]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_method_named() async {
-    Source source = addSource(r'''
-class A {
-  m({x : 2 + 3}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_method_positional() async {
-    Source source = addSource(r'''
-class A {
-  m([x = 2 + 3]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantDefaultValue_typedConstList() async {
-    Source source = addSource(r'''
-class A {
-  m([p111 = const <String>[]]) {}
-}
-class B extends A {
-  m([p222 = const <String>[]]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstantValueInInitializer_namedArgument() async {
-    Source source = addSource(r'''
-class A {
-  final a;
-  const A({this.a});
-}
-class B extends A {
-  const B({b}) : super(a: b);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstCaseExpression_constField() async {
-    Source source = addSource(r'''
-f(double p) {
-  switch (p) {
-    case double.INFINITY:
-      return true;
-    default:
-      return false;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_nonConstCaseExpression_typeLiteral() async {
-    Source source = addSource(r'''
-f(Type t) {
-  switch (t) {
-    case bool:
-    case int:
-      return true;
-    default:
-      return false;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstListElement_constField() async {
-    Source source = addSource(r'''
-main() {
-  const [double.INFINITY];
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstMapAsExpressionStatement_const() async {
-    Source source = addSource(r'''
-f() {
-  const {'a' : 0, 'b' : 1};
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstMapAsExpressionStatement_notExpressionStatement() async {
-    Source source = addSource(r'''
-f() {
-  var m = {'a' : 0, 'b' : 1};
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstMapAsExpressionStatement_typeArguments() async {
-    Source source = addSource(r'''
-f() {
-  <String, int> {'a' : 0, 'b' : 1};
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstMapKey_constField() async {
-    Source source = addSource(r'''
-main() {
-  const {double.INFINITY: 0};
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
-    verify([source]);
-  }
-
-  test_nonConstMapValue_constField() async {
-    Source source = addSource(r'''
-main() {
-  const {0: double.INFINITY};
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_bool() async {
-    Source source = addSource(r'''
-class A {
-  final v;
-  const A.a1(bool p) : v = p && true;
-  const A.a2(bool p) : v = true && p;
-  const A.b1(bool p) : v = p || true;
-  const A.b2(bool p) : v = true || p;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.DEAD_CODE]);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_dynamic() async {
-    Source source = addSource(r'''
-class A {
-  final v;
-  const A.a1(p) : v = p + 5;
-  const A.a2(p) : v = 5 + p;
-  const A.b1(p) : v = p - 5;
-  const A.b2(p) : v = 5 - p;
-  const A.c1(p) : v = p * 5;
-  const A.c2(p) : v = 5 * p;
-  const A.d1(p) : v = p / 5;
-  const A.d2(p) : v = 5 / p;
-  const A.e1(p) : v = p ~/ 5;
-  const A.e2(p) : v = 5 ~/ p;
-  const A.f1(p) : v = p > 5;
-  const A.f2(p) : v = 5 > p;
-  const A.g1(p) : v = p < 5;
-  const A.g2(p) : v = 5 < p;
-  const A.h1(p) : v = p >= 5;
-  const A.h2(p) : v = 5 >= p;
-  const A.i1(p) : v = p <= 5;
-  const A.i2(p) : v = 5 <= p;
-  const A.j1(p) : v = p % 5;
-  const A.j2(p) : v = 5 % p;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    // operations on "p" are not resolved
-  }
-
-  test_nonConstValueInInitializer_binary_int() async {
-    Source source = addSource(r'''
-class A {
-  final v;
-  const A.a1(int p) : v = p ^ 5;
-  const A.a2(int p) : v = 5 ^ p;
-  const A.b1(int p) : v = p & 5;
-  const A.b2(int p) : v = 5 & p;
-  const A.c1(int p) : v = p | 5;
-  const A.c2(int p) : v = 5 | p;
-  const A.d1(int p) : v = p >> 5;
-  const A.d2(int p) : v = 5 >> p;
-  const A.e1(int p) : v = p << 5;
-  const A.e2(int p) : v = 5 << p;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_binary_num() async {
-    Source source = addSource(r'''
-class A {
-  final v;
-  const A.a1(num p) : v = p + 5;
-  const A.a2(num p) : v = 5 + p;
-  const A.b1(num p) : v = p - 5;
-  const A.b2(num p) : v = 5 - p;
-  const A.c1(num p) : v = p * 5;
-  const A.c2(num p) : v = 5 * p;
-  const A.d1(num p) : v = p / 5;
-  const A.d2(num p) : v = 5 / p;
-  const A.e1(num p) : v = p ~/ 5;
-  const A.e2(num p) : v = 5 ~/ p;
-  const A.f1(num p) : v = p > 5;
-  const A.f2(num p) : v = 5 > p;
-  const A.g1(num p) : v = p < 5;
-  const A.g2(num p) : v = 5 < p;
-  const A.h1(num p) : v = p >= 5;
-  const A.h2(num p) : v = 5 >= p;
-  const A.i1(num p) : v = p <= 5;
-  const A.i2(num p) : v = 5 <= p;
-  const A.j1(num p) : v = p % 5;
-  const A.j2(num p) : v = 5 % p;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_field() async {
-    Source source = addSource(r'''
-class A {
-  final int a;
-  const A() : a = 5;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_redirecting() async {
-    Source source = addSource(r'''
-class A {
-  const A.named(p);
-  const A() : this.named(42);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_super() async {
-    Source source = addSource(r'''
-class A {
-  const A(p);
-}
-class B extends A {
-  const B() : super(42);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstValueInInitializer_unary() async {
-    Source source = addSource(r'''
-class A {
-  final v;
-  const A.a(bool p) : v = !p;
-  const A.b(int p) : v = ~p;
-  const A.c(num p) : v = -p;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonGenerativeConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A.named() {}
-  factory A() => null;
-}
-class B extends A {
-  B() : super.named();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonTypeInCatchClause_isClass() async {
-    Source source = addSource(r'''
-f() {
-  try {
-  } on String catch (e) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonTypeInCatchClause_isFunctionTypeAlias() async {
-    Source source = addSource(r'''
-typedef F();
-f() {
-  try {
-  } on F catch (e) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonTypeInCatchClause_isTypeParameter() async {
-    Source source = addSource(r'''
-class A<T> {
-  f() {
-    try {
-    } on T catch (e) {
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonTypeInCatchClause_noType() async {
-    Source source = addSource(r'''
-f() {
-  try {
-  } catch (e) {
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonVoidReturnForOperator_no() async {
-    Source source = addSource(r'''
-class A {
-  operator []=(a, b) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonVoidReturnForOperator_void() async {
-    Source source = addSource(r'''
-class A {
-  void operator []=(a, b) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonVoidReturnForSetter_function_no() async {
-    Source source = addSource("set x(v) {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonVoidReturnForSetter_function_void() async {
-    Source source = addSource("void set x(v) {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonVoidReturnForSetter_method_no() async {
-    Source source = addSource(r'''
-class A {
-  set x(v) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonVoidReturnForSetter_method_void() async {
-    Source source = addSource(r'''
-class A {
-  void set x(v) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_null_callOperator() async {
-    Source source = addSource(r'''
-main() {
-  null + 5;
-  null == 5;
-  null[0];
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.UNDEFINED_METHOD,
-      StaticTypeWarningCode.UNDEFINED_METHOD
-    ]);
-  }
-
-  test_optionalNew_rewrite() async {
-    resetWith(options: new AnalysisOptionsImpl());
-    Source source = addSource(r'''
-import 'b.dart';
-main() {
-  const B.named1();
-  const B.named2();
-  const B.named3();
-  const B.named4();
-}
-''');
-    addNamedSource("/a.dart", r'''
-class A {
-  const A();
-  const A.named();
-}
-''');
-    addNamedSource("/b.dart", r'''
-import 'a.dart';
-import 'a.dart' as p;
-
-const _a1 = A();
-const _a2 = A.named();
-const _a3 = p.A();
-const _a4 = p.A.named();
-
-class B {
-  const B.named1({this.a: _a1}) : assert(a != null);
-  const B.named2({this.a: _a2}) : assert(a != null);
-  const B.named3({this.a: _a3}) : assert(a != null);
-  const B.named4({this.a: _a4}) : assert(a != null);
-
-  final A a;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_optionalNew_rewrite_instantiatesToBounds() async {
-    resetWith(options: new AnalysisOptionsImpl());
-    Source source = addSource(r'''
-import 'b.dart';
-
-@B.named1()
-@B.named2()
-@B.named3()
-@B.named4()
-@B.named5()
-@B.named6()
-@B.named7()
-@B.named8()
-main() {}
-''');
-    addNamedSource("/a.dart", r'''
-class Unbounded<T> {
-  const Unbounded();
-  const Unbounded.named();
-}
-class Bounded<T extends String> {
-  const Bounded();
-  const Bounded.named();
-}
-''');
-    addNamedSource("/b.dart", r'''
-import 'a.dart';
-import 'a.dart' as p;
-
-const unbounded1 = Unbounded();
-const unbounded2 = Unbounded.named();
-const unbounded3 = p.Unbounded();
-const unbounded4 = p.Unbounded.named();
-const bounded1 = Bounded();
-const bounded2 = Bounded.named();
-const bounded3 = p.Bounded();
-const bounded4 = p.Bounded.named();
-
-class B {
-  const B.named1({this.unbounded: unbounded1}) : bounded = null;
-  const B.named2({this.unbounded: unbounded2}) : bounded = null;
-  const B.named3({this.unbounded: unbounded3}) : bounded = null;
-  const B.named4({this.unbounded: unbounded4}) : bounded = null;
-  const B.named5({this.bounded: bounded1}) : unbounded = null;
-  const B.named6({this.bounded: bounded2}) : unbounded = null;
-  const B.named7({this.bounded: bounded3}) : unbounded = null;
-  const B.named8({this.bounded: bounded4}) : unbounded = null;
-
-  final Unbounded unbounded;
-  final Bounded bounded;
-}
-''');
-    final result = await computeAnalysisResult(source);
-    expect(result.unit.declarations, hasLength(1));
-    final mainDecl = result.unit.declarations[0];
-    expect(mainDecl.metadata, hasLength(8));
-    mainDecl.metadata.forEach((metadata) {
-      final value = metadata.elementAnnotation.computeConstantValue();
-      expect(value, isNotNull);
-      expect(value.type.toString(), 'B');
-      final unbounded = value.getField('unbounded');
-      final bounded = value.getField('bounded');
-      if (!unbounded.isNull) {
-        expect(bounded.isNull, true);
-        expect(unbounded.type.name, 'Unbounded');
-        expect(unbounded.type.typeArguments, hasLength(1));
-        expect(unbounded.type.typeArguments[0].isDynamic, isTrue);
-      } else {
-        expect(unbounded.isNull, true);
-        expect(bounded.type.name, 'Bounded');
-        expect(bounded.type.typeArguments, hasLength(1));
-        expect(bounded.type.typeArguments[0].name, 'String');
-      }
-    });
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_optionalParameterInOperator_required() async {
-    Source source = addSource(r'''
-class A {
-  operator +(p) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_parameterScope_local() async {
-    // Parameter names shouldn't conflict with the name of the function they
-    // are enclosed in.
-    Source source = addSource(r'''
-f() {
-  g(g) {
-    h(g);
-  }
-}
-h(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_parameterScope_method() async {
-    // Parameter names shouldn't conflict with the name of the function they
-    // are enclosed in.
-    Source source = addSource(r'''
-class C {
-  g(g) {
-    h(g);
-  }
-}
-h(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_parameterScope_topLevel() async {
-    // Parameter names shouldn't conflict with the name of the function they
-    // are enclosed in.
-    Source source = addSource(r'''
-g(g) {
-  h(g);
-}
-h(x) {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_parametricCallFunction() async {
-    Source source = addSource(r'''
-f() {
-  var c = new C();
-  c<String>().codeUnits;
-}
-
-class C {
-  T call<T>() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_prefixCollidesWithTopLevelMembers() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class A {}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-typedef P();
-p2() {}
-var p3;
-class p4 {}
-p.A a;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_propagateTypeArgs_intoBounds() async {
-    Source source = addSource(r'''
-abstract class A<E> {}
-abstract class B<F> implements A<F>{}
-abstract class C<G, H extends A<G>> {}
-class D<I> extends C<I, B<I>> {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_propagateTypeArgs_intoSupertype() async {
-    Source source = addSource(r'''
-class A<T> {
-  A(T p);
-  A.named(T p);
-}
-class B<S> extends A<S> {
-  B(S p) : super(p);
-  B.named(S p) : super.named(p);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_recursiveConstructorRedirect() async {
-    Source source = addSource(r'''
-class A {
-  A.a() : this.b();
-  A.b() : this.c();
-  A.c() {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_recursiveFactoryRedirect() async {
-    Source source = addSource(r'''
-class A {
-  factory A() = B;
-}
-class B implements A {
-  factory B() = C;
-}
-class C implements B {
-  factory C() => null;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_redirectToInvalidFunctionType() async {
-    Source source = addSource(r'''
-class A implements B {
-  A(int p) {}
-}
-class B {
-  factory B(int p) = A;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_redirectToNonConstConstructor() async {
-    Source source = addSource(r'''
-class A {
-  const A.a();
-  const factory A.b() = A.a;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_referencedBeforeDeclaration_cascade() async {
-    Source source = addSource(r'''
-testRequestHandler() {}
-
-main() {
-  var s1 = null;
-  testRequestHandler()
-    ..stream(s1);
-  var stream = 123;
-  print(stream);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_referenceToDeclaredVariableInInitializer_constructorName() async {
-    Source source = addSource(r'''
-class A {
-  A.x() {}
-}
-f() {
-  var x = new A.x();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_referenceToDeclaredVariableInInitializer_methodName() async {
-    Source source = addSource(r'''
-class A {
-  x() {}
-}
-f(A a) {
-  var x = a.x();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_referenceToDeclaredVariableInInitializer_propertyName() async {
-    Source source = addSource(r'''
-class A {
-  var x;
-}
-f(A a) {
-  var x = a.x;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_regress34906() async {
-    Source source = addSource(r'''
-typedef G<X, Y extends Function(X)> = X Function(Function(Y));
-G<dynamic, Function(Null)> superBoundedG;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_rethrowOutsideCatch() async {
-    Source source = addSource(r'''
-class A {
-  void m() {
-    try {} catch (e) {rethrow;}
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_return_in_generator_async() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream<int> f() async* {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_return_in_generator_sync() async {
-    Source source = addSource('''
-Iterable<int> f() sync* {
-  return;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnInGenerativeConstructor() async {
-    Source source = addSource(r'''
-class A {
-  A() { return; }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnInGenerator_async() async {
-    Source source = addSource(r'''
-f() async {
-  return 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnInGenerator_sync() async {
-    Source source = addSource(r'''
-f() {
-  return 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnOfInvalidType_async() async {
-    Source source = addSource(r'''
-import 'dart:async';
-class A {
-  Future<int> m() async {
-    return 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnOfInvalidType_dynamic() async {
-    Source source = addSource(r'''
-class TypeError {}
-class A {
-  static void testLogicalOp() {
-    testOr(a, b, onTypeError) {
-      try {
-        return a || b;
-      } on TypeError catch (t) {
-        return onTypeError;
-      }
-    }
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnOfInvalidType_subtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-A f(B b) { return b; }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnOfInvalidType_supertype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-B f(A a) { return a; }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnOfInvalidType_typeParameter_18468() async {
-    // https://code.google.com/p/dart/issues/detail?id=18468
-    //
-    // This test verifies that the type of T is more specific than Type,
-    // where T is a type parameter and Type is the type Type from
-    // core, this particular test case comes from issue 18468.
-    //
-    // A test cannot be added to TypeParameterTypeImplTest since the types
-    // returned out of the TestTypeProvider don't have a mock 'dart.core'
-    // enclosing library element.
-    // See TypeParameterTypeImpl.isMoreSpecificThan().
-    Source source = addSource(r'''
-class Foo<T> {
-  Type get t => T;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source);
-    verify([source]);
-  }
-
-  test_returnOfInvalidType_void() async {
-    Source source = addSource(r'''
-void f1() {}
-void f2() { return; }
-void f3() { return null; }
-void f4() { return g1(); }
-void f5() { return g2(); }
-void f6() => throw 42;
-g1() {}
-void g2() {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnWithoutValue_noReturnType() async {
-    Source source = addSource("f() { return; }");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_returnWithoutValue_void() async {
-    Source source = addSource("void f() { return; }");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_reversedTypeArguments() async {
-    Source source = addSource(r'''
-class Codec<S1, T1> {
-  Codec<T1, S1> get inverted => new _InvertedCodec<T1, S1>(this);
-}
-class _InvertedCodec<T2, S2> extends Codec<T2, S2> {
-  _InvertedCodec(Codec<S2, T2> codec);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_sharedDeferredPrefix() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-f1() {}''',
-      r'''
-library lib2;
-f2() {}''',
-      r'''
-library lib3;
-f3() {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-import 'lib2.dart' as lib;
-import 'lib3.dart' as lib;
-main() { lib1.f1(); lib.f2(); lib.f3(); }'''
-    ], <ErrorCode>[]);
-  }
-
-  test_staticAccessToInstanceMember_annotation() async {
-    Source source = addSource(r'''
-class A {
-  const A.name();
-}
-@A.name()
-main() {
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_staticAccessToInstanceMember_method() async {
-    Source source = addSource(r'''
-class A {
-  static m() {}
-}
-main() {
-  A.m;
-  A.m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_staticAccessToInstanceMember_propertyAccess_field() async {
-    Source source = addSource(r'''
-class A {
-  static var f;
-}
-main() {
-  A.f;
-  A.f = 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_staticAccessToInstanceMember_propertyAccess_propertyAccessor() async {
-    Source source = addSource(r'''
-class A {
-  static get f => 42;
-  static set f(x) {}
-}
-main() {
-  A.f;
-  A.f = 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_superInInvalidContext() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  B() {
-    var v = super.m();
-  }
-  n() {
-    var v = super.m();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeAliasCannotReferenceItself_returnClass_withTypeAlias() async {
-    Source source = addSource(r'''
-typedef B A();
-class B {
-  A a;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeArgument_boundToFunctionType() async {
-    Source source = addSource("class A<T extends void Function(T)>{}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeArgumentNotMatchingBounds_const() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class G<E extends A> {
-  const G();
-}
-f() { return const G<B>(); }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class G<E extends A> {}
-f() { return new G<B>(); }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-typedef F<T extends A>();
-F<A> fa;
-F<B> fb;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound2() async {
-    Source source = addSource(r'''
-class MyClass<T> {}
-typedef MyFunction<T, P extends MyClass<T>>();
-class A<T, P extends MyClass<T>> {
-  MyFunction<T, P> f;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_noBound() async {
-    Source source = addSource(r'''
-typedef F<T>();
-F<int> f1;
-F<String> f2;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_booleanAnd_useInRight() async {
-    Source source = addSource(r'''
-main(Object p) {
-  p is String && p.length != 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() async {
-    Source source = addSource(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  (p is String) && callMe(() { p.length; });
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_conditional_issue14655() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C extends B {
-  mc() {}
-}
-print(_) {}
-main(A p) {
-  (p is C) && (print(() => p) && (p is B)) ? p.mc() : p = null;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_conditional_useInThen() async {
-    Source source = addSource(r'''
-main(Object p) {
-  p is String ? p.length : 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() async {
-    Source source = addSource(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  p is String ? callMe(() { p.length; }) : 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_functionType_arg_ignoreIfNotMoreSpecific() async {
-    Source source = addSource(r'''
-typedef FuncB(B b);
-typedef FuncA(A a);
-class A {}
-class B {}
-main(FuncA f) {
-  if (f is FuncB) {
-    f(new A());
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_functionType_return_ignoreIfNotMoreSpecific() async {
-    Source source = addSource(r'''
-class A {}
-typedef FuncAtoDyn(A a);
-typedef FuncDynToDyn(x);
-main(FuncAtoDyn f) {
-  if (f is FuncDynToDyn) {
-    A a = f(new A());
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_functionType_return_voidToDynamic() async {
-    Source source = addSource(r'''
-typedef FuncDynToDyn(x);
-typedef void FuncDynToVoid(x);
-class A {}
-main(FuncDynToVoid f) {
-  if (f is FuncDynToDyn) {
-    A a = f(null);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_accessedInClosure_noAssignment() async {
-    Source source = addSource(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  if (p is String) {
-    callMe(() {
-      p.length;
-    });
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_extends_moreSpecific() async {
-    Source source = addSource(r'''
-class V {}
-class VP extends V {}
-class A<T> {}
-class B<S> extends A<S> {
-  var b;
-}
-
-main(A<V> p) {
-  if (p is B<VP>) {
-    p.b;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_hasAssignment_outsideAfter() async {
-    Source source = addSource(r'''
-main(Object p) {
-  if (p is String) {
-    p.length;
-  }
-  p = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_hasAssignment_outsideBefore() async {
-    Source source = addSource(r'''
-main(Object p, Object p2) {
-  p = p2;
-  if (p is String) {
-    p.length;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_implements_moreSpecific() async {
-    Source source = addSource(r'''
-class V {}
-class VP extends V {}
-class A<T> {}
-class B<S> implements A<S> {
-  var b;
-}
-
-main(A<V> p) {
-  if (p is B<VP>) {
-    p.b;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_inClosure_assignedAfter_inSameFunction() async {
-    Source source = addSource(r'''
-main() {
-  f(Object p) {
-    if (p is String) {
-      p.length;
-    }
-    p = 0;
-  };
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_is_and_left() async {
-    Source source = addSource(r'''
-bool tt() => true;
-main(Object p) {
-  if (p is String && tt()) {
-    p.length;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_is_and_right() async {
-    Source source = addSource(r'''
-bool tt() => true;
-main(Object p) {
-  if (tt() && p is String) {
-    p.length;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_is_and_subThenSuper() async {
-    Source source = addSource(r'''
-class A {
-  var a;
-}
-class B extends A {
-  var b;
-}
-main(Object p) {
-  if (p is B && p is A) {
-    p.a;
-    p.b;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_is_parenthesized() async {
-    Source source = addSource(r'''
-main(Object p) {
-  if ((p is String)) {
-    p.length;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_if_is_single() async {
-    Source source = addSource(r'''
-main(Object p) {
-  if (p is String) {
-    p.length;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typePromotion_parentheses() async {
-    Source source = addSource(r'''
-main(Object p) {
-  (p is String) ? p.length : 0;
-  (p) is String ? p.length : 0;
-  ((p)) is String ? p.length : 0;
-  ((p) is String) ? p.length : 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeType_class() async {
-    Source source = addSource(r'''
-class C {}
-f(Type t) {}
-main() {
-  f(C);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeType_class_prefixed() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-class C {}''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-f(Type t) {}
-main() {
-  f(p.C);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeType_functionTypeAlias() async {
-    Source source = addSource(r'''
-typedef F();
-f(Type t) {}
-main() {
-  f(F);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_typeType_functionTypeAlias_prefixed() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-typedef F();''');
-    Source source = addSource(r'''
-import 'lib.dart' as p;
-f(Type t) {}
-main() {
-  f(p.F);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_explicit_named() async {
-    Source source = addSource(r'''
-class A {
-  A.named() {}
-}
-class B extends A {
-  B() : super.named();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_explicit_unnamed() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-class B extends A {
-  B() : super();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_hasOptionalParameters() async {
-    Source source = addSource(r'''
-class A {
-  A([p]) {}
-}
-class B extends A {
-  B();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_implicit() async {
-    Source source = addSource(r'''
-class A {
-  A() {}
-}
-class B extends A {
-  B();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedConstructorInInitializer_redirecting() async {
-    Source source = addSource(r'''
-class Foo {
-  Foo.ctor();
-}
-class Bar extends Foo {
-  Bar() : this.ctor();
-  Bar.ctor() : super.ctor();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedGetter_static_conditionalAccess() async {
-    // The conditional access operator '?.' can be used to access static
-    // fields.
-    Source source = addSource('''
-class A {
-  static var x;
-}
-var a = A?.x;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedGetter_typeSubstitution() async {
-    Source source = addSource(r'''
-class A<E> {
-  E element;
-}
-class B extends A<List> {
-  m() {
-    element.last;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedIdentifier_synthetic_whenExpression() async {
-    Source source = addSource(r'''
-print(x) {}
-main() {
-  print(is String);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ParserErrorCode.MISSING_IDENTIFIER]);
-  }
-
-  test_undefinedIdentifier_synthetic_whenMethodName() async {
-    Source source = addSource(r'''
-print(x) {}
-main(int p) {
-  p.();
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      ParserErrorCode.MISSING_IDENTIFIER,
-      ParserErrorCode.MISSING_IDENTIFIER,
-      StaticTypeWarningCode.UNDEFINED_GETTER
-    ]);
-  }
-
-  test_undefinedMethod_functionExpression_callMethod() async {
-    Source source = addSource(r'''
-main() {
-  (() => null).call();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    // A call to verify(source) fails as '.call()' isn't resolved.
-  }
-
-  test_undefinedMethod_functionExpression_directCall() async {
-    Source source = addSource(r'''
-main() {
-  (() => null)();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    // A call to verify(source) fails as '(() => null)()' isn't resolved.
-  }
-
-  test_undefinedMethod_static_conditionalAccess() async {
-    // The conditional access operator '?.' can be used to access static
-    // methods.
-    Source source = addSource('''
-class A {
-  static void m() {}
-}
-f() { A?.m(); }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedOperator_index() async {
-    Source source = addSource(r'''
-class A {
-  operator [](a) {}
-  operator []=(a, b) {}
-}
-f(A a) {
-  a[0];
-  a[0] = 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedOperator_tilde() async {
-    Source source = addSource(r'''
-const A = 3;
-const B = ~((1 << A) - 1);''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedSetter_importWithPrefix() async {
-    addNamedSource("/lib.dart", r'''
-library lib;
-set y(int value) {}''');
-    Source source = addSource(r'''
-import 'lib.dart' as x;
-main() {
-  x.y = 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedSetter_static_conditionalAccess() async {
-    // The conditional access operator '?.' can be used to access static
-    // fields.
-    Source source = addSource('''
-class A {
-  static var x;
-}
-f() { A?.x = 1; }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedSuperMethod_field() async {
-    Source source = addSource(r'''
-class A {
-  var m;
-}
-class B extends A {
-  f() {
-    super.m();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_undefinedSuperMethod_method() async {
-    Source source = addSource(r'''
-class A {
-  m() {}
-}
-class B extends A {
-  f() {
-    super.m();
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unusedShownName_unresolved() async {
-    Source source = addSource(r'''
-import 'dart:math' show max, FooBar;
-main() {
-  print(max(1, 2));
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.UNDEFINED_SHOWN_NAME]);
-  }
-
-  test_uriDoesNotExist_dll() async {
-    addNamedSource("/lib.dll", "");
-    Source source = addSource("import 'dart-ext:lib';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_uriDoesNotExist_dylib() async {
-    addNamedSource("/lib.dylib", "");
-    Source source = addSource("import 'dart-ext:lib';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_uriDoesNotExist_so() async {
-    addNamedSource("/lib.so", "");
-    Source source = addSource("import 'dart-ext:lib';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  Future test_useDynamicWithPrefix() async {
-    final Source source = addSource('''
-import 'dart:core' as core;
-
-core.dynamic dynamicVariable;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForOperator1() async {
-    await _check_wrongNumberOfParametersForOperator1("<");
-    await _check_wrongNumberOfParametersForOperator1(">");
-    await _check_wrongNumberOfParametersForOperator1("<=");
-    await _check_wrongNumberOfParametersForOperator1(">=");
-    await _check_wrongNumberOfParametersForOperator1("+");
-    await _check_wrongNumberOfParametersForOperator1("/");
-    await _check_wrongNumberOfParametersForOperator1("~/");
-    await _check_wrongNumberOfParametersForOperator1("*");
-    await _check_wrongNumberOfParametersForOperator1("%");
-    await _check_wrongNumberOfParametersForOperator1("|");
-    await _check_wrongNumberOfParametersForOperator1("^");
-    await _check_wrongNumberOfParametersForOperator1("&");
-    await _check_wrongNumberOfParametersForOperator1("<<");
-    await _check_wrongNumberOfParametersForOperator1(">>");
-    await _check_wrongNumberOfParametersForOperator1("[]");
-  }
-
-  test_wrongNumberOfParametersForOperator_index() async {
-    Source source = addSource(r'''
-class A {
-  operator []=(a, b) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_wrongNumberOfParametersForOperator_minus() async {
-    await _check_wrongNumberOfParametersForOperator("-", "");
-    await _check_wrongNumberOfParametersForOperator("-", "a");
-  }
-
-  test_wrongNumberOfParametersForSetter() async {
-    Source source = addSource(r'''
-class A {
-  set x(a) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_async_to_dynamic_type() async {
-    Source source = addSource('''
-dynamic f() async* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_async_to_generic_type() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream f() async* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_async_to_parameterized_type() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream<int> f() async* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_async_to_untyped() async {
-    Source source = addSource('''
-f() async* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_async_dynamic_to_dynamic() async {
-    Source source = addSource('''
-f() async* {
-  yield* g();
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_async_dynamic_to_stream() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream f() async* {
-  yield* g();
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_async_dynamic_to_typed_stream() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream<int> f() async* {
-  yield* g();
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_async_stream_to_dynamic() async {
-    Source source = addSource('''
-import 'dart:async';
-f() async* {
-  yield* g();
-}
-Stream g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_async_typed_stream_to_dynamic() async {
-    Source source = addSource('''
-import 'dart:async';
-f() async* {
-  yield* g();
-}
-Stream<int> g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_async_typed_stream_to_typed_stream() async {
-    Source source = addSource('''
-import 'dart:async';
-Stream<int> f() async* {
-  yield* g();
-}
-Stream<int> g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_sync_dynamic_to_dynamic() async {
-    Source source = addSource('''
-f() sync* {
-  yield* g();
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_sync_dynamic_to_iterable() async {
-    Source source = addSource('''
-Iterable f() sync* {
-  yield* g();
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_sync_dynamic_to_typed_iterable() async {
-    Source source = addSource('''
-Iterable<int> f() sync* {
-  yield* g();
-}
-g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_sync_iterable_to_dynamic() async {
-    Source source = addSource('''
-f() sync* {
-  yield* g();
-}
-Iterable g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_sync_typed_iterable_to_dynamic() async {
-    Source source = addSource('''
-f() sync* {
-  yield* g();
-}
-Iterable<int> g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_each_sync_typed_iterable_to_typed_iterable() async {
-    Source source = addSource('''
-Iterable<int> f() sync* {
-  yield* g();
-}
-Iterable<int> g() => null;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_sync_to_dynamic_type() async {
-    Source source = addSource('''
-dynamic f() sync* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_sync_to_generic_type() async {
-    Source source = addSource('''
-Iterable f() sync* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_sync_to_parameterized_type() async {
-    Source source = addSource('''
-Iterable<int> f() sync* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yield_sync_to_untyped() async {
-    Source source = addSource('''
-f() sync* {
-  yield 3;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yieldInNonGenerator_asyncStar() async {
-    Source source = addSource(r'''
-f() async* {
-  yield 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_yieldInNonGenerator_syncStar() async {
-    Source source = addSource(r'''
-f() sync* {
-  yield 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  Future<void> _check_wrongNumberOfParametersForOperator(
-      String name, String parameters) async {
-    Source source = addSource("""
-class A {
-  operator $name($parameters) {}
-}""");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  Future<void> _check_wrongNumberOfParametersForOperator1(String name) async {
-    await _check_wrongNumberOfParametersForOperator(name, "a");
-  }
-}
diff --git a/pkg/analyzer/test/generated/non_hint_code.dart b/pkg/analyzer/test/generated/non_hint_code.dart
new file mode 100644
index 0000000..206e154
--- /dev/null
+++ b/pkg/analyzer/test/generated/non_hint_code.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.
+
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+
+import 'resolver_test_case.dart';
+
+abstract class NonHintCodeTest extends ResolverTestCase {
+  @override
+  void reset() {
+    super.resetWith(packages: [
+      [
+        'meta',
+        r'''
+library meta;
+
+const _AlwaysThrows alwaysThrows = const _AlwaysThrows();
+const _Literal literal = const _Literal();
+
+class _AlwaysThrows {
+  const _AlwaysThrows();
+}
+class _Literal {
+  const _Literal();
+}
+'''
+      ]
+    ]);
+  }
+
+  test_async_future_object_without_return() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<Object> f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [HintCode.MISSING_RETURN]);
+    verify([source]);
+  }
+
+  test_deadCode_afterForEachWithBreakLabel() async {
+    Source source = addSource('''
+f() {
+  named: {
+    for (var x in [1]) {
+      if (x == null)
+        break named;
+    }
+    return;
+  }
+  print('not dead');
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_afterForWithBreakLabel() async {
+    Source source = addSource('''
+f() {
+  named: {
+    for (int i = 0; i < 7; i++) {
+      if (i == null)
+        break named;
+    }
+    return;
+  }
+  print('not dead');
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_afterTryCatch() async {
+    Source source = addSource('''
+main() {
+  try {
+    return f();
+  } catch (e) {
+    print(e);
+  }
+  print('not dead');
+}
+f() {
+  throw 'foo';
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_conditionalElse_debugConst() async {
+    Source source = addSource(r'''
+const bool DEBUG = true;
+f() {
+  DEBUG ? 1 : 2;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_conditionalIf_debugConst() async {
+    Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+  DEBUG ? 1 : 2;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_else() async {
+    Source source = addSource(r'''
+const bool DEBUG = true;
+f() {
+  if(DEBUG) {} else {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() async {
+    Source source = addSource(r'''
+class A {
+  static const bool DEBUG = false;
+}
+f() {
+  if(A.DEBUG) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() async {
+    Source source = addSource(r'''
+library L;
+import 'lib2.dart';
+f() {
+  if(A.DEBUG) {}
+}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+class A {
+  static const bool DEBUG = false;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_if_debugConst_propertyAccessor() async {
+    Source source = addSource(r'''
+library L;
+import 'lib2.dart' as LIB;
+f() {
+  if(LIB.A.DEBUG) {}
+}''');
+    addNamedSource("/lib2.dart", r'''
+library lib2;
+class A {
+  static const bool DEBUG = false;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_if_debugConst_simpleIdentifier() async {
+    Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+  if(DEBUG) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadBlock_while_debugConst() async {
+    Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+  while(DEBUG) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadCatch_onCatchSubtype() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+f() {
+  try {} on B catch (e) {} on A catch (e) {} catch (e) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadFinalBreakInCase() async {
+    Source source = addSource(r'''
+f() {
+  switch (true) {
+  case true:
+    try {
+      int a = 1;
+    } finally {
+      return;
+    }
+    break;
+  default:
+    break;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadOperandLHS_and_debugConst() async {
+    Source source = addSource(r'''
+const bool DEBUG = false;
+f() {
+  bool b = DEBUG && false;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_deadOperandLHS_or_debugConst() async {
+    Source source = addSource(r'''
+const bool DEBUG = true;
+f() {
+  bool b = DEBUG || true;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_deadCode_statementAfterIfWithoutElse() async {
+    Source source = addSource(r'''
+f() {
+  if (1 < 0) {
+    return;
+  }
+  int a = 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_duplicateImport_as() async {
+    Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' as one;
+A a;
+one.A a2;''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class A {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_duplicateImport_hide() async {
+    Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' hide A;
+A a;
+B b;''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class A {}
+class B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_duplicateImport_show() async {
+    Source source = addSource(r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' show A;
+A a;
+B b;''');
+    addNamedSource("/lib1.dart", r'''
+library lib1;
+class A {}
+class B {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_importDeferredLibraryWithLoadFunction() async {
+    await resolveWithErrors(<String>[
+      r'''
+library lib1;
+f() {}''',
+      r'''
+library root;
+import 'lib1.dart' deferred as lib1;
+main() { lib1.f(); }'''
+    ], const <ErrorCode>[]);
+  }
+
+  test_issue20904BuggyTypePromotionAtIfJoin_1() async {
+    // https://code.google.com/p/dart/issues/detail?id=20904
+    Source source = addSource(r'''
+f(var message, var dynamic_) {
+  if (message is Function) {
+    message = dynamic_;
+  }
+  int s = message;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_issue20904BuggyTypePromotionAtIfJoin_3() async {
+    // https://code.google.com/p/dart/issues/detail?id=20904
+    Source source = addSource(r'''
+f(var message) {
+  var dynamic_;
+  if (message is Function) {
+    message = dynamic_;
+  } else {
+    return;
+  }
+  int s = message;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_issue20904BuggyTypePromotionAtIfJoin_4() async {
+    // https://code.google.com/p/dart/issues/detail?id=20904
+    Source source = addSource(r'''
+f(var message) {
+  if (message is Function) {
+    message = '';
+  } else {
+    return;
+  }
+  String s = message;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingReturn_alwaysThrows() async {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+
+@alwaysThrows
+void a() {
+  throw 'msg';
+}
+
+int f() {
+  a();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingReturn_emptyFunctionBody() async {
+    Source source = addSource(r'''
+abstract class A {
+  int m();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingReturn_expressionFunctionBody() async {
+    Source source = addSource("int f() => 0;");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingReturn_futureVoidReturnType() async {
+    Source source = addSource('''
+import 'dart:async';
+Future<void> f() async {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingReturn_noReturnType() async {
+    Source source = addSource("f() {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_missingReturn_voidReturnType() async {
+    Source source = addSource("void f() {}");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nullAwareInCondition_for_noCondition() async {
+    Source source = addSource(r'''
+m(x) {
+  for (var v = x; ; v++) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nullAwareInCondition_if_notTopLevel() async {
+    Source source = addSource(r'''
+m(x) {
+  if (x?.y == null) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideEqualsButNotHashCode() async {
+    Source source = addSource(r'''
+class A {
+  bool operator ==(x) { return x; }
+  get hashCode => 0;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidLiteralAnnotation_constConstructor() async {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstCallToLiteralConstructor_constCreation() async {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+
+void main() {
+  const a = const A();
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstCallToLiteralConstructor_constContextCreation() async {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+
+void main() {
+  const a = A();
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_nonConstCallToLiteralConstructor_unconstableCreation() async {
+    Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A(List list);
+}
+
+void main() {
+  var a = A(new List());
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingField_inInterface() async {
+    Source source = addSource(r'''
+class A {
+  int get a => 0;
+  void set b(_) {}
+  int c;
+}
+class B implements A {
+  @override
+  final int a = 1;
+  @override
+  int b;
+  @override
+  int c;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+      source,
+      [CompileTimeErrorCode.INVALID_OVERRIDE],
+    );
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingField_inSuperclass() async {
+    Source source = addSource(r'''
+class A {
+  int get a => 0;
+  void set b(_) {}
+  int c;
+}
+class B extends A {
+  @override
+  final int a = 1;
+  @override
+  int b;
+  @override
+  int c;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(
+      source,
+      [CompileTimeErrorCode.INVALID_OVERRIDE],
+    );
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingGetter_inInterface() async {
+    Source source = addSource(r'''
+class A {
+  int get m => 0;
+}
+class B implements A {
+  @override
+  int get m => 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingGetter_inSuperclass() async {
+    Source source = addSource(r'''
+class A {
+  int get m => 0;
+}
+class B extends A {
+  @override
+  int get m => 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingMethod_inInterface() async {
+    Source source = addSource(r'''
+class A {
+  int m() => 0;
+}
+class B implements A {
+  @override
+  int m() => 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingMethod_inInterfaces() async {
+    Source source = addSource(r'''
+abstract class I {
+  void foo(int _);
+}
+
+abstract class J {
+  void foo(String _);
+}
+
+class C implements I, J {
+  @override
+  void foo(Object _) {}
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingMethod_inSuperclass() async {
+    Source source = addSource(r'''
+class A {
+  int m() => 0;
+}
+class B extends A {
+  @override
+  int m() => 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingMethod_inSuperclass_abstract() async {
+    Source source = addSource(r'''
+abstract class A {
+  int m();
+}
+class B extends A {
+  @override
+  int m() => 1;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingSetter_inInterface() async {
+    Source source = addSource(r'''
+class A {
+  set m(int x) {}
+}
+class B implements A {
+  @override
+  set m(int x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_overrideOnNonOverridingSetter_inSuperclass() async {
+    Source source = addSource(r'''
+class A {
+  set m(int x) {}
+}
+class B extends A {
+  @override
+  set m(int x) {}
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_propagatedFieldType() async {
+    Source source = addSource(r'''
+class A { }
+class X<T> {
+  final x = new List<T>();
+}
+class Z {
+  final X<A> y = new X<A>();
+  foo() {
+    y.x.add(new A());
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_proxy_annotation_prefixed() async {
+    Source source = addSource(r'''
+library L;
+@proxy
+class A {}
+f(var a) {
+  a = new A();
+  a.m();
+  var x = a.g;
+  a.s = 1;
+  var y = a + a;
+  a++;
+  ++a;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_proxy_annotation_prefixed2() async {
+    Source source = addSource(r'''
+library L;
+@proxy
+class A {}
+class B {
+  f(var a) {
+    a = new A();
+    a.m();
+    var x = a.g;
+    a.s = 1;
+    var y = a + a;
+    a++;
+    ++a;
+  }
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_proxy_annotation_prefixed3() async {
+    Source source = addSource(r'''
+library L;
+class B {
+  f(var a) {
+    a = new A();
+    a.m();
+    var x = a.g;
+    a.s = 1;
+    var y = a + a;
+    a++;
+    ++a;
+  }
+}
+@proxy
+class A {}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_undefinedMethod_assignmentExpression_inSubtype() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {
+  operator +(B b) {return new B();}
+}
+f(var a, var a2) {
+  a = new A();
+  a2 = new A();
+  a += a2;
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_undefinedMethod_dynamic() async {
+    Source source = addSource(r'''
+class D<T extends dynamic> {
+  fieldAccess(T t) => t.abc;
+  methodAccess(T t) => t.xyz(1, 2, 'three');
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_undefinedMethod_unionType_all() async {
+    Source source = addSource(r'''
+class A {
+  int m(int x) => 0;
+}
+class B {
+  String m() => '0';
+}
+f(A a, B b) {
+  var ab;
+  if (0 < 1) {
+    ab = a;
+  } else {
+    ab = b;
+  }
+  ab.m();
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_undefinedMethod_unionType_some() async {
+    Source source = addSource(r'''
+class A {
+  int m(int x) => 0;
+}
+class B {}
+f(A a, B b) {
+  var ab;
+  if (0 < 1) {
+    ab = a;
+  } else {
+    ab = b;
+  }
+  ab.m(0);
+}''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+}
+
+class PubSuggestionCodeTest extends ResolverTestCase {
+  // TODO(brianwilkerson) The tests in this class are not being run, and all but
+  //  the first would fail. We should implement these checks and enable the
+  //  tests.
+  test_import_package() async {
+    Source source = addSource("import 'package:somepackage/other.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+  }
+
+  test_import_packageWithDotDot() async {
+    Source source = addSource("import 'package:somepackage/../other.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+    ]);
+  }
+
+  test_import_packageWithLeadingDotDot() async {
+    Source source = addSource("import 'package:../other.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+    ]);
+  }
+
+  test_import_referenceIntoLibDirectory() async {
+    addNamedSource("/myproj/pubspec.yaml", "");
+    addNamedSource("/myproj/lib/other.dart", "");
+    Source source =
+        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
+  }
+
+  test_import_referenceIntoLibDirectory_no_pubspec() async {
+    addNamedSource("/myproj/lib/other.dart", "");
+    Source source =
+        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_import_referenceOutOfLibDirectory() async {
+    addNamedSource("/myproj/pubspec.yaml", "");
+    addNamedSource("/myproj/web/other.dart", "");
+    Source source =
+        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
+  }
+
+  test_import_referenceOutOfLibDirectory_no_pubspec() async {
+    addNamedSource("/myproj/web/other.dart", "");
+    Source source =
+        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_import_valid_inside_lib1() async {
+    addNamedSource("/myproj/pubspec.yaml", "");
+    addNamedSource("/myproj/lib/other.dart", "");
+    Source source =
+        addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_import_valid_inside_lib2() async {
+    addNamedSource("/myproj/pubspec.yaml", "");
+    addNamedSource("/myproj/lib/bar/other.dart", "");
+    Source source = addNamedSource(
+        "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_import_valid_outside_lib() async {
+    addNamedSource("/myproj/pubspec.yaml", "");
+    addNamedSource("/myproj/web/other.dart", "");
+    Source source =
+        addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+}
diff --git a/pkg/analyzer/test/generated/non_hint_code_driver_test.dart b/pkg/analyzer/test/generated/non_hint_code_driver_test.dart
index d13f558..c7c53cf 100644
--- a/pkg/analyzer/test/generated/non_hint_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_driver_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'non_hint_code_test.dart';
+import 'non_hint_code.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
deleted file mode 100644
index bf270f1..0000000
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ /dev/null
@@ -1,1116 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(NonHintCodeTest);
-  });
-}
-
-@reflectiveTest
-class NonHintCodeTest extends ResolverTestCase {
-  @override
-  void reset() {
-    super.resetWith(packages: [
-      [
-        'meta',
-        r'''
-library meta;
-
-const _AlwaysThrows alwaysThrows = const _AlwaysThrows();
-const _Literal literal = const _Literal();
-
-class _AlwaysThrows {
-  const _AlwaysThrows();
-}
-class _Literal {
-  const _Literal();
-}
-'''
-      ]
-    ]);
-  }
-
-  test_async_future_object_without_return() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<Object> f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_RETURN]);
-    verify([source]);
-  }
-
-  test_deadCode_afterForEachWithBreakLabel() async {
-    Source source = addSource('''
-f() {
-  named: {
-    for (var x in [1]) {
-      if (x == null)
-        break named;
-    }
-    return;
-  }
-  print('not dead');
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_afterForWithBreakLabel() async {
-    Source source = addSource('''
-f() {
-  named: {
-    for (int i = 0; i < 7; i++) {
-      if (i == null)
-        break named;
-    }
-    return;
-  }
-  print('not dead');
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_afterTryCatch() async {
-    Source source = addSource('''
-main() {
-  try {
-    return f();
-  } catch (e) {
-    print(e);
-  }
-  print('not dead');
-}
-f() {
-  throw 'foo';
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_conditionalElse_debugConst() async {
-    Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
-  DEBUG ? 1 : 2;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_conditionalIf_debugConst() async {
-    Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
-  DEBUG ? 1 : 2;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_else() async {
-    Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
-  if(DEBUG) {} else {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_if_debugConst_prefixedIdentifier() async {
-    Source source = addSource(r'''
-class A {
-  static const bool DEBUG = false;
-}
-f() {
-  if(A.DEBUG) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_if_debugConst_prefixedIdentifier2() async {
-    Source source = addSource(r'''
-library L;
-import 'lib2.dart';
-f() {
-  if(A.DEBUG) {}
-}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-class A {
-  static const bool DEBUG = false;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_if_debugConst_propertyAccessor() async {
-    Source source = addSource(r'''
-library L;
-import 'lib2.dart' as LIB;
-f() {
-  if(LIB.A.DEBUG) {}
-}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
-class A {
-  static const bool DEBUG = false;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_if_debugConst_simpleIdentifier() async {
-    Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
-  if(DEBUG) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadBlock_while_debugConst() async {
-    Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
-  while(DEBUG) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadCatch_onCatchSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-f() {
-  try {} on B catch (e) {} on A catch (e) {} catch (e) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadFinalBreakInCase() async {
-    Source source = addSource(r'''
-f() {
-  switch (true) {
-  case true:
-    try {
-      int a = 1;
-    } finally {
-      return;
-    }
-    break;
-  default:
-    break;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadOperandLHS_and_debugConst() async {
-    Source source = addSource(r'''
-const bool DEBUG = false;
-f() {
-  bool b = DEBUG && false;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_deadOperandLHS_or_debugConst() async {
-    Source source = addSource(r'''
-const bool DEBUG = true;
-f() {
-  bool b = DEBUG || true;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_deadCode_statementAfterIfWithoutElse() async {
-    Source source = addSource(r'''
-f() {
-  if (1 < 0) {
-    return;
-  }
-  int a = 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_duplicateImport_as() async {
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' as one;
-A a;
-one.A a2;''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class A {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_duplicateImport_hide() async {
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' hide A;
-A a;
-B b;''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class A {}
-class B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_duplicateImport_show() async {
-    Source source = addSource(r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' show A;
-A a;
-B b;''');
-    addNamedSource("/lib1.dart", r'''
-library lib1;
-class A {}
-class B {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_importDeferredLibraryWithLoadFunction() async {
-    await resolveWithErrors(<String>[
-      r'''
-library lib1;
-f() {}''',
-      r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }'''
-    ], const <ErrorCode>[]);
-  }
-
-  test_issue20904BuggyTypePromotionAtIfJoin_1() async {
-    // https://code.google.com/p/dart/issues/detail?id=20904
-    Source source = addSource(r'''
-f(var message, var dynamic_) {
-  if (message is Function) {
-    message = dynamic_;
-  }
-  int s = message;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_issue20904BuggyTypePromotionAtIfJoin_3() async {
-    // https://code.google.com/p/dart/issues/detail?id=20904
-    Source source = addSource(r'''
-f(var message) {
-  var dynamic_;
-  if (message is Function) {
-    message = dynamic_;
-  } else {
-    return;
-  }
-  int s = message;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_issue20904BuggyTypePromotionAtIfJoin_4() async {
-    // https://code.google.com/p/dart/issues/detail?id=20904
-    Source source = addSource(r'''
-f(var message) {
-  if (message is Function) {
-    message = '';
-  } else {
-    return;
-  }
-  String s = message;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingReturn_alwaysThrows() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-@alwaysThrows
-void a() {
-  throw 'msg';
-}
-
-int f() {
-  a();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingReturn_emptyFunctionBody() async {
-    Source source = addSource(r'''
-abstract class A {
-  int m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingReturn_expressionFunctionBody() async {
-    Source source = addSource("int f() => 0;");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingReturn_futureVoidReturnType() async {
-    Source source = addSource('''
-import 'dart:async';
-Future<void> f() async {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingReturn_noReturnType() async {
-    Source source = addSource("f() {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_missingReturn_voidReturnType() async {
-    Source source = addSource("void f() {}");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nullAwareInCondition_for_noCondition() async {
-    Source source = addSource(r'''
-m(x) {
-  for (var v = x; ; v++) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nullAwareInCondition_if_notTopLevel() async {
-    Source source = addSource(r'''
-m(x) {
-  if (x?.y == null) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideEqualsButNotHashCode() async {
-    Source source = addSource(r'''
-class A {
-  bool operator ==(x) { return x; }
-  get hashCode => 0;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidLiteralAnnotation_constConstructor() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstCallToLiteralConstructor_constCreation() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-
-void main() {
-  const a = const A();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstCallToLiteralConstructor_constContextCreation() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-
-void main() {
-  const a = A();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_nonConstCallToLiteralConstructor_unconstableCreation() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A(List list);
-}
-
-void main() {
-  var a = A(new List());
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingField_inInterface() async {
-    Source source = addSource(r'''
-class A {
-  int get a => 0;
-  void set b(_) {}
-  int c;
-}
-class B implements A {
-  @override
-  final int a = 1;
-  @override
-  int b;
-  @override
-  int c;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
-      [CompileTimeErrorCode.INVALID_OVERRIDE],
-    );
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingField_inSuperclass() async {
-    Source source = addSource(r'''
-class A {
-  int get a => 0;
-  void set b(_) {}
-  int c;
-}
-class B extends A {
-  @override
-  final int a = 1;
-  @override
-  int b;
-  @override
-  int c;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
-      [CompileTimeErrorCode.INVALID_OVERRIDE],
-    );
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingGetter_inInterface() async {
-    Source source = addSource(r'''
-class A {
-  int get m => 0;
-}
-class B implements A {
-  @override
-  int get m => 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingGetter_inSuperclass() async {
-    Source source = addSource(r'''
-class A {
-  int get m => 0;
-}
-class B extends A {
-  @override
-  int get m => 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingMethod_inInterface() async {
-    Source source = addSource(r'''
-class A {
-  int m() => 0;
-}
-class B implements A {
-  @override
-  int m() => 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingMethod_inInterfaces() async {
-    Source source = addSource(r'''
-abstract class I {
-  void foo(int _);
-}
-
-abstract class J {
-  void foo(String _);
-}
-
-class C implements I, J {
-  @override
-  void foo(Object _) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingMethod_inSuperclass() async {
-    Source source = addSource(r'''
-class A {
-  int m() => 0;
-}
-class B extends A {
-  @override
-  int m() => 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingMethod_inSuperclass_abstract() async {
-    Source source = addSource(r'''
-abstract class A {
-  int m();
-}
-class B extends A {
-  @override
-  int m() => 1;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingSetter_inInterface() async {
-    Source source = addSource(r'''
-class A {
-  set m(int x) {}
-}
-class B implements A {
-  @override
-  set m(int x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_overrideOnNonOverridingSetter_inSuperclass() async {
-    Source source = addSource(r'''
-class A {
-  set m(int x) {}
-}
-class B extends A {
-  @override
-  set m(int x) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_propagatedFieldType() async {
-    Source source = addSource(r'''
-class A { }
-class X<T> {
-  final x = new List<T>();
-}
-class Z {
-  final X<A> y = new X<A>();
-  foo() {
-    y.x.add(new A());
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_proxy_annotation_prefixed() async {
-    Source source = addSource(r'''
-library L;
-@proxy
-class A {}
-f(var a) {
-  a = new A();
-  a.m();
-  var x = a.g;
-  a.s = 1;
-  var y = a + a;
-  a++;
-  ++a;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_proxy_annotation_prefixed2() async {
-    Source source = addSource(r'''
-library L;
-@proxy
-class A {}
-class B {
-  f(var a) {
-    a = new A();
-    a.m();
-    var x = a.g;
-    a.s = 1;
-    var y = a + a;
-    a++;
-    ++a;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_proxy_annotation_prefixed3() async {
-    Source source = addSource(r'''
-library L;
-class B {
-  f(var a) {
-    a = new A();
-    a.m();
-    var x = a.g;
-    a.s = 1;
-    var y = a + a;
-    a++;
-    ++a;
-  }
-}
-@proxy
-class A {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedGetter_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  get b => 0;
-}
-f(var a) {
-  if(a is A) {
-    return a.b;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedMethod_assignmentExpression_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator +(B b) {return new B();}
-}
-f(var a, var a2) {
-  a = new A();
-  a2 = new A();
-  a += a2;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedMethod_dynamic() async {
-    Source source = addSource(r'''
-class D<T extends dynamic> {
-  fieldAccess(T t) => t.abc;
-  methodAccess(T t) => t.xyz(1, 2, 'three');
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedMethod_unionType_all() async {
-    Source source = addSource(r'''
-class A {
-  int m(int x) => 0;
-}
-class B {
-  String m() => '0';
-}
-f(A a, B b) {
-  var ab;
-  if (0 < 1) {
-    ab = a;
-  } else {
-    ab = b;
-  }
-  ab.m();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedMethod_unionType_some() async {
-    Source source = addSource(r'''
-class A {
-  int m(int x) => 0;
-}
-class B {}
-f(A a, B b) {
-  var ab;
-  if (0 < 1) {
-    ab = a;
-  } else {
-    ab = b;
-  }
-  ab.m(0);
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedOperator_binaryExpression_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator +(B b) {}
-}
-f(var a) {
-  if(a is A) {
-    a + 1;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_indexBoth_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator [](int index) {}
-}
-f(var a) {
-  if(a is A) {
-    a[0]++;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.UNDEFINED_OPERATOR,
-      StaticTypeWarningCode.UNDEFINED_OPERATOR,
-    ]);
-  }
-
-  test_undefinedOperator_indexGetter_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator [](int index) {}
-}
-f(var a) {
-  if(a is A) {
-    a[0];
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_indexSetter_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator []=(i, v) {}
-}
-f(var a) {
-  if(a is A) {
-    a[0] = 1;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_postfixExpression() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator +(B b) {return new B();}
-}
-f(var a) {
-  if(a is A) {
-    a++;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedOperator_prefixExpression() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  operator +(B b) {return new B();}
-}
-f(var a) {
-  if(a is A) {
-    ++a;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_undefinedSetter_inSubtype() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {
-  set b(x) {}
-}
-f(var a) {
-  if (a is A) {
-    a.b = 0;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
-  }
-
-  test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
-  mmm();
-  noSuchMethod(y) {
-    print(y);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
-  mmm();
-  noSuchMethod(y) {
-    print(y);
-    return super.noSuchMethod(y);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
-  mmm();
-  noSuchMethod(y) => super.hashCode;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_unnecessaryNoSuchMethod_expressionBody_notSuper() async {
-    Source source = addSource(r'''
-class A {
-  noSuchMethod(x) => super.noSuchMethod(x);
-}
-class B extends A {
-  mmm();
-  noSuchMethod(y) => 42;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-}
-
-class PubSuggestionCodeTest extends ResolverTestCase {
-  // TODO(brianwilkerson) The tests in this class are not being run, and all but
-  //  the first would fail. We should implement these checks and enable the
-  //  tests.
-  test_import_package() async {
-    Source source = addSource("import 'package:somepackage/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  test_import_packageWithDotDot() async {
-    Source source = addSource("import 'package:somepackage/../other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
-    ]);
-  }
-
-  test_import_packageWithLeadingDotDot() async {
-    Source source = addSource("import 'package:../other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
-    ]);
-  }
-
-  test_import_referenceIntoLibDirectory() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
-  }
-
-  test_import_referenceIntoLibDirectory_no_pubspec() async {
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_import_referenceOutOfLibDirectory() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
-  }
-
-  test_import_referenceOutOfLibDirectory_no_pubspec() async {
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_import_valid_inside_lib1() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_import_valid_inside_lib2() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/bar/other.dart", "");
-    Source source = addNamedSource(
-        "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_import_valid_outside_lib() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-}
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index 0808c6b..7217806 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -214,6 +214,12 @@
   }
 
   @override
+  void beginForControlFlow(Token awaitToken, Token forToken) {
+    super.beginForControlFlow(awaitToken, forToken);
+    begin('ForControlFlow');
+  }
+
+  @override
   void beginForInBody(Token token) {
     super.beginForInBody(token);
     begin('ForInBody');
@@ -251,6 +257,12 @@
   }
 
   @override
+  void beginIfControlFlow(Token ifToken) {
+    super.beginIfControlFlow(ifToken);
+    begin('IfControlFlow');
+  }
+
+  @override
   void beginLocalFunctionDeclaration(Token token) {
     super.beginLocalFunctionDeclaration(token);
     begin('LocalFunctionDeclaration');
@@ -698,10 +710,21 @@
   }
 
   @override
-  void endForIn(Token awaitToken, Token forToken, Token leftParen,
-      Token inKeyword, Token endToken) {
+  void endForControlFlow(Token token) {
+    end('ForControlFlow');
+    super.endForControlFlow(token);
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    end('ForControlFlow');
+    super.endForInControlFlow(token);
+  }
+
+  @override
+  void endForIn(Token endToken) {
     end('ForStatement');
-    super.endForIn(awaitToken, forToken, leftParen, inKeyword, endToken);
+    super.endForIn(endToken);
   }
 
   @override
@@ -717,11 +740,9 @@
   }
 
   @override
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
+  void endForStatement(Token endToken) {
     end('ForStatement');
-    super.endForStatement(
-        forKeyword, leftParen, leftSeparator, updateExpressionCount, endToken);
+    super.endForStatement(endToken);
   }
 
   @override
@@ -789,6 +810,18 @@
   }
 
   @override
+  void endIfControlFlow(Token token) {
+    end('IfControlFlow');
+    super.endIfControlFlow(token);
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    end('IfControlFlow');
+    super.endIfElseControlFlow(token);
+  }
+
+  @override
   void endIfStatement(Token ifToken, Token elseToken) {
     end('IfStatement');
     super.endIfStatement(ifToken, elseToken);
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index b022212..4809b48 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/src/generated/parser.dart' as analyzer;
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/string_source.dart';
+import 'package:front_end/src/fasta/parser/async_modifier.dart';
 import 'package:front_end/src/fasta/parser/forwarding_listener.dart' as fasta;
 import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
 import 'package:front_end/src/fasta/scanner.dart'
@@ -33,6 +34,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ClassMemberParserTest_Fasta);
+    defineReflectiveTests(CollectionLiteralParserTest);
     defineReflectiveTests(ComplexParserTest_Fasta);
     defineReflectiveTests(ErrorParserTest_Fasta);
     defineReflectiveTests(ExpressionParserTest_Fasta);
@@ -105,6 +107,626 @@
 }
 
 /**
+ * Tests of the fasta parser based on [ExpressionParserTestMixin].
+ */
+@reflectiveTest
+class CollectionLiteralParserTest extends FastaParserTestCase {
+  Expression parseCollectionLiteral(String source,
+      {List<ErrorCode> codes,
+      List<ExpectedError> errors,
+      int expectedEndOffset,
+      bool inAsync = false}) {
+    return parseExpression(source,
+        codes: codes,
+        errors: errors,
+        expectedEndOffset: expectedEndOffset,
+        inAsync: inAsync,
+        parseSetLiterals: true,
+        parseSpreadCollections: true,
+        parseControlFlowCollections: true);
+  }
+
+  void test_listLiteral_for() {
+    ListLiteral2 list = parseCollectionLiteral(
+      '[1, await for (var x in list) 2]',
+      inAsync: true,
+    );
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    ForElement second = list.elements[1];
+    expect(second.awaitKeyword, isNotNull);
+    expect(second.forKeyword.isKeyword, isTrue);
+    expect(second.leftParenthesis.lexeme, '(');
+    expect(second.rightParenthesis.lexeme, ')');
+    ForEachPartsWithDeclaration forLoopParts = second.forLoopParts;
+    DeclaredIdentifier forLoopVar = forLoopParts.loopVariable;
+    expect(forLoopVar.identifier.name, 'x');
+    expect(forLoopParts.inKeyword, isNotNull);
+    SimpleIdentifier iterable = forLoopParts.iterable;
+    expect(iterable.name, 'list');
+  }
+
+  void test_listLiteral_forIf() {
+    ListLiteral2 list = parseCollectionLiteral(
+      '[1, await for (var x in list) if (c) 2]',
+      inAsync: true,
+    );
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    ForElement second = list.elements[1];
+    expect(second.awaitKeyword, isNotNull);
+    expect(second.forKeyword.isKeyword, isTrue);
+    expect(second.leftParenthesis.lexeme, '(');
+    expect(second.rightParenthesis.lexeme, ')');
+    ForEachPartsWithDeclaration forLoopParts = second.forLoopParts;
+    DeclaredIdentifier forLoopVar = forLoopParts.loopVariable;
+    expect(forLoopVar.identifier.name, 'x');
+    expect(forLoopParts.inKeyword, isNotNull);
+    SimpleIdentifier iterable = forLoopParts.iterable;
+    expect(iterable.name, 'list');
+
+    IfElement body = second.body;
+    SimpleIdentifier condition = body.condition;
+    expect(condition.name, 'c');
+    IntegerLiteral thenElement = body.thenElement;
+    expect(thenElement.value, 2);
+  }
+
+  void test_listLiteral_forSpread() {
+    ListLiteral2 list =
+        parseCollectionLiteral('[1, for (int x = 0; x < 10; ++x) ...[2]]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    ForElement second = list.elements[1];
+    expect(second.awaitKeyword, isNull);
+    expect(second.forKeyword.isKeyword, isTrue);
+    expect(second.leftParenthesis.lexeme, '(');
+    expect(second.rightParenthesis.lexeme, ')');
+    ForPartsWithDeclarations forLoopParts = second.forLoopParts;
+    VariableDeclaration forLoopVar = forLoopParts.variables.variables[0];
+    expect(forLoopVar.name.name, 'x');
+    BinaryExpression condition = forLoopParts.condition;
+    IntegerLiteral rightOperand = condition.rightOperand;
+    expect(rightOperand.value, 10);
+    PrefixExpression updater = forLoopParts.updaters[0];
+    SimpleIdentifier updaterOperand = updater.operand;
+    expect(updaterOperand.name, 'x');
+  }
+
+  void test_listLiteral_if() {
+    ListLiteral2 list = parseCollectionLiteral('[1, if (true) 2]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    IntegerLiteral thenElement = second.thenElement;
+    expect(thenElement.value, 2);
+    expect(second.elseElement, isNull);
+  }
+
+  void test_listLiteral_ifElse() {
+    ListLiteral2 list = parseCollectionLiteral('[1, if (true) 2 else 5]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    IntegerLiteral thenElement = second.thenElement;
+    expect(thenElement.value, 2);
+    IntegerLiteral elseElement = second.elseElement;
+    expect(elseElement.value, 5);
+  }
+
+  void test_listLiteral_ifElseFor() {
+    ListLiteral2 list =
+        parseCollectionLiteral('[1, if (true) 2 else for (a in b) 5]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    IntegerLiteral thenElement = second.thenElement;
+    expect(thenElement.value, 2);
+
+    ForElement elseElement = second.elseElement;
+    ForEachPartsWithIdentifier forLoopParts = elseElement.forLoopParts;
+    expect(forLoopParts.identifier.name, 'a');
+
+    IntegerLiteral forValue = elseElement.body;
+    expect(forValue.value, 5);
+  }
+
+  void test_listLiteral_ifElseSpread() {
+    ListLiteral2 list =
+        parseCollectionLiteral('[1, if (true) ...[2] else ...?[5]]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    SpreadElement elseElement = second.elseElement;
+    expect(elseElement.spreadOperator.lexeme, '...?');
+  }
+
+  void test_listLiteral_ifFor() {
+    ListLiteral2 list = parseCollectionLiteral('[1, if (true) for (a in b) 2]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+
+    ForElement thenElement = second.thenElement;
+    ForEachPartsWithIdentifier forLoopParts = thenElement.forLoopParts;
+    expect(forLoopParts.identifier.name, 'a');
+
+    IntegerLiteral forValue = thenElement.body;
+    expect(forValue.value, 2);
+    expect(second.elseElement, isNull);
+  }
+
+  void test_listLiteral_ifSpread() {
+    ListLiteral2 list = parseCollectionLiteral('[1, if (true) ...[2]]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = list.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    expect(second.elseElement, isNull);
+  }
+
+  void test_listLiteral_spread() {
+    ListLiteral2 list = parseCollectionLiteral('[1, ...[2]]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    SpreadElement element = list.elements[1];
+    expect(element.spreadOperator.lexeme, '...');
+    ListLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.elements, hasLength(1));
+  }
+
+  void test_listLiteral_spreadQ() {
+    ListLiteral2 list = parseCollectionLiteral('[1, ...?[2]]');
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+
+    SpreadElement element = list.elements[1];
+    expect(element.spreadOperator.lexeme, '...?');
+    ListLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.elements, hasLength(1));
+  }
+
+  void test_mapLiteral_for() {
+    MapLiteral2 map = parseCollectionLiteral('{1:7, await for (y in list) 2:3}',
+        inAsync: true);
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 7);
+
+    ForElement second = map.entries[1];
+    expect(second.awaitKeyword, isNotNull);
+    expect(second.forKeyword.isKeyword, isTrue);
+    expect(second.leftParenthesis.lexeme, '(');
+    expect(second.rightParenthesis.lexeme, ')');
+    ForEachPartsWithIdentifier forLoopParts = second.forLoopParts;
+    SimpleIdentifier forLoopVar = forLoopParts.identifier;
+    expect(forLoopVar.name, 'y');
+    expect(forLoopParts.inKeyword, isNotNull);
+    SimpleIdentifier iterable = forLoopParts.iterable;
+    expect(iterable.name, 'list');
+  }
+
+  void test_mapLiteral_forIf() {
+    MapLiteral2 map = parseCollectionLiteral(
+        '{1:7, await for (y in list) if (c) 2:3}',
+        inAsync: true);
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 7);
+
+    ForElement second = map.entries[1];
+    expect(second.awaitKeyword, isNotNull);
+    expect(second.forKeyword.isKeyword, isTrue);
+    expect(second.leftParenthesis.lexeme, '(');
+    expect(second.rightParenthesis.lexeme, ')');
+    ForEachPartsWithIdentifier forLoopParts = second.forLoopParts;
+    SimpleIdentifier forLoopVar = forLoopParts.identifier;
+    expect(forLoopVar.name, 'y');
+    expect(forLoopParts.inKeyword, isNotNull);
+    SimpleIdentifier iterable = forLoopParts.iterable;
+    expect(iterable.name, 'list');
+
+    IfElement body = second.body;
+    SimpleIdentifier condition = body.condition;
+    expect(condition.name, 'c');
+    MapLiteralEntry thenElement = body.thenElement;
+    IntegerLiteral thenValue = thenElement.value;
+    expect(thenValue.value, 3);
+  }
+
+  void test_mapLiteral_forSpread() {
+    MapLiteral2 map =
+        parseCollectionLiteral('{1:7, for (x = 0; x < 10; ++x) ...{2:3}}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 7);
+
+    ForElement second = map.entries[1];
+    expect(second.awaitKeyword, isNull);
+    expect(second.forKeyword.isKeyword, isTrue);
+    expect(second.leftParenthesis.lexeme, '(');
+    expect(second.rightParenthesis.lexeme, ')');
+    ForPartsWithExpression forLoopParts = second.forLoopParts;
+    AssignmentExpression forLoopInit = forLoopParts.initialization;
+    SimpleIdentifier forLoopVar = forLoopInit.leftHandSide;
+    expect(forLoopVar.name, 'x');
+    BinaryExpression condition = forLoopParts.condition;
+    IntegerLiteral rightOperand = condition.rightOperand;
+    expect(rightOperand.value, 10);
+    PrefixExpression updater = forLoopParts.updaters[0];
+    SimpleIdentifier updaterOperand = updater.operand;
+    expect(updaterOperand.name, 'x');
+  }
+
+  void test_mapLiteral_if() {
+    MapLiteral2 map = parseCollectionLiteral('{1:1, if (true) 2:4}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 1);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    MapLiteralEntry thenElement = second.thenElement;
+    IntegerLiteral thenElementValue = thenElement.value;
+    expect(thenElementValue.value, 4);
+    expect(second.elseElement, isNull);
+  }
+
+  void test_mapLiteral_ifElse() {
+    MapLiteral2 map = parseCollectionLiteral('{1:1, if (true) 2:4 else 5:6}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 1);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    MapLiteralEntry thenElement = second.thenElement;
+    IntegerLiteral thenElementValue = thenElement.value;
+    expect(thenElementValue.value, 4);
+    MapLiteralEntry elseElement = second.elseElement;
+    IntegerLiteral elseElementValue = elseElement.value;
+    expect(elseElementValue.value, 6);
+  }
+
+  void test_mapLiteral_ifElseFor() {
+    MapLiteral2 map =
+        parseCollectionLiteral('{1:1, if (true) 2:4 else for (c in d) 5:6}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 1);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    MapLiteralEntry thenElement = second.thenElement;
+    IntegerLiteral thenElementValue = thenElement.value;
+    expect(thenElementValue.value, 4);
+
+    ForElement elseElement = second.elseElement;
+    ForEachPartsWithIdentifier forLoopParts = elseElement.forLoopParts;
+    expect(forLoopParts.identifier.name, 'c');
+
+    MapLiteralEntry body = elseElement.body;
+    IntegerLiteral bodyValue = body.value;
+    expect(bodyValue.value, 6);
+  }
+
+  void test_mapLiteral_ifElseSpread() {
+    MapLiteral2 map =
+        parseCollectionLiteral('{1:7, if (true) ...{2:4} else ...?{5:6}}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 7);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    SpreadElement elseElement = second.elseElement;
+    expect(elseElement.spreadOperator.lexeme, '...?');
+    MapLiteral2 elseElementExpression = elseElement.expression;
+    expect(elseElementExpression.entries, hasLength(1));
+    MapLiteralEntry entry = elseElementExpression.entries[0];
+    IntegerLiteral entryValue = entry.value;
+    expect(entryValue.value, 6);
+  }
+
+  void test_mapLiteral_ifFor() {
+    MapLiteral2 map =
+        parseCollectionLiteral('{1:1, if (true) for (a in b) 2:4}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 1);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+
+    ForElement thenElement = second.thenElement;
+    ForEachPartsWithIdentifier forLoopParts = thenElement.forLoopParts;
+    expect(forLoopParts.identifier.name, 'a');
+
+    MapLiteralEntry body = thenElement.body;
+    IntegerLiteral thenElementValue = body.value;
+    expect(thenElementValue.value, 4);
+    expect(second.elseElement, isNull);
+  }
+
+  void test_mapLiteral_ifSpread() {
+    MapLiteral2 map = parseCollectionLiteral('{1:1, if (true) ...{2:4}}');
+    expect(map.entries, hasLength(2));
+    MapLiteralEntry first = map.entries[0];
+    IntegerLiteral firstValue = first.value;
+    expect(firstValue.value, 1);
+
+    IfElement second = map.entries[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    expect(second.elseElement, isNull);
+  }
+
+  void test_mapLiteral_spread() {
+    MapLiteral2 map = parseCollectionLiteral('{1: 2, ...{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments, isNull);
+    expect(map.entries, hasLength(2));
+
+    SpreadElement element = map.entries[1];
+    expect(element.spreadOperator.lexeme, '...');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spread2_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{1: 2, ...{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(2));
+
+    SpreadElement element = map.entries[1];
+    expect(element.spreadOperator.lexeme, '...');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spread_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{...{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(1));
+
+    SpreadElement element = map.entries[0];
+    expect(element.spreadOperator.lexeme, '...');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spreadQ() {
+    MapLiteral2 map = parseCollectionLiteral('{1: 2, ...?{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments, isNull);
+    expect(map.entries, hasLength(2));
+
+    SpreadElement element = map.entries[1];
+    expect(element.spreadOperator.lexeme, '...?');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spreadQ2_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{1: 2, ...?{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(2));
+
+    SpreadElement element = map.entries[1];
+    expect(element.spreadOperator.lexeme, '...?');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spreadQ_typed() {
+    MapLiteral2 map = parseCollectionLiteral('<int, int>{...?{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(1));
+
+    SpreadElement element = map.entries[0];
+    expect(element.spreadOperator.lexeme, '...?');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_setLiteral_if() {
+    SetLiteral2 setLiteral = parseCollectionLiteral('{1, if (true) 2}');
+    expect(setLiteral.elements, hasLength(2));
+    IntegerLiteral first = setLiteral.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = setLiteral.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    IntegerLiteral thenElement = second.thenElement;
+    expect(thenElement.value, 2);
+    expect(second.elseElement, isNull);
+  }
+
+  void test_setLiteral_ifElse() {
+    SetLiteral2 setLiteral = parseCollectionLiteral('{1, if (true) 2 else 5}');
+    expect(setLiteral.elements, hasLength(2));
+    IntegerLiteral first = setLiteral.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = setLiteral.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    IntegerLiteral thenElement = second.thenElement;
+    expect(thenElement.value, 2);
+    IntegerLiteral elseElement = second.elseElement;
+    expect(elseElement.value, 5);
+  }
+
+  void test_setLiteral_ifElseSpread() {
+    SetLiteral2 setLiteral =
+        parseCollectionLiteral('{1, if (true) ...{2} else ...?[5]}');
+    expect(setLiteral.elements, hasLength(2));
+    IntegerLiteral first = setLiteral.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = setLiteral.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    SetLiteral2 theExpression = thenElement.expression;
+    expect(theExpression.elements, hasLength(1));
+    SpreadElement elseElement = second.elseElement;
+    expect(elseElement.spreadOperator.lexeme, '...?');
+    ListLiteral2 elseExpression = elseElement.expression;
+    expect(elseExpression.elements, hasLength(1));
+  }
+
+  void test_setLiteral_ifSpread() {
+    SetLiteral2 setLiteral = parseCollectionLiteral('{1, if (true) ...[2]}');
+    expect(setLiteral.elements, hasLength(2));
+    IntegerLiteral first = setLiteral.elements[0];
+    expect(first.value, 1);
+
+    IfElement second = setLiteral.elements[1];
+    BooleanLiteral condition = second.condition;
+    expect(condition.value, isTrue);
+    SpreadElement thenElement = second.thenElement;
+    expect(thenElement.spreadOperator.lexeme, '...');
+    expect(second.elseElement, isNull);
+  }
+
+  void test_setLiteral_spread2() {
+    SetLiteral2 set = parseCollectionLiteral('{3, ...[4]}');
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNull);
+    expect(set.elements, hasLength(2));
+    IntegerLiteral value = set.elements[0];
+    expect(value.value, 3);
+
+    SpreadElement element = set.elements[1];
+    expect(element.spreadOperator.lexeme, '...');
+    ListLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.elements, hasLength(1));
+  }
+
+  void test_setLiteral_spread2Q() {
+    SetLiteral2 set = parseCollectionLiteral('{3, ...?[4]}');
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNull);
+    expect(set.elements, hasLength(2));
+    IntegerLiteral value = set.elements[0];
+    expect(value.value, 3);
+
+    SpreadElement element = set.elements[1];
+    expect(element.spreadOperator.lexeme, '...?');
+    ListLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.elements, hasLength(1));
+  }
+
+  void test_setLiteral_spread_typed() {
+    SetLiteral2 set = parseCollectionLiteral('<int>{...[3]}');
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNotNull);
+    expect(set.elements, hasLength(1));
+
+    SpreadElement element = set.elements[0];
+    expect(element.spreadOperator.lexeme, '...');
+    ListLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.elements, hasLength(1));
+  }
+
+  void test_setLiteral_spreadQ_typed() {
+    SetLiteral2 set = parseCollectionLiteral('<int>{...?[3]}');
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNotNull);
+    expect(set.elements, hasLength(1));
+
+    SpreadElement element = set.elements[0];
+    expect(element.spreadOperator.lexeme, '...?');
+    ListLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.elements, hasLength(1));
+  }
+
+  void test_setOrMapLiteral_spread() {
+    MapLiteral2 map = parseCollectionLiteral('{...{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments, isNull);
+    expect(map.entries, hasLength(1));
+
+    SpreadElement element = map.entries[0];
+    expect(element.spreadOperator.lexeme, '...');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+
+  void test_setOrMapLiteral_spreadQ() {
+    MapLiteral2 map = parseCollectionLiteral('{...?{3: 4}}');
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments, isNull);
+    expect(map.entries, hasLength(1));
+
+    SpreadElement element = map.entries[0];
+    expect(element.spreadOperator.lexeme, '...?');
+    MapLiteral2 spreadExpression = element.expression;
+    expect(spreadExpression.entries, hasLength(1));
+  }
+}
+
+/**
  * Tests of the fasta parser based on [ComplexParserTestMixin].
  */
 @reflectiveTest
@@ -242,22 +864,28 @@
 @reflectiveTest
 class ExpressionParserTest_Fasta extends FastaParserTestCase
     with ExpressionParserTestMixin {
-  @override
-  @failingTest
-  void test_parseUnaryExpression_decrement_super() {
-    // TODO(danrubel) Reports a different error and different token stream.
-    // Expected: TokenType:<MINUS>
-    //   Actual: TokenType:<MINUS_MINUS>
-    super.test_parseUnaryExpression_decrement_super();
+  void test_listLiteral_spread() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    ListLiteral list = parseExpression('[1, ...[2]]', errors: [
+      expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 3),
+    ]);
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+    ListLiteral second = list.elements[1];
+    expect(second.elements, hasLength(1));
   }
 
-  @override
-  @failingTest
-  void test_parseUnaryExpression_decrement_super_withComment() {
-    // TODO(danrubel) Reports a different error and different token stream.
-    // Expected: TokenType:<MINUS>
-    //   Actual: TokenType:<MINUS_MINUS>
-    super.test_parseUnaryExpression_decrement_super_withComment();
+  void test_listLiteral_spreadQ() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    ListLiteral list = parseExpression('[1, ...?[2]]', errors: [
+      expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 4),
+    ]);
+    expect(list.elements, hasLength(2));
+    IntegerLiteral first = list.elements[0];
+    expect(first.value, 1);
+    ListLiteral second = list.elements[1];
+    expect(second.elements, hasLength(1));
   }
 
   void test_mapLiteral() {
@@ -284,6 +912,127 @@
     expect(value.value, 6);
   }
 
+  void test_mapLiteral_invalid_set_entry() {
+    MapLiteral map =
+        parseExpression('<int, int>{1}', parseSetLiterals: true, errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 1),
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 12, 1),
+    ]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(1));
+  }
+
+  @failingTest
+  void test_mapLiteral_invalid_too_many_type_arguments1() {
+    MapLiteral map =
+        parseExpression('<int, int, int>{}', parseSetLiterals: true, errors: [
+      // TODO(danrubel): Currently the resolver reports invalid number of
+      // type arguments, but the parser could report this.
+      expectedError(
+          /* ParserErrorCode.EXPECTED_ONE_OR_TWO_TYPE_VARIABLES */
+          ParserErrorCode.EXPECTED_TOKEN,
+          11,
+          3),
+    ]);
+    expect(map.constKeyword, isNull);
+    expect(map.entries, hasLength(0));
+  }
+
+  @failingTest
+  void test_mapLiteral_invalid_too_many_type_arguments2() {
+    MapLiteral map =
+        parseExpression('<int, int, int>{1}', parseSetLiterals: true, errors: [
+      // TODO(danrubel): Currently the resolver reports invalid number of
+      // type arguments, but the parser could report this.
+      expectedError(
+          /* ParserErrorCode.EXPECTED_ONE_OR_TWO_TYPE_VARIABLES */
+          ParserErrorCode.EXPECTED_TOKEN,
+          11,
+          3),
+    ]);
+    expect(map.constKeyword, isNull);
+    expect(map.entries, hasLength(0));
+  }
+
+  void test_mapLiteral_spread() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('{1: 2, ...{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 3)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments, isNull);
+    expect(map.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spread2_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('<int, int>{1: 2, ...{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 3)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spread_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('<int, int>{...{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 3)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(0));
+  }
+
+  void test_mapLiteral_spreadQ() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('{1: 2, ...?{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 4)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments, isNull);
+    expect(map.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spreadQ2_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('<int, int>{1: 2, ...?{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 17, 4)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(1));
+  }
+
+  void test_mapLiteral_spreadQ_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral map = parseExpression('<int, int>{...?{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 4)]);
+    expect(map.constKeyword, isNull);
+    expect(map.typeArguments.arguments, hasLength(2));
+    expect(map.entries, hasLength(0));
+  }
+
+  @override
+  @failingTest
+  void test_parseUnaryExpression_decrement_super() {
+    // TODO(danrubel) Reports a different error and different token stream.
+    // Expected: TokenType:<MINUS>
+    //   Actual: TokenType:<MINUS_MINUS>
+    super.test_parseUnaryExpression_decrement_super();
+  }
+
+  @override
+  @failingTest
+  void test_parseUnaryExpression_decrement_super_withComment() {
+    // TODO(danrubel) Reports a different error and different token stream.
+    // Expected: TokenType:<MINUS>
+    //   Actual: TokenType:<MINUS_MINUS>
+    super.test_parseUnaryExpression_decrement_super_withComment();
+  }
+
   void test_setLiteral() {
     SetLiteral set = parseExpression('{3}', parseSetLiterals: true);
     expect(set.constKeyword, isNull);
@@ -304,7 +1053,7 @@
     expect(value2.value, 6);
   }
 
-  void test_setLiteral_const_typeArgument() {
+  void test_setLiteral_const_typed() {
     SetLiteral set = parseExpression('const <int>{3}', parseSetLiterals: true);
     expect(set.constKeyword, isNotNull);
     expect(set.typeArguments.arguments, hasLength(1));
@@ -316,48 +1065,15 @@
   }
 
   void test_setLiteral_invalid_map_entry() {
-    parseExpression('<int>{1: 1}', parseSetLiterals: true, errors: [
+    SetLiteral set =
+        parseExpression('<int>{1: 1}', parseSetLiterals: true, errors: [
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 1),
     ]);
-  }
-
-  @failingTest
-  void test_setLiteral_invalid_too_many_type_arguments1() {
-    parseExpression('<int, int, int>{}', parseSetLiterals: true, errors: [
-      // TODO(danrubel): Currently the resolver reports invalid number of
-      // type arguments, but the parser could report this.
-      expectedError(
-          /* ParserErrorCode.EXPECTED_ONE_TYPE_VARIABLE */
-          ParserErrorCode.EXPECTED_TOKEN,
-          15,
-          1),
-    ]);
-  }
-
-  @failingTest
-  void test_setLiteral_invalid_too_many_type_arguments2() {
-    parseExpression('<int, int, int>{1}', parseSetLiterals: true, errors: [
-      // TODO(danrubel): Currently the resolver reports invalid number of
-      // type arguments, but the parser could report this.
-      expectedError(
-          /* ParserErrorCode.EXPECTED_ONE_TYPE_VARIABLE */
-          ParserErrorCode.EXPECTED_TOKEN,
-          15,
-          1),
-    ]);
-  }
-
-  @failingTest
-  void test_setLiteral_invalid_too_many_type_arguments3() {
-    parseExpression('<int, int>{1}', parseSetLiterals: true, errors: [
-      // TODO(danrubel): Currently the resolver reports invalid number of
-      // type arguments, but the parser could report this.
-      expectedError(
-          /* ParserErrorCode.EXPECTED_ONE_TYPE_VARIABLE */
-          ParserErrorCode.EXPECTED_TOKEN,
-          10,
-          1),
-    ]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments.arguments, hasLength(1));
+    NamedType typeArg = set.typeArguments.arguments[0];
+    expect(typeArg.name.name, 'int');
+    expect(set.elements.length, 1);
   }
 
   void test_setLiteral_nested_typeArgument() {
@@ -376,7 +1092,59 @@
     expect(value.value, 3);
   }
 
-  void test_setLiteral_typeArgument() {
+  void test_setLiteral_spread2() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    SetLiteral set = parseExpression('{3, ...[4]}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 3)]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNull);
+    expect(set.elements, hasLength(2));
+    IntegerLiteral value = set.elements[0];
+    expect(value.value, 3);
+    ListLiteral list = set.elements[1];
+    expect(list.elements, hasLength(1));
+  }
+
+  void test_setLiteral_spread2Q() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    SetLiteral set = parseExpression('{3, ...?[4]}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 4)]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNull);
+    expect(set.elements, hasLength(2));
+    IntegerLiteral value = set.elements[0];
+    expect(value.value, 3);
+    ListLiteral list = set.elements[1];
+    expect(list.elements, hasLength(1));
+  }
+
+  void test_setLiteral_spread_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    SetLiteral set = parseExpression('<int>{...[3]}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 6, 3)]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNotNull);
+    expect(set.elements, hasLength(1));
+    ListLiteral list = set.elements[0];
+    expect(list.elements, hasLength(1));
+  }
+
+  void test_setLiteral_spreadQ_typed() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    SetLiteral set = parseExpression('<int>{...?[3]}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 6, 4)]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNotNull);
+    expect(set.elements, hasLength(1));
+    ListLiteral list = set.elements[0];
+    expect(list.elements, hasLength(1));
+  }
+
+  void test_setLiteral_typed() {
     SetLiteral set = parseExpression('<int>{3}', parseSetLiterals: true);
     expect(set.constKeyword, isNull);
     expect(set.typeArguments.arguments, hasLength(1));
@@ -386,6 +1154,26 @@
     IntegerLiteral value = set.elements[0];
     expect(value.value, 3);
   }
+
+  void test_setOrMapLiteral_spread() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral set = parseExpression('{...{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 1, 3)]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNull);
+    expect(set.entries, hasLength(0));
+  }
+
+  void test_setOrMapLiteral_spreadQ() {
+    // TODO(danrubel): Remove this once spread_collections is enabled by default
+    MapLiteral set = parseExpression('{...?{3: 4}}',
+        parseSetLiterals: true,
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 1, 4)]);
+    expect(set.constKeyword, isNull);
+    expect(set.typeArguments, isNull);
+    expect(set.entries, hasLength(0));
+  }
 }
 
 /**
@@ -644,9 +1432,18 @@
       {List<ErrorCode> codes,
       List<ExpectedError> errors,
       int expectedEndOffset,
-      bool parseSetLiterals = false}) {
+      bool inAsync = false,
+      bool parseSetLiterals = false,
+      bool parseSpreadCollections = false,
+      bool parseControlFlowCollections = false}) {
     createParser(source, expectedEndOffset: expectedEndOffset);
     _parserProxy.fastaParser.enableSetLiterals = parseSetLiterals;
+    _parserProxy.astBuilder.enableSpreadCollections = parseSpreadCollections;
+    _parserProxy.astBuilder.enableControlFlowCollections =
+        parseControlFlowCollections;
+    if (inAsync) {
+      _parserProxy.fastaParser.asyncState = AsyncModifier.Async;
+    }
     Expression result = _parserProxy.parseExpression2();
     assertErrors(codes: codes, errors: errors);
     return result;
@@ -823,8 +1620,20 @@
 
   @override
   Statement parseStatement(String source,
-      {bool enableLazyAssignmentOperators, int expectedEndOffset}) {
+      {bool enableLazyAssignmentOperators,
+      int expectedEndOffset,
+      bool parseSetLiterals = false,
+      bool parseSpreadCollections = false,
+      bool parseControlFlowCollections = false,
+      bool inAsync = false}) {
     createParser(source, expectedEndOffset: expectedEndOffset);
+    _parserProxy.fastaParser.enableSetLiterals = parseSetLiterals;
+    _parserProxy.astBuilder.enableSpreadCollections = parseSpreadCollections;
+    _parserProxy.astBuilder.enableControlFlowCollections =
+        parseControlFlowCollections;
+    if (inAsync) {
+      _parserProxy.fastaParser.asyncState = AsyncModifier.Async;
+    }
     Statement statement = _parserProxy.parseStatement2();
     assertErrors(codes: NO_ERROR_COMPARISON);
     return statement;
@@ -895,6 +1704,172 @@
     with FormalParameterParserTestMixin {}
 
 /**
+ * Tests of the fasta parser based on [ComplexParserTestMixin].
+ */
+@reflectiveTest
+class NNBDParserTest_Fasta extends FastaParserTestCase {
+  CompilationUnit parseNNBDCompilationUnit(String code,
+      {List<ExpectedError> errors}) {
+    createParser('''
+@pragma('analyzer:non-nullable') library nnbd.parser.test;
+$code
+''');
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnit unit = _parserProxy.parseCompilationUnit2();
+    assertErrors(errors: errors);
+    return unit;
+  }
+
+  void test_assignment_complex() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
+  }
+
+  void test_assignment_simple() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x; }');
+  }
+
+  void test_binary_expression_statement() {
+    final unit = parseNNBDCompilationUnit('D? foo(X? x) { X ?? x2; }');
+    FunctionDeclaration funct = unit.declarations[0];
+    BlockFunctionBody body = funct.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    BinaryExpression expression = statement.expression;
+    SimpleIdentifier lhs = expression.leftOperand;
+    expect(lhs.name, 'X');
+    expect(expression.operator.lexeme, '??');
+    SimpleIdentifier rhs = expression.rightOperand;
+    expect(rhs.name, 'x2');
+  }
+
+  void test_conditional() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? 7 : y; }');
+  }
+
+  void test_conditional_complex() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x + bar(7) : y; }');
+  }
+
+  void test_conditional_error() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? ? x2 = x + bar(7) : y; }',
+        errors: [
+          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 78, 1),
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 99, 1),
+          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 99, 1),
+        ]);
+  }
+
+  void test_conditional_simple() {
+    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x : y; }');
+  }
+
+  void test_enableNonNullable_false() {
+    parseCompilationUnit('main() { x is String? ? (x + y) : z; }',
+        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 20, 1)]);
+  }
+
+  void test_for() {
+    parseNNBDCompilationUnit('main() { for(int x = 0; x < 7; ++x) { } }');
+  }
+
+  void test_for_conditional() {
+    parseNNBDCompilationUnit(
+        'main() { for(x ? y = 7 : y = 8; y < 10; ++y) { } }');
+  }
+
+  void test_for_nullable() {
+    parseNNBDCompilationUnit('main() { for(int? x = 0; x < 7; ++x) { } }');
+  }
+
+  void test_foreach() {
+    parseNNBDCompilationUnit('main() { for(int x in [7]) { } }');
+  }
+
+  void test_foreach_nullable() {
+    parseNNBDCompilationUnit('main() { for(int? x in [7, null]) { } }');
+  }
+
+  void test_gft_nullable() {
+    parseNNBDCompilationUnit('main() { C? Function() x = 7; }');
+  }
+
+  void test_gft_nullable_1() {
+    parseNNBDCompilationUnit('main() { C Function()? x = 7; }');
+  }
+
+  void test_gft_nullable_2() {
+    parseNNBDCompilationUnit('main() { C? Function()? x = 7; }');
+  }
+
+  void test_gft_nullable_3() {
+    parseNNBDCompilationUnit('main() { C? Function()? Function()? x = 7; }');
+  }
+
+  void test_gft_nullable_prefixed() {
+    parseNNBDCompilationUnit('main() { C.a? Function()? x = 7; }');
+  }
+
+  void test_is_nullable() {
+    CompilationUnit unit =
+        parseNNBDCompilationUnit('main() { x is String? ? (x + y) : z; }');
+    FunctionDeclaration function = unit.declarations[0];
+    BlockFunctionBody body = function.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    ConditionalExpression expression = statement.expression;
+
+    IsExpression condition = expression.condition;
+    expect((condition.type as NamedType).question, isNotNull);
+    Expression thenExpression = expression.thenExpression;
+    expect(thenExpression, isParenthesizedExpression);
+    Expression elseExpression = expression.elseExpression;
+    expect(elseExpression, isSimpleIdentifier);
+  }
+
+  void test_is_nullable_parenthesis() {
+    CompilationUnit unit =
+        parseNNBDCompilationUnit('main() { (x is String?) ? (x + y) : z; }');
+    FunctionDeclaration function = unit.declarations[0];
+    BlockFunctionBody body = function.functionExpression.body;
+    ExpressionStatement statement = body.block.statements[0];
+    ConditionalExpression expression = statement.expression;
+
+    ParenthesizedExpression condition = expression.condition;
+    IsExpression isExpression = condition.expression;
+    expect((isExpression.type as NamedType).question, isNotNull);
+    Expression thenExpression = expression.thenExpression;
+    expect(thenExpression, isParenthesizedExpression);
+    Expression elseExpression = expression.elseExpression;
+    expect(elseExpression, isSimpleIdentifier);
+  }
+
+  void test_pragma_missing() {
+    createParser("library foo;");
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, false);
+  }
+
+  void test_pragma_non_nullable() {
+    createParser("@pragma('analyzer:non-nullable') library foo;");
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, true);
+  }
+
+  void test_pragma_non_nullable_not_enabled() {
+    createParser("@pragma('analyzer:non-nullable') library foo;");
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, false);
+  }
+
+  void test_pragma_other() {
+    createParser("@pragma('analyzer:foo') library foo;");
+    _parserProxy.astBuilder.enableNonNullable = true;
+    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
+    expect(unit.hasPragmaAnalyzerNonNullable, false);
+  }
+}
+
+/**
  * Proxy implementation of the analyzer parser, implemented in terms of the
  * Fasta parser.
  *
@@ -1108,6 +2083,21 @@
     ]);
   }
 
+  void test_incompleteForEach2() {
+    ForStatement2 statement = parseStatement('for (String item i) {}',
+        parseControlFlowCollections: true);
+    listener.assertErrors([
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 4),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1)
+    ]);
+    expect(statement.toSource(), 'for (String item; i;) {}');
+    ForPartsWithDeclarations forLoopParts = statement.forLoopParts;
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.leftSeparator.type, TokenType.SEMICOLON);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.rightSeparator.type, TokenType.SEMICOLON);
+  }
+
   void test_invalidTypeParameters_super() {
     parseCompilationUnit('class C<X super Y> {}', errors: [
       // TODO(danrubel): Improve recovery.
@@ -1211,6 +2201,304 @@
     }
   }
 
+  void test_parseForStatement_each_await2() {
+    ForStatement2 forStatement = parseStatement(
+      'await for (element in list) {}',
+      inAsync: true,
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.awaitKeyword, isNotNull);
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForEachPartsWithIdentifier forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.identifier, isNotNull);
+    expect(forLoopParts.inKeyword, isNotNull);
+    expect(forLoopParts.iterable, isNotNull);
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_each_genericFunctionType2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (void Function<T>(T) element in list) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.awaitKeyword, isNull);
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.loopVariable, isNotNull);
+    expect(forLoopParts.inKeyword, isNotNull);
+    expect(forLoopParts.iterable, isNotNull);
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_each_identifier2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (element in list) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.awaitKeyword, isNull);
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForEachPartsWithIdentifier forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.identifier, isNotNull);
+    expect(forLoopParts.inKeyword, isNotNull);
+    expect(forLoopParts.iterable, isNotNull);
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_each_noType_metadata2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (@A var element in list) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.awaitKeyword, isNull);
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.loopVariable, isNotNull);
+    expect(forLoopParts.loopVariable.metadata, hasLength(1));
+    expect(forLoopParts.inKeyword, isNotNull);
+    expect(forLoopParts.iterable, isNotNull);
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_each_type2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (A element in list) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.awaitKeyword, isNull);
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.loopVariable, isNotNull);
+    expect(forLoopParts.inKeyword, isNotNull);
+    expect(forLoopParts.iterable, isNotNull);
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_each_var2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (var element in list) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.awaitKeyword, isNull);
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForEachPartsWithDeclaration forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.loopVariable, isNotNull);
+    expect(forLoopParts.inKeyword, isNotNull);
+    expect(forLoopParts.iterable, isNotNull);
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_c2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (; i < count;) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithExpression forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.initialization, isNull);
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNotNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(0));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_cu2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (; i < count; i++) {}',
+      parseControlFlowCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithExpression forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.initialization, isNull);
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNotNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(1));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_ecu2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (i--; i < count; i++) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithExpression forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.initialization, isNotNull);
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNotNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(1));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_i2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (var i = 0;;) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts;
+    VariableDeclarationList variables = forLoopParts.variables;
+    expect(variables, isNotNull);
+    expect(variables.metadata, hasLength(0));
+    expect(variables.variables, hasLength(1));
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(0));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_i_withMetadata2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (@A var i = 0;;) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts;
+    VariableDeclarationList variables = forLoopParts.variables;
+    expect(variables, isNotNull);
+    expect(variables.metadata, hasLength(1));
+    expect(variables.variables, hasLength(1));
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(0));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_ic2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (var i = 0; i < count;) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts;
+    VariableDeclarationList variables = forLoopParts.variables;
+    expect(variables, isNotNull);
+    expect(variables.variables, hasLength(1));
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNotNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(0));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_icu2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (var i = 0; i < count; i++) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts;
+    VariableDeclarationList variables = forLoopParts.variables;
+    expect(variables, isNotNull);
+    expect(variables.variables, hasLength(1));
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNotNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(1));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_iicuu2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (int i = 0, j = count; i < j; i++, j--) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts;
+    VariableDeclarationList variables = forLoopParts.variables;
+    expect(variables, isNotNull);
+    expect(variables.variables, hasLength(2));
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNotNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(2));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_iu2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (var i = 0;; i++) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithDeclarations forLoopParts = forStatement.forLoopParts;
+    VariableDeclarationList variables = forLoopParts.variables;
+    expect(variables, isNotNull);
+    expect(variables.variables, hasLength(1));
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(1));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
+  void test_parseForStatement_loop_u2() {
+    ForStatement2 forStatement = parseStatement(
+      'for (;; i++) {}',
+      parseSpreadCollections: true,
+    );
+    assertNoErrors();
+    expect(forStatement.forKeyword, isNotNull);
+    expect(forStatement.leftParenthesis, isNotNull);
+    ForPartsWithExpression forLoopParts = forStatement.forLoopParts;
+    expect(forLoopParts.initialization, isNull);
+    expect(forLoopParts.leftSeparator, isNotNull);
+    expect(forLoopParts.condition, isNull);
+    expect(forLoopParts.rightSeparator, isNotNull);
+    expect(forLoopParts.updaters, hasLength(1));
+    expect(forStatement.rightParenthesis, isNotNull);
+    expect(forStatement.body, isNotNull);
+  }
+
   void test_partial_typeArg1_34850() {
     var unit = parseCompilationUnit('<bar<', errors: [
       expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 0, 1),
@@ -1487,146 +2775,3 @@
     expectCommentText(declaration.documentationComment, '/// Doc');
   }
 }
-
-/**
- * Tests of the fasta parser based on [ComplexParserTestMixin].
- */
-@reflectiveTest
-class NNBDParserTest_Fasta extends FastaParserTestCase {
-  parseNNBDCompilationUnit(String code, {List<ExpectedError> errors}) {
-    createParser('''
-@pragma('analyzer:non-nullable') library nnbd.parser.test;
-$code
-''');
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnit unit = _parserProxy.parseCompilationUnit2();
-    assertNoErrors();
-    return unit;
-  }
-
-  void test_assignment_complex() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
-  }
-
-  void test_assignment_simple() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x; }');
-  }
-
-  void test_gft_nullable() {
-    parseNNBDCompilationUnit('main() { C? Function() x = 7; }');
-  }
-
-  void test_gft_nullable_1() {
-    parseNNBDCompilationUnit('main() { C Function()? x = 7; }');
-  }
-
-  void test_gft_nullable_2() {
-    parseNNBDCompilationUnit('main() { C? Function()? x = 7; }');
-  }
-
-  void test_gft_nullable_3() {
-    parseNNBDCompilationUnit('main() { C? Function()? Function()? x = 7; }');
-  }
-
-  void test_gft_nullable_prefixed() {
-    parseNNBDCompilationUnit('main() { C.a? Function()? x = 7; }');
-  }
-
-  void test_conditional() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? 7 : y; }');
-  }
-
-  void test_conditional_complex() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x + bar(7) : y; }');
-  }
-
-  void test_conditional_simple() {
-    parseNNBDCompilationUnit('D? foo(X? x) { X ? x2 = x : y; }');
-  }
-
-  void test_for() {
-    parseNNBDCompilationUnit('main() { for(int x = 0; x < 7; ++x) { } }');
-  }
-
-  void test_for_conditional() {
-    parseNNBDCompilationUnit(
-        'main() { for(x ? y = 7 : y = 8; y < 10; ++y) { } }');
-  }
-
-  void test_for_nullable() {
-    parseNNBDCompilationUnit('main() { for(int? x = 0; x < 7; ++x) { } }');
-  }
-
-  void test_foreach() {
-    parseNNBDCompilationUnit('main() { for(int x in [7]) { } }');
-  }
-
-  void test_foreach_nullable() {
-    parseNNBDCompilationUnit('main() { for(int? x in [7, null]) { } }');
-  }
-
-  void test_is_nullable() {
-    CompilationUnit unit =
-        parseNNBDCompilationUnit('main() { x is String? ? (x + y) : z; }');
-    FunctionDeclaration function = unit.declarations[0];
-    BlockFunctionBody body = function.functionExpression.body;
-    ExpressionStatement statement = body.block.statements[0];
-    ConditionalExpression expression = statement.expression;
-
-    IsExpression condition = expression.condition;
-    expect((condition.type as NamedType).question, isNotNull);
-    Expression thenExpression = expression.thenExpression;
-    expect(thenExpression, isParenthesizedExpression);
-    Expression elseExpression = expression.elseExpression;
-    expect(elseExpression, isSimpleIdentifier);
-  }
-
-  void test_is_nullable_parenthesis() {
-    CompilationUnit unit =
-        parseNNBDCompilationUnit('main() { (x is String?) ? (x + y) : z; }');
-    FunctionDeclaration function = unit.declarations[0];
-    BlockFunctionBody body = function.functionExpression.body;
-    ExpressionStatement statement = body.block.statements[0];
-    ConditionalExpression expression = statement.expression;
-
-    ParenthesizedExpression condition = expression.condition;
-    IsExpression isExpression = condition.expression;
-    expect((isExpression.type as NamedType).question, isNotNull);
-    Expression thenExpression = expression.thenExpression;
-    expect(thenExpression, isParenthesizedExpression);
-    Expression elseExpression = expression.elseExpression;
-    expect(elseExpression, isSimpleIdentifier);
-  }
-
-  void test_pragma_missing() {
-    createParser("library foo;");
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, false);
-  }
-
-  void test_pragma_non_nullable() {
-    createParser("@pragma('analyzer:non-nullable') library foo;");
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, true);
-  }
-
-  void test_pragma_non_nullable_not_enabled() {
-    createParser("@pragma('analyzer:non-nullable') library foo;");
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, false);
-  }
-
-  void test_pragma_other() {
-    createParser("@pragma('analyzer:foo') library foo;");
-    _parserProxy.astBuilder.enableNonNullable = true;
-    CompilationUnitImpl unit = _parserProxy.parseCompilationUnit2();
-    expect(unit.hasPragmaAnalyzerNonNullable, false);
-  }
-
-  void test_enableNonNullable_false() {
-    parseCompilationUnit('main() { x is String? ? (x + y) : z; }',
-        errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 20, 1)]);
-  }
-}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index e6fbf65..faf4a1c 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1930,46 +1930,6 @@
     expect(expression.condition, isBinaryExpression);
   }
 
-  void test_conditionalExpression_precedence_withAssignment() {
-    ExpressionStatement statement = parseStatement('b ? c = true : g();');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<SimpleIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
-  }
-
-  void test_conditionalExpression_precedence_withAssignment2() {
-    ExpressionStatement statement = parseStatement('b.x ? c = true : g();');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
-  }
-
-  void test_conditionalExpression_prefixedValue() {
-    ExpressionStatement statement = parseStatement('a.b ? y : z;');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<SimpleIdentifier>());
-  }
-
-  void test_conditionalExpression_prefixedValue2() {
-    ExpressionStatement statement = parseStatement('a.b ? x.y : z;');
-    ConditionalExpression expression = statement.expression;
-    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
-    expect(expression.thenExpression, new TypeMatcher<PrefixedIdentifier>());
-  }
-
-  void test_conditionalExpression_precedence_prefixedNullableType_is() {
-    ExpressionStatement statement = parseStatement('x is p.A ? (x + y) : z;');
-    ConditionalExpression expression = statement.expression;
-
-    Expression condition = expression.condition;
-    expect(condition, new TypeMatcher<IsExpression>());
-    Expression thenExpression = expression.thenExpression;
-    expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
-    Expression elseExpression = expression.elseExpression;
-    expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
-  }
-
   void test_conditionalExpression_precedence_nullableType_as() {
     ExpressionStatement statement = parseStatement('x as bool ? (x + y) : z;');
     ConditionalExpression expression = statement.expression;
@@ -2029,6 +1989,46 @@
     expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
   }
 
+  void test_conditionalExpression_precedence_prefixedNullableType_is() {
+    ExpressionStatement statement = parseStatement('x is p.A ? (x + y) : z;');
+    ConditionalExpression expression = statement.expression;
+
+    Expression condition = expression.condition;
+    expect(condition, new TypeMatcher<IsExpression>());
+    Expression thenExpression = expression.thenExpression;
+    expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
+    Expression elseExpression = expression.elseExpression;
+    expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
+  }
+
+  void test_conditionalExpression_precedence_withAssignment() {
+    ExpressionStatement statement = parseStatement('b ? c = true : g();');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<SimpleIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
+  }
+
+  void test_conditionalExpression_precedence_withAssignment2() {
+    ExpressionStatement statement = parseStatement('b.x ? c = true : g();');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<AssignmentExpression>());
+  }
+
+  void test_conditionalExpression_prefixedValue() {
+    ExpressionStatement statement = parseStatement('a.b ? y : z;');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<SimpleIdentifier>());
+  }
+
+  void test_conditionalExpression_prefixedValue2() {
+    ExpressionStatement statement = parseStatement('a.b ? x.y : z;');
+    ConditionalExpression expression = statement.expression;
+    expect(expression.condition, new TypeMatcher<PrefixedIdentifier>());
+    expect(expression.thenExpression, new TypeMatcher<PrefixedIdentifier>());
+  }
+
   void test_constructor_initializer_withParenthesizedExpression() {
     CompilationUnit unit = parseCompilationUnit(r'''
 class C {
@@ -10860,6 +10860,8 @@
   }
 
   void test_incompleteForEach() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     ForStatement statement = parseStatement('for (String item i) {}');
     listener.assertErrors([
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 4),
@@ -14571,6 +14573,8 @@
   }
 
   void test_parseForStatement_each_await() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     String code = 'await for (element in list) {}';
     var forStatement = _parseAsyncStatement(code) as ForEachStatement;
     assertNoErrors();
@@ -14586,6 +14590,8 @@
   }
 
   void test_parseForStatement_each_genericFunctionType() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (void Function<T>(T) element in list) {}')
             as ForEachStatement;
@@ -14602,6 +14608,8 @@
   }
 
   void test_parseForStatement_each_identifier() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (element in list) {}') as ForEachStatement;
     assertNoErrors();
@@ -14617,6 +14625,8 @@
   }
 
   void test_parseForStatement_each_noType_metadata() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (@A var element in list) {}') as ForEachStatement;
     assertNoErrors();
@@ -14633,6 +14643,8 @@
   }
 
   void test_parseForStatement_each_type() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (A element in list) {}') as ForEachStatement;
     assertNoErrors();
@@ -14648,6 +14660,8 @@
   }
 
   void test_parseForStatement_each_var() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (var element in list) {}') as ForEachStatement;
     assertNoErrors();
@@ -14663,6 +14677,8 @@
   }
 
   void test_parseForStatement_loop_c() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement = parseStatement('for (; i < count;) {}') as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -14678,6 +14694,8 @@
   }
 
   void test_parseForStatement_loop_cu() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (; i < count; i++) {}') as ForStatement;
     assertNoErrors();
@@ -14694,6 +14712,8 @@
   }
 
   void test_parseForStatement_loop_ecu() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (i--; i < count; i++) {}') as ForStatement;
     assertNoErrors();
@@ -14710,6 +14730,8 @@
   }
 
   void test_parseForStatement_loop_i() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement = parseStatement('for (var i = 0;;) {}') as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
@@ -14728,6 +14750,8 @@
   }
 
   void test_parseForStatement_loop_i_withMetadata() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (@A var i = 0;;) {}') as ForStatement;
     assertNoErrors();
@@ -14747,6 +14771,8 @@
   }
 
   void test_parseForStatement_loop_ic() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (var i = 0; i < count;) {}') as ForStatement;
     assertNoErrors();
@@ -14765,6 +14791,8 @@
   }
 
   void test_parseForStatement_loop_icu() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (var i = 0; i < count; i++) {}') as ForStatement;
     assertNoErrors();
@@ -14783,6 +14811,8 @@
   }
 
   void test_parseForStatement_loop_iicuu() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (int i = 0, j = count; i < j; i++, j--) {}')
             as ForStatement;
@@ -14802,6 +14832,8 @@
   }
 
   void test_parseForStatement_loop_iu() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement =
         parseStatement('for (var i = 0;; i++) {}') as ForStatement;
     assertNoErrors();
@@ -14820,6 +14852,8 @@
   }
 
   void test_parseForStatement_loop_u() {
+    // TODO(danrubel): remove this once control flow and spread collection
+    // entry parsing is enabled by default
     var forStatement = parseStatement('for (;; i++) {}') as ForStatement;
     assertNoErrors();
     expect(forStatement.forKeyword, isNotNull);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 69dc68b..5d5b657 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -23,13 +23,13 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/element_search.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/source/source_resource.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../src/dart/resolution/driver_resolution.dart';
 import 'analysis_context_factory.dart';
 import 'parser_test.dart';
 import 'resolver_test_case.dart';
@@ -45,9 +45,6 @@
     defineReflectiveTests(LibraryScopeTest);
     defineReflectiveTests(PrefixedNamespaceTest);
     defineReflectiveTests(ScopeTest);
-    defineReflectiveTests(StrictModeTest);
-    defineReflectiveTests(TypeOverrideManagerTest);
-    defineReflectiveTests(TypePropagationTest);
     defineReflectiveTests(TypeProviderImplTest);
     defineReflectiveTests(TypeResolverVisitorTest);
   });
@@ -167,9 +164,9 @@
 }
 
 @reflectiveTest
-class ErrorResolverTest extends ResolverTestCase {
+class ErrorResolverTest extends DriverResolutionTest {
   test_breakLabelOnSwitchMember() async {
-    Source source = addSource(r'''
+    assertErrorsInCode(r'''
 class A {
   void m(int i) {
     switch (i) {
@@ -179,14 +176,11 @@
         break l;
     }
   }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
-    verify([source]);
+}''', [ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER]);
   }
 
   test_continueLabelOnSwitch() async {
-    Source source = addSource(r'''
+    assertErrorsInCode(r'''
 class A {
   void m(int i) {
     l: switch (i) {
@@ -194,43 +188,24 @@
         continue l;
     }
   }
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
-    verify([source]);
+}''', [ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH]);
   }
 
   test_enclosingElement_invalidLocalFunction() async {
-    String code = r'''
+    addTestFile(r'''
 class C {
   C() {
     int get x => 0;
   }
-}''';
-    Source source = addSource(code);
-
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertErrors(source, [
+}''');
+    await resolveTestFile();
+    assertTestErrors([
       ParserErrorCode.MISSING_FUNCTION_PARAMETERS,
       ParserErrorCode.EXPECTED_TOKEN
     ]);
 
-    CompilationUnitElement unit = analysisResult.unit.declaredElement;
-    LibraryElement library = unit.library;
-    expect(library, isNotNull);
-    expect(unit.enclosingElement, same(library));
-
-    var types = unit.types;
-    expect(types, hasLength(1));
-    var type = types[0];
-    expect(type, isNotNull);
-
-    var constructors = type.constructors;
-    expect(constructors, hasLength(1));
-    ConstructorElement constructor = constructors[0];
-    expect(constructor, isNotNull);
-
-    FunctionElement x = findElementsByName(analysisResult.unit, 'x').single;
+    var constructor = findElement.unnamedConstructor('C');
+    var x = findElement.localFunction('x');
     expect(x.enclosingElement, constructor);
   }
 }
@@ -596,8 +571,7 @@
  * The class `StrictModeTest` contains tests to ensure that the correct errors and warnings
  * are reported when the analysis engine is run in strict mode.
  */
-@reflectiveTest
-class StrictModeTest extends ResolverTestCase {
+abstract class StrictModeTest extends ResolverTestCase {
   fail_for() async {
     Source source = addSource(r'''
 int f(List<int> list) {
@@ -748,70 +722,7 @@
   }
 }
 
-@reflectiveTest
-class TypeOverrideManagerTest extends EngineTestCase {
-  void test_exitScope_noScopes() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    expect(() {
-      manager.exitScope();
-    }, throwsStateError);
-  }
-
-  void test_exitScope_oneScope() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    manager.enterScope();
-    manager.exitScope();
-    expect(() {
-      manager.exitScope();
-    }, throwsStateError);
-  }
-
-  void test_exitScope_twoScopes() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    manager.enterScope();
-    manager.exitScope();
-    manager.enterScope();
-    manager.exitScope();
-    expect(() {
-      manager.exitScope();
-    }, throwsStateError);
-  }
-
-  void test_getType_enclosedOverride() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    LocalVariableElementImpl element =
-        ElementFactory.localVariableElement2("v");
-    InterfaceType type = ElementFactory.classElement2("C").type;
-    manager.enterScope();
-    manager.setType(element, type);
-    manager.enterScope();
-    expect(manager.getType(element), same(type));
-  }
-
-  void test_getType_immediateOverride() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    LocalVariableElementImpl element =
-        ElementFactory.localVariableElement2("v");
-    InterfaceType type = ElementFactory.classElement2("C").type;
-    manager.enterScope();
-    manager.setType(element, type);
-    expect(manager.getType(element), same(type));
-  }
-
-  void test_getType_noOverride() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    manager.enterScope();
-    expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
-  }
-
-  void test_getType_noScope() {
-    TypeOverrideManager manager = new TypeOverrideManager();
-    expect(manager.getType(ElementFactory.localVariableElement2("v")), isNull);
-  }
-}
-
-@reflectiveTest
-class TypePropagationTest extends ResolverTestCase {
+abstract class TypePropagationTest extends ResolverTestCase {
   fail_propagatedReturnType_functionExpression() async {
     // TODO(scheglov) disabled because we don't resolve function expression
     String code = r'''
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 91bb80a..a4d99bb 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -3,19 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.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/exception/exception.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../utils.dart';
+import '../src/dart/resolution/driver_resolution.dart';
 import 'resolver_test_case.dart';
-import 'test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -24,108 +18,108 @@
 }
 
 @reflectiveTest
-class SimpleResolverTest extends ResolverTestCase {
+class SimpleResolverTest extends DriverResolutionTest {
   test_argumentResolution_required_matching() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void f() {
     g(1, 2, 3);
   }
   void g(a, b, c) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 2]);
+    await _validateArgumentResolution([0, 1, 2]);
   }
 
   test_argumentResolution_required_tooFew() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void f() {
     g(1, 2);
   }
   void g(a, b, c) {}
 }''');
-    _validateArgumentResolution(source, [0, 1]);
+    await _validateArgumentResolution([0, 1]);
   }
 
   test_argumentResolution_required_tooMany() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void f() {
     g(1, 2, 3);
   }
   void g(a, b) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, -1]);
+    await _validateArgumentResolution([0, 1, -1]);
   }
 
   test_argumentResolution_requiredAndNamed_extra() async {
-    Source source = addSource(r'''
+    addTestFile('''
 class A {
   void f() {
     g(1, 2, c: 3, d: 4);
   }
   void g(a, b, {c}) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 2, -1]);
+    await _validateArgumentResolution([0, 1, 2, -1]);
   }
 
   test_argumentResolution_requiredAndNamed_matching() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void f() {
     g(1, 2, c: 3);
   }
   void g(a, b, {c}) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 2]);
+    await _validateArgumentResolution([0, 1, 2]);
   }
 
   test_argumentResolution_requiredAndNamed_missing() async {
-    Source source = addSource(r'''
+    addTestFile('''
 class A {
   void f() {
     g(1, 2, d: 3);
   }
   void g(a, b, {c, d}) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 3]);
+    await _validateArgumentResolution([0, 1, 3]);
   }
 
   test_argumentResolution_requiredAndPositional_fewer() async {
-    Source source = addSource(r'''
+    addTestFile('''
 class A {
   void f() {
     g(1, 2, 3);
   }
   void g(a, b, [c, d]) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 2]);
+    await _validateArgumentResolution([0, 1, 2]);
   }
 
   test_argumentResolution_requiredAndPositional_matching() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void f() {
     g(1, 2, 3, 4);
   }
   void g(a, b, [c, d]) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 2, 3]);
+    await _validateArgumentResolution([0, 1, 2, 3]);
   }
 
   test_argumentResolution_requiredAndPositional_more() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void f() {
     g(1, 2, 3, 4);
   }
   void g(a, b, [c]) {}
 }''');
-    _validateArgumentResolution(source, [0, 1, 2, -1]);
+    await _validateArgumentResolution([0, 1, 2, -1]);
   }
 
   test_argumentResolution_setter_propagated() async {
-    CompilationUnit unit = await resolveSource(r'''
+    addTestFile(r'''
 main() {
   var a = new A();
   a.sss = 0;
@@ -133,20 +127,17 @@
 class A {
   set sss(x) {}
 }''');
-    // find "a.sss = 0"
-    AssignmentExpression assignment;
-    {
-      var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');
-      var statement = statements[1] as ExpressionStatement;
-      assignment = statement.expression as AssignmentExpression;
-    }
-    // get parameter
-    Expression rhs = assignment.rightHandSide;
-    expect(rhs.staticParameterElement, isNotNull);
+    await resolveTestFile();
+
+    var rhs = findNode.assignment(' = 0;').rightHandSide;
+    expect(
+      rhs.staticParameterElement,
+      findElement.parameter('x'),
+    );
   }
 
   test_argumentResolution_setter_propagated_propertyAccess() async {
-    CompilationUnit unit = await resolveSource(r'''
+    addTestFile(r'''
 main() {
   var a = new A();
   a.b.sss = 0;
@@ -157,20 +148,17 @@
 class B {
   set sss(x) {}
 }''');
-    // find "a.b.sss = 0"
-    AssignmentExpression assignment;
-    {
-      var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');
-      var statement = statements[1] as ExpressionStatement;
-      assignment = statement.expression as AssignmentExpression;
-    }
-    // get parameter
-    Expression rhs = assignment.rightHandSide;
-    expect(rhs.staticParameterElement, isNotNull);
+    await resolveTestFile();
+
+    var rhs = findNode.assignment(' = 0;').rightHandSide;
+    expect(
+      rhs.staticParameterElement,
+      findElement.parameter('x'),
+    );
   }
 
   test_argumentResolution_setter_static() async {
-    CompilationUnit unit = await resolveSource(r'''
+    addTestFile(r'''
 main() {
   A a = new A();
   a.sss = 0;
@@ -178,26 +166,17 @@
 class A {
   set sss(x) {}
 }''');
-    // find "a.sss = 0"
-    AssignmentExpression assignment;
-    {
-      var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');
-      var statement = statements[1] as ExpressionStatement;
-      assignment = statement.expression as AssignmentExpression;
-    }
-    // get parameter
-    Expression rhs = assignment.rightHandSide;
-    ParameterElement parameter = rhs.staticParameterElement;
-    expect(parameter, isNotNull);
-    expect(parameter.displayName, "x");
-    // validate
-    ClassElement classA = unit.declaredElement.types[0];
-    PropertyAccessorElement setter = classA.accessors[0];
-    expect(setter.parameters[0], same(parameter));
+    await resolveTestFile();
+
+    var rhs = findNode.assignment(' = 0;').rightHandSide;
+    expect(
+      rhs.staticParameterElement,
+      findElement.parameter('x'),
+    );
   }
 
   test_argumentResolution_setter_static_propertyAccess() async {
-    CompilationUnit unit = await resolveSource(r'''
+    addTestFile(r'''
 main() {
   A a = new A();
   a.b.sss = 0;
@@ -208,28 +187,19 @@
 class B {
   set sss(x) {}
 }''');
-    // find "a.b.sss = 0"
-    AssignmentExpression assignment;
-    {
-      var statements = AstFinder.getStatementsInTopLevelFunction(unit, 'main');
-      var statement = statements[1] as ExpressionStatement;
-      assignment = statement.expression as AssignmentExpression;
-    }
-    // get parameter
-    Expression rhs = assignment.rightHandSide;
-    ParameterElement parameter = rhs.staticParameterElement;
-    expect(parameter, isNotNull);
-    expect(parameter.displayName, "x");
-    // validate
-    ClassElement classB = unit.declaredElement.types[1];
-    PropertyAccessorElement setter = classB.accessors[0];
-    expect(setter.parameters[0], same(parameter));
+    await resolveTestFile();
+
+    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.
-    String text = r'''
+    addTestFile(r'''
 void f() {
   loop1: while (true) {
     loop2: for (int i = 0; i < 10; i++) {
@@ -238,70 +208,65 @@
     }
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    WhileStatement whileStatement = EngineTestCase.findNode(
-        unit, text, 'while (true)', (n) => n is WhileStatement);
-    ForStatement forStatement =
-        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
-    BreakStatement break1 = EngineTestCase.findNode(
-        unit, text, 'break loop1', (n) => n is BreakStatement);
-    BreakStatement break2 = EngineTestCase.findNode(
-        unit, text, 'break loop2', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    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 {
-    String text = r'''
+    addTestFile('''
 void f() {
   do {
     break;
   } while (true);
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    DoStatement doStatement =
-        EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
-    BreakStatement breakStatement = EngineTestCase.findNode(
-        unit, text, 'break', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    var doStatement = findNode.doStatement('do {');
+    var breakStatement = findNode.breakStatement('break;');
     expect(breakStatement.target, same(doStatement));
   }
 
   test_breakTarget_unlabeledBreakFromFor() async {
-    String text = r'''
+    addTestFile(r'''
 void f() {
   for (int i = 0; i < 10; i++) {
     break;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    ForStatement forStatement =
-        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
-    BreakStatement breakStatement = EngineTestCase.findNode(
-        unit, text, 'break', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    var forStatement = findNode.forStatement('for (');
+    var breakStatement = findNode.breakStatement('break;');
     expect(breakStatement.target, same(forStatement));
   }
 
   test_breakTarget_unlabeledBreakFromForEach() async {
-    String text = r'''
+    addTestFile('''
 void f() {
   for (x in []) {
     break;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    ForEachStatement forStatement = EngineTestCase.findNode(
-        unit, text, 'for', (n) => n is ForEachStatement);
-    BreakStatement breakStatement = EngineTestCase.findNode(
-        unit, text, 'break', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    var forStatement = findNode.forEachStatement('for (');
+    var breakStatement = findNode.breakStatement('break;');
     expect(breakStatement.target, same(forStatement));
   }
 
   test_breakTarget_unlabeledBreakFromSwitch() async {
-    String text = r'''
+    addTestFile(r'''
 void f() {
   while (true) {
     switch (0) {
@@ -310,35 +275,33 @@
     }
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    SwitchStatement switchStatement = EngineTestCase.findNode(
-        unit, text, 'switch', (n) => n is SwitchStatement);
-    BreakStatement breakStatement = EngineTestCase.findNode(
-        unit, text, 'break', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    var switchStatement = findNode.switchStatement('switch (');
+    var breakStatement = findNode.breakStatement('break;');
     expect(breakStatement.target, same(switchStatement));
   }
 
   test_breakTarget_unlabeledBreakFromWhile() async {
-    String text = r'''
+    addTestFile(r'''
 void f() {
   while (true) {
     break;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    WhileStatement whileStatement = EngineTestCase.findNode(
-        unit, text, 'while', (n) => n is WhileStatement);
-    BreakStatement breakStatement = EngineTestCase.findNode(
-        unit, text, 'break', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    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.
-    String text = r'''
+    addTestFile(r'''
 void f() {
   while (true) {
     void g() {
@@ -346,40 +309,34 @@
     }
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    BreakStatement breakStatement = EngineTestCase.findNode(
-        unit, text, 'break', (n) => n is BreakStatement);
+''');
+    await resolveTestFile();
+
+    var breakStatement = findNode.breakStatement('break;');
     expect(breakStatement.target, isNull);
   }
 
   test_class_definesCall() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 class A {
   int call(int x) { return x; }
 }
 int f(A a) {
   return a(0);
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_class_extends_implements() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 class A extends B implements C {}
 class B {}
 class C {}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_continueTarget_labeled() async {
     // Verify that the target of the label is correctly found and is recorded
     // as the unlabeled portion of the statement.
-    String text = r'''
+    addTestFile('''
 void f() {
   loop1: while (true) {
     loop2: for (int i = 0; i < 10; i++) {
@@ -388,86 +345,80 @@
     }
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    WhileStatement whileStatement = EngineTestCase.findNode(
-        unit, text, 'while (true)', (n) => n is WhileStatement);
-    ForStatement forStatement =
-        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
-    ContinueStatement continue1 = EngineTestCase.findNode(
-        unit, text, 'continue loop1', (n) => n is ContinueStatement);
-    ContinueStatement continue2 = EngineTestCase.findNode(
-        unit, text, 'continue loop2', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    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 {
-    String text = r'''
+    addTestFile('''
 void f() {
   do {
     continue;
   } while (true);
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    DoStatement doStatement =
-        EngineTestCase.findNode(unit, text, 'do', (n) => n is DoStatement);
-    ContinueStatement continueStatement = EngineTestCase.findNode(
-        unit, text, 'continue', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    var doStatement = findNode.doStatement('do {');
+    var continueStatement = findNode.continueStatement('continue;');
     expect(continueStatement.target, same(doStatement));
   }
 
   test_continueTarget_unlabeledContinueFromFor() async {
-    String text = r'''
+    addTestFile('''
 void f() {
   for (int i = 0; i < 10; i++) {
     continue;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    ForStatement forStatement =
-        EngineTestCase.findNode(unit, text, 'for', (n) => n is ForStatement);
-    ContinueStatement continueStatement = EngineTestCase.findNode(
-        unit, text, 'continue', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    var forStatement = findNode.forStatement('for (');
+    var continueStatement = findNode.continueStatement('continue;');
     expect(continueStatement.target, same(forStatement));
   }
 
   test_continueTarget_unlabeledContinueFromForEach() async {
-    String text = r'''
+    addTestFile(r'''
 void f() {
   for (x in []) {
     continue;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    ForEachStatement forStatement = EngineTestCase.findNode(
-        unit, text, 'for', (n) => n is ForEachStatement);
-    ContinueStatement continueStatement = EngineTestCase.findNode(
-        unit, text, 'continue', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    var forStatement = findNode.forEachStatement('for (');
+    var continueStatement = findNode.continueStatement('continue;');
     expect(continueStatement.target, same(forStatement));
   }
 
   test_continueTarget_unlabeledContinueFromWhile() async {
-    String text = r'''
+    addTestFile(r'''
 void f() {
   while (true) {
     continue;
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    WhileStatement whileStatement = EngineTestCase.findNode(
-        unit, text, 'while', (n) => n is WhileStatement);
-    ContinueStatement continueStatement = EngineTestCase.findNode(
-        unit, text, 'continue', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    var whileStatement = findNode.whileStatement('while (');
+    var continueStatement = findNode.continueStatement('continue;');
     expect(continueStatement.target, same(whileStatement));
   }
 
   test_continueTarget_unlabeledContinueSkipsSwitch() async {
-    String text = r'''
+    addTestFile(r'''
 void f() {
   while (true) {
     switch (0) {
@@ -476,19 +427,18 @@
     }
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    WhileStatement whileStatement = EngineTestCase.findNode(
-        unit, text, 'while', (n) => n is WhileStatement);
-    ContinueStatement continueStatement = EngineTestCase.findNode(
-        unit, text, 'continue', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    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.
-    String text = r'''
+    addTestFile(r'''
 void f() {
   while (true) {
     void g() {
@@ -496,77 +446,76 @@
     }
   }
 }
-''';
-    CompilationUnit unit = await resolveSource(text);
-    ContinueStatement continueStatement = EngineTestCase.findNode(
-        unit, text, 'continue', (n) => n is ContinueStatement);
+''');
+    await resolveTestFile();
+
+    var continueStatement = findNode.continueStatement('continue;');
     expect(continueStatement.target, isNull);
   }
 
   test_empty() async {
-    Source source = addSource("");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    addTestFile('');
+    await resolveTestFile();
+    assertNoTestErrors();
   }
 
   test_entryPoint_exported() async {
-    addNamedSource("/two.dart", r'''
-library two;
-main() {}''');
-    Source source = addNamedSource("/one.dart", r'''
-library one;
-export 'two.dart';''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    FunctionElement main = library.entryPoint;
+    newFile('/test/lib/a.dart', content: r'''
+main() {}
+''');
+
+    addTestFile(r'''
+export 'a.dart';
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var library = result.libraryElement;
+    var main = library.entryPoint;
+
     expect(main, isNotNull);
     expect(main.library, isNot(same(library)));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_entryPoint_local() async {
-    Source source = addNamedSource("/one.dart", r'''
-library one;
-main() {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    FunctionElement main = library.entryPoint;
+    addTestFile(r'''
+main() {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var library = result.libraryElement;
+    var main = library.entryPoint;
+
     expect(main, isNotNull);
     expect(main.library, same(library));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_entryPoint_none() async {
-    Source source = addNamedSource("/one.dart", "library one;");
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
+    addTestFile('');
+    await resolveTestFile();
+    assertNoTestErrors();
+
+    var library = result.libraryElement;
     expect(library.entryPoint, isNull);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_enum_externalLibrary() async {
-    addNamedSource("/my_lib.dart", r'''
-library my_lib;
-enum EEE {A, B, C}''');
-    Source source = addSource(r'''
-import 'my_lib.dart';
-main() {
-  EEE e = null;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    newFile('/test/lib/a.dart', content: r'''
+enum EEE {A, B, C}
+''');
+    addTestFile(r'''
+import 'a.dart';
+
+void f(EEE e) {}
+''');
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_extractedMethodAsConstant() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 abstract class Comparable<T> {
   int compareTo(T other);
   static int compare(Comparable a, Comparable b) => a.compareTo(b);
@@ -574,64 +523,55 @@
 class A {
   void sort([compare = Comparable.compare]) {}
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_fieldFormalParameter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   int x;
   int y;
   A(this.x) : y = x {}
 }''');
-    CompilationUnit unit =
-        analysisContext2.resolveCompilationUnit2(source, source);
-    ClassDeclaration classA = unit.declarations[0];
-    FieldDeclaration field = classA.members[0];
-    ConstructorDeclaration constructor = classA.members[2];
-    ParameterElement paramElement =
-        constructor.parameters.parameters[0].declaredElement;
-    expect(paramElement, new TypeMatcher<FieldFormalParameterElement>());
-    expect((paramElement as FieldFormalParameterElement).field,
-        field.fields.variables[0].declaredElement);
-    ConstructorFieldInitializer initializer = constructor.initializers[0];
-    SimpleIdentifier identifierX = initializer.expression;
-    expect(identifierX.staticElement, paramElement);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
 
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    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 {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 f() {
   List list = [1,2,3];
   for (int x in list) {}
   for (int x in list) {}
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_forLoops_nonConflicting() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 f() {
   for (int i = 0; i < 3; i++) {
   }
   for (int i = 0; i < 3; i++) {
   }
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_functionTypeAlias() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 typedef bool P(e);
 class A {
   P p;
@@ -639,13 +579,11 @@
     if (p(e)) {}
   }
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_getter_and_setter_fromMixins_bare_identifier() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   get x => null;
@@ -661,24 +599,21 @@
   }
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     // Verify that both the getter and setter for "x" in C.f() refer to the
     // accessors defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInMethod(analysisResult.unit, 'C', 'f');
-    var statement = statements[0] as ExpressionStatement;
-    AssignmentExpression assignment = statement.expression;
-    SimpleIdentifier leftHandSide = assignment.leftHandSide;
+    var leftHandSide = findNode.simple('x +=');
     expect(
-        resolutionMap
-            .staticElementForIdentifier(leftHandSide)
-            .enclosingElement
-            .name,
-        'M2');
-    expect(leftHandSide.auxiliaryElements.staticElement.enclosingElement.name,
-        'M2');
+      leftHandSide.staticElement,
+      findElement.setter('x', of: 'M2'),
+    );
+    expect(
+      leftHandSide.auxiliaryElements.staticElement,
+      findElement.getter('x', of: 'M2'),
+    );
   }
 
   @failingTest
@@ -686,7 +621,7 @@
     // TODO(paulberry): it appears that auxiliaryElements isn't properly set on
     // a SimpleIdentifier that's inside a property access.  This bug should be
     // fixed.
-    Source source = addSource(r'''
+    addTestFile(r'''
 class B {}
 class M1 {
   get x => null;
@@ -701,30 +636,24 @@
   new C().x += 1;
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    assertNoTestErrors();
+    verifyTestResolved();
+
     // Verify that both the getter and setter for "x" in "new C().x" refer to
     // the accessors defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(analysisResult.unit, 'main');
-    var statement = statements[0] as ExpressionStatement;
-    AssignmentExpression assignment = statement.expression;
-    PropertyAccess propertyAccess = assignment.leftHandSide;
+    var leftHandSide = findNode.simple('x +=');
     expect(
-        resolutionMap
-            .staticElementForIdentifier(propertyAccess.propertyName)
-            .enclosingElement
-            .name,
-        'M2');
+      leftHandSide.staticElement,
+      findElement.setter('x', of: 'M2'),
+    );
     expect(
-        propertyAccess
-            .propertyName.auxiliaryElements.staticElement.enclosingElement.name,
-        'M2');
+      leftHandSide.auxiliaryElements.staticElement,
+      findElement.getter('x', of: 'M2'),
+    );
   }
 
   test_getter_fromMixins_bare_identifier() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   get x => null;
@@ -738,21 +667,20 @@
   }
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     // Verify that the getter for "x" in C.f() refers to the getter defined in
     // M2.
-    var statements =
-        AstFinder.getStatementsInMethod(analysisResult.unit, 'C', 'f');
-    var statement = statements[0] as ReturnStatement;
-    SimpleIdentifier x = statement.expression;
-    expect(resolutionMap.staticElementForIdentifier(x).enclosingElement.name,
-        'M2');
+    expect(
+      findNode.simple('x;').staticElement,
+      findElement.getter('x', of: 'M2'),
+    );
   }
 
   test_getter_fromMixins_property_access() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   get x => null;
@@ -765,26 +693,20 @@
   var y = new C().x;
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     // Verify that the getter for "x" in "new C().x" refers to the getter
     // defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(analysisResult.unit, 'main');
-    var statement = statements[0] as VariableDeclarationStatement;
-    PropertyAccess propertyAccess =
-        statement.variables.variables[0].initializer;
     expect(
-        resolutionMap
-            .staticElementForIdentifier(propertyAccess.propertyName)
-            .enclosingElement
-            .name,
-        'M2');
+      findNode.simple('x;').staticElement,
+      findElement.getter('x', of: 'M2'),
+    );
   }
 
   test_getterAndSetterWithDifferentTypes() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   int get f => 0;
   void set f(String s) {}
@@ -792,38 +714,35 @@
 g (A a) {
   a.f = a.f.toString();
 }''');
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
-    verify([source]);
+    await resolveTestFile();
+    assertTestErrors([StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES]);
+    verifyTestResolved();
   }
 
   test_hasReferenceToSuper() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {}
 class B {toString() => super.toString();}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(2));
-    expect(classes[0].hasReferenceToSuper, isFalse);
-    expect(classes[1].hasReferenceToSuper, isTrue);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var a = findElement.class_('A');
+    expect(a.hasReferenceToSuper, isFalse);
+
+    var b = findElement.class_('B');
+    expect(b.hasReferenceToSuper, isTrue);
   }
 
   test_import_hide() async {
-    addNamedSource("/lib1.dart", r'''
-library lib1;
+    newFile('/test/lib/lib1.dart', content: r'''
 set foo(value) {}
 class A {}''');
-    addNamedSource("/lib2.dart", r'''
-library lib2;
+
+    newFile('/test/lib/lib2.dart', content: r'''
 set foo(value) {}''');
-    Source source = addNamedSource("/lib3.dart", r'''
+
+    addTestFile(r'''
 import 'lib1.dart' hide foo;
 import 'lib2.dart';
 
@@ -831,26 +750,25 @@
   foo = 0;
 }
 A a;''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_import_prefix() async {
-    addNamedSource("/two.dart", r'''
-library two;
+    newFile('/test/lib/a.dart', content: r'''
 f(int x) {
   return x * x;
 }''');
-    Source source = addNamedSource("/one.dart", r'''
-library one;
-import 'two.dart' as _two;
+
+    addTestFile(r'''
+import 'a.dart' as _a;
 main() {
-  _two.f(0);
+  _a.f(0);
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_import_prefix_doesNotExist() async {
@@ -859,7 +777,7 @@
     // single error generated when the only problem is that an imported file
     // does not exist.
     //
-    Source source = addNamedSource("/a.dart", r'''
+    addTestFile('''
 import 'missing.dart' as p;
 int a = p.q + p.r.s;
 String b = p.t(a) + p.u(v: 0);
@@ -876,9 +794,9 @@
   H(int i) : super(i);
 }
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-    verify([source]);
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+    verifyTestResolved();
   }
 
   test_import_show_doesNotExist() async {
@@ -887,7 +805,7 @@
     // single error generated when the only problem is that an imported file
     // does not exist.
     //
-    Source source = addNamedSource("/a.dart", r'''
+    addTestFile('''
 import 'missing.dart' show q, r, t, u, T, U, V, W;
 int a = q + r.s;
 String b = t(a) + u(v: 0);
@@ -904,28 +822,28 @@
   H(int i) : super(i);
 }
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-    verify([source]);
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+    verifyTestResolved();
   }
 
+  @failingTest
   test_import_spaceInUri() async {
-    addNamedSource("/sub folder/lib.dart", r'''
-library lib;
+    // TODO(scheglov) Fix this. The problem is in `package` URI resolver.
+    newFile('/test/lib/sub folder/a.dart', content: r'''
 foo() {}''');
-    Source source = addNamedSource("/app.dart", r'''
-import 'sub folder/lib.dart';
+
+    await assertNoErrorsInCode(r'''
+import 'sub folder/a.dart';
 
 main() {
   foo();
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_indexExpression_typeParameters() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 f() {
   List<int> a;
   a[0];
@@ -934,24 +852,22 @@
   List<List<List<int>>> c;
   c[0][0][0];
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_indexExpression_typeParameters_invalidAssignmentWarning() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 f() {
   List<List<int>> b;
   b[0][0] = 'hi';
 }''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-    verify([source]);
+    await resolveTestFile();
+    assertTestErrors([StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verifyTestResolved();
   }
 
   test_indirectOperatorThroughCall() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 class A {
   B call() { return new B(); }
 }
@@ -967,113 +883,91 @@
 main() {
   g(f()[0]);
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_invoke_dynamicThroughGetter() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 class A {
   List get X => [() => 0];
   m(A a) {
     X.last;
   }
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_isValidMixin_badSuperclass() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A extends B {}
 class B {}
 class C = Object with A;''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    ClassElement a = unit.getType('A');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verifyTestResolved();
+
+    var a = findElement.class_('A');
     expect(a.isValidMixin, isFalse);
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
-    verify([source]);
   }
 
   test_isValidMixin_constructor() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   A() {}
 }
 class C = Object with A;''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    ClassElement a = unit.getType('A');
-    expect(a.isValidMixin, isFalse);
-    await computeAnalysisResult(source);
-    assertErrors(
-      source,
+    await resolveTestFile();
+    assertTestErrors(
       [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
     );
-    verify([source]);
+    verifyTestResolved();
+
+    var a = findElement.class_('A');
+    expect(a.isValidMixin, isFalse);
   }
 
   test_isValidMixin_factoryConstructor() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   factory A() => null;
 }
 class C = Object with A;''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    ClassElement a = unit.getType('A');
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var a = findElement.class_('A');
     expect(a.isValidMixin, isTrue);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_isValidMixin_super() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   toString() {
     return super.toString();
   }
 }
 class C = Object with A;''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    ClassElement a = unit.getType('A');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+    verifyTestResolved();
+
+    var a = findElement.class_('A');
     expect(a.isValidMixin, isFalse);
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
-    verify([source]);
   }
 
   test_isValidMixin_valid() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 class A {}
 class C = Object with A;''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    ClassElement a = unit.getType('A');
+    verifyTestResolved();
+
+    var a = findElement.class_('A');
     expect(a.isValidMixin, isTrue);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_labels_switch() async {
-    Source source = addSource(r'''
+    await assertNoErrorsInCode(r'''
 void doSwitch(int target) {
   switch (target) {
     l0: case 0:
@@ -1084,269 +978,174 @@
       continue l1;
   }
 }''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    verifyTestResolved();
   }
 
   test_localVariable_types_invoked() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 main() {
   var myVar = (int p) => 'foo';
   myVar(42);
 }''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(source, library);
-    expect(unit, isNotNull);
-    List<bool> found = [false];
-    List<CaughtException> thrownException = new List<CaughtException>(1);
-    unit.accept(new _SimpleResolverTest_localVariable_types_invoked(
-        this, found, thrownException));
-    if (thrownException[0] != null) {
-      throw new AnalysisException(
-          "Exception", new CaughtException(thrownException[0], null));
-    }
-    expect(found[0], isTrue);
+    await resolveTestFile();
+
+    var node = findNode.simple('myVar(42)');
+    assertType(node, '(int) → String');
   }
 
   test_metadata_class() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 @A class C<A> {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unitElement = library.definingCompilationUnit;
-    expect(unitElement, isNotNull);
-    List<ClassElement> classes = unitElement.types;
-    expect(classes, hasLength(1));
-    List<ElementAnnotation> annotations = classes[0].metadata;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var annotations = findElement.class_('C').metadata;
     expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
 
-    CompilationUnit unit = resolveCompilationUnit(source, library);
-    NodeList<CompilationUnitMember> declarations = unit.declarations;
-    expect(declarations, hasLength(2));
-
-    TopLevelVariableDeclaration variableDeclaration = declarations[0];
-    ClassDeclaration classDeclaration = declarations[1];
-
-    PropertyInducingElement expectedElement =
-        variableDeclaration.variables.variables[0].name.staticElement;
-
-    Element actualElement = classDeclaration.metadata[0].name.staticElement;
-    expect(actualElement, same(expectedElement.getter));
+    var cDeclaration = findNode.classDeclaration('C<A>');
+    assertElement(
+      cDeclaration.metadata[0].name,
+      findElement.topGet('A'),
+    );
   }
 
   test_metadata_field() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 class C {
   @A int f;
 }''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(1));
-    FieldElement field = classes[0].fields[0];
-    List<ElementAnnotation> annotations = field.metadata;
-    expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = findElement.field('f').metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_fieldFormalParameter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 class C {
   int f;
   C(@A this.f);
 }''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(1));
-    List<ConstructorElement> constructors = classes[0].constructors;
-    expect(constructors, hasLength(1));
-    List<ParameterElement> parameters = constructors[0].parameters;
-    expect(parameters, hasLength(1));
-    List<ElementAnnotation> annotations = parameters[0].metadata;
-    expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = findElement.fieldFormalParameter('f').metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_function() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 @A f() {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<FunctionElement> functions = unit.functions;
-    expect(functions, hasLength(1));
-    List<ElementAnnotation> annotations = functions[0].metadata;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var annotations = findElement.topFunction('f').metadata;
     expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
   }
 
   test_metadata_functionTypedParameter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 f(@A int p(int x)) {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<FunctionElement> functions = unit.functions;
-    expect(functions, hasLength(1));
-    List<ParameterElement> parameters = functions[0].parameters;
-    expect(parameters, hasLength(1));
-    List<ElementAnnotation> annotations1 = parameters[0].metadata;
-    expect(annotations1, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = findElement.parameter('p').metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_libraryDirective() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 @A library lib;
 const A = null;''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    List<ElementAnnotation> annotations = library.metadata;
-    expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = result.libraryElement.metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_method() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 class C {
   @A void m() {}
 }''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(1));
-    MethodElement method = classes[0].methods[0];
-    List<ElementAnnotation> annotations = method.metadata;
-    expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = findElement.method('m').metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_namedParameter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 f({@A int p : 0}) {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<FunctionElement> functions = unit.functions;
-    expect(functions, hasLength(1));
-    List<ParameterElement> parameters = functions[0].parameters;
-    expect(parameters, hasLength(1));
-    List<ElementAnnotation> annotations1 = parameters[0].metadata;
-    expect(annotations1, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = findElement.parameter('p').metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_positionalParameter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 f([@A int p = 0]) {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<FunctionElement> functions = unit.functions;
-    expect(functions, hasLength(1));
-    List<ParameterElement> parameters = functions[0].parameters;
-    expect(parameters, hasLength(1));
-    List<ElementAnnotation> annotations1 = parameters[0].metadata;
-    expect(annotations1, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    var metadata = findElement.parameter('p').metadata;
+    expect(metadata, hasLength(1));
   }
 
   test_metadata_simpleParameter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 f(@A p1, @A int p2) {}''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull);
-    List<FunctionElement> functions = unit.functions;
-    expect(functions, hasLength(1));
-    List<ParameterElement> parameters = functions[0].parameters;
-    expect(parameters, hasLength(2));
-    List<ElementAnnotation> annotations1 = parameters[0].metadata;
-    expect(annotations1, hasLength(1));
-    List<ElementAnnotation> annotations2 = parameters[1].metadata;
-    expect(annotations2, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
+    expect(findElement.parameter('p1').metadata, hasLength(1));
+    expect(findElement.parameter('p2').metadata, hasLength(1));
   }
 
   test_metadata_typedef() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 const A = null;
 @A typedef F<A>();''');
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    CompilationUnitElement unitElement = library.definingCompilationUnit;
-    expect(unitElement, isNotNull);
-    List<FunctionTypeAliasElement> aliases = unitElement.functionTypeAliases;
-    expect(aliases, hasLength(1));
-    List<ElementAnnotation> annotations = aliases[0].metadata;
-    expect(annotations, hasLength(1));
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = resolveCompilationUnit(source, library);
-    NodeList<CompilationUnitMember> declarations = unit.declarations;
-    expect(declarations, hasLength(2));
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
 
-    TopLevelVariableDeclaration variableDeclaration = declarations[0];
-    FunctionTypeAlias functionTypeAlias = declarations[1];
+    expect(
+      findElement.genericTypeAlias('F').metadata,
+      hasLength(1),
+    );
 
-    PropertyInducingElement expectedElement =
-        variableDeclaration.variables.variables[0].name.staticElement;
-
-    Element actualElement = functionTypeAlias.metadata[0].name.staticElement;
-    expect(actualElement, same(expectedElement.getter));
+    var actualElement = findNode.annotation('@A').name.staticElement;
+    expect(actualElement, findElement.topGet('A'));
   }
 
   test_method_fromMixin() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class B {
   bar() => 1;
 }
@@ -1358,13 +1157,13 @@
   bar() => super.bar();
   foo() => super.foo();
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_method_fromMixins() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   void f() {}
@@ -1377,24 +1176,18 @@
   new C().f();
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    // Verify that the "f" in "new C().f()" refers to the "f" defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(analysisResult.unit, 'main');
-    var statement = statements[0] as ExpressionStatement;
-    MethodInvocation expr = statement.expression;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     expect(
-        resolutionMap
-            .staticElementForIdentifier(expr.methodName)
-            .enclosingElement
-            .name,
-        'M2');
+      findNode.simple('f();').staticElement,
+      findElement.method('f', of: 'M2'),
+    );
   }
 
   test_method_fromMixins_bare_identifier() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   void f() {}
@@ -1408,25 +1201,18 @@
   }
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    // Verify that the call to f() in C.g() refers to the method defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInMethod(analysisResult.unit, 'C', 'g');
-    var statement = statements[0] as ExpressionStatement;
-    MethodInvocation invocation = statement.expression;
-    SimpleIdentifier methodName = invocation.methodName;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     expect(
-        resolutionMap
-            .staticElementForIdentifier(methodName)
-            .enclosingElement
-            .name,
-        'M2');
+      findNode.simple('f();').staticElement,
+      findElement.method('f', of: 'M2'),
+    );
   }
 
   test_method_fromMixins_invoked_from_outside_class() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   void f() {}
@@ -1439,25 +1225,18 @@
   new C().f();
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    // Verify that the call to f() in "new C().f()" refers to the method
-    // defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(analysisResult.unit, 'main');
-    var statement = statements[0] as ExpressionStatement;
-    MethodInvocation invocation = statement.expression;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     expect(
-        resolutionMap
-            .staticElementForIdentifier(invocation.methodName)
-            .enclosingElement
-            .name,
-        'M2');
+      findNode.simple('f();').staticElement,
+      findElement.method('f', of: 'M2'),
+    );
   }
 
   test_method_fromSuperclassMixin() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void m1() {}
 }
@@ -1468,13 +1247,13 @@
 f(C c) {
   c.m1();
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_methodCascades() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   void m1() {}
   void m2() {}
@@ -1484,13 +1263,13 @@
      ..m2();
   }
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_methodCascades_withSetter() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   String name;
   void m1() {}
@@ -1502,23 +1281,23 @@
      ..m2();
   }
 }''');
-    // failing with error code: INVOCATION_OF_NON_FUNCTION
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_resolveAgainstNull() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 f(var p) {
   return null == p;
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_setter_fromMixins_bare_identifier() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   set x(value) {}
@@ -1532,26 +1311,18 @@
   }
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    // Verify that the setter for "x" in C.f() refers to the setter defined in
-    // M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInMethod(analysisResult.unit, 'C', 'f');
-    var statement = statements[0] as ExpressionStatement;
-    AssignmentExpression assignment = statement.expression;
-    SimpleIdentifier leftHandSide = assignment.leftHandSide;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     expect(
-        resolutionMap
-            .staticElementForIdentifier(leftHandSide)
-            .enclosingElement
-            .name,
-        'M2');
+      findNode.simple('x = ').staticElement,
+      findElement.setter('x', of: 'M2'),
+    );
   }
 
   test_setter_fromMixins_property_access() async {
-    Source source = addSource('''
+    addTestFile('''
 class B {}
 class M1 {
   set x(value) {}
@@ -1564,26 +1335,18 @@
   new C().x = 1;
 }
 ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    // Verify that the setter for "x" in "new C().x" refers to the setter
-    // defined in M2.
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(analysisResult.unit, 'main');
-    var statement = statements[0] as ExpressionStatement;
-    AssignmentExpression assignment = statement.expression;
-    PropertyAccess propertyAccess = assignment.leftHandSide;
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
+
     expect(
-        resolutionMap
-            .staticElementForIdentifier(propertyAccess.propertyName)
-            .enclosingElement
-            .name,
-        'M2');
+      findNode.simple('x = ').staticElement,
+      findElement.setter('x', of: 'M2'),
+    );
   }
 
   test_setter_inherited() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 class A {
   int get x => 0;
   set x(int p) {}
@@ -1592,49 +1355,41 @@
   int get x => super.x == null ? 0 : super.x;
   int f() => x = 1;
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   test_setter_static() async {
-    Source source = addSource(r'''
+    addTestFile(r'''
 set s(x) {
 }
 
 main() {
   s = 123;
 }''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  @failingTest
-  test_staticInvocation() async {
-    Source source = addSource(r'''
-class A {
-  static int get g => (a,b) => 0;
-}
-class B {
-  f() {
-    A.g(1,0);
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
+    await resolveTestFile();
+    assertNoTestErrors();
+    verifyTestResolved();
   }
 
   /**
-   * Resolve the given source and verify that the arguments in a specific method invocation were
-   * correctly resolved.
+   * Verify that all of the identifiers in the [result] have been resolved.
+   */
+  void verifyTestResolved() {
+    var verifier = new 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 source is expected to be source for a compilation unit, the first declaration is expected
-   * to be a class, the first member of which is expected to be a method with a block body, and the
-   * first statement in the body is expected to be an expression statement whose expression is a
-   * method invocation. It is the arguments to that method invocation that are tested. The method
-   * invocation can contain errors.
+   * 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
@@ -1642,66 +1397,33 @@
    * 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 source the source to be resolved
    * @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
    */
-  void _validateArgumentResolution(Source source, List<int> indices) {
-    LibraryElement library = resolve2(source);
-    expect(library, isNotNull);
-    ClassElement classElement = library.definingCompilationUnit.types[0];
-    List<ParameterElement> parameters = classElement.methods[1].parameters;
-    CompilationUnit unit = resolveCompilationUnit(source, library);
-    expect(unit, isNotNull);
-    ClassDeclaration classDeclaration =
-        unit.declarations[0] as ClassDeclaration;
-    MethodDeclaration methodDeclaration =
-        classDeclaration.members[0] as MethodDeclaration;
-    Block block = (methodDeclaration.body as BlockFunctionBody).block;
-    ExpressionStatement statement = block.statements[0] as ExpressionStatement;
-    MethodInvocation invocation = statement.expression as MethodInvocation;
-    NodeList<Expression> arguments = invocation.argumentList.arguments;
-    int argumentCount = arguments.length;
+  Future<void> _validateArgumentResolution(List<int> indices) async {
+    await resolveTestFile();
+
+    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 (int i = 0; i < argumentCount; i++) {
-      Expression argument = arguments[i];
-      ParameterElement element = argument.staticParameterElement;
-      int index = indices[i];
+
+    for (var i = 0; i < argumentCount; i++) {
+      var argument = arguments[i];
+      var actualParameter = argument.staticParameterElement;
+
+      var index = indices[i];
       if (index < 0) {
-        expect(element, isNull);
+        expect(actualParameter, isNull);
       } else {
-        expect(element, same(parameters[index]));
-      }
-    }
-  }
-}
-
-class _SimpleResolverTest_localVariable_types_invoked
-    extends RecursiveAstVisitor<void> {
-  final SimpleResolverTest test;
-
-  List<bool> found;
-
-  List<CaughtException> thrownException;
-
-  _SimpleResolverTest_localVariable_types_invoked(
-      this.test, this.found, this.thrownException)
-      : super();
-
-  @override
-  void visitSimpleIdentifier(SimpleIdentifier node) {
-    if (node.name == "myVar" && node.parent is MethodInvocation) {
-      try {
-        found[0] = true;
-        // check static type
-        DartType staticType = node.staticType;
-        expect(staticType is FunctionType, isTrue);
-        FunctionType functionType = staticType;
-        expect(functionType.parameters[0].type, test.typeProvider.intType);
-        expect(functionType.returnType, test.typeProvider.stringType);
-      } on AnalysisException catch (e, stackTrace) {
-        thrownException[0] = new CaughtException(e, stackTrace);
+        var expectedParameter = parameters[index];
+        expect(actualParameter, same(expectedParameter));
       }
     }
   }
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index fe9cb89..c6bafc8 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -35,7 +35,6 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(SetLiteralsTest);
     defineReflectiveTests(StaticTypeAnalyzerTest);
-    defineReflectiveTests(StaticTypeAnalyzer2Test);
     defineReflectiveTests(StaticTypeAnalyzer3Test);
     defineReflectiveTests(StaticTypeAnalyzerWithSetLiteralsTest);
   });
@@ -74,8 +73,7 @@
 /**
  * Like [StaticTypeAnalyzerTest], but as end-to-end tests.
  */
-@reflectiveTest
-class StaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
+abstract class StaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
   test_FunctionExpressionInvocation_block() async {
     String code = r'''
 main() {
@@ -1542,7 +1540,6 @@
     _visitor = new ResolverVisitor(
         inheritance, definingLibrary, source, _typeProvider, _listener,
         nameScope: new LibraryScope(definingLibrary));
-    _visitor.overrideManager.enterScope();
     return _visitor.typeAnalyzer;
   }
 
@@ -1586,7 +1583,7 @@
     for (FormalParameter parameter in parameters.parameters) {
       ParameterElementImpl element =
           new ParameterElementImpl.forNode(parameter.identifier);
-      // ignore: deprecated_member_use
+      // ignore: deprecated_member_use_from_same_package
       element.parameterKind = parameter.kind;
       element.type = _typeProvider.dynamicType;
       parameter.identifier.staticElement = element;
diff --git a/pkg/analyzer/test/generated/static_type_warning_code.dart b/pkg/analyzer/test/generated/static_type_warning_code.dart
new file mode 100644
index 0000000..01f0538
--- /dev/null
+++ b/pkg/analyzer/test/generated/static_type_warning_code.dart
@@ -0,0 +1,1755 @@
+// 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/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'resolver_test_case.dart';
+
+abstract class StaticTypeWarningCodeTest extends ResolverTestCase {
+  fail_undefinedEnumConstant() async {
+    // We need a way to set the parseEnum flag in the parser to true.
+    await assertErrorsInCode(r'''
+enum E { ONE }
+E e() {
+  return E.TWO;
+}''', [StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT]);
+  }
+
+  test_assert_message_suppresses_type_promotion() async {
+    // If a variable is assigned to inside the expression for an assert
+    // message, type promotion should be suppressed, just as it would be if the
+    // assignment occurred outside an assert statement.  (Note that it is a
+    // dubious practice for the computation of an assert message to have side
+    // effects, since it is only evaluated if the assert fails).
+    await assertErrorsInCode('''
+class C {
+  void foo() {}
+}
+
+f(Object x) {
+  if (x is C) {
+    x.foo();
+    assert(true, () { x = new C(); return 'msg'; }());
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    // Do not verify since `x.foo()` fails to resolve.
+  }
+
+  test_await_flattened() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Future<Future<int>> ffi() => null;
+f() async {
+  Future<int> b = await ffi(); 
+}
+''', []);
+  }
+
+  test_await_simple() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Future<int> fi() => null;
+f() async {
+  String a = await fi(); // Warning: int not assignable to String
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_awaitForIn_declaredVariableRightType() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<int> stream;
+  await for (int i in stream) {}
+}
+''');
+  }
+
+  test_awaitForIn_declaredVariableWrongType() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<String> stream;
+  await for (int i in stream) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_awaitForIn_downcast() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<num> stream;
+  await for (int i in stream) {}
+}
+''');
+  }
+
+  test_awaitForIn_dynamicStream() async {
+    await assertNoErrorsInCode('''
+f() async {
+  dynamic stream;
+  await for (int i in stream) {}
+}
+''');
+  }
+
+  test_awaitForIn_dynamicVariable() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<int> stream;
+  await for (var i in stream) {}
+}
+''');
+  }
+
+  test_awaitForIn_existingVariableRightType() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<int> stream;
+  int i;
+  await for (i in stream) {}
+}
+''');
+  }
+
+  test_awaitForIn_existingVariableWrongType() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<String> stream;
+  int i;
+  await for (i in stream) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_awaitForIn_notStream() async {
+    await assertErrorsInCode('''
+f() async {
+  await for (var i in true) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE]);
+  }
+
+  test_awaitForIn_streamOfDynamic() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream stream;
+  await for (int i in stream) {}
+}
+''');
+  }
+
+  test_awaitForIn_upcast() async {
+    await assertNoErrorsInCode('''
+import 'dart:async';
+f() async {
+  Stream<int> stream;
+  await for (num i in stream) {}
+}
+''');
+  }
+
+  test_bug21912() async {
+    await assertErrorsInCode('''
+class A {}
+class B extends A {}
+
+typedef T Function2<S, T>(S z);
+typedef B AToB(A x);
+typedef A BToA(B x);
+
+void main() {
+  {
+    Function2<Function2<A, B>, Function2<B, A>> t1;
+    Function2<AToB, BToA> t2;
+
+    Function2<Function2<int, double>, Function2<int, double>> left;
+
+    left = t1;
+    left = t2;
+  }
+}
+''', [
+      StaticTypeWarningCode.INVALID_ASSIGNMENT,
+      StaticTypeWarningCode.INVALID_ASSIGNMENT
+    ]);
+  }
+
+  test_expectedOneListTypeArgument() async {
+    await assertErrorsInCode(r'''
+main() {
+  <int, int> [];
+}''', [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]);
+  }
+
+  @failingTest
+  test_expectedOneSetTypeArgument() async {
+    await assertErrorsInCode(r'''
+main() {
+  <int, int>{2, 3};
+}''', [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS]);
+  }
+
+  test_expectedTwoMapTypeArguments_three() async {
+    await assertErrorsInCode(r'''
+main() {
+  <int, int, int> {};
+}''', [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]);
+  }
+
+  test_forIn_declaredVariableRightType() async {
+    await assertNoErrorsInCode('''
+f() {
+  for (int i in <int>[]) {}
+}
+''');
+  }
+
+  test_forIn_declaredVariableWrongType() async {
+    await assertErrorsInCode('''
+f() {
+  for (int i in <String>[]) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_forIn_downcast() async {
+    await assertNoErrorsInCode('''
+f() {
+  for (int i in <num>[]) {}
+}
+''');
+  }
+
+  test_forIn_dynamic() async {
+    await assertNoErrorsInCode('''
+f() {
+  dynamic d; // Could be [].
+  for (var i in d) {}
+}
+''');
+  }
+
+  test_forIn_dynamicIterable() async {
+    await assertNoErrorsInCode('''
+f() {
+  dynamic iterable;
+  for (int i in iterable) {}
+}
+''');
+  }
+
+  test_forIn_dynamicVariable() async {
+    await assertNoErrorsInCode('''
+f() {
+  for (var i in <int>[]) {}
+}
+''');
+  }
+
+  test_forIn_existingVariableRightType() async {
+    await assertNoErrorsInCode('''
+f() {
+  int i;
+  for (i in <int>[]) {}
+}
+''');
+  }
+
+  test_forIn_existingVariableWrongType() async {
+    await assertErrorsInCode('''
+f() {
+  int i;
+  for (i in <String>[]) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_forIn_iterableOfDynamic() async {
+    await assertNoErrorsInCode('''
+f() {
+  for (int i in []) {}
+}
+''');
+  }
+
+  test_forIn_notIterable() async {
+    await assertErrorsInCode('''
+f() {
+  for (var i in true) {}
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE]);
+  }
+
+  test_forIn_object() async {
+    await assertNoErrorsInCode('''
+f() {
+  Object o; // Could be [].
+  for (var i in o) {}
+}
+''');
+  }
+
+  test_forIn_typeBoundBad() async {
+    await assertErrorsInCode('''
+class Foo<T extends Iterable<int>> {
+  void method(T iterable) {
+    for (String i in iterable) {}
+  }
+}
+''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
+  }
+
+  test_forIn_typeBoundGood() async {
+    await assertNoErrorsInCode('''
+class Foo<T extends Iterable<int>> {
+  void method(T iterable) {
+    for (var i in iterable) {}
+  }
+}
+''');
+  }
+
+  test_forIn_upcast() async {
+    await assertNoErrorsInCode('''
+f() {
+  for (num i in <int>[]) {}
+}
+''');
+  }
+
+  test_illegalAsyncGeneratorReturnType_function_nonStream() async {
+    await assertErrorsInCode('''
+int f() async* {}
+''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalAsyncGeneratorReturnType_function_subtypeOfStream() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+abstract class SubStream<T> implements Stream<T> {}
+SubStream<int> f() async* {}
+''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalAsyncGeneratorReturnType_method_nonStream() async {
+    await assertErrorsInCode('''
+class C {
+  int f() async* {}
+}
+''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalAsyncGeneratorReturnType_method_subtypeOfStream() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+abstract class SubStream<T> implements Stream<T> {}
+class C {
+  SubStream<int> f() async* {}
+}
+''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalAsyncReturnType_function_nonFuture() async {
+    await assertErrorsInCode('''
+int f() async {}
+''', [
+      StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
+      HintCode.MISSING_RETURN
+    ]);
+  }
+
+  test_illegalAsyncReturnType_function_subtypeOfFuture() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+abstract class SubFuture<T> implements Future<T> {}
+SubFuture<int> f() async {
+  return 0;
+}
+''', [StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE]);
+  }
+
+  test_illegalAsyncReturnType_method_nonFuture() async {
+    await assertErrorsInCode('''
+class C {
+  int m() async {}
+}
+''', [
+      StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
+      HintCode.MISSING_RETURN
+    ]);
+  }
+
+  test_illegalAsyncReturnType_method_subtypeOfFuture() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+abstract class SubFuture<T> implements Future<T> {}
+class C {
+  SubFuture<int> m() async {
+    return 0;
+  }
+}
+''', [StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE]);
+  }
+
+  test_illegalSyncGeneratorReturnType_function_nonIterator() async {
+    await assertErrorsInCode('''
+int f() sync* {}
+''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalSyncGeneratorReturnType_function_subclassOfIterator() async {
+    await assertErrorsInCode('''
+abstract class SubIterator<T> implements Iterator<T> {}
+SubIterator<int> f() sync* {}
+''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalSyncGeneratorReturnType_method_nonIterator() async {
+    await assertErrorsInCode('''
+class C {
+  int f() sync* {}
+}
+''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_illegalSyncGeneratorReturnType_method_subclassOfIterator() async {
+    await assertErrorsInCode('''
+abstract class SubIterator<T> implements Iterator<T> {}
+class C {
+  SubIterator<int> f() sync* {}
+}
+''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
+  }
+
+  test_instanceAccessToStaticMember_method_reference() async {
+    await assertErrorsInCode(r'''
+class A {
+  static m() {}
+}
+main(A a) {
+  a.m;
+}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+  }
+
+  test_instanceAccessToStaticMember_propertyAccess_field() async {
+    await assertErrorsInCode(r'''
+class A {
+  static var f;
+}
+main(A a) {
+  a.f;
+}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+  }
+
+  test_instanceAccessToStaticMember_propertyAccess_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  static get f => 42;
+}
+main(A a) {
+  a.f;
+}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+  }
+
+  test_instanceAccessToStaticMember_propertyAccess_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  static set f(x) {}
+}
+main(A a) {
+  a.f = 42;
+}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
+  }
+
+  test_invalidAssignment_compoundAssignment() async {
+    await assertErrorsInCode(r'''
+class byte {
+  int _value;
+  byte(this._value);
+  int operator +(int val) { return 0; }
+}
+
+void main() {
+  byte b = new byte(52);
+  b += 3;
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_defaultValue_named() async {
+    await assertErrorsInCode(r'''
+f({String x: 0}) {
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_defaultValue_optional() async {
+    await assertErrorsInCode(r'''
+f([String x = 0]) {
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_dynamic() async {
+    await assertErrorsInCode(r'''
+main() {
+  dynamic = 1;
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_functionExpressionInvocation() async {
+    await assertErrorsInCode('''
+main() {
+  String x = (() => 5)();
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_ifNullAssignment() async {
+    await assertErrorsInCode('''
+void f(int i) {
+  double d;
+  d ??= i;
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_instanceVariable() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+}
+f() {
+  A a;
+  a.x = '0';
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_localVariable() async {
+    await assertErrorsInCode(r'''
+f() {
+  int x;
+  x = '0';
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_postfixExpression_localVariable() async {
+    await assertErrorsInCode(r'''
+class A {
+  B operator+(_) => new B();
+}
+
+class B {}
+
+f(A a) {
+  a++;
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_postfixExpression_property() async {
+    await assertErrorsInCode(r'''
+class A {
+  B operator+(_) => new B();
+}
+
+class B {}
+
+class C {
+  A a;
+}
+
+f(C c) {
+  c.a++;
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_prefixExpression_localVariable() async {
+    await assertErrorsInCode(r'''
+class A {
+  B operator+(_) => new B();
+}
+
+class B {}
+
+f(A a) {
+  ++a;
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_prefixExpression_property() async {
+    await assertErrorsInCode(r'''
+class A {
+  B operator+(_) => new B();
+}
+
+class B {}
+
+class C {
+  A a;
+}
+
+f(C c) {
+  ++c.a;
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_regressionInIssue18468Fix() async {
+    // https://code.google.com/p/dart/issues/detail?id=18628
+    await assertErrorsInCode(r'''
+class C<T> {
+  T t = int;
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_staticVariable() async {
+    await assertErrorsInCode(r'''
+class A {
+  static int x;
+}
+f() {
+  A.x = '0';
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_topLevelVariableDeclaration() async {
+    await assertErrorsInCode(
+        "int x = 'string';", [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_typeParameter() async {
+    // 14221
+    await assertErrorsInCode(r'''
+class B<T> {
+  T value;
+  void test(num n) {
+    value = n;
+  }
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invalidAssignment_variableDeclaration() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x = 'string';
+}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
+  test_invocationOfNonFunctionExpression_literal() async {
+    await assertErrorsInCode(r'''
+f() {
+  3(5);
+}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION]);
+  }
+
+  test_nonBoolCondition_conditional() async {
+    await assertErrorsInCode("f() { return 3 ? 2 : 1; }",
+        [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonBoolCondition_do() async {
+    await assertErrorsInCode(r'''
+f() {
+  do {} while (3);
+}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonBoolCondition_for() async {
+    // https://github.com/dart-lang/sdk/issues/24713
+    await assertErrorsInCode(r'''
+f() {
+  for (;3;) {}
+}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonBoolCondition_if() async {
+    await assertErrorsInCode(r'''
+f() {
+  if (3) return 2; else return 1;
+}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonBoolCondition_while() async {
+    await assertErrorsInCode(r'''
+f() {
+  while (3) {}
+}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+  }
+
+  test_nonBoolExpression_functionType_bool() async {
+    Source source = addSource(r'''
+bool makeAssertion() => true;
+f() {
+  assert(makeAssertion);
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+    verify([source]);
+  }
+
+  test_nonBoolExpression_functionType_int() async {
+    await assertErrorsInCode(r'''
+int makeAssertion() => 1;
+f() {
+  assert(makeAssertion);
+}''', [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+  }
+
+  test_nonBoolExpression_interfaceType() async {
+    await assertErrorsInCode(r'''
+f() {
+  assert(0);
+}''', [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+  }
+
+  test_nonBoolNegationExpression() async {
+    await assertErrorsInCode(r'''
+f() {
+  !42;
+}''', [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]);
+  }
+
+  test_nonBoolOperand_and_left() async {
+    await assertErrorsInCode(r'''
+bool f(int left, bool right) {
+  return left && right;
+}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
+  }
+
+  test_nonBoolOperand_and_right() async {
+    await assertErrorsInCode(r'''
+bool f(bool left, String right) {
+  return left && right;
+}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
+  }
+
+  test_nonBoolOperand_or_left() async {
+    await assertErrorsInCode(r'''
+bool f(List<int> left, bool right) {
+  return left || right;
+}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
+  }
+
+  test_nonBoolOperand_or_right() async {
+    await assertErrorsInCode(r'''
+bool f(bool left, double right) {
+  return left || right;
+}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
+  }
+
+  test_nonTypeAsTypeArgument_notAType() async {
+    await assertErrorsInCode(r'''
+int A;
+class B<E> {}
+f(B<A> b) {}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
+  }
+
+  test_nonTypeAsTypeArgument_undefinedIdentifier() async {
+    await assertErrorsInCode(r'''
+class B<E> {}
+f(B<A> b) {}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
+  }
+
+  test_returnOfInvalidType_async_future_future_int_mismatches_future_int() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Future<int> f() async {
+  return g();
+}
+Future<Future<int>> g() => null;
+''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_async_future_int_mismatches_future_string() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Future<String> f() async {
+  return 5;
+}
+''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_async_future_int_mismatches_int() async {
+    await assertErrorsInCode('''
+int f() async {
+  return 5;
+}
+''', [
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+      StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE
+    ]);
+  }
+
+  test_returnOfInvalidType_expressionFunctionBody_function() async {
+    await assertErrorsInCode(
+        "int f() => '0';", [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_expressionFunctionBody_getter() async {
+    await assertErrorsInCode(
+        "int get g => '0';", [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_expressionFunctionBody_localFunction() async {
+    await assertErrorsInCode(r'''
+class A {
+  String m() {
+    int f() => '0';
+    return '0';
+  }
+}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_expressionFunctionBody_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int f() => '0';
+}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_function() async {
+    await assertErrorsInCode("int f() { return '0'; }",
+        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_getter() async {
+    await assertErrorsInCode("int get g { return '0'; }",
+        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_localFunction() async {
+    await assertErrorsInCode(r'''
+class A {
+  String m() {
+    int f() { return '0'; }
+    return '0';
+  }
+}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  int f() { return '0'; }
+}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_returnOfInvalidType_not_issued_for_expressionFunctionBody_void() async {
+    await assertNoErrorsInCode("void f() => 42;");
+  }
+
+  test_returnOfInvalidType_not_issued_for_valid_generic_return() async {
+    await assertNoErrorsInCode(r'''
+abstract class F<T, U>  {
+  U get value;
+}
+
+abstract class G<T> {
+  T test(F<int, T> arg) => arg.value;
+}
+
+abstract class H<S> {
+  S test(F<int, S> arg) => arg.value;
+}
+
+void main() { }''');
+  }
+
+  test_returnOfInvalidType_void() async {
+    await assertErrorsInCode("void f() { return 42; }",
+        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_typeArgumentNotMatchingBounds_classTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C {}
+class G<E extends A> {}
+class D = G<B> with C;
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_extends() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C extends G<B>{}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_extends_regressionInIssue18468Fix() async {
+    // https://code.google.com/p/dart/issues/detail?id=18628
+    await assertErrorsInCode(r'''
+class X<T extends Type> {}
+class Y<U> extends X<U> {}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_fieldFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C {
+  var f;
+  C(G<B> this.f) {}
+}''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_functionReturnType() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+G<B> f() { return null; }
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_functionTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+typedef G<B> f();
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_functionTypedFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f(G<B> h()) {}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_implements() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C implements G<B>{}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_is() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+var b = 1 is G<B>;
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_methodInvocation_localFunction() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+main() {
+  Point<T> f<T extends num>(T x, T y) {
+    return new Point<T>(x, y);
+  }
+  print(f<String>('hello', 'world'));
+}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_methodInvocation_method() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+class PointFactory {
+  Point<T> point<T extends num>(T x, T y) {
+    return new Point<T>(x, y);
+  }
+}
+
+f(PointFactory factory) {
+  print(factory.point<String>('hello', 'world'));
+}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_methodInvocation_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+class Point<T extends num> {
+  Point(T x, T y);
+}
+
+Point<T> f<T extends num>(T x, T y) {
+  return new Point<T>(x, y);
+}
+
+main() {
+  print(f<String>('hello', 'world'));
+}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_methodReturnType() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C {
+  G<B> m() { return null; }
+}''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_new() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f() { return new G<B>(); }
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_new_superTypeOfUpperBound() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {}
+class C extends B {}
+class G<E extends B> {}
+f() { return new G<A>(); }
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+typedef F<T extends A>();
+F<B> fff;
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_parameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+f(G<B> g) {}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_redirectingConstructor() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class X<T extends A> {
+  X(int x, int y) {}
+  factory X.name(int x, int y) = X<B>;
+}''', [
+      StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
+      StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE
+    ]);
+  }
+
+  test_typeArgumentNotMatchingBounds_typeArgumentList() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C<E> {}
+class D<E extends A> {}
+C<D<B>> Var;
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_typeParameter() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class C {}
+class G<E extends A> {}
+class D<F extends G<B>> {}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_variableDeclaration() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+G<B> g;
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeArgumentNotMatchingBounds_with() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {}
+class G<E extends A> {}
+class C extends Object with G<B>{}
+''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
+  test_typeParameterSupertypeOfItsBound() async {
+    await assertErrorsInCode(r'''
+class A<T extends T> {
+}
+''', [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]);
+  }
+
+  test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() async {
+    await assertErrorsInUnverifiedCode(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  (p is String) && callMe(() { p.length; });
+  p = 0;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_booleanAnd_useInRight_mutatedInLeft() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  ((p is String) && ((p = 42) == 42)) && p.length != 0;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_booleanAnd_useInRight_mutatedInRight() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  (p is String) && (((p = 42) == 42) && p.length != 0);
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() async {
+    await assertErrorsInUnverifiedCode(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  p is String ? callMe(() { p.length; }) : 0;
+  p = 42;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() async {
+    await assertErrorsInUnverifiedCode(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  p = 42;
+  p is String ? callMe(() { p.length; }) : 0;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_conditional_useInThen_hasAssignment() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  p is String ? (p.length + (p = 42)) : 0;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_accessedInClosure_hasAssignment() async {
+    await assertErrorsInUnverifiedCode(r'''
+callMe(f()) { f(); }
+main(Object p) {
+  if (p is String) {
+    callMe(() {
+      p.length;
+    });
+  }
+  p = 0;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_and_right_hasAssignment() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  if (p is String && (p = null) == null) {
+    p.length;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_extends_notMoreSpecific_dynamic() async {
+    await assertErrorsInUnverifiedCode(r'''
+class V {}
+class A<T> {}
+class B<S> extends A<S> {
+  var b;
+}
+
+main(A<V> p) {
+  if (p is B) {
+    p.b;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_extends_notMoreSpecific_notMoreSpecificTypeArg() async {
+    await assertErrorsInUnverifiedCode(r'''
+class V {}
+class A<T> {}
+class B<S> extends A<S> {
+  var b;
+}
+
+main(A<V> p) {
+  if (p is B<int>) {
+    p.b;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_hasAssignment_after() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  if (p is String) {
+    p.length;
+    p = 0;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_hasAssignment_before() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  if (p is String) {
+    p = 0;
+    p.length;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_hasAssignment_inClosure_anonymous_after() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  if (p is String) {
+    p.length;
+  }
+  () {p = 0;};
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_hasAssignment_inClosure_anonymous_before() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  () {p = 0;};
+  if (p is String) {
+    p.length;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_hasAssignment_inClosure_function_after() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  if (p is String) {
+    p.length;
+  }
+  f() {p = 0;};
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_hasAssignment_inClosure_function_before() async {
+    await assertErrorsInUnverifiedCode(r'''
+main(Object p) {
+  f() {p = 0;};
+  if (p is String) {
+    p.length;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_implements_notMoreSpecific_dynamic() async {
+    await assertErrorsInUnverifiedCode(r'''
+class V {}
+class A<T> {}
+class B<S> implements A<S> {
+  var b;
+}
+
+main(A<V> p) {
+  if (p is B) {
+    p.b;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_typePromotion_if_with_notMoreSpecific_dynamic() async {
+    await assertErrorsInUnverifiedCode(r'''
+class V {}
+class A<T> {}
+class B<S> extends Object with A<S> {
+  var b;
+}
+
+main(A<V> p) {
+  if (p is B) {
+    p.b;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_undefinedGetter() async {
+    await assertErrorsInUnverifiedCode(r'''
+class T {}
+f(T e) { return e.m; }''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_undefinedGetter_generic_function_call() async {
+    // Referencing `.call` on a `Function` type works similarly to referencing
+    // it on `dynamic`--the reference is accepted at compile time, and all type
+    // checking is deferred until runtime.
+    await assertErrorsInUnverifiedCode('''
+f(Function f) {
+  return f.call;
+}
+''', []);
+  }
+
+  test_undefinedGetter_object_call() async {
+    await assertErrorsInUnverifiedCode('''
+f(Object o) {
+  return o.call;
+}
+''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_undefinedGetter_proxy_annotation_fakeProxy() async {
+    await assertErrorsInCode(r'''
+library L;
+class Fake {
+  const Fake();
+}
+const proxy = const Fake();
+@proxy class PrefixProxy {}
+main() {
+  new PrefixProxy().foo;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_undefinedGetter_static() async {
+    await assertErrorsInUnverifiedCode(r'''
+class A {}
+var a = A.B;''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_undefinedGetter_typeLiteral_cascadeTarget() async {
+    await assertErrorsInCode(r'''
+class T {
+  static int get foo => 42;
+}
+main() {
+  T..foo;
+}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  test_undefinedGetter_typeLiteral_conditionalAccess() async {
+    // When applied to a type literal, the conditional access operator '?.'
+    // cannot be used to access instance getters of Type.
+    // TODO(brianwilkerson) We cannot verify because hashCode isn't resolved.
+    await assertErrorsInCode('''
+class A {}
+f() => A?.hashCode;
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
+  }
+
+  test_undefinedGetter_wrongNumberOfTypeArguments_tooLittle() async {
+    await assertErrorsInCode(r'''
+class A<K, V> {
+  K element;
+}
+main(A<int> a) {
+  a.element.anyGetterExistsInDynamic;
+}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_undefinedGetter_wrongNumberOfTypeArguments_tooMany() async {
+    await assertErrorsInCode(r'''
+class A<E> {
+  E element;
+}
+main(A<int,int> a) {
+  a.element.anyGetterExistsInDynamic;
+}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_undefinedGetter_wrongOfTypeArgument() async {
+    await assertErrorsInCode(r'''
+class A<E> {
+  E element;
+}
+main(A<NoSuchType> a) {
+  a.element.anyGetterExistsInDynamic;
+}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
+  }
+
+  test_undefinedMethod_assignmentExpression() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B {
+  f(A a) {
+    A a2 = new A();
+    a += a2;
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
+  test_undefinedMethod_ignoreTypePropagation() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  m() {}
+}
+class C {
+  f() {
+    A a = new B();
+    a.m();
+  }
+}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
+  test_undefinedMethod_leastUpperBoundWithNull() async {
+    await assertErrorsInCode('f(bool b, int i) => (b ? null : i).foo();',
+        [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
+  test_undefinedMethod_ofNull() async {
+    // TODO(scheglov) Track https://github.com/dart-lang/sdk/issues/28430 to
+    // decide whether a warning should be reported here.
+    await assertErrorsInCode(r'''
+Null f(int x) => null;
+main() {
+  f(42).abs();
+}
+''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
+  test_undefinedMethodWithConstructor() async {
+    // TODO(brianwilkerson) We cannot verify because 'C' could not be resolved.
+    await assertErrorsInCode(r'''
+class C {
+  C.m();
+}
+f() {
+  C c = C.m();
+}''', [], verify: false);
+  }
+
+  test_undefinedOperator_indexBoth() async {
+    await assertErrorsInUnverifiedCode(r'''
+class A {}
+f(A a) {
+  a[0]++;
+}''', [
+      StaticTypeWarningCode.UNDEFINED_OPERATOR,
+      StaticTypeWarningCode.UNDEFINED_OPERATOR,
+    ]);
+  }
+
+  test_undefinedOperator_indexGetter() async {
+    await assertErrorsInUnverifiedCode(r'''
+class A {}
+f(A a) {
+  a[0];
+}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_undefinedOperator_indexSetter() async {
+    await assertErrorsInUnverifiedCode(r'''
+class A {}
+f(A a) {
+  a[0] = 1;
+}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_undefinedOperator_plus() async {
+    await assertErrorsInUnverifiedCode(r'''
+class A {}
+f(A a) {
+  a + 1;
+}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_undefinedOperator_postfixExpression() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  a++;
+}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_undefinedOperator_prefixExpression() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(A a) {
+  ++a;
+}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_undefinedSetter() async {
+    await assertErrorsInUnverifiedCode(r'''
+class T {}
+f(T e1) { e1.m = 0; }''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+
+  test_undefinedSetter_static() async {
+    await assertErrorsInUnverifiedCode(r'''
+class A {}
+f() { A.B = 0;}''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+
+  test_undefinedSetter_typeLiteral_cascadeTarget() async {
+    await assertErrorsInCode(r'''
+class T {
+  static void set foo(_) {}
+}
+main() {
+  T..foo = 42;
+}''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+
+  test_unqualifiedReferenceToNonLocalStaticMember_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  static int get a => 0;
+}
+class B extends A {
+  int b() {
+    return a;
+  }
+}''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
+  }
+
+  test_unqualifiedReferenceToNonLocalStaticMember_getter_invokeTarget() async {
+    await assertErrorsInCode(r'''
+class A {
+  static int foo;
+}
+
+class B extends A {
+  static bar() {
+    foo.abs();
+  }
+}
+''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
+  }
+
+  test_unqualifiedReferenceToNonLocalStaticMember_setter() async {
+    await assertErrorsInCode(r'''
+class A {
+  static set a(x) {}
+}
+class B extends A {
+  b(y) {
+    a = y;
+  }
+}''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
+  }
+
+  test_wrongNumberOfTypeArguments_class_tooFew() async {
+    await assertErrorsInCode(r'''
+class A<E, F> {}
+A<A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_class_tooMany() async {
+    await assertErrorsInCode(r'''
+class A<E> {}
+A<A, A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_classAlias() async {
+    await assertErrorsInCode(r'''
+class A {}
+class M {}
+class B<F extends num> = A<F> with M;''',
+        [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_dynamic() async {
+    await assertErrorsInCode(r'''
+dynamic<int> v;
+''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_typeParameter() async {
+    await assertErrorsInCode(r'''
+class C<T> {
+  T<int> f;
+}
+''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_typeTest_tooFew() async {
+    await assertErrorsInCode(r'''
+class A {}
+class C<K, V> {}
+f(p) {
+  return p is C<A>;
+}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_typeTest_tooMany() async {
+    await assertErrorsInCode(r'''
+class A {}
+class C<E> {}
+f(p) {
+  return p is C<A, A>;
+}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_yield_async_to_basic_type() async {
+    await assertErrorsInCode('''
+int f() async* {
+  yield 3;
+}
+''', [
+      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
+      StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE
+    ]);
+  }
+
+  test_yield_async_to_iterable() async {
+    await assertErrorsInCode('''
+Iterable<int> f() async* {
+  yield 3;
+}
+''', [
+      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
+      StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE
+    ]);
+  }
+
+  test_yield_async_to_mistyped_stream() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Stream<int> f() async* {
+  yield "foo";
+}
+''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
+  }
+
+  test_yield_each_async_non_stream() async {
+    await assertErrorsInCode('''
+f() async* {
+  yield* 0;
+}
+''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
+  }
+
+  test_yield_each_async_to_mistyped_stream() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Stream<int> f() async* {
+  yield* g();
+}
+Stream<String> g() => null;
+''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
+  }
+
+  test_yield_each_sync_non_iterable() async {
+    await assertErrorsInCode('''
+f() sync* {
+  yield* 0;
+}
+''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
+  }
+
+  test_yield_each_sync_to_mistyped_iterable() async {
+    await assertErrorsInCode('''
+Iterable<int> f() sync* {
+  yield* g();
+}
+Iterable<String> g() => null;
+''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
+  }
+
+  test_yield_sync_to_basic_type() async {
+    await assertErrorsInCode('''
+int f() sync* {
+  yield 3;
+}
+''', [
+      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
+      StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE
+    ]);
+  }
+
+  test_yield_sync_to_mistyped_iterable() async {
+    await assertErrorsInCode('''
+Iterable<int> f() sync* {
+  yield "foo";
+}
+''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
+  }
+
+  test_yield_sync_to_stream() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+Stream<int> f() sync* {
+  yield 3;
+}
+''', [
+      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
+      StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE
+    ]);
+  }
+}
+
+abstract class StrongModeStaticTypeWarningCodeTest extends ResolverTestCase {
+  void setUp() {
+    super.setUp();
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    resetWith(options: options);
+  }
+
+  test_legalAsyncGeneratorReturnType_function_supertypeOfStream() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+f() async* { yield 42; }
+dynamic f2() async* { yield 42; }
+Object f3() async* { yield 42; }
+Stream f4() async* { yield 42; }
+Stream<dynamic> f5() async* { yield 42; }
+Stream<Object> f6() async* { yield 42; }
+Stream<num> f7() async* { yield 42; }
+Stream<int> f8() async* { yield 42; }
+''', []);
+  }
+
+  test_legalAsyncReturnType_function_supertypeOfFuture() async {
+    await assertErrorsInCode('''
+import 'dart:async';
+f() async { return 42; }
+dynamic f2() async { return 42; }
+Object f3() async { return 42; }
+Future f4() async { return 42; }
+Future<dynamic> f5() async { return 42; }
+Future<Object> f6() async { return 42; }
+Future<num> f7() async { return 42; }
+Future<int> f8() async { return 42; }
+''', []);
+  }
+
+  test_legalSyncGeneratorReturnType_function_supertypeOfIterable() async {
+    await assertErrorsInCode('''
+f() sync* { yield 42; }
+dynamic f2() sync* { yield 42; }
+Object f3() sync* { yield 42; }
+Iterable f4() sync* { yield 42; }
+Iterable<dynamic> f5() sync* { yield 42; }
+Iterable<Object> f6() sync* { yield 42; }
+Iterable<num> f7() sync* { yield 42; }
+Iterable<int> f8() sync* { yield 42; }
+''', []);
+  }
+}
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_driver_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_driver_test.dart
index fcb17db..6286728 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_driver_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'static_type_warning_code_test.dart';
+import 'static_type_warning_code.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
deleted file mode 100644
index 5c1f94b..0000000
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ /dev/null
@@ -1,1771 +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/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(StaticTypeWarningCodeTest);
-    defineReflectiveTests(StrongModeStaticTypeWarningCodeTest);
-  });
-}
-
-@reflectiveTest
-class StaticTypeWarningCodeTest extends ResolverTestCase {
-  fail_undefinedEnumConstant() async {
-    // We need a way to set the parseEnum flag in the parser to true.
-    await assertErrorsInCode(r'''
-enum E { ONE }
-E e() {
-  return E.TWO;
-}''', [StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT]);
-  }
-
-  test_assert_message_suppresses_type_promotion() async {
-    // If a variable is assigned to inside the expression for an assert
-    // message, type promotion should be suppressed, just as it would be if the
-    // assignment occurred outside an assert statement.  (Note that it is a
-    // dubious practice for the computation of an assert message to have side
-    // effects, since it is only evaluated if the assert fails).
-    await assertErrorsInCode('''
-class C {
-  void foo() {}
-}
-
-f(Object x) {
-  if (x is C) {
-    x.foo();
-    assert(true, () { x = new C(); return 'msg'; }());
-  }
-}
-''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
-    // Do not verify since `x.foo()` fails to resolve.
-  }
-
-  test_await_flattened() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Future<Future<int>> ffi() => null;
-f() async {
-  Future<int> b = await ffi(); 
-}
-''', []);
-  }
-
-  test_await_simple() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Future<int> fi() => null;
-f() async {
-  String a = await fi(); // Warning: int not assignable to String
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_awaitForIn_declaredVariableRightType() async {
-    await assertNoErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<int> stream;
-  await for (int i in stream) {}
-}
-''');
-  }
-
-  test_awaitForIn_declaredVariableWrongType() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<String> stream;
-  await for (int i in stream) {}
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
-  }
-
-  test_awaitForIn_downcast() async {
-    await assertNoErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<num> stream;
-  await for (int i in stream) {}
-}
-''');
-  }
-
-  test_awaitForIn_dynamicStream() async {
-    await assertNoErrorsInCode('''
-f() async {
-  dynamic stream;
-  await for (int i in stream) {}
-}
-''');
-  }
-
-  test_awaitForIn_dynamicVariable() async {
-    await assertNoErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<int> stream;
-  await for (var i in stream) {}
-}
-''');
-  }
-
-  test_awaitForIn_existingVariableRightType() async {
-    await assertNoErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<int> stream;
-  int i;
-  await for (i in stream) {}
-}
-''');
-  }
-
-  test_awaitForIn_existingVariableWrongType() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<String> stream;
-  int i;
-  await for (i in stream) {}
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
-  }
-
-  test_awaitForIn_notStream() async {
-    await assertErrorsInCode('''
-f() async {
-  await for (var i in true) {}
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE]);
-  }
-
-  test_awaitForIn_streamOfDynamic() async {
-    await assertNoErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream stream;
-  await for (int i in stream) {}
-}
-''');
-  }
-
-  test_awaitForIn_upcast() async {
-    await assertNoErrorsInCode('''
-import 'dart:async';
-f() async {
-  Stream<int> stream;
-  await for (num i in stream) {}
-}
-''');
-  }
-
-  test_bug21912() async {
-    await assertErrorsInCode('''
-class A {}
-class B extends A {}
-
-typedef T Function2<S, T>(S z);
-typedef B AToB(A x);
-typedef A BToA(B x);
-
-void main() {
-  {
-    Function2<Function2<A, B>, Function2<B, A>> t1;
-    Function2<AToB, BToA> t2;
-
-    Function2<Function2<int, double>, Function2<int, double>> left;
-
-    left = t1;
-    left = t2;
-  }
-}
-''', [
-      StaticTypeWarningCode.INVALID_ASSIGNMENT,
-      StaticTypeWarningCode.INVALID_ASSIGNMENT
-    ]);
-  }
-
-  test_defaultSetLiteralNotEnabled() async {
-    await assertErrorsInCode(r'''
-void main() {
-  Set _ = {};
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_expectedOneListTypeArgument() async {
-    await assertErrorsInCode(r'''
-main() {
-  <int, int> [];
-}''', [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]);
-  }
-
-  @failingTest
-  test_expectedOneSetTypeArgument() async {
-    await assertErrorsInCode(r'''
-main() {
-  <int, int>{2, 3};
-}''', [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS]);
-  }
-
-  test_expectedTwoMapTypeArguments_three() async {
-    await assertErrorsInCode(r'''
-main() {
-  <int, int, int> {};
-}''', [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]);
-  }
-
-  test_forIn_declaredVariableRightType() async {
-    await assertNoErrorsInCode('''
-f() {
-  for (int i in <int>[]) {}
-}
-''');
-  }
-
-  test_forIn_declaredVariableWrongType() async {
-    await assertErrorsInCode('''
-f() {
-  for (int i in <String>[]) {}
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
-  }
-
-  test_forIn_downcast() async {
-    await assertNoErrorsInCode('''
-f() {
-  for (int i in <num>[]) {}
-}
-''');
-  }
-
-  test_forIn_dynamic() async {
-    await assertNoErrorsInCode('''
-f() {
-  dynamic d; // Could be [].
-  for (var i in d) {}
-}
-''');
-  }
-
-  test_forIn_dynamicIterable() async {
-    await assertNoErrorsInCode('''
-f() {
-  dynamic iterable;
-  for (int i in iterable) {}
-}
-''');
-  }
-
-  test_forIn_dynamicVariable() async {
-    await assertNoErrorsInCode('''
-f() {
-  for (var i in <int>[]) {}
-}
-''');
-  }
-
-  test_forIn_existingVariableRightType() async {
-    await assertNoErrorsInCode('''
-f() {
-  int i;
-  for (i in <int>[]) {}
-}
-''');
-  }
-
-  test_forIn_existingVariableWrongType() async {
-    await assertErrorsInCode('''
-f() {
-  int i;
-  for (i in <String>[]) {}
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
-  }
-
-  test_forIn_iterableOfDynamic() async {
-    await assertNoErrorsInCode('''
-f() {
-  for (int i in []) {}
-}
-''');
-  }
-
-  test_forIn_notIterable() async {
-    await assertErrorsInCode('''
-f() {
-  for (var i in true) {}
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE]);
-  }
-
-  test_forIn_object() async {
-    await assertNoErrorsInCode('''
-f() {
-  Object o; // Could be [].
-  for (var i in o) {}
-}
-''');
-  }
-
-  test_forIn_typeBoundBad() async {
-    await assertErrorsInCode('''
-class Foo<T extends Iterable<int>> {
-  void method(T iterable) {
-    for (String i in iterable) {}
-  }
-}
-''', [StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE]);
-  }
-
-  test_forIn_typeBoundGood() async {
-    await assertNoErrorsInCode('''
-class Foo<T extends Iterable<int>> {
-  void method(T iterable) {
-    for (var i in iterable) {}
-  }
-}
-''');
-  }
-
-  test_forIn_upcast() async {
-    await assertNoErrorsInCode('''
-f() {
-  for (num i in <int>[]) {}
-}
-''');
-  }
-
-  test_illegalAsyncGeneratorReturnType_function_nonStream() async {
-    await assertErrorsInCode('''
-int f() async* {}
-''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalAsyncGeneratorReturnType_function_subtypeOfStream() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-abstract class SubStream<T> implements Stream<T> {}
-SubStream<int> f() async* {}
-''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalAsyncGeneratorReturnType_method_nonStream() async {
-    await assertErrorsInCode('''
-class C {
-  int f() async* {}
-}
-''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalAsyncGeneratorReturnType_method_subtypeOfStream() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-abstract class SubStream<T> implements Stream<T> {}
-class C {
-  SubStream<int> f() async* {}
-}
-''', [StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalAsyncReturnType_function_nonFuture() async {
-    await assertErrorsInCode('''
-int f() async {}
-''', [
-      StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
-      HintCode.MISSING_RETURN
-    ]);
-  }
-
-  test_illegalAsyncReturnType_function_subtypeOfFuture() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-abstract class SubFuture<T> implements Future<T> {}
-SubFuture<int> f() async {
-  return 0;
-}
-''', [StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE]);
-  }
-
-  test_illegalAsyncReturnType_method_nonFuture() async {
-    await assertErrorsInCode('''
-class C {
-  int m() async {}
-}
-''', [
-      StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE,
-      HintCode.MISSING_RETURN
-    ]);
-  }
-
-  test_illegalAsyncReturnType_method_subtypeOfFuture() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-abstract class SubFuture<T> implements Future<T> {}
-class C {
-  SubFuture<int> m() async {
-    return 0;
-  }
-}
-''', [StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE]);
-  }
-
-  test_illegalSyncGeneratorReturnType_function_nonIterator() async {
-    await assertErrorsInCode('''
-int f() sync* {}
-''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalSyncGeneratorReturnType_function_subclassOfIterator() async {
-    await assertErrorsInCode('''
-abstract class SubIterator<T> implements Iterator<T> {}
-SubIterator<int> f() sync* {}
-''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalSyncGeneratorReturnType_method_nonIterator() async {
-    await assertErrorsInCode('''
-class C {
-  int f() sync* {}
-}
-''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_illegalSyncGeneratorReturnType_method_subclassOfIterator() async {
-    await assertErrorsInCode('''
-abstract class SubIterator<T> implements Iterator<T> {}
-class C {
-  SubIterator<int> f() sync* {}
-}
-''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
-  }
-
-  test_instanceAccessToStaticMember_method_reference() async {
-    await assertErrorsInCode(r'''
-class A {
-  static m() {}
-}
-main(A a) {
-  a.m;
-}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
-  }
-
-  test_instanceAccessToStaticMember_propertyAccess_field() async {
-    await assertErrorsInCode(r'''
-class A {
-  static var f;
-}
-main(A a) {
-  a.f;
-}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
-  }
-
-  test_instanceAccessToStaticMember_propertyAccess_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  static get f => 42;
-}
-main(A a) {
-  a.f;
-}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
-  }
-
-  test_instanceAccessToStaticMember_propertyAccess_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  static set f(x) {}
-}
-main(A a) {
-  a.f = 42;
-}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
-  }
-
-  test_invalidAssignment_compoundAssignment() async {
-    await assertErrorsInCode(r'''
-class byte {
-  int _value;
-  byte(this._value);
-  int operator +(int val) { return 0; }
-}
-
-void main() {
-  byte b = new byte(52);
-  b += 3;
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_defaultValue_named() async {
-    await assertErrorsInCode(r'''
-f({String x: 0}) {
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_defaultValue_optional() async {
-    await assertErrorsInCode(r'''
-f([String x = 0]) {
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_dynamic() async {
-    await assertErrorsInCode(r'''
-main() {
-  dynamic = 1;
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_functionExpressionInvocation() async {
-    await assertErrorsInCode('''
-main() {
-  String x = (() => 5)();
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_ifNullAssignment() async {
-    await assertErrorsInCode('''
-void f(int i) {
-  double d;
-  d ??= i;
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_instanceVariable() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-}
-f() {
-  A a;
-  a.x = '0';
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_localVariable() async {
-    await assertErrorsInCode(r'''
-f() {
-  int x;
-  x = '0';
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_postfixExpression_localVariable() async {
-    await assertErrorsInCode(r'''
-class A {
-  B operator+(_) => new B();
-}
-
-class B {}
-
-f(A a) {
-  a++;
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_postfixExpression_property() async {
-    await assertErrorsInCode(r'''
-class A {
-  B operator+(_) => new B();
-}
-
-class B {}
-
-class C {
-  A a;
-}
-
-f(C c) {
-  c.a++;
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_prefixExpression_localVariable() async {
-    await assertErrorsInCode(r'''
-class A {
-  B operator+(_) => new B();
-}
-
-class B {}
-
-f(A a) {
-  ++a;
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_prefixExpression_property() async {
-    await assertErrorsInCode(r'''
-class A {
-  B operator+(_) => new B();
-}
-
-class B {}
-
-class C {
-  A a;
-}
-
-f(C c) {
-  ++c.a;
-}
-''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_regressionInIssue18468Fix() async {
-    // https://code.google.com/p/dart/issues/detail?id=18628
-    await assertErrorsInCode(r'''
-class C<T> {
-  T t = int;
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_staticVariable() async {
-    await assertErrorsInCode(r'''
-class A {
-  static int x;
-}
-f() {
-  A.x = '0';
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_topLevelVariableDeclaration() async {
-    await assertErrorsInCode(
-        "int x = 'string';", [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_typeParameter() async {
-    // 14221
-    await assertErrorsInCode(r'''
-class B<T> {
-  T value;
-  void test(num n) {
-    value = n;
-  }
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invalidAssignment_variableDeclaration() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x = 'string';
-}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
-  }
-
-  test_invocationOfNonFunctionExpression_literal() async {
-    await assertErrorsInCode(r'''
-f() {
-  3(5);
-}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION]);
-  }
-
-  test_nonBoolCondition_conditional() async {
-    await assertErrorsInCode("f() { return 3 ? 2 : 1; }",
-        [StaticTypeWarningCode.NON_BOOL_CONDITION]);
-  }
-
-  test_nonBoolCondition_do() async {
-    await assertErrorsInCode(r'''
-f() {
-  do {} while (3);
-}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
-  }
-
-  test_nonBoolCondition_for() async {
-    // https://github.com/dart-lang/sdk/issues/24713
-    await assertErrorsInCode(r'''
-f() {
-  for (;3;) {}
-}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
-  }
-
-  test_nonBoolCondition_if() async {
-    await assertErrorsInCode(r'''
-f() {
-  if (3) return 2; else return 1;
-}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
-  }
-
-  test_nonBoolCondition_while() async {
-    await assertErrorsInCode(r'''
-f() {
-  while (3) {}
-}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
-  }
-
-  test_nonBoolExpression_functionType_bool() async {
-    Source source = addSource(r'''
-bool makeAssertion() => true;
-f() {
-  assert(makeAssertion);
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
-    verify([source]);
-  }
-
-  test_nonBoolExpression_functionType_int() async {
-    await assertErrorsInCode(r'''
-int makeAssertion() => 1;
-f() {
-  assert(makeAssertion);
-}''', [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
-  }
-
-  test_nonBoolExpression_interfaceType() async {
-    await assertErrorsInCode(r'''
-f() {
-  assert(0);
-}''', [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
-  }
-
-  test_nonBoolNegationExpression() async {
-    await assertErrorsInCode(r'''
-f() {
-  !42;
-}''', [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION]);
-  }
-
-  test_nonBoolOperand_and_left() async {
-    await assertErrorsInCode(r'''
-bool f(int left, bool right) {
-  return left && right;
-}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
-  }
-
-  test_nonBoolOperand_and_right() async {
-    await assertErrorsInCode(r'''
-bool f(bool left, String right) {
-  return left && right;
-}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
-  }
-
-  test_nonBoolOperand_or_left() async {
-    await assertErrorsInCode(r'''
-bool f(List<int> left, bool right) {
-  return left || right;
-}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
-  }
-
-  test_nonBoolOperand_or_right() async {
-    await assertErrorsInCode(r'''
-bool f(bool left, double right) {
-  return left || right;
-}''', [StaticTypeWarningCode.NON_BOOL_OPERAND]);
-  }
-
-  test_nonTypeAsTypeArgument_notAType() async {
-    await assertErrorsInCode(r'''
-int A;
-class B<E> {}
-f(B<A> b) {}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
-  }
-
-  test_nonTypeAsTypeArgument_undefinedIdentifier() async {
-    await assertErrorsInCode(r'''
-class B<E> {}
-f(B<A> b) {}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
-  }
-
-  test_returnOfInvalidType_async_future_future_int_mismatches_future_int() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Future<int> f() async {
-  return g();
-}
-Future<Future<int>> g() => null;
-''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_async_future_int_mismatches_future_string() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Future<String> f() async {
-  return 5;
-}
-''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_async_future_int_mismatches_int() async {
-    await assertErrorsInCode('''
-int f() async {
-  return 5;
-}
-''', [
-      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
-      StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE
-    ]);
-  }
-
-  test_returnOfInvalidType_expressionFunctionBody_function() async {
-    await assertErrorsInCode(
-        "int f() => '0';", [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_expressionFunctionBody_getter() async {
-    await assertErrorsInCode(
-        "int get g => '0';", [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_expressionFunctionBody_localFunction() async {
-    await assertErrorsInCode(r'''
-class A {
-  String m() {
-    int f() => '0';
-    return '0';
-  }
-}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_expressionFunctionBody_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  int f() => '0';
-}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_function() async {
-    await assertErrorsInCode("int f() { return '0'; }",
-        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_getter() async {
-    await assertErrorsInCode("int get g { return '0'; }",
-        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_localFunction() async {
-    await assertErrorsInCode(r'''
-class A {
-  String m() {
-    int f() { return '0'; }
-    return '0';
-  }
-}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_method() async {
-    await assertErrorsInCode(r'''
-class A {
-  int f() { return '0'; }
-}''', [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_returnOfInvalidType_not_issued_for_expressionFunctionBody_void() async {
-    await assertNoErrorsInCode("void f() => 42;");
-  }
-
-  test_returnOfInvalidType_not_issued_for_valid_generic_return() async {
-    await assertNoErrorsInCode(r'''
-abstract class F<T, U>  {
-  U get value;
-}
-
-abstract class G<T> {
-  T test(F<int, T> arg) => arg.value;
-}
-
-abstract class H<S> {
-  S test(F<int, S> arg) => arg.value;
-}
-
-void main() { }''');
-  }
-
-  test_returnOfInvalidType_void() async {
-    await assertErrorsInCode("void f() { return 42; }",
-        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_typeArgumentNotMatchingBounds_classTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C {}
-class G<E extends A> {}
-class D = G<B> with C;
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_extends() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C extends G<B>{}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_extends_regressionInIssue18468Fix() async {
-    // https://code.google.com/p/dart/issues/detail?id=18628
-    await assertErrorsInCode(r'''
-class X<T extends Type> {}
-class Y<U> extends X<U> {}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_fieldFormalParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C {
-  var f;
-  C(G<B> this.f) {}
-}''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionReturnType() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-G<B> f() { return null; }
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-typedef G<B> f();
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_functionTypedFormalParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f(G<B> h()) {}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_implements() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C implements G<B>{}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_is() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-var b = 1 is G<B>;
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_localFunction() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-main() {
-  Point<T> f<T extends num>(T x, T y) {
-    return new Point<T>(x, y);
-  }
-  print(f<String>('hello', 'world'));
-}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_method() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-class PointFactory {
-  Point<T> point<T extends num>(T x, T y) {
-    return new Point<T>(x, y);
-  }
-}
-
-f(PointFactory factory) {
-  print(factory.point<String>('hello', 'world'));
-}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodInvocation_topLevelFunction() async {
-    await assertErrorsInCode(r'''
-class Point<T extends num> {
-  Point(T x, T y);
-}
-
-Point<T> f<T extends num>(T x, T y) {
-  return new Point<T>(x, y);
-}
-
-main() {
-  print(f<String>('hello', 'world'));
-}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_methodReturnType() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C {
-  G<B> m() { return null; }
-}''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f() { return new G<B>(); }
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_new_superTypeOfUpperBound() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {}
-class C extends B {}
-class G<E extends B> {}
-f() { return new G<A>(); }
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-typedef F<T extends A>();
-F<B> fff;
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_parameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-f(G<B> g) {}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_redirectingConstructor() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class X<T extends A> {
-  X(int x, int y) {}
-  factory X.name(int x, int y) = X<B>;
-}''', [
-      StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
-      StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE
-    ]);
-  }
-
-  test_typeArgumentNotMatchingBounds_typeArgumentList() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C<E> {}
-class D<E extends A> {}
-C<D<B>> Var;
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_typeParameter() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class C {}
-class G<E extends A> {}
-class D<F extends G<B>> {}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_variableDeclaration() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-G<B> g;
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeArgumentNotMatchingBounds_with() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {}
-class G<E extends A> {}
-class C extends Object with G<B>{}
-''', [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
-  }
-
-  test_typeParameterSupertypeOfItsBound() async {
-    await assertErrorsInCode(r'''
-class A<T extends T> {
-}
-''', [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]);
-  }
-
-  test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() async {
-    await assertErrorsInUnverifiedCode(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  (p is String) && callMe(() { p.length; });
-  p = 0;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_booleanAnd_useInRight_mutatedInLeft() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  ((p is String) && ((p = 42) == 42)) && p.length != 0;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_booleanAnd_useInRight_mutatedInRight() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  (p is String) && (((p = 42) == 42) && p.length != 0);
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() async {
-    await assertErrorsInUnverifiedCode(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  p is String ? callMe(() { p.length; }) : 0;
-  p = 42;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() async {
-    await assertErrorsInUnverifiedCode(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  p = 42;
-  p is String ? callMe(() { p.length; }) : 0;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_conditional_useInThen_hasAssignment() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  p is String ? (p.length + (p = 42)) : 0;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_accessedInClosure_hasAssignment() async {
-    await assertErrorsInUnverifiedCode(r'''
-callMe(f()) { f(); }
-main(Object p) {
-  if (p is String) {
-    callMe(() {
-      p.length;
-    });
-  }
-  p = 0;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_and_right_hasAssignment() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  if (p is String && (p = null) == null) {
-    p.length;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_extends_notMoreSpecific_dynamic() async {
-    await assertErrorsInUnverifiedCode(r'''
-class V {}
-class A<T> {}
-class B<S> extends A<S> {
-  var b;
-}
-
-main(A<V> p) {
-  if (p is B) {
-    p.b;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_extends_notMoreSpecific_notMoreSpecificTypeArg() async {
-    await assertErrorsInUnverifiedCode(r'''
-class V {}
-class A<T> {}
-class B<S> extends A<S> {
-  var b;
-}
-
-main(A<V> p) {
-  if (p is B<int>) {
-    p.b;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_hasAssignment_after() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  if (p is String) {
-    p.length;
-    p = 0;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_hasAssignment_before() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  if (p is String) {
-    p = 0;
-    p.length;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_hasAssignment_inClosure_anonymous_after() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  if (p is String) {
-    p.length;
-  }
-  () {p = 0;};
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_hasAssignment_inClosure_anonymous_before() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  () {p = 0;};
-  if (p is String) {
-    p.length;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_hasAssignment_inClosure_function_after() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  if (p is String) {
-    p.length;
-  }
-  f() {p = 0;};
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_hasAssignment_inClosure_function_before() async {
-    await assertErrorsInUnverifiedCode(r'''
-main(Object p) {
-  f() {p = 0;};
-  if (p is String) {
-    p.length;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_implements_notMoreSpecific_dynamic() async {
-    await assertErrorsInUnverifiedCode(r'''
-class V {}
-class A<T> {}
-class B<S> implements A<S> {
-  var b;
-}
-
-main(A<V> p) {
-  if (p is B) {
-    p.b;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_typePromotion_if_with_notMoreSpecific_dynamic() async {
-    await assertErrorsInUnverifiedCode(r'''
-class V {}
-class A<T> {}
-class B<S> extends Object with A<S> {
-  var b;
-}
-
-main(A<V> p) {
-  if (p is B) {
-    p.b;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedGetter() async {
-    await assertErrorsInUnverifiedCode(r'''
-class T {}
-f(T e) { return e.m; }''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedGetter_generic_function_call() async {
-    // Referencing `.call` on a `Function` type works similarly to referencing
-    // it on `dynamic`--the reference is accepted at compile time, and all type
-    // checking is deferred until runtime.
-    await assertErrorsInUnverifiedCode('''
-f(Function f) {
-  return f.call;
-}
-''', []);
-  }
-
-  test_undefinedGetter_object_call() async {
-    await assertErrorsInUnverifiedCode('''
-f(Object o) {
-  return o.call;
-}
-''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedGetter_proxy_annotation_fakeProxy() async {
-    await assertErrorsInCode(r'''
-library L;
-class Fake {
-  const Fake();
-}
-const proxy = const Fake();
-@proxy class PrefixProxy {}
-main() {
-  new PrefixProxy().foo;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedGetter_static() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-var a = A.B;''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedGetter_typeLiteral_cascadeTarget() async {
-    await assertErrorsInCode(r'''
-class T {
-  static int get foo => 42;
-}
-main() {
-  T..foo;
-}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
-  }
-
-  test_undefinedGetter_typeLiteral_conditionalAccess() async {
-    // When applied to a type literal, the conditional access operator '?.'
-    // cannot be used to access instance getters of Type.
-    // TODO(brianwilkerson) We cannot verify because hashCode isn't resolved.
-    await assertErrorsInCode('''
-class A {}
-f() => A?.hashCode;
-''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
-  }
-
-  test_undefinedGetter_wrongNumberOfTypeArguments_tooLittle() async {
-    await assertErrorsInCode(r'''
-class A<K, V> {
-  K element;
-}
-main(A<int> a) {
-  a.element.anyGetterExistsInDynamic;
-}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_undefinedGetter_wrongNumberOfTypeArguments_tooMany() async {
-    await assertErrorsInCode(r'''
-class A<E> {
-  E element;
-}
-main(A<int,int> a) {
-  a.element.anyGetterExistsInDynamic;
-}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_undefinedGetter_wrongOfTypeArgument() async {
-    await assertErrorsInCode(r'''
-class A<E> {
-  E element;
-}
-main(A<NoSuchType> a) {
-  a.element.anyGetterExistsInDynamic;
-}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
-  }
-
-  test_undefinedMethod_assignmentExpression() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B {
-  f(A a) {
-    A a2 = new A();
-    a += a2;
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
-  }
-
-  test_undefinedMethod_ignoreTypePropagation() async {
-    await assertErrorsInCode(r'''
-class A {}
-class B extends A {
-  m() {}
-}
-class C {
-  f() {
-    A a = new B();
-    a.m();
-  }
-}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
-  }
-
-  test_undefinedMethod_leastUpperBoundWithNull() async {
-    await assertErrorsInCode('f(bool b, int i) => (b ? null : i).foo();',
-        [StaticTypeWarningCode.UNDEFINED_METHOD]);
-  }
-
-  test_undefinedMethod_ofNull() async {
-    // TODO(scheglov) Track https://github.com/dart-lang/sdk/issues/28430 to
-    // decide whether a warning should be reported here.
-    await assertErrorsInCode(r'''
-Null f(int x) => null;
-main() {
-  f(42).abs();
-}
-''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
-  }
-
-  test_undefinedMethodWithConstructor() async {
-    // TODO(brianwilkerson) We cannot verify because 'C' could not be resolved.
-    await assertErrorsInCode(r'''
-class C {
-  C.m();
-}
-f() {
-  C c = C.m();
-}''', [], verify: false);
-  }
-
-  test_undefinedOperator_indexBoth() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-f(A a) {
-  a[0]++;
-}''', [
-      StaticTypeWarningCode.UNDEFINED_OPERATOR,
-      StaticTypeWarningCode.UNDEFINED_OPERATOR,
-    ]);
-  }
-
-  test_undefinedOperator_indexGetter() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-f(A a) {
-  a[0];
-}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_indexSetter() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-f(A a) {
-  a[0] = 1;
-}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_plus() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-f(A a) {
-  a + 1;
-}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_postfixExpression() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  a++;
-}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedOperator_prefixExpression() async {
-    await assertErrorsInCode(r'''
-class A {}
-f(A a) {
-  ++a;
-}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
-  }
-
-  test_undefinedSetter() async {
-    await assertErrorsInUnverifiedCode(r'''
-class T {}
-f(T e1) { e1.m = 0; }''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
-  }
-
-  test_undefinedSetter_static() async {
-    await assertErrorsInUnverifiedCode(r'''
-class A {}
-f() { A.B = 0;}''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
-  }
-
-  test_undefinedSetter_typeLiteral_cascadeTarget() async {
-    await assertErrorsInCode(r'''
-class T {
-  static void set foo(_) {}
-}
-main() {
-  T..foo = 42;
-}''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
-  }
-
-  test_unqualifiedReferenceToNonLocalStaticMember_getter() async {
-    await assertErrorsInCode(r'''
-class A {
-  static int get a => 0;
-}
-class B extends A {
-  int b() {
-    return a;
-  }
-}''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
-  }
-
-  test_unqualifiedReferenceToNonLocalStaticMember_getter_invokeTarget() async {
-    await assertErrorsInCode(r'''
-class A {
-  static int foo;
-}
-
-class B extends A {
-  static bar() {
-    foo.abs();
-  }
-}
-''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
-  }
-
-  test_unqualifiedReferenceToNonLocalStaticMember_setter() async {
-    await assertErrorsInCode(r'''
-class A {
-  static set a(x) {}
-}
-class B extends A {
-  b(y) {
-    a = y;
-  }
-}''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
-  }
-
-  test_wrongNumberOfTypeArguments_class_tooFew() async {
-    await assertErrorsInCode(r'''
-class A<E, F> {}
-A<A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_wrongNumberOfTypeArguments_class_tooMany() async {
-    await assertErrorsInCode(r'''
-class A<E> {}
-A<A, A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_wrongNumberOfTypeArguments_classAlias() async {
-    await assertErrorsInCode(r'''
-class A {}
-class M {}
-class B<F extends num> = A<F> with M;''',
-        [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_wrongNumberOfTypeArguments_dynamic() async {
-    await assertErrorsInCode(r'''
-dynamic<int> v;
-''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_wrongNumberOfTypeArguments_typeParameter() async {
-    await assertErrorsInCode(r'''
-class C<T> {
-  T<int> f;
-}
-''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_wrongNumberOfTypeArguments_typeTest_tooFew() async {
-    await assertErrorsInCode(r'''
-class A {}
-class C<K, V> {}
-f(p) {
-  return p is C<A>;
-}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_wrongNumberOfTypeArguments_typeTest_tooMany() async {
-    await assertErrorsInCode(r'''
-class A {}
-class C<E> {}
-f(p) {
-  return p is C<A, A>;
-}''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
-  }
-
-  test_yield_async_to_basic_type() async {
-    await assertErrorsInCode('''
-int f() async* {
-  yield 3;
-}
-''', [
-      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
-      StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE
-    ]);
-  }
-
-  test_yield_async_to_iterable() async {
-    await assertErrorsInCode('''
-Iterable<int> f() async* {
-  yield 3;
-}
-''', [
-      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
-      StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE
-    ]);
-  }
-
-  test_yield_async_to_mistyped_stream() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Stream<int> f() async* {
-  yield "foo";
-}
-''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
-  }
-
-  test_yield_each_async_non_stream() async {
-    await assertErrorsInCode('''
-f() async* {
-  yield* 0;
-}
-''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
-  }
-
-  test_yield_each_async_to_mistyped_stream() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Stream<int> f() async* {
-  yield* g();
-}
-Stream<String> g() => null;
-''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
-  }
-
-  test_yield_each_sync_non_iterable() async {
-    await assertErrorsInCode('''
-f() sync* {
-  yield* 0;
-}
-''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
-  }
-
-  test_yield_each_sync_to_mistyped_iterable() async {
-    await assertErrorsInCode('''
-Iterable<int> f() sync* {
-  yield* g();
-}
-Iterable<String> g() => null;
-''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
-  }
-
-  test_yield_sync_to_basic_type() async {
-    await assertErrorsInCode('''
-int f() sync* {
-  yield 3;
-}
-''', [
-      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
-      StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE
-    ]);
-  }
-
-  test_yield_sync_to_mistyped_iterable() async {
-    await assertErrorsInCode('''
-Iterable<int> f() sync* {
-  yield "foo";
-}
-''', [StaticTypeWarningCode.YIELD_OF_INVALID_TYPE]);
-  }
-
-  test_yield_sync_to_stream() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-Stream<int> f() sync* {
-  yield 3;
-}
-''', [
-      StaticTypeWarningCode.YIELD_OF_INVALID_TYPE,
-      StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE
-    ]);
-  }
-}
-
-@reflectiveTest
-class StrongModeStaticTypeWarningCodeTest extends ResolverTestCase {
-  void setUp() {
-    super.setUp();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    resetWith(options: options);
-  }
-
-  test_legalAsyncGeneratorReturnType_function_supertypeOfStream() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-f() async* { yield 42; }
-dynamic f2() async* { yield 42; }
-Object f3() async* { yield 42; }
-Stream f4() async* { yield 42; }
-Stream<dynamic> f5() async* { yield 42; }
-Stream<Object> f6() async* { yield 42; }
-Stream<num> f7() async* { yield 42; }
-Stream<int> f8() async* { yield 42; }
-''', []);
-  }
-
-  test_legalAsyncReturnType_function_supertypeOfFuture() async {
-    await assertErrorsInCode('''
-import 'dart:async';
-f() async { return 42; }
-dynamic f2() async { return 42; }
-Object f3() async { return 42; }
-Future f4() async { return 42; }
-Future<dynamic> f5() async { return 42; }
-Future<Object> f6() async { return 42; }
-Future<num> f7() async { return 42; }
-Future<int> f8() async { return 42; }
-''', []);
-  }
-
-  test_legalSyncGeneratorReturnType_function_supertypeOfIterable() async {
-    await assertErrorsInCode('''
-f() sync* { yield 42; }
-dynamic f2() sync* { yield 42; }
-Object f3() sync* { yield 42; }
-Iterable f4() sync* { yield 42; }
-Iterable<dynamic> f5() sync* { yield 42; }
-Iterable<Object> f6() sync* { yield 42; }
-Iterable<num> f7() sync* { yield 42; }
-Iterable<int> f8() sync* { yield 42; }
-''', []);
-  }
-}
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f5b8968..53664c9 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -15,7 +15,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(EqualValuesInConstSetTest);
-    defineReflectiveTests(StaticWarningCodeTest);
   });
 }
 
@@ -61,8 +60,7 @@
   }
 }
 
-@reflectiveTest
-class StaticWarningCodeTest extends ResolverTestCase {
+abstract class StaticWarningCodeTest extends ResolverTestCase {
   fail_argumentTypeNotAssignable_tearOff_required() async {
     Source source = addSource(r'''
 class C {
@@ -2175,136 +2173,6 @@
     verify([source]);
   }
 
-  test_invalidOverride_defaultOverridesNonDefault() async {
-    // If the base class provided an explicit value for a default parameter,
-    // then it is a static warning for the derived class to provide a different
-    // value, even if implicitly.
-    Source source = addSource(r'''
-class A {
-  foo([x = 1]) {}
-}
-class B extends A {
-  foo([x]) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverride_defaultOverridesNonDefault_named() async {
-    // If the base class provided an explicit value for a default parameter,
-    // then it is a static warning for the derived class to provide a different
-    // value, even if implicitly.
-    Source source = addSource(r'''
-class A {
-  foo({x: 1}) {}
-}
-class B extends A {
-  foo({x}) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverride_defaultOverridesNonDefaultNull() async {
-    // If the base class provided an explicit null value for a default
-    // parameter, then it is ok for the derived class to let the default value
-    // be implicit, because the implicit default value of null matches the
-    // explicit default value of null.
-    Source source = addSource(r'''
-class A {
-  foo([x = null]) {}
-}
-class B extends A {
-  foo([x]) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverride_defaultOverridesNonDefaultNull_named() async {
-    // If the base class provided an explicit null value for a default
-    // parameter, then it is ok for the derived class to let the default value
-    // be implicit, because the implicit default value of null matches the
-    // explicit default value of null.
-    Source source = addSource(r'''
-class A {
-  foo({x: null}) {}
-}
-class B extends A {
-  foo({x}) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverride_nonDefaultOverridesDefault() async {
-    // If the base class lets the default parameter be implicit, then it is ok
-    // for the derived class to provide an explicit default value, even if it's
-    // not null.
-    Source source = addSource(r'''
-class A {
-  foo([x]) {}
-}
-class B extends A {
-  foo([x = 1]) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverride_nonDefaultOverridesDefault_named() async {
-    // If the base class lets the default parameter be implicit, then it is ok
-    // for the derived class to provide an explicit default value, even if it's
-    // not null.
-    Source source = addSource(r'''
-class A {
-  foo({x}) {}
-}
-class B extends A {
-  foo({x: 1}) {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_named() async {
-    Source source = addSource(r'''
-class A {
-  m({int p : 0}) {}
-}
-class B extends A {
-  m({int p : 1}) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidOverrideDifferentDefaultValues_positional() async {
-    Source source = addSource(r'''
-class A {
-  m([int p = 0]) {}
-}
-class B extends A {
-  m([int p = 1]) {}
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   test_invalidOverrideNamed_fewerNamedParameters() async {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/strong_mode.dart b/pkg/analyzer/test/generated/strong_mode.dart
new file mode 100644
index 0000000..d5d561b
--- /dev/null
+++ b/pkg/analyzer/test/generated/strong_mode.dart
@@ -0,0 +1,4601 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_resolution_map.dart';
+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/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/task/strong/ast_properties.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:front_end/src/base/errors.dart';
+import 'package:test/test.dart';
+
+import '../utils.dart';
+import 'resolver_test_case.dart';
+
+/// Strong mode static analyzer local type inference tests
+abstract class StrongModeLocalInferenceTest extends ResolverTestCase {
+  TypeAssertions _assertions;
+
+  Asserter<DartType> _isDynamic;
+  Asserter<InterfaceType> _isFutureOfDynamic;
+  Asserter<InterfaceType> _isFutureOfInt;
+  Asserter<InterfaceType> _isFutureOfNull;
+  Asserter<InterfaceType> _isFutureOrOfInt;
+  Asserter<DartType> _isInt;
+  Asserter<DartType> _isNull;
+  Asserter<DartType> _isNum;
+  Asserter<DartType> _isObject;
+  Asserter<DartType> _isString;
+
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
+      _isFunction2Of;
+  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
+  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOrOf;
+  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
+      _isInstantiationOf;
+  AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
+      _isMapOf;
+  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
+  AsserterBuilder<DartType, DartType> _isType;
+
+  AsserterBuilder<Element, DartType> _hasElement;
+  AsserterBuilder<DartType, DartType> _hasElementOf;
+
+  @override
+  Future<TestAnalysisResult> computeAnalysisResult(Source source) async {
+    TestAnalysisResult result = await super.computeAnalysisResult(source);
+    if (_assertions == null) {
+      _assertions = new TypeAssertions(typeProvider);
+      _isType = _assertions.isType;
+      _hasElement = _assertions.hasElement;
+      _isInstantiationOf = _assertions.isInstantiationOf;
+      _isInt = _assertions.isInt;
+      _isNull = _assertions.isNull;
+      _isNum = _assertions.isNum;
+      _isObject = _assertions.isObject;
+      _isString = _assertions.isString;
+      _isDynamic = _assertions.isDynamic;
+      _isListOf = _assertions.isListOf;
+      _isMapOf = _assertions.isMapOf;
+      _isFunction2Of = _assertions.isFunction2Of;
+      _hasElementOf = _assertions.hasElementOf;
+      _isFutureOf = _isInstantiationOf(_hasElementOf(typeProvider.futureType));
+      _isFutureOrOf =
+          _isInstantiationOf(_hasElementOf(typeProvider.futureOrType));
+      _isFutureOfDynamic = _isFutureOf([_isDynamic]);
+      _isFutureOfInt = _isFutureOf([_isInt]);
+      _isFutureOfNull = _isFutureOf([_isNull]);
+      _isFutureOrOfInt = _isFutureOrOf([_isInt]);
+      _isStreamOf = _isInstantiationOf(_hasElementOf(typeProvider.streamType));
+    }
+    return result;
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    resetWith(options: options);
+  }
+
+  test_async_method_propagation() async {
+    String code = r'''
+      import "dart:async";
+      class A {
+        Future f0() => new Future.value(3);
+        Future f1() async => new Future.value(3);
+        Future f2() async => await new Future.value(3);
+
+        Future<int> f3() => new Future.value(3);
+        Future<int> f4() async => new Future.value(3);
+        Future<int> f5() async => await new Future.value(3);
+
+        Future g0() { return new Future.value(3); }
+        Future g1() async { return new Future.value(3); }
+        Future g2() async { return await new Future.value(3); }
+
+        Future<int> g3() { return new Future.value(3); }
+        Future<int> g4() async { return new Future.value(3); }
+        Future<int> g5() async { return await new Future.value(3); }
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+      FunctionBody body = test.body;
+      Expression returnExp;
+      if (body is ExpressionFunctionBody) {
+        returnExp = body.expression;
+      } else {
+        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+        returnExp = stmt.expression;
+      }
+      DartType type = returnExp.staticType;
+      if (returnExp is AwaitExpression) {
+        type = returnExp.expression.staticType;
+      }
+      typeTest(type);
+    }
+
+    check("f0", _isFutureOfDynamic);
+    check("f1", _isFutureOfDynamic);
+    check("f2", _isFutureOfDynamic);
+
+    check("f3", _isFutureOfInt);
+    check("f4", _isFutureOfInt);
+    check("f5", _isFutureOfInt);
+
+    check("g0", _isFutureOfDynamic);
+    check("g1", _isFutureOfDynamic);
+    check("g2", _isFutureOfDynamic);
+
+    check("g3", _isFutureOfInt);
+    check("g4", _isFutureOfInt);
+    check("g5", _isFutureOfInt);
+  }
+
+  test_async_propagation() async {
+    String code = r'''
+      import "dart:async";
+
+      Future f0() => new Future.value(3);
+      Future f1() async => new Future.value(3);
+      Future f2() async => await new Future.value(3);
+
+      Future<int> f3() => new Future.value(3);
+      Future<int> f4() async => new Future.value(3);
+      Future<int> f5() async => await new Future.value(3);
+
+      Future g0() { return new Future.value(3); }
+      Future g1() async { return new Future.value(3); }
+      Future g2() async { return await new Future.value(3); }
+
+      Future<int> g3() { return new Future.value(3); }
+      Future<int> g4() async { return new Future.value(3); }
+      Future<int> g5() async { return await new Future.value(3); }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+      FunctionBody body = test.functionExpression.body;
+      Expression returnExp;
+      if (body is ExpressionFunctionBody) {
+        returnExp = body.expression;
+      } else {
+        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
+        returnExp = stmt.expression;
+      }
+      DartType type = returnExp.staticType;
+      if (returnExp is AwaitExpression) {
+        type = returnExp.expression.staticType;
+      }
+      typeTest(type);
+    }
+
+    check("f0", _isFutureOfDynamic);
+    check("f1", _isFutureOfDynamic);
+    check("f2", _isFutureOfDynamic);
+
+    check("f3", _isFutureOfInt);
+    check("f4", _isFutureOfInt);
+    check("f5", _isFutureOfInt);
+
+    check("g0", _isFutureOfDynamic);
+    check("g1", _isFutureOfDynamic);
+    check("g2", _isFutureOfDynamic);
+
+    check("g3", _isFutureOfInt);
+    check("g4", _isFutureOfInt);
+    check("g5", _isFutureOfInt);
+  }
+
+  test_async_star_method_propagation() async {
+    String code = r'''
+      import "dart:async";
+      class A {
+        Stream g0() async* { yield []; }
+        Stream g1() async* { yield* new Stream(); }
+
+        Stream<List<int>> g2() async* { yield []; }
+        Stream<List<int>> g3() async* { yield* new Stream(); }
+      }
+    ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+      BlockFunctionBody body = test.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("g0", _isListOf(_isDynamic));
+    check("g1", _isStreamOf([_isDynamic]));
+
+    check("g2", _isListOf(_isInt));
+    check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
+  }
+
+  test_async_star_propagation() async {
+    String code = r'''
+      import "dart:async";
+
+      Stream g0() async* { yield []; }
+      Stream g1() async* { yield* new Stream(); }
+
+      Stream<List<int>> g2() async* { yield []; }
+      Stream<List<int>> g3() async* { yield* new Stream(); }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+      BlockFunctionBody body = test.functionExpression.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("g0", _isListOf(_isDynamic));
+    check("g1", _isStreamOf([_isDynamic]));
+
+    check("g2", _isListOf(_isInt));
+    check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
+  }
+
+  test_cascadeExpression() async {
+    String code = r'''
+      class A<T> {
+        List<T> map(T a, List<T> mapper(T x)) => mapper(a);
+      }
+
+      void main () {
+        A<int> a = new A()..map(0, (x) => [x]);
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    CascadeExpression fetch(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      CascadeExpression exp = decl.initializer;
+      return exp;
+    }
+
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+
+    CascadeExpression cascade = fetch(0);
+    _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
+    MethodInvocation invoke = cascade.cascadeSections[0];
+    FunctionExpression function = invoke.argumentList.arguments[1];
+    ExecutableElement f0 = function.declaredElement;
+    _isListOf(_isInt)(f0.type.returnType);
+    expect(f0.type.normalParameterTypes[0], typeProvider.intType);
+  }
+
+  test_constrainedByBounds1() async {
+    // Test that upwards inference with two type variables correctly
+    // propogates from the constrained variable to the unconstrained
+    // variable if they are ordered left to right.
+    String code = r'''
+    T f<S, T extends S>(S x) => null;
+    void test() { var x = f(3); }
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
+    VariableDeclarationStatement stmt = statements[0];
+    VariableDeclaration decl = stmt.variables.variables[0];
+    Expression call = decl.initializer;
+    _isInt(call.staticType);
+  }
+
+  test_constrainedByBounds2() async {
+    // Test that upwards inference with two type variables does
+    // propogate from the constrained variable to the unconstrained
+    // variable if they are ordered right to left.
+    String code = r'''
+    T f<T extends S, S>(S x) => null;
+    void test() { var x = f(3); }
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
+    VariableDeclarationStatement stmt = statements[0];
+    VariableDeclaration decl = stmt.variables.variables[0];
+    Expression call = decl.initializer;
+    _isInt(call.staticType);
+  }
+
+  test_constrainedByBounds3() async {
+    Source source = addSource(r'''
+      T f<T extends S, S extends int>(S x) => null;
+      void test() { var x = f(3); }
+   ''');
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
+    VariableDeclarationStatement stmt = statements[0];
+    VariableDeclaration decl = stmt.variables.variables[0];
+    Expression call = decl.initializer;
+    _isInt(call.staticType);
+  }
+
+  test_constrainedByBounds4() async {
+    // Test that upwards inference with two type variables correctly
+    // propogates from the constrained variable to the unconstrained
+    // variable if they are ordered left to right, when the variable
+    // appears co and contra variantly
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    T f<S, T extends Func1<S, S>>(S x) => null;
+    void test() { var x = f(3)(4); }
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
+    VariableDeclarationStatement stmt = statements[0];
+    VariableDeclaration decl = stmt.variables.variables[0];
+    Expression call = decl.initializer;
+    _isInt(call.staticType);
+  }
+
+  test_constrainedByBounds5() async {
+    // Test that upwards inference with two type variables does not
+    // propogate from the constrained variable to the unconstrained
+    // variable if they are ordered right to left, when the variable
+    // appears co and contra variantly, and that an error is issued
+    // for the non-matching bound.
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    T f<T extends Func1<S, S>, S>(S x) => null;
+    void test() { var x = f(3)(null); }
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
+    VariableDeclarationStatement stmt = statements[0];
+    VariableDeclaration decl = stmt.variables.variables[0];
+    Expression call = decl.initializer;
+    _isDynamic(call.staticType);
+  }
+
+  test_constructorInitializer_propagation() async {
+    String code = r'''
+      class A {
+        List<String> x;
+        A() : this.x = [];
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    ConstructorFieldInitializer assignment = constructor.initializers[0];
+    Expression exp = assignment.expression;
+    _isListOf(_isString)(exp.staticType);
+  }
+
+  test_covarianceChecks() async {
+    var source = addSource(r'''
+class C<T> {
+  add(T t) {}
+  forEach(void f(T t)) {}
+}
+class D extends C<int> {
+  add(int t) {}
+  forEach(void f(int t)) {}
+}
+class E extends C<int> {
+  add(Object t) {}
+  forEach(void f(Null t)) {}
+}
+''');
+    var unit = (await computeAnalysisResult(source)).unit;
+    assertNoErrors(source);
+    var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
+    var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
+    expect(covariantC.toList(), [cAdd.declaredElement.parameters[0]]);
+
+    var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
+    var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
+    expect(covariantD.toList(), [dAdd.declaredElement.parameters[0]]);
+
+    var covariantE = getClassCovariantParameters(AstFinder.getClass(unit, "E"));
+    expect(covariantE.toList(), []);
+  }
+
+  test_covarianceChecks2() async {
+    var content = r'''
+class View<T1> {
+  View<T1> create() => this;
+}
+
+class Bar<T2> extends View<Bar<T2>> {}
+
+main() {
+  var b = new Bar<int>();
+  b.create();
+}
+''';
+    var source = addSource(content);
+    var unit = (await computeAnalysisResult(source)).unit;
+    assertNoErrors(source);
+
+    var findNode = FindNode(content, unit);
+    expect(getImplicitCast(findNode.methodInvocation('b.create')), isNull);
+  }
+
+  test_covarianceChecks_genericMethods() async {
+    var source = addSource(r'''
+class C<T> {
+  add<S>(T t) {}
+  forEach<S>(S f(T t)) {}
+}
+class D extends C<int> {
+  add<S>(int t) {}
+  forEach<S>(S f(int t)) {}
+}
+class E extends C<int> {
+  add<S>(Object t) {}
+  forEach<S>(S f(Null t)) {}
+}
+''');
+    var unit = (await computeAnalysisResult(source)).unit;
+    assertNoErrors(source);
+
+    var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
+    var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
+    expect(covariantC.toList(), [cAdd.declaredElement.parameters[0]]);
+
+    var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
+    var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
+    expect(covariantD.toList(), [dAdd.declaredElement.parameters[0]]);
+
+    var covariantE = getClassCovariantParameters(AstFinder.getClass(unit, "E"));
+    expect(covariantE.toList(), []);
+  }
+
+  test_covarianceChecks_returnFunction() async {
+    var source = addSource(r'''
+typedef F<T>(T t);
+typedef T R<T>();
+class C<T> {
+  F<T> f;
+
+  C();
+  factory C.fact() => new C<Null>();
+
+  F<T> get g => null;
+  F<T> m1() => null;
+  R<F<T>> m2() => null;
+
+  casts(C<T> other, T t) {
+    other.f;
+    other.g(t);
+    other.m1();
+    other.m2;
+
+    new C<T>.fact().f(t);
+    new C<int>.fact().g;
+    new C<int>.fact().m1;
+    new C<T>.fact().m2();
+
+    new C<Object>.fact().f(42);
+    new C<Object>.fact().g;
+    new C<Object>.fact().m1;
+    new C<Object>.fact().m2();
+
+    new C.fact().f(42);
+    new C.fact().g;
+    new C.fact().m1;
+    new C.fact().m2();
+  }
+
+  noCasts(T t) {
+    f;
+    g;
+    m1();
+    m2();
+
+    f(t);
+    g(t);
+    (f)(t);
+    (g)(t);
+    m1;
+    m2;
+
+    this.f;
+    this.g;
+    this.m1();
+    this.m2();
+    this.m1;
+    this.m2;
+    (this.m1)();
+    (this.m2)();
+    this.f(t);
+    this.g(t);
+    (this.f)(t);
+    (this.g)(t);
+
+    new C<int>().f;
+    new C<T>().g;
+    new C<int>().m1();
+    new C().m2();
+
+    new D().f;
+    new D().g;
+    new D().m1();
+    new D().m2();
+  }
+}
+class D extends C<num> {
+  noCasts(t) {
+    f;
+    this.g;
+    this.m1();
+    m2;
+
+    super.f;
+    super.g;
+    super.m1;
+    super.m2();
+  }
+}
+
+D d;
+C<Object> c;
+C cD;
+C<Null> cN;
+F<Object> f;
+F<Null> fN;
+R<F<Object>> rf;
+R<F<Null>> rfN;
+R<R<F<Object>>> rrf;
+R<R<F<Null>>> rrfN;
+Object obj;
+F<int> fi;
+R<F<int>> rfi;
+R<R<F<int>>> rrfi;
+
+casts() {
+  c.f;
+  c.g;
+  c.m1;
+  c.m1();
+  c.m2();
+
+  fN = c.f;
+  fN = c.g;
+  rfN = c.m1;
+  rrfN = c.m2;
+  fN = c.m1();
+  rfN = c.m2();
+
+  f = c.f;
+  f = c.g;
+  rf = c.m1;
+  rrf = c.m2;
+  f = c.m1();
+  rf = c.m2();
+  c.m2()();
+
+  c.f(obj);
+  c.g(obj);
+  (c.f)(obj);
+  (c.g)(obj);
+  (c.m1)();
+  c.m1()(obj);
+  (c.m2)();
+
+  cD.f;
+  cD.g;
+  cD.m1;
+  cD.m1();
+  cD.m2();
+}
+
+noCasts() {
+  fi = d.f;
+  fi = d.g;
+  rfi = d.m1;
+  fi = d.m1();
+  rrfi = d.m2;
+  rfi = d.m2();
+  d.f(42);
+  d.g(42);
+  (d.f)(42);
+  (d.g)(42);
+  d.m1()(42);
+  d.m2()()(42);
+
+  cN.f;
+  cN.g;
+  cN.m1;
+  cN.m1();
+  cN.m2();
+}
+''');
+    var unit = (await computeAnalysisResult(source)).unit;
+    assertNoErrors(source);
+
+    void expectCast(Statement statement, bool hasCast) {
+      var value = (statement as ExpressionStatement).expression;
+      if (value is AssignmentExpression) {
+        value = (value as AssignmentExpression).rightHandSide;
+      }
+      while (value is FunctionExpressionInvocation) {
+        value = (value as FunctionExpressionInvocation).function;
+      }
+      while (value is ParenthesizedExpression) {
+        value = (value as ParenthesizedExpression).expression;
+      }
+      var isCallingGetter =
+          value is MethodInvocation && !value.methodName.name.startsWith('m');
+      var cast = isCallingGetter
+          ? getImplicitOperationCast(value)
+          : getImplicitCast(value);
+      var castKind = isCallingGetter ? 'special cast' : 'cast';
+      expect(cast, hasCast ? isNotNull : isNull,
+          reason: '`$statement` should ' +
+              (hasCast ? '' : 'not ') +
+              'have a $castKind on `$value`.');
+    }
+
+    for (var s in AstFinder.getStatementsInMethod(unit, 'C', 'noCasts')) {
+      expectCast(s, false);
+    }
+    for (var s in AstFinder.getStatementsInMethod(unit, 'C', 'casts')) {
+      expectCast(s, true);
+    }
+    for (var s in AstFinder.getStatementsInMethod(unit, 'D', 'noCasts')) {
+      expectCast(s, false);
+    }
+    for (var s in AstFinder.getStatementsInTopLevelFunction(unit, 'noCasts')) {
+      expectCast(s, false);
+    }
+    for (var s in AstFinder.getStatementsInTopLevelFunction(unit, 'casts')) {
+      expectCast(s, true);
+    }
+  }
+
+  test_covarianceChecks_superclass() async {
+    var source = addSource(r'''
+class C<T> {
+  add(T t) {}
+  forEach(void f(T t)) {}
+}
+class D {
+  add(int t) {}
+  forEach(void f(int t)) {}
+}
+class E extends D implements C<int> {}
+''');
+    var unit = (await computeAnalysisResult(source)).unit;
+    assertNoErrors(source);
+    var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
+    var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
+    expect(covariantC.toList(), [cAdd.declaredElement.parameters[0]]);
+
+    var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
+    var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
+    expect(covariantD, null);
+
+    var classE = AstFinder.getClass(unit, "E");
+    var covariantE = getClassCovariantParameters(classE);
+    var superCovariantE = getSuperclassCovariantParameters(classE);
+    expect(covariantE.toList(), []);
+    expect(superCovariantE.toList(), [dAdd.declaredElement.parameters[0]]);
+  }
+
+  test_factoryConstructor_propagation() async {
+    String code = r'''
+      class A<T> {
+        factory A() { return new B(); }
+      }
+      class B<S> extends A<S> {}
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    BlockFunctionBody body = constructor.body;
+    ReturnStatement stmt = body.block.statements[0];
+    InstanceCreationExpression exp = stmt.expression;
+    ClassElement elementB = AstFinder.getClass(unit, "B").declaredElement;
+    ClassElement elementA = AstFinder.getClass(unit, "A").declaredElement;
+    expect(resolutionMap.typeForTypeName(exp.constructorName.type).element,
+        elementB);
+    _isInstantiationOf(_hasElement(elementB))(
+        [_isType(elementA.typeParameters[0].type)])(exp.staticType);
+  }
+
+  test_fieldDeclaration_propagation() async {
+    String code = r'''
+      class A {
+        List<String> f0 = ["hello"];
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
+
+    _isListOf(_isString)(field.initializer.staticType);
+  }
+
+  test_functionDeclaration_body_propagation() async {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      List<int> test1() => [];
+
+      Function2<int, int> test2 (int x) {
+        Function2<String, int> inner() {
+          return (x) => x.length;
+        }
+        return (x) => x;
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
+    ExpressionFunctionBody body = test1.functionExpression.body;
+    assertListOfInt(body.expression.staticType);
+
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+
+    FunctionDeclaration inner =
+        (statements[0] as FunctionDeclarationStatement).functionDeclaration;
+    BlockFunctionBody body0 = inner.functionExpression.body;
+    ReturnStatement return0 = body0.block.statements[0];
+    Expression anon0 = return0.expression;
+    FunctionType type0 = anon0.staticType;
+    expect(type0.returnType, typeProvider.intType);
+    expect(type0.normalParameterTypes[0], typeProvider.stringType);
+
+    FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
+    FunctionType type1 =
+        resolutionMap.elementDeclaredByFunctionExpression(anon1).type;
+    expect(type1.returnType, typeProvider.intType);
+    expect(type1.normalParameterTypes[0], typeProvider.intType);
+  }
+
+  test_functionLiteral_assignment_typedArguments() async {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, String> l0 = (int x) => null;
+        Function2<int, String> l1 = (int x) => "hello";
+        Function2<int, String> l2 = (String x) => "hello";
+        Function2<int, String> l3 = (int x) => 3;
+        Function2<int, String> l4 = (int x) {return 3;};
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_assignment_unTypedArguments() async {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, String> l0 = (x) => null;
+        Function2<int, String> l1 = (x) => "hello";
+        Function2<int, String> l2 = (x) => "hello";
+        Function2<int, String> l3 = (x) => 3;
+        Function2<int, String> l4 = (x) {return 3;};
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_body_propagation() async {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, List<String>> l0 = (int x) => ["hello"];
+        Function2<int, List<String>> l1 = (String x) => ["hello"];
+        Function2<int, List<String>> l2 = (int x) => [3];
+        Function2<int, List<String>> l3 = (int x) {return [3];};
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    Expression functionReturnValue(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      FunctionBody body = exp.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else {
+        Statement stmt = (body as BlockFunctionBody).block.statements[0];
+        return (stmt as ReturnStatement).expression;
+      }
+    }
+
+    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+    assertListOfString(functionReturnValue(0).staticType);
+    assertListOfString(functionReturnValue(1).staticType);
+    assertListOfString(functionReturnValue(2).staticType);
+    assertListOfString(functionReturnValue(3).staticType);
+  }
+
+  test_functionLiteral_functionExpressionInvocation_typedArguments() async {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        (new Mapper<int, String>().map)((int x) => null);
+        (new Mapper<int, String>().map)((int x) => "hello");
+        (new Mapper<int, String>().map)((String x) => "hello");
+        (new Mapper<int, String>().map)((int x) => 3);
+        (new Mapper<int, String>().map)((int x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      FunctionExpressionInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_functionExpressionInvocation_unTypedArguments() async {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        (new Mapper<int, String>().map)((x) => null);
+        (new Mapper<int, String>().map)((x) => "hello");
+        (new Mapper<int, String>().map)((x) => "hello");
+        (new Mapper<int, String>().map)((x) => 3);
+        (new Mapper<int, String>().map)((x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      FunctionExpressionInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_functionInvocation_typedArguments() async {
+    String code = r'''
+      String map(String mapper(int x)) => mapper(null);
+
+      void main () {
+        map((int x) => null);
+        map((int x) => "hello");
+        map((String x) => "hello");
+        map((int x) => 3);
+        map((int x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_functionInvocation_unTypedArguments() async {
+    String code = r'''
+      String map(String mapper(int x)) => mapper(null);
+
+      void main () {
+        map((x) => null);
+        map((x) => "hello");
+        map((x) => "hello");
+        map((x) => 3);
+        map((x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_methodInvocation_typedArguments() async {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        new Mapper<int, String>().map((int x) => null);
+        new Mapper<int, String>().map((int x) => "hello");
+        new Mapper<int, String>().map((String x) => "hello");
+        new Mapper<int, String>().map((int x) => 3);
+        new Mapper<int, String>().map((int x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isString, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_methodInvocation_unTypedArguments() async {
+    String code = r'''
+      class Mapper<F, T> {
+        T map(T mapper(F x)) => mapper(null);
+      }
+
+      void main () {
+        new Mapper<int, String>().map((x) => null);
+        new Mapper<int, String>().map((x) => "hello");
+        new Mapper<int, String>().map((x) => "hello");
+        new Mapper<int, String>().map((x) => 3);
+        new Mapper<int, String>().map((x) {return 3;});
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      ExpressionStatement stmt = statements[i];
+      MethodInvocation invk = stmt.expression;
+      FunctionExpression exp = invk.argumentList.arguments[0];
+      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
+    }
+
+    _isFunction2Of(_isInt, _isNull)(literal(0));
+    _isFunction2Of(_isInt, _isString)(literal(1));
+    _isFunction2Of(_isInt, _isString)(literal(2));
+    _isFunction2Of(_isInt, _isString)(literal(3));
+    _isFunction2Of(_isInt, _isString)(literal(4));
+  }
+
+  test_functionLiteral_unTypedArgument_propagation() async {
+    String code = r'''
+      typedef T Function2<S, T>(S x);
+
+      void main () {
+        Function2<int, int> l0 = (x) => x;
+        Function2<int, int> l1 = (x) => x+1;
+        Function2<int, String> l2 = (x) => x;
+        Function2<int, String> l3 = (x) => x.toLowerCase();
+        Function2<String, String> l4 = (x) => x.toLowerCase();
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    Expression functionReturnValue(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      FunctionExpression exp = decl.initializer;
+      FunctionBody body = exp.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else {
+        Statement stmt = (body as BlockFunctionBody).block.statements[0];
+        return (stmt as ReturnStatement).expression;
+      }
+    }
+
+    expect(functionReturnValue(0).staticType, typeProvider.intType);
+    expect(functionReturnValue(1).staticType, typeProvider.intType);
+    expect(functionReturnValue(2).staticType, typeProvider.intType);
+    expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
+    expect(functionReturnValue(4).staticType, typeProvider.stringType);
+  }
+
+  test_futureOr_assignFromFuture() async {
+    // Test a Future<T> can be assigned to FutureOr<T>.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    test() => mk(new Future<int>.value(42));
+    ''');
+    _isFutureOrOfInt(invoke.staticType);
+  }
+
+  test_futureOr_assignFromValue() async {
+    // Test a T can be assigned to FutureOr<T>.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(T x) => x;
+    test() => mk(42);
+    ''');
+    _isFutureOrOfInt(invoke.staticType);
+  }
+
+  test_futureOr_asyncExpressionBody() async {
+    // A FutureOr<T> can be used as the expression body for an async function
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) async => x;
+    test() => mk(42);
+    ''');
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOr_asyncReturn() async {
+    // A FutureOr<T> can be used as the return value for an async function
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) async { return x; }
+    test() => mk(42);
+    ''');
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOr_await() async {
+    // Test a FutureOr<T> can be awaited.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) async => await x;
+    test() => mk(42);
+    ''');
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOr_downwards1() async {
+    // Test that downwards inference interacts correctly with FutureOr
+    // parameters.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) => null;
+    Future<int> test() => mk(new Future<int>.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOr_downwards2() async {
+    // Test that downwards inference interacts correctly with FutureOr
+    // parameters when the downwards context is FutureOr
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) => null;
+    FutureOr<int> test() => mk(new Future<int>.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOr_downwards3() async {
+    // Test that downwards inference correctly propogates into
+    // arguments.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) => null;
+    Future<int> test() => mk(new Future.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_downwards4() async {
+    // Test that downwards inference interacts correctly with FutureOr
+    // parameters when the downwards context is FutureOr
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) => null;
+    FutureOr<int> test() => mk(new Future.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_downwards5() async {
+    // Test that downwards inference correctly pins the type when it
+    // comes from a FutureOr
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) => null;
+    FutureOr<num> test() => mk(new Future.value(42));
+    ''');
+    _isFutureOf([_isNum])(invoke.staticType);
+    _isFutureOf([_isNum])(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_downwards6() async {
+    // Test that downwards inference doesn't decompose FutureOr
+    // when instantiating type variables.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    T mk<T>(T x) => null;
+    FutureOr<int> test() => mk(new Future.value(42));
+    ''');
+    _isFutureOrOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_downwards7() async {
+    // Test that downwards inference incorporates bounds correctly
+    // when instantiating type variables.
+    MethodInvocation invoke = await _testFutureOr(r'''
+      T mk<T extends Future<int>>(T x) => null;
+      FutureOr<int> test() => mk(new Future.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_downwards8() async {
+    // Test that downwards inference incorporates bounds correctly
+    // when instantiating type variables.
+    // TODO(leafp): I think this should pass once the inference changes
+    // that jmesserly is adding are landed.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    T mk<T extends Future<Object>>(T x) => null;
+    FutureOr<int> test() => mk(new Future.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_downwards9() async {
+    // Test that downwards inference decomposes correctly with
+    // other composite types
+    MethodInvocation invoke = await _testFutureOr(r'''
+    List<T> mk<T>(T x) => null;
+    FutureOr<List<int>> test() => mk(3);
+    ''');
+    _isListOf(_isInt)(invoke.staticType);
+    _isInt(invoke.argumentList.arguments[0].staticType);
+  }
+
+  test_futureOr_methods1() async {
+    // Test that FutureOr has the Object methods
+    MethodInvocation invoke = await _testFutureOr(r'''
+    dynamic test(FutureOr<int> x) => x.toString();
+    ''');
+    _isString(invoke.staticType);
+  }
+
+  test_futureOr_methods2() async {
+    // Test that FutureOr does not have the constituent type methods
+    MethodInvocation invoke = await _testFutureOr(r'''
+    dynamic test(FutureOr<int> x) => x.abs();
+    ''', errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    _isDynamic(invoke.staticType);
+  }
+
+  test_futureOr_methods3() async {
+    // Test that FutureOr does not have the Future type methods
+    MethodInvocation invoke = await _testFutureOr(r'''
+    dynamic test(FutureOr<int> x) => x.then((x) => x);
+    ''', errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    _isDynamic(invoke.staticType);
+  }
+
+  test_futureOr_methods4() async {
+    // Test that FutureOr<dynamic> does not have all methods
+    MethodInvocation invoke = await _testFutureOr(r'''
+    dynamic test(FutureOr<dynamic> x) => x.abs();
+    ''', errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    _isDynamic(invoke.staticType);
+  }
+
+  test_futureOr_no_return() async {
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    Future<int> f;
+    test() => f.then((int x) {});
+    ''');
+    _isFunction2Of(_isInt, _isNull)(
+        invoke.argumentList.arguments[0].staticType);
+    _isFutureOfNull(invoke.staticType);
+  }
+
+  test_futureOr_no_return_value() async {
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    Future<int> f;
+    test() => f.then((int x) {return;});
+    ''');
+    _isFunction2Of(_isInt, _isNull)(
+        invoke.argumentList.arguments[0].staticType);
+    _isFutureOfNull(invoke.staticType);
+  }
+
+  test_futureOr_return_null() async {
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    Future<int> f;
+    test() => f.then((int x) {return null;});
+    ''');
+    _isFunction2Of(_isInt, _isNull)(
+        invoke.argumentList.arguments[0].staticType);
+    _isFutureOfNull(invoke.staticType);
+  }
+
+  test_futureOr_upwards1() async {
+    // Test that upwards inference correctly prefers to instantiate type
+    // variables with the "smaller" solution when both are possible.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T>(FutureOr<T> x) => null;
+    dynamic test() => mk(new Future<int>.value(42));
+    ''');
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOr_upwards2() async {
+    // Test that upwards inference fails when the solution doesn't
+    // match the bound.
+    MethodInvocation invoke = await _testFutureOr(r'''
+    Future<T> mk<T extends Future<Object>>(FutureOr<T> x) => null;
+    dynamic test() => mk(new Future<int>.value(42));
+    ''', errors: [StrongModeCode.COULD_NOT_INFER]);
+    _isFutureOfInt(invoke.staticType);
+  }
+
+  test_futureOrNull_no_return() async {
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    Future<int> f;
+    test() => f.then<Null>((int x) {});
+    ''');
+    _isFunction2Of(_isInt, _isNull)(
+        invoke.argumentList.arguments[0].staticType);
+    _isFutureOfNull(invoke.staticType);
+  }
+
+  test_futureOrNull_no_return_value() async {
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    Future<int> f;
+    test() => f.then<Null>((int x) {return;});
+    ''');
+    _isFunction2Of(_isInt, _isNull)(
+        invoke.argumentList.arguments[0].staticType);
+    _isFutureOfNull(invoke.staticType);
+  }
+
+  test_futureOrNull_return_null() async {
+    MethodInvocation invoke = await _testFutureOr(r'''
+    FutureOr<T> mk<T>(Future<T> x) => x;
+    Future<int> f;
+    test() => f.then<Null>((int x) { return null;});
+    ''');
+    _isFunction2Of(_isInt, _isNull)(
+        invoke.argumentList.arguments[0].staticType);
+    _isFutureOfNull(invoke.staticType);
+  }
+
+  test_generic_partial() async {
+    // Test that upward and downward type inference handles partial
+    // type schemas correctly.  Downwards inference in a partial context
+    // (e.g. Map<String, ?>) should still allow upwards inference to fill
+    // in the missing information.
+    String code = r'''
+class A<T> {
+  A(T x);
+  A.fromA(A<T> a) {}
+  A.fromMap(Map<String, T> m) {}
+  A.fromList(List<T> m) {}
+  A.fromT(T t) {}
+  A.fromB(B<T, String> a) {}
+}
+
+class B<S, T> {
+  B(S s);
+}
+
+void test() {
+    var a0 = new A.fromA(new A(3));
+    var a1 = new A.fromMap({'hello' : 3});
+    var a2 = new A.fromList([3]);
+    var a3 = new A.fromT(3);
+    var a4 = new A.fromB(new B(3));
+}
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "test");
+    void check(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      Expression init = decl.initializer;
+      _isInstantiationOf(_hasElement(elementA))([_isInt])(init.staticType);
+    }
+
+    for (var i = 0; i < 5; i++) check(i);
+  }
+
+  test_inferConstructor_unknownTypeLowerBound() async {
+    Source source = addSource(r'''
+        class C<T> {
+          C(void callback(List<T> a));
+        }
+        test() {
+          // downwards inference pushes List<?> and in parameter position this
+          // becomes inferred as List<Null>.
+          var c = new C((items) {});
+        }
+        ''');
+    CompilationUnit unit = (await computeAnalysisResult(source)).unit;
+    assertNoErrors(source);
+    verify([source]);
+    DartType cType = findLocalVariable(unit, 'c').type;
+    Element elementC = AstFinder.getClass(unit, "C").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType);
+  }
+
+  test_inference_error_arguments() async {
+    Source source = addSource(r'''
+typedef R F<T, R>(T t);
+
+F<T, T> g<T>(F<T, T> f) => (x) => f(f(x));
+
+test() {
+  var h = g((int x) => 42.0);
+}
+ ''');
+    await computeAnalysisResult(source);
+    _expectInferenceError(source, [
+      StrongModeCode.COULD_NOT_INFER,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ], r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'double' for 'T' which doesn't work:
+  Parameter 'f' declared as     '(T) → T'
+                but argument is '(int) → double'.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+  }
+
+  test_inference_error_arguments2() async {
+    Source source = addSource(r'''
+typedef R F<T, R>(T t);
+
+F<T, T> g<T>(F<T, T> a, F<T, T> b) => (x) => a(b(x));
+
+test() {
+  var h = g((int x) => 42.0, (double x) => 42);
+}
+ ''');
+    await computeAnalysisResult(source);
+    _expectInferenceError(source, [
+      StrongModeCode.COULD_NOT_INFER,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ], r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'num' for 'T' which doesn't work:
+  Parameter 'a' declared as     '(T) → T'
+                but argument is '(int) → double'.
+  Parameter 'b' declared as     '(T) → T'
+                but argument is '(double) → int'.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+  }
+
+  test_inference_error_extendsFromReturn() async {
+    // This is not an inference error because we successfully infer Null.
+    Source source = addSource(r'''
+T max<T extends num>(T x, T y) => x;
+
+test() {
+  String hello = max(1, 2);
+}
+ ''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertErrors(source, [
+      StrongModeCode.INVALID_CAST_LITERAL,
+      StrongModeCode.INVALID_CAST_LITERAL
+    ]);
+    var unit = analysisResult.unit;
+    var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0]
+            as VariableDeclarationStatement)
+        .variables
+        .variables[0];
+    var call = h.initializer as MethodInvocation;
+    expect(call.staticInvokeType.toString(), '(Null, Null) → Null');
+  }
+
+  test_inference_error_extendsFromReturn2() async {
+    Source source = addSource(r'''
+typedef R F<T, R>(T t);
+F<T, T> g<T extends num>() => (y) => y;
+
+test() {
+  F<String, String> hello = g();
+}
+ ''');
+    await computeAnalysisResult(source);
+    _expectInferenceError(source, [
+      StrongModeCode.COULD_NOT_INFER,
+    ], r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'String' for 'T' which doesn't work:
+  Type parameter 'T' declared to extend 'num'.
+The type 'String' was inferred from:
+  Return type declared as '(T) → T'
+              used where  '(String) → String' is required.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+  }
+
+  test_inference_error_genericFunction() async {
+    Source source = addSource(r'''
+T max<T extends num>(T x, T y) => x < y ? y : x;
+abstract class Iterable<T> {
+  T get first;
+  S fold<S>(S s, S f(S s, T t));
+}
+test(Iterable values) {
+  num n = values.fold(values.first as num, max);
+}
+ ''');
+    await computeAnalysisResult(source);
+    _expectInferenceError(source, [
+      StrongModeCode.COULD_NOT_INFER,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ], r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'dynamic' for 'T' which doesn't work:
+  Function type declared as '<T extends num>(T, T) → T'
+                used where  '(num, dynamic) → num' is required.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+  }
+
+  test_inference_error_returnContext() async {
+    Source source = addSource(r'''
+typedef R F<T, R>(T t);
+
+F<T, T> g<T>(T t) => (x) => t;
+
+test() {
+  F<num, int> h = g(42);
+}
+ ''');
+    await computeAnalysisResult(source);
+    _expectInferenceError(source, [StrongModeCode.COULD_NOT_INFER], r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'num' for 'T' which doesn't work:
+  Return type declared as '(T) → T'
+              used where  '(num) → int' is required.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+  }
+
+  test_inference_hints() async {
+    Source source = addSource(r'''
+      void main () {
+        var x = 3;
+        List<int> l0 = [];
+     }
+   ''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_inference_simplePolymorphicRecursion_function() async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/30980
+    // Check that inference works properly when inferring the type argument
+    // for a self-recursive call with a function type
+    var source = addSource(r'''
+void _mergeSort<T>(T Function(T) list, int compare(T a, T b), T Function(T) target) {
+  _mergeSort(list, compare, target);
+  _mergeSort(list, compare, list);
+  _mergeSort(target, compare, target);
+  _mergeSort(target, compare, list);
+}
+    ''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var unit = analysisResult.unit;
+    var body = (AstFinder.getTopLevelFunction(unit, '_mergeSort')
+        .functionExpression
+        .body as BlockFunctionBody);
+    var stmts = body.block.statements;
+    for (ExpressionStatement stmt in stmts) {
+      MethodInvocation invoke = stmt.expression;
+      ParameterizedType fType = invoke.staticInvokeType;
+      expect(fType.typeArguments[0].toString(), 'T');
+    }
+  }
+
+  test_inference_simplePolymorphicRecursion_interface() async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/30980
+    // Check that inference works properly when inferring the type argument
+    // for a self-recursive call with an interface type
+    var source = addSource(r'''
+void _mergeSort<T>(List<T> list, int compare(T a, T b), List<T> target) {
+  _mergeSort(list, compare, target);
+  _mergeSort(list, compare, list);
+  _mergeSort(target, compare, target);
+  _mergeSort(target, compare, list);
+}
+    ''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var unit = analysisResult.unit;
+    var body = (AstFinder.getTopLevelFunction(unit, '_mergeSort')
+        .functionExpression
+        .body as BlockFunctionBody);
+    var stmts = body.block.statements;
+    for (ExpressionStatement stmt in stmts) {
+      MethodInvocation invoke = stmt.expression;
+      ParameterizedType fType = invoke.staticInvokeType;
+      expect(fType.typeArguments[0].toString(), 'T');
+    }
+  }
+
+  test_inference_simplePolymorphicRecursion_simple() async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/30980
+    // Check that inference works properly when inferring the type argument
+    // for a self-recursive call with a simple type parameter
+    var source = addSource(r'''
+void _mergeSort<T>(T list, int compare(T a, T b), T target) {
+  _mergeSort(list, compare, target);
+  _mergeSort(list, compare, list);
+  _mergeSort(target, compare, target);
+  _mergeSort(target, compare, list);
+}
+    ''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var unit = analysisResult.unit;
+    var body = (AstFinder.getTopLevelFunction(unit, '_mergeSort')
+        .functionExpression
+        .body as BlockFunctionBody);
+    var stmts = body.block.statements;
+    for (ExpressionStatement stmt in stmts) {
+      MethodInvocation invoke = stmt.expression;
+      ParameterizedType fType = invoke.staticInvokeType;
+      expect(fType.typeArguments[0].toString(), 'T');
+    }
+  }
+
+  test_inferGenericInstantiation() async {
+    // Verify that we don't infer '?` when we instantiate a generic function.
+    var source = addSource(r'''
+T f<T>(T x(T t)) => x(null);
+S g<S>(S s) => s;
+test() {
+ var h = f(g);
+}
+    ''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    var unit = analysisResult.unit;
+    var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0]
+            as VariableDeclarationStatement)
+        .variables
+        .variables[0];
+    _isDynamic(h.declaredElement.type);
+    var fCall = h.initializer as MethodInvocation;
+    expect(
+        fCall.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
+    var g = fCall.argumentList.arguments[0];
+    expect(g.staticType.toString(), '(dynamic) → dynamic');
+  }
+
+  test_inferGenericInstantiation2() async {
+    // Verify the behavior when we cannot infer an instantiation due to invalid
+    // constraints from an outer generic method.
+    var source = addSource(r'''
+T max<T extends num>(T x, T y) => x < y ? y : x;
+abstract class Iterable<T> {
+  T get first;
+  S fold<S>(S s, S f(S s, T t));
+}
+num test(Iterable values) => values.fold(values.first as num, max);
+    ''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertErrors(source, [
+      StrongModeCode.COULD_NOT_INFER,
+      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    ]);
+    verify([source]);
+    var unit = analysisResult.unit;
+    var fold = (AstFinder.getTopLevelFunction(unit, 'test')
+            .functionExpression
+            .body as ExpressionFunctionBody)
+        .expression as MethodInvocation;
+    expect(
+        fold.staticInvokeType.toString(), '(num, (num, dynamic) → num) → num');
+    var max = fold.argumentList.arguments[1];
+    // TODO(jmesserly): arguably (num, num) → num is better here.
+    expect(max.staticType.toString(), '(dynamic, dynamic) → dynamic');
+  }
+
+  test_inferredFieldDeclaration_propagation() async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25546
+    String code = r'''
+      abstract class A {
+        Map<int, List<int>> get map;
+      }
+      class B extends A {
+        var map = { 42: [] };
+      }
+      class C extends A {
+        get map => { 43: [] };
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+    Asserter<InterfaceType> assertMapOfIntToListOfInt =
+        _isMapOf(_isInt, (DartType type) => assertListOfInt(type));
+
+    VariableDeclaration mapB = AstFinder.getFieldInClass(unit, "B", "map");
+    MethodDeclaration mapC = AstFinder.getMethodInClass(unit, "C", "map");
+    assertMapOfIntToListOfInt(
+        resolutionMap.elementDeclaredByVariableDeclaration(mapB).type);
+    assertMapOfIntToListOfInt(
+        resolutionMap.elementDeclaredByMethodDeclaration(mapC).returnType);
+
+    MapLiteral mapLiteralB = mapB.initializer;
+    MapLiteral mapLiteralC = (mapC.body as ExpressionFunctionBody).expression;
+    assertMapOfIntToListOfInt(mapLiteralB.staticType);
+    assertMapOfIntToListOfInt(mapLiteralC.staticType);
+
+    ListLiteral listLiteralB = mapLiteralB.entries[0].value;
+    ListLiteral listLiteralC = mapLiteralC.entries[0].value;
+    assertListOfInt(listLiteralB.staticType);
+    assertListOfInt(listLiteralC.staticType);
+  }
+
+  test_instanceCreation() async {
+    String code = r'''
+      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 test0() {
+        A<int, String> a0 = new A(3, "hello");
+        A<int, String> a1 = new A.named(3, "hello");
+        A<int, String> a2 = new A<int, String>(3, "hello");
+        A<int, String> a3 = new A<int, String>.named(3, "hello");
+        A<int, String> a4 = new A<int, dynamic>(3, "hello");
+        A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
+      }
+      void test1()  {
+        A<int, String> a0 = new A("hello", 3);
+        A<int, String> a1 = new A.named("hello", 3);
+      }
+      void test2() {
+        A<int, String> a0 = new B("hello", 3);
+        A<int, String> a1 = new B.named("hello", 3);
+        A<int, String> a2 = new B<String, int>("hello", 3);
+        A<int, String> a3 = new B<String, int>.named("hello", 3);
+        A<int, String> a4 = new B<String, dynamic>("hello", 3);
+        A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
+      }
+      void test3() {
+        A<int, String> a0 = new B(3, "hello");
+        A<int, String> a1 = new B.named(3, "hello");
+      }
+      void test4() {
+        A<int, int> a0 = new C(3);
+        A<int, int> a1 = new C.named(3);
+        A<int, int> a2 = new C<int>(3);
+        A<int, int> a3 = new C<int>.named(3);
+        A<int, int> a4 = new C<dynamic>(3);
+        A<int, int> a5 = new C<dynamic>.named(3);
+      }
+      void test5() {
+        A<int, int> a0 = new C("hello");
+        A<int, int> a1 = new C.named("hello");
+      }
+      void test6()  {
+        A<int, String> a0 = new D("hello");
+        A<int, String> a1 = new D.named("hello");
+        A<int, String> a2 = new D<int, String>("hello");
+        A<int, String> a3 = new D<String, String>.named("hello");
+        A<int, String> a4 = new D<num, dynamic>("hello");
+        A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
+      }
+      void test7() {
+        A<int, String> a0 = new D(3);
+        A<int, String> a1 = new D.named(3);
+      }
+      void test8() {
+        A<C<int>, String> a0 = new E("hello");
+      }
+      void test9() { // Check named and optional arguments
+        A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
+        A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
+        A<int, String> a2 = new F.named(3, "hello", 3, "hello");
+        A<int, String> a3 = new F.named(3, "hello");
+        A<int, String> a4 = new F.named(3, "hello", "hello", 3);
+        A<int, String> a5 = new F.named(3, "hello", "hello");
+      }''';
+    CompilationUnit unit = await resolveSource(code);
+
+    Expression rhs(VariableDeclarationStatement stmt) {
+      VariableDeclaration decl = stmt.variables.variables[0];
+      Expression exp = decl.initializer;
+      return exp;
+    }
+
+    void hasType(Asserter<DartType> assertion, Expression exp) =>
+        assertion(exp.staticType);
+
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
+    Element elementC = AstFinder.getClass(unit, "C").declaredElement;
+    Element elementD = AstFinder.getClass(unit, "D").declaredElement;
+    Element elementE = AstFinder.getClass(unit, "E").declaredElement;
+    Element elementF = AstFinder.getClass(unit, "F").declaredElement;
+
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
+        _isInstantiationOf(_hasElement(elementA));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
+        _isInstantiationOf(_hasElement(elementB));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
+        _isInstantiationOf(_hasElement(elementC));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
+        _isInstantiationOf(_hasElement(elementD));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
+        _isInstantiationOf(_hasElement(elementE));
+    AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
+        _isInstantiationOf(_hasElement(elementF));
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test0");
+
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
+      hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
+      hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test1");
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test2");
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
+      hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
+      hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test3");
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
+      hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test4");
+      hasType(assertCOf([_isInt]), rhs(statements[0]));
+      hasType(assertCOf([_isInt]), rhs(statements[1]));
+      hasType(assertCOf([_isInt]), rhs(statements[2]));
+      hasType(assertCOf([_isInt]), rhs(statements[3]));
+      hasType(assertCOf([_isDynamic]), rhs(statements[4]));
+      hasType(assertCOf([_isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test5");
+      hasType(assertCOf([_isInt]), rhs(statements[0]));
+      hasType(assertCOf([_isInt]), rhs(statements[1]));
+    }
+
+    {
+      // The first type parameter is not constrained by the
+      // context.  We could choose a tighter type, but currently
+      // we just use dynamic.
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test6");
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
+      hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
+      hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
+      hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
+      hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test7");
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
+      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test8");
+      hasType(assertEOf([_isInt, _isString]), rhs(statements[0]));
+    }
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInTopLevelFunction(unit, "test9");
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
+      hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
+    }
+  }
+
+  test_listLiteral_nested() async {
+    String code = r'''
+      void main () {
+        List<List<int>> l0 = [[]];
+        Iterable<List<int>> l1 = [[3]];
+        Iterable<List<int>> l2 = [[3], [4]];
+        List<List<int>> l3 = [["hello", 3], []];
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    ListLiteral literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+    Asserter<InterfaceType> assertListOfListOfInt =
+        _isListOf((DartType type) => assertListOfInt(type));
+
+    assertListOfListOfInt(literal(0).staticType);
+    assertListOfListOfInt(literal(1).staticType);
+    assertListOfListOfInt(literal(2).staticType);
+    assertListOfListOfInt(literal(3).staticType);
+
+    assertListOfInt(literal(1).elements[0].staticType);
+    assertListOfInt(literal(2).elements[0].staticType);
+    assertListOfInt(literal(3).elements[0].staticType);
+  }
+
+  test_listLiteral_simple() async {
+    String code = r'''
+      void main () {
+        List<int> l0 = [];
+        List<int> l1 = [3];
+        List<int> l2 = ["hello"];
+        List<int> l3 = ["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    assertListOfInt(literal(0));
+    assertListOfInt(literal(1));
+    assertListOfInt(literal(2));
+    assertListOfInt(literal(3));
+  }
+
+  test_listLiteral_simple_const() async {
+    String code = r'''
+      void main () {
+        const List<int> c0 = const [];
+        const List<int> c1 = const [3];
+        const List<int> c2 = const ["hello"];
+        const List<int> c3 = const ["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    assertListOfInt(literal(0));
+    assertListOfInt(literal(1));
+    assertListOfInt(literal(2));
+    assertListOfInt(literal(3));
+  }
+
+  test_listLiteral_simple_disabled() async {
+    String code = r'''
+      void main () {
+        List<int> l0 = <num>[];
+        List<int> l1 = <num>[3];
+        List<int> l2 = <String>["hello"];
+        List<int> l3 = <dynamic>["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    _isListOf(_isNum)(literal(0));
+    _isListOf(_isNum)(literal(1));
+    _isListOf(_isString)(literal(2));
+    _isListOf(_isDynamic)(literal(3));
+  }
+
+  test_listLiteral_simple_subtype() async {
+    String code = r'''
+      void main () {
+        Iterable<int> l0 = [];
+        Iterable<int> l1 = [3];
+        Iterable<int> l2 = ["hello"];
+        Iterable<int> l3 = ["hello", 3];
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      ListLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
+
+    assertListOfInt(literal(0));
+    assertListOfInt(literal(1));
+    assertListOfInt(literal(2));
+    assertListOfInt(literal(3));
+  }
+
+  test_mapLiteral_nested() async {
+    String code = r'''
+      void main () {
+        Map<int, List<String>> l0 = {};
+        Map<int, List<String>> l1 = {3: ["hello"]};
+        Map<int, List<String>> l2 = {"hello": ["hello"]};
+        Map<int, List<String>> l3 = {3: [3]};
+        Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    MapLiteral literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      MapLiteral exp = decl.initializer;
+      return exp;
+    }
+
+    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+    Asserter<InterfaceType> assertMapOfIntToListOfString =
+        _isMapOf(_isInt, (DartType type) => assertListOfString(type));
+
+    assertMapOfIntToListOfString(literal(0).staticType);
+    assertMapOfIntToListOfString(literal(1).staticType);
+    assertMapOfIntToListOfString(literal(2).staticType);
+    assertMapOfIntToListOfString(literal(3).staticType);
+    assertMapOfIntToListOfString(literal(4).staticType);
+
+    assertListOfString(literal(1).entries[0].value.staticType);
+    assertListOfString(literal(2).entries[0].value.staticType);
+    assertListOfString(literal(3).entries[0].value.staticType);
+    assertListOfString(literal(4).entries[0].value.staticType);
+  }
+
+  test_mapLiteral_simple() async {
+    String code = r'''
+      void main () {
+        Map<int, String> l0 = {};
+        Map<int, String> l1 = {3: "hello"};
+        Map<int, String> l2 = {"hello": "hello"};
+        Map<int, String> l3 = {3: 3};
+        Map<int, String> l4 = {3:"hello", "hello": 3};
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      MapLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertMapOfIntToString =
+        _isMapOf(_isInt, _isString);
+
+    assertMapOfIntToString(literal(0));
+    assertMapOfIntToString(literal(1));
+    assertMapOfIntToString(literal(2));
+    assertMapOfIntToString(literal(3));
+  }
+
+  test_mapLiteral_simple_disabled() async {
+    String code = r'''
+      void main () {
+        Map<int, String> l0 = <int, dynamic>{};
+        Map<int, String> l1 = <int, dynamic>{3: "hello"};
+        Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
+        Map<int, String> l3 = <int, dynamic>{3: 3};
+     }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    List<Statement> statements =
+        AstFinder.getStatementsInTopLevelFunction(unit, "main");
+    DartType literal(int i) {
+      VariableDeclarationStatement stmt = statements[i];
+      VariableDeclaration decl = stmt.variables.variables[0];
+      MapLiteral exp = decl.initializer;
+      return exp.staticType;
+    }
+
+    Asserter<InterfaceType> assertMapOfIntToDynamic =
+        _isMapOf(_isInt, _isDynamic);
+
+    assertMapOfIntToDynamic(literal(0));
+    assertMapOfIntToDynamic(literal(1));
+    assertMapOfIntToDynamic(literal(2));
+    assertMapOfIntToDynamic(literal(3));
+  }
+
+  test_methodDeclaration_body_propagation() async {
+    String code = r'''
+      class A {
+        List<String> m0(int x) => ["hello"];
+        List<String> m1(int x) {return [3];}
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+    Expression methodReturnValue(String methodName) {
+      MethodDeclaration method =
+          AstFinder.getMethodInClass(unit, "A", methodName);
+      FunctionBody body = method.body;
+      if (body is ExpressionFunctionBody) {
+        return body.expression;
+      } else {
+        Statement stmt = (body as BlockFunctionBody).block.statements[0];
+        return (stmt as ReturnStatement).expression;
+      }
+    }
+
+    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
+    assertListOfString(methodReturnValue("m0").staticType);
+    assertListOfString(methodReturnValue("m1").staticType);
+  }
+
+  test_partialTypes1() async {
+    // Test that downwards inference with a partial type
+    // correctly uses the partial information to fill in subterm
+    // types
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    S f<S, T>(Func1<S, T> g) => null;
+    String test() => f((l) => l.length);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    _isString(body.expression.staticType);
+    MethodInvocation invoke = body.expression;
+    FunctionExpression function = invoke.argumentList.arguments[0];
+    ExecutableElement f0 = function.declaredElement;
+    FunctionType type = f0.type;
+    _isFunction2Of(_isString, _isInt)(type);
+  }
+
+  test_pinning_multipleConstraints1() async {
+    // Test that downwards inference with two different downwards covariant
+    // constraints on the same parameter correctly fails to infer when
+    // the types do not share a common subtype
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> { B(S s); }
+    A<int, String> test() => new B(3);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.INVALID_CAST_LITERAL]);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    DartType type = body.expression.staticType;
+
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementB))([_isNull])(type);
+  }
+
+  test_pinning_multipleConstraints2() async {
+    // Test that downwards inference with two identical downwards covariant
+    // constraints on the same parameter correctly infers and pins the type
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> { B(S s); }
+    A<num, num> test() => new B(3);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    DartType type = body.expression.staticType;
+
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementB))([_isNum])(type);
+  }
+
+  test_pinning_multipleConstraints3() async {
+    // Test that downwards inference with two different downwards covariant
+    // constraints on the same parameter correctly fails to infer when
+    // the types do not share a common subtype, but do share a common supertype
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> { B(S s); }
+    A<int, double> test() => new B(3);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertErrors(source, [
+      StrongModeCode.INVALID_CAST_LITERAL,
+    ]);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    DartType type = body.expression.staticType;
+
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementB))([_isNull])(type);
+  }
+
+  test_pinning_multipleConstraints4() async {
+    // Test that downwards inference with two subtype related downwards
+    // covariant constraints on the same parameter correctly infers and pins
+    // the type
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> {}
+    A<int, num> test() => new B();
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    DartType type = body.expression.staticType;
+
+    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementB))([_isInt])(type);
+  }
+
+  test_pinning_multipleConstraints_contravariant1() async {
+    // Test that downwards inference with two different downwards contravariant
+    // constraints on the same parameter chooses the upper bound
+    // when the only supertype is Object
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> {}
+    typedef void Contra1<T>(T x);
+    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
+    Contra1<A<int, String>> test() => mkA();
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    FunctionType functionType = body.expression.staticType;
+    DartType type = functionType.normalParameterTypes[0];
+
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementA))([_isObject, _isObject])(type);
+  }
+
+  test_pinning_multipleConstraints_contravariant2() async {
+    // Test that downwards inference with two identical downwards contravariant
+    // constraints on the same parameter correctly pins the type
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> {}
+    typedef void Contra1<T>(T x);
+    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
+    Contra1<A<num, num>> test() => mkA();
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    FunctionType functionType = body.expression.staticType;
+    DartType type = functionType.normalParameterTypes[0];
+
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
+  }
+
+  test_pinning_multipleConstraints_contravariant3() async {
+    // Test that downwards inference with two different downwards contravariant
+    // constraints on the same parameter correctly choose the least upper bound
+    // when they share a common supertype
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> {}
+    typedef void Contra1<T>(T x);
+    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
+    Contra1<A<int, double>> test() => mkA();
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    FunctionType functionType = body.expression.staticType;
+    DartType type = functionType.normalParameterTypes[0];
+
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
+  }
+
+  test_pinning_multipleConstraints_contravariant4() async {
+    // Test that downwards inference with two different downwards contravariant
+    // constraints on the same parameter correctly choose the least upper bound
+    // when one is a subtype of the other
+    String code = r'''
+    class A<S, T> {
+      S s;
+      T t;
+    }
+    class B<S> extends A<S, S> {}
+    typedef void Contra1<T>(T x);
+    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
+    Contra1<A<int, num>> test() => mkA();
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    FunctionType functionType = body.expression.staticType;
+    DartType type = functionType.normalParameterTypes[0];
+
+    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
+
+    _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
+  }
+
+  test_redirectedConstructor_named() async {
+    Source source = addSource(r'''
+class A<T, U> implements B<T, U> {
+  A.named();
+}
+
+class B<T2, U2> {
+  factory B() = A.named;
+}
+   ''');
+    TestAnalysisResult result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+
+    ClassDeclaration b = result.unit.declarations[1];
+    ConstructorDeclaration bConstructor = b.members[0];
+    ConstructorName redirected = bConstructor.redirectedConstructor;
+
+    TypeName typeName = redirected.type;
+    expect(typeName.type.toString(), 'A<T2, U2>');
+    expect(typeName.type.toString(), 'A<T2, U2>');
+
+    var constructorMember = redirected.staticElement;
+    expect(constructorMember.toString(), 'A.named() → A<T2, U2>');
+    expect(redirected.name.staticElement, constructorMember);
+  }
+
+  test_redirectedConstructor_self() async {
+    Source source = addSource(r'''
+class A<T> {
+  A();
+  factory A.redirected() = A;
+}
+   ''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_redirectedConstructor_unnamed() async {
+    Source source = addSource(r'''
+class A<T, U> implements B<T, U> {
+  A();
+}
+
+class B<T2, U2> {
+  factory B() = A;
+}
+   ''');
+    TestAnalysisResult result = await computeAnalysisResult(source);
+    assertNoErrors(source);
+
+    ClassDeclaration b = result.unit.declarations[1];
+    ConstructorDeclaration bConstructor = b.members[0];
+    ConstructorName redirected = bConstructor.redirectedConstructor;
+
+    TypeName typeName = redirected.type;
+    expect(typeName.type.toString(), 'A<T2, U2>');
+    expect(typeName.type.toString(), 'A<T2, U2>');
+
+    expect(redirected.name, isNull);
+    expect(redirected.staticElement.toString(), 'A() → A<T2, U2>');
+  }
+
+  test_redirectingConstructor_propagation() async {
+    String code = r'''
+      class A {
+        A() : this.named([]);
+        A.named(List<String> x);
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    RedirectingConstructorInvocation invocation = constructor.initializers[0];
+    Expression exp = invocation.argumentList.arguments[0];
+    _isListOf(_isString)(exp.staticType);
+  }
+
+  test_returnType_variance1() async {
+    // Check that downwards inference correctly pins a type parameter
+    // when the parameter is constrained in a contravariant position
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    Func1<T, String> f<T>(T x) => null;
+    Func1<num, String> test() => f(42);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    MethodInvocation invoke = body.expression;
+    _isFunction2Of(_isNum, _isFunction2Of(_isNum, _isString))(
+        invoke.staticInvokeType);
+  }
+
+  test_returnType_variance2() async {
+    // Check that downwards inference correctly pins a type parameter
+    // when the parameter is constrained in a covariant position
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    Func1<String, T> f<T>(T x) => null;
+    Func1<String, num> test() => f(42);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    MethodInvocation invoke = body.expression;
+    _isFunction2Of(_isNum, _isFunction2Of(_isString, _isNum))(
+        invoke.staticInvokeType);
+  }
+
+  test_returnType_variance3() async {
+    // Check that the variance heuristic chooses the most precise type
+    // when the return type uses the variable in a contravariant position
+    // and there is no downwards constraint.
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    Func1<T, String> f<T>(T x, g(T x)) => null;
+    dynamic test() => f(42, (num x) => x);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    FunctionType functionType = body.expression.staticType;
+    DartType type = functionType.normalParameterTypes[0];
+    _isInt(type);
+  }
+
+  test_returnType_variance4() async {
+    // Check that the variance heuristic chooses the more precise type
+    // when the return type uses the variable in a covariant position
+    // and there is no downwards constraint
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    Func1<String, T> f<T>(T x, g(T x)) => null;
+    dynamic test() => f(42, (num x) => x);
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    FunctionType functionType = body.expression.staticType;
+    DartType type = functionType.returnType;
+    _isInt(type);
+  }
+
+  test_returnType_variance5() async {
+    // Check that pinning works correctly with a partial type
+    // when the return type uses the variable in a contravariant position
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    Func1<T, String> f<T>(T x) => null;
+    T g<T, S>(Func1<T, S> f) => null;
+    num test() => g(f(3));
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    MethodInvocation call = body.expression;
+    _isNum(call.staticType);
+    _isFunction2Of(_isFunction2Of(_isNum, _isString), _isNum)(
+        call.staticInvokeType);
+  }
+
+  test_returnType_variance6() async {
+    // Check that pinning works correctly with a partial type
+    // when the return type uses the variable in a covariant position
+    String code = r'''
+    typedef To Func1<From, To>(From x);
+    Func1<String, T> f<T>(T x) => null;
+    T g<T, S>(Func1<S, T> f) => null;
+    num test() => g(f(3));
+   ''';
+    Source source = addSource(code);
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = analysisResult.unit;
+    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    MethodInvocation call = body.expression;
+    _isNum(call.staticType);
+    _isFunction2Of(_isFunction2Of(_isString, _isNum), _isNum)(
+        call.staticInvokeType);
+  }
+
+  test_superConstructorInvocation_propagation() async {
+    String code = r'''
+      class B {
+        B(List<String> p);
+      }
+      class A extends B {
+        A() : super([]);
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    ConstructorDeclaration constructor =
+        AstFinder.getConstructorInClass(unit, "A", null);
+    SuperConstructorInvocation invocation = constructor.initializers[0];
+    Expression exp = invocation.argumentList.arguments[0];
+    _isListOf(_isString)(exp.staticType);
+  }
+
+  test_sync_star_method_propagation() async {
+    String code = r'''
+      import "dart:async";
+      class A {
+        Iterable f0() sync* { yield []; }
+        Iterable f1() sync* { yield* new List(); }
+
+        Iterable<List<int>> f2() sync* { yield []; }
+        Iterable<List<int>> f3() sync* { yield* new List(); }
+      }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
+      BlockFunctionBody body = test.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("f0", _isListOf(_isDynamic));
+    check("f1", _isListOf(_isDynamic));
+
+    check("f2", _isListOf(_isInt));
+    check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
+  }
+
+  test_sync_star_propagation() async {
+    String code = r'''
+      import "dart:async";
+
+      Iterable f0() sync* { yield []; }
+      Iterable f1() sync* { yield* new List(); }
+
+      Iterable<List<int>> f2() sync* { yield []; }
+      Iterable<List<int>> f3() sync* { yield* new List(); }
+   ''';
+    CompilationUnit unit = await resolveSource(code);
+
+    void check(String name, Asserter<InterfaceType> typeTest) {
+      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
+      BlockFunctionBody body = test.functionExpression.body;
+      YieldStatement stmt = body.block.statements[0];
+      Expression exp = stmt.expression;
+      typeTest(exp.staticType);
+    }
+
+    check("f0", _isListOf(_isDynamic));
+    check("f1", _isListOf(_isDynamic));
+
+    check("f2", _isListOf(_isInt));
+    check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
+  }
+
+  /// Verifies the source has the expected [errorCodes] as well as the
+  /// expected [errorMessage].
+  void _expectInferenceError(
+      Source source, List<ErrorCode> errorCodes, String errorMessage) {
+    assertErrors(source, errorCodes);
+    var errors = analysisResults[source]
+        .errors
+        .where((e) => e.errorCode == StrongModeCode.COULD_NOT_INFER)
+        .map((e) => e.message)
+        .toList();
+    expect(errors.length, 1);
+    var actual = errors[0];
+    expect(actual,
+        errorMessage, // Print the literal error message for easy copy+paste:
+        reason: 'Actual error did not match expected error:\n$actual');
+  }
+
+  /// Helper method for testing `FutureOr<T>`.
+  ///
+  /// Validates that [code] produces [errors]. It should define a function
+  /// "test", whose body is an expression that invokes a method. Returns that
+  /// invocation.
+  Future<MethodInvocation> _testFutureOr(String code,
+      {List<ErrorCode> errors}) async {
+    Source source = addSource("""
+    import "dart:async";
+    $code""");
+    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+
+    if (errors == null) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, errors);
+    }
+    verify([source]);
+    FunctionDeclaration test =
+        AstFinder.getTopLevelFunction(analysisResult.unit, "test");
+    ExpressionFunctionBody body = test.functionExpression.body;
+    return body.expression;
+  }
+}
+
+/// Test cases for [StrongModeStaticTypeAnalyzer2Test]
+mixin StrongModeStaticTypeAnalyzer2TestCases
+    implements StaticTypeAnalyzer2TestShared {
+  void expectStaticInvokeType(String search, String type) {
+    var invocation = findIdentifier(search).parent as MethodInvocation;
+    expect(invocation.staticInvokeType.toString(), type);
+  }
+
+  test_dynamicObjectGetter_hashCode() async {
+    String code = r'''
+main() {
+  dynamic a = null;
+  var foo = a.hashCode;
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'int');
+  }
+
+  test_futureOr_promotion1() async {
+    // Test that promotion from FutureOr<T> to T works for concrete types
+    String code = r'''
+    import "dart:async";
+    dynamic test(FutureOr<int> x) => (x is int) && (x.abs() == 0);
+   ''';
+    await resolveTestUnit(code);
+  }
+
+  test_futureOr_promotion2() async {
+    // Test that promotion from FutureOr<T> to Future<T> works for concrete
+    // types
+    String code = r'''
+    import "dart:async";
+    dynamic test(FutureOr<int> x) => (x is Future<int>) &&
+                                     (x.then((x) => x) == null);
+   ''';
+    await resolveTestUnit(code);
+  }
+
+  test_futureOr_promotion3() async {
+    // Test that promotion from FutureOr<T> to T works for type
+    // parameters T
+    String code = r'''
+    import "dart:async";
+    dynamic test<T extends num>(FutureOr<T> x) => (x is T) &&
+                                                  (x.abs() == 0);
+   ''';
+    await resolveTestUnit(code);
+  }
+
+  test_futureOr_promotion4() async {
+    // Test that promotion from FutureOr<T> to Future<T> works for type
+    // parameters T
+    String code = r'''
+    import "dart:async";
+    dynamic test<T extends num>(FutureOr<T> x) => (x is Future<T>) &&
+                                                  (x.then((x) => x) == null);
+   ''';
+    await resolveTestUnit(code);
+  }
+
+  test_generalizedVoid_assignToVoidOk() async {
+    Source source = addSource(r'''
+void main() {
+  void x;
+  x = 42;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+  }
+
+  test_genericFunction() async {
+    await resolveTestUnit(r'T f<T>(T x) => null;');
+    expectFunctionType('f', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
+    SimpleIdentifier f = findIdentifier('f');
+    FunctionElementImpl e = f.staticElement;
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  test_genericFunction_bounds() async {
+    await resolveTestUnit(r'T f<T extends num>(T x) => null;');
+    expectFunctionType('f', '<T extends num>(T) → T',
+        elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
+  }
+
+  test_genericFunction_parameter() async {
+    await resolveTestUnit(r'''
+void g(T f<T>(T x)) {}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectFunctionType('f', '<T>(T) → T',
+        elementTypeParams: '[]', typeFormals: '[T]');
+    SimpleIdentifier f = findIdentifier('f');
+    ParameterElementImpl e = f.staticElement;
+    FunctionType type = e.type;
+    FunctionType ft = type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  test_genericFunction_static() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  static T f<T>(T x) => null;
+}
+''');
+    expectFunctionType('f', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
+    SimpleIdentifier f = findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  test_genericFunction_typedef() async {
+    String code = r'''
+typedef T F<T>(T x);
+F f0;
+
+class C {
+  static F f1;
+  F f2;
+  void g(F f3) {
+    F f4;
+    f0(3);
+    f1(3);
+    f2(3);
+    f3(3);
+    f4(3);
+  }
+}
+
+class D<S> {
+  static F f1;
+  F f2;
+  void g(F f3) {
+    F f4;
+    f0(3);
+    f1(3);
+    f2(3);
+    f3(3);
+    f4(3);
+  }
+}
+''';
+    await resolveTestUnit(code);
+
+    checkBody(String className) {
+      List<Statement> statements =
+          AstFinder.getStatementsInMethod(testUnit, className, "g");
+
+      for (int i = 1; i <= 5; i++) {
+        Expression exp = (statements[i] as ExpressionStatement).expression;
+        expect(exp.staticType, typeProvider.dynamicType);
+      }
+    }
+
+    checkBody("C");
+    checkBody("D");
+  }
+
+  test_genericFunction_upwardsAndDownwards() async {
+    // Regression tests for https://github.com/dart-lang/sdk/issues/27586.
+    await resolveTestUnit(r'List<num> x = [1, 2];');
+    expectInitializerType('x', 'List<num>');
+  }
+
+  test_genericFunction_upwardsAndDownwards_Object() async {
+    // Regression tests for https://github.com/dart-lang/sdk/issues/27625.
+    await resolveTestUnit(r'''
+List<Object> aaa = [];
+List<Object> bbb = [1, 2, 3];
+List<Object> ccc = [null];
+List<Object> ddd = [1 as dynamic];
+List<Object> eee = [new Object()];
+    ''');
+    expectInitializerType('aaa', 'List<Object>');
+    expectInitializerType('bbb', 'List<Object>');
+    expectInitializerType('ccc', 'List<Object>');
+    expectInitializerType('ddd', 'List<Object>');
+    expectInitializerType('eee', 'List<Object>');
+  }
+
+  test_genericMethod() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  List<T> f<T>(E e) => null;
+}
+main() {
+  C<String> cOfString;
+}
+''');
+    expectFunctionType('f', '<T>(E) → List<T>',
+        elementTypeParams: '[T]',
+        typeParams: '[E]',
+        typeArgs: '[E]',
+        typeFormals: '[T]');
+    SimpleIdentifier c = findIdentifier('cOfString');
+    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+    expect(ft.toString(), '<T>(String) → List<T>');
+    ft = ft.instantiate([typeProvider.intType]);
+    expect(ft.toString(), '(String) → List<int>');
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+  }
+
+  test_genericMethod_explicitTypeParams() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  List<T> f<T>(E e) => null;
+}
+main() {
+  C<String> cOfString;
+  var x = cOfString.f<int>('hi');
+}
+''');
+    MethodInvocation f = findIdentifier('f<int>').parent;
+    FunctionType ft = f.staticInvokeType;
+    expect(ft.toString(), '(String) → List<int>');
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+
+    SimpleIdentifier x = findIdentifier('x');
+    expect(x.staticType,
+        typeProvider.listType.instantiate([typeProvider.intType]));
+  }
+
+  test_genericMethod_functionExpressionInvocation_explicit() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  T f<T>(T e) => null;
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+T topF<T>(T e) => null;
+var topG = topF;
+void test<S>(T Function<T>(T) pf) {
+  var c = new C<int>();
+  T lf<T>(T e) => null;
+
+  var lambdaCall = (<E>(E e) => e)<int>(3);
+  var methodCall = (c.f)<int>(3);
+  var staticCall = (C.g)<int>(3);
+  var staticFieldCall = (C.h)<int>(3);
+  var topFunCall = (topF)<int>(3);
+  var topFieldCall = (topG)<int>(3);
+  var localCall = (lf)<int>(3);
+  var paramCall = (pf)<int>(3);
+}
+''');
+    expectIdentifierType('methodCall', "int");
+    expectIdentifierType('staticCall', "int");
+    expectIdentifierType('staticFieldCall', "int");
+    expectIdentifierType('topFunCall', "int");
+    expectIdentifierType('topFieldCall', "int");
+    expectIdentifierType('localCall', "int");
+    expectIdentifierType('paramCall', "int");
+    expectIdentifierType('lambdaCall', "int");
+  }
+
+  test_genericMethod_functionExpressionInvocation_functionTypedParameter_explicit() async {
+    await resolveTestUnit(r'''
+void test<S>(T pf<T>(T e)) {
+  var paramCall = (pf)<int>(3);
+}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectIdentifierType('paramCall', "int");
+  }
+
+  test_genericMethod_functionExpressionInvocation_functionTypedParameter_inferred() async {
+    await resolveTestUnit(r'''
+void test<S>(T pf<T>(T e)) {
+  var paramCall = (pf)(3);
+}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectIdentifierType('paramCall', "int");
+  }
+
+  test_genericMethod_functionExpressionInvocation_inferred() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  T f<T>(T e) => null;
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+T topF<T>(T e) => null;
+var topG = topF;
+void test<S>(T Function<T>(T) pf) {
+  var c = new C<int>();
+  T lf<T>(T e) => null;
+
+  var lambdaCall = (<E>(E e) => e)(3);
+  var methodCall = (c.f)(3);
+  var staticCall = (C.g)(3);
+  var staticFieldCall = (C.h)(3);
+  var topFunCall = (topF)(3);
+  var topFieldCall = (topG)(3);
+  var localCall = (lf)(3);
+  var paramCall = (pf)(3);
+}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectIdentifierType('methodCall', "int");
+    expectIdentifierType('staticCall', "int");
+    expectIdentifierType('staticFieldCall', "int");
+    expectIdentifierType('topFunCall', "int");
+    expectIdentifierType('topFieldCall', "int");
+    expectIdentifierType('localCall', "int");
+    expectIdentifierType('paramCall', "int");
+    expectIdentifierType('lambdaCall', "int");
+  }
+
+  test_genericMethod_functionInvocation_explicit() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  T f<T>(T e) => null;
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+T topF<T>(T e) => null;
+var topG = topF;
+void test<S>(T Function<T>(T) pf) {
+  var c = new C<int>();
+  T lf<T>(T e) => null;
+  var methodCall = c.f<int>(3);
+  var staticCall = C.g<int>(3);
+  var staticFieldCall = C.h<int>(3);
+  var topFunCall = topF<int>(3);
+  var topFieldCall = topG<int>(3);
+  var localCall = lf<int>(3);
+  var paramCall = pf<int>(3);
+}
+''');
+    expectIdentifierType('methodCall', "int");
+    expectIdentifierType('staticCall', "int");
+    expectIdentifierType('staticFieldCall', "int");
+    expectIdentifierType('topFunCall', "int");
+    expectIdentifierType('topFieldCall', "int");
+    expectIdentifierType('localCall', "int");
+    expectIdentifierType('paramCall', "int");
+  }
+
+  test_genericMethod_functionInvocation_functionTypedParameter_explicit() async {
+    await resolveTestUnit(r'''
+void test<S>(T pf<T>(T e)) {
+  var paramCall = pf<int>(3);
+}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectIdentifierType('paramCall', "int");
+  }
+
+  test_genericMethod_functionInvocation_functionTypedParameter_inferred() async {
+    await resolveTestUnit(r'''
+void test<S>(T pf<T>(T e)) {
+  var paramCall = pf(3);
+}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectIdentifierType('paramCall', "int");
+  }
+
+  test_genericMethod_functionInvocation_inferred() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  T f<T>(T e) => null;
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+T topF<T>(T e) => null;
+var topG = topF;
+void test<S>(T Function<T>(T) pf) {
+  var c = new C<int>();
+  T lf<T>(T e) => null;
+  var methodCall = c.f(3);
+  var staticCall = C.g(3);
+  var staticFieldCall = C.h(3);
+  var topFunCall = topF(3);
+  var topFieldCall = topG(3);
+  var localCall = lf(3);
+  var paramCall = pf(3);
+}
+''');
+    expectIdentifierType('methodCall', "int");
+    expectIdentifierType('staticCall', "int");
+    expectIdentifierType('staticFieldCall', "int");
+    expectIdentifierType('topFunCall', "int");
+    expectIdentifierType('topFieldCall', "int");
+    expectIdentifierType('localCall', "int");
+    expectIdentifierType('paramCall', "int");
+  }
+
+  test_genericMethod_functionTypedParameter() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  List<T> f<T>(T f(E e)) => null;
+}
+main() {
+  C<String> cOfString;
+}
+''');
+    expectFunctionType('f', '<T>((E) → T) → List<T>',
+        elementTypeParams: '[T]',
+        typeParams: '[E]',
+        typeArgs: '[E]',
+        typeFormals: '[T]');
+
+    SimpleIdentifier c = findIdentifier('cOfString');
+    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
+    expect(ft.toString(), '<T>((String) → T) → List<T>');
+    ft = ft.instantiate([typeProvider.intType]);
+    expect(ft.toString(), '((String) → int) → List<int>');
+  }
+
+  test_genericMethod_functionTypedParameter_tearoff() async {
+    await resolveTestUnit(r'''
+void test<S>(T pf<T>(T e)) {
+  var paramTearOff = pf;
+}
+''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
+        );
+    expectIdentifierType('paramTearOff', "<T>(T) → T");
+  }
+
+  test_genericMethod_implicitDynamic() async {
+    // Regression test for:
+    // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
+    // These should not cause any hints or warnings.
+    await resolveTestUnit(r'''
+class List<E> {
+  T map<T>(T f(E e)) => null;
+}
+void foo() {
+  List list = null;
+  list.map((e) => e);
+  list.map((e) => 3);
+}''');
+    expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T');
+    expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T');
+
+    MethodInvocation m1 = findIdentifier('map((e) => e);').parent;
+    expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
+    MethodInvocation m2 = findIdentifier('map((e) => 3);').parent;
+    expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
+  }
+
+  test_genericMethod_max_doubleDouble() async {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1.0, 2.0);
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'double');
+  }
+
+  test_genericMethod_max_doubleDouble_prefixed() async {
+    String code = r'''
+import 'dart:math' as math;
+main() {
+  var foo = math.max(1.0, 2.0);
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'double');
+  }
+
+  test_genericMethod_max_doubleInt() async {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1.0, 2);
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'num');
+  }
+
+  test_genericMethod_max_intDouble() async {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1, 2.0);
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'num');
+  }
+
+  test_genericMethod_max_intInt() async {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1, 2);
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'int');
+  }
+
+  test_genericMethod_nestedBound() async {
+    String code = r'''
+class Foo<T extends num> {
+  void method<U extends T>(U u) {
+    u.abs();
+  }
+}
+''';
+    // Just validate that there is no warning on the call to `.abs()`.
+    await resolveTestUnit(code);
+  }
+
+  test_genericMethod_nestedCapture() async {
+    await resolveTestUnit(r'''
+class C<T> {
+  T f<S>(S x) {
+    new C<S>().f<int>(3);
+    new C<S>().f; // tear-off
+    return null;
+  }
+}
+''');
+    MethodInvocation f = findIdentifier('f<int>(3);').parent;
+    expect(f.staticInvokeType.toString(), '(int) → S');
+    FunctionType ft = f.staticInvokeType;
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
+
+    expectIdentifierType('f;', '<S₀>(S₀) → S');
+  }
+
+  test_genericMethod_nestedCaptureBounds() async {
+    await resolveTestUnit(r'''
+class C<T> {
+  T f<S extends T>(S x) {
+    new C<S>().f<int>(3);
+    new C<S>().f; // tear-off
+    return null;
+  }
+}
+''');
+    MethodInvocation f = findIdentifier('f<int>(3);').parent;
+    expect(f.staticInvokeType.toString(), '(int) → S');
+    FunctionType ft = f.staticInvokeType;
+    expect('${ft.typeArguments}/${ft.typeParameters}',
+        '[S, int]/[T, S extends T]');
+
+    expectIdentifierType('f;', '<S₀ extends S>(S₀) → S');
+  }
+
+  test_genericMethod_nestedFunctions() async {
+    await resolveTestUnit(r'''
+S f<S>(S x) {
+  g<S>(S x) => f;
+  return null;
+}
+''');
+    expectIdentifierType('f', '<S>(S) → S');
+    expectIdentifierType('g', '<S>(S) → <S>(S) → S');
+  }
+
+  test_genericMethod_override() async {
+    await resolveTestUnit(r'''
+class C {
+  T f<T>(T x) => null;
+}
+class D extends C {
+  T f<T>(T x) => null; // from D
+}
+''');
+    expectFunctionType('f<T>(T x) => null; // from D', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
+    SimpleIdentifier f = findIdentifier('f<T>(T x) => null; // from D');
+    MethodElementImpl e = f.staticElement;
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  test_genericMethod_override_bounds() async {
+    await resolveTestUnit(r'''
+class A {}
+class B {
+  T f<T extends A>(T x) => null;
+}
+// override with the same bound is OK
+class C extends B {
+  T f<T extends A>(T x) => null;
+}
+// override with new name and the same bound is OK
+class D extends B {
+  Q f<Q extends A>(Q x) => null;
+}
+''');
+  }
+
+  test_genericMethod_override_covariant_field() async {
+    Source source = addSource(r'''
+abstract class A {
+  num get x;
+  set x(covariant num _);
+}
+
+class B extends A {
+  int x;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericMethod_override_differentContextsSameBounds() async {
+    Source source = addSource(r'''
+        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>();
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_genericMethod_override_invalidContravariantTypeParamBounds() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+  T f<T extends A>(T x) => null;
+}
+class D extends C {
+  T f<T extends B>(T x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
+    verify([source]);
+  }
+
+  test_genericMethod_override_invalidCovariantTypeParamBounds() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+  T f<T extends B>(T x) => null;
+}
+class D extends C {
+  T f<T extends A>(T x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
+    verify([source]);
+  }
+
+  test_genericMethod_override_invalidReturnType() async {
+    Source source = addSource(r'''
+class C {
+  Iterable<T> f<T>(T x) => null;
+}
+class D extends C {
+  String f<S>(S x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
+    verify([source]);
+  }
+
+  test_genericMethod_override_invalidTypeParamCount() async {
+    Source source = addSource(r'''
+class C {
+  T f<T>(T x) => null;
+}
+class D extends C {
+  S f<T, S>(T x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
+    verify([source]);
+  }
+
+  test_genericMethod_propagatedType_promotion() async {
+    // Regression test for:
+    // https://github.com/dart-lang/sdk/issues/25340
+
+    // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
+    // example won't work, as we now compute a static type and therefore discard
+    // the propagated type. So a new test was created that doesn't run under
+    // strong mode.
+    await resolveTestUnit(r'''
+abstract class Iter {
+  List<S> map<S>(S f(x));
+}
+class C {}
+C toSpan(dynamic element) {
+  if (element is Iter) {
+    var y = element.map(toSpan);
+  }
+  return null;
+}''');
+    expectIdentifierType('y = ', 'List<C>');
+  }
+
+  test_genericMethod_tearoff() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  T f<T>(E e) => null;
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+T topF<T>(T e) => null;
+var topG = topF;
+void test<S>(T Function<T>(T) pf) {
+  var c = new C<int>();
+  T lf<T>(T e) => null;
+  var methodTearOff = c.f;
+  var staticTearOff = C.g;
+  var staticFieldTearOff = C.h;
+  var topFunTearOff = topF;
+  var topFieldTearOff = topG;
+  var localTearOff = lf;
+  var paramTearOff = pf;
+}
+''');
+    expectIdentifierType('methodTearOff', "<T>(int) → T");
+    expectIdentifierType('staticTearOff', "<T>(T) → T");
+    expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
+    expectIdentifierType('topFunTearOff', "<T>(T) → T");
+    expectIdentifierType('topFieldTearOff', "<T>(T) → T");
+    expectIdentifierType('localTearOff', "<T>(T) → T");
+    expectIdentifierType('paramTearOff', "<T>(T) → T");
+  }
+
+  test_genericMethod_tearoff_instantiated() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  T f<T>(E e) => null;
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+T topF<T>(T e) => null;
+var topG = topF;
+void test<S>(T pf<T>(T e)) {
+  var c = new C<int>();
+  T lf<T>(T e) => null;
+  var methodTearOffInst = c.f<int>;
+  var staticTearOffInst = C.g<int>;
+  var staticFieldTearOffInst = C.h<int>;
+  var topFunTearOffInst = topF<int>;
+  var topFieldTearOffInst = topG<int>;
+  var localTearOffInst = lf<int>;
+  var paramTearOffInst = pf<int>;
+}
+''');
+    expectIdentifierType('methodTearOffInst', "(int) → int");
+    expectIdentifierType('staticTearOffInst', "(int) → int");
+    expectIdentifierType('staticFieldTearOffInst', "(int) → int");
+    expectIdentifierType('topFunTearOffInst', "(int) → int");
+    expectIdentifierType('topFieldTearOffInst', "(int) → int");
+    expectIdentifierType('localTearOffInst', "(int) → int");
+    expectIdentifierType('paramTearOffInst', "(int) → int");
+  }
+
+  test_genericMethod_then() async {
+    String code = r'''
+import 'dart:async';
+String toString(int x) => x.toString();
+main() {
+  Future<int> bar = null;
+  var foo = bar.then(toString);
+}
+''';
+    await resolveTestUnit(code);
+
+    expectInitializerType('foo', 'Future<String>');
+  }
+
+  test_genericMethod_then_prefixed() async {
+    String code = r'''
+import 'dart:async' as async;
+String toString(int x) => x.toString();
+main() {
+  async.Future<int> bar = null;
+  var foo = bar.then(toString);
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'Future<String>');
+  }
+
+  test_genericMethod_then_propagatedType() async {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25482.
+    String code = r'''
+import 'dart:async';
+void main() {
+  Future<String> p;
+  var foo = p.then((r) => new Future<String>.value(3));
+}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    // Note: this correctly reports the error
+    // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE when run with the driver;
+    // when run without the driver, it reports no errors.  So we don't bother
+    // checking whether the correct errors were reported.
+    expectInitializerType('foo', 'Future<String>');
+  }
+
+  test_genericMethod_toplevel_field_staticTearoff() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  static T g<T>(T e) => null;
+  static T Function<T>(T) h = null;
+}
+
+void test() {
+  var fieldRead = C.h;
+}
+''');
+    expectIdentifierType('fieldRead', "<T>(T) → T");
+  }
+
+  test_implicitBounds() async {
+    String code = r'''
+class A<T> {}
+
+class B<T extends num> {}
+
+class C<S extends int, T extends B<S>, U extends A> {}
+
+void test() {
+//
+  A ai;
+  B bi;
+  C ci;
+  var aa = new A();
+  var bb = new B();
+  var cc = new C();
+}
+''';
+    await resolveTestUnit(code);
+    expectIdentifierType('ai', "A<dynamic>");
+    expectIdentifierType('bi', "B<num>");
+    expectIdentifierType('ci', "C<int, B<int>, A<dynamic>>");
+    expectIdentifierType('aa', "A<dynamic>");
+    expectIdentifierType('bb', "B<num>");
+    expectIdentifierType('cc', "C<int, B<int>, A<dynamic>>");
+  }
+
+  test_inferClosureType_parameters() async {
+    Source source = addSource(r'''
+typedef F({bool p});
+foo(callback(F f)) {}
+main() {
+  foo((f) {
+    f(p: false);
+  });
+}
+''');
+    var result = await computeAnalysisResult(source);
+    var main = result.unit.declarations[2] as FunctionDeclaration;
+    var body = main.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var invocation = statement.expression as MethodInvocation;
+    var closure = invocation.argumentList.arguments[0] as FunctionExpression;
+    var closureType = closure.staticType as FunctionType;
+    var fType = closureType.parameters[0].type as FunctionType;
+    // The inferred type of "f" in "foo()" invocation must own its parameters.
+    ParameterElement p = fType.parameters[0];
+    expect(p.name, 'p');
+    expect(p.enclosingElement, same(fType.element));
+  }
+
+  test_instantiateToBounds_class_error_extension_malbounded() async {
+    // Test that superclasses are strictly checked for malbounded default
+    // types
+    String code = r'''
+class C<T0 extends List<T1>, T1 extends List<T0>> {}
+class D extends C {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]);
+  }
+
+  test_instantiateToBounds_class_error_instantiation_malbounded() async {
+    // Test that instance creations are strictly checked for malbounded default
+    // types
+    String code = r'''
+class C<T0 extends List<T1>, T1 extends List<T0>> {}
+void test() {
+  var c = new C();
+}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]);
+    expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>');
+  }
+
+  test_instantiateToBounds_class_error_recursion() async {
+    String code = r'''
+class C<T0 extends List<T1>, T1 extends List<T0>> {}
+C c;
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>');
+  }
+
+  test_instantiateToBounds_class_error_recursion_self() async {
+    String code = r'''
+class C<T extends C<T>> {}
+C c;
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<C<dynamic>>');
+  }
+
+  test_instantiateToBounds_class_error_recursion_self2() async {
+    String code = r'''
+class A<E> {}
+class C<T extends A<T>> {}
+C c;
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<A<dynamic>>');
+  }
+
+  test_instantiateToBounds_class_error_typedef() async {
+    String code = r'''
+typedef T F<T>(T x);
+class C<T extends F<T>> {}
+C c;
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<(dynamic) → dynamic>');
+  }
+
+  test_instantiateToBounds_class_ok_implicitDynamic_multi() async {
+    String code = r'''
+class C<T0 extends Map<T1, T2>, T1 extends List, T2 extends int> {}
+C c;
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectIdentifierType(
+        'c;', 'C<Map<List<dynamic>, int>, List<dynamic>, int>');
+  }
+
+  test_instantiateToBounds_class_ok_referenceOther_after() async {
+    String code = r'''
+class C<T0 extends T1, T1 extends int> {}
+C c;
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<int, int>');
+  }
+
+  test_instantiateToBounds_class_ok_referenceOther_after2() async {
+    String code = r'''
+class C<T0 extends Map<T1, T1>, T1 extends int> {}
+C c;
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<Map<int, int>, int>');
+  }
+
+  test_instantiateToBounds_class_ok_referenceOther_before() async {
+    String code = r'''
+class C<T0 extends int, T1 extends T0> {}
+C c;
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<int, int>');
+  }
+
+  test_instantiateToBounds_class_ok_referenceOther_multi() async {
+    String code = r'''
+class C<T0 extends Map<T1, T2>, T1 extends List<T2>, T2 extends int> {}
+C c;
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectIdentifierType('c;', 'C<Map<List<int>, int>, List<int>, int>');
+  }
+
+  test_instantiateToBounds_class_ok_simpleBounds() async {
+    String code = r'''
+class A<T> {}
+class B<T extends num> {}
+class C<T extends List<int>> {}
+class D<T extends A> {}
+void main() {
+  A a;
+  B b;
+  C c;
+  D d;
+}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectIdentifierType('a;', 'A<dynamic>');
+    expectIdentifierType('b;', 'B<num>');
+    expectIdentifierType('c;', 'C<List<int>>');
+    expectIdentifierType('d;', 'D<A<dynamic>>');
+  }
+
+  test_instantiateToBounds_generic_function_error_malbounded() async {
+    // Test that generic methods are strictly checked for malbounded default
+    // types
+    String code = r'''
+T0 f<T0 extends List<T1>, T1 extends List<T0>>() {}
+void g() {
+  var c = f();
+  return;
+}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]);
+    expectIdentifierType('c;', 'List<dynamic>');
+  }
+
+  test_instantiateToBounds_method_ok_referenceOther_before() async {
+    String code = r'''
+class C<T> {
+  void m<S0 extends T, S1 extends List<S0>>(S0 p0, S1 p1) {}
+
+  void main() {
+    m(null, null);
+  }
+}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectStaticInvokeType('m(null', '(Null, Null) → void');
+  }
+
+  test_instantiateToBounds_method_ok_referenceOther_before2() async {
+    String code = r'''
+class C<T> {
+  Map<S0, S1> m<S0 extends T, S1 extends List<S0>>() => null;
+
+  void main() {
+    m();
+  }
+}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectStaticInvokeType('m();', '() → Map<T, List<T>>');
+  }
+
+  test_instantiateToBounds_method_ok_simpleBounds() async {
+    String code = r'''
+class C<T> {
+  void m<S extends T>(S p0) {}
+
+  void main() {
+    m(null);
+  }
+}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectStaticInvokeType('m(null)', '(Null) → void');
+  }
+
+  test_instantiateToBounds_method_ok_simpleBounds2() async {
+    String code = r'''
+class C<T> {
+  S m<S extends T>() => null;
+
+  void main() {
+    m();
+  }
+}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+    expectStaticInvokeType('m();', '() → T');
+  }
+
+  test_issue32396() async {
+    await resolveTestUnit(r'''
+class C<E> {
+  static T g<T>(T e) => null;
+  static final h = g;
+}
+''');
+  }
+
+  test_notInstantiatedBound_class_error_recursion() async {
+    String code = r'''
+class A<T extends B> {} // points to a
+class B<T extends A> {} // points to b
+class C<T extends A> {} // points to a cyclical type
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+    ]);
+  }
+
+  test_notInstantiatedBound_class_error_recursion_less_direct() async {
+    String code = r'''
+class A<T extends B<A>> {}
+class B<T extends A<B>> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+    ]);
+  }
+
+  test_notInstantiatedBound_class_error_recursion_typedef() async {
+    String code = r'''
+typedef F(C value);
+class C<T extends F> {}
+class D<T extends C> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+    ]);
+  }
+
+  test_notInstantiatedBound_error_class_argument() async {
+    String code = r'''
+class A<K, V extends List<K>> {}
+class C<T extends A> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_error_class_argument2() async {
+    String code = r'''
+class A<K, V extends List<List<K>>> {}
+class C<T extends A> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_error_class_direct() async {
+    String code = r'''
+class A<K, V extends K> {}
+class C<T extends A> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_error_class_indirect() async {
+    String code = r'''
+class A<K, V extends K> {}
+class C<T extends List<A>> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_error_functionType() async {
+    await resolveTestUnit(r'''
+class A<T extends Function(T)> {}
+class B<T extends T Function()> {}
+class C<T extends A> {}
+class D<T extends B> {}
+''', noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND
+    ]);
+  }
+
+  test_notInstantiatedBound_error_typedef_argument() async {
+    String code = r'''
+class A<K, V extends List<K>> {}
+typedef void F<T extends A>();
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_error_typedef_argument2() async {
+    String code = r'''
+class A<K, V extends List<List<K>>> {}
+typedef void F<T extends A>();
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_error_typedef_direct() async {
+    String code = r'''
+class A<K, V extends K> {}
+typedef void F<T extends A>();
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+  }
+
+  test_notInstantiatedBound_ok_class() async {
+    String code = r'''
+class A<T extends int> {}
+class C1<T extends A> {}
+class C2<T extends List<A>> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_notInstantiatedBound_ok_class_class2() async {
+    String code = r'''
+class A<T> {}
+class C<T extends A<int>> {}
+class D<T extends C> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_notInstantiatedBound_ok_class_class3() async {
+    String code = r'''
+class A<T> {}
+class B<T extends int> {}
+class C<T extends A<B>> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_notInstantiatedBound_ok_class_class4() async {
+    String code = r'''
+class A<K, V> {}
+class B<T extends int> {}
+class C<T extends A<B, B>> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_notInstantiatedBound_ok_class_function() async {
+    String code = r'''
+class A<T extends void Function()> {}
+class B<T extends A> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_notInstantiatedBound_ok_class_typedef() async {
+    String code = r'''
+typedef void F<T extends int>();
+class C<T extends F> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_notInstantiatedBound_ok_typedef_class() async {
+    String code = r'''
+class C<T extends int> {}
+typedef void F<T extends C>();
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
+  test_objectMethodOnFunctions_Anonymous() async {
+    String code = r'''
+void main() {
+  var f = (x) => 3;
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    await _objectMethodOnFunctions_helper2(code);
+  }
+
+  test_objectMethodOnFunctions_Function() async {
+    String code = r'''
+void main() {
+  Function f;
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    await _objectMethodOnFunctions_helper2(code);
+  }
+
+  test_objectMethodOnFunctions_Static() async {
+    String code = r'''
+int f(int x) => null;
+void main() {
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    await _objectMethodOnFunctions_helper2(code);
+  }
+
+  test_objectMethodOnFunctions_Typedef() async {
+    String code = r'''
+typedef bool Predicate<T>(T object);
+
+void main() {
+  Predicate<int> f;
+  // No errors, correct type
+  var t0 = f.toString();
+  var t1 = f.toString;
+  var t2 = f.hashCode;
+
+  // Expressions, no errors, correct type
+  var t3 = (f).toString();
+  var t4 = (f).toString;
+  var t5 = (f).hashCode;
+
+  // Cascades, no errors
+  f..toString();
+  f..toString;
+  f..hashCode;
+
+  // Expression cascades, no errors
+  (f)..toString();
+  (f)..toString;
+  (f)..hashCode;
+}''';
+    await _objectMethodOnFunctions_helper2(code);
+  }
+
+  test_returnOfInvalidType_object_void() async {
+    await assertErrorsInCode(
+        "Object f() { void voidFn() => null; return voidFn(); }",
+        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
+  }
+
+  test_setterWithDynamicTypeIsError() async {
+    Source source = addSource(r'''
+class A {
+  dynamic set f(String s) => null;
+}
+dynamic set g(int x) => null;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+    ]);
+    verify([source]);
+  }
+
+  test_setterWithExplicitVoidType_returningVoid() async {
+    Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+  void set f(String s) => returnsVoid();
+}
+void set g(int x) => returnsVoid();
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_setterWithNoVoidType() async {
+    Source source = addSource(r'''
+class A {
+  set f(String s) {
+    return '42';
+  }
+}
+set g(int x) => 42;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+    ]);
+    verify([source]);
+  }
+
+  test_setterWithNoVoidType_returningVoid() async {
+    Source source = addSource(r'''
+void returnsVoid() {}
+class A {
+  set f(String s) => returnsVoid();
+}
+set g(int x) => returnsVoid();
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_setterWithOtherTypeIsError() async {
+    Source source = addSource(r'''
+class A {
+  String set f(String s) => null;
+}
+Object set g(x) => null;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
+      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
+    ]);
+    verify([source]);
+  }
+
+  test_ternaryOperator_null_left() async {
+    String code = r'''
+main() {
+  var foo = (true) ? null : 3;
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'int');
+  }
+
+  test_ternaryOperator_null_right() async {
+    String code = r'''
+main() {
+  var foo = (true) ? 3 : null;
+}
+''';
+    await resolveTestUnit(code);
+    expectInitializerType('foo', 'int');
+  }
+
+  Future<void> _objectMethodOnFunctions_helper2(String code) async {
+    await resolveTestUnit(code);
+    expectIdentifierType('t0', "String");
+    expectIdentifierType('t1', "() → String");
+    expectIdentifierType('t2', "int");
+    expectIdentifierType('t3', "String");
+    expectIdentifierType('t4', "() → String");
+    expectIdentifierType('t5', "int");
+  }
+}
+
+abstract class StrongModeTypePropagationTest extends ResolverTestCase {
+  @override
+  void setUp() {
+    super.setUp();
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    resetWith(options: options);
+  }
+
+  test_foreachInference_dynamic_disabled() async {
+    String code = r'''
+main() {
+  var list = <int>[];
+  for (dynamic v in list) {
+    v; // marker
+  }
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertPropagatedIterationType(code, unit, typeProvider.dynamicType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+  }
+
+  test_foreachInference_reusedVar_disabled() async {
+    String code = r'''
+main() {
+  var list = <int>[];
+  var v;
+  for (v in list) {
+    v; // marker
+  }
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertPropagatedIterationType(code, unit, typeProvider.dynamicType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+  }
+
+  test_foreachInference_var() async {
+    String code = r'''
+main() {
+  var list = <int>[];
+  for (var v in list) {
+    v; // marker
+  }
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertPropagatedIterationType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_foreachInference_var_iterable() async {
+    String code = r'''
+main() {
+  Iterable<int> list = <int>[];
+  for (var v in list) {
+    v; // marker
+  }
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertPropagatedIterationType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_foreachInference_var_stream() async {
+    String code = r'''
+import 'dart:async';
+main() async {
+  Stream<int> stream = null;
+  await for (var v in stream) {
+    v; // marker
+  }
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertPropagatedIterationType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_inconsistentMethodInheritance_inferFunctionTypeFromTypedef() async {
+    Source source = addSource(r'''
+typedef bool F<E>(E argument);
+
+abstract class Base {
+  f<E extends int>(F<int> x);
+}
+
+abstract class BaseCopy extends Base {
+}
+
+abstract class Override implements Base, BaseCopy {
+  f<E extends int>(x) => null;
+}
+
+class C extends Override implements Base {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_localVariableInference_bottom_disabled() async {
+    String code = r'''
+main() {
+  var v = null;
+  v; // marker
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.dynamicType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+  }
+
+  test_localVariableInference_constant() async {
+    String code = r'''
+main() {
+  var v = 3;
+  v; // marker
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_declaredType_disabled() async {
+    String code = r'''
+main() {
+  dynamic v = 3;
+  v; // marker
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.dynamicType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+  }
+
+  test_localVariableInference_noInitializer_disabled() async {
+    String code = r'''
+main() {
+  var v;
+  v = 3;
+  v; // marker
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.dynamicType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
+  }
+
+  test_localVariableInference_transitive_field_inferred_lexical() async {
+    String code = r'''
+class A {
+  final x = 3;
+  f() {
+    var v = x;
+    return v; // marker
+  }
+}
+main() {
+}
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_field_inferred_reversed() async {
+    String code = r'''
+class A {
+  f() {
+    var v = x;
+    return v; // marker
+  }
+  final x = 3;
+}
+main() {
+}
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_field_lexical() async {
+    String code = r'''
+class A {
+  int x = 3;
+  f() {
+    var v = x;
+    return v; // marker
+  }
+}
+main() {
+}
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_field_reversed() async {
+    String code = r'''
+class A {
+  f() {
+    var v = x;
+    return v; // marker
+  }
+  int x = 3;
+}
+main() {
+}
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_list_local() async {
+    String code = r'''
+main() {
+  var x = <int>[3];
+  var v = x[0];
+  v; // marker
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_local() async {
+    String code = r'''
+main() {
+  var x = 3;
+  var v = x;
+  v; // marker
+}''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_toplevel_inferred_lexical() async {
+    String code = r'''
+final x = 3;
+main() {
+  var v = x;
+  v; // marker
+}
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_toplevel_inferred_reversed() async {
+    String code = r'''
+main() {
+  var v = x;
+  v; // marker
+}
+final x = 3;
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_toplevel_lexical() async {
+    String code = r'''
+int x = 3;
+main() {
+  var v = x;
+  v; // marker
+}
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+
+  test_localVariableInference_transitive_toplevel_reversed() async {
+    String code = r'''
+main() {
+  var v = x;
+  v; // marker
+}
+int x = 3;
+''';
+    CompilationUnit unit = await resolveSource(code);
+    assertAssignedType(code, unit, typeProvider.intType);
+    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
+  }
+}
diff --git a/pkg/analyzer/test/generated/strong_mode_driver_test.dart b/pkg/analyzer/test/generated/strong_mode_driver_test.dart
index ec98e5b..c6047e6 100644
--- a/pkg/analyzer/test/generated/strong_mode_driver_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_driver_test.dart
@@ -6,7 +6,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'resolver_test_case.dart';
-import 'strong_mode_test.dart';
+import 'strong_mode.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
deleted file mode 100644
index 88127b5..0000000
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ /dev/null
@@ -1,4730 +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 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-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/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/task/strong/ast_properties.dart';
-import 'package:front_end/src/base/errors.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../src/dart/resolution/find_node.dart';
-import '../utils.dart';
-import 'resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(StrongModeLocalInferenceTest);
-    defineReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
-    defineReflectiveTests(StrongModeTypePropagationTest);
-  });
-}
-
-/// Strong mode static analyzer local type inference tests
-@reflectiveTest
-class StrongModeLocalInferenceTest extends ResolverTestCase {
-  TypeAssertions _assertions;
-
-  Asserter<DartType> _isDynamic;
-  Asserter<InterfaceType> _isFutureOfDynamic;
-  Asserter<InterfaceType> _isFutureOfInt;
-  Asserter<InterfaceType> _isFutureOfNull;
-  Asserter<InterfaceType> _isFutureOrOfInt;
-  Asserter<DartType> _isInt;
-  Asserter<DartType> _isNull;
-  Asserter<DartType> _isNum;
-  Asserter<DartType> _isObject;
-  Asserter<DartType> _isString;
-
-  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
-      _isFunction2Of;
-  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
-  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOrOf;
-  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
-      _isInstantiationOf;
-  AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
-  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
-      _isMapOf;
-  AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
-  AsserterBuilder<DartType, DartType> _isType;
-
-  AsserterBuilder<Element, DartType> _hasElement;
-  AsserterBuilder<DartType, DartType> _hasElementOf;
-
-  @override
-  Future<TestAnalysisResult> computeAnalysisResult(Source source) async {
-    TestAnalysisResult result = await super.computeAnalysisResult(source);
-    if (_assertions == null) {
-      _assertions = new TypeAssertions(typeProvider);
-      _isType = _assertions.isType;
-      _hasElement = _assertions.hasElement;
-      _isInstantiationOf = _assertions.isInstantiationOf;
-      _isInt = _assertions.isInt;
-      _isNull = _assertions.isNull;
-      _isNum = _assertions.isNum;
-      _isObject = _assertions.isObject;
-      _isString = _assertions.isString;
-      _isDynamic = _assertions.isDynamic;
-      _isListOf = _assertions.isListOf;
-      _isMapOf = _assertions.isMapOf;
-      _isFunction2Of = _assertions.isFunction2Of;
-      _hasElementOf = _assertions.hasElementOf;
-      _isFutureOf = _isInstantiationOf(_hasElementOf(typeProvider.futureType));
-      _isFutureOrOf =
-          _isInstantiationOf(_hasElementOf(typeProvider.futureOrType));
-      _isFutureOfDynamic = _isFutureOf([_isDynamic]);
-      _isFutureOfInt = _isFutureOf([_isInt]);
-      _isFutureOfNull = _isFutureOf([_isNull]);
-      _isFutureOrOfInt = _isFutureOrOf([_isInt]);
-      _isStreamOf = _isInstantiationOf(_hasElementOf(typeProvider.streamType));
-    }
-    return result;
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    resetWith(options: options);
-  }
-
-  test_async_method_propagation() async {
-    String code = r'''
-      import "dart:async";
-      class A {
-        Future f0() => new Future.value(3);
-        Future f1() async => new Future.value(3);
-        Future f2() async => await new Future.value(3);
-
-        Future<int> f3() => new Future.value(3);
-        Future<int> f4() async => new Future.value(3);
-        Future<int> f5() async => await new Future.value(3);
-
-        Future g0() { return new Future.value(3); }
-        Future g1() async { return new Future.value(3); }
-        Future g2() async { return await new Future.value(3); }
-
-        Future<int> g3() { return new Future.value(3); }
-        Future<int> g4() async { return new Future.value(3); }
-        Future<int> g5() async { return await new Future.value(3); }
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    void check(String name, Asserter<InterfaceType> typeTest) {
-      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
-      FunctionBody body = test.body;
-      Expression returnExp;
-      if (body is ExpressionFunctionBody) {
-        returnExp = body.expression;
-      } else {
-        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
-        returnExp = stmt.expression;
-      }
-      DartType type = returnExp.staticType;
-      if (returnExp is AwaitExpression) {
-        type = returnExp.expression.staticType;
-      }
-      typeTest(type);
-    }
-
-    check("f0", _isFutureOfDynamic);
-    check("f1", _isFutureOfDynamic);
-    check("f2", _isFutureOfDynamic);
-
-    check("f3", _isFutureOfInt);
-    check("f4", _isFutureOfInt);
-    check("f5", _isFutureOfInt);
-
-    check("g0", _isFutureOfDynamic);
-    check("g1", _isFutureOfDynamic);
-    check("g2", _isFutureOfDynamic);
-
-    check("g3", _isFutureOfInt);
-    check("g4", _isFutureOfInt);
-    check("g5", _isFutureOfInt);
-  }
-
-  test_async_propagation() async {
-    String code = r'''
-      import "dart:async";
-
-      Future f0() => new Future.value(3);
-      Future f1() async => new Future.value(3);
-      Future f2() async => await new Future.value(3);
-
-      Future<int> f3() => new Future.value(3);
-      Future<int> f4() async => new Future.value(3);
-      Future<int> f5() async => await new Future.value(3);
-
-      Future g0() { return new Future.value(3); }
-      Future g1() async { return new Future.value(3); }
-      Future g2() async { return await new Future.value(3); }
-
-      Future<int> g3() { return new Future.value(3); }
-      Future<int> g4() async { return new Future.value(3); }
-      Future<int> g5() async { return await new Future.value(3); }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    void check(String name, Asserter<InterfaceType> typeTest) {
-      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
-      FunctionBody body = test.functionExpression.body;
-      Expression returnExp;
-      if (body is ExpressionFunctionBody) {
-        returnExp = body.expression;
-      } else {
-        ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
-        returnExp = stmt.expression;
-      }
-      DartType type = returnExp.staticType;
-      if (returnExp is AwaitExpression) {
-        type = returnExp.expression.staticType;
-      }
-      typeTest(type);
-    }
-
-    check("f0", _isFutureOfDynamic);
-    check("f1", _isFutureOfDynamic);
-    check("f2", _isFutureOfDynamic);
-
-    check("f3", _isFutureOfInt);
-    check("f4", _isFutureOfInt);
-    check("f5", _isFutureOfInt);
-
-    check("g0", _isFutureOfDynamic);
-    check("g1", _isFutureOfDynamic);
-    check("g2", _isFutureOfDynamic);
-
-    check("g3", _isFutureOfInt);
-    check("g4", _isFutureOfInt);
-    check("g5", _isFutureOfInt);
-  }
-
-  test_async_star_method_propagation() async {
-    String code = r'''
-      import "dart:async";
-      class A {
-        Stream g0() async* { yield []; }
-        Stream g1() async* { yield* new Stream(); }
-
-        Stream<List<int>> g2() async* { yield []; }
-        Stream<List<int>> g3() async* { yield* new Stream(); }
-      }
-    ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    void check(String name, Asserter<InterfaceType> typeTest) {
-      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
-      BlockFunctionBody body = test.body;
-      YieldStatement stmt = body.block.statements[0];
-      Expression exp = stmt.expression;
-      typeTest(exp.staticType);
-    }
-
-    check("g0", _isListOf(_isDynamic));
-    check("g1", _isStreamOf([_isDynamic]));
-
-    check("g2", _isListOf(_isInt));
-    check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
-  }
-
-  test_async_star_propagation() async {
-    String code = r'''
-      import "dart:async";
-
-      Stream g0() async* { yield []; }
-      Stream g1() async* { yield* new Stream(); }
-
-      Stream<List<int>> g2() async* { yield []; }
-      Stream<List<int>> g3() async* { yield* new Stream(); }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    void check(String name, Asserter<InterfaceType> typeTest) {
-      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
-      BlockFunctionBody body = test.functionExpression.body;
-      YieldStatement stmt = body.block.statements[0];
-      Expression exp = stmt.expression;
-      typeTest(exp.staticType);
-    }
-
-    check("g0", _isListOf(_isDynamic));
-    check("g1", _isStreamOf([_isDynamic]));
-
-    check("g2", _isListOf(_isInt));
-    check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
-  }
-
-  test_cascadeExpression() async {
-    String code = r'''
-      class A<T> {
-        List<T> map(T a, List<T> mapper(T x)) => mapper(a);
-      }
-
-      void main () {
-        A<int> a = new A()..map(0, (x) => [x]);
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    CascadeExpression fetch(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      CascadeExpression exp = decl.initializer;
-      return exp;
-    }
-
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-
-    CascadeExpression cascade = fetch(0);
-    _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
-    MethodInvocation invoke = cascade.cascadeSections[0];
-    FunctionExpression function = invoke.argumentList.arguments[1];
-    ExecutableElement f0 = function.declaredElement;
-    _isListOf(_isInt)(f0.type.returnType);
-    expect(f0.type.normalParameterTypes[0], typeProvider.intType);
-  }
-
-  test_constrainedByBounds1() async {
-    // Test that upwards inference with two type variables correctly
-    // propogates from the constrained variable to the unconstrained
-    // variable if they are ordered left to right.
-    String code = r'''
-    T f<S, T extends S>(S x) => null;
-    void test() { var x = f(3); }
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
-    VariableDeclaration decl = stmt.variables.variables[0];
-    Expression call = decl.initializer;
-    _isInt(call.staticType);
-  }
-
-  test_constrainedByBounds2() async {
-    // Test that upwards inference with two type variables does
-    // propogate from the constrained variable to the unconstrained
-    // variable if they are ordered right to left.
-    String code = r'''
-    T f<T extends S, S>(S x) => null;
-    void test() { var x = f(3); }
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
-    VariableDeclaration decl = stmt.variables.variables[0];
-    Expression call = decl.initializer;
-    _isInt(call.staticType);
-  }
-
-  test_constrainedByBounds3() async {
-    Source source = addSource(r'''
-      T f<T extends S, S extends int>(S x) => null;
-      void test() { var x = f(3); }
-   ''');
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
-    VariableDeclaration decl = stmt.variables.variables[0];
-    Expression call = decl.initializer;
-    _isInt(call.staticType);
-  }
-
-  test_constrainedByBounds4() async {
-    // Test that upwards inference with two type variables correctly
-    // propogates from the constrained variable to the unconstrained
-    // variable if they are ordered left to right, when the variable
-    // appears co and contra variantly
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    T f<S, T extends Func1<S, S>>(S x) => null;
-    void test() { var x = f(3)(4); }
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
-    VariableDeclaration decl = stmt.variables.variables[0];
-    Expression call = decl.initializer;
-    _isInt(call.staticType);
-  }
-
-  test_constrainedByBounds5() async {
-    // Test that upwards inference with two type variables does not
-    // propogate from the constrained variable to the unconstrained
-    // variable if they are ordered right to left, when the variable
-    // appears co and contra variantly, and that an error is issued
-    // for the non-matching bound.
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    T f<T extends Func1<S, S>, S>(S x) => null;
-    void test() { var x = f(3)(null); }
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclarationStatement stmt = statements[0];
-    VariableDeclaration decl = stmt.variables.variables[0];
-    Expression call = decl.initializer;
-    _isDynamic(call.staticType);
-  }
-
-  test_constructorInitializer_propagation() async {
-    String code = r'''
-      class A {
-        List<String> x;
-        A() : this.x = [];
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    ConstructorDeclaration constructor =
-        AstFinder.getConstructorInClass(unit, "A", null);
-    ConstructorFieldInitializer assignment = constructor.initializers[0];
-    Expression exp = assignment.expression;
-    _isListOf(_isString)(exp.staticType);
-  }
-
-  test_covarianceChecks() async {
-    var source = addSource(r'''
-class C<T> {
-  add(T t) {}
-  forEach(void f(T t)) {}
-}
-class D extends C<int> {
-  add(int t) {}
-  forEach(void f(int t)) {}
-}
-class E extends C<int> {
-  add(Object t) {}
-  forEach(void f(Null t)) {}
-}
-''');
-    var unit = (await computeAnalysisResult(source)).unit;
-    assertNoErrors(source);
-    var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
-    var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
-    expect(covariantC.toList(), [cAdd.declaredElement.parameters[0]]);
-
-    var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
-    var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
-    expect(covariantD.toList(), [dAdd.declaredElement.parameters[0]]);
-
-    var covariantE = getClassCovariantParameters(AstFinder.getClass(unit, "E"));
-    expect(covariantE.toList(), []);
-  }
-
-  test_covarianceChecks2() async {
-    var content = r'''
-class View<T1> {
-  View<T1> create() => this;
-}
-
-class Bar<T2> extends View<Bar<T2>> {}
-
-main() {
-  var b = new Bar<int>();
-  b.create();
-}
-''';
-    var source = addSource(content);
-    var unit = (await computeAnalysisResult(source)).unit;
-    assertNoErrors(source);
-
-    var findNode = FindNode(content, unit);
-    expect(getImplicitCast(findNode.methodInvocation('b.create')), isNull);
-  }
-
-  test_covarianceChecks_genericMethods() async {
-    var source = addSource(r'''
-class C<T> {
-  add<S>(T t) {}
-  forEach<S>(S f(T t)) {}
-}
-class D extends C<int> {
-  add<S>(int t) {}
-  forEach<S>(S f(int t)) {}
-}
-class E extends C<int> {
-  add<S>(Object t) {}
-  forEach<S>(S f(Null t)) {}
-}
-''');
-    var unit = (await computeAnalysisResult(source)).unit;
-    assertNoErrors(source);
-
-    var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
-    var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
-    expect(covariantC.toList(), [cAdd.declaredElement.parameters[0]]);
-
-    var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
-    var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
-    expect(covariantD.toList(), [dAdd.declaredElement.parameters[0]]);
-
-    var covariantE = getClassCovariantParameters(AstFinder.getClass(unit, "E"));
-    expect(covariantE.toList(), []);
-  }
-
-  test_covarianceChecks_returnFunction() async {
-    var source = addSource(r'''
-typedef F<T>(T t);
-typedef T R<T>();
-class C<T> {
-  F<T> f;
-
-  C();
-  factory C.fact() => new C<Null>();
-
-  F<T> get g => null;
-  F<T> m1() => null;
-  R<F<T>> m2() => null;
-
-  casts(C<T> other, T t) {
-    other.f;
-    other.g(t);
-    other.m1();
-    other.m2;
-
-    new C<T>.fact().f(t);
-    new C<int>.fact().g;
-    new C<int>.fact().m1;
-    new C<T>.fact().m2();
-
-    new C<Object>.fact().f(42);
-    new C<Object>.fact().g;
-    new C<Object>.fact().m1;
-    new C<Object>.fact().m2();
-
-    new C.fact().f(42);
-    new C.fact().g;
-    new C.fact().m1;
-    new C.fact().m2();
-  }
-
-  noCasts(T t) {
-    f;
-    g;
-    m1();
-    m2();
-
-    f(t);
-    g(t);
-    (f)(t);
-    (g)(t);
-    m1;
-    m2;
-
-    this.f;
-    this.g;
-    this.m1();
-    this.m2();
-    this.m1;
-    this.m2;
-    (this.m1)();
-    (this.m2)();
-    this.f(t);
-    this.g(t);
-    (this.f)(t);
-    (this.g)(t);
-
-    new C<int>().f;
-    new C<T>().g;
-    new C<int>().m1();
-    new C().m2();
-
-    new D().f;
-    new D().g;
-    new D().m1();
-    new D().m2();
-  }
-}
-class D extends C<num> {
-  noCasts(t) {
-    f;
-    this.g;
-    this.m1();
-    m2;
-
-    super.f;
-    super.g;
-    super.m1;
-    super.m2();
-  }
-}
-
-D d;
-C<Object> c;
-C cD;
-C<Null> cN;
-F<Object> f;
-F<Null> fN;
-R<F<Object>> rf;
-R<F<Null>> rfN;
-R<R<F<Object>>> rrf;
-R<R<F<Null>>> rrfN;
-Object obj;
-F<int> fi;
-R<F<int>> rfi;
-R<R<F<int>>> rrfi;
-
-casts() {
-  c.f;
-  c.g;
-  c.m1;
-  c.m1();
-  c.m2();
-
-  fN = c.f;
-  fN = c.g;
-  rfN = c.m1;
-  rrfN = c.m2;
-  fN = c.m1();
-  rfN = c.m2();
-
-  f = c.f;
-  f = c.g;
-  rf = c.m1;
-  rrf = c.m2;
-  f = c.m1();
-  rf = c.m2();
-  c.m2()();
-
-  c.f(obj);
-  c.g(obj);
-  (c.f)(obj);
-  (c.g)(obj);
-  (c.m1)();
-  c.m1()(obj);
-  (c.m2)();
-
-  cD.f;
-  cD.g;
-  cD.m1;
-  cD.m1();
-  cD.m2();
-}
-
-noCasts() {
-  fi = d.f;
-  fi = d.g;
-  rfi = d.m1;
-  fi = d.m1();
-  rrfi = d.m2;
-  rfi = d.m2();
-  d.f(42);
-  d.g(42);
-  (d.f)(42);
-  (d.g)(42);
-  d.m1()(42);
-  d.m2()()(42);
-
-  cN.f;
-  cN.g;
-  cN.m1;
-  cN.m1();
-  cN.m2();
-}
-''');
-    var unit = (await computeAnalysisResult(source)).unit;
-    assertNoErrors(source);
-
-    void expectCast(Statement statement, bool hasCast) {
-      var value = (statement as ExpressionStatement).expression;
-      if (value is AssignmentExpression) {
-        value = (value as AssignmentExpression).rightHandSide;
-      }
-      while (value is FunctionExpressionInvocation) {
-        value = (value as FunctionExpressionInvocation).function;
-      }
-      while (value is ParenthesizedExpression) {
-        value = (value as ParenthesizedExpression).expression;
-      }
-      var isCallingGetter =
-          value is MethodInvocation && !value.methodName.name.startsWith('m');
-      var cast = isCallingGetter
-          ? getImplicitOperationCast(value)
-          : getImplicitCast(value);
-      var castKind = isCallingGetter ? 'special cast' : 'cast';
-      expect(cast, hasCast ? isNotNull : isNull,
-          reason: '`$statement` should ' +
-              (hasCast ? '' : 'not ') +
-              'have a $castKind on `$value`.');
-    }
-
-    for (var s in AstFinder.getStatementsInMethod(unit, 'C', 'noCasts')) {
-      expectCast(s, false);
-    }
-    for (var s in AstFinder.getStatementsInMethod(unit, 'C', 'casts')) {
-      expectCast(s, true);
-    }
-    for (var s in AstFinder.getStatementsInMethod(unit, 'D', 'noCasts')) {
-      expectCast(s, false);
-    }
-    for (var s in AstFinder.getStatementsInTopLevelFunction(unit, 'noCasts')) {
-      expectCast(s, false);
-    }
-    for (var s in AstFinder.getStatementsInTopLevelFunction(unit, 'casts')) {
-      expectCast(s, true);
-    }
-  }
-
-  test_covarianceChecks_superclass() async {
-    var source = addSource(r'''
-class C<T> {
-  add(T t) {}
-  forEach(void f(T t)) {}
-}
-class D {
-  add(int t) {}
-  forEach(void f(int t)) {}
-}
-class E extends D implements C<int> {}
-''');
-    var unit = (await computeAnalysisResult(source)).unit;
-    assertNoErrors(source);
-    var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
-    var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
-    expect(covariantC.toList(), [cAdd.declaredElement.parameters[0]]);
-
-    var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
-    var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
-    expect(covariantD, null);
-
-    var classE = AstFinder.getClass(unit, "E");
-    var covariantE = getClassCovariantParameters(classE);
-    var superCovariantE = getSuperclassCovariantParameters(classE);
-    expect(covariantE.toList(), []);
-    expect(superCovariantE.toList(), [dAdd.declaredElement.parameters[0]]);
-  }
-
-  test_factoryConstructor_propagation() async {
-    String code = r'''
-      class A<T> {
-        factory A() { return new B(); }
-      }
-      class B<S> extends A<S> {}
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    ConstructorDeclaration constructor =
-        AstFinder.getConstructorInClass(unit, "A", null);
-    BlockFunctionBody body = constructor.body;
-    ReturnStatement stmt = body.block.statements[0];
-    InstanceCreationExpression exp = stmt.expression;
-    ClassElement elementB = AstFinder.getClass(unit, "B").declaredElement;
-    ClassElement elementA = AstFinder.getClass(unit, "A").declaredElement;
-    expect(resolutionMap.typeForTypeName(exp.constructorName.type).element,
-        elementB);
-    _isInstantiationOf(_hasElement(elementB))(
-        [_isType(elementA.typeParameters[0].type)])(exp.staticType);
-  }
-
-  test_fieldDeclaration_propagation() async {
-    String code = r'''
-      class A {
-        List<String> f0 = ["hello"];
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
-
-    _isListOf(_isString)(field.initializer.staticType);
-  }
-
-  test_functionDeclaration_body_propagation() async {
-    String code = r'''
-      typedef T Function2<S, T>(S x);
-
-      List<int> test1() => [];
-
-      Function2<int, int> test2 (int x) {
-        Function2<String, int> inner() {
-          return (x) => x.length;
-        }
-        return (x) => x;
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
-    FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
-    ExpressionFunctionBody body = test1.functionExpression.body;
-    assertListOfInt(body.expression.staticType);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test2");
-
-    FunctionDeclaration inner =
-        (statements[0] as FunctionDeclarationStatement).functionDeclaration;
-    BlockFunctionBody body0 = inner.functionExpression.body;
-    ReturnStatement return0 = body0.block.statements[0];
-    Expression anon0 = return0.expression;
-    FunctionType type0 = anon0.staticType;
-    expect(type0.returnType, typeProvider.intType);
-    expect(type0.normalParameterTypes[0], typeProvider.stringType);
-
-    FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
-    FunctionType type1 =
-        resolutionMap.elementDeclaredByFunctionExpression(anon1).type;
-    expect(type1.returnType, typeProvider.intType);
-    expect(type1.normalParameterTypes[0], typeProvider.intType);
-  }
-
-  test_functionLiteral_assignment_typedArguments() async {
-    String code = r'''
-      typedef T Function2<S, T>(S x);
-
-      void main () {
-        Function2<int, String> l0 = (int x) => null;
-        Function2<int, String> l1 = (int x) => "hello";
-        Function2<int, String> l2 = (String x) => "hello";
-        Function2<int, String> l3 = (int x) => 3;
-        Function2<int, String> l4 = (int x) {return 3;};
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isString, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_assignment_unTypedArguments() async {
-    String code = r'''
-      typedef T Function2<S, T>(S x);
-
-      void main () {
-        Function2<int, String> l0 = (x) => null;
-        Function2<int, String> l1 = (x) => "hello";
-        Function2<int, String> l2 = (x) => "hello";
-        Function2<int, String> l3 = (x) => 3;
-        Function2<int, String> l4 = (x) {return 3;};
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isInt, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_body_propagation() async {
-    String code = r'''
-      typedef T Function2<S, T>(S x);
-
-      void main () {
-        Function2<int, List<String>> l0 = (int x) => ["hello"];
-        Function2<int, List<String>> l1 = (String x) => ["hello"];
-        Function2<int, List<String>> l2 = (int x) => [3];
-        Function2<int, List<String>> l3 = (int x) {return [3];};
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    Expression functionReturnValue(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
-      FunctionBody body = exp.body;
-      if (body is ExpressionFunctionBody) {
-        return body.expression;
-      } else {
-        Statement stmt = (body as BlockFunctionBody).block.statements[0];
-        return (stmt as ReturnStatement).expression;
-      }
-    }
-
-    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
-    assertListOfString(functionReturnValue(0).staticType);
-    assertListOfString(functionReturnValue(1).staticType);
-    assertListOfString(functionReturnValue(2).staticType);
-    assertListOfString(functionReturnValue(3).staticType);
-  }
-
-  test_functionLiteral_functionExpressionInvocation_typedArguments() async {
-    String code = r'''
-      class Mapper<F, T> {
-        T map(T mapper(F x)) => mapper(null);
-      }
-
-      void main () {
-        (new Mapper<int, String>().map)((int x) => null);
-        (new Mapper<int, String>().map)((int x) => "hello");
-        (new Mapper<int, String>().map)((String x) => "hello");
-        (new Mapper<int, String>().map)((int x) => 3);
-        (new Mapper<int, String>().map)((int x) {return 3;});
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      FunctionExpressionInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isString, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_functionExpressionInvocation_unTypedArguments() async {
-    String code = r'''
-      class Mapper<F, T> {
-        T map(T mapper(F x)) => mapper(null);
-      }
-
-      void main () {
-        (new Mapper<int, String>().map)((x) => null);
-        (new Mapper<int, String>().map)((x) => "hello");
-        (new Mapper<int, String>().map)((x) => "hello");
-        (new Mapper<int, String>().map)((x) => 3);
-        (new Mapper<int, String>().map)((x) {return 3;});
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      FunctionExpressionInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isInt, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_functionInvocation_typedArguments() async {
-    String code = r'''
-      String map(String mapper(int x)) => mapper(null);
-
-      void main () {
-        map((int x) => null);
-        map((int x) => "hello");
-        map((String x) => "hello");
-        map((int x) => 3);
-        map((int x) {return 3;});
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isString, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_functionInvocation_unTypedArguments() async {
-    String code = r'''
-      String map(String mapper(int x)) => mapper(null);
-
-      void main () {
-        map((x) => null);
-        map((x) => "hello");
-        map((x) => "hello");
-        map((x) => 3);
-        map((x) {return 3;});
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isInt, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_methodInvocation_typedArguments() async {
-    String code = r'''
-      class Mapper<F, T> {
-        T map(T mapper(F x)) => mapper(null);
-      }
-
-      void main () {
-        new Mapper<int, String>().map((int x) => null);
-        new Mapper<int, String>().map((int x) => "hello");
-        new Mapper<int, String>().map((String x) => "hello");
-        new Mapper<int, String>().map((int x) => 3);
-        new Mapper<int, String>().map((int x) {return 3;});
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isString, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_methodInvocation_unTypedArguments() async {
-    String code = r'''
-      class Mapper<F, T> {
-        T map(T mapper(F x)) => mapper(null);
-      }
-
-      void main () {
-        new Mapper<int, String>().map((x) => null);
-        new Mapper<int, String>().map((x) => "hello");
-        new Mapper<int, String>().map((x) => "hello");
-        new Mapper<int, String>().map((x) => 3);
-        new Mapper<int, String>().map((x) {return 3;});
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      ExpressionStatement stmt = statements[i];
-      MethodInvocation invk = stmt.expression;
-      FunctionExpression exp = invk.argumentList.arguments[0];
-      return resolutionMap.elementDeclaredByFunctionExpression(exp).type;
-    }
-
-    _isFunction2Of(_isInt, _isNull)(literal(0));
-    _isFunction2Of(_isInt, _isString)(literal(1));
-    _isFunction2Of(_isInt, _isString)(literal(2));
-    _isFunction2Of(_isInt, _isString)(literal(3));
-    _isFunction2Of(_isInt, _isString)(literal(4));
-  }
-
-  test_functionLiteral_unTypedArgument_propagation() async {
-    String code = r'''
-      typedef T Function2<S, T>(S x);
-
-      void main () {
-        Function2<int, int> l0 = (x) => x;
-        Function2<int, int> l1 = (x) => x+1;
-        Function2<int, String> l2 = (x) => x;
-        Function2<int, String> l3 = (x) => x.toLowerCase();
-        Function2<String, String> l4 = (x) => x.toLowerCase();
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    Expression functionReturnValue(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      FunctionExpression exp = decl.initializer;
-      FunctionBody body = exp.body;
-      if (body is ExpressionFunctionBody) {
-        return body.expression;
-      } else {
-        Statement stmt = (body as BlockFunctionBody).block.statements[0];
-        return (stmt as ReturnStatement).expression;
-      }
-    }
-
-    expect(functionReturnValue(0).staticType, typeProvider.intType);
-    expect(functionReturnValue(1).staticType, typeProvider.intType);
-    expect(functionReturnValue(2).staticType, typeProvider.intType);
-    expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
-    expect(functionReturnValue(4).staticType, typeProvider.stringType);
-  }
-
-  test_futureOr_assignFromFuture() async {
-    // Test a Future<T> can be assigned to FutureOr<T>.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    test() => mk(new Future<int>.value(42));
-    ''');
-    _isFutureOrOfInt(invoke.staticType);
-  }
-
-  test_futureOr_assignFromValue() async {
-    // Test a T can be assigned to FutureOr<T>.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(T x) => x;
-    test() => mk(42);
-    ''');
-    _isFutureOrOfInt(invoke.staticType);
-  }
-
-  test_futureOr_asyncExpressionBody() async {
-    // A FutureOr<T> can be used as the expression body for an async function
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) async => x;
-    test() => mk(42);
-    ''');
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOr_asyncReturn() async {
-    // A FutureOr<T> can be used as the return value for an async function
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) async { return x; }
-    test() => mk(42);
-    ''');
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOr_await() async {
-    // Test a FutureOr<T> can be awaited.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) async => await x;
-    test() => mk(42);
-    ''');
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOr_downwards1() async {
-    // Test that downwards inference interacts correctly with FutureOr
-    // parameters.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) => null;
-    Future<int> test() => mk(new Future<int>.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOr_downwards2() async {
-    // Test that downwards inference interacts correctly with FutureOr
-    // parameters when the downwards context is FutureOr
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) => null;
-    FutureOr<int> test() => mk(new Future<int>.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOr_downwards3() async {
-    // Test that downwards inference correctly propogates into
-    // arguments.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) => null;
-    Future<int> test() => mk(new Future.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_downwards4() async {
-    // Test that downwards inference interacts correctly with FutureOr
-    // parameters when the downwards context is FutureOr
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) => null;
-    FutureOr<int> test() => mk(new Future.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_downwards5() async {
-    // Test that downwards inference correctly pins the type when it
-    // comes from a FutureOr
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) => null;
-    FutureOr<num> test() => mk(new Future.value(42));
-    ''');
-    _isFutureOf([_isNum])(invoke.staticType);
-    _isFutureOf([_isNum])(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_downwards6() async {
-    // Test that downwards inference doesn't decompose FutureOr
-    // when instantiating type variables.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    T mk<T>(T x) => null;
-    FutureOr<int> test() => mk(new Future.value(42));
-    ''');
-    _isFutureOrOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_downwards7() async {
-    // Test that downwards inference incorporates bounds correctly
-    // when instantiating type variables.
-    MethodInvocation invoke = await _testFutureOr(r'''
-      T mk<T extends Future<int>>(T x) => null;
-      FutureOr<int> test() => mk(new Future.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_downwards8() async {
-    // Test that downwards inference incorporates bounds correctly
-    // when instantiating type variables.
-    // TODO(leafp): I think this should pass once the inference changes
-    // that jmesserly is adding are landed.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    T mk<T extends Future<Object>>(T x) => null;
-    FutureOr<int> test() => mk(new Future.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-    _isFutureOfInt(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_downwards9() async {
-    // Test that downwards inference decomposes correctly with
-    // other composite types
-    MethodInvocation invoke = await _testFutureOr(r'''
-    List<T> mk<T>(T x) => null;
-    FutureOr<List<int>> test() => mk(3);
-    ''');
-    _isListOf(_isInt)(invoke.staticType);
-    _isInt(invoke.argumentList.arguments[0].staticType);
-  }
-
-  test_futureOr_methods1() async {
-    // Test that FutureOr has the Object methods
-    MethodInvocation invoke = await _testFutureOr(r'''
-    dynamic test(FutureOr<int> x) => x.toString();
-    ''');
-    _isString(invoke.staticType);
-  }
-
-  test_futureOr_methods2() async {
-    // Test that FutureOr does not have the constituent type methods
-    MethodInvocation invoke = await _testFutureOr(r'''
-    dynamic test(FutureOr<int> x) => x.abs();
-    ''', errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
-    _isDynamic(invoke.staticType);
-  }
-
-  test_futureOr_methods3() async {
-    // Test that FutureOr does not have the Future type methods
-    MethodInvocation invoke = await _testFutureOr(r'''
-    dynamic test(FutureOr<int> x) => x.then((x) => x);
-    ''', errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
-    _isDynamic(invoke.staticType);
-  }
-
-  test_futureOr_methods4() async {
-    // Test that FutureOr<dynamic> does not have all methods
-    MethodInvocation invoke = await _testFutureOr(r'''
-    dynamic test(FutureOr<dynamic> x) => x.abs();
-    ''', errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
-    _isDynamic(invoke.staticType);
-  }
-
-  test_futureOr_no_return() async {
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    Future<int> f;
-    test() => f.then((int x) {});
-    ''');
-    _isFunction2Of(_isInt, _isNull)(
-        invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
-  }
-
-  test_futureOr_no_return_value() async {
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    Future<int> f;
-    test() => f.then((int x) {return;});
-    ''');
-    _isFunction2Of(_isInt, _isNull)(
-        invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
-  }
-
-  test_futureOr_return_null() async {
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    Future<int> f;
-    test() => f.then((int x) {return null;});
-    ''');
-    _isFunction2Of(_isInt, _isNull)(
-        invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
-  }
-
-  test_futureOr_upwards1() async {
-    // Test that upwards inference correctly prefers to instantiate type
-    // variables with the "smaller" solution when both are possible.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T>(FutureOr<T> x) => null;
-    dynamic test() => mk(new Future<int>.value(42));
-    ''');
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOr_upwards2() async {
-    // Test that upwards inference fails when the solution doesn't
-    // match the bound.
-    MethodInvocation invoke = await _testFutureOr(r'''
-    Future<T> mk<T extends Future<Object>>(FutureOr<T> x) => null;
-    dynamic test() => mk(new Future<int>.value(42));
-    ''', errors: [StrongModeCode.COULD_NOT_INFER]);
-    _isFutureOfInt(invoke.staticType);
-  }
-
-  test_futureOrNull_no_return() async {
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    Future<int> f;
-    test() => f.then<Null>((int x) {});
-    ''');
-    _isFunction2Of(_isInt, _isNull)(
-        invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
-  }
-
-  test_futureOrNull_no_return_value() async {
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    Future<int> f;
-    test() => f.then<Null>((int x) {return;});
-    ''');
-    _isFunction2Of(_isInt, _isNull)(
-        invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
-  }
-
-  test_futureOrNull_return_null() async {
-    MethodInvocation invoke = await _testFutureOr(r'''
-    FutureOr<T> mk<T>(Future<T> x) => x;
-    Future<int> f;
-    test() => f.then<Null>((int x) { return null;});
-    ''');
-    _isFunction2Of(_isInt, _isNull)(
-        invoke.argumentList.arguments[0].staticType);
-    _isFutureOfNull(invoke.staticType);
-  }
-
-  test_generic_partial() async {
-    // Test that upward and downward type inference handles partial
-    // type schemas correctly.  Downwards inference in a partial context
-    // (e.g. Map<String, ?>) should still allow upwards inference to fill
-    // in the missing information.
-    String code = r'''
-class A<T> {
-  A(T x);
-  A.fromA(A<T> a) {}
-  A.fromMap(Map<String, T> m) {}
-  A.fromList(List<T> m) {}
-  A.fromT(T t) {}
-  A.fromB(B<T, String> a) {}
-}
-
-class B<S, T> {
-  B(S s);
-}
-
-void test() {
-    var a0 = new A.fromA(new A(3));
-    var a1 = new A.fromMap({'hello' : 3});
-    var a2 = new A.fromList([3]);
-    var a3 = new A.fromT(3);
-    var a4 = new A.fromB(new B(3));
-}
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    void check(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      Expression init = decl.initializer;
-      _isInstantiationOf(_hasElement(elementA))([_isInt])(init.staticType);
-    }
-
-    for (var i = 0; i < 5; i++) check(i);
-  }
-
-  test_inferConstructor_unknownTypeLowerBound() async {
-    Source source = addSource(r'''
-        class C<T> {
-          C(void callback(List<T> a));
-        }
-        test() {
-          // downwards inference pushes List<?> and in parameter position this
-          // becomes inferred as List<Null>.
-          var c = new C((items) {});
-        }
-        ''');
-    CompilationUnit unit = (await computeAnalysisResult(source)).unit;
-    assertNoErrors(source);
-    verify([source]);
-    DartType cType = findLocalVariable(unit, 'c').type;
-    Element elementC = AstFinder.getClass(unit, "C").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType);
-  }
-
-  test_inference_error_arguments() async {
-    Source source = addSource(r'''
-typedef R F<T, R>(T t);
-
-F<T, T> g<T>(F<T, T> f) => (x) => f(f(x));
-
-test() {
-  var h = g((int x) => 42.0);
-}
- ''');
-    await computeAnalysisResult(source);
-    _expectInferenceError(source, [
-      StrongModeCode.COULD_NOT_INFER,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ], r'''
-Couldn't infer type parameter 'T'.
-
-Tried to infer 'double' for 'T' which doesn't work:
-  Parameter 'f' declared as     '(T) → T'
-                but argument is '(int) → double'.
-
-Consider passing explicit type argument(s) to the generic.
-
-''');
-  }
-
-  test_inference_error_arguments2() async {
-    Source source = addSource(r'''
-typedef R F<T, R>(T t);
-
-F<T, T> g<T>(F<T, T> a, F<T, T> b) => (x) => a(b(x));
-
-test() {
-  var h = g((int x) => 42.0, (double x) => 42);
-}
- ''');
-    await computeAnalysisResult(source);
-    _expectInferenceError(source, [
-      StrongModeCode.COULD_NOT_INFER,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ], r'''
-Couldn't infer type parameter 'T'.
-
-Tried to infer 'num' for 'T' which doesn't work:
-  Parameter 'a' declared as     '(T) → T'
-                but argument is '(int) → double'.
-  Parameter 'b' declared as     '(T) → T'
-                but argument is '(double) → int'.
-
-Consider passing explicit type argument(s) to the generic.
-
-''');
-  }
-
-  test_inference_error_extendsFromReturn() async {
-    // This is not an inference error because we successfully infer Null.
-    Source source = addSource(r'''
-T max<T extends num>(T x, T y) => x;
-
-test() {
-  String hello = max(1, 2);
-}
- ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertErrors(source, [
-      StrongModeCode.INVALID_CAST_LITERAL,
-      StrongModeCode.INVALID_CAST_LITERAL
-    ]);
-    var unit = analysisResult.unit;
-    var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0]
-            as VariableDeclarationStatement)
-        .variables
-        .variables[0];
-    var call = h.initializer as MethodInvocation;
-    expect(call.staticInvokeType.toString(), '(Null, Null) → Null');
-  }
-
-  test_inference_error_extendsFromReturn2() async {
-    Source source = addSource(r'''
-typedef R F<T, R>(T t);
-F<T, T> g<T extends num>() => (y) => y;
-
-test() {
-  F<String, String> hello = g();
-}
- ''');
-    await computeAnalysisResult(source);
-    _expectInferenceError(source, [
-      StrongModeCode.COULD_NOT_INFER,
-    ], r'''
-Couldn't infer type parameter 'T'.
-
-Tried to infer 'String' for 'T' which doesn't work:
-  Type parameter 'T' declared to extend 'num'.
-The type 'String' was inferred from:
-  Return type declared as '(T) → T'
-              used where  '(String) → String' is required.
-
-Consider passing explicit type argument(s) to the generic.
-
-''');
-  }
-
-  test_inference_error_genericFunction() async {
-    Source source = addSource(r'''
-T max<T extends num>(T x, T y) => x < y ? y : x;
-abstract class Iterable<T> {
-  T get first;
-  S fold<S>(S s, S f(S s, T t));
-}
-test(Iterable values) {
-  num n = values.fold(values.first as num, max);
-}
- ''');
-    await computeAnalysisResult(source);
-    _expectInferenceError(source, [
-      StrongModeCode.COULD_NOT_INFER,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ], r'''
-Couldn't infer type parameter 'T'.
-
-Tried to infer 'dynamic' for 'T' which doesn't work:
-  Function type declared as '<T extends num>(T, T) → T'
-                used where  '(num, dynamic) → num' is required.
-
-Consider passing explicit type argument(s) to the generic.
-
-''');
-  }
-
-  test_inference_error_returnContext() async {
-    Source source = addSource(r'''
-typedef R F<T, R>(T t);
-
-F<T, T> g<T>(T t) => (x) => t;
-
-test() {
-  F<num, int> h = g(42);
-}
- ''');
-    await computeAnalysisResult(source);
-    _expectInferenceError(source, [StrongModeCode.COULD_NOT_INFER], r'''
-Couldn't infer type parameter 'T'.
-
-Tried to infer 'num' for 'T' which doesn't work:
-  Return type declared as '(T) → T'
-              used where  '(num) → int' is required.
-
-Consider passing explicit type argument(s) to the generic.
-
-''');
-  }
-
-  test_inference_hints() async {
-    Source source = addSource(r'''
-      void main () {
-        var x = 3;
-        List<int> l0 = [];
-     }
-   ''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_inference_simplePolymorphicRecursion_function() async {
-    // Regression test for https://github.com/dart-lang/sdk/issues/30980
-    // Check that inference works properly when inferring the type argument
-    // for a self-recursive call with a function type
-    var source = addSource(r'''
-void _mergeSort<T>(T Function(T) list, int compare(T a, T b), T Function(T) target) {
-  _mergeSort(list, compare, target);
-  _mergeSort(list, compare, list);
-  _mergeSort(target, compare, target);
-  _mergeSort(target, compare, list);
-}
-    ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var unit = analysisResult.unit;
-    var body = (AstFinder.getTopLevelFunction(unit, '_mergeSort')
-        .functionExpression
-        .body as BlockFunctionBody);
-    var stmts = body.block.statements;
-    for (ExpressionStatement stmt in stmts) {
-      MethodInvocation invoke = stmt.expression;
-      ParameterizedType fType = invoke.staticInvokeType;
-      expect(fType.typeArguments[0].toString(), 'T');
-    }
-  }
-
-  test_inference_simplePolymorphicRecursion_interface() async {
-    // Regression test for https://github.com/dart-lang/sdk/issues/30980
-    // Check that inference works properly when inferring the type argument
-    // for a self-recursive call with an interface type
-    var source = addSource(r'''
-void _mergeSort<T>(List<T> list, int compare(T a, T b), List<T> target) {
-  _mergeSort(list, compare, target);
-  _mergeSort(list, compare, list);
-  _mergeSort(target, compare, target);
-  _mergeSort(target, compare, list);
-}
-    ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var unit = analysisResult.unit;
-    var body = (AstFinder.getTopLevelFunction(unit, '_mergeSort')
-        .functionExpression
-        .body as BlockFunctionBody);
-    var stmts = body.block.statements;
-    for (ExpressionStatement stmt in stmts) {
-      MethodInvocation invoke = stmt.expression;
-      ParameterizedType fType = invoke.staticInvokeType;
-      expect(fType.typeArguments[0].toString(), 'T');
-    }
-  }
-
-  test_inference_simplePolymorphicRecursion_simple() async {
-    // Regression test for https://github.com/dart-lang/sdk/issues/30980
-    // Check that inference works properly when inferring the type argument
-    // for a self-recursive call with a simple type parameter
-    var source = addSource(r'''
-void _mergeSort<T>(T list, int compare(T a, T b), T target) {
-  _mergeSort(list, compare, target);
-  _mergeSort(list, compare, list);
-  _mergeSort(target, compare, target);
-  _mergeSort(target, compare, list);
-}
-    ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var unit = analysisResult.unit;
-    var body = (AstFinder.getTopLevelFunction(unit, '_mergeSort')
-        .functionExpression
-        .body as BlockFunctionBody);
-    var stmts = body.block.statements;
-    for (ExpressionStatement stmt in stmts) {
-      MethodInvocation invoke = stmt.expression;
-      ParameterizedType fType = invoke.staticInvokeType;
-      expect(fType.typeArguments[0].toString(), 'T');
-    }
-  }
-
-  test_inferGenericInstantiation() async {
-    // Verify that we don't infer '?` when we instantiate a generic function.
-    var source = addSource(r'''
-T f<T>(T x(T t)) => x(null);
-S g<S>(S s) => s;
-test() {
- var h = f(g);
-}
-    ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    var unit = analysisResult.unit;
-    var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0]
-            as VariableDeclarationStatement)
-        .variables
-        .variables[0];
-    _isDynamic(h.declaredElement.type);
-    var fCall = h.initializer as MethodInvocation;
-    expect(
-        fCall.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
-    var g = fCall.argumentList.arguments[0];
-    expect(g.staticType.toString(), '(dynamic) → dynamic');
-  }
-
-  test_inferGenericInstantiation2() async {
-    // Verify the behavior when we cannot infer an instantiation due to invalid
-    // constraints from an outer generic method.
-    var source = addSource(r'''
-T max<T extends num>(T x, T y) => x < y ? y : x;
-abstract class Iterable<T> {
-  T get first;
-  S fold<S>(S s, S f(S s, T t));
-}
-num test(Iterable values) => values.fold(values.first as num, max);
-    ''');
-    var analysisResult = await computeAnalysisResult(source);
-    assertErrors(source, [
-      StrongModeCode.COULD_NOT_INFER,
-      StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
-    ]);
-    verify([source]);
-    var unit = analysisResult.unit;
-    var fold = (AstFinder.getTopLevelFunction(unit, 'test')
-            .functionExpression
-            .body as ExpressionFunctionBody)
-        .expression as MethodInvocation;
-    expect(
-        fold.staticInvokeType.toString(), '(num, (num, dynamic) → num) → num');
-    var max = fold.argumentList.arguments[1];
-    // TODO(jmesserly): arguably (num, num) → num is better here.
-    expect(max.staticType.toString(), '(dynamic, dynamic) → dynamic');
-  }
-
-  test_inferredFieldDeclaration_propagation() async {
-    // Regression test for https://github.com/dart-lang/sdk/issues/25546
-    String code = r'''
-      abstract class A {
-        Map<int, List<int>> get map;
-      }
-      class B extends A {
-        var map = { 42: [] };
-      }
-      class C extends A {
-        get map => { 43: [] };
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-    Asserter<InterfaceType> assertMapOfIntToListOfInt =
-        _isMapOf(_isInt, (DartType type) => assertListOfInt(type));
-
-    VariableDeclaration mapB = AstFinder.getFieldInClass(unit, "B", "map");
-    MethodDeclaration mapC = AstFinder.getMethodInClass(unit, "C", "map");
-    assertMapOfIntToListOfInt(
-        resolutionMap.elementDeclaredByVariableDeclaration(mapB).type);
-    assertMapOfIntToListOfInt(
-        resolutionMap.elementDeclaredByMethodDeclaration(mapC).returnType);
-
-    MapLiteral mapLiteralB = mapB.initializer;
-    MapLiteral mapLiteralC = (mapC.body as ExpressionFunctionBody).expression;
-    assertMapOfIntToListOfInt(mapLiteralB.staticType);
-    assertMapOfIntToListOfInt(mapLiteralC.staticType);
-
-    ListLiteral listLiteralB = mapLiteralB.entries[0].value;
-    ListLiteral listLiteralC = mapLiteralC.entries[0].value;
-    assertListOfInt(listLiteralB.staticType);
-    assertListOfInt(listLiteralC.staticType);
-  }
-
-  test_instanceCreation() async {
-    String code = r'''
-      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 test0() {
-        A<int, String> a0 = new A(3, "hello");
-        A<int, String> a1 = new A.named(3, "hello");
-        A<int, String> a2 = new A<int, String>(3, "hello");
-        A<int, String> a3 = new A<int, String>.named(3, "hello");
-        A<int, String> a4 = new A<int, dynamic>(3, "hello");
-        A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
-      }
-      void test1()  {
-        A<int, String> a0 = new A("hello", 3);
-        A<int, String> a1 = new A.named("hello", 3);
-      }
-      void test2() {
-        A<int, String> a0 = new B("hello", 3);
-        A<int, String> a1 = new B.named("hello", 3);
-        A<int, String> a2 = new B<String, int>("hello", 3);
-        A<int, String> a3 = new B<String, int>.named("hello", 3);
-        A<int, String> a4 = new B<String, dynamic>("hello", 3);
-        A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
-      }
-      void test3() {
-        A<int, String> a0 = new B(3, "hello");
-        A<int, String> a1 = new B.named(3, "hello");
-      }
-      void test4() {
-        A<int, int> a0 = new C(3);
-        A<int, int> a1 = new C.named(3);
-        A<int, int> a2 = new C<int>(3);
-        A<int, int> a3 = new C<int>.named(3);
-        A<int, int> a4 = new C<dynamic>(3);
-        A<int, int> a5 = new C<dynamic>.named(3);
-      }
-      void test5() {
-        A<int, int> a0 = new C("hello");
-        A<int, int> a1 = new C.named("hello");
-      }
-      void test6()  {
-        A<int, String> a0 = new D("hello");
-        A<int, String> a1 = new D.named("hello");
-        A<int, String> a2 = new D<int, String>("hello");
-        A<int, String> a3 = new D<String, String>.named("hello");
-        A<int, String> a4 = new D<num, dynamic>("hello");
-        A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
-      }
-      void test7() {
-        A<int, String> a0 = new D(3);
-        A<int, String> a1 = new D.named(3);
-      }
-      void test8() {
-        A<C<int>, String> a0 = new E("hello");
-      }
-      void test9() { // Check named and optional arguments
-        A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
-        A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
-        A<int, String> a2 = new F.named(3, "hello", 3, "hello");
-        A<int, String> a3 = new F.named(3, "hello");
-        A<int, String> a4 = new F.named(3, "hello", "hello", 3);
-        A<int, String> a5 = new F.named(3, "hello", "hello");
-      }''';
-    CompilationUnit unit = await resolveSource(code);
-
-    Expression rhs(VariableDeclarationStatement stmt) {
-      VariableDeclaration decl = stmt.variables.variables[0];
-      Expression exp = decl.initializer;
-      return exp;
-    }
-
-    void hasType(Asserter<DartType> assertion, Expression exp) =>
-        assertion(exp.staticType);
-
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
-    Element elementC = AstFinder.getClass(unit, "C").declaredElement;
-    Element elementD = AstFinder.getClass(unit, "D").declaredElement;
-    Element elementE = AstFinder.getClass(unit, "E").declaredElement;
-    Element elementF = AstFinder.getClass(unit, "F").declaredElement;
-
-    AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
-        _isInstantiationOf(_hasElement(elementA));
-    AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
-        _isInstantiationOf(_hasElement(elementB));
-    AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
-        _isInstantiationOf(_hasElement(elementC));
-    AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
-        _isInstantiationOf(_hasElement(elementD));
-    AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
-        _isInstantiationOf(_hasElement(elementE));
-    AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
-        _isInstantiationOf(_hasElement(elementF));
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test0");
-
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
-      hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
-      hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test1");
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
-      hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test2");
-      hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
-      hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
-      hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
-      hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
-      hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
-      hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test3");
-      hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
-      hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test4");
-      hasType(assertCOf([_isInt]), rhs(statements[0]));
-      hasType(assertCOf([_isInt]), rhs(statements[1]));
-      hasType(assertCOf([_isInt]), rhs(statements[2]));
-      hasType(assertCOf([_isInt]), rhs(statements[3]));
-      hasType(assertCOf([_isDynamic]), rhs(statements[4]));
-      hasType(assertCOf([_isDynamic]), rhs(statements[5]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test5");
-      hasType(assertCOf([_isInt]), rhs(statements[0]));
-      hasType(assertCOf([_isInt]), rhs(statements[1]));
-    }
-
-    {
-      // The first type parameter is not constrained by the
-      // context.  We could choose a tighter type, but currently
-      // we just use dynamic.
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test6");
-      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
-      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
-      hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
-      hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
-      hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
-      hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test7");
-      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
-      hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test8");
-      hasType(assertEOf([_isInt, _isString]), rhs(statements[0]));
-    }
-
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInTopLevelFunction(unit, "test9");
-      hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
-      hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
-      hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
-      hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
-      hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
-      hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
-    }
-  }
-
-  test_listLiteral_nested() async {
-    String code = r'''
-      void main () {
-        List<List<int>> l0 = [[]];
-        Iterable<List<int>> l1 = [[3]];
-        Iterable<List<int>> l2 = [[3], [4]];
-        List<List<int>> l3 = [["hello", 3], []];
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    ListLiteral literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
-      return exp;
-    }
-
-    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-    Asserter<InterfaceType> assertListOfListOfInt =
-        _isListOf((DartType type) => assertListOfInt(type));
-
-    assertListOfListOfInt(literal(0).staticType);
-    assertListOfListOfInt(literal(1).staticType);
-    assertListOfListOfInt(literal(2).staticType);
-    assertListOfListOfInt(literal(3).staticType);
-
-    assertListOfInt(literal(1).elements[0].staticType);
-    assertListOfInt(literal(2).elements[0].staticType);
-    assertListOfInt(literal(3).elements[0].staticType);
-  }
-
-  test_listLiteral_simple() async {
-    String code = r'''
-      void main () {
-        List<int> l0 = [];
-        List<int> l1 = [3];
-        List<int> l2 = ["hello"];
-        List<int> l3 = ["hello", 3];
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
-      return exp.staticType;
-    }
-
-    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
-    assertListOfInt(literal(0));
-    assertListOfInt(literal(1));
-    assertListOfInt(literal(2));
-    assertListOfInt(literal(3));
-  }
-
-  test_listLiteral_simple_const() async {
-    String code = r'''
-      void main () {
-        const List<int> c0 = const [];
-        const List<int> c1 = const [3];
-        const List<int> c2 = const ["hello"];
-        const List<int> c3 = const ["hello", 3];
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
-      return exp.staticType;
-    }
-
-    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
-    assertListOfInt(literal(0));
-    assertListOfInt(literal(1));
-    assertListOfInt(literal(2));
-    assertListOfInt(literal(3));
-  }
-
-  test_listLiteral_simple_disabled() async {
-    String code = r'''
-      void main () {
-        List<int> l0 = <num>[];
-        List<int> l1 = <num>[3];
-        List<int> l2 = <String>["hello"];
-        List<int> l3 = <dynamic>["hello", 3];
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
-      return exp.staticType;
-    }
-
-    _isListOf(_isNum)(literal(0));
-    _isListOf(_isNum)(literal(1));
-    _isListOf(_isString)(literal(2));
-    _isListOf(_isDynamic)(literal(3));
-  }
-
-  test_listLiteral_simple_subtype() async {
-    String code = r'''
-      void main () {
-        Iterable<int> l0 = [];
-        Iterable<int> l1 = [3];
-        Iterable<int> l2 = ["hello"];
-        Iterable<int> l3 = ["hello", 3];
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      ListLiteral exp = decl.initializer;
-      return exp.staticType;
-    }
-
-    Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
-
-    assertListOfInt(literal(0));
-    assertListOfInt(literal(1));
-    assertListOfInt(literal(2));
-    assertListOfInt(literal(3));
-  }
-
-  test_mapLiteral_nested() async {
-    String code = r'''
-      void main () {
-        Map<int, List<String>> l0 = {};
-        Map<int, List<String>> l1 = {3: ["hello"]};
-        Map<int, List<String>> l2 = {"hello": ["hello"]};
-        Map<int, List<String>> l3 = {3: [3]};
-        Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    MapLiteral literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      MapLiteral exp = decl.initializer;
-      return exp;
-    }
-
-    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
-    Asserter<InterfaceType> assertMapOfIntToListOfString =
-        _isMapOf(_isInt, (DartType type) => assertListOfString(type));
-
-    assertMapOfIntToListOfString(literal(0).staticType);
-    assertMapOfIntToListOfString(literal(1).staticType);
-    assertMapOfIntToListOfString(literal(2).staticType);
-    assertMapOfIntToListOfString(literal(3).staticType);
-    assertMapOfIntToListOfString(literal(4).staticType);
-
-    assertListOfString(literal(1).entries[0].value.staticType);
-    assertListOfString(literal(2).entries[0].value.staticType);
-    assertListOfString(literal(3).entries[0].value.staticType);
-    assertListOfString(literal(4).entries[0].value.staticType);
-  }
-
-  test_mapLiteral_simple() async {
-    String code = r'''
-      void main () {
-        Map<int, String> l0 = {};
-        Map<int, String> l1 = {3: "hello"};
-        Map<int, String> l2 = {"hello": "hello"};
-        Map<int, String> l3 = {3: 3};
-        Map<int, String> l4 = {3:"hello", "hello": 3};
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      MapLiteral exp = decl.initializer;
-      return exp.staticType;
-    }
-
-    Asserter<InterfaceType> assertMapOfIntToString =
-        _isMapOf(_isInt, _isString);
-
-    assertMapOfIntToString(literal(0));
-    assertMapOfIntToString(literal(1));
-    assertMapOfIntToString(literal(2));
-    assertMapOfIntToString(literal(3));
-  }
-
-  test_mapLiteral_simple_disabled() async {
-    String code = r'''
-      void main () {
-        Map<int, String> l0 = <int, dynamic>{};
-        Map<int, String> l1 = <int, dynamic>{3: "hello"};
-        Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
-        Map<int, String> l3 = <int, dynamic>{3: 3};
-     }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    DartType literal(int i) {
-      VariableDeclarationStatement stmt = statements[i];
-      VariableDeclaration decl = stmt.variables.variables[0];
-      MapLiteral exp = decl.initializer;
-      return exp.staticType;
-    }
-
-    Asserter<InterfaceType> assertMapOfIntToDynamic =
-        _isMapOf(_isInt, _isDynamic);
-
-    assertMapOfIntToDynamic(literal(0));
-    assertMapOfIntToDynamic(literal(1));
-    assertMapOfIntToDynamic(literal(2));
-    assertMapOfIntToDynamic(literal(3));
-  }
-
-  test_methodDeclaration_body_propagation() async {
-    String code = r'''
-      class A {
-        List<String> m0(int x) => ["hello"];
-        List<String> m1(int x) {return [3];}
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-    Expression methodReturnValue(String methodName) {
-      MethodDeclaration method =
-          AstFinder.getMethodInClass(unit, "A", methodName);
-      FunctionBody body = method.body;
-      if (body is ExpressionFunctionBody) {
-        return body.expression;
-      } else {
-        Statement stmt = (body as BlockFunctionBody).block.statements[0];
-        return (stmt as ReturnStatement).expression;
-      }
-    }
-
-    Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
-    assertListOfString(methodReturnValue("m0").staticType);
-    assertListOfString(methodReturnValue("m1").staticType);
-  }
-
-  test_partialTypes1() async {
-    // Test that downwards inference with a partial type
-    // correctly uses the partial information to fill in subterm
-    // types
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    S f<S, T>(Func1<S, T> g) => null;
-    String test() => f((l) => l.length);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    _isString(body.expression.staticType);
-    MethodInvocation invoke = body.expression;
-    FunctionExpression function = invoke.argumentList.arguments[0];
-    ExecutableElement f0 = function.declaredElement;
-    FunctionType type = f0.type;
-    _isFunction2Of(_isString, _isInt)(type);
-  }
-
-  test_pinning_multipleConstraints1() async {
-    // Test that downwards inference with two different downwards covariant
-    // constraints on the same parameter correctly fails to infer when
-    // the types do not share a common subtype
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> { B(S s); }
-    A<int, String> test() => new B(3);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.INVALID_CAST_LITERAL]);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    DartType type = body.expression.staticType;
-
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementB))([_isNull])(type);
-  }
-
-  test_pinning_multipleConstraints2() async {
-    // Test that downwards inference with two identical downwards covariant
-    // constraints on the same parameter correctly infers and pins the type
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> { B(S s); }
-    A<num, num> test() => new B(3);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    DartType type = body.expression.staticType;
-
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementB))([_isNum])(type);
-  }
-
-  test_pinning_multipleConstraints3() async {
-    // Test that downwards inference with two different downwards covariant
-    // constraints on the same parameter correctly fails to infer when
-    // the types do not share a common subtype, but do share a common supertype
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> { B(S s); }
-    A<int, double> test() => new B(3);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertErrors(source, [
-      StrongModeCode.INVALID_CAST_LITERAL,
-    ]);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    DartType type = body.expression.staticType;
-
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementB))([_isNull])(type);
-  }
-
-  test_pinning_multipleConstraints4() async {
-    // Test that downwards inference with two subtype related downwards
-    // covariant constraints on the same parameter correctly infers and pins
-    // the type
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> {}
-    A<int, num> test() => new B();
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    DartType type = body.expression.staticType;
-
-    Element elementB = AstFinder.getClass(unit, "B").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementB))([_isInt])(type);
-  }
-
-  test_pinning_multipleConstraints_contravariant1() async {
-    // Test that downwards inference with two different downwards contravariant
-    // constraints on the same parameter chooses the upper bound
-    // when the only supertype is Object
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> {}
-    typedef void Contra1<T>(T x);
-    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
-    Contra1<A<int, String>> test() => mkA();
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    FunctionType functionType = body.expression.staticType;
-    DartType type = functionType.normalParameterTypes[0];
-
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementA))([_isObject, _isObject])(type);
-  }
-
-  test_pinning_multipleConstraints_contravariant2() async {
-    // Test that downwards inference with two identical downwards contravariant
-    // constraints on the same parameter correctly pins the type
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> {}
-    typedef void Contra1<T>(T x);
-    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
-    Contra1<A<num, num>> test() => mkA();
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    FunctionType functionType = body.expression.staticType;
-    DartType type = functionType.normalParameterTypes[0];
-
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
-  }
-
-  test_pinning_multipleConstraints_contravariant3() async {
-    // Test that downwards inference with two different downwards contravariant
-    // constraints on the same parameter correctly choose the least upper bound
-    // when they share a common supertype
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> {}
-    typedef void Contra1<T>(T x);
-    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
-    Contra1<A<int, double>> test() => mkA();
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    FunctionType functionType = body.expression.staticType;
-    DartType type = functionType.normalParameterTypes[0];
-
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
-  }
-
-  test_pinning_multipleConstraints_contravariant4() async {
-    // Test that downwards inference with two different downwards contravariant
-    // constraints on the same parameter correctly choose the least upper bound
-    // when one is a subtype of the other
-    String code = r'''
-    class A<S, T> {
-      S s;
-      T t;
-    }
-    class B<S> extends A<S, S> {}
-    typedef void Contra1<T>(T x);
-    Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {};
-    Contra1<A<int, num>> test() => mkA();
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    FunctionType functionType = body.expression.staticType;
-    DartType type = functionType.normalParameterTypes[0];
-
-    Element elementA = AstFinder.getClass(unit, "A").declaredElement;
-
-    _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type);
-  }
-
-  test_redirectedConstructor_named() async {
-    Source source = addSource(r'''
-class A<T, U> implements B<T, U> {
-  A.named();
-}
-
-class B<T2, U2> {
-  factory B() = A.named;
-}
-   ''');
-    TestAnalysisResult result = await computeAnalysisResult(source);
-    assertNoErrors(source);
-
-    ClassDeclaration b = result.unit.declarations[1];
-    ConstructorDeclaration bConstructor = b.members[0];
-    ConstructorName redirected = bConstructor.redirectedConstructor;
-
-    TypeName typeName = redirected.type;
-    expect(typeName.type.toString(), 'A<T2, U2>');
-    expect(typeName.type.toString(), 'A<T2, U2>');
-
-    var constructorMember = redirected.staticElement;
-    expect(constructorMember.toString(), 'A.named() → A<T2, U2>');
-    expect(redirected.name.staticElement, constructorMember);
-  }
-
-  test_redirectedConstructor_self() async {
-    Source source = addSource(r'''
-class A<T> {
-  A();
-  factory A.redirected() = A;
-}
-   ''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_redirectedConstructor_unnamed() async {
-    Source source = addSource(r'''
-class A<T, U> implements B<T, U> {
-  A();
-}
-
-class B<T2, U2> {
-  factory B() = A;
-}
-   ''');
-    TestAnalysisResult result = await computeAnalysisResult(source);
-    assertNoErrors(source);
-
-    ClassDeclaration b = result.unit.declarations[1];
-    ConstructorDeclaration bConstructor = b.members[0];
-    ConstructorName redirected = bConstructor.redirectedConstructor;
-
-    TypeName typeName = redirected.type;
-    expect(typeName.type.toString(), 'A<T2, U2>');
-    expect(typeName.type.toString(), 'A<T2, U2>');
-
-    expect(redirected.name, isNull);
-    expect(redirected.staticElement.toString(), 'A() → A<T2, U2>');
-  }
-
-  test_redirectingConstructor_propagation() async {
-    String code = r'''
-      class A {
-        A() : this.named([]);
-        A.named(List<String> x);
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    ConstructorDeclaration constructor =
-        AstFinder.getConstructorInClass(unit, "A", null);
-    RedirectingConstructorInvocation invocation = constructor.initializers[0];
-    Expression exp = invocation.argumentList.arguments[0];
-    _isListOf(_isString)(exp.staticType);
-  }
-
-  test_returnType_variance1() async {
-    // Check that downwards inference correctly pins a type parameter
-    // when the parameter is constrained in a contravariant position
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    Func1<T, String> f<T>(T x) => null;
-    Func1<num, String> test() => f(42);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    MethodInvocation invoke = body.expression;
-    _isFunction2Of(_isNum, _isFunction2Of(_isNum, _isString))(
-        invoke.staticInvokeType);
-  }
-
-  test_returnType_variance2() async {
-    // Check that downwards inference correctly pins a type parameter
-    // when the parameter is constrained in a covariant position
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    Func1<String, T> f<T>(T x) => null;
-    Func1<String, num> test() => f(42);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    MethodInvocation invoke = body.expression;
-    _isFunction2Of(_isNum, _isFunction2Of(_isString, _isNum))(
-        invoke.staticInvokeType);
-  }
-
-  test_returnType_variance3() async {
-    // Check that the variance heuristic chooses the most precise type
-    // when the return type uses the variable in a contravariant position
-    // and there is no downwards constraint.
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    Func1<T, String> f<T>(T x, g(T x)) => null;
-    dynamic test() => f(42, (num x) => x);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    FunctionType functionType = body.expression.staticType;
-    DartType type = functionType.normalParameterTypes[0];
-    _isInt(type);
-  }
-
-  test_returnType_variance4() async {
-    // Check that the variance heuristic chooses the more precise type
-    // when the return type uses the variable in a covariant position
-    // and there is no downwards constraint
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    Func1<String, T> f<T>(T x, g(T x)) => null;
-    dynamic test() => f(42, (num x) => x);
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    FunctionType functionType = body.expression.staticType;
-    DartType type = functionType.returnType;
-    _isInt(type);
-  }
-
-  test_returnType_variance5() async {
-    // Check that pinning works correctly with a partial type
-    // when the return type uses the variable in a contravariant position
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    Func1<T, String> f<T>(T x) => null;
-    T g<T, S>(Func1<T, S> f) => null;
-    num test() => g(f(3));
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    MethodInvocation call = body.expression;
-    _isNum(call.staticType);
-    _isFunction2Of(_isFunction2Of(_isNum, _isString), _isNum)(
-        call.staticInvokeType);
-  }
-
-  test_returnType_variance6() async {
-    // Check that pinning works correctly with a partial type
-    // when the return type uses the variable in a covariant position
-    String code = r'''
-    typedef To Func1<From, To>(From x);
-    Func1<String, T> f<T>(T x) => null;
-    T g<T, S>(Func1<S, T> f) => null;
-    num test() => g(f(3));
-   ''';
-    Source source = addSource(code);
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = analysisResult.unit;
-    FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    MethodInvocation call = body.expression;
-    _isNum(call.staticType);
-    _isFunction2Of(_isFunction2Of(_isString, _isNum), _isNum)(
-        call.staticInvokeType);
-  }
-
-  test_superConstructorInvocation_propagation() async {
-    String code = r'''
-      class B {
-        B(List<String> p);
-      }
-      class A extends B {
-        A() : super([]);
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    ConstructorDeclaration constructor =
-        AstFinder.getConstructorInClass(unit, "A", null);
-    SuperConstructorInvocation invocation = constructor.initializers[0];
-    Expression exp = invocation.argumentList.arguments[0];
-    _isListOf(_isString)(exp.staticType);
-  }
-
-  test_sync_star_method_propagation() async {
-    String code = r'''
-      import "dart:async";
-      class A {
-        Iterable f0() sync* { yield []; }
-        Iterable f1() sync* { yield* new List(); }
-
-        Iterable<List<int>> f2() sync* { yield []; }
-        Iterable<List<int>> f3() sync* { yield* new List(); }
-      }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    void check(String name, Asserter<InterfaceType> typeTest) {
-      MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
-      BlockFunctionBody body = test.body;
-      YieldStatement stmt = body.block.statements[0];
-      Expression exp = stmt.expression;
-      typeTest(exp.staticType);
-    }
-
-    check("f0", _isListOf(_isDynamic));
-    check("f1", _isListOf(_isDynamic));
-
-    check("f2", _isListOf(_isInt));
-    check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
-  }
-
-  test_sync_star_propagation() async {
-    String code = r'''
-      import "dart:async";
-
-      Iterable f0() sync* { yield []; }
-      Iterable f1() sync* { yield* new List(); }
-
-      Iterable<List<int>> f2() sync* { yield []; }
-      Iterable<List<int>> f3() sync* { yield* new List(); }
-   ''';
-    CompilationUnit unit = await resolveSource(code);
-
-    void check(String name, Asserter<InterfaceType> typeTest) {
-      FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
-      BlockFunctionBody body = test.functionExpression.body;
-      YieldStatement stmt = body.block.statements[0];
-      Expression exp = stmt.expression;
-      typeTest(exp.staticType);
-    }
-
-    check("f0", _isListOf(_isDynamic));
-    check("f1", _isListOf(_isDynamic));
-
-    check("f2", _isListOf(_isInt));
-    check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
-  }
-
-  /// Verifies the source has the expected [errorCodes] as well as the
-  /// expected [errorMessage].
-  void _expectInferenceError(
-      Source source, List<ErrorCode> errorCodes, String errorMessage) {
-    assertErrors(source, errorCodes);
-    var errors = analysisResults[source]
-        .errors
-        .where((e) => e.errorCode == StrongModeCode.COULD_NOT_INFER)
-        .map((e) => e.message)
-        .toList();
-    expect(errors.length, 1);
-    var actual = errors[0];
-    expect(actual,
-        errorMessage, // Print the literal error message for easy copy+paste:
-        reason: 'Actual error did not match expected error:\n$actual');
-  }
-
-  /// Helper method for testing `FutureOr<T>`.
-  ///
-  /// Validates that [code] produces [errors]. It should define a function
-  /// "test", whose body is an expression that invokes a method. Returns that
-  /// invocation.
-  Future<MethodInvocation> _testFutureOr(String code,
-      {List<ErrorCode> errors}) async {
-    Source source = addSource("""
-    import "dart:async";
-    $code""");
-    TestAnalysisResult analysisResult = await computeAnalysisResult(source);
-
-    if (errors == null) {
-      assertNoErrors(source);
-    } else {
-      assertErrors(source, errors);
-    }
-    verify([source]);
-    FunctionDeclaration test =
-        AstFinder.getTopLevelFunction(analysisResult.unit, "test");
-    ExpressionFunctionBody body = test.functionExpression.body;
-    return body.expression;
-  }
-}
-
-/// Strong mode static analyzer end to end tests
-@reflectiveTest
-class StrongModeStaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared
-    with StrongModeStaticTypeAnalyzer2TestCases {
-  void setUp() {
-    super.setUp();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    resetWith(options: options);
-  }
-
-  @override
-  @failingTest
-  test_genericMethod_nestedCaptureBounds() {
-    // https://github.com/dart-lang/sdk/issues/30236
-    return super.test_genericMethod_nestedCaptureBounds();
-  }
-
-  @override
-  @failingTest
-  test_genericMethod_tearoff_instantiated() {
-    return super.test_genericMethod_tearoff_instantiated();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_class_error_extension_malbounded() {
-    return super.test_instantiateToBounds_class_error_extension_malbounded();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_class_error_instantiation_malbounded() {
-    return super
-        .test_instantiateToBounds_class_error_instantiation_malbounded();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_generic_function_error_malbounded() {
-    return super.test_instantiateToBounds_generic_function_error_malbounded();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_class_error_recursion() {
-    return super.test_notInstantiatedBound_class_error_recursion();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_class_error_recursion_less_direct() {
-    return super.test_notInstantiatedBound_class_error_recursion_less_direct();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_class_error_recursion_typedef() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_class_error_recursion_typedef();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_class_argument() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_class_argument();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_class_argument2() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_class_argument2();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_class_direct() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_class_direct();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_class_indirect() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_class_indirect();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_functionType() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_functionType();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_typedef_argument() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_typedef_argument();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_typedef_argument2() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_typedef_argument2();
-  }
-
-  @override
-  @failingTest
-  test_notInstantiatedBound_error_typedef_direct() {
-    // Does not work with the task model
-    return super.test_notInstantiatedBound_error_typedef_direct();
-  }
-}
-
-/// Test cases for [StrongModeStaticTypeAnalyzer2Test]
-mixin StrongModeStaticTypeAnalyzer2TestCases
-    implements StaticTypeAnalyzer2TestShared {
-  void expectStaticInvokeType(String search, String type) {
-    var invocation = findIdentifier(search).parent as MethodInvocation;
-    expect(invocation.staticInvokeType.toString(), type);
-  }
-
-  test_dynamicObjectGetter_hashCode() async {
-    String code = r'''
-main() {
-  dynamic a = null;
-  var foo = a.hashCode;
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'int');
-  }
-
-  test_futureOr_promotion1() async {
-    // Test that promotion from FutureOr<T> to T works for concrete types
-    String code = r'''
-    import "dart:async";
-    dynamic test(FutureOr<int> x) => (x is int) && (x.abs() == 0);
-   ''';
-    await resolveTestUnit(code);
-  }
-
-  test_futureOr_promotion2() async {
-    // Test that promotion from FutureOr<T> to Future<T> works for concrete
-    // types
-    String code = r'''
-    import "dart:async";
-    dynamic test(FutureOr<int> x) => (x is Future<int>) &&
-                                     (x.then((x) => x) == null);
-   ''';
-    await resolveTestUnit(code);
-  }
-
-  test_futureOr_promotion3() async {
-    // Test that promotion from FutureOr<T> to T works for type
-    // parameters T
-    String code = r'''
-    import "dart:async";
-    dynamic test<T extends num>(FutureOr<T> x) => (x is T) &&
-                                                  (x.abs() == 0);
-   ''';
-    await resolveTestUnit(code);
-  }
-
-  test_futureOr_promotion4() async {
-    // Test that promotion from FutureOr<T> to Future<T> works for type
-    // parameters T
-    String code = r'''
-    import "dart:async";
-    dynamic test<T extends num>(FutureOr<T> x) => (x is Future<T>) &&
-                                                  (x.then((x) => x) == null);
-   ''';
-    await resolveTestUnit(code);
-  }
-
-  test_generalizedVoid_assignToVoidOk() async {
-    Source source = addSource(r'''
-void main() {
-  void x;
-  x = 42;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-  }
-
-  test_genericFunction() async {
-    await resolveTestUnit(r'T f<T>(T x) => null;');
-    expectFunctionType('f', '<T>(T) → T',
-        elementTypeParams: '[T]', typeFormals: '[T]');
-    SimpleIdentifier f = findIdentifier('f');
-    FunctionElementImpl e = f.staticElement;
-    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
-    expect(ft.toString(), '(String) → String');
-  }
-
-  test_genericFunction_bounds() async {
-    await resolveTestUnit(r'T f<T extends num>(T x) => null;');
-    expectFunctionType('f', '<T extends num>(T) → T',
-        elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
-  }
-
-  test_genericFunction_parameter() async {
-    await resolveTestUnit(r'''
-void g(T f<T>(T x)) {}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectFunctionType('f', '<T>(T) → T',
-        elementTypeParams: '[]', typeFormals: '[T]');
-    SimpleIdentifier f = findIdentifier('f');
-    ParameterElementImpl e = f.staticElement;
-    FunctionType type = e.type;
-    FunctionType ft = type.instantiate([typeProvider.stringType]);
-    expect(ft.toString(), '(String) → String');
-  }
-
-  test_genericFunction_static() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  static T f<T>(T x) => null;
-}
-''');
-    expectFunctionType('f', '<T>(T) → T',
-        elementTypeParams: '[T]', typeFormals: '[T]');
-    SimpleIdentifier f = findIdentifier('f');
-    MethodElementImpl e = f.staticElement;
-    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
-    expect(ft.toString(), '(String) → String');
-  }
-
-  test_genericFunction_typedef() async {
-    String code = r'''
-typedef T F<T>(T x);
-F f0;
-
-class C {
-  static F f1;
-  F f2;
-  void g(F f3) {
-    F f4;
-    f0(3);
-    f1(3);
-    f2(3);
-    f3(3);
-    f4(3);
-  }
-}
-
-class D<S> {
-  static F f1;
-  F f2;
-  void g(F f3) {
-    F f4;
-    f0(3);
-    f1(3);
-    f2(3);
-    f3(3);
-    f4(3);
-  }
-}
-''';
-    await resolveTestUnit(code);
-
-    checkBody(String className) {
-      List<Statement> statements =
-          AstFinder.getStatementsInMethod(testUnit, className, "g");
-
-      for (int i = 1; i <= 5; i++) {
-        Expression exp = (statements[i] as ExpressionStatement).expression;
-        expect(exp.staticType, typeProvider.dynamicType);
-      }
-    }
-
-    checkBody("C");
-    checkBody("D");
-  }
-
-  test_genericFunction_upwardsAndDownwards() async {
-    // Regression tests for https://github.com/dart-lang/sdk/issues/27586.
-    await resolveTestUnit(r'List<num> x = [1, 2];');
-    expectInitializerType('x', 'List<num>');
-  }
-
-  test_genericFunction_upwardsAndDownwards_Object() async {
-    // Regression tests for https://github.com/dart-lang/sdk/issues/27625.
-    await resolveTestUnit(r'''
-List<Object> aaa = [];
-List<Object> bbb = [1, 2, 3];
-List<Object> ccc = [null];
-List<Object> ddd = [1 as dynamic];
-List<Object> eee = [new Object()];
-    ''');
-    expectInitializerType('aaa', 'List<Object>');
-    expectInitializerType('bbb', 'List<Object>');
-    expectInitializerType('ccc', 'List<Object>');
-    expectInitializerType('ddd', 'List<Object>');
-    expectInitializerType('eee', 'List<Object>');
-  }
-
-  test_genericMethod() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  List<T> f<T>(E e) => null;
-}
-main() {
-  C<String> cOfString;
-}
-''');
-    expectFunctionType('f', '<T>(E) → List<T>',
-        elementTypeParams: '[T]',
-        typeParams: '[E]',
-        typeArgs: '[E]',
-        typeFormals: '[T]');
-    SimpleIdentifier c = findIdentifier('cOfString');
-    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
-    expect(ft.toString(), '<T>(String) → List<T>');
-    ft = ft.instantiate([typeProvider.intType]);
-    expect(ft.toString(), '(String) → List<int>');
-    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
-  }
-
-  test_genericMethod_explicitTypeParams() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  List<T> f<T>(E e) => null;
-}
-main() {
-  C<String> cOfString;
-  var x = cOfString.f<int>('hi');
-}
-''');
-    MethodInvocation f = findIdentifier('f<int>').parent;
-    FunctionType ft = f.staticInvokeType;
-    expect(ft.toString(), '(String) → List<int>');
-    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
-
-    SimpleIdentifier x = findIdentifier('x');
-    expect(x.staticType,
-        typeProvider.listType.instantiate([typeProvider.intType]));
-  }
-
-  test_genericMethod_functionExpressionInvocation_explicit() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  T f<T>(T e) => null;
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-T topF<T>(T e) => null;
-var topG = topF;
-void test<S>(T Function<T>(T) pf) {
-  var c = new C<int>();
-  T lf<T>(T e) => null;
-
-  var lambdaCall = (<E>(E e) => e)<int>(3);
-  var methodCall = (c.f)<int>(3);
-  var staticCall = (C.g)<int>(3);
-  var staticFieldCall = (C.h)<int>(3);
-  var topFunCall = (topF)<int>(3);
-  var topFieldCall = (topG)<int>(3);
-  var localCall = (lf)<int>(3);
-  var paramCall = (pf)<int>(3);
-}
-''');
-    expectIdentifierType('methodCall', "int");
-    expectIdentifierType('staticCall', "int");
-    expectIdentifierType('staticFieldCall', "int");
-    expectIdentifierType('topFunCall', "int");
-    expectIdentifierType('topFieldCall', "int");
-    expectIdentifierType('localCall', "int");
-    expectIdentifierType('paramCall', "int");
-    expectIdentifierType('lambdaCall', "int");
-  }
-
-  test_genericMethod_functionExpressionInvocation_functionTypedParameter_explicit() async {
-    await resolveTestUnit(r'''
-void test<S>(T pf<T>(T e)) {
-  var paramCall = (pf)<int>(3);
-}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectIdentifierType('paramCall', "int");
-  }
-
-  test_genericMethod_functionExpressionInvocation_functionTypedParameter_inferred() async {
-    await resolveTestUnit(r'''
-void test<S>(T pf<T>(T e)) {
-  var paramCall = (pf)(3);
-}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectIdentifierType('paramCall', "int");
-  }
-
-  test_genericMethod_functionExpressionInvocation_inferred() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  T f<T>(T e) => null;
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-T topF<T>(T e) => null;
-var topG = topF;
-void test<S>(T Function<T>(T) pf) {
-  var c = new C<int>();
-  T lf<T>(T e) => null;
-
-  var lambdaCall = (<E>(E e) => e)(3);
-  var methodCall = (c.f)(3);
-  var staticCall = (C.g)(3);
-  var staticFieldCall = (C.h)(3);
-  var topFunCall = (topF)(3);
-  var topFieldCall = (topG)(3);
-  var localCall = (lf)(3);
-  var paramCall = (pf)(3);
-}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectIdentifierType('methodCall', "int");
-    expectIdentifierType('staticCall', "int");
-    expectIdentifierType('staticFieldCall', "int");
-    expectIdentifierType('topFunCall', "int");
-    expectIdentifierType('topFieldCall', "int");
-    expectIdentifierType('localCall', "int");
-    expectIdentifierType('paramCall', "int");
-    expectIdentifierType('lambdaCall', "int");
-  }
-
-  test_genericMethod_functionInvocation_explicit() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  T f<T>(T e) => null;
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-T topF<T>(T e) => null;
-var topG = topF;
-void test<S>(T Function<T>(T) pf) {
-  var c = new C<int>();
-  T lf<T>(T e) => null;
-  var methodCall = c.f<int>(3);
-  var staticCall = C.g<int>(3);
-  var staticFieldCall = C.h<int>(3);
-  var topFunCall = topF<int>(3);
-  var topFieldCall = topG<int>(3);
-  var localCall = lf<int>(3);
-  var paramCall = pf<int>(3);
-}
-''');
-    expectIdentifierType('methodCall', "int");
-    expectIdentifierType('staticCall', "int");
-    expectIdentifierType('staticFieldCall', "int");
-    expectIdentifierType('topFunCall', "int");
-    expectIdentifierType('topFieldCall', "int");
-    expectIdentifierType('localCall', "int");
-    expectIdentifierType('paramCall', "int");
-  }
-
-  test_genericMethod_functionInvocation_functionTypedParameter_explicit() async {
-    await resolveTestUnit(r'''
-void test<S>(T pf<T>(T e)) {
-  var paramCall = pf<int>(3);
-}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectIdentifierType('paramCall', "int");
-  }
-
-  test_genericMethod_functionInvocation_functionTypedParameter_inferred() async {
-    await resolveTestUnit(r'''
-void test<S>(T pf<T>(T e)) {
-  var paramCall = pf(3);
-}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectIdentifierType('paramCall', "int");
-  }
-
-  test_genericMethod_functionInvocation_inferred() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  T f<T>(T e) => null;
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-T topF<T>(T e) => null;
-var topG = topF;
-void test<S>(T Function<T>(T) pf) {
-  var c = new C<int>();
-  T lf<T>(T e) => null;
-  var methodCall = c.f(3);
-  var staticCall = C.g(3);
-  var staticFieldCall = C.h(3);
-  var topFunCall = topF(3);
-  var topFieldCall = topG(3);
-  var localCall = lf(3);
-  var paramCall = pf(3);
-}
-''');
-    expectIdentifierType('methodCall', "int");
-    expectIdentifierType('staticCall', "int");
-    expectIdentifierType('staticFieldCall', "int");
-    expectIdentifierType('topFunCall', "int");
-    expectIdentifierType('topFieldCall', "int");
-    expectIdentifierType('localCall', "int");
-    expectIdentifierType('paramCall', "int");
-  }
-
-  test_genericMethod_functionTypedParameter() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  List<T> f<T>(T f(E e)) => null;
-}
-main() {
-  C<String> cOfString;
-}
-''');
-    expectFunctionType('f', '<T>((E) → T) → List<T>',
-        elementTypeParams: '[T]',
-        typeParams: '[E]',
-        typeArgs: '[E]',
-        typeFormals: '[T]');
-
-    SimpleIdentifier c = findIdentifier('cOfString');
-    FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
-    expect(ft.toString(), '<T>((String) → T) → List<T>');
-    ft = ft.instantiate([typeProvider.intType]);
-    expect(ft.toString(), '((String) → int) → List<int>');
-  }
-
-  test_genericMethod_functionTypedParameter_tearoff() async {
-    await resolveTestUnit(r'''
-void test<S>(T pf<T>(T e)) {
-  var paramTearOff = pf;
-}
-''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
-        );
-    expectIdentifierType('paramTearOff', "<T>(T) → T");
-  }
-
-  test_genericMethod_implicitDynamic() async {
-    // Regression test for:
-    // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
-    // These should not cause any hints or warnings.
-    await resolveTestUnit(r'''
-class List<E> {
-  T map<T>(T f(E e)) => null;
-}
-void foo() {
-  List list = null;
-  list.map((e) => e);
-  list.map((e) => 3);
-}''');
-    expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T');
-    expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T');
-
-    MethodInvocation m1 = findIdentifier('map((e) => e);').parent;
-    expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
-    MethodInvocation m2 = findIdentifier('map((e) => 3);').parent;
-    expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
-  }
-
-  test_genericMethod_max_doubleDouble() async {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1.0, 2.0);
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'double');
-  }
-
-  test_genericMethod_max_doubleDouble_prefixed() async {
-    String code = r'''
-import 'dart:math' as math;
-main() {
-  var foo = math.max(1.0, 2.0);
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'double');
-  }
-
-  test_genericMethod_max_doubleInt() async {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1.0, 2);
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'num');
-  }
-
-  test_genericMethod_max_intDouble() async {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1, 2.0);
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'num');
-  }
-
-  test_genericMethod_max_intInt() async {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1, 2);
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'int');
-  }
-
-  test_genericMethod_nestedBound() async {
-    String code = r'''
-class Foo<T extends num> {
-  void method<U extends T>(U u) {
-    u.abs();
-  }
-}
-''';
-    // Just validate that there is no warning on the call to `.abs()`.
-    await resolveTestUnit(code);
-  }
-
-  test_genericMethod_nestedCapture() async {
-    await resolveTestUnit(r'''
-class C<T> {
-  T f<S>(S x) {
-    new C<S>().f<int>(3);
-    new C<S>().f; // tear-off
-    return null;
-  }
-}
-''');
-    MethodInvocation f = findIdentifier('f<int>(3);').parent;
-    expect(f.staticInvokeType.toString(), '(int) → S');
-    FunctionType ft = f.staticInvokeType;
-    expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
-
-    expectIdentifierType('f;', '<S₀>(S₀) → S');
-  }
-
-  test_genericMethod_nestedCaptureBounds() async {
-    await resolveTestUnit(r'''
-class C<T> {
-  T f<S extends T>(S x) {
-    new C<S>().f<int>(3);
-    new C<S>().f; // tear-off
-    return null;
-  }
-}
-''');
-    MethodInvocation f = findIdentifier('f<int>(3);').parent;
-    expect(f.staticInvokeType.toString(), '(int) → S');
-    FunctionType ft = f.staticInvokeType;
-    expect('${ft.typeArguments}/${ft.typeParameters}',
-        '[S, int]/[T, S extends T]');
-
-    expectIdentifierType('f;', '<S₀ extends S>(S₀) → S');
-  }
-
-  test_genericMethod_nestedFunctions() async {
-    await resolveTestUnit(r'''
-S f<S>(S x) {
-  g<S>(S x) => f;
-  return null;
-}
-''');
-    expectIdentifierType('f', '<S>(S) → S');
-    expectIdentifierType('g', '<S>(S) → <S>(S) → S');
-  }
-
-  test_genericMethod_override() async {
-    await resolveTestUnit(r'''
-class C {
-  T f<T>(T x) => null;
-}
-class D extends C {
-  T f<T>(T x) => null; // from D
-}
-''');
-    expectFunctionType('f<T>(T x) => null; // from D', '<T>(T) → T',
-        elementTypeParams: '[T]', typeFormals: '[T]');
-    SimpleIdentifier f = findIdentifier('f<T>(T x) => null; // from D');
-    MethodElementImpl e = f.staticElement;
-    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
-    expect(ft.toString(), '(String) → String');
-  }
-
-  test_genericMethod_override_bounds() async {
-    await resolveTestUnit(r'''
-class A {}
-class B {
-  T f<T extends A>(T x) => null;
-}
-// override with the same bound is OK
-class C extends B {
-  T f<T extends A>(T x) => null;
-}
-// override with new name and the same bound is OK
-class D extends B {
-  Q f<Q extends A>(Q x) => null;
-}
-''');
-  }
-
-  test_genericMethod_override_covariant_field() async {
-    Source source = addSource(r'''
-abstract class A {
-  num get x;
-  set x(covariant num _);
-}
-
-class B extends A {
-  int x;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericMethod_override_differentContextsSameBounds() async {
-    Source source = addSource(r'''
-        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>();
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_genericMethod_override_invalidContravariantTypeParamBounds() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C {
-  T f<T extends A>(T x) => null;
-}
-class D extends C {
-  T f<T extends B>(T x) => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
-    verify([source]);
-  }
-
-  test_genericMethod_override_invalidCovariantTypeParamBounds() async {
-    Source source = addSource(r'''
-class A {}
-class B extends A {}
-class C {
-  T f<T extends B>(T x) => null;
-}
-class D extends C {
-  T f<T extends A>(T x) => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
-    verify([source]);
-  }
-
-  test_genericMethod_override_invalidReturnType() async {
-    Source source = addSource(r'''
-class C {
-  Iterable<T> f<T>(T x) => null;
-}
-class D extends C {
-  String f<S>(S x) => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
-    verify([source]);
-  }
-
-  test_genericMethod_override_invalidTypeParamCount() async {
-    Source source = addSource(r'''
-class C {
-  T f<T>(T x) => null;
-}
-class D extends C {
-  S f<T, S>(T x) => null;
-}''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
-    verify([source]);
-  }
-
-  test_genericMethod_propagatedType_promotion() async {
-    // Regression test for:
-    // https://github.com/dart-lang/sdk/issues/25340
-
-    // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
-    // example won't work, as we now compute a static type and therefore discard
-    // the propagated type. So a new test was created that doesn't run under
-    // strong mode.
-    await resolveTestUnit(r'''
-abstract class Iter {
-  List<S> map<S>(S f(x));
-}
-class C {}
-C toSpan(dynamic element) {
-  if (element is Iter) {
-    var y = element.map(toSpan);
-  }
-  return null;
-}''');
-    expectIdentifierType('y = ', 'List<C>');
-  }
-
-  test_genericMethod_tearoff() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  T f<T>(E e) => null;
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-T topF<T>(T e) => null;
-var topG = topF;
-void test<S>(T Function<T>(T) pf) {
-  var c = new C<int>();
-  T lf<T>(T e) => null;
-  var methodTearOff = c.f;
-  var staticTearOff = C.g;
-  var staticFieldTearOff = C.h;
-  var topFunTearOff = topF;
-  var topFieldTearOff = topG;
-  var localTearOff = lf;
-  var paramTearOff = pf;
-}
-''');
-    expectIdentifierType('methodTearOff', "<T>(int) → T");
-    expectIdentifierType('staticTearOff', "<T>(T) → T");
-    expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
-    expectIdentifierType('topFunTearOff', "<T>(T) → T");
-    expectIdentifierType('topFieldTearOff', "<T>(T) → T");
-    expectIdentifierType('localTearOff', "<T>(T) → T");
-    expectIdentifierType('paramTearOff', "<T>(T) → T");
-  }
-
-  test_genericMethod_tearoff_instantiated() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  T f<T>(E e) => null;
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-T topF<T>(T e) => null;
-var topG = topF;
-void test<S>(T pf<T>(T e)) {
-  var c = new C<int>();
-  T lf<T>(T e) => null;
-  var methodTearOffInst = c.f<int>;
-  var staticTearOffInst = C.g<int>;
-  var staticFieldTearOffInst = C.h<int>;
-  var topFunTearOffInst = topF<int>;
-  var topFieldTearOffInst = topG<int>;
-  var localTearOffInst = lf<int>;
-  var paramTearOffInst = pf<int>;
-}
-''');
-    expectIdentifierType('methodTearOffInst', "(int) → int");
-    expectIdentifierType('staticTearOffInst', "(int) → int");
-    expectIdentifierType('staticFieldTearOffInst', "(int) → int");
-    expectIdentifierType('topFunTearOffInst', "(int) → int");
-    expectIdentifierType('topFieldTearOffInst', "(int) → int");
-    expectIdentifierType('localTearOffInst', "(int) → int");
-    expectIdentifierType('paramTearOffInst', "(int) → int");
-  }
-
-  test_genericMethod_then() async {
-    String code = r'''
-import 'dart:async';
-String toString(int x) => x.toString();
-main() {
-  Future<int> bar = null;
-  var foo = bar.then(toString);
-}
-''';
-    await resolveTestUnit(code);
-
-    expectInitializerType('foo', 'Future<String>');
-  }
-
-  test_genericMethod_then_prefixed() async {
-    String code = r'''
-import 'dart:async' as async;
-String toString(int x) => x.toString();
-main() {
-  async.Future<int> bar = null;
-  var foo = bar.then(toString);
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'Future<String>');
-  }
-
-  test_genericMethod_then_propagatedType() async {
-    // Regression test for https://github.com/dart-lang/sdk/issues/25482.
-    String code = r'''
-import 'dart:async';
-void main() {
-  Future<String> p;
-  var foo = p.then((r) => new Future<String>.value(3));
-}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    // Note: this correctly reports the error
-    // StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE when run with the driver;
-    // when run without the driver, it reports no errors.  So we don't bother
-    // checking whether the correct errors were reported.
-    expectInitializerType('foo', 'Future<String>');
-  }
-
-  test_genericMethod_toplevel_field_staticTearoff() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  static T g<T>(T e) => null;
-  static T Function<T>(T) h = null;
-}
-
-void test() {
-  var fieldRead = C.h;
-}
-''');
-    expectIdentifierType('fieldRead', "<T>(T) → T");
-  }
-
-  test_implicitBounds() async {
-    String code = r'''
-class A<T> {}
-
-class B<T extends num> {}
-
-class C<S extends int, T extends B<S>, U extends A> {}
-
-void test() {
-//
-  A ai;
-  B bi;
-  C ci;
-  var aa = new A();
-  var bb = new B();
-  var cc = new C();
-}
-''';
-    await resolveTestUnit(code);
-    expectIdentifierType('ai', "A<dynamic>");
-    expectIdentifierType('bi', "B<num>");
-    expectIdentifierType('ci', "C<int, B<int>, A<dynamic>>");
-    expectIdentifierType('aa', "A<dynamic>");
-    expectIdentifierType('bb', "B<num>");
-    expectIdentifierType('cc', "C<int, B<int>, A<dynamic>>");
-  }
-
-  test_inferClosureType_parameters() async {
-    Source source = addSource(r'''
-typedef F({bool p});
-foo(callback(F f)) {}
-main() {
-  foo((f) {
-    f(p: false);
-  });
-}
-''');
-    var result = await computeAnalysisResult(source);
-    var main = result.unit.declarations[2] as FunctionDeclaration;
-    var body = main.functionExpression.body as BlockFunctionBody;
-    var statement = body.block.statements[0] as ExpressionStatement;
-    var invocation = statement.expression as MethodInvocation;
-    var closure = invocation.argumentList.arguments[0] as FunctionExpression;
-    var closureType = closure.staticType as FunctionType;
-    var fType = closureType.parameters[0].type as FunctionType;
-    // The inferred type of "f" in "foo()" invocation must own its parameters.
-    ParameterElement p = fType.parameters[0];
-    expect(p.name, 'p');
-    expect(p.enclosingElement, same(fType.element));
-  }
-
-  test_instantiateToBounds_class_error_extension_malbounded() async {
-    // Test that superclasses are strictly checked for malbounded default
-    // types
-    String code = r'''
-class C<T0 extends List<T1>, T1 extends List<T0>> {}
-class D extends C {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]);
-  }
-
-  test_instantiateToBounds_class_error_instantiation_malbounded() async {
-    // Test that instance creations are strictly checked for malbounded default
-    // types
-    String code = r'''
-class C<T0 extends List<T1>, T1 extends List<T0>> {}
-void test() {
-  var c = new C();
-}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]);
-    expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>');
-  }
-
-  test_instantiateToBounds_class_error_recursion() async {
-    String code = r'''
-class C<T0 extends List<T1>, T1 extends List<T0>> {}
-C c;
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>');
-  }
-
-  test_instantiateToBounds_class_error_recursion_self() async {
-    String code = r'''
-class C<T extends C<T>> {}
-C c;
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<C<dynamic>>');
-  }
-
-  test_instantiateToBounds_class_error_recursion_self2() async {
-    String code = r'''
-class A<E> {}
-class C<T extends A<T>> {}
-C c;
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<A<dynamic>>');
-  }
-
-  test_instantiateToBounds_class_error_typedef() async {
-    String code = r'''
-typedef T F<T>(T x);
-class C<T extends F<T>> {}
-C c;
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<(dynamic) → dynamic>');
-  }
-
-  test_instantiateToBounds_class_ok_implicitDynamic_multi() async {
-    String code = r'''
-class C<T0 extends Map<T1, T2>, T1 extends List, T2 extends int> {}
-C c;
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectIdentifierType(
-        'c;', 'C<Map<List<dynamic>, int>, List<dynamic>, int>');
-  }
-
-  test_instantiateToBounds_class_ok_referenceOther_after() async {
-    String code = r'''
-class C<T0 extends T1, T1 extends int> {}
-C c;
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<int, int>');
-  }
-
-  test_instantiateToBounds_class_ok_referenceOther_after2() async {
-    String code = r'''
-class C<T0 extends Map<T1, T1>, T1 extends int> {}
-C c;
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<Map<int, int>, int>');
-  }
-
-  test_instantiateToBounds_class_ok_referenceOther_before() async {
-    String code = r'''
-class C<T0 extends int, T1 extends T0> {}
-C c;
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<int, int>');
-  }
-
-  test_instantiateToBounds_class_ok_referenceOther_multi() async {
-    String code = r'''
-class C<T0 extends Map<T1, T2>, T1 extends List<T2>, T2 extends int> {}
-C c;
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectIdentifierType('c;', 'C<Map<List<int>, int>, List<int>, int>');
-  }
-
-  test_instantiateToBounds_class_ok_simpleBounds() async {
-    String code = r'''
-class A<T> {}
-class B<T extends num> {}
-class C<T extends List<int>> {}
-class D<T extends A> {}
-void main() {
-  A a;
-  B b;
-  C c;
-  D d;
-}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectIdentifierType('a;', 'A<dynamic>');
-    expectIdentifierType('b;', 'B<num>');
-    expectIdentifierType('c;', 'C<List<int>>');
-    expectIdentifierType('d;', 'D<A<dynamic>>');
-  }
-
-  test_instantiateToBounds_generic_function_error_malbounded() async {
-    // Test that generic methods are strictly checked for malbounded default
-    // types
-    String code = r'''
-T0 f<T0 extends List<T1>, T1 extends List<T0>>() {}
-void g() {
-  var c = f();
-  return;
-}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]);
-    expectIdentifierType('c;', 'List<dynamic>');
-  }
-
-  test_instantiateToBounds_method_ok_referenceOther_before() async {
-    String code = r'''
-class C<T> {
-  void m<S0 extends T, S1 extends List<S0>>(S0 p0, S1 p1) {}
-
-  void main() {
-    m(null, null);
-  }
-}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectStaticInvokeType('m(null', '(Null, Null) → void');
-  }
-
-  test_instantiateToBounds_method_ok_referenceOther_before2() async {
-    String code = r'''
-class C<T> {
-  Map<S0, S1> m<S0 extends T, S1 extends List<S0>>() => null;
-
-  void main() {
-    m();
-  }
-}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectStaticInvokeType('m();', '() → Map<T, List<T>>');
-  }
-
-  test_instantiateToBounds_method_ok_simpleBounds() async {
-    String code = r'''
-class C<T> {
-  void m<S extends T>(S p0) {}
-
-  void main() {
-    m(null);
-  }
-}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectStaticInvokeType('m(null)', '(Null) → void');
-  }
-
-  test_instantiateToBounds_method_ok_simpleBounds2() async {
-    String code = r'''
-class C<T> {
-  S m<S extends T>() => null;
-
-  void main() {
-    m();
-  }
-}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-    expectStaticInvokeType('m();', '() → T');
-  }
-
-  test_issue32396() async {
-    await resolveTestUnit(r'''
-class C<E> {
-  static T g<T>(T e) => null;
-  static final h = g;
-}
-''');
-  }
-
-  test_notInstantiatedBound_class_error_recursion() async {
-    String code = r'''
-class A<T extends B> {} // points to a
-class B<T extends A> {} // points to b
-class C<T extends A> {} // points to a cyclical type
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-    ]);
-  }
-
-  test_notInstantiatedBound_class_error_recursion_less_direct() async {
-    String code = r'''
-class A<T extends B<A>> {}
-class B<T extends A<B>> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-    ]);
-  }
-
-  test_notInstantiatedBound_class_error_recursion_typedef() async {
-    String code = r'''
-typedef F(C value);
-class C<T extends F> {}
-class D<T extends C> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-    ]);
-  }
-
-  test_notInstantiatedBound_error_class_argument() async {
-    String code = r'''
-class A<K, V extends List<K>> {}
-class C<T extends A> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_error_class_argument2() async {
-    String code = r'''
-class A<K, V extends List<List<K>>> {}
-class C<T extends A> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_error_class_direct() async {
-    String code = r'''
-class A<K, V extends K> {}
-class C<T extends A> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_error_class_indirect() async {
-    String code = r'''
-class A<K, V extends K> {}
-class C<T extends List<A>> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_error_functionType() async {
-    await resolveTestUnit(r'''
-class A<T extends Function(T)> {}
-class B<T extends T Function()> {}
-class C<T extends A> {}
-class D<T extends B> {}
-''', noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND
-    ]);
-  }
-
-  test_notInstantiatedBound_error_typedef_argument() async {
-    String code = r'''
-class A<K, V extends List<K>> {}
-typedef void F<T extends A>();
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_error_typedef_argument2() async {
-    String code = r'''
-class A<K, V extends List<List<K>>> {}
-typedef void F<T extends A>();
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_error_typedef_direct() async {
-    String code = r'''
-class A<K, V extends K> {}
-typedef void F<T extends A>();
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
-  }
-
-  test_notInstantiatedBound_ok_class() async {
-    String code = r'''
-class A<T extends int> {}
-class C1<T extends A> {}
-class C2<T extends List<A>> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_notInstantiatedBound_ok_class_class2() async {
-    String code = r'''
-class A<T> {}
-class C<T extends A<int>> {}
-class D<T extends C> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_notInstantiatedBound_ok_class_class3() async {
-    String code = r'''
-class A<T> {}
-class B<T extends int> {}
-class C<T extends A<B>> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_notInstantiatedBound_ok_class_class4() async {
-    String code = r'''
-class A<K, V> {}
-class B<T extends int> {}
-class C<T extends A<B, B>> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_notInstantiatedBound_ok_class_function() async {
-    String code = r'''
-class A<T extends void Function()> {}
-class B<T extends A> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_notInstantiatedBound_ok_class_typedef() async {
-    String code = r'''
-typedef void F<T extends int>();
-class C<T extends F> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_notInstantiatedBound_ok_typedef_class() async {
-    String code = r'''
-class C<T extends int> {}
-typedef void F<T extends C>();
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
-  test_objectMethodOnFunctions_Anonymous() async {
-    String code = r'''
-void main() {
-  var f = (x) => 3;
-  // No errors, correct type
-  var t0 = f.toString();
-  var t1 = f.toString;
-  var t2 = f.hashCode;
-
-  // Expressions, no errors, correct type
-  var t3 = (f).toString();
-  var t4 = (f).toString;
-  var t5 = (f).hashCode;
-
-  // Cascades, no errors
-  f..toString();
-  f..toString;
-  f..hashCode;
-
-  // Expression cascades, no errors
-  (f)..toString();
-  (f)..toString;
-  (f)..hashCode;
-}''';
-    await _objectMethodOnFunctions_helper2(code);
-  }
-
-  test_objectMethodOnFunctions_Function() async {
-    String code = r'''
-void main() {
-  Function f;
-  // No errors, correct type
-  var t0 = f.toString();
-  var t1 = f.toString;
-  var t2 = f.hashCode;
-
-  // Expressions, no errors, correct type
-  var t3 = (f).toString();
-  var t4 = (f).toString;
-  var t5 = (f).hashCode;
-
-  // Cascades, no errors
-  f..toString();
-  f..toString;
-  f..hashCode;
-
-  // Expression cascades, no errors
-  (f)..toString();
-  (f)..toString;
-  (f)..hashCode;
-}''';
-    await _objectMethodOnFunctions_helper2(code);
-  }
-
-  test_objectMethodOnFunctions_Static() async {
-    String code = r'''
-int f(int x) => null;
-void main() {
-  // No errors, correct type
-  var t0 = f.toString();
-  var t1 = f.toString;
-  var t2 = f.hashCode;
-
-  // Expressions, no errors, correct type
-  var t3 = (f).toString();
-  var t4 = (f).toString;
-  var t5 = (f).hashCode;
-
-  // Cascades, no errors
-  f..toString();
-  f..toString;
-  f..hashCode;
-
-  // Expression cascades, no errors
-  (f)..toString();
-  (f)..toString;
-  (f)..hashCode;
-}''';
-    await _objectMethodOnFunctions_helper2(code);
-  }
-
-  test_objectMethodOnFunctions_Typedef() async {
-    String code = r'''
-typedef bool Predicate<T>(T object);
-
-void main() {
-  Predicate<int> f;
-  // No errors, correct type
-  var t0 = f.toString();
-  var t1 = f.toString;
-  var t2 = f.hashCode;
-
-  // Expressions, no errors, correct type
-  var t3 = (f).toString();
-  var t4 = (f).toString;
-  var t5 = (f).hashCode;
-
-  // Cascades, no errors
-  f..toString();
-  f..toString;
-  f..hashCode;
-
-  // Expression cascades, no errors
-  (f)..toString();
-  (f)..toString;
-  (f)..hashCode;
-}''';
-    await _objectMethodOnFunctions_helper2(code);
-  }
-
-  test_returnOfInvalidType_object_void() async {
-    await assertErrorsInCode(
-        "Object f() { void voidFn() => null; return voidFn(); }",
-        [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]);
-  }
-
-  test_setterWithDynamicTypeIsError() async {
-    Source source = addSource(r'''
-class A {
-  dynamic set f(String s) => null;
-}
-dynamic set g(int x) => null;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
-      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
-    ]);
-    verify([source]);
-  }
-
-  test_setterWithExplicitVoidType_returningVoid() async {
-    Source source = addSource(r'''
-void returnsVoid() {}
-class A {
-  void set f(String s) => returnsVoid();
-}
-void set g(int x) => returnsVoid();
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_setterWithNoVoidType() async {
-    Source source = addSource(r'''
-class A {
-  set f(String s) {
-    return '42';
-  }
-}
-set g(int x) => 42;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
-    ]);
-    verify([source]);
-  }
-
-  test_setterWithNoVoidType_returningVoid() async {
-    Source source = addSource(r'''
-void returnsVoid() {}
-class A {
-  set f(String s) => returnsVoid();
-}
-set g(int x) => returnsVoid();
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_setterWithOtherTypeIsError() async {
-    Source source = addSource(r'''
-class A {
-  String set f(String s) => null;
-}
-Object set g(x) => null;
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
-      StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
-    ]);
-    verify([source]);
-  }
-
-  test_ternaryOperator_null_left() async {
-    String code = r'''
-main() {
-  var foo = (true) ? null : 3;
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'int');
-  }
-
-  test_ternaryOperator_null_right() async {
-    String code = r'''
-main() {
-  var foo = (true) ? 3 : null;
-}
-''';
-    await resolveTestUnit(code);
-    expectInitializerType('foo', 'int');
-  }
-
-  Future<void> _objectMethodOnFunctions_helper2(String code) async {
-    await resolveTestUnit(code);
-    expectIdentifierType('t0', "String");
-    expectIdentifierType('t1', "() → String");
-    expectIdentifierType('t2', "int");
-    expectIdentifierType('t3', "String");
-    expectIdentifierType('t4', "() → String");
-    expectIdentifierType('t5', "int");
-  }
-}
-
-@reflectiveTest
-class StrongModeTypePropagationTest extends ResolverTestCase {
-  @override
-  void setUp() {
-    super.setUp();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    resetWith(options: options);
-  }
-
-  test_foreachInference_dynamic_disabled() async {
-    String code = r'''
-main() {
-  var list = <int>[];
-  for (dynamic v in list) {
-    v; // marker
-  }
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertPropagatedIterationType(code, unit, typeProvider.dynamicType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
-  }
-
-  test_foreachInference_reusedVar_disabled() async {
-    String code = r'''
-main() {
-  var list = <int>[];
-  var v;
-  for (v in list) {
-    v; // marker
-  }
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertPropagatedIterationType(code, unit, typeProvider.dynamicType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
-  }
-
-  test_foreachInference_var() async {
-    String code = r'''
-main() {
-  var list = <int>[];
-  for (var v in list) {
-    v; // marker
-  }
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertPropagatedIterationType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_foreachInference_var_iterable() async {
-    String code = r'''
-main() {
-  Iterable<int> list = <int>[];
-  for (var v in list) {
-    v; // marker
-  }
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertPropagatedIterationType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_foreachInference_var_stream() async {
-    String code = r'''
-import 'dart:async';
-main() async {
-  Stream<int> stream = null;
-  await for (var v in stream) {
-    v; // marker
-  }
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertPropagatedIterationType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_inconsistentMethodInheritance_inferFunctionTypeFromTypedef() async {
-    Source source = addSource(r'''
-typedef bool F<E>(E argument);
-
-abstract class Base {
-  f<E extends int>(F<int> x);
-}
-
-abstract class BaseCopy extends Base {
-}
-
-abstract class Override implements Base, BaseCopy {
-  f<E extends int>(x) => null;
-}
-
-class C extends Override implements Base {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_localVariableInference_bottom_disabled() async {
-    String code = r'''
-main() {
-  var v = null;
-  v; // marker
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.dynamicType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
-  }
-
-  test_localVariableInference_constant() async {
-    String code = r'''
-main() {
-  var v = 3;
-  v; // marker
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_declaredType_disabled() async {
-    String code = r'''
-main() {
-  dynamic v = 3;
-  v; // marker
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.dynamicType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
-  }
-
-  test_localVariableInference_noInitializer_disabled() async {
-    String code = r'''
-main() {
-  var v;
-  v = 3;
-  v; // marker
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.dynamicType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.dynamicType);
-  }
-
-  test_localVariableInference_transitive_field_inferred_lexical() async {
-    String code = r'''
-class A {
-  final x = 3;
-  f() {
-    var v = x;
-    return v; // marker
-  }
-}
-main() {
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_field_inferred_reversed() async {
-    String code = r'''
-class A {
-  f() {
-    var v = x;
-    return v; // marker
-  }
-  final x = 3;
-}
-main() {
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_field_lexical() async {
-    String code = r'''
-class A {
-  int x = 3;
-  f() {
-    var v = x;
-    return v; // marker
-  }
-}
-main() {
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_field_reversed() async {
-    String code = r'''
-class A {
-  f() {
-    var v = x;
-    return v; // marker
-  }
-  int x = 3;
-}
-main() {
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_list_local() async {
-    String code = r'''
-main() {
-  var x = <int>[3];
-  var v = x[0];
-  v; // marker
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_local() async {
-    String code = r'''
-main() {
-  var x = 3;
-  var v = x;
-  v; // marker
-}''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_toplevel_inferred_lexical() async {
-    String code = r'''
-final x = 3;
-main() {
-  var v = x;
-  v; // marker
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_toplevel_inferred_reversed() async {
-    String code = r'''
-main() {
-  var v = x;
-  v; // marker
-}
-final x = 3;
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_toplevel_lexical() async {
-    String code = r'''
-int x = 3;
-main() {
-  var v = x;
-  v; // marker
-}
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-
-  test_localVariableInference_transitive_toplevel_reversed() async {
-    String code = r'''
-main() {
-  var v = x;
-  v; // marker
-}
-int x = 3;
-''';
-    CompilationUnit unit = await resolveSource(code);
-    assertAssignedType(code, unit, typeProvider.intType);
-    assertTypeOfMarkedExpression(code, unit, typeProvider.intType);
-  }
-}
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index ac07574..5215932 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -7,28 +7,22 @@
 import 'all_the_rest_test.dart' as all_the_rest;
 import 'checked_mode_compile_time_error_code_driver_test.dart'
     as checked_mode_compile_time_error_code_driver_test;
-import 'checked_mode_compile_time_error_code_test.dart'
-    as checked_mode_compile_time_error_code_test;
 import 'compile_time_error_code_driver_test.dart'
     as compile_time_error_code_driver_test;
-import 'compile_time_error_code_test.dart' as compile_time_error_code_test;
-import 'constant_test.dart' as constant_test;
+import 'constant_test.dart'
+    as constant_test; // ignore: deprecated_member_use_from_same_package
 import 'declaration_resolver_test.dart' as declaration_resolver_test;
 import 'element_resolver_test.dart' as element_resolver_test;
 import 'engine_test.dart' as engine_test;
 import 'error_suppression_driver_test.dart' as error_suppression_driver_test;
-import 'error_suppression_test.dart' as error_suppression_test;
 import 'hint_code_driver_test.dart' as hint_code_driver_test;
 import 'hint_code_test.dart' as hint_code_test;
 import 'inheritance_manager_test.dart' as inheritance_manager_test;
 import 'invalid_code_driver_test.dart' as invalid_code_driver_test;
-import 'invalid_code_test.dart' as invalid_code_test;
 import 'java_core_test.dart' as java_core_test;
 import 'java_io_test.dart' as java_io_test;
 import 'non_error_resolver_driver_test.dart' as non_error_resolver_driver_test;
-import 'non_error_resolver_test.dart' as non_error_resolver_test;
 import 'non_hint_code_driver_test.dart' as non_hint_code_driver_test;
-import 'non_hint_code_test.dart' as non_hint_code_test;
 import 'parser_fasta_test.dart' as parser_fasta_test;
 import 'parser_test.dart' as parser_test;
 import 'resolver_driver_test.dart' as resolver_driver_test;
@@ -42,12 +36,10 @@
 import 'static_type_analyzer_test.dart' as static_type_analyzer_test;
 import 'static_type_warning_code_driver_test.dart'
     as static_type_warning_code_driver_test;
-import 'static_type_warning_code_test.dart' as static_type_warning_code_test;
 import 'static_warning_code_driver_test.dart'
     as static_warning_code_driver_test;
 import 'static_warning_code_test.dart' as static_warning_code_test;
 import 'strong_mode_driver_test.dart' as strong_mode_driver_test;
-import 'strong_mode_test.dart' as strong_mode_test;
 import 'type_system_test.dart' as type_system_test;
 import 'utilities_dart_test.dart' as utilities_dart_test;
 import 'utilities_test.dart' as utilities_test;
@@ -56,26 +48,20 @@
   defineReflectiveSuite(() {
     all_the_rest.main();
     checked_mode_compile_time_error_code_driver_test.main();
-    checked_mode_compile_time_error_code_test.main();
     compile_time_error_code_driver_test.main();
-    compile_time_error_code_test.main();
     constant_test.main();
     declaration_resolver_test.main();
     element_resolver_test.main();
     engine_test.main();
     error_suppression_driver_test.main();
-    error_suppression_test.main();
     hint_code_driver_test.main();
     hint_code_test.main();
     inheritance_manager_test.main();
     invalid_code_driver_test.main();
-    invalid_code_test.main();
     java_core_test.main();
     java_io_test.main();
     non_error_resolver_driver_test.main();
-    non_error_resolver_test.main();
     non_hint_code_driver_test.main();
-    non_hint_code_test.main();
     parser_fasta_test.main();
     parser_test.main();
     resolver_driver_test.main();
@@ -87,11 +73,9 @@
     static_type_analyzer_driver_test.main();
     static_type_analyzer_test.main();
     static_type_warning_code_driver_test.main();
-    static_type_warning_code_test.main();
     static_warning_code_driver_test.main();
     static_warning_code_test.main();
     strong_mode_driver_test.main();
-    strong_mode_test.main();
     type_system_test.main();
     utilities_dart_test.main();
     utilities_test.main();
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index 74a0179..899f832 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_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.
 
-// ignore: deprecated_member_use
+// ignore: deprecated_member_use_from_same_package
 import 'package:analyzer/analyzer.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index 247d10f..d55cd52 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -39,11 +39,6 @@
     ['x']
   ]);
 
-  AnalysisError assignment_no_type = new AnalysisError(
-      new TestSource(), 0, 1, StaticWarningCode.ASSIGNMENT_TO_TYPE, [
-    ['x']
-  ]);
-
   // We in-line a lint code here in order to avoid adding a dependency on the
   // linter package.
   AnalysisError annotate_overrides = new AnalysisError(
@@ -68,15 +63,7 @@
       expect(getProcessor(invalid_assignment).severity, ErrorSeverity.ERROR);
       expect(getProcessor(missing_return).severity, isNull);
       expect(getProcessor(unused_local_variable), isNull);
-      expect(getProcessor(use_of_void_result), isNotNull);
-    });
-
-    test('upgrades static warnings to errors in strong mode', () {
-      configureOptions('''
-analyzer:
-  strong-mode: true
-''');
-      expect(getProcessor(assignment_no_type).severity, ErrorSeverity.ERROR);
+      expect(getProcessor(use_of_void_result), isNull);
     });
 
     test('does not upgrade other warnings to errors in strong mode', () {
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index 643b514..f356dc3 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -5,7 +5,8 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
-import 'embedder_test.dart' as embedder_test; // ignore: deprecated_member_use
+import 'embedder_test.dart'
+    as embedder_test; // ignore: deprecated_member_use_from_same_package
 import 'error_processor_test.dart' as error_processor_test;
 import 'package_map_resolver_test.dart' as package_map_resolver_test;
 import 'path_filter_test.dart' as path_filter_test;
diff --git a/pkg/analyzer/test/src/abstract_single_unit.dart b/pkg/analyzer/test/src/abstract_single_unit.dart
index 164b2f5..d42f775 100644
--- a/pkg/analyzer/test/src/abstract_single_unit.dart
+++ b/pkg/analyzer/test/src/abstract_single_unit.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 23e564e..5c6cd3c 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -111,26 +111,6 @@
     fail('Incomplete test');
   }
 
-  void test_cmdline_lint_default() {
-    _defineMockLintRules();
-    ArgParser argParser = new ArgParser();
-    defineAnalysisArguments(argParser);
-    ArgResults argResults = argParser.parse(['--$lintsFlag']);
-    var builder = new ContextBuilder(resourceProvider, sdkManager, contentCache,
-        options: createContextBuilderOptions(argResults));
-
-    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = Registry.ruleRegistry.defaultRules;
-
-    String path = convertPath('/some/directory/path');
-    String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
-    newFile(filePath);
-
-    AnalysisOptions options = builder.getAnalysisOptions(path);
-    _expectEqualOptions(options, expected);
-  }
-
   void test_cmdline_lint_defined() {
     _defineMockLintRules();
     ArgParser argParser = new ArgParser();
@@ -881,44 +861,44 @@
     newFile('/workspace/.packages');
     newFolder('/workspace/.dart_tool/build/generated/project/lib');
     newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<PackageBuildWorkspace>());
   }
 
   void test_createWorkspace_hasPackagesFile_hasPubspec() {
     newFile('/workspace/.packages');
     newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<PubWorkspace>());
   }
 
   void test_createWorkspace_hasPackagesFile_noMarkerFiles() {
     newFile('/workspace/.packages');
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<BasicWorkspace>());
   }
 
   void test_createWorkspace_noPackagesFile_hasDartToolAndPubspec() {
     newFolder('/workspace/.dart_tool/build/generated/project/lib');
     newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<PackageBuildWorkspace>());
   }
 
   void test_createWorkspace_noPackagesFile_hasPubspec() {
     newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<PubWorkspace>());
   }
 
   void test_createWorkspace_noPackagesFile_noMarkerFiles() {
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<BasicWorkspace>());
   }
 
@@ -926,24 +906,24 @@
     newFolder('/workspace/.jiri_root');
     newFile(
         '/workspace/out/debug-x87_128/dartlang/gen/project/lib/lib.packages');
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<GnWorkspace>());
   }
 
   void test_createWorkspace_noPackagesFile_hasBazelMarkerFiles() {
     newFile('/workspace/WORKSPACE');
     newFolder('/workspace/bazel-genfiles');
-    Workspace workspace = ContextBuilder.createWorkspace(
-        resourceProvider, '/workspace/project/lib/lib.dart', builder);
+    Workspace workspace = ContextBuilder.createWorkspace(resourceProvider,
+        convertPath('/workspace/project/lib/lib.dart'), builder);
     expect(workspace, TypeMatcher<BazelWorkspace>());
   }
 
   _defineMockLintRules() {
     _mockLintRule = new _MockLintRule('mock_lint_rule');
-    Registry.ruleRegistry.registerDefault(_mockLintRule);
+    Registry.ruleRegistry.register(_mockLintRule);
     _mockLintRule2 = new _MockLintRule('mock_lint_rule2');
-    Registry.ruleRegistry.registerDefault(_mockLintRule2);
+    Registry.ruleRegistry.register(_mockLintRule2);
     _mockLintRule3 = new _MockLintRule('mock_lint_rule3');
     Registry.ruleRegistry.register(_mockLintRule3);
     _mockPublicMemberApiDocs = new _MockLintRule('public_member_api_docs');
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
deleted file mode 100644
index 5822d82..0000000
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ /dev/null
@@ -1,2984 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/dart/element/visitor.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/task/api/dart.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:html/dom.dart' show Document;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/engine_test.dart';
-import '../../generated/test_support.dart';
-import '../../util/element_type_matchers.dart';
-import 'abstract_context.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisContextImplTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisContextImplTest extends AbstractContextTest
-    with ResourceProviderMixin {
-  void fail_getErrors_html_some() {
-    Source source = addSource("/test.html", r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-</head></html>''');
-    AnalysisErrorInfo errorInfo = context.getErrors(source);
-    expect(errorInfo, isNotNull);
-    List<AnalysisError> errors = errorInfo.errors;
-    expect(errors, hasLength(0));
-    errors = context.computeErrors(source);
-    expect(errors, hasLength(2));
-  }
-
-  Future fail_implicitAnalysisEvents_removed() async {
-    AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
-    context.implicitAnalysisEvents.listen(listener.onData);
-    //
-    // Create a file that references an file that is not explicitly being
-    // analyzed and fully analyze it. Ensure that the listener is told about
-    // the implicitly analyzed file.
-    //
-    Source sourceA = newSource('/a.dart', "library a; import 'b.dart';");
-    Source sourceB = newSource('/b.dart', "library b;");
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(sourceA);
-    context.applyChanges(changeSet);
-    context.computeErrors(sourceA);
-    await pumpEventQueue();
-    listener.expectAnalyzed(sourceB);
-    //
-    // Remove the reference and ensure that the listener is told that we're no
-    // longer implicitly analyzing the file.
-    //
-    context.setContents(sourceA, "library a;");
-    context.computeErrors(sourceA);
-    await pumpEventQueue();
-    listener.expectNotAnalyzed(sourceB);
-  }
-
-  void fail_performAnalysisTask_importedLibraryDelete_html() {
-    // NOTE: This was failing before converting to the new task model.
-    Source htmlSource = addSource("/page.html", r'''
-<html><body><script type="application/dart">
-  import 'libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    Source libBSource = addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    context.computeErrors(htmlSource);
-    expect(
-        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 1");
-    expect(!_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)),
-        isTrue,
-        reason: "htmlSource doesn't have errors");
-    // remove libB.dart content and analyze
-    context.setContents(libBSource, null);
-    _analyzeAll_assertFinished();
-    context.computeErrors(htmlSource);
-    AnalysisErrorInfo errors = context.getErrors(htmlSource);
-    expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue,
-        reason: "htmlSource has an error");
-  }
-
-  void fail_recordLibraryElements() {
-    fail("Implement this");
-  }
-
-  @override
-  void tearDown() {
-    context = null;
-    sourceFactory = null;
-    super.tearDown();
-  }
-
-  Future test_applyChanges_add() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    expect(context.sourcesNeedingProcessing, isEmpty);
-    Source source = newSource('/test.dart');
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    expect(context.sourcesNeedingProcessing, contains(source));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_add_makesExplicit() {
-    Source source = newSource('/test.dart');
-    // get the entry, it's not explicit
-    CacheEntry entry = context.getCacheEntry(source);
-    expect(entry.explicitlyAdded, isFalse);
-    // add the source
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    // now the entry is explicit
-    expect(entry.explicitlyAdded, isTrue);
-  }
-
-  void test_applyChanges_addNewImport_invalidateLibraryCycle() {
-    context.analysisOptions =
-        new AnalysisOptionsImpl.from(context.analysisOptions);
-    Source embedder = addSource('/a.dart', r'''
-library a;
-import 'b.dart';
-//import 'c.dart';
-''');
-    addSource('/b.dart', r'''
-library b;
-import 'a.dart';
-''');
-    addSource('/c.dart', r'''
-library c;
-import 'b.dart';
-''');
-    _performPendingAnalysisTasks();
-    // Add a new import into a.dart, this should invalidate its library cycle.
-    // If it doesn't, we will get a task cycle exception.
-    context.setContents(embedder, r'''
-library a;
-import 'b.dart';
-import 'c.dart';
-''');
-    _performPendingAnalysisTasks();
-    expect(context.getCacheEntry(embedder).exception, isNull);
-  }
-
-  Future test_applyChanges_change() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    expect(context.sourcesNeedingProcessing, isEmpty);
-    Source source = newSource('/test.dart');
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    context.applyChanges(changeSet1);
-    expect(context.sourcesNeedingProcessing, contains(source));
-    Source source2 = newSource('/test2.dart');
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedSource(source);
-    context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change_content() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    expect(context.sourcesNeedingProcessing, isEmpty);
-    Source source = newSource('/test.dart');
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    context.applyChanges(changeSet1);
-    expect(context.sourcesNeedingProcessing, contains(source));
-    Source source2 = newSource('/test2.dart');
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedContent(source, 'library test;');
-    context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_change_flush_element() {
-    Source librarySource = addSource("/lib.dart", r'''
-library lib;
-int a = 0;''');
-    expect(context.computeLibraryElement(librarySource), isNotNull);
-    context.setContents(librarySource, r'''
-library lib;
-int aa = 0;''');
-    expect(context.getLibraryElement(librarySource), isNull);
-  }
-
-  Future test_applyChanges_change_multiple() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = addSource("/lib.dart", libraryContents1);
-    String partContents1 = r'''
-part of lib;
-int b = a;''';
-    Source partSource = addSource("/part.dart", partContents1);
-    context.computeLibraryElement(librarySource);
-    String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
-    context.setContents(librarySource, libraryContents2);
-    String partContents2 = r'''
-part of lib;
-int b = aa;''';
-    context.setContents(partSource, partContents2);
-    context.computeLibraryElement(librarySource);
-    CompilationUnit libraryUnit =
-        context.resolveCompilationUnit2(librarySource, librarySource);
-    expect(libraryUnit, isNotNull);
-    CompilationUnit partUnit =
-        context.resolveCompilationUnit2(partSource, librarySource);
-    expect(partUnit, isNotNull);
-    TopLevelVariableDeclaration declaration =
-        libraryUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element declarationElement =
-        declaration.variables.variables[0].declaredElement;
-    TopLevelVariableDeclaration use =
-        partUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element useElement =
-        (use.variables.variables[0].initializer as SimpleIdentifier)
-            .staticElement;
-    expect((useElement as PropertyAccessorElement).variable,
-        same(declarationElement));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change_range() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    expect(context.sourcesNeedingProcessing, isEmpty);
-    Source source = newSource('/test.dart');
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    context.applyChanges(changeSet1);
-    expect(context.sourcesNeedingProcessing, contains(source));
-    Source source2 = newSource('/test2.dart');
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedRange(source, 'library test;', 0, 0, 13);
-    context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_changedSource_updateModificationTime() {
-    File file = newFile('/test.dart', content: 'var V = 1;');
-    Source source = file.createSource();
-    context.applyChanges(new ChangeSet()..addedSource(source));
-    // Analyze all.
-    _analyzeAll_assertFinished();
-    expect(context.analysisCache.getState(source, RESOLVED_UNIT),
-        CacheState.INVALID);
-    // Update the file and notify the context about the change.
-    modifyFile('/test.dart', 'var V = 2;');
-    context.applyChanges(new ChangeSet()..changedSource(source));
-    // The analysis results are invalidated.
-    // We have seen the new contents, so 'modificationTime' is also updated.
-    expect(context.analysisCache.getState(source, RESOLVED_UNIT),
-        CacheState.INVALID);
-    expect(
-        context.getCacheEntry(source).modificationTime, file.modificationStamp);
-  }
-
-  void test_applyChanges_empty() {
-    context.applyChanges(new ChangeSet());
-    expect(context.performAnalysisTask().changeNotices, isNull);
-  }
-
-  void test_applyChanges_incremental_resetDriver() {
-    // AnalysisContext incremental analysis has been removed
-    if (context != null) return;
-    throw 'is this test used by the new analysis driver?';
-
-//    context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
-//    Source source = addSource(
-//        "/test.dart",
-//        r'''
-//main() {
-//  print(42);
-//}
-//''');
-//    _performPendingAnalysisTasks();
-//    expect(context.getErrors(source).errors, hasLength(0));
-//    // Update the source to have a parse error.
-//    // This is an incremental change, but we always invalidate DART_ERRORS.
-//    context.setContents(
-//        source,
-//        r'''
-//main() {
-//  print(42)
-//}
-//''');
-//    AnalysisCache cache = context.analysisCache;
-//    expect(cache.getValue(source, PARSE_ERRORS), hasLength(1));
-//    expect(cache.getState(source, DART_ERRORS), CacheState.INVALID);
-//    // Perform enough analysis to prepare inputs (is not actually tested) for
-//    // the DART_ERRORS computing task, but don't compute it yet.
-//    context.performAnalysisTask();
-//    context.performAnalysisTask();
-//    expect(cache.getState(source, DART_ERRORS), CacheState.INVALID);
-//    // Update the source so that PARSE_ERRORS is empty.
-//    context.setContents(
-//        source,
-//        r'''
-//main() {
-//  print(42);
-//}
-//''');
-//    expect(cache.getValue(source, PARSE_ERRORS), hasLength(0));
-//    // After full analysis DART_ERRORS should also be empty.
-//    _performPendingAnalysisTasks();
-//    expect(cache.getValue(source, DART_ERRORS), hasLength(0));
-//    expect(context.getErrors(source).errors, hasLength(0));
-  }
-
-  void test_applyChanges_overriddenSource() {
-    String content = "library test;";
-    Source source = addSource("/test.dart", content);
-    context.setContents(source, content);
-    context.computeErrors(source);
-    while (!context.sourcesNeedingProcessing.isEmpty) {
-      context.performAnalysisTask();
-    }
-    // Adding the source as a changedSource should have no effect since
-    // it is already overridden in the content cache.
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(source);
-    context.applyChanges(changeSet);
-    expect(context.sourcesNeedingProcessing, hasLength(0));
-  }
-
-  void test_applyChanges_recompute_exportNamespace() {
-    Source libSource = addSource("/lib.dart", r'''
-class A {}
-''');
-    Source exporterSource = addSource("/exporter.dart", r'''
-export 'lib.dart';
-''');
-    _performPendingAnalysisTasks();
-    // initially: A
-    {
-      LibraryElement libraryElement =
-          context.getResult(exporterSource, LIBRARY_ELEMENT1);
-      expect(libraryElement.exportNamespace.definedNames.keys,
-          unorderedEquals(['A']));
-    }
-    // after update: B
-    context.setContents(libSource, r'''
-class B {}''');
-    _performPendingAnalysisTasks();
-    {
-      LibraryElement libraryElement =
-          context.getResult(exporterSource, LIBRARY_ELEMENT1);
-      expect(libraryElement.exportNamespace.definedNames.keys,
-          unorderedEquals(['B']));
-    }
-  }
-
-  Future test_applyChanges_remove() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    String libAContents = r'''
-library libA;
-import 'libB.dart';''';
-    Source libA = addSource("/libA.dart", libAContents);
-    String libBContents = "library libB;";
-    Source libB = addSource("/libB.dart", libBContents);
-    LibraryElement libAElement = context.computeLibraryElement(libA);
-    expect(libAElement, isNotNull);
-    List<LibraryElement> importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(2));
-    context.computeErrors(libA);
-    context.computeErrors(libB);
-    context.setContents(libB, null);
-    _removeSource(libB);
-    List<Source> sources = context.sourcesNeedingProcessing;
-    expect(sources, hasLength(1));
-    expect(sources[0], same(libA));
-    libAElement = context.computeLibraryElement(libA);
-    importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(2));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  /**
-   * IDEA uses the following scenario:
-   * 1. Add overlay.
-   * 2. Change overlay.
-   * 3. If the contents of the document buffer is the same as the contents
-   *    of the file, remove overlay.
-   * So, we need to try to use incremental resolution for removing overlays too.
-   */
-  void test_applyChanges_remove_incremental() {
-    // AnalysisContext incremental analysis has been removed
-    if (context != null) return;
-    throw 'is this test used by the new analysis driver?';
-
-//    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-//    Source source = resourceProvider
-//        .newFile(
-//            '/test.dart',
-//            r'''
-//main() {
-//  print(1);
-//}
-//''')
-//        .createSource();
-//    context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
-//    context.applyChanges(new ChangeSet()..addedSource(source));
-//    // remember compilation unit
-//    _analyzeAll_assertFinished();
-//    CompilationUnit unit = context.getResolvedCompilationUnit2(source, source);
-//    // add overlay
-//    context.setContents(
-//        source,
-//        r'''
-//main() {
-//  print(12);
-//}
-//''');
-//    _analyzeAll_assertFinished();
-//    expect(context.getResolvedCompilationUnit2(source, source), unit);
-//    // remove overlay
-//    context.setContents(source, null);
-//    _analyzeAll_assertFinished();
-//    expect(context.getResolvedCompilationUnit2(source, source), unit);
-  }
-
-  Future test_applyChanges_removeContainer() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    String libAContents = r'''
-library libA;
-import 'libB.dart';''';
-    Source libA = addSource("/libA.dart", libAContents);
-    String libBContents = "library libB;";
-    Source libB = addSource("/libB.dart", libBContents);
-    context.computeLibraryElement(libA);
-    context.computeErrors(libA);
-    context.computeErrors(libB);
-    ChangeSet changeSet = new ChangeSet();
-    SourceContainer removedContainer =
-        new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
-    changeSet.removedContainer(removedContainer);
-    context.applyChanges(changeSet);
-    List<Source> sources = context.sourcesNeedingProcessing;
-    expect(sources, hasLength(1));
-    expect(sources[0], same(libA));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_removeUsedLibrary_addAgain() {
-    String codeA = r'''
-import 'b.dart';
-B b = null;
-''';
-    String codeB = r'''
-class B {}
-''';
-    Source a = addSource('/a.dart', codeA);
-    Source b = addSource('/b.dart', codeB);
-    CacheState getErrorsState(Source source) =>
-        context.analysisCache.getState(source, LIBRARY_ERRORS_READY);
-    _performPendingAnalysisTasks();
-    expect(context.getErrors(a).errors, hasLength(0));
-    // Remove b.dart - errors in a.dart are invalidated and recomputed.
-    // Now a.dart has an error.
-    _removeSource(b);
-    expect(getErrorsState(a), CacheState.INVALID);
-    _performPendingAnalysisTasks();
-    expect(getErrorsState(a), CacheState.VALID);
-    expect(context.getErrors(a).errors, hasLength(isPositive));
-    // Add b.dart - errors in a.dart are invalidated and recomputed.
-    // The reason is that a.dart adds dependencies on (not existing) b.dart
-    // results in cache.
-    // Now a.dart does not have errors.
-    addSource('/b.dart', codeB);
-    expect(getErrorsState(a), CacheState.INVALID);
-    _performPendingAnalysisTasks();
-    expect(getErrorsState(a), CacheState.VALID);
-    expect(context.getErrors(a).errors, hasLength(0));
-  }
-
-  void test_cacheConsistencyValidator_computed_deleted() {
-    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
-    var stat = PerformanceStatistics.cacheConsistencyValidationStatistics;
-    stat.reset();
-    // Add sources.
-    String path1 = '/test1.dart';
-    String path2 = '/test2.dart';
-    Source source1 = newFile(path1, content: '// 1-1').createSource();
-    Source source2 = newFile(path2, content: '// 2-1').createSource();
-    context.applyChanges(
-        new ChangeSet()..addedSource(source1)..addedSource(source2));
-    // Same modification times.
-    expect(
-        validator.sourceModificationTimesComputed([source1, source2],
-            [source1.modificationStamp, source2.modificationStamp]),
-        isFalse);
-    expect(stat.numOfChanged, 0);
-    expect(stat.numOfRemoved, 0);
-    // Add overlay
-    context.setContents(source1, '// 1-2');
-    expect(
-        validator.sourceModificationTimesComputed(
-            [source1, source2], [-1, source2.modificationStamp]),
-        isFalse);
-    context.setContents(source1, null);
-    expect(stat.numOfChanged, 0);
-    expect(stat.numOfRemoved, 0);
-    // Different modification times.
-    expect(
-        validator.sourceModificationTimesComputed(
-            [source1, source2], [-1, source2.modificationStamp]),
-        isTrue);
-    expect(stat.numOfChanged, 0);
-    expect(stat.numOfRemoved, 1);
-  }
-
-  void test_cacheConsistencyValidator_computed_modified() {
-    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
-    var stat = PerformanceStatistics.cacheConsistencyValidationStatistics;
-    stat.reset();
-    // Add sources.
-    String path1 = '/test1.dart';
-    String path2 = '/test2.dart';
-    Source source1 = newFile(path1, content: '// 1-1').createSource();
-    Source source2 = newFile(path2, content: '// 2-1').createSource();
-    context.applyChanges(
-        new ChangeSet()..addedSource(source1)..addedSource(source2));
-    // Same modification times.
-    expect(
-        validator.sourceModificationTimesComputed([source1, source2],
-            [source1.modificationStamp, source2.modificationStamp]),
-        isFalse);
-    expect(stat.numOfChanged, 0);
-    expect(stat.numOfRemoved, 0);
-    // Add overlay
-    context.setContents(source1, '// 1-2');
-    expect(
-        validator.sourceModificationTimesComputed([source1, source2],
-            [source1.modificationStamp + 1, source2.modificationStamp]),
-        isFalse);
-    context.setContents(source1, null);
-    expect(stat.numOfChanged, 0);
-    expect(stat.numOfRemoved, 0);
-    // Different modification times.
-    expect(
-        validator.sourceModificationTimesComputed([source1, source2],
-            [source1.modificationStamp + 1, source2.modificationStamp]),
-        isTrue);
-    expect(stat.numOfChanged, 1);
-    expect(stat.numOfRemoved, 0);
-  }
-
-  void test_cacheConsistencyValidator_getSources() {
-    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
-    // Add sources.
-    String path1 = '/test1.dart';
-    String path2 = '/test2.dart';
-    Source source1 = newFile(path1, content: '// 1-1').createSource();
-    Source source2 = newFile(path2, content: '// 2-1').createSource();
-    context.applyChanges(
-        new ChangeSet()..addedSource(source1)..addedSource(source2));
-    // Verify.
-    expect(validator.getSourcesToComputeModificationTimes(),
-        unorderedEquals([source1, source2]));
-  }
-
-  void test_computeDocumentationComment_class_block() {
-    String comment = "/** Comment */";
-    Source source = addSource("/test.dart", """
-$comment
-class A {}""");
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    expect(context.computeDocumentationComment(classElement), comment);
-  }
-
-  void test_computeDocumentationComment_class_none() {
-    Source source = addSource("/test.dart", "class A {}");
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    expect(context.computeDocumentationComment(classElement), isNull);
-  }
-
-  void test_computeDocumentationComment_class_singleLine_multiple_EOL_n() {
-    String comment = "/// line 1\n/// line 2\n/// line 3\n";
-    Source source = addSource("/test.dart", "${comment}class A {}");
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    String actual = context.computeDocumentationComment(classElement);
-    expect(actual, "/// line 1\n/// line 2\n/// line 3");
-  }
-
-  void test_computeDocumentationComment_class_singleLine_multiple_EOL_rn() {
-    String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n";
-    Source source = addSource("/test.dart", "${comment}class A {}");
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    String actual = context.computeDocumentationComment(classElement);
-    expect(actual, "/// line 1\n/// line 2\n/// line 3");
-  }
-
-  void test_computeDocumentationComment_exportDirective_block() {
-    String comment = '/** Comment */';
-    Source source = addSource("/test.dart", '''
-$comment
-export 'dart:async';
-''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ExportElement exportElement = libraryElement.exports[0];
-    expect(context.computeDocumentationComment(exportElement), comment);
-  }
-
-  void test_computeDocumentationComment_importDirective_block() {
-    String comment = '/** Comment */';
-    Source source = addSource("/test.dart", '''
-$comment
-import 'dart:async';
-''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ImportElement importElement = libraryElement.imports[0];
-    expect(context.computeDocumentationComment(importElement), comment);
-  }
-
-  void test_computeDocumentationComment_libraryDirective_block() {
-    String comment = '/** Comment */';
-    Source source = addSource("/test.dart", '''
-$comment
-library lib;
-''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    expect(context.computeDocumentationComment(libraryElement), comment);
-  }
-
-  void test_computeDocumentationComment_null() {
-    expect(context.computeDocumentationComment(null), isNull);
-  }
-
-  void test_computeErrors_dart_malformedCode() {
-    Source source = addSource("/lib.dart", "final int , = 42;");
-    List<AnalysisError> errors = context.computeErrors(source);
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_computeErrors_dart_none() {
-    Source source = addSource("/lib.dart", "library lib;");
-    List<AnalysisError> errors = context.computeErrors(source);
-    expect(errors, hasLength(0));
-  }
-
-  @failingTest
-  void test_computeErrors_dart_part() {
-    Source librarySource =
-        addSource("/lib.dart", "library lib; part 'part.dart';");
-    Source partSource = addSource("/part.dart", "part of 'lib';");
-    context.parseCompilationUnit(librarySource);
-    List<AnalysisError> errors = context.computeErrors(partSource);
-    expect(errors, isNotNull);
-    // TODO(28522)
-    fail("Should report that 'lib' isn't the correct URI.");
-  }
-
-  void test_computeErrors_dart_some() {
-    Source source = addSource("/lib.dart", "library 'lib';");
-    List<AnalysisError> errors = context.computeErrors(source);
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_computeErrors_html_none() {
-    Source source = addSource("/test.html", "<!DOCTYPE html><html></html>");
-    List<AnalysisError> errors = context.computeErrors(source);
-    expect(errors, hasLength(0));
-  }
-
-  void test_computeExportedLibraries_none() {
-    Source source = addSource("/test.dart", "library test;");
-    expect(context.computeExportedLibraries(source), hasLength(0));
-  }
-
-  void test_computeExportedLibraries_some() {
-    //    addSource("/lib1.dart", "library lib1;");
-    //    addSource("/lib2.dart", "library lib2;");
-    Source source = addSource(
-        "/test.dart", "library test; export 'lib1.dart'; export 'lib2.dart';");
-    expect(context.computeExportedLibraries(source), hasLength(2));
-  }
-
-  void test_computeImportedLibraries_none() {
-    Source source = addSource("/test.dart", "library test;");
-    expect(context.computeImportedLibraries(source), hasLength(0));
-  }
-
-  void test_computeImportedLibraries_some() {
-    Source source = addSource(
-        "/test.dart", "library test; import 'lib1.dart'; import 'lib2.dart';");
-    expect(context.computeImportedLibraries(source), hasLength(2));
-  }
-
-  void test_computeKindOf_html() {
-    Source source = addSource("/test.html", "");
-    expect(context.computeKindOf(source), same(SourceKind.HTML));
-  }
-
-  void test_computeKindOf_library() {
-    Source source = addSource("/test.dart", "library lib;");
-    expect(context.computeKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_computeKindOf_libraryAndPart() {
-    Source source = addSource("/test.dart", "library lib; part of lib;");
-    expect(context.computeKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_computeKindOf_part() {
-    Source source = addSource("/test.dart", "part of lib;");
-    expect(context.computeKindOf(source), same(SourceKind.PART));
-  }
-
-  void test_computeLibraryElement() {
-    Source source = addSource("/test.dart", "library lib;");
-    LibraryElement element = context.computeLibraryElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_computeLibraryElement_unresolvedUris() {
-    Source source = addSource("/lib.dart", r'''
-import 'package:foo/bar.dart';
-export 'package:foo/baz.dart';
-''');
-    var libraryElement = context.computeLibraryElement(source);
-    expect(libraryElement.imports, hasLength(2));
-    expect(libraryElement.exports, hasLength(1));
-    expect(libraryElement.imports[0].uri, 'package:foo/bar.dart');
-    expect(libraryElement.imports[0].importedLibrary, isNull);
-    expect(libraryElement.exports[0].uri, 'package:foo/baz.dart');
-    expect(libraryElement.exports[0].exportedLibrary, isNull);
-  }
-
-  void test_computeLineInfo_dart() {
-    Source source = addSource("/test.dart", r'''
-library lib;
-
-main() {}''');
-    LineInfo info = context.computeLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_computeLineInfo_html() {
-    Source source = addSource("/test.html", r'''
-<html>
-  <body>
-    <h1>A</h1>
-  </body>
-</html>''');
-    LineInfo info = context.computeLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  Future test_computeResolvedCompilationUnitAsync() {
-    Source source = addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    _flushAst(source);
-    bool completed = false;
-    context
-        .computeResolvedCompilationUnitAsync(source, source)
-        .then((CompilationUnit unit) {
-      expect(unit, isNotNull);
-      completed = true;
-    });
-    return pumpEventQueue()
-        .then((_) {
-          expect(completed, isFalse);
-          _performPendingAnalysisTasks();
-        })
-        .then((_) => pumpEventQueue())
-        .then((_) {
-          expect(completed, isTrue);
-        });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_afterDispose() {
-    Source source = addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    _flushAst(source);
-    // Dispose of the context.
-    context.dispose();
-    // Any attempt to start an asynchronous computation should return a future
-    // which completes with error.
-    CancelableFuture<CompilationUnit> future =
-        context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have completed with error');
-    }, onError: (error) {
-      expect(error, new TypeMatcher<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_cancel() {
-    Source source = addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    _flushAst(source);
-    CancelableFuture<CompilationUnit> future =
-        context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have been canceled');
-    }, onError: (error) {
-      expect(error, new TypeMatcher<FutureCanceledError>());
-      completed = true;
-    });
-    expect(completed, isFalse);
-    expect(context.pendingFutureSources_forTesting, isNotEmpty);
-    future.cancel();
-    expect(context.pendingFutureSources_forTesting, isEmpty);
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-      expect(context.pendingFutureSources_forTesting, isEmpty);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_dispose() {
-    Source source = addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    _flushAst(source);
-    bool completed = false;
-    CancelableFuture<CompilationUnit> future =
-        context.computeResolvedCompilationUnitAsync(source, source);
-    future.then((CompilationUnit unit) {
-      fail('Future should have completed with error');
-    }, onError: (error) {
-      expect(error, new TypeMatcher<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    expect(completed, isFalse);
-    expect(context.pendingFutureSources_forTesting, isNotEmpty);
-    // Disposing of the context should cause all pending futures to complete
-    // with AnalysisNotScheduled, so that no clients are left hanging.
-    context.dispose();
-    expect(context.pendingFutureSources_forTesting, isEmpty);
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-      expect(context.pendingFutureSources_forTesting, isEmpty);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_noCacheEntry() {
-    Source librarySource = addSource("/lib.dart", "library lib;");
-    Source partSource = addSource("/part.dart", "part of foo;");
-    bool completed = false;
-    context
-        .computeResolvedCompilationUnitAsync(partSource, librarySource)
-        .then((CompilationUnit unit) {
-      expect(unit, isNotNull);
-      completed = true;
-    });
-    return pumpEventQueue()
-        .then((_) {
-          expect(completed, isFalse);
-          _performPendingAnalysisTasks();
-        })
-        .then((_) => pumpEventQueue())
-        .then((_) {
-          expect(completed, isTrue);
-        });
-  }
-
-  void test_dispose() {
-    expect(context.isDisposed, isFalse);
-    context.dispose();
-    expect(context.isDisposed, isTrue);
-  }
-
-  void test_ensureResolvedDartUnits_definingUnit_hasResolved() {
-    Source source = addSource('/test.dart', '');
-    LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source);
-    analysisDriver.computeResult(libTarget, RESOLVED_UNIT);
-    CompilationUnit unit =
-        context.getCacheEntry(libTarget).getValue(RESOLVED_UNIT);
-    List<CompilationUnit> units = context.ensureResolvedDartUnits(source);
-    expect(units, unorderedEquals([unit]));
-  }
-
-  void test_ensureResolvedDartUnits_definingUnit_notResolved() {
-    Source source = addSource('/test.dart', '');
-    LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source);
-    analysisDriver.computeResult(libTarget, RESOLVED_UNIT);
-    // flush
-    context
-        .getCacheEntry(libTarget)
-        .setState(RESOLVED_UNIT, CacheState.FLUSHED);
-    // schedule recomputing
-    List<CompilationUnit> units = context.ensureResolvedDartUnits(source);
-    expect(units, isNull);
-    // should be the next result to compute
-    TargetedResult nextResult = context.dartWorkManager.getNextResult();
-    expect(nextResult.target, libTarget);
-    expect(nextResult.result, RESOLVED_UNIT);
-  }
-
-  void test_ensureResolvedDartUnits_partUnit_hasResolved() {
-    Source libSource1 = addSource('/lib1.dart', r'''
-library lib;
-part 'part.dart';
-''');
-    Source libSource2 = addSource('/lib2.dart', r'''
-library lib;
-part 'part.dart';
-''');
-    Source partSource = addSource('/part.dart', r'''
-part of lib;
-''');
-    LibrarySpecificUnit partTarget1 =
-        new LibrarySpecificUnit(libSource1, partSource);
-    LibrarySpecificUnit partTarget2 =
-        new LibrarySpecificUnit(libSource2, partSource);
-    analysisDriver.computeResult(partTarget1, RESOLVED_UNIT);
-    analysisDriver.computeResult(partTarget2, RESOLVED_UNIT);
-    CompilationUnit unit1 =
-        context.getCacheEntry(partTarget1).getValue(RESOLVED_UNIT);
-    CompilationUnit unit2 =
-        context.getCacheEntry(partTarget2).getValue(RESOLVED_UNIT);
-    List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource);
-    expect(units, unorderedEquals([unit1, unit2]));
-  }
-
-  void test_ensureResolvedDartUnits_partUnit_notResolved() {
-    Source libSource1 = addSource('/lib1.dart', r'''
-library lib;
-part 'part.dart';
-''');
-    Source libSource2 = addSource('/lib2.dart', r'''
-library lib;
-part 'part.dart';
-''');
-    Source partSource = addSource('/part.dart', r'''
-part of lib;
-''');
-    LibrarySpecificUnit partTarget1 =
-        new LibrarySpecificUnit(libSource1, partSource);
-    LibrarySpecificUnit partTarget2 =
-        new LibrarySpecificUnit(libSource2, partSource);
-    analysisDriver.computeResult(partTarget1, RESOLVED_UNIT);
-    analysisDriver.computeResult(partTarget2, RESOLVED_UNIT);
-    // flush
-    context
-        .getCacheEntry(partTarget1)
-        .setState(RESOLVED_UNIT, CacheState.FLUSHED);
-    context
-        .getCacheEntry(partTarget2)
-        .setState(RESOLVED_UNIT, CacheState.FLUSHED);
-    // schedule recomputing
-    List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource);
-    expect(units, isNull);
-    // should be the next result to compute
-    TargetedResult nextResult = context.dartWorkManager.getNextResult();
-    expect(nextResult.target, anyOf(partTarget1, partTarget2));
-    expect(nextResult.result, RESOLVED_UNIT);
-  }
-
-  void test_exists_false() {
-    TestSource source = new TestSource();
-    source.exists2 = false;
-    expect(context.exists(source), isFalse);
-  }
-
-  void test_exists_null() {
-    expect(context.exists(null), isFalse);
-  }
-
-  void test_exists_overridden() {
-    Source source = new TestSource();
-    context.setContents(source, "");
-    expect(context.exists(source), isTrue);
-  }
-
-  void test_exists_true() {
-    expect(context.exists(new _AnalysisContextImplTest_Source_exists_true()),
-        isTrue);
-  }
-
-  void test_flushResolvedUnit_updateFile_dontNotify() {
-    String oldCode = '';
-    String newCode = r'''
-import 'dart:async';
-''';
-    Source source = newFile('/test.dart', content: oldCode).createSource();
-    context.applyChanges(new ChangeSet()..addedSource(source));
-    context.resolveCompilationUnit2(source, source);
-    // Flush all results units.
-    context.analysisCache.flush((target, result) {
-      if (target.source == source) {
-        return RESOLVED_UNIT_RESULTS.contains(result);
-      }
-      return false;
-    });
-    // Update the file, but don't notify the context.
-    modifyFile('/test.dart', newCode);
-    // Driver must detect that the file was changed and recover.
-    CompilationUnit unit = context.resolveCompilationUnit2(source, source);
-    expect(unit, isNotNull);
-  }
-
-  void test_flushResolvedUnit_updateFile_dontNotify2() {
-    String oldCode = r'''
-main() {}
-''';
-    String newCode = r'''
-import 'dart:async';
-main() {}
-''';
-    Source source = newFile('/test.dart', content: oldCode).createSource();
-    context.applyChanges(new ChangeSet()..addedSource(source));
-    context.resolveCompilationUnit2(source, source);
-    // Flush all results units.
-    context.analysisCache.flush((target, result) {
-      if (target.source == source) {
-        if (target.source == source) {
-          return RESOLVED_UNIT_RESULTS.contains(result);
-        }
-      }
-      return false;
-    });
-    // Update the file, but don't notify the context.
-    modifyFile('/test.dart', newCode);
-    // Driver must detect that the file was changed and recover.
-    CompilationUnit unit = context.resolveCompilationUnit2(source, source);
-    expect(unit, isNotNull);
-  }
-
-  void test_flushSingleResolvedUnit_instanceField() {
-    _checkFlushSingleResolvedUnit('class C { var x = 0; }',
-        (CompilationUnitElement unitElement, String reason) {
-      expect(unitElement.types, hasLength(1), reason: reason);
-      ClassElement cls = unitElement.types[0];
-      expect(cls.fields, hasLength(1), reason: reason);
-      expect(cls.fields[0].type.toString(), 'int', reason: reason);
-      expect(cls.accessors, hasLength(2), reason: reason);
-      expect(cls.accessors[0].isGetter, isTrue, reason: reason);
-      expect(cls.accessors[0].returnType.toString(), 'int', reason: reason);
-      expect(cls.accessors[1].isSetter, isTrue, reason: reason);
-      expect(cls.accessors[1].returnType.toString(), 'void', reason: reason);
-      expect(cls.accessors[1].parameters, hasLength(1), reason: reason);
-      expect(cls.accessors[1].parameters[0].type.toString(), 'int',
-          reason: reason);
-    });
-  }
-
-  void test_flushSingleResolvedUnit_instanceGetter() {
-    _checkFlushSingleResolvedUnit('''
-abstract class B {
-  int get x;
-}
-class C extends B {
-  get x => null;
-}
-''', (CompilationUnitElement unitElement, String reason) {
-      expect(unitElement.types, hasLength(2), reason: reason);
-      ClassElement cls = unitElement.types[1];
-      expect(cls.name, 'C', reason: reason);
-      expect(cls.accessors, hasLength(1), reason: reason);
-      expect(cls.accessors[0].returnType.toString(), 'int', reason: reason);
-      expect(cls.fields, hasLength(1), reason: reason);
-      expect(cls.fields[0].type.toString(), 'int', reason: reason);
-    });
-  }
-
-  void test_flushSingleResolvedUnit_instanceMethod() {
-    _checkFlushSingleResolvedUnit('''
-abstract class B {
-  int f(String s);
-}
-class C extends B {
-  f(s) => null;
-}
-''', (CompilationUnitElement unitElement, String reason) {
-      expect(unitElement.types, hasLength(2), reason: reason);
-      ClassElement cls = unitElement.types[1];
-      expect(cls.name, 'C', reason: reason);
-      expect(cls.methods, hasLength(1), reason: reason);
-      expect(cls.methods[0].returnType.toString(), 'int', reason: reason);
-      expect(cls.methods[0].parameters, hasLength(1), reason: reason);
-      expect(cls.methods[0].parameters[0].type.toString(), 'String',
-          reason: reason);
-    });
-  }
-
-  void test_flushSingleResolvedUnit_instanceSetter() {
-    _checkFlushSingleResolvedUnit('''
-abstract class B {
-  set x(int value);
-}
-class C extends B {
-  set x(value) {}
-}
-''', (CompilationUnitElement unitElement, String reason) {
-      expect(unitElement.types, hasLength(2), reason: reason);
-      ClassElement cls = unitElement.types[1];
-      expect(cls.name, 'C', reason: reason);
-      expect(cls.accessors, hasLength(1), reason: reason);
-      expect(cls.accessors[0].returnType.toString(), 'void', reason: reason);
-      expect(cls.accessors[0].parameters, hasLength(1), reason: reason);
-      expect(cls.accessors[0].parameters[0].type.toString(), 'int',
-          reason: reason);
-      expect(cls.fields, hasLength(1), reason: reason);
-      expect(cls.fields[0].type.toString(), 'int', reason: reason);
-    });
-  }
-
-  void test_flushSingleResolvedUnit_staticField() {
-    _checkFlushSingleResolvedUnit('class C { static var x = 0; }',
-        (CompilationUnitElement unitElement, String reason) {
-      expect(unitElement.types, hasLength(1), reason: reason);
-      ClassElement cls = unitElement.types[0];
-      expect(cls.fields, hasLength(1), reason: reason);
-      expect(cls.fields[0].type.toString(), 'int', reason: reason);
-      expect(cls.accessors, hasLength(2), reason: reason);
-      expect(cls.accessors[0].isGetter, isTrue, reason: reason);
-      expect(cls.accessors[0].returnType.toString(), 'int', reason: reason);
-      expect(cls.accessors[1].isSetter, isTrue, reason: reason);
-      expect(cls.accessors[1].returnType.toString(), 'void', reason: reason);
-      expect(cls.accessors[1].parameters, hasLength(1), reason: reason);
-      expect(cls.accessors[1].parameters[0].type.toString(), 'int',
-          reason: reason);
-    });
-  }
-
-  void test_flushSingleResolvedUnit_topLevelVariable() {
-    _checkFlushSingleResolvedUnit('var x = 0;',
-        (CompilationUnitElement unitElement, String reason) {
-      expect(unitElement.topLevelVariables, hasLength(1), reason: reason);
-      expect(unitElement.topLevelVariables[0].type.toString(), 'int',
-          reason: reason);
-      expect(unitElement.accessors, hasLength(2), reason: reason);
-      expect(unitElement.accessors[0].isGetter, isTrue, reason: reason);
-      expect(unitElement.accessors[0].returnType.toString(), 'int',
-          reason: reason);
-      expect(unitElement.accessors[1].isSetter, isTrue, reason: reason);
-      expect(unitElement.accessors[1].returnType.toString(), 'void',
-          reason: reason);
-      expect(unitElement.accessors[1].parameters, hasLength(1), reason: reason);
-      expect(unitElement.accessors[1].parameters[0].type.toString(), 'int',
-          reason: reason);
-    });
-  }
-
-  void test_getAnalysisOptions() {
-    expect(context.analysisOptions, isNotNull);
-  }
-
-  void test_getContents_fromSource() {
-    String content = "library lib;";
-    TimestampedData<String> contents =
-        context.getContents(new TestSource('/test.dart', content));
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getContents_notOverridden() {
-    String content = "library lib;";
-    Source source = new TestSource('/test.dart', content);
-    context.setContents(source, "part of lib;");
-    context.setContents(source, null);
-    TimestampedData<String> contents = context.getContents(source);
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getContents_overridden() {
-    String content = "library lib;";
-    Source source = new TestSource();
-    context.setContents(source, content);
-    TimestampedData<String> contents = context.getContents(source);
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getDeclaredVariables() {
-    expect(context.declaredVariables, isNotNull);
-  }
-
-  void test_getElement() {
-    LibraryElement core =
-        context.computeLibraryElement(sourceFactory.forUri("dart:core"));
-    expect(core, isNotNull);
-    ClassElement classObject =
-        _findClass(core.definingCompilationUnit, "Object");
-    expect(classObject, isNotNull);
-    ElementLocation location = classObject.location;
-    Element element = context.getElement(location);
-    expect(element, same(classObject));
-  }
-
-  void test_getElement_constructor_named() {
-    Source source = addSource("/lib.dart", r'''
-class A {
-  A.named() {}
-}''');
-    _analyzeAll_assertFinished();
-    LibraryElement library = context.computeLibraryElement(source);
-    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
-    ConstructorElement constructor = classA.constructors[0];
-    ElementLocation location = constructor.location;
-    Element element = context.getElement(location);
-    expect(element, same(constructor));
-  }
-
-  void test_getElement_constructor_unnamed() {
-    Source source = addSource("/lib.dart", r'''
-class A {
-  A() {}
-}''');
-    _analyzeAll_assertFinished();
-    LibraryElement library = context.computeLibraryElement(source);
-    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
-    ConstructorElement constructor = classA.constructors[0];
-    ElementLocation location = constructor.location;
-    Element element = context.getElement(location);
-    expect(element, same(constructor));
-  }
-
-  void test_getElement_enum() {
-    Source source = addSource('/test.dart', 'enum MyEnum {A, B, C}');
-    _analyzeAll_assertFinished();
-    LibraryElement library = context.computeLibraryElement(source);
-    ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum');
-    ElementLocation location = myEnum.location;
-    Element element = context.getElement(location);
-    expect(element, same(myEnum));
-  }
-
-  void test_getErrors_dart_none() {
-    Source source = addSource("/lib.dart", "library lib;");
-    var errorInfo = context.getErrors(source);
-    expect(errorInfo, isNotNull);
-    List<AnalysisError> errors = errorInfo.errors;
-    expect(errors, hasLength(0));
-    context.computeErrors(source);
-    errors = errorInfo.errors;
-    expect(errors, hasLength(0));
-  }
-
-  void test_getErrors_dart_some() {
-    Source source = addSource("/lib.dart", "library 'lib';");
-    var errorInfo = context.getErrors(source);
-    expect(errorInfo, isNotNull);
-    List<AnalysisError> errors = errorInfo.errors;
-    expect(errors, hasLength(0));
-    errors = context.computeErrors(source);
-    expect(errors, hasLength(1));
-  }
-
-  void test_getErrors_html_none() {
-    Source source = addSource("/test.html", "<html></html>");
-    AnalysisErrorInfo errorInfo = context.getErrors(source);
-    expect(errorInfo, isNotNull);
-    List<AnalysisError> errors = errorInfo.errors;
-    expect(errors, hasLength(0));
-    context.computeErrors(source);
-    errors = errorInfo.errors;
-    expect(errors, hasLength(0));
-  }
-
-  void test_getHtmlFilesReferencing_html() {
-    Source htmlSource = addSource("/test.html", r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = addSource("/test.dart", "library lib;");
-    Source secondHtmlSource = addSource("/test.html", "<html></html>");
-    context.computeLibraryElement(librarySource);
-    List<Source> result = context.getHtmlFilesReferencing(secondHtmlSource);
-    expect(result, hasLength(0));
-    context.parseHtmlDocument(htmlSource);
-    result = context.getHtmlFilesReferencing(secondHtmlSource);
-    expect(result, hasLength(0));
-  }
-
-  void test_getHtmlFilesReferencing_library() {
-    Source htmlSource = addSource("/test.html", r'''
-<!DOCTYPE html>
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = addSource("/test.dart", "library lib;");
-    context.computeLibraryElement(librarySource);
-    List<Source> result = context.getHtmlFilesReferencing(librarySource);
-    expect(result, hasLength(0));
-    // Indirectly force the data to be computed.
-    context.computeErrors(htmlSource);
-    result = context.getHtmlFilesReferencing(librarySource);
-    expect(result, hasLength(1));
-    expect(result[0], htmlSource);
-  }
-
-  void test_getHtmlFilesReferencing_part() {
-    Source htmlSource = addSource("/test.html", r'''
-<!DOCTYPE html>
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource =
-        addSource("/test.dart", "library lib; part 'part.dart';");
-    Source partSource = addSource("/part.dart", "part of lib;");
-    context.computeLibraryElement(librarySource);
-    List<Source> result = context.getHtmlFilesReferencing(partSource);
-    expect(result, hasLength(0));
-    // Indirectly force the data to be computed.
-    context.computeErrors(htmlSource);
-    result = context.getHtmlFilesReferencing(partSource);
-    expect(result, hasLength(1));
-    expect(result[0], htmlSource);
-  }
-
-  void test_getHtmlSources() {
-    List<Source> sources = context.htmlSources;
-    expect(sources, hasLength(0));
-    Source source = addSource("/test.html", "");
-    sources = context.htmlSources;
-    expect(sources, hasLength(1));
-    expect(sources[0], source);
-  }
-
-  void test_getKindOf_html() {
-    Source source = addSource("/test.html", "");
-    expect(context.getKindOf(source), same(SourceKind.HTML));
-  }
-
-  void test_getKindOf_library() {
-    Source source = addSource("/test.dart", "library lib;");
-    expect(context.getKindOf(source), same(SourceKind.UNKNOWN));
-    context.computeKindOf(source);
-    expect(context.getKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_getKindOf_part() {
-    Source source = addSource("/test.dart", "part of lib;");
-    expect(context.getKindOf(source), same(SourceKind.UNKNOWN));
-    context.computeKindOf(source);
-    expect(context.getKindOf(source), same(SourceKind.PART));
-  }
-
-  void test_getKindOf_unknown() {
-    Source source = addSource("/test.css", "");
-    expect(context.getKindOf(source), same(SourceKind.UNKNOWN));
-  }
-
-  void test_getLaunchableClientLibrarySources_doesNotImportHtml() {
-    Source source = addSource("/test.dart", r'''
-main() {}''');
-    context.computeLibraryElement(source);
-    List<Source> sources = context.launchableClientLibrarySources;
-    expect(sources, isEmpty);
-  }
-
-  void test_getLaunchableClientLibrarySources_importsHtml_explicitly() {
-    List<Source> sources = context.launchableClientLibrarySources;
-    expect(sources, isEmpty);
-    Source source = addSource("/test.dart", r'''
-import 'dart:html';
-main() {}''');
-    context.computeLibraryElement(source);
-    sources = context.launchableClientLibrarySources;
-    expect(sources, unorderedEquals([source]));
-  }
-
-  void test_getLaunchableClientLibrarySources_importsHtml_implicitly() {
-    List<Source> sources = context.launchableClientLibrarySources;
-    expect(sources, isEmpty);
-    addSource('/a.dart', r'''
-import 'dart:html';
-''');
-    Source source = addSource("/test.dart", r'''
-import 'a.dart';
-main() {}''');
-    _analyzeAll_assertFinished();
-    sources = context.launchableClientLibrarySources;
-    expect(sources, unorderedEquals([source]));
-  }
-
-  void test_getLaunchableClientLibrarySources_importsHtml_implicitly2() {
-    List<Source> sources = context.launchableClientLibrarySources;
-    expect(sources, isEmpty);
-    addSource('/a.dart', r'''
-export 'dart:html';
-''');
-    Source source = addSource("/test.dart", r'''
-import 'a.dart';
-main() {}''');
-    _analyzeAll_assertFinished();
-    sources = context.launchableClientLibrarySources;
-    expect(sources, unorderedEquals([source]));
-  }
-
-  void test_getLaunchableServerLibrarySources() {
-    expect(context.launchableServerLibrarySources, isEmpty);
-    Source source = addSource("/test.dart", "main() {}");
-    context.computeLibraryElement(source);
-    expect(context.launchableServerLibrarySources, unorderedEquals([source]));
-  }
-
-  void test_getLaunchableServerLibrarySources_importsHtml_explicitly() {
-    Source source = addSource("/test.dart", r'''
-import 'dart:html';
-main() {}
-''');
-    context.computeLibraryElement(source);
-    expect(context.launchableServerLibrarySources, isEmpty);
-  }
-
-  void test_getLaunchableServerLibrarySources_importsHtml_implicitly() {
-    addSource("/imports_html.dart", r'''
-import 'dart:html';
-''');
-    addSource("/test.dart", r'''
-import 'imports_html.dart';
-main() {}''');
-    _analyzeAll_assertFinished();
-    expect(context.launchableServerLibrarySources, isEmpty);
-  }
-
-  void test_getLaunchableServerLibrarySources_noMain() {
-    Source source = addSource("/test.dart", '');
-    context.computeLibraryElement(source);
-    expect(context.launchableServerLibrarySources, isEmpty);
-  }
-
-  void test_getLibrariesContaining() {
-    Source librarySource = addSource("/lib.dart", r'''
-library lib;
-part 'part.dart';''');
-    Source partSource = addSource("/part.dart", "part of lib;");
-    context.computeLibraryElement(librarySource);
-    List<Source> result = context.getLibrariesContaining(librarySource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-    result = context.getLibrariesContaining(partSource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-  }
-
-  void test_getLibrariesDependingOn() {
-    Source libASource = addSource("/libA.dart", "library libA;");
-    addSource("/libB.dart", "library libB;");
-    Source lib1Source = addSource("/lib1.dart", r'''
-library lib1;
-import 'libA.dart';
-export 'libB.dart';''');
-    Source lib2Source = addSource("/lib2.dart", r'''
-library lib2;
-import 'libB.dart';
-export 'libA.dart';''');
-    context.computeLibraryElement(lib1Source);
-    context.computeLibraryElement(lib2Source);
-    List<Source> result = context.getLibrariesDependingOn(libASource);
-    expect(result, unorderedEquals([lib1Source, lib2Source]));
-  }
-
-  void test_getLibrariesReferencedFromHtml() {
-    Source htmlSource = addSource("/test.html", r'''
-<!DOCTYPE html>
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = addSource("/test.dart", "library lib;");
-    context.computeLibraryElement(librarySource);
-    // Indirectly force the data to be computed.
-    context.computeErrors(htmlSource);
-    List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-  }
-
-  void test_getLibrariesReferencedFromHtml_none() {
-    Source htmlSource = addSource("/test.html", r'''
-<html><head>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    addSource("/test.dart", "library lib;");
-    context.parseHtmlDocument(htmlSource);
-    List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource);
-    expect(result, hasLength(0));
-  }
-
-  void test_getLibraryElement() {
-    Source source = addSource("/test.dart", "library lib;");
-    LibraryElement element = context.getLibraryElement(source);
-    expect(element, isNull);
-    context.computeLibraryElement(source);
-    element = context.getLibraryElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_getLibrarySources() {
-    List<Source> sources = context.librarySources;
-    int originalLength = sources.length;
-    Source source = addSource("/test.dart", "library lib;");
-    context.computeKindOf(source);
-    sources = context.librarySources;
-    expect(sources, hasLength(originalLength + 1));
-    for (Source returnedSource in sources) {
-      if (returnedSource == source) {
-        return;
-      }
-    }
-    fail("The added source was not in the list of library sources");
-  }
-
-  void test_getLibrarySources_inSDK() {
-    Source source = addSource('/test.dart', r'''
-import 'dart:async';
-Stream S = null;
-''');
-    LibraryElement testLibrary = context.computeLibraryElement(source);
-    // prepare "Stream" ClassElement
-    ClassElement streamElement;
-    {
-      CompilationUnitElement testUnit = testLibrary.definingCompilationUnit;
-      InterfaceType streamType = testUnit.topLevelVariables[0].type;
-      streamElement = streamType.element;
-    }
-    // must be from SDK context
-    AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
-    expect(sdkContext, streamElement.context);
-    Source intSource = streamElement.source;
-    // must be in the "async" library - SDK context
-    {
-      List<Source> coreLibraries = sdkContext.getLibrariesContaining(intSource);
-      expect(coreLibraries, hasLength(1));
-      Source coreSource = coreLibraries[0];
-      expect(coreSource.isInSystemLibrary, isTrue);
-      expect(coreSource.shortName, 'async.dart');
-    }
-    // must be in the "async" library - main context
-    {
-      List<Source> coreLibraries = context.getLibrariesContaining(intSource);
-      expect(coreLibraries, hasLength(1));
-      Source coreSource = coreLibraries[0];
-      expect(coreSource.isInSystemLibrary, isTrue);
-      expect(coreSource.shortName, 'async.dart');
-    }
-  }
-
-  void test_getLineInfo() {
-    Source source = addSource("/test.dart", r'''
-library lib;
-
-main() {}''');
-    LineInfo info = context.getLineInfo(source);
-    expect(info, isNull);
-    context.parseCompilationUnit(source);
-    info = context.getLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_getModificationStamp_fromSource() {
-    int stamp = 42;
-    expect(
-        context.getModificationStamp(
-            new _AnalysisContextImplTest_Source_getModificationStamp_fromSource(
-                stamp)),
-        stamp);
-  }
-
-  void test_getModificationStamp_overridden() {
-    int stamp = 42;
-    Source source =
-        new _AnalysisContextImplTest_Source_getModificationStamp_overridden(
-            stamp);
-    context.setContents(source, "");
-    expect(stamp != context.getModificationStamp(source), isTrue);
-  }
-
-  void test_getPublicNamespace_element() {
-    Source source = addSource("/test.dart", "class A {}");
-    LibraryElement library = context.computeLibraryElement(source);
-    expect(library, isNotNull);
-    Namespace namespace = context.getPublicNamespace(library);
-    expect(namespace, isNotNull);
-    expect(namespace.get("A"), isClassElement);
-  }
-
-  void test_getResolvedCompilationUnit_library() {
-    Source source = addSource("/lib.dart", "library libb;");
-    LibraryElement library = context.computeLibraryElement(source);
-    context.computeErrors(source); // Force the resolved unit to be built.
-    expect(context.getResolvedCompilationUnit(source, library), isNotNull);
-    context.setContents(source, "library lib;");
-    expect(context.getResolvedCompilationUnit(source, library), isNull);
-  }
-
-  void test_getResolvedCompilationUnit_library_null() {
-    Source source = addSource("/lib.dart", "library lib;");
-    expect(context.getResolvedCompilationUnit(source, null), isNull);
-  }
-
-  void test_getResolvedCompilationUnit_source_dart() {
-    Source source = addSource("/lib.dart", "library lib;");
-    expect(context.getResolvedCompilationUnit2(source, source), isNull);
-    context.resolveCompilationUnit2(source, source);
-    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
-  }
-
-  void test_getSourceFactory() {
-    expect(context.sourceFactory, same(sourceFactory));
-  }
-
-  void test_getSourcesWithFullName() {
-    String filePath = '/foo/lib/file.dart';
-    List<Source> expected = <Source>[];
-    ChangeSet changeSet = new ChangeSet();
-
-    TestSourceWithUri source1 =
-        new TestSourceWithUri(filePath, Uri.parse('file://$filePath'));
-    expected.add(source1);
-    changeSet.addedSource(source1);
-
-    TestSourceWithUri source2 =
-        new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart'));
-    expected.add(source2);
-    changeSet.addedSource(source2);
-
-    context.applyChanges(changeSet);
-    expect(context.getSourcesWithFullName(filePath), unorderedEquals(expected));
-  }
-
-  void test_handleContentsChanged() {
-    ContentCache contentCache = new ContentCache();
-    context.contentCache = contentCache;
-    String oldContents = 'foo() {}';
-    String newContents = 'bar() {}';
-    // old contents
-    Source source = addSource("/test.dart", oldContents);
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
-    // new contents
-    contentCache.setContents(source, newContents);
-    context.handleContentsChanged(source, oldContents, newContents, true);
-    // there is some work to do
-    AnalysisResult analysisResult = context.performAnalysisTask();
-    expect(analysisResult.changeNotices, isNotNull);
-  }
-
-  void test_handleContentsChanged_noOriginal_sameAsFile() {
-    ContentCache contentCache = new ContentCache();
-    context.contentCache = contentCache;
-    // Add the source.
-    String code = 'foo() {}';
-    Source source = addSource("/test.dart", code);
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
-    // Update the content cache, and notify that we updated the source.
-    // We pass "null" as "originalContents" because the was no one.
-    contentCache.setContents(source, code);
-    context.handleContentsChanged(source, null, code, true);
-    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
-  }
-
-  void test_handleContentsChanged_noOriginal_sameAsFile_butFileUpdated() {
-    ContentCache contentCache = new ContentCache();
-    context.contentCache = contentCache;
-    // Add the source.
-    String oldCode = 'foo() {}';
-    String newCode = 'bar() {}';
-    var file = newFile('/test.dart', content: oldCode);
-    Source source = file.createSource();
-    context.applyChanges(new ChangeSet()..addedSource(source));
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
-    // Test for the race condition.
-    // 1. Update the file.
-    // 2. Update the content cache.
-    // 3. Notify the context, and because this is the first time when we
-    //    update the content cache, we don't know "originalContents".
-    // The source must be invalidated, because it has different contents now.
-    modifyFile('/test.dart', newCode);
-    contentCache.setContents(source, newCode);
-    context.handleContentsChanged(source, null, newCode, true);
-    expect(context.getResolvedCompilationUnit2(source, source), isNull);
-  }
-
-  Future test_implicitAnalysisEvents_added() async {
-    AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
-    context.implicitAnalysisEvents.listen(listener.onData);
-    //
-    // Create a file that references an file that is not explicitly being
-    // analyzed and fully analyze it. Ensure that the listener is told about
-    // the implicitly analyzed file.
-    //
-    Source sourceA = newSource('/a.dart', "library a; import 'b.dart';");
-    Source sourceB = newSource('/b.dart', "library b;");
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(sourceA);
-    context.applyChanges(changeSet);
-    context.computeErrors(sourceA);
-    await pumpEventQueue();
-    listener.expectAnalyzed(sourceB);
-  }
-
-  void test_isClientLibrary_dart() {
-    Source source = addSource("/test.dart", r'''
-import 'dart:html';
-
-main() {}''');
-    expect(context.isClientLibrary(source), isFalse);
-    expect(context.isServerLibrary(source), isFalse);
-    context.computeLibraryElement(source);
-    expect(context.isClientLibrary(source), isTrue);
-    expect(context.isServerLibrary(source), isFalse);
-  }
-
-  void test_isClientLibrary_html() {
-    Source source = addSource("/test.html", "<html></html>");
-    expect(context.isClientLibrary(source), isFalse);
-  }
-
-  void test_isClientLibrary_unknown() {
-    Source source = newSource("/test.dart");
-    expect(context.isClientLibrary(source), isFalse);
-  }
-
-  void test_isServerLibrary_dart() {
-    Source source = addSource("/test.dart", r'''
-library lib;
-
-main() {}''');
-    expect(context.isClientLibrary(source), isFalse);
-    expect(context.isServerLibrary(source), isFalse);
-    context.computeLibraryElement(source);
-    expect(context.isClientLibrary(source), isFalse);
-    expect(context.isServerLibrary(source), isTrue);
-  }
-
-  void test_isServerLibrary_html() {
-    Source source = addSource("/test.html", "<html></html>");
-    expect(context.isServerLibrary(source), isFalse);
-  }
-
-  void test_isServerLibrary_unknown() {
-    Source source = newSource("/test.dart");
-    expect(context.isServerLibrary(source), isFalse);
-  }
-
-  void test_onResultInvalidated_removeSource() {
-    Source source = addSource('/test.dart', 'main() {}');
-    _analyzeAll_assertFinished();
-    // listen for changes
-    bool listenerInvoked = false;
-    context.onResultChanged(RESOLVED_UNIT).listen((ResultChangedEvent event) {
-      Source eventSource = event.target.source;
-      expect(event.wasComputed, isFalse);
-      expect(event.wasInvalidated, isTrue);
-      expect(event.descriptor, RESOLVED_UNIT);
-      expect(eventSource, source);
-      listenerInvoked = true;
-    });
-    // apply changes
-    expect(listenerInvoked, false);
-    context.applyChanges(new ChangeSet()..removedSource(source));
-    // verify
-    expect(listenerInvoked, isTrue);
-  }
-
-  void test_onResultInvalidated_setContents() {
-    Source source = addSource('/test.dart', 'main() {}');
-    _analyzeAll_assertFinished();
-    // listen for changes
-    bool listenerInvoked = false;
-    context.onResultChanged(RESOLVED_UNIT).listen((ResultChangedEvent event) {
-      Source eventSource = event.target.source;
-      expect(event.wasComputed, isFalse);
-      expect(event.wasInvalidated, isTrue);
-      expect(event.descriptor, RESOLVED_UNIT);
-      expect(eventSource, source);
-      listenerInvoked = true;
-    });
-    // apply changes
-    expect(listenerInvoked, false);
-    context.setContents(source, 'class B {}');
-    // verify
-    expect(listenerInvoked, isTrue);
-  }
-
-  void test_parseCompilationUnit_errors() {
-    Source source = addSource("/lib.dart", "library {");
-    CompilationUnit compilationUnit = context.parseCompilationUnit(source);
-    expect(compilationUnit, isNotNull);
-    var errorInfo = context.getErrors(source);
-    expect(errorInfo, isNotNull);
-    List<AnalysisError> errors = errorInfo.errors;
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_parseCompilationUnit_exception() {
-    Source source = _addSourceWithException("/test.dart");
-    try {
-      context.parseCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_parseCompilationUnit_html() {
-    Source source = addSource("/test.html", "<html></html>");
-    expect(context.parseCompilationUnit(source), isNull);
-  }
-
-  void test_parseCompilationUnit_noErrors() {
-    Source source = addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit = context.parseCompilationUnit(source);
-    expect(compilationUnit, isNotNull);
-    AnalysisErrorInfo errorInfo = context.getErrors(source);
-    expect(errorInfo, isNotNull);
-    expect(errorInfo.errors, hasLength(0));
-  }
-
-  void test_parseCompilationUnit_nonExistentSource() {
-    Source source = newSource('/test.dart');
-    deleteFile('/test.dart');
-    try {
-      context.parseCompilationUnit(source);
-      fail("Expected AnalysisException because file does not exist");
-    } on AnalysisException {
-      // Expected result
-    }
-  }
-
-  void test_parseHtmlDocument() {
-    Source source = addSource("/lib.html", "<!DOCTYPE html><html></html>");
-    Document document = context.parseHtmlDocument(source);
-    expect(document, isNotNull);
-  }
-
-  void test_parseHtmlUnit_resolveDirectives() {
-    Source libSource = addSource("/lib.dart", r'''
-library lib;
-class ClassA {}''');
-    Source source = addSource("/lib.html", r'''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart'>
-    import 'lib.dart';
-    ClassA v = null;
-  </script>
-</head>
-<body>
-</body>
-</html>''');
-    Document document = context.parseHtmlDocument(source);
-    expect(document, isNotNull);
-    List<DartScript> scripts = context.computeResult(source, DART_SCRIPTS);
-    expect(scripts, hasLength(1));
-    CompilationUnit unit = context.computeResult(scripts[0], PARSED_UNIT);
-    ImportDirective importNode = unit.directives[0] as ImportDirective;
-    expect(importNode.uriContent, isNotNull);
-    expect(importNode.uriSource, libSource);
-  }
-
-  void test_performAnalysisTask_addPart() {
-    Source libSource = addSource("/lib.dart", r'''
-library lib;
-part 'part.dart';''');
-    // run all tasks without part
-    _analyzeAll_assertFinished();
-    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)),
-        isTrue,
-        reason: "lib has errors");
-    // add part and run all tasks
-    Source partSource = addSource("/part.dart", r'''
-part of lib;
-''');
-    _analyzeAll_assertFinished();
-    // "libSource" should be here
-    List<Source> librariesWithPart = context.getLibrariesContaining(partSource);
-    expect(librariesWithPart, unorderedEquals([libSource]));
-    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)),
-        isFalse,
-        reason: "lib doesn't have errors");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved");
-  }
-
-  void test_performAnalysisTask_changeLibraryContents() {
-    Source libSource =
-        addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    context.setContents(libSource, "library lib;");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    context.setContents(libSource, "library lib; part 'test-part.dart';");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_changeLibraryThenPartContents() {
-    Source libSource =
-        addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    context.setContents(libSource, "library lib;");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    context.setContents(partSource, "part of lib; // 1");
-    // Assert that changing the part's content does not effect the library
-    // now that it is no longer part of that library
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library changed 3");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_changePartContents_makeItAPart() {
-    Source libSource = addSource("/lib.dart", r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
-    Source partSource = addSource("/part.dart", "void g() { f(null); }");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, partSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze
-    context.setContents(partSource, r'''
-part of lib;
-void g() { f(null); }''');
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(context.getResolvedCompilationUnit2(partSource, partSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
-    expect(context.getErrors(libSource).errors, hasLength(0));
-    expect(context.getErrors(partSource).errors, hasLength(0));
-  }
-
-  /**
-   * https://code.google.com/p/dart/issues/detail?id=12424
-   */
-  void test_performAnalysisTask_changePartContents_makeItNotPart() {
-    Source libSource = addSource("/lib.dart", r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
-    Source partSource = addSource("/part.dart", r'''
-part of lib;
-void g() { f(null); }''');
-    _analyzeAll_assertFinished();
-    expect(context.getErrors(libSource).errors, hasLength(0));
-    expect(context.getErrors(partSource).errors, hasLength(0));
-    // Remove 'part' directive, which should make "f(null)" an error.
-    context.setContents(partSource, r'''
-//part of lib;
-void g() { f(null); }''');
-    _analyzeAll_assertFinished();
-    expect(context.getErrors(libSource).errors.length != 0, isTrue);
-  }
-
-  void test_performAnalysisTask_changePartContents_noSemanticChanges() {
-    Source libSource =
-        addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    context.setContents(partSource, "part of lib; // 1");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    context.setContents(partSource, "part of lib; // 12");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_getContentException_dart() {
-    Source source = _addSourceWithException('test.dart');
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_getContentException_html() {
-    Source source = _addSourceWithException('test.html');
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd() {
-    Source libASource =
-        addSource("/libA.dart", "library libA; import 'libB.dart';");
-    _analyzeAll_assertFinished();
-    expect(
-        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 1");
-    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)),
-        isTrue,
-        reason: "libA has an error");
-    // add libB.dart and analyze
-    Source libBSource = addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 2");
-    expect(
-        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)),
-        isFalse,
-        reason: "libA doesn't have errors");
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd_html() {
-    Source htmlSource = addSource("/page.html", r'''
-<html><body><script type="application/dart">
-  import '/libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    _analyzeAll_assertFinished();
-    context.computeErrors(htmlSource);
-//    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)),
-//        isTrue,
-//        reason: "htmlSource has an error");
-    // add libB.dart and analyze
-    Source libBSource = addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    // TODO (danrubel) commented out to fix red bots
-//    context.computeErrors(htmlSource);
-//    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-//    expect(
-//        !_hasAnalysisErrorWithErrorSeverity(errors),
-//        isTrue,
-//        reason: "htmlSource doesn't have errors");
-  }
-
-  void test_performAnalysisTask_importedLibraryDelete() {
-    Source libASource =
-        addSource("/libA.dart", "library libA; import 'libB.dart';");
-    Source libBSource = addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 1");
-    expect(
-        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 1");
-    expect(!_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)),
-        isTrue,
-        reason: "libA doesn't have errors");
-    // remove libB.dart and analyze
-    _removeSource(libBSource);
-    _analyzeAll_assertFinished();
-    expect(
-        context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 2");
-    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libASource)),
-        isTrue,
-        reason: "libA has an error");
-  }
-
-  void test_performAnalysisTask_interruptBy_setContents() {
-    Source sourceA = addSource('/a.dart', r'''
-library expectedToFindSemicolon
-''');
-    // Analyze to the point where some of the results stop depending on
-    // the source content.
-    LibrarySpecificUnit unitA = new LibrarySpecificUnit(sourceA, sourceA);
-    for (int i = 0; i < 10000; i++) {
-      context.performAnalysisTask();
-      if (context.getResult(unitA, RESOLVED_UNIT3) != null) {
-        break;
-      }
-    }
-    // Update the source.
-    // This should invalidate all the results and also reset the driver.
-    context.setContents(sourceA, "library semicolonWasAdded;");
-    expect(context.getResult(unitA, RESOLVED_UNIT3), isNull);
-    expect(analysisDriver.currentWorkOrder, isNull);
-    // Continue analysis.
-    _analyzeAll_assertFinished();
-    expect(context.getErrors(sourceA).errors, isEmpty);
-  }
-
-  void test_performAnalysisTask_IOException() {
-    TestSource source = _addSourceWithException2("/test.dart", "library test;");
-    source.generateExceptionOnRead = false;
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 2);
-    _changeSource(source, "");
-    source.generateExceptionOnRead = true;
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 5);
-  }
-
-  void test_performAnalysisTask_missingPart() {
-    Source source =
-        addSource("/test.dart", "library lib; part 'no-such-file.dart';");
-    _analyzeAll_assertFinished();
-    expect(context.getLibraryElement(source), isNotNull,
-        reason: "performAnalysisTask failed to compute an element model");
-  }
-
-  void test_performAnalysisTask_modifiedAfterParse() {
-    // TODO(scheglov) no threads in Dart
-//    Source source = _addSource("/test.dart", "library lib;");
-//    int initialTime = _context.getModificationStamp(source);
-//    List<Source> sources = <Source>[];
-//    sources.add(source);
-//    _context.analysisPriorityOrder = sources;
-//    _context.parseCompilationUnit(source);
-//    while (initialTime == JavaSystem.currentTimeMillis()) {
-//      Thread.sleep(1);
-//      // Force the modification time to be different.
-//    }
-//    _context.setContents(source, "library test;");
-//    JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(source));
-//    _analyzeAll_assertFinished();
-//    JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an element model", _context.getLibraryElement(source));
-  }
-
-  void test_performAnalysisTask_onResultChanged() {
-    Set<String> libraryElementUris = new Set<String>();
-    Set<String> parsedUnitUris = new Set<String>();
-    Set<String> resolvedUnitUris = new Set<String>();
-    // listen
-    context.onResultChanged(LIBRARY_ELEMENT).listen((event) {
-      expect(event.wasComputed, isTrue);
-      expect(event.wasInvalidated, isFalse);
-      Source librarySource = event.target;
-      libraryElementUris.add(librarySource.uri.toString());
-    });
-    context.onResultChanged(PARSED_UNIT).listen((event) {
-      expect(event.wasComputed, isTrue);
-      expect(event.wasInvalidated, isFalse);
-      Source source = event.target;
-      parsedUnitUris.add(source.uri.toString());
-    });
-    context.onResultChanged(RESOLVED_UNIT).listen((event) {
-      expect(event.wasComputed, isTrue);
-      expect(event.wasInvalidated, isFalse);
-      LibrarySpecificUnit target = event.target;
-      Source librarySource = target.library;
-      resolvedUnitUris.add(librarySource.uri.toString());
-    });
-    // analyze
-    addSource('/test.dart', 'main() {}');
-    _analyzeAll_assertFinished();
-    // verify
-    String testUri = getFile('/test.dart').toUri().toString();
-    expect(libraryElementUris, contains(testUri));
-    expect(parsedUnitUris, contains(testUri));
-    expect(resolvedUnitUris, contains(testUri));
-  }
-
-  void test_performAnalysisTask_switchPackageVersion() {
-    // version 1
-    newFile('/pkgs/crypto-1/lib/crypto.dart', content: r'''
-library crypto;
-part 'src/hash_utils.dart';
-''');
-    newFile('/pkgs/crypto-1/lib/src/hash_utils.dart', content: r'''
-part of crypto;
-const _MASK_8 = 0xff;
-''');
-    // version 2
-    newFile('/pkgs/crypto-2/lib/crypto.dart', content: r'''
-library crypto;
-part 'src/hash_utils.dart';
-''');
-    newFile('/pkgs/crypto-2/lib/src/hash_utils.dart', content: r'''
-part of crypto;
-const _MASK_8 = 0xff;
-''');
-    // use version 1
-    context.sourceFactory = new SourceFactory(<UriResolver>[
-      sdkResolver,
-      resourceResolver,
-      new PackageMapUriResolver(resourceProvider, {
-        'crypto': [getFolder('/pkgs/crypto-1/lib')]
-      })
-    ]);
-    // analyze
-    addSource("/test.dart", r'''
-import 'package:crypto/crypto.dart';
-''');
-    _analyzeAll_assertFinished();
-    // use version 2
-    context.sourceFactory = new SourceFactory(<UriResolver>[
-      sdkResolver,
-      resourceResolver,
-      new PackageMapUriResolver(resourceProvider, {
-        'crypto': [getFolder('/pkgs/crypto-2/lib')]
-      })
-    ]);
-    _analyzeAll_assertFinished();
-    _assertNoExceptions();
-  }
-
-  void test_resolveCompilationUnit_existingElementModel() {
-    prepareAnalysisContext(new AnalysisOptionsImpl());
-    Source source = addSource('/test.dart', r'''
-library test;
-
-String topLevelVariable;
-int get topLevelGetter => 0;
-void set topLevelSetter(int value) {}
-String topLevelFunction(int i) => '';
-
-typedef String FunctionTypeAlias(int i);
-
-enum EnumeratedType {Invalid, Valid}
-
-class A {
-  const A(x);
-}
-
-@A(const [(_) => null])
-class ClassOne {
-  int instanceField;
-  static int staticField;
-
-  ClassOne();
-  ClassOne.named();
-
-  int get instanceGetter => 0;
-  static String get staticGetter => '';
-
-  void set instanceSetter(int value) {}
-  static void set staticSetter(int value) {}
-
-  int instanceMethod(int first, [int second = 0]) {
-    int localVariable;
-    int localFunction(String s) {}
-  }
-  static String staticMethod(int first, {int second: 0}) => '';
-}
-
-class ClassTwo {
-  // Implicit no-argument constructor
-}
-
-void topLevelFunctionWithLocalFunction() {
-  void localFunction({bool b: false}) {}
-}
-
-void functionWithGenericFunctionTypedParam/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {}
-void functionWithClosureAsDefaultParam([x = () => null]) {}
-''');
-    context.resolveCompilationUnit2(source, source);
-    LibraryElement firstElement = context.computeLibraryElement(source);
-    _ElementGatherer gatherer = new _ElementGatherer();
-    firstElement.accept(gatherer);
-
-    CacheEntry entry =
-        context.analysisCache.get(new LibrarySpecificUnit(source, source));
-    entry.setState(RESOLVED_UNIT1, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT2, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT3, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT4, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT5, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT6, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT7, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT8, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
-
-    context.resolveCompilationUnit2(source, source);
-    LibraryElement secondElement = context.computeLibraryElement(source);
-    _ElementComparer comparer = new _ElementComparer(gatherer.elements);
-    secondElement.accept(comparer);
-    comparer.expectNoDifferences();
-  }
-
-  void test_resolveCompilationUnit_import_relative() {
-    Source sourceA =
-        addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
-    addSource("/libB.dart", "library libB; class B{}");
-    CompilationUnit compilationUnit =
-        context.resolveCompilationUnit2(sourceA, sourceA);
-    expect(compilationUnit, isNotNull);
-    LibraryElement library =
-        resolutionMap.elementDeclaredByCompilationUnit(compilationUnit).library;
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-  }
-
-  void test_resolveCompilationUnit_import_relative_cyclic() {
-    Source sourceA =
-        addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
-    addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}");
-    CompilationUnit compilationUnit =
-        context.resolveCompilationUnit2(sourceA, sourceA);
-    expect(compilationUnit, isNotNull);
-    LibraryElement library =
-        resolutionMap.elementDeclaredByCompilationUnit(compilationUnit).library;
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-  }
-
-//  void test_resolveCompilationUnit_sourceChangeDuringResolution() {
-//    _context = new _AnalysisContext_sourceChangeDuringResolution();
-//    AnalysisContextFactory.initContextWithCore(_context);
-//    _sourceFactory = _context.sourceFactory;
-//    Source source = _addSource("/lib.dart", "library lib;");
-//    CompilationUnit compilationUnit =
-//        _context.resolveCompilationUnit2(source, source);
-//    expect(compilationUnit, isNotNull);
-//    expect(_context.getLineInfo(source), isNotNull);
-//  }
-
-  void test_resolveCompilationUnit_library() {
-    Source source = addSource("/lib.dart", "library lib;");
-    LibraryElement library = context.computeLibraryElement(source);
-    CompilationUnit compilationUnit =
-        context.resolveCompilationUnit(source, library);
-    expect(compilationUnit, isNotNull);
-    expect(compilationUnit.declaredElement, isNotNull);
-  }
-
-  void test_resolveCompilationUnit_source() {
-    Source source = addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit =
-        context.resolveCompilationUnit2(source, source);
-    expect(compilationUnit, isNotNull);
-  }
-
-  void test_setAnalysisOptions() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.dart2jsHint = false;
-    options.hint = false;
-    context.analysisOptions = options;
-    AnalysisOptions result = context.analysisOptions;
-    expect(result.dart2jsHint, options.dart2jsHint);
-    expect(result.hint, options.hint);
-  }
-
-  void test_setAnalysisPriorityOrder() {
-    int priorityCount = 4;
-    List<Source> sources = <Source>[];
-    for (int index = 0; index < priorityCount; index++) {
-      sources.add(addSource("/lib.dart$index", ""));
-    }
-    context.analysisPriorityOrder = sources;
-    expect(_getPriorityOrder(context).length, priorityCount);
-  }
-
-  void test_setAnalysisPriorityOrder_empty() {
-    context.analysisPriorityOrder = <Source>[];
-  }
-
-  void test_setAnalysisPriorityOrder_nonEmpty() {
-    List<Source> sources = <Source>[];
-    sources.add(addSource("/lib.dart", "library lib;"));
-    context.analysisPriorityOrder = sources;
-  }
-
-  void test_setAnalysisPriorityOrder_resetAnalysisDriver() {
-    Source source = addSource('/lib.dart', 'library lib;');
-    // start analysis
-    context.performAnalysisTask();
-    expect(context.driver.currentWorkOrder, isNotNull);
-    // set priority sources, AnalysisDriver is reset
-    context.analysisPriorityOrder = <Source>[source];
-    expect(context.driver.currentWorkOrder, isNull);
-    // analysis continues
-    context.performAnalysisTask();
-    expect(context.driver.currentWorkOrder, isNotNull);
-  }
-
-  Future test_setChangedContents_libraryWithPart() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    context.analysisOptions = options;
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    String oldCode = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = addSource("/lib.dart", oldCode);
-    String partContents = r'''
-part of lib;
-int b = a;''';
-    Source partSource = addSource("/part.dart", partContents);
-    LibraryElement element = context.computeLibraryElement(librarySource);
-    CompilationUnit unit =
-        context.resolveCompilationUnit(librarySource, element);
-    expect(unit, isNotNull);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-part 'part.dart';
-int ya = 0;''';
-    context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(context.getContents(librarySource).data, newCode);
-    expect(
-        context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_setChangedContents_notResolved() {
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(context.analysisOptions);
-    context.analysisOptions = options;
-    String oldCode = r'''
-library lib;
-int a = 0;''';
-    Source librarySource = addSource("/lib.dart", oldCode);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-int ya = 0;''';
-    context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(context.getContents(librarySource).data, newCode);
-  }
-
-  Future test_setContents_libraryWithPart() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = addSource("/lib.dart", libraryContents1);
-    String partContents1 = r'''
-part of lib;
-int b = a;''';
-    Source partSource = addSource("/part.dart", partContents1);
-    context.computeLibraryElement(librarySource);
-    String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
-    context.setContents(librarySource, libraryContents2);
-    expect(
-        context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_setContents_null() {
-    // AnalysisContext incremental analysis has been removed
-    if (context != null) return;
-    throw 'is this test used by the new analysis driver?';
-
-//    Source librarySource = addSource(
-//        "/lib.dart",
-//        r'''
-//library lib;
-//int a = 0;''');
-//    context.setContents(librarySource, '// different');
-//    context.computeLibraryElement(librarySource);
-//    context.setContents(librarySource, null);
-//    expect(context.getResolvedCompilationUnit2(librarySource, librarySource),
-//        isNull);
-  }
-
-  void test_setContents_unchanged_consistentModificationTime() {
-    String contents = "// foo";
-    Source source = addSource("/test.dart", contents);
-    context.setContents(source, contents);
-    // do all, no tasks
-    _analyzeAll_assertFinished();
-    {
-      AnalysisResult result = context.performAnalysisTask();
-      expect(result.changeNotices, isNull);
-    }
-    // set the same contents, still no tasks
-    context.setContents(source, contents);
-    {
-      AnalysisResult result = context.performAnalysisTask();
-      expect(result.changeNotices, isNull);
-    }
-  }
-
-  void test_setSourceFactory() {
-    expect(context.sourceFactory, sourceFactory);
-    SourceFactory factory = new SourceFactory([]);
-    context.sourceFactory = factory;
-    expect(context.sourceFactory, factory);
-  }
-
-  void test_updateAnalysis() {
-    expect(context.sourcesNeedingProcessing, isEmpty);
-    Source source = newSource('/test.dart');
-    AnalysisDelta delta = new AnalysisDelta();
-    delta.setAnalysisLevel(source, AnalysisLevel.ALL);
-    context.applyAnalysisDelta(delta);
-    expect(context.sourcesNeedingProcessing, contains(source));
-    delta = new AnalysisDelta();
-    delta.setAnalysisLevel(source, AnalysisLevel.NONE);
-    context.applyAnalysisDelta(delta);
-    expect(context.sourcesNeedingProcessing.contains(source), isFalse);
-  }
-
-  void test_validateCacheConsistency_deletedFile() {
-    String pathA = '/a.dart';
-    String pathB = '/b.dart';
-    var fileA = newFile(pathA);
-    var fileB = newFile(pathB, content: "import 'a.dart';");
-    Source sourceA = fileA.createSource();
-    Source sourceB = fileB.createSource();
-    context.applyChanges(
-        new ChangeSet()..addedSource(sourceA)..addedSource(sourceB));
-    // analyze everything
-    _analyzeAll_assertFinished();
-    // delete a.dart
-    deleteFile(pathA);
-    // analysis should eventually stop
-    _analyzeAll_assertFinished();
-  }
-
-  void xtest_performAnalysisTask_stress() {
-    int maxCacheSize = 4;
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(context.analysisOptions);
-    context.analysisOptions = options;
-    int sourceCount = maxCacheSize + 2;
-    List<Source> sources = <Source>[];
-    ChangeSet changeSet = new ChangeSet();
-    for (int i = 0; i < sourceCount; i++) {
-      Source source = addSource("/lib$i.dart", "library lib$i;");
-      sources.add(source);
-      changeSet.addedSource(source);
-    }
-    context.applyChanges(changeSet);
-    context.analysisPriorityOrder = sources;
-    for (int i = 0; i < 1000; i++) {
-      List<ChangeNotice> notice = context.performAnalysisTask().changeNotices;
-      if (notice == null) {
-        //System.out.println("test_performAnalysisTask_stress: " + i);
-        break;
-      }
-    }
-    List<ChangeNotice> notice = context.performAnalysisTask().changeNotices;
-    if (notice != null) {
-      fail(
-          "performAnalysisTask failed to terminate after analyzing all sources");
-    }
-  }
-
-  TestSource _addSourceWithException(String fileName) {
-    return _addSourceWithException2(fileName, "");
-  }
-
-  TestSource _addSourceWithException2(String fileName, String contents) {
-    TestSource source = new TestSource(fileName, contents);
-    source.generateExceptionOnRead = true;
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    return source;
-  }
-
-  /**
-   * Perform analysis tasks up to 512 times and assert that it was enough.
-   */
-  void _analyzeAll_assertFinished([int maxIterations = 512]) {
-    for (int i = 0; i < maxIterations; i++) {
-      List<ChangeNotice> notice = context.performAnalysisTask().changeNotices;
-      if (notice == null) {
-        return;
-      }
-    }
-    fail("performAnalysisTask failed to terminate after analyzing all sources");
-  }
-
-  void _assertNoExceptions() {
-    MapIterator<AnalysisTarget, CacheEntry> iterator = analysisCache.iterator();
-    String exceptionsStr = '';
-    while (iterator.moveNext()) {
-      CaughtException exception = iterator.value.exception;
-      if (exception != null) {
-        AnalysisTarget target = iterator.key;
-        exceptionsStr +=
-            '============= key: $target   source: ${target.source}\n';
-        exceptionsStr += exception.toString();
-        exceptionsStr += '\n';
-      }
-    }
-    if (exceptionsStr.isNotEmpty) {
-      fail(exceptionsStr);
-    }
-  }
-
-  void _changeSource(TestSource source, String contents) {
-    source.setContents(contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(source);
-    context.applyChanges(changeSet);
-  }
-
-  void _checkFlushSingleResolvedUnit(String code,
-      void validate(CompilationUnitElement unitElement, String reason)) {
-    prepareAnalysisContext(new AnalysisOptionsImpl());
-    Source source = newFile('/test.dart', content: code).createSource();
-    context.applyChanges(new ChangeSet()..addedSource(source));
-    CompilationUnitElement unitElement =
-        context.resolveCompilationUnit2(source, source).declaredElement;
-    validate(unitElement, 'initial state');
-    for (ResultDescriptor<CompilationUnit> descriptor
-        in RESOLVED_UNIT_RESULTS) {
-      context.analysisCache.flush(
-          (target, result) => target.source == source && result == descriptor);
-      context.computeResult(
-          new LibrarySpecificUnit(source, source), descriptor);
-      validate(unitElement, 'after flushing $descriptor');
-    }
-  }
-
-  /**
-   * Search the given compilation unit for a class with the given name. Return the class with the
-   * given name, or `null` if the class cannot be found.
-   *
-   * @param unit the compilation unit being searched
-   * @param className the name of the class being searched for
-   * @return the class with the given name
-   */
-  ClassElement _findClass(CompilationUnitElement unit, String className) {
-    for (ClassElement classElement in unit.types) {
-      if (classElement.displayName == className) {
-        return classElement;
-      }
-    }
-    return null;
-  }
-
-  void _flushAst(Source source) {
-    CacheEntry entry =
-        context.getCacheEntry(new LibrarySpecificUnit(source, source));
-    entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
-  }
-
-  List<Source> _getPriorityOrder(AnalysisContextImpl context) {
-    return context.test_priorityOrder;
-  }
-
-  void _performPendingAnalysisTasks([int maxTasks = 512]) {
-    for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) {
-      if (i > maxTasks) {
-        fail('Analysis did not terminate.');
-      }
-    }
-  }
-
-  void _removeSource(Source source) {
-    deleteFile(source.fullName);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.removedSource(source);
-    context.applyChanges(changeSet);
-  }
-
-  /**
-   * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
-   * the given [AnalysisErrorInfo].
-   */
-  static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) {
-    List<AnalysisError> errors = errorInfo.errors;
-    for (AnalysisError analysisError in errors) {
-      if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-class _AnalysisContextImplTest_Source_exists_true extends TestSource {
-  @override
-  bool exists() => true;
-}
-
-class _AnalysisContextImplTest_Source_getModificationStamp_fromSource
-    extends TestSource {
-  int stamp;
-  _AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
-  @override
-  int get modificationStamp => stamp;
-}
-
-class _AnalysisContextImplTest_Source_getModificationStamp_overridden
-    extends TestSource {
-  int stamp;
-  _AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
-  @override
-  int get modificationStamp => stamp;
-}
-
-class _AnalysisContextImplTest_test_applyChanges_removeContainer
-    implements SourceContainer {
-  Source libB;
-  _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB);
-  @override
-  bool contains(Source source) => source == libB;
-}
-
-/**
- * A visitor that can be used to compare all of the elements in an element model
- * with a previously created map of elements. The class [ElementGatherer] can be
- * used to create the map of elements.
- */
-class _ElementComparer extends GeneralizingElementVisitor {
-  /**
-   * The previously created map of elements.
-   */
-  final Map<Element, Element> previousElements;
-
-  /**
-   * The number of elements that were found to have been overwritten.
-   */
-  int overwrittenCount = 0;
-
-  /**
-   * A buffer to which a description of the overwritten elements will be written.
-   */
-  final StringBuffer buffer = new StringBuffer();
-
-  /**
-   * Initialize a newly created visitor.
-   */
-  _ElementComparer(this.previousElements);
-
-  /**
-   * Expect that no differences were found, causing the test to fail if that
-   * wasn't the case.
-   */
-  void expectNoDifferences() {
-    if (overwrittenCount > 0) {
-      fail('Found $overwrittenCount overwritten elements.$buffer');
-    }
-  }
-
-  @override
-  void visitElement(Element element) {
-    Element previousElement = previousElements[element];
-    bool ok = _expectedIdentical(element)
-        ? identical(previousElement, element)
-        : previousElement == element;
-    if (!ok) {
-      if (overwrittenCount == 0) {
-        buffer.writeln();
-      }
-      overwrittenCount++;
-      buffer.writeln('Overwritten element:');
-      Element currentElement = element;
-      while (currentElement != null) {
-        buffer.write('  ');
-        buffer.writeln(currentElement.toString());
-        currentElement = currentElement.enclosingElement;
-      }
-    }
-    super.visitElement(element);
-  }
-
-  /**
-   * Return `true` if the given [element] should be the same as the previous
-   * element at the same position in the element model.
-   */
-  static bool _expectedIdentical(Element element) {
-    while (element != null) {
-      if (element is ConstructorElement ||
-          element is MethodElement ||
-          element is FunctionElement &&
-              element.enclosingElement is CompilationUnitElement) {
-        return false;
-      }
-      element = element.enclosingElement;
-    }
-    return true;
-  }
-}
-
-/**
- * A visitor that can be used to collect all of the elements in an element
- * model.
- */
-class _ElementGatherer extends GeneralizingElementVisitor {
-  /**
-   * The map in which the elements are collected. The value of each key is the
-   * key itself.
-   */
-  Map<Element, Element> elements = new HashMap<Element, Element>();
-
-  /**
-   * Initialize the visitor.
-   */
-  _ElementGatherer();
-
-  @override
-  void visitElement(Element element) {
-    elements[element] = element;
-    super.visitElement(element);
-  }
-}
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index 26c449b..5f5e2d0 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -6,7 +6,6 @@
 
 import 'builder_test.dart' as builder_test;
 import 'cache_test.dart' as cache_test;
-import 'context_test.dart' as context_test;
 import 'source_test.dart' as source_test;
 
 /// Utility for manually running all tests.
@@ -14,7 +13,6 @@
   defineReflectiveSuite(() {
     builder_test.main();
     cache_test.main();
-    context_test.main();
     source_test.main();
   }, name: 'context');
 }
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 e52ece7..f5d7695 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -16,12 +16,12 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../utils.dart';
-import '../resolution/find_element.dart';
-import '../resolution/find_node.dart';
 import 'base.dart';
 
 main() {
@@ -5209,23 +5209,6 @@
     }
   }
 
-  test_mapLiteral_1() async {
-    addTestFile(r'''
-main() {
-  var v = <int>{};
-}
-''');
-    await resolveTestFile();
-    expect(result.errors, isNotEmpty);
-
-    var literal = findNode.mapLiteral('<int>{}');
-    assertType(literal, 'Map<dynamic, dynamic>');
-
-    var intRef = findNode.simple('int>{}');
-    assertElement(intRef, intElement);
-    assertType(intRef, 'int');
-  }
-
   test_mapLiteral_3() async {
     addTestFile(r'''
 main() {
@@ -6732,6 +6715,24 @@
     assertElement(tReference, tElement);
   }
 
+  test_setLiteral() async {
+    addTestFile(r'''
+main() {
+  var v = <int>{};
+  print(v);
+}
+''');
+    await resolveTestFile();
+    expect(result.errors, isEmpty);
+
+    var literal = findNode.setLiteral('<int>{}');
+    assertType(literal, 'Set<int>');
+
+    var intRef = findNode.simple('int>{}');
+    assertElement(intRef, intElement);
+    assertType(intRef, 'int');
+  }
+
   test_stringInterpolation() async {
     String content = r'''
 void main() {
@@ -8797,7 +8798,7 @@
     expect(type, isNotNull);
     expect(element.name, name);
     expect(element.nameOffset, offset);
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     expect(element.parameterKind, kind);
     expect(element.type, type);
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 0970f26..5cfbae5 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -31,6 +31,7 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../../../util/element_type_matchers.dart';
 import '../../../utils.dart';
 import 'base.dart';
 
@@ -340,6 +341,8 @@
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class AnalysisDriverTest extends BaseAnalysisDriverTest {
   void configurePreviewDart2() {
@@ -1114,7 +1117,7 @@
         await createAnalysisDriver().test.getSummaryStore(a);
 
     // There are at least a.dart and dart:core libraries.
-    String aUri = toUri(a).toString();
+    String aUri = toUriStr(a);
     expect(summaryStore.unlinkedMap.keys, contains(aUri));
     expect(summaryStore.linkedMap.keys, contains(aUri));
     expect(summaryStore.unlinkedMap.keys, contains('dart:core'));
@@ -1156,8 +1159,8 @@
     SummaryDataStore summaryStore =
         await createAnalysisDriver().test.getSummaryStore(a);
 
-    String aUri = toUri(a).toString();
-    String bUri = toUri(b).toString();
+    String aUri = toUriStr(a);
+    String bUri = toUriStr(b);
     // There are unlinked units for a.dart and b.dart files.
     expect(summaryStore.hasUnlinkedUnit(aUri), isTrue);
     expect(summaryStore.hasUnlinkedUnit(bUri), isTrue);
@@ -1865,7 +1868,7 @@
     ClassDeclaration c = result.unit.declarations[1] as ClassDeclaration;
     Annotation a = c.metadata[0];
     expect(a.name.name, 'fff');
-    expect(a.name.staticElement, new TypeMatcher<FunctionElement>());
+    expect(a.name.staticElement, isFunctionElement);
   }
 
   test_getResult_invalidUri() async {
@@ -2074,7 +2077,7 @@
       ResolvedUnitResult result = await driver.getResult(c);
       expect(
         _getImportSource(result.unit, 0).uri,
-        toUri(convertPath('/test/lib/a.dart')),
+        toUri('/test/lib/a.dart'),
       );
       expect(_getTopLevelVarType(result.unit, 'VC'), 'A<double>');
     }
@@ -2425,6 +2428,32 @@
     expect(_getTopLevelVarType(result.unit, 'b'), 'B');
   }
 
+  test_importOfNonLibrary_part_afterLibrary() async {
+    var a = convertPath('/test/lib/a.dart');
+    var b = convertPath('/test/lib/b.dart');
+    var c = convertPath('/test/lib/c.dart');
+
+    newFile(a, content: '''
+library my.lib;
+
+part 'b.dart';
+''');
+    newFile(b, content: '''
+part of my.lib;
+
+class A {}
+''');
+    newFile(c, content: '''
+import 'b.dart';
+''');
+
+    // This ensures that `a.dart` linked library is cached.
+    await driver.getResult(a);
+
+    // Should not fail because of considering `b.dart` part as `a.dart` library.
+    await driver.getResult(c);
+  }
+
   test_instantiateToBounds_invalid() async {
     var a = convertPath('/test/lib/a.dart');
     newFile(a, content: r'''
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 119f2b3..0a97168 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -889,6 +889,29 @@
     _assertFilesWithoutLibraryCycle([fa, fb, fc]);
   }
 
+  test_transitiveSignature_part() {
+    var aPath = convertPath('/test/lib/a.dart');
+    var bPath = convertPath('/test/lib/b.dart');
+
+    newFile(aPath, content: r'''
+part 'b.dart';
+''');
+    newFile(bPath, content: '''
+part of 'a.dart';
+''');
+
+    var aFile = fileSystemState.getFileForPath(aPath);
+    var bFile = fileSystemState.getFileForPath(bPath);
+
+    var aSignature = aFile.transitiveSignature;
+    var bSignature = bFile.transitiveSignature;
+
+    // It is not valid to use a part as a library, and so ask its signature.
+    // But when this happens, we should compute the transitive signature anyway.
+    // And it should not be the signature of the containing library.
+    expect(bSignature, isNot(aSignature));
+  }
+
   void _assertExportedTopLevelDeclarations(String path, List<String> expected) {
     FileState file = fileSystemState.getFileForPath(path);
     Map<String, TopLevelDeclaration> declarations =
diff --git a/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart b/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart
index f829d24..097d3ed 100644
--- a/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart
@@ -431,6 +431,14 @@
     expect(names, unorderedEquals(['A', 'B', 'C', 'D', 'E']));
   }
 
+  void test_mixinDeclaration() {
+    Set<String> names = _computeSubtypedNames('''
+import 'lib.dart';
+mixin M on A, B implements C, D {}
+''');
+    expect(names, unorderedEquals(['A', 'B', 'C', 'D']));
+  }
+
   void test_prefixed() {
     Set<String> names = _computeSubtypedNames('''
 import 'lib.dart' as p;
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 8be9b97..e0f2b7d 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/analysis/search.dart';
+import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/testing/element_search.dart';
@@ -1894,6 +1895,45 @@
     expect(c.id, endsWith('c.dart;C'));
   }
 
+  test_subtypes_mixin_superclassConstraints() async {
+    await _resolveTestUnit('''
+class A {
+  void methodA() {}
+}
+
+class B {
+  void methodB() {}
+}
+
+mixin M on A, B {
+  void methodA() {}
+  void methodM() {}
+}
+''');
+    ClassElement a = _findElement('A');
+    ClassElement b = _findElement('B');
+
+    {
+      var subtypes = await driver.search.subtypes(type: a);
+      expect(subtypes, hasLength(1));
+
+      var m = subtypes.singleWhere((r) => r.name == 'M');
+      expect(m.libraryUri, testUri);
+      expect(m.id, '$testUri;$testUri;M');
+      expect(m.members, ['methodA', 'methodM']);
+    }
+
+    {
+      var subtypes = await driver.search.subtypes(type: b);
+      expect(subtypes, hasLength(1));
+
+      var m = subtypes.singleWhere((r) => r.name == 'M');
+      expect(m.libraryUri, testUri);
+      expect(m.id, '$testUri;$testUri;M');
+      expect(m.members, ['methodA', 'methodM']);
+    }
+  }
+
   test_subtypes_partWithoutLibrary() async {
     await _resolveTestUnit('''
 part of lib;
diff --git a/pkg/analyzer/test/src/dart/ast/constant_evaluator_test.dart b/pkg/analyzer/test/src/dart/ast/constant_evaluator_test.dart
new file mode 100644
index 0000000..ac0dc66
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/ast/constant_evaluator_test.dart
@@ -0,0 +1,355 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/ast/constant_evaluator.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'parse_base.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConstantEvaluatorTest);
+  });
+}
+
+@reflectiveTest
+class ConstantEvaluatorTest extends ParseBase {
+  void test_binary_bitAnd() {
+    int value = _getConstantValue("74 & 42");
+    expect(value, 74 & 42);
+  }
+
+  void test_binary_bitOr() {
+    int value = _getConstantValue("74 | 42");
+    expect(value, 74 | 42);
+  }
+
+  void test_binary_bitXor() {
+    int value = _getConstantValue("74 ^ 42");
+    expect(value, 74 ^ 42);
+  }
+
+  void test_binary_divide_double() {
+    Object value = _getConstantValue("3.2 / 2.3");
+    expect(value, 3.2 / 2.3);
+  }
+
+  void test_binary_divide_integer() {
+    Object value = _getConstantValue("3 / 2");
+    expect(value, 1.5);
+  }
+
+  void test_binary_equal_boolean() {
+    Object value = _getConstantValue("true == false");
+    expect(value, false);
+  }
+
+  void test_binary_equal_integer() {
+    Object value = _getConstantValue("2 == 3");
+    expect(value, false);
+  }
+
+  void test_binary_equal_invalidLeft() {
+    Object value = _getConstantValue("a == 3");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_equal_invalidRight() {
+    Object value = _getConstantValue("2 == a");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_equal_string() {
+    Object value = _getConstantValue("'a' == 'b'");
+    expect(value, false);
+  }
+
+  void test_binary_greaterThan() {
+    Object value = _getConstantValue("2 > 3");
+    expect(value, false);
+  }
+
+  void test_binary_greaterThanOrEqual() {
+    Object value = _getConstantValue("2 >= 3");
+    expect(value, false);
+  }
+
+  void test_binary_leftShift() {
+    int value = _getConstantValue("16 << 2");
+    expect(value, 64);
+  }
+
+  void test_binary_lessThan() {
+    Object value = _getConstantValue("2 < 3");
+    expect(value, true);
+  }
+
+  void test_binary_lessThanOrEqual() {
+    Object value = _getConstantValue("2 <= 3");
+    expect(value, true);
+  }
+
+  void test_binary_logicalAnd() {
+    Object value = _getConstantValue("true && false");
+    expect(value, false);
+  }
+
+  void test_binary_logicalOr() {
+    Object value = _getConstantValue("true || false");
+    expect(value, true);
+  }
+
+  void test_binary_minus_double() {
+    Object value = _getConstantValue("3.2 - 2.3");
+    expect(value, 3.2 - 2.3);
+  }
+
+  void test_binary_minus_integer() {
+    Object value = _getConstantValue("3 - 2");
+    expect(value, 1);
+  }
+
+  void test_binary_notEqual_boolean() {
+    Object value = _getConstantValue("true != false");
+    expect(value, true);
+  }
+
+  void test_binary_notEqual_integer() {
+    Object value = _getConstantValue("2 != 3");
+    expect(value, true);
+  }
+
+  void test_binary_notEqual_invalidLeft() {
+    Object value = _getConstantValue("a != 3");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_notEqual_invalidRight() {
+    Object value = _getConstantValue("2 != a");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_notEqual_string() {
+    Object value = _getConstantValue("'a' != 'b'");
+    expect(value, true);
+  }
+
+  void test_binary_plus_double() {
+    Object value = _getConstantValue("2.3 + 3.2");
+    expect(value, 2.3 + 3.2);
+  }
+
+  void test_binary_plus_double_string() {
+    Object value = _getConstantValue("'world' + 5.5");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_plus_int_string() {
+    Object value = _getConstantValue("'world' + 5");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_plus_integer() {
+    Object value = _getConstantValue("2 + 3");
+    expect(value, 5);
+  }
+
+  void test_binary_plus_string() {
+    Object value = _getConstantValue("'hello ' + 'world'");
+    expect(value, 'hello world');
+  }
+
+  void test_binary_plus_string_double() {
+    Object value = _getConstantValue("5.5 + 'world'");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_plus_string_int() {
+    Object value = _getConstantValue("5 + 'world'");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_binary_remainder_double() {
+    Object value = _getConstantValue("3.2 % 2.3");
+    expect(value, 3.2 % 2.3);
+  }
+
+  void test_binary_remainder_integer() {
+    Object value = _getConstantValue("8 % 3");
+    expect(value, 2);
+  }
+
+  void test_binary_rightShift() {
+    int value = _getConstantValue("64 >> 2");
+    expect(value, 16);
+  }
+
+  void test_binary_times_double() {
+    Object value = _getConstantValue("2.3 * 3.2");
+    expect(value, 2.3 * 3.2);
+  }
+
+  void test_binary_times_integer() {
+    Object value = _getConstantValue("2 * 3");
+    expect(value, 6);
+  }
+
+  void test_binary_truncatingDivide_double() {
+    int value = _getConstantValue("3.2 ~/ 2.3");
+    expect(value, 1);
+  }
+
+  void test_binary_truncatingDivide_integer() {
+    int value = _getConstantValue("10 ~/ 3");
+    expect(value, 3);
+  }
+
+  @failingTest
+  void test_constructor() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  @failingTest
+  void test_identifier_class() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  @failingTest
+  void test_identifier_function() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  @failingTest
+  void test_identifier_static() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  @failingTest
+  void test_identifier_staticMethod() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  @failingTest
+  void test_identifier_topLevel() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  @failingTest
+  void test_identifier_typeParameter() {
+    Object value = _getConstantValue("?");
+    expect(value, null);
+  }
+
+  void test_literal_boolean_false() {
+    Object value = _getConstantValue("false");
+    expect(value, false);
+  }
+
+  void test_literal_boolean_true() {
+    Object value = _getConstantValue("true");
+    expect(value, true);
+  }
+
+  void test_literal_list() {
+    List value = _getConstantValue("['a', 'b', 'c']");
+    expect(value.length, 3);
+    expect(value[0], "a");
+    expect(value[1], "b");
+    expect(value[2], "c");
+  }
+
+  void test_literal_map() {
+    Map value = _getConstantValue("{'a' : 'm', 'b' : 'n', 'c' : 'o'}");
+    expect(value.length, 3);
+    expect(value["a"], "m");
+    expect(value["b"], "n");
+    expect(value["c"], "o");
+  }
+
+  void test_literal_null() {
+    Object value = _getConstantValue("null");
+    expect(value, null);
+  }
+
+  void test_literal_number_double() {
+    Object value = _getConstantValue("3.45");
+    expect(value, 3.45);
+  }
+
+  void test_literal_number_integer() {
+    Object value = _getConstantValue("42");
+    expect(value, 42);
+  }
+
+  void test_literal_string_adjacent() {
+    Object value = _getConstantValue("'abc' 'def'");
+    expect(value, "abcdef");
+  }
+
+  void test_literal_string_interpolation_invalid() {
+    Object value = _getConstantValue("'a\${f()}c'");
+    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
+  }
+
+  void test_literal_string_interpolation_valid() {
+    Object value = _getConstantValue("'a\${3}c'");
+    expect(value, "a3c");
+  }
+
+  void test_literal_string_simple() {
+    Object value = _getConstantValue("'abc'");
+    expect(value, "abc");
+  }
+
+  void test_parenthesizedExpression() {
+    Object value = _getConstantValue("('a')");
+    expect(value, "a");
+  }
+
+  void test_unary_bitNot() {
+    int value = _getConstantValue("~42");
+    expect(value, ~42);
+  }
+
+  void test_unary_logicalNot() {
+    Object value = _getConstantValue("!true");
+    expect(value, false);
+  }
+
+  void test_unary_negated_double() {
+    Object value = _getConstantValue("-42.3");
+    expect(value, -42.3);
+  }
+
+  void test_unary_negated_integer() {
+    Object value = _getConstantValue("-42");
+    expect(value, -42);
+  }
+
+  Object _getConstantValue(String expressionCode) {
+    var path = convertPath('/test/lib/test.dart');
+
+    newFile(path, content: '''
+void f() {
+  ($expressionCode); // ref
+}
+''');
+
+    var parseResult = parseUnit(path);
+    expect(parseResult.errors, isEmpty);
+
+    var findNode = FindNode(parseResult.content, parseResult.unit);
+    var expression = findNode.parenthesized('); // ref').expression;
+
+    return expression.accept(ConstantEvaluator());
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
new file mode 100644
index 0000000..e7e1ac1
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart
@@ -0,0 +1,368 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analyzer/src/dart/ast/element_locator.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../util/element_type_matchers.dart';
+import '../resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ElementLocatorTest);
+  });
+}
+
+@reflectiveTest
+class ElementLocatorTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions {
+    return AnalysisOptionsImpl()..hint = false;
+  }
+
+  test_locate_AssignmentExpression() async {
+    await _resolveTestCode(r'''
+int x = 0;
+void main() {
+  x += 1;
+}
+''');
+    var node = findNode.assignment('+=');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_BinaryExpression() async {
+    await _resolveTestCode('var x = 3 + 4');
+    var node = findNode.binary('+');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_ClassDeclaration() async {
+    await _resolveTestCode('class A {}');
+    var node = findNode.classDeclaration('class');
+    var element = ElementLocator.locate(node);
+    expect(element, isClassElement);
+  }
+
+  test_locate_CompilationUnit() async {
+    await _resolveTestCode('// only comment');
+
+    var unitElement = result.unit.declaredElement;
+    expect(unitElement, isNotNull);
+
+    var element = ElementLocator.locate(result.unit);
+    expect(element, same(unitElement));
+  }
+
+  test_locate_ConstructorDeclaration() async {
+    await _resolveTestCode(r'''
+class A {
+  A.foo();
+}
+''');
+    var node = findNode.constructor('foo();');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_ExportDirective() async {
+    await _resolveTestCode("export 'dart:code';");
+    var node = findNode.export('export');
+    var element = ElementLocator.locate(node);
+    expect(element, isExportElement);
+  }
+
+  test_locate_FunctionDeclaration() async {
+    await _resolveTestCode('int f() => 3;');
+    var node = findNode.functionDeclaration('f');
+    var element = ElementLocator.locate(node);
+    expect(element, isFunctionElement);
+  }
+
+  test_locate_Identifier_annotationClass_namedConstructor() async {
+    await _resolveTestCode(r'''
+class Class {
+  const Class.name();
+}
+void main(@Class.name() parameter) {}
+''');
+    var node = findNode.simple('Class.name() parameter');
+    var element = ElementLocator.locate(node);
+    expect(element, isClassElement);
+  }
+
+  test_locate_Identifier_annotationClass_unnamedConstructor() async {
+    await _resolveTestCode(r'''
+class Class {
+  const Class();
+}
+void main(@Class() parameter) {}
+''');
+    var node = findNode.simple('Class() parameter');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_Identifier_className() async {
+    await _resolveTestCode('class A {}');
+    var node = findNode.simple('A');
+    var element = ElementLocator.locate(node);
+    expect(element, isClassElement);
+  }
+
+  test_locate_Identifier_constructor_named() async {
+    await _resolveTestCode(r'''
+class A {
+  A.bar();
+}
+''');
+    var node = findNode.simple('bar');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_Identifier_constructor_unnamed() async {
+    await _resolveTestCode(r'''
+class A {
+  A();
+}
+''');
+    var node = findNode.constructor('A();');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_Identifier_fieldName() async {
+    await _resolveTestCode('''
+class A {
+  var x;
+}
+''');
+    var node = findNode.simple('x;');
+    var element = ElementLocator.locate(node);
+    expect(element, isFieldElement);
+  }
+
+  test_locate_Identifier_libraryDirective() async {
+    await _resolveTestCode('library foo.bar;');
+    var node = findNode.simple('foo');
+    var element = ElementLocator.locate(node);
+    expect(element, isLibraryElement);
+  }
+
+  test_locate_Identifier_propertyAccess() async {
+    await _resolveTestCode(r'''
+void main() {
+ int x = 'foo'.length;
+}
+''');
+    var node = findNode.simple('length');
+    var element = ElementLocator.locate(node);
+    expect(element, isPropertyAccessorElement);
+  }
+
+  test_locate_ImportDirective() async {
+    await _resolveTestCode("import 'dart:core';");
+    var node = findNode.import('import');
+    var element = ElementLocator.locate(node);
+    expect(element, isImportElement);
+  }
+
+  test_locate_IndexExpression() async {
+    await _resolveTestCode(r'''
+void main() {
+  var x = [1, 2];
+  var y = x[0];
+}
+''');
+    var node = findNode.index('[0]');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_InstanceCreationExpression() async {
+    await _resolveTestCode(r'''
+class A {}
+
+void main() {
+ new A();
+}
+''');
+    var node = findNode.instanceCreation('new A()');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_InstanceCreationExpression_type_prefixedIdentifier() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {}
+''');
+    await _resolveTestCode(r'''
+import 'a.dart' as pref;
+
+void main() {
+ new pref.A();
+}
+''');
+    var node = findNode.instanceCreation('A();');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_InstanceCreationExpression_type_simpleIdentifier() async {
+    newFile('/test/lib/a.dart', content: r'''
+''');
+    await _resolveTestCode(r'''
+class A {}
+
+void main() {
+ new A();
+}
+''');
+    var node = findNode.instanceCreation('A();');
+    var element = ElementLocator.locate(node);
+    expect(element, isConstructorElement);
+  }
+
+  test_locate_LibraryDirective() async {
+    await _resolveTestCode('library foo;');
+    var node = findNode.library('library');
+    var element = ElementLocator.locate(node);
+    expect(element, isLibraryElement);
+  }
+
+  test_locate_MethodDeclaration() async {
+    await _resolveTestCode(r'''
+class A {
+  void foo() {}
+}
+''');
+    var node = findNode.methodDeclaration('foo');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_MethodInvocation_method() async {
+    await _resolveTestCode(r'''
+class A {
+  void foo() {}
+}
+
+void main() {
+ new A().foo();
+}
+''');
+    var node = findNode.methodInvocation('foo();');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_MethodInvocation_topLevel() async {
+    await _resolveTestCode(r'''
+foo(x) {}
+
+void main() {
+ foo(0);
+}
+''');
+    var node = findNode.methodInvocation('foo(0)');
+    var element = ElementLocator.locate(node);
+    expect(element, isFunctionElement);
+  }
+
+  test_locate_PartOfDirective() async {
+    var libPath = convertPath('/test/lib/lib.dart');
+    var partPath = convertPath('/test/lib/test.dart');
+
+    newFile(libPath, content: r'''
+library my.lib;
+part 'test.dart';
+''');
+
+    driver.addFile(libPath);
+    driver.addFile(partPath);
+
+    await _resolveTestCode('part of my.lib;');
+    var node = findNode.partOf('part of');
+    var element = ElementLocator.locate(node);
+    expect(element, isLibraryElement);
+  }
+
+  test_locate_PostfixExpression() async {
+    await _resolveTestCode('int addOne(int x) => x++;');
+    var node = findNode.postfix('x++');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_PrefixedIdentifier() async {
+    await _resolveTestCode(r'''
+import 'dart:core' as core;
+core.int value;
+''');
+    var node = findNode.prefixed('core.int');
+    var element = ElementLocator.locate(node);
+    expect(element, isClassElement);
+  }
+
+  test_locate_PrefixExpression() async {
+    await _resolveTestCode('int addOne(int x) => ++x;');
+    var node = findNode.prefix('++x');
+    var element = ElementLocator.locate(node);
+    expect(element, isMethodElement);
+  }
+
+  test_locate_StringLiteral_exportUri() async {
+    newFile("/test/lib/foo.dart", content: '');
+    await _resolveTestCode("export 'foo.dart';");
+    var node = findNode.stringLiteral('foo.dart');
+    var element = ElementLocator.locate(node);
+    expect(element, isLibraryElement);
+  }
+
+  test_locate_StringLiteral_expression() async {
+    await _resolveTestCode("var x = 'abc';");
+    var node = findNode.stringLiteral('abc');
+    var element = ElementLocator.locate(node);
+    expect(element, isNull);
+  }
+
+  test_locate_StringLiteral_importUri() async {
+    newFile("/test/lib/foo.dart", content: '');
+    await _resolveTestCode("import 'foo.dart';");
+    var node = findNode.stringLiteral('foo.dart');
+    var element = ElementLocator.locate(node);
+    expect(element, isLibraryElement);
+  }
+
+  test_locate_StringLiteral_partUri() async {
+    newFile("/test/lib/foo.dart", content: 'part of lib;');
+    await _resolveTestCode('''
+library lib;
+
+part 'foo.dart';
+''');
+    var node = findNode.stringLiteral('foo.dart');
+    var element = ElementLocator.locate(node);
+    expect(element, isCompilationUnitElement);
+  }
+
+  test_locate_VariableDeclaration() async {
+    await _resolveTestCode('var x = 42;');
+    var node = findNode.variableDeclaration('x =');
+    var element = ElementLocator.locate(node);
+    expect(element, isTopLevelVariableElement);
+  }
+
+  Future<void> _resolveTestCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/ast/parse_base.dart b/pkg/analyzer/test/src/dart/ast/parse_base.dart
new file mode 100644
index 0000000..a157430
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/ast/parse_base.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+
+class ParseBase with ResourceProviderMixin {
+  /// Override this to change the analysis options for a given set of tests.
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl();
+
+  ParseResult parseUnit(String path) {
+    var file = getFile(path);
+    var source = file.createSource();
+    var content = file.readAsStringSync();
+
+    var analysisOptions = this.analysisOptions;
+    var experimentStatus = analysisOptions.experimentStatus;
+
+    var errorListener = RecordingErrorListener();
+
+    var reader = CharSequenceReader(content);
+    var scanner = Scanner(source, reader, errorListener);
+
+    scanner.enableGtGtGt = experimentStatus.constant_update_2018;
+    var token = scanner.tokenize();
+
+    var useFasta = analysisOptions.useFastaParser;
+    var parser = Parser(source, errorListener, useFasta: useFasta);
+    parser.enableOptionalNewAndConst = true;
+    parser.enableSetLiterals = experimentStatus.set_literals;
+    parser.enableNonNullable = experimentStatus.non_nullable;
+    parser.enableSpreadCollections = experimentStatus.spread_collections;
+    parser.enableControlFlowCollections =
+        experimentStatus.control_flow_collections;
+
+    var unit = parser.parseCompilationUnit(token);
+    unit.lineInfo = LineInfo(scanner.lineStarts);
+
+    return ParseResult(path, content, unit, errorListener.errors);
+  }
+}
+
+class ParseResult {
+  final String path;
+  final String content;
+  final CompilationUnit unit;
+  final List<AnalysisError> errors;
+
+  ParseResult(this.path, this.content, this.unit, this.errors);
+}
diff --git a/pkg/analyzer/test/src/dart/ast/test_all.dart b/pkg/analyzer/test/src/dart/ast/test_all.dart
index 2330fd9..25eb567 100644
--- a/pkg/analyzer/test/src/dart/ast/test_all.dart
+++ b/pkg/analyzer/test/src/dart/ast/test_all.dart
@@ -5,11 +5,15 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'ast_test.dart' as ast;
+import 'constant_evaluator_test.dart' as constant_evaluator;
+import 'element_locator_test.dart' as element_locator;
 import 'utilities_test.dart' as utilities;
 
 main() {
   defineReflectiveSuite(() {
     ast.main();
+    constant_evaluator.main();
+    element_locator.main();
     utilities.main();
   }, name: 'ast');
 }
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index c6d4eab..1a9032b 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -23,334 +23,16 @@
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ConstantEvaluatorTest);
     defineReflectiveTests(NodeLocatorTest);
     defineReflectiveTests(NodeLocator2Test);
     defineReflectiveTests(ResolutionCopierTest);
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     defineReflectiveTests(ToSourceVisitorTest);
     defineReflectiveTests(ToSourceVisitor2Test);
   });
 }
 
 @reflectiveTest
-class ConstantEvaluatorTest extends ParserTestCase {
-  void fail_constructor() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void fail_identifier_class() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void fail_identifier_function() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void fail_identifier_static() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void fail_identifier_staticMethod() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void fail_identifier_topLevel() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void fail_identifier_typeParameter() {
-    Object value = _getConstantValue("?");
-    expect(value, null);
-  }
-
-  void test_binary_bitAnd() {
-    int value = _getConstantValue("74 & 42");
-    expect(value, 74 & 42);
-  }
-
-  void test_binary_bitOr() {
-    int value = _getConstantValue("74 | 42");
-    expect(value, 74 | 42);
-  }
-
-  void test_binary_bitXor() {
-    int value = _getConstantValue("74 ^ 42");
-    expect(value, 74 ^ 42);
-  }
-
-  void test_binary_divide_double() {
-    Object value = _getConstantValue("3.2 / 2.3");
-    expect(value, 3.2 / 2.3);
-  }
-
-  void test_binary_divide_integer() {
-    Object value = _getConstantValue("3 / 2");
-    expect(value, 1.5);
-  }
-
-  void test_binary_equal_boolean() {
-    Object value = _getConstantValue("true == false");
-    expect(value, false);
-  }
-
-  void test_binary_equal_integer() {
-    Object value = _getConstantValue("2 == 3");
-    expect(value, false);
-  }
-
-  void test_binary_equal_invalidLeft() {
-    Object value = _getConstantValue("a == 3");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_equal_invalidRight() {
-    Object value = _getConstantValue("2 == a");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_equal_string() {
-    Object value = _getConstantValue("'a' == 'b'");
-    expect(value, false);
-  }
-
-  void test_binary_greaterThan() {
-    Object value = _getConstantValue("2 > 3");
-    expect(value, false);
-  }
-
-  void test_binary_greaterThanOrEqual() {
-    Object value = _getConstantValue("2 >= 3");
-    expect(value, false);
-  }
-
-  void test_binary_leftShift() {
-    int value = _getConstantValue("16 << 2");
-    expect(value, 64);
-  }
-
-  void test_binary_lessThan() {
-    Object value = _getConstantValue("2 < 3");
-    expect(value, true);
-  }
-
-  void test_binary_lessThanOrEqual() {
-    Object value = _getConstantValue("2 <= 3");
-    expect(value, true);
-  }
-
-  void test_binary_logicalAnd() {
-    Object value = _getConstantValue("true && false");
-    expect(value, false);
-  }
-
-  void test_binary_logicalOr() {
-    Object value = _getConstantValue("true || false");
-    expect(value, true);
-  }
-
-  void test_binary_minus_double() {
-    Object value = _getConstantValue("3.2 - 2.3");
-    expect(value, 3.2 - 2.3);
-  }
-
-  void test_binary_minus_integer() {
-    Object value = _getConstantValue("3 - 2");
-    expect(value, 1);
-  }
-
-  void test_binary_notEqual_boolean() {
-    Object value = _getConstantValue("true != false");
-    expect(value, true);
-  }
-
-  void test_binary_notEqual_integer() {
-    Object value = _getConstantValue("2 != 3");
-    expect(value, true);
-  }
-
-  void test_binary_notEqual_invalidLeft() {
-    Object value = _getConstantValue("a != 3");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_notEqual_invalidRight() {
-    Object value = _getConstantValue("2 != a");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_notEqual_string() {
-    Object value = _getConstantValue("'a' != 'b'");
-    expect(value, true);
-  }
-
-  void test_binary_plus_double() {
-    Object value = _getConstantValue("2.3 + 3.2");
-    expect(value, 2.3 + 3.2);
-  }
-
-  void test_binary_plus_double_string() {
-    Object value = _getConstantValue("'world' + 5.5");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_plus_int_string() {
-    Object value = _getConstantValue("'world' + 5");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_plus_integer() {
-    Object value = _getConstantValue("2 + 3");
-    expect(value, 5);
-  }
-
-  void test_binary_plus_string() {
-    Object value = _getConstantValue("'hello ' + 'world'");
-    expect(value, 'hello world');
-  }
-
-  void test_binary_plus_string_double() {
-    Object value = _getConstantValue("5.5 + 'world'");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_plus_string_int() {
-    Object value = _getConstantValue("5 + 'world'");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_binary_remainder_double() {
-    Object value = _getConstantValue("3.2 % 2.3");
-    expect(value, 3.2 % 2.3);
-  }
-
-  void test_binary_remainder_integer() {
-    Object value = _getConstantValue("8 % 3");
-    expect(value, 2);
-  }
-
-  void test_binary_rightShift() {
-    int value = _getConstantValue("64 >> 2");
-    expect(value, 16);
-  }
-
-  void test_binary_times_double() {
-    Object value = _getConstantValue("2.3 * 3.2");
-    expect(value, 2.3 * 3.2);
-  }
-
-  void test_binary_times_integer() {
-    Object value = _getConstantValue("2 * 3");
-    expect(value, 6);
-  }
-
-  void test_binary_truncatingDivide_double() {
-    int value = _getConstantValue("3.2 ~/ 2.3");
-    expect(value, 1);
-  }
-
-  void test_binary_truncatingDivide_integer() {
-    int value = _getConstantValue("10 ~/ 3");
-    expect(value, 3);
-  }
-
-  void test_literal_boolean_false() {
-    Object value = _getConstantValue("false");
-    expect(value, false);
-  }
-
-  void test_literal_boolean_true() {
-    Object value = _getConstantValue("true");
-    expect(value, true);
-  }
-
-  void test_literal_list() {
-    List value = _getConstantValue("['a', 'b', 'c']");
-    expect(value.length, 3);
-    expect(value[0], "a");
-    expect(value[1], "b");
-    expect(value[2], "c");
-  }
-
-  void test_literal_map() {
-    Map value = _getConstantValue("{'a' : 'm', 'b' : 'n', 'c' : 'o'}");
-    expect(value.length, 3);
-    expect(value["a"], "m");
-    expect(value["b"], "n");
-    expect(value["c"], "o");
-  }
-
-  void test_literal_null() {
-    Object value = _getConstantValue("null");
-    expect(value, null);
-  }
-
-  void test_literal_number_double() {
-    Object value = _getConstantValue("3.45");
-    expect(value, 3.45);
-  }
-
-  void test_literal_number_integer() {
-    Object value = _getConstantValue("42");
-    expect(value, 42);
-  }
-
-  void test_literal_string_adjacent() {
-    Object value = _getConstantValue("'abc' 'def'");
-    expect(value, "abcdef");
-  }
-
-  void test_literal_string_interpolation_invalid() {
-    Object value = _getConstantValue("'a\${f()}c'");
-    expect(value, ConstantEvaluator.NOT_A_CONSTANT);
-  }
-
-  void test_literal_string_interpolation_valid() {
-    Object value = _getConstantValue("'a\${3}c'");
-    expect(value, "a3c");
-  }
-
-  void test_literal_string_simple() {
-    Object value = _getConstantValue("'abc'");
-    expect(value, "abc");
-  }
-
-  void test_parenthesizedExpression() {
-    Object value = _getConstantValue("('a')");
-    expect(value, "a");
-  }
-
-  void test_unary_bitNot() {
-    int value = _getConstantValue("~42");
-    expect(value, ~42);
-  }
-
-  void test_unary_logicalNot() {
-    Object value = _getConstantValue("!true");
-    expect(value, false);
-  }
-
-  void test_unary_negated_double() {
-    Object value = _getConstantValue("-42.3");
-    expect(value, -42.3);
-  }
-
-  void test_unary_negated_integer() {
-    Object value = _getConstantValue("-42");
-    expect(value, -42);
-  }
-
-  Object _getConstantValue(String source) =>
-      parseExpression(source).accept(new ConstantEvaluator());
-}
-
-@reflectiveTest
 class NodeLocator2Test extends ParserTestCase {
   void test_onlyStartOffset() {
     String code = ' int vv; ';
@@ -617,6 +299,132 @@
     expect(toNode.element, same(element));
   }
 
+  void test_visitForEachPartsWithDeclaration() {
+    ForEachPartsWithDeclaration createNode() =>
+        astFactory.forEachPartsWithDeclaration(
+            loopVariable: AstTestFactory.declaredIdentifier3('a'),
+            iterable: AstTestFactory.identifier3('b'));
+
+    DartType typeB = ElementFactory.classElement2("B").type;
+
+    ForEachPartsWithDeclaration fromNode = createNode();
+    (fromNode.iterable as SimpleIdentifier).staticType = typeB;
+
+    ForEachPartsWithDeclaration toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.iterable as SimpleIdentifier).staticType, same(typeB));
+  }
+
+  void test_visitForEachPartsWithIdentifier() {
+    ForEachPartsWithIdentifier createNode() =>
+        astFactory.forEachPartsWithIdentifier(
+            identifier: AstTestFactory.identifier3('a'),
+            iterable: AstTestFactory.identifier3('b'));
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+
+    ForEachPartsWithIdentifier fromNode = createNode();
+    fromNode.identifier.staticType = typeA;
+    (fromNode.iterable as SimpleIdentifier).staticType = typeB;
+
+    ForEachPartsWithIdentifier toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect(toNode.identifier.staticType, same(typeA));
+    expect((toNode.iterable as SimpleIdentifier).staticType, same(typeB));
+  }
+
+  void test_visitForElement() {
+    ForElement createNode() => astFactory.forElement(
+        forLoopParts: astFactory.forEachPartsWithIdentifier(
+            identifier: AstTestFactory.identifier3('a'),
+            iterable: AstTestFactory.identifier3('b')),
+        body: AstTestFactory.identifier3('c'));
+
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    ForElement fromNode = createNode();
+    (fromNode.body as SimpleIdentifier).staticType = typeC;
+
+    ForElement toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.body as SimpleIdentifier).staticType, same(typeC));
+  }
+
+  void test_visitForPartsWithDeclarations() {
+    ForPartsWithDeclarations createNode() =>
+        astFactory.forPartsWithDeclarations(
+            variables: AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration('a')]),
+            condition: AstTestFactory.identifier3('b'),
+            updaters: [AstTestFactory.identifier3('c')]);
+
+    DartType typeB = ElementFactory.classElement2("B").type;
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    ForPartsWithDeclarations fromNode = createNode();
+    (fromNode.condition as SimpleIdentifier).staticType = typeB;
+    (fromNode.updaters[0] as SimpleIdentifier).staticType = typeC;
+
+    ForPartsWithDeclarations toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.condition as SimpleIdentifier).staticType, same(typeB));
+    expect((toNode.updaters[0] as SimpleIdentifier).staticType, same(typeC));
+  }
+
+  void test_visitForPartsWithExpression() {
+    ForPartsWithExpression createNode() => astFactory.forPartsWithExpression(
+        initialization: AstTestFactory.identifier3('a'),
+        condition: AstTestFactory.identifier3('b'),
+        updaters: [AstTestFactory.identifier3('c')]);
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    ForPartsWithExpression fromNode = createNode();
+    (fromNode.initialization as SimpleIdentifier).staticType = typeA;
+    (fromNode.condition as SimpleIdentifier).staticType = typeB;
+    (fromNode.updaters[0] as SimpleIdentifier).staticType = typeC;
+
+    ForPartsWithExpression toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.initialization as SimpleIdentifier).staticType, same(typeA));
+    expect((toNode.condition as SimpleIdentifier).staticType, same(typeB));
+    expect((toNode.updaters[0] as SimpleIdentifier).staticType, same(typeC));
+  }
+
+  void test_visitForStatement2() {
+    ForStatement2 createNode() => astFactory.forStatement2(
+        forLoopParts: astFactory.forEachPartsWithIdentifier(
+            identifier: AstTestFactory.identifier3('a'),
+            iterable: AstTestFactory.identifier3('b')),
+        body: AstTestFactory.expressionStatement(
+            AstTestFactory.identifier3('c')));
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    ForStatement2 fromNode = createNode();
+    ForEachPartsWithIdentifier fromForLoopParts = fromNode.forLoopParts;
+    fromForLoopParts.identifier.staticType = typeA;
+    (fromForLoopParts.iterable as SimpleIdentifier).staticType = typeB;
+    ((fromNode.body as ExpressionStatement).expression as SimpleIdentifier)
+        .staticType = typeC;
+
+    ForStatement2 toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    ForEachPartsWithIdentifier toForLoopParts = fromNode.forLoopParts;
+    expect(toForLoopParts.identifier.staticType, same(typeA));
+    expect(
+        (toForLoopParts.iterable as SimpleIdentifier).staticType, same(typeB));
+    expect(
+        ((toNode.body as ExpressionStatement).expression as SimpleIdentifier)
+            .staticType,
+        same(typeC));
+  }
+
   void test_visitFunctionExpression() {
     FunctionExpressionImpl fromNode = AstTestFactory.functionExpression2(
         AstTestFactory.formalParameterList(),
@@ -655,6 +463,28 @@
     expect(toNode.staticElement, same(staticElement));
   }
 
+  void test_visitIfElement() {
+    IfElement createNode() => astFactory.ifElement(
+        condition: AstTestFactory.identifier3('a'),
+        thenElement: AstTestFactory.identifier3('b'),
+        elseElement: AstTestFactory.identifier3('c'));
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+    DartType typeC = ElementFactory.classElement2("C").type;
+
+    IfElement fromNode = createNode();
+    (fromNode.condition as SimpleIdentifier).staticType = typeA;
+    (fromNode.thenElement as SimpleIdentifier).staticType = typeB;
+    (fromNode.elseElement as SimpleIdentifier).staticType = typeC;
+
+    IfElement toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect(toNode.condition.staticType, same(typeA));
+    expect((toNode.thenElement as SimpleIdentifier).staticType, same(typeB));
+    expect((toNode.elseElement as SimpleIdentifier).staticType, same(typeC));
+  }
+
   void test_visitImportDirective() {
     ImportDirective fromNode =
         AstTestFactory.importDirective3("dart:uri", null);
@@ -741,6 +571,25 @@
     expect(toNode.staticType, same(staticType));
   }
 
+  void test_visitListLiteral2() {
+    ListLiteral2 createNode() => astFactory.listLiteral2(
+        typeArguments:
+            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')]),
+        elements: [AstTestFactory.identifier3('b')]);
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+
+    ListLiteral2 fromNode = createNode();
+    (fromNode.typeArguments.arguments[0] as TypeName).type = typeA;
+    (fromNode.elements[0] as SimpleIdentifier).staticType = typeB;
+
+    ListLiteral2 toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.typeArguments.arguments[0] as TypeName).type, same(typeA));
+    expect((toNode.elements[0] as SimpleIdentifier).staticType, same(typeB));
+  }
+
   void test_visitMapLiteral() {
     MapLiteral fromNode = AstTestFactory.mapLiteral2();
     DartType staticType = ElementFactory.classElement2("C").type;
@@ -750,6 +599,33 @@
     expect(toNode.staticType, same(staticType));
   }
 
+  void test_visitMapLiteral2() {
+    MapLiteral2 createNode() => astFactory.mapLiteral2(
+        typeArguments: AstTestFactory.typeArgumentList(
+            [AstTestFactory.typeName4('A'), AstTestFactory.typeName4('B')]),
+        entries: [AstTestFactory.mapLiteralEntry3('c', 'd')]);
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+    DartType typeC = ElementFactory.classElement2("C").type;
+    DartType typeD = ElementFactory.classElement2("D").type;
+
+    MapLiteral2 fromNode = createNode();
+    (fromNode.typeArguments.arguments[0] as TypeName).type = typeA;
+    (fromNode.typeArguments.arguments[1] as TypeName).type = typeB;
+    MapLiteralEntry fromEntry = fromNode.entries[0] as MapLiteralEntry;
+    (fromEntry.key as SimpleStringLiteral).staticType = typeC;
+    (fromEntry.value as SimpleStringLiteral).staticType = typeD;
+
+    MapLiteral2 toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.typeArguments.arguments[0] as TypeName).type, same(typeA));
+    expect((toNode.typeArguments.arguments[1] as TypeName).type, same(typeB));
+    MapLiteralEntry toEntry = fromNode.entries[0] as MapLiteralEntry;
+    expect((toEntry.key as SimpleStringLiteral).staticType, same(typeC));
+    expect((toEntry.value as SimpleStringLiteral).staticType, same(typeD));
+  }
+
   void test_visitMethodInvocation() {
     MethodInvocation fromNode = AstTestFactory.methodInvocation2("m");
     MethodInvocation toNode = AstTestFactory.methodInvocation2("m");
@@ -886,6 +762,25 @@
     expect(toNode.staticType, same(staticType));
   }
 
+  void test_visitSetLiteral2() {
+    SetLiteral2 createNode() => astFactory.setLiteral2(
+        typeArguments:
+            AstTestFactory.typeArgumentList([AstTestFactory.typeName4('A')]),
+        elements: [AstTestFactory.identifier3('b')]);
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+    DartType typeB = ElementFactory.classElement2("B").type;
+
+    SetLiteral2 fromNode = createNode();
+    (fromNode.typeArguments.arguments[0] as TypeName).type = typeA;
+    (fromNode.elements[0] as SimpleIdentifier).staticType = typeB;
+
+    SetLiteral2 toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect((toNode.typeArguments.arguments[0] as TypeName).type, same(typeA));
+    expect((toNode.elements[0] as SimpleIdentifier).staticType, same(typeB));
+  }
+
   void test_visitSimpleIdentifier() {
     SimpleIdentifier fromNode = AstTestFactory.identifier3("x");
     MethodElement staticElement = ElementFactory.methodElement(
@@ -912,6 +807,27 @@
     expect(toNode.staticType, same(staticType));
   }
 
+  void test_visitSpreadElement() {
+    SpreadElement createNode() => astFactory.spreadElement(
+        spreadOperator:
+            TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
+        expression: astFactory
+            .listLiteral2(elements: [AstTestFactory.identifier3('a')]));
+
+    DartType typeA = ElementFactory.classElement2("A").type;
+
+    SpreadElement fromNode = createNode();
+    ((fromNode.expression as ListLiteral2).elements[0] as SimpleIdentifier)
+        .staticType = typeA;
+
+    SpreadElement toNode = createNode();
+    ResolutionCopier.copyResolutionData(fromNode, toNode);
+    expect(
+        ((toNode.expression as ListLiteral2).elements[0] as SimpleIdentifier)
+            .staticType,
+        same(typeA));
+  }
+
   void test_visitStringInterpolation() {
     StringInterpolation fromNode =
         AstTestFactory.string([AstTestFactory.interpolationString("a", "'a'")]);
@@ -1881,6 +1797,22 @@
     _assertSource("covariant A this.a", expected);
   }
 
+  void test_visitForEachPartsWithDeclaration() {
+    _assertSource(
+        'var e in l',
+        astFactory.forEachPartsWithDeclaration(
+            loopVariable: AstTestFactory.declaredIdentifier3('e'),
+            iterable: AstTestFactory.identifier3('l')));
+  }
+
+  void test_visitForEachPartsWithIdentifier() {
+    _assertSource(
+        'e in l',
+        astFactory.forEachPartsWithIdentifier(
+            identifier: AstTestFactory.identifier3('e'),
+            iterable: AstTestFactory.identifier3('l')));
+  }
+
   void test_visitForEachStatement_declared() {
     _assertSource(
         "for (var a in b) {}",
@@ -1916,6 +1848,16 @@
             AstTestFactory.block()));
   }
 
+  void test_visitForElement() {
+    _assertSource(
+        'for (e in l) 0',
+        astFactory.forElement(
+            forLoopParts: astFactory.forEachPartsWithIdentifier(
+                identifier: AstTestFactory.identifier3('e'),
+                iterable: AstTestFactory.identifier3('l')),
+            body: AstTestFactory.integer(0)));
+  }
+
   void test_visitFormalParameterList_empty() {
     _assertSource("()", AstTestFactory.formalParameterList());
   }
@@ -2086,6 +2028,36 @@
         ]));
   }
 
+  void test_visitForPartsWithDeclarations() {
+    _assertSource(
+        'var v; b; u',
+        astFactory.forPartsWithDeclarations(
+            variables: AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration('v')]),
+            condition: AstTestFactory.identifier3('b'),
+            updaters: [AstTestFactory.identifier3('u')]));
+  }
+
+  void test_visitForPartsWithExpression() {
+    _assertSource(
+        'v; b; u',
+        astFactory.forPartsWithExpression(
+            initialization: AstTestFactory.identifier3('v'),
+            condition: AstTestFactory.identifier3('b'),
+            updaters: [AstTestFactory.identifier3('u')]));
+  }
+
+  void test_visitForStatement2() {
+    _assertSource(
+        'for (e in l) s;',
+        astFactory.forStatement2(
+            forLoopParts: astFactory.forEachPartsWithIdentifier(
+                identifier: AstTestFactory.identifier3('e'),
+                iterable: AstTestFactory.identifier3('l')),
+            body: AstTestFactory.expressionStatement(
+                AstTestFactory.identifier3('s'))));
+  }
+
   void test_visitForStatement_c() {
     _assertSource(
         "for (; c;) {}",
@@ -2422,6 +2394,23 @@
                 ]))));
   }
 
+  void test_visitIfElement_else() {
+    _assertSource(
+        'if (b) 1 else 0',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1),
+            elseElement: AstTestFactory.integer(0)));
+  }
+
+  void test_visitIfElement_then() {
+    _assertSource(
+        'if (b) 1',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1)));
+  }
+
   void test_visitIfStatement_withElse() {
     _assertSource(
         "if (c) {} else {}",
@@ -2638,6 +2627,62 @@
         AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("a")]));
   }
 
+  void test_visitListLiteral2_complex() {
+    _assertSource(
+        '<int>[0, for (e in l) 0, if (b) 1, ...[0]]',
+        astFactory.listLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [
+              AstTestFactory.integer(0),
+              astFactory.forElement(
+                  forLoopParts: astFactory.forEachPartsWithIdentifier(
+                      identifier: AstTestFactory.identifier3('e'),
+                      iterable: AstTestFactory.identifier3('l')),
+                  body: AstTestFactory.integer(0)),
+              astFactory.ifElement(
+                  condition: AstTestFactory.identifier3('b'),
+                  thenElement: AstTestFactory.integer(1)),
+              astFactory.spreadElement(
+                  spreadOperator: TokenFactory.tokenFromType(
+                      TokenType.PERIOD_PERIOD_PERIOD),
+                  expression: astFactory
+                      .listLiteral2(elements: [AstTestFactory.integer(0)]))
+            ]));
+  }
+
+  void test_visitListLiteral2_withConst_withoutTypeArgs() {
+    _assertSource(
+        'const [0]',
+        astFactory.listLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitListLiteral2_withConst_withTypeArgs() {
+    _assertSource(
+        'const <int>[0]',
+        astFactory.listLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitListLiteral2_withoutConst_withoutTypeArgs() {
+    _assertSource(
+        '[0]', astFactory.listLiteral2(elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitListLiteral2_withoutConst_withTypeArgs() {
+    _assertSource(
+        '<int>[0]',
+        astFactory.listLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
   void test_visitListLiteral_const() {
     _assertSource("const []", AstTestFactory.listLiteral2(Keyword.CONST, null));
   }
@@ -2656,6 +2701,70 @@
         ]));
   }
 
+  void test_visitMapLiteral2_complex() {
+    _assertSource(
+        "<String, String>{'a' : 'b', for (c in d) 'e' : 'f', if (g) 'h' : 'i', ...{'j' : 'k'}}",
+        astFactory.mapLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList([
+              AstTestFactory.typeName4('String'),
+              AstTestFactory.typeName4('String')
+            ]),
+            entries: [
+              AstTestFactory.mapLiteralEntry3('a', 'b'),
+              astFactory.forElement(
+                  forLoopParts: astFactory.forEachPartsWithIdentifier(
+                      identifier: AstTestFactory.identifier3('c'),
+                      iterable: AstTestFactory.identifier3('d')),
+                  body: AstTestFactory.mapLiteralEntry3('e', 'f')),
+              astFactory.ifElement(
+                  condition: AstTestFactory.identifier3('g'),
+                  thenElement: AstTestFactory.mapLiteralEntry3('h', 'i')),
+              astFactory.spreadElement(
+                  spreadOperator: TokenFactory.tokenFromType(
+                      TokenType.PERIOD_PERIOD_PERIOD),
+                  expression: astFactory.mapLiteral2(
+                      entries: [AstTestFactory.mapLiteralEntry3('j', 'k')]))
+            ]));
+  }
+
+  void test_visitMapLiteral2_withConst_withoutTypeArgs() {
+    _assertSource(
+        "const {'a' : 'b'}",
+        astFactory.mapLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
+  void test_visitMapLiteral2_withConst_withTypeArgs() {
+    _assertSource(
+        "const <String, String>{'a' : 'b'}",
+        astFactory.mapLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            typeArguments: AstTestFactory.typeArgumentList([
+              AstTestFactory.typeName4('String'),
+              AstTestFactory.typeName4('String')
+            ]),
+            entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
+  void test_visitMapLiteral2_withoutConst_withoutTypeArgs() {
+    _assertSource(
+        "{'a' : 'b'}",
+        astFactory
+            .mapLiteral2(entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
+  void test_visitMapLiteral2_withoutConst_withTypeArgs() {
+    _assertSource(
+        "<String, String>{'a' : 'b'}",
+        astFactory.mapLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList([
+              AstTestFactory.typeName4('String'),
+              AstTestFactory.typeName4('String')
+            ]),
+            entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
   void test_visitMapLiteral_const() {
     _assertSource("const {}", AstTestFactory.mapLiteral(Keyword.CONST, null));
   }
@@ -3034,6 +3143,62 @@
     _assertSource(scriptTag, AstTestFactory.scriptTag(scriptTag));
   }
 
+  void test_visitSetLiteral2_complex() {
+    _assertSource(
+        '<int>{0, for (e in l) 0, if (b) 1, ...[0]}',
+        astFactory.setLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [
+              AstTestFactory.integer(0),
+              astFactory.forElement(
+                  forLoopParts: astFactory.forEachPartsWithIdentifier(
+                      identifier: AstTestFactory.identifier3('e'),
+                      iterable: AstTestFactory.identifier3('l')),
+                  body: AstTestFactory.integer(0)),
+              astFactory.ifElement(
+                  condition: AstTestFactory.identifier3('b'),
+                  thenElement: AstTestFactory.integer(1)),
+              astFactory.spreadElement(
+                  spreadOperator: TokenFactory.tokenFromType(
+                      TokenType.PERIOD_PERIOD_PERIOD),
+                  expression: astFactory
+                      .listLiteral2(elements: [AstTestFactory.integer(0)]))
+            ]));
+  }
+
+  void test_visitSetLiteral2_withConst_withoutTypeArgs() {
+    _assertSource(
+        'const {0}',
+        astFactory.setLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitSetLiteral2_withConst_withTypeArgs() {
+    _assertSource(
+        'const <int>{0}',
+        astFactory.setLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitSetLiteral2_withoutConst_withoutTypeArgs() {
+    _assertSource(
+        '{0}', astFactory.setLiteral2(elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitSetLiteral2_withoutConst_withTypeArgs() {
+    _assertSource(
+        '<int>{0}',
+        astFactory.setLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
   void test_visitSimpleFormalParameter_annotation() {
     SimpleFormalParameter parameter =
         AstTestFactory.simpleFormalParameter3('x');
@@ -3077,6 +3242,29 @@
     _assertSource("'a'", AstTestFactory.string2("a"));
   }
 
+  void test_visitSpreadElement_nonNullable() {
+    _assertSource(
+        '...[0]',
+        astFactory.spreadElement(
+            spreadOperator:
+                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
+            expression: astFactory
+                .listLiteral2(elements: [AstTestFactory.integer(0)])));
+  }
+
+  @failingTest
+  void test_visitSpreadElement_nullable() {
+    // TODO(brianwilkerson) Replace the token type below when there is one for
+    //  '...?'.
+    _assertSource(
+        '...?[0]',
+        astFactory.spreadElement(
+            spreadOperator:
+                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
+            expression: astFactory
+                .listLiteral2(elements: [AstTestFactory.integer(0)])));
+  }
+
   void test_visitStringInterpolation() {
     _assertSource(
         "'a\${e}b'",
@@ -4289,6 +4477,22 @@
     _assertSource("covariant A this.a", expected);
   }
 
+  void test_visitForEachPartsWithDeclaration() {
+    _assertSource(
+        'var e in l',
+        astFactory.forEachPartsWithDeclaration(
+            loopVariable: AstTestFactory.declaredIdentifier3('e'),
+            iterable: AstTestFactory.identifier3('l')));
+  }
+
+  void test_visitForEachPartsWithIdentifier() {
+    _assertSource(
+        'e in l',
+        astFactory.forEachPartsWithIdentifier(
+            identifier: AstTestFactory.identifier3('e'),
+            iterable: AstTestFactory.identifier3('l')));
+  }
+
   void test_visitForEachStatement_declared() {
     _assertSource(
         "for (var a in b) {}",
@@ -4324,6 +4528,16 @@
             AstTestFactory.block()));
   }
 
+  void test_visitForElement() {
+    _assertSource(
+        'for (e in l) 0',
+        astFactory.forElement(
+            forLoopParts: astFactory.forEachPartsWithIdentifier(
+                identifier: AstTestFactory.identifier3('e'),
+                iterable: AstTestFactory.identifier3('l')),
+            body: AstTestFactory.integer(0)));
+  }
+
   void test_visitFormalParameterList_empty() {
     _assertSource("()", AstTestFactory.formalParameterList());
   }
@@ -4494,6 +4708,36 @@
         ]));
   }
 
+  void test_visitForPartsWithDeclarations() {
+    _assertSource(
+        'var v; b; u',
+        astFactory.forPartsWithDeclarations(
+            variables: AstTestFactory.variableDeclarationList2(
+                Keyword.VAR, [AstTestFactory.variableDeclaration('v')]),
+            condition: AstTestFactory.identifier3('b'),
+            updaters: [AstTestFactory.identifier3('u')]));
+  }
+
+  void test_visitForPartsWithExpression() {
+    _assertSource(
+        'v; b; u',
+        astFactory.forPartsWithExpression(
+            initialization: AstTestFactory.identifier3('v'),
+            condition: AstTestFactory.identifier3('b'),
+            updaters: [AstTestFactory.identifier3('u')]));
+  }
+
+  void test_visitForStatement2() {
+    _assertSource(
+        'for (e in l) s;',
+        astFactory.forStatement2(
+            forLoopParts: astFactory.forEachPartsWithIdentifier(
+                identifier: AstTestFactory.identifier3('e'),
+                iterable: AstTestFactory.identifier3('l')),
+            body: AstTestFactory.expressionStatement(
+                AstTestFactory.identifier3('s'))));
+  }
+
   void test_visitForStatement_c() {
     _assertSource(
         "for (; c;) {}",
@@ -4830,6 +5074,23 @@
                 ]))));
   }
 
+  void test_visitIfElement_else() {
+    _assertSource(
+        'if (b) 1 else 0',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1),
+            elseElement: AstTestFactory.integer(0)));
+  }
+
+  void test_visitIfElement_then() {
+    _assertSource(
+        'if (b) 1',
+        astFactory.ifElement(
+            condition: AstTestFactory.identifier3('b'),
+            thenElement: AstTestFactory.integer(1)));
+  }
+
   void test_visitIfStatement_withElse() {
     _assertSource(
         "if (c) {} else {}",
@@ -5046,6 +5307,62 @@
         AstTestFactory.libraryIdentifier([AstTestFactory.identifier3("a")]));
   }
 
+  void test_visitListLiteral2_complex() {
+    _assertSource(
+        '<int>[0, for (e in l) 0, if (b) 1, ...[0]]',
+        astFactory.listLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [
+              AstTestFactory.integer(0),
+              astFactory.forElement(
+                  forLoopParts: astFactory.forEachPartsWithIdentifier(
+                      identifier: AstTestFactory.identifier3('e'),
+                      iterable: AstTestFactory.identifier3('l')),
+                  body: AstTestFactory.integer(0)),
+              astFactory.ifElement(
+                  condition: AstTestFactory.identifier3('b'),
+                  thenElement: AstTestFactory.integer(1)),
+              astFactory.spreadElement(
+                  spreadOperator: TokenFactory.tokenFromType(
+                      TokenType.PERIOD_PERIOD_PERIOD),
+                  expression: astFactory
+                      .listLiteral2(elements: [AstTestFactory.integer(0)]))
+            ]));
+  }
+
+  void test_visitListLiteral2_withConst_withoutTypeArgs() {
+    _assertSource(
+        'const [0]',
+        astFactory.listLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitListLiteral2_withConst_withTypeArgs() {
+    _assertSource(
+        'const <int>[0]',
+        astFactory.listLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitListLiteral2_withoutConst_withoutTypeArgs() {
+    _assertSource(
+        '[0]', astFactory.listLiteral2(elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitListLiteral2_withoutConst_withTypeArgs() {
+    _assertSource(
+        '<int>[0]',
+        astFactory.listLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
   void test_visitListLiteral_const() {
     _assertSource("const []", AstTestFactory.listLiteral2(Keyword.CONST, null));
   }
@@ -5064,6 +5381,70 @@
         ]));
   }
 
+  void test_visitMapLiteral2_complex() {
+    _assertSource(
+        "<String, String>{'a' : 'b', for (c in d) 'e' : 'f', if (g) 'h' : 'i', ...{'j' : 'k'}}",
+        astFactory.mapLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList([
+              AstTestFactory.typeName4('String'),
+              AstTestFactory.typeName4('String')
+            ]),
+            entries: [
+              AstTestFactory.mapLiteralEntry3('a', 'b'),
+              astFactory.forElement(
+                  forLoopParts: astFactory.forEachPartsWithIdentifier(
+                      identifier: AstTestFactory.identifier3('c'),
+                      iterable: AstTestFactory.identifier3('d')),
+                  body: AstTestFactory.mapLiteralEntry3('e', 'f')),
+              astFactory.ifElement(
+                  condition: AstTestFactory.identifier3('g'),
+                  thenElement: AstTestFactory.mapLiteralEntry3('h', 'i')),
+              astFactory.spreadElement(
+                  spreadOperator: TokenFactory.tokenFromType(
+                      TokenType.PERIOD_PERIOD_PERIOD),
+                  expression: astFactory.mapLiteral2(
+                      entries: [AstTestFactory.mapLiteralEntry3('j', 'k')]))
+            ]));
+  }
+
+  void test_visitMapLiteral2_withConst_withoutTypeArgs() {
+    _assertSource(
+        "const {'a' : 'b'}",
+        astFactory.mapLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
+  void test_visitMapLiteral2_withConst_withTypeArgs() {
+    _assertSource(
+        "const <String, String>{'a' : 'b'}",
+        astFactory.mapLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            typeArguments: AstTestFactory.typeArgumentList([
+              AstTestFactory.typeName4('String'),
+              AstTestFactory.typeName4('String')
+            ]),
+            entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
+  void test_visitMapLiteral2_withoutConst_withoutTypeArgs() {
+    _assertSource(
+        "{'a' : 'b'}",
+        astFactory
+            .mapLiteral2(entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
+  void test_visitMapLiteral2_withoutConst_withTypeArgs() {
+    _assertSource(
+        "<String, String>{'a' : 'b'}",
+        astFactory.mapLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList([
+              AstTestFactory.typeName4('String'),
+              AstTestFactory.typeName4('String')
+            ]),
+            entries: [AstTestFactory.mapLiteralEntry3('a', 'b')]));
+  }
+
   void test_visitMapLiteral_const() {
     _assertSource("const {}", AstTestFactory.mapLiteral(Keyword.CONST, null));
   }
@@ -5433,6 +5814,62 @@
     _assertSource(scriptTag, AstTestFactory.scriptTag(scriptTag));
   }
 
+  void test_visitSetLiteral2_complex() {
+    _assertSource(
+        '<int>{0, for (e in l) 0, if (b) 1, ...[0]}',
+        astFactory.setLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [
+              AstTestFactory.integer(0),
+              astFactory.forElement(
+                  forLoopParts: astFactory.forEachPartsWithIdentifier(
+                      identifier: AstTestFactory.identifier3('e'),
+                      iterable: AstTestFactory.identifier3('l')),
+                  body: AstTestFactory.integer(0)),
+              astFactory.ifElement(
+                  condition: AstTestFactory.identifier3('b'),
+                  thenElement: AstTestFactory.integer(1)),
+              astFactory.spreadElement(
+                  spreadOperator: TokenFactory.tokenFromType(
+                      TokenType.PERIOD_PERIOD_PERIOD),
+                  expression: astFactory
+                      .listLiteral2(elements: [AstTestFactory.integer(0)]))
+            ]));
+  }
+
+  void test_visitSetLiteral2_withConst_withoutTypeArgs() {
+    _assertSource(
+        'const {0}',
+        astFactory.setLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitSetLiteral2_withConst_withTypeArgs() {
+    _assertSource(
+        'const <int>{0}',
+        astFactory.setLiteral2(
+            constKeyword: TokenFactory.tokenFromKeyword(Keyword.CONST),
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitSetLiteral2_withoutConst_withoutTypeArgs() {
+    _assertSource(
+        '{0}', astFactory.setLiteral2(elements: [AstTestFactory.integer(0)]));
+  }
+
+  void test_visitSetLiteral2_withoutConst_withTypeArgs() {
+    _assertSource(
+        '<int>{0}',
+        astFactory.setLiteral2(
+            typeArguments: AstTestFactory.typeArgumentList(
+                [AstTestFactory.typeName4('int')]),
+            elements: [AstTestFactory.integer(0)]));
+  }
+
   void test_visitSimpleFormalParameter_annotation() {
     SimpleFormalParameter parameter =
         AstTestFactory.simpleFormalParameter3('x');
@@ -5476,6 +5913,29 @@
     _assertSource("'a'", AstTestFactory.string2("a"));
   }
 
+  void test_visitSpreadElement_nonNullable() {
+    _assertSource(
+        '...[0]',
+        astFactory.spreadElement(
+            spreadOperator:
+                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
+            expression: astFactory
+                .listLiteral2(elements: [AstTestFactory.integer(0)])));
+  }
+
+  @failingTest
+  void test_visitSpreadElement_nullable() {
+    // TODO(brianwilkerson) Replace the token type below when there is one for
+    //  '...?'.
+    _assertSource(
+        '...?[0]',
+        astFactory.spreadElement(
+            spreadOperator:
+                TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD_PERIOD),
+            expression: astFactory
+                .listLiteral2(elements: [AstTestFactory.integer(0)])));
+  }
+
   void test_visitStringInterpolation() {
     _assertSource(
         "'a\${e}b'",
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 94176f6..fe9fbf9 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -4,822 +4,193 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/generated/testing/test_type_provider.dart';
-import 'package:path/path.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../../generated/resolver_test_case.dart';
 import '../../../generated/test_support.dart';
+import '../resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConstantVisitorTest);
-    defineReflectiveTests(ConstantVisitorTest_Driver);
     defineReflectiveTests(ConstantVisitorWithConstantUpdate2018Test);
+    defineReflectiveTests(
+        ConstantVisitorWithFlowControlAndSpreadCollectionsTest);
   });
 }
 
 @reflectiveTest
 class ConstantVisitorTest extends ConstantVisitorTestSupport {
-  test_visitAsExpression_instanceOfSameClass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a as A;
-class A {
-  const A();
-}
-''');
-    DartObjectImpl resultA = _evaluateConstant(compilationUnit, 'a',
-        experiments: [EnableString.constant_update_2018]);
-    DartObjectImpl resultB = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(resultB, resultA);
-  }
-
-  test_visitAsExpression_instanceOfSubclass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const B();
-const b = a as A;
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-''');
-    DartObjectImpl resultA = _evaluateConstant(compilationUnit, 'a',
-        experiments: [EnableString.constant_update_2018]);
-    DartObjectImpl resultB = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(resultB, resultA);
-  }
-
-  test_visitAsExpression_instanceOfSuperclass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a as B;
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION],
-        experiments: [EnableString.constant_update_2018]);
-    expect(result, isNull);
-  }
-
-  test_visitAsExpression_instanceOfUnrelatedClass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a as B;
-class A {
-  const A();
-}
-class B {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION],
-        experiments: [EnableString.constant_update_2018]);
-    expect(result, isNull);
-  }
-
-  test_visitAsExpression_null() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = null;
-const b = a as A;
-class A {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.nullType);
-  }
-
-  test_visitBinaryExpression_and_bool_known_known() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = false & true;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_and_bool_known_unknown() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const b = bool.fromEnvironment('y');
-const c = false & b;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_and_bool_unknown_known() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = bool.fromEnvironment('x');
-const c = a & true;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_and_bool_unknown_unknown() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = bool.fromEnvironment('x');
-const b = bool.fromEnvironment('y');
-const c = a & b;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_and_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 & 5;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-  }
-
-  test_visitBinaryExpression_and_mixed() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 & false;
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT],
-        experiments: [EnableString.constant_update_2018]);
-  }
-
-  test_visitBinaryExpression_or_bool_known_known() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = false | true;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_or_bool_known_unknown() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const b = bool.fromEnvironment('y');
-const c = false | b;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_or_bool_unknown_known() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = bool.fromEnvironment('x');
-const c = a | true;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_or_bool_unknown_unknown() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = bool.fromEnvironment('x');
-const b = bool.fromEnvironment('y');
-const c = a | b;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_or_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 | 5;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-  }
-
-  test_visitBinaryExpression_or_mixed() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 | false;
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT],
-        experiments: [EnableString.constant_update_2018]);
-  }
-
   test_visitBinaryExpression_questionQuestion_eager_notNull_notNull() async {
-    Expression left = AstTestFactory.string2('a');
-    Expression right = AstTestFactory.string2('b');
-    Expression expression = AstTestFactory.binaryExpression(
-        left, TokenType.QUESTION_QUESTION, right);
-
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = _evaluate(expression, errorReporter);
-    expect(result, isNotNull);
-    expect(result.isNull, isFalse);
+    await _resolveTestCode('''
+const c = 'a' ?? 'b';
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.stringType);
     expect(result.toStringValue(), 'a');
-    errorListener.assertNoErrors();
   }
 
   test_visitBinaryExpression_questionQuestion_eager_null_notNull() async {
-    Expression left = AstTestFactory.nullLiteral();
-    Expression right = AstTestFactory.string2('b');
-    Expression expression = AstTestFactory.binaryExpression(
-        left, TokenType.QUESTION_QUESTION, right);
-
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = _evaluate(expression, errorReporter);
-    expect(result, isNotNull);
-    expect(result.isNull, isFalse);
+    await _resolveTestCode('''
+const c = null ?? 'b';
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.stringType);
     expect(result.toStringValue(), 'b');
-    errorListener.assertNoErrors();
   }
 
   test_visitBinaryExpression_questionQuestion_eager_null_null() async {
-    Expression left = AstTestFactory.nullLiteral();
-    Expression right = AstTestFactory.nullLiteral();
-    Expression expression = AstTestFactory.binaryExpression(
-        left, TokenType.QUESTION_QUESTION, right);
-
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = _evaluate(expression, errorReporter);
-    expect(result, isNotNull);
-    expect(result.isNull, isTrue);
-    errorListener.assertNoErrors();
-  }
-
-  test_visitBinaryExpression_questionQuestion_lazy_notNull_invalid() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 'a' ?? new C();
-class C {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.stringType);
-    expect(result.toStringValue(), 'a');
-  }
-
-  test_visitBinaryExpression_questionQuestion_lazy_notNull_notNull() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 'a' ?? 'b';
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.stringType);
-    expect(result.toStringValue(), 'a');
-  }
-
-  test_visitBinaryExpression_questionQuestion_lazy_null_invalid() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = null ?? new C();
-class C {}
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
-        experiments: [EnableString.constant_update_2018]);
-  }
-
-  test_visitBinaryExpression_questionQuestion_lazy_null_notNull() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = null ?? 'b';
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.stringType);
-    expect(result.toStringValue(), 'b');
-  }
-
-  test_visitBinaryExpression_questionQuestion_lazy_null_null() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = null ?? null;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.isNull, isTrue);
   }
 
-  test_visitBinaryExpression_xor_bool_known_known() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = false ^ true;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_xor_bool_known_unknown() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const b = bool.fromEnvironment('y');
-const c = false ^ b;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_xor_bool_unknown_known() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = bool.fromEnvironment('x');
-const c = a ^ true;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_xor_bool_unknown_unknown() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = bool.fromEnvironment('x');
-const b = bool.fromEnvironment('y');
-const c = a ^ b;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-  }
-
-  test_visitBinaryExpression_xor_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 ^ 5;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-  }
-
-  test_visitBinaryExpression_xor_mixed() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 ^ false;
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT],
-        experiments: [EnableString.constant_update_2018]);
-  }
-
   test_visitConditionalExpression_eager_false_int_int() async {
-    Expression thenExpression = AstTestFactory.integer(1);
-    Expression elseExpression = AstTestFactory.integer(0);
-    ConditionalExpression expression = AstTestFactory.conditionalExpression(
-        AstTestFactory.booleanLiteral(false), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    _assertValue(0, _evaluate(expression, errorReporter));
-    errorListener.assertNoErrors();
+    await _resolveTestCode('''
+const c = false ? 1 : 0;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 0);
   }
 
   test_visitConditionalExpression_eager_invalid_int_int() async {
-    Expression thenExpression = AstTestFactory.integer(1);
-    Expression elseExpression = AstTestFactory.integer(0);
-    NullLiteral conditionExpression = AstTestFactory.nullLiteral();
-    ConditionalExpression expression = AstTestFactory.conditionalExpression(
-        conditionExpression, thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = _evaluate(expression, errorReporter);
+    await _resolveTestCode('''
+const c = null ? 1 : 0;
+''');
+    DartObjectImpl result = _evaluateConstant(
+      'c',
+      errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL],
+    );
     expect(result, isNull);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
   }
 
   test_visitConditionalExpression_eager_true_int_int() async {
-    Expression thenExpression = AstTestFactory.integer(1);
-    Expression elseExpression = AstTestFactory.integer(0);
-    ConditionalExpression expression = AstTestFactory.conditionalExpression(
-        AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    _assertValue(1, _evaluate(expression, errorReporter));
-    errorListener.assertNoErrors();
+    await _resolveTestCode('''
+const c = true ? 1 : 0;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 1);
   }
 
   test_visitConditionalExpression_eager_true_int_invalid() async {
-    Expression thenExpression = AstTestFactory.integer(1);
-    Expression elseExpression = AstTestFactory.identifier3("x");
-    ConditionalExpression expression = AstTestFactory.conditionalExpression(
-        AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = _evaluate(expression, errorReporter);
+    await _resolveTestCode('''
+const c = true ? 1 : x;
+''');
+    DartObjectImpl result = _evaluateConstant(
+      'c',
+      errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
+    );
     expect(result, isNull);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
   }
 
   test_visitConditionalExpression_eager_true_invalid_int() async {
-    Expression thenExpression = AstTestFactory.identifier3("x");
-    Expression elseExpression = AstTestFactory.integer(0);
-    ConditionalExpression expression = AstTestFactory.conditionalExpression(
-        AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = _evaluate(expression, errorReporter);
+    await _resolveTestCode('''
+const c = true ? x : 0;
+''');
+    DartObjectImpl result = _evaluateConstant(
+      'c',
+      errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
+    );
     expect(result, isNull);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
-  }
-
-  test_visitConditionalExpression_lazy_false_int_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = false ? 1 : 0;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-    expect(result.toIntValue(), 0);
-  }
-
-  test_visitConditionalExpression_lazy_false_int_invalid() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = false ? 1 : new C();
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
-        experiments: [EnableString.constant_update_2018]);
-  }
-
-  test_visitConditionalExpression_lazy_false_invalid_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = false ? new C() : 0;
-class C {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-    expect(result.toIntValue(), 0);
-  }
-
-  test_visitConditionalExpression_lazy_invalid_int_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = 3 ? 1 : 0;
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL],
-        experiments: [EnableString.constant_update_2018]);
-  }
-
-  test_visitConditionalExpression_lazy_true_int_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = true ? 1 : 0;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-    expect(result.toIntValue(), 1);
-  }
-
-  test_visitConditionalExpression_lazy_true_int_invalid() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = true ? 1 : new C();
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.intType);
-    expect(result.toIntValue(), 1);
-  }
-
-  test_visitConditionalExpression_lazy_true_invalid_int() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const c = true ? new C() : 0;
-class C {}
-''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
-        experiments: [EnableString.constant_update_2018]);
   }
 
   test_visitIntegerLiteral() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const double d = 3;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'd');
+    DartObjectImpl result = _evaluateConstant('d');
     expect(result.type, typeProvider.doubleType);
     expect(result.toDoubleValue(), 3.0);
   }
 
-  test_visitIsExpression_is_instanceOfSameClass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a is A;
-class A {
-  const A();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_is_instanceOfSubclass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const B();
-const b = a is A;
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_is_instanceOfSuperclass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a is B;
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), false);
-  }
-
-  test_visitIsExpression_is_instanceOfUnrelatedClass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a is B;
-class A {
-  const A();
-}
-class B {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), false);
-  }
-
-  test_visitIsExpression_is_null() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = null;
-const b = a is A;
-class A {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), false);
-  }
-
-  test_visitIsExpression_is_null_dynamic() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = null;
-const b = a is dynamic;
-class A {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_is_null_null() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = null;
-const b = a is Null;
-class A {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_is_null_object() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = null;
-const b = a is Object;
-class A {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_isNot_instanceOfSameClass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a is! A;
-class A {
-  const A();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), false);
-  }
-
-  test_visitIsExpression_isNot_instanceOfSubclass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const B();
-const b = a is! A;
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), false);
-  }
-
-  test_visitIsExpression_isNot_instanceOfSuperclass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a is! B;
-class A {
-  const A();
-}
-class B extends A {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_isNot_instanceOfUnrelatedClass() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = const A();
-const b = a is! B;
-class A {
-  const A();
-}
-class B {
-  const B();
-}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
-  test_visitIsExpression_isNot_null() async {
-    CompilationUnit compilationUnit = await resolveSource('''
-const a = null;
-const b = a is! A;
-class A {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
-        experiments: [EnableString.constant_update_2018]);
-    expect(result.type, typeProvider.boolType);
-    expect(result.toBoolValue(), true);
-  }
-
   test_visitSimpleIdentifier_className() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const a = C;
 class C {}
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'a');
+    DartObjectImpl result = _evaluateConstant('a');
     expect(result.type, typeProvider.typeType);
     expect(result.toTypeValue().name, 'C');
   }
 
   test_visitSimpleIdentifier_dynamic() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const a = dynamic;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'a');
+    DartObjectImpl result = _evaluateConstant('a');
     expect(result.type, typeProvider.typeType);
     expect(result.toTypeValue(), typeProvider.dynamicType);
   }
 
   test_visitSimpleIdentifier_inEnvironment() async {
-    CompilationUnit compilationUnit = await resolveSource(r'''
+    await _resolveTestCode(r'''
 const a = b;
 const b = 3;''');
-    Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
-    DartObjectImpl six =
-        new DartObjectImpl(typeProvider.intType, new IntState(6));
-    environment["b"] = six;
-    _assertValue(
-        6,
-        _evaluateConstant(compilationUnit, "a",
-            lexicalEnvironment: environment));
+    var environment = <String, DartObjectImpl>{
+      'b': DartObjectImpl(typeProvider.intType, IntState(6)),
+    };
+    var result = _evaluateConstant('a', lexicalEnvironment: environment);
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 6);
   }
 
   test_visitSimpleIdentifier_notInEnvironment() async {
-    CompilationUnit compilationUnit = await resolveSource(r'''
+    await _resolveTestCode(r'''
 const a = b;
 const b = 3;''');
-    Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
-    DartObjectImpl six =
-        new DartObjectImpl(typeProvider.intType, new IntState(6));
-    environment["c"] = six;
-    _assertValue(
-        3,
-        _evaluateConstant(compilationUnit, "a",
-            lexicalEnvironment: environment));
+    var environment = <String, DartObjectImpl>{
+      'c': DartObjectImpl(typeProvider.intType, IntState(6)),
+    };
+    var result = _evaluateConstant('a', lexicalEnvironment: environment);
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 3);
   }
 
   test_visitSimpleIdentifier_withoutEnvironment() async {
-    CompilationUnit compilationUnit = await resolveSource(r'''
+    await _resolveTestCode(r'''
 const a = b;
 const b = 3;''');
-    _assertValue(3, _evaluateConstant(compilationUnit, "a"));
-  }
-
-  void _assertValue(int expectedValue, DartObjectImpl result) {
-    expect(result, isNotNull);
-    expect(result.type.name, "int");
-    expect(result.toIntValue(), expectedValue);
-  }
-
-  NonExistingSource _dummySource() {
-    String path = '/test.dart';
-    return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
-  }
-
-  DartObjectImpl _evaluate(Expression expression, ErrorReporter errorReporter) {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    return expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
-            typeSystem: new Dart2TypeSystem(typeProvider)),
-        errorReporter));
+    var result = _evaluateConstant('a');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 3);
   }
 }
 
-@reflectiveTest
-class ConstantVisitorTest_Driver extends ConstantVisitorTest {
-  bool get enableNewAnalysisDriver => true;
-}
+class ConstantVisitorTestSupport extends DriverResolutionTest {
+  DartObjectImpl _evaluateConstant(
+    String name, {
+    List<ErrorCode> errorCodes,
+    Map<String, DartObjectImpl> lexicalEnvironment,
+  }) {
+    var options = driver.analysisOptions as AnalysisOptionsImpl;
+    var expression = findNode.topVariableDeclarationByName(name).initializer;
 
-class ConstantVisitorTestSupport extends ResolverTestCase {
-  DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
-      {List<ErrorCode> errorCodes,
-      List<String> experiments,
-      Map<String, DartObjectImpl> lexicalEnvironment}) {
-    Source source =
-        resolutionMap.elementDeclaredByCompilationUnit(compilationUnit).source;
-    Expression expression =
-        findTopLevelConstantExpression(compilationUnit, name);
+    var source = this.result.unit.declaredElement.source;
+    var errorListener = GatheringErrorListener();
+    var errorReporter = ErrorReporter(errorListener, source);
 
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    if (experiments != null) {
-      options..enabledExperiments = experiments;
-    }
-
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-
-    DartObjectImpl result = expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
-            experimentStatus: options.experimentStatus, typeSystem: typeSystem),
+    DartObjectImpl result = expression.accept(
+      ConstantVisitor(
+        ConstantEvaluationEngine(
+          typeProvider,
+          new DeclaredVariables(),
+          experimentStatus: options.experimentStatus,
+          typeSystem: this.result.typeSystem,
+        ),
         errorReporter,
-        lexicalEnvironment: lexicalEnvironment));
+        lexicalEnvironment: lexicalEnvironment,
+      ),
+    );
     if (errorCodes == null) {
       errorListener.assertNoErrors();
     } else {
@@ -827,92 +198,823 @@
     }
     return result;
   }
+
+  Future<CompilationUnit> _resolveTestCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+    return result.unit;
+  }
 }
 
 @reflectiveTest
 class ConstantVisitorWithConstantUpdate2018Test
     extends ConstantVisitorTestSupport {
   @override
-  List<String> get enabledExperiments => [EnableString.constant_update_2018];
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [EnableString.constant_update_2018];
 
-  bool get enableNewAnalysisDriver => true;
+  test_visitAsExpression_instanceOfSameClass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a as A;
+class A {
+  const A();
+}
+''');
+    DartObjectImpl resultA = _evaluateConstant('a');
+    DartObjectImpl resultB = _evaluateConstant('b');
+    expect(resultB, resultA);
+  }
+
+  test_visitAsExpression_instanceOfSubclass() async {
+    await _resolveTestCode('''
+const a = const B();
+const b = a as A;
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''');
+    DartObjectImpl resultA = _evaluateConstant('a');
+    DartObjectImpl resultB = _evaluateConstant('b');
+    expect(resultB, resultA);
+  }
+
+  test_visitAsExpression_instanceOfSuperclass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a as B;
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    expect(result, isNull);
+  }
+
+  test_visitAsExpression_instanceOfUnrelatedClass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a as B;
+class A {
+  const A();
+}
+class B {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+    expect(result, isNull);
+  }
+
+  test_visitAsExpression_null() async {
+    await _resolveTestCode('''
+const a = null;
+const b = a as A;
+class A {}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.nullType);
+  }
+
+  test_visitBinaryExpression_and_bool_known_known() async {
+    await _resolveTestCode('''
+const c = false & true;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_and_bool_known_unknown() async {
+    await _resolveTestCode('''
+const b = bool.fromEnvironment('y');
+const c = false & b;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_and_bool_unknown_known() async {
+    await _resolveTestCode('''
+const a = bool.fromEnvironment('x');
+const c = a & true;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_and_bool_unknown_unknown() async {
+    await _resolveTestCode('''
+const a = bool.fromEnvironment('x');
+const b = bool.fromEnvironment('y');
+const c = a & b;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_and_int() async {
+    await _resolveTestCode('''
+const c = 3 & 5;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+  }
+
+  test_visitBinaryExpression_and_mixed() async {
+    await _resolveTestCode('''
+const c = 3 & false;
+''');
+    _evaluateConstant('c',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT]);
+  }
 
   test_visitBinaryExpression_gtGtGt_negative_fewerBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFFFFFFFF >>> 8;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.type, typeProvider.intType);
     expect(result.toIntValue(), 0xFFFFFF);
   }
 
   test_visitBinaryExpression_gtGtGt_negative_moreBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFFFFFFFF >>> 33;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.type, typeProvider.intType);
     expect(result.toIntValue(), 0);
   }
 
   test_visitBinaryExpression_gtGtGt_negative_negativeBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFFFFFFFF >>> -2;
 ''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION],
-        experiments: [EnableString.constant_update_2018]);
+    _evaluateConstant('c',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
   }
 
   test_visitBinaryExpression_gtGtGt_negative_zeroBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFFFFFFFF >>> 0;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.type, typeProvider.intType);
     expect(result.toIntValue(), 0xFFFFFFFF);
   }
 
-//  @soloTest
   test_visitBinaryExpression_gtGtGt_positive_fewerBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFF >>> 3;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.type, typeProvider.intType);
     expect(result.toIntValue(), 0x1F);
   }
 
   test_visitBinaryExpression_gtGtGt_positive_moreBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFF >>> 9;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.type, typeProvider.intType);
     expect(result.toIntValue(), 0);
   }
 
   test_visitBinaryExpression_gtGtGt_positive_negativeBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFF >>> -2;
 ''');
-    _evaluateConstant(compilationUnit, 'c',
-        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION],
-        experiments: [EnableString.constant_update_2018]);
+    _evaluateConstant('c',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
   }
 
   test_visitBinaryExpression_gtGtGt_positive_zeroBits() async {
-    CompilationUnit compilationUnit = await resolveSource('''
+    await _resolveTestCode('''
 const c = 0xFF >>> 0;
 ''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
-        experiments: [EnableString.constant_update_2018]);
+    DartObjectImpl result = _evaluateConstant('c');
     expect(result.type, typeProvider.intType);
     expect(result.toIntValue(), 0xFF);
   }
+
+  test_visitBinaryExpression_or_bool_known_known() async {
+    await _resolveTestCode('''
+const c = false | true;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_or_bool_known_unknown() async {
+    await _resolveTestCode('''
+const b = bool.fromEnvironment('y');
+const c = false | b;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_or_bool_unknown_known() async {
+    await _resolveTestCode('''
+const a = bool.fromEnvironment('x');
+const c = a | true;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_or_bool_unknown_unknown() async {
+    await _resolveTestCode('''
+const a = bool.fromEnvironment('x');
+const b = bool.fromEnvironment('y');
+const c = a | b;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_or_int() async {
+    await _resolveTestCode('''
+const c = 3 | 5;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+  }
+
+  test_visitBinaryExpression_or_mixed() async {
+    await _resolveTestCode('''
+const c = 3 | false;
+''');
+    _evaluateConstant('c',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT]);
+  }
+
+  test_visitBinaryExpression_questionQuestion_lazy_notNull_invalid() async {
+    await _resolveTestCode('''
+const c = 'a' ?? new C();
+class C {}
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.stringType);
+    expect(result.toStringValue(), 'a');
+  }
+
+  test_visitBinaryExpression_questionQuestion_lazy_notNull_notNull() async {
+    await _resolveTestCode('''
+const c = 'a' ?? 'b';
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.stringType);
+    expect(result.toStringValue(), 'a');
+  }
+
+  test_visitBinaryExpression_questionQuestion_lazy_null_invalid() async {
+    await _resolveTestCode('''
+const c = null ?? new C();
+class C {}
+''');
+    _evaluateConstant('c', errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT]);
+  }
+
+  test_visitBinaryExpression_questionQuestion_lazy_null_notNull() async {
+    await _resolveTestCode('''
+const c = null ?? 'b';
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.stringType);
+    expect(result.toStringValue(), 'b');
+  }
+
+  test_visitBinaryExpression_questionQuestion_lazy_null_null() async {
+    await _resolveTestCode('''
+const c = null ?? null;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.isNull, isTrue);
+  }
+
+  test_visitBinaryExpression_xor_bool_known_known() async {
+    await _resolveTestCode('''
+const c = false ^ true;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_xor_bool_known_unknown() async {
+    await _resolveTestCode('''
+const b = bool.fromEnvironment('y');
+const c = false ^ b;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_xor_bool_unknown_known() async {
+    await _resolveTestCode('''
+const a = bool.fromEnvironment('x');
+const c = a ^ true;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_xor_bool_unknown_unknown() async {
+    await _resolveTestCode('''
+const a = bool.fromEnvironment('x');
+const b = bool.fromEnvironment('y');
+const c = a ^ b;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.boolType);
+  }
+
+  test_visitBinaryExpression_xor_int() async {
+    await _resolveTestCode('''
+const c = 3 ^ 5;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+  }
+
+  test_visitBinaryExpression_xor_mixed() async {
+    await _resolveTestCode('''
+const c = 3 ^ false;
+''');
+    _evaluateConstant('c',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT]);
+  }
+
+  test_visitConditionalExpression_lazy_false_int_int() async {
+    await _resolveTestCode('''
+const c = false ? 1 : 0;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 0);
+  }
+
+  test_visitConditionalExpression_lazy_false_int_invalid() async {
+    await _resolveTestCode('''
+const c = false ? 1 : new C();
+''');
+    _evaluateConstant('c', errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT]);
+  }
+
+  test_visitConditionalExpression_lazy_false_invalid_int() async {
+    await _resolveTestCode('''
+const c = false ? new C() : 0;
+class C {}
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 0);
+  }
+
+  test_visitConditionalExpression_lazy_invalid_int_int() async {
+    await _resolveTestCode('''
+const c = 3 ? 1 : 0;
+''');
+    _evaluateConstant('c',
+        errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
+  }
+
+  test_visitConditionalExpression_lazy_true_int_int() async {
+    await _resolveTestCode('''
+const c = true ? 1 : 0;
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 1);
+  }
+
+  test_visitConditionalExpression_lazy_true_int_invalid() async {
+    await _resolveTestCode('''
+const c = true ? 1 : new C();
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(result.type, typeProvider.intType);
+    expect(result.toIntValue(), 1);
+  }
+
+  test_visitConditionalExpression_lazy_true_invalid_int() async {
+    await _resolveTestCode('''
+const c = true ? new C() : 0;
+class C {}
+''');
+    _evaluateConstant('c', errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT]);
+  }
+
+  test_visitIsExpression_is_instanceOfSameClass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a is A;
+class A {
+  const A();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_is_instanceOfSubclass() async {
+    await _resolveTestCode('''
+const a = const B();
+const b = a is A;
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_is_instanceOfSuperclass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a is B;
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
+  test_visitIsExpression_is_instanceOfUnrelatedClass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a is B;
+class A {
+  const A();
+}
+class B {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
+  test_visitIsExpression_is_null() async {
+    await _resolveTestCode('''
+const a = null;
+const b = a is A;
+class A {}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
+  test_visitIsExpression_is_null_dynamic() async {
+    await _resolveTestCode('''
+const a = null;
+const b = a is dynamic;
+class A {}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_is_null_null() async {
+    await _resolveTestCode('''
+const a = null;
+const b = a is Null;
+class A {}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_is_null_object() async {
+    await _resolveTestCode('''
+const a = null;
+const b = a is Object;
+class A {}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_isNot_instanceOfSameClass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a is! A;
+class A {
+  const A();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
+  test_visitIsExpression_isNot_instanceOfSubclass() async {
+    await _resolveTestCode('''
+const a = const B();
+const b = a is! A;
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), false);
+  }
+
+  test_visitIsExpression_isNot_instanceOfSuperclass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a is! B;
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_isNot_instanceOfUnrelatedClass() async {
+    await _resolveTestCode('''
+const a = const A();
+const b = a is! B;
+class A {
+  const A();
+}
+class B {
+  const B();
+}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+
+  test_visitIsExpression_isNot_null() async {
+    await _resolveTestCode('''
+const a = null;
+const b = a is! A;
+class A {}
+''');
+    DartObjectImpl result = _evaluateConstant('b');
+    expect(result.type, typeProvider.boolType);
+    expect(result.toBoolValue(), true);
+  }
+}
+
+@reflectiveTest
+class ConstantVisitorWithFlowControlAndSpreadCollectionsTest
+    extends ConstantVisitorTestSupport {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [
+      EnableString.control_flow_collections,
+      EnableString.set_literals,
+      EnableString.spread_collections
+    ];
+
+  test_listLiteral_nested() async {
+    await _resolveTestCode('''
+const c = [1, if (1 > 0) if (2 > 1) 2, 3];
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    // The expected type ought to be `List<int>`, but type inference isn't yet
+    // implemented.
+    expect(
+        result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+    expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 3]);
+  }
+
+  test_listLiteral_withIf_false_withElse() async {
+    await _resolveTestCode('''
+const c = [1, if (1 < 0) 2 else 3, 4];
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+    expect(result.toListValue().map((e) => e.toIntValue()), [1, 3, 4]);
+  }
+
+  test_listLiteral_withIf_false_withoutElse() async {
+    await _resolveTestCode('''
+const c = [1, if (1 < 0) 2, 3];
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+    expect(result.toListValue().map((e) => e.toIntValue()), [1, 3]);
+  }
+
+  test_listLiteral_withIf_true_withElse() async {
+    await _resolveTestCode('''
+const c = [1, if (1 > 0) 2 else 3, 4];
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+    expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 4]);
+  }
+
+  test_listLiteral_withIf_true_withoutElse() async {
+    await _resolveTestCode('''
+const c = [1, if (1 > 0) 2, 3];
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+    expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 3]);
+  }
+
+  test_listLiteral_withSpread() async {
+    await _resolveTestCode('''
+const c = [1, ...[2, 3], 4];
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.listType.instantiate([typeProvider.intType]));
+    expect(result.toListValue().map((e) => e.toIntValue()), [1, 2, 3, 4]);
+  }
+
+  @failingTest
+  test_mapLiteral_nested() async {
+    // Fails because we're not yet parsing nested elements.
+    await _resolveTestCode('''
+const c = {'a' : 1, if (1 > 0) if (2 > 1) {'b' : 2}, 'c' : 3};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type,
+        typeProvider.mapType
+            .instantiate([typeProvider.intType, typeProvider.intType]));
+    Map<DartObject, DartObject> value = result.toMapValue();
+    expect(value.keys.map((e) => e.toStringValue()),
+        unorderedEquals(['a', 'b', 'c']));
+    expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 3]));
+  }
+
+  test_mapLiteral_withIf_false_withElse() async {
+    await _resolveTestCode('''
+const c = {'a' : 1, if (1 < 0) 'b' : 2 else 'c' : 3, 'd' : 4};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type,
+        typeProvider.mapType
+            .instantiate([typeProvider.stringType, typeProvider.intType]));
+    Map<DartObject, DartObject> value = result.toMapValue();
+    expect(value.keys.map((e) => e.toStringValue()),
+        unorderedEquals(['a', 'c', 'd']));
+    expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 3, 4]));
+  }
+
+  test_mapLiteral_withIf_false_withoutElse() async {
+    await _resolveTestCode('''
+const c = {'a' : 1, if (1 < 0) 'b' : 2, 'c' : 3};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type,
+        typeProvider.mapType
+            .instantiate([typeProvider.stringType, typeProvider.intType]));
+    Map<DartObject, DartObject> value = result.toMapValue();
+    expect(
+        value.keys.map((e) => e.toStringValue()), unorderedEquals(['a', 'c']));
+    expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 3]));
+  }
+
+  test_mapLiteral_withIf_true_withElse() async {
+    await _resolveTestCode('''
+const c = {'a' : 1, if (1 > 0) 'b' : 2 else 'c' : 3, 'd' : 4};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type,
+        typeProvider.mapType
+            .instantiate([typeProvider.stringType, typeProvider.intType]));
+    Map<DartObject, DartObject> value = result.toMapValue();
+    expect(value.keys.map((e) => e.toStringValue()),
+        unorderedEquals(['a', 'b', 'd']));
+    expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 4]));
+  }
+
+  test_mapLiteral_withIf_true_withoutElse() async {
+    await _resolveTestCode('''
+const c = {'a' : 1, if (1 > 0) 'b' : 2, 'c' : 3};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type,
+        typeProvider.mapType
+            .instantiate([typeProvider.stringType, typeProvider.intType]));
+    Map<DartObject, DartObject> value = result.toMapValue();
+    expect(value.keys.map((e) => e.toStringValue()),
+        unorderedEquals(['a', 'b', 'c']));
+    expect(value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 3]));
+  }
+
+  test_mapLiteral_withSpread() async {
+    await _resolveTestCode('''
+const c = {'a' : 1, ...{'b' : 2, 'c' : 3}, 'd' : 4};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type,
+        typeProvider.mapType
+            .instantiate([typeProvider.stringType, typeProvider.intType]));
+    Map<DartObject, DartObject> value = result.toMapValue();
+    expect(value.keys.map((e) => e.toStringValue()),
+        unorderedEquals(['a', 'b', 'c', 'd']));
+    expect(
+        value.values.map((e) => e.toIntValue()), unorderedEquals([1, 2, 3, 4]));
+  }
+
+  test_setLiteral_nested() async {
+    await _resolveTestCode('''
+const c = {1, if (1 > 0) if (2 > 1) 2, 3};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+    expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3]);
+  }
+
+  test_setLiteral_withIf_false_withElse() async {
+    await _resolveTestCode('''
+const c = {1, if (1 < 0) 2 else 3, 4};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+    expect(result.toSetValue().map((e) => e.toIntValue()), [1, 3, 4]);
+  }
+
+  test_setLiteral_withIf_false_withoutElse() async {
+    await _resolveTestCode('''
+const c = {1, if (1 < 0) 2, 3};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+    expect(result.toSetValue().map((e) => e.toIntValue()), [1, 3]);
+  }
+
+  test_setLiteral_withIf_true_withElse() async {
+    await _resolveTestCode('''
+const c = {1, if (1 > 0) 2 else 3, 4};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+    expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 4]);
+  }
+
+  test_setLiteral_withIf_true_withoutElse() async {
+    await _resolveTestCode('''
+const c = {1, if (1 > 0) 2, 3};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+    expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3]);
+  }
+
+  test_setLiteral_withSpread() async {
+    await _resolveTestCode('''
+const c = {1, ...{2, 3}, 4};
+''');
+    DartObjectImpl result = _evaluateConstant('c');
+    expect(
+        result.type, typeProvider.setType.instantiate([typeProvider.intType]));
+    expect(result.toSetValue().map((e) => e.toIntValue()), [1, 2, 3, 4]);
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index dbebb31..565ee2d 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -46,99 +46,7 @@
 }
 
 @reflectiveTest
-class ClassElementImplTest extends EngineTestCase {
-  @deprecated
-  void test_computeNode_ClassDeclaration() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource("/test.dart", r'''
-class A {}
-@deprecated class B {}
-enum C {C1, C2, C3}
-@deprecated enum D {D1, D2, D3}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    {
-      ClassElement elementA = unitElement.getType("A");
-      expect(elementA.hasDeprecated, isFalse);
-      expect(elementA.isEnum, isFalse);
-      ClassDeclaration nodeA = elementA.computeNode();
-      expect(nodeA, isNotNull);
-      expect(nodeA.name.name, "A");
-      expect(nodeA.declaredElement, same(elementA));
-    }
-    // B
-    {
-      ClassElement elementB = unitElement.getType("B");
-      expect(elementB.hasDeprecated, isTrue);
-      expect(elementB.isEnum, isFalse);
-      ClassDeclaration nodeB = elementB.computeNode();
-      expect(nodeB, isNotNull);
-      expect(nodeB.name.name, "B");
-      expect(nodeB.declaredElement, same(elementB));
-    }
-    // C
-    {
-      ClassElement elementC = unitElement.getEnum("C");
-      expect(elementC.hasDeprecated, isFalse);
-      expect(elementC.isEnum, isTrue);
-      EnumDeclaration nodeC = elementC.computeNode();
-      expect(nodeC, isNotNull);
-      expect(nodeC.name.name, "C");
-      expect(nodeC.declaredElement, same(elementC));
-    }
-    // D
-    {
-      ClassElement elementD = unitElement.getEnum("D");
-      expect(elementD.hasDeprecated, isTrue);
-      expect(elementD.isEnum, isTrue);
-      EnumDeclaration nodeC = elementD.computeNode();
-      expect(nodeC, isNotNull);
-      expect(nodeC.name.name, "D");
-      expect(nodeC.declaredElement, same(elementD));
-    }
-  }
-
-  @deprecated
-  void test_computeNode_ClassTypeAlias() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource("/test.dart", r'''
-abstract class A<K, V> = Object with MapMixin<K, V>;
-''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    {
-      ClassElement elementA = unitElement.getType("A");
-      ClassTypeAlias nodeA = elementA.computeNode();
-      expect(nodeA, isNotNull);
-      expect(nodeA.name.name, "A");
-      expect(nodeA.declaredElement, same(elementA));
-    }
-  }
-
-  void test_constructors_mixinApplicationWithHandle() {
-    AnalysisContext context = createAnalysisContext();
-    context.sourceFactory = new SourceFactory([]);
-
-    ElementLocation location = new ElementLocationImpl.con2('');
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    classA.mixinApplication = true;
-    TestElementResynthesizer resynthesizer =
-        new TestElementResynthesizer(context, {location: classA});
-    ClassElementHandle classAHandle =
-        new ClassElementHandle(resynthesizer, location);
-    ClassElementImpl classB = new ClassElementImpl('B', 0)
-      ..supertype = new InterfaceTypeImpl(classAHandle);
-    classB.mixinApplication = true;
-
-    expect(classB.constructors, hasLength(1));
-  }
-
+class ClassElementImplTest {
   void test_getAllSupertypes_interface() {
     ClassElement classA = ElementFactory.classElement2("A");
     ClassElement classB = ElementFactory.classElement("B", classA.type);
@@ -319,8 +227,7 @@
     // class A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null);
@@ -334,8 +241,7 @@
     // class A {
     //   m();
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElementImpl method = ElementFactory.methodElement(methodName, null);
@@ -353,8 +259,7 @@
     // class B extends A {
     //   m();
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -377,8 +282,7 @@
     // class B extends A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -399,8 +303,7 @@
     // class B extends A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.abstract = true;
     String methodName = "m";
@@ -422,8 +325,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -439,8 +341,7 @@
   void test_lookUpConcreteMethod_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -451,8 +352,7 @@
     // class A {
     //   get g {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String getterName = "g";
     PropertyAccessorElement getter =
@@ -469,8 +369,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String getterName = "g";
     PropertyAccessorElement getter =
@@ -485,8 +384,7 @@
   void test_lookUpGetter_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -498,8 +396,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     classA.supertype = classB.type;
@@ -512,8 +409,7 @@
     // class A {
     //   get g {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String getterName = "g";
     PropertyAccessorElement getter =
@@ -530,8 +426,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String getterName = "g";
     PropertyAccessorElement inheritedGetter =
@@ -547,8 +442,7 @@
   void test_lookUpInheritedConcreteGetter_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -560,8 +454,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     classA.supertype = classB.type;
@@ -574,8 +467,7 @@
     // class A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null);
@@ -592,8 +484,7 @@
     // class B extends A {
     //   m();
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -616,8 +507,7 @@
     // class B extends A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -639,8 +529,7 @@
     // class B extends A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.abstract = true;
     String methodName = "m";
@@ -667,8 +556,7 @@
     // class C extends B {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -694,8 +582,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -711,8 +598,7 @@
   void test_lookUpInheritedConcreteMethod_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -723,8 +609,7 @@
     // class A {
     //   set g(x) {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String setterName = "s";
     PropertyAccessorElement setter =
@@ -741,8 +626,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String setterName = "s";
     PropertyAccessorElement setter =
@@ -758,8 +642,7 @@
   void test_lookUpInheritedConcreteSetter_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -771,8 +654,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     classA.supertype = classB.type;
@@ -785,8 +667,7 @@
     // class A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null);
@@ -803,8 +684,7 @@
     // class B extends A {
     //   m() {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -825,8 +705,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement inheritedMethod =
@@ -842,8 +721,7 @@
   void test_lookUpInheritedMethod_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -851,8 +729,7 @@
   }
 
   void test_lookUpMethod_declared() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null);
@@ -863,8 +740,7 @@
   }
 
   void test_lookUpMethod_inherited() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String methodName = "m";
     MethodElement method = ElementFactory.methodElement(methodName, null);
@@ -876,8 +752,7 @@
   }
 
   void test_lookUpMethod_undeclared() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -885,8 +760,7 @@
   }
 
   void test_lookUpMethod_undeclared_recursive() {
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     classA.supertype = classB.type;
@@ -899,8 +773,7 @@
     // class A {
     //   set g(x) {}
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String setterName = "s";
     PropertyAccessorElement setter =
@@ -917,8 +790,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String setterName = "s";
     PropertyAccessorElement setter =
@@ -933,8 +805,7 @@
   void test_lookUpSetter_undeclared() {
     // class A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     (library.definingCompilationUnit as CompilationUnitElementImpl).types =
         <ClassElement>[classA];
@@ -946,8 +817,7 @@
     // }
     // class B extends A {
     // }
-    LibraryElementImpl library =
-        ElementFactory.library(createAnalysisContext(), "lib");
+    LibraryElementImpl library = _newLibrary();
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     classA.supertype = classB.type;
@@ -955,6 +825,8 @@
         <ClassElement>[classA, classB];
     expect(classA.lookUpSetter("s", library), isNull);
   }
+
+  LibraryElementImpl _newLibrary() => ElementFactory.library(null, 'lib');
 }
 
 @reflectiveTest
@@ -1000,6 +872,8 @@
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class ElementAnnotationImplTest extends ResolverTestCase {
   void test_computeConstantValue() {
@@ -1194,6 +1068,8 @@
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class FieldElementImplTest extends EngineTestCase {
   @deprecated
@@ -3800,6 +3676,8 @@
 @reflectiveTest
 class LocalVariableElementImplTest extends EngineTestCase {}
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class MethodElementImplTest extends EngineTestCase {
   @deprecated
@@ -3867,6 +3745,8 @@
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class MethodMemberTest extends EngineTestCase {
   /**
@@ -3904,13 +3784,15 @@
     MethodElement AfElement = elementB.type
         .lookUpInheritedMethod("f", library: libraryElement, thisType: false);
     expect(
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
         BfElement.getReifiedType(objectType),
-        // ignore: deprecated_member_use
+        // ignore: deprecated_member_use_from_same_package
         equals(AfElement.getReifiedType(objectType)));
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class ParameterElementImplTest extends EngineTestCase {
   @deprecated
@@ -4044,6 +3926,8 @@
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class TopLevelVariableElementImplTest extends ResolverTestCase {
   void test_computeConstantValue() {
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
index 60497d0..2755ffb 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
@@ -2,8 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -43,9 +44,10 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getInherited('X', 'foo'),
-      same(findElement.method('foo', of: 'B')),
+    _assertGetInherited(
+      className: 'X',
+      name: 'foo',
+      expected: 'B.foo: () → void',
     );
   }
 
@@ -65,9 +67,10 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getInherited('X', 'foo'),
-      same(findElement.method('foo', of: 'J')),
+    _assertGetInherited(
+      className: 'X',
+      name: 'foo',
+      expected: 'J.foo: () → void',
     );
   }
 
@@ -87,9 +90,10 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getInherited('X', 'foo'),
-      same(findElement.method('foo', of: 'M')),
+    _assertGetInherited(
+      className: 'X',
+      name: 'foo',
+      expected: 'M.foo: () → void',
     );
   }
 
@@ -109,12 +113,593 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getInherited('X', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetInherited(
+      className: 'X',
+      name: 'foo',
+      expected: 'A.foo: () → void',
     );
   }
 
+  test_getInheritedConcreteMap_accessor_extends() async {
+    addTestFile('''
+class A {
+  int get foo => 0;
+}
+
+class B extends A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('B', r'''
+A.foo: () → int
+''');
+  }
+
+  test_getInheritedConcreteMap_accessor_implements() async {
+    addTestFile('''
+class A {
+  int get foo => 0;
+}
+
+abstract class B implements A {}
+''');
+    await resolveTestFile();
+    _assertInheritedConcreteMap('B', '');
+  }
+
+  test_getInheritedConcreteMap_accessor_with() async {
+    addTestFile('''
+mixin A {
+  int get foo => 0;
+}
+
+class B extends Object with A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('B', r'''
+A.foo: () → int
+''');
+  }
+
+  test_getInheritedConcreteMap_implicitExtends() async {
+    addTestFile('''
+class A {}
+''');
+    await resolveTestFile();
+    _assertInheritedConcreteMap('A', '');
+  }
+
+  test_getInheritedConcreteMap_method_extends() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+class B extends A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('B', r'''
+A.foo: () → void
+''');
+  }
+
+  test_getInheritedConcreteMap_method_extends_abstract() async {
+    addTestFile('''
+abstract class A {
+  void foo();
+}
+
+class B extends A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('B', '');
+  }
+
+  test_getInheritedConcreteMap_method_extends_invalidForImplements() async {
+    addTestFile('''
+abstract class I {
+  void foo(int x, {int y});
+  void bar(String s);
+}
+
+class A {
+  void foo(int x) {}
+}
+
+class C extends A implements I {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('C', r'''
+A.foo: (int) → void
+''');
+  }
+
+  test_getInheritedConcreteMap_method_implements() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+abstract class B implements A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('B', '');
+  }
+
+  test_getInheritedConcreteMap_method_with() async {
+    addTestFile('''
+mixin A {
+  void foo() {}
+}
+
+class B extends Object with A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('B', r'''
+A.foo: () → void
+''');
+  }
+
+  test_getInheritedConcreteMap_method_with2() async {
+    addTestFile('''
+mixin A {
+  void foo() {}
+}
+
+mixin B {
+  void bar() {}
+}
+
+class C extends Object with A, B {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedConcreteMap('C', r'''
+A.foo: () → void
+B.bar: () → void
+''');
+  }
+
+  test_getInheritedMap_accessor_extends() async {
+    addTestFile('''
+class A {
+  int get foo => 0;
+}
+
+class B extends A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → int
+''');
+  }
+
+  test_getInheritedMap_accessor_implements() async {
+    addTestFile('''
+class A {
+  int get foo => 0;
+}
+
+abstract class B implements A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → int
+''');
+  }
+
+  test_getInheritedMap_accessor_with() async {
+    addTestFile('''
+mixin A {
+  int get foo => 0;
+}
+
+class B extends Object with A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → int
+''');
+  }
+
+  test_getInheritedMap_closestSuper() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+class B extends A {
+  void foo() {}
+}
+
+class X extends B {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('X', r'''
+B.foo: () → void
+''');
+  }
+
+  test_getInheritedMap_field_extends() async {
+    addTestFile('''
+class A {
+  int foo;
+}
+
+class B extends A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → int
+A.foo=: (int) → void
+''');
+  }
+
+  test_getInheritedMap_field_implements() async {
+    addTestFile('''
+class A {
+  int foo;
+}
+
+abstract class B implements A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → int
+A.foo=: (int) → void
+''');
+  }
+
+  test_getInheritedMap_field_with() async {
+    addTestFile('''
+mixin A {
+  int foo;
+}
+
+class B extends Object with A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → int
+A.foo=: (int) → void
+''');
+  }
+
+  test_getInheritedMap_implicitExtendsObject() async {
+    addTestFile('''
+class A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', '');
+  }
+
+  test_getInheritedMap_method_extends() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+class B extends A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → void
+''');
+  }
+
+  test_getInheritedMap_method_implements() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+abstract class B implements A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → void
+''');
+  }
+
+  test_getInheritedMap_method_with() async {
+    addTestFile('''
+mixin A {
+  void foo() {}
+}
+
+class B extends Object with A {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('B', r'''
+A.foo: () → void
+''');
+  }
+
+  test_getInheritedMap_preferImplemented() async {
+    addTestFile('''
+class A {
+  void foo() {}
+}
+
+class I {
+  void foo() {}
+}
+
+class X extends A implements I {
+  void foo() {}
+}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('X', r'''
+A.foo: () → void
+''');
+  }
+
+  test_getInheritedMap_union_conflict() async {
+    addTestFile('''
+abstract class I {
+  int foo();
+  void bar();
+}
+
+abstract class J {
+  double foo();
+  void bar();
+}
+
+abstract class A implements I, J {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+J.bar: () → void
+''');
+  }
+
+  test_getInheritedMap_union_differentNames() async {
+    addTestFile('''
+abstract class I {
+  int foo();
+}
+
+abstract class J {
+  double bar();
+}
+
+abstract class A implements I, J {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+I.foo: () → int
+J.bar: () → double
+''');
+  }
+
+  test_getInheritedMap_union_multipleSubtypes_2_getters() async {
+    addTestFile('''
+abstract class I {
+  int get foo;
+}
+
+abstract class J {
+  int get foo;
+}
+
+abstract class A implements I, J {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+J.foo: () → int
+''');
+  }
+
+  test_getInheritedMap_union_multipleSubtypes_2_methods() async {
+    addTestFile('''
+abstract class I {
+  void foo();
+}
+
+abstract class J {
+  void foo();
+}
+
+abstract class A implements I, J {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+J.foo: () → void
+''');
+  }
+
+  test_getInheritedMap_union_multipleSubtypes_2_setters() async {
+    addTestFile('''
+abstract class I {
+  void set foo(num _);
+}
+
+abstract class J {
+  void set foo(int _);
+}
+
+abstract class A implements I, J {}
+abstract class B implements J, I {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+I.foo=: (num) → void
+''');
+
+    _assertInheritedMap('B', r'''
+I.foo=: (num) → void
+''');
+  }
+
+  test_getInheritedMap_union_multipleSubtypes_3_getters() async {
+    addTestFile('''
+class A {}
+class B extends A {}
+class C extends B {}
+
+abstract class I1 {
+  A get foo;
+}
+
+abstract class I2 {
+  B get foo;
+}
+
+abstract class I3 {
+  C get foo;
+}
+
+abstract class D implements I1, I2, I3 {}
+abstract class E implements I3, I2, I1 {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('D', r'''
+I3.foo: () → C
+''');
+
+    _assertInheritedMap('E', r'''
+I3.foo: () → C
+''');
+  }
+
+  test_getInheritedMap_union_multipleSubtypes_3_methods() async {
+    addTestFile('''
+class A {}
+class B extends A {}
+class C extends B {}
+
+abstract class I1 {
+  void foo(A _);
+}
+
+abstract class I2 {
+  void foo(B _);
+}
+
+abstract class I3 {
+  void foo(C _);
+}
+
+abstract class D implements I1, I2, I3 {}
+abstract class E implements I3, I2, I1 {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('D', r'''
+I1.foo: (A) → void
+''');
+  }
+
+  test_getInheritedMap_union_multipleSubtypes_3_setters() async {
+    addTestFile('''
+class A {}
+class B extends A {}
+class C extends B {}
+
+abstract class I1 {
+  set foo(A _);
+}
+
+abstract class I2 {
+  set foo(B _);
+}
+
+abstract class I3 {
+  set foo(C _);
+}
+
+abstract class D implements I1, I2, I3 {}
+abstract class E implements I3, I2, I1 {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('D', r'''
+I1.foo=: (A) → void
+''');
+
+    _assertInheritedMap('E', r'''
+I1.foo=: (A) → void
+''');
+  }
+
+  test_getInheritedMap_union_oneSubtype_2_methods() async {
+    addTestFile('''
+abstract class I1 {
+  int foo();
+}
+
+abstract class I2 {
+  int foo([int _]);
+}
+
+abstract class A implements I1, I2 {}
+abstract class B implements I2, I1 {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+I2.foo: ([int]) → int
+''');
+
+    _assertInheritedMap('B', r'''
+I2.foo: ([int]) → int
+''');
+  }
+
+  test_getInheritedMap_union_oneSubtype_3_methods() async {
+    addTestFile('''
+abstract class I1 {
+  int foo();
+}
+
+abstract class I2 {
+  int foo([int _]);
+}
+
+abstract class I3 {
+  int foo([int _, int __]);
+}
+
+abstract class A implements I1, I2, I3 {}
+abstract class B implements I3, I2, I1 {}
+''');
+    await resolveTestFile();
+
+    _assertInheritedMap('A', r'''
+I3.foo: ([int, int]) → int
+''');
+
+    _assertInheritedMap('B', r'''
+I3.foo: ([int, int]) → int
+''');
+  }
+
   test_getMember() async {
     addTestFile('''
 abstract class I1 {
@@ -129,11 +714,11 @@
 ''');
     await resolveTestFile();
 
-    var memberType = manager.getMember(
-      findElement.class_('C').type,
-      new Name(null, 'f'),
+    _assertGetMember(
+      className: 'C',
+      name: 'f',
+      expected: 'I2.f: (Object) → void',
     );
-    assertElementTypeString(memberType, '(Object) → void');
   }
 
   test_getMember_concrete() async {
@@ -144,9 +729,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('A', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'A',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
   }
 
@@ -158,7 +745,11 @@
 ''');
     await resolveTestFile();
 
-    expect(_getConcrete('A', 'foo'), isNull);
+    _assertGetMember(
+      className: 'A',
+      name: 'foo',
+      concrete: true,
+    );
   }
 
   test_getMember_concrete_fromMixedClass() async {
@@ -171,9 +762,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('X', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
   }
 
@@ -189,9 +782,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('X', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
   }
 
@@ -207,9 +802,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('X', 'toString'),
-      same(findElement.method('toString', of: 'A')),
+    _assertGetMember(
+      className: 'X',
+      name: 'toString',
+      concrete: true,
+      expected: 'A.toString: () → String',
     );
   }
 
@@ -223,9 +820,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('X', 'foo'),
-      same(findElement.method('foo', of: 'M')),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      concrete: true,
+      expected: 'M.foo: () → void',
     );
   }
 
@@ -241,14 +840,18 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('B', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
 
-    expect(
-      _getConcrete('C', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'C',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
   }
 
@@ -258,7 +861,11 @@
 ''');
     await resolveTestFile();
 
-    expect(_getConcrete('A', 'foo'), isNull);
+    _assertGetMember(
+      className: 'A',
+      name: 'foo',
+      concrete: true,
+    );
   }
 
   test_getMember_concrete_noSuchMethod() async {
@@ -275,14 +882,18 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('B', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
 
-    expect(
-      _getConcrete('C', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'C',
+      name: 'foo',
+      concrete: true,
+      expected: 'A.foo: () → void',
     );
   }
 
@@ -300,7 +911,11 @@
 
     // noSuchMethod forwarders are not mixed-in.
     // https://github.com/dart-lang/sdk/issues/33553#issuecomment-424638320
-    expect(_getConcrete('B', 'foo'), isNull);
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      concrete: true,
+    );
   }
 
   test_getMember_concrete_noSuchMethod_moreSpecificSignature() async {
@@ -314,14 +929,16 @@
 }
 
 class C extends B {
-  void foo([a]);
+  void foo([int a]);
 }
 ''');
     await resolveTestFile();
 
-    expect(
-      _getConcrete('C', 'foo'),
-      same(findElement.method('foo', of: 'C')),
+    _assertGetMember(
+      className: 'C',
+      name: 'foo',
+      concrete: true,
+      expected: 'C.foo: ([int]) → void',
     );
   }
 
@@ -347,11 +964,11 @@
 ''');
     await resolveTestFile();
 
-    var member = manager.getMember(
-      findElement.class_('X').type,
-      new Name(null, 'foo'),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      expected: 'M2.foo: () → void',
     );
-    expect(member.element, findElement.method('foo', of: 'M2'));
   }
 
   test_getMember_preferLatest_superclass() async {
@@ -372,11 +989,11 @@
 ''');
     await resolveTestFile();
 
-    var member = manager.getMember(
-      findElement.class_('X').type,
-      new Name(null, 'foo'),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      expected: 'B.foo: () → void',
     );
-    expect(member.element, findElement.method('foo', of: 'B'));
   }
 
   test_getMember_preferLatest_this() async {
@@ -395,11 +1012,11 @@
 ''');
     await resolveTestFile();
 
-    var member = manager.getMember(
-      findElement.class_('X').type,
-      new Name(null, 'foo'),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      expected: 'X.foo: () → void',
     );
-    expect(member.element, findElement.method('foo', of: 'X'));
   }
 
   test_getMember_super_abstract() async {
@@ -414,7 +1031,46 @@
 ''');
     await resolveTestFile();
 
-    expect(_getSuper('B', 'foo'), isNull);
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      forSuper: true,
+    );
+  }
+
+  test_getMember_super_forMixin_interface() async {
+    addTestFile('''
+abstract class A {
+  void foo();
+}
+
+mixin M implements A {}
+''');
+    await resolveTestFile();
+
+    _assertGetMember(
+      className: 'M',
+      name: 'foo',
+      forSuper: true,
+    );
+  }
+
+  test_getMember_super_forMixin_superclassConstraint() async {
+    addTestFile('''
+abstract class A {
+  void foo();
+}
+
+mixin M on A {}
+''');
+    await resolveTestFile();
+
+    _assertGetMember(
+      className: 'M',
+      name: 'foo',
+      forSuper: true,
+      expected: 'A.foo: () → void',
+    );
   }
 
   test_getMember_super_fromMixin() async {
@@ -429,9 +1085,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getSuper('X', 'foo'),
-      same(findElement.method('foo', of: 'M')),
+    _assertGetMember(
+      className: 'X',
+      name: 'foo',
+      forSuper: true,
+      expected: 'M.foo: () → void',
     );
   }
 
@@ -447,9 +1105,11 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getSuper('B', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      forSuper: true,
+      expected: 'A.foo: () → void',
     );
   }
 
@@ -461,7 +1121,11 @@
 ''');
     await resolveTestFile();
 
-    expect(_getSuper('B', 'foo'), isNull);
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      forSuper: true,
+    );
   }
 
   test_getMember_super_noSuchMember() async {
@@ -477,28 +1141,90 @@
 ''');
     await resolveTestFile();
 
-    expect(
-      _getSuper('B', 'foo'),
-      same(findElement.method('foo', of: 'A')),
+    _assertGetMember(
+      className: 'B',
+      name: 'foo',
+      forSuper: true,
+      expected: 'A.foo: () → void',
     );
   }
 
-  ExecutableElement _getConcrete(String className, String name) {
-    var type = findElement.class_(className).type;
-    return manager
-        .getMember(type, new Name(null, name), concrete: true)
-        ?.element;
+  void _assertGetInherited({
+    @required String className,
+    @required String name,
+    String expected,
+  }) {
+    var interfaceType = findElement.classOrMixin(className).type;
+
+    var memberType = manager.getInherited(
+      interfaceType,
+      new Name(null, name),
+    );
+
+    _assertMemberType(memberType, expected);
   }
 
-  ExecutableElement _getInherited(String className, String name) {
-    var type = findElement.class_(className).type;
-    return manager.getInherited(type, new Name(null, name)).element;
+  void _assertGetMember({
+    @required String className,
+    @required String name,
+    String expected,
+    bool concrete = false,
+    bool forSuper = false,
+  }) {
+    var interfaceType = findElement.classOrMixin(className).type;
+
+    var memberType = manager.getMember(
+      interfaceType,
+      new Name(null, name),
+      concrete: concrete,
+      forSuper: forSuper,
+    );
+
+    _assertMemberType(memberType, expected);
   }
 
-  ExecutableElement _getSuper(String className, String name) {
+  void _assertInheritedConcreteMap(String className, String expected) {
     var type = findElement.class_(className).type;
-    return manager
-        .getMember(type, new Name(null, name), forSuper: true)
-        ?.element;
+    var map = manager.getInheritedConcreteMap(type);
+    _assertNameToFunctionTypeMap(map, expected);
+  }
+
+  void _assertInheritedMap(String className, String expected) {
+    var type = findElement.class_(className).type;
+    var map = manager.getInheritedMap(type);
+    _assertNameToFunctionTypeMap(map, expected);
+  }
+
+  void _assertMemberType(FunctionType type, String expected) {
+    if (expected != null) {
+      var element = type.element;
+      var enclosingElement = element.enclosingElement;
+      var actual = '${enclosingElement.name}.${element.name}: $type';
+      expect(actual, expected);
+    } else {
+      expect(type, isNull);
+    }
+  }
+
+  void _assertNameToFunctionTypeMap(
+      Map<Name, FunctionType> map, String expected) {
+    var lines = <String>[];
+    for (var name in map.keys) {
+      var type = map[name];
+      var element = type.element;
+
+      var enclosingElement = element.enclosingElement;
+      if (enclosingElement.name == 'Object') continue;
+
+      lines.add('${enclosingElement.name}.${element.name}: $type');
+    }
+
+    lines.sort();
+    var actual = lines.isNotEmpty ? lines.join('\n') + '\n' : '';
+
+    if (actual != expected) {
+      print(actual);
+    }
+    expect(actual, expected);
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index a2abdd1..8e1a8a1 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -9,12 +9,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AssignmentDriverResolutionTest);
-    defineReflectiveTests(AssignmentTaskResolutionTest);
   });
 }
 
@@ -1245,7 +1243,3 @@
     assertType(xRef, 'int');
   }
 }
-
-@reflectiveTest
-class AssignmentTaskResolutionTest extends TaskResolutionTest
-    with AssignmentResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
index 6a6388a..e97423c 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
@@ -6,12 +6,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ClassAliasDriverResolutionTest);
-    defineReflectiveTests(ClassAliasTaskResolutionTest);
   });
 }
 
@@ -130,7 +128,3 @@
     assertConstructors(findElement.class_('B'), ['B(E x, E y) → B<E>']);
   }
 }
-
-@reflectiveTest
-class ClassAliasTaskResolutionTest extends TaskResolutionTest
-    with ClassAliasResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index efcec88..f8ce37a 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -8,12 +8,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ClassDriverResolutionTest);
-    defineReflectiveTests(ClassTaskResolutionTest);
   });
 }
 
@@ -1681,17 +1679,3 @@
     assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_SETTER]);
   }
 }
-
-@reflectiveTest
-class ClassTaskResolutionTest extends TaskResolutionTest
-    with ClassResolutionMixin {
-  @failingTest
-  test_conflictingGenericInterfaces_simple() {
-    return super.test_conflictingGenericInterfaces_simple();
-  }
-
-  @failingTest
-  test_conflictingGenericInterfaces_viaMixin() {
-    return super.test_conflictingGenericInterfaces_viaMixin();
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
index 5371eac..8fba266 100644
--- a/pkg/analyzer/test/src/dart/resolution/comment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -6,12 +6,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CommentDriverResolutionTest);
-    defineReflectiveTests(CommentTaskResolutionTest);
   });
 }
 
@@ -255,7 +253,3 @@
     assertElement(findNode.simple('x] in B'), x);
   }
 }
-
-@reflectiveTest
-class CommentTaskResolutionTest extends TaskResolutionTest
-    with ClassAliasResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 4ba17ed..4fde7c2 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -9,12 +9,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConstantDriverTest);
-    defineReflectiveTests(ConstantTaskTest);
   });
 }
 
@@ -151,6 +149,3 @@
     ]);
   }
 }
-
-@reflectiveTest
-class ConstantTaskTest extends TaskResolutionTest with ConstantMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/definite_assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/definite_assignment_test.dart
index c9d840d..48a15c7 100644
--- a/pkg/analyzer/test/src/dart/resolution/definite_assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/definite_assignment_test.dart
@@ -1357,6 +1357,42 @@
   }
 
   @override
+  void visitForStatement2(ForStatement2 node) {
+    var parts = node.forLoopParts;
+    VariableDeclarationList variables;
+    Expression initialization;
+    Expression condition;
+    Expression iterable;
+    NodeList<Expression> updaters;
+    if (parts is ForPartsWithDeclarations) {
+      variables = parts.variables;
+      condition = parts.condition;
+      updaters = parts.updaters;
+    } else if (parts is ForPartsWithExpression) {
+      initialization = parts.initialization;
+      condition = parts.condition;
+      updaters = parts.updaters;
+    } else if (parts is ForEachParts) {
+      iterable = parts.iterable;
+    }
+
+    tracker.beginForStatement2(node);
+
+    variables?.accept(this);
+    initialization?.accept(this);
+    condition?.accept(this);
+    iterable?.accept(this);
+
+    tracker.beginForStatementBody();
+    node.body?.accept(this);
+
+    tracker.beginForStatementUpdaters();
+    updaters?.accept(this);
+
+    tracker.endForStatement();
+  }
+
+  @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     super.visitFunctionDeclaration(node);
     if (node.parent is CompilationUnit) {
diff --git a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
index 081ef0e..50902ca 100644
--- a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+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/driver.dart';
@@ -41,14 +42,8 @@
   }
 
   @override
-  Future<TestAnalysisResult> resolveFile(String path) async {
-    var result = await driver.getResult(path);
-    return new TestAnalysisResult(
-      path,
-      result.content,
-      result.unit,
-      result.errors,
-    );
+  Future<ResolvedUnitResult> resolveFile(String path) async {
+    return await driver.getResult(path);
   }
 
   void setUp() {
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index ff350fb..90a59b1 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -8,12 +8,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(EnumDriverResolutionTest);
-    defineReflectiveTests(EnumTaskResolutionTest);
   });
 }
 
@@ -60,7 +58,3 @@
     expect(findElement.field('values').isConstantEvaluated, isTrue);
   }
 }
-
-@reflectiveTest
-class EnumTaskResolutionTest extends TaskResolutionTest
-    with EnumResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/find_element.dart b/pkg/analyzer/test/src/dart/resolution/find_element.dart
deleted file mode 100644
index d0ac7bf..0000000
--- a/pkg/analyzer/test/src/dart/resolution/find_element.dart
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:test/test.dart';
-
-import 'function_ast_visitor.dart';
-
-/// Helper for finding elements declared in the resolved [unit].
-class FindElement {
-  final CompilationUnit unit;
-
-  FindElement(this.unit);
-
-  CompilationUnitElement get unitElement => unit.declaredElement;
-
-  ClassElement class_(String name) {
-    for (var class_ in unitElement.types) {
-      if (class_.name == name) {
-        return class_;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  ConstructorElement constructor(String name, {String of}) {
-    assert(name != '');
-    ConstructorElement result;
-    for (var class_ in unitElement.types) {
-      if (of == null || class_.name == of) {
-        for (var constructor in class_.constructors) {
-          if (constructor.name == name) {
-            if (result != null) {
-              fail('Not unique: $name');
-            }
-            result = constructor;
-          }
-        }
-      }
-    }
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  ClassElement enum_(String name) {
-    for (var enum_ in unitElement.enums) {
-      if (enum_.name == name) {
-        return enum_;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  ExportElement export(String targetUri) {
-    ExportElement result;
-
-    for (var export in unitElement.library.exports) {
-      var exportedUri = export.exportedLibrary.source.uri.toString();
-      if (exportedUri == targetUri) {
-        if (result != null) {
-          fail('Not unique: $targetUri');
-        }
-        result = export;
-      }
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $targetUri');
-  }
-
-  FieldElement field(String name, {String of}) {
-    FieldElement result;
-
-    void findIn(List<FieldElement> fields) {
-      for (var field in fields) {
-        if (field.name == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = field;
-        }
-      }
-    }
-
-    for (var enum_ in unitElement.enums) {
-      if (of != null && enum_.name != of) {
-        continue;
-      }
-      findIn(enum_.fields);
-    }
-
-    for (var class_ in unitElement.types) {
-      if (of != null && class_.name != of) {
-        continue;
-      }
-      findIn(class_.fields);
-    }
-
-    for (var mixin in unitElement.mixins) {
-      if (of != null && mixin.name != of) {
-        continue;
-      }
-      findIn(mixin.fields);
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  FunctionElement function(String name) {
-    for (var function in unitElement.functions) {
-      if (function.name == name) {
-        return function;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  GenericTypeAliasElement genericTypeAlias(String name) {
-    for (var element in unitElement.functionTypeAliases) {
-      if (element is GenericTypeAliasElement && element.name == name) {
-        return element;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  PropertyAccessorElement getter(String name, {String of}) {
-    PropertyAccessorElement result;
-
-    void findIn(List<PropertyAccessorElement> accessors) {
-      for (var accessor in accessors) {
-        if (accessor.isGetter && accessor.displayName == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = accessor;
-        }
-      }
-    }
-
-    for (var enum_ in unitElement.enums) {
-      if (of != null && enum_.name != of) {
-        continue;
-      }
-      findIn(enum_.accessors);
-    }
-
-    for (var class_ in unitElement.types) {
-      if (of != null && class_.name != of) {
-        continue;
-      }
-      findIn(class_.accessors);
-    }
-
-    for (var mixin in unitElement.mixins) {
-      if (of != null && mixin.name != of) {
-        continue;
-      }
-      findIn(mixin.accessors);
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  ImportElement import(String targetUri) {
-    ImportElement importElement;
-
-    for (var import in unitElement.library.imports) {
-      var importedUri = import.importedLibrary.source.uri.toString();
-      if (importedUri == targetUri) {
-        if (importElement != null) {
-          fail('Not unique: $targetUri');
-        }
-        importElement = import;
-      }
-    }
-
-    if (importElement != null) {
-      return importElement;
-    }
-    fail('Not found: $targetUri');
-  }
-
-  InterfaceType interfaceType(String name) {
-    return class_(name).type;
-  }
-
-  FunctionElement localFunction(String name) {
-    FunctionElement result;
-
-    unit.accept(new FunctionAstVisitor(
-      functionDeclarationStatement: (node) {
-        var element = node.functionDeclaration.declaredElement;
-        if (element is FunctionElement) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = element;
-        }
-      },
-    ));
-
-    if (result == null) {
-      fail('Not found: $name');
-    }
-    return result;
-  }
-
-  LocalVariableElement localVar(String name) {
-    LocalVariableElement result;
-
-    unit.accept(new FunctionAstVisitor(
-      variableDeclaration: (node) {
-        var element = node.declaredElement;
-        if (element is LocalVariableElement && element.name == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = element;
-        }
-      },
-    ));
-
-    if (result == null) {
-      fail('Not found: $name');
-    }
-    return result;
-  }
-
-  MethodElement method(String name, {String of}) {
-    MethodElement result;
-
-    void findIn(List<MethodElement> methods) {
-      for (var method in methods) {
-        if (method.name == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = method;
-        }
-      }
-    }
-
-    for (var class_ in unitElement.types) {
-      if (of != null && class_.name != of) {
-        continue;
-      }
-      findIn(class_.methods);
-    }
-
-    for (var mixin in unitElement.mixins) {
-      if (of != null && mixin.name != of) {
-        continue;
-      }
-      findIn(mixin.methods);
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  ClassElement mixin(String name) {
-    for (var mixin in unitElement.mixins) {
-      if (mixin.name == name) {
-        return mixin;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  ParameterElement parameter(String name) {
-    ParameterElement result;
-
-    void findIn(List<ParameterElement> parameters) {
-      for (var parameter in parameters) {
-        if (parameter.name == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = parameter;
-        }
-      }
-    }
-
-    for (var accessor in unitElement.accessors) {
-      findIn(accessor.parameters);
-    }
-
-    for (var function in unitElement.functions) {
-      findIn(function.parameters);
-    }
-
-    for (var function in unitElement.functionTypeAliases) {
-      findIn(function.parameters);
-    }
-
-    for (var class_ in unitElement.types) {
-      for (var constructor in class_.constructors) {
-        findIn(constructor.parameters);
-      }
-      for (var method in class_.methods) {
-        findIn(method.parameters);
-      }
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  PrefixElement prefix(String name) {
-    for (var import_ in unitElement.library.imports) {
-      var prefix = import_.prefix;
-      if (prefix?.name == name) {
-        return prefix;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  PropertyAccessorElement setter(String name, {String of}) {
-    PropertyAccessorElement result;
-
-    void findIn(List<PropertyAccessorElement> accessors) {
-      for (var accessor in accessors) {
-        if (accessor.isSetter && accessor.displayName == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = accessor;
-        }
-      }
-    }
-
-    for (var class_ in unitElement.types) {
-      if (of != null && class_.name != of) {
-        continue;
-      }
-      findIn(class_.accessors);
-    }
-
-    for (var mixin in unitElement.mixins) {
-      if (of != null && mixin.name != of) {
-        continue;
-      }
-      findIn(mixin.accessors);
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  FunctionElement topFunction(String name) {
-    for (var function in unitElement.functions) {
-      if (function.name == name) {
-        return function;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  PropertyAccessorElement topGet(String name) {
-    return topVar(name).getter;
-  }
-
-  PropertyAccessorElement topSet(String name) {
-    return topVar(name).setter;
-  }
-
-  TopLevelVariableElement topVar(String name) {
-    for (var variable in unitElement.topLevelVariables) {
-      if (variable.name == name) {
-        return variable;
-      }
-    }
-    fail('Not found: $name');
-  }
-
-  TypeParameterElement typeParameter(String name) {
-    TypeParameterElement result;
-
-    void findIn(List<TypeParameterElement> typeParameters) {
-      for (var typeParameter in typeParameters) {
-        if (typeParameter.name == name) {
-          if (result != null) {
-            fail('Not unique: $name');
-          }
-          result = typeParameter;
-        }
-      }
-    }
-
-    for (var type in unitElement.functionTypeAliases) {
-      findIn(type.typeParameters);
-      if (type is GenericTypeAliasElement) {
-        findIn(type.function.typeParameters);
-      }
-    }
-
-    for (var class_ in unitElement.types) {
-      findIn(class_.typeParameters);
-    }
-
-    for (var mixin in unitElement.mixins) {
-      findIn(mixin.typeParameters);
-    }
-
-    if (result != null) {
-      return result;
-    }
-    fail('Not found: $name');
-  }
-
-  ConstructorElement unnamedConstructor(String name) {
-    return class_(name).unnamedConstructor;
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/find_node.dart b/pkg/analyzer/test/src/dart/resolution/find_node.dart
deleted file mode 100644
index 08de2f9..0000000
--- a/pkg/analyzer/test/src/dart/resolution/find_node.dart
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:test/test.dart';
-
-class FindNode {
-  final String content;
-  final CompilationUnit unit;
-
-  FindNode(this.content, this.unit);
-
-  LibraryDirective get libraryDirective {
-    return unit.directives.singleWhere((d) => d is LibraryDirective);
-  }
-
-  Annotation annotation(String search) {
-    return _node(search, (n) => n is Annotation);
-  }
-
-  AssignmentExpression assignment(String search) {
-    return _node(search, (n) => n is AssignmentExpression);
-  }
-
-  CascadeExpression cascade(String search) {
-    return _node(search, (n) => n is CascadeExpression);
-  }
-
-  ClassDeclaration classDeclaration(String search) {
-    return _node(search, (n) => n is ClassDeclaration);
-  }
-
-  CommentReference commentReference(String search) {
-    return _node(search, (n) => n is CommentReference);
-  }
-
-  ConstructorDeclaration constructor(String search) {
-    return _node(search, (n) => n is ConstructorDeclaration);
-  }
-
-  ExportDirective export(String search) {
-    return _node(search, (n) => n is ExportDirective);
-  }
-
-  FieldFormalParameter fieldFormalParameter(String search) {
-    return _node(search, (n) => n is FieldFormalParameter);
-  }
-
-  FunctionExpression functionExpression(String search) {
-    return _node(search, (n) => n is FunctionExpression);
-  }
-
-  GenericFunctionType genericFunctionType(String search) {
-    return _node(search, (n) => n is GenericFunctionType);
-  }
-
-  ImportDirective import(String search) {
-    return _node(search, (n) => n is ImportDirective);
-  }
-
-  InstanceCreationExpression instanceCreation(String search) {
-    return _node(search, (n) => n is InstanceCreationExpression);
-  }
-
-  ListLiteral listLiteral(String search) {
-    return _node(search, (n) => n is ListLiteral);
-  }
-
-  MapLiteral mapLiteral(String search) {
-    return _node(search, (n) => n is MapLiteral);
-  }
-
-  MethodDeclaration methodDeclaration(String search) {
-    return _node(search, (n) => n is MethodDeclaration);
-  }
-
-  MethodInvocation methodInvocation(String search) {
-    return _node(search, (n) => n is MethodInvocation);
-  }
-
-  MixinDeclaration mixin(String search) {
-    return _node(search, (n) => n is MixinDeclaration);
-  }
-
-  ParenthesizedExpression parenthesized(String search) {
-    return _node(search, (n) => n is ParenthesizedExpression);
-  }
-
-  PartDirective part(String search) {
-    return _node(search, (n) => n is PartDirective);
-  }
-
-  PartOfDirective partOf(String search) {
-    return _node(search, (n) => n is PartOfDirective);
-  }
-
-  PostfixExpression postfix(String search) {
-    return _node(search, (n) => n is PostfixExpression);
-  }
-
-  PrefixExpression prefix(String search) {
-    return _node(search, (n) => n is PrefixExpression);
-  }
-
-  PrefixedIdentifier prefixed(String search) {
-    return _node(search, (n) => n is PrefixedIdentifier);
-  }
-
-  PropertyAccess propertyAccess(String search) {
-    return _node(search, (n) => n is PropertyAccess);
-  }
-
-  RethrowExpression rethrow_(String search) {
-    return _node(search, (n) => n is RethrowExpression);
-  }
-
-  SimpleIdentifier simple(String search) {
-    return _node(search, (_) => true);
-  }
-
-  SimpleFormalParameter simpleParameter(String search) {
-    return _node(search, (n) => n is SimpleFormalParameter);
-  }
-
-  StringLiteral stringLiteral(String search) {
-    return _node(search, (n) => n is StringLiteral);
-  }
-
-  SuperExpression super_(String search) {
-    return _node(search, (n) => n is SuperExpression);
-  }
-
-  ThisExpression this_(String search) {
-    return _node(search, (n) => n is ThisExpression);
-  }
-
-  ThrowExpression throw_(String search) {
-    return _node(search, (n) => n is ThrowExpression);
-  }
-
-  TypeName typeName(String search) {
-    return _node(search, (n) => n is TypeName);
-  }
-
-  TypeParameter typeParameter(String search) {
-    return _node(search, (n) => n is TypeParameter);
-  }
-
-  VariableDeclaration variableDeclaration(String search) {
-    return _node(search, (n) => n is VariableDeclaration);
-  }
-
-  AstNode _node(String search, bool Function(AstNode) predicate) {
-    var index = content.indexOf(search);
-    if (content.indexOf(search, index + 1) != -1) {
-      fail('The pattern |$search| is not unique in:\n$content');
-    }
-    expect(index, greaterThanOrEqualTo(0));
-
-    var node = new NodeLocator2(index).searchWithin(unit);
-    expect(node, isNotNull);
-
-    var result = node.thisOrAncestorMatching(predicate);
-    expect(result, isNotNull);
-    return result;
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
new file mode 100644
index 0000000..4c7daeb
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/flow_analysis_test.dart
@@ -0,0 +1,3581 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NullableFlowTest);
+    defineReflectiveTests(DefiniteAssignmentFlowTest);
+    defineReflectiveTests(ReachableFlowTest);
+    defineReflectiveTests(TypePromotionFlowTest);
+  });
+}
+
+@reflectiveTest
+class DefiniteAssignmentFlowTest extends DriverResolutionTest {
+  final List<LocalVariableElement> readBeforeWritten = [];
+
+  /// Assert that only local variables with the given names are marked as read
+  /// before being written.  All the other local variables are implicitly
+  /// considered definitely assigned.
+  void assertReadBeforeWritten(
+      [String name1, String name2, String name3, String name4]) {
+    var expected = [name1, name2, name3, name4]
+        .where((i) => i != null)
+        .map((name) => findElement.localVar(name))
+        .toList();
+    expect(readBeforeWritten, unorderedEquals(expected));
+  }
+
+  test_assignment_leftExpression() async {
+    await trackCode(r'''
+void f() {
+  List<int> v;
+  v[0] = (v = [1, 2])[1];
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_assignment_leftLocal_compound() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  v += 1;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_assignment_leftLocal_compound_assignInRight() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  v += (v = v);
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_assignment_leftLocal_pure_eq() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  v = 0;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_assignment_leftLocal_pure_eq_self() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  v = v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_assignment_leftLocal_pure_questionEq() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  v ??= 0;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_assignment_leftLocal_pure_questionEq_self() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  v ??= v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_binaryExpression_ifNull_left() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  (v = 0) ?? 0;
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_binaryExpression_ifNull_right() async {
+    await trackCode(r'''
+void f(int a) {
+  int v;
+  a ?? (v = 0);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_binaryExpression_logicalAnd_left() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  ((v = 0) >= 0) && c;
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_binaryExpression_logicalAnd_right() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  c && ((v = 0) >= 0);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_binaryExpression_logicalOr_left() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  ((v = 0) >= 0) || c;
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_binaryExpression_logicalOr_right() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  c || ((v = 0) >= 0);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_binaryExpression_plus_left() async {
+    await trackCode(r'''
+main() {
+  int v;
+  (v = 0) + 1;
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_binaryExpression_plus_right() async {
+    await trackCode(r'''
+main() {
+  int v;
+  1 + (v = 0);
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_conditional_both() async {
+    await trackCode(r'''
+f(bool v) {
+  int v;
+  b ? (v = 1) : (v = 2);
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_conditional_else() async {
+    await trackCode(r'''
+f(bool v) {
+  int v;
+  b ? 1 : (v = 2);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_conditional_then() async {
+    await trackCode(r'''
+f(bool v) {
+  int v;
+  b ? (v = 1) : 2;
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_conditionalExpression_condition() async {
+    await trackCode(r'''
+main() {
+  int v;
+  (v = 0) >= 0 ? 1 : 2;
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_doWhile_break_afterAssignment() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    v = 0;
+    v;
+    if (b) break;
+  } while (b);
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_doWhile_break_beforeAssignment() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) break;
+    v = 0;
+  } while (b);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_doWhile_breakOuterFromInner() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2, v3;
+  L1: do {
+    do {
+      v1 = 0;
+      if (b) break L1;
+      v2 = 0;
+      v3 = 0;
+    } while (b);
+    v2;
+  } while (b);
+  v1;
+  v3;
+}
+''');
+    assertReadBeforeWritten('v3');
+  }
+
+  test_doWhile_condition() async {
+    await trackCode(r'''
+void f() {
+  int v1, v2;
+  do {
+    v1; // assigned in the condition, but not yet
+  } while ((v1 = 0) + (v2 = 0) >= 0);
+  v2;
+}
+''');
+    assertReadBeforeWritten('v1');
+  }
+
+  test_doWhile_condition_break() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) break;
+  } while ((v = 0) >= 0);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_doWhile_condition_break_continue() async {
+    await trackCode(r'''
+void f(bool b1, b2) {
+  int v1, v2, v3, v4, v5, v6;
+  do {
+    v1 = 0; // visible outside, visible to the condition
+    if (b1) break;
+    v2 = 0; // not visible outside, visible to the condition
+    v3 = 0; // not visible outside, visible to the condition
+    if (b2) continue;
+    v4 = 0; // not visible
+    v5 = 0; // not visible
+  } while ((v6 = v1 + v2 + v4) == 0); // has break => v6 is not visible outside
+  v1;
+  v3;
+  v5;
+  v6;
+}
+''');
+    assertReadBeforeWritten('v3', 'v4', 'v5', 'v6');
+  }
+
+  test_doWhile_condition_continue() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2, v3, v4;
+  do {
+    v1 = 0; // visible outside, visible to the condition
+    if (b) continue;
+    v2 = 0; // not visible
+    v3 = 0; // not visible
+  } while ((v4 = v1 + v2) == 0); // no break => v4 visible outside
+  v1;
+  v3;
+  v4;
+}
+''');
+    assertReadBeforeWritten('v2', 'v3');
+  }
+
+  test_doWhile_continue_beforeAssignment() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) continue;
+    v = 0;
+  } while (b);
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_doWhile_true_assignInBreak() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  do {
+    if (b) {
+      v = 0;
+      break;
+    }
+  } while (true);
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_for_body() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  for (; b;) {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_for_break() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b;) {
+    v1 = 0;
+    if (b) break;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v1', 'v2');
+  }
+
+  test_for_break_updaters() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b; v1 + v2) {
+    v1 = 0;
+    if (b) break;
+    v2 = 0;
+  }
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_for_condition() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  for (; (v = 0) >= 0;) {
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_for_continue() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b;) {
+    v1 = 0;
+    if (b) continue;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v1', 'v2');
+  }
+
+  test_for_continue_updaters() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (; b; v1 + v2) {
+    v1 = 0;
+    if (b) continue;
+    v2 = 0;
+  }
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_for_initializer_expression() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  for (v = 0;;) {
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_for_initializer_variable() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  for (var t = (v = 0);;) {
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_for_updaters() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2, v3, v4;
+  for (; b; v1 = 0, v2 = 0, v3 = 0, v4) {
+    v1;
+  }
+  v2;
+}
+''');
+    assertReadBeforeWritten('v1', 'v2', 'v4');
+  }
+
+  test_for_updaters_afterBody() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  for (; b; v) {
+    v = 0;
+  }
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_forEach() async {
+    await trackCode(r'''
+void f() {
+  int v1, v2;
+  for (var _ in (v1 = [0, 1, 2])) {
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_forEach_break() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (var _ in [0, 1, 2]) {
+    v1 = 0;
+    if (b) break;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v1', 'v2');
+  }
+
+  test_forEach_continue() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  for (var _ in [0, 1, 2]) {
+    v1 = 0;
+    if (b) continue;
+    v2 = 0;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v1', 'v2');
+  }
+
+  test_functionExpression_closure_read() async {
+    await trackCode(r'''
+void f() {
+  int v1, v2;
+  
+  v1 = 0;
+  
+  [0, 1, 2].forEach((t) {
+    v1;
+    v2;
+  });
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_functionExpression_closure_write() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  
+  [0, 1, 2].forEach((t) {
+    v = t;
+  });
+
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_functionExpression_localFunction_local() async {
+    await trackCode(r'''
+void f() {
+  int v;
+
+  v = 0;
+
+  void f() {
+    int v; // 1
+    v;
+  }
+}
+''');
+    var localV = findNode.simple('v; // 1').staticElement;
+    expect(readBeforeWritten, unorderedEquals([localV]));
+  }
+
+  test_functionExpression_localFunction_local2() async {
+    await trackCode(r'''
+void f() {
+  int v1;
+
+  v1 = 0;
+
+  void f() {
+    int v2, v3;
+    v2 = 0;
+    v1;
+    v2;
+    v3;
+  }
+}
+''');
+    assertReadBeforeWritten('v3');
+  }
+
+  test_functionExpression_localFunction_read() async {
+    await trackCode(r'''
+void f() {
+  int v1, v2, v3;
+
+  v1 = 0;
+
+  void f() {
+    v1;
+    v2;
+  }
+
+  v2 = 0;
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_functionExpression_localFunction_write() async {
+    await trackCode(r'''
+void f() {
+  int v;
+
+  void f() {
+    v = 0;
+  }
+
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_if_condition() async {
+    await trackCode(r'''
+main() {
+  int v;
+  if ((v = 0) >= 0) {
+    v;
+  } else {
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_condition_false() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  if (false) {
+    // not assigned
+  } else {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_condition_logicalAnd_else() async {
+    await trackCode(r'''
+void f(bool b, int i) {
+  int v;
+  if (b && (v = i) > 0) {
+  } else {
+    v;
+  }
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_if_condition_logicalAnd_then() async {
+    await trackCode(r'''
+void f(bool b, int i) {
+  int v;
+  if (b && (v = i) > 0) {
+    v;
+  }
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_condition_logicalOr_else() async {
+    await trackCode(r'''
+void f(bool b, int i) {
+  int v;
+  if (b || (v = i) > 0) {
+  } else {
+    v;
+  }
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_condition_logicalOr_then() async {
+    await trackCode(r'''
+void f(bool b, int i) {
+  int v;
+  if (b || (v = i) > 0) {
+    v;
+  } else {
+  }
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_if_condition_notFalse() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  if (!false) {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_condition_notTrue() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  if (!true) {
+    // not assigned
+  } else {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_condition_true() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  if (true) {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_then() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_if_thenElse_all() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    v = 0;
+    v;
+  } else {
+    v = 0;
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_if_thenElse_else() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    // not assigned
+  } else {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_if_thenElse_then() async {
+    await trackCode(r'''
+main(bool c) {
+  int v;
+  if (c) {
+    v = 0;
+  } else {
+    // not assigned
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_switch_case1_default() async {
+    await trackCode(r'''
+void f(int e) {
+  int v;
+  switch (e) {
+    case 1:
+      v = 0;
+      break;
+    case 2:
+      // not assigned
+      break;
+    default:
+      v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_switch_case2_default() async {
+    await trackCode(r'''
+void f(int e) {
+  int v1, v2;
+  switch (e) {
+    case 1:
+      v1 = 0;
+      v2 = 0;
+      v1;
+      break;
+    default:
+      v1 = 0;
+      v1;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_switch_case_default_break() async {
+    await trackCode(r'''
+void f(bool b, int e) {
+  int v1, v2;
+  switch (e) {
+    case 1:
+      v1 = 0;
+      if (b) break;
+      v2 = 0;
+      break;
+    default:
+      v1 = 0;
+      if (b) break;
+      v2 = 0;
+  }
+  v1;
+  v2;
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_switch_case_default_continue() async {
+    await trackCode(r'''
+void f(int e) {
+  int v;
+  switch (e) {
+    L: case 1:
+      v = 0;
+      break;
+    case 2:
+      continue L;
+      break;
+    default:
+      v = 0;
+  }
+  v;
+}
+''');
+    // We don't analyze to which `case` we go from `continue L`,
+    // but we don't have to. If all cases assign, then the variable is
+    // removed from the unassigned set in the `breakState`. And if there is a
+    // case when it is not assigned, then the variable will be left unassigned
+    // in the `breakState`.
+    assertReadBeforeWritten();
+  }
+
+  test_switch_case_noDefault() async {
+    await trackCode(r'''
+void f(int e) {
+  int v;
+  switch (e) {
+    case 1:
+      v = 0;
+      break;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_switch_expression() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  switch (v = 0) {}
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_tryCatch_body() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } catch (_) {
+    // not assigned
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_tryCatch_body_catch() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    g();
+    v = 0;
+  } catch (_) {
+    v = 0;
+  }
+  v;
+}
+
+void g() {}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_tryCatch_body_catchRethrow() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } catch (_) {
+    rethrow;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_tryCatch_catch() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } catch (_) {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_tryCatchFinally_body() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } catch (_) {
+    // not assigned
+  } finally {
+    // not assigned
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_tryCatchFinally_catch() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } catch (_) {
+    v = 0;
+  } finally {
+    // not assigned
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten('v');
+  }
+
+  test_tryCatchFinally_finally() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } catch (_) {
+    // not assigned
+  } finally {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_tryCatchFinally_useInFinally() async {
+    await trackCode(r'''
+f() {
+  int x;
+  try {
+    g(); // may throw an exception
+    x = 1;
+  } catch (_) {
+    x = 1;
+  } finally {
+    x; // BAD
+  }
+}
+
+void g() {}
+''');
+    assertReadBeforeWritten('x');
+  }
+
+  test_tryFinally_body() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    v = 0;
+  } finally {
+    // not assigned
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_tryFinally_finally() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  try {
+    // not assigned
+  } finally {
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_while_condition() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  while ((v = 0) >= 0) {
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_while_condition_notTrue() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  while (b) {
+    v1 = 0;
+    v2 = 0;
+    v1;
+  }
+  v2;
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_while_true_break_afterAssignment() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  while (true) {
+    v1 = 0;
+    v1;
+    if (b) break;
+    v1;
+    v2 = 0;
+    v2;
+  }
+  v1;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_while_true_break_beforeAssignment() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  while (true) {
+    if (b) break;
+    v1 = 0;
+    v2 = 0;
+    v2;
+  }
+  v1;
+}
+''');
+    assertReadBeforeWritten('v1');
+  }
+
+  test_while_true_break_if() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  while (true) {
+    if (b) {
+      v = 0;
+      break;
+    } else {
+      v = 0;
+      break;
+    }
+    v;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_while_true_break_if2() async {
+    await trackCode(r'''
+void f(bool b) {
+  var v;
+  while (true) {
+    if (b) {
+      break;
+    } else {
+      v = 0;
+    }
+    v;
+  }
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_while_true_break_if3() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2;
+  while (true) {
+    if (b) {
+      v1 = 0;
+      v2 = 0;
+      if (b) break;
+    } else {
+      if (b) break;
+      v1 = 0;
+      v2 = 0;
+    }
+    v1;
+  }
+  v2;
+}
+''');
+    assertReadBeforeWritten('v2');
+  }
+
+  test_while_true_breakOuterFromInner() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v1, v2, v3;
+  L1: while (true) {
+    L2: while (true) {
+      v1 = 0;
+      if (b) break L1;
+      v2 = 0;
+      v3 = 0;
+      if (b) break L2;
+    }
+    v2;
+  }
+  v1;
+  v3;
+}
+''');
+    assertReadBeforeWritten('v3');
+  }
+
+  test_while_true_continue() async {
+    await trackCode(r'''
+void f(bool b) {
+  int v;
+  while (true) {
+    if (b) continue;
+    v = 0;
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  test_while_true_noBreak() async {
+    await trackCode(r'''
+void f() {
+  int v;
+  while (true) {
+    // No assignment, but no break.
+    // So, we don't exit the loop.
+    // So, all variables are assigned.
+  }
+  v;
+}
+''');
+    assertReadBeforeWritten();
+  }
+
+  /// Resolve the given [code] and track assignments in the unit.
+  Future<void> trackCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+
+    var unit = result.unit;
+
+    var loopAssignedVariables = AssignedVariables();
+    unit.accept(_AssignedVariablesVisitor(loopAssignedVariables));
+
+    var typeSystem = unit.declaredElement.context.typeSystem;
+    unit.accept(_AstVisitor(
+      typeSystem,
+      loopAssignedVariables,
+      {},
+      readBeforeWritten,
+      [],
+      [],
+      [],
+      [],
+    ));
+  }
+}
+
+@reflectiveTest
+class NullableFlowTest extends DriverResolutionTest {
+  final List<AstNode> nullableNodes = [];
+  final List<AstNode> nonNullableNodes = [];
+
+  void assertNonNullable([
+    String search1,
+    String search2,
+    String search3,
+    String search4,
+    String search5,
+  ]) {
+    var expected = [search1, search2, search3, search4, search5]
+        .where((i) => i != null)
+        .map((search) => findNode.simple(search))
+        .toList();
+    expect(nonNullableNodes, unorderedEquals(expected));
+  }
+
+  void assertNullable([
+    String search1,
+    String search2,
+    String search3,
+    String search4,
+    String search5,
+  ]) {
+    var expected = [search1, search2, search3, search4, search5]
+        .where((i) => i != null)
+        .map((search) => findNode.simple(search))
+        .toList();
+    expect(nullableNodes, unorderedEquals(expected));
+  }
+
+  test_assign_toNonNull() async {
+    await trackCode(r'''
+void f(int x) {
+  if (x != null) return;
+  x; // 1
+  x = 0;
+  x; // 2
+}
+''');
+    assertNullable('x; // 1');
+    assertNonNullable('x; // 2');
+  }
+
+  test_assign_toNull() async {
+    await trackCode(r'''
+void f(int x) {
+  if (x == null) return;
+  x; // 1
+  x = null;
+  x; // 2
+}
+''');
+    assertNullable('x; // 2');
+    assertNonNullable('x; // 1');
+  }
+
+  test_assign_toUnknown_fromNotNull() async {
+    await trackCode(r'''
+void f(int a, int b) {
+  if (a == null) return;
+  a; // 1
+  a = b;
+  a; // 2
+}
+''');
+    assertNullable();
+    assertNonNullable('a; // 1');
+  }
+
+  test_assign_toUnknown_fromNull() async {
+    await trackCode(r'''
+void f(int a, int b) {
+  if (a != null) return;
+  a; // 1
+  a = b;
+  a; // 2
+}
+''');
+    assertNullable('a; // 1');
+    assertNonNullable();
+  }
+
+  test_binaryExpression_logicalAnd() async {
+    await trackCode(r'''
+void f(int x) {
+  x == null && x.isEven;
+}
+''');
+    assertNullable('x.isEven');
+    assertNonNullable();
+  }
+
+  test_binaryExpression_logicalOr() async {
+    await trackCode(r'''
+void f(int x) {
+  x == null || x.isEven;
+}
+''');
+    assertNullable();
+    assertNonNullable('x.isEven');
+  }
+
+  test_if_joinThenElse_ifNull() async {
+    await trackCode(r'''
+void f(int a, int b) {
+  if (a == null) {
+    a; // 1
+    if (b == null) return;
+    b; // 2
+  } else {
+    a; // 3
+    if (b == null) return;
+    b; // 4
+  }
+  a; // 5
+  b; // 6
+}
+''');
+    assertNullable('a; // 1');
+    assertNonNullable('b; // 2', 'a; // 3', 'b; // 4', 'b; // 6');
+  }
+
+  test_if_notNull_thenExit() async {
+    await trackCode(r'''
+void f(int x) {
+  if (x != null) return;
+  x; // 1
+}
+''');
+    assertNullable('x; // 1');
+    assertNonNullable();
+  }
+
+  test_if_null_thenExit() async {
+    await trackCode(r'''
+void f(int x) {
+  if (x == null) return;
+  x; // 1
+}
+''');
+    assertNullable();
+    assertNonNullable('x; // 1');
+  }
+
+  test_if_then_else() async {
+    await trackCode(r'''
+void f(int x) {
+  if (x == null) {
+    x; // 1
+  } else {
+    x; // 2
+  }
+}
+''');
+    assertNullable('x; // 1');
+    assertNonNullable('x; // 2');
+  }
+
+  test_potentiallyMutatedInClosure() async {
+    await trackCode(r'''
+f(int a, int b) {
+  localFunction() {
+    a = b;
+  }
+
+  if (a == null) {
+    a; // 1
+    localFunction();
+    a; // 2
+  }
+}
+''');
+    assertNullable();
+    assertNonNullable();
+  }
+
+  test_tryFinally_eqNullExit_body() async {
+    await trackCode(r'''
+void f(int x) {
+  try {
+    if (x == null) return;
+    x; // 1
+  } finally {
+    x; // 2
+  }
+  x; // 3
+}
+''');
+    assertNullable();
+    assertNonNullable('x; // 1', 'x; // 3');
+  }
+
+  test_tryFinally_eqNullExit_finally() async {
+    await trackCode(r'''
+void f(int x) {
+  try {
+    x; // 1
+  } finally {
+    if (x == null) return;
+    x; // 2
+  }
+  x; // 3
+}
+''');
+    assertNullable();
+    assertNonNullable('x; // 2', 'x; // 3');
+  }
+
+  test_tryFinally_outerEqNotNullExit_assignUnknown_body() async {
+    await trackCode(r'''
+void f(int a, int b) {
+  if (a != null) return;
+  try {
+    a; // 1
+    a = b;
+    a; // 2
+  } finally {
+    a; // 3
+  }
+  a; // 4
+}
+''');
+    assertNullable('a; // 1');
+    assertNonNullable();
+  }
+
+  test_tryFinally_outerEqNullExit_assignUnknown_body() async {
+    await trackCode(r'''
+void f(int a, int b) {
+  if (a == null) return;
+  try {
+    a; // 1
+    a = b;
+    a; // 2
+  } finally {
+    a; // 3
+  }
+  a; // 4
+}
+''');
+    assertNullable();
+    assertNonNullable('a; // 1');
+  }
+
+  test_tryFinally_outerEqNullExit_assignUnknown_finally() async {
+    await trackCode(r'''
+void f(int a, int b) {
+  if (a == null) return;
+  try {
+    a; // 1
+  } finally {
+    a; // 2
+    a = b;
+    a; // 3
+  }
+  a; // 4
+}
+''');
+    assertNullable();
+    assertNonNullable('a; // 1', 'a; // 2');
+  }
+
+  test_while_eqNull() async {
+    await trackCode(r'''
+void f(int x) {
+  while (x == null) {
+    x; // 1
+  }
+  x; // 2
+}
+''');
+    assertNullable('x; // 1');
+    assertNonNullable('x; // 2');
+  }
+
+  test_while_notEqNull() async {
+    await trackCode(r'''
+void f(int x) {
+  while (x != null) {
+    x; // 1
+  }
+  x; // 2
+}
+''');
+    assertNullable('x; // 2');
+    assertNonNullable('x; // 1');
+  }
+
+  /// Resolve the given [code] and track nullability in the unit.
+  Future<void> trackCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+
+    var unit = result.unit;
+
+    var loopAssignedVariables = AssignedVariables();
+    unit.accept(_AssignedVariablesVisitor(loopAssignedVariables));
+
+    var typeSystem = unit.declaredElement.context.typeSystem;
+    unit.accept(_AstVisitor(
+      typeSystem,
+      loopAssignedVariables,
+      {},
+      [],
+      nullableNodes,
+      nonNullableNodes,
+      [],
+      [],
+    ));
+  }
+}
+
+@reflectiveTest
+class ReachableFlowTest extends DriverResolutionTest {
+  final List<AstNode> unreachableNodes = [];
+  final List<FunctionBody> functionBodiesThatDontComplete = [];
+
+  test_conditional_false() async {
+    await trackCode(r'''
+void f() {
+  false ? 1 : 2;
+}
+''');
+    verify(unreachableExpressions: ['1']);
+  }
+
+  test_conditional_true() async {
+    await trackCode(r'''
+void f() {
+  true ? 1 : 2;
+}
+''');
+    verify(unreachableExpressions: ['2']);
+  }
+
+  test_do_false() async {
+    await trackCode(r'''
+void f() {
+  do (true) {
+    1;
+  } while (false);
+  2;
+}
+''');
+    verify();
+  }
+
+  test_do_true() async {
+    await trackCode(r'''
+void f() { // f
+  do (true) {
+    1;
+  } while (true);
+  2;
+}
+''');
+    verify(
+      unreachableStatements: ['2;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_exit_beforeSplitStatement() async {
+    await trackCode(r'''
+void f(bool b, int i) { // f
+  return;
+  do {} while (b);
+  for (;;) {}
+  for (_ in []) {}
+  if (b) {}
+  switch (i) {}
+  try {} finally {}
+  while (b) {}
+}
+''');
+    verify(
+      unreachableStatements: [
+        'do {}',
+        'for (;;',
+        'for (_',
+        'if (b)',
+        'try {',
+        'switch (i)',
+        'while (b) {}'
+      ],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_for_condition_true() async {
+    await trackCode(r'''
+void f() { // f
+  for (; true;) {
+    1;
+  }
+  2;
+}
+''');
+    verify(
+      unreachableStatements: ['2;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_for_condition_true_implicit() async {
+    await trackCode(r'''
+void f() { // f
+  for (;;) {
+    1;
+  }
+  2;
+}
+''');
+    verify(
+      unreachableStatements: ['2;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_forEach() async {
+    await trackCode(r'''
+void f() {
+  for (_ in [0, 1, 2]) {
+    1;
+    return;
+  }
+  2;
+}
+''');
+    verify();
+  }
+
+  test_functionBody_hasReturn() async {
+    await trackCode(r'''
+int f() { // f
+  return 42;
+}
+''');
+    verify(functionBodiesThatDontComplete: ['{ // f']);
+  }
+
+  test_functionBody_noReturn() async {
+    await trackCode(r'''
+void f() {
+  1;
+}
+''');
+    verify();
+  }
+
+  test_if_condition() async {
+    await trackCode(r'''
+void f(bool b) {
+  if (b) {
+    1;
+  } else {
+    2;
+  }
+  3;
+}
+''');
+    verify();
+  }
+
+  test_if_false_then_else() async {
+    await trackCode(r'''
+void f() {
+  if (false) { // 1
+    1;
+  } else { // 2
+  }
+  3;
+}
+''');
+    verify(unreachableStatements: ['{ // 1']);
+  }
+
+  test_if_true_return() async {
+    await trackCode(r'''
+void f() { // f
+  1;
+  if (true) {
+    return;
+  }
+  2;
+}
+''');
+    verify(
+      unreachableStatements: ['2;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_if_true_then_else() async {
+    await trackCode(r'''
+void f() {
+  if (true) { // 1
+  } else { // 2
+    2;
+  }
+  3;
+}
+''');
+    verify(unreachableStatements: ['{ // 2']);
+  }
+
+  test_logicalAnd_leftFalse() async {
+    await trackCode(r'''
+void f(int x) {
+  false && (x == 1);
+}
+''');
+    verify(unreachableExpressions: ['(x == 1)']);
+  }
+
+  test_logicalOr_leftTrue() async {
+    await trackCode(r'''
+void f(int x) {
+  true || (x == 1);
+}
+''');
+    verify(unreachableExpressions: ['(x == 1)']);
+  }
+
+  test_switch_case_neverCompletes() async {
+    await trackCode(r'''
+void f(bool b, int i) {
+  switch (i) {
+    case 1:
+      1;
+      if (b) {
+        return;
+      } else {
+        return;
+      }
+      2;
+  }
+  3;
+}
+''');
+    verify(unreachableStatements: ['2;']);
+  }
+
+  test_tryCatch() async {
+    await trackCode(r'''
+void f() {
+  try {
+    1;
+  } catch (_) {
+    2;
+  }
+  3;
+}
+''');
+    verify();
+  }
+
+  test_tryCatch_return_body() async {
+    await trackCode(r'''
+void f() {
+  try {
+    1;
+    return;
+    2;
+  } catch (_) {
+    3;
+  }
+  4;
+}
+''');
+    verify(unreachableStatements: ['2;']);
+  }
+
+  test_tryCatch_return_catch() async {
+    await trackCode(r'''
+void f() {
+  try {
+    1;
+  } catch (_) {
+    2;
+    return;
+    3;
+  }
+  4;
+}
+''');
+    verify(unreachableStatements: ['3;']);
+  }
+
+  test_tryCatchFinally_return_body() async {
+    await trackCode(r'''
+void f() {
+  try {
+    1;
+    return;
+  } catch (_) {
+    2;
+  } finally {
+    3;
+  }
+  4;
+}
+''');
+    verify();
+  }
+
+  test_tryCatchFinally_return_bodyCatch() async {
+    await trackCode(r'''
+void f() { // f
+  try {
+    1;
+    return;
+  } catch (_) {
+    2;
+    return;
+  } finally {
+    3;
+  }
+  4;
+}
+''');
+    verify(
+      unreachableStatements: ['4;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_tryCatchFinally_return_catch() async {
+    await trackCode(r'''
+void f() {
+  try {
+    1;
+  } catch (_) {
+    2;
+    return;
+  } finally {
+    3;
+  }
+  4;
+}
+''');
+    verify();
+  }
+
+  test_tryFinally_return_body() async {
+    await trackCode(r'''
+void f() { // f
+  try {
+    1;
+    return;
+  } finally {
+    2;
+  }
+  3;
+}
+''');
+    verify(
+      unreachableStatements: ['3;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_while_false() async {
+    await trackCode(r'''
+void f() {
+  while (false) { // 1
+    1;
+  }
+  2;
+}
+''');
+    verify(unreachableStatements: ['{ // 1']);
+  }
+
+  test_while_true() async {
+    await trackCode(r'''
+void f() { // f
+  while (true) {
+    1;
+  }
+  2;
+  3;
+}
+''');
+    verify(
+      unreachableStatements: ['2;', '3;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  test_while_true_break() async {
+    await trackCode(r'''
+void f() {
+  while (true) {
+    1;
+    break;
+    2;
+  }
+  3;
+}
+''');
+    verify(unreachableStatements: ['2;']);
+  }
+
+  test_while_true_breakIf() async {
+    await trackCode(r'''
+void f(bool b) {
+  while (true) {
+    1;
+    if (b) break;
+    2;
+  }
+  3;
+}
+''');
+    verify();
+  }
+
+  test_while_true_continue() async {
+    await trackCode(r'''
+void f() { // f
+  while (true) {
+    1;
+    continue;
+    2;
+  }
+  3;
+}
+''');
+    verify(
+      unreachableStatements: ['2;', '3;'],
+      functionBodiesThatDontComplete: ['{ // f'],
+    );
+  }
+
+  /// Resolve the given [code] and track unreachable nodes in the unit.
+  Future<void> trackCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+
+    var unit = result.unit;
+
+    var loopAssignedVariables = AssignedVariables();
+    unit.accept(_AssignedVariablesVisitor(loopAssignedVariables));
+
+    var typeSystem = unit.declaredElement.context.typeSystem;
+    unit.accept(_AstVisitor(
+      typeSystem,
+      loopAssignedVariables,
+      {},
+      [],
+      [],
+      [],
+      unreachableNodes,
+      functionBodiesThatDontComplete,
+    ));
+  }
+
+  void verify({
+    List<String> unreachableExpressions = const [],
+    List<String> unreachableStatements = const [],
+    List<String> functionBodiesThatDontComplete = const [],
+  }) {
+    var expectedUnreachableNodes = <AstNode>[];
+    expectedUnreachableNodes.addAll(
+      unreachableStatements.map((search) => findNode.statement(search)),
+    );
+    expectedUnreachableNodes.addAll(
+      unreachableExpressions.map((search) => findNode.expression(search)),
+    );
+
+    expect(
+      this.unreachableNodes,
+      unorderedEquals(expectedUnreachableNodes),
+    );
+    expect(
+      this.functionBodiesThatDontComplete,
+      unorderedEquals(
+        functionBodiesThatDontComplete
+            .map((search) => findNode.functionBody(search))
+            .toList(),
+      ),
+    );
+  }
+}
+
+@reflectiveTest
+class TypePromotionFlowTest extends DriverResolutionTest {
+  final Map<AstNode, DartType> promotedTypes = {};
+
+  void assertNotPromoted(String search) {
+    var node = findNode.simple(search);
+    var actualType = promotedTypes[node];
+    expect(actualType, isNull, reason: search);
+  }
+
+  void assertPromoted(String search, String expectedType) {
+    var node = findNode.simple(search);
+    var actualType = promotedTypes[node];
+    if (actualType == null) {
+      fail('$expectedType expected, but actually not promoted\n$search');
+    }
+    assertElementTypeString(actualType, expectedType);
+  }
+
+  test_assignment() async {
+    await trackCode(r'''
+f(Object x) {
+  if (x is String) {
+    x = 42;
+    x; // 1
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_binaryExpression_ifNull() async {
+    await trackCode(r'''
+void f(Object x) {
+  ((x is num) || (throw 1)) ?? ((x is int) || (throw 2));
+  x; // 1
+}
+''');
+    assertPromoted('x; // 1', 'num');
+  }
+
+  test_binaryExpression_ifNull_rightUnPromote() async {
+    await trackCode(r'''
+void f(Object x, Object y, Object z) {
+  if (x is int) {
+    x; // 1
+    y ?? (x = z);
+    x; // 2
+  }
+}
+''');
+    assertPromoted('x; // 1', 'int');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_conditional_both() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  b ? ((x is num) || (throw 1)) : ((x is int) || (throw 2));
+  x; // 1
+}
+''');
+    assertPromoted('x; // 1', 'num');
+  }
+
+  test_conditional_else() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  b ? 0 : ((x is int) || (throw 2));
+  x; // 1
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_conditional_then() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  b ? ((x is num) || (throw 1)) : 0;
+  x; // 1
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_do_condition_isNotType() async {
+    await trackCode(r'''
+void f(Object x) {
+  do {
+    x; // 1
+    x = '';
+  } while (x is! String)
+  x; // 2
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertPromoted('x; // 2', 'String');
+  }
+
+  test_do_condition_isType() async {
+    await trackCode(r'''
+void f(Object x) {
+  do {
+    x; // 1
+  } while (x is String)
+  x; // 2
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_do_outerIsType() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x; // 1
+    } while (b);
+    x; // 2
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+  }
+
+  test_do_outerIsType_loopAssigned_body() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x; // 1
+      x = x.length;
+    } while (b);
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_do_outerIsType_loopAssigned_condition() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x; // 1
+      x = x.length;
+    } while (x != 0);
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x != 0');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_do_outerIsType_loopAssigned_condition2() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    do {
+      x; // 1
+    } while ((x = 1) != 0);
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_for_outerIsType() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b;) {
+      x; // 1
+    }
+    x; // 2
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+  }
+
+  test_for_outerIsType_loopAssigned_body() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b;) {
+      x; // 1
+      x = 42;
+    }
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_for_outerIsType_loopAssigned_condition() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    for (; (x = 42) > 0;) {
+      x; // 1
+    }
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_for_outerIsType_loopAssigned_updaters() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    for (; b; x = 42) {
+      x; // 1
+    }
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_forEach_outerIsType_loopAssigned() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    for (var _ in (v1 = [0, 1, 2])) {
+      x; // 1
+      x = 42;
+    }
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_functionExpression_isType() async {
+    await trackCode(r'''
+void f() {
+  void g(Object x) {
+    if (x is String) {
+      x; // 1
+    }
+    x = 42;
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+  }
+
+  test_functionExpression_isType_mutatedInClosure2() async {
+    await trackCode(r'''
+void f() {
+  void g(Object x) {
+    if (x is String) {
+      x; // 1
+    }
+    
+    void h() {
+      x = 42;
+    }
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_functionExpression_outerIsType_assignedOutside() async {
+    await trackCode(r'''
+void f(Object x) {
+  void Function() g;
+  
+  if (x is String) {
+    x; // 1
+
+    g = () {
+      x; // 2
+    }
+  }
+
+  x = 42;
+  x; // 3
+  g();
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+    assertNotPromoted('x; // 3');
+  }
+
+  test_if_combine_empty() async {
+    await trackCode(r'''
+main(bool b, Object v) {
+  if (b) {
+    v is int || (throw 1);
+  } else {
+    v is String || (throw 2);
+  }
+  v; // 3
+}
+''');
+    assertNotPromoted('v; // 3');
+  }
+
+  test_if_conditional_isNotType() async {
+    await trackCode(r'''
+f(bool b, Object v) {
+  if (b ? (v is! int) : (v is! num)) {
+    v; // 1
+  } else {
+    v; // 2
+  }
+  v; // 3
+}
+''');
+    assertNotPromoted('v; // 1');
+    assertPromoted('v; // 2', 'num');
+    assertNotPromoted('v; // 3');
+  }
+
+  test_if_conditional_isType() async {
+    await trackCode(r'''
+f(bool b, Object v) {
+  if (b ? (v is int) : (v is num)) {
+    v; // 1
+  } else {
+    v; // 2
+  }
+  v; // 3
+}
+''');
+    assertPromoted('v; // 1', 'num');
+    assertNotPromoted('v; // 2');
+    assertNotPromoted('v; // 3');
+  }
+
+  test_if_isNotType() async {
+    await trackCode(r'''
+main(v) {
+  if (v is! String) {
+    v; // 1
+  } else {
+    v; // 2
+  }
+  v; // 3
+}
+''');
+    assertNotPromoted('v; // 1');
+    assertPromoted('v; // 2', 'String');
+    assertNotPromoted('v; // 3');
+  }
+
+  test_if_isNotType_return() async {
+    await trackCode(r'''
+main(v) {
+  if (v is! String) return;
+  v; // ref
+}
+''');
+    assertPromoted('v; // ref', 'String');
+  }
+
+  test_if_isNotType_throw() async {
+    await trackCode(r'''
+main(v) {
+  if (v is! String) throw 42;
+  v; // ref
+}
+''');
+    assertPromoted('v; // ref', 'String');
+  }
+
+  test_if_isType() async {
+    await trackCode(r'''
+main(v) {
+  if (v is String) {
+    v; // 1
+  } else {
+    v; // 2
+  }
+  v; // 3
+}
+''');
+    assertPromoted('v; // 1', 'String');
+    assertNotPromoted('v; // 2');
+    assertNotPromoted('v; // 3');
+  }
+
+  test_if_isType_thenNonBoolean() async {
+    await trackCode(r'''
+f(Object x) {
+  if ((x is String) != 3) {
+    x; // 1
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_if_logicalNot_isType() async {
+    await trackCode(r'''
+main(v) {
+  if (!(v is String)) {
+    v; // 1
+  } else {
+    v; // 2
+  }
+  v; // 3
+}
+''');
+    assertNotPromoted('v; // 1');
+    assertPromoted('v; // 2', 'String');
+    assertNotPromoted('v; // 3');
+  }
+
+  test_if_then_isNotType_return() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (b) {
+    if (x is! String) return;
+  }
+  x; // 1
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_logicalOr_throw() async {
+    await trackCode(r'''
+main(v) {
+  v is String || (throw 42);
+  v; // ref
+}
+''');
+    assertPromoted('v; // ref', 'String');
+  }
+
+  test_potentiallyMutatedInClosure() async {
+    await trackCode(r'''
+f(Object x) {
+  localFunction() {
+    x = 42;
+  }
+
+  if (x is String) {
+    localFunction();
+    x; // 1
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+  }
+
+  test_potentiallyMutatedInScope() async {
+    await trackCode(r'''
+f(Object x) {
+  if (x is String) {
+    x; // 1
+  }
+
+  x = 42;
+}
+''');
+    assertPromoted('x; // 1', 'String');
+  }
+
+  test_switch_outerIsType_assignedInCase() async {
+    await trackCode(r'''
+void f(int e, Object x) {
+  if (x is String) {
+    switch (e) {
+      L: case 1:
+        x; // 1
+        break;
+      case 2: // no label
+        x; // 2
+        break;
+      case 3:
+        x = 42;
+        continue L;
+    }
+    x; // 3
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertPromoted('x; // 2', 'String');
+    assertNotPromoted('x; // 3');
+  }
+
+  test_tryCatch_assigned_body() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is! String) return;
+  x; // 1
+  try {
+    x = 42;
+    g(); // might throw
+    if (x is! String) return;
+    x; // 2
+  } catch (_) {}
+  x; // 3
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+    assertNotPromoted('x; // 3');
+  }
+
+  test_tryCatch_isNotType_exit_body() async {
+    await trackCode(r'''
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    x; // 1
+  } catch (_) {}
+  x; // 2
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_tryCatch_isNotType_exit_body_catch() async {
+    await trackCode(r'''
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    x; // 1
+  } catch (_) {
+    if (x is! String) return;
+    x; // 2
+  }
+  x; // 3
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+    assertPromoted('x; // 3', 'String');
+  }
+
+  test_tryCatch_isNotType_exit_body_catchRethrow() async {
+    await trackCode(r'''
+void f(Object x) {
+  try {
+    if (x is! String) return;
+    x; // 1
+  } catch (_) {
+    x; // 2
+    rethrow;
+  }
+  x; // 3
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+    assertPromoted('x; // 3', 'String');
+  }
+
+  test_tryCatch_isNotType_exit_catch() async {
+    await trackCode(r'''
+void f(Object x) {
+  try {
+  } catch (_) {
+    if (x is! String) return;
+    x; // 1
+  }
+  x; // 2
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_tryCatchFinally_outerIsType() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      x; // 1
+    } catch (_) {
+      x; // 2
+    } finally {
+      x; // 3
+    }
+    x; // 4
+  }
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+    assertPromoted('x; // 3', 'String');
+    assertPromoted('x; // 4', 'String');
+  }
+
+  test_tryCatchFinally_outerIsType_assigned_body() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      x; // 1
+      x = 42;
+      g();
+    } catch (_) {
+      x; // 2
+    } finally {
+      x; // 3
+    }
+    x; // 4
+  }
+}
+
+void g() {}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+    assertNotPromoted('x; // 3');
+    assertNotPromoted('x; // 4');
+  }
+
+  test_tryCatchFinally_outerIsType_assigned_catch() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      x; // 1
+    } catch (_) {
+      x; // 2
+      x = 42;
+    } finally {
+      x; // 3
+    }
+    x; // 4
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+    assertNotPromoted('x; // 3');
+    assertNotPromoted('x; // 4');
+  }
+
+  test_tryFinally_outerIsType_assigned_body() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      x; // 1
+      x = 42;
+    } finally {
+      x; // 2
+    }
+    x; // 3
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+    assertNotPromoted('x; // 3');
+  }
+
+  test_tryFinally_outerIsType_assigned_finally() async {
+    await trackCode(r'''
+void f(Object x) {
+  if (x is String) {
+    try {
+      x; // 1
+    } finally {
+      x; // 2
+      x = 42;
+    }
+    x; // 3
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+    assertNotPromoted('x; // 3');
+  }
+
+  test_while_condition_false() async {
+    await trackCode(r'''
+void f(Object x) {
+  while (x is! String) {
+    x; // 1
+  }
+  x; // 2
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertPromoted('x; // 2', 'String');
+  }
+
+  test_while_condition_true() async {
+    await trackCode(r'''
+void f(Object x) {
+  while (x is String) {
+    x; // 1
+  }
+  x; // 2
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_while_outerIsType() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    while (b) {
+      x; // 1
+    }
+    x; // 2
+  }
+}
+''');
+    assertPromoted('x; // 1', 'String');
+    assertPromoted('x; // 2', 'String');
+  }
+
+  test_while_outerIsType_loopAssigned_body() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    while (b) {
+      x; // 1
+      x = x.length;
+    }
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  test_while_outerIsType_loopAssigned_condition() async {
+    await trackCode(r'''
+void f(bool b, Object x) {
+  if (x is String) {
+    while (x != 0) {
+      x; // 1
+      x = x.length;
+    }
+    x; // 2
+  }
+}
+''');
+    assertNotPromoted('x != 0');
+    assertNotPromoted('x; // 1');
+    assertNotPromoted('x; // 2');
+  }
+
+  /// Resolve the given [code] and track assignments in the unit.
+  Future<void> trackCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+
+    var unit = result.unit;
+
+    var loopAssignedVariables = AssignedVariables();
+    unit.accept(_AssignedVariablesVisitor(loopAssignedVariables));
+
+    var typeSystem = unit.declaredElement.context.typeSystem;
+    unit.accept(_AstVisitor(
+      typeSystem,
+      loopAssignedVariables,
+      promotedTypes,
+      [],
+      [],
+      [],
+      [],
+      [],
+    ));
+  }
+}
+
+class _AssignedVariablesVisitor extends RecursiveAstVisitor<void> {
+  final AssignedVariables assignedVariables;
+
+  _AssignedVariablesVisitor(this.assignedVariables);
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var left = node.leftHandSide;
+
+    super.visitAssignmentExpression(node);
+
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is VariableElement) {
+        assignedVariables.write(element);
+      }
+    }
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    assignedVariables.beginLoop();
+    super.visitDoStatement(node);
+    assignedVariables.endLoop(node);
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    var iterable = node.iterable;
+    var body = node.body;
+
+    iterable.accept(this);
+
+    assignedVariables.beginLoop();
+    body.accept(this);
+    assignedVariables.endLoop(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    node.initialization?.accept(this);
+    node.variables?.accept(this);
+
+    assignedVariables.beginLoop();
+    node.condition?.accept(this);
+    node.body.accept(this);
+    node.updaters?.accept(this);
+    assignedVariables.endLoop(node);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    var expression = node.expression;
+    var members = node.members;
+
+    expression.accept(this);
+
+    assignedVariables.beginLoop();
+    members.accept(this);
+    assignedVariables.endLoop(node);
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    assignedVariables.beginLoop();
+    node.body.accept(this);
+    assignedVariables.endLoop(node.body);
+
+    node.catchClauses.accept(this);
+
+    var finallyBlock = node.finallyBlock;
+    if (finallyBlock != null) {
+      assignedVariables.beginLoop();
+      finallyBlock.accept(this);
+      assignedVariables.endLoop(finallyBlock);
+    }
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    assignedVariables.beginLoop();
+    super.visitWhileStatement(node);
+    assignedVariables.endLoop(node);
+  }
+}
+
+/// [AstVisitor] that drives the [flow] in the way we expect the resolver
+/// will do in production.
+class _AstVisitor extends GeneralizingAstVisitor<void> {
+  static final trueLiteral = astFactory.booleanLiteral(null, true);
+
+  final TypeOperations<DartType> typeOperations;
+  final AssignedVariables assignedVariables;
+  final Map<AstNode, DartType> promotedTypes;
+  final List<LocalVariableElement> readBeforeWritten;
+  final List<AstNode> nullableNodes;
+  final List<AstNode> nonNullableNodes;
+  final List<AstNode> unreachableNodes;
+  final List<FunctionBody> functionBodiesThatDontComplete;
+
+  FlowAnalysis<DartType> flow;
+
+  _AstVisitor(
+      TypeSystem typeSystem,
+      this.assignedVariables,
+      this.promotedTypes,
+      this.readBeforeWritten,
+      this.nullableNodes,
+      this.nonNullableNodes,
+      this.unreachableNodes,
+      this.functionBodiesThatDontComplete)
+      : typeOperations = _TypeSystemTypeOperations(typeSystem);
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var left = node.leftHandSide;
+    var right = node.rightHandSide;
+
+    VariableElement localElement;
+    if (left is SimpleIdentifier) {
+      var element = left.staticElement;
+      if (element is VariableElement) {
+        localElement = element;
+      }
+    }
+
+    if (localElement != null) {
+      var isPure = node.operator.type == TokenType.EQ;
+      if (!isPure) {
+        flow.read(localElement);
+      }
+      right.accept(this);
+      flow.write(
+        localElement,
+        isNull: _isNull(right),
+        isNonNull: _isNonNull(right),
+      );
+    } else {
+      left.accept(this);
+      right.accept(this);
+    }
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    var left = node.leftOperand;
+    var right = node.rightOperand;
+
+    var operator = node.operator.type;
+
+    if (operator == TokenType.AMPERSAND_AMPERSAND) {
+      left.accept(this);
+
+      flow.logicalAnd_rightBegin(node);
+      _checkUnreachableNode(node.rightOperand);
+      right.accept(this);
+
+      flow.logicalAnd_end(node);
+    } else if (operator == TokenType.BAR_BAR) {
+      left.accept(this);
+
+      flow.logicalOr_rightBegin(node);
+      _checkUnreachableNode(node.rightOperand);
+      right.accept(this);
+
+      flow.logicalOr_end(node);
+    } else if (operator == TokenType.BANG_EQ) {
+      left.accept(this);
+      right.accept(this);
+      if (right is NullLiteral) {
+        if (left is SimpleIdentifier) {
+          var element = left.staticElement;
+          if (element is VariableElement) {
+            flow.conditionNotEqNull(node, element);
+          }
+        }
+      }
+    } else if (operator == TokenType.EQ_EQ) {
+      left.accept(this);
+      right.accept(this);
+      if (right is NullLiteral) {
+        if (left is SimpleIdentifier) {
+          var element = left.staticElement;
+          if (element is VariableElement) {
+            flow.conditionEqNull(node, element);
+          }
+        }
+      }
+    } else if (operator == TokenType.QUESTION_QUESTION) {
+      left.accept(this);
+
+      flow.ifNullExpression_rightBegin();
+      right.accept(this);
+
+      flow.ifNullExpression_end();
+    } else {
+      left.accept(this);
+      right.accept(this);
+    }
+  }
+
+  @override
+  void visitBlockFunctionBody(BlockFunctionBody node) {
+    var isFlowOwner = flow == null;
+
+    if (isFlowOwner) {
+      flow = FlowAnalysis<DartType>(typeOperations, node);
+
+      var function = node.parent;
+      if (function is FunctionExpression) {
+        var parameters = function.parameters;
+        if (parameters != null) {
+          for (var parameter in parameters?.parameters) {
+            flow.add(parameter.declaredElement, assigned: true);
+          }
+        }
+      }
+    }
+
+    super.visitBlockFunctionBody(node);
+
+    if (isFlowOwner) {
+      readBeforeWritten.addAll(flow.readBeforeWritten);
+
+      if (!flow.isReachable) {
+        functionBodiesThatDontComplete.add(node);
+      }
+
+      flow.verifyStackEmpty();
+      flow = null;
+    }
+  }
+
+  @override
+  void visitBooleanLiteral(BooleanLiteral node) {
+    super.visitBooleanLiteral(node);
+    if (_isFalseLiteral(node)) {
+      flow.falseLiteral(node);
+    }
+    if (_isTrueLiteral(node)) {
+      flow.trueLiteral(node);
+    }
+  }
+
+  @override
+  void visitBreakStatement(BreakStatement node) {
+    super.visitBreakStatement(node);
+    var target = _getLabelTarget(node, node.label?.staticElement);
+    flow.handleBreak(target);
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    var condition = node.condition;
+    var thenExpression = node.thenExpression;
+    var elseExpression = node.elseExpression;
+
+    condition.accept(this);
+
+    flow.conditional_thenBegin(node);
+    _checkUnreachableNode(node.thenExpression);
+    thenExpression.accept(this);
+    var isBool = thenExpression.staticType.isDartCoreBool;
+
+    flow.conditional_elseBegin(node, isBool);
+    _checkUnreachableNode(node.elseExpression);
+    elseExpression.accept(this);
+
+    flow.conditional_end(node, isBool);
+  }
+
+  @override
+  void visitContinueStatement(ContinueStatement node) {
+    super.visitContinueStatement(node);
+    var target = _getLabelTarget(node, node.label?.staticElement);
+    flow.handleContinue(target);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    _checkUnreachableNode(node);
+
+    var body = node.body;
+    var condition = node.condition;
+
+    flow.doStatement_bodyBegin(node, assignedVariables[node]);
+    body.accept(this);
+
+    flow.doStatement_conditionBegin();
+    condition.accept(this);
+
+    flow.doStatement_end(node);
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    _checkUnreachableNode(node);
+
+    var iterable = node.iterable;
+    var body = node.body;
+
+    iterable.accept(this);
+    flow.forEachStatement_bodyBegin(assignedVariables[node]);
+
+    body.accept(this);
+
+    flow.forEachStatement_end();
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    _checkUnreachableNode(node);
+
+    var condition = node.condition;
+
+    node.initialization?.accept(this);
+    node.variables?.accept(this);
+
+    flow.forStatement_conditionBegin(assignedVariables[node]);
+    if (condition != null) {
+      condition.accept(this);
+    } else {
+      flow.trueLiteral(trueLiteral);
+    }
+
+    flow.forStatement_bodyBegin(node, condition ?? trueLiteral);
+    node.body.accept(this);
+
+    flow.forStatement_updaterBegin();
+    node.updaters?.accept(this);
+
+    flow.forStatement_end();
+  }
+
+  @override
+  void visitForStatement2(ForStatement2 node) {
+    ForLoopParts parts = node.forLoopParts;
+    if (parts is ForEachParts) {
+      parts.iterable?.accept(this);
+
+      flow.forEachStatement_bodyBegin(assignedVariables[node]);
+
+      node.body.accept(this);
+
+      flow.forEachStatement_end();
+      return;
+    }
+    VariableDeclarationList variables;
+    Expression initialization;
+    Expression condition;
+    NodeList<Expression> updaters;
+    if (parts is ForPartsWithDeclarations) {
+      variables = parts.variables;
+      condition = parts.condition;
+      updaters = parts.updaters;
+    } else if (parts is ForPartsWithExpression) {
+      initialization = parts.initialization;
+      condition = parts.condition;
+      updaters = parts.updaters;
+    }
+    initialization?.accept(this);
+    variables?.accept(this);
+
+    flow.forStatement_conditionBegin(assignedVariables[node]);
+    if (condition != null) {
+      condition.accept(this);
+    } else {
+      flow.trueLiteral(trueLiteral);
+    }
+
+    flow.forStatement_bodyBegin(node, condition ?? trueLiteral);
+    node.body.accept(this);
+
+    flow.forStatement_updaterBegin();
+    updaters?.accept(this);
+
+    flow.forStatement_end();
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    flow?.functionExpression_begin();
+    super.visitFunctionExpression(node);
+    flow?.functionExpression_end();
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    _checkUnreachableNode(node);
+
+    var condition = node.condition;
+    var thenStatement = node.thenStatement;
+    var elseStatement = node.elseStatement;
+
+    condition.accept(this);
+
+    flow.ifStatement_thenBegin(node);
+    thenStatement.accept(this);
+
+    if (elseStatement != null) {
+      flow.ifStatement_elseBegin();
+      elseStatement.accept(this);
+    }
+
+    flow.ifStatement_end(elseStatement != null);
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    super.visitIsExpression(node);
+    var expression = node.expression;
+    var typeAnnotation = node.type;
+
+    if (expression is SimpleIdentifier) {
+      var element = expression.staticElement;
+      if (element is VariableElement) {
+        flow.isExpression_end(node, element, typeAnnotation.type);
+      }
+    }
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    var operand = node.operand;
+
+    var operator = node.operator.type;
+    if (operator == TokenType.BANG) {
+      operand.accept(this);
+      flow.logicalNot_end(node);
+    } else {
+      operand.accept(this);
+    }
+  }
+
+  @override
+  void visitRethrowExpression(RethrowExpression node) {
+    super.visitRethrowExpression(node);
+    flow.handleExit();
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    super.visitReturnStatement(node);
+    flow.handleExit();
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    var element = node.staticElement;
+    var isLocalVariable = element is LocalVariableElement;
+    if (isLocalVariable || element is ParameterElement) {
+      if (node.inGetterContext() && !node.inDeclarationContext()) {
+        if (isLocalVariable) {
+          flow.read(element);
+        }
+
+        if (flow.isNullable(element)) {
+          nullableNodes?.add(node);
+        }
+
+        if (flow.isNonNullable(element)) {
+          nonNullableNodes?.add(node);
+        }
+
+        var promotedType = flow?.promotedType(element);
+        if (promotedType != null) {
+          promotedTypes[node] = promotedType;
+        }
+      }
+    }
+
+    super.visitSimpleIdentifier(node);
+  }
+
+  @override
+  void visitStatement(Statement node) {
+    _checkUnreachableNode(node);
+    super.visitStatement(node);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    _checkUnreachableNode(node);
+
+    node.expression.accept(this);
+    flow.switchStatement_expressionEnd(node);
+
+    var assignedInCases = assignedVariables[node];
+
+    var members = node.members;
+    var membersLength = members.length;
+    var hasDefault = false;
+    for (var i = 0; i < membersLength; i++) {
+      var member = members[i];
+
+      flow.switchStatement_beginCase(
+        member.labels.isNotEmpty ? assignedInCases : AssignedVariables.emptySet,
+      );
+      member.accept(this);
+
+      // Implicit `break` at the end of `default`.
+      if (member is SwitchDefault) {
+        hasDefault = true;
+        flow.handleBreak(node);
+      }
+    }
+
+    flow.switchStatement_end(node, hasDefault);
+  }
+
+  @override
+  void visitThrowExpression(ThrowExpression node) {
+    super.visitThrowExpression(node);
+    flow.handleExit();
+  }
+
+  @override
+  void visitTryStatement(TryStatement node) {
+    _checkUnreachableNode(node);
+
+    var body = node.body;
+    var catchClauses = node.catchClauses;
+    var finallyBlock = node.finallyBlock;
+
+    if (finallyBlock != null) {
+      flow.tryFinallyStatement_bodyBegin();
+    }
+
+    flow.tryCatchStatement_bodyBegin();
+    body.accept(this);
+    flow.tryCatchStatement_bodyEnd(assignedVariables[body]);
+
+    var catchLength = catchClauses.length;
+    for (var i = 0; i < catchLength; ++i) {
+      var catchClause = catchClauses[i];
+      flow.tryCatchStatement_catchBegin();
+      catchClause.accept(this);
+      flow.tryCatchStatement_catchEnd();
+    }
+
+    flow.tryCatchStatement_end();
+
+    if (finallyBlock != null) {
+      flow.tryFinallyStatement_finallyBegin(assignedVariables[body]);
+      finallyBlock.accept(this);
+      flow.tryFinallyStatement_end(assignedVariables[finallyBlock]);
+    }
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    var variables = node.variables.variables;
+    for (var i = 0; i < variables.length; ++i) {
+      var variable = variables[i];
+      flow.add(variable.declaredElement,
+          assigned: variable.initializer != null);
+    }
+
+    super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    _checkUnreachableNode(node);
+
+    var condition = node.condition;
+    var body = node.body;
+
+    flow.whileStatement_conditionBegin(assignedVariables[node]);
+    condition.accept(this);
+
+    flow.whileStatement_bodyBegin(node);
+    body.accept(this);
+
+    flow.whileStatement_end();
+  }
+
+  /// Mark the [node] as unreachable if it is not covered by another node that
+  /// is already known to be unreachable.
+  void _checkUnreachableNode(AstNode node) {
+    if (flow.isReachable) return;
+
+    // Ignore the [node] if it is fully covered by the last unreachable.
+    if (unreachableNodes.isNotEmpty) {
+      var last = unreachableNodes.last;
+      if (node.offset >= last.offset && node.end <= last.end) return;
+    }
+
+    unreachableNodes.add(node);
+  }
+
+  /// This code has OK performance for tests, but think if there is something
+  /// better when using in production.
+  AstNode _getLabelTarget(AstNode node, LabelElement element) {
+    for (; node != null; node = node.parent) {
+      if (node is DoStatement ||
+          node is ForEachStatement ||
+          node is ForStatement ||
+          node is SwitchStatement ||
+          node is WhileStatement) {
+        if (element == null) {
+          return node;
+        }
+        var parent = node.parent;
+        if (parent is LabeledStatement) {
+          for (var nodeLabel in parent.labels) {
+            if (identical(nodeLabel.label.staticElement, element)) {
+              return node;
+            }
+          }
+        }
+      }
+      if (element != null && node is SwitchStatement) {
+        for (var member in node.members) {
+          for (var nodeLabel in member.labels) {
+            if (identical(nodeLabel.label.staticElement, element)) {
+              return node;
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  static bool _isFalseLiteral(AstNode node) {
+    return node is BooleanLiteral && !node.value;
+  }
+
+  static bool _isNonNull(Expression node) {
+    if (node is NullLiteral) return false;
+
+    return node is Literal;
+  }
+
+  static bool _isNull(Expression node) {
+    return node is NullLiteral;
+  }
+
+  static bool _isTrueLiteral(AstNode node) {
+    return node is BooleanLiteral && node.value;
+  }
+}
+
+class _TypeSystemTypeOperations implements TypeOperations<DartType> {
+  final TypeSystem typeSystem;
+
+  _TypeSystemTypeOperations(this.typeSystem);
+
+  @override
+  DartType elementType(VariableElement element) {
+    return element.type;
+  }
+
+  @override
+  bool isSubtypeOf(DartType leftType, DartType rightType) {
+    return typeSystem.isSubtypeOf(leftType, rightType);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
index 7ec1a40..e06e3a7 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
@@ -7,12 +7,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ForInDriverResolutionTest);
-    defineReflectiveTests(ForInTaskResolutionTest);
   });
 }
 
@@ -42,7 +40,3 @@
     assertTypeDynamic(pRef);
   }
 }
-
-@reflectiveTest
-class ForInTaskResolutionTest extends TaskResolutionTest
-    with ForInResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
index 2e64644..891c0f7 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
@@ -8,12 +8,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(GenericTypeAliasDriverResolutionTest);
-    defineReflectiveTests(GenericTypeAliasTaskResolutionTest);
   });
 }
 
@@ -151,7 +149,3 @@
     assertElementTypeString(u.bound, 'B');
   }
 }
-
-@reflectiveTest
-class GenericTypeAliasTaskResolutionTest extends TaskResolutionTest
-    with GenericTypeAliasResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
index b13db90..647c4c8 100644
--- a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
@@ -8,12 +8,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ImportPrefixDriverResolutionTest);
-    defineReflectiveTests(ImportPrefixTaskResolutionTest);
   });
 }
 
@@ -113,7 +111,3 @@
     assertTypeNull(pRef);
   }
 }
-
-@reflectiveTest
-class ImportPrefixTaskResolutionTest extends TaskResolutionTest
-    with ImportPrefixResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 302d84b..a4af48e 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -7,12 +7,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InstanceCreationDriverResolutionTest);
-    defineReflectiveTests(InstanceCreationTaskResolutionTest);
   });
 }
 
@@ -152,13 +150,3 @@
     );
   }
 }
-
-@reflectiveTest
-class InstanceCreationTaskResolutionTest extends TaskResolutionTest
-    with InstanceCreationResolutionMixin {
-  @FailingTest(reason: 'Does not report the error.')
-  test_error_newWithInvalidTypeParameters_implicitNew_inference_top() {
-    return super
-        .test_error_newWithInvalidTypeParameters_implicitNew_inference_top();
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
index ad4b765..4c0fd6a 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
@@ -6,12 +6,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InstanceMemberInferenceClassDriverResolutionTest);
-    defineReflectiveTests(InstanceMemberInferenceClassTaskResolutionTest);
   });
 }
 
@@ -290,7 +288,3 @@
     assertElementTypeString(foo.returnType, 'T');
   }
 }
-
-@reflectiveTest
-class InstanceMemberInferenceClassTaskResolutionTest extends TaskResolutionTest
-    with InstanceMemberInferenceClassMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
index 36db4b0..0ab92025 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
@@ -6,12 +6,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InstanceMemberInferenceMixinDriverResolutionTest);
-    defineReflectiveTests(InstanceMemberInferenceMixinTaskResolutionTest);
   });
 }
 
@@ -290,7 +288,3 @@
     assertElementTypeString(foo.returnType, 'T');
   }
 }
-
-@reflectiveTest
-class InstanceMemberInferenceMixinTaskResolutionTest extends TaskResolutionTest
-    with InstanceMemberInferenceMixinMixin {}
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 a10b0e1..2af994d 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -5,7 +5,6 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'driver_resolution.dart';
@@ -43,6 +42,30 @@
     assertSuperExpression(invocation.target);
   }
 
+  test_error_abstractSuperMemberReference_mixin_implements() async {
+    addTestFile(r'''
+class A {
+  void foo(int _) {}
+}
+
+mixin M implements A {
+  void bar() {
+    super.foo(0);
+  }
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+
+    var invocation = findNode.methodInvocation('foo(0)');
+    assertMethodInvocation(
+      invocation,
+      findElement.method('foo', of: 'A'),
+      '(int) → void',
+    );
+    assertSuperExpression(invocation.target);
+  }
+
   test_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
     addTestFile('''
 class A {
@@ -444,7 +467,7 @@
       CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
     ]);
 
-    var import = _importFinder('package:test/a.dart');
+    var import = findElement.importFind('package:test/a.dart');
 
     var invocation = findNode.methodInvocation('foo();');
     assertMethodInvocation(
@@ -468,7 +491,7 @@
       CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
     ]);
 
-    var import = _importFinder('dart:math');
+    var import = findElement.importFind('dart:math');
 
     var invocation = findNode.methodInvocation('loadLibrary()');
     assertMethodInvocation(
@@ -1052,7 +1075,7 @@
     await resolveTestFile();
     assertNoTestErrors();
 
-    var import = _importFinder('dart:math');
+    var import = findElement.importFind('dart:math');
 
     var invocation = findNode.methodInvocation('loadLibrary()');
     assertMethodInvocation(
@@ -1099,7 +1122,7 @@
     await resolveTestFile();
     assertNoTestErrors();
 
-    var import = _importFinder('package:test/a.dart');
+    var import = findElement.importFind('package:test/a.dart');
 
     var invocation = findNode.methodInvocation('foo(1, 2)');
     assertMethodInvocation(
@@ -1125,7 +1148,7 @@
     await resolveTestFile();
     assertNoTestErrors();
 
-    var import = _importFinder('package:test/a.dart');
+    var import = findElement.importFind('package:test/a.dart');
 
     var invocation = findNode.methodInvocation('foo(1, 2)');
     assertMethodInvocation(
@@ -1304,7 +1327,7 @@
     await resolveTestFile();
     assertNoTestErrors();
 
-    var import = _importFinder('package:test/a.dart');
+    var import = findElement.importFind('package:test/a.dart');
 
     var invocation = findNode.methodInvocation('foo(0)');
     assertMethodInvocation(
@@ -1336,7 +1359,7 @@
     await resolveTestFile();
     assertNoTestErrors();
 
-    var import = _importFinder('package:test/a.dart');
+    var import = findElement.importFind('package:test/a.dart');
 
     var invocation = findNode.methodInvocation('foo(0)');
     assertMethodInvocation(
@@ -1727,50 +1750,4 @@
 //      expectedType: 'dynamic',
 //    );
   }
-
-  _ImportElementFinder _importFinder(String targetUri) {
-    var import = findElement.import(targetUri);
-    return _ImportElementFinder(import);
-  }
-}
-
-class _ImportElementFinder {
-  final ImportElement import;
-
-  _ImportElementFinder(this.import);
-
-  CompilationUnitElement get definingUnit {
-    return importedLibrary.definingCompilationUnit;
-  }
-
-  LibraryElement get importedLibrary => import.importedLibrary;
-
-  PrefixElement get prefix => import.prefix;
-
-  ClassElement class_(String name) {
-    for (var class_ in definingUnit.types) {
-      if (class_.name == name) {
-        return class_;
-      }
-    }
-    fail('Not found class: $name');
-  }
-
-  FunctionElement topFunction(String name) {
-    for (var function in definingUnit.functions) {
-      if (function.name == name) {
-        return function;
-      }
-    }
-    fail('Not found top-level function: $name');
-  }
-
-  PropertyAccessorElement topGetter(String name) {
-    for (var accessor in definingUnit.accessors) {
-      if (accessor.name == name && accessor.isGetter) {
-        return accessor;
-      }
-    }
-    fail('Not found top-level getter: $name');
-  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 65cb6d7..496f774 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -10,12 +10,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(MixinDriverResolutionTest);
-    defineReflectiveTests(MixinTaskResolutionTest);
   });
 }
 
@@ -1924,12 +1922,3 @@
     assertTypeDynamic(access);
   }
 }
-
-@reflectiveTest
-class MixinTaskResolutionTest extends TaskResolutionTest
-    with MixinResolutionMixin {
-  @failingTest
-  test_conflictingGenericInterfaces() {
-    return super.test_conflictingGenericInterfaces();
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index efd7d8e..be8eb31 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -14,12 +15,12 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/test_utilities/find_element.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
 
 import '../../../generated/test_support.dart';
-import 'find_element.dart';
-import 'find_node.dart';
 
 final isBottomType = new TypeMatcher<BottomTypeImpl>();
 
@@ -31,7 +32,7 @@
 
 /// Base for resolution tests.
 mixin ResolutionTest implements ResourceProviderMixin {
-  TestAnalysisResult result;
+  ResolvedUnitResult result;
   FindNode findNode;
   FindElement findElement;
 
@@ -143,6 +144,10 @@
     expect(element.enclosingElement, expectedEnclosing);
   }
 
+  bool get enableUnusedLocalVariable => false;
+
+  bool get enableUnusedElement => false;
+
   /**
    * Assert that the number of error codes in reported [errors] matches the
    * number of [expected] error codes. The order of errors is ignored.
@@ -152,11 +157,15 @@
     var errorListener = new GatheringErrorListener();
     for (AnalysisError error in result.errors) {
       ErrorCode errorCode = error.errorCode;
-      if (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
-          errorCode == HintCode.UNUSED_CATCH_STACK ||
-          errorCode == HintCode.UNUSED_ELEMENT ||
-          errorCode == HintCode.UNUSED_FIELD ||
-          errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
+      if (!enableUnusedElement &&
+          (errorCode == HintCode.UNUSED_ELEMENT ||
+              errorCode == HintCode.UNUSED_FIELD)) {
+        continue;
+      }
+      if (!enableUnusedLocalVariable &&
+          (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
+              errorCode == HintCode.UNUSED_CATCH_STACK ||
+              errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
         continue;
       }
       errorListener.onError(error);
@@ -164,6 +173,12 @@
     errorListener.assertErrorsWithCodes(expected);
   }
 
+  Future<void> assertErrorsInCode(String code, List<ErrorCode> errors) async {
+    addTestFile(code);
+    await resolveTestFile();
+    assertTestErrors(errors);
+  }
+
   void assertHasTestErrors() {
     expect(result.errors, isNotEmpty);
   }
@@ -295,6 +310,12 @@
     assertTypeNull(ref);
   }
 
+  Future<void> assertNoErrorsInCode(String code) async {
+    addTestFile(code);
+    await resolveTestFile();
+    assertNoTestErrors();
+  }
+
   void assertNoTestErrors() {
     assertTestErrors(const <ErrorCode>[]);
   }
@@ -397,7 +418,7 @@
     }
   }
 
-  Future<TestAnalysisResult> resolveFile(String path);
+  Future<ResolvedUnitResult> resolveFile(String path);
 
   Future<void> resolveTestFile() async {
     var path = convertPath('/test/lib/test.dart');
@@ -419,12 +440,3 @@
     return invokeType.substring(arrowIndex + 1).trim();
   }
 }
-
-class TestAnalysisResult {
-  final String path;
-  final String content;
-  final CompilationUnit unit;
-  final List<AnalysisError> errors;
-
-  TestAnalysisResult(this.path, this.content, this.unit, this.errors);
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
deleted file mode 100644
index 7c84ed2..0000000
--- a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analyzer/file_system/file_system.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/mock_sdk.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-
-import '../../../generated/analysis_context_factory.dart';
-import 'resolution.dart';
-
-/// Task model based implementation of [ResolutionTest].
-class TaskResolutionTest with ResourceProviderMixin, ResolutionTest {
-  DartSdk sdk;
-
-  SourceFactory sourceFactory;
-  InternalAnalysisContext analysisContext;
-
-  @override
-  Future<TestAnalysisResult> resolveFile(String path) async {
-    var file = resourceProvider.getFile(path);
-    var content = file.readAsStringSync();
-    var source = file.createSource(Uri.parse('package:test/test.dart'));
-
-    analysisContext.computeKindOf(source);
-    List<Source> libraries = analysisContext.getLibrariesContaining(source);
-    Source library = libraries.first;
-
-    var unit = analysisContext.resolveCompilationUnit2(source, library);
-    var errors = analysisContext.computeErrors(source);
-
-    return new TestAnalysisResult(path, content, unit, errors);
-  }
-
-  void setUp() {
-    sdk = new MockSdk(resourceProvider: resourceProvider);
-
-    Map<String, List<Folder>> packageMap = <String, List<Folder>>{
-      'test': [getFolder('/test/lib')],
-      'aaa': [getFolder('/aaa/lib')],
-      'bbb': [getFolder('/bbb/lib')],
-    };
-
-    analysisContext = AnalysisContextFactory.contextWithCore(
-      contributedResolver:
-          new PackageMapUriResolver(resourceProvider, packageMap),
-      resourceProvider: resourceProvider,
-    );
-  }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 4848102..d8c0076 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -9,6 +9,7 @@
 import 'comment_test.dart' as comment_test;
 import 'constant_test.dart' as constant_test;
 import 'enum_test.dart' as enum_test;
+import 'flow_analysis_test.dart' as flow_analysis_test;
 import 'for_in_test.dart' as for_in_test;
 import 'generic_type_alias_test.dart' as generic_type_alias_test;
 import 'import_prefix_test.dart' as import_prefix_test;
@@ -31,6 +32,7 @@
     comment_test.main();
     constant_test.main();
     enum_test.main();
+    flow_analysis_test.main();
     for_in_test.main();
     generic_type_alias_test.main();
     import_prefix_test.main();
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 3c3defe..cdb193e 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -7,12 +7,10 @@
 
 import 'driver_resolution.dart';
 import 'resolution.dart';
-import 'task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(TopTypeInferenceDriverResolutionTest);
-    defineReflectiveTests(TopTypeInferenceTaskResolutionTest);
   });
 }
 
@@ -20,10 +18,6 @@
 class TopTypeInferenceDriverResolutionTest extends DriverResolutionTest
     with TopTypeInstanceMixin {}
 
-@reflectiveTest
-class TopTypeInferenceTaskResolutionTest extends TaskResolutionTest
-    with TopTypeInstanceMixin {}
-
 mixin TopTypeInstanceMixin implements ResolutionTest {
   test_referenceInstanceVariable_withDeclaredType() async {
     addTestFile(r'''
diff --git a/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart b/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart
new file mode 100644
index 0000000..6a313d0
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolver/exit_detector_test.dart
@@ -0,0 +1,1118 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../ast/parse_base.dart';
+import '../resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ExitDetectorParsedStatementTest);
+    defineReflectiveTests(ExitDetectorResolvedStatementTest);
+    defineReflectiveTests(ExitDetectorForCodeAsUiTest);
+  });
+}
+
+/// Tests for the [ExitDetector] that require that the control flow and spread
+/// experiments be enabled.
+@reflectiveTest
+class ExitDetectorForCodeAsUiTest extends ParseBase {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [
+      EnableString.control_flow_collections,
+      EnableString.spread_collections,
+    ];
+
+  test_for_condition() async {
+    _assertTrue('[for (; throw 0;) 0]');
+  }
+
+  test_for_implicitTrue() async {
+    _assertTrue('[for (;;) 0]');
+  }
+
+  test_for_initialization() async {
+    _assertTrue('[for (i = throw 0;;) 0]');
+  }
+
+  test_for_true() async {
+    _assertTrue('[for (; true; ) 0]');
+  }
+
+  test_for_true_if_return() async {
+    _assertTrue('[for (; true; ) if (true) throw 42]');
+  }
+
+  test_for_true_noBreak() async {
+    _assertTrue('[for (; true; ) 0]');
+  }
+
+  test_for_updaters() async {
+    _assertTrue('[for (;; i++, throw 0) 1]');
+  }
+
+  test_for_variableDeclaration() async {
+    _assertTrue('[for (int i = throw 0;;) 1]');
+  }
+
+  test_forEach() async {
+    _assertFalse('[for (element in list) 0]');
+  }
+
+  test_forEach_throw() async {
+    _assertTrue('[for (element in throw 42) 0]');
+  }
+
+  test_if_false_else_throw() async {
+    _assertTrue('[if (false) 0 else throw 42]');
+  }
+
+  test_if_false_noThrow() async {
+    _assertFalse('[if (false) 0]');
+  }
+
+  test_if_false_throw() async {
+    _assertFalse('[if (false) throw 42]');
+  }
+
+  test_if_noThrow() async {
+    _assertFalse('[if (c) i++]');
+  }
+
+  test_if_throw() async {
+    _assertFalse('[if (c) throw 42]');
+  }
+
+  test_if_true_noThrow() async {
+    _assertFalse('[if (true) 0]');
+  }
+
+  test_if_true_throw() async {
+    _assertTrue('[if (true) throw 42]');
+  }
+
+  test_ifElse_bothThrow() async {
+    _assertTrue("[if (c) throw 0 else throw 1]");
+  }
+
+  test_ifElse_elseThrow() async {
+    _assertFalse('[if (c) 0 else throw 42]');
+  }
+
+  test_ifElse_noThrow() async {
+    _assertFalse('[if (c) 0 else 1]');
+  }
+
+  test_ifElse_thenThrow() async {
+    _assertFalse('[if (c) throw 42 else 0]');
+  }
+
+  void _assertFalse(String expressionCode) {
+    _assertHasReturn(expressionCode, false);
+  }
+
+  void _assertHasReturn(String expressionCode, bool expected) {
+    var path = convertPath('/test/lib/test.dart');
+
+    newFile(path, content: '''
+void f() { // ref
+  $expressionCode;
+}
+''');
+
+    var parseResult = parseUnit(path);
+    expect(parseResult.errors, isEmpty);
+
+    var findNode = FindNode(parseResult.content, parseResult.unit);
+
+    var block = findNode.block('{ // ref');
+    var statement = block.statements.single as ExpressionStatement;
+    var expression = statement.expression;
+
+    var actual = ExitDetector.exits(expression);
+    expect(actual, expected);
+  }
+
+  void _assertTrue(String expressionCode) {
+    _assertHasReturn(expressionCode, true);
+  }
+}
+
+/// Tests for the [ExitDetector] that do not require that the AST be resolved.
+///
+/// See [ExitDetectorResolvedStatementTest] for tests that require the AST to be resolved.
+@reflectiveTest
+class ExitDetectorParsedStatementTest extends ParseBase {
+  test_asExpression() async {
+    _assertFalse('a as Object;');
+  }
+
+  test_asExpression_throw() async {
+    _assertTrue('throw 42 as Object;');
+  }
+
+  test_assertStatement() async {
+    _assertFalse("assert(a);");
+  }
+
+  test_assertStatement_throw() async {
+    _assertFalse('assert((throw 0));');
+  }
+
+  test_assignmentExpression() async {
+    _assertFalse('v = 1;');
+  }
+
+  @failingTest
+  test_assignmentExpression_compound_lazy() async {
+    _assertFalse('v ||= false;');
+  }
+
+  test_assignmentExpression_lhs_throw() async {
+    _assertTrue('a[throw 42] = 0;');
+  }
+
+  test_assignmentExpression_rhs_throw() async {
+    _assertTrue('v = throw 42;');
+  }
+
+  test_await_false() async {
+    _assertFalse('await x;');
+  }
+
+  test_await_throw_true() async {
+    _assertTrue('bool b = await (throw 42 || true);');
+  }
+
+  test_binaryExpression_and() async {
+    _assertFalse('a && b;');
+  }
+
+  test_binaryExpression_and_lhs() async {
+    _assertTrue('throw 42 && b;');
+  }
+
+  test_binaryExpression_and_rhs() async {
+    _assertFalse('a && (throw 42);');
+  }
+
+  test_binaryExpression_and_rhs2() async {
+    _assertFalse('false && (throw 42);');
+  }
+
+  test_binaryExpression_and_rhs3() async {
+    _assertTrue('true && (throw 42);');
+  }
+
+  test_binaryExpression_ifNull() async {
+    _assertFalse('a ?? b;');
+  }
+
+  test_binaryExpression_ifNull_lhs() async {
+    _assertTrue('throw 42 ?? b;');
+  }
+
+  test_binaryExpression_ifNull_rhs() async {
+    _assertFalse('a ?? (throw 42);');
+  }
+
+  test_binaryExpression_ifNull_rhs2() async {
+    _assertFalse('null ?? (throw 42);');
+  }
+
+  test_binaryExpression_or() async {
+    _assertFalse('a || b;');
+  }
+
+  test_binaryExpression_or_lhs() async {
+    _assertTrue('throw 42 || b;');
+  }
+
+  test_binaryExpression_or_rhs() async {
+    _assertFalse('a || (throw 42);');
+  }
+
+  test_binaryExpression_or_rhs2() async {
+    _assertFalse('true || (throw 42);');
+  }
+
+  test_binaryExpression_or_rhs3() async {
+    _assertTrue('false || (throw 42);');
+  }
+
+  test_block_empty() async {
+    _assertFalse('{}');
+  }
+
+  test_block_noReturn() async {
+    _assertFalse('{ int i = 0; }');
+  }
+
+  test_block_return() async {
+    _assertTrue('{ return 0; }');
+  }
+
+  test_block_returnNotLast() async {
+    _assertTrue('{ return 0; throw 42; }');
+  }
+
+  test_block_throwNotLast() async {
+    _assertTrue('{ throw 0; x = null; }');
+  }
+
+  test_cascadeExpression_argument() async {
+    _assertTrue('a..b(throw 42);');
+  }
+
+  test_cascadeExpression_index() async {
+    _assertTrue('a..[throw 42];');
+  }
+
+  test_cascadeExpression_target() async {
+    _assertTrue('throw a..b();');
+  }
+
+  test_conditional_ifElse_bothThrows() async {
+    _assertTrue('c ? throw 42 : throw 42;');
+  }
+
+  test_conditional_ifElse_elseThrows() async {
+    _assertFalse('c ? i : throw 42;');
+  }
+
+  test_conditional_ifElse_noThrow() async {
+    _assertFalse('c ? i : j;');
+  }
+
+  test_conditional_ifElse_thenThrow() async {
+    _assertFalse('c ? throw 42 : j;');
+  }
+
+  test_conditionalAccess() async {
+    _assertFalse('a?.b;');
+  }
+
+  test_conditionalAccess_lhs() async {
+    _assertTrue('(throw 42)?.b;');
+  }
+
+  test_conditionalAccessAssign() async {
+    _assertFalse('a?.b = c;');
+  }
+
+  test_conditionalAccessAssign_lhs() async {
+    _assertTrue('(throw 42)?.b = c;');
+  }
+
+  test_conditionalAccessAssign_rhs() async {
+    _assertFalse('a?.b = throw 42;');
+  }
+
+  test_conditionalAccessAssign_rhs2() async {
+    _assertFalse("null?.b = throw 42;");
+  }
+
+  test_conditionalAccessIfNullAssign() async {
+    _assertFalse('a?.b ??= c;');
+  }
+
+  test_conditionalAccessIfNullAssign_lhs() async {
+    _assertTrue('(throw 42)?.b ??= c;');
+  }
+
+  test_conditionalAccessIfNullAssign_rhs() async {
+    _assertFalse('a?.b ??= throw 42;');
+  }
+
+  test_conditionalAccessIfNullAssign_rhs2() async {
+    _assertFalse('null?.b ??= throw 42;');
+  }
+
+  test_conditionalCall() async {
+    _assertFalse('a?.b(c);');
+  }
+
+  test_conditionalCall_lhs() async {
+    _assertTrue('(throw 42)?.b(c);');
+  }
+
+  test_conditionalCall_rhs() async {
+    _assertFalse('a?.b(throw 42);');
+  }
+
+  test_conditionalCall_rhs2() async {
+    _assertFalse('null?.b(throw 42);');
+  }
+
+  test_doStatement_break_and_throw() async {
+    _assertFalse('''
+{
+  do {
+    if (1 == 1) break;
+    throw 42;
+  } while (0 == 1);
+}
+''');
+  }
+
+  test_doStatement_continue_and_throw() async {
+    _assertFalse('''
+{
+  do {
+    if (1 == 1) continue;
+    throw 42;
+  } while (0 == 1);
+}
+''');
+  }
+
+  test_doStatement_continueDoInSwitch_and_throw() async {
+    _assertFalse('''
+{
+  D: do {
+    switch (1) {
+      L: case 0: continue D;
+      M: case 1: break;
+    }
+    throw 42;
+  } while (0 == 1);
+}''');
+  }
+
+  test_doStatement_continueInSwitch_and_throw() async {
+    _assertFalse('''
+{
+  do {
+    switch (1) {
+      L: case 0: continue;
+      M: case 1: break;
+    }
+    throw 42;
+  } while (0 == 1);
+}''');
+  }
+
+  test_doStatement_return() async {
+    _assertTrue('{ do { return null; } while (1 == 2); }');
+  }
+
+  test_doStatement_throwCondition() async {
+    _assertTrue('{ do {} while (throw 42); }');
+  }
+
+  test_doStatement_true_break() async {
+    _assertFalse('{ do { break; } while (true); }');
+  }
+
+  test_doStatement_true_continue() async {
+    _assertTrue('{ do { continue; } while (true); }');
+  }
+
+  test_doStatement_true_continueWithLabel() async {
+    _assertTrue('{ x: do { continue x; } while (true); }');
+  }
+
+  test_doStatement_true_if_return() async {
+    _assertTrue('{ do { if (true) {return null;} } while (true); }');
+  }
+
+  test_doStatement_true_noBreak() async {
+    _assertTrue('{ do {} while (true); }');
+  }
+
+  test_doStatement_true_return() async {
+    _assertTrue('{ do { return null; } while (true);  }');
+  }
+
+  test_emptyStatement() async {
+    _assertFalse(';');
+  }
+
+  test_forEachStatement() async {
+    _assertFalse('for (element in list) {}');
+  }
+
+  test_forEachStatement_throw() async {
+    _assertTrue('for (element in throw 42) {}');
+  }
+
+  test_forStatement_condition() async {
+    _assertTrue('for (; throw 0;) {}');
+  }
+
+  test_forStatement_implicitTrue() async {
+    _assertTrue('for (;;) {}');
+  }
+
+  test_forStatement_implicitTrue_break() async {
+    _assertFalse('for (;;) { break; }');
+  }
+
+  test_forStatement_implicitTrue_if_break() async {
+    _assertFalse('''
+{
+  for (;;) {
+    if (1==2) {
+      var a = 1;
+    } else {
+      break;
+    }
+  }
+}
+''');
+  }
+
+  test_forStatement_initialization() async {
+    _assertTrue('for (i = throw 0;;) {}');
+  }
+
+  test_forStatement_true() async {
+    _assertTrue('for (; true; ) {}');
+  }
+
+  test_forStatement_true_break() async {
+    _assertFalse('{ for (; true; ) { break; } }');
+  }
+
+  test_forStatement_true_continue() async {
+    _assertTrue('{ for (; true; ) { continue; } }');
+  }
+
+  test_forStatement_true_if_return() async {
+    _assertTrue('{ for (; true; ) { if (true) {return null;} } }');
+  }
+
+  test_forStatement_true_noBreak() async {
+    _assertTrue('{ for (; true; ) {} }');
+  }
+
+  test_forStatement_updaters() async {
+    _assertTrue('for (;; i++, throw 0) {}');
+  }
+
+  test_forStatement_variableDeclaration() async {
+    _assertTrue('for (int i = throw 0;;) {}');
+  }
+
+  test_functionExpression() async {
+    _assertFalse('(){};');
+  }
+
+  test_functionExpression_bodyThrows() async {
+    _assertFalse('(int i) => throw 42;');
+  }
+
+  test_functionExpressionInvocation() async {
+    _assertFalse('f(g);');
+  }
+
+  test_functionExpressionInvocation_argumentThrows() async {
+    _assertTrue('f(throw 42);');
+  }
+
+  test_functionExpressionInvocation_targetThrows() async {
+    _assertTrue("(throw 42)(g);");
+  }
+
+  test_identifier_prefixedIdentifier() async {
+    _assertFalse('a.b;');
+  }
+
+  test_identifier_simpleIdentifier() async {
+    _assertFalse('a;');
+  }
+
+  test_if_false_else_return() async {
+    _assertTrue('if (false) {} else { return 0; }');
+  }
+
+  test_if_false_noReturn() async {
+    _assertFalse('if (false) {}');
+  }
+
+  test_if_false_return() async {
+    _assertFalse('if (false) { return 0; }');
+  }
+
+  test_if_noReturn() async {
+    _assertFalse('if (c) i++;');
+  }
+
+  test_if_return() async {
+    _assertFalse('if (c) return 0;');
+  }
+
+  test_if_true_noReturn() async {
+    _assertFalse('if (true) {}');
+  }
+
+  test_if_true_return() async {
+    _assertTrue('if (true) { return 0; }');
+  }
+
+  test_ifElse_bothReturn() async {
+    _assertTrue('if (c) return 0; else return 1;');
+  }
+
+  test_ifElse_elseReturn() async {
+    _assertFalse('if (c) i++; else return 1;');
+  }
+
+  test_ifElse_noReturn() async {
+    _assertFalse('if (c) i++; else j++;');
+  }
+
+  test_ifElse_thenReturn() async {
+    _assertFalse('if (c) return 0; else j++;');
+  }
+
+  test_ifNullAssign() async {
+    _assertFalse('a ??= b;');
+  }
+
+  test_ifNullAssign_rhs() async {
+    _assertFalse('a ??= throw 42;');
+  }
+
+  test_indexExpression() async {
+    _assertFalse('a[b];');
+  }
+
+  test_indexExpression_index() async {
+    _assertTrue('a[throw 42];');
+  }
+
+  test_indexExpression_target() async {
+    _assertTrue("(throw 42)[b];");
+  }
+
+  test_instanceCreationExpression() async {
+    _assertFalse('new A(b);');
+  }
+
+  test_instanceCreationExpression_argumentThrows() async {
+    _assertTrue('new A(throw 42);');
+  }
+
+  test_isExpression() async {
+    _assertFalse('A is B;');
+  }
+
+  test_isExpression_throws() async {
+    _assertTrue('throw 42 is B;');
+  }
+
+  test_labeledStatement() async {
+    _assertFalse('label: a;');
+  }
+
+  test_labeledStatement_throws() async {
+    _assertTrue('label: throw 42;');
+  }
+
+  test_literal_boolean() async {
+    _assertFalse('true;');
+  }
+
+  test_literal_double() async {
+    _assertFalse('1.1;');
+  }
+
+  test_literal_integer() async {
+    _assertFalse('1;');
+  }
+
+  test_literal_null() async {
+    _assertFalse('null;');
+  }
+
+  test_literal_String() async {
+    _assertFalse('"str";');
+  }
+
+  test_methodInvocation() async {
+    _assertFalse('a.b(c);');
+  }
+
+  test_methodInvocation_argument() async {
+    _assertTrue('a.b(throw 42);');
+  }
+
+  test_methodInvocation_target() async {
+    _assertTrue("(throw 42).b(c);");
+  }
+
+  test_parenthesizedExpression() async {
+    _assertFalse('(a);');
+  }
+
+  test_parenthesizedExpression_throw() async {
+    _assertTrue('(throw 42);');
+  }
+
+  test_propertyAccess() async {
+    _assertFalse('new Object().a;');
+  }
+
+  test_propertyAccess_throws() async {
+    _assertTrue('(throw 42).a;');
+  }
+
+  test_rethrow() async {
+    _assertTrue('rethrow;');
+  }
+
+  test_return() async {
+    _assertTrue('return 0;');
+  }
+
+  test_superExpression() async {
+    _assertFalse('super.a;');
+  }
+
+  test_switch_allReturn() async {
+    _assertTrue('switch (i) { case 0: return 0; default: return 1; }');
+  }
+
+  test_switch_defaultWithNoStatements() async {
+    _assertFalse('switch (i) { case 0: return 0; default: }');
+  }
+
+  test_switch_fallThroughToNotReturn() async {
+    _assertFalse(r'''
+switch (i) {
+  case 0:
+  case 1:
+    break;
+  default:
+    return 1;
+}
+''');
+  }
+
+  test_switch_fallThroughToReturn() async {
+    _assertTrue(r'''
+switch (i) {
+  case 0:
+  case 1:
+    return 0;
+  default:
+    return 1;
+}
+''');
+  }
+
+  @failingTest
+  test_switch_includesContinue() async {
+    _assertTrue('''
+switch (i) {
+  zero: case 0: return 0;
+  case 1: continue zero;
+  default: return 1;
+}''');
+  }
+
+  test_switch_noDefault() async {
+    _assertFalse('switch (i) { case 0: return 0; }');
+  }
+
+  // The ExitDetector could conceivably follow switch continue labels and
+  // determine that `case 0` exits, `case 1` continues to an exiting case, and
+  // `default` exits, so the switch exits.
+  test_switch_nonReturn() async {
+    _assertFalse('switch (i) { case 0: i++; default: return 1; }');
+  }
+
+  test_thisExpression() async {
+    _assertFalse('this.a;');
+  }
+
+  test_throwExpression() async {
+    _assertTrue('throw new Object();');
+  }
+
+  test_tryStatement_noReturn() async {
+    _assertFalse('try {} catch (e, s) {} finally {}');
+  }
+
+  test_tryStatement_noReturn_noFinally() async {
+    _assertFalse('try {} catch (e, s) {}');
+  }
+
+  test_tryStatement_return_catch() async {
+    _assertFalse('try {} catch (e, s) { return 1; } finally {}');
+  }
+
+  test_tryStatement_return_catch_noFinally() async {
+    _assertFalse('try {} catch (e, s) { return 1; }');
+  }
+
+  test_tryStatement_return_finally() async {
+    _assertTrue('try {} catch (e, s) {} finally { return 1; }');
+  }
+
+  test_tryStatement_return_try_noCatch() async {
+    _assertTrue('try { return 1; } finally {}');
+  }
+
+  test_tryStatement_return_try_oneCatchDoesNotExit() async {
+    _assertFalse('try { return 1; } catch (e, s) {} finally {}');
+  }
+
+  test_tryStatement_return_try_oneCatchDoesNotExit_noFinally() async {
+    _assertFalse('try { return 1; } catch (e, s) {}');
+  }
+
+  test_tryStatement_return_try_oneCatchExits() async {
+    _assertTrue('''
+try {
+  return 1;
+} catch (e, s) {
+  return 1;
+} finally {}
+''');
+  }
+
+  test_tryStatement_return_try_oneCatchExits_noFinally() async {
+    _assertTrue('try { return 1; } catch (e, s) { return 1; }');
+  }
+
+  test_tryStatement_return_try_twoCatchesDoExit() async {
+    _assertTrue('''
+try { return 1; }
+on int catch (e, s) { return 1; }
+on String catch (e, s) { return 1; }
+finally {}
+''');
+  }
+
+  test_tryStatement_return_try_twoCatchesDoExit_noFinally() async {
+    _assertTrue('''
+try { return 1; }
+on int catch (e, s) { return 1; }
+on String catch (e, s) { return 1; }
+''');
+  }
+
+  test_tryStatement_return_try_twoCatchesDoNotExit() async {
+    _assertFalse('''
+try { return 1; }
+on int catch (e, s) {}
+on String catch (e, s) {}
+finally {}
+''');
+  }
+
+  test_tryStatement_return_try_twoCatchesDoNotExit_noFinally() async {
+    _assertFalse('''
+try { return 1; }
+on int catch (e, s) {}
+on String catch (e, s) {}
+''');
+  }
+
+  test_tryStatement_return_try_twoCatchesMixed() async {
+    _assertFalse('''
+try { return 1; }
+on int catch (e, s) {}
+on String catch (e, s) { return 1; }
+finally {}
+''');
+  }
+
+  test_tryStatement_return_try_twoCatchesMixed_noFinally() async {
+    _assertFalse('''
+try { return 1; }
+on int catch (e, s) {}
+on String catch (e, s) { return 1; }
+''');
+  }
+
+  test_variableDeclarationStatement_noInitializer() async {
+    _assertFalse('int i;');
+  }
+
+  test_variableDeclarationStatement_noThrow() async {
+    _assertFalse('int i = 0;');
+  }
+
+  test_variableDeclarationStatement_throw() async {
+    _assertTrue('int i = throw new Object();');
+  }
+
+  test_whileStatement_false_nonReturn() async {
+    _assertFalse("{ while (false) {} }");
+  }
+
+  test_whileStatement_throwCondition() async {
+    _assertTrue('{ while (throw 42) {} }');
+  }
+
+  test_whileStatement_true_break() async {
+    _assertFalse('{ while (true) { break; } }');
+  }
+
+  test_whileStatement_true_break_and_throw() async {
+    _assertFalse('{ while (true) { if (1==1) break; throw 42; } }');
+  }
+
+  test_whileStatement_true_continue() async {
+    _assertTrue('{ while (true) { continue; } }');
+  }
+
+  test_whileStatement_true_continueWithLabel() async {
+    _assertTrue('{ x: while (true) { continue x; } }');
+  }
+
+  test_whileStatement_true_doStatement_scopeRequired() async {
+    _assertTrue('{ while (true) { x: do { continue x; } while (true); } }');
+  }
+
+  test_whileStatement_true_if_return() async {
+    _assertTrue('{ while (true) { if (true) {return null;} } }');
+  }
+
+  test_whileStatement_true_noBreak() async {
+    _assertTrue('{ while (true) {} }');
+  }
+
+  test_whileStatement_true_return() async {
+    _assertTrue('{ while (true) { return null; } }');
+  }
+
+  test_whileStatement_true_throw() async {
+    _assertTrue('{ while (true) { throw 42; } }');
+  }
+
+  void _assertFalse(String code) {
+    _assertHasReturn(code, false);
+  }
+
+  void _assertHasReturn(String statementCode, bool expected) {
+    var path = convertPath('/test/lib/test.dart');
+
+    newFile(path, content: '''
+void f() { // ref
+  $statementCode
+}
+''');
+
+    var parseResult = parseUnit(path);
+    expect(parseResult.errors, isEmpty);
+
+    var findNode = FindNode(parseResult.content, parseResult.unit);
+
+    var block = findNode.block('{ // ref');
+    var statement = block.statements.single;
+
+    var actual = ExitDetector.exits(statement);
+    expect(actual, expected);
+  }
+
+  void _assertTrue(String code) {
+    _assertHasReturn(code, true);
+  }
+}
+
+/// Tests for the [ExitDetector] that require that the AST be resolved.
+///
+/// See [ExitDetectorParsedStatementTest] for tests that do not require the AST to be resolved.
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
+@reflectiveTest
+class ExitDetectorResolvedStatementTest extends DriverResolutionTest {
+  test_forStatement_implicitTrue_breakWithLabel() async {
+    await _assertNthStatementDoesNotExit(r'''
+void f() {
+  x: for (;;) {
+    if (1 < 2) {
+      break x;
+    }
+    return;
+  }
+}
+''', 0);
+  }
+
+  test_switch_withEnum_false_noDefault() async {
+    await _assertNthStatementDoesNotExit(r'''
+enum E { A, B }
+String f(E e) {
+  var x;
+  switch (e) {
+    case A:
+      x = 'A';
+    case B:
+      x = 'B';
+  }
+  return x;
+}
+''', 1);
+  }
+
+  test_switch_withEnum_false_withDefault() async {
+    await _assertNthStatementDoesNotExit(r'''
+enum E { A, B }
+String f(E e) {
+  var x;
+  switch (e) {
+    case A:
+      x = 'A';
+    default:
+      x = '?';
+  }
+  return x;
+}
+''', 1);
+  }
+
+  test_switch_withEnum_true_noDefault() async {
+    await _assertNthStatementDoesNotExit(r'''
+enum E { A, B }
+String f(E e) {
+  switch (e) {
+    case A:
+      return 'A';
+    case B:
+      return 'B';
+  }
+}
+''', 0);
+  }
+
+  test_switch_withEnum_true_withExitingDefault() async {
+    await _assertNthStatementExits(r'''
+enum E { A, B }
+String f(E e) {
+  switch (e) {
+    case A:
+      return 'A';
+    default:
+      return '?';
+  }
+}
+''', 0);
+  }
+
+  test_switch_withEnum_true_withNonExitingDefault() async {
+    await _assertNthStatementDoesNotExit(r'''
+enum E { A, B }
+String f(E e) {
+  var x;
+  switch (e) {
+    case A:
+      return 'A';
+    default:
+      x = '?';
+  }
+}
+''', 1);
+  }
+
+  test_whileStatement_breakWithLabel() async {
+    await _assertNthStatementDoesNotExit(r'''
+void f() {
+  x: while (true) {
+    if (1 < 2) {
+      break x;
+    }
+    return;
+  }
+}
+''', 0);
+  }
+
+  test_whileStatement_breakWithLabel_afterExiting() async {
+    await _assertNthStatementExits(r'''
+void f() {
+  x: while (true) {
+    return;
+    if (1 < 2) {
+      break x;
+    }
+  }
+}
+''', 0);
+  }
+
+  test_whileStatement_switchWithBreakWithLabel() async {
+    await _assertNthStatementDoesNotExit(r'''
+void f() {
+  x: while (true) {
+    switch (true) {
+      case false: break;
+      case true: break x;
+    }
+  }
+}
+''', 0);
+  }
+
+  test_yieldStatement_plain() async {
+    await _assertNthStatementDoesNotExit(r'''
+void f() sync* {
+  yield 1;
+}
+''', 0);
+  }
+
+  test_yieldStatement_star_plain() async {
+    await _assertNthStatementDoesNotExit(r'''
+void f() sync* {
+  yield* 1;
+}
+''', 0);
+  }
+
+  test_yieldStatement_star_throw() async {
+    await _assertNthStatementExits(r'''
+void f() sync* {
+  yield* throw '';
+}
+''', 0);
+  }
+
+  test_yieldStatement_throw() async {
+    await _assertNthStatementExits(r'''
+void f() sync* {
+  yield throw '';
+}
+''', 0);
+  }
+
+  Future<void> _assertHasReturn(String code, int n, bool expected) async {
+    var path = convertPath('/test/lib/test.dart');
+
+    newFile(path, content: code);
+
+    var session = driver.currentSession;
+    var resolvedResult = await session.getResolvedUnit(path);
+
+    var unit = resolvedResult.unit;
+    FunctionDeclaration function = unit.declarations.last;
+    BlockFunctionBody body = function.functionExpression.body;
+    Statement statement = body.block.statements[n];
+    expect(ExitDetector.exits(statement), expected);
+  }
+
+  /// Assert that the [n]th statement in the last function declaration of
+  /// [code] exits.
+  Future<void> _assertNthStatementDoesNotExit(String code, int n) async {
+    await _assertHasReturn(code, n, false);
+  }
+
+  /// Assert that the [n]th statement in the last function declaration of
+  /// [code] does not exit.
+  Future<void> _assertNthStatementExits(String code, int n) async {
+    await _assertHasReturn(code, n, true);
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolver/test_all.dart b/pkg/analyzer/test/src/dart/resolver/test_all.dart
new file mode 100644
index 0000000..aff3b4f
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolver/test_all.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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'exit_detector_test.dart' as exit_detector;
+
+main() {
+  defineReflectiveSuite(() {
+    exit_detector.main();
+  }, name: 'resolver');
+}
diff --git a/pkg/analyzer/test/src/dart/test_all.dart b/pkg/analyzer/test/src/dart/test_all.dart
index 6d03856..adae467 100644
--- a/pkg/analyzer/test/src/dart/test_all.dart
+++ b/pkg/analyzer/test/src/dart/test_all.dart
@@ -9,6 +9,7 @@
 import 'constant/test_all.dart' as constant;
 import 'element/test_all.dart' as element;
 import 'resolution/test_all.dart' as resolution;
+import 'resolver/test_all.dart' as resolver;
 import 'sdk/test_all.dart' as sdk;
 
 /// Utility for manually running all tests.
@@ -19,6 +20,7 @@
     constant.main();
     element.main();
     resolution.main();
+    resolver.main();
     sdk.main();
   }, name: 'dart');
 }
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 73966e0..5915938 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
@@ -10,12 +10,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ArgumentTypeNotAssignableTest);
-    defineReflectiveTests(ArgumentTypeNotAssignableTest_Driver);
   });
 }
 
 @reflectiveTest
 class ArgumentTypeNotAssignableTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_functionType() async {
     await assertErrorsInCode(r'''
 m() {
@@ -38,10 +40,3 @@
 ''', [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
   }
 }
-
-@reflectiveTest
-class ArgumentTypeNotAssignableTest_Driver
-    extends ArgumentTypeNotAssignableTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart b/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart
index 94f9c00..534c440 100644
--- a/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/can_be_null_after_null_aware_test.dart
@@ -10,12 +10,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CanBeNullAfterNullAwareTest);
-    defineReflectiveTests(CanBeNullAfterNullAwareTest_Driver);
   });
 }
 
 @reflectiveTest
 class CanBeNullAfterNullAwareTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_afterCascade() async {
     await assertErrorsInCode(r'''
 m(x) {
@@ -103,9 +105,3 @@
 ''', [HintCode.CAN_BE_NULL_AFTER_NULL_AWARE]);
   }
 }
-
-@reflectiveTest
-class CanBeNullAfterNullAwareTest_Driver extends CanBeNullAfterNullAwareTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
index c864b70..f8b4aec 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
@@ -6,17 +6,15 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
-import '../dart/resolution/resolution.dart';
-import '../dart/resolution/task_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(ConstConstructorWithMixinWithFieldTest_DriverTest);
-    defineReflectiveTests(ConstConstructorWithMixinWithFieldTest_TaskTest);
+    defineReflectiveTests(ConstConstructorWithMixinWithFieldTest);
   });
 }
 
-mixin ConstConstructorWithMixinWithFieldMixin implements ResolutionTest {
+@reflectiveTest
+class ConstConstructorWithMixinWithFieldTest extends DriverResolutionTest {
   test_class_instance() async {
     addTestFile(r'''
 class A {
@@ -135,11 +133,3 @@
     assertNoTestErrors();
   }
 }
-
-@reflectiveTest
-class ConstConstructorWithMixinWithFieldTest_DriverTest
-    extends DriverResolutionTest with ConstConstructorWithMixinWithFieldMixin {}
-
-@reflectiveTest
-class ConstConstructorWithMixinWithFieldTest_TaskTest extends TaskResolutionTest
-    with ConstConstructorWithMixinWithFieldMixin {}
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
index 1dcc23e..2f91806 100644
--- a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../generated/resolver_test_case.dart';
@@ -11,17 +10,18 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(DeprecatedMemberUseFromSamePackageTest);
-    defineReflectiveTests(DeprecatedMemberUseFromSamePackageTest_Driver);
     defineReflectiveTests(DeprecatedMemberUseTest);
-    defineReflectiveTests(DeprecatedMemberUseTest_Driver);
   });
 }
 
 @reflectiveTest
 class DeprecatedMemberUseTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   /// Write a pubspec file at [root], so that BestPracticesVerifier can see that
-  /// [root] is the root of a BasicWorkspace, and a BasicWorkspacePackage.
-  void newBasicPackage(String root) {
+  /// [root] is the root of a PubWorkspace, and a PubWorkspacePackage.
+  void newPubPackage(String root) {
     newFile('$root/pubspec.yaml');
   }
 
@@ -33,7 +33,7 @@
 }
 ''');
 
-    newBasicPackage('/pkg1');
+    newPubPackage('/pkg1');
     assertErrorsInCode(r'''
 import 'package:foo/foo.dart';
 void main() => A().m();
@@ -48,7 +48,7 @@
 }
 ''');
 
-    newBasicPackage('/pkg1');
+    newPubPackage('/pkg1');
     assertErrorsInCode(r'''
 import 'package:foo/foo.dart';
 void main() => A().m();
@@ -68,7 +68,7 @@
 class A {}
 ''');
 
-    newBasicPackage('/pkg1');
+    newPubPackage('/pkg1');
     assertErrorsInCode('''
 export 'package:foo/foo.dart';
 ''', [HintCode.DEPRECATED_MEMBER_USE], sourceName: '/pkg1/lib/lib1.dart');
@@ -81,22 +81,140 @@
 class A {}
 ''');
 
-    newBasicPackage('/pkg1');
+    newPubPackage('/pkg1');
     assertErrorsInCode(r'''
 import 'package:foo/foo.dart';
 f(A a) {}
 ''', [HintCode.DEPRECATED_MEMBER_USE], sourceName: '/pkg1/lib/lib1.dart');
   }
-}
 
-@reflectiveTest
-class DeprecatedMemberUseTest_Driver extends DeprecatedMemberUseTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
+  test_basicWorkspace() async {
+    resetWithFooLibrary(r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+f(A a) {}
+''', // This is a cross-package deprecated member usage.
+        [HintCode.DEPRECATED_MEMBER_USE],
+        sourceName: '/workspace/project/lib/lib1.dart');
+  }
+
+  test_bazelWorkspace() async {
+    resetWithFooLibrary(r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    newFile('/workspace/WORKSPACE');
+    newFile('/workspace/project/BUILD');
+    newFolder('/workspace/bazel-genfiles');
+
+    assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+f(A a) {}
+''', // This is a cross-package deprecated member usage.
+        [HintCode.DEPRECATED_MEMBER_USE],
+        sourceName: '/workspace/project/lib/lib1.dart');
+  }
+
+  test_bazelWorkspace_sameWorkspace() async {
+    newFile('/workspace/WORKSPACE');
+    newFile('/workspace/project_a/BUILD');
+    newFile('/workspace/project_b/BUILD');
+    newFolder('/workspace/bazel-genfiles');
+
+    addNamedSource('/workspace/project_a/lib/deprecated_library.dart', r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import '../../project_a/lib/deprecated_library.dart';
+f(A a) {}
+''', // This is a same-workspace, cross-package deprecated member usage.
+        [HintCode.DEPRECATED_MEMBER_USE],
+        sourceName: '/workspace/project_b/lib/lib1.dart');
+  }
+
+  test_gnWorkspace() async {
+    resetWithFooLibrary(r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    newFolder('/workspace/.jiri_root');
+    newFile('/workspace/project/pubspec.yaml');
+    String buildDir = convertPath('out/debug-x87_128');
+    newFile('/workspace/.config',
+        content: 'FOO=foo\n'
+            'FUCHSIA_BUILD_DIR=$buildDir\n'
+            'BAR=bar\n');
+    newFile('/workspace/out/debug-x87_128/dartlang/gen/project/foo.packages');
+
+    assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+f(A a) {}
+''', // This is a cross-package deprecated member usage.
+        [HintCode.DEPRECATED_MEMBER_USE],
+        sourceName: '/workspace/project/lib/lib1.dart');
+  }
+
+  test_gnWorkspace_sameWorkspace() async {
+    newFolder('/workspace/.jiri_root');
+    newFile('/workspace/project_a/pubspec.yaml');
+    newFile('/workspace/project_b/pubspec.yaml');
+    newFile('/workspace/project_a/BUILD.gn');
+    newFile('/workspace/project_b/BUILD.gn');
+    String buildDir = convertPath('out/debug-x87_128');
+    newFile('/workspace/.config',
+        content: 'FOO=foo\n'
+            'FUCHSIA_BUILD_DIR=$buildDir\n');
+    newFile('/workspace/out/debug-x87_128/dartlang/gen/project_a/foo.packages');
+
+    addNamedSource('/workspace/project_a/lib/deprecated_library.dart', r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import '../../project_a/lib/deprecated_library.dart';
+f(A a) {}
+''', // This is a same-workspace, cross-package deprecated member usage.
+        [HintCode.DEPRECATED_MEMBER_USE],
+        sourceName: '/workspace/project_b/lib/lib1.dart');
+  }
+
+  test_packageBuildWorkspace() async {
+    resetWithFooLibrary(r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    newFolder('/workspace/.dart_tool/build/generated/project/lib');
+    newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+    assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+f(A a) {}
+''', // This is a cross-package deprecated member usage.
+        [HintCode.DEPRECATED_MEMBER_USE],
+        sourceName: '/workspace/package/lib/lib1.dart');
+  }
 }
 
 @reflectiveTest
 class DeprecatedMemberUseFromSamePackageTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_methodInvocation_contructor() async {
     assertErrorsInCode(r'''
 class A {
@@ -441,11 +559,77 @@
 }
 ''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
   }
-}
 
-@reflectiveTest
-class DeprecatedMemberUseFromSamePackageTest_Driver
-    extends DeprecatedMemberUseFromSamePackageTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
+  test_basicWorkspace() async {
+    addNamedSource('/workspace/lib/deprecated_library.dart', r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import 'deprecated_library.dart';
+f(A a) {}
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE],
+        sourceName: '/workspace/lib/lib1.dart');
+  }
+
+  test_bazelWorkspace() async {
+    newFile('/workspace/WORKSPACE');
+    newFile('/workspace/project/BUILD');
+    newFolder('/workspace/bazel-genfiles');
+
+    addNamedSource('/workspace/project/lib/deprecated_library.dart', r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import 'deprecated_library.dart';
+f(A a) {}
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE],
+        sourceName: '/workspace/project/lib/lib1.dart');
+  }
+
+  test_gnWorkspace() async {
+    newFolder('/workspace/.jiri_root');
+    newFile('/workspace/project/pubspec.yaml');
+    newFile('/workspace/project/BUILD.gn');
+    String buildDir = convertPath('out/debug-x87_128');
+    newFile('/workspace/.config',
+        content: 'FOO=foo\n'
+            'FUCHSIA_BUILD_DIR=$buildDir\n');
+    newFile('/workspace/out/debug-x87_128/dartlang/gen/project/foo.packages');
+
+    addNamedSource('/workspace/project/lib/deprecated_library.dart', r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import 'deprecated_library.dart';
+f(A a) {}
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE],
+        sourceName: '/workspace/project/lib/lib1.dart');
+  }
+
+  test_packageBuildWorkspace() async {
+    newFolder('/workspace/.dart_tool/build/generated/project/lib');
+    newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+    newFileWithBytes('/workspace/.packages', 'project:lib/'.codeUnits);
+
+    addNamedSource('/workspace/lib/deprecated_library.dart', r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+    assertErrorsInCode(r'''
+import 'deprecated_library.dart';
+f(A a) {}
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE],
+        sourceName: '/workspace/lib/lib1.dart');
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart b/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
index 6adfcf2..7fb98b8 100644
--- a/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/division_optimization_test.dart
@@ -10,12 +10,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(DivisionOptimizationTest);
-    defineReflectiveTests(DivisionOptimizationTest_Driver);
   });
 }
 
 @reflectiveTest
 class DivisionOptimizationTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_divisionOptimization() async {
     await assertNoErrorsInCode(r'''
 f(int x, int y) {
@@ -67,9 +69,3 @@
 ''', [HintCode.DIVISION_OPTIMIZATION]);
   }
 }
-
-@reflectiveTest
-class DivisionOptimizationTest_Driver extends DivisionOptimizationTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
index 0630617..f35bbcc 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_assignment_test.dart
@@ -10,12 +10,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InvalidAssignmentTest);
-    defineReflectiveTests(InvalidAssignmentTest_Driver);
   });
 }
 
 @reflectiveTest
 class InvalidAssignmentTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_instanceVariable() async {
     await assertErrorsInCode(r'''
 class A {
@@ -40,6 +42,24 @@
 ''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
   }
 
+  test_promotedTypeParameter_regress35306() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B extends A {}
+class C extends D {}
+class D {}
+
+void f<X extends A, Y extends B>(X x) {
+  if (x is Y) {
+    A a = x;
+    B b = x;
+    X x2 = x;
+    Y y = x;
+  }
+}
+''');
+  }
+
   test_staticVariable() async {
     await assertErrorsInCode(r'''
 class A {
@@ -53,6 +73,21 @@
 ''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
   }
 
+  test_typeParameterRecursion_regress35306() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {}
+class C extends D {}
+class D {}
+
+void f<X extends A, Y extends B>(X x) {
+  if (x is Y) {
+    D d = x;
+  }
+}
+''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+  }
+
   test_variableDeclaration() async {
     // 17971
     await assertErrorsInCode(r'''
@@ -71,9 +106,3 @@
 ''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
   }
 }
-
-@reflectiveTest
-class InvalidAssignmentTest_Driver extends InvalidAssignmentTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
new file mode 100644
index 0000000..125d43d
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_cast_new_expr_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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 '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidCastNewExprTest);
+  });
+}
+
+@reflectiveTest
+class InvalidCastNewExprTest extends ResolverTestCase {
+  @override
+  List<String> get enabledExperiments => ['set-literals'];
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_listLiteral_const() async {
+    await assertErrorsInCode(r'''
+const c = <B>[A()];
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+
+  test_listLiteral_nonConst() async {
+    await assertErrorsInCode(r'''
+var c = <B>[A()];
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+
+  test_setLiteral_const() async {
+    await assertErrorsInCode(r'''
+const c = <B>{A()};
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+
+  test_setLiteral_nonConst() async {
+    await assertErrorsInCode(r'''
+var c = <B>{A()};
+class A {
+  const A();
+}
+class B extends A {
+  const B();
+}
+''', [StrongModeCode.INVALID_CAST_NEW_EXPR]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
new file mode 100644
index 0000000..684a9c3
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_named_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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(InvalidOverrideDifferentDefaultValuesNamedTest);
+  });
+}
+
+@reflectiveTest
+class InvalidOverrideDifferentDefaultValuesNamedTest
+    extends DriverResolutionTest {
+  test_baseClassInOtherLibrary() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  foo([a = 0]) {}
+}
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+class C extends A {
+  foo([a = 0]) {}
+}
+''');
+  }
+
+  test_differentValues() async {
+    await _assertError(r'''
+class A {
+  m({x = 0}) {}
+}
+class B extends A {
+  m({x = 1}) {}
+}''');
+  }
+
+  test_equalValues() async {
+    await assertNoErrorsInCode(r'''
+abstract class A {
+  foo({x = 1});
+}
+
+class C extends A {
+  foo({x = 3 - 2}) {}
+}
+''');
+  }
+
+  test_equalValues_function() async {
+    await assertNoErrorsInCode(r'''
+nothing() => 'nothing';
+
+class A {
+  foo(String a, {orElse = nothing}) {}
+}
+
+class B extends A {
+  foo(String a, {orElse = nothing}) {}
+}
+''');
+  }
+
+  test_explicitNull_overriddenWith_implicitNull() async {
+    // If the base class provided an explicit null value for a default
+    // parameter, then it is ok for the derived class to let the default value
+    // be implicit, because the implicit default value of null matches the
+    // explicit default value of null.
+    await assertNoErrorsInCode(r'''
+class A {
+  foo({x: null}) {}
+}
+class B extends A {
+  foo({x}) {}
+}
+''');
+  }
+
+  test_implicitNull_overriddenWith_value() async {
+    // If the base class lets the default parameter be implicit, then it is ok
+    // for the derived class to provide an explicit default value, even if it's
+    // not null.
+    await assertNoErrorsInCode(r'''
+class A {
+  foo({x}) {}
+}
+class B extends A {
+  foo({x = 1}) {}
+}
+''');
+  }
+
+  test_value_overriddenWith_implicitNull() async {
+    // If the base class provided an explicit value for a default parameter,
+    // then it is a static warning for the derived class to provide a different
+    // value, even if implicitly.
+    await _assertError(r'''
+class A {
+  foo({x: 1}) {}
+}
+class B extends A {
+  foo({x}) {}
+}
+''');
+  }
+
+  Future<void> _assertError(String code) async {
+    await assertErrorsInCode(code, [
+      StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
new file mode 100644
index 0000000..0de7735
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_override_different_default_values_positional_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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(InvalidOverrideDifferentDefaultValuesPositionalTest);
+  });
+}
+
+@reflectiveTest
+class InvalidOverrideDifferentDefaultValuesPositionalTest
+    extends DriverResolutionTest {
+  test_baseClassInOtherLibrary() async {
+    newFile('/test/lib/a.dart', content: r'''
+class A {
+  foo([a = 0]) {}
+}
+''');
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+class C extends A {
+  foo([a = 0]) {}
+}
+''');
+  }
+
+  test_differentValues() async {
+    await _assertError(r'''
+class A {
+  m([x = 0]) {}
+}
+class B extends A {
+  m([x = 1]) {}
+}''');
+  }
+
+  test_equalValues() async {
+    await assertNoErrorsInCode(r'''
+abstract class A {
+  foo([x = 1]);
+}
+
+class C extends A {
+  foo([x = 3 - 2]) {}
+}
+''');
+  }
+
+  test_equalValues_function() async {
+    await assertNoErrorsInCode(r'''
+nothing() => 'nothing';
+
+class A {
+  foo(String a, [orElse = nothing]) {}
+}
+
+class B extends A {
+  foo(String a, [orElse = nothing]) {}
+}
+''');
+  }
+
+  test_explicitNull_overriddenWith_implicitNull() async {
+    // If the base class provided an explicit null value for a default
+    // parameter, then it is ok for the derived class to let the default value
+    // be implicit, because the implicit default value of null matches the
+    // explicit default value of null.
+    await assertNoErrorsInCode(r'''
+class A {
+  foo([x = null]) {}
+}
+class B extends A {
+  foo([x]) {}
+}
+''');
+  }
+
+  test_implicitNull_overriddenWith_value() async {
+    // If the base class lets the default parameter be implicit, then it is ok
+    // for the derived class to provide an explicit default value, even if it's
+    // not null.
+    await assertNoErrorsInCode(r'''
+class A {
+  foo([x]) {}
+}
+class B extends A {
+  foo([x = 1]) {}
+}
+''');
+  }
+
+  test_value_overriddenWith_implicitNull() async {
+    // If the base class provided an explicit value for a default parameter,
+    // then it is a static warning for the derived class to provide a different
+    // value, even if implicitly.
+    await _assertError(r'''
+class A {
+  foo([x = 1]) {}
+}
+class B extends A {
+  foo([x]) {}
+}
+''');
+  }
+
+  Future<void> _assertError(String code) async {
+    await assertErrorsInCode(code, [
+      StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart
index e10b266..d426e08 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_required_param_test.dart
@@ -11,13 +11,15 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InvalidRequiredParamTest);
-    defineReflectiveTests(InvalidRequiredParamTest_Driver);
   });
 }
 
 @reflectiveTest
 class InvalidRequiredParamTest extends ResolverTestCase {
   @override
+  bool get enableNewAnalysisDriver => true;
+
+  @override
   void reset() {
     super.resetWith(packages: [
       ['meta', metaLibraryStub]
@@ -69,9 +71,3 @@
 ''');
   }
 }
-
-@reflectiveTest
-class InvalidRequiredParamTest_Driver extends InvalidRequiredParamTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart
new file mode 100644
index 0000000..b842600
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_visibility_annotation_test.dart
@@ -0,0 +1,175 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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 '../../generated/hint_code_test.dart' show metaLibraryStub;
+import '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidVisibilityAnnotationTest);
+  });
+}
+
+@reflectiveTest
+class InvalidVisibilityAnnotationTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  @override
+  void reset() {
+    super.resetWith(packages: [
+      ['meta', metaLibraryStub]
+    ]);
+  }
+
+  test_publicTopLevelVariable() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting final _a = 1;
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_topLevelVariable_multiplePrivate() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting final _a = 1, _b = 2;
+''', [
+      HintCode.INVALID_VISIBILITY_ANNOTATION,
+      HintCode.INVALID_VISIBILITY_ANNOTATION
+    ]);
+  }
+
+  test_topLevelVariable_multipleMixed() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting final _a = 1, b = 2;
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_topLevelVariable_multiplePublic() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting final a = 1, b = 2;
+''');
+  }
+
+  test_privateTopLevelFucntion() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting void _f() {}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateTopLevelFunction() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting void _f() {}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateEnum() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting enum _E {a, b, c}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateTypedef() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting typedef _T = Function();
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateClass() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting class _C {}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateMixin() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting mixin _M {}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateConstructor() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  @visibleForTesting C._() {}
+}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateMethod() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  @visibleForTesting void _m() {}
+}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_privateField() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  @visibleForTesting int _a;
+}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_fields_multiplePrivate() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  @visibleForTesting int _a, _b;
+}
+''', [
+      HintCode.INVALID_VISIBILITY_ANNOTATION,
+      HintCode.INVALID_VISIBILITY_ANNOTATION
+    ]);
+  }
+
+  test_fields_multipleMixed() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  @visibleForTesting int _a, b;
+}
+''', [HintCode.INVALID_VISIBILITY_ANNOTATION]);
+  }
+
+  test_fields_multiplePublic() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  @visibleForTesting int a, b;
+}
+''');
+  }
+
+  test_valid() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@visibleForTesting void f() {}
+@visibleForTesting enum E {a, b, c}
+@visibleForTesting typedef T = Function();
+@visibleForTesting class C1 {}
+@visibleForTesting mixin M {}
+class C2 {
+  @visibleForTesting C2.named() {}
+}
+class C3 {
+  @visibleForTesting void m() {}
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 0be860c..5deb7f2 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -9,11 +9,32 @@
 import 'deprecated_member_use_test.dart' as deprecated_member_use;
 import 'division_optimization_test.dart' as division_optimization;
 import 'invalid_assignment_test.dart' as invalid_assignment;
+import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr;
+import 'invalid_override_different_default_values_named_test.dart'
+    as invalid_override_different_default_values_named;
+import 'invalid_override_different_default_values_positional_test.dart'
+    as invalid_override_different_default_values_positional;
 import 'invalid_required_param_test.dart' as invalid_required_param;
+import 'top_level_instance_getter_test.dart' as top_level_instance_getter;
+import 'top_level_instance_method_test.dart' as top_level_instance_method;
+import 'type_check_is_not_null_test.dart' as type_check_is_not_null;
+import 'type_check_is_null_test.dart' as type_check_is_null;
+import 'undefined_getter_test.dart' as undefined_getter;
+import 'undefined_hidden_name_test.dart' as undefined_hidden_name;
+import 'undefined_operator_test.dart' as undefined_operator;
+import 'undefined_setter_test.dart' as undefined_setter;
+import 'undefined_shown_name_test.dart' as undefined_shown_name;
 import 'unnecessary_cast_test.dart' as unnecessary_cast;
+import 'unnecessary_no_such_method_test.dart' as unnecessary_no_such_method;
+import 'unnecessary_type_check_false_test.dart' as unnecessary_type_check_false;
+import 'unnecessary_type_check_true_test.dart' as unnecessary_type_check_true;
+import 'unused_catch_clause_test.dart' as unused_catch_clause;
+import 'unused_catch_stack_test.dart' as unused_catch_stack;
+import 'unused_element_test.dart' as unused_element;
 import 'unused_field_test.dart' as unused_field;
 import 'unused_import_test.dart' as unused_import;
 import 'unused_label_test.dart' as unused_label;
+import 'unused_local_variable_test.dart' as unused_local_variable;
 import 'unused_shown_name_test.dart' as unused_shown_name;
 import 'use_of_void_result_test.dart' as use_of_void_result;
 
@@ -24,11 +45,30 @@
     deprecated_member_use.main();
     division_optimization.main();
     invalid_assignment.main();
+    invalid_cast_new_expr.main();
+    invalid_override_different_default_values_named.main();
+    invalid_override_different_default_values_positional.main();
     invalid_required_param.main();
+    top_level_instance_getter.main();
+    top_level_instance_method.main();
+    type_check_is_not_null.main();
+    type_check_is_null.main();
+    undefined_getter.main();
+    undefined_hidden_name.main();
+    undefined_operator.main();
+    undefined_setter.main();
+    undefined_shown_name.main();
     unnecessary_cast.main();
+    unnecessary_no_such_method.main();
+    unnecessary_type_check_false.main();
+    unnecessary_type_check_true.main();
+    unused_catch_clause.main();
+    unused_catch_stack.main();
+    unused_element.main();
     unused_field.main();
     unused_import.main();
     unused_label.main();
+    unused_local_variable.main();
     unused_shown_name.main();
     use_of_void_result.main();
   }, name: 'diagnostics');
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
new file mode 100644
index 0000000..dae29d6
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_getter_test.dart
@@ -0,0 +1,434 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/src/error/codes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TopLevelInstanceGetterTest);
+  });
+}
+
+@reflectiveTest
+class TopLevelInstanceGetterTest extends DriverResolutionTest {
+  test_call() async {
+    await assertNoErrorsInCode('''
+class A {
+  int Function() get g => () => 0;
+}
+var a = new A();
+var b = a.g();
+''');
+    TopLevelVariableDeclaration b = result.unit.declarations[2];
+    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
+  }
+
+  test_field() async {
+    await assertNoErrorsInCode('''
+class A {
+  int g;
+}
+var b = new A().g;
+''');
+    TopLevelVariableDeclaration b = result.unit.declarations[1];
+    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
+  }
+
+  test_field_call() async {
+    await assertNoErrorsInCode('''
+class A {
+  int Function() g;
+}
+var a = new A();
+var b = a.g();
+''');
+    TopLevelVariableDeclaration b = result.unit.declarations[2];
+    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
+  }
+
+  test_field_prefixedIdentifier() async {
+    await assertNoErrorsInCode('''
+class A {
+  int g;
+}
+var a = new A();
+var b = a.g;
+''');
+    TopLevelVariableDeclaration b = result.unit.declarations[2];
+    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
+  }
+
+  test_getter() async {
+    await assertNoErrorsInCode('''
+class A {
+  int get g => 0;
+}
+var b = new A().g;
+''');
+    TopLevelVariableDeclaration b = result.unit.declarations[1];
+    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
+  }
+
+  test_implicitlyTyped() async {
+    await assertErrorsInCode('''
+class A {
+  get g => 0;
+}
+var b = new A().g;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_call() async {
+    await assertErrorsInCode('''
+class A {
+  get g => () => 0;
+}
+var a = new A();
+var b = a.g();
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_field() async {
+    await assertErrorsInCode('''
+class A {
+  var g = 0;
+}
+var b = new A().g;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_field_call() async {
+    await assertErrorsInCode('''
+class A {
+  var g = () => 0;
+}
+var a = new A();
+var b = a.g();
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_field_prefixedIdentifier() async {
+    await assertErrorsInCode('''
+class A {
+  var g = 0;
+}
+var a = new A();
+var b = a.g;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_fn() async {
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
+class A {
+  var x = 0;
+}
+int f<T>(x) => 0;
+var a = new A();
+var b = f(a.x);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_fn_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+int f<T>(x) => 0;
+var a = new A();
+var b = f<int>(a.x);
+''');
+  }
+
+  test_implicitlyTyped_fn_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+int f(x) => 0;
+var a = new A();
+var b = f(a.x);
+''');
+  }
+
+  test_implicitlyTyped_indexExpression() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+  int operator[](int value) => 0;
+}
+var a = new A();
+var b = a[a.x];
+''');
+  }
+
+  test_implicitlyTyped_invoke() async {
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the
+    // closure is generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
+class A {
+  var x = 0;
+}
+var a = new A();
+var b = (<T>(y) => 0)(a.x);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_invoke_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+var a = new A();
+var b = (<T>(y) => 0)<int>(a.x);
+''');
+  }
+
+  test_implicitlyTyped_invoke_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+var a = new A();
+var b = ((y) => 0)(a.x);
+''');
+  }
+
+  test_implicitlyTyped_method() async {
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because f is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
+class A {
+  var x = 0;
+  int f<T>(int x) => 0;
+}
+var a = new A();
+var b = a.f(a.x);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_method_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+  int f<T>(x) => 0;
+}
+var a = new A();
+var b = a.f<int>(a.x);
+''');
+  }
+
+  test_implicitlyTyped_method_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+  int f(x) => 0;
+}
+var a = new A();
+var b = a.f(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new() async {
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
+class A {
+  var x = 0;
+}
+class B<T> {
+  B(x);
+}
+var a = new A();
+var b = new B(a.x);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_new_explicit_type_params() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+class B<T> {
+  B(x);
+}
+var a = new A();
+var b = new B<int>(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new_explicit_type_params_named() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+class B<T> {
+  B.named(x);
+}
+var a = new A();
+var b = new B<int>.named(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new_explicit_type_params_prefixed() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    newFile('/test/lib/lib1.dart', content: '''
+class B<T> {
+  B(x);
+}
+''');
+    await assertNoErrorsInCode('''
+import 'lib1.dart' as foo;
+class A {
+  var x = 0;
+}
+var a = new A();
+var b = new foo.B<int>(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new_named() async {
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
+class A {
+  var x = 0;
+}
+class B<T> {
+  B.named(x);
+}
+var a = new A();
+var b = new B.named(a.x);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_new_not_generic() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+class B {
+  B(x);
+}
+var a = new A();
+var b = new B(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new_not_generic_named() async {
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+class A {
+  var x = 0;
+}
+class B {
+  B.named(x);
+}
+var a = new A();
+var b = new B.named(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new_not_generic_prefixed() async {
+    newFile('/test/lib/lib1.dart', content: '''
+class B {
+  B(x);
+}
+''');
+    // The reference to a.x does not trigger TOP_LEVEL_INSTANCE_GETTER because
+    // it can't possibly affect the type of b.
+    await assertNoErrorsInCode('''
+import 'lib1.dart' as foo;
+class A {
+  var x = 0;
+}
+var a = new A();
+var b = new foo.B(a.x);
+''');
+  }
+
+  test_implicitlyTyped_new_prefixed() async {
+    newFile('/test/lib/lib1.dart', content: '''
+class B<T> {
+  B(x);
+}
+''');
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because B is
+    // generic, so the type of a.x might affect the type of b.
+    await assertErrorsInCode('''
+import 'lib1.dart' as foo;
+class A {
+  var x = 0;
+}
+var a = new A();
+var b = new foo.B(a.x);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_prefixedIdentifier() async {
+    await assertErrorsInCode('''
+class A {
+  get g => 0;
+}
+var a = new A();
+var b = a.g;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_implicitlyTyped_propertyAccessLhs() async {
+    // The reference to a.x triggers TOP_LEVEL_INSTANCE_GETTER because the type
+    // of a.x affects the lookup of y, which in turn affects the type of b.
+    await assertErrorsInCode('''
+class A {
+  var x = new B();
+  int operator[](int value) => 0;
+}
+class B {
+  int y;
+}
+var a = new A();
+var b = (a.x).y;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+  }
+
+  test_prefixedIdentifier() async {
+    await assertNoErrorsInCode('''
+class A {
+  int get g => 0;
+}
+var a = new A();
+var b = a.g;
+''');
+    TopLevelVariableDeclaration b = result.unit.declarations[2];
+    expect(b.variables.variables[0].declaredElement.type.toString(), 'int');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart b/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
new file mode 100644
index 0000000..4e6dde5
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/top_level_instance_method_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(TopLevelInstanceMethodTest);
+  });
+}
+
+@reflectiveTest
+class TopLevelInstanceMethodTest extends DriverResolutionTest {
+  test_noParameter() async {
+    await assertErrorsInCode('''
+class A {
+  f() => 0;
+}
+var x = new A().f();
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
+  }
+
+  test_parameter() async {
+    await assertNoErrorsInCode('''
+class A {
+  int f(v) => 0;
+}
+var x = new A().f(0);
+''');
+  }
+
+  test_parameter_generic() async {
+    await assertErrorsInCode('''
+class A {
+  int f<T>(v) => 0;
+}
+var x = new A().f(0);
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
+  }
+
+  test_parameter_generic_explicit() async {
+    await assertNoErrorsInCode('''
+class A {
+  int f<T>(v) => 0;
+}
+var x = new A().f<int>(0);
+''');
+  }
+
+  test_static() async {
+    await assertNoErrorsInCode('''
+class A {
+  static f() => 0;
+}
+var x = A.f();
+''');
+  }
+
+  test_tearOff() async {
+    await assertErrorsInCode('''
+class A {
+  f() => 0;
+}
+var x = new A().f;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
+  }
+
+  test_tearOff_parameter() async {
+    await assertErrorsInCode('''
+class A {
+  int f(v) => 0;
+}
+var x = new A().f;
+''', [StrongModeCode.TOP_LEVEL_INSTANCE_METHOD]);
+  }
+
+  test_tearoff_static() async {
+    await assertNoErrorsInCode('''
+class A {
+  static f() => 0;
+}
+var x = A.f;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_test.dart b/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_test.dart
new file mode 100644
index 0000000..a5d66af
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_check_is_not_null_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.
+
+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(TypeCheckIsNotNullTest);
+  });
+}
+
+@reflectiveTest
+class TypeCheckIsNotNullTest extends DriverResolutionTest {
+  test_not_Null() async {
+    await assertErrorsInCode(r'''
+bool m(i) {
+  return i is! Null;
+}
+''', [HintCode.TYPE_CHECK_IS_NOT_NULL]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/type_check_is_null_test.dart b/pkg/analyzer/test/src/diagnostics/type_check_is_null_test.dart
new file mode 100644
index 0000000..4f50661
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/type_check_is_null_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.
+
+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(TypeCheckIsNullTest);
+  });
+}
+
+@reflectiveTest
+class TypeCheckIsNullTest extends DriverResolutionTest {
+  test_is_Null() async {
+    await assertErrorsInCode(r'''
+bool m(i) {
+  return i is Null;
+}
+''', [HintCode.TYPE_CHECK_IS_NULL]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
new file mode 100644
index 0000000..36dc5fb
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unchecked_use_of_nullable_value_test.dart
@@ -0,0 +1,561 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UncheckedUseOfNullableValueTest);
+  });
+}
+
+@reflectiveTest
+class UncheckedUseOfNullableValueTest extends ResolverTestCase {
+  @override
+  List<String> get enabledExperiments => [EnableString.non_nullable];
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_and_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  bool x = true;
+  if(x && true) {}
+}
+''');
+  }
+
+  test_and_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  bool? x;
+  if(x && true) {}
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_as_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  num? x;
+  x as int;
+}
+''');
+  }
+
+  test_await_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() async {
+  Future x = Future.value(null);
+  await x;
+}
+''');
+  }
+
+  test_await_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() async {
+  Future? x;
+  await x;
+}
+''');
+  }
+
+  test_cascade_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x..isEven;
+}
+''');
+  }
+
+  test_cascade_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x..isEven;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_eq_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x == null;
+}
+''');
+  }
+
+  test_forLoop_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  List x = [];
+  for (var y in x) {}
+}
+''');
+  }
+
+  test_forLoop_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  List? x;
+  for (var y in x) {}
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_if_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  bool x = true;
+  if (x) {}
+}
+''');
+  }
+
+  test_if_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  bool? x;
+  if (x) {}
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_index_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  List x = [1];
+  x[0];
+}
+''');
+  }
+
+  test_index_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  List? x;
+  x[0];
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_invoke_dynamicFunctionType_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  Function x = () {};
+  x();
+}
+''');
+  }
+
+  @failingTest
+  test_invoke_dynamicFunctionType_nullable() async {
+    // test is failing because nullable function invocations aren't being
+    // resolved correctly
+    await assertErrorsInCode(r'''
+m() {
+  Function? x;
+  x();
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_invoke_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  Function() x = () {};
+  x();
+}
+''');
+  }
+
+  @failingTest
+  test_invoke_nullable() async {
+    // test is failing because nullable function invocations aren't being
+    // resolved correctly
+    await assertErrorsInCode(r'''
+m() {
+  Function()? x;
+  x();
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_invoke_parenthesized_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  Function x = () {};
+  (x)();
+}
+''');
+  }
+
+  test_is_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x is int;
+}
+''');
+  }
+
+  test_member_hashCode_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x.hashCode;
+}
+''');
+  }
+
+  test_member_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x.isEven;
+}
+''');
+  }
+
+  test_member_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x.isEven;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_member_parenthesized_hashCode_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  (x).hashCode;
+}
+''');
+  }
+
+  test_member_parenthesized_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  (x).isEven;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_member_parenthesized_runtimeType_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  (x).runtimeType;
+}
+''');
+  }
+
+  test_member_questionDot_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x?.isEven;
+}
+''');
+  }
+
+  test_member_runtimeType_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x.runtimeType;
+}
+''');
+  }
+
+  test_method_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x.round();
+}
+''');
+  }
+
+  test_method_noSuchMethod_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x;
+  x.noSuchMethod(null);
+}
+''');
+  }
+
+  test_method_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x.round();
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_method_questionDot_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x?.round();
+}
+''');
+  }
+
+  test_method_toString_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x;
+  x.toString();
+}
+''');
+  }
+
+  test_minusEq_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x -= 1;
+}
+''');
+  }
+
+  test_minusEq_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x -= 1;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_not_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  bool x = true;
+  if(!x) {}
+}
+''');
+  }
+
+  test_not_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  bool? x;
+  if(!x) {}
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_notEq_nullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int? x;
+  x != null;
+}
+''');
+  }
+
+  test_operatorMinus_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x - 3;
+}
+''');
+  }
+
+  test_operatorMinus_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x - 3;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_operatorPlus_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x + 3;
+}
+''');
+  }
+
+  test_operatorPlus_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x + 3;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_operatorPostfixDec_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  x--;
+}
+''');
+  }
+
+  test_operatorPostfixDec_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x--;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_operatorPostfixInc_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x;
+  x++;
+}
+''');
+  }
+
+  test_operatorPostfixInc_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x++;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_operatorPrefixDec_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  --x;
+}
+''');
+  }
+
+  test_operatorPrefixDec_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  --x;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_operatorPrefixInc_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x;
+  ++x;
+}
+''');
+  }
+
+  test_operatorPrefixInc_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  ++x;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_operatorUnaryMinus_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x = 0;
+  -x;
+}
+''');
+  }
+
+  test_operatorUnaryMinus_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  -x;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_or_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  bool x = true;
+  if(x || false) {}
+}
+''');
+  }
+
+  test_or_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  bool? x;
+  if(x || false) {}
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_plusEq_nonNullable() async {
+    await assertNoErrorsInCode(r'''
+m() {
+  int x;
+  x += 1;
+}
+''');
+  }
+
+  test_plusEq_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  int? x;
+  x += 1;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_ternary_condition_nullable() async {
+    await assertErrorsInCode(r'''
+m() {
+  bool? x;
+  x ? 0 : 1;
+}
+''', [StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE]);
+  }
+
+  test_ternary_lhs_nullable() async {
+    await assertNoErrorsInCode(r'''
+m(bool cond) {
+  int? x;
+  cond ? x : 1;
+}
+''');
+  }
+
+  test_ternary_rhs_nullable() async {
+    await assertNoErrorsInCode(r'''
+m(bool cond) {
+  int? x;
+  cond ? 0 : x;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_getter_test.dart
new file mode 100644
index 0000000..e0f34b6
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_getter_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.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UndefinedGetterTest);
+    defineReflectiveTests(UndefinedGetterWithControlFlowCollectionsTest);
+  });
+}
+
+@reflectiveTest
+class UndefinedGetterTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_ifStatement_notPromoted() async {
+    await assertErrorsInCode('''
+f(int x) {
+  if (x is String) {
+    x.length;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
+  }
+
+  test_ifStatement_promoted() async {
+    await assertNoErrorsInCode('''
+f(Object x) {
+  if (x is String) {
+    x.length;
+  }
+}
+''');
+  }
+
+  test_promotedTypeParameter_regress35305() async {
+    await assertErrorsInCode(r'''
+void f<X extends num, Y extends X>(Y y) {
+  if (y is int) {
+    y.isEven;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
+  }
+}
+
+@reflectiveTest
+class UndefinedGetterWithControlFlowCollectionsTest extends ResolverTestCase {
+  @override
+  List<String> get enabledExperiments =>
+      [EnableString.control_flow_collections, EnableString.set_literals];
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_ifElement_inList_notPromoted() async {
+    await assertErrorsInCode('''
+f(int x) {
+  return [if (x is String) x.length];
+}
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
+  }
+
+  test_ifElement_inList_promoted() async {
+    await assertNoErrorsInCode('''
+f(Object x) {
+  return [if (x is String) x.length];
+}
+''');
+  }
+
+  test_ifElement_inMap_notPromoted() async {
+    await assertErrorsInCode('''
+f(int x) {
+  return {if (x is String) x : x.length};
+}
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
+  }
+
+  test_ifElement_inMap_promoted() async {
+    await assertNoErrorsInCode('''
+f(Object x) {
+  return {if (x is String) x : x.length};
+}
+''');
+  }
+
+  test_ifElement_inSet_notPromoted() async {
+    await assertErrorsInCode('''
+f(int x) {
+  return {if (x is String) x.length};
+}
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
+  }
+
+  test_ifElement_inSet_promoted() async {
+    await assertNoErrorsInCode('''
+f(Object x) {
+  return {if (x is String) x.length};
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.dart
new file mode 100644
index 0000000..3391749
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_hidden_name_test.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 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UndefinedHiddenNameTest);
+  });
+}
+
+@reflectiveTest
+class UndefinedHiddenNameTest extends DriverResolutionTest {
+  test_export() async {
+    newFile('/test/lib/lib1.dart');
+    await assertErrorsInCode(r'''
+export 'lib1.dart' hide a;
+''', [HintCode.UNDEFINED_HIDDEN_NAME]);
+  }
+
+  test_import() async {
+    newFile('/test/lib/lib1.dart');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' hide a;
+''', [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_HIDDEN_NAME]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
new file mode 100644
index 0000000..b05ef9b
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_operator_test.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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(UndefinedOperatorTest);
+  });
+}
+
+@reflectiveTest
+class UndefinedOperatorTest extends DriverResolutionTest {
+  test_binaryExpression() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(var a) {
+  if (a is A) {
+    a + 1;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_binaryExpression_inSubtype() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  operator +(B b) {}
+}
+f(var a) {
+  if (a is A) {
+    a + 1;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_indexBoth() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(var a) {
+  if (a is A) {
+    a[0]++;
+  }
+}
+''', [
+      StaticTypeWarningCode.UNDEFINED_OPERATOR,
+      StaticTypeWarningCode.UNDEFINED_OPERATOR,
+    ]);
+  }
+
+  test_indexBoth_inSubtype() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  operator [](int index) {}
+}
+f(var a) {
+  if (a is A) {
+    a[0]++;
+  }
+}
+''', [
+      StaticTypeWarningCode.UNDEFINED_OPERATOR,
+      StaticTypeWarningCode.UNDEFINED_OPERATOR,
+    ]);
+  }
+
+  test_indexGetter() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(var a) {
+  if (a is A) {
+    a[0];
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_indexGetter_inSubtype() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  operator [](int index) {}
+}
+f(var a) {
+  if (a is A) {
+    a[0];
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_indexSetter() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(var a) {
+  if (a is A) {
+    a[0] = 1;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_indexSetter_inSubtype() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  operator []=(i, v) {}
+}
+f(var a) {
+  if (a is A) {
+    a[0] = 1;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+  }
+
+  test_postfixExpression() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+f(var a) {
+  if (a is A) {
+    a++;
+  }
+}
+''');
+  }
+
+  test_postfixExpression_inSubtype() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B extends A {
+  operator +(B b) {return new B();}
+}
+f(var a) {
+  if (a is A) {
+    a++;
+  }
+}
+''');
+  }
+
+  test_prefixExpression() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+f(var a) {
+  if (a is A) {
+    ++a;
+  }
+}
+''');
+  }
+
+  test_prefixExpression_inSubtype() async {
+    await assertNoErrorsInCode(r'''
+class A {}
+class B extends A {
+  operator +(B b) {return new B();}
+}
+f(var a) {
+  if (a is A) {
+    ++a;
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
new file mode 100644
index 0000000..fd9bafd
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_setter_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UndefinedSetterTest);
+  });
+}
+
+@reflectiveTest
+class UndefinedSetterTest extends DriverResolutionTest {
+  test_inSubtype() async {
+    await assertErrorsInCode(r'''
+class A {}
+class B extends A {
+  set b(x) {}
+}
+f(var a) {
+  if (a is A) {
+    a.b = 0;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+
+  test_inType() async {
+    await assertErrorsInCode(r'''
+class A {}
+f(var a) {
+  if(a is A) {
+    a.m = 0;
+  }
+}
+''', [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.dart
new file mode 100644
index 0000000..9bbc57a
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/undefined_shown_name_test.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 'package:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UndefinedShownNameTest);
+  });
+}
+
+@reflectiveTest
+class UndefinedShownNameTest extends DriverResolutionTest {
+  test_export() async {
+    newFile('/test/lib/lib1.dart');
+    await assertErrorsInCode(r'''
+export 'lib1.dart' show a;
+''', [HintCode.UNDEFINED_SHOWN_NAME]);
+  }
+
+  test_import() async {
+    newFile('/test/lib/lib1.dart');
+    await assertErrorsInCode(r'''
+import 'lib1.dart' show a;
+''', [HintCode.UNUSED_IMPORT, HintCode.UNDEFINED_SHOWN_NAME]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart
index 507e656..28e76bf 100644
--- a/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_cast_test.dart
@@ -10,7 +10,6 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UnnecessaryCastTest);
-    defineReflectiveTests(UnnecessaryCastTest_Driver);
   });
 }
 
@@ -58,17 +57,6 @@
 ''');
   }
 
-  test_generics() async {
-    // dartbug.com/18953
-    await assertNoErrorsInCode(r'''
-import 'dart:async';
-Future<int> f() => new Future.value(0);
-void g(bool c) {
-  (c ? f(): new Future.value(0) as Future<int>).then((int value) {});
-}
-''');
-  }
-
   test_parameter_A() async {
     // dartbug.com/13855, dartbug.com/13732
     await assertNoErrorsInCode(r'''
@@ -107,14 +95,10 @@
 }
 ''', [HintCode.UNNECESSARY_CAST]);
   }
-}
 
-@reflectiveTest
-class UnnecessaryCastTest_Driver extends UnnecessaryCastTest {
   @override
   bool get enableNewAnalysisDriver => true;
 
-  @override
   test_generics() async {
     // dartbug.com/18953
     assertErrorsInCode(r'''
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart
new file mode 100644
index 0000000..e6f36ad
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_no_such_method_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnnecessaryNoSuchMethodTest);
+  });
+}
+
+@reflectiveTest
+class UnnecessaryNoSuchMethodTest extends DriverResolutionTest {
+  test_blockBody() async {
+    await assertErrorsInCode(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    return super.noSuchMethod(y);
+  }
+}
+''', [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+  }
+
+  test_blockBody_notReturnStatement() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    print(y);
+  }
+}
+''');
+  }
+
+  test_blockBody_notSingleStatement() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    print(y);
+    return super.noSuchMethod(y);
+  }
+}
+''');
+  }
+
+  test_expressionBody() async {
+    await assertErrorsInCode(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => super.noSuchMethod(y);
+}
+''', [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+  }
+
+  test_expressionBody_notNoSuchMethod() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => super.hashCode;
+}
+''');
+  }
+
+  test_expressionBody_notSuper() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => 42;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart
new file mode 100644
index 0000000..6b48d25
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_false_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnnecessaryTypeCheckFalseTest);
+  });
+}
+
+@reflectiveTest
+class UnnecessaryTypeCheckFalseTest extends DriverResolutionTest {
+  test_null_not_Null() async {
+    await assertErrorsInCode(r'''
+bool b = null is! Null;
+''', [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+  }
+
+  test_type_not_dynamic() async {
+    await assertErrorsInCode(r'''
+m(i) {
+  bool b = i is! dynamic;
+}
+''', [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+  }
+
+  test_type_not_object() async {
+    await assertErrorsInCode(r'''
+m(i) {
+  bool b = i is! Object;
+}
+''', [HintCode.UNNECESSARY_TYPE_CHECK_FALSE]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart
new file mode 100644
index 0000000..44e96ea
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unnecessary_type_check_true_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnnecessaryTypeCheckTrueTest);
+  });
+}
+
+@reflectiveTest
+class UnnecessaryTypeCheckTrueTest extends DriverResolutionTest {
+  test_null_is_Null() async {
+    await assertErrorsInCode(r'''
+bool b = null is Null;
+''', [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+  }
+
+  test_type_is_dynamic() async {
+    await assertErrorsInCode(r'''
+m(i) {
+  bool b = i is dynamic;
+}
+''', [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+  }
+
+  test_type_is_object() async {
+    await assertErrorsInCode(r'''
+m(i) {
+  bool b = i is Object;
+}
+''', [HintCode.UNNECESSARY_TYPE_CHECK_TRUE]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart b/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart
new file mode 100644
index 0000000..841f0df
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unused_catch_clause_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnusedCatchClauseTest);
+  });
+}
+
+@reflectiveTest
+class UnusedCatchClauseTest extends DriverResolutionTest {
+  @override
+  bool get enableUnusedLocalVariable => true;
+
+  test_on_unusedException() async {
+    await assertErrorsInCode(r'''
+main() {
+  try {
+  } on String catch (exception) {
+  }
+}
+''', [HintCode.UNUSED_CATCH_CLAUSE]);
+  }
+
+  test_on_usedException() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  try {
+  } on String catch (exception) {
+    print(exception);
+  }
+}
+''');
+  }
+
+  test_unusedException() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  try {
+  } catch (exception) {
+  }
+}
+''');
+  }
+
+  test_usedException() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  try {
+  } catch (exception) {
+    print(exception);
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart b/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart
new file mode 100644
index 0000000..0a7330b
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unused_catch_stack_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnusedCatchStackTest);
+  });
+}
+
+@reflectiveTest
+class UnusedCatchStackTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_on_unusedStack() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+main() {
+  try {
+  } on String catch (exception, stackTrace) {
+  }
+}
+''', [HintCode.UNUSED_CATCH_STACK]);
+  }
+
+  test_on_usedStack() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+main() {
+  try {
+  } on String catch (exception, stackTrace) {
+    print(stackTrace);
+  }
+}
+''');
+  }
+
+  test_unusedStack() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+main() {
+  try {
+  } catch (exception, stackTrace) {
+  }
+}
+''', [HintCode.UNUSED_CATCH_STACK]);
+  }
+
+  test_usedStack() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+main() {
+  try {
+  } catch (exception, stackTrace) {
+    print(stackTrace);
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
new file mode 100644
index 0000000..871023a
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
@@ -0,0 +1,577 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnusedElementTest);
+  });
+}
+
+@reflectiveTest
+class UnusedElementTest extends DriverResolutionTest {
+  @override
+  bool get enableUnusedElement => true;
+
+  test_class_isUsed_extends() async {
+    await assertNoErrorsInCode(r'''
+class _A {}
+class B extends _A {}
+''');
+  }
+
+  test_class_isUsed_fieldDeclaration() async {
+    await assertNoErrorsInCode(r'''
+class Foo {
+  _Bar x;
+}
+
+class _Bar {
+}
+''');
+  }
+
+  test_class_isUsed_implements() async {
+    await assertNoErrorsInCode(r'''
+class _A {}
+class B implements _A {}
+''');
+  }
+
+  test_class_isUsed_instanceCreation() async {
+    await assertNoErrorsInCode(r'''
+class _A {}
+main() {
+  new _A();
+}
+''');
+  }
+
+  test_class_isUsed_staticFieldAccess() async {
+    await assertNoErrorsInCode(r'''
+class _A {
+  static const F = 42;
+}
+main() {
+  _A.F;
+}
+''');
+  }
+
+  test_class_isUsed_staticMethodInvocation() async {
+    await assertNoErrorsInCode(r'''
+class _A {
+  static m() {}
+}
+main() {
+  _A.m();
+}
+''');
+  }
+
+  test_class_isUsed_typeArgument() async {
+    await assertNoErrorsInCode(r'''
+class _A {}
+main() {
+  var v = new List<_A>();
+  print(v);
+}
+''');
+  }
+
+  test_class_notUsed_inClassMember() async {
+    await assertErrorsInCode(r'''
+class _A {
+  static staticMethod() {
+    new _A();
+  }
+  instanceMethod() {
+    new _A();
+  }
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_class_notUsed_inConstructorName() async {
+    await assertErrorsInCode(r'''
+class _A {
+  _A() {}
+  _A.named() {}
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_class_notUsed_isExpression() async {
+    await assertErrorsInCode(r'''
+class _A {}
+main(p) {
+  if (p is _A) {
+  }
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_class_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+class _A {}
+main() {
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_class_notUsed_variableDeclaration() async {
+    await assertErrorsInCode(r'''
+class _A {}
+main() {
+  _A v;
+  print(v);
+}
+print(x) {}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_enum_isUsed_fieldReference() async {
+    await assertNoErrorsInCode(r'''
+enum _MyEnum {A, B, C}
+main() {
+  print(_MyEnum.B);
+}
+''');
+  }
+
+  test_enum_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+enum _MyEnum {A, B, C}
+main() {
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_functionLocal_isUsed_closure() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  print(() {});
+}
+print(x) {}
+''');
+  }
+
+  test_functionLocal_isUsed_invocation() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  f() {}
+  f();
+}
+''');
+  }
+
+  test_functionLocal_isUsed_reference() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  f() {}
+  print(f);
+}
+print(x) {}
+''');
+  }
+
+  test_functionLocal_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+main() {
+  f() {}
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_functionLocal_notUsed_referenceFromItself() async {
+    await assertErrorsInCode(r'''
+main() {
+  _f(int p) {
+    _f(p - 1);
+  }
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_functionTop_isUsed_invocation() async {
+    await assertNoErrorsInCode(r'''
+_f() {}
+main() {
+  _f();
+}
+''');
+  }
+
+  test_functionTop_isUsed_reference() async {
+    await assertNoErrorsInCode(r'''
+_f() {}
+main() {
+  print(_f);
+}
+print(x) {}
+''');
+  }
+
+  test_functionTop_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+_f() {}
+main() {
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_functionTop_notUsed_referenceFromItself() async {
+    await assertErrorsInCode(r'''
+_f(int p) {
+  _f(p - 1);
+}
+main() {
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_functionTypeAlias_isUsed_isExpression() async {
+    await assertNoErrorsInCode(r'''
+typedef _F(a, b);
+main(f) {
+  if (f is _F) {
+    print('F');
+  }
+}
+''');
+  }
+
+  test_functionTypeAlias_isUsed_reference() async {
+    await assertNoErrorsInCode(r'''
+typedef _F(a, b);
+main(_F f) {
+}
+''');
+  }
+
+  test_functionTypeAlias_isUsed_typeArgument() async {
+    await assertNoErrorsInCode(r'''
+typedef _F(a, b);
+main() {
+  var v = new List<_F>();
+  print(v);
+}
+''');
+  }
+
+  test_functionTypeAlias_isUsed_variableDeclaration() async {
+    await assertNoErrorsInCode(r'''
+typedef _F(a, b);
+class A {
+  _F f;
+}
+''');
+  }
+
+  test_functionTypeAlias_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+typedef _F(a, b);
+main() {
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_getter_isUsed_invocation_implicitThis() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  get _g => null;
+  useGetter() {
+    var v = _g;
+  }
+}
+''');
+  }
+
+  test_getter_isUsed_invocation_PrefixedIdentifier() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  get _g => null;
+}
+main(A a) {
+  var v = a._g;
+}
+''');
+  }
+
+  test_getter_isUsed_invocation_PropertyAccess() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  get _g => null;
+}
+main() {
+  var v = new A()._g;
+}
+''');
+  }
+
+  test_getter_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+class A {
+  get _g => null;
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_getter_notUsed_referenceFromItself() async {
+    await assertErrorsInCode(r'''
+class A {
+  get _g {
+    return _g;
+  }
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_method_isUsed_hasReference_implicitThis() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+  useMethod() {
+    print(_m);
+  }
+}
+print(x) {}
+''');
+  }
+
+  test_method_isUsed_hasReference_implicitThis_subclass() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+  useMethod() {
+    print(_m);
+  }
+}
+class B extends A {
+  _m() {}
+}
+print(x) {}
+''');
+  }
+
+  test_method_isUsed_hasReference_PrefixedIdentifier() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+}
+main(A a) {
+  a._m;
+}
+''');
+  }
+
+  test_method_isUsed_hasReference_PropertyAccess() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+}
+main() {
+  new A()._m;
+}
+''');
+  }
+
+  test_method_isUsed_invocation_implicitThis() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+  useMethod() {
+    _m();
+  }
+}
+''');
+  }
+
+  test_method_isUsed_invocation_implicitThis_subclass() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+  useMethod() {
+    _m();
+  }
+}
+class B extends A {
+  _m() {}
+}
+''');
+  }
+
+  test_method_isUsed_invocation_MemberElement() async {
+    await assertNoErrorsInCode(r'''
+class A<T> {
+  _m(T t) {}
+}
+main(A<int> a) {
+  a._m(0);
+}
+''');
+  }
+
+  test_method_isUsed_invocation_propagated() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+}
+main() {
+  var a = new A();
+  a._m();
+}
+''');
+  }
+
+  test_method_isUsed_invocation_static() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+}
+main() {
+  A a = new A();
+  a._m();
+}
+''');
+  }
+
+  test_method_isUsed_invocation_subclass() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  _m() {}
+}
+class B extends A {
+  _m() {}
+}
+main(A a) {
+  a._m();
+}
+''');
+  }
+
+  test_method_isUsed_notPrivate() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  m() {}
+}
+main() {
+}
+''');
+  }
+
+  test_method_isUsed_staticInvocation() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  static _m() {}
+}
+main() {
+  A._m();
+}
+''');
+  }
+
+  test_method_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+class A {
+  static _m() {}
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_method_notUsed_referenceFromItself() async {
+    await assertErrorsInCode(r'''
+class A {
+  static _m(int p) {
+    _m(p - 1);
+  }
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_setter_isUsed_invocation_implicitThis() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  set _s(x) {}
+  useSetter() {
+    _s = 42;
+  }
+}
+''');
+  }
+
+  test_setter_isUsed_invocation_PrefixedIdentifier() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  set _s(x) {}
+}
+main(A a) {
+  a._s = 42;
+}
+''');
+  }
+
+  test_setter_isUsed_invocation_PropertyAccess() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  set _s(x) {}
+}
+main() {
+  new A()._s = 42;
+}
+''');
+  }
+
+  test_setter_notUsed_noReference() async {
+    await assertErrorsInCode(r'''
+class A {
+  set _s(x) {}
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_setter_notUsed_referenceFromItself() async {
+    await assertErrorsInCode(r'''
+class A {
+  set _s(int x) {
+    if (x > 5) {
+      _s = x - 1;
+    }
+  }
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+
+  test_topLevelVariable_isUsed() async {
+    await assertNoErrorsInCode(r'''
+int _a = 1;
+main() {
+  _a;
+}
+''');
+  }
+
+  test_topLevelVariable_isUsed_plusPlus() async {
+    await assertNoErrorsInCode(r'''
+int _a = 0;
+main() {
+  var b = _a++;
+  b;
+}
+''');
+  }
+
+  test_topLevelVariable_notUsed() async {
+    await assertErrorsInCode(r'''
+int _a = 1;
+main() {
+  _a = 2;
+}
+''', [HintCode.UNUSED_ELEMENT]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
index 6a60a1b..3fa352c 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_field_test.dart
@@ -10,13 +10,15 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UnusedFieldTest);
-    defineReflectiveTests(UnusedFieldTest_Driver);
   });
 }
 
 @reflectiveTest
 class UnusedFieldTest extends ResolverTestCase {
   @override
+  bool get enableNewAnalysisDriver => true;
+
+  @override
   bool get enableUnusedElement => true;
 
   test_unusedField_isUsed_argument() async {
@@ -190,9 +192,3 @@
 ''', [HintCode.UNUSED_FIELD]);
   }
 }
-
-@reflectiveTest
-class UnusedFieldTest_Driver extends UnusedFieldTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
index e930e3e..34319e4 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_import_test.dart
@@ -11,12 +11,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UnusedImportTest);
-    defineReflectiveTests(UnusedImportTest_Driver);
   });
 }
 
 @reflectiveTest
 class UnusedImportTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_annotationOnDirective() async {
     Source source = addSource(r'''
 library L;
@@ -313,9 +315,3 @@
     verify([source, source2]);
   }
 }
-
-@reflectiveTest
-class UnusedImportTest_Driver extends UnusedImportTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_label_test.dart b/pkg/analyzer/test/src/diagnostics/unused_label_test.dart
index 7609554..e14f291 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_label_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_label_test.dart
@@ -10,12 +10,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UnusedLabelTest);
-    defineReflectiveTests(UnusedLabelTest_Driver);
   });
 }
 
 @reflectiveTest
 class UnusedLabelTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_unused_inSwitch() async {
     await assertErrorsInCode(r'''
 f(x) {
@@ -62,9 +64,3 @@
 ''');
   }
 }
-
-@reflectiveTest
-class UnusedLabelTest_Driver extends UnusedLabelTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart b/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart
new file mode 100644
index 0000000..ee12d06
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/unused_local_variable_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/resolver_test_case.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(UnusedLocalVariableTest);
+  });
+}
+
+@reflectiveTest
+class UnusedLocalVariableTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_inFor_underscore_ignored() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+main() {
+  for (var _ in [1,2,3]) {
+    for (var __ in [4,5,6]) {
+      // do something
+    }
+  }
+}
+''');
+  }
+
+  test_inFunction() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+main() {
+  var v = 1;
+  v = 2;
+}
+''', [HintCode.UNUSED_LOCAL_VARIABLE]);
+  }
+
+  test_inMethod() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+class A {
+  foo() {
+    var v = 1;
+    v = 2;
+  }
+}
+''', [HintCode.UNUSED_LOCAL_VARIABLE]);
+  }
+
+  test_isInvoked() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+typedef Foo();
+main() {
+  Foo foo;
+  foo();
+}
+''');
+  }
+
+  test_isNullAssigned() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+typedef Foo();
+main() {
+  var v;
+  v ??= doSomething();
+}
+doSomething() => 42;
+''');
+  }
+
+  test_isRead_notUsed_compoundAssign() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+main() {
+  var v = 1;
+  v += 2;
+}
+''', [HintCode.UNUSED_LOCAL_VARIABLE]);
+  }
+
+  test_isRead_notUsed_postfixExpr() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+main() {
+  var v = 1;
+  v++;
+}
+''', [HintCode.UNUSED_LOCAL_VARIABLE]);
+  }
+
+  test_isRead_notUsed_prefixExpr() async {
+    enableUnusedLocalVariable = true;
+    await assertErrorsInCode(r'''
+main() {
+  var v = 1;
+  ++v;
+}
+''', [HintCode.UNUSED_LOCAL_VARIABLE]);
+  }
+
+  test_isRead_usedArgument() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+main() {
+  var v = 1;
+  print(++v);
+}
+print(x) {}
+''');
+  }
+
+  test_isRead_usedInvocationTarget() async {
+    enableUnusedLocalVariable = true;
+    await assertNoErrorsInCode(r'''
+class A {
+  foo() {}
+}
+main() {
+  var a = new A();
+  a.foo();
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart b/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart
index 8fba003..7b9f834 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_shown_name_test.dart
@@ -11,12 +11,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UnusedShownNameTest);
-    defineReflectiveTests(UnusedShownNameTest_Driver);
   });
 }
 
 @reflectiveTest
 class UnusedShownNameTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_unreferenced() async {
     Source source = addSource(r'''
 library L;
@@ -99,9 +101,3 @@
     verify([source, source2]);
   }
 }
-
-@reflectiveTest
-class UnusedShownNameTest_Driver extends UnusedShownNameTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
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 f44a502..dfe12c9 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
@@ -9,12 +9,14 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(UseOfVoidResultTest);
-    defineReflectiveTests(UseOfVoidResultTest_Driver);
   });
 }
 
 @reflectiveTest
 class UseOfVoidResultTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
   test_implicitReturnValue() async {
     await assertNoErrorsInCode(r'''
 f() {}
@@ -35,9 +37,3 @@
 ''');
   }
 }
-
-@reflectiveTest
-class UseOfVoidResultTest_Driver extends UseOfVoidResultTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-}
diff --git a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
index ebcd8d0..ad6a248 100644
--- a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
@@ -57,9 +57,9 @@
 
   void test_missingColonAndValue_last() {
     testRecovery('''
-f() => {a };
+f() => {a: b, c };
 ''', [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.MISSING_IDENTIFIER], '''
-f() => {a: _s_};
+f() => {a: b, c: _s_};
 ''');
   }
 
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
index 247cc34..2d7ef0f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/forEach_statement_test.dart
@@ -63,6 +63,8 @@
                 ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.MISSING_IDENTIFIER,
+                // TODO(danrubel): investigate why 4 missing identifier errors
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN,
                 ParserErrorCode.EXPECTED_TOKEN
               ],
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 49e4be9..c8aed44 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
@@ -50,7 +50,8 @@
         contextUnit,
         analysisResult.session.declaredVariables,
         analysisResult.typeProvider,
-        analysisResult.typeSystem);
+        analysisResult.typeSystem,
+        analysisOptions);
   }
 
   void test_canBeConst_false_argument_invocation() async {
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
new file mode 100644
index 0000000..2f03798
--- /dev/null
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -0,0 +1,2252 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AvailableDeclarationsTest);
+    defineReflectiveTests(ChangeFileTest);
+    defineReflectiveTests(DeclarationTest);
+    defineReflectiveTests(ExportTest);
+    defineReflectiveTests(GetLibrariesTest);
+  });
+}
+
+class AbstractContextTest with ResourceProviderMixin {
+  final byteStore = MemoryByteStore();
+
+  AnalysisContextCollection analysisContextCollection;
+
+  AnalysisContext testAnalysisContext;
+
+  void addDotPackagesDependency(String path, String name, String rootPath) {
+    var packagesFile = getFile(path);
+
+    String packagesContent;
+    try {
+      packagesContent = packagesFile.readAsStringSync();
+    } catch (_) {
+      packagesContent = '';
+    }
+
+    // Ignore if there is already the same package dependency.
+    if (packagesContent.contains('$name:file://')) {
+      return;
+    }
+
+    rootPath = convertPath(rootPath);
+    packagesContent += '$name:${toUri('$rootPath/lib')}\n';
+
+    packagesFile.writeAsStringSync(packagesContent);
+
+    createAnalysisContexts();
+  }
+
+  void addTestPackageDependency(String name, String rootPath) {
+    addDotPackagesDependency('/home/test/.packages', name, rootPath);
+  }
+
+  /// Create all analysis contexts in `/home`.
+  void createAnalysisContexts() {
+    analysisContextCollection = AnalysisContextCollectionImpl(
+      includedPaths: [convertPath('/home')],
+      resourceProvider: resourceProvider,
+      sdkPath: convertPath('/sdk'),
+    );
+
+    var testPath = convertPath('/home/test');
+    testAnalysisContext = getContext(testPath);
+  }
+
+  /// Return the existing analysis context that should be used to analyze the
+  /// given [path], or throw [StateError] if the [path] is not analyzed in any
+  /// of the created analysis contexts.
+  AnalysisContext getContext(String path) {
+    path = convertPath(path);
+    return analysisContextCollection.contextFor(path);
+  }
+
+  setUp() {
+    new MockSdk(resourceProvider: resourceProvider);
+
+    newFolder('/home/test');
+    newFile('/home/test/.packages', content: '''
+test:${toUri('/home/test/lib')}
+''');
+
+    createAnalysisContexts();
+  }
+}
+
+@reflectiveTest
+class AvailableDeclarationsTest extends _Base {
+  test_changesStream_noDuplicates() async {
+    newFile('/home/aaa/lib/a.dart', content: 'class A {}');
+
+    newFile('/home/bbb/pubspec.yaml', content: r'''
+dependencies:
+  aaa: any
+''');
+    addDotPackagesDependency('/home/bbb/.packages', 'aaa', '/home/aaa');
+    newFile('/home/bbb/lib/b.dart', content: 'class B {}');
+
+    newFile('/home/ccc/pubspec.yaml', content: r'''
+dependencies:
+  aaa: any
+''');
+    addDotPackagesDependency('/home/ccc/.packages', 'aaa', '/home/aaa');
+    newFile('/home/ccc/lib/c.dart', content: 'class C {}');
+
+    createAnalysisContexts();
+
+    var bPath = convertPath('/home/bbb');
+    var cPath = convertPath('/home/ccc');
+
+    var bAnalysisContext = analysisContextCollection.contextFor(bPath);
+    var cAnalysisContext = analysisContextCollection.contextFor(cPath);
+
+    tracker.addContext(bAnalysisContext);
+    tracker.addContext(cAnalysisContext);
+    await _doAllTrackerWork();
+
+    var uniquePathSet = Set<String>();
+    for (var change in changes) {
+      for (var library in change.changed) {
+        if (!uniquePathSet.add(library.path)) {
+          fail('Not unique path: ${library.path}');
+        }
+      }
+    }
+  }
+
+  test_discardContexts() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+class A {}
+''');
+
+    // No libraries initially.
+    expect(uriToLibrary, isEmpty);
+
+    // Add the context, and discard everything immediately.
+    tracker.addContext(testAnalysisContext);
+    tracker.discardContexts();
+
+    // There is no context.
+    expect(tracker.getContext(testAnalysisContext), isNull);
+
+    // There is no work to do.
+    expect(tracker.hasWork, isFalse);
+    await _doAllTrackerWork();
+
+    // So, there are no new libraries.
+    expect(uriToLibrary, isEmpty);
+  }
+
+  test_getContext() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+''');
+    var addContext = tracker.addContext(testAnalysisContext);
+    expect(tracker.getContext(testAnalysisContext), same(addContext));
+  }
+
+  test_getLibrary() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+
+    var id = uriToLibrary['package:test/test.dart'].id;
+    var library = tracker.getLibrary(id);
+    expect(library.id, id);
+    expect(library.uriStr, 'package:test/test.dart');
+  }
+
+  test_readByteStore() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    newFile('/home/test/lib/b.dart', content: r'''
+class B {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart' show A;
+part 'b.dart';
+class C {}
+enum E {v}
+''');
+
+    // The byte store is empty, fill it.
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    // Re-create tracker, will read from byte store.
+    _createTracker();
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.enum_('E'),
+      _ExpectedDeclaration.enumConstant('v', 'E'),
+    ]);
+  }
+
+  static Future pumpEventQueue([int times = 5000]) {
+    if (times == 0) return new Future.value();
+    return new Future.delayed(Duration.zero, () => pumpEventQueue(times - 1));
+  }
+}
+
+@reflectiveTest
+class ChangeFileTest extends _Base {
+  test_added_exported() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+    var d = convertPath('/home/test/lib/d.dart');
+
+    newFile(a, content: r'''
+export 'b.dart';
+class A {}
+''');
+    newFile(b, content: r'''
+export 'c.dart';
+class B {}
+''');
+    newFile(d, content: r'''
+class D {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasNoLibrary('package:test/c.dart');
+    _assertHasLibrary('package:test/d.dart', declarations: [
+      _ExpectedDeclaration.class_('D'),
+    ]);
+
+    newFile(c, content: r'''
+class C {}
+''');
+    tracker.changeFile(c);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/d.dart', declarations: [
+      _ExpectedDeclaration.class_('D'),
+    ]);
+  }
+
+  test_added_library() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+
+    newFile(a, content: r'''
+class A {}
+''');
+    var declarationsContext = tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasNoLibrary('package:test/b.dart');
+
+    newFile(b, content: r'''
+class B {}
+''');
+    tracker.changeFile(b);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+
+    var librariesObject = declarationsContext.getLibraries(
+      '/home/test/lib/test.dart',
+    );
+    expect(
+      librariesObject.context.map((library) => library.uriStr).toSet(),
+      containsAll(['package:test/a.dart', 'package:test/b.dart']),
+    );
+  }
+
+  test_added_part() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+
+    newFile(a, content: r'''
+part 'b.dart';
+class A {}
+''');
+    newFile(c, content: r'''
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasNoLibrary('package:test/b.dart');
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+
+    newFile(b, content: r'''
+part of 'a.dart';
+class B {}
+''');
+    tracker.changeFile(b);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasNoLibrary('package:test/b.dart');
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+
+  test_chooseContext_inAnalysisRoot() async {
+    var homePath = convertPath('/home');
+    var testPath = convertPath('/home/test');
+    var filePath = convertPath('/home/test/lib/test.dart');
+
+    var homeContext = analysisContextCollection.contextFor(homePath);
+    var testContext = analysisContextCollection.contextFor(testPath);
+
+    tracker.addContext(homeContext);
+    tracker.addContext(testContext);
+    await _doAllTrackerWork();
+
+    newFile(filePath, content: 'class A {}');
+    uriToLibrary.clear();
+    tracker.changeFile(filePath);
+    await _doAllTrackerWork();
+
+    _assertDeclaration(
+      _getLibrary('package:test/test.dart'),
+      'A',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+
+    newFile(filePath, content: 'class B {}');
+    uriToLibrary.clear();
+    tracker.changeFile(filePath);
+    await _doAllTrackerWork();
+
+    _assertDeclaration(
+      _getLibrary('package:test/test.dart'),
+      'B',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:test/test.dart::B'],
+    );
+  }
+
+  test_chooseContext_inPackage() async {
+    var homePath = convertPath('/home');
+    var testPath = convertPath('/home/test');
+    var filePath = convertPath('/packages/aaa/lib/a.dart');
+
+    newFile('/home/test/pubspec.yaml', content: r'''
+name: test
+dependencies:
+  aaa: any
+''');
+    addTestPackageDependency('aaa', '/packages/aaa');
+
+    var homeContext = analysisContextCollection.contextFor(homePath);
+    var testContext = analysisContextCollection.contextFor(testPath);
+
+    tracker.addContext(homeContext);
+    tracker.addContext(testContext);
+    await _doAllTrackerWork();
+
+    newFile(filePath, content: 'class A {}');
+    uriToLibrary.clear();
+    tracker.changeFile(filePath);
+    await _doAllTrackerWork();
+
+    _assertDeclaration(
+      _getLibrary('package:aaa/a.dart'),
+      'A',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:aaa/a.dart::A'],
+    );
+
+    newFile(filePath, content: 'class B {}');
+    uriToLibrary.clear();
+    tracker.changeFile(filePath);
+    await _doAllTrackerWork();
+
+    _assertDeclaration(
+      _getLibrary('package:aaa/a.dart'),
+      'B',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:aaa/a.dart::B'],
+    );
+  }
+
+  test_chooseContext_inSdk() async {
+    var filePath = convertPath('/sdk/lib/math/math.dart');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    newFile(filePath, content: 'class A {}');
+    uriToLibrary.clear();
+    tracker.changeFile(filePath);
+    await _doAllTrackerWork();
+
+    _assertDeclaration(
+      _getLibrary('dart:math'),
+      'A',
+      DeclarationKind.CLASS,
+      relevanceTags: ['dart:math::A'],
+    );
+
+    newFile(filePath, content: 'class B {}');
+    uriToLibrary.clear();
+    tracker.changeFile(filePath);
+    await _doAllTrackerWork();
+
+    _assertDeclaration(
+      _getLibrary('dart:math'),
+      'B',
+      DeclarationKind.CLASS,
+      relevanceTags: ['dart:math::B'],
+    );
+  }
+
+  test_deleted_exported() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+    var d = convertPath('/home/test/lib/d.dart');
+
+    newFile(a, content: r'''
+export 'b.dart';
+class A {}
+''');
+    newFile(b, content: r'''
+export 'c.dart';
+class B {}
+''');
+    newFile(c, content: r'''
+class C {}
+''');
+    newFile(d, content: r'''
+class D {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/d.dart', declarations: [
+      _ExpectedDeclaration.class_('D'),
+    ]);
+
+    deleteFile(c);
+    tracker.changeFile(c);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasNoLibrary('package:test/c.dart');
+    _assertHasLibrary('package:test/d.dart', declarations: [
+      _ExpectedDeclaration.class_('D'),
+    ]);
+  }
+
+  test_deleted_library() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+
+    newFile(a, content: '');
+    newFile(b, content: '');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart');
+    _assertHasLibrary('package:test/b.dart');
+
+    deleteFile(a);
+    tracker.changeFile(a);
+    await _doAllTrackerWork();
+
+    _assertHasNoLibrary('package:test/a.dart');
+    _assertHasLibrary('package:test/b.dart');
+  }
+
+  test_deleted_part() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+
+    newFile(a, content: r'''
+part 'b.dart';
+class A {}
+''');
+    newFile(b, content: r'''
+part of 'a.dart';
+class B {}
+''');
+    newFile(c, content: r'''
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+
+    deleteFile(b);
+    tracker.changeFile(b);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+
+  test_updated_exported() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+    var d = convertPath('/home/test/lib/d.dart');
+
+    newFile(a, content: r'''
+export 'b.dart';
+class A {}
+''');
+    newFile(b, content: r'''
+export 'c.dart';
+class B {}
+''');
+    newFile(c, content: r'''
+class C {}
+''');
+    newFile(d, content: r'''
+class D {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasLibrary('package:test/d.dart', declarations: [
+      _ExpectedDeclaration.class_('D'),
+    ]);
+
+    newFile(c, content: r'''
+class C2 {}
+''');
+    tracker.changeFile(c);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C2'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C2'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C2'),
+    ]);
+    _assertHasLibrary('package:test/d.dart', declarations: [
+      _ExpectedDeclaration.class_('D'),
+    ]);
+  }
+
+  test_updated_library() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+
+    newFile(a, content: r'''
+class A {}
+''');
+    newFile(b, content: r'''
+class B {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+
+    newFile(a, content: r'''
+class A2 {}
+''');
+    tracker.changeFile(a);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A2'),
+    ]);
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+  }
+
+  test_updated_part() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+
+    newFile(a, content: r'''
+part 'b.dart';
+class A {}
+''');
+    newFile(b, content: r'''
+part of 'a.dart';
+class B {}
+''');
+    newFile(c, content: r'''
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+
+    newFile(b, content: r'''
+part of 'a.dart';
+class B2 {}
+''');
+    tracker.changeFile(b);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B2'),
+    ]);
+    _assertHasLibrary('package:test/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+}
+
+@reflectiveTest
+class DeclarationTest extends _Base {
+  test_CLASS() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+class A {}
+
+abstract class B {}
+
+@deprecated
+class C {}
+
+/// aaa
+///
+/// bbb bbb
+/// ccc ccc
+class D {}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+    _assertDeclaration(
+      library,
+      'B',
+      DeclarationKind.CLASS,
+      isAbstract: true,
+      relevanceTags: ['package:test/test.dart::B'],
+    );
+    _assertDeclaration(
+      library,
+      'C',
+      DeclarationKind.CLASS,
+      isDeprecated: true,
+      relevanceTags: ['package:test/test.dart::C'],
+    );
+    _assertDeclaration(
+      library,
+      'D',
+      DeclarationKind.CLASS,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb\nccc ccc',
+      relevanceTags: ['package:test/test.dart::D'],
+    );
+  }
+
+  test_CLASS_TYPE_ALIAS() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+mixin M {}
+
+class A = Object with M;
+
+@deprecated
+class B = Object with M;
+
+/// aaa
+///
+/// bbb bbb
+class C = Object with M;
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.CLASS_TYPE_ALIAS,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+    _assertDeclaration(
+      library,
+      'B',
+      DeclarationKind.CLASS_TYPE_ALIAS,
+      isDeprecated: true,
+      relevanceTags: ['package:test/test.dart::B'],
+    );
+    _assertDeclaration(
+      library,
+      'C',
+      DeclarationKind.CLASS_TYPE_ALIAS,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      relevanceTags: ['package:test/test.dart::C'],
+    );
+  }
+
+  test_ENUM() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+enum A {v}
+
+@deprecated
+enum B {v}
+
+/// aaa
+///
+/// bbb bbb
+enum C {v}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.ENUM,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+    _assertDeclaration(
+      library,
+      'B',
+      DeclarationKind.ENUM,
+      isDeprecated: true,
+      relevanceTags: ['package:test/test.dart::B'],
+    );
+    _assertDeclaration(
+      library,
+      'C',
+      DeclarationKind.ENUM,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      relevanceTags: ['package:test/test.dart::C'],
+    );
+  }
+
+  test_ENUM_CONSTANT() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+enum MyEnum {
+  a,
+
+  @deprecated
+  b,
+
+  /// aaa
+  ///
+  /// bbb bbb
+  c
+}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'a',
+      DeclarationKind.ENUM_CONSTANT,
+      name2: 'MyEnum',
+      relevanceTags: ['package:test/test.dart::MyEnum'],
+    );
+    _assertDeclaration(
+      library,
+      'b',
+      DeclarationKind.ENUM_CONSTANT,
+      isDeprecated: true,
+      name2: 'MyEnum',
+      relevanceTags: ['package:test/test.dart::MyEnum'],
+    );
+    _assertDeclaration(
+      library,
+      'c',
+      DeclarationKind.ENUM_CONSTANT,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      name2: 'MyEnum',
+      relevanceTags: ['package:test/test.dart::MyEnum'],
+    );
+  }
+
+  test_FUNCTION() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+void a() {}
+
+@deprecated
+void b() {}
+
+/// aaa
+///
+/// bbb bbb
+void c() {}
+
+List<String> d(Map<String, int> p1, int p2, {double p3}) {}
+
+void e<T extends num, U>() {}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(library, 'a', DeclarationKind.FUNCTION,
+        parameterNames: [],
+        parameters: '()',
+        parameterTypes: [],
+        requiredParameterCount: 0,
+        returnType: 'void');
+    _assertDeclaration(library, 'b', DeclarationKind.FUNCTION,
+        isDeprecated: true,
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        requiredParameterCount: 0,
+        returnType: 'void');
+    _assertDeclaration(library, 'c', DeclarationKind.FUNCTION,
+        docSummary: 'aaa',
+        docComplete: 'aaa\n\nbbb bbb',
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        requiredParameterCount: 0,
+        returnType: 'void');
+    _assertDeclaration(library, 'd', DeclarationKind.FUNCTION,
+        parameters: '(Map<String, int> p1, int p2, {double p3})',
+        parameterNames: ['p1', 'p2', 'p3'],
+        parameterTypes: ['Map<String, int>', 'int', 'double'],
+        requiredParameterCount: 2,
+        returnType: 'List<String>');
+    _assertDeclaration(library, 'e', DeclarationKind.FUNCTION,
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        requiredParameterCount: 0,
+        returnType: 'void',
+        typeParameters: '<T extends num, U>');
+  }
+
+  test_FUNCTION_TYPE_ALIAS() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+typedef A = void Function();
+
+@deprecated
+typedef B = void Function();
+
+/// aaa
+///
+/// bbb bbb
+typedef C = void Function();
+
+typedef D = int Function(int p1, [double p2, String p3]);
+
+typedef E = void Function(int, double, {String p3});
+
+typedef F = void Function<T extends num, U>();
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(library, 'A', DeclarationKind.FUNCTION_TYPE_ALIAS,
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        relevanceTags: ['package:test/test.dart::A'],
+        requiredParameterCount: 0,
+        returnType: 'void');
+    _assertDeclaration(library, 'B', DeclarationKind.FUNCTION_TYPE_ALIAS,
+        isDeprecated: true,
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        relevanceTags: ['package:test/test.dart::B'],
+        requiredParameterCount: 0,
+        returnType: 'void');
+    _assertDeclaration(library, 'C', DeclarationKind.FUNCTION_TYPE_ALIAS,
+        docSummary: 'aaa',
+        docComplete: 'aaa\n\nbbb bbb',
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        relevanceTags: ['package:test/test.dart::C'],
+        requiredParameterCount: 0,
+        returnType: 'void');
+    _assertDeclaration(library, 'D', DeclarationKind.FUNCTION_TYPE_ALIAS,
+        parameters: '(int p1, [double p2, String p3])',
+        parameterNames: ['p1', 'p2', 'p3'],
+        parameterTypes: ['int', 'double', 'String'],
+        relevanceTags: ['package:test/test.dart::D'],
+        requiredParameterCount: 1,
+        returnType: 'int');
+    _assertDeclaration(library, 'E', DeclarationKind.FUNCTION_TYPE_ALIAS,
+        parameters: '(int, double, {String p3})',
+        parameterNames: ['', '', 'p3'],
+        parameterTypes: ['int', 'double', 'String'],
+        relevanceTags: ['package:test/test.dart::E'],
+        requiredParameterCount: 2,
+        returnType: 'void');
+    _assertDeclaration(library, 'F', DeclarationKind.FUNCTION_TYPE_ALIAS,
+        parameters: '()',
+        parameterNames: [],
+        parameterTypes: [],
+        requiredParameterCount: 0,
+        relevanceTags: ['package:test/test.dart::F'],
+        returnType: 'void',
+        typeParameters: '<T extends num, U>');
+  }
+
+  test_GETTER() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+int get a => 0;
+
+@deprecated
+int get b => 0;
+
+/// aaa
+///
+/// bbb bbb
+int get c => 0;
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(library, 'a', DeclarationKind.GETTER, returnType: 'int');
+    _assertDeclaration(
+      library,
+      'b',
+      DeclarationKind.GETTER,
+      isDeprecated: true,
+      returnType: 'int',
+    );
+    _assertDeclaration(
+      library,
+      'c',
+      DeclarationKind.GETTER,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      returnType: 'int',
+    );
+  }
+
+  test_library_isDeprecated() async {
+    newFile('/home/test/lib/a.dart', content: '');
+    newFile('/home/test/lib/b.dart', content: r'''
+@deprecated
+library my.lib;
+''');
+    newFile('/home/test/lib/c.dart', content: r'''
+@Deprecated('description')
+library my.lib;
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+
+    expect(uriToLibrary['package:test/a.dart'].isDeprecated, isFalse);
+    expect(uriToLibrary['package:test/b.dart'].isDeprecated, isTrue);
+    expect(uriToLibrary['package:test/c.dart'].isDeprecated, isTrue);
+  }
+
+  test_library_partDirective_empty() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+part ' ';
+
+class A {}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+  }
+
+  test_library_partDirective_incomplete() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+part
+
+class A {}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.CLASS,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+  }
+
+  test_library_parts() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+part of 'test.dart';
+class A {}
+''');
+    newFile('/home/test/lib/b.dart', content: r'''
+part of 'test.dart';
+class B {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+part 'a.dart';
+part 'b.dart';
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+
+  test_library_publicOnly() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+part of 'test.dart';
+class A {}
+class _A {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+part 'a.dart';
+class B {}
+class _B {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+  }
+
+  test_location() async {
+    var code = r'''
+class A {}
+
+class B {}
+''';
+    var testPath = newFile('/home/test/lib/test.dart', content: code).path;
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.CLASS,
+      locationOffset: code.indexOf('A {}'),
+      locationPath: testPath,
+      locationStartColumn: 7,
+      locationStartLine: 1,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+    _assertDeclaration(
+      library,
+      'B',
+      DeclarationKind.CLASS,
+      locationOffset: code.indexOf('B {}'),
+      locationPath: testPath,
+      locationStartColumn: 7,
+      locationStartLine: 3,
+      relevanceTags: ['package:test/test.dart::B'],
+    );
+  }
+
+  test_MIXIN() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+mixin A {}
+
+@deprecated
+mixin B {}
+
+/// aaa
+///
+/// bbb bbb
+/// ccc ccc
+mixin C {}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'A',
+      DeclarationKind.MIXIN,
+      relevanceTags: ['package:test/test.dart::A'],
+    );
+    _assertDeclaration(
+      library,
+      'B',
+      DeclarationKind.MIXIN,
+      isDeprecated: true,
+      relevanceTags: ['package:test/test.dart::B'],
+    );
+    _assertDeclaration(
+      library,
+      'C',
+      DeclarationKind.MIXIN,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb\nccc ccc',
+      relevanceTags: ['package:test/test.dart::C'],
+    );
+  }
+
+  test_SETTER() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+set a(int value) {}
+
+@deprecated
+set b(int value) {}
+
+/// aaa
+///
+/// bbb bbb
+set c(int value) {}
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(
+      library,
+      'a',
+      DeclarationKind.SETTER,
+      parameters: '(int value)',
+      parameterNames: ['value'],
+      parameterTypes: ['int'],
+      requiredParameterCount: 1,
+    );
+    _assertDeclaration(
+      library,
+      'b',
+      DeclarationKind.SETTER,
+      isDeprecated: true,
+      parameters: '(int value)',
+      parameterNames: ['value'],
+      parameterTypes: ['int'],
+      requiredParameterCount: 1,
+    );
+    _assertDeclaration(
+      library,
+      'c',
+      DeclarationKind.SETTER,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      parameters: '(int value)',
+      parameterNames: ['value'],
+      parameterTypes: ['int'],
+      requiredParameterCount: 1,
+    );
+  }
+
+  test_VARIABLE() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+int a;
+
+@deprecated
+int b;
+
+/// aaa
+///
+/// bbb bbb
+int c;
+
+const d = 0;
+
+final double e = 2.7;
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertDeclaration(library, 'a', DeclarationKind.VARIABLE,
+        returnType: 'int');
+    _assertDeclaration(library, 'b', DeclarationKind.VARIABLE,
+        isDeprecated: true, returnType: 'int');
+    _assertDeclaration(library, 'c', DeclarationKind.VARIABLE,
+        docSummary: 'aaa', docComplete: 'aaa\n\nbbb bbb', returnType: 'int');
+    _assertDeclaration(library, 'd', DeclarationKind.VARIABLE,
+        isConst: true, relevanceTags: ['dart:core::int'], returnType: '');
+    _assertDeclaration(library, 'e', DeclarationKind.VARIABLE,
+        isFinal: true,
+        relevanceTags: ['dart:core::double'],
+        returnType: 'double');
+  }
+}
+
+@reflectiveTest
+class ExportTest extends _Base {
+  test_combinators_hide() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+class C {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart' hide B;
+class D {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('D'),
+    ]);
+  }
+
+  test_combinators_show() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+class C {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart' show B;
+class D {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('D'),
+    ]);
+  }
+
+  test_combinators_show_enum() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+enum E1 {a}
+enum E2 {b}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart' show E1;
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.enum_('E1'),
+      _ExpectedDeclaration.enumConstant('a', 'E1'),
+    ]);
+  }
+
+  test_cycle() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+export 'b.dart';
+class A {}
+''');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+class B {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'b.dart';
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+
+  test_enum() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+enum E1 {a, b}
+enum E2 {a, b}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.enum_('E1'),
+      _ExpectedDeclaration.enumConstant('a', 'E1'),
+      _ExpectedDeclaration.enumConstant('b', 'E1'),
+      _ExpectedDeclaration.enum_('E2'),
+      _ExpectedDeclaration.enumConstant('a', 'E2'),
+      _ExpectedDeclaration.enumConstant('b', 'E2'),
+    ]);
+  }
+
+  test_missing() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart';
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+
+  test_sequence() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+class B {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'b.dart';
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:test/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+
+    _assertHasLibrary('package:test/b.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+    ]);
+
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+
+  test_shadowedByLocal() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart';
+
+mixin B {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.mixin('B'),
+    ]);
+  }
+
+  test_simple() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+''');
+    newFile('/home/test/lib/test.dart', content: r'''
+export 'a.dart';
+class C {}
+''');
+    tracker.addContext(testAnalysisContext);
+
+    await _doAllTrackerWork();
+    _assertHasLibrary('package:test/test.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('C'),
+    ]);
+  }
+}
+
+@reflectiveTest
+class GetLibrariesTest extends _Base {
+  test_bazel() async {
+    newFile('/home/aaa/lib/a.dart', content: 'class A {}');
+    newFile('/home/aaa/lib/src/a2.dart', content: 'class A2 {}');
+
+    newFile('/home/bbb/lib/b.dart', content: 'class B {}');
+    newFile('/home/bbb/lib/src/b2.dart', content: 'class B2 {}');
+
+    newFile('/home/material_button/BUILD', content: '');
+    newFile(
+      '/home/material_button/lib/button.dart',
+      content: 'class MaterialButton {}',
+    );
+    newFile(
+      '/home/material_button/test/button_test.dart',
+      content: 'class MaterialButtonTest {}',
+    );
+
+    newFile('/home/material_button/testing/BUILD', content: '');
+    newFile(
+      '/home/material_button/testing/lib/material_button_po.dart',
+      content: 'class MaterialButtonPO {}',
+    );
+
+    var packagesFilePath = '/home/material_button/.packages';
+    addDotPackagesDependency(packagesFilePath, 'aaa', '/home/aaa');
+    addDotPackagesDependency(packagesFilePath, 'bbb', '/home/bbb');
+    addDotPackagesDependency(
+      packagesFilePath,
+      'material_button',
+      '/home/material_button',
+    );
+    addDotPackagesDependency(
+      packagesFilePath,
+      'material_button_testing',
+      '/home/material_button/testing',
+    );
+
+    var analysisContext = analysisContextCollection.contextFor(
+      convertPath('/home/material_button'),
+    );
+    var context = tracker.addContext(analysisContext);
+    context.setDependencies({
+      convertPath('/home/material_button'): [convertPath('/home/aaa/lib')],
+      convertPath('/home/material_button/testing'): [
+        convertPath('/home/bbb/lib'),
+        convertPath('/home/material_button/lib'),
+      ],
+    });
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:aaa/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasNoLibrary('package:aaa/src/a2.dart');
+
+    _assertHasLibrary('package:bbb/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasNoLibrary('package:bbb/src/b2.dart');
+
+    _assertHasLibrary('package:material_button/button.dart', declarations: [
+      _ExpectedDeclaration.class_('MaterialButton'),
+    ]);
+    _assertHasLibrary(
+      toUriStr('/home/material_button/test/button_test.dart'),
+      declarations: [
+        _ExpectedDeclaration.class_('MaterialButtonTest'),
+      ],
+    );
+    _assertHasLibrary(
+      'package:material_button_testing/material_button_po.dart',
+      declarations: [
+        _ExpectedDeclaration.class_('MaterialButtonPO'),
+      ],
+    );
+
+    {
+      var path = convertPath('/home/material_button/lib/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: ['package:aaa/a.dart'],
+        only: true,
+      );
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:material_button/button.dart',
+        ],
+        only: true,
+      );
+    }
+
+    {
+      var path = convertPath('/home/material_button/test/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: ['package:aaa/a.dart'],
+        only: true,
+      );
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:material_button/button.dart',
+          toUriStr('/home/material_button/test/button_test.dart'),
+        ],
+        only: true,
+      );
+    }
+
+    {
+      var path = convertPath('/home/material_button/testing/lib/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: [
+          'package:bbb/b.dart',
+          'package:material_button/button.dart',
+        ],
+        only: true,
+      );
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:material_button_testing/material_button_po.dart',
+        ],
+        only: true,
+      );
+    }
+  }
+
+  test_excludeSelf() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+
+    newFile(a);
+    newFile(b);
+    newFile(c);
+
+    var context = tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var aList = _uriListOfContextLibraries(context, a);
+    expect(
+      aList,
+      unorderedEquals([
+        'package:test/b.dart',
+        'package:test/c.dart',
+      ]),
+    );
+
+    var bList = _uriListOfContextLibraries(context, b);
+    expect(
+      bList,
+      unorderedEquals([
+        'package:test/a.dart',
+        'package:test/c.dart',
+      ]),
+    );
+  }
+
+  test_excludeSelf_part() async {
+    var a = convertPath('/home/test/lib/a.dart');
+    var b = convertPath('/home/test/lib/b.dart');
+    var c = convertPath('/home/test/lib/c.dart');
+
+    newFile(a, content: r'''
+part 'b.dart';
+''');
+    newFile(b, content: r'''
+part of 'a.dart';
+''');
+    newFile(c);
+
+    var context = tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var aList = _uriListOfContextLibraries(context, a);
+    expect(aList, unorderedEquals(['package:test/c.dart']));
+
+    var bList = _uriListOfContextLibraries(context, b);
+    expect(bList, unorderedEquals(['package:test/c.dart']));
+
+    var cList = _uriListOfContextLibraries(context, c);
+    expect(cList, unorderedEquals(['package:test/a.dart']));
+  }
+
+  test_pub() async {
+    newFile('/home/aaa/lib/a.dart', content: 'class A {}');
+    newFile('/home/aaa/lib/src/a2.dart', content: 'class A2 {}');
+
+    newFile('/home/bbb/lib/b.dart', content: 'class B {}');
+    newFile('/home/bbb/lib/src/b2.dart', content: 'class B2 {}');
+
+    newFile('/home/ccc/lib/c.dart', content: 'class C {}');
+    newFile('/home/ccc/lib/src/c2.dart', content: 'class C2 {}');
+
+    newFile('/home/test/pubspec.yaml', content: r'''
+name: test
+dependencies:
+  aaa: any
+dev_dependencies:
+  bbb: any
+''');
+    newFile('/home/test/lib/t.dart', content: 'class T {}');
+    newFile('/home/test/lib/src/t2.dart', content: 'class T2 {}');
+    newFile('/home/test/bin/t3.dart', content: 'class T3 {}');
+    newFile('/home/test/test/t4.dart', content: 'class T4 {}');
+
+    newFile('/home/test/samples/basic/pubspec.yaml', content: r'''
+name: test
+dependencies:
+  ccc: any
+  test: any
+''');
+    newFile('/home/test/samples/basic/lib/s.dart', content: 'class S {}');
+
+    addTestPackageDependency('aaa', '/home/aaa');
+    addTestPackageDependency('bbb', '/home/bbb');
+    addTestPackageDependency('ccc', '/home/ccc');
+    addTestPackageDependency('basic', '/home/test/samples/basic');
+
+    var context = tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:aaa/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasNoLibrary('package:aaa/src/a2.dart');
+
+    _assertHasLibrary('package:bbb/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasNoLibrary('package:bbb/src/b2.dart');
+
+    _assertHasLibrary('package:ccc/c.dart', declarations: [
+      _ExpectedDeclaration.class_('C'),
+    ]);
+    _assertHasNoLibrary('package:ccc/src/c2.dart');
+
+    _assertHasLibrary('package:test/t.dart', declarations: [
+      _ExpectedDeclaration.class_('T'),
+    ]);
+    _assertHasLibrary('package:test/src/t2.dart', declarations: [
+      _ExpectedDeclaration.class_('T2'),
+    ]);
+
+    _assertHasLibrary('package:basic/s.dart', declarations: [
+      _ExpectedDeclaration.class_('S'),
+    ]);
+
+    {
+      var path = convertPath('/home/test/lib/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: ['package:aaa/a.dart'],
+        only: true,
+      );
+      // Note, no `bin/` or `test/` libraries.
+      // Note, has `lib/src` library.
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:test/t.dart',
+          'package:test/src/t2.dart',
+        ],
+        only: true,
+      );
+    }
+
+    {
+      var path = convertPath('/home/test/bin/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: [
+          'package:aaa/a.dart',
+          'package:bbb/b.dart',
+        ],
+        only: true,
+      );
+      // Note, no `test/` libraries.
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:test/t.dart',
+          'package:test/src/t2.dart',
+          toUriStr('/home/test/bin/t3.dart'),
+        ],
+        only: true,
+      );
+    }
+
+    {
+      var path = convertPath('/home/test/test/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: [
+          'package:aaa/a.dart',
+          'package:bbb/b.dart',
+        ],
+        only: true,
+      );
+      // Note, no `bin/` libraries.
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:test/t.dart',
+          'package:test/src/t2.dart',
+          toUriStr('/home/test/test/t4.dart'),
+        ],
+        only: true,
+      );
+    }
+
+    {
+      var path = convertPath('/home/test/samples/basic/lib/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.sdk,
+        uriList: ['dart:core', 'dart:async'],
+      );
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: [
+          'package:ccc/c.dart',
+          'package:test/t.dart',
+        ],
+        only: true,
+      );
+      // Note, no `package:test` libraries.
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:basic/s.dart',
+        ],
+        only: true,
+      );
+    }
+  }
+
+  test_sdk_excludesPrivate() async {
+    newFile('/home/test/lib/test.dart', content: '');
+
+    var context = tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var path = convertPath('/home/test/lib/_.dart');
+    var libraries = context.getLibraries(path);
+    expect(
+      libraries.sdk.where((library) => library.uriStr.startsWith('dart:_')),
+      isEmpty,
+    );
+  }
+
+  test_setDependencies() async {
+    newFile('/home/aaa/lib/a.dart', content: r'''
+export 'src/a2.dart' show A2;
+class A1 {}
+''');
+    newFile('/home/aaa/lib/src/a2.dart', content: r'''
+class A2 {}
+class A3 {}
+''');
+    newFile('/home/bbb/lib/b.dart', content: r'''
+class B {}
+''');
+
+    addTestPackageDependency('aaa', '/home/aaa');
+    addTestPackageDependency('bbb', '/home/bbb');
+
+    newFile('/home/test/lib/t.dart', content: 'class T {}');
+    newFile('/home/test/lib/src/t2.dart', content: 'class T2 {}');
+    newFile('/home/test/test/t3.dart', content: 'class T3 {}');
+
+    var context = tracker.addContext(testAnalysisContext);
+    context.setDependencies({
+      convertPath('/home/test'): [
+        convertPath('/home/aaa/lib'),
+        convertPath('/home/bbb/lib'),
+      ],
+      convertPath('/home/test/lib'): [convertPath('/home/aaa/lib')],
+    });
+
+    await _doAllTrackerWork();
+
+    _assertHasLibrary('package:aaa/a.dart', declarations: [
+      _ExpectedDeclaration.class_('A1'),
+      _ExpectedDeclaration.class_('A2'),
+    ]);
+    _assertHasNoLibrary('package:aaa/src/a2.dart');
+    _assertHasLibrary('package:bbb/b.dart', declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+    _assertHasLibrary('package:test/t.dart', declarations: [
+      _ExpectedDeclaration.class_('T'),
+    ]);
+    _assertHasLibrary('package:test/src/t2.dart', declarations: [
+      _ExpectedDeclaration.class_('T2'),
+    ]);
+    _assertHasLibrary(
+      toUriStr('/home/test/test/t3.dart'),
+      declarations: [
+        _ExpectedDeclaration.class_('T3'),
+      ],
+    );
+
+    // `lib/` is configured to see `package:aaa`.
+    {
+      var path = convertPath('/home/test/lib/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: ['package:aaa/a.dart'],
+        only: true,
+      );
+      // Not in a package, so all context files are visible.
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:test/t.dart',
+          'package:test/src/t2.dart',
+          toUriStr('/home/test/test/t3.dart'),
+        ],
+        only: true,
+      );
+    }
+
+    // `test/` is configured to see `package:aaa` and `package:bbb`.
+    {
+      var path = convertPath('/home/test/bin/_.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: [
+          'package:aaa/a.dart',
+          'package:bbb/b.dart',
+        ],
+        only: true,
+      );
+      // Not in a package, so all context files are visible.
+      _assertHasLibraries(
+        libraries.context,
+        uriList: [
+          'package:test/t.dart',
+          'package:test/src/t2.dart',
+          toUriStr('/home/test/test/t3.dart'),
+        ],
+        only: true,
+      );
+    }
+  }
+
+  test_setDependencies_twice() async {
+    newFile('/home/aaa/lib/a.dart', content: r'''
+class A {}
+''');
+    newFile('/home/bbb/lib/b.dart', content: r'''
+class B {}
+''');
+
+    addTestPackageDependency('aaa', '/home/aaa');
+    addTestPackageDependency('bbb', '/home/bbb');
+
+    newFile('/home/test/lib/test.dart', content: r'''
+class C {}
+''');
+
+    var context = tracker.addContext(testAnalysisContext);
+
+    var aUri = 'package:aaa/a.dart';
+    var bUri = 'package:bbb/b.dart';
+
+    context.setDependencies({
+      convertPath('/home/test'): [convertPath('/home/aaa/lib')],
+    });
+    await _doAllTrackerWork();
+
+    _assertHasLibrary(aUri, declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasNoLibrary(bUri);
+
+    // The package can see package:aaa, but not package:bbb
+    {
+      var path = convertPath('/home/test/lib/a.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: ['package:aaa/a.dart'],
+        only: true,
+      );
+    }
+
+    context.setDependencies({
+      convertPath('/home/test'): [convertPath('/home/bbb/lib')],
+    });
+    await _doAllTrackerWork();
+
+    _assertHasLibrary(aUri, declarations: [
+      _ExpectedDeclaration.class_('A'),
+    ]);
+    _assertHasLibrary(bUri, declarations: [
+      _ExpectedDeclaration.class_('B'),
+    ]);
+
+    // The package can see package:bbb, but not package:aaa
+    {
+      var path = convertPath('/home/test/lib/a.dart');
+      var libraries = context.getLibraries(path);
+      _assertHasLibraries(
+        libraries.dependencies,
+        uriList: ['package:bbb/b.dart'],
+        only: true,
+      );
+    }
+  }
+
+  static void _assertHasLibraries(List<Library> libraries,
+      {@required List<String> uriList, bool only = false}) {
+    var actualUriList = libraries.map((lib) => lib.uriStr).toList();
+    if (only) {
+      expect(actualUriList, unorderedEquals(uriList));
+    } else {
+      expect(actualUriList, containsAll(uriList));
+    }
+  }
+
+  static List<String> _uriListOfContextLibraries(
+    DeclarationsContext context,
+    String path,
+  ) {
+    return context.getLibraries(path).context.map((l) => l.uriStr).toList();
+  }
+}
+
+class _Base extends AbstractContextTest {
+  DeclarationsTracker tracker;
+
+  final List<LibraryChange> changes = [];
+
+  final Map<int, Library> idToLibrary = {};
+  final Map<String, Library> uriToLibrary = {};
+
+  @override
+  setUp() {
+    super.setUp();
+    _createTracker();
+  }
+
+  void _assertDeclaration(
+    Library library,
+    String name,
+    DeclarationKind kind, {
+    String docComplete,
+    String docSummary,
+    bool isAbstract = false,
+    bool isConst = false,
+    bool isDeprecated = false,
+    bool isFinal = false,
+    int locationOffset,
+    String locationPath,
+    int locationStartColumn,
+    int locationStartLine,
+    String name2,
+    String parameters,
+    List<String> parameterNames,
+    List<String> parameterTypes,
+    List<String> relevanceTags,
+    int requiredParameterCount,
+    String returnType,
+    String typeParameters,
+  }) {
+    var declaration = _getDeclaration(library, name);
+    expect(declaration.docComplete, docComplete);
+    expect(declaration.docSummary, docSummary);
+    expect(declaration.name, name);
+    expect(declaration.name2, name2);
+    expect(declaration.kind, kind);
+    expect(declaration.isAbstract, isAbstract);
+    expect(declaration.isConst, isConst);
+    expect(declaration.isDeprecated, isDeprecated);
+    expect(declaration.isFinal, isFinal);
+    expect(declaration.parameters, parameters);
+    expect(declaration.parameterNames, parameterNames);
+    expect(declaration.parameterTypes, parameterTypes);
+    expect(declaration.relevanceTags, relevanceTags);
+    expect(declaration.requiredParameterCount, requiredParameterCount);
+    expect(declaration.returnType, returnType);
+    expect(declaration.typeParameters, typeParameters);
+    if (locationOffset != null) {
+      expect(declaration.locationOffset, locationOffset);
+      expect(declaration.locationPath, locationPath);
+      expect(declaration.locationStartColumn, locationStartColumn);
+      expect(declaration.locationStartLine, locationStartLine);
+    }
+  }
+
+  void _assertHasDeclaration(Library library, _ExpectedDeclaration expected) {
+    expect(
+      library.declarations,
+      contains(predicate((Declaration d) {
+        return d.name == expected.name &&
+            d.name2 == expected.name2 &&
+            d.kind == expected.kind;
+      })),
+      reason: '$expected',
+    );
+  }
+
+  /// Assert that the current state has the library with the given [uri].
+  ///
+  /// If [declarations] provided, also checks that the library has exactly
+  /// these declarations.
+  void _assertHasLibrary(String uri,
+      {List<_ExpectedDeclaration> declarations}) {
+    var library = uriToLibrary[uri];
+    expect(library, isNotNull);
+    if (declarations != null) {
+      expect(library.declarations, hasLength(declarations.length));
+      for (var expected in declarations) {
+        _assertHasDeclaration(library, expected);
+      }
+    }
+  }
+
+  void _assertHasNoLibrary(String uri) {
+    expect(uriToLibrary, isNot(contains(uri)));
+  }
+
+  void _createTracker() {
+    uriToLibrary.clear();
+
+    tracker = DeclarationsTracker(byteStore, resourceProvider);
+    tracker.changes.listen((change) {
+      changes.add(change);
+      for (var library in change.changed) {
+        idToLibrary[library.id] = library;
+        uriToLibrary[library.uriStr] = library;
+      }
+      idToLibrary.removeWhere((uriStr, library) {
+        return change.removed.contains(library.id);
+      });
+      uriToLibrary.removeWhere((uriStr, library) {
+        return change.removed.contains(library.id);
+      });
+    });
+  }
+
+  Future<void> _doAllTrackerWork() async {
+    while (tracker.hasWork) {
+      tracker.doWork();
+    }
+    await pumpEventQueue();
+  }
+
+  Declaration _getDeclaration(Library library, String name) {
+    return library.declarations
+        .singleWhere((declaration) => declaration.name == name);
+  }
+
+  Library _getLibrary(String uriStr) {
+    var library = uriToLibrary[uriStr];
+    expect(library, isNotNull);
+    return library;
+  }
+}
+
+class _ExpectedDeclaration {
+  final DeclarationKind kind;
+  final String name;
+  final String name2;
+
+  _ExpectedDeclaration(this.kind, this.name, this.name2);
+
+  _ExpectedDeclaration.class_(String name)
+      : this(DeclarationKind.CLASS, name, null);
+
+  _ExpectedDeclaration.classTypeAlias(String name)
+      : this(DeclarationKind.CLASS_TYPE_ALIAS, name, null);
+
+  _ExpectedDeclaration.enum_(String name)
+      : this(DeclarationKind.ENUM, name, null);
+
+  _ExpectedDeclaration.enumConstant(String name, String name2)
+      : this(DeclarationKind.ENUM_CONSTANT, name, name2);
+
+  _ExpectedDeclaration.function(String name)
+      : this(DeclarationKind.FUNCTION, name, null);
+
+  _ExpectedDeclaration.functionTypeAlias(String name)
+      : this(DeclarationKind.FUNCTION_TYPE_ALIAS, name, null);
+
+  _ExpectedDeclaration.mixin(String name)
+      : this(DeclarationKind.MIXIN, name, null);
+
+  _ExpectedDeclaration.variable(String name)
+      : this(DeclarationKind.VARIABLE, name, null);
+
+  @override
+  String toString() {
+    if (name2 != null) {
+      return '($kind, $name, $name2)';
+    } else {
+      return '($kind, $name)';
+    }
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index cf2ecd6..e655fec 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -28,6 +28,8 @@
   });
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class ExprBuilderTest extends ResynthesizeTestStrategyTwoPhase
     with ExprBuilderTestCases, ExprBuilderTestHelpers {}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index c15af1e..a3b399e 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -22,6 +22,8 @@
   }
 }
 
+/// TODO(paulberry): migrate this test away from the task model.
+/// See dartbug.com/35734.
 @reflectiveTest
 class ResynthesizeAstStrongTest extends ResynthesizeTestStrategyTwoPhase
     with ResynthesizeTestCases, ResynthesizeTestHelpers {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 69d2215..dd5daa7 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -30,6 +30,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../generated/test_support.dart';
+import '../../util/element_type_matchers.dart';
 import '../abstract_single_unit.dart';
 import 'element_text.dart';
 import 'test_strategies.dart';
@@ -9671,7 +9672,7 @@
     compareVariableElements(resynthesized, original, desc);
     compareParameterElementLists(
         resynthesized.parameters, original.parameters, desc);
-    // ignore: deprecated_member_use
+    // ignore: deprecated_member_use_from_same_package
     expect(resynthesized.parameterKind, original.parameterKind, reason: desc);
     expect(resynthesized.isInitializingFormal, original.isInitializingFormal,
         reason: desc);
@@ -9796,7 +9797,7 @@
           reason: desc);
       if (original.element.enclosingElement == null &&
           original.element is FunctionElement) {
-        expect(resynthesized.element, new TypeMatcher<FunctionElement>());
+        expect(resynthesized.element, isFunctionElement);
         expect(resynthesized.element.enclosingElement, isNull, reason: desc);
         compareFunctionElements(
             resynthesized.element, original.element, '$desc.element',
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
deleted file mode 100644
index 22b79c4..0000000
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ /dev/null
@@ -1,4897 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.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/error/error.dart';
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisOptionsImpl, CacheState;
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/task/api/dart.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/src/task/html.dart';
-import 'package:analyzer/src/task/strong/ast_properties.dart' as strong_ast;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/resolver_test_case.dart';
-import '../../generated/test_support.dart';
-import '../../utils.dart';
-import '../context/abstract_context.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(BuildCompilationUnitElementTaskTest);
-    defineReflectiveTests(BuildDirectiveElementsTaskTest);
-    defineReflectiveTests(BuildEnumMemberElementsTaskTest);
-    defineReflectiveTests(BuildExportNamespaceTaskTest);
-    defineReflectiveTests(BuildLibraryElementTaskTest);
-    defineReflectiveTests(BuildPublicNamespaceTaskTest);
-    defineReflectiveTests(BuildSourceExportClosureTaskTest);
-    defineReflectiveTests(BuildTypeProviderTaskTest);
-    defineReflectiveTests(ComputeConstantDependenciesTaskTest);
-    defineReflectiveTests(ComputeConstantValueTaskTest);
-    defineReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
-    defineReflectiveTests(ComputeLibraryCycleTaskTest);
-    defineReflectiveTests(ContainingLibrariesTaskTest);
-    defineReflectiveTests(DartErrorsTaskTest);
-    defineReflectiveTests(EvaluateUnitConstantsTaskTest);
-    defineReflectiveTests(GatherUsedImportedElementsTaskTest);
-    defineReflectiveTests(GatherUsedLocalElementsTaskTest);
-    defineReflectiveTests(GenerateHintsTaskTest);
-    defineReflectiveTests(GenerateLintsTaskTest);
-    defineReflectiveTests(InferInstanceMembersInUnitTaskTest);
-    defineReflectiveTests(InferStaticVariableTypesInUnitTaskTest);
-    defineReflectiveTests(InferStaticVariableTypeTaskTest);
-    defineReflectiveTests(LibraryErrorsReadyTaskTest);
-    defineReflectiveTests(LibraryUnitErrorsTaskTest);
-    defineReflectiveTests(ParseDartTaskTest);
-    defineReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
-    defineReflectiveTests(ResolveDirectiveElementsTaskTest);
-    defineReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
-    defineReflectiveTests(ResolveLibraryTaskTest);
-    defineReflectiveTests(ResolveLibraryTypeNamesTaskTest);
-    defineReflectiveTests(ResolveTopLevelUnitTypeBoundsTaskTest);
-    defineReflectiveTests(ResolveUnitTaskTest);
-    defineReflectiveTests(ResolveUnitTypeNamesTaskTest);
-    defineReflectiveTests(ResolveVariableReferencesTaskTest);
-    defineReflectiveTests(ScanDartTaskTest);
-    defineReflectiveTests(StrongModeInferenceTest);
-    defineReflectiveTests(StrongModeVerifyUnitTaskTest);
-    defineReflectiveTests(VerifyUnitTaskTest);
-  });
-}
-
-final isBuildCompilationUnitElementTask =
-    new TypeMatcher<BuildCompilationUnitElementTask>();
-final isBuildDirectiveElementsTask =
-    new TypeMatcher<BuildDirectiveElementsTask>();
-final isBuildEnumMemberElementsTask =
-    new TypeMatcher<BuildEnumMemberElementsTask>();
-final isBuildExportNamespaceTask = new TypeMatcher<BuildExportNamespaceTask>();
-final isBuildLibraryElementTask = new TypeMatcher<BuildLibraryElementTask>();
-final isBuildPublicNamespaceTask = new TypeMatcher<BuildPublicNamespaceTask>();
-final isBuildSourceExportClosureTask =
-    new TypeMatcher<BuildSourceExportClosureTask>();
-final isBuildTypeProviderTask = new TypeMatcher<BuildTypeProviderTask>();
-final isComputeConstantDependenciesTask =
-    new TypeMatcher<ComputeConstantDependenciesTask>();
-final isComputeConstantValueTask = new TypeMatcher<ComputeConstantValueTask>();
-final isComputeInferableStaticVariableDependenciesTask =
-    new TypeMatcher<ComputeInferableStaticVariableDependenciesTask>();
-final isContainingLibrariesTask = new TypeMatcher<ContainingLibrariesTask>();
-final isDartErrorsTask = new TypeMatcher<DartErrorsTask>();
-final isEvaluateUnitConstantsTask =
-    new TypeMatcher<EvaluateUnitConstantsTask>();
-final isGatherUsedImportedElementsTask =
-    new TypeMatcher<GatherUsedImportedElementsTask>();
-final isGatherUsedLocalElementsTask =
-    new TypeMatcher<GatherUsedLocalElementsTask>();
-final isGenerateHintsTask = new TypeMatcher<GenerateHintsTask>();
-final isGenerateLintsTask = new TypeMatcher<GenerateLintsTask>();
-final isInferInstanceMembersInUnitTask =
-    new TypeMatcher<InferInstanceMembersInUnitTask>();
-final isInferStaticVariableTypesInUnitTask =
-    new TypeMatcher<InferStaticVariableTypesInUnitTask>();
-final isInferStaticVariableTypeTask =
-    new TypeMatcher<InferStaticVariableTypeTask>();
-final isLibraryErrorsReadyTask = new TypeMatcher<LibraryErrorsReadyTask>();
-final isLibraryUnitErrorsTask = new TypeMatcher<LibraryUnitErrorsTask>();
-final isParseDartTask = new TypeMatcher<ParseDartTask>();
-final isPartiallyResolveUnitReferencesTask =
-    new TypeMatcher<PartiallyResolveUnitReferencesTask>();
-final isResolveDirectiveElementsTask =
-    new TypeMatcher<ResolveDirectiveElementsTask>();
-final isResolveLibraryReferencesTask =
-    new TypeMatcher<ResolveLibraryReferencesTask>();
-final isResolveLibraryTask = new TypeMatcher<ResolveLibraryTask>();
-final isResolveLibraryTypeNamesTask =
-    new TypeMatcher<ResolveLibraryTypeNamesTask>();
-final isResolveTopLevelUnitTypeBoundsTask =
-    new TypeMatcher<ResolveTopLevelUnitTypeBoundsTask>();
-final isResolveUnitTask = new TypeMatcher<ResolveUnitTask>();
-final isResolveUnitTypeNamesTask = new TypeMatcher<ResolveUnitTypeNamesTask>();
-final isResolveVariableReferencesTask =
-    new TypeMatcher<ResolveVariableReferencesTask>();
-final isScanDartTask = new TypeMatcher<ScanDartTask>();
-final isStrongModeVerifyUnitTask = new TypeMatcher<StrongModeVerifyUnitTask>();
-final isVerifyUnitTask = new TypeMatcher<VerifyUnitTask>();
-
-final LintCode _testLintCode = new LintCode('test lint', 'test lint code');
-
-@reflectiveTest
-class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest {
-  Source source;
-  LibrarySpecificUnit target;
-
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT1);
-    expect(outputs[RESOLVED_UNIT1], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT1], isTrue);
-  }
-
-  test_perform_find_constants() {
-    _performBuildTask('''
-const x = 1;
-class C {
-  static const y = 1;
-  const C([p = 1]);
-}
-@x
-f() {
-  const z = 1;
-}
-''');
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
-    Annotation annotation = unit.declarations
-        .firstWhere((m) => m is FunctionDeclaration)
-        .metadata[0];
-    List<ConstantEvaluationTarget> expectedConstants =
-        <ConstantEvaluationTarget>[
-      unitElement.accessors.firstWhere((e) => e.isGetter).variable,
-      unitElement.types[0].fields[0],
-      findLocalVariable(unit, 'z'),
-      unitElement.types[0].constructors[0],
-      resolutionMap.elementAnnotationForAnnotation(annotation),
-      unitElement.types[0].constructors[0].parameters[0]
-    ];
-    expect(
-        outputs[COMPILATION_UNIT_CONSTANTS].toSet(), expectedConstants.toSet());
-  }
-
-  test_perform_library() {
-    _performBuildTask(r'''
-library lib;
-import 'lib2.dart';
-export 'lib3.dart';
-part 'part.dart';
-final x = '';
-class A {
-  static final y = 0;
-}
-class B = Object with A;
-''');
-    expect(outputs, hasLength(4));
-    expect(outputs[COMPILATION_UNIT_CONSTANTS], isNotNull);
-    expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull);
-    expect(outputs[RESOLVED_UNIT1], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT1], isTrue);
-  }
-
-  test_perform_reuseElement() {
-    _performBuildTask(r'''
-library lib;
-class A {}
-class B = Object with A;
-''');
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    CompilationUnitElement unitElement = outputs[COMPILATION_UNIT_ELEMENT];
-    expect(unit, isNotNull);
-    expect(unitElement, isNotNull);
-    // invalidate RESOLVED_UNIT1
-    CacheEntry cacheEntry = analysisCache.get(target);
-    cacheEntry.setState(RESOLVED_UNIT1, CacheState.INVALID);
-    // compute again
-    computeResult(target, RESOLVED_UNIT1,
-        matcher: isBuildCompilationUnitElementTask);
-    expect(outputs[COMPILATION_UNIT_ELEMENT], same(unitElement));
-    expect(outputs[RESOLVED_UNIT1], isNot(same(unit)));
-  }
-
-  void _performBuildTask(String content) {
-    source = newSource('/test.dart', content);
-    target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT1,
-        matcher: isBuildCompilationUnitElementTask);
-  }
-}
-
-@reflectiveTest
-class BuildDirectiveElementsTaskTest extends _AbstractDartTaskTest {
-  /**
-   * Verify that the given [element] has exactly one annotation, and that its
-   * [ElementAnnotationImpl] is unresolved and points back to [element].
-   *
-   * The compilation unit stored in the [ElementAnnotationImpl] should be
-   * [compilationUnit].
-   */
-  void checkMetadata(Element element, CompilationUnitElement compilationUnit) {
-    expect(element.metadata, hasLength(1));
-    expect(element.metadata[0], new TypeMatcher<ElementAnnotationImpl>());
-    ElementAnnotationImpl elementAnnotation = element.metadata[0];
-    expect(elementAnnotation.element, isNull); // Not yet resolved
-    expect(elementAnnotation.compilationUnit, isNotNull);
-    expect(elementAnnotation.compilationUnit, compilationUnit);
-  }
-
-  test_perform() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-import 'libB.dart';
-export 'libC.dart';
-''',
-      '/libB.dart': '''
-library libB;
-''',
-      '/libC.dart': '''
-library libC;
-'''
-    });
-    Source sourceA = sources[0];
-    Source sourceB = sources[1];
-    Source sourceC = sources[2];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
-    LibraryElement libraryElementB = _getImportLibraryInput(sourceB);
-    LibraryElement libraryElementC = _getExportLibraryInput(sourceC);
-    // no errors
-    _assertErrorsWithCodes([]);
-    // validate directives
-    CompilationUnit libraryUnitA = context
-        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
-        .getValue(RESOLVED_UNIT1);
-    {
-      ImportDirective importNode = libraryUnitA.directives[1];
-      ImportElement importElement = importNode.element;
-      expect(importElement, isNotNull);
-      expect(importElement.importedLibrary, libraryElementB);
-      expect(importElement.prefix, isNull);
-      expect(importElement.nameOffset, 14);
-    }
-    {
-      ExportDirective exportNode = libraryUnitA.directives[2];
-      ExportElement exportElement = exportNode.element;
-      expect(exportElement, isNotNull);
-      expect(exportElement.exportedLibrary, libraryElementC);
-      expect(exportElement.nameOffset, 34);
-    }
-    // validate LibraryElement
-    expect(libraryElementA.hasExtUri, isFalse);
-    // has an artificial "dart:core" import
-    {
-      List<ImportElement> imports = libraryElementA.imports;
-      expect(imports, hasLength(2));
-      expect(imports[1].importedLibrary.isDartCore, isTrue);
-      expect(imports[1].isSynthetic, isTrue);
-    }
-  }
-
-  test_perform_combinators() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-import 'libB.dart' show A, B hide C, D;
-''',
-      '/libB.dart': '''
-library libB;
-'''
-    });
-    Source sourceA = sources[0];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    CompilationUnit libraryUnitA = context
-        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
-        .getValue(RESOLVED_UNIT1);
-    // no errors
-    _assertErrorsWithCodes([]);
-    // validate directives
-    ImportDirective importNode = libraryUnitA.directives[1];
-    ImportElement importElement = importNode.element;
-    List<NamespaceCombinator> combinators = importElement.combinators;
-    expect(combinators, hasLength(2));
-    {
-      ShowElementCombinator combinator = combinators[0];
-      expect(combinator.offset, 33);
-      expect(combinator.end, 42);
-      expect(combinator.shownNames, ['A', 'B']);
-    }
-    {
-      HideElementCombinator combinator = combinators[1];
-      expect(combinator.hiddenNames, ['C', 'D']);
-    }
-  }
-
-  test_perform_configurations_export() {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'true', 'dart.library.html': 'true'});
-    newSource('/foo.dart', '');
-    var foo_io = newSource('/foo_io.dart', '');
-    newSource('/foo_html.dart', '');
-    var testSource = newSource('/test.dart', r'''
-export 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    // Perform the task.
-    computeResult(testSource, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    LibraryElement testLibrary = outputs[LIBRARY_ELEMENT2];
-    // Validate the export element.
-    ExportElement export = testLibrary.exports[0];
-    expect(export.exportedLibrary.source, foo_io);
-  }
-
-  test_perform_configurations_import() {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'true', 'dart.library.html': 'true'});
-    newSource('/foo.dart', '');
-    var foo_io = newSource('/foo_io.dart', '');
-    newSource('/foo_html.dart', '');
-    var testSource = newSource('/test.dart', r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    // Perform the task.
-    computeResult(testSource, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    LibraryElement testLibrary = outputs[LIBRARY_ELEMENT2];
-    // Validate the import element.
-    ImportElement import = testLibrary.imports[0];
-    expect(import.importedLibrary.source, foo_io);
-  }
-
-  test_perform_dartCoreContext() {
-    List<Source> sources = newSources({'/libA.dart': ''});
-    Source source = sources[0];
-    // perform task
-    computeResult(source, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
-    // verify that dart:core has SDK context
-    {
-      LibraryElement coreLibrary = libraryElement.importedLibraries[0];
-      DartSdk dartSdk = context.sourceFactory.dartSdk;
-      expect(coreLibrary.context, same(dartSdk.context));
-    }
-  }
-
-  test_perform_error_exportOfNonLibrary() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-export 'part.dart';
-''',
-      '/part.dart': '''
-part of notLib;
-'''
-    });
-    Source sourceA = sources[0];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // validate errors
-    _assertErrorsWithCodes([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
-  }
-
-  test_perform_error_importOfNonLibrary() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-import 'part.dart';
-''',
-      '/part.dart': '''
-part of notLib;
-'''
-    });
-    Source sourceA = sources[0];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // validate errors
-    _assertErrorsWithCodes([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
-  }
-
-  test_perform_explicitDartCoreImport() {
-    List<Source> sources = newSources({
-      '/lib.dart': '''
-library lib;
-import 'dart:core' show List;
-'''
-    });
-    Source source = sources[0];
-    // perform task
-    computeResult(source, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
-    // has an explicit "dart:core" import
-    {
-      List<ImportElement> imports = libraryElement.imports;
-      expect(imports, hasLength(1));
-      expect(imports[0].importedLibrary.isDartCore, isTrue);
-      expect(imports[0].isSynthetic, isFalse);
-    }
-  }
-
-  test_perform_hasExtUri() {
-    List<Source> sources = newSources({
-      '/lib.dart': '''
-import 'dart-ext:doesNotExist.dart';
-'''
-    });
-    Source source = sources[0];
-    // perform task
-    computeResult(source, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
-    expect(libraryElement.hasExtUri, isTrue);
-  }
-
-  test_perform_importPrefix() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-import 'libB.dart' as pref;
-import 'libC.dart' as pref;
-''',
-      '/libB.dart': '''
-library libB;
-''',
-      '/libC.dart': '''
-library libC;
-'''
-    });
-    Source sourceA = sources[0];
-    Source sourceB = sources[1];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    CompilationUnit libraryUnitA = context
-        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourceA))
-        .getValue(RESOLVED_UNIT1);
-    // validate directives
-    ImportDirective importNodeB = libraryUnitA.directives[1];
-    SimpleIdentifier prefixNodeB = importNodeB.prefix;
-    ImportElement importElementB = importNodeB.element;
-    PrefixElement prefixElement = importElementB.prefix;
-    expect(importElementB, isNotNull);
-    expect(importElementB.importedLibrary, _getImportLibraryInput(sourceB));
-    expect(prefixElement, isNotNull);
-    expect(importElementB.prefixOffset, prefixElement.nameOffset);
-    expect(prefixNodeB.staticElement, prefixElement);
-    // PrefixElement "pref" is shared
-    ImportDirective importNodeC = libraryUnitA.directives[2];
-    SimpleIdentifier prefixNodeC = importNodeC.prefix;
-    ImportElement importElementC = importNodeC.element;
-    expect(prefixNodeC.staticElement, prefixElement);
-    expect(importElementC.prefix, prefixElement);
-  }
-
-  test_perform_metadata() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-@a library libA;
-@b import 'libB.dart';
-@c export 'libC.dart';
-@d part 'part.dart';''',
-      '/libB.dart': 'library libB;',
-      '/libC.dart': 'library libC;',
-      '/part.dart': 'part of libA;'
-    });
-    Source sourceA = sources[0];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // Get outputs
-    LibraryElement libraryA =
-        context.getCacheEntry(sourceA).getValue(LIBRARY_ELEMENT2);
-    // Validate metadata
-    checkMetadata(libraryA, libraryA.definingCompilationUnit);
-    checkMetadata(libraryA.imports[0], libraryA.definingCompilationUnit);
-    checkMetadata(libraryA.exports[0], libraryA.definingCompilationUnit);
-    checkMetadata(libraryA.parts[0], libraryA.definingCompilationUnit);
-  }
-
-  test_perform_metadata_partOf() {
-    // We don't record annotations on `part of` directives because the element
-    // associated with a `part of` directive is the library, and the convention
-    // is to annotate the library at the site of the `library` declaration.
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-part 'part.dart';''',
-      '/part.dart': '@a part of libA;'
-    });
-    Source sourceA = sources[0];
-    Source sourcePart = sources[1];
-    // perform task
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // Get outputs
-    LibraryElement libraryA =
-        context.getCacheEntry(sourceA).getValue(LIBRARY_ELEMENT2);
-    CompilationUnit part = context
-        .getCacheEntry(new LibrarySpecificUnit(sourceA, sourcePart))
-        .getValue(RESOLVED_UNIT1);
-    // Validate metadata
-    expect(part.directives[0], new TypeMatcher<PartOfDirective>());
-    expect(part.directives[0].element, same(libraryA));
-    expect(
-        resolutionMap.elementDeclaredByDirective(part.directives[0]).metadata,
-        isEmpty);
-  }
-
-  void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
-    _fillErrorListener(BUILD_DIRECTIVES_ERRORS);
-    errorListener.assertErrorsWithCodes(expectedErrorCodes);
-  }
-
-  _getExportLibraryInput(Source source) {
-    var key = BuildDirectiveElementsTask.EXPORTS_LIBRARY_ELEMENT_INPUT_NAME;
-    return task.inputs[key][source];
-  }
-
-  _getImportLibraryInput(Source source) {
-    var key = BuildDirectiveElementsTask.IMPORTS_LIBRARY_ELEMENT_INPUT_NAME;
-    return task.inputs[key][source];
-  }
-}
-
-@reflectiveTest
-class BuildEnumMemberElementsTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT3);
-    expect(outputs[RESOLVED_UNIT3], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT3], isTrue);
-  }
-
-  test_perform() {
-    Source source = newSource('/test.dart', '''
-enum MyEnum {
-  A, B
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT3,
-        matcher: isBuildEnumMemberElementsTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT3];
-    // validate Element
-    ClassElement enumElement =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).getEnum('MyEnum');
-    List<FieldElement> fields = enumElement.fields;
-    expect(fields, hasLength(4));
-    {
-      FieldElementImpl index = fields[0];
-      expect(index, isNotNull);
-      expect(index.name, 'index');
-      expect(index.isStatic, isFalse);
-      expect(index.evaluationResult, isNull);
-      _assertGetter(index);
-    }
-    {
-      ConstFieldElementImpl values = fields[1];
-      expect(values, isNotNull);
-      expect(values.name, 'values');
-      expect(values.isStatic, isTrue);
-      expect(values.evaluationResult, isNotNull);
-      _assertGetter(values);
-    }
-    {
-      ConstFieldElementImpl constant = fields[2];
-      expect(constant, isNotNull);
-      expect(constant.name, 'A');
-      expect(constant.isStatic, isTrue);
-      expect(constant.evaluationResult, isNotNull);
-      _assertGetter(constant);
-    }
-    {
-      ConstFieldElementImpl constant = fields[3];
-      expect(constant, isNotNull);
-      expect(constant.name, 'B');
-      expect(constant.isStatic, isTrue);
-      expect(constant.evaluationResult, isNotNull);
-      _assertGetter(constant);
-    }
-    // validate nodes
-    EnumDeclaration enumNode = unit.declarations[0];
-    expect(enumNode.name.staticElement, same(enumElement));
-    expect(
-        enumNode.constants[0].declaredElement, same(enumElement.getField('A')));
-    expect(
-        enumNode.constants[1].declaredElement, same(enumElement.getField('B')));
-  }
-
-  static void _assertGetter(FieldElement field) {
-    PropertyAccessorElement getter = field.getter;
-    expect(getter, isNotNull);
-    expect(getter.variable, same(field));
-    expect(getter.type, isNotNull);
-  }
-}
-
-@reflectiveTest
-class BuildExportNamespaceTaskTest extends _AbstractDartTaskTest {
-  test_perform_entryPoint() {
-    Source sourceA = newSource('/a.dart', '''
-library lib_a;
-export 'b.dart';
-''');
-    Source sourceB = newSource('/b.dart', '''
-library lib_b;
-main() {}
-''');
-    computeResult(sourceA, LIBRARY_ELEMENT4,
-        matcher: isBuildExportNamespaceTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT4];
-    FunctionElement entryPoint = library.entryPoint;
-    expect(entryPoint, isNotNull);
-    expect(entryPoint.source, sourceB);
-  }
-
-  test_perform_hideCombinator() {
-    Source sourceA = newSource('/a.dart', '''
-library lib_a;
-export 'b.dart' hide B1;
-class A1 {}
-class A2 {}
-class _A3 {}
-''');
-    newSource('/b.dart', '''
-library lib_b;
-class B1 {}
-class B2 {}
-class B3 {}
-class _B4 {}
-''');
-    newSource('/c.dart', '''
-library lib_c;
-class C1 {}
-class C2 {}
-class C3 {}
-''');
-    computeResult(sourceA, LIBRARY_ELEMENT4,
-        matcher: isBuildExportNamespaceTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT4];
-    Namespace namespace = library.exportNamespace;
-    Iterable<String> definedKeys = namespace.definedNames.keys;
-    expect(definedKeys, unorderedEquals(['A1', 'A2', 'B2', 'B3']));
-  }
-
-  test_perform_showCombinator() {
-    Source sourceA = newSource('/a.dart', '''
-library lib_a;
-export 'b.dart' show B1;
-class A1 {}
-class A2 {}
-class _A3 {}
-''');
-    newSource('/b.dart', '''
-library lib_b;
-class B1 {}
-class B2 {}
-class _B3 {}
-''');
-    computeResult(sourceA, LIBRARY_ELEMENT4,
-        matcher: isBuildExportNamespaceTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT4];
-    Namespace namespace = library.exportNamespace;
-    Iterable<String> definedKeys = namespace.definedNames.keys;
-    expect(definedKeys, unorderedEquals(['A1', 'A2', 'B1']));
-  }
-
-  test_perform_showCombinator_setter() {
-    Source sourceA = newSource('/a.dart', '''
-library lib_a;
-export 'b.dart' show topLevelB;
-class A {}
-''');
-    newSource('/b.dart', '''
-library lib_b;
-int topLevelB;
-''');
-    computeResult(sourceA, LIBRARY_ELEMENT4,
-        matcher: isBuildExportNamespaceTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT4];
-    Namespace namespace = library.exportNamespace;
-    Iterable<String> definedKeys = namespace.definedNames.keys;
-    expect(definedKeys, unorderedEquals(['A', 'topLevelB', 'topLevelB=']));
-  }
-}
-
-@reflectiveTest
-class BuildLibraryElementTaskTest extends _AbstractDartTaskTest {
-  Source librarySource;
-  CompilationUnit libraryUnit;
-  CompilationUnitElement libraryUnitElement;
-  List<CompilationUnit> partUnits;
-
-  LibraryElement libraryElement;
-
-  test_perform() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'part1.dart';
-part 'part2.dart';
-''',
-      '/part1.dart': '''
-part of lib;
-''',
-      '/part2.dart': '''
-part of 'lib.dart';
-'''
-    });
-    expect(outputs, hasLength(3));
-    // simple outputs
-    expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty);
-    expect(outputs[IS_LAUNCHABLE], isFalse);
-    // LibraryElement output
-    expect(libraryElement, isNotNull);
-    expect(libraryElement.entryPoint, isNull);
-    expect(libraryElement.source, same(librarySource));
-    expect(libraryElement.definingCompilationUnit, libraryUnitElement);
-    expect(
-        libraryElement.parts,
-        unorderedEquals(
-            [partUnits[0].declaredElement, partUnits[1].declaredElement]));
-    // LibraryElement references
-    expect((libraryUnit.directives[0] as LibraryDirective).element,
-        same(libraryElement));
-    expect((partUnits[0].directives[0] as PartOfDirective).element,
-        same(libraryElement));
-    expect((partUnits[1].directives[0] as PartOfDirective).element,
-        same(libraryElement));
-    // CompilationUnitElement(s)
-    CompilationUnitElement firstPart;
-    CompilationUnitElement secondPart;
-    if (resolutionMap
-            .elementDeclaredByCompilationUnit(partUnits[0])
-            .source
-            .shortName ==
-        'part1.dart') {
-      firstPart = partUnits[0].declaredElement;
-      secondPart = partUnits[1].declaredElement;
-    } else {
-      firstPart = partUnits[1].declaredElement;
-      secondPart = partUnits[0].declaredElement;
-    }
-    expect(firstPart.source.shortName, 'part1.dart');
-    expect(
-        (libraryUnit.directives[1] as PartDirective).element, same(firstPart));
-
-    expect(secondPart.source.shortName, 'part2.dart');
-    expect(
-        (libraryUnit.directives[2] as PartDirective).element, same(secondPart));
-  }
-
-  @failingTest
-  test_perform_error_missingLibraryDirectiveWithPart() {
-    _performBuildTask({
-      '/lib.dart': '''
-part 'partA.dart';
-part 'partB.dart';
-''',
-      '/partA.dart': '''
-part of my_lib;
-        ''',
-      '/partB.dart': '''
-part of my_lib;
-'''
-    });
-    // TODO(28522)
-    fail('Should report that names are wrong.');
-  }
-
-  @failingTest
-  test_perform_error_missingLibraryDirectiveWithPart_noCommon() {
-    _performBuildTask({
-      '/lib.dart': '''
-part 'partA.dart';
-part 'partB.dart';
-''',
-      '/partA.dart': '''
-part of libA;
-        ''',
-      '/partB.dart': '''
-part of libB;
-'''
-    });
-    // TODO(28522)
-    fail('Should report that names are wrong.');
-  }
-
-  test_perform_error_partDoesNotExist() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'part.dart';
-'''
-    });
-    // we already report URI_DOES_NOT_EXIST, no need to report other errors
-    _assertErrorsWithCodes([]);
-  }
-
-  test_perform_error_partOfDifferentLibrary() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'part.dart';
-''',
-      '/part.dart': '''
-part of someOtherLib;
-'''
-    });
-    _assertErrorsWithCodes([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
-  }
-
-  test_perform_error_partOfNonPart() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'part.dart';
-''',
-      '/part.dart': '''
-// no part of
-'''
-    });
-    _assertErrorsWithCodes([CompileTimeErrorCode.PART_OF_NON_PART]);
-  }
-
-  test_perform_invalidUri_part() {
-    String invalidUri = resourceProvider.pathContext.separator == '/'
-        ? '//////////'
-        : '\\\\\\\\\\\\';
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part '$invalidUri';
-'''
-    });
-    expect(libraryElement.parts, hasLength(1));
-  }
-
-  test_perform_isLaunchable_inDefiningUnit() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-main() {
-}
-'''
-    });
-    expect(outputs[IS_LAUNCHABLE], isTrue);
-    expect(libraryElement.entryPoint, isNotNull);
-  }
-
-  test_perform_isLaunchable_inPartUnit() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'part.dart';
-''',
-      '/part.dart': '''
-part of lib;
-main() {
-}
-'''
-    });
-    expect(outputs[IS_LAUNCHABLE], isTrue);
-    expect(libraryElement.entryPoint, isNotNull);
-  }
-
-  test_perform_noSuchFilePart() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'no-such-file.dart';
-'''
-    });
-    expect(libraryElement.parts, hasLength(1));
-    CompilationUnitElement part = libraryElement.parts[0];
-    expect(part, isNotNull);
-    expect(part.source, isNotNull);
-    expect(part.library, same(libraryElement));
-    expect(context.exists(part.source), isFalse);
-  }
-
-  test_perform_patchTopLevelAccessors() {
-    _performBuildTask({
-      '/lib.dart': '''
-library lib;
-part 'part1.dart';
-part 'part2.dart';
-''',
-      '/part1.dart': '''
-part of lib;
-int get test => 0;
-''',
-      '/part2.dart': '''
-part of lib;
-void set test(_) {}
-'''
-    });
-    CompilationUnitElement unitElement1 = partUnits
-        .singleWhere((u) => resolutionMap
-            .elementDeclaredByCompilationUnit(u)
-            .source
-            .fullName
-            .endsWith('part1.dart'))
-        .declaredElement;
-    CompilationUnitElement unitElement2 = partUnits
-        .singleWhere((u) => resolutionMap
-            .elementDeclaredByCompilationUnit(u)
-            .source
-            .fullName
-            .endsWith('part2.dart'))
-        .declaredElement;
-    PropertyAccessorElement getter = unitElement1.accessors[0];
-    PropertyAccessorElement setter = unitElement2.accessors[0];
-    PropertyInducingElement variable = getter.variable;
-    expect(getter.isGetter, isTrue);
-    expect(setter.isSetter, isTrue);
-    expect(variable, isNotNull);
-    expect(setter.variable, same(variable));
-    expect(unitElement1.topLevelVariables, [variable]);
-    expect(unitElement2.topLevelVariables, [variable]);
-  }
-
-  void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
-    _fillErrorListener(BUILD_LIBRARY_ERRORS);
-    errorListener.assertErrorsWithCodes(expectedErrorCodes);
-  }
-
-  void _performBuildTask(Map<String, String> sourceMap) {
-    List<Source> sources = newSources(sourceMap);
-    Source libSource = sources.first;
-    computeResult(libSource, LIBRARY_ELEMENT1,
-        matcher: isBuildLibraryElementTask);
-    libraryUnit = context
-        .getCacheEntry(new LibrarySpecificUnit(libSource, libSource))
-        .getValue(RESOLVED_UNIT1);
-    libraryUnitElement = libraryUnit.declaredElement;
-    librarySource = libraryUnitElement.source;
-    libraryElement = outputs[LIBRARY_ELEMENT1];
-    partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT]
-        as List<CompilationUnit>;
-  }
-}
-
-@reflectiveTest
-class BuildPublicNamespaceTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
-    List<Source> sources = newSources({
-      '/lib.dart': '''
-library lib;
-part 'part.dart';
-a() {}
-_b() {}
-''',
-      '/part.dart': '''
-part of lib;
-_c() {}
-d() {}
-'''
-    });
-    computeResult(sources.first, LIBRARY_ELEMENT3,
-        matcher: isBuildPublicNamespaceTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT3];
-    Namespace namespace = library.publicNamespace;
-    expect(namespace.definedNames.keys, unorderedEquals(['a', 'd']));
-  }
-}
-
-@reflectiveTest
-class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest {
-  List<Source> getExportSourceClosure(Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[EXPORT_SOURCE_CLOSURE] as List<Source>;
-  }
-
-  test_perform_exportClosure() {
-    Source sourceA = newSource('/a.dart', '''
-library lib_a;
-export 'b.dart';
-''');
-    Source sourceB = newSource('/b.dart', '''
-library lib_b;
-export 'c.dart';
-''');
-    Source sourceC = newSource('/c.dart', '''
-library lib_c;
-export 'a.dart';
-''');
-    Source sourceD = newSource('/d.dart', '''
-library lib_d;
-''');
-    // a.dart
-    {
-      computeResult(sourceA, EXPORT_SOURCE_CLOSURE,
-          matcher: isBuildSourceExportClosureTask);
-      List<Source> closure = getExportSourceClosure(outputs);
-      expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
-    }
-    // c.dart
-    {
-      computeResult(sourceC, EXPORT_SOURCE_CLOSURE,
-          matcher: isBuildSourceExportClosureTask);
-      List<Source> closure = getExportSourceClosure(outputs);
-      expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
-    }
-    // d.dart
-    {
-      computeResult(sourceD, EXPORT_SOURCE_CLOSURE,
-          matcher: isBuildSourceExportClosureTask);
-      List<Source> closure = getExportSourceClosure(outputs);
-      expect(closure, unorderedEquals([sourceD]));
-    }
-  }
-}
-
-@reflectiveTest
-class BuildTypeProviderTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
-    computeResult(AnalysisContextTarget.request, TYPE_PROVIDER,
-        matcher: isBuildTypeProviderTask);
-    // validate
-    TypeProvider typeProvider = outputs[TYPE_PROVIDER];
-    expect(typeProvider, isNotNull);
-    expect(typeProvider.boolType, isNotNull);
-    expect(typeProvider.intType, isNotNull);
-    expect(typeProvider.futureType, isNotNull);
-  }
-}
-
-@reflectiveTest
-class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest {
-  Annotation findClassAnnotation(CompilationUnit unit, String className) {
-    for (CompilationUnitMember member in unit.declarations) {
-      if (member is ClassDeclaration && member.name.name == className) {
-        expect(member.metadata, hasLength(1));
-        return member.metadata[0];
-      }
-    }
-    fail('Annotation not found');
-  }
-
-  test_annotation_with_args() {
-    Source source = newSource('/test.dart', '''
-const x = 1;
-@D(x) class C {}
-class D { const D(value); }
-''');
-    // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    // Find the elements for x and D's constructor, and the annotation on C.
-    CompilationUnitElement compilationUnitElement =
-        resolutionMap.elementDeclaredByCompilationUnit(unit);
-    List<PropertyAccessorElement> accessors = compilationUnitElement.accessors;
-    Element x = accessors
-        .firstWhere((PropertyAccessorElement accessor) =>
-            accessor.isGetter && accessor.name == 'x')
-        .variable;
-    List<ClassElement> types = compilationUnitElement.types;
-    Element constructorForD =
-        types.firstWhere((ClassElement cls) => cls.name == 'D').constructors[0];
-    Annotation annotation = findClassAnnotation(unit, 'C');
-    // Now compute the dependencies for the annotation, and check that it is
-    // the set [x, constructorForD].
-    // TODO(paulberry): test librarySource != source
-    computeResult(resolutionMap.elementAnnotationForAnnotation(annotation),
-        CONSTANT_DEPENDENCIES,
-        matcher: isComputeConstantDependenciesTask);
-    expect(
-        outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet());
-  }
-
-  test_annotation_with_nonConstArg() {
-    Source source = newSource('/test.dart', '''
-class A {
-  const A(x);
-}
-class C {
-  @A(const [(_) => null])
-  String s;
-}
-''');
-    // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    // Find the annotation on the field.
-    ClassDeclaration classC = unit.declarations[1];
-    Annotation annotation = classC.members[0].metadata[0];
-    // Now compute the dependencies for the annotation, and check that it is
-    // the right size.
-    computeResult(resolutionMap.elementAnnotationForAnnotation(annotation),
-        CONSTANT_DEPENDENCIES,
-        matcher: isComputeConstantDependenciesTask);
-    expect(outputs[CONSTANT_DEPENDENCIES], hasLength(1));
-  }
-
-  test_annotation_without_args() {
-    Source source = newSource('/test.dart', '''
-const x = 1;
-@x class C {}
-''');
-    // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    // Find the element for x and the annotation on C.
-    List<PropertyAccessorElement> accessors =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).accessors;
-    Element x = accessors
-        .firstWhere((PropertyAccessorElement accessor) =>
-            accessor.isGetter && accessor.name == 'x')
-        .variable;
-    Annotation annotation = findClassAnnotation(unit, 'C');
-    // Now compute the dependencies for the annotation, and check that it is
-    // the list [x].
-    computeResult(resolutionMap.elementAnnotationForAnnotation(annotation),
-        CONSTANT_DEPENDENCIES,
-        matcher: isComputeConstantDependenciesTask);
-    expect(outputs[CONSTANT_DEPENDENCIES], [x]);
-  }
-
-  test_enumConstant() {
-    Source source = newSource('/test.dart', '''
-enum E {A, B, C}
-''');
-    // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT3);
-    CompilationUnit unit = outputs[RESOLVED_UNIT3];
-    // Find the element for 'A'
-    EnumDeclaration enumDeclaration = unit.declarations[0];
-    EnumConstantDeclaration constantDeclaration = enumDeclaration.constants[0];
-    FieldElement constantElement = constantDeclaration.declaredElement;
-    // Now compute the dependencies for the constant and check that there are
-    // none.
-    computeResult(constantElement, CONSTANT_DEPENDENCIES,
-        matcher: isComputeConstantDependenciesTask);
-    expect(outputs[CONSTANT_DEPENDENCIES], isEmpty);
-  }
-
-  test_perform() {
-    Source source = newSource('/test.dart', '''
-const x = y;
-const y = 1;
-''');
-    // First compute the resolved unit for the source.
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    // Find the elements for the constants x and y.
-    List<PropertyAccessorElement> accessors =
-        resolutionMap.elementDeclaredByCompilationUnit(unit).accessors;
-    Element x = accessors
-        .firstWhere((PropertyAccessorElement accessor) =>
-            accessor.isGetter && accessor.name == 'x')
-        .variable;
-    Element y = accessors
-        .firstWhere((PropertyAccessorElement accessor) =>
-            accessor.isGetter && accessor.name == 'y')
-        .variable;
-    // Now compute the dependencies for x, and check that it is the list [y].
-    computeResult(x, CONSTANT_DEPENDENCIES,
-        matcher: isComputeConstantDependenciesTask);
-    expect(outputs[CONSTANT_DEPENDENCIES], [y]);
-  }
-}
-
-@reflectiveTest
-class ComputeConstantValueTaskTest extends _AbstractDartTaskTest {
-  EvaluationResultImpl computeClassAnnotation(
-      Source source, CompilationUnit unit, String className) {
-    for (CompilationUnitMember member in unit.declarations) {
-      if (member is ClassDeclaration && member.name.name == className) {
-        expect(member.metadata, hasLength(1));
-        Annotation annotation = member.metadata[0];
-        ElementAnnotationImpl target = annotation.elementAnnotation;
-        computeResult(target, CONSTANT_VALUE,
-            matcher: isComputeConstantValueTask);
-        expect(outputs[CONSTANT_VALUE], same(target));
-        EvaluationResultImpl evaluationResult =
-            (annotation.elementAnnotation as ElementAnnotationImpl)
-                .evaluationResult;
-        return evaluationResult;
-      }
-    }
-    fail('Annotation not found');
-  }
-
-  test_annotation_non_const_constructor() {
-    // Calling a non-const constructor from an annotation that is illegal, but
-    // shouldn't crash analysis.
-    Source source = newSource('/test.dart', '''
-class A {
-  final int i;
-  A(this.i);
-}
-
-@A(5)
-class C {}
-''');
-    // First compute the resolved unit for the source.
-    CompilationUnit unit = _resolveSource(source);
-    // Compute the constant value of the annotation on C.
-    EvaluationResultImpl evaluationResult =
-        computeClassAnnotation(source, unit, 'C');
-    // And check that it has no value stored in it.
-    expect(evaluationResult, isNotNull);
-    expect(evaluationResult.value, isNull);
-  }
-
-  test_annotation_with_args() {
-    Source source = newSource('/test.dart', '''
-const x = 1;
-@D(x) class C {}
-class D {
-  const D(this.value);
-  final value;
-}
-''');
-    // First compute the resolved unit for the source.
-    CompilationUnit unit = _resolveSource(source);
-    // Compute the constant value of the annotation on C.
-    EvaluationResultImpl evaluationResult =
-        computeClassAnnotation(source, unit, 'C');
-    // And check that it has the expected value.
-    expect(evaluationResult, isNotNull);
-    expect(evaluationResult.value, isNotNull);
-    expect(evaluationResult.value.type, isNotNull);
-    expect(evaluationResult.value.type.name, 'D');
-    expect(evaluationResult.value.fields, contains('value'));
-    expect(evaluationResult.value.fields['value'].toIntValue(), 1);
-  }
-
-  test_annotation_without_args() {
-    Source source = newSource('/test.dart', '''
-const x = 1;
-@x class C {}
-''');
-    // First compute the resolved unit for the source.
-    CompilationUnit unit = _resolveSource(source);
-    // Compute the constant value of the annotation on C.
-    EvaluationResultImpl evaluationResult =
-        computeClassAnnotation(source, unit, 'C');
-    // And check that it has the expected value.
-    expect(evaluationResult, isNotNull);
-    expect(evaluationResult.value, isNotNull);
-    expect(evaluationResult.value.toIntValue(), 1);
-  }
-
-  test_circular_reference() {
-    _checkCircularities('x', ['y'], '''
-const x = y + 1;
-const y = x + 1;
-''');
-  }
-
-  test_circular_reference_one_element() {
-    // See dartbug.com/23490.
-    _checkCircularities('x', [], 'const x = x;');
-  }
-
-  test_circular_reference_strongly_connected_component() {
-    // When there is a circularity, all elements in the strongly connected
-    // component should be marked as having an error.
-    _checkCircularities('a', ['b', 'c', 'd'], '''
-const a = b;
-const b = c + d;
-const c = a;
-const d = a;
-''');
-  }
-
-  test_const_constructor_calls_implicit_super_constructor_implicitly() {
-    // Note: the situation below is a compile-time error (since the synthetic
-    // constructor for Base is non-const), but we need to handle it without
-    // throwing an exception.
-    EvaluationResultImpl evaluationResult =
-        _computeTopLevelVariableConstValue('x', '''
-class Base {}
-class Derived extends Base {
-  const Derived();
-}
-const x = const Derived();
-''');
-    expect(evaluationResult, isNotNull);
-  }
-
-  test_dependency() {
-    EvaluationResultImpl evaluationResult =
-        _computeTopLevelVariableConstValue('x', '''
-const x = y + 1;
-const y = 1;
-''');
-    expect(evaluationResult, isNotNull);
-    expect(evaluationResult.value, isNotNull);
-    expect(evaluationResult.value.toIntValue(), 2);
-  }
-
-  test_external_const_factory() {
-    EvaluationResultImpl evaluationResult =
-        _computeTopLevelVariableConstValue('x', '''
-const x = const C.foo();
-
-class C extends B {
-  external const factory C.foo();
-}
-
-class B {}
-''');
-    expect(evaluationResult, isNotNull);
-  }
-
-  test_simple_constant() {
-    EvaluationResultImpl evaluationResult =
-        _computeTopLevelVariableConstValue('x', '''
-const x = 1;
-''');
-    expect(evaluationResult, isNotNull);
-    expect(evaluationResult.value, isNotNull);
-    expect(evaluationResult.value.toIntValue(), 1);
-  }
-
-  void _checkCircularities(
-      String variableName, List<String> otherVariables, String content) {
-    // Evaluating the first constant should produce an error.
-    CompilationUnit unit = _resolveUnit(content);
-    _expectCircularityError(_evaluateConstant(unit, variableName));
-    // And all the other constants involved in the strongly connected component
-    // should be set to the same error state.
-    for (String otherVariableName in otherVariables) {
-      PropertyInducingElement otherVariableElement =
-          AstFinder.getTopLevelVariableElement(unit, otherVariableName);
-      _expectCircularityError(
-          (otherVariableElement as TopLevelVariableElementImpl)
-              .evaluationResult);
-    }
-  }
-
-  EvaluationResultImpl _computeTopLevelVariableConstValue(
-      String variableName, String content) {
-    return _evaluateConstant(_resolveUnit(content), variableName);
-  }
-
-  EvaluationResultImpl _evaluateConstant(
-      CompilationUnit unit, String variableName) {
-    // Find the element for the given constant.
-    PropertyInducingElement variableElement =
-        AstFinder.getTopLevelVariableElement(unit, variableName);
-    // Now compute the value of the constant.
-    computeResult(variableElement, CONSTANT_VALUE,
-        matcher: isComputeConstantValueTask);
-    expect(outputs[CONSTANT_VALUE], same(variableElement));
-    EvaluationResultImpl evaluationResult =
-        (variableElement as TopLevelVariableElementImpl).evaluationResult;
-    return evaluationResult;
-  }
-
-  void _expectCircularityError(EvaluationResultImpl evaluationResult) {
-    expect(evaluationResult, isNotNull);
-    expect(evaluationResult.value, isNull);
-    expect(evaluationResult.errors, hasLength(1));
-    expect(evaluationResult.errors[0].errorCode,
-        CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);
-  }
-
-  CompilationUnit _resolveSource(Source source) {
-    LibrarySpecificUnit librarySpecificUnit =
-        new LibrarySpecificUnit(source, source);
-    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
-    CompilationUnit unit = outputs[RESOLVED_UNIT1];
-    return unit;
-  }
-
-  CompilationUnit _resolveUnit(String content) =>
-      _resolveSource(newSource('/test.dart', content));
-}
-
-@reflectiveTest
-class ComputeInferableStaticVariableDependenciesTaskTest
-    extends _AbstractDartTaskTest {
-  @override
-  void setUp() {
-    super.setUp();
-    // Variable dependencies are only available in strong mode.
-  }
-
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    expect(outputs[RESOLVED_UNIT7], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT7], isTrue);
-  }
-
-  test_perform() {
-    AnalysisTarget source = newSource('/test.dart', '''
-const a = b;
-const b = 0;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement elementA = resolutionMap
-        .elementDeclaredByCompilationUnit(unit)
-        .topLevelVariables[0];
-    TopLevelVariableElement elementB = resolutionMap
-        .elementDeclaredByCompilationUnit(unit)
-        .topLevelVariables[1];
-
-    computeResult(elementA, INFERABLE_STATIC_VARIABLE_DEPENDENCIES,
-        matcher: isComputeInferableStaticVariableDependenciesTask);
-    expect(outputs, hasLength(1));
-    List<VariableElement> dependencies =
-        outputs[INFERABLE_STATIC_VARIABLE_DEPENDENCIES]
-            as List<VariableElement>;
-    expect(dependencies, unorderedEquals([elementB]));
-  }
-}
-
-@reflectiveTest
-class ComputeLibraryCycleTaskTest extends _AbstractDartTaskTest {
-  List<LibraryElement> getLibraryCycle(Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[LIBRARY_CYCLE] as List<LibraryElement>;
-  }
-
-  List<LibrarySpecificUnit> getLibraryCycleDependencies(
-      Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[LIBRARY_CYCLE_DEPENDENCIES] as List<LibrarySpecificUnit>;
-  }
-
-  List<LibrarySpecificUnit> getLibraryCycleUnits(
-      Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[LIBRARY_CYCLE_UNITS] as List<LibrarySpecificUnit>;
-  }
-
-  void test_library_cycle_incremental() {
-    Source a = newSource('/a.dart', '''
-library a;
-''');
-    Source b = newSource('/b.dart', '''
-library b;
-import 'a.dart';
-''');
-    Source c = newSource('/c.dart', '''
-library c;
-import 'b.dart';
-''');
-
-    _assertLibraryCycle(a, [a]);
-    _assertLibraryCycle(b, [b]);
-    _assertLibraryCycle(c, [c]);
-
-    // Create a cycle.
-    context.setContents(a, '''
-library a;
-import 'c.dart';
-''');
-    _expectInvalid(a);
-    _expectInvalid(b);
-    _expectInvalid(c);
-
-    _assertLibraryCycle(a, [a, b, c]);
-    _assertLibraryCycle(b, [a, b, c]);
-    _assertLibraryCycle(c, [a, b, c]);
-
-    // Break the cycle again.
-    context.setContents(a, '''
-library a;
-''');
-    _expectInvalid(a);
-    _expectInvalid(b);
-    _expectInvalid(c);
-
-    _assertLibraryCycle(a, [a]);
-    _assertLibraryCycle(b, [b]);
-    _assertLibraryCycle(c, [c]);
-  }
-
-  void test_library_cycle_incremental_partial() {
-    Source a = newSource('/a.dart', r'''
-library a;
-''');
-    Source b = newSource('/b.dart', r'''
-library b;
-import 'a.dart';
-''');
-    Source c = newSource('/c.dart', r'''
-library c;
-import 'b.dart';
-''');
-
-    _assertLibraryCycle(a, [a]);
-    _assertLibraryCycle(b, [b]);
-    // 'c' is not reachable, so we have not yet computed its library cycles.
-
-    // Complete the cycle, via 'c'.
-    context.setContents(a, r'''
-library a;
-import 'c.dart';
-''');
-    _expectInvalid(a);
-    _expectInvalid(b);
-    _expectInvalid(c);
-
-    // Ensure that everything reachable through 'c' was invalidated,
-    // and recomputed to include all three sources.
-    _assertLibraryCycle(a, [a, b, c]);
-    _assertLibraryCycle(b, [a, b, c]);
-    _assertLibraryCycle(c, [a, b, c]);
-  }
-
-  void test_library_cycle_incremental_partial2() {
-    Source a = newSource('/a.dart', r'''
-library a;
-import 'b.dart';
-''');
-    Source b = newSource('/b.dart', r'''
-library b;
-import 'a.dart';
-''');
-    Source c = newSource('/c.dart', r'''
-library c;
-import 'b.dart';
-''');
-
-    _assertLibraryCycle(a, [a, b]);
-    _assertLibraryCycle(b, [a, b]);
-    _assertLibraryCycle(c, [c]);
-
-    // Include 'c' into the cycle.
-    context.setContents(a, r'''
-library a;
-import 'b.dart';
-import 'c.dart';
-''');
-    _expectInvalid(a);
-    _expectInvalid(b);
-    _expectInvalid(c);
-
-    // Start processing with 'b', so that when we resolve 'b' directives,
-    // and invalidate library cycles, the 'a' directives are not resolved yet,
-    // so we don't know that the cycle must include 'c'.
-    _assertLibraryCycle(b, [a, b, c]);
-    _assertLibraryCycle(a, [a, b, c]);
-    _assertLibraryCycle(c, [a, b, c]);
-  }
-
-  void test_library_cycle_linear() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-''',
-      '/b.dart': '''
-import 'a.dart';
-  '''
-    });
-    List<Map<ResultDescriptor, dynamic>> results =
-        computeLibraryResultsMap(sources, LIBRARY_CYCLE);
-    List<LibraryElement> component0 = getLibraryCycle(results[0]);
-    List<LibraryElement> component1 = getLibraryCycle(results[1]);
-    expect(component0, hasLength(1));
-    expect(component1, hasLength(1));
-
-    List<LibrarySpecificUnit> units0 = getLibraryCycleUnits(results[0]);
-    List<LibrarySpecificUnit> units1 = getLibraryCycleUnits(results[1]);
-    expect(units0, hasLength(1));
-    expect(units1, hasLength(1));
-
-    List<LibrarySpecificUnit> dep0 = getLibraryCycleDependencies(results[0]);
-    List<LibrarySpecificUnit> dep1 = getLibraryCycleDependencies(results[1]);
-    expect(dep0, hasLength(1)); // dart:core
-    expect(dep1, hasLength(2)); // dart:core, a.dart
-  }
-
-  void test_library_cycle_loop() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-  import 'c.dart';
-''',
-      '/b.dart': '''
-  import 'a.dart';
-  ''',
-      '/c.dart': '''
-  import 'b.dart';
-  '''
-    });
-    List<Map<ResultDescriptor, dynamic>> results =
-        computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
-    List<LibraryElement> component0 = getLibraryCycle(results[0]);
-    List<LibraryElement> component1 = getLibraryCycle(results[1]);
-    List<LibraryElement> component2 = getLibraryCycle(results[2]);
-
-    expect(component0, hasLength(3));
-    expect(component1, hasLength(3));
-    expect(component2, hasLength(3));
-
-    List<LibrarySpecificUnit> units0 = getLibraryCycleUnits(results[0]);
-    List<LibrarySpecificUnit> units1 = getLibraryCycleUnits(results[1]);
-    List<LibrarySpecificUnit> units2 = getLibraryCycleUnits(results[2]);
-    expect(units0, hasLength(3));
-    expect(units1, hasLength(3));
-    expect(units2, hasLength(3));
-
-    List<LibrarySpecificUnit> dep0 = getLibraryCycleDependencies(results[0]);
-    List<LibrarySpecificUnit> dep1 = getLibraryCycleDependencies(results[1]);
-    List<LibrarySpecificUnit> dep2 = getLibraryCycleDependencies(results[2]);
-    expect(dep0, hasLength(1)); // dart:core
-    expect(dep1, hasLength(1)); // dart:core
-    expect(dep2, hasLength(1)); // dart:core
-  }
-
-  void test_library_cycle_override_inference_incremental() {
-    Source lib1Source = newSource('/my_lib1.dart', '''
-library my_lib1;
-import 'my_lib3.dart';
-''');
-    Source lib2Source = newSource('/my_lib2.dart', '''
-library my_lib2;
-import 'my_lib1.dart';
-''');
-    Source lib3Source = newSource('/my_lib3.dart', '''
-library my_lib3;
-import 'my_lib2.dart';
-
-class A {
-  int foo(int x) => null;
-}
-class B extends A {
-  foo(x) => null;
-}
-''');
-    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
-    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
-    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
-
-    computeResult(lib1Target, RESOLVED_UNIT);
-    computeResult(lib2Target, RESOLVED_UNIT);
-    computeResult(lib3Target, RESOLVED_UNIT);
-    CompilationUnit unit = outputs[RESOLVED_UNIT];
-    ClassElement b = unit.declarations[1].declaredElement;
-    expect(b.getMethod('foo').returnType.toString(), 'int');
-
-    // add a dummy edit.
-    context.setContents(lib1Source, '''
-library my_lib1;
-import 'my_lib3.dart';
-var foo = 123;
-''');
-    _expectInvalid(lib1Source);
-    _expectInvalid(lib2Source);
-    _expectInvalid(lib3Source);
-
-    computeResult(lib1Target, RESOLVED_UNIT);
-    computeResult(lib2Target, RESOLVED_UNIT);
-    computeResult(lib3Target, RESOLVED_UNIT);
-    unit = outputs[RESOLVED_UNIT];
-    b = unit.declarations[1].declaredElement;
-    expect(b.getMethod('foo').returnType.toString(), 'int',
-        reason: 'edit should not affect member inference');
-  }
-
-  void test_library_cycle_self_loop() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-  import 'a.dart';
-'''
-    });
-    List<Map<ResultDescriptor, dynamic>> results =
-        computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
-    List<LibraryElement> component0 = getLibraryCycle(results[0]);
-    expect(component0, hasLength(1));
-
-    List<LibrarySpecificUnit> units0 = getLibraryCycleUnits(results[0]);
-    expect(units0, hasLength(1));
-
-    List<LibrarySpecificUnit> dep0 = getLibraryCycleDependencies(results[0]);
-    expect(dep0, hasLength(1)); // dart:core
-  }
-
-  void test_library_cycle_singleton() {
-    Source source = newSource('/test.dart', '''
-import 'dart:core';
-''');
-    computeResult(source, LIBRARY_CYCLE);
-    List<LibraryElement> component = getLibraryCycle(outputs);
-    List<LibrarySpecificUnit> units = getLibraryCycleUnits(outputs);
-    List<LibrarySpecificUnit> deps = getLibraryCycleDependencies(outputs);
-    expect(component, hasLength(1));
-    expect(units, hasLength(1));
-    expect(deps, hasLength(1));
-  }
-
-  void test_library_cycle_tree() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-''',
-      '/b.dart': '''
-  ''',
-      '/c.dart': '''
-  import 'a.dart';
-  import 'b.dart';
-  '''
-    });
-    List<Map<ResultDescriptor, dynamic>> results =
-        computeLibraryResultsMap(sources, LIBRARY_CYCLE);
-    List<LibraryElement> component0 = getLibraryCycle(results[0]);
-    List<LibraryElement> component1 = getLibraryCycle(results[1]);
-    List<LibraryElement> component2 = getLibraryCycle(results[2]);
-    expect(component0, hasLength(1));
-    expect(component1, hasLength(1));
-    expect(component2, hasLength(1));
-
-    List<LibrarySpecificUnit> units0 = getLibraryCycleUnits(results[0]);
-    List<LibrarySpecificUnit> units1 = getLibraryCycleUnits(results[1]);
-    List<LibrarySpecificUnit> units2 = getLibraryCycleUnits(results[2]);
-    expect(units0, hasLength(1));
-    expect(units1, hasLength(1));
-    expect(units2, hasLength(1));
-
-    List<LibrarySpecificUnit> dep0 = getLibraryCycleDependencies(results[0]);
-    List<LibrarySpecificUnit> dep1 = getLibraryCycleDependencies(results[1]);
-    List<LibrarySpecificUnit> dep2 = getLibraryCycleDependencies(results[2]);
-    expect(dep0, hasLength(1)); // dart:core
-    expect(dep1, hasLength(1)); // dart:core,
-    expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
-  }
-
-  void test_library_double_loop() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-  import 'b.dart';
-''',
-      '/b.dart': '''
-  import 'a.dart';
-  ''',
-      '/c.dart': '''
-  import 'd.dart' as foo;
-  import 'a.dart' as bar;
-  export 'b.dart';
-  ''',
-      '/d.dart': '''
-  import 'c.dart' as foo;
-  import 'b.dart' as bar;
-  export 'a.dart';
-  '''
-    });
-    List<Map<ResultDescriptor, dynamic>> results =
-        computeLibraryResultsMap(sources, LIBRARY_CYCLE).toList();
-    List<LibraryElement> component0 = getLibraryCycle(results[0]);
-    List<LibraryElement> component1 = getLibraryCycle(results[1]);
-    List<LibraryElement> component2 = getLibraryCycle(results[2]);
-    List<LibraryElement> component3 = getLibraryCycle(results[3]);
-
-    expect(component0, hasLength(2));
-    expect(component1, hasLength(2));
-    expect(component2, hasLength(2));
-    expect(component3, hasLength(2));
-
-    List<LibrarySpecificUnit> units0 = getLibraryCycleUnits(results[0]);
-    List<LibrarySpecificUnit> units1 = getLibraryCycleUnits(results[1]);
-    List<LibrarySpecificUnit> units2 = getLibraryCycleUnits(results[2]);
-    List<LibrarySpecificUnit> units3 = getLibraryCycleUnits(results[3]);
-    expect(units0, hasLength(2));
-    expect(units1, hasLength(2));
-    expect(units2, hasLength(2));
-    expect(units3, hasLength(2));
-
-    List<LibrarySpecificUnit> dep0 = getLibraryCycleDependencies(results[0]);
-    List<LibrarySpecificUnit> dep1 = getLibraryCycleDependencies(results[1]);
-    List<LibrarySpecificUnit> dep2 = getLibraryCycleDependencies(results[2]);
-    List<LibrarySpecificUnit> dep3 = getLibraryCycleDependencies(results[3]);
-    expect(dep0, hasLength(1)); // dart:core
-    expect(dep1, hasLength(1)); // dart:core
-    expect(dep2, hasLength(3)); // dart:core, a.dart, b.dart
-    expect(dep3, hasLength(3)); // dart:core, a.dart, b.dart
-  }
-
-  void test_library_double_loop_parts() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-  import 'b.dart';
-  part 'aa.dart';
-  part 'ab.dart';
-''',
-      '/b.dart': '''
-  import 'a.dart';
-''',
-      '/aa.dart': '''
-''',
-      '/ab.dart': '''
-''',
-      '/c.dart': '''
-  import 'd.dart' as foo;
-  import 'a.dart' as bar;
-  export 'b.dart';
-''',
-      '/d.dart': '''
-  import 'c.dart' as foo;
-  import 'b.dart' as bar;
-  export 'a.dart';
-  part 'da.dart';
-  part 'db.dart';
-''',
-      '/da.dart': '''
-''',
-      '/db.dart': '''
-'''
-    });
-    computeResult(sources[0], LIBRARY_CYCLE);
-    Map<ResultDescriptor, dynamic> results0 = outputs;
-    computeResult(sources[1], LIBRARY_CYCLE);
-    Map<ResultDescriptor, dynamic> results1 = outputs;
-    computeResult(sources[4], LIBRARY_CYCLE);
-    Map<ResultDescriptor, dynamic> results4 = outputs;
-    computeResult(sources[5], LIBRARY_CYCLE);
-    Map<ResultDescriptor, dynamic> results5 = outputs;
-
-    List<LibraryElement> component0 = getLibraryCycle(results0);
-    List<LibraryElement> component1 = getLibraryCycle(results1);
-    List<LibraryElement> component4 = getLibraryCycle(results4);
-    List<LibraryElement> component5 = getLibraryCycle(results5);
-
-    expect(component0, hasLength(2));
-    expect(component1, hasLength(2));
-    expect(component4, hasLength(2));
-    expect(component5, hasLength(2));
-
-    List<LibrarySpecificUnit> units0 = getLibraryCycleUnits(results0);
-    List<LibrarySpecificUnit> units1 = getLibraryCycleUnits(results1);
-    List<LibrarySpecificUnit> units4 = getLibraryCycleUnits(results4);
-    List<LibrarySpecificUnit> units5 = getLibraryCycleUnits(results5);
-    expect(units0, hasLength(4));
-    expect(units1, hasLength(4));
-    expect(units4, hasLength(4));
-    expect(units5, hasLength(4));
-
-    List<LibrarySpecificUnit> dep0 = getLibraryCycleDependencies(results0);
-    List<LibrarySpecificUnit> dep1 = getLibraryCycleDependencies(results1);
-    List<LibrarySpecificUnit> dep4 = getLibraryCycleDependencies(results4);
-    List<LibrarySpecificUnit> dep5 = getLibraryCycleDependencies(results5);
-    expect(dep0, hasLength(1)); // dart:core
-    expect(dep1, hasLength(1)); // dart:core
-    expect(dep4, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
-    expect(dep5, hasLength(5)); // dart:core, a.dart, aa.dart, ab.dart, b.dart
-  }
-
-  void _assertLibraryCycle(Source source, List<Source> expected) {
-    computeResult(source, LIBRARY_CYCLE);
-    List<LibraryElement> cycle = outputs[LIBRARY_CYCLE] as List<LibraryElement>;
-    expect(cycle.map((e) => e.source), unorderedEquals(expected));
-  }
-
-  void _expectInvalid(Source librarySource) {
-    CacheEntry entry = context.getCacheEntry(librarySource);
-    expect(entry.getState(LIBRARY_CYCLE), CacheState.INVALID);
-  }
-}
-
-@reflectiveTest
-class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
-  List<Source> getContainingLibraries(Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[CONTAINING_LIBRARIES] as List<Source>;
-  }
-
-  test_perform_definingCompilationUnit() {
-    AnalysisTarget library = newSource('/test.dart', 'library test;');
-    computeResult(library, INCLUDED_PARTS);
-    computeResult(library, CONTAINING_LIBRARIES,
-        matcher: isContainingLibrariesTask);
-    expect(outputs, hasLength(1));
-    List<Source> containingLibraries = getContainingLibraries(outputs);
-    expect(containingLibraries, unorderedEquals([library]));
-  }
-
-  test_perform_partInMultipleLibraries() {
-    AnalysisTarget library1 =
-        newSource('/lib1.dart', 'library test; part "part.dart";');
-    AnalysisTarget library2 =
-        newSource('/lib2.dart', 'library test; part "part.dart";');
-    AnalysisTarget part = newSource('/part.dart', 'part of test;');
-    computeResult(library1, INCLUDED_PARTS);
-    computeResult(library2, INCLUDED_PARTS);
-    computeResult(part, SOURCE_KIND);
-    computeResult(part, CONTAINING_LIBRARIES,
-        matcher: isContainingLibrariesTask);
-    expect(outputs, hasLength(1));
-    List<Source> containingLibraries = getContainingLibraries(outputs);
-    expect(containingLibraries, unorderedEquals([library1, library2]));
-  }
-
-  test_perform_partInSingleLibrary() {
-    AnalysisTarget library =
-        newSource('/lib.dart', 'library test; part "part.dart";');
-    AnalysisTarget part = newSource('/part.dart', 'part of test;');
-    computeResult(library, INCLUDED_PARTS);
-    computeResult(part, SOURCE_KIND);
-    computeResult(part, CONTAINING_LIBRARIES,
-        matcher: isContainingLibrariesTask);
-    expect(outputs, hasLength(1));
-    List<Source> containingLibraries = getContainingLibraries(outputs);
-    expect(containingLibraries, unorderedEquals([library]));
-  }
-}
-
-@reflectiveTest
-class DartErrorsTaskTest extends _AbstractDartTaskTest {
-  List<AnalysisError> getDartErrors(Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[DART_ERRORS] as List<AnalysisError>;
-  }
-
-  test_perform_definingCompilationUnit() {
-    AnalysisTarget library =
-        newSource('/test.dart', 'library test; import "dart:math";');
-    computeResult(library, INCLUDED_PARTS);
-    computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
-    expect(outputs, hasLength(1));
-    List<AnalysisError> errors = getDartErrors(outputs);
-    expect(errors, hasLength(1));
-  }
-
-  test_perform_partInSingleLibrary() {
-    AnalysisTarget library = newSource(
-        '/lib.dart', 'library test; import "dart:math"; part "part.dart";');
-    AnalysisTarget part =
-        newSource('/part.dart', 'part of test; class A extends A {}');
-    computeResult(library, INCLUDED_PARTS);
-    computeResult(library, DART_ERRORS);
-    computeResult(part, DART_ERRORS, matcher: isDartErrorsTask);
-    expect(outputs, hasLength(1));
-    List<AnalysisError> errors = getDartErrors(outputs);
-    // This should contain only the errors in the part file, not the ones in the
-    // library.
-    expect(errors, hasLength(1));
-  }
-}
-
-@reflectiveTest
-class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT12);
-    expect(outputs[RESOLVED_UNIT12], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
-  }
-
-  test_perform() {
-    Source source = newSource('/test.dart', '''
-class C {
-  const C();
-}
-
-@x
-f() {}
-
-const x = const C();
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT12,
-        matcher: isEvaluateUnitConstantsTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
-    CompilationUnitElement unitElement = unit.declaredElement;
-    expect(
-        (unitElement.types[0].constructors[0] as ConstructorElementImpl)
-            .isCycleFree,
-        isTrue);
-    expect(
-        (unitElement.functions[0].metadata[0] as ElementAnnotationImpl)
-            .evaluationResult,
-        isNotNull);
-    expect(
-        (unitElement.topLevelVariables[0] as TopLevelVariableElementImpl)
-            .evaluationResult,
-        isNotNull);
-  }
-}
-
-@reflectiveTest
-class GatherUsedImportedElementsTaskTest extends _AbstractDartTaskTest {
-  UsedImportedElements usedElements;
-  Set<String> usedElementNames;
-
-  test_perform_inBody() {
-    newSource('/a.dart', r'''
-library lib_a;
-class A {}
-''');
-    newSource('/b.dart', r'''
-library lib_b;
-class B {}
-''');
-    Source source = newSource('/test.dart', r'''
-import 'a.dart';
-import 'b.dart';
-main() {
-  new A();
-}''');
-    _computeUsedElements(source);
-    // validate
-    expect(usedElementNames, unorderedEquals(['A']));
-  }
-
-  test_perform_inComment_exportDirective() {
-    Source source = newSource('/test.dart', r'''
-import 'dart:async';
-/// Use [Future].
-export 'dart:math';
-''');
-    _computeUsedElements(source);
-    expect(usedElementNames, unorderedEquals(['Future']));
-  }
-
-  test_perform_inComment_importDirective() {
-    Source source = newSource('/test.dart', r'''
-import 'dart:async';
-/// Use [Future].
-import 'dart:math';
-''');
-    _computeUsedElements(source);
-    expect(usedElementNames, unorderedEquals(['Future']));
-  }
-
-  test_perform_inComment_libraryDirective() {
-    Source source = newSource('/test.dart', r'''
-/// Use [Future].
-library test;
-import 'dart:async';
-''');
-    _computeUsedElements(source);
-    expect(usedElementNames, unorderedEquals(['Future']));
-  }
-
-  test_perform_inComment_topLevelFunction() {
-    Source source = newSource('/test.dart', r'''
-import 'dart:async';
-/// Use [Future].
-main() {}
-''');
-    _computeUsedElements(source);
-    expect(usedElementNames, unorderedEquals(['Future']));
-  }
-
-  void _computeUsedElements(Source source) {
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, USED_IMPORTED_ELEMENTS,
-        matcher: isGatherUsedImportedElementsTask);
-    usedElements = outputs[USED_IMPORTED_ELEMENTS];
-    usedElementNames = usedElements.elements.map((e) => e.name).toSet();
-  }
-}
-
-@reflectiveTest
-class GatherUsedLocalElementsTaskTest extends _AbstractDartTaskTest {
-  UsedLocalElements usedElements;
-  Set<String> usedElementNames;
-
-  test_perform_forPart_afterLibraryUpdate() {
-    Source libSource = newSource('/my_lib.dart', '''
-library my_lib;
-part 'my_part.dart';
-foo() => null;
-class _LocalClass {}
-''');
-    Source partSource = newSource('/my_part.dart', '''
-part of my_lib;
-bar() {
-  print(_LocalClass);
-}
-''');
-    AnalysisTarget libTarget = new LibrarySpecificUnit(libSource, libSource);
-    AnalysisTarget partTarget = new LibrarySpecificUnit(libSource, partSource);
-    computeResult(libTarget, USED_LOCAL_ELEMENTS);
-    computeResult(partTarget, USED_LOCAL_ELEMENTS);
-    // _LocalClass is used in my_part.dart
-    {
-      UsedLocalElements usedElements =
-          analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS);
-      expect(usedElements.elements, contains(predicate((Element e) {
-        return e.displayName == '_LocalClass';
-      })));
-    }
-    // change my_lib.dart and recompute
-    context.setContents(libSource, '''
-library my_lib;
-part 'my_part.dart';
-String foo() => null;
-class _LocalClass {}
-''');
-    computeResult(libTarget, USED_LOCAL_ELEMENTS);
-    computeResult(partTarget, USED_LOCAL_ELEMENTS);
-    // _LocalClass should still be used in my_part.dart
-    {
-      UsedLocalElements usedElements =
-          analysisCache.getValue(partTarget, USED_LOCAL_ELEMENTS);
-      expect(usedElements.elements, contains(predicate((Element e) {
-        return e.displayName == '_LocalClass';
-      })));
-    }
-  }
-
-  test_perform_localVariable() {
-    Source source = newSource('/test.dart', r'''
-main() {
-  var v1 = 1;
-  var v2 = 2;
-  print(v2);
-}''');
-    _computeUsedElements(source);
-    // validate
-    expect(usedElementNames, unorderedEquals(['v2']));
-  }
-
-  test_perform_method() {
-    Source source = newSource('/test.dart', r'''
-class A {
-  _m1() {}
-  _m2() {}
-}
-
-main(A a, p) {
-  a._m2();
-  p._m3();
-}
-''');
-    _computeUsedElements(source);
-    // validate
-    expect(usedElementNames, unorderedEquals(['A', 'a', 'p', '_m2']));
-    expect(usedElements.members, unorderedEquals(['_m2', '_m3']));
-  }
-
-  void _computeUsedElements(Source source) {
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, USED_LOCAL_ELEMENTS,
-        matcher: isGatherUsedLocalElementsTask);
-    usedElements = outputs[USED_LOCAL_ELEMENTS];
-    usedElementNames = usedElements.elements.map((e) => e.name).toSet();
-  }
-}
-
-@reflectiveTest
-class GenerateHintsTaskTest extends _AbstractDartTaskTest {
-  test_perform_bestPractices_missingReturn() {
-    Source source = newSource('/test.dart', '''
-int main() {
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.MISSING_RETURN]);
-  }
-
-  test_perform_dart2js() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.dart2jsHint = true;
-    prepareAnalysisContext(options);
-    Source source = newSource('/test.dart', '''
-main(p) {
-  if (p is double) {
-    print('double');
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.IS_DOUBLE]);
-  }
-
-  test_perform_deadCode() {
-    Source source = newSource('/test.dart', '''
-main() {
-  if (false) {
-    print('how?');
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DEAD_CODE]);
-  }
-
-  test_perform_disabled() {
-    context.analysisOptions =
-        new AnalysisOptionsImpl.from(context.analysisOptions)..hint = false;
-    Source source = newSource('/test.dart', '''
-int main() {
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertNoErrors();
-  }
-
-  test_perform_imports_duplicateImport() {
-    newSource('/a.dart', r'''
-library lib_a;
-class A {}
-''');
-    Source source = newSource('/test.dart', r'''
-import 'a.dart';
-import 'a.dart';
-main() {
-  new A();
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.DUPLICATE_IMPORT]);
-  }
-
-  test_perform_imports_unusedImport_one() {
-    newSource('/a.dart', r'''
-library lib_a;
-class A {}
-''');
-    newSource('/b.dart', r'''
-library lib_b;
-class B {}
-''');
-    Source source = newSource('/test.dart', r'''
-import 'a.dart';
-import 'b.dart';
-main() {
-  new A();
-}''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_IMPORT]);
-  }
-
-  test_perform_imports_unusedImport_zero() {
-    newSource('/a.dart', r'''
-library lib_a;
-class A {}
-''');
-    Source source = newSource('/test.dart', r'''
-import 'a.dart';
-main() {
-  new A();
-}''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertNoErrors();
-  }
-
-  test_perform_overrideVerifier() {
-    Source source = newSource('/test.dart', '''
-class A {}
-class B {
-  @override
-  m() {}
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
-  }
-
-  test_perform_todo() {
-    Source source = newSource('/test.dart', '''
-main() {
-  // TODO(developer) foo bar
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[TodoCode.TODO]);
-  }
-
-  test_perform_unusedLocalElements_class() {
-    Source source = newSource('/test.dart', '''
-class _A {}
-class _B {}
-main() {
-  new _A();
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_ELEMENT]);
-  }
-
-  test_perform_unusedLocalElements_localVariable() {
-    Source source = newSource('/test.dart', '''
-main() {
-  var v = 42;
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener
-        .assertErrorsWithCodes(<ErrorCode>[HintCode.UNUSED_LOCAL_VARIABLE]);
-  }
-
-  test_perform_unusedLocalElements_method() {
-    Source source = newSource('/my_lib.dart', '''
-library my_lib;
-part 'my_part.dart';
-class A {
-  _ma() {}
-  _mb() {}
-  _mc() {}
-}
-''');
-    newSource('/my_part.dart', '''
-part of my_lib;
-
-f(A a) {
-  a._mb();
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, HINTS, matcher: isGenerateHintsTask);
-    // validate
-    _fillErrorListener(HINTS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[HintCode.UNUSED_ELEMENT, HintCode.UNUSED_ELEMENT]);
-  }
-}
-
-@reflectiveTest
-class GenerateLintsTaskTest extends _AbstractDartTaskTest {
-  void enableLints() {
-    AnalysisOptionsImpl options = context.analysisOptions;
-    options.lint = true;
-    context.analysisOptions = options;
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    enableLints();
-    setLints(context, [new GenerateLintsTaskTest_TestLinter()]);
-  }
-
-  @override
-  void tearDown() {
-    setLints(context, []);
-    super.tearDown();
-  }
-
-  test_camel_case_types() {
-    Source source = newSource('/test.dart', '''
-class a { }
-''');
-
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, LINTS, matcher: isGenerateLintsTask);
-    // validate
-    _fillErrorListener(LINTS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[_testLintCode]);
-  }
-}
-
-class GenerateLintsTaskTest_AstVisitor extends SimpleAstVisitor {
-  Linter linter;
-
-  GenerateLintsTaskTest_AstVisitor(this.linter);
-
-  @override
-  visitClassDeclaration(ClassDeclaration node) {
-    if (!new RegExp(r'^([_]*)([A-Z]+[a-z0-9]*)+$')
-        .hasMatch(node.name.toString())) {
-      linter.reporter.reportErrorForNode(_testLintCode, node, []);
-    }
-  }
-}
-
-class GenerateLintsTaskTest_TestLinter extends Linter {
-  @override
-  String get name => 'GenerateLintsTaskTest_TestLinter';
-
-  @override
-  AstVisitor getVisitor() => new GenerateLintsTaskTest_AstVisitor(this);
-}
-
-@reflectiveTest
-class InferInstanceMembersInUnitTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT10);
-    expect(outputs[RESOLVED_UNIT10], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
-  }
-
-  void test_perform() {
-    AnalysisTarget source = newSource('/test.dart', '''
-class A {
-  X f;
-  Y m(Z x) {}
-}
-class B extends A {
-  var f;
-  m(x) {}
-}
-class X {}
-class Y {}
-class Z {}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
-        matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
-    VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
-    MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
-    DartType typeX = resolutionMap
-        .elementDeclaredByClassDeclaration(AstFinder.getClass(unit, 'X'))
-        .type;
-    DartType typeY = resolutionMap
-        .elementDeclaredByClassDeclaration(AstFinder.getClass(unit, 'Y'))
-        .type;
-    DartType typeZ = resolutionMap
-        .elementDeclaredByClassDeclaration(AstFinder.getClass(unit, 'Z'))
-        .type;
-
-    expect(
-        resolutionMap.elementDeclaredByVariableDeclaration(field).type, typeX);
-    expect(resolutionMap.elementDeclaredByMethodDeclaration(method).returnType,
-        typeY);
-    expect(
-        resolutionMap
-            .elementDeclaredByMethodDeclaration(method)
-            .parameters[0]
-            .type,
-        typeZ);
-  }
-
-  void test_perform_cross_library_const() {
-    AnalysisTarget firstSource = newSource('/first.dart', '''
-library first;
-
-const a = 'hello';
-''');
-    AnalysisTarget secondSource = newSource('/second.dart', '''
-import 'first.dart';
-
-const b = a;
-class M {
-   String c = a;
-}
-''');
-    computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10,
-        matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT10];
-    computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT10];
-
-    VariableDeclaration variableA =
-        AstFinder.getTopLevelVariable(firstUnit, 'a');
-    VariableDeclaration variableB =
-        AstFinder.getTopLevelVariable(secondUnit, 'b');
-    VariableDeclaration variableC =
-        AstFinder.getFieldInClass(secondUnit, 'M', 'c');
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(variableA).type,
-        stringType);
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(variableB).type,
-        stringType);
-    expect(variableB.initializer.staticType, stringType);
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(variableC).type,
-        stringType);
-    expect(variableC.initializer.staticType, stringType);
-  }
-
-  void test_perform_reresolution() {
-    AnalysisTarget source = newSource('/test.dart', '''
-const topLevel = '';
-class C {
-  String field = topLevel;
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
-    CompilationUnit unit = outputs[RESOLVED_UNIT10];
-    VariableDeclaration topLevelDecl =
-        AstFinder.getTopLevelVariable(unit, 'topLevel');
-    VariableDeclaration fieldDecl =
-        AstFinder.getFieldInClass(unit, 'C', 'field');
-    VariableElement topLevel = topLevelDecl.name.staticElement;
-    VariableElement field = fieldDecl.name.staticElement;
-
-    InterfaceType stringType = context.typeProvider.stringType;
-    expect(topLevel.type, stringType);
-    expect(field.type, stringType);
-    expect(fieldDecl.initializer.staticType, stringType);
-  }
-}
-
-@reflectiveTest
-class InferStaticVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT8);
-    expect(outputs[RESOLVED_UNIT8], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
-  }
-
-  void test_perform_const_field() {
-    AnalysisTarget source = newSource('/test.dart', '''
-class M {
-  static const X = "";
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
-        matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT8];
-    VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
-    InterfaceType stringType = context.typeProvider.stringType;
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(declaration).type,
-        stringType);
-  }
-
-  test_perform_hasParseError() {
-    Source source = newSource('/test.dart', r'''
-@(i $=
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT8);
-    expect(outputs[RESOLVED_UNIT8], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
-  }
-
-  void test_perform_nestedDeclarations() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var f = (int x) {
-  int squared(int value) => value * value;
-  var xSquared = squared(x);
-  return xSquared;
-};
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
-        matcher: isInferStaticVariableTypesInUnitTask);
-  }
-
-  void test_perform_recursive() {
-    AnalysisTarget firstSource = newSource('/first.dart', '''
-import 'second.dart';
-
-var a = new M();
-var c = b;
-''');
-    AnalysisTarget secondSource = newSource('/second.dart', '''
-import 'first.dart';
-
-var b = a;
-class M {}
-''');
-    computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
-        matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
-    computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
-
-    VariableDeclaration variableA =
-        AstFinder.getTopLevelVariable(firstUnit, 'a');
-    VariableDeclaration variableB =
-        AstFinder.getTopLevelVariable(secondUnit, 'b');
-    VariableDeclaration variableC =
-        AstFinder.getTopLevelVariable(firstUnit, 'c');
-    ClassDeclaration classM = AstFinder.getClass(secondUnit, 'M');
-    DartType typeM =
-        resolutionMap.elementDeclaredByClassDeclaration(classM).type;
-
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(variableA).type,
-        typeM);
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(variableB).type,
-        typeM);
-    expect(variableB.initializer.staticType, typeM);
-    expect(resolutionMap.elementDeclaredByVariableDeclaration(variableC).type,
-        typeM);
-    expect(variableC.initializer.staticType, typeM);
-  }
-
-  void test_perform_simple() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var X = 1;
-var Y = () => 1 + X;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
-        matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT8];
-    TopLevelVariableDeclaration declaration = unit.declarations[1];
-    FunctionExpression function =
-        declaration.variables.variables[0].initializer;
-    ExpressionFunctionBody body = function.body;
-    Expression expression = body.expression;
-    InterfaceType intType = context.typeProvider.intType;
-    expect(expression.staticType, intType);
-  }
-
-  test_staticModeHints_forStaticVariableInference() {
-    context.analysisOptions =
-        new AnalysisOptionsImpl.from(context.analysisOptions)
-          ..strongModeHints = true;
-    Source source = newSource('/test.dart', r'''
-var V = [42];
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT8);
-    expect(outputs[RESOLVED_UNIT8], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
-    // An INFERRED_TYPE_LITERAL error should be generated.
-    List<AnalysisError> errors =
-        outputs[STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT]
-            as List<AnalysisError>;
-    expect(errors, hasLength(1));
-    expect(errors[0].errorCode, StrongModeCode.INFERRED_TYPE_LITERAL);
-  }
-}
-
-@reflectiveTest
-class InferStaticVariableTypeTaskTest extends _AbstractDartTaskTest {
-  void test_getDeclaration_staticField() {
-    AnalysisTarget source = newSource('/test.dart', '''
-class C {
-  var field = '';
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableDeclaration declaration =
-        AstFinder.getFieldInClass(unit, 'C', 'field');
-    VariableElement variable = declaration.name.staticElement;
-    InferStaticVariableTypeTask inferTask =
-        new InferStaticVariableTypeTask(task.context, variable);
-    expect(inferTask.getDeclaration(unit), declaration);
-  }
-
-  void test_getDeclaration_topLevel() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var topLevel = '';
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableDeclaration declaration =
-        AstFinder.getTopLevelVariable(unit, 'topLevel');
-    VariableElement variable = declaration.name.staticElement;
-    InferStaticVariableTypeTask inferTask =
-        new InferStaticVariableTypeTask(task.context, variable);
-    expect(inferTask.getDeclaration(unit), declaration);
-  }
-
-  void test_perform() {
-    AnalysisTarget source = newSource('/test3.dart', '''
-var topLevel3 = '';
-class C {
-  var field3 = topLevel3;
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableDeclaration topLevelDecl =
-        AstFinder.getTopLevelVariable(unit, 'topLevel3');
-    VariableDeclaration fieldDecl =
-        AstFinder.getFieldInClass(unit, 'C', 'field3');
-    VariableElement topLevel = topLevelDecl.name.staticElement;
-    VariableElement field = fieldDecl.name.staticElement;
-
-    computeResult(field, INFERRED_STATIC_VARIABLE,
-        matcher: isInferStaticVariableTypeTask);
-    InterfaceType stringType = context.typeProvider.stringType;
-    expect(topLevel.type, stringType);
-    expect(field.type, stringType);
-    expect(fieldDecl.initializer.staticType, stringType);
-  }
-
-  void test_perform_const() {
-    AnalysisTarget source = newSource('/test.dart', '''
-const topLevel = "hello";
-class C {
-  var field = topLevel;
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableElement topLevel =
-        AstFinder.getTopLevelVariable(unit, 'topLevel').name.staticElement;
-    VariableElement field =
-        AstFinder.getFieldInClass(unit, 'C', 'field').name.staticElement;
-
-    computeResult(field, INFERRED_STATIC_VARIABLE,
-        matcher: isInferStaticVariableTypeTask);
-    InterfaceType stringType = context.typeProvider.stringType;
-    expect(topLevel.type, stringType);
-    expect(field.type, stringType);
-  }
-
-  void test_perform_cycle() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var piFirst = true;
-var pi = piFirst ? 3.14 : tau / 2;
-var tau = piFirst ? pi * 2 : 6.28;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableElement piFirst =
-        AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
-    VariableElement pi =
-        AstFinder.getTopLevelVariable(unit, 'pi').name.staticElement;
-    VariableElement tau =
-        AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
-
-    computeResult(piFirst, INFERRED_STATIC_VARIABLE,
-        matcher: isInferStaticVariableTypeTask);
-    expect(piFirst.type, context.typeProvider.boolType);
-    expect(pi.type.isDynamic, isTrue);
-    expect(tau.type.isDynamic, isTrue);
-  }
-
-  void test_perform_error() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var a = '' / null;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableElement a =
-        AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
-
-    computeResult(a, INFERRED_STATIC_VARIABLE,
-        matcher: isInferStaticVariableTypeTask);
-    expect(a.type.isDynamic, isTrue);
-  }
-
-  void test_perform_null() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var a = null;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    VariableElement a =
-        AstFinder.getTopLevelVariable(unit, 'a').name.staticElement;
-
-    computeResult(a, INFERRED_STATIC_VARIABLE,
-        matcher: isInferStaticVariableTypeTask);
-    expect(a.type.isDynamic, isTrue);
-  }
-}
-
-@reflectiveTest
-class LibraryErrorsReadyTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
-    Source library = newSource('/lib.dart', r'''
-library lib;
-part 'part1.dart';
-part 'part2.dart';
-X v1;
-''');
-    Source part1 = newSource('/part1.dart', r'''
-part of lib;
-X v2;
-''');
-    Source part2 = newSource('/part2.dart', r'''
-part of lib;
-X v3;
-''');
-    computeResult(library, LIBRARY_ERRORS_READY,
-        matcher: isLibraryErrorsReadyTask);
-    expect(outputs, hasLength(1));
-    bool ready = outputs[LIBRARY_ERRORS_READY];
-    expect(ready, isTrue);
-    expect(context.getErrors(library).errors, hasLength(1));
-    expect(context.getErrors(part1).errors, hasLength(1));
-    expect(context.getErrors(part2).errors, hasLength(1));
-  }
-}
-
-@reflectiveTest
-class LibraryUnitErrorsTaskTest extends _AbstractDartTaskTest {
-  List<AnalysisError> getLibraryUnitErrors(
-      Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[LIBRARY_UNIT_ERRORS] as List<AnalysisError>;
-  }
-
-  test_perform_definingCompilationUnit() {
-    AnalysisTarget library =
-        newSource('/test.dart', 'library test; import "dart:math";');
-    computeResult(
-        new LibrarySpecificUnit(library, library), LIBRARY_UNIT_ERRORS,
-        matcher: isLibraryUnitErrorsTask);
-    expect(outputs, hasLength(1));
-    List<AnalysisError> errors = getLibraryUnitErrors(outputs);
-    expect(errors, hasLength(1));
-  }
-
-  test_perform_partInSingleLibrary() {
-    AnalysisTarget library =
-        newSource('/lib.dart', 'library test; part "part.dart";');
-    AnalysisTarget part = newSource('/part.dart', 'part of test;');
-    computeResult(new LibrarySpecificUnit(library, part), LIBRARY_UNIT_ERRORS,
-        matcher: isLibraryUnitErrorsTask);
-    expect(outputs, hasLength(1));
-    List<AnalysisError> errors = getLibraryUnitErrors(outputs);
-    expect(errors, hasLength(0));
-  }
-}
-
-@reflectiveTest
-class ParseDartTaskTest extends _AbstractDartTaskTest {
-  Source source;
-
-  test_perform() {
-    _performParseTask(r'''
-part of lib;
-class B {}''');
-    expect(outputs, hasLength(10));
-    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
-    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
-    expect(outputs[INCLUDED_PARTS], hasLength(0));
-    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
-    expect(outputs[PARSE_ERRORS], hasLength(0));
-    expect(outputs[PARSED_UNIT], isNotNull);
-    expect(outputs[REFERENCED_SOURCES], hasLength(2));
-    expect(outputs[SOURCE_KIND], SourceKind.PART);
-    expect(outputs[UNITS], hasLength(1));
-  }
-
-  test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
-    // Parse "lib.dart" to let the context know that "test.dart" is included.
-    computeResult(newSource('/lib.dart', r'''
-library lib;
-part 'test.dart';
-'''), PARSED_UNIT);
-    // If there are no the "part of" directive, then it is not a part.
-    _performParseTask('');
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-  }
-
-  test_perform_computeSourceKind_noDirectives_noContainingLibrary() {
-    _performParseTask('');
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-  }
-
-  test_perform_doesNotExist() {
-    _performParseTask(null);
-    expect(outputs, hasLength(10));
-    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
-    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
-    expect(outputs[INCLUDED_PARTS], hasLength(0));
-    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
-    expect(outputs[PARSE_ERRORS], hasLength(0));
-    expect(outputs[PARSED_UNIT], isNotNull);
-    expect(outputs[REFERENCED_SOURCES], hasLength(2));
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-    expect(outputs[UNITS], hasLength(1));
-  }
-
-  test_perform_flushTokenStream() {
-    _performParseTask(r'''
-class Test {}
-''');
-    expect(analysisCache.getState(source, TOKEN_STREAM), CacheState.FLUSHED);
-  }
-
-  test_perform_invalidDirectives() {
-    _performParseTask(r'''
-library lib;
-import '/does/not/exist.dart';
-import '://invaliduri.dart';
-export '${a}lib3.dart';
-part 'part.dart';
-class A {}''');
-    expect(outputs, hasLength(10));
-    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
-    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
-    expect(outputs[INCLUDED_PARTS], hasLength(1));
-    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
-    expect(outputs[PARSE_ERRORS], hasLength(2));
-    expect(outputs[PARSED_UNIT], isNotNull);
-    expect(outputs[REFERENCED_SOURCES], hasLength(4));
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-    expect(outputs[UNITS], hasLength(2));
-  }
-
-  test_perform_library() {
-    _performParseTask(r'''
-library lib;
-import 'lib2.dart';
-export 'lib3.dart';
-part 'part.dart';
-class A {''');
-    expect(outputs, hasLength(10));
-    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
-    expect(outputs[EXPORTED_LIBRARIES], hasLength(1));
-    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
-    expect(outputs[INCLUDED_PARTS], hasLength(1));
-    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(2));
-    // Missing closing brace error is reported by the Fasta scanner.
-    expect(outputs[PARSE_ERRORS], hasLength(0));
-    expect(outputs[PARSED_UNIT], isNotNull);
-    expect(outputs[REFERENCED_SOURCES], hasLength(5));
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-    expect(outputs[UNITS], hasLength(2));
-  }
-
-  test_perform_library_configurations_bool1() {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.library.io': 'true'});
-    newSource('/foo.dart', '');
-    newSource('/foo_io.dart', '');
-    newSource('/foo_html.dart', '');
-    newSource('/bar.dart', '');
-    newSource('/bar_io.dart', '');
-    newSource('/bar_html.dart', '');
-    _performParseTask(r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-export 'bar.dart'
-  if (dart.library.io) 'bar_io.dart'
-  if (dart.library.html) 'bar_html.dart';
-''');
-    var unit = outputs[PARSED_UNIT] as CompilationUnit;
-
-    var imported = outputs[IMPORTED_LIBRARIES] as List<Source>;
-    _assertContainsOnlyShortName(imported, 'foo_io.dart');
-
-    var import = unit.directives[0] as ImportDirective;
-    expect(import.uriSource.shortName, 'foo.dart');
-    expect(import.selectedSource.shortName, 'foo_io.dart');
-    expect(import.configurations[0].uriSource.shortName, 'foo_io.dart');
-    expect(import.configurations[1].uriSource.shortName, 'foo_html.dart');
-
-    var exported = outputs[EXPORTED_LIBRARIES] as List<Source>;
-    _assertContainsOnlyShortName(exported, 'bar_io.dart');
-
-    var export = unit.directives[1] as ExportDirective;
-    expect(export.uriSource.shortName, 'bar.dart');
-    expect(export.selectedSource.shortName, 'bar_io.dart');
-    expect(export.configurations[0].uriSource.shortName, 'bar_io.dart');
-    expect(export.configurations[1].uriSource.shortName, 'bar_html.dart');
-
-    var refSources = outputs[REFERENCED_SOURCES] as List<Source>;
-    var refNames = refSources.map((source) => source.shortName).toList();
-    expect(refNames, contains('test.dart'));
-    expect(refNames, contains('foo.dart'));
-    expect(refNames, contains('foo_io.dart'));
-    expect(refNames, contains('foo_html.dart'));
-    expect(refNames, contains('bar.dart'));
-    expect(refNames, contains('bar_io.dart'));
-    expect(refNames, contains('bar_html.dart'));
-  }
-
-  test_perform_library_configurations_bool2() {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.library.html': 'true'});
-    newSource('/foo.dart', '');
-    newSource('/foo_io.dart', '');
-    newSource('/foo_html.dart', '');
-    _performParseTask(r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    var imported = outputs[IMPORTED_LIBRARIES] as List<Source>;
-    _assertContainsOnlyShortName(imported, 'foo_html.dart');
-  }
-
-  test_perform_library_configurations_default() {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.library.io': 'false'});
-    newSource('/foo.dart', '');
-    newSource('/foo_io.dart', '');
-    newSource('/foo_html.dart', '');
-    _performParseTask(r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-    var imported = outputs[IMPORTED_LIBRARIES] as List<Source>;
-    _assertContainsOnlyShortName(imported, 'foo.dart');
-  }
-
-  test_perform_library_configurations_preferFirst() {
-    context.declaredVariables = new DeclaredVariables.fromMap(
-        {'dart.library.io': 'true', 'dart.library.html': 'true'});
-    newSource('/foo.dart', '');
-    newSource('/foo_io.dart', '');
-    newSource('/foo_html.dart', '');
-    _performParseTask(r'''
-import 'foo.dart'
-  if (dart.library.io) 'foo_io.dart'
-  if (dart.library.html) 'foo_html.dart';
-''');
-
-    var imported = outputs[IMPORTED_LIBRARIES] as List<Source>;
-    _assertContainsOnlyShortName(imported, 'foo_io.dart');
-
-    var unit = outputs[PARSED_UNIT] as CompilationUnit;
-    var import = unit.directives[0] as ImportDirective;
-    expect(import.uriSource.shortName, 'foo.dart');
-    expect(import.selectedSource.shortName, 'foo_io.dart');
-    expect(import.configurations[0].uriSource.shortName, 'foo_io.dart');
-    expect(import.configurations[1].uriSource.shortName, 'foo_html.dart');
-  }
-
-  test_perform_library_configurations_value() {
-    context.declaredVariables =
-        new DeclaredVariables.fromMap({'dart.platform': 'Windows'});
-    newSource('/foo.dart', '');
-    newSource('/foo_posix.dart', '');
-    newSource('/foo_windows.dart', '');
-    _performParseTask(r'''
-import 'foo.dart'
-  if (dart.platform == 'Posix') 'foo_posix.dart'
-  if (dart.platform == 'Windows') 'foo_windows.dart';
-''');
-    var imported = outputs[IMPORTED_LIBRARIES] as List<Source>;
-    _assertContainsOnlyShortName(imported, 'foo_windows.dart');
-  }
-
-  test_perform_library_selfReferenceAsPart() {
-    _performParseTask(r'''
-library lib;
-part 'test.dart';
-''');
-    expect(outputs[INCLUDED_PARTS], unorderedEquals(<Source>[source]));
-  }
-
-  test_perform_part() {
-    _performParseTask(r'''
-part of lib;
-class B {}''');
-    expect(outputs, hasLength(10));
-    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
-    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
-    expect(outputs[INCLUDED_PARTS], hasLength(0));
-    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
-    expect(outputs[PARSE_ERRORS], hasLength(0));
-    expect(outputs[PARSED_UNIT], isNotNull);
-    expect(outputs[REFERENCED_SOURCES], hasLength(2));
-    expect(outputs[SOURCE_KIND], SourceKind.PART);
-    expect(outputs[UNITS], hasLength(1));
-  }
-
-  /**
-   * Assert that [sources] contains either just a source with the given
-   * [expectedShortName], or it and the `dart:core` source.
-   */
-  void _assertContainsOnlyShortName(
-      List<Source> sources, String expectedShortName) {
-    Iterable<String> shortNames = sources.map((s) => s.shortName);
-    if (shortNames.length == 2) {
-      expect(shortNames, unorderedEquals(['core.dart', expectedShortName]));
-    } else {
-      expect(shortNames, unorderedEquals([expectedShortName]));
-    }
-  }
-
-  void _performParseTask(String content) {
-    if (content == null) {
-      source = getFile('/test.dart').createSource();
-    } else {
-      source = newSource('/test.dart', content);
-    }
-    computeResult(source, PARSED_UNIT, matcher: isParseDartTask);
-  }
-
-  static void _assertHasCore(dynamic sourceList, int lenght) {
-    List<Source> sources = sourceList as List<Source>;
-    expect(sources, hasLength(lenght));
-    expect(sources, contains(predicate((Source s) {
-      return s.fullName.endsWith('core.dart');
-    })));
-  }
-}
-
-@reflectiveTest
-class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest {
-  test_perform_strong_importExport() {
-    newSource('/a.dart', '''
-library a;
-class A<T> {
-  T m() {}
-}
-''');
-    newSource('/b.dart', '''
-library b;
-export 'a.dart';
-''');
-    Source sourceC = newSource('/c.dart', '''
-library c;
-import 'b.dart';
-main() {
-  new A<int>().m();
-}
-''');
-    computeResult(new LibrarySpecificUnit(sourceC, sourceC), RESOLVED_UNIT7,
-        matcher: isPartiallyResolveUnitReferencesTask);
-    // validate
-    expect(outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT], hasLength(0));
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    expect(unit, isNotNull);
-
-    FunctionDeclaration mainFunction = unit.declarations[0];
-    expect(mainFunction.declaredElement, isNotNull);
-    BlockFunctionBody body = mainFunction.functionExpression.body;
-    List<Statement> statements = body.block.statements;
-    ExpressionStatement statement = statements[0];
-    MethodInvocation invocation = statement.expression;
-    MethodElement methodElement = invocation.methodName.staticElement;
-    expect(methodElement, isNull);
-  }
-
-  test_perform_strong_inferable() {
-    Source source = newSource('/test.dart', '''
-int a = b;
-int b = c;
-var d = 0;
-class A {}
-class C {
-  static final f = '';
-  var g = 0;
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7,
-        matcher: isPartiallyResolveUnitReferencesTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    // INFERABLE_STATIC_VARIABLES_IN_UNIT
-    {
-      List<VariableElement> variables =
-          outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] as List<VariableElement>;
-      expect(variables, hasLength(4));
-      expect(variables.map((v) => v.displayName),
-          unorderedEquals(['a', 'b', 'd', 'f']));
-    }
-    // Test the state of the AST
-    TopLevelVariableDeclaration a = unit.declarations[0];
-    VariableDeclaration variableA = a.variables.variables[0];
-    SimpleIdentifier initializer = variableA.initializer;
-    expect(initializer.staticElement, isNotNull);
-  }
-
-  test_perform_strong_notResolved() {
-    Source source = newSource('/test.dart', '''
-int A;
-f1() {
-  A;
-}
-var f2 = () {
-  A;
-  void f3() {
-    A;
-  }
-}
-class C {
-  C() {
-    A;
-  }
-  m() {
-    A;
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7,
-        matcher: isPartiallyResolveUnitReferencesTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    NodeList<CompilationUnitMember> declarations = unit.declarations;
-
-    void expectReference(BlockFunctionBody body, bool isResolved) {
-      ExpressionStatement statement = body.block.statements[0];
-      SimpleIdentifier reference = statement.expression;
-      expect(reference.staticElement, isResolved ? isNotNull : isNull);
-    }
-
-    //
-    // The reference to 'A' in 'f1' should not be resolved.
-    //
-    FunctionDeclaration f1 = declarations[1];
-    expectReference(f1.functionExpression.body, false);
-    //
-    // The references to 'A' in 'f2' should be resolved.
-    //
-    TopLevelVariableDeclaration f2 = declarations[2];
-    FunctionExpression expression2 = f2.variables.variables[0].initializer;
-    BlockFunctionBody body2 = expression2.body;
-    expectReference(body2, true);
-
-    FunctionDeclarationStatement statement2 = body2.block.statements[1];
-    BlockFunctionBody innerBody =
-        statement2.functionDeclaration.functionExpression.body;
-    expectReference(innerBody, true);
-    //
-    // The references to 'A' in 'C' should not be resolved.
-    //
-    ClassDeclaration c = declarations[3];
-    NodeList<ClassMember> members = c.members;
-
-    ConstructorDeclaration constructor = members[0];
-    expectReference(constructor.body, false);
-
-    MethodDeclaration method = members[1];
-    expectReference(method.body, false);
-  }
-}
-
-@reflectiveTest
-class ResolveDirectiveElementsTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
-    List<Source> sources = newSources({
-      '/libA.dart': '''
-library libA;
-import 'libB.dart';
-export 'libC.dart';
-''',
-      '/libB.dart': '''
-library libB;
-''',
-      '/libC.dart': '''
-library libC;
-'''
-    });
-    Source sourceA = sources[0];
-    LibrarySpecificUnit targetA = new LibrarySpecificUnit(sourceA, sourceA);
-    // build directive elements
-    computeResult(sourceA, LIBRARY_ELEMENT2,
-        matcher: isBuildDirectiveElementsTask);
-    // prepare outputs
-    LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
-    LibraryElement libraryElementB = libraryElementA.imports[0].importedLibrary;
-    LibraryElement libraryElementC = libraryElementA.exports[0].exportedLibrary;
-    // clear elements in directive ASTs
-    {
-      CompilationUnit unitA = context.getResult(targetA, RESOLVED_UNIT1);
-      unitA.directives[1].element = null;
-      unitA.directives[2].element = null;
-    }
-    // resolve directive ASTs
-    computeResult(targetA, RESOLVED_UNIT2,
-        matcher: isResolveDirectiveElementsTask);
-    // validate that directive ASTs have elements
-    CompilationUnit unitA = context.getResult(targetA, RESOLVED_UNIT2);
-    {
-      ImportDirective importNode = unitA.directives[1];
-      ImportElement importElement = importNode.element;
-      expect(importElement, isNotNull);
-      expect(importElement.importedLibrary, libraryElementB);
-    }
-    {
-      ExportDirective exportNode = unitA.directives[2];
-      ExportElement exportElement = exportNode.element;
-      expect(exportElement, isNotNull);
-      expect(exportElement.exportedLibrary, libraryElementC);
-    }
-  }
-}
-
-@reflectiveTest
-class ResolveInstanceFieldsInUnitTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT9);
-    expect(outputs[RESOLVED_UNIT9], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
-  }
-
-  /**
-   * Test inference of instance fields across units
-   */
-  void test_perform_inference_cross_unit_instance() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-          class A {
-            final a2 = new B().b2;
-          }
-      ''',
-      '/b.dart': '''
-          class B {
-            final b2 = 1;
-          }
-      ''',
-      '/main.dart': '''
-          import "a.dart";
-
-          test1() {
-            int x = 0;
-            x = new A().a2;
-          }
-    '''
-    });
-    InterfaceType intType = context.typeProvider.intType;
-    DartType dynamicType = context.typeProvider.dynamicType;
-
-    computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
-
-    // B.b2 shoud be resolved on the rhs, but not yet inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
-
-    computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
-
-    // B.b2 should now be fully resolved and inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
-
-    // A.a2 should now be resolved on the rhs, but not yet inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
-
-    computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
-
-    // A.a2 should now be fully resolved and inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
-  }
-
-  /**
-   * Test inference of instance fields across units
-   */
-  void test_perform_inference_cross_unit_instance_cyclic() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-          class A {
-            final a2 = new B().b2;
-          }
-      ''',
-      '/b.dart': '''
-          import 'a.dart';
-          class B {
-            final b2 = 1;
-          }
-      ''',
-      '/main.dart': '''
-          import "a.dart";
-
-          test1() {
-            int x = 0;
-            x = new A().a2;
-          }
-    '''
-    });
-    DartType dynamicType = context.typeProvider.dynamicType;
-
-    computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
-
-    // A.a2 should now be resolved on the rhs, but not yet inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
-
-    computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
-
-    // A.a2 should now be fully resolved and inferred (but not re-resolved).
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
-  }
-
-  /**
-   * Test inference of instance fields across units with cycles
-   */
-  void test_perform_inference_cross_unit_static_instance() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-          class A {
-            static final a1 = B.b1;
-            final a2 = new B().b2;
-          }
-      ''',
-      '/b.dart': '''
-          class B {
-            static final b1 = 1;
-            final b2 = 1;
-          }
-      ''',
-      '/main.dart': '''
-          import "a.dart";
-
-          test1() {
-            int x = 0;
-            // inference in A now works.
-            x = A.a1;
-            x = new A().a2;
-          }
-    '''
-    });
-    InterfaceType intType = context.typeProvider.intType;
-    DartType dynamicType = context.typeProvider.dynamicType;
-
-    computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
-
-    computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
-
-    computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
-  }
-
-  /**
-   * Test inference between static and instance fields
-   */
-  void test_perform_inference_instance() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-          class A {
-            final a2 = new B().b2;
-          }
-
-          class B {
-            final b2 = 1;
-          }
-      ''',
-      '/main.dart': '''
-          import "a.dart";
-
-          test1() {
-            int x = 0;
-            x = new A().a2;
-          }
-    '''
-    });
-    InterfaceType intType = context.typeProvider.intType;
-    DartType dynamicType = context.typeProvider.dynamicType;
-
-    computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
-
-    // A.a2 should now be resolved on the rhs, but not yet inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
-
-    // B.b2 shoud be resolved on the rhs, but not yet inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
-
-    computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
-
-    // A.a2 should now be fully resolved and inferred (but not re-resolved).
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
-
-    // B.b2 should now be fully resolved and inferred.
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "B", "b2"), intType, intType);
-  }
-}
-
-@reflectiveTest
-class ResolveLibraryTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
-    Source sourceLib = newSource('/my_lib.dart', '''
-library my_lib;
-const a = new A();
-class A {
-  const A();
-}
-@a
-class C {}
-''');
-    computeResult(sourceLib, LIBRARY_ELEMENT, matcher: isResolveLibraryTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT];
-    ClassElement classC = library.getType('C');
-    List<ElementAnnotation> metadata = classC.metadata;
-    expect(metadata, hasLength(1));
-    ElementAnnotation annotation = metadata[0];
-    expect(annotation, isNotNull);
-    expect((annotation as ElementAnnotationImpl).evaluationResult, isNotNull);
-  }
-}
-
-@reflectiveTest
-class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest {
-  test_perform() {
-    Source sourceLib = newSource('/my_lib.dart', '''
-library my_lib;
-part 'my_part.dart';
-class A {}
-class B extends A {}
-''');
-    newSource('/my_part.dart', '''
-part of my_lib;
-class C extends A {}
-''');
-    computeResult(sourceLib, LIBRARY_ELEMENT6,
-        matcher: isResolveLibraryTypeNamesTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT6];
-    {
-      ClassElement classB = library.getType('B');
-      expect(classB.supertype.displayName, 'A');
-    }
-    {
-      ClassElement classC = library.getType('C');
-      expect(classC.supertype.displayName, 'A');
-    }
-    expect(library.loadLibraryFunction, isNotNull);
-  }
-
-  test_perform_external() {
-    Source sourceA = newSource('/a.dart', '''
-library a;
-import 'b.dart';
-class A extends B {}
-''');
-    newSource('/b.dart', '''
-library b;
-class B {}
-''');
-    // The reference A to B should be resolved, but there's no requirement that
-    // the full class hierarchy be resolved.
-    computeResult(sourceA, LIBRARY_ELEMENT6,
-        matcher: isResolveLibraryTypeNamesTask);
-    // validate
-    LibraryElement library = outputs[LIBRARY_ELEMENT6];
-    {
-      ClassElement clazz = library.getType('A');
-      expect(clazz.displayName, 'A');
-      clazz = clazz.supertype.element;
-      expect(clazz.displayName, 'B');
-    }
-  }
-}
-
-@reflectiveTest
-class ResolveTopLevelUnitTypeBoundsTaskTest extends _AbstractDartTaskTest {
-  test_perform_boundIsGenericType() {
-    Source source = newSource('/test.dart', '''
-class C<T extends Map<String, List<int>>> {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
-        matcher: isResolveTopLevelUnitTypeBoundsTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
-    ClassDeclaration nodeC = unit.declarations[0];
-    _assertTypeParameterBound(nodeC.typeParameters.typeParameters[0],
-        'Map<String, List<int>>', 'Map');
-  }
-
-  test_perform_errors() {
-    Source source = newSource('/test.dart', '''
-class C<T extends NoSuchClass> {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVE_TYPE_BOUNDS_ERRORS,
-        matcher: isResolveTopLevelUnitTypeBoundsTask);
-    // validate
-    _fillErrorListener(RESOLVE_TYPE_BOUNDS_ERRORS);
-    errorListener
-        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
-  }
-
-  test_perform_ignoreBoundsOfBounds() {
-    Source source = newSource('/test.dart', '''
-class A<T1 extends num> {}
-class B<T2 extends A> {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
-        matcher: isResolveTopLevelUnitTypeBoundsTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
-    ClassDeclaration nodeB = unit.declarations[1];
-    _assertTypeParameterBound(
-        nodeB.typeParameters.typeParameters[0], 'A<num>', 'A');
-  }
-
-  test_perform_outputs() {
-    Source source = newSource('/test.dart', r'''
-class C<T extends int> {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4);
-    expect(outputs[RESOLVED_UNIT4], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT4], isTrue);
-    expect(outputs[RESOLVE_TYPE_BOUNDS_ERRORS], isNotNull);
-  }
-
-  test_perform_unitMember_ClassDeclaration() {
-    Source source = newSource('/test.dart', '''
-class C<T extends int> extends Object {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
-        matcher: isResolveTopLevelUnitTypeBoundsTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
-    ClassDeclaration nodeC = unit.declarations[0];
-    // 'extends Object' is not resolved
-    expect(nodeC.extendsClause.superclass.name.staticElement, isNull);
-    // but 'T extends int' is resolved
-    _assertTypeParameterBound(
-        nodeC.typeParameters.typeParameters[0], 'int', 'int');
-  }
-
-  test_perform_unitMember_ClassTypeAlias() {
-    Source source = newSource('/test.dart', '''
-class C<T extends double> = Object;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
-        matcher: isResolveTopLevelUnitTypeBoundsTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
-    ClassTypeAlias nodeC = unit.declarations[0];
-    // '= Object' is not resolved
-    expect(nodeC.superclass.name.staticElement, isNull);
-    // but 'T extends int' is resolved
-    _assertTypeParameterBound(
-        nodeC.typeParameters.typeParameters[0], 'double', 'double');
-  }
-
-  test_perform_unitMember_FunctionTypeAlias() {
-    Source source = newSource('/test.dart', '''
-typedef F<T extends String>();
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT4,
-        matcher: isResolveTopLevelUnitTypeBoundsTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT4];
-    FunctionTypeAlias nodeF = unit.declarations[0];
-    // but 'T extends String' is resolved
-    _assertTypeParameterBound(
-        nodeF.typeParameters.typeParameters[0], 'String', 'String');
-  }
-
-  void _assertTypeParameterBound(TypeParameter typeParameter,
-      String expectedBoundTypeString, String expectedBoundElementName) {
-    TypeAnnotation bound = typeParameter.bound;
-    // TODO(brianwilkerson) Extend this to support function types as bounds.
-    expect(bound, new TypeMatcher<TypeName>());
-    TypeName boundNode = bound;
-    Identifier boundName = boundNode.name;
-    expect(boundNode.type.toString(), expectedBoundTypeString);
-    expect(boundName.staticType.toString(), expectedBoundTypeString);
-    expect(resolutionMap.staticElementForIdentifier(boundName).displayName,
-        expectedBoundElementName);
-  }
-}
-
-@reflectiveTest
-class ResolveUnitTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT11);
-    expect(outputs[RESOLVED_UNIT11], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
-  }
-
-  void test_perform() {
-    AnalysisTarget source = newSource('/test.dart', '''
-void f() {
-  var c = new C();
-  c.m();
-}
-class C {
-  void m() {
-    f();
-  }
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
-        matcher: isResolveUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-
-    FunctionDeclaration f = unit.declarations[0];
-    _assertResolved(f.functionExpression.body);
-
-    MethodDeclaration m = (unit.declarations[1] as ClassDeclaration).members[0];
-    _assertResolved(m.body);
-
-    expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
-  }
-
-  void _assertResolved(FunctionBody body) {
-    ResolutionVerifier verifier = new ResolutionVerifier();
-    body.accept(verifier);
-    verifier.assertResolved();
-  }
-}
-
-@reflectiveTest
-class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5);
-    expect(outputs[RESOLVED_UNIT5], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT5], isTrue);
-  }
-
-  test_perform() {
-    Source source = newSource('/test.dart', '''
-class A {}
-class B extends A {}
-int f(String p) => p.length;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5, matcher: isResolveUnitTypeNamesTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    {
-      ClassDeclaration nodeA = unit.declarations[0];
-      ClassDeclaration nodeB = unit.declarations[1];
-      DartType extendsType = nodeB.extendsClause.superclass.type;
-      expect(extendsType,
-          resolutionMap.elementDeclaredByClassDeclaration(nodeA).type);
-    }
-    {
-      FunctionDeclaration functionNode = unit.declarations[2];
-      DartType returnType = functionNode.returnType.type;
-      List<FormalParameter> parameters =
-          functionNode.functionExpression.parameters.parameters;
-      expect(returnType.displayName, 'int');
-      expect(
-          resolutionMap
-              .elementDeclaredByFormalParameter(parameters[0])
-              .type
-              .displayName,
-          'String');
-    }
-  }
-
-  test_perform_errors() {
-    Source source = newSource('/test.dart', '''
-NoSuchClass f() => null;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
-        matcher: isResolveUnitTypeNamesTask);
-    // validate
-    _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
-    errorListener
-        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
-  }
-
-  test_perform_typedef() {
-    Source source = newSource('/test.dart', '''
-typedef int F(G g);
-typedef String G(int p);
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT5, matcher: isResolveUnitTypeNamesTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT5];
-    FunctionTypeAlias nodeF = unit.declarations[0];
-    FunctionTypeAlias nodeG = unit.declarations[1];
-    GenericTypeAliasElement elementG = nodeG.declaredElement;
-    {
-      FormalParameter parameter = nodeF.parameters.parameters[0];
-      DartType parameterType =
-          resolutionMap.elementDeclaredByFormalParameter(parameter).type;
-      Element returnTypeElement =
-          resolutionMap.typeForTypeName(nodeF.returnType).element;
-      expect(returnTypeElement.displayName, 'int');
-      expect(parameterType.element, elementG.function);
-    }
-    {
-      FormalParameter parameter = nodeG.parameters.parameters[0];
-      DartType parameterType =
-          resolutionMap.elementDeclaredByFormalParameter(parameter).type;
-      expect(
-          resolutionMap.typeForTypeName(nodeG.returnType).element.displayName,
-          'String');
-      expect(parameterType.element.displayName, 'int');
-    }
-  }
-
-  test_perform_typedef_errors() {
-    Source source = newSource('/test.dart', '''
-typedef int F(NoSuchType p);
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVE_TYPE_NAMES_ERRORS,
-        matcher: isResolveUnitTypeNamesTask);
-    // validate
-    _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
-    errorListener
-        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
-  }
-}
-
-@reflectiveTest
-class ResolveVariableReferencesTaskTest extends _AbstractDartTaskTest {
-  /**
-   * Verify that the mutated states of the given [variable] correspond to the
-   * [mutatedInClosure] and [mutatedInScope] matchers.
-   */
-  void expectMutated(FunctionBody body, VariableElement variable,
-      bool mutatedInClosure, bool mutatedInScope) {
-    expect(body.isPotentiallyMutatedInClosure(variable), mutatedInClosure);
-    expect(body.isPotentiallyMutatedInScope(variable), mutatedInScope);
-  }
-
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT6);
-    expect(outputs[RESOLVED_UNIT6], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT6], isTrue);
-  }
-
-  test_perform_buildClosureLibraryElements() {
-    Source source = newSource('/test.dart', '''
-main() {
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT6,
-        matcher: isResolveVariableReferencesTask);
-  }
-
-  test_perform_local() {
-    Source source = newSource('/test.dart', '''
-main() {
-  var v1 = 1;
-  var v2 = 1;
-  var v3 = 1;
-  var v4 = 1;
-  v2 = 2;
-  v4 = 2;
-  localFunction() {
-    v3 = 3;
-    v4 = 3;
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT6,
-        matcher: isResolveVariableReferencesTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT6];
-    FunctionDeclaration mainDeclaration = unit.declarations[0];
-    FunctionBody body = mainDeclaration.functionExpression.body;
-    LocalVariableElement v1 = findLocalVariable(unit, 'v1');
-    LocalVariableElement v2 = findLocalVariable(unit, 'v2');
-    LocalVariableElement v3 = findLocalVariable(unit, 'v3');
-    LocalVariableElement v4 = findLocalVariable(unit, 'v4');
-    expectMutated(body, v1, false, false);
-    expectMutated(body, v2, false, true);
-    expectMutated(body, v3, true, true);
-    expectMutated(body, v4, true, true);
-  }
-
-  test_perform_parameter() {
-    Source source = newSource('/test.dart', '''
-main(p1, p2, p3, p4) {
-  p2 = 2;
-  p4 = 2;
-  localFunction() {
-    p3 = 3;
-    p4 = 3;
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT6,
-        matcher: isResolveVariableReferencesTask);
-    // validate
-    CompilationUnit unit = outputs[RESOLVED_UNIT6];
-    FunctionDeclaration mainDeclaration = unit.declarations[0];
-    FunctionBody body = mainDeclaration.functionExpression.body;
-    FunctionElement main = mainDeclaration.declaredElement;
-    expectMutated(body, main.parameters[0], false, false);
-    expectMutated(body, main.parameters[1], false, true);
-    expectMutated(body, main.parameters[2], true, true);
-    expectMutated(body, main.parameters[3], true, true);
-  }
-}
-
-@reflectiveTest
-class ScanDartTaskTest extends _AbstractDartTaskTest {
-  test_ignore_info() {
-    _performScanTask('''
-//ignore: error_code
-//ignore_for_file: error_code
-var x = '';
-foo(); // ignore:   error_code_2
-bar(); //ignore: error_code, error_code_2
-// ignore_for_file:  error_code_2, error_code_3
-''');
-
-    IgnoreInfo info = outputs[IGNORE_INFO];
-    expect(info.ignores.keys, hasLength(3));
-    expect(info.ignores[2].first, 'error_code');
-    expect(info.ignores[4].first, 'error_code_2');
-    expect(info.ignores[5], unorderedEquals(['error_code', 'error_code_2']));
-    expect(info.ignoreForFiles,
-        unorderedEquals(['error_code', 'error_code_2', 'error_code_3']));
-  }
-
-  test_perform_errors() {
-    _performScanTask('import "');
-    expect(outputs, hasLength(4));
-    expect(outputs[LINE_INFO], isNotNull);
-    expect(outputs[SCAN_ERRORS], hasLength(1));
-    expect(outputs[TOKEN_STREAM], isNotNull);
-    IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
-    expect(ignoreInfo, isNotNull);
-    expect(ignoreInfo.hasIgnores, isFalse);
-  }
-
-  test_perform_library() {
-    _performScanTask(r'''
-library lib;
-import 'lib2.dart';
-export 'lib3.dart';
-part 'part.dart';
-class A {''');
-    expect(outputs, hasLength(4));
-    expect(outputs[LINE_INFO], isNotNull);
-    // Missing closing brace error is reported by the Fasta scanner.
-    expect(outputs[SCAN_ERRORS], hasLength(1));
-    expect(outputs[TOKEN_STREAM], isNotNull);
-    IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
-    expect(ignoreInfo, isNotNull);
-    expect(ignoreInfo.hasIgnores, isFalse);
-  }
-
-  test_perform_noErrors() {
-    _performScanTask('class A {}');
-    expect(outputs, hasLength(4));
-    expect(outputs[LINE_INFO], isNotNull);
-    expect(outputs[SCAN_ERRORS], hasLength(0));
-    expect(outputs[TOKEN_STREAM], isNotNull);
-    IgnoreInfo ignoreInfo = outputs[IGNORE_INFO];
-    expect(ignoreInfo, isNotNull);
-    expect(ignoreInfo.hasIgnores, isFalse);
-  }
-
-  test_perform_script() {
-    String scriptContent = '''
-      void buttonPressed() {
-    ''';
-    String htmlContent = '''
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>test page</title>
-    <script type='application/dart'>$scriptContent</script>
-  </head>
-  <body>Test</body>
-</html>
-''';
-    Source source = newSource('/test.html', htmlContent);
-    DartScript script =
-        new DartScript(source, [new ScriptFragment(97, 5, 36, scriptContent)]);
-
-    computeResult(script, TOKEN_STREAM, matcher: isScanDartTask);
-    expect(outputs[LINE_INFO], isNotNull);
-    // Missing closing brace error is reported by Fasta scanner.
-    expect(outputs[SCAN_ERRORS], hasLength(1));
-    Token tokenStream = outputs[TOKEN_STREAM];
-    expect(tokenStream, isNotNull);
-    expect(tokenStream.lexeme, 'void');
-  }
-
-  void _performScanTask(String content) {
-    AnalysisTarget target = newSource('/test.dart', content);
-    computeResult(target, TOKEN_STREAM, matcher: isScanDartTask);
-  }
-}
-
-@reflectiveTest
-class StrongModeInferenceTest extends _AbstractDartTaskTest {
-  // Check that even within a static variable cycle, inferred
-  // types get propagated to the members of the cycle.
-  void test_perform_cycle() {
-    AnalysisTarget source = newSource('/test.dart', '''
-var piFirst = true;
-var pi = piFirst ? 3.14 : tau / 2;
-var tau = piFirst ? pi * 2 : 6.28;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-    VariableElement piFirst =
-        AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
-    VariableElement pi =
-        AstFinder.getTopLevelVariable(unit, 'pi').name.staticElement;
-    VariableElement tau =
-        AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
-    Expression piFirstUse = (AstFinder.getTopLevelVariable(unit, 'tau')
-            .initializer as ConditionalExpression)
-        .condition;
-
-    expect(piFirstUse.staticType, context.typeProvider.boolType);
-    expect(piFirst.type, context.typeProvider.boolType);
-    expect(pi.type.isDynamic, isTrue);
-    expect(tau.type.isDynamic, isTrue);
-  }
-
-  void test_perform_inference_cross_unit_cyclic() {
-    AnalysisTarget firstSource = newSource('/a.dart', '''
-          import 'test.dart';
-          var x = 2;
-          class A { static var x = 2; }
-''');
-    AnalysisTarget secondSource = newSource('/test.dart', '''
-          import 'a.dart';
-          var y = x;
-          class B { static var y = A.x; }
-
-          test1() {
-            int t = 3;
-            t = x;
-            t = y;
-            t = A.x;
-            t = B.y;
-          }
-''');
-    computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
-    computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit1, "x"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "A", "x"), intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit2, "y"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit2, "B", "y"), intType, intType);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
-
-    assertAssignmentStatementTypes(statements[1], intType, intType);
-    assertAssignmentStatementTypes(statements[2], intType, intType);
-    assertAssignmentStatementTypes(statements[3], intType, intType);
-    assertAssignmentStatementTypes(statements[4], intType, intType);
-  }
-
-  // Test that local variables in method bodies are inferred appropriately
-  void test_perform_inference_cross_unit_instance() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-          class A {
-            final a2 = new B().b2;
-          }
-      ''',
-      '/b.dart': '''
-          class B {
-            final b2 = 1;
-          }
-      ''',
-      '/main.dart': '''
-          import "a.dart";
-
-          test1() {
-            int x = 0;
-            x = new A().a2;
-          }
-    '''
-    });
-    List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
-    CompilationUnit unit0 = units[0];
-    CompilationUnit unit1 = units[1];
-    CompilationUnit unit2 = units[2];
-
-    InterfaceType intType = context.typeProvider.intType;
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
-
-    assertAssignmentStatementTypes(statements[1], intType, intType);
-  }
-
-  // Test inference interactions between local variables and fields
-  void test_perform_inference_cross_unit_instance_member() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-            var bar = new B();
-            void foo() {
-              String x = bar.f.z;
-            }
-      ''',
-      '/b.dart': '''
-        class C {
-          var z = 3;
-        }
-
-        class B {
-          var f = new C();
-        }
-      ''',
-      '/c.dart': '''
-          import 'b.dart';
-            var bar = new B();
-            void foo() {
-              String x = bar.f.z;
-            }
-    '''
-    });
-    List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
-    CompilationUnit unit0 = units[0];
-    CompilationUnit unit2 = units[2];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    assertVariableDeclarationStatementTypes(
-        AstFinder.getStatementsInTopLevelFunction(unit0, "foo")[0],
-        stringType,
-        intType);
-    assertVariableDeclarationStatementTypes(
-        AstFinder.getStatementsInTopLevelFunction(unit2, "foo")[0],
-        stringType,
-        intType);
-  }
-
-  // Test inference interactions between local variables and top level
-  // variables
-  void test_perform_inference_cross_unit_non_cyclic() {
-    AnalysisTarget firstSource = newSource('/a.dart', '''
-          var x = 2;
-          class A { static var x = 2; }
-''');
-    AnalysisTarget secondSource = newSource('/test.dart', '''
-          import 'a.dart';
-          var y = x;
-          class B { static var y = A.x; }
-
-          test1() {
-            x = /*severe:StaticTypeError*/"hi";
-            y = /*severe:StaticTypeError*/"hi";
-            A.x = /*severe:StaticTypeError*/"hi";
-            B.y = /*severe:StaticTypeError*/"hi";
-          }
-''');
-    computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
-    computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit1, "x"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "A", "x"), intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit2, "y"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit2, "B", "y"), intType, intType);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
-
-    assertAssignmentStatementTypes(statements[0], intType, stringType);
-    assertAssignmentStatementTypes(statements[1], intType, stringType);
-  }
-
-  // Test that inference does not propagate from null
-  void test_perform_inference_cross_unit_static_instance() {
-    List<Source> sources = newSources({
-      '/a.dart': '''
-          import 'b.dart';
-          class A {
-            static final a1 = B.b1;
-            final a2 = new B().b2;
-          }
-      ''',
-      '/b.dart': '''
-          class B {
-            static final b1 = 1;
-            final b2 = 1;
-          }
-      ''',
-      '/main.dart': '''
-          import "a.dart";
-
-          test1() {
-            int x = 0;
-            // inference in A now works.
-            x = A.a1;
-            x = new A().a2;
-          }
-    '''
-    });
-    List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
-    CompilationUnit unit0 = units[0];
-    CompilationUnit unit1 = units[1];
-    CompilationUnit unit2 = units[2];
-
-    InterfaceType intType = context.typeProvider.intType;
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit0, "A", "a2"), intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit2, "test1");
-
-    assertAssignmentStatementTypes(statements[1], intType, intType);
-    assertAssignmentStatementTypes(statements[2], intType, intType);
-  }
-
-  // Test inference across units (non-cyclic)
-  void test_perform_inference_local_variables() {
-    AnalysisTarget source = newSource('/test.dart', '''
-      test() {
-        int x = 3;
-        x = "hi";
-        var y = 3;
-        y = "hi";
-      }
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-
-    assertVariableDeclarationStatementTypes(statements[0], intType, intType);
-    assertAssignmentStatementTypes(statements[1], intType, stringType);
-    assertVariableDeclarationStatementTypes(statements[2], intType, intType);
-    assertAssignmentStatementTypes(statements[3], intType, stringType);
-  }
-
-  // Test inference across units (cyclic)
-  void test_perform_inference_local_variables_fields() {
-    AnalysisTarget source = newSource('/test.dart', '''
-      class A {
-        int x = 0;
-
-        test1() {
-          var a = x;
-          a = "hi";
-          a = 3;
-          var b = y;
-          b = "hi";
-          b = 4;
-          var c = z;
-          c = "hi";
-          c = 4;
-        }
-
-        int y; // field def after use
-        final z = 42; // should infer `int`
-      }
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    List<Statement> statements =
-        AstFinder.getStatementsInMethod(unit, "A", "test1");
-
-    assertVariableDeclarationStatementTypes(statements[0], intType, intType);
-    assertAssignmentStatementTypes(statements[1], intType, stringType);
-    assertAssignmentStatementTypes(statements[2], intType, intType);
-
-    assertVariableDeclarationStatementTypes(statements[3], intType, intType);
-    assertAssignmentStatementTypes(statements[4], intType, stringType);
-    assertAssignmentStatementTypes(statements[5], intType, intType);
-
-    assertVariableDeclarationStatementTypes(statements[6], intType, intType);
-    assertAssignmentStatementTypes(statements[7], intType, stringType);
-    assertAssignmentStatementTypes(statements[8], intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit, "A", "x"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit, "A", "z"), intType, intType);
-  }
-
-  // Test inference of instance fields across units
-  void test_perform_inference_local_variables_topLevel() {
-    AnalysisTarget source = newSource('/test.dart', '''
-      int x = 0;
-
-      test1() {
-        var a = x;
-        a = /*severe:StaticTypeError*/"hi";
-        a = 3;
-        var b = y;
-        b = /*severe:StaticTypeError*/"hi";
-        b = 4;
-        var c = z;
-        c = /*severe:StaticTypeError*/"hi";
-        c = 4;
-      }
-
-      int y = 0; // field def after use
-      final z = 42; // should infer `int`
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test1");
-
-    assertVariableDeclarationStatementTypes(statements[0], intType, intType);
-    assertAssignmentStatementTypes(statements[1], intType, stringType);
-    assertAssignmentStatementTypes(statements[2], intType, intType);
-
-    assertVariableDeclarationStatementTypes(statements[3], intType, intType);
-    assertAssignmentStatementTypes(statements[4], intType, stringType);
-    assertAssignmentStatementTypes(statements[5], intType, intType);
-
-    assertVariableDeclarationStatementTypes(statements[6], intType, intType);
-    assertAssignmentStatementTypes(statements[7], intType, stringType);
-    assertAssignmentStatementTypes(statements[8], intType, intType);
-
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit, "x"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit, "y"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit, "z"), intType, intType);
-  }
-
-  // Test inference between static and instance fields
-  void test_perform_inference_null() {
-    AnalysisTarget source = newSource('/test.dart', '''
-      var x = null;
-      var y = 3;
-      class A {
-        static var x = null;
-        static var y = 3;
-
-        var x2 = null;
-        var y2 = 3;
-      }
-
-      test() {
-        x = "hi";
-        y = /*severe:StaticTypeError*/"hi";
-        A.x = "hi";
-        A.y = /*severe:StaticTypeError*/"hi";
-        new A().x2 = "hi";
-        new A().y2 = /*severe:StaticTypeError*/"hi";
-      }
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-    DartType nullType = context.typeProvider.nullType;
-    DartType dynamicType = context.typeProvider.dynamicType;
-
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit, "x"), dynamicType, nullType);
-    assertVariableDeclarationTypes(
-        AstFinder.getTopLevelVariable(unit, "y"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit, "A", "x"), dynamicType, nullType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit, "A", "y"), intType, intType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit, "A", "x2"), dynamicType, nullType);
-    assertVariableDeclarationTypes(
-        AstFinder.getFieldInClass(unit, "A", "y2"), intType, intType);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-
-    assertAssignmentStatementTypes(statements[0], dynamicType, stringType);
-    assertAssignmentStatementTypes(statements[1], intType, stringType);
-    assertAssignmentStatementTypes(statements[2], dynamicType, stringType);
-    assertAssignmentStatementTypes(statements[3], intType, stringType);
-    assertAssignmentStatementTypes(statements[4], dynamicType, stringType);
-    assertAssignmentStatementTypes(statements[5], intType, stringType);
-  }
-
-  // Test inference between fields and method bodies
-  void test_perform_local_explicit_disabled() {
-    AnalysisTarget source = newSource('/test.dart', '''
-      test() {
-        int x = 3;
-        x = "hi";
-      }
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
-
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "test");
-    VariableDeclaration decl =
-        (statements[0] as VariableDeclarationStatement).variables.variables[0];
-    expect(
-        resolutionMap.elementDeclaredByVariableDeclaration(decl).type, intType);
-    expect(decl.initializer.staticType, intType);
-
-    ExpressionStatement statement = statements[1];
-    AssignmentExpression assgn = statement.expression;
-    expect(assgn.leftHandSide.staticType, intType);
-    expect(assgn.rightHandSide.staticType, stringType);
-  }
-}
-
-@reflectiveTest
-class StrongModeVerifyUnitTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource('/test.dart', r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT);
-    expect(outputs[RESOLVED_UNIT], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT], isTrue);
-  }
-
-  void test_perform_recordDynamicInvoke() {
-    AnalysisTarget source = newSource('/test.dart', '''
-void main() {
-  dynamic a = [];
-  a[0];
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), STRONG_MODE_ERRORS);
-    CompilationUnit unit = outputs[RESOLVED_UNIT];
-
-    // validate
-    _fillErrorListener(STRONG_MODE_ERRORS);
-    expect(errorListener.errors, isEmpty);
-
-    List<Statement> statements =
-        AstFinder.getStatementsInTopLevelFunction(unit, "main");
-    ExpressionStatement statement = statements[1];
-    IndexExpression idx = statement.expression;
-    expect(strong_ast.isDynamicInvoke(idx.target), isTrue);
-  }
-
-  void test_perform_verifyError() {
-    AnalysisTarget source = newSource('/test.dart', '''
-class A {}
-class B extends A {}
-B b = new A();
-''');
-    computeResult(new LibrarySpecificUnit(source, source), STRONG_MODE_ERRORS);
-    // validate
-    _fillErrorListener(STRONG_MODE_ERRORS);
-
-    var errors = errorListener.errors;
-    expect(errors.length, 1);
-    expect(errors[0].errorCode.name, "STRONG_MODE_INVALID_CAST_NEW_EXPR");
-  }
-}
-
-@reflectiveTest
-class VerifyUnitTaskTest extends _AbstractDartTaskTest {
-  test_perform_constantError() {
-    Source source = newSource('/test.dart', '''
-main(int p) {
-  const v = p;
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[
-      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-    ]);
-  }
-
-  test_perform_ConstantValidator_declaredIdentifier() {
-    Source source = newSource('/test.dart', '''
-void main() {
-  for (const foo in []) {
-    print(foo);
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
-  }
-
-  test_perform_ConstantValidator_dependencyCycle() {
-    Source source = newSource('/test.dart', '''
-const int a = b;
-const int b = c;
-const int c = a;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[
-      CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-      CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
-      CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT
-    ]);
-  }
-
-  test_perform_ConstantValidator_duplicateFields() {
-    Source source = newSource('/test.dart', '''
-class Test {
-  final int x = 1;
-  final int x = 2;
-  const Test();
-}
-
-main() {
-  const Test();
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-  }
-
-  test_perform_ConstantValidator_noInitializer() {
-    Source source = newSource('/test.dart', '''
-const x;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[CompileTimeErrorCode.CONST_NOT_INITIALIZED]);
-  }
-
-  test_perform_ConstantValidator_unknownValue() {
-    Source source = newSource('/test.dart', '''
-import 'no-such-file.dart' as p;
-
-const int x = p.y;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(<ErrorCode>[
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-    ]);
-  }
-
-  test_perform_directiveError_generated() {
-    Source source = newSource('/test.dart', '''
-import 'generated-file.g.dart';
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED]);
-  }
-
-  test_perform_directiveError_nonGenerated() {
-    Source source = newSource('/test.dart', '''
-import 'no-such-file.dart';
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
-  }
-
-  void test_perform_reresolution() {
-    AnalysisTarget source = newSource('/test.dart', '''
-const topLevel = 3;
-class C {
-  String field = topLevel;
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), VERIFY_ERRORS);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-
-    var errors = errorListener.errors;
-    expect(errors.length, 1);
-    expect(errors[0].errorCode, StaticTypeWarningCode.INVALID_ASSIGNMENT);
-  }
-
-  test_perform_verifyError() {
-    Source source = newSource('/test.dart', '''
-main() {
-  if (42) {
-    print('Not bool!');
-  }
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
-    // validate
-    _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertErrorsWithCodes(
-        <ErrorCode>[StaticTypeWarningCode.NON_BOOL_CONDITION]);
-  }
-}
-
-class _AbstractDartTaskTest extends AbstractContextTest {
-  Source emptySource;
-
-  GatheringErrorListener errorListener = new GatheringErrorListener();
-
-  void assertAssignmentStatementTypes(
-      Statement stmt, DartType leftType, DartType rightType) {
-    AssignmentExpression assgn = (stmt as ExpressionStatement).expression;
-    expect(assgn.leftHandSide.staticType, leftType);
-    expect(assgn.rightHandSide.staticType, rightType);
-  }
-
-  void assertIsInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
-    CacheEntry entry = context.getCacheEntry(target);
-    expect(entry.isInvalid(descriptor), isTrue);
-  }
-
-  void assertIsValid(AnalysisTarget target, ResultDescriptor descriptor) {
-    CacheEntry entry = context.getCacheEntry(target);
-    expect(entry.isValid(descriptor), isTrue);
-  }
-
-  void assertSameResults(List<ResultDescriptor> descriptors) {
-    descriptors.forEach((descriptor) {
-      var oldResult = oldOutputs[descriptor];
-      var newResult = outputs[descriptor];
-      expect(newResult, same(oldResult), reason: descriptor.name);
-    });
-  }
-
-  void assertVariableDeclarationStatementTypes(
-      Statement stmt, DartType varType, DartType initializerType) {
-    VariableDeclaration decl =
-        (stmt as VariableDeclarationStatement).variables.variables[0];
-    assertVariableDeclarationTypes(decl, varType, initializerType);
-  }
-
-  void assertVariableDeclarationTypes(
-      VariableDeclaration decl, DartType varType, DartType initializerType) {
-    expect(
-        resolutionMap.elementDeclaredByVariableDeclaration(decl).type, varType);
-    expect(decl.initializer.staticType, initializerType);
-  }
-
-  List<dynamic> computeLibraryResults(
-      List<Source> sources, ResultDescriptor result,
-      {Matcher matcher: null}) {
-    dynamic compute(Source source) {
-      computeResult(new LibrarySpecificUnit(source, source), result,
-          matcher: matcher);
-      return outputs[result];
-    }
-
-    return sources.map(compute).toList();
-  }
-
-  List<Map<ResultDescriptor, dynamic>> computeLibraryResultsMap(
-      List<Source> sources, ResultDescriptor result,
-      {Matcher matcher: null}) {
-    Map<ResultDescriptor, dynamic> compute(Source source) {
-      computeResult(source, result, matcher: matcher);
-      return outputs;
-    }
-
-    return sources.map(compute).toList();
-  }
-
-  /**
-   * Create a script object with a single fragment containing the given
-   * [scriptContent].
-   */
-  DartScript createScript(String scriptContent) {
-    String htmlContent = '''
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>test page</title>
-    <script type='application/dart'>$scriptContent</script>
-  </head>
-  <body>Test</body>
-</html>
-''';
-    Source source = newSource('/test.html', htmlContent);
-    return new DartScript(
-        source, [new ScriptFragment(97, 5, 36, scriptContent)]);
-  }
-
-  void setUp() {
-    super.setUp();
-    emptySource = newSource('/test.dart');
-  }
-
-  /**
-   * Fill [errorListener] with [result] errors in the current [task].
-   */
-  void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) {
-    List<AnalysisError> errors = task.outputs[result] as List<AnalysisError>;
-    expect(errors, isNotNull, reason: result.name);
-    errorListener = new GatheringErrorListener();
-    errorListener.addAll(errors);
-  }
-}
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
deleted file mode 100644
index bc4abcc..0000000
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ /dev/null
@@ -1,881 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/driver.dart';
-import 'package:analyzer/src/task/inputs.dart';
-import 'package:analyzer/src/task/manager.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-import 'test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisDriverTest);
-    defineReflectiveTests(CycleAwareDependencyWalkerTest);
-    defineReflectiveTests(WorkItemTest);
-    defineReflectiveTests(WorkOrderTest);
-  });
-}
-
-class AbstractDriverTest {
-  TaskManager taskManager = new TaskManager();
-  List<WorkManager> workManagers = <WorkManager>[];
-  _InternalAnalysisContextMock context = new _InternalAnalysisContextMock();
-  AnalysisDriver analysisDriver;
-
-  void setUp() {
-    context = new _InternalAnalysisContextMock();
-    analysisDriver = new AnalysisDriver(taskManager, workManagers, context);
-  }
-}
-
-@reflectiveTest
-class AnalysisDriverTest extends AbstractDriverTest {
-  _WorkManagerMock workManager1 = new _WorkManagerMock();
-  _WorkManagerMock workManager2 = new _WorkManagerMock();
-
-  AnalysisTarget target1 = new TestSource('/1.dart');
-  AnalysisTarget target2 = new TestSource('/2.dart');
-
-  ResultDescriptor result1 = new ResultDescriptor('result1', -1);
-  ResultDescriptor result2 = new ResultDescriptor('result2', -2);
-
-  TaskDescriptor descriptor1;
-  TaskDescriptor descriptor2;
-
-  void setUp() {
-    super.setUp();
-    workManager1.nextResultPriority = WorkOrderPriority.NONE;
-    workManager2.nextResultPriority = WorkOrderPriority.NONE;
-
-    workManagers.add(workManager1);
-    workManagers.add(workManager2);
-  }
-
-  test_computeResult() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    TestAnalysisTask task;
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', (context, target) => task, (target) => {}, [result]);
-    task = new TestAnalysisTask(context, target, descriptor: descriptor);
-    taskManager.addTaskDescriptor(descriptor);
-
-    analysisDriver.computeResult(target, result);
-    expect(context.getCacheEntry(target).getValue(result), 1);
-  }
-
-  test_create() {
-    expect(analysisDriver, isNotNull);
-    expect(analysisDriver.context, context);
-    expect(analysisDriver.currentWorkOrder, isNull);
-    expect(analysisDriver.taskManager, taskManager);
-  }
-
-  test_createNextWorkOrder_highLow() {
-    _configureDescriptors12();
-    workManager1.nextResultPriority = WorkOrderPriority.PRIORITY;
-    workManager2.nextResultPriority = WorkOrderPriority.NORMAL;
-    workManager1.nextResult = new TargetedResult(target1, result1);
-    WorkOrder workOrder = analysisDriver.createNextWorkOrder();
-    expect(workOrder, isNotNull);
-    expect(workOrder.moveNext(), true);
-    expect(workOrder.current.target, target1);
-    expect(workOrder.current.descriptor, descriptor1);
-  }
-
-  test_createNextWorkOrder_lowHigh() {
-    _configureDescriptors12();
-    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
-    workManager2.nextResultPriority = WorkOrderPriority.PRIORITY;
-    workManager2.nextResult = new TargetedResult(target1, result1);
-    WorkOrder workOrder = analysisDriver.createNextWorkOrder();
-    expect(workOrder, isNotNull);
-    expect(workOrder.moveNext(), true);
-    expect(workOrder.current.target, target1);
-    expect(workOrder.current.descriptor, descriptor1);
-  }
-
-  test_createNextWorkOrder_none() {
-    _configureDescriptors12();
-    workManager1.nextResultPriority = WorkOrderPriority.NONE;
-    workManager2.nextResultPriority = WorkOrderPriority.NONE;
-    expect(analysisDriver.createNextWorkOrder(), isNull);
-  }
-
-  test_createWorkOrderForResult_aboutToComputeResult() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {},
-        [result]);
-    taskManager.addTaskDescriptor(descriptor);
-    context.getCacheEntry(target).setState(result, CacheState.INVALID);
-    // has result
-    {
-      context.aboutToComputeResultMap[result] = true;
-      WorkOrder workOrder =
-          analysisDriver.createWorkOrderForResult(target, result);
-      expect(workOrder, isNull);
-    }
-    // no result
-    {
-      context.aboutToComputeResultMap[result] = false;
-      WorkOrder workOrder =
-          analysisDriver.createWorkOrderForResult(target, result);
-      expect(workOrder, isNotNull);
-    }
-  }
-
-  test_createWorkOrderForResult_error() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    CaughtException exception = new CaughtException(null, null);
-    context
-        .getCacheEntry(target)
-        .setErrorState(exception, <ResultDescriptor>[result]);
-
-    expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
-  }
-
-  test_createWorkOrderForResult_inProcess() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    context.getCacheEntry(target).setState(result, CacheState.IN_PROCESS);
-
-    expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
-  }
-
-  test_createWorkOrderForResult_invalid() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {},
-        [result]);
-    taskManager.addTaskDescriptor(descriptor);
-    context.getCacheEntry(target).setState(result, CacheState.INVALID);
-
-    WorkOrder workOrder =
-        analysisDriver.createWorkOrderForResult(target, result);
-    expect(workOrder, isNotNull);
-  }
-
-  test_createWorkOrderForResult_valid() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor<String> result =
-        new ResultDescriptor<String>('result', null);
-    context
-        .getCacheEntry(target)
-        .setValue(result, '', const <TargetedResult>[]);
-
-    expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
-  }
-
-  test_createWorkOrderForTarget_complete_generalTarget_generalResult() {
-    _createWorkOrderForTarget(true, false, false);
-  }
-
-  test_createWorkOrderForTarget_complete_generalTarget_priorityResult() {
-    _createWorkOrderForTarget(true, false, true);
-  }
-
-  test_createWorkOrderForTarget_complete_priorityTarget_generalResult() {
-    _createWorkOrderForTarget(true, true, false);
-  }
-
-  test_createWorkOrderForTarget_complete_priorityTarget_priorityResult() {
-    _createWorkOrderForTarget(true, true, true);
-  }
-
-  test_createWorkOrderForTarget_incomplete_generalTarget_generalResult() {
-    _createWorkOrderForTarget(false, false, false);
-  }
-
-  test_createWorkOrderForTarget_incomplete_generalTarget_priorityResult() {
-    _createWorkOrderForTarget(false, false, true);
-  }
-
-  test_createWorkOrderForTarget_incomplete_priorityTarget_generalResult() {
-    _createWorkOrderForTarget(false, true, false);
-  }
-
-  test_createWorkOrderForTarget_incomplete_priorityTarget_priorityResult() {
-    _createWorkOrderForTarget(false, true, true);
-  }
-
-  test_performAnalysisTask() {
-    _configureDescriptors12();
-    workManager1.nextResult = new TargetedResult(target1, result1);
-
-    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
-    expect(analysisDriver.performAnalysisTask(), true);
-    expect(analysisDriver.performAnalysisTask(), true);
-
-    workManager1.nextResultPriority = WorkOrderPriority.NONE;
-    expect(analysisDriver.performAnalysisTask(), false);
-  }
-
-  test_performAnalysisTask_infiniteLoop_handled() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
-    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
-    // configure tasks
-    TestAnalysisTask task1;
-    TestAnalysisTask task2;
-    TaskDescriptor descriptor1 = new TaskDescriptor(
-        'task1',
-        (context, target) => task1,
-        (target) => {'inputB': new SimpleTaskInput<int>(target, resultB)},
-        [resultA]);
-    TaskDescriptor descriptor2 = new TaskDescriptor(
-        'task2',
-        (context, target) => task2,
-        (target) => {'inputA': new SimpleTaskInput<int>(target, resultA)},
-        [resultB]);
-    task1 = new TestAnalysisTask(context, target,
-        descriptor: descriptor1,
-        results: [resultA],
-        value: 10,
-        handlesDependencyCycles: true);
-    task2 = new TestAnalysisTask(context, target,
-        descriptor: descriptor2,
-        results: [resultB],
-        value: 20,
-        handlesDependencyCycles: true);
-    taskManager.addTaskDescriptor(descriptor1);
-    taskManager.addTaskDescriptor(descriptor2);
-    // configure WorkManager
-    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
-    workManager1.nextResult = new TargetedResult(target, resultB);
-    // prepare work order
-    while (analysisDriver.performAnalysisTask()) {
-      workManager1.nextResultPriority = WorkOrderPriority.NONE;
-    }
-    Set<TaskDescriptor> expectedCycle = [descriptor1, descriptor2].toSet();
-    expect(task1.dependencyCycle, isNotNull);
-    expect(task1.dependencyCycle.map((workItem) => workItem.descriptor).toSet(),
-        expectedCycle);
-    expect(task2.dependencyCycle, isNotNull);
-    expect(task2.dependencyCycle.map((workItem) => workItem.descriptor).toSet(),
-        expectedCycle);
-    CaughtException exception = context.getCacheEntry(target).exception;
-    expect(exception, isNull);
-    expect(context.getCacheEntry(target).getValue(resultA), 10);
-    expect(context.getCacheEntry(target).getValue(resultB), 20);
-  }
-
-  test_performAnalysisTask_infiniteLoop_unhandled() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
-    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
-    // configure tasks
-    TestAnalysisTask task1;
-    TestAnalysisTask task2;
-    TaskDescriptor descriptor1 = new TaskDescriptor(
-        'task1',
-        (context, target) => task1,
-        (target) => {'inputB': new SimpleTaskInput<int>(target, resultB)},
-        [resultA]);
-    TaskDescriptor descriptor2 = new TaskDescriptor(
-        'task2',
-        (context, target) => task2,
-        (target) => {'inputA': new SimpleTaskInput<int>(target, resultA)},
-        [resultB]);
-    task1 = new TestAnalysisTask(context, target, descriptor: descriptor1);
-    task2 = new TestAnalysisTask(context, target, descriptor: descriptor2);
-    taskManager.addTaskDescriptor(descriptor1);
-    taskManager.addTaskDescriptor(descriptor2);
-    // configure WorkManager
-    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
-    workManager1.nextResult = new TargetedResult(target, resultB);
-    // prepare work order
-    expect(analysisDriver.performAnalysisTask(), true);
-    expect(analysisDriver.performAnalysisTask(), true);
-    CaughtException exception = context.getCacheEntry(target).exception;
-    expect(exception, isNotNull);
-    expect(exception.exception, new TypeMatcher<InfiniteTaskLoopException>());
-  }
-
-  test_performAnalysisTask_inputsFirst() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor<int> resultA = new ResultDescriptor<int>('resultA', -1);
-    ResultDescriptor<int> resultB = new ResultDescriptor<int>('resultB', -2);
-    // configure tasks
-    TestAnalysisTask task1;
-    TestAnalysisTask task2;
-    TaskDescriptor descriptor1 = new TaskDescriptor(
-        'task1', (context, target) => task1, (target) => {}, [resultA]);
-    TaskDescriptor descriptor2 = new TaskDescriptor(
-        'task2',
-        (context, target) => task2,
-        (target) => {'inputA': new SimpleTaskInput<int>(target, resultA)},
-        [resultB]);
-    task1 = new TestAnalysisTask(context, target,
-        descriptor: descriptor1, results: [resultA], value: 10);
-    task2 = new TestAnalysisTask(context, target,
-        descriptor: descriptor2, value: 20);
-    taskManager.addTaskDescriptor(descriptor1);
-    taskManager.addTaskDescriptor(descriptor2);
-    // configure WorkManager
-    workManager1.nextResultPriority = WorkOrderPriority.NORMAL;
-    workManager1.nextResult = new TargetedResult(target, resultB);
-    // prepare work order
-    expect(analysisDriver.performAnalysisTask(), true);
-    expect(context.getCacheEntry(target).getValue(resultA), -1);
-    expect(context.getCacheEntry(target).getValue(resultB), -2);
-    // compute resultA
-    expect(analysisDriver.performAnalysisTask(), true);
-    expect(context.getCacheEntry(target).getValue(resultA), 10);
-    expect(context.getCacheEntry(target).getValue(resultB), -2);
-    // compute resultB
-    expect(analysisDriver.performAnalysisTask(), true);
-    expect(context.getCacheEntry(target).getValue(resultA), 10);
-    expect(context.getCacheEntry(target).getValue(resultB), 20);
-    // done
-    workManager1.nextResultPriority = WorkOrderPriority.NONE;
-    expect(analysisDriver.performAnalysisTask(), false);
-  }
-
-  test_performAnalysisTask_onResultComputed() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    TestAnalysisTask task;
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', (context, target) => task, (target) => {}, [result]);
-    task = new TestAnalysisTask(context, target,
-        descriptor: descriptor, value: 42);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-
-    bool streamNotified = false;
-    analysisDriver.onResultComputed(result).listen((event) {
-      streamNotified = true;
-      expect(event.context, same(context));
-      expect(event.target, same(target));
-      expect(event.descriptor, same(result));
-      expect(event.value, 42);
-    });
-    analysisDriver.performWorkItem(item);
-    expect(streamNotified, isTrue);
-  }
-
-  test_performWorkItem_exceptionInTask() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    CaughtException exception =
-        new CaughtException(new AnalysisException(), null);
-    TestAnalysisTask task;
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', (context, target) => task, (target) => {}, [result]);
-    task = new TestAnalysisTask(context, target,
-        descriptor: descriptor, exception: exception);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-
-    analysisDriver.performWorkItem(item);
-    CacheEntry targetEntry = context.getCacheEntry(item.target);
-    expect(targetEntry.exception, exception);
-    expect(targetEntry.getState(result), CacheState.ERROR);
-  }
-
-  test_performWorkItem_noException() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    TestAnalysisTask task;
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', (context, target) => task, (target) => {}, [result]);
-    task = new TestAnalysisTask(context, target, descriptor: descriptor);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-
-    analysisDriver.performWorkItem(item);
-    CacheEntry targetEntry = context.getCacheEntry(item.target);
-    expect(targetEntry.exception, isNull);
-    expect(targetEntry.getState(result), CacheState.VALID);
-  }
-
-  test_performWorkItem_preExistingException() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor result = new ResultDescriptor('result', null);
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {},
-        [result]);
-    CaughtException exception =
-        new CaughtException(new AnalysisException(), null);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-    item.exception = exception;
-
-    analysisDriver.performWorkItem(item);
-    CacheEntry targetEntry = context.getCacheEntry(item.target);
-    expect(targetEntry.exception, exception);
-    expect(targetEntry.getState(result), CacheState.ERROR);
-  }
-
-  test_reset() {
-    ResultDescriptor inputResult = new ResultDescriptor('input', null);
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': inputResult.of(target)},
-        [new ResultDescriptor('output', null)]);
-    analysisDriver.currentWorkOrder = new WorkOrder(
-        taskManager, new WorkItem(null, null, descriptor, null, 0, null));
-
-    analysisDriver.reset();
-    expect(analysisDriver.currentWorkOrder, isNull);
-  }
-
-  void _configureDescriptors12() {
-    descriptor1 = new TaskDescriptor(
-        'task1',
-        (context, target) =>
-            new TestAnalysisTask(context, target, descriptor: descriptor1),
-        (target) => {},
-        [result1]);
-    taskManager.addTaskDescriptor(descriptor1);
-
-    descriptor2 = new TaskDescriptor(
-        'task2',
-        (context, target) =>
-            new TestAnalysisTask(context, target, descriptor: descriptor1),
-        (target) => {},
-        [result2]);
-    taskManager.addTaskDescriptor(descriptor2);
-  }
-
-  /**
-   * [complete] is `true` if the value of the result has already been computed.
-   * [priorityTarget] is `true` if the target is in the list of priority
-   * targets.
-   * [priorityResult] is `true` if the result should only be computed for
-   * priority targets.
-   */
-  _createWorkOrderForTarget(
-      bool complete, bool priorityTarget, bool priorityResult) {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor<String> result =
-        new ResultDescriptor<String>('result', null);
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {},
-        [result]);
-    if (priorityResult) {
-      taskManager.addPriorityResult(result);
-    } else {
-      taskManager.addGeneralResult(result);
-    }
-    taskManager.addTaskDescriptor(descriptor);
-    if (priorityTarget) {
-      context.priorityTargets.add(target);
-    } else {
-      context.explicitTargets.add(target);
-    }
-    if (complete) {
-      context
-          .getCacheEntry(target)
-          .setValue(result, '', const <TargetedResult>[]);
-    } else {
-      context.getCacheEntry(target).setState(result, CacheState.INVALID);
-    }
-
-    WorkOrder workOrder =
-        analysisDriver.createWorkOrderForTarget(target, priorityTarget);
-    if (complete) {
-      expect(workOrder, isNull);
-    } else if (priorityResult) {
-      expect(workOrder, priorityTarget ? isNotNull : isNull);
-    } else {
-      expect(workOrder, isNotNull);
-    }
-  }
-}
-
-@reflectiveTest
-class CycleAwareDependencyWalkerTest {
-  void checkGraph(Map<int, List<int>> graph, int startingNode,
-      List<StronglyConnectedComponent<int>> expectedResults) {
-    List<Set<int>> expectedResultsDisregardingOrder =
-        expectedResults.map((component) => component.nodes.toSet()).toList();
-    List<bool> expectedCycleIndicators =
-        expectedResults.map((component) => component.containsCycle).toList();
-    List<Set<int>> results = <Set<int>>[];
-    List<bool> cycleIndicators = <bool>[];
-    _TestCycleAwareDependencyWalker walker =
-        new _TestCycleAwareDependencyWalker(graph, startingNode);
-    while (true) {
-      StronglyConnectedComponent<int> nextStronglyConnectedComponent =
-          walker.getNextStronglyConnectedComponent();
-      if (nextStronglyConnectedComponent == null) {
-        break;
-      }
-      results.add(nextStronglyConnectedComponent.nodes.toSet());
-      cycleIndicators.add(nextStronglyConnectedComponent.containsCycle);
-      walker.evaluatedNodes.addAll(nextStronglyConnectedComponent.nodes);
-    }
-    expect(results, expectedResultsDisregardingOrder);
-    expect(cycleIndicators, expectedCycleIndicators);
-  }
-
-  StronglyConnectedComponent<int> cycle(List<int> nodes) =>
-      new StronglyConnectedComponent(nodes, true);
-
-  StronglyConnectedComponent<int> singleton(int node) =>
-      new StronglyConnectedComponent(<int>[node], false);
-
-  void test_complex_graph() {
-    checkGraph(
-        {
-          1: [2, 3],
-          2: [3, 4],
-          3: [],
-          4: [3, 5],
-          5: [2, 6],
-          6: [3, 4]
-        },
-        1,
-        [
-          singleton(3),
-          cycle([2, 4, 5, 6]),
-          singleton(1)
-        ]);
-  }
-
-  void test_cycle_depends_on_other_nodes() {
-    checkGraph(
-        {
-          1: [2, 3],
-          2: [4, 1],
-          3: [],
-          4: []
-        },
-        1,
-        [
-          singleton(4),
-          singleton(3),
-          cycle([1, 2])
-        ]);
-  }
-
-  void test_initial_node_depends_on_cycle() {
-    checkGraph(
-        {
-          1: [2],
-          2: [3],
-          3: [2]
-        },
-        1,
-        [
-          cycle([2, 3]),
-          singleton(1)
-        ]);
-  }
-
-  void test_simple_cycle() {
-    checkGraph(
-        {
-          1: [2],
-          2: [1]
-        },
-        1,
-        [
-          cycle([1, 2])
-        ]);
-  }
-
-  void test_simple_dependency_chain() {
-    checkGraph(
-        {
-          1: [2],
-          2: []
-        },
-        1,
-        [singleton(2), singleton(1)]);
-  }
-
-  void test_single_node() {
-    checkGraph({1: []}, 1, [singleton(1)]);
-  }
-
-  void test_single_node_cycle() {
-    checkGraph(
-        {
-          1: [1]
-        },
-        1,
-        [
-          cycle([1])
-        ]);
-  }
-}
-
-@reflectiveTest
-class WorkItemTest extends AbstractDriverTest {
-  test_buildTask_complete() {
-    AnalysisTarget target = new TestSource();
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {},
-        [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-    AnalysisTask task = item.buildTask();
-    expect(task, isNotNull);
-  }
-
-  test_buildTask_incomplete() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor inputResult = new ResultDescriptor('input', null);
-    List<ResultDescriptor> outputResults = <ResultDescriptor>[
-      new ResultDescriptor('output', null)
-    ];
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) =>
-            new TestAnalysisTask(context, target, results: outputResults),
-        (target) => {'one': inputResult.of(target)},
-        outputResults);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-    expect(() => item.buildTask(), throwsStateError);
-  }
-
-  test_create() {
-    AnalysisTarget target = new TestSource();
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', null, (target) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-    expect(item, isNotNull);
-    expect(item.context, context);
-    expect(item.descriptor, descriptor);
-    expect(item.target, target);
-  }
-
-  test_gatherInputs_aboutToComputeResult_hasResult() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
-    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
-    // prepare tasks
-    TaskDescriptor task1 = new TaskDescriptor(
-        'task',
-        (context, target) =>
-            new TestAnalysisTask(context, target, results: [resultA]),
-        (target) => {},
-        [resultA]);
-    TaskDescriptor task2 = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': resultA.of(target)},
-        [resultB]);
-    taskManager.addTaskDescriptor(task1);
-    taskManager.addTaskDescriptor(task2);
-    // configure mocks
-    context.aboutToComputeResultMap[resultA] = true;
-    // gather inputs
-    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
-    WorkItem inputItem = item.gatherInputs(taskManager, []);
-    expect(inputItem, isNull);
-  }
-
-  test_gatherInputs_aboutToComputeResult_noResult() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
-    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
-    // prepare tasks
-    TaskDescriptor task1 = new TaskDescriptor(
-        'task',
-        (context, target) =>
-            new TestAnalysisTask(context, target, results: [resultA]),
-        (target) => {},
-        [resultA]);
-    TaskDescriptor task2 = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': resultA.of(target)},
-        [resultB]);
-    taskManager.addTaskDescriptor(task1);
-    taskManager.addTaskDescriptor(task2);
-    // configure ResultProvider
-    // configure mocks
-    context.aboutToComputeResultMap[resultA] = false;
-    // gather inputs
-    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
-    WorkItem inputItem = item.gatherInputs(taskManager, []);
-    expect(inputItem, isNotNull);
-    expect(inputItem.target, target);
-    expect(inputItem.descriptor, task1);
-  }
-
-  test_gatherInputs_complete() {
-    AnalysisTarget target = new TestSource();
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {},
-        [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-    WorkItem result = item.gatherInputs(taskManager, []);
-    expect(result, isNull);
-    expect(item.exception, isNull);
-  }
-
-  test_gatherInputs_incomplete() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor resultA = new ResultDescriptor('resultA', null);
-    ResultDescriptor resultB = new ResultDescriptor('resultB', null);
-    // prepare tasks
-    TaskDescriptor task1 = new TaskDescriptor(
-        'task',
-        (context, target) =>
-            new TestAnalysisTask(context, target, results: [resultA]),
-        (target) => {},
-        [resultA]);
-    TaskDescriptor task2 = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': resultA.of(target)},
-        [resultB]);
-    taskManager.addTaskDescriptor(task1);
-    taskManager.addTaskDescriptor(task2);
-    // gather inputs
-    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
-    WorkItem inputItem = item.gatherInputs(taskManager, []);
-    expect(inputItem, isNotNull);
-  }
-
-  test_gatherInputs_invalid() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptor inputResult = new ResultDescriptor('input', null);
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task',
-        (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': inputResult.of(target)},
-        [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
-    WorkItem result = item.gatherInputs(taskManager, []);
-    expect(result, isNull);
-    expect(item.exception, isNotNull);
-  }
-}
-
-@reflectiveTest
-class WorkOrderTest extends EngineTestCase {
-  test_create() {
-    TaskManager manager = new TaskManager();
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkOrder order = new WorkOrder(
-        manager, new WorkItem(null, null, descriptor, null, 0, null));
-    expect(order, isNotNull);
-    expect(order.currentItems, isNull);
-    expect(order.current, isNull);
-  }
-
-  test_moveNext() {
-    TaskManager manager = new TaskManager();
-    TaskDescriptor descriptor = new TaskDescriptor(
-        'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem workItem = new WorkItem(null, null, descriptor, null, 0, null);
-    WorkOrder order = new WorkOrder(manager, workItem);
-    // "item" has no child items
-    expect(order.moveNext(), isTrue);
-    expect(order.current, workItem);
-    // done
-    expect(order.moveNext(), isFalse);
-    expect(order.current, isNull);
-  }
-}
-
-/**
- * A dummy [InternalAnalysisContext] that does not use [AnalysisDriver] itself,
- * but provides enough implementation for it to function.
- */
-class _InternalAnalysisContextMock implements InternalAnalysisContext {
-  AnalysisCache analysisCache;
-
-  Map<ResultDescriptor, bool> aboutToComputeResultMap = {};
-
-  @override
-  final AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
-
-  @override
-  List<AnalysisTarget> explicitTargets = <AnalysisTarget>[];
-
-  @override
-  List<AnalysisTarget> priorityTargets = <AnalysisTarget>[];
-
-  _InternalAnalysisContextMock() {
-    analysisCache = new AnalysisCache([new UniversalCachePartition(this)]);
-  }
-
-  String get name => 'mock';
-
-  @override
-  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) =>
-      aboutToComputeResultMap[result] ?? false;
-
-  @override
-  CacheEntry getCacheEntry(AnalysisTarget target) {
-    CacheEntry entry = analysisCache.get(target);
-    if (entry == null) {
-      entry = new CacheEntry(target);
-      analysisCache.put(entry);
-    }
-    return entry;
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-}
-
-/**
- * Concrete class for testing [CycleAwareDependencyWalker] behavior.
- */
-class _TestCycleAwareDependencyWalker extends CycleAwareDependencyWalker<int> {
-  final Map<int, List<int>> graph;
-
-  Set<int> evaluatedNodes = new Set<int>();
-
-  _TestCycleAwareDependencyWalker(this.graph, int startingNode)
-      : super(startingNode);
-
-  @override
-  int getNextInput(int node, List<int> skipInputs) {
-    for (int dependency in graph[node]) {
-      if (!skipInputs.contains(dependency) &&
-          !evaluatedNodes.contains(dependency)) {
-        return dependency;
-      }
-    }
-    return null;
-  }
-}
-
-class _WorkManagerMock implements WorkManager {
-  WorkOrderPriority nextResultPriority;
-
-  TargetedResult nextResult;
-
-  TargetedResult getNextResult() => nextResult;
-
-  WorkOrderPriority getNextResultPriority() => nextResultPriority;
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-
-  void resultsComputed(
-      AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) {}
-}
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
deleted file mode 100644
index 27a6dfb..0000000
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/html.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/html.dart';
-import 'package:html/dom.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../context/abstract_context.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(DartScriptsTaskTest);
-    defineReflectiveTests(HtmlErrorsTaskTest);
-    defineReflectiveTests(ParseHtmlTaskTest);
-  });
-}
-
-final isDartScriptsTask = new TypeMatcher<DartScriptsTask>();
-final isHtmlErrorsTask = new TypeMatcher<HtmlErrorsTask>();
-final isParseHtmlTask = new TypeMatcher<ParseHtmlTask>();
-
-@reflectiveTest
-class DartScriptsTaskTest extends AbstractContextTest {
-  test_buildInputs() {
-    Source source = newSource('/test.html');
-    Map<String, TaskInput> inputs = DartScriptsTask.buildInputs(source);
-    expect(inputs, isNotNull);
-    expect(inputs.keys, unorderedEquals([DartScriptsTask.DOCUMENT_INPUT]));
-  }
-
-  test_constructor() {
-    Source source = newSource('/test.html');
-    DartScriptsTask task = new DartScriptsTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_createTask() {
-    Source source = newSource('/test.html');
-    DartScriptsTask task = DartScriptsTask.createTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_description() {
-    Source source = newSource('/test.html');
-    DartScriptsTask task = new DartScriptsTask(null, source);
-    expect(task.description, isNotNull);
-  }
-
-  test_descriptor() {
-    TaskDescriptor descriptor = DartScriptsTask.DESCRIPTOR;
-    expect(descriptor, isNotNull);
-  }
-
-  void test_perform_embedded_source() {
-    String content = r'''
-    void buttonPressed() {}
-  ''';
-    AnalysisTarget target = newSource('/test.html', '''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart'>$content</script>
-</head>
-<body>
-</body>
-</html>''');
-    computeResult(target, REFERENCED_LIBRARIES, matcher: isDartScriptsTask);
-    expect(outputs[REFERENCED_LIBRARIES], hasLength(0));
-    expect(outputs[DART_SCRIPTS], hasLength(1));
-    DartScript script = outputs[DART_SCRIPTS][0];
-    expect(script.fragments, hasLength(1));
-    ScriptFragment fragment = script.fragments[0];
-    expect(fragment.content, content);
-  }
-
-  void test_perform_empty_source_reference() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart' src=''/>
-</head>
-<body>
-</body>
-</html>''');
-    computeResult(target, REFERENCED_LIBRARIES, matcher: isDartScriptsTask);
-    expect(outputs[REFERENCED_LIBRARIES], hasLength(0));
-    expect(outputs[DART_SCRIPTS], hasLength(0));
-  }
-
-  void test_perform_invalid_source_reference() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart' src='an;invalid:[]uri'/>
-</head>
-<body>
-</body>
-</html>''');
-    computeResult(target, REFERENCED_LIBRARIES, matcher: isDartScriptsTask);
-    expect(outputs[REFERENCED_LIBRARIES], hasLength(0));
-    expect(outputs[DART_SCRIPTS], hasLength(0));
-  }
-
-  void test_perform_non_existing_source_reference() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart' src='does/not/exist.dart'/>
-</head>
-<body>
-</body>
-</html>''');
-    computeResult(target, REFERENCED_LIBRARIES, matcher: isDartScriptsTask);
-    expect(outputs[REFERENCED_LIBRARIES], hasLength(1));
-    expect(outputs[DART_SCRIPTS], hasLength(0));
-  }
-
-  test_perform_none() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>test page</title>
-  </head>
-  <body>
-    Test
-  </body>
-</html>
-''');
-    computeResult(target, REFERENCED_LIBRARIES, matcher: isDartScriptsTask);
-    expect(outputs[REFERENCED_LIBRARIES], hasLength(0));
-    expect(outputs[DART_SCRIPTS], hasLength(0));
-  }
-
-  void test_perform_referenced_source() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart' src='test.dart'/>
-</head>
-<body>
-</body>
-</html>''');
-    computeResult(target, REFERENCED_LIBRARIES, matcher: isDartScriptsTask);
-    expect(outputs[REFERENCED_LIBRARIES], hasLength(1));
-    expect(outputs[DART_SCRIPTS], hasLength(0));
-  }
-}
-
-@reflectiveTest
-class HtmlErrorsTaskTest extends AbstractContextTest {
-  fail_perform_htmlErrors() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<html>
-  <head>
-    <title>test page</not-title>
-  </head>
-  <body>
-    Test
-  </body>
-</html>
-''');
-    computeResult(target, HTML_ERRORS, matcher: isHtmlErrorsTask);
-    expect(outputs[HTML_ERRORS], hasLength(1));
-  }
-
-  test_constructor() {
-    Source source = newSource('/test.html');
-    HtmlErrorsTask task = new HtmlErrorsTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_createTask() {
-    Source source = newSource('/test.html');
-    HtmlErrorsTask task = HtmlErrorsTask.createTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_description() {
-    Source source = newSource('/test.html');
-    HtmlErrorsTask task = new HtmlErrorsTask(null, source);
-    expect(task.description, isNotNull);
-  }
-
-  test_descriptor() {
-    TaskDescriptor descriptor = HtmlErrorsTask.DESCRIPTOR;
-    expect(descriptor, isNotNull);
-  }
-
-  test_perform_dartErrors() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>test page</title>
-    <script type='application/dart'>
-      void buttonPressed() {
-    </script>
-  </head>
-  <body>Test</body>
-</html>
-''');
-    computeResult(target, HTML_ERRORS, matcher: isHtmlErrorsTask);
-    expect(outputs[HTML_ERRORS], hasLength(1));
-  }
-
-  test_perform_noErrors() {
-    AnalysisTarget target = newSource('/test.html', r'''
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>test page</title>
-  </head>
-  <body>
-    Test
-  </body>
-</html>
-''');
-    computeResult(target, HTML_ERRORS, matcher: isHtmlErrorsTask);
-    expect(outputs[HTML_ERRORS], isEmpty);
-  }
-}
-
-@reflectiveTest
-class ParseHtmlTaskTest extends AbstractContextTest {
-  test_buildInputs() {
-    Source source = newSource('/test.html');
-    Map<String, TaskInput> inputs = ParseHtmlTask.buildInputs(source);
-    expect(inputs, isNotNull);
-    expect(
-        inputs.keys,
-        unorderedEquals([
-          ParseHtmlTask.CONTENT_INPUT_NAME,
-          ParseHtmlTask.MODIFICATION_TIME_INPUT
-        ]));
-  }
-
-  test_constructor() {
-    Source source = newSource('/test.html');
-    ParseHtmlTask task = new ParseHtmlTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_createTask() {
-    Source source = newSource('/test.html');
-    ParseHtmlTask task = ParseHtmlTask.createTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_description() {
-    Source source = newSource('/test.html');
-    ParseHtmlTask task = new ParseHtmlTask(null, source);
-    expect(task.description, isNotNull);
-  }
-
-  test_descriptor() {
-    TaskDescriptor descriptor = ParseHtmlTask.DESCRIPTOR;
-    expect(descriptor, isNotNull);
-  }
-
-  test_perform() {
-    String code = r'''
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>test page</title>
-  </head>
-  <body>
-    <h1 myAttr='my value'>Test</h1>
-  </body>
-</html>
-''';
-    AnalysisTarget target = newSource('/test.html', code);
-    computeResult(target, HTML_DOCUMENT);
-    expect(task, isParseHtmlTask);
-    expect(outputs[HTML_DOCUMENT_ERRORS], isEmpty);
-    // HTML_DOCUMENT
-    {
-      Document document = outputs[HTML_DOCUMENT];
-      expect(document, isNotNull);
-      // verify that attributes are not lower-cased
-      Element element = document.body.getElementsByTagName('h1').single;
-      expect(element.attributes['myAttr'], 'my value');
-    }
-    // LINE_INFO
-    {
-      LineInfo lineInfo = outputs[LINE_INFO];
-      expect(lineInfo, isNotNull);
-      {
-        int offset = code.indexOf('<!DOCTYPE');
-        CharacterLocation location = lineInfo.getLocation(offset);
-        expect(location.lineNumber, 1);
-        expect(location.columnNumber, 1);
-      }
-      {
-        int offset = code.indexOf('<html>');
-        CharacterLocation location = lineInfo.getLocation(offset);
-        expect(location.lineNumber, 2);
-        expect(location.columnNumber, 1);
-      }
-      {
-        int offset = code.indexOf('<title>');
-        CharacterLocation location = lineInfo.getLocation(offset);
-        expect(location.lineNumber, 4);
-        expect(location.columnNumber, 5);
-      }
-    }
-  }
-
-  test_perform_noDocType() {
-    String code = r'''
-<div>AAA</div>
-<span>BBB</span>
-''';
-    AnalysisTarget target = newSource('/test.html', code);
-    computeResult(target, HTML_DOCUMENT);
-    expect(task, isParseHtmlTask);
-    // validate Document
-    {
-      Document document = outputs[HTML_DOCUMENT];
-      expect(document, isNotNull);
-      // artificial <html>
-      expect(document.nodes, hasLength(1));
-      Element htmlElement = document.nodes[0];
-      expect(htmlElement.localName, 'html');
-      // artificial <body>
-      expect(htmlElement.nodes, hasLength(2));
-      Element bodyElement = htmlElement.nodes[1];
-      expect(bodyElement.localName, 'body');
-      // actual nodes
-      expect(bodyElement.nodes, hasLength(4));
-      expect((bodyElement.nodes[0] as Element).localName, 'div');
-      expect((bodyElement.nodes[2] as Element).localName, 'span');
-    }
-    // it's OK to don't have DOCTYPE
-    expect(outputs[HTML_DOCUMENT_ERRORS], isEmpty);
-  }
-}
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index cd1e370..02f48c5 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -17,8 +17,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/lint/linter.dart';
 import 'package:analyzer/src/lint/registry.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/model.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -32,7 +30,6 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(ContextConfigurationTest);
     defineReflectiveTests(ErrorCodeValuesTest);
-    defineReflectiveTests(GenerateNewOptionsErrorsTaskTest);
     defineReflectiveTests(GenerateOldOptionsErrorsTaskTest);
     defineReflectiveTests(OptionsFileValidatorTest);
     defineReflectiveTests(OptionsProviderTest);
@@ -265,190 +262,6 @@
 }
 
 @reflectiveTest
-class GenerateNewOptionsErrorsTaskTest extends AbstractContextTest {
-  Source source;
-
-  String get optionsFilePath => '/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
-
-  LineInfo lineInfo(String source) =>
-      GenerateOptionsErrorsTask.computeLineInfo(source);
-
-  @override
-  setUp() {
-    super.setUp();
-    source = newSource(optionsFilePath);
-  }
-
-  test_buildInputs() {
-    Map<String, TaskInput> inputs =
-        GenerateOptionsErrorsTask.buildInputs(source);
-    expect(inputs, isNotNull);
-    expect(inputs.keys,
-        unorderedEquals([GenerateOptionsErrorsTask.CONTENT_INPUT_NAME]));
-  }
-
-  test_compute_lineInfo() {
-    expect(lineInfo('foo\nbar').getLocation(4).lineNumber, 2);
-    expect(lineInfo('foo\nbar').getLocation(4).columnNumber, 1);
-    expect(lineInfo('foo\r\nbar').getLocation(5).lineNumber, 2);
-    expect(lineInfo('foo\r\nbar').getLocation(5).columnNumber, 1);
-    expect(lineInfo('foo\rbar').getLocation(4).lineNumber, 2);
-    expect(lineInfo('foo\rbar').getLocation(4).columnNumber, 1);
-    expect(lineInfo('foo').getLocation(0).lineNumber, 1);
-    expect(lineInfo('foo').getLocation(0).columnNumber, 1);
-    expect(lineInfo('').getLocation(1).lineNumber, 1);
-  }
-
-  test_constructor() {
-    GenerateOptionsErrorsTask task =
-        new GenerateOptionsErrorsTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_createTask() {
-    GenerateOptionsErrorsTask task =
-        GenerateOptionsErrorsTask.createTask(context, source);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, source);
-  }
-
-  test_description() {
-    GenerateOptionsErrorsTask task =
-        new GenerateOptionsErrorsTask(null, source);
-    expect(task.description, isNotNull);
-  }
-
-  test_descriptor() {
-    TaskDescriptor descriptor = GenerateOptionsErrorsTask.DESCRIPTOR;
-    expect(descriptor, isNotNull);
-  }
-
-  @failingTest
-  test_perform_bad_yaml() {
-    // We have lost the ability to detect this kind of error.
-    String code = r'''
-:
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors =
-        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
-    expect(errors, hasLength(1));
-    expect(errors[0].errorCode, AnalysisOptionsErrorCode.PARSE_ERROR);
-  }
-
-  test_perform_include() {
-    newSource('/other_options.yaml', '');
-    String code = r'''
-include: other_options.yaml
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors =
-        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
-    expect(errors, hasLength(0));
-  }
-
-  test_perform_include_bad_value() {
-    newSource('/other_options.yaml', '''
-analyzer:
-  errors:
-    unused_local_variable: ftw
-''');
-    String code = r'''
-include: other_options.yaml
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors =
-        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.errorCode, AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING);
-    expect(error.source, target.source);
-    expect(error.offset, 10);
-    expect(error.length, 18);
-    expect(error.message, contains('other_options.yaml(47..49)'));
-  }
-
-  @failingTest
-  test_perform_include_bad_yaml() {
-    // We have lost the ability to detect this kind of error.
-    newSource('/other_options.yaml', ':');
-    String code = r'''
-include: other_options.yaml
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors =
-        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.errorCode, AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR);
-    expect(error.source, target.source);
-    expect(error.offset, 10);
-    expect(error.length, 18);
-    expect(error.message, contains('other_options.yaml(0..0)'));
-  }
-
-  test_perform_include_missing() {
-    String code = r'''
-include: other_options.yaml
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors =
-        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.errorCode, AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND);
-    expect(error.offset, 10);
-    expect(error.length, 18);
-  }
-
-  test_perform_OK() {
-    String code = r'''
-analyzer:
-  strong-mode: true
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    expect(outputs[ANALYSIS_OPTIONS_ERRORS], hasLength(1));
-    expect(outputs[ANALYSIS_OPTIONS_ERRORS].first.errorCode,
-        AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED);
-
-    LineInfo lineInfo = outputs[LINE_INFO];
-    expect(lineInfo, isNotNull);
-    expect(lineInfo.getLocation(1).lineNumber, 1);
-    expect(lineInfo.getLocation(10).lineNumber, 2);
-  }
-
-  test_perform_unsupported_analyzer_option() {
-    String code = r'''
-analyzer:
-  not_supported: true
-''';
-    AnalysisTarget target = newSource(optionsFilePath, code);
-    computeResult(target, ANALYSIS_OPTIONS_ERRORS);
-    expect(task, isGenerateOptionsErrorsTask);
-    List<AnalysisError> errors =
-        outputs[ANALYSIS_OPTIONS_ERRORS] as List<AnalysisError>;
-    expect(errors, hasLength(1));
-    expect(errors[0].errorCode,
-        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES);
-  }
-}
-
-@reflectiveTest
 class GenerateOldOptionsErrorsTaskTest extends AbstractContextTest {
   final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
 
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 981b10e..f46df08 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -8,13 +8,11 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(CheckerTest);
     defineReflectiveTests(CheckerTest_Driver);
   });
 }
 
-@reflectiveTest
-class CheckerTest extends AbstractStrongTest {
+abstract class CheckerTest extends AbstractStrongTest {
   test_awaitForInCastsStreamElementToVariable() async {
     await checkFile('''
 import 'dart:async';
@@ -3985,7 +3983,10 @@
 
     SubClonable<T> s = object;
     takesSubClonable<T>(object);
-    h(object);
+    // Issue #35799: According to the language team, this should work, but both
+    // analyzer and CFE currently reject it, likely due to a strange
+    // representation of promoted type variables.
+    // h(object);
   }
 }
 ''');
diff --git a/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart b/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
index df6b540..0036bd3 100644
--- a/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
+++ b/pkg/analyzer/test/src/task/strong/dart2_inference_test.dart
@@ -17,7 +17,6 @@
 void main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(Dart2InferenceTest);
-    defineReflectiveTests(Dart2InferenceTest_Task);
   });
 }
 
@@ -886,12 +885,6 @@
   }
 }
 
-@reflectiveTest
-class Dart2InferenceTest_Task extends Dart2InferenceTest {
-  @override
-  bool get enableNewAnalysisDriver => false;
-}
-
 class _TypeAnnotationsValidator extends RecursiveAstVisitor {
   final Map<int, String> types;
 
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 51c6016..80c62f1 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -16,77 +16,11 @@
 
 void main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InferredTypeTest);
     defineReflectiveTests(InferredTypeTest_Driver);
     defineReflectiveTests(InferredTypeTest_SetLiterals);
   });
 }
 
-@reflectiveTest
-class InferredTypeTest extends AbstractStrongTest with InferredTypeMixin {
-  @override
-  bool get mayCheckTypesOfLocals => true;
-
-  @override
-  Future<CompilationUnitElement> checkFileElement(String content) async {
-    CompilationUnit unit = await checkFile(content);
-    return unit.declaredElement;
-  }
-
-  @override
-  @failingTest
-  test_circularReference_viaClosures() {
-    return super.test_circularReference_viaClosures();
-  }
-
-  @override
-  @failingTest
-  test_circularReference_viaClosures_initializerTypes() {
-    return super.test_circularReference_viaClosures_initializerTypes();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_typeName_error1() {
-    // Test doesn't work with the old task model
-    return super.test_instantiateToBounds_typeName_error1();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_typeName_error2() {
-    // Test doesn't work with the old task model
-    return super.test_instantiateToBounds_typeName_error2();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_typeName_error3() {
-    // Test doesn't work with the old task model
-    return super.test_instantiateToBounds_typeName_error3();
-  }
-
-  @override
-  @failingTest
-  test_instantiateToBounds_typeName_OK_hasBound_definedAfter() {
-    return super.test_instantiateToBounds_typeName_OK_hasBound_definedAfter();
-  }
-
-  @override
-  @failingTest
-  test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1() {
-    return super
-        .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1();
-  }
-
-  @failingTest
-  @override
-  test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() {
-    return super
-        .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1();
-  }
-}
-
 mixin InferredTypeMixin {
   /// Extra top-level errors if needed due to being analyze multiple times.
   bool get hasExtraTaskModelPass => true;
@@ -1571,7 +1505,7 @@
 Iterable<Map<int, int>> bar() sync* {
   yield /*info:INFERRED_TYPE_LITERAL*/{};
   yield /*error:YIELD_OF_INVALID_TYPE*/new List();
-  yield* /*error:YIELD_OF_INVALID_TYPE*/{};
+  yield* {};
   yield* /*info:INFERRED_TYPE_ALLOCATION*/new List();
 }
 ''');
@@ -4458,6 +4392,71 @@
 }
 
 @reflectiveTest
+class InferredTypeTest extends AbstractStrongTest with InferredTypeMixin {
+  @override
+  bool get mayCheckTypesOfLocals => true;
+
+  @override
+  Future<CompilationUnitElement> checkFileElement(String content) async {
+    CompilationUnit unit = await checkFile(content);
+    return unit.declaredElement;
+  }
+
+  @override
+  @failingTest
+  test_circularReference_viaClosures() {
+    return super.test_circularReference_viaClosures();
+  }
+
+  @override
+  @failingTest
+  test_circularReference_viaClosures_initializerTypes() {
+    return super.test_circularReference_viaClosures_initializerTypes();
+  }
+
+  @override
+  @failingTest
+  test_instantiateToBounds_typeName_error1() {
+    // Test doesn't work with the old task model
+    return super.test_instantiateToBounds_typeName_error1();
+  }
+
+  @override
+  @failingTest
+  test_instantiateToBounds_typeName_error2() {
+    // Test doesn't work with the old task model
+    return super.test_instantiateToBounds_typeName_error2();
+  }
+
+  @override
+  @failingTest
+  test_instantiateToBounds_typeName_error3() {
+    // Test doesn't work with the old task model
+    return super.test_instantiateToBounds_typeName_error3();
+  }
+
+  @override
+  @failingTest
+  test_instantiateToBounds_typeName_OK_hasBound_definedAfter() {
+    return super.test_instantiateToBounds_typeName_OK_hasBound_definedAfter();
+  }
+
+  @override
+  @failingTest
+  test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1() {
+    return super
+        .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1();
+  }
+
+  @failingTest
+  @override
+  test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() {
+    return super
+        .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1();
+  }
+}
+
+@reflectiveTest
 class InferredTypeTest_Driver extends AbstractStrongTest
     with InferredTypeMixin {
   @override
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
deleted file mode 100644
index cbf2625..0000000
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/strong_mode.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/resolver_test_case.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(SetFieldTypeTest);
-    defineReflectiveTests(VariableGathererTest);
-  });
-}
-
-@reflectiveTest
-class SetFieldTypeTest extends ResolverTestCase {
-  test_setter_withoutParameter() async {
-    Source source = addSource('''
-var x = 0;
-set x() {}
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    CompilationUnitElement unit = analysisResult.unit.declaredElement;
-    TopLevelVariableElement variable = unit.topLevelVariables.single;
-    setFieldType(variable, unit.context.typeProvider.intType);
-  }
-}
-
-@reflectiveTest
-class VariableGathererTest extends ResolverTestCase {
-  test_creation_withFilter() async {
-    VariableFilter filter = (variable) => true;
-    VariableGatherer gatherer = new VariableGatherer(filter);
-    expect(gatherer, isNotNull);
-    expect(gatherer.filter, same(filter));
-  }
-
-  test_creation_withoutFilter() async {
-    VariableGatherer gatherer = new VariableGatherer();
-    expect(gatherer, isNotNull);
-    expect(gatherer.filter, isNull);
-  }
-
-  test_visit_noReferences() async {
-    Source source = addNamedSource('/test.dart', '''
-library lib;
-import 'dart:math';
-int zero = 0;
-class C {
-  void m() => null;
-}
-typedef void F();
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    VariableGatherer gatherer = new VariableGatherer();
-    analysisResult.unit.accept(gatherer);
-    expect(gatherer.results, hasLength(0));
-  }
-
-  test_visit_withFilter() async {
-    VariableFilter filter = (VariableElement variable) => variable.isStatic;
-    Set<VariableElement> variables = await _gather(filter);
-    expect(variables, hasLength(1));
-  }
-
-  test_visit_withoutFilter() async {
-    Set<VariableElement> variables = await _gather();
-    expect(variables, hasLength(4));
-  }
-
-  Future<Set<VariableElement>> _gather([VariableFilter filter = null]) async {
-    Source source = addNamedSource('/test.dart', '''
-const int zero = 0;
-class Counter {
-  int value = zero;
-  void inc() {
-    value++;
-  }
-  void dec() {
-    value = value - 1;
-  }
-  void fromZero(f(int index)) {
-    for (int i = zero; i < value; i++) {
-      f(i);
-    }
-  }
-}
-''');
-    var analysisResult = await computeAnalysisResult(source);
-    VariableGatherer gatherer = new VariableGatherer(filter);
-    analysisResult.unit.accept(gatherer);
-    return gatherer.results;
-  }
-}
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index 7353891..f8f989c5 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -4,11 +4,8 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'dart_test.dart' as dart_test;
 import 'dart_work_manager_test.dart' as dart_work_manager_test;
-import 'driver_test.dart' as driver_test;
 import 'general_test.dart' as general_test;
-import 'html_test.dart' as html_test;
 import 'html_work_manager_test.dart' as html_work_manager_test;
 import 'inputs_test.dart' as inputs_test;
 import 'manager_test.dart' as manager_test;
@@ -16,17 +13,12 @@
 import 'options_test.dart' as options_test;
 import 'options_work_manager_test.dart' as options_work_manager_test;
 import 'strong/test_all.dart' as strong_mode_test_all;
-import 'strong_mode_test.dart' as strong_mode_test;
-import 'yaml_test.dart' as yaml_test;
 
 /// Utility for manually running all tests.
 main() {
   defineReflectiveSuite(() {
-    dart_test.main();
     dart_work_manager_test.main();
-    driver_test.main();
     general_test.main();
-    html_test.main();
     html_work_manager_test.main();
     inputs_test.main();
     manager_test.main();
@@ -34,7 +26,5 @@
     options_test.main();
     options_work_manager_test.main();
     strong_mode_test_all.main();
-    strong_mode_test.main();
-    yaml_test.main();
   }, name: 'task');
 }
diff --git a/pkg/analyzer/test/src/task/yaml_test.dart b/pkg/analyzer/test/src/task/yaml_test.dart
deleted file mode 100644
index 4342087..0000000
--- a/pkg/analyzer/test/src/task/yaml_test.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/yaml.dart';
-import 'package:analyzer/src/task/yaml.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:yaml/yaml.dart';
-
-import '../context/abstract_context.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ParseYamlTaskTest);
-  });
-}
-
-final isParseYamlTask = new TypeMatcher<ParseYamlTask>();
-
-@reflectiveTest
-class ParseYamlTaskTest extends AbstractContextTest {
-  Source source;
-
-  test_perform() {
-    _performParseTask(r'''
-rules:
-  style_guide:
-    camel_case_types: false
-''');
-    expect(outputs, hasLength(3));
-    YamlDocument document = outputs[YAML_DOCUMENT];
-    expect(document, isNotNull);
-    var value = document.contents.value;
-    expect(value, new TypeMatcher<Map>());
-    expect(value['rules']['style_guide']['camel_case_types'], isFalse);
-    expect(outputs[YAML_ERRORS], hasLength(0));
-    LineInfo lineInfo = outputs[LINE_INFO];
-    expect(lineInfo, isNotNull);
-    expect(lineInfo.getOffsetOfLine(0), 0);
-    expect(lineInfo.getOffsetOfLine(1), 7);
-    expect(lineInfo.getOffsetOfLine(2), 22);
-    expect(lineInfo.getOffsetOfLine(3), 50);
-  }
-
-  test_perform_doesNotExist() {
-    _performParseTask(null);
-    expect(outputs, hasLength(3));
-    YamlDocument document = outputs[YAML_DOCUMENT];
-    expect(document, isNotNull);
-    expect(document.contents.value, isNull);
-    expect(outputs[YAML_ERRORS], hasLength(1));
-    LineInfo lineInfo = outputs[LINE_INFO];
-    expect(lineInfo, isNotNull);
-    expect(lineInfo.getOffsetOfLine(0), 0);
-  }
-
-  void _performParseTask(String content) {
-    var path = '/test.yaml';
-    if (content == null) {
-      source = getFile(path).createSource();
-    } else {
-      source = newSource(path, content);
-    }
-    computeResult(source, YAML_DOCUMENT, matcher: isParseYamlTask);
-  }
-}
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index 173fc46..7fd9011 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -488,10 +488,19 @@
 class PackageBuildWorkspacePackageTest with ResourceProviderMixin {
   PackageBuildWorkspace _createPackageBuildWorkspace() {
     final contextBuilder = new MockContextBuilder();
-    final packages = new MockPackages();
-    final packageMap = <String, List<Folder>>{'project': []};
-    contextBuilder.packagesMapMap[convertPath('/workspace')] = packages;
-    contextBuilder.packagesToMapMap[packages] = packageMap;
+    final packagesForWorkspace = new MockPackages();
+    contextBuilder.packagesMapMap[convertPath('/workspace')] =
+        packagesForWorkspace;
+    contextBuilder.packagesToMapMap[packagesForWorkspace] = {
+      'project': <Folder>[]
+    };
+
+    final packagesForWorkspace2 = new MockPackages();
+    contextBuilder.packagesMapMap[convertPath('/workspace2')] =
+        packagesForWorkspace2;
+    contextBuilder.packagesToMapMap[packagesForWorkspace2] = {
+      'project2': <Folder>[]
+    };
 
     newFolder('/workspace/.dart_tool/build');
     newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
@@ -504,7 +513,7 @@
     newFile('/workspace/project/lib/file.dart');
 
     var package = workspace
-        .findPackageFor(convertPath('/workspace2/project/lib/file.dart'));
+        .findPackageFor(convertPath('/workspace2/project2/lib/file.dart'));
     expect(package, isNull);
   }
 
@@ -521,11 +530,11 @@
 
   void test_contains_differentWorkspace() {
     PackageBuildWorkspace workspace = _createPackageBuildWorkspace();
-    newFile('/workspace2/project/lib/file.dart');
+    newFile('/workspace2/project2/lib/file.dart');
 
     var package = workspace
         .findPackageFor(convertPath('/workspace/project/lib/code.dart'));
-    expect(package.contains('/workspace2/project/lib/file.dart'), isFalse);
+    expect(package.contains('/workspace2/project2/lib/file.dart'), isFalse);
   }
 
   void test_contains_sameWorkspace() {
diff --git a/pkg/analyzer/tool/messages/generate.dart b/pkg/analyzer/tool/messages/generate.dart
index b0e7c53..a88a897 100644
--- a/pkg/analyzer/tool/messages/generate.dart
+++ b/pkg/analyzer/tool/messages/generate.dart
@@ -15,7 +15,7 @@
 import 'dart:io';
 
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:front_end/src/testing/package_root.dart' as pkgRoot;
 import 'package:front_end/src/fasta/scanner.dart';
diff --git a/pkg/analyzer/tool/summary/check_test.dart b/pkg/analyzer/tool/summary/check_test.dart
index c7ddf9e..ff689ba 100644
--- a/pkg/analyzer/tool/summary/check_test.dart
+++ b/pkg/analyzer/tool/summary/check_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart';
 
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index d99b76a..d4d5157 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -20,7 +20,7 @@
 import 'dart:convert';
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:front_end/src/fasta/scanner/string_scanner.dart';
 import 'package:front_end/src/scanner/token.dart' show Token;
diff --git a/pkg/analyzer/tool/task_dependency_graph/check_test.dart b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
index 3452f40..efc365d 100644
--- a/pkg/analyzer/tool/task_dependency_graph/check_test.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart';
 
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index 3a9aa7b..da4e3a9 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -19,13 +19,13 @@
 import 'dart:io' hide File;
 import 'dart:io' as io;
 
+import 'package:analysis_tool/tools.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/codegen/tools.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 2c64108..ee2a239 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -193,11 +193,17 @@
   PackageBundleAssembler assembler;
   final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
 
+  // May be null.
+  final DependencyTracker dependencyTracker;
+
   BuildMode(this.resourceProvider, this.options, this.stats, this.contextCache,
       {PerformanceLog logger, PackageBundleProvider packageBundleProvider})
       : logger = logger ?? new PerformanceLog(null),
         packageBundleProvider = packageBundleProvider ??
-            new DirectPackageBundleProvider(resourceProvider);
+            new DirectPackageBundleProvider(resourceProvider),
+        dependencyTracker = options.summaryDepsOutput != null
+            ? DependencyTracker(options.summaryDepsOutput)
+            : null;
 
   bool get _shouldOutputSummary =>
       options.buildSummaryOutput != null ||
@@ -306,6 +312,11 @@
         }
       }
 
+      if (dependencyTracker != null) {
+        io.File file = new io.File(dependencyTracker.outputPath);
+        file.writeAsStringSync(dependencyTracker.dependencies.join('\n'));
+      }
+
       if (options.buildSummaryOnly) {
         return ErrorSeverity.NONE;
       } else {
@@ -323,11 +334,25 @@
    */
   void _computeLinkedLibraries(Set<String> libraryUris) {
     logger.run('Link output summary', () {
-      LinkedLibrary getDependency(String absoluteUri) =>
-          summaryDataStore.linkedMap[absoluteUri];
+      void trackDependency(String absoluteUri) {
+        if (dependencyTracker != null) {
+          var summaryUri = summaryDataStore.uriToSummaryPath[absoluteUri];
+          if (summaryUri != null) {
+            dependencyTracker.record(summaryUri);
+          }
+        }
+      }
 
-      UnlinkedUnit getUnit(String absoluteUri) =>
-          summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri];
+      LinkedLibrary getDependency(String absoluteUri) {
+        trackDependency(absoluteUri);
+        return summaryDataStore.linkedMap[absoluteUri];
+      }
+
+      UnlinkedUnit getUnit(String absoluteUri) {
+        trackDependency(absoluteUri);
+        return summaryDataStore.unlinkedMap[absoluteUri] ??
+            uriToUnit[absoluteUri];
+      }
 
       Map<String, LinkedLibraryBuilder> linkResult = link(libraryUris,
           getDependency, getUnit, analysisDriver.declaredVariables.get);
@@ -694,3 +719,19 @@
     return cache.get(inputs, path);
   }
 }
+
+/**
+ * Tracks paths to dependencies, really just a thin api around a Set<String>.
+ */
+class DependencyTracker {
+  final _dependencies = Set<String>();
+
+  Iterable<String> get dependencies => _dependencies;
+
+  /// The path to the file to create once tracking is done.
+  final String outputPath;
+
+  DependencyTracker(this.outputPath);
+
+  void record(String path) => _dependencies.add(path);
+}
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 81712bc..6330d84 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -150,6 +150,10 @@
   /// Dart analyzer snapshot.
   final bool trainSnapshot;
 
+  /// Path to a file to dump summary dependency information to for any given
+  /// build.
+  final String summaryDepsOutput;
+
   /// Initialize options from the given parsed [args].
   CommandLineOptions._fromArgs(ArgResults args)
       : buildAnalysisOutput = cast(args['build-analysis-output']),
@@ -191,7 +195,8 @@
         lintsAreFatal = cast(args['fatal-lints']),
         trainSnapshot = cast(args['train-snapshot']),
         verbose = cast(args['verbose']),
-        color = cast(args['color']);
+        color = cast(args['color']),
+        summaryDepsOutput = cast(args['summary-deps-output']);
 
   /// The path to an analysis options file
   String get analysisOptionsFile =>
@@ -405,6 +410,9 @@
       ..addFlag('color',
           help: 'Use ansi colors when printing messages.',
           defaultsTo: ansi.terminalSupportsAnsi(),
+          hide: hide)
+      ..addOption('summary-deps-output',
+          help: 'Path to a file to dump summary dependency info to.',
           hide: hide);
 
     // Hidden flags.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index d1ab672..5ce4c0e 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -18,12 +18,14 @@
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     hide Element, ElementKind;
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/dart/import_library_element.dart';
 import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
 import 'package:charcode/ascii.dart';
+import 'package:meta/meta.dart';
 
 /**
  * A [ChangeBuilder] used to build changes in Dart files.
@@ -1203,6 +1205,35 @@
   }
 
   @override
+  ImportLibraryElementResult importLibraryElement({
+    @required ResolvedLibraryResult targetLibrary,
+    @required String targetPath,
+    @required int targetOffset,
+    @required LibraryElement requestedLibrary,
+    @required String requestedName,
+  }) {
+    if (librariesToImport.isNotEmpty) {
+      throw StateError('Only one library can be safely imported.');
+    }
+
+    var request = importLibraryElementImpl(
+      targetResolvedLibrary: targetLibrary,
+      targetPath: targetPath,
+      targetOffset: targetOffset,
+      requestedLibrary: requestedLibrary,
+      requestedName: requestedName,
+    );
+
+    var prefix = request.prefix;
+    if (request.uri != null) {
+      var uriText = _getLibraryUriText(request.uri);
+      librariesToImport[request.uri] = _LibraryToImport(uriText, prefix);
+    }
+
+    return ImportLibraryElementResultImpl(prefix);
+  }
+
+  @override
   void replaceTypeWithFuture(
       TypeAnnotation typeAnnotation, TypeProvider typeProvider) {
     InterfaceType futureType = typeProvider.futureType;
@@ -1511,6 +1542,14 @@
   }
 }
 
+/// Information about a library to import.
+class ImportLibraryElementResultImpl implements ImportLibraryElementResult {
+  @override
+  final String prefix;
+
+  ImportLibraryElementResultImpl(this.prefix);
+}
+
 class _EnclosingElementFinder {
   ClassElement enclosingClass;
   ExecutableElement enclosingExecutable;
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
new file mode 100644
index 0000000..086f7c6
--- /dev/null
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/import_library_element.dart
@@ -0,0 +1,191 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All 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/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/dart/syntactic_scope.dart';
+import 'package:meta/meta.dart';
+
+ImportLibraryRequest importLibraryElementImpl({
+  @required ResolvedLibraryResult targetResolvedLibrary,
+  @required String targetPath,
+  @required int targetOffset,
+  @required LibraryElement requestedLibrary,
+  @required String requestedName,
+}) {
+  var targetLibrary = targetResolvedLibrary.element;
+
+  var requestedLibraryUri = requestedLibrary.source.uri;
+  var requestedElement = requestedLibrary.exportNamespace.get(requestedName);
+  var requestedElementUri = requestedElement.librarySource.uri;
+
+  // If the element is defined in this library, then no prefix needed.
+  if (targetLibrary == requestedElement.library) {
+    return ImportLibraryRequest(null, null);
+  }
+
+  var requestedElements = requestedLibrary.exportNamespace.definedNames;
+  _removeEntryForDynamic(requestedElements);
+
+  // Find URIs of all libraries that import the requested name into the target.
+  var unprefixedNameUriSet = Set<Uri>();
+  for (var import in targetLibrary.imports) {
+    var definedNames = import.namespace.definedNames;
+    if (import.prefix == null) {
+      var element = definedNames[requestedName];
+      if (element != null) {
+        unprefixedNameUriSet.add(element.librarySource.uri);
+      }
+    }
+  }
+
+  // Find names that will be shadowed by a new unprefixed import.
+  var collector = NotSyntacticScopeReferencedNamesCollector(
+    targetResolvedLibrary.element,
+    requestedElements.keys.toSet(),
+  );
+  for (var resolvedUnit in targetResolvedLibrary.units) {
+    resolvedUnit.unit.accept(collector);
+  }
+
+  // Find names that will shadow unprefixed references.
+  var scopeNames = Set<String>();
+  targetLibrary.accept(_TopLevelNamesCollector(scopeNames));
+  for (var resolvedUnit in targetResolvedLibrary.units) {
+    if (resolvedUnit.path == targetPath) {
+      resolvedUnit.unit.accept(
+        SyntacticScopeNamesCollector(scopeNames, targetOffset),
+      );
+    }
+  }
+
+  var canUseUnprefixedImport = true;
+
+  // If a name is inherited, it will be shadowed by a new unprefixed import.
+  if (collector.inheritedNames.isNotEmpty) {
+    canUseUnprefixedImport = false;
+  }
+
+  // If a name is imported, and it is not the same as the one from the
+  // requested library, then a new unprefixed import will cause ambiguity.
+  for (var name in collector.importedNames.keys) {
+    var importedUri = collector.importedNames[name];
+    var requestedUri = requestedElements[name]?.librarySource?.uri;
+    if (requestedUri != importedUri) {
+      canUseUnprefixedImport = false;
+      break;
+    }
+  }
+
+  // If syntactic scope at the offset has the requested name, then the name
+  // from an unprefixed import will be shadowed.
+  if (scopeNames.contains(requestedName)) {
+    canUseUnprefixedImport = false;
+  }
+
+  // If the requested name is ambiguous from existing unprefixed imports,
+  // or is not the same element as the one from the requested library, then
+  // we cannot use unprefixed import.
+  if (unprefixedNameUriSet.isNotEmpty) {
+    if (unprefixedNameUriSet.length > 1 ||
+        unprefixedNameUriSet.first != requestedElementUri) {
+      canUseUnprefixedImport = false;
+    }
+  }
+
+  // Find import prefixes with which the name is ambiguous.
+  var ambiguousWithImportPrefixes = Set<String>();
+  for (var import in targetLibrary.imports) {
+    var definedNames = import.namespace.definedNames;
+    if (import.prefix != null) {
+      var prefix = import.prefix.name;
+      var prefixedName = '$prefix.$requestedName';
+      var importedElement = definedNames[prefixedName];
+      if (importedElement != null &&
+          importedElement.librarySource.uri != requestedElementUri) {
+        ambiguousWithImportPrefixes.add(prefix);
+      }
+    }
+  }
+
+  // Check for existing imports of the requested library.
+  for (var import in targetLibrary.imports) {
+    if (import.importedLibrary.source.uri == requestedLibraryUri) {
+      var importedNames = import.namespace.definedNames;
+      if (import.prefix == null) {
+        if (canUseUnprefixedImport &&
+            importedNames.containsKey(requestedName)) {
+          return ImportLibraryRequest(null, null);
+        }
+      } else {
+        var prefix = import.prefix.name;
+        var prefixedName = '$prefix.$requestedName';
+        if (importedNames.containsKey(prefixedName) &&
+            !ambiguousWithImportPrefixes.contains(prefix)) {
+          return ImportLibraryRequest(null, prefix);
+        }
+      }
+    }
+  }
+
+  // If the name cannot be used without import prefix, generate one.
+  String prefix;
+  if (!canUseUnprefixedImport) {
+    prefix = 'prefix';
+    for (var index = 0;; index++) {
+      prefix = 'prefix$index';
+      if (!collector.referencedNames.contains(prefix)) {
+        break;
+      }
+    }
+  }
+
+  return ImportLibraryRequest(requestedLibraryUri, prefix);
+}
+
+/// The type `dynamic` is part of 'dart:core', but has no library.
+void _removeEntryForDynamic(Map<String, Element> requestedElements) {
+  requestedElements.removeWhere((_, element) {
+    if (element.librarySource == null) {
+      assert(element.displayName == 'dynamic');
+      return true;
+    }
+    return false;
+  });
+}
+
+/// Information about a library to import.
+class ImportLibraryRequest {
+  /// The URI of the library to import, or `null` if the requested library is
+  /// already imported, with the [prefix], so no new import is required.
+  final Uri uri;
+
+  /// The prefix with which ths requested library is already imported,
+  /// or should be imported, or `null` is no prefix is necessary.
+  final String prefix;
+
+  ImportLibraryRequest(this.uri, this.prefix);
+}
+
+/// Element visitor that collects names of top-level elements.
+class _TopLevelNamesCollector extends GeneralizingElementVisitor<void> {
+  final Set<String> names;
+
+  _TopLevelNamesCollector(this.names);
+
+  @override
+  void visitElement(Element element) {
+    if (element is LibraryElement || element is CompilationUnitElement) {
+      super.visitElement(element);
+    } else if (element is ImportElement) {
+      var prefix = element.prefix?.displayName;
+      if (prefix != null) {
+        names.add(prefix);
+      }
+    } else if (element.enclosingElement is CompilationUnitElement) {
+      names.add(element.displayName);
+    }
+  }
+}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
new file mode 100644
index 0000000..71cf0f0
--- /dev/null
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
@@ -0,0 +1,322 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+
+/// AST visitor that collects names that are referenced, but the target element
+/// is not defined in the syntactic scope of the reference.  Resolution of
+/// such names will change when the import scope of the library changes.
+class NotSyntacticScopeReferencedNamesCollector
+    extends GeneralizingAstVisitor<void> {
+  /// The library that contains resolved AST(s) being visited.
+  final LibraryElement enclosingLibraryElement;
+
+  /// The names that we need to check.
+  final Set<String> interestingNames;
+
+  /// All the referenced unqualified names.
+  final Set<String> referencedNames = Set<String>();
+
+  /// The subset of [interestingNames] that are resolved to a top-level
+  /// element that is not in the syntactic scope of the reference, and the
+  /// library [Uri] is the value in the mapping.
+  final Map<String, Uri> importedNames = {};
+
+  /// The subset of [interestingNames] that are resolved to inherited names.
+  final Set<String> inheritedNames = Set<String>();
+
+  Element enclosingUnitMemberElement;
+
+  NotSyntacticScopeReferencedNamesCollector(
+    this.enclosingLibraryElement,
+    this.interestingNames,
+  );
+
+  @override
+  void visitCombinator(Combinator node) {}
+
+  @override
+  void visitCompilationUnitMember(CompilationUnitMember node) {
+    enclosingUnitMemberElement = node.declaredElement;
+    super.visitCompilationUnitMember(node);
+    enclosingUnitMemberElement = null;
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    var name = node.name;
+    referencedNames.add(name);
+
+    if (node.isQualified) return;
+    if (!interestingNames.contains(name)) return;
+
+    var element = node.staticElement;
+    if (element == null) return;
+
+    if (_inSyntacticScope(element)) return;
+
+    if (element.enclosingElement is CompilationUnitElement) {
+      importedNames[name] = element.librarySource.uri;
+    } else {
+      inheritedNames.add(name);
+    }
+  }
+
+  bool _inSyntacticScope(Element element) {
+    if (element.enclosingElement is CompilationUnitElement &&
+        element.enclosingElement.enclosingElement == enclosingLibraryElement) {
+      return true;
+    }
+
+    while (element != null) {
+      if (element == enclosingUnitMemberElement) return true;
+      element = element.enclosingElement;
+    }
+    return false;
+  }
+}
+
+/// AST visitor that collects syntactic scope names visible at the [offset].
+///
+/// The AST does not need to be resolved.
+class SyntacticScopeNamesCollector extends RecursiveAstVisitor<void> {
+  final Set<String> names;
+  final int offset;
+
+  SyntacticScopeNamesCollector(this.names, this.offset);
+
+  @override
+  void visitBlock(Block node) {
+    if (!_isCoveredBy(node)) return;
+
+    super.visitBlock(node);
+
+    for (var statement in node.statements) {
+      if (statement is FunctionDeclarationStatement) {
+        _addName(statement.functionDeclaration.name);
+      } else if (statement is VariableDeclarationStatement) {
+        _addVariables(statement.variables);
+      }
+    }
+  }
+
+  @override
+  void visitCatchClause(CatchClause node) {
+    if (!_isCoveredBy(node)) return;
+
+    if (node.exceptionParameter != null) {
+      _addName(node.exceptionParameter);
+    }
+
+    if (node.stackTraceParameter != null) {
+      _addName(node.stackTraceParameter);
+    }
+
+    node.body.accept(this);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addTypeParameters(node.typeParameters);
+    _visitClassOrMixinMembers(node);
+  }
+
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    if (!_isCoveredBy(node)) return;
+    _addTypeParameters(node.typeParameters);
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addFormalParameters(node.parameters);
+
+    node.body.accept(this);
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    if (!_isCoveredBy(node)) return;
+
+    if (node.loopVariable != null && _isCoveredBy(node.body)) {
+      _addName(node.loopVariable.identifier);
+    }
+
+    node.iterable?.accept(this);
+    node.body.accept(this);
+  }
+
+  @override
+  void visitForElement(ForElement node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addForLoopParts(node.forLoopParts, node.body);
+
+    super.visitForElement(node);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    if (!_isCoveredBy(node)) return;
+
+    if (node.variables != null) {
+      _addVariables(node.variables);
+    }
+
+    node.condition?.accept(this);
+    node.updaters?.accept(this);
+    node.body.accept(this);
+  }
+
+  @override
+  void visitForStatement2(ForStatement2 node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addForLoopParts(node.forLoopParts, node.body);
+
+    super.visitForStatement2(node);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    if (!_isCoveredBy(node)) return;
+
+    var function = node.functionExpression;
+    _addTypeParameters(function.typeParameters);
+
+    if (function.parameters != null && offset > function.parameters.offset) {
+      _addFormalParameters(function.parameters);
+    }
+
+    function.body.accept(this);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addTypeParameters(node.typeParameters);
+
+    if (offset > node.parameters.offset) {
+      _addFormalParameters(node.parameters);
+    }
+  }
+
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addTypeParameters(node.typeParameters);
+
+    if (offset > node.parameters.offset) {
+      _addFormalParameters(node.parameters);
+    }
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addTypeParameters(node.typeParameters);
+
+    node.functionType.accept(this);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addTypeParameters(node.typeParameters);
+
+    if (node.parameters != null && offset > node.parameters.offset) {
+      _addFormalParameters(node.parameters);
+    }
+
+    node.body.accept(this);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    if (!_isCoveredBy(node)) return;
+
+    _addTypeParameters(node.typeParameters);
+    _visitClassOrMixinMembers(node);
+  }
+
+  void _addForLoopParts(ForLoopParts forLoopParts, AstNode body) {
+    if (forLoopParts is ForEachPartsWithDeclaration) {
+      if (_isCoveredBy(body)) {
+        _addName(forLoopParts.loopVariable.identifier);
+      }
+    } else if (forLoopParts is ForPartsWithDeclarations) {
+      _addVariables(forLoopParts.variables);
+    }
+  }
+
+  void _addFormalParameter(FormalParameter parameter) {
+    if (parameter is DefaultFormalParameter) {
+      _addFormalParameter(parameter.parameter);
+    } else if (parameter is FunctionTypedFormalParameter) {
+      _addName(parameter.identifier);
+      var parameters = parameter.parameters;
+      if (parameters != null && _isCoveredBy(parameters)) {
+        _addFormalParameters(parameters);
+      }
+    } else if (parameter is SimpleFormalParameter) {
+      _addName(parameter.identifier);
+    } else {
+      throw UnimplementedError('(${parameter.runtimeType}) $parameter');
+    }
+  }
+
+  void _addFormalParameters(FormalParameterList parameterList) {
+    for (var parameter in parameterList.parameters) {
+      _addFormalParameter(parameter);
+    }
+  }
+
+  void _addName(SimpleIdentifier node) {
+    if (node != null) {
+      names.add(node.name);
+    }
+  }
+
+  void _addTypeParameters(TypeParameterList typeParameterList) {
+    if (typeParameterList == null) return;
+
+    for (var typeParameter in typeParameterList.typeParameters) {
+      _addName(typeParameter.name);
+    }
+  }
+
+  void _addVariables(VariableDeclarationList variableList) {
+    for (var field in variableList.variables) {
+      _addName(field.name);
+    }
+  }
+
+  bool _isCoveredBy(AstNode node) {
+    return node.offset < offset && offset < node.end;
+  }
+
+  void _visitClassOrMixinMembers(ClassOrMixinDeclaration node) {
+    if (offset < node.leftBracket.offset) return;
+
+    for (var member in node.members) {
+      if (member is FieldDeclaration) {
+        _addVariables(member.fields);
+      } else if (member is MethodDeclaration) {
+        _addName(member.name);
+      }
+    }
+
+    node.members.accept(this);
+  }
+}
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 69a0aae..2449bb7 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -123,6 +123,19 @@
   final int argIndex;
 
   /**
+   * If the target is an argument in an [ArgumentList], then this is the
+   * invoked [ExecutableElement], otherwise this is `null`.
+   */
+  ExecutableElement _executableElement;
+
+  /**
+   * If the target is an argument in an [ArgumentList], then this is the
+   * corresponding [ParameterElement] in the invoked [ExecutableElement],
+   * otherwise this is `null`.
+   */
+  ParameterElement _parameterElement;
+
+  /**
    * Compute the appropriate [CompletionTarget] for the given [offset] within
    * the [compilationUnit].
    *
@@ -250,6 +263,38 @@
             _computeDroppedToken(containingNode, entity, offset);
 
   /**
+   * If the target is an argument in an argument list, and the invocation is
+   * resolved, return the invoked [ExecutableElement].
+   */
+  ExecutableElement get executableElement {
+    if (_executableElement == null) {
+      var argumentList = containingNode;
+      if (argumentList is NamedExpression) {
+        argumentList = argumentList.parent;
+      }
+      if (argumentList is! ArgumentList) {
+        return null;
+      }
+
+      var invocation = argumentList.parent;
+
+      Element executable;
+      if (invocation is Annotation) {
+        executable = invocation.element;
+      } else if (invocation is InstanceCreationExpression) {
+        executable = invocation.constructorName.staticElement;
+      } else if (invocation is MethodInvocation) {
+        executable = invocation.methodName.staticElement;
+      }
+
+      if (executable is ExecutableElement) {
+        _executableElement = executable;
+      }
+    }
+    return _executableElement;
+  }
+
+  /**
    * Return `true` if the [containingNode] is a cascade
    * and the completion insertion is not between the two dots.
    * For example, `..d^` and `..^d` are considered a cascade
@@ -267,6 +312,21 @@
   }
 
   /**
+   * If the target is an argument in an argument list, and the invocation is
+   * resolved, return the corresponding [ParameterElement].
+   */
+  ParameterElement get parameterElement {
+    if (_parameterElement == null) {
+      var executable = executableElement;
+      if (executable != null) {
+        _parameterElement = _getParameterElement(
+            executable.parameters, containingNode, argIndex);
+      }
+    }
+    return _parameterElement;
+  }
+
+  /**
    * Return a source range that represents the region of text that should be
    * replaced when a suggestion based on this target is selected, given that the
    * completion was requested at the given [requestOffset].
@@ -328,63 +388,9 @@
   /**
    * Return `true` if the target is a functional argument in an argument list.
    * The target [AstNode] hierarchy *must* be resolved for this to work.
-   * See [maybeFunctionalArgument].
    */
   bool isFunctionalArgument() {
-    if (!maybeFunctionalArgument()) {
-      return false;
-    }
-    AstNode parent = containingNode.parent;
-    if (parent is ArgumentList) {
-      parent = parent.parent;
-    }
-    if (parent is InstanceCreationExpression) {
-      DartType instType = parent.staticType;
-      if (instType != null) {
-        Element intTypeElem = instType.element;
-        if (intTypeElem is ClassElement) {
-          SimpleIdentifier constructorName = parent.constructorName.name;
-          ConstructorElement constructor = constructorName != null
-              ? intTypeElem.getNamedConstructor(constructorName.name)
-              : intTypeElem.unnamedConstructor;
-          return constructor != null &&
-              _isFunctionalParameter(
-                  constructor.parameters, argIndex, containingNode);
-        }
-      }
-    } else if (parent is MethodInvocation) {
-      SimpleIdentifier methodName = parent.methodName;
-      if (methodName != null) {
-        Element methodElem = methodName.staticElement;
-        if (methodElem is MethodElement) {
-          return _isFunctionalParameter(
-              methodElem.parameters, argIndex, containingNode);
-        } else if (methodElem is FunctionElement) {
-          return _isFunctionalParameter(
-              methodElem.parameters, argIndex, containingNode);
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the target maybe a functional argument in an argument list.
-   * This is used in determining whether the target [AstNode] hierarchy
-   * needs to be resolved so that [isFunctionalArgument] will work.
-   */
-  bool maybeFunctionalArgument() {
-    if (argIndex != null) {
-      if (containingNode is ArgumentList) {
-        return true;
-      }
-      if (containingNode is NamedExpression) {
-        if (containingNode.parent is ArgumentList) {
-          return true;
-        }
-      }
-    }
-    return false;
+    return parameterElement?.type is FunctionType;
   }
 
   static int _computeArgIndex(AstNode containingNode, Object entity) {
@@ -501,6 +507,32 @@
   }
 
   /**
+   * Return the [ParameterElement] that corresponds to the given [argumentNode]
+   * at the given [argumentIndex].
+   */
+  static ParameterElement _getParameterElement(
+    List<ParameterElement> parameters,
+    AstNode argumentNode,
+    int argumentIndex,
+  ) {
+    if (argumentNode is NamedExpression) {
+      var name = argumentNode.name?.label?.name;
+      for (var parameter in parameters) {
+        if (parameter.name == name) {
+          return parameter;
+        }
+      }
+      return null;
+    }
+
+    if (argumentIndex < parameters.length) {
+      return parameters[argumentIndex];
+    }
+
+    return null;
+  }
+
+  /**
    * Determine whether [node] could possibly be the [entity] for a
    * [CompletionTarget] associated with the given [offset].
    */
@@ -554,27 +586,4 @@
       return false;
     }
   }
-
-  /**
-   * Return `true` if the parameter is a functional parameter.
-   */
-  static bool _isFunctionalParameter(List<ParameterElement> parameters,
-      int paramIndex, AstNode containingNode) {
-    DartType paramType;
-    if (paramIndex < parameters.length) {
-      ParameterElement param = parameters[paramIndex];
-      if (param.isNamed) {
-        if (containingNode is NamedExpression) {
-          String name = containingNode.name?.label?.name;
-          param = parameters.firstWhere(
-              (ParameterElement param) => param.isNamed && param.name == name,
-              orElse: () => null);
-          paramType = param?.type;
-        }
-      } else {
-        paramType = param.type;
-      }
-    }
-    return paramType is FunctionType || paramType is FunctionTypeAlias;
-  }
 }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index e005b30..bddc32d 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -816,7 +816,12 @@
       AstNode grandparent = node.parent.parent;
       if (grandparent is ConstructorReferenceNode) {
         ConstructorElement element =
-            (grandparent as ConstructorReferenceNode).staticElement;
+            // TODO(paulberry): remove the unnecessary cast when we are ready to
+            // depend on a version of the analyzer that includes
+            // https://dart-review.googlesource.com/c/sdk/+/89923
+            (grandparent // ignore: unnecessary_cast
+                    as ConstructorReferenceNode)
+                .staticElement;
         if (element != null) {
           List<ParameterElement> parameters = element.parameters;
           ParameterElement parameterElement = parameters.firstWhere((e) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index ba1ec8f..dca1c1a 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -48,6 +48,8 @@
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl);
 
+  void declaredTypeParameter(TypeParameter node) {}
+
   /**
    * Throw an exception indicating that [LocalDeclarationVisitor] should
    * stop visiting. This is caught in [visit] which then exits normally.
@@ -100,10 +102,15 @@
     node.declarations.forEach((Declaration declaration) {
       if (declaration is ClassDeclaration) {
         declaredClass(declaration);
+        _visitTypeParameters(declaration, declaration.typeParameters);
       } else if (declaration is EnumDeclaration) {
         declaredEnum(declaration);
       } else if (declaration is FunctionDeclaration) {
         declaredFunction(declaration);
+        _visitTypeParameters(
+          declaration,
+          declaration.functionExpression.typeParameters,
+        );
       } else if (declaration is TopLevelVariableDeclaration) {
         var varList = declaration.variables;
         if (varList != null) {
@@ -113,10 +120,17 @@
         }
       } else if (declaration is ClassTypeAlias) {
         declaredClassTypeAlias(declaration);
+        _visitTypeParameters(declaration, declaration.typeParameters);
       } else if (declaration is FunctionTypeAlias) {
         declaredFunctionTypeAlias(declaration);
+        _visitTypeParameters(declaration, declaration.typeParameters);
       } else if (declaration is GenericTypeAlias) {
         declaredGenericTypeAlias(declaration);
+        _visitTypeParameters(declaration, declaration.typeParameters);
+        _visitTypeParameters(
+          declaration.functionType,
+          declaration.functionType.typeParameters,
+        );
       }
     });
   }
@@ -224,6 +238,7 @@
         });
       } else if (member is MethodDeclaration) {
         declaredMethod(member);
+        _visitTypeParameters(member, member.typeParameters);
       }
     }
   }
@@ -271,6 +286,10 @@
               String name = id.name;
               if (name != null && name.length > 0) {
                 declaredFunction(declaration);
+                _visitTypeParameters(
+                  declaration,
+                  declaration.functionExpression.typeParameters,
+                );
               }
             }
           }
@@ -278,6 +297,16 @@
       }
     }
   }
+
+  void _visitTypeParameters(AstNode node, TypeParameterList typeParameters) {
+    if (typeParameters == null) return;
+
+    if (node.offset < offset && offset < node.end) {
+      for (var typeParameter in typeParameters.typeParameters) {
+        declaredTypeParameter(typeParameter);
+      }
+    }
+  }
 }
 
 /**
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 7e02aea..4dca383 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -102,10 +102,17 @@
   final String message;
 
   /**
-   * Initialize a newly created kind of assist to have the given [id],
-   * [priority] and [message].
+   * A list of any associated error codes. Assists with associated error codes
+   * can be presented as "fixes" for the associated errors by clients.
    */
-  const AssistKind(this.id, this.priority, this.message);
+  final List<String> associatedErrorCodes;
+
+  /**
+   * Initialize a newly created kind of assist to have the given [id],
+   * [priority], [message] and optionally any [associatedErrorCodes].
+   */
+  const AssistKind(this.id, this.priority, this.message,
+      {this.associatedErrorCodes});
 
   @override
   String toString() => id;
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 25932c0..50e2721 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -4,6 +4,7 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -12,6 +13,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:meta/meta.dart';
 
 /**
  * The optional generator for prefix that should be used for new imports.
@@ -214,7 +216,7 @@
   void writeOverride(
     FunctionType signature, {
     StringBuffer displayTextBuffer,
-    bool invokeSuper: true,
+    bool invokeSuper: false,
   });
 
   /**
@@ -354,6 +356,34 @@
   String importLibrary(Uri uri);
 
   /**
+   * Ensure that the [requestedLibrary] is imported into the [targetLibrary],
+   * and the top-level [requestedName] is accessible at the [targetOffset] of
+   * the file with the [targetPath].
+   *
+   * Parameters [targetPath] and [targetOffset] are used to determine if the
+   * unprefixed reference to the [requestedName] will be shadowed by a local
+   * declaration in the target syntactic scope.
+   *
+   * If there is already an import for the [requestedLibrary], and the
+   * [requestedName] refers to the same element in the namespace of the import
+   * directive, and the name of the element is not ambiguous in existing import
+   * directives, and the name does not conflict with existing declarations and
+   * references, return the import prefix of the existing import directive.
+   *
+   * If there is no existing import, or there is a conflict, a new import is
+   * added, possibly with an import prefix.
+   *
+   * This method can be used only alone, and only once.
+   */
+  ImportLibraryElementResult importLibraryElement({
+    @required ResolvedLibraryResult targetLibrary,
+    @required String targetPath,
+    @required int targetOffset,
+    @required LibraryElement requestedLibrary,
+    @required String requestedName,
+  });
+
+  /**
    * Optionally create an edit to replace the given [typeAnnotation] with the
    * type `Future` (with the given type annotation as the type argument). The
    * [typeProvider] is used to check the current type, because if it is already
@@ -375,3 +405,10 @@
    */
   void addSuperTypesAsSuggestions(DartType type);
 }
+
+/// Information about a library to import.
+abstract class ImportLibraryElementResult {
+  /// If the library is already imported with a prefix, or should be imported
+  /// with a prefix, the prefix name (without `.`).  Otherwise `null`.
+  String get prefix;
+}
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
index e306286..eca6b97 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
@@ -7,6 +7,14 @@
 // suggestions in Dart code.
 //
 
+/// The relevance boost for available declarations with the matching tag.
+const int DART_RELEVANCE_BOOST_AVAILABLE_DECLARATION = 10;
+
+/// The relevance boost for available enum constants with the matching tag.
+///
+/// It is so large to move enum constants to the very top.
+const int DART_RELEVANCE_BOOST_AVAILABLE_ENUM = 1100;
+
 const int DART_RELEVANCE_BOOST_SUBTYPE = 100;
 const int DART_RELEVANCE_BOOST_TYPE = 200;
 const int DART_RELEVANCE_COMMON_USAGE = 1200;
@@ -26,3 +34,4 @@
 const int DART_RELEVANCE_NAMED_PARAMETER = 1060;
 const int DART_RELEVANCE_NAMED_PARAMETER_REQUIRED = 1065;
 const int DART_RELEVANCE_PARAMETER = 1059;
+const int DART_RELEVANCE_TYPE_PARAMETER = 1058;
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index a174edc..c1c6502 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -1,6 +1,6 @@
 name: analyzer_plugin
 description: A framework for building plugins for the analysis server.
-version: 0.0.1-alpha.5
+version: 0.0.1-alpha.6
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_plugin
 
@@ -8,7 +8,7 @@
   sdk: '>=1.8.0 <3.0.0'
 
 dependencies:
-  analyzer: '^0.33.0'
+  analyzer: '^0.34.2'
   charcode: '^1.1.0'
   html: '^0.13.1'
   meta: ^1.0.2
@@ -16,5 +16,7 @@
   pub_semver: '^1.3.2'
 
 dev_dependencies:
+  analysis_tool:
+    path: ../analysis_tool
   test_reflective_loader: ^0.1.8
   test: ^1.0.0
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 1ed1d1d..a3be8b8 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -21,6 +21,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../support/abstract_context.dart';
+import 'dart/dart_change_builder_mixin.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -28,40 +29,14 @@
     defineReflectiveTests(DartEditBuilderImplTest);
     defineReflectiveTests(DartFileEditBuilderImplTest);
     defineReflectiveTests(DartLinkedEditBuilderImplTest);
+    defineReflectiveTests(ImportLibraryTest);
+    defineReflectiveTests(WriteOverrideTest);
   });
 }
 
-mixin BuilderTestMixin implements AbstractContextTest {
-  SourceEdit getEdit(DartChangeBuilder builder) {
-    SourceChange sourceChange = builder.sourceChange;
-    expect(sourceChange, isNotNull);
-    List<SourceFileEdit> fileEdits = sourceChange.edits;
-    expect(fileEdits, hasLength(1));
-    SourceFileEdit fileEdit = fileEdits[0];
-    expect(fileEdit, isNotNull);
-    List<SourceEdit> edits = fileEdit.edits;
-    expect(edits, hasLength(1));
-    return edits[0];
-  }
-
-  List<SourceEdit> getEdits(DartChangeBuilder builder) {
-    SourceChange sourceChange = builder.sourceChange;
-    expect(sourceChange, isNotNull);
-    List<SourceFileEdit> fileEdits = sourceChange.edits;
-    expect(fileEdits, hasLength(1));
-    SourceFileEdit fileEdit = fileEdits[0];
-    expect(fileEdit, isNotNull);
-    return fileEdit.edits;
-  }
-
-  /// Return a newly created Dart change builder.
-  DartChangeBuilderImpl newBuilder() =>
-      new DartChangeBuilder(session) as DartChangeBuilderImpl;
-}
-
 @reflectiveTest
 class DartChangeBuilderImplTest extends AbstractContextTest
-    with BuilderTestMixin {
+    with DartChangeBuilderMixin {
   test_createFileEditBuilder() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'library test;');
@@ -76,319 +51,7 @@
 
 @reflectiveTest
 class DartEditBuilderImplTest extends AbstractContextTest
-    with BuilderTestMixin {
-  test_importLibraries_DP() async {
-    await _assertImportLibrary('''
-import 'dart:aaa';
-import 'dart:ccc';
-
-import 'package:aaa/aaa.dart';
-import 'package:ccc/ccc.dart';
-''', ['dart:bbb', 'package:bbb/bbb.dart'], '''
-import 'dart:aaa';
-import 'dart:bbb';
-import 'dart:ccc';
-
-import 'package:aaa/aaa.dart';
-import 'package:bbb/bbb.dart';
-import 'package:ccc/ccc.dart';
-''');
-  }
-
-  test_importLibraries_PD() async {
-    await _assertImportLibrary('''
-import 'dart:aaa';
-import 'dart:ccc';
-
-import 'package:aaa/aaa.dart';
-import 'package:ccc/ccc.dart';
-''', ['package:bbb/bbb.dart', 'dart:bbb'], '''
-import 'dart:aaa';
-import 'dart:bbb';
-import 'dart:ccc';
-
-import 'package:aaa/aaa.dart';
-import 'package:bbb/bbb.dart';
-import 'package:ccc/ccc.dart';
-''');
-  }
-
-  test_importLibrary_afterLibraryDirective_dart() async {
-    await _assertImportLibrary('''
-library test;
-
-class A {}
-''', ['dart:async'], '''
-library test;
-
-import 'dart:async';
-
-
-class A {}
-''');
-  }
-
-  test_importLibrary_dart_beforeDart() async {
-    await _assertImportLibrary('''
-import 'dart:aaa';
-import 'dart:ccc';
-''', ['dart:bbb'], '''
-import 'dart:aaa';
-import 'dart:bbb';
-import 'dart:ccc';
-''');
-  }
-
-  test_importLibrary_dart_beforeDart_first() async {
-    await _assertImportLibrary('''
-import 'dart:bbb';
-''', ['dart:aaa'], '''
-import 'dart:aaa';
-import 'dart:bbb';
-''');
-  }
-
-  test_importLibrary_dart_beforePackage() async {
-    await _assertImportLibrary('''
-import 'package:foo/foo.dart';
-''', ['dart:async'], '''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-''');
-  }
-
-  test_importLibrary_noDirectives_docComment() async {
-    await _assertImportLibrary('''
-/// Documentation comment.
-/// Continues.
-void main() {}
-''', ['dart:async'], '''
-import 'dart:async';
-
-/// Documentation comment.
-/// Continues.
-void main() {}
-''');
-  }
-
-  test_importLibrary_noDirectives_hashBang() async {
-    await _assertImportLibrary('''
-#!/bin/dart
-
-void main() {}
-''', ['dart:async'], '''
-#!/bin/dart
-
-import 'dart:async';
-
-void main() {}
-''');
-  }
-
-  test_importLibrary_noDirectives_lineComment() async {
-    await _assertImportLibrary('''
-// Not documentation comment.
-// Continues.
-
-void main() {}
-''', ['dart:async'], '''
-// Not documentation comment.
-// Continues.
-
-import 'dart:async';
-
-void main() {}
-''');
-  }
-
-  test_importLibrary_package_afterDart() async {
-    await _assertImportLibrary('''
-import 'dart:async';
-''', ['package:aaa/aaa.dart'], '''
-import 'dart:async';
-
-import 'package:aaa/aaa.dart';
-''');
-  }
-
-  test_importLibrary_package_afterPackage() async {
-    await _assertImportLibrary('''
-import 'package:aaa/a1.dart';
-
-import 'foo.dart';
-''', ['package:aaa/a2.dart'], '''
-import 'package:aaa/a1.dart';
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_afterPackage_leadingComment() async {
-    await _assertImportLibrary('''
-// comment
-import 'package:aaa/a1.dart';
-
-import 'foo.dart';
-''', ['package:aaa/a2.dart'], '''
-// comment
-import 'package:aaa/a1.dart';
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_afterPackage_trailingComment() async {
-    await _assertImportLibrary('''
-import 'package:aaa/a1.dart'; // comment
-
-import 'foo.dart';
-''', ['package:aaa/a2.dart'], '''
-import 'package:aaa/a1.dart'; // comment
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_beforePackage() async {
-    await _assertImportLibrary('''
-import 'package:aaa/a1.dart';
-import 'package:aaa/a3.dart';
-
-import 'foo.dart';
-''', ['package:aaa/a2.dart'], '''
-import 'package:aaa/a1.dart';
-import 'package:aaa/a2.dart';
-import 'package:aaa/a3.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_beforePackage_first() async {
-    await _assertImportLibrary('''
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''', ['package:aaa/a1.dart'], '''
-import 'package:aaa/a1.dart';
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_beforePackage_leadingComments() async {
-    await _assertImportLibrary('''
-// comment a2
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''', ['package:aaa/a1.dart'], '''
-// comment a2
-import 'package:aaa/a1.dart';
-import 'package:aaa/a2.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_beforePackage_trailingComments() async {
-    await _assertImportLibrary('''
-import 'package:aaa/a2.dart'; // comment a2
-
-import 'foo.dart';
-''', ['package:aaa/a1.dart'], '''
-import 'package:aaa/a1.dart';
-import 'package:aaa/a2.dart'; // comment a2
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_package_beforeRelative() async {
-    await _assertImportLibrary('''
-import 'foo.dart';
-''', ['package:aaa/aaa.dart'], '''
-import 'package:aaa/aaa.dart';
-
-import 'foo.dart';
-''');
-  }
-
-  test_importLibrary_relative_afterDart() async {
-    await _assertImportLibrary('''
-import 'dart:async';
-''', ['aaa.dart'], '''
-import 'dart:async';
-
-import 'aaa.dart';
-''');
-  }
-
-  test_importLibrary_relative_afterPackage() async {
-    await _assertImportLibrary('''
-import 'package:foo/foo.dart';
-''', ['aaa.dart'], '''
-import 'package:foo/foo.dart';
-
-import 'aaa.dart';
-''');
-  }
-
-  test_importLibrary_relative_beforeRelative() async {
-    await _assertImportLibrary('''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-
-import 'aaa.dart';
-import 'ccc.dart';
-''', ['bbb.dart'], '''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-
-import 'aaa.dart';
-import 'bbb.dart';
-import 'ccc.dart';
-''');
-  }
-
-  test_importLibrary_relative_beforeRelative_first() async {
-    await _assertImportLibrary('''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-
-import 'bbb.dart';
-''', ['aaa.dart'], '''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-
-import 'aaa.dart';
-import 'bbb.dart';
-''');
-  }
-
-  test_importLibrary_relative_last() async {
-    await _assertImportLibrary('''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-''', ['aaa.dart'], '''
-import 'dart:async';
-
-import 'package:foo/foo.dart';
-
-import 'aaa.dart';
-''');
-  }
-
+    with DartChangeBuilderMixin {
   test_writeClassDeclaration_interfaces() async {
     String path = convertPath('/home/test/lib/test.dart');
     addSource(path, 'class A {}');
@@ -1182,464 +845,6 @@
     expect(edit.replacement, equalsIgnoringWhitespace('mixin M on A { }'));
   }
 
-  test_writeOverride_getter_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  int get zero;
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'zero',
-      expected: '''
-  @override
-  // TODO: implement zero
-  int get zero => null;
-''',
-      displayText: 'zero => …',
-      selection: new SourceRange(111, 4),
-    );
-  }
-
-  test_writeOverride_getter_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  int get zero => 0;
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'zero',
-      expected: '''
-  @override
-  // TODO: implement zero
-  int get zero => super.zero;
-''',
-      displayText: 'zero => …',
-      selection: new SourceRange(107, 10),
-    );
-  }
-
-  test_writeOverride_method_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  A add(A a);
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'add',
-      expected: '''
-  @override
-  A add(A a) {
-    // TODO: implement add
-    return null;
-  }
-''',
-      displayText: 'add(A a) { … }',
-      selection: new SourceRange(111, 12),
-    );
-  }
-
-  test_writeOverride_method_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  A add(A a) => null;
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'add',
-      expected: '''
-  @override
-  A add(A a) {
-    // TODO: implement add
-    return super.add(a);
-  }
-''',
-      displayText: 'add(A a) { … }',
-      selection: new SourceRange(110, 20),
-    );
-  }
-
-  test_writeOverride_method_functionTypeAlias_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-typedef int F(int left, int right);
-abstract class A {
-  void perform(F f);
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'perform',
-      expected: '''
-  @override
-  void perform(F f) {
-    // TODO: implement perform
-  }
-''',
-      displayText: 'perform(F f) { … }',
-    );
-  }
-
-  test_writeOverride_method_functionTypeAlias_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-typedef int F(int left, int right);
-class A {
-  void perform(F f) {}
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'perform',
-      expected: '''
-  @override
-  void perform(F f) {
-    // TODO: implement perform
-    super.perform(f);
-  }
-''',
-      displayText: 'perform(F f) { … }',
-      selection: new SourceRange(158, 17),
-    );
-  }
-
-  test_writeOverride_method_functionTypedParameter_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  forEach(int f(double p1, String p2));
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'forEach',
-      expected: '''
-  @override
-  forEach(int Function(double p1, String p2) f) {
-    // TODO: implement forEach
-    return null;
-  }
-''',
-      displayText: 'forEach(int Function(double p1, String p2) f) { … }',
-      selection: new SourceRange(176, 12),
-    );
-  }
-
-  test_writeOverride_method_functionTypedParameter_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  forEach(int f(double p1, String p2)) {}
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'forEach',
-      expected: '''
-  @override
-  forEach(int Function(double p1, String p2) f) {
-    // TODO: implement forEach
-    return super.forEach(f);
-  }
-''',
-      displayText: 'forEach(int Function(double p1, String p2) f) { … }',
-      selection: new SourceRange(169, 24),
-    );
-  }
-
-  test_writeOverride_method_generic_noBounds_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  List<T> get<T>(T key);
-}
-class B implements A {
-}
-''',
-      nameToOverride: 'get',
-      expected: '''
-  @override
-  List<T> get<T>(T key) {
-    // TODO: implement get
-    return null;
-  }
-''',
-      displayText: 'get<T>(T key) { … }',
-      selection: new SourceRange(136, 12),
-    );
-  }
-
-  test_writeOverride_method_generic_noBounds_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  List<T> get<T>(T key) {}
-}
-class B implements A {
-}
-''',
-      nameToOverride: 'get',
-      expected: '''
-  @override
-  List<T> get<T>(T key) {
-    // TODO: implement get
-    return super.get(key);
-  }
-''',
-      displayText: 'get<T>(T key) { … }',
-      selection: new SourceRange(129, 22),
-    );
-  }
-
-  test_writeOverride_method_generic_withBounds_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A<K1, V1> {
-  List<T> get<T extends V1>(K1 key);
-}
-class B<K2, V2> implements A<K2, V2> {
-}
-''',
-      nameToOverride: 'get',
-      expected: '''
-  @override
-  List<T> get<T extends V2>(K2 key) {
-    // TODO: implement get
-    return null;
-  }
-''',
-      displayText: 'get<T extends V2>(K2 key) { … }',
-      selection: new SourceRange(184, 12),
-    );
-  }
-
-  test_writeOverride_method_generic_withBounds_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A<K1, V1> {
-  List<T> get<T extends V1>(K1 key) {
-    return null;
-  }
-}
-class B<K2, V2> implements A<K2, V2> {
-}
-''',
-      nameToOverride: 'get',
-      expected: '''
-  @override
-  List<T> get<T extends V2>(K2 key) {
-    // TODO: implement get
-    return super.get(key);
-  }
-''',
-      displayText: 'get<T extends V2>(K2 key) { … }',
-      selection: new SourceRange(197, 22),
-    );
-  }
-
-  test_writeOverride_method_genericFunctionTypedParameter_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  int foo(T Function<T>() fn);
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'foo',
-      expected: '''
-  @override
-  int foo(T Function<T>() fn) {
-    // TODO: implement foo
-    return null;
- }
-''',
-      displayText: 'foo(T Function<T>() fn) { … }',
-      selection: new SourceRange(145, 12),
-    );
-  }
-
-  test_writeOverride_method_genericFunctionTypedParameter_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  int foo(T Function<T>() fn) => 0;
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'foo',
-      expected: '''
-  @override
-  int foo(T Function<T>() fn) {
-    // TODO: implement foo
-    return super.foo(fn);
- }
-''',
-      displayText: 'foo(T Function<T>() fn) { … }',
-      selection: new SourceRange(141, 21),
-    );
-  }
-
-  test_writeOverride_method_nullAsTypeArgument_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  List<Null> foo();
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'foo',
-      expected: '''
-  @override
-  List<Null> foo() {
-    // TODO: implement foo
-    return null;
- }
-''',
-      displayText: 'foo() { … }',
-      selection: new SourceRange(123, 12),
-    );
-  }
-
-  test_writeOverride_method_nullAsTypeArgument_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  List<Null> foo() => null
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'foo',
-      expected: '''
-  @override
-  List<Null> foo() {
-    // TODO: implement foo
-    return super.foo();
- }
-''',
-      displayText: 'foo() { … }',
-      selection: new SourceRange(121, 19),
-    );
-  }
-
-  test_writeOverride_method_returnVoid_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  void test();
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'test',
-      expected: '''
-  @override
-  void test() {
-    // TODO: implement test
-  }
-''',
-      displayText: 'test() { … }',
-      selection: new SourceRange(109, 0),
-    );
-  }
-
-  test_writeOverride_method_voidAsTypeArgument_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  List<void> foo();
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'foo',
-      expected: '''
-  @override
-  List<void> foo() {
-    // TODO: implement foo
-    return null;
-  }
-''',
-      displayText: 'foo() { … }',
-      selection: new SourceRange(123, 12),
-    );
-  }
-
-  test_writeOverride_method_voidAsTypeArgument_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  List<void> foo() => null;
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'foo',
-      expected: '''
-  @override
-  List<void> foo() {
-    // TODO: implement foo
-    return super.foo();
-  }
-''',
-      displayText: 'foo() { … }',
-      selection: new SourceRange(122, 19),
-    );
-  }
-
-  test_writeOverride_setter_abstract() async {
-    await _assertWriteOverride(
-      content: '''
-abstract class A {
-  set value(int value);
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'value=',
-      expected: '''
-  @override
-  void set value(int value) {
-    // TODO: implement value
-  }
-''',
-      displayText: 'value(int value) { … }',
-      selection: new SourceRange(133, 0),
-    );
-  }
-
-  test_writeOverride_setter_concrete() async {
-    await _assertWriteOverride(
-      content: '''
-class A {
-  set value(int value) {}
-}
-class B extends A {
-}
-''',
-      nameToOverride: 'value=',
-      expected: '''
-  @override
-  void set value(int value) {
-    // TODO: implement value
-    super.value = value;
-  }
-''',
-      displayText: 'value(int value) { … }',
-      selection: new SourceRange(131, 20),
-    );
-  }
-
   test_writeParameter() async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = 'class A {}';
@@ -2259,73 +1464,6 @@
     expect(edit.replacement, equalsIgnoringWhitespace('implements A, B'));
   }
 
-  Future<void> _assertImportLibrary(
-      String initialCode, List<String> newUris, String expectedCode) async {
-    String path = convertPath('/home/test/lib/test.dart');
-    addSource(path, initialCode);
-    DartChangeBuilderImpl builder = newBuilder();
-    await builder.addFileEdit(path, (DartFileEditBuilder builder) {
-      for (String newUri in newUris) {
-        builder.importLibrary(Uri.parse(newUri));
-      }
-    });
-
-    String resultCode = initialCode;
-    List<SourceEdit> edits = getEdits(builder);
-    for (SourceEdit edit in edits) {
-      resultCode = edit.apply(resultCode);
-    }
-    expect(resultCode, expectedCode);
-  }
-
-  /**
-   * Assuming that the [content] being edited defines a class named `A` whose
-   * member with the given [nameToOverride] to be overridden and has
-   * `class B extends A {...}` to which an inherited method is to be added,
-   * assert that the text of the overridden member matches the [expected] text
-   * (modulo white space). Assert that the generated display text matches the
-   * given [displayText]. If a [selection] is provided, assert that the
-   * generated selection range matches it.
-   */
-  _assertWriteOverride({
-    String content,
-    String nameToOverride,
-    String expected,
-    String displayText,
-    SourceRange selection,
-  }) async {
-    String path = convertPath('/home/test/lib/test.dart');
-    addSource(path, content);
-
-    TypeSystem typeSystem = await session.typeSystem;
-    var b = await _getClassElement(path, 'B');
-    var inherited = new InheritanceManager2(typeSystem).getInherited(
-      b.type,
-      new Name(null, nameToOverride),
-    );
-
-    StringBuffer displayBuffer =
-        displayText != null ? new StringBuffer() : null;
-
-    DartChangeBuilderImpl builder = newBuilder();
-    await builder.addFileEdit(path, (FileEditBuilder builder) {
-      builder.addInsertion(content.length - 2, (EditBuilder builder) {
-        ExecutableElement element = inherited.element as ExecutableElement;
-        (builder as DartEditBuilder).writeOverride(
-          inherited,
-          displayTextBuffer: displayBuffer,
-          invokeSuper: !element.isAbstract,
-        );
-      });
-    });
-    SourceEdit edit = getEdit(builder);
-    expect(edit.replacement, equalsIgnoringWhitespace(expected));
-    expect(displayBuffer?.toString(), displayText);
-    if (selection != null) {
-      expect(builder.selectionRange, selection);
-    }
-  }
-
   Future<void> _assertWriteType(String typeCode, {String declarations}) async {
     String path = convertPath('/home/test/lib/test.dart');
     String content = (declarations ?? '') + '$typeCode v;';
@@ -2362,7 +1500,7 @@
 
 @reflectiveTest
 class DartFileEditBuilderImplTest extends AbstractContextTest
-    with BuilderTestMixin {
+    with DartChangeBuilderMixin {
   TypeProvider get typeProvider {
     return new TestTypeProvider(null, driver);
   }
@@ -2462,3 +1600,1015 @@
         unorderedEquals(['Object', 'A', 'B', 'C']));
   }
 }
+
+@reflectiveTest
+class ImportLibraryTest extends AbstractContextTest
+    with DartChangeBuilderMixin {
+  test_afterLibraryDirective_dart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+library test;
+
+class A {}
+''',
+      uriList: ['dart:async'],
+      expectedCode: '''
+library test;
+
+import 'dart:async';
+
+
+class A {}
+''',
+    );
+  }
+
+  test_dart_beforeDart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:aaa';
+import 'dart:ccc';
+''',
+      uriList: ['dart:bbb'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:bbb';
+import 'dart:ccc';
+''',
+    );
+  }
+
+  test_dart_beforeDart_first() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:bbb';
+''',
+      uriList: ['dart:aaa'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:bbb';
+''',
+    );
+  }
+
+  test_dart_beforePackage() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:foo/foo.dart';
+''',
+      uriList: ['dart:async'],
+      expectedCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+''',
+    );
+  }
+
+  test_multiple_dart_then_package() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:aaa';
+import 'dart:ccc';
+
+import 'package:aaa/aaa.dart';
+import 'package:ccc/ccc.dart';
+''',
+      uriList: ['dart:bbb', 'package:bbb/bbb.dart'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:bbb';
+import 'dart:ccc';
+
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+import 'package:ccc/ccc.dart';
+''',
+    );
+  }
+
+  test_multiple_package_then_dart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:aaa';
+import 'dart:ccc';
+
+import 'package:aaa/aaa.dart';
+import 'package:ccc/ccc.dart';
+''',
+      uriList: ['package:bbb/bbb.dart', 'dart:bbb'],
+      expectedCode: '''
+import 'dart:aaa';
+import 'dart:bbb';
+import 'dart:ccc';
+
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+import 'package:ccc/ccc.dart';
+''',
+    );
+  }
+
+  test_noDirectives_docComment() async {
+    await _assertImportLibrary(
+      initialCode: '''
+/// Documentation comment.
+/// Continues.
+void main() {}
+''',
+      uriList: ['dart:async'],
+      expectedCode: '''
+import 'dart:async';
+
+/// Documentation comment.
+/// Continues.
+void main() {}
+''',
+    );
+  }
+
+  test_noDirectives_hashBang() async {
+    await _assertImportLibrary(
+      initialCode: '''
+#!/bin/dart
+
+void main() {}
+''',
+      uriList: ['dart:async'],
+      expectedCode: '''
+#!/bin/dart
+
+import 'dart:async';
+
+void main() {}
+''',
+    );
+  }
+
+  test_noDirectives_lineComment() async {
+    await _assertImportLibrary(
+      initialCode: '''
+// Not documentation comment.
+// Continues.
+
+void main() {}
+''',
+      uriList: ['dart:async'],
+      expectedCode: '''
+// Not documentation comment.
+// Continues.
+
+import 'dart:async';
+
+void main() {}
+''',
+    );
+  }
+
+  test_package_afterDart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:async';
+''',
+      uriList: ['package:aaa/aaa.dart'],
+      expectedCode: '''
+import 'dart:async';
+
+import 'package:aaa/aaa.dart';
+''',
+    );
+  }
+
+  test_package_afterPackage() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:aaa/a1.dart';
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a2.dart'],
+      expectedCode: '''
+import 'package:aaa/a1.dart';
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_afterPackage_leadingComment() async {
+    await _assertImportLibrary(
+      initialCode: '''
+// comment
+import 'package:aaa/a1.dart';
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a2.dart'],
+      expectedCode: '''
+// comment
+import 'package:aaa/a1.dart';
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_afterPackage_trailingComment() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:aaa/a1.dart'; // comment
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a2.dart'],
+      expectedCode: '''
+import 'package:aaa/a1.dart'; // comment
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_beforePackage() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:aaa/a1.dart';
+import 'package:aaa/a3.dart';
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a2.dart'],
+      expectedCode: '''
+import 'package:aaa/a1.dart';
+import 'package:aaa/a2.dart';
+import 'package:aaa/a3.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_beforePackage_first() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a1.dart'],
+      expectedCode: '''
+import 'package:aaa/a1.dart';
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_beforePackage_leadingComments() async {
+    await _assertImportLibrary(
+      initialCode: '''
+// comment a2
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a1.dart'],
+      expectedCode: '''
+// comment a2
+import 'package:aaa/a1.dart';
+import 'package:aaa/a2.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_beforePackage_trailingComments() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:aaa/a2.dart'; // comment a2
+
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/a1.dart'],
+      expectedCode: '''
+import 'package:aaa/a1.dart';
+import 'package:aaa/a2.dart'; // comment a2
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_package_beforeRelative() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'foo.dart';
+''',
+      uriList: ['package:aaa/aaa.dart'],
+      expectedCode: '''
+import 'package:aaa/aaa.dart';
+
+import 'foo.dart';
+''',
+    );
+  }
+
+  test_relative_afterDart() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:async';
+''',
+      uriList: ['aaa.dart'],
+      expectedCode: '''
+import 'dart:async';
+
+import 'aaa.dart';
+''',
+    );
+  }
+
+  test_relative_afterPackage() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'package:foo/foo.dart';
+''',
+      uriList: ['aaa.dart'],
+      expectedCode: '''
+import 'package:foo/foo.dart';
+
+import 'aaa.dart';
+''',
+    );
+  }
+
+  test_relative_beforeRelative() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+
+import 'aaa.dart';
+import 'ccc.dart';
+''',
+      uriList: ['bbb.dart'],
+      expectedCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+
+import 'aaa.dart';
+import 'bbb.dart';
+import 'ccc.dart';
+''',
+    );
+  }
+
+  test_relative_beforeRelative_first() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+
+import 'bbb.dart';
+''',
+      uriList: ['aaa.dart'],
+      expectedCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+
+import 'aaa.dart';
+import 'bbb.dart';
+''',
+    );
+  }
+
+  test_relative_last() async {
+    await _assertImportLibrary(
+      initialCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+''',
+      uriList: ['aaa.dart'],
+      expectedCode: '''
+import 'dart:async';
+
+import 'package:foo/foo.dart';
+
+import 'aaa.dart';
+''',
+    );
+  }
+
+  Future<void> _assertImportLibrary({
+    String initialCode,
+    List<String> uriList,
+    String expectedCode,
+  }) async {
+    String path = convertPath('/home/test/lib/test.dart');
+    addSource(path, initialCode);
+    DartChangeBuilderImpl builder = newBuilder();
+    await builder.addFileEdit(path, (DartFileEditBuilder builder) {
+      for (var i = 0; i < uriList.length; ++i) {
+        var uri = Uri.parse(uriList[i]);
+        builder.importLibrary(uri);
+      }
+    });
+
+    String resultCode = initialCode;
+    List<SourceEdit> edits = getEdits(builder);
+    for (SourceEdit edit in edits) {
+      resultCode = edit.apply(resultCode);
+    }
+    expect(resultCode, expectedCode);
+  }
+}
+
+@reflectiveTest
+class WriteOverrideTest extends AbstractContextTest
+    with DartChangeBuilderMixin {
+  test_getter_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  int get zero;
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'zero',
+      expected: '''
+  @override
+  // TODO: implement zero
+  int get zero => null;
+''',
+      displayText: 'zero => …',
+      selection: new SourceRange(111, 4),
+    );
+  }
+
+  test_getter_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  int get zero => 0;
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'zero',
+      invokeSuper: true,
+      expected: '''
+  @override
+  // TODO: implement zero
+  int get zero => super.zero;
+''',
+      displayText: 'zero => …',
+      selection: new SourceRange(107, 10),
+    );
+  }
+
+  test_method_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  A add(A a);
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'add',
+      expected: '''
+  @override
+  A add(A a) {
+    // TODO: implement add
+    return null;
+  }
+''',
+      displayText: 'add(A a) { … }',
+      selection: new SourceRange(111, 12),
+    );
+  }
+
+  test_method_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  A add(A a) => null;
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'add',
+      invokeSuper: true,
+      expected: '''
+  @override
+  A add(A a) {
+    // TODO: implement add
+    return super.add(a);
+  }
+''',
+      displayText: 'add(A a) { … }',
+      selection: new SourceRange(110, 20),
+    );
+  }
+
+  test_method_functionTypeAlias_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+typedef int F(int left, int right);
+abstract class A {
+  void perform(F f);
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'perform',
+      expected: '''
+  @override
+  void perform(F f) {
+    // TODO: implement perform
+  }
+''',
+      displayText: 'perform(F f) { … }',
+    );
+  }
+
+  test_method_functionTypeAlias_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+typedef int F(int left, int right);
+class A {
+  void perform(F f) {}
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'perform',
+      invokeSuper: true,
+      expected: '''
+  @override
+  void perform(F f) {
+    // TODO: implement perform
+    super.perform(f);
+  }
+''',
+      displayText: 'perform(F f) { … }',
+      selection: new SourceRange(158, 17),
+    );
+  }
+
+  test_method_functionTypedParameter_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  forEach(int f(double p1, String p2));
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'forEach',
+      expected: '''
+  @override
+  forEach(int Function(double p1, String p2) f) {
+    // TODO: implement forEach
+    return null;
+  }
+''',
+      displayText: 'forEach(int Function(double p1, String p2) f) { … }',
+      selection: new SourceRange(176, 12),
+    );
+  }
+
+  test_method_functionTypedParameter_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  forEach(int f(double p1, String p2)) {}
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'forEach',
+      invokeSuper: true,
+      expected: '''
+  @override
+  forEach(int Function(double p1, String p2) f) {
+    // TODO: implement forEach
+    return super.forEach(f);
+  }
+''',
+      displayText: 'forEach(int Function(double p1, String p2) f) { … }',
+      selection: new SourceRange(169, 24),
+    );
+  }
+
+  test_method_generic_noBounds_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  List<T> get<T>(T key);
+}
+class B implements A {
+}
+''',
+      nameToOverride: 'get',
+      expected: '''
+  @override
+  List<T> get<T>(T key) {
+    // TODO: implement get
+    return null;
+  }
+''',
+      displayText: 'get<T>(T key) { … }',
+      selection: new SourceRange(136, 12),
+    );
+  }
+
+  test_method_generic_noBounds_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  List<T> get<T>(T key) {}
+}
+class B implements A {
+}
+''',
+      nameToOverride: 'get',
+      invokeSuper: true,
+      expected: '''
+  @override
+  List<T> get<T>(T key) {
+    // TODO: implement get
+    return super.get(key);
+  }
+''',
+      displayText: 'get<T>(T key) { … }',
+      selection: new SourceRange(129, 22),
+    );
+  }
+
+  test_method_generic_withBounds_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A<K1, V1> {
+  List<T> get<T extends V1>(K1 key);
+}
+class B<K2, V2> implements A<K2, V2> {
+}
+''',
+      nameToOverride: 'get',
+      expected: '''
+  @override
+  List<T> get<T extends V2>(K2 key) {
+    // TODO: implement get
+    return null;
+  }
+''',
+      displayText: 'get<T extends V2>(K2 key) { … }',
+      selection: new SourceRange(184, 12),
+    );
+  }
+
+  test_method_generic_withBounds_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A<K1, V1> {
+  List<T> get<T extends V1>(K1 key) {
+    return null;
+  }
+}
+class B<K2, V2> implements A<K2, V2> {
+}
+''',
+      nameToOverride: 'get',
+      invokeSuper: true,
+      expected: '''
+  @override
+  List<T> get<T extends V2>(K2 key) {
+    // TODO: implement get
+    return super.get(key);
+  }
+''',
+      displayText: 'get<T extends V2>(K2 key) { … }',
+      selection: new SourceRange(197, 22),
+    );
+  }
+
+  test_method_genericFunctionTypedParameter_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  int foo(T Function<T>() fn);
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'foo',
+      expected: '''
+  @override
+  int foo(T Function<T>() fn) {
+    // TODO: implement foo
+    return null;
+ }
+''',
+      displayText: 'foo(T Function<T>() fn) { … }',
+      selection: new SourceRange(145, 12),
+    );
+  }
+
+  test_method_genericFunctionTypedParameter_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  int foo(T Function<T>() fn) => 0;
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'foo',
+      invokeSuper: true,
+      expected: '''
+  @override
+  int foo(T Function<T>() fn) {
+    // TODO: implement foo
+    return super.foo(fn);
+ }
+''',
+      displayText: 'foo(T Function<T>() fn) { … }',
+      selection: new SourceRange(141, 21),
+    );
+  }
+
+  test_method_nullAsTypeArgument_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  List<Null> foo();
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'foo',
+      expected: '''
+  @override
+  List<Null> foo() {
+    // TODO: implement foo
+    return null;
+ }
+''',
+      displayText: 'foo() { … }',
+      selection: new SourceRange(123, 12),
+    );
+  }
+
+  test_method_nullAsTypeArgument_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  List<Null> foo() => null
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'foo',
+      invokeSuper: true,
+      expected: '''
+  @override
+  List<Null> foo() {
+    // TODO: implement foo
+    return super.foo();
+ }
+''',
+      displayText: 'foo() { … }',
+      selection: new SourceRange(121, 19),
+    );
+  }
+
+  test_method_returnVoid_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  void test();
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'test',
+      expected: '''
+  @override
+  void test() {
+    // TODO: implement test
+  }
+''',
+      displayText: 'test() { … }',
+      selection: new SourceRange(109, 0),
+    );
+  }
+
+  test_method_voidAsTypeArgument_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  List<void> foo();
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'foo',
+      expected: '''
+  @override
+  List<void> foo() {
+    // TODO: implement foo
+    return null;
+  }
+''',
+      displayText: 'foo() { … }',
+      selection: new SourceRange(123, 12),
+    );
+  }
+
+  test_method_voidAsTypeArgument_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  List<void> foo() => null;
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'foo',
+      invokeSuper: true,
+      expected: '''
+  @override
+  List<void> foo() {
+    // TODO: implement foo
+    return super.foo();
+  }
+''',
+      displayText: 'foo() { … }',
+      selection: new SourceRange(122, 19),
+    );
+  }
+
+  test_mixin_method_of_interface() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  void foo(int a) {}
+}
+
+mixin M implements A {
+}
+''',
+      nameToOverride: 'foo',
+      targetMixinName: 'M',
+      expected: '''
+  @override
+  void foo(int a) {
+    // TODO: implement foo
+  }
+''',
+      displayText: 'foo(int a) { … }',
+      selection: new SourceRange(113, 0),
+    );
+  }
+
+  test_mixin_method_of_superclassConstraint() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  void foo(int a) {}
+}
+
+mixin M on A {
+}
+''',
+      nameToOverride: 'foo',
+      targetMixinName: 'M',
+      invokeSuper: true,
+      expected: '''
+  @override
+  void foo(int a) {
+    // TODO: implement foo
+    super.foo(a);
+  }
+''',
+      displayText: 'foo(int a) { … }',
+      selection: new SourceRange(110, 13),
+    );
+  }
+
+  test_setter_abstract() async {
+    await _assertWriteOverride(
+      content: '''
+abstract class A {
+  set value(int value);
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'value=',
+      expected: '''
+  @override
+  void set value(int value) {
+    // TODO: implement value
+  }
+''',
+      displayText: 'value(int value) { … }',
+      selection: new SourceRange(133, 0),
+    );
+  }
+
+  test_setter_concrete() async {
+    await _assertWriteOverride(
+      content: '''
+class A {
+  set value(int value) {}
+}
+class B extends A {
+}
+''',
+      nameToOverride: 'value=',
+      invokeSuper: true,
+      expected: '''
+  @override
+  void set value(int value) {
+    // TODO: implement value
+    super.value = value;
+  }
+''',
+      displayText: 'value(int value) { … }',
+      selection: new SourceRange(131, 20),
+    );
+  }
+
+  /**
+   * Assuming that the [content] being edited defines a class named `A` whose
+   * member with the given [nameToOverride] to be overridden and has
+   * `class B extends A {...}` to which an inherited method is to be added,
+   * assert that the text of the overridden member matches the [expected] text
+   * (modulo white space). Assert that the generated display text matches the
+   * given [displayText]. If a [selection] is provided, assert that the
+   * generated selection range matches it.
+   */
+  _assertWriteOverride({
+    String content,
+    String nameToOverride,
+    String expected,
+    String displayText,
+    SourceRange selection,
+    String targetClassName = 'B',
+    String targetMixinName,
+    bool invokeSuper = false,
+  }) async {
+    String path = convertPath('/home/test/lib/test.dart');
+    addSource(path, content);
+
+    ClassElement targetElement;
+    {
+      var unitResult = await driver.getUnitElement(path);
+      if (targetMixinName != null) {
+        targetElement = unitResult.element.mixins
+            .firstWhere((e) => e.name == targetMixinName);
+      } else {
+        targetElement = unitResult.element.types
+            .firstWhere((e) => e.name == targetClassName);
+      }
+    }
+
+    TypeSystem typeSystem = await session.typeSystem;
+    var inherited = new InheritanceManager2(typeSystem).getInherited(
+      targetElement.type,
+      new Name(null, nameToOverride),
+    );
+
+    StringBuffer displayBuffer =
+        displayText != null ? new StringBuffer() : null;
+
+    DartChangeBuilderImpl builder = newBuilder();
+    await builder.addFileEdit(path, (FileEditBuilder builder) {
+      builder.addInsertion(content.length - 2, (EditBuilder builder) {
+        (builder as DartEditBuilder).writeOverride(
+          inherited,
+          displayTextBuffer: displayBuffer,
+          invokeSuper: invokeSuper,
+        );
+      });
+    });
+    SourceEdit edit = getEdit(builder);
+    expect(edit.replacement, equalsIgnoringWhitespace(expected));
+    expect(displayBuffer?.toString(), displayText);
+    if (selection != null) {
+      expect(builder.selectionRange, selection);
+    }
+  }
+}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/dart_change_builder_mixin.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/dart_change_builder_mixin.dart
new file mode 100644
index 0000000..aea3ed8
--- /dev/null
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/dart_change_builder_mixin.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:test/test.dart';
+
+import '../../../../support/abstract_context.dart';
+
+mixin DartChangeBuilderMixin implements AbstractContextTest {
+  SourceEdit getEdit(DartChangeBuilder builder) {
+    List<SourceEdit> edits = getEdits(builder);
+    expect(edits, hasLength(1));
+    return edits[0];
+  }
+
+  List<SourceEdit> getEdits(DartChangeBuilder builder) {
+    SourceChange sourceChange = builder.sourceChange;
+    expect(sourceChange, isNotNull);
+
+    List<SourceFileEdit> fileEdits = sourceChange.edits;
+    expect(fileEdits, hasLength(1));
+
+    SourceFileEdit fileEdit = fileEdits[0];
+    expect(fileEdit, isNotNull);
+    return fileEdit.edits;
+  }
+
+  /// Return a newly created Dart change builder.
+  DartChangeBuilderImpl newBuilder() =>
+      new DartChangeBuilder(session) as DartChangeBuilderImpl;
+}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
new file mode 100644
index 0000000..7f5ea6f
--- /dev/null
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -0,0 +1,761 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../support/abstract_context.dart';
+import 'dart_change_builder_mixin.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ImportLibraryElementTest);
+    defineReflectiveTests(ImportLibraryElement_existingImport_Test);
+    defineReflectiveTests(ImportLibraryElement_newImport_withoutPrefix_Test);
+    defineReflectiveTests(ImportLibraryElement_newImport_withPrefix_Test);
+  });
+}
+
+@reflectiveTest
+class ImportLibraryElement_existingImport_Test extends _Base {
+  test_dartCore_implicit() async {
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'dart:math';
+''',
+      uriStr: 'dart:core',
+      name: 'String',
+    );
+  }
+
+  test_dartCore_withPrefix() async {
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'dart:core' as my_core;
+import 'dart:math';
+''',
+      uriStr: 'dart:core',
+      name: 'String',
+      expectedPrefix: 'my_core',
+    );
+  }
+
+  test_withoutPrefix() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+    );
+  }
+
+  test_withoutPrefix_exported() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/b.dart';
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'A',
+    );
+  }
+
+  test_withoutPrefix_referencedNames_sameElements() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+
+class B {}
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/b.dart';
+
+A a;
+B b;
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'B',
+    );
+  }
+
+  test_withoutPrefix_twoImports_sameElement() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'package:test/a.dart';
+''');
+
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'C',
+    );
+
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'C',
+    );
+  }
+
+  test_withPrefix() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart' as p;
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedPrefix: 'p',
+    );
+  }
+
+  test_withPrefix_twoImports_sameElement() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'package:test/a.dart';
+''');
+
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart' as p;
+import 'package:test/b.dart' as p;
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'C',
+      expectedPrefix: 'p',
+    );
+
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart' as p;
+import 'package:test/b.dart' as p;
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'C',
+      expectedPrefix: 'p',
+    );
+  }
+}
+
+@reflectiveTest
+class ImportLibraryElement_newImport_withoutPrefix_Test extends _Base {
+  test_exported() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+''');
+    await _assertImportLibraryElement(
+      initialCode: '',
+      uriStr: 'package:test/b.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/b.dart';
+''',
+    );
+  }
+
+  test_exported_differentUri() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+''',
+    );
+  }
+
+  test_noConflict_otherImport_hide() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+''');
+    newFile('/home/test/lib/b.dart', content: 'class B {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart' hide B;
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'B',
+      expectedCode: r'''
+import 'package:test/a.dart' hide B;
+import 'package:test/b.dart';
+''',
+    );
+  }
+
+  test_noConflict_otherImport_show() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+class B {}
+''');
+    newFile('/home/test/lib/b.dart', content: 'class B {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart' show A;
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'B',
+      expectedCode: r'''
+import 'package:test/a.dart' show A;
+import 'package:test/b.dart';
+''',
+    );
+  }
+
+  test_noShadow_syntacticScope_localVariable() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+var foo = 0;
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void f() {
+^
+}
+
+void g() {
+  var foo = 1;
+  foo;
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+void f() {
+
+}
+
+void g() {
+  var foo = 1;
+  foo;
+}
+''',
+    );
+  }
+
+  test_noShadow_syntacticScope_typeParameter() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class C<A> {
+  A f;
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+class C<A> {
+  A f;
+}
+''',
+    );
+  }
+
+  test_thisName_notShadowed_localVariable_otherFunction() async {
+    newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void f() {
+^
+}
+
+void g() {
+  var foo = '';
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+void f() {
+
+}
+
+void g() {
+  var foo = '';
+}
+''',
+    );
+  }
+
+  test_unrelated() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('/home/test/lib/b.dart', content: 'class B {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'B',
+      expectedCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+''',
+    );
+  }
+}
+
+@reflectiveTest
+class ImportLibraryElement_newImport_withPrefix_Test extends _Base {
+  test_existingImport_nameIsAmbiguous() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    newFile('/home/test/lib/b.dart', content: 'class C {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'C',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+import 'package:test/b.dart' as prefix0;
+''',
+    );
+  }
+
+  test_existingImport_nameIsAmbiguous_prefixed() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    newFile('/home/test/lib/b.dart', content: 'class C {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart' as p;
+import 'package:test/b.dart' as p;
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'C',
+      expectedCode: r'''
+import 'package:test/a.dart' as p;
+import 'package:test/b.dart' as p;
+import 'package:test/b.dart';
+''',
+    );
+  }
+
+  test_nameIsAmbiguous() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    newFile('/home/test/lib/b.dart', content: 'class C {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'C',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart' as prefix0;
+''',
+    );
+  }
+
+  test_shadow_otherName_imported() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    newFile('/home/test/lib/b.dart', content: r'''
+class A {}
+class B {}
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+
+A a;
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'B',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart';
+import 'package:test/b.dart' as prefix0;
+
+A a;
+''',
+    );
+  }
+
+  test_shadow_otherName_inherited() async {
+    newFile('/home/test/lib/b.dart', content: '''
+int foo = 0;
+int bar = 0;
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class A {
+  void bar() {}
+}
+
+class X extends A {
+  voif f() {
+    bar();
+  }
+}
+''',
+      uriStr: 'package:test/b.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/b.dart' as prefix0;
+
+class A {
+  void bar() {}
+}
+
+class X extends A {
+  voif f() {
+    bar();
+  }
+}
+''',
+    );
+  }
+
+  test_shadowed_class() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'package:test/a.dart';
+
+class C {}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'C',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart';
+import 'package:test/a.dart' as prefix0;
+
+class C {}
+''',
+    );
+  }
+
+  @failingTest
+  test_shadowed_class_inPart() async {
+    newFile('/home/test/lib/a.dart', content: 'class C {}');
+    newFile('/home/test/lib/p.dart', content: 'class C {}');
+    // TODO(scheglov) "import" must be before "part"
+    await _assertImportLibraryElement(
+      initialCode: r'''
+part 'p.dart';
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'C',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+part 'p.dart';
+''',
+    );
+  }
+
+  test_shadowed_formalParameter() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+var foo = 0;
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void f(int foo) {^}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+void f(int foo) {}
+''',
+    );
+  }
+
+  test_shadowed_function() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+var foo = 0;
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void foo() {^}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+void foo() {}
+''',
+    );
+  }
+
+  test_shadowed_function_local_after() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+var foo = 0;
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void f() {
+  void foo() {}
+^}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+void f() {
+  void foo() {}
+}
+''',
+    );
+  }
+
+  test_shadowed_function_local_before() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+var foo = 0;
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void f() {^
+  void foo() {}
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+void f() {
+  void foo() {}
+}
+''',
+    );
+  }
+
+  test_shadowed_importPrefix() async {
+    newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+import 'dart:math' as foo;
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'dart:math' as foo;
+
+import 'package:test/a.dart' as prefix0;
+''',
+    );
+  }
+
+  test_shadowed_localVariable_after() async {
+    newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+main() {
+  var foo = '';
+^}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+main() {
+  var foo = '';
+}
+''',
+    );
+  }
+
+  test_shadowed_localVariable_before() async {
+    newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+main() {^
+  var foo = '';
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+main() {
+  var foo = '';
+}
+''',
+    );
+  }
+
+  test_shadowed_method() async {
+    newFile('/home/test/lib/a.dart', content: 'int foo = 0;');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class A {
+  void foo() {}
+  
+  void bar() {^}
+}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'foo',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+class A {
+  void foo() {}
+  
+  void bar() {}
+}
+''',
+    );
+  }
+
+  test_shadowed_typeParameter_class() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class C<A> {^}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+class C<A> {}
+''',
+    );
+  }
+
+  test_shadowed_typeParameter_function() async {
+    newFile('/home/test/lib/a.dart', content: r'''
+class A {}
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+void f<A>() {^}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedPrefix: 'prefix0',
+      expectedCode: r'''
+import 'package:test/a.dart' as prefix0;
+
+void f<A>() {}
+''',
+    );
+  }
+}
+
+@reflectiveTest
+class ImportLibraryElementTest extends _Base {
+  test_thisLibrary() async {
+    await _assertImportLibraryElement(
+      initialCode: r'''
+class A {}
+''',
+      uriStr: 'package:test/test.dart',
+      name: 'A',
+    );
+  }
+}
+
+class _Base extends AbstractContextTest with DartChangeBuilderMixin {
+  void _assertEmptyChange(DartChangeBuilderImpl builder) {
+    var change = builder.sourceChange;
+    expect(change, isNotNull);
+    expect(change.edits, isEmpty);
+  }
+
+  Future<void> _assertImportLibraryElement(
+      {String initialCode,
+      String uriStr,
+      String name,
+      String expectedPrefix,
+      String expectedCode}) async {
+    var offset = initialCode.indexOf('^');
+    if (offset > 0) {
+      initialCode =
+          initialCode.substring(0, offset) + initialCode.substring(offset + 1);
+    } else {
+      offset = initialCode.length;
+    }
+
+    var path = convertPath('/home/test/lib/test.dart');
+    newFile(path, content: initialCode);
+
+    var resolvedLibrary = await session.getResolvedLibrary(path);
+    var requestedLibrary = await session.getLibraryByUri(uriStr);
+
+    var element = requestedLibrary.exportNamespace.get(name);
+    expect(element, isNotNull, reason: '`$name` in $uriStr');
+
+    var builder = newBuilder();
+    await builder.addFileEdit(path, (builder) {
+      var result = builder.importLibraryElement(
+        targetLibrary: resolvedLibrary,
+        targetPath: path,
+        targetOffset: offset,
+        requestedLibrary: requestedLibrary,
+        requestedName: name,
+      );
+      expect(result.prefix, expectedPrefix);
+    });
+
+    if (expectedCode != null) {
+      var edits = getEdits(builder);
+      var resultCode = SourceEdit.applySequence(initialCode, edits);
+      expect(resultCode, expectedCode);
+    } else {
+      _assertEmptyChange(builder);
+    }
+  }
+}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/syntactic_scope_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/syntactic_scope_test.dart
new file mode 100644
index 0000000..d4f04be
--- /dev/null
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/syntactic_scope_test.dart
@@ -0,0 +1,645 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/src/utilities/change_builder/dart/syntactic_scope.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../support/abstract_context.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NotSyntacticScopeReferencedNamesCollectorTest);
+    defineReflectiveTests(SyntacticScopeNamesCollectorTest);
+  });
+}
+
+@reflectiveTest
+class NotSyntacticScopeReferencedNamesCollectorTest
+    extends AbstractContextTest {
+  test_notSyntacticScopeNames() async {
+    var path = convertPath('/home/test/lib/test.dart');
+
+    newFile('/home/test/lib/a.dart', content: r'''
+var N1;
+''');
+
+    newFile(path, content: r'''
+import 'package:test/a.dart';
+
+class A {
+  var N2;
+  
+  void N3() {}
+  
+  get N4 => null;
+  
+  set N5(_) {}
+}
+
+var S1;
+
+class B<S2> extends A {
+  var S3;
+  
+  void S4() {}
+  
+  get S5 => null;
+  
+  set S6(_) {}
+  
+  void f<S7>(S8) {
+    var S9;
+    N1;
+    N1 = 0;
+    N2;
+    N3;
+    N4;
+    N5 = 0;
+    B;
+    S1;
+    S1 = 0;
+    S2;
+    S3;
+    S4;
+    S5;
+    S6 = 0;
+    S7;
+    S8;
+    S9;
+  }
+}
+''');
+
+    var resolvedUnit = await session.getResolvedUnit(path);
+    var collector = NotSyntacticScopeReferencedNamesCollector(
+      resolvedUnit.libraryElement,
+      (<String>[]
+            ..addAll(List.generate(20, (i) => 'N$i'))
+            ..addAll(List.generate(20, (i) => 'S$i')))
+          .toSet(),
+    );
+    resolvedUnit.unit.accept(collector);
+
+    expect(
+      collector.importedNames,
+      containsPair('N1', Uri.parse('package:test/a.dart')),
+    );
+
+    expect(
+      collector.inheritedNames,
+      unorderedEquals(['N2', 'N3', 'N4', 'N5']),
+    );
+  }
+
+  test_referencedNames() async {
+    var path = convertPath('/home/test/lib/test.dart');
+    newFile(path, content: r'''
+class N1 {}
+
+N2 N3<N4>(N5 N6, N7) {
+  N7.N8(N9);
+}
+''');
+
+    var resolvedUnit = await session.getResolvedUnit(path);
+    var collector = NotSyntacticScopeReferencedNamesCollector(
+      resolvedUnit.libraryElement,
+      <String>[].toSet(),
+    );
+    resolvedUnit.unit.accept(collector);
+
+    expect(
+      collector.referencedNames,
+      unorderedEquals(['N1', 'N2', 'N3', 'N4', 'N5', 'N6', 'N7', 'N8', 'N9']),
+    );
+  }
+}
+
+@reflectiveTest
+class SyntacticScopeNamesCollectorTest extends AbstractContextTest {
+  test_Block() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  N2 N3, N4;
+  ^2
+  {
+    ^3
+    var N5;
+    ^4
+  }
+  ^5
+  var N6;
+  ^6
+  {
+    ^7
+    var N7;
+    ^8
+  }
+  ^9
+}
+''', expected: r'''
+1: N3, N4, N6
+2: N3, N4, N6
+3: N3, N4, N5, N6
+4: N3, N4, N5, N6
+5: N3, N4, N6
+6: N3, N4, N6
+7: N3, N4, N6, N7
+8: N3, N4, N6, N7
+9: N3, N4, N6
+''');
+  }
+
+  test_CatchClause() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  try {
+    var N2;
+    ^2
+  } on N3 catch (N4, N5) {
+    ^3
+  } catch (N6) {
+    ^4
+  }
+  ^5
+}
+''', expected: r'''
+1: {}
+2: N2
+3: N4, N5
+4: N6
+5: {}
+''');
+  }
+
+  test_ClassDeclaration() {
+    _assertScopeNames(code: r'''
+class N1<N2 ^1> extends ^2 N3<N4 ^3> with ^4 N5, N6 implements ^5 N7, N8 {
+  ^6
+  N9 N10, N11;
+  
+  N1.N12() {}
+  
+  N13 N14<N15>() {}
+  
+  ^7
+}
+
+class N16<N17> {
+  ^8
+}
+''', expected: r'''
+1: N2
+2: N2
+3: N2
+4: N2
+5: N2
+6: N2, N10, N11, N14
+7: N2, N10, N11, N14
+8: N17
+''');
+  }
+
+  test_ClassTypeAlias() {
+    _assertScopeNames(code: r'''
+class N1<N2 ^1> = N3<N4 ^2> with N5<N6 ^3> implements N7;
+''', expected: r'''
+1: N2
+2: N2
+3: N2
+''');
+  }
+
+  test_CollectionForElement_ForEachPartsWithDeclaration() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  [
+    0 ^1,
+    for (var N2 in N3 ^2) {
+      ^3
+    },
+    ^4
+    for (var N4 in N5) {
+      ^5
+    },
+    ^6
+  ];
+  ^7
+}
+''', expected: r'''
+1: {}
+2: {}
+3: N2
+4: {}
+5: N4
+6: {}
+7: {}
+''');
+  }
+
+  test_CollectionForElement_ForPartsWithDeclarations() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  [
+    0 ^1,
+    for (var N2 = 0 ^2; ^3; ^4) {
+      ^5
+    },
+    ^6
+    for (var N3 = 0 ^7; ^8; ^9) {
+      ^10
+    },
+    ^11
+  ];
+  ^12
+}
+''', expected: r'''
+1: {}
+2: N2
+3: N2
+4: N2
+5: N2
+6: {}
+7: N3
+8: N3
+9: N3
+10: N3
+11: {}
+12: {}
+''');
+  }
+
+  test_ConstructorDeclaration() {
+    _assertScopeNames(code: r'''
+class N1<N2> extends N3 {
+  N1.N4(N5 ^1) {
+    ^2
+  }
+  ^3
+}
+''', expected: r'''
+1: N2, N5
+2: N2, N5
+3: N2
+''');
+  }
+
+  test_ForEachStatement_identifier() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N2 in N3 ^2) {
+    ^3
+  }
+  ^4
+}
+''', expected: r'''
+1: {}
+2: {}
+3: {}
+4: {}
+''');
+  }
+
+  test_ForEachStatement_iterable() {
+    _assertScopeNames(code: r'''
+N1() {
+  for (var N2 in (){ var N3; ^1 }()) {
+    ^2
+  }
+  ^3
+}
+''', expected: r'''
+1: N3
+2: N2
+3: {}
+''');
+  }
+
+  test_ForEachStatement_loopVariable() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (var N2 in N3 ^2) {
+    ^3
+  }
+  ^4
+}
+''', expected: r'''
+1: {}
+2: {}
+3: N2
+4: {}
+''');
+  }
+
+  test_FormalParameter_functionTyped() {
+    _assertScopeNames(code: r'''
+N1 N2(N3 N4(N5 N6 ^1, N7), N8 ^2) {
+  ^3
+}
+''', expected: r'''
+1: N4, N6, N7, N8
+2: N4, N8
+3: N4, N8
+''');
+  }
+
+  test_ForStatement2_ForEachPartsWithDeclaration() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (var N2 in N3 ^2) {
+    ^3
+  }
+  ^4
+}
+''', expected: r'''
+1: {}
+2: {}
+3: N2
+4: {}
+''');
+  }
+
+  test_ForStatement2_ForEachPartsWithIdentifier() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N2 in N3 ^2) {
+    ^3
+  }
+  ^4
+}
+''', expected: r'''
+1: {}
+2: {}
+3: {}
+4: {}
+''');
+  }
+
+  test_ForStatement2_ForPartsWithDeclarations_condition() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N1 N2; (){ var N3; ^2 }(); ^3) {
+    ^4
+  }
+  ^5
+}
+''', expected: r'''
+1: {}
+2: N2, N3
+3: N2
+4: N2
+5: {}
+''');
+  }
+
+  test_ForStatement2_ForPartsWithDeclarations_updaters() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N1 N2; ^2; (){ var N3; ^3 }()) {
+    ^4
+  }
+  ^5
+}
+''', expected: r'''
+1: {}
+2: N2
+3: N2, N3
+4: N2
+5: {}
+''');
+  }
+
+  test_ForStatement2_ForPartsWithDeclarations_variables() {
+    _enableExperiments();
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N2 N3, N4 ^2; N5 ^3; N6 ^4) {
+    ^5
+  }
+  ^6
+}
+''', expected: r'''
+1: {}
+2: N3, N4
+3: N3, N4
+4: N3, N4
+5: N3, N4
+6: {}
+''');
+  }
+
+  test_ForStatement_condition() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N1 N2; (){ var N3; ^2 }(); ^3) {
+    ^4
+  }
+  ^5
+}
+''', expected: r'''
+1: {}
+2: N2, N3
+3: N2
+4: N2
+5: {}
+''');
+  }
+
+  test_ForStatement_updaters() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N1 N2; ^2; (){ var N3; ^3 }()) {
+    ^4
+  }
+  ^5
+}
+''', expected: r'''
+1: {}
+2: N2
+3: N2, N3
+4: N2
+5: {}
+''');
+  }
+
+  test_ForStatement_variables() {
+    _assertScopeNames(code: r'''
+N1() {
+  ^1
+  for (N2 N3, N4 ^2; N5 ^3; N6 ^4) {
+    ^5
+  }
+  ^6
+}
+''', expected: r'''
+1: {}
+2: N3, N4
+3: N3, N4
+4: N3, N4
+5: N3, N4
+6: {}
+''');
+  }
+
+  test_FunctionDeclaration() {
+    _assertScopeNames(code: r'''
+N1 N2<N3 extends N4 ^1>(N5 N6 ^2, [N7 N8 = N9, N10]) {
+  ^3
+}
+''', expected: r'''
+1: N3
+2: N3, N6, N8, N10
+3: N3, N6, N8, N10
+''');
+  }
+
+  test_FunctionTypeAlias() {
+    _assertScopeNames(code: r'''
+typedef N1 N2<N3 ^1>(N3 N4, N5 ^2);
+''', expected: r'''
+1: N3
+2: N3, N4, N5
+''');
+  }
+
+  test_GenericFunctionType() {
+    _assertScopeNames(code: r'''
+N1 Function<N2 ^1>(N3, N4 N5 ^2) N6;
+''', expected: r'''
+1: N2
+2: N2, N5
+''');
+  }
+
+  test_GenericTypeAlias() {
+    _assertScopeNames(code: r'''
+typedef N1<N2 ^1> = Function<N3 ^2>(N4 N5, N6 ^3);
+''', expected: r'''
+1: N2
+2: N2, N3
+3: N2, N3, N5
+''');
+  }
+
+  test_MethodDeclaration() {
+    _assertScopeNames(code: r'''
+class N1<N2> {
+  N3 N4, N5;
+  
+  ^1
+  
+  N6 ^2 N7<N8 ^3>(N9 N10, N11 ^4) {
+    ^5
+  }
+}
+''', expected: r'''
+1: N2, N4, N5, N7
+2: N2, N4, N5, N7, N8
+3: N2, N4, N5, N7, N8
+4: N2, N4, N5, N7, N8, N10, N11
+5: N2, N4, N5, N7, N8, N10, N11
+''');
+  }
+
+  test_MixinDeclaration() {
+    _assertScopeNames(code: r'''
+mixin N1<N2> on N3, N4 ^1 implements N5 ^2 {
+  ^3
+  N6 N7, N8;
+  ^4
+  
+  N9(N10 ^5) {
+    ^6
+  }
+  
+  ^7
+}
+''', expected: r'''
+1: N2
+2: N2
+3: N2, N7, N8, N9
+4: N2, N7, N8, N9
+5: N2, N7, N8, N9, N10
+6: N2, N7, N8, N9, N10
+7: N2, N7, N8, N9
+''');
+  }
+
+  void _assertScopeNames({String code, String expected}) {
+    var matches = RegExp(r'\^\d{1,2}').allMatches(code).toList();
+
+    var matchOffsets = <String, int>{};
+    var delta = 0;
+    for (var match in matches) {
+      var newStart = match.start - delta;
+      var newEnd = match.end - delta;
+      matchOffsets[code.substring(newStart + 1, newEnd)] = newStart;
+      delta += match.end - match.start;
+      code = code.substring(0, newStart) + code.substring(newEnd);
+    }
+
+    var path = convertPath('/home/test/lib/a.dart');
+    newFile(path, content: code);
+
+    var parsedResult = session.getParsedUnit(path);
+    expect(parsedResult.errors, isEmpty);
+
+    var unit = parsedResult.unit;
+    var buffer = StringBuffer();
+    for (var offsetName in matchOffsets.keys) {
+      var offset = matchOffsets[offsetName];
+      var nameSet = Set<String>();
+
+      unit.accept(SyntacticScopeNamesCollector(nameSet, offset));
+
+      var nameList = nameSet.toList();
+      nameList.sort((a, b) {
+        expect(a.startsWith('N'), isTrue);
+        expect(b.startsWith('N'), isTrue);
+        return int.parse(a.substring(1)) - int.parse(b.substring(1));
+      });
+
+      buffer.write('$offsetName: ');
+      if (nameList.isEmpty) {
+        buffer.writeln('{}');
+      } else {
+        buffer.writeln(nameList.join(', '));
+      }
+    }
+
+    var actual = buffer.toString();
+    if (actual != expected) {
+      print(actual);
+    }
+    expect(actual, expected);
+  }
+
+  void _enableExperiments() {
+    createAnalysisOptionsFile(
+      experiments: [
+        EnableString.control_flow_collections,
+        EnableString.spread_collections,
+      ],
+    );
+  }
+}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.dart
new file mode 100644
index 0000000..9d53f53
--- /dev/null
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/test_all.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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'import_library_element_test.dart' as import_library_element;
+import 'syntactic_scope_test.dart' as syntactic_scope;
+
+/// Utility for manually running all tests.
+main() {
+  defineReflectiveSuite(() {
+    import_library_element.main();
+    syntactic_scope.main();
+  });
+}
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart
index 2c50f7e..2e5d995 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/test_all.dart
@@ -6,11 +6,13 @@
 
 import 'change_builder_core_test.dart' as change_builder_core_test;
 import 'change_builder_dart_test.dart' as change_builder_dart_test;
+import 'dart/test_all.dart' as dart_all;
 
 /// Utility for manually running all tests.
 main() {
   defineReflectiveSuite(() {
     change_builder_core_test.main();
     change_builder_dart_test.main();
+    dart_all.main();
   });
 }
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index 241ec1f..37958bb 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -4,10 +4,10 @@
 
 import 'dart:async';
 
-import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/parser.dart' as analyzer;
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -16,604 +16,976 @@
 
 main() {
   defineReflectiveSuite(() {
+    defineReflectiveTests(ArgumentListCompletionTargetTest);
     defineReflectiveTests(CompletionTargetTest);
   });
 }
 
 @reflectiveTest
-class CompletionTargetTest extends AbstractContextTest {
-  Source testSource;
-  int completionOffset;
-  CompletionTarget target;
+class ArgumentListCompletionTargetTest extends _Base {
+  test_Annotation_named() async {
+    await createTarget('''
+class Foo {
+  const Foo({int a, String b});
+}
 
-  bool get usingFastaParser => analyzer.Parser.useFasta;
-
-  Future<void> addTestSource(String content) async {
-    expect(completionOffset, isNull, reason: 'Call addTestSource exactly once');
-    completionOffset = content.indexOf('^');
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    content = content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1);
-    testSource = addSource('/test.dart', content);
-    ResolvedUnitResult result = await driver.getResult(testSource.fullName);
-    target = new CompletionTarget.forOffset(result.unit, completionOffset);
+@Foo(b: ^)
+main() {}
+''');
+    assertTarget(
+      '',
+      'b: ',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: ({a: int, b: String}) → Foo',
+      expectedParameter: 'b: String',
+    );
   }
 
-  Future<void> assertTarget(entityText, nodeText,
-      {int argIndex: null,
-      bool isFunctionalArgument: false,
-      String droppedToken}) async {
-    void assertCommon() {
-      expect(target.entity.toString(), entityText, reason: 'entity');
-      expect(target.containingNode.toString(), nodeText,
-          reason: 'containingNode');
-      expect(target.argIndex, argIndex, reason: 'argIndex');
-      expect(target.droppedToken?.toString(), droppedToken ?? isNull,
-          reason: 'droppedToken');
-    }
+  test_Annotation_positional() async {
+    await createTarget('''
+class Foo {
+  const Foo(int a);
+}
 
-    // Assert with parsed unit
-    assertCommon();
-    ResolvedUnitResult result = await driver.getResult(testSource.fullName);
-    target = new CompletionTarget.forOffset(result.unit, completionOffset);
-    // Assert more with resolved unit
-    assertCommon();
-    expect(target.isFunctionalArgument(), isFunctionalArgument);
+@Foo(^)
+main() {}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: (int) → Foo',
+      expectedParameter: 'a: int',
+    );
   }
 
-  test_ArgumentList_InstanceCreationExpression() async {
-    // ArgumentList  InstanceCreationExpression  Block
-    await addTestSource('main() {new Foo(^)}');
-    await assertTarget(')', '()', argIndex: 0);
+  test_InstanceCreationExpression_explicitNew_unresolved() async {
+    await createTarget('''
+main() {
+  new Foo(^)
+}
+''');
+    assertTarget(')', '()', argIndex: 0);
   }
 
-  test_ArgumentList_InstanceCreationExpression2() async {
-    // ArgumentList  InstanceCreationExpression  Block
-    await addTestSource('main() {new Foo(a,^)}');
-    await assertTarget(')', '(a)', argIndex: 1);
+  test_InstanceCreationExpression_generic_explicitTypeArgument() async {
+    await createTarget('''
+class Foo<T> {
+  Foo(T a, T b);
+}
+
+main() {
+  Foo<int>(^)
+}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: (int, int) → Foo<int>',
+      expectedParameter: 'a: int',
+    );
   }
 
-  test_ArgumentList_InstanceCreationExpression_functionArg2() async {
-    // ArgumentList  InstanceCreationExpression  Block
-    await addTestSource('main() {new B(^)} class B{B(f()){}}');
-    await assertTarget(')', '()', argIndex: 0, isFunctionalArgument: true);
+  test_InstanceCreationExpression_generic_inferredTypeArgument() async {
+    await createTarget('''
+class Foo<T> {
+  Foo(T a, T b);
+}
+
+main() {
+  Foo(false, ^)
+}
+''');
+    assertTarget(
+      ')',
+      '(false)',
+      argIndex: 1,
+      expectedExecutable: 'Foo.<init>: (bool, bool) → Foo<bool>',
+      expectedParameter: 'b: bool',
+    );
   }
 
-  test_ArgumentList_InstanceCreationExpression_functionArg3() async {
-    // ArgumentList  InstanceCreationExpression  Block
-    await addTestSource('main() {new B(1, f: ^)} class B{B(int i, {f()}){}}');
-    await assertTarget('', 'f: ', argIndex: 1, isFunctionalArgument: true);
+  test_InstanceCreationExpression_named() async {
+    await createTarget('''
+class Foo {
+  Foo({int a, String b, double c});
+}
+
+main() {
+  Foo(b: ^)
+}
+''');
+    assertTarget(
+      '',
+      'b: ',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: ({a: int, b: String, c: double}) → Foo',
+      expectedParameter: 'b: String',
+    );
   }
 
-  test_ArgumentList_MethodInvocation() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo(^)}');
-    await assertTarget(')', '()', argIndex: 0);
+  test_InstanceCreationExpression_named_unresolved() async {
+    await createTarget('''
+class Foo {
+  Foo({int a});
+}
+
+main() {
+  Foo(b: ^)
+}
+''');
+    assertTarget(
+      '',
+      'b: ',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: ({a: int}) → Foo',
+    );
   }
 
-  test_ArgumentList_MethodInvocation2() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo(^n)}');
-    await assertTarget('n', '(n)', argIndex: 0);
+  test_InstanceCreationExpression_namedConstructor() async {
+    await createTarget('''
+class Foo {
+  Foo.named(int a, String b, double c);
+}
+
+main() {
+  Foo.named(0, ^)
+}
+''');
+    assertTarget(
+      ')',
+      '(0)',
+      argIndex: 1,
+      expectedExecutable: 'Foo.named: (int, String, double) → Foo',
+      expectedParameter: 'b: String',
+    );
   }
 
-  test_ArgumentList_MethodInvocation3() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo(n^)}');
-    await assertTarget('n', '(n)', argIndex: 0);
+  test_InstanceCreationExpression_positional() async {
+    await createTarget('''
+class Foo {
+  Foo(int a);
+}
+
+main() {
+  Foo(^)
+}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: (int) → Foo',
+      expectedParameter: 'a: int',
+    );
   }
 
-  test_ArgumentList_MethodInvocation3a() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo((n)^)}');
-    await assertTarget(')', '((n))', argIndex: 0);
+  test_InstanceCreationExpression_positional_isFunctional() async {
+    await createTarget('''
+class Foo {
+  Foo(int Function(String) f);
+}
+
+main() {
+  Foo(^)
+}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: ((String) → int) → Foo',
+      expectedParameter: 'f: (String) → int',
+      isFunctionalArgument: true,
+    );
   }
 
-  test_ArgumentList_MethodInvocation4() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo(n,^)}');
-    await assertTarget(')', '(n)', argIndex: 1);
+  test_InstanceCreationExpression_positional_noParameter0() async {
+    await createTarget('''
+class Foo {}
+
+main() {
+  Foo(^)
+}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'Foo.<init>: () → Foo',
+    );
   }
 
-  test_ArgumentList_MethodInvocation_functionArg() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo(^)} foo(f()) {}');
-    await assertTarget(')', '()', argIndex: 0, isFunctionalArgument: true);
+  test_InstanceCreationExpression_positional_noParameter1() async {
+    await createTarget('''
+class Foo {}
+
+main() {
+  Foo(a, ^)
+}
+''');
+    assertTarget(
+      ')',
+      '(a)',
+      argIndex: 1,
+      expectedExecutable: 'Foo.<init>: () → Foo',
+    );
   }
 
-  test_ArgumentList_MethodInvocation_functionArg2() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {new B().boo(^)} class B{boo(f()){}}');
-    await assertTarget(')', '()', argIndex: 0, isFunctionalArgument: true);
+  test_MethodInvocation_named() async {
+    await createTarget('''
+int foo({int a, String b, double c}) {}
+
+main() {
+  foo(b: ^)
+}
+''');
+    assertTarget(
+      '',
+      'b: ',
+      argIndex: 0,
+      expectedExecutable: 'foo: ({a: int, b: String, c: double}) → int',
+      expectedParameter: 'b: String',
+    );
   }
 
-  test_ArgumentList_MethodInvocation_functionArg3() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {foo(f: ^)} foo({f()}) {}');
-    await assertTarget('', 'f: ', argIndex: 0, isFunctionalArgument: true);
+  test_MethodInvocation_named_isFunctional() async {
+    await createTarget('''
+int foo({int Function(String) f}) {}
+
+main() {
+  foo(f: ^)
+}
+''');
+    assertTarget(
+      '',
+      'f: ',
+      argIndex: 0,
+      expectedExecutable: 'foo: ({f: (String) → int}) → int',
+      expectedParameter: 'f: (String) → int',
+      isFunctionalArgument: true,
+    );
   }
 
-  test_ArgumentList_MethodInvocation_functionArg4() async {
-    // ArgumentList  MethodInvocation  Block
-    await addTestSource('main() {new B().boo(f: ^)} class B{boo({f()}){}}');
-    await assertTarget('', 'f: ', argIndex: 0, isFunctionalArgument: true);
+  test_MethodInvocation_named_unresolved() async {
+    await createTarget('''
+int foo({int a}) {}
+
+main() {
+  foo(b: ^)
+}
+''');
+    assertTarget(
+      '',
+      'b: ',
+      argIndex: 0,
+      expectedExecutable: 'foo: ({a: int}) → int',
+    );
   }
 
+  test_MethodInvocation_positional2() async {
+    await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+  foo(0, ^)
+}
+''');
+    assertTarget(
+      ')',
+      '(0)',
+      argIndex: 1,
+      expectedExecutable: 'foo: (int, String) → int',
+      expectedParameter: 'b: String',
+    );
+  }
+
+  test_MethodInvocation_positional_isFunctional() async {
+    await createTarget('''
+int foo(int Function(String) f) {}
+
+main() {
+  foo(^)
+}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'foo: ((String) → int) → int',
+      expectedParameter: 'f: (String) → int',
+      isFunctionalArgument: true,
+    );
+  }
+
+  test_MethodInvocation_positional_isFunctional2() async {
+    await createTarget('''
+class C {
+  int foo(int Function(String) f) {}
+}
+
+main(C c) {
+  c.foo(^)
+}
+''');
+    assertTarget(
+      ')',
+      '()',
+      argIndex: 0,
+      expectedExecutable: 'C.foo: ((String) → int) → int',
+      expectedParameter: 'f: (String) → int',
+      isFunctionalArgument: true,
+    );
+  }
+
+  test_MethodInvocation_positional_withPrefix() async {
+    await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+  foo(n^)
+}
+''');
+    assertTarget(
+      'n',
+      '(n)',
+      argIndex: 0,
+      expectedExecutable: 'foo: (int, String) → int',
+      expectedParameter: 'a: int',
+    );
+  }
+
+  test_MethodInvocation_positional_withPrefix2() async {
+    await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+  foo((n)^)
+}
+''');
+    assertTarget(
+      ')',
+      '((n))',
+      argIndex: 0,
+      expectedExecutable: 'foo: (int, String) → int',
+      expectedParameter: 'a: int',
+    );
+  }
+
+  test_MethodInvocation_positional_withSuffix() async {
+    await createTarget('''
+int foo(int a, String b) {}
+
+main() {
+  foo(^n)
+}
+''');
+    assertTarget(
+      'n',
+      '(n)',
+      argIndex: 0,
+      expectedExecutable: 'foo: (int, String) → int',
+      expectedParameter: 'a: int',
+    );
+  }
+
+  test_MethodInvocation_unresolved() async {
+    await createTarget('''
+main() {
+  foo(^)
+}
+''');
+    assertTarget(')', '()', argIndex: 0);
+  }
+
+  test_not_ListLiteral() async {
+    await createTarget('''
+main() {
+  print([^]);
+}
+''');
+    expect(target.argIndex, isNull);
+    expect(target.executableElement, isNull);
+    expect(target.parameterElement, isNull);
+  }
+}
+
+@reflectiveTest
+class CompletionTargetTest extends _Base {
   test_AsExpression_identifier() async {
     // SimpleIdentifier  TypeName  AsExpression
-    await addTestSource(
+    await createTarget(
         'class A {var b; X _c; foo() {var a; (a^ as String).foo();}');
-    await assertTarget('a as String', '(a as String)');
+    assertTarget('a as String', '(a as String)');
   }
 
   test_AsExpression_keyword() async {
     // SimpleIdentifier  TypeName  AsExpression
-    await addTestSource(
+    await createTarget(
         'class A {var b; X _c; foo() {var a; (a ^as String).foo();}');
-    await assertTarget('as', 'a as String');
+    assertTarget('as', 'a as String');
   }
 
   test_AsExpression_keyword2() async {
     // SimpleIdentifier  TypeName  AsExpression
-    await addTestSource(
+    await createTarget(
         'class A {var b; X _c; foo() {var a; (a a^s String).foo();}');
-    await assertTarget('as', 'a as String');
+    assertTarget('as', 'a as String');
   }
 
   test_AsExpression_keyword3() async {
     // SimpleIdentifier  TypeName  AsExpression
-    await addTestSource(
+    await createTarget(
         'class A {var b; X _c; foo() {var a; (a as^ String).foo();}');
-    await assertTarget('as', 'a as String');
+    assertTarget('as', 'a as String');
   }
 
   test_AsExpression_type() async {
     // SimpleIdentifier  TypeName  AsExpression
-    await addTestSource(
+    await createTarget(
         'class A {var b; X _c; foo() {var a; (a as ^String).foo();}');
-    await assertTarget('String', 'a as String');
+    assertTarget('String', 'a as String');
   }
 
   test_Block() async {
     // Block
-    await addTestSource('main() {^}');
-    await assertTarget('}', '{}');
+    await createTarget('main() {^}');
+    assertTarget('}', '{}');
   }
 
   test_Block_keyword() async {
-    await addTestSource(
+    await createTarget(
         'class C { static C get instance => null; } main() {C.in^}');
-    await assertTarget('in', 'C.in');
+    assertTarget('in', 'C.in');
   }
 
   test_Block_keyword2() async {
-    await addTestSource(
+    await createTarget(
         'class C { static C get instance => null; } main() {C.i^n}');
-    await assertTarget('in', 'C.in');
+    assertTarget('in', 'C.in');
   }
 
   test_FormalParameter_partialType() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
-    await addTestSource('foo(b.^ f) { }');
-    await assertTarget('f', 'b.f');
+    await createTarget('foo(b.^ f) { }');
+    assertTarget('f', 'b.f');
   }
 
   test_FormalParameter_partialType2() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
-    await addTestSource('foo(b.z^ f) { }');
-    await assertTarget('z', 'b.z');
+    await createTarget('foo(b.z^ f) { }');
+    assertTarget('z', 'b.z');
   }
 
   test_FormalParameter_partialType3() async {
     // SimpleIdentifier  PrefixedIdentifier  TypeName
-    await addTestSource('foo(b.^) { }');
-    await assertTarget('', 'b.');
+    await createTarget('foo(b.^) { }');
+    assertTarget('', 'b.');
   }
 
   test_FormalParameterList() async {
     // Token  FormalParameterList  FunctionExpression
-    await addTestSource('foo(^) { }');
-    await assertTarget(')', '()');
+    await createTarget('foo(^) { }');
+    assertTarget(')', '()');
   }
 
   test_FunctionDeclaration_inLineComment() async {
     // Comment  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       // normal comment ^
       zoo(z) { } String name;''');
-    await assertTarget('// normal comment ', 'zoo(z) {} String name;');
+    assertTarget('// normal comment ', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_inLineComment2() async {
     // Comment  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       // normal ^comment
       zoo(z) { } String name;''');
-    await assertTarget('// normal comment', 'zoo(z) {} String name;');
+    assertTarget('// normal comment', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_inLineComment3() async {
     // Comment  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       // normal comment ^
       // normal comment 2
       zoo(z) { } String name;''');
-    await assertTarget('// normal comment ', 'zoo(z) {} String name;');
+    assertTarget('// normal comment ', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_inLineComment4() async {
     // Comment  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       // normal comment
       // normal comment 2^
       zoo(z) { } String name;''');
-    await assertTarget('// normal comment 2', 'zoo(z) {} String name;');
+    assertTarget('// normal comment 2', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_inLineDocComment() async {
     // Comment  FunctionDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       /// some dartdoc ^
       zoo(z) { } String name;''');
-    await assertTarget('/// some dartdoc ', '');
+    assertTarget('/// some dartdoc ', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_inLineDocComment2() async {
     // Comment  FunctionDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       /// some ^dartdoc
       zoo(z) { } String name;''');
-    await assertTarget('/// some dartdoc', '');
+    assertTarget('/// some dartdoc', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_inStarComment() async {
     // Comment  CompilationUnit
-    await addTestSource('/* ^ */ zoo(z) {} String name;');
-    await assertTarget('/*  */', 'zoo(z) {} String name;');
+    await createTarget('/* ^ */ zoo(z) {} String name;');
+    assertTarget('/*  */', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_inStarComment2() async {
     // Comment  CompilationUnit
-    await addTestSource('/*  *^/ zoo(z) {} String name;');
-    await assertTarget('/*  */', 'zoo(z) {} String name;');
+    await createTarget('/*  *^/ zoo(z) {} String name;');
+    assertTarget('/*  */', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_inStarDocComment() async {
     // Comment  FunctionDeclaration  CompilationUnit
-    await addTestSource('/** ^ */ zoo(z) { } String name;');
-    await assertTarget('/**  */', '');
+    await createTarget('/** ^ */ zoo(z) { } String name;');
+    assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_inStarDocComment2() async {
     // Comment  FunctionDeclaration  CompilationUnit
-    await addTestSource('/**  *^/ zoo(z) { } String name;');
-    await assertTarget('/**  */', '');
+    await createTarget('/**  *^/ zoo(z) { } String name;');
+    assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_returnType() async {
     // CompilationUnit
-    await addTestSource('^ zoo(z) { } String name;');
-    await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+    await createTarget('^ zoo(z) { } String name;');
+    assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_returnType_afterLineComment() async {
     // FunctionDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       // normal comment
       ^ zoo(z) {} String name;''');
-    await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+    assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_returnType_afterLineComment2() async {
     // FunctionDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
-    await addTestSource('''
+    await createTarget('''
 // normal comment
 ^ zoo(z) {} String name;''');
-    await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+    assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_returnType_afterLineDocComment() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       /// some dartdoc
       ^ zoo(z) { } String name; ''');
-    await assertTarget('zoo', 'zoo(z) {}');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  FunctionDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
 /// some dartdoc
 ^ zoo(z) { } String name;''');
-    await assertTarget('zoo', 'zoo(z) {}');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_returnType_afterStarComment() async {
     // CompilationUnit
-    await addTestSource('/* */ ^ zoo(z) { } String name;');
-    await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+    await createTarget('/* */ ^ zoo(z) { } String name;');
+    assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_returnType_afterStarComment2() async {
     // CompilationUnit
-    await addTestSource('/* */^ zoo(z) { } String name;');
-    await assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
+    await createTarget('/* */^ zoo(z) { } String name;');
+    assertTarget('zoo(z) {}', 'zoo(z) {} String name;');
   }
 
   test_FunctionDeclaration_returnType_afterStarDocComment() async {
     // FunctionDeclaration  CompilationUnit
-    await addTestSource('/** */ ^ zoo(z) { } String name;');
-    await assertTarget('zoo', 'zoo(z) {}');
+    await createTarget('/** */ ^ zoo(z) { } String name;');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_FunctionDeclaration_returnType_afterStarDocComment2() async {
     // FunctionDeclaration  CompilationUnit
-    await addTestSource('/** */^ zoo(z) { } String name;');
-    await assertTarget('zoo', 'zoo(z) {}');
+    await createTarget('/** */^ zoo(z) { } String name;');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_IfStatement_droppedToken() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('main() { if (v i^) }');
+    await createTarget('main() { if (v i^) }');
     if (usingFastaParser) {
-      await assertTarget(')', 'if (v) ;', droppedToken: 'i');
+      assertTarget(')', 'if (v) ;', droppedToken: 'i');
     } else {
-      await assertTarget('i;', 'if (v) i;');
+      assertTarget('i;', 'if (v) i;');
     }
   }
 
   test_InstanceCreationExpression_identifier() async {
     // InstanceCreationExpression  ExpressionStatement  Block
-    await addTestSource('class C {foo(){var f; {var x;} new ^C();}}');
-    await assertTarget('C', 'new C()');
+    await createTarget('class C {foo(){var f; {var x;} new ^C();}}');
+    assertTarget('C', 'new C()');
   }
 
   test_InstanceCreationExpression_keyword() async {
     // InstanceCreationExpression  ExpressionStatement  Block
-    await addTestSource('class C {foo(){var f; {var x;} new^ }}');
-    await assertTarget('new ();', '{var f; {var x;} new ();}');
+    await createTarget('class C {foo(){var f; {var x;} new^ }}');
+    assertTarget('new ();', '{var f; {var x;} new ();}');
   }
 
   test_InstanceCreationExpression_keyword2() async {
     // InstanceCreationExpression  ExpressionStatement  Block
-    await addTestSource('class C {foo(){var f; {var x;} new^ C();}}');
-    await assertTarget('new C();', '{var f; {var x;} new C();}');
+    await createTarget('class C {foo(){var f; {var x;} new^ C();}}');
+    assertTarget('new C();', '{var f; {var x;} new C();}');
   }
 
   test_MapLiteralEntry() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    await addTestSource('foo = {^');
+    await createTarget('foo = {^');
     // fasta scanner inserts synthetic closing '}'
-    await assertTarget('}', '{}');
+    assertTarget('}', '{}');
   }
 
   test_MapLiteralEntry1() async {
     // MapLiteralEntry  MapLiteral  VariableDeclaration
-    await addTestSource('foo = {T^');
-    await assertTarget('T : ', '{T : }');
+    await createTarget('foo = {1: 2, T^');
+    assertTarget('T : ', '{1 : 2, T : }');
   }
 
   test_MapLiteralEntry2() async {
     // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    await addTestSource('foo = {7:T^};');
-    await assertTarget('T', '7 : T');
+    await createTarget('foo = {7:T^};');
+    assertTarget('T', '7 : T');
   }
 
   test_MethodDeclaration_inLineComment() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         // normal comment ^
         zoo(z) { } String name; }''');
-    await assertTarget(
-        '// normal comment ', 'class C2 {zoo(z) {} String name;}');
+    assertTarget('// normal comment ', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_inLineComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         // normal ^comment
         zoo(z) { } String name; }''');
-    await assertTarget(
-        '// normal comment', 'class C2 {zoo(z) {} String name;}');
+    assertTarget('// normal comment', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_inLineComment3() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         // normal comment ^
         // normal comment 2
         zoo(z) { } String name; }''');
-    await assertTarget(
-        '// normal comment ', 'class C2 {zoo(z) {} String name;}');
+    assertTarget('// normal comment ', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_inLineComment4() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         // normal comment
         // normal comment 2^
         zoo(z) { } String name; }''');
-    await assertTarget(
-        '// normal comment 2', 'class C2 {zoo(z) {} String name;}');
+    assertTarget('// normal comment 2', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_inLineDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         /// some dartdoc ^
         zoo(z) { } String name; }''');
-    await assertTarget('/// some dartdoc ', '');
+    assertTarget('/// some dartdoc ', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_MethodDeclaration_inLineDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         /// some ^dartdoc
         zoo(z) { } String name; }''');
-    await assertTarget('/// some dartdoc', '');
+    assertTarget('/// some dartdoc', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_MethodDeclaration_inStarComment() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/* ^ */ zoo(z) {} String name;}');
-    await assertTarget('/*  */', 'class C2 {zoo(z) {} String name;}');
+    await createTarget('class C2 {/* ^ */ zoo(z) {} String name;}');
+    assertTarget('/*  */', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_inStarComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/*  *^/ zoo(z) {} String name;}');
-    await assertTarget('/*  */', 'class C2 {zoo(z) {} String name;}');
+    await createTarget('class C2 {/*  *^/ zoo(z) {} String name;}');
+    assertTarget('/*  */', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_inStarDocComment() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
-    await assertTarget('/**  */', '');
+    await createTarget('class C2 {/** ^ */ zoo(z) { } String name; }');
+    assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_MethodDeclaration_inStarDocComment2() async {
     // Comment  MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/**  *^/ zoo(z) { } String name; }');
-    await assertTarget('/**  */', '');
+    await createTarget('class C2 {/**  *^/ zoo(z) { } String name; }');
+    assertTarget('/**  */', '');
     expect(target.containingNode is Comment, isTrue);
     expect(target.containingNode.parent.toSource(), 'zoo(z) {}');
   }
 
   test_MethodDeclaration_returnType() async {
     // ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {^ zoo(z) { } String name; }');
-    await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+    await createTarget('class C2 {^ zoo(z) { } String name; }');
+    assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_returnType_afterLineComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         // normal comment
         ^ zoo(z) {} String name;}''');
-    await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+    assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_returnType_afterLineComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
     // TOD(danrubel) left align all test source
-    await addTestSource('''
+    await createTarget('''
 class C2 {
   // normal comment
 ^ zoo(z) {} String name;}''');
-    await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+    assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_returnType_afterLineDocComment() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
       class C2 {
         /// some dartdoc
         ^ zoo(z) { } String name; }''');
-    await assertTarget('zoo', 'zoo(z) {}');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_MethodDeclaration_returnType_afterLineDocComment2() async {
     // SimpleIdentifier  MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('''
+    await createTarget('''
 class C2 {
   /// some dartdoc
 ^ zoo(z) { } String name; }''');
-    await assertTarget('zoo', 'zoo(z) {}');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_MethodDeclaration_returnType_afterStarComment() async {
     // ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/* */ ^ zoo(z) { } String name; }');
-    await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+    await createTarget('class C2 {/* */ ^ zoo(z) { } String name; }');
+    assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_returnType_afterStarComment2() async {
     // ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/* */^ zoo(z) { } String name; }');
-    await assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
+    await createTarget('class C2 {/* */^ zoo(z) { } String name; }');
+    assertTarget('zoo(z) {}', 'class C2 {zoo(z) {} String name;}');
   }
 
   test_MethodDeclaration_returnType_afterStarDocComment() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
-    await assertTarget('zoo', 'zoo(z) {}');
+    await createTarget('class C2 {/** */ ^ zoo(z) { } String name; }');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_MethodDeclaration_returnType_afterStarDocComment2() async {
     // MethodDeclaration  ClassDeclaration  CompilationUnit
-    await addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
-    await assertTarget('zoo', 'zoo(z) {}');
+    await createTarget('class C2 {/** */^ zoo(z) { } String name; }');
+    assertTarget('zoo', 'zoo(z) {}');
   }
 
   test_SwitchStatement_c() async {
     // Token('c') SwitchStatement
-    await addTestSource('main() { switch(x) {c^} }');
-    await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
+    await createTarget('main() { switch(x) {c^} }');
+    assertTarget('}', 'switch (x) {}', droppedToken: 'c');
   }
 
   test_SwitchStatement_c2() async {
     // Token('c') SwitchStatement
-    await addTestSource('main() { switch(x) { c^ } }');
-    await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
+    await createTarget('main() { switch(x) { c^ } }');
+    assertTarget('}', 'switch (x) {}', droppedToken: 'c');
   }
 
   test_SwitchStatement_empty() async {
     // SwitchStatement
-    await addTestSource('main() { switch(x) {^} }');
-    await assertTarget('}', 'switch (x) {}');
+    await createTarget('main() { switch(x) {^} }');
+    assertTarget('}', 'switch (x) {}');
   }
 
   test_SwitchStatement_empty2() async {
     // SwitchStatement
-    await addTestSource('main() { switch(x) { ^ } }');
-    await assertTarget('}', 'switch (x) {}');
+    await createTarget('main() { switch(x) { ^ } }');
+    assertTarget('}', 'switch (x) {}');
   }
 
   test_TypeArgumentList() async {
     // TypeName  TypeArgumentList  TypeName
-    await addTestSource('main() { C<^> c; }');
-    await assertTarget('', '<>');
+    await createTarget('main() { C<^> c; }');
+    assertTarget('', '<>');
   }
 
   test_TypeArgumentList2() async {
     // TypeName  TypeArgumentList  TypeName
-    await addTestSource('main() { C<C^> c; }');
-    await assertTarget('C', '<C>');
+    await createTarget('main() { C<C^> c; }');
+    assertTarget('C', '<C>');
   }
 
   test_VariableDeclaration_lhs_identifier_after() async {
     // VariableDeclaration  VariableDeclarationList
-    await addTestSource('main() {int b^ = 1;}');
-    await assertTarget('b = 1', 'int b = 1');
+    await createTarget('main() {int b^ = 1;}');
+    assertTarget('b = 1', 'int b = 1');
   }
 
   test_VariableDeclaration_lhs_identifier_before() async {
     // VariableDeclaration  VariableDeclarationList
-    await addTestSource('main() {int ^b = 1;}');
-    await assertTarget('b = 1', 'int b = 1');
+    await createTarget('main() {int ^b = 1;}');
+    assertTarget('b = 1', 'int b = 1');
+  }
+}
+
+class _Base extends AbstractContextTest {
+  int offset;
+  CompletionTarget target;
+  FindElement findElement;
+
+  bool get usingFastaParser => analyzer.Parser.useFasta;
+
+  void assertTarget(
+    String entityText,
+    String nodeText, {
+    int argIndex: null,
+    String droppedToken,
+    bool isFunctionalArgument: false,
+    String expectedExecutable,
+    String expectedParameter,
+  }) {
+    expect(
+      target.entity.toString(),
+      entityText,
+      reason: 'entity',
+    );
+
+    expect(
+      target.containingNode.toString(),
+      nodeText,
+      reason: 'containingNode',
+    );
+
+    expect(
+      target.argIndex,
+      argIndex,
+      reason: 'argIndex',
+    );
+
+    expect(
+      target.droppedToken?.toString(),
+      droppedToken ?? isNull,
+      reason: 'droppedToken',
+    );
+
+    var actualExecutable = target.executableElement;
+    if (expectedExecutable == null) {
+      expect(actualExecutable, isNull);
+    } else {
+      expect(_executableStr(actualExecutable), expectedExecutable);
+    }
+
+    var actualParameter = target.parameterElement;
+    if (expectedParameter == null) {
+      expect(actualParameter, isNull);
+    } else {
+      expect(_parameterStr(actualParameter), expectedParameter);
+    }
+
+    expect(target.isFunctionalArgument(), isFunctionalArgument);
+  }
+
+  Future<void> createTarget(String content) async {
+    expect(offset, isNull, reason: 'Call createTarget exactly once');
+
+    offset = content.indexOf('^');
+    expect(offset, isNot(equals(-1)), reason: 'missing ^');
+
+    int nextOffset = content.indexOf('^', offset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+
+    content = content.substring(0, offset) + content.substring(offset + 1);
+
+    var path = convertPath('/home/test/lib/test.dart');
+    newFile(path, content: content);
+
+    var result = await driver.getResult(path);
+    findElement = FindElement(result.unit);
+
+    target = new CompletionTarget.forOffset(result.unit, offset);
+  }
+
+  static String _executableNameStr(ExecutableElement executable) {
+    var executableEnclosing = executable.enclosingElement;
+    if (executableEnclosing is CompilationUnitElement) {
+      return executable.name;
+    } else if (executable is ConstructorElement) {
+      if (executable.name == '') {
+        return '${executableEnclosing.name}.<init>';
+      } else {
+        return '${executableEnclosing.name}.${executable.name}';
+      }
+    } else if (executable is MethodElement) {
+      return '${executableEnclosing.name}.${executable.name}';
+    }
+    fail('Unexpected element: $executable');
+  }
+
+  static String _executableStr(ExecutableElement element) {
+    var executableStr = _executableNameStr(element);
+
+    return '$executableStr: ${element.type}';
+  }
+
+  static String _parameterStr(ParameterElement element) {
+    return '${element.name}: ${element.type}';
   }
 }
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index f06e837..10d21a7 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -44,6 +44,10 @@
 class AbstractContextTest with ResourceProviderMixin {
   AnalysisDriver _driver;
 
+  /// The file system specific `/home/test/analysis_options.yaml` path.
+  String get analysisOptionsPath =>
+      convertPath('/home/test/analysis_options.yaml');
+
   AnalysisDriver get driver => _driver;
 
   AnalysisSession get session => driver.currentSession;
@@ -81,6 +85,25 @@
     return source;
   }
 
+  /// Create an analysis options file based on the given arguments.
+  void createAnalysisOptionsFile({List<String> experiments}) {
+    var buffer = new StringBuffer();
+    buffer.writeln('analyzer:');
+
+    if (experiments != null) {
+      buffer.writeln('  enable-experiment:');
+      for (var experiment in experiments) {
+        buffer.writeln('    - $experiment');
+      }
+    }
+
+    newFile(analysisOptionsPath, content: buffer.toString());
+
+    if (_driver != null) {
+      _createDriver();
+    }
+  }
+
   Element findElementInUnit(CompilationUnit unit, String name,
       [ElementKind kind]) {
     return findElementsByName(unit, name)
diff --git a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
index 0b14065..923d7b0 100644
--- a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/ast/element_locator.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
diff --git a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
index 5611381..08ba2a4 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
@@ -126,7 +126,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -152,7 +151,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -179,7 +177,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -208,7 +205,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -235,7 +231,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -261,7 +256,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -288,7 +282,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('bar');
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
@@ -315,7 +308,6 @@
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
     assertNotSuggested('hasLength');
     assertNotSuggested('identical');
     assertNotSuggested('B');
diff --git a/pkg/analyzer_plugin/tool/spec/check_all_test.dart b/pkg/analyzer_plugin/tool/spec/check_all_test.dart
index 33f1cca..82806db 100644
--- a/pkg/analyzer_plugin/tool/spec/check_all_test.dart
+++ b/pkg/analyzer_plugin/tool/spec/check_all_test.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart';
 
 import 'generate_all.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
index 0669bef..f4e92dd 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_dart_protocol.dart
@@ -4,7 +4,7 @@
 
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:path/path.dart' as path;
 
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
index 8fec4fa..924e5c3 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_inttest_methods.dart
@@ -7,7 +7,7 @@
  */
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart' as path;
 
 import 'api.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
index 226c707..bd6c7e1 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_matchers.dart
@@ -7,7 +7,7 @@
  */
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 import 'from_html.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart
index 4f81c83..0798d31 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_common.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart' as path;
 
 import 'api.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
index 755f586..7ff2570 100644
--- a/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
+++ b/pkg/analyzer_plugin/tool/spec/codegen_protocol_constants.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 import 'codegen_dart.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/from_html.dart b/pkg/analyzer_plugin/tool/spec/from_html.dart
index 34f8a62..fe9cf69 100644
--- a/pkg/analyzer_plugin/tool/spec/from_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/from_html.dart
@@ -7,7 +7,7 @@
  */
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/html.dart';
+import 'package:analysis_tool/html.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:html/parser.dart' as parser;
 import 'package:path/path.dart';
diff --git a/pkg/analyzer_plugin/tool/spec/generate_all.dart b/pkg/analyzer_plugin/tool/spec/generate_all.dart
index f60d83a..f959c85 100644
--- a/pkg/analyzer_plugin/tool/spec/generate_all.dart
+++ b/pkg/analyzer_plugin/tool/spec/generate_all.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:path/path.dart';
 
 import 'codegen_dart_protocol.dart' as codegen_dart_protocol;
diff --git a/pkg/analyzer_plugin/tool/spec/implied_types.dart b/pkg/analyzer_plugin/tool/spec/implied_types.dart
index 856b2a4..2cf1c8b 100644
--- a/pkg/analyzer_plugin/tool/spec/implied_types.dart
+++ b/pkg/analyzer_plugin/tool/spec/implied_types.dart
@@ -5,7 +5,7 @@
 /**
  * Code for enumerating the set of types implied by the API.
  */
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/tools.dart';
 
 import 'api.dart';
 
diff --git a/pkg/analyzer_plugin/tool/spec/to_html.dart b/pkg/analyzer_plugin/tool/spec/to_html.dart
index 0956e6f..5a519e0 100644
--- a/pkg/analyzer_plugin/tool/spec/to_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/to_html.dart
@@ -9,8 +9,8 @@
  */
 import 'dart:convert';
 
-import 'package:analyzer/src/codegen/html.dart';
-import 'package:analyzer/src/codegen/tools.dart';
+import 'package:analysis_tool/html.dart';
+import 'package:analysis_tool/tools.dart';
 import 'package:html/dom.dart' as dom;
 
 import 'api.dart';
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 9913a66..124cfce 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -61,6 +61,9 @@
   /// The `Map` class defined in 'dart:core';
   ClassEntity get mapClass;
 
+  /// The `Set` class defined in 'dart:core';
+  ClassEntity get unmodifiableSetClass;
+
   /// The `Iterable` class defined in 'dart:core';
   ClassEntity get iterableClass;
 
@@ -653,6 +656,11 @@
   ClassEntity _mapClass;
   ClassEntity get mapClass => _mapClass ??= _findClass(coreLibrary, 'Map');
 
+  /// The `_UnmodifiableSet` class defined in 'dart:collection';
+  ClassEntity _unmodifiableSetClass;
+  ClassEntity get unmodifiableSetClass => _unmodifiableSetClass ??=
+      _findClass(_env.lookupLibrary(Uris.dart_collection), '_UnmodifiableSet');
+
   /// The `Iterable` class defined in 'dart:core';
   ClassEntity _iterableClass;
   ClassEntity get iterableClass =>
diff --git a/pkg/compiler/lib/src/constants/evaluation.dart b/pkg/compiler/lib/src/constants/evaluation.dart
index ff9355f..386a2ee 100644
--- a/pkg/compiler/lib/src/constants/evaluation.dart
+++ b/pkg/compiler/lib/src/constants/evaluation.dart
@@ -24,6 +24,12 @@
   /// Type in the enclosing constructed
   InterfaceType get enclosingConstructedType;
 
+  /// Whether the immediate parent is a set literal.
+  ///
+  /// Used to distinguish map-literal from set-literal errors. This will be
+  /// removed once the CFE reports errors on constants.
+  bool get immediateUnderSetLiteral;
+
   /// Read environments string passed in using the '-Dname=value' option.
   String readFromEnvironment(String name);
 
@@ -55,6 +61,8 @@
   ConstantValue evaluateConstructor(ConstructorEntity constructor,
       InterfaceType type, ConstantValue evaluate());
 
+  ConstantValue evaluateMapBody(ConstantValue evaluate());
+
   ConstantValue evaluateField(FieldEntity field, ConstantValue evaluate());
 
   /// `true` if assertions are enabled.
@@ -70,6 +78,7 @@
 abstract class EvaluationEnvironmentBase implements EvaluationEnvironment {
   Link<Spannable> _spannableStack = const Link<Spannable>();
   InterfaceType enclosingConstructedType;
+  bool immediateUnderSetLiteral = false;
   final Set<FieldEntity> _currentlyEvaluatedFields = new Set<FieldEntity>();
   final bool constantRequired;
 
@@ -117,13 +126,26 @@
     _spannableStack = _spannableStack.prepend(constructor);
     var old = enclosingConstructedType;
     enclosingConstructedType = type;
+    if (type.element == commonElements.unmodifiableSetClass) {
+      immediateUnderSetLiteral = true;
+    }
     ConstantValue result = evaluate();
+    // All const set literals have as an immediate child a const map. The map
+    // evaluate method calls evaluateMapBody and reset this flag immediately.
+    // Because there are no other children, the flag is kept false.
+    assert(!immediateUnderSetLiteral);
     enclosingConstructedType = old;
     _spannableStack = _spannableStack.tail;
     return result;
   }
 
   @override
+  ConstantValue evaluateMapBody(ConstantValue evaluate()) {
+    immediateUnderSetLiteral = false;
+    return evaluate();
+  }
+
+  @override
   void reportError(
       ConstantExpression expression, MessageKind kind, Map arguments) {
     if (constantRequired) {
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 60a18ca..82f640d 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -433,23 +433,32 @@
   @override
   ConstantValue evaluate(
       EvaluationEnvironment environment, ConstantSystem constantSystem) {
-    Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
-    for (int i = 0; i < keys.length; i++) {
-      ConstantValue key = keys[i].evaluate(environment, constantSystem);
-      if (!key.isConstant) {
-        return new NonConstantValue();
+    // TODO(sigmund): delete once the CFE provides these error messages.
+    bool isSetLiteral = environment.immediateUnderSetLiteral;
+    return environment.evaluateMapBody(() {
+      Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
+      for (int i = 0; i < keys.length; i++) {
+        ConstantValue key = keys[i].evaluate(environment, constantSystem);
+        if (!key.isConstant) {
+          return new NonConstantValue();
+        }
+        ConstantValue value = values[i].evaluate(environment, constantSystem);
+        if (!value.isConstant) {
+          return new NonConstantValue();
+        }
+        if (map.containsKey(key)) {
+          environment.reportError(
+              keys[i],
+              isSetLiteral
+                  ? MessageKind.EQUAL_SET_ENTRY
+                  : MessageKind.EQUAL_MAP_ENTRY_KEY,
+              {});
+        }
+        map[key] = value;
       }
-      ConstantValue value = values[i].evaluate(environment, constantSystem);
-      if (!value.isConstant) {
-        return new NonConstantValue();
-      }
-      if (map.containsKey(key)) {
-        environment.reportError(keys[i], MessageKind.EQUAL_MAP_ENTRY_KEY, {});
-      }
-      map[key] = value;
-    }
-    return constantSystem.createMap(environment.commonElements, type,
-        map.keys.toList(), map.values.toList());
+      return constantSystem.createMap(environment.commonElements, type,
+          map.keys.toList(), map.values.toList());
+    });
   }
 
   ConstantExpression apply(NormalizedArguments arguments) {
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index dbfe890..50b8aeb 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -658,7 +658,7 @@
   if (uri.scheme != 'file') {
     fail('Unhandled scheme ${uri.scheme}.');
   }
-  var file = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
+  var file = new File(uri.toFilePath()).openSync(mode: FileMode.write);
   file.writeStringSync(text);
   file.closeSync();
 }
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index ddbd195..a3532c9 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -37,6 +37,7 @@
   CYCLIC_COMPILE_TIME_CONSTANTS,
   DIRECTLY_THROWING_NSM,
   EQUAL_MAP_ENTRY_KEY,
+  EQUAL_SET_ENTRY,
   EXTRANEOUS_MODIFIER,
   EXTRANEOUS_MODIFIER_REPLACE,
   FORIN_NOT_ASSIGNABLE,
@@ -87,7 +88,6 @@
   LIBRARY_NOT_FOUND,
   MIRRORS_LIBRARY_NOT_SUPPORT_WITH_CFE,
   MISSING_EXPRESSION_IN_THROW,
-  MULTI_INHERITANCE,
   NO_SUCH_SUPER_MEMBER,
   NON_NATIVE_EXTERNAL,
   NOT_A_COMPILE_TIME_CONSTANT,
@@ -172,12 +172,6 @@
           MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS,
           "Cycle in the compile-time constant computation."),
 
-      MessageKind.MULTI_INHERITANCE: const MessageTemplate(
-          MessageKind.MULTI_INHERITANCE,
-          "Dart2js does not currently support inheritance of the same class "
-          "with different type arguments: Both #{firstType} and #{secondType} "
-          "are supertypes of #{thisType}."),
-
       MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER: const MessageTemplate(
           MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER,
           "Cannot resolve setter."),
@@ -440,6 +434,16 @@
 }"""
           ]),
 
+      MessageKind.EQUAL_SET_ENTRY: const MessageTemplate(
+          MessageKind.EQUAL_SET_ENTRY, "An entry appears twice in the set.",
+          howToFix: "Try removing one of the entries.",
+          examples: const [
+            """
+main() {
+  var m = const {'foo', 'bar', 'foo'};
+}"""
+          ]),
+
       MessageKind.COMPILER_CRASHED: const MessageTemplate(
           MessageKind.COMPILER_CRASHED,
           "The compiler crashed when compiling this element."),
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 0adff08..a3a5c4d 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -350,6 +350,24 @@
     return true;
   }
 
+  /// Short textual representation use for testing.
+  String get shortText {
+    StringBuffer sb = new StringBuffer();
+    if (typeParameters != 0) {
+      sb.write('<');
+      sb.write(typeParameters);
+      sb.write('>');
+    }
+    sb.write('(');
+    sb.write(positionalParameters);
+    if (namedParameters.length > 0) {
+      sb.write(',');
+      sb.write(namedParameters.join(','));
+    }
+    sb.write(')');
+    return sb.toString();
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('ParameterStructure(');
@@ -359,4 +377,7 @@
     sb.write('typeParameters=$typeParameters)');
     return sb.toString();
   }
+
+  int get size =>
+      positionalParameters + typeParameters + namedParameters.length;
 }
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 499f749..4defca5 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -76,6 +76,14 @@
 }
 
 abstract class Enqueuer {
+  /// If `true` the checking for unenqueued members is skipped. The current
+  /// implementation registers parameter usages as a side-effect so unit
+  /// testing of member usage we need to test both with and without the
+  /// enqueuer check.
+  // TODO(johnniwinther): [checkEnqueuerConsistency] should not have
+  // side-effects.
+  static bool skipEnqueuerCheckForTesting = false;
+
   WorldBuilder get worldBuilder;
 
   void open(ImpactStrategy impactStrategy, FunctionEntity mainMethod,
@@ -277,6 +285,7 @@
 
   bool checkNoEnqueuedInvokedInstanceMethods(
       ElementEnvironment elementEnvironment) {
+    if (Enqueuer.skipEnqueuerCheckForTesting) return true;
     return checkEnqueuerConsistency(elementEnvironment);
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index 784e018..6322222 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -7,6 +7,7 @@
 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
 import '../elements/entities.dart';
 import '../elements/names.dart';
+import '../elements/types.dart' show DartType;
 import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
@@ -43,6 +44,9 @@
   static AbstractBool trueOrFalse(bool value) => value ? True : False;
 
   static AbstractBool maybeOrFalse(bool value) => value ? Maybe : False;
+
+  String toString() =>
+      'AbstractBool.${_value == null ? 'Maybe' : (_value ? 'True' : 'False')}';
 }
 
 /// Strategy for the abstraction of runtime values used by the global type
@@ -477,6 +481,11 @@
   AbstractBool needsNoSuchMethodHandling(
       AbstractValue receiver, Selector selector);
 
+  /// Returns the [AbstractValue] for the [parameterType] of a native
+  /// method. May return `null`, for example, if [parameterType] is not modelled
+  /// precisely by an [AbstractValue].
+  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type);
+
   /// Returns an [AbstractBool] that describes if the set of runtime values of
   /// [subset] are known to all be in the set of runtime values of [superset].
   AbstractBool contains(AbstractValue superset, AbstractValue subset);
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index 60ea7a3..2eedb7b 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -1242,7 +1242,7 @@
 
   @override
   bool assumeDynamic(MemberEntity member) {
-    return closedWorld.annotationsData.assumeDynamicMembers.contains(member);
+    return closedWorld.annotationsData.hasAssumeDynamic(member);
   }
 }
 
@@ -1272,8 +1272,11 @@
 
   @override
   void forEachParameter(FunctionEntity function, void f(Local parameter)) {
-    forEachOrderedParameter(
-        _closedWorld.globalLocalsMap, _closedWorld.elementMap, function, f);
+    forEachOrderedParameterAsLocal(
+        _closedWorld.globalLocalsMap, _closedWorld.elementMap, function,
+        (Local parameter, {bool isElided}) {
+      f(parameter);
+    });
   }
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/trivial.dart b/pkg/compiler/lib/src/inferrer/trivial.dart
index 63d0b8e..86df64c 100644
--- a/pkg/compiler/lib/src/inferrer/trivial.dart
+++ b/pkg/compiler/lib/src/inferrer/trivial.dart
@@ -5,6 +5,7 @@
 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue;
 import '../elements/entities.dart';
 import '../elements/names.dart';
+import '../elements/types.dart' show DartType;
 import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
@@ -170,6 +171,10 @@
       const TrivialAbstractValue();
 
   @override
+  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) =>
+      null;
+
+  @override
   AbstractBool containsAll(AbstractValue a) => AbstractBool.Maybe;
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index 17794f1..03ccfef 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -11,6 +11,7 @@
 import '../../constants/values.dart';
 import '../../elements/entities.dart';
 import '../../elements/names.dart';
+import '../../elements/types.dart' show DartType, InterfaceType, DynamicType;
 import '../../serialization/serialization.dart';
 import '../../universe/class_hierarchy.dart';
 import '../../universe/selector.dart' show Selector;
@@ -775,6 +776,20 @@
   }
 
   @override
+  AbstractValue getAbstractValueForNativeMethodParameterType(DartType type) {
+    if (type is InterfaceType) {
+      if (type.typeArguments.isNotEmpty) return null;
+      // TODO(sra): Consider using a strengthened type check to avoid passing
+      // `null` to primitive types since the native methods usually have
+      // non-nullable primitive parameter types.
+      return createNullableSubtype(type.element);
+    }
+    if (type is DynamicType) return dynamicType;
+    // TODO(sra): Convert other [DartType]s to [AbstractValue]s
+    return null;
+  }
+
+  @override
   String getCompactText(AbstractValue value) {
     return formatType(value);
   }
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index eb71af5..3e63370 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -24,7 +24,10 @@
   @override
   SourceInformationBuilder createBuilderForContext(MemberEntity member) {
     return new KernelSourceInformationBuilder(
-        _backendStrategy.elementMap, member);
+        _backendStrategy
+            // ignore:deprecated_member_use_from_same_package
+            .elementMap,
+        member);
   }
 }
 
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 570fa82..f7118bd 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -10,15 +10,185 @@
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
+import 'impact_data.dart';
+import 'runtime_type_analysis.dart';
 import 'scope.dart';
 import 'static_type.dart';
 import 'static_type_base.dart';
 import 'util.dart';
 
-abstract class ImpactBuilder extends StaticTypeVisitor {
+/// Interface for collecting world impact data.
+///
+/// This is used both for direct world impact computation through the
+/// [KernelImpactBuilder] and for serialization through the [ImpactBuilder]
+/// and [ImpactLoader].
+abstract class ImpactRegistry {
+  void registerIntLiteral(int value);
+
+  void registerDoubleLiteral(double value);
+
+  void registerBoolLiteral(bool value);
+
+  void registerStringLiteral(String value);
+
+  void registerSymbolLiteral(String value);
+
+  void registerNullLiteral();
+
+  void registerListLiteral(ir.DartType elementType,
+      {bool isConst, bool isEmpty});
+
+  void registerSetLiteral(ir.DartType elementType,
+      {bool isConst, bool isEmpty});
+
+  void registerMapLiteral(ir.DartType keyType, ir.DartType valueType,
+      {bool isConst, bool isEmpty});
+
+  void registerStaticTearOff(
+      ir.Procedure procedure, ir.LibraryDependency import);
+
+  void registerStaticGet(ir.Member member, ir.LibraryDependency import);
+
+  void registerStaticSet(ir.Member member, ir.LibraryDependency import);
+
+  void registerAssert({bool withMessage});
+
+  void registerGenericInstantiation(
+      ir.FunctionType expressionType, List<ir.DartType> typeArguments);
+
+  void registerSyncStar(ir.DartType elementType);
+
+  void registerAsync(ir.DartType elementType);
+
+  void registerAsyncStar(ir.DartType elementType);
+
+  void registerStringConcatenation();
+
+  void registerLocalFunction(ir.TreeNode node);
+
+  void registerLocalWithoutInitializer();
+
+  void registerIsCheck(ir.DartType type);
+
+  void registerImplicitCast(ir.DartType type);
+
+  void registerAsCast(ir.DartType type);
+
+  void registerThrow();
+
+  void registerSyncForIn(ir.DartType iterableType);
+
+  void registerAsyncForIn(ir.DartType iterableType);
+
+  void registerCatch();
+
+  void registerStackTrace();
+
+  void registerCatchType(ir.DartType type);
+
+  void registerTypeLiteral(ir.DartType type, ir.LibraryDependency import);
+
+  void registerFieldInitializer(ir.Field node);
+
+  void registerLoadLibrary();
+
+  void registerRedirectingInitializer(
+      ir.Constructor constructor,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments);
+
+  void registerParameterCheck(ir.DartType type);
+
+  void registerLazyField();
+
+  void registerNew(
+      ir.Member constructor,
+      ir.InterfaceType type,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments,
+      ir.LibraryDependency import,
+      {bool isConst});
+
+  void registerStaticInvocation(
+      ir.Procedure target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments,
+      ir.LibraryDependency import);
+
+  void registerLocalFunctionInvocation(
+      ir.FunctionDeclaration localFunction,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments);
+
+  void registerDynamicInvocation(
+      ir.DartType receiverType,
+      ClassRelation relation,
+      ir.Name name,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments);
+
+  void registerInstanceInvocation(
+      ir.DartType receiverType,
+      ClassRelation relation,
+      ir.Member target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments);
+
+  void registerFunctionInvocation(
+      ir.DartType receiverType,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments);
+
+  void registerDynamicGet(
+      ir.DartType receiverType, ClassRelation relation, ir.Name name);
+
+  void registerInstanceGet(
+      ir.DartType receiverType, ClassRelation relation, ir.Member target);
+
+  void registerDynamicSet(
+      ir.DartType receiverType, ClassRelation relation, ir.Name name);
+
+  void registerInstanceSet(
+      ir.DartType receiverType, ClassRelation relation, ir.Member target);
+
+  void registerSuperInvocation(ir.Name name, int positionalArguments,
+      List<String> namedArguments, List<ir.DartType> typeArguments);
+
+  void registerSuperGet(ir.Name name);
+
+  void registerSuperSet(ir.Name name);
+
+  void registerSuperInitializer(
+      ir.Constructor source,
+      ir.Constructor target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments);
+
+  void registerRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+      ir.DartType receiverType, ir.DartType argumentType);
+
+  // TODO(johnniwinther): Remove these when CFE provides constants.
+  void registerConstructorNode(ir.Constructor node);
+  void registerFieldNode(ir.Field node);
+  void registerProcedureNode(ir.Procedure node);
+  void registerStaticInvocationNode(ir.StaticInvocation node);
+  void registerSwitchStatementNode(ir.SwitchStatement node);
+  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node);
+}
+
+abstract class ImpactBuilderBase extends StaticTypeVisitor
+    implements ImpactRegistry {
   final VariableScopeModel variableScopeModel;
 
-  ImpactBuilder(ir.TypeEnvironment typeEnvironment,
+  ImpactBuilderBase(ir.TypeEnvironment typeEnvironment,
       ir.ClassHierarchy classHierarchy, this.variableScopeModel)
       : super(typeEnvironment, classHierarchy);
 
@@ -32,71 +202,54 @@
     }
   }
 
-  void registerIntLiteral(int value);
-
   @override
   void handleIntLiteral(ir.IntLiteral node) {
     registerIntLiteral(node.value);
   }
 
-  void registerDoubleLiteral(double value);
-
   @override
   void handleDoubleLiteral(ir.DoubleLiteral node) {
     registerDoubleLiteral(node.value);
   }
 
-  void registerBoolLiteral(bool value);
-
   @override
   void handleBoolLiteral(ir.BoolLiteral node) {
     registerBoolLiteral(node.value);
   }
 
-  void registerStringLiteral(String value);
-
   @override
   void handleStringLiteral(ir.StringLiteral node) {
     registerStringLiteral(node.value);
   }
 
-  void registerSymbolLiteral(String value);
-
   @override
   void handleSymbolLiteral(ir.SymbolLiteral node) {
     registerSymbolLiteral(node.value);
   }
 
-  void registerNullLiteral();
-
   @override
   void handleNullLiteral(ir.NullLiteral node) {
     registerNullLiteral();
   }
 
-  void registerListLiteral(ir.DartType elementType,
-      {bool isConstant, bool isEmpty});
-
   @override
   void handleListLiteral(ir.ListLiteral node) {
     registerListLiteral(node.typeArgument,
-        isConstant: node.isConst, isEmpty: node.expressions.isEmpty);
+        isConst: node.isConst, isEmpty: node.expressions.isEmpty);
   }
 
-  void registerMapLiteral(ir.DartType keyType, ir.DartType valueType,
-      {bool isConstant, bool isEmpty});
+  @override
+  void handleSetLiteral(ir.SetLiteral node) {
+    registerSetLiteral(node.typeArgument,
+        isConst: node.isConst, isEmpty: node.expressions.isEmpty);
+  }
 
   @override
   void handleMapLiteral(ir.MapLiteral node) {
     registerMapLiteral(node.keyType, node.valueType,
-        isConstant: node.isConst, isEmpty: node.entries.isEmpty);
+        isConst: node.isConst, isEmpty: node.entries.isEmpty);
   }
 
-  void registerStaticTearOff(
-      ir.Procedure procedure, ir.LibraryDependency import);
-
-  void registerStaticGet(ir.Member member, ir.LibraryDependency import);
-
   @override
   void handleStaticGet(ir.StaticGet node, ir.DartType resultType) {
     ir.Member target = node.target;
@@ -107,35 +260,22 @@
     }
   }
 
-  void registerStaticSet(ir.Member member, ir.LibraryDependency import);
-
   @override
   void handleStaticSet(ir.StaticSet node, ir.DartType valueType) {
     registerStaticSet(node.target, getDeferredImport(node));
   }
 
-  void registerAssert({bool withMessage});
-
   @override
   void handleAssertStatement(ir.AssertStatement node) {
     registerAssert(withMessage: node.message != null);
   }
 
-  void registerGenericInstantiation(
-      ir.FunctionType expressionType, List<ir.DartType> typeArguments);
-
   @override
   void handleInstantiation(ir.Instantiation node,
       ir.FunctionType expressionType, ir.DartType resultType) {
     registerGenericInstantiation(expressionType, node.typeArguments);
   }
 
-  void registerSyncStar(ir.DartType elementType);
-
-  void registerAsync(ir.DartType elementType);
-
-  void registerAsyncStar(ir.DartType elementType);
-
   void handleAsyncMarker(ir.FunctionNode function) {
     ir.AsyncMarker asyncMarker = function.asyncMarker;
     ir.DartType returnType = function.returnType;
@@ -182,15 +322,11 @@
     }
   }
 
-  void registerStringConcatenation();
-
   @override
   void handleStringConcatenation(ir.StringConcatenation node) {
     registerStringConcatenation();
   }
 
-  void registerLocalFunction(ir.TreeNode node);
-
   @override
   Null handleFunctionDeclaration(ir.FunctionDeclaration node) {
     registerLocalFunction(node);
@@ -203,8 +339,6 @@
     handleAsyncMarker(node.function);
   }
 
-  void registerLocalWithoutInitializer();
-
   @override
   void handleVariableDeclaration(ir.VariableDeclaration node) {
     if (node.initializer == null) {
@@ -212,17 +346,11 @@
     }
   }
 
-  void registerIsCheck(ir.DartType type);
-
   @override
   void handleIsExpression(ir.IsExpression node) {
     registerIsCheck(node.type);
   }
 
-  void registerImplicitCast(ir.DartType type);
-
-  void registerAsCast(ir.DartType type);
-
   @override
   void handleAsExpression(ir.AsExpression node, ir.DartType operandType) {
     if (typeEnvironment.isSubtypeOf(operandType, node.type)) {
@@ -236,17 +364,11 @@
     }
   }
 
-  void registerThrow();
-
   @override
   void handleThrow(ir.Throw node) {
     registerThrow();
   }
 
-  void registerSyncForIn(ir.DartType iterableType);
-
-  void registerAsyncForIn(ir.DartType iterableType);
-
   @override
   void handleForInStatement(ir.ForInStatement node, ir.DartType iterableType) {
     if (node.isAsync) {
@@ -256,12 +378,6 @@
     }
   }
 
-  void registerCatch();
-
-  void registerStackTrace();
-
-  void registerCatchType(ir.DartType type);
-
   @override
   void handleCatch(ir.Catch node) {
     registerCatch();
@@ -273,37 +389,30 @@
     }
   }
 
-  void registerTypeLiteral(ir.DartType type, ir.LibraryDependency import);
-
   @override
   void handleTypeLiteral(ir.TypeLiteral node) {
     registerTypeLiteral(node.type, getDeferredImport(node));
   }
 
-  void registerFieldInitializer(ir.Field node);
-
   @override
   void handleFieldInitializer(ir.FieldInitializer node) {
     registerFieldInitializer(node.field);
   }
 
-  void registerLoadLibrary();
-
   @override
   void handleLoadLibrary(ir.LoadLibrary node) {
     registerLoadLibrary();
   }
 
-  void registerRedirectingInitializer(
-      ir.Constructor constructor, ir.Arguments arguments);
-
   void handleRedirectingInitializer(
       ir.RedirectingInitializer node, ArgumentTypes argumentTypes) {
-    registerRedirectingInitializer(node.target, node.arguments);
+    registerRedirectingInitializer(
+        node.target,
+        node.arguments.positional.length,
+        _getNamedArguments(node.arguments),
+        node.arguments.types);
   }
 
-  void registerParameterCheck(ir.DartType type);
-
   @override
   void handleParameter(ir.VariableDeclaration parameter) {
     registerParameterCheck(parameter.type);
@@ -316,7 +425,10 @@
     }
   }
 
-  void registerLazyField();
+  @override
+  void handleConstructor(ir.Constructor node) {
+    registerConstructorNode(node);
+  }
 
   @override
   void handleField(ir.Field field) {
@@ -330,31 +442,37 @@
     } else {
       registerNullLiteral();
     }
+    registerFieldNode(field);
   }
 
   @override
   void handleProcedure(ir.Procedure procedure) {
     handleAsyncMarker(procedure.function);
+    registerProcedureNode(procedure);
   }
 
-  void registerNew(ir.Member constructor, ir.InterfaceType type,
-      ir.Arguments arguments, ir.LibraryDependency import,
-      {bool isConst});
-
   @override
   void handleConstructorInvocation(ir.ConstructorInvocation node,
       ArgumentTypes argumentTypes, ir.DartType resultType) {
-    registerNew(node.target, node.constructedType, node.arguments,
+    registerNew(
+        node.target,
+        node.constructedType,
+        node.arguments.positional.length,
+        _getNamedArguments(node.arguments),
+        node.arguments.types,
         getDeferredImport(node),
         isConst: node.isConst);
+    if (node.isConst) {
+      registerConstConstructorInvocationNode(node);
+    }
   }
 
-  void registerStaticInvocation(
-      ir.Procedure target, ir.Arguments arguments, ir.LibraryDependency import);
-
   @override
   void handleStaticInvocation(ir.StaticInvocation node,
       ArgumentTypes argumentTypes, ir.DartType returnType) {
+    int positionArguments = node.arguments.positional.length;
+    List<String> namedArguments = _getNamedArguments(node.arguments);
+    List<ir.DartType> typeArguments = node.arguments.types;
     if (node.target.kind == ir.ProcedureKind.Factory) {
       // TODO(johnniwinther): We should not mark the type as instantiated but
       // rather follow the type arguments directly.
@@ -380,65 +498,60 @@
       // instantiated as int and String.
       registerNew(
           node.target,
-          new ir.InterfaceType(
-              node.target.enclosingClass, node.arguments.types),
-          node.arguments,
+          new ir.InterfaceType(node.target.enclosingClass, typeArguments),
+          positionArguments,
+          namedArguments,
+          node.arguments.types,
           getDeferredImport(node),
           isConst: node.isConst);
     } else {
-      registerStaticInvocation(
-          node.target, node.arguments, getDeferredImport(node));
+      registerStaticInvocation(node.target, positionArguments, namedArguments,
+          typeArguments, getDeferredImport(node));
     }
+    registerStaticInvocationNode(node);
   }
 
-  void registerLocalFunctionInvocation(
-      ir.FunctionDeclaration localFunction, ir.Arguments arguments);
-
-  void registerDynamicInvocation(ir.DartType receiverType,
-      ClassRelation relation, ir.Name name, ir.Arguments arguments);
-
-  void registerInstanceInvocation(ir.DartType receiverType,
-      ClassRelation relation, ir.Member target, ir.Arguments arguments);
-
-  void registerFunctionInvocation(
-      ir.DartType receiverType, ir.Arguments arguments);
-
   @override
   void handleMethodInvocation(
       ir.MethodInvocation node,
       ir.DartType receiverType,
       ArgumentTypes argumentTypes,
       ir.DartType returnType) {
+    int positionArguments = node.arguments.positional.length;
+    List<String> namedArguments = _getNamedArguments(node.arguments);
+    List<ir.DartType> typeArguments = node.arguments.types;
     ir.Expression receiver = node.receiver;
     if (receiver is ir.VariableGet &&
         receiver.variable.isFinal &&
         receiver.variable.parent is ir.FunctionDeclaration) {
-      registerLocalFunctionInvocation(receiver.variable.parent, node.arguments);
+      registerLocalFunctionInvocation(receiver.variable.parent,
+          positionArguments, namedArguments, typeArguments);
     } else {
       ClassRelation relation = _computeClassRelationFromType(receiverType);
 
       ir.Member interfaceTarget = node.interfaceTarget;
       if (interfaceTarget == null) {
-        registerDynamicInvocation(
-            receiverType, relation, node.name, node.arguments);
+        registerDynamicInvocation(receiverType, relation, node.name,
+            positionArguments, namedArguments, typeArguments);
         // TODO(johnniwinther): Avoid treating a known function call as a
         // dynamic call when CFE provides a way to distinguish the two.
         if (operatorFromString(node.name.name) == null &&
             receiverType is ir.DynamicType) {
           // We might implicitly call a getter that returns a function.
-          registerFunctionInvocation(const ir.DynamicType(), node.arguments);
+          registerFunctionInvocation(const ir.DynamicType(), positionArguments,
+              namedArguments, typeArguments);
         }
       } else {
         if (interfaceTarget is ir.Field ||
             interfaceTarget is ir.Procedure &&
                 interfaceTarget.kind == ir.ProcedureKind.Getter) {
-          registerInstanceInvocation(
-              receiverType, relation, interfaceTarget, node.arguments);
-          registerFunctionInvocation(
-              interfaceTarget.getterType, node.arguments);
+          registerInstanceInvocation(receiverType, relation, interfaceTarget,
+              positionArguments, namedArguments, typeArguments);
+          registerFunctionInvocation(interfaceTarget.getterType,
+              positionArguments, namedArguments, typeArguments);
         } else {
-          registerInstanceInvocation(
-              receiverType, relation, interfaceTarget, node.arguments);
+          registerInstanceInvocation(receiverType, relation, interfaceTarget,
+              positionArguments, namedArguments, typeArguments);
         }
       }
     }
@@ -451,15 +564,14 @@
       ArgumentTypes argumentTypes,
       ir.DartType returnType) {
     registerInstanceInvocation(
-        receiverType, ClassRelation.exact, node.target, node.arguments);
+        receiverType,
+        ClassRelation.exact,
+        node.target,
+        node.arguments.positional.length,
+        _getNamedArguments(node.arguments),
+        node.arguments.types);
   }
 
-  void registerDynamicGet(
-      ir.DartType receiverType, ClassRelation relation, ir.Name name);
-
-  void registerInstanceGet(
-      ir.DartType receiverType, ClassRelation relation, ir.Member target);
-
   @override
   void handlePropertyGet(
       ir.PropertyGet node, ir.DartType receiverType, ir.DartType resultType) {
@@ -477,12 +589,6 @@
     registerInstanceGet(receiverType, ClassRelation.exact, node.target);
   }
 
-  void registerDynamicSet(
-      ir.DartType receiverType, ClassRelation relation, ir.Name name);
-
-  void registerInstanceSet(
-      ir.DartType receiverType, ClassRelation relation, ir.Member target);
-
   @override
   void handlePropertySet(
       ir.PropertySet node, ir.DartType receiverType, ir.DartType valueType) {
@@ -500,35 +606,59 @@
     registerInstanceSet(receiverType, ClassRelation.exact, node.target);
   }
 
-  void registerSuperInvocation(ir.Name name, ir.Arguments arguments);
-
   @override
   void handleSuperMethodInvocation(ir.SuperMethodInvocation node,
       ArgumentTypes argumentTypes, ir.DartType returnType) {
-    registerSuperInvocation(node.name, node.arguments);
+    registerSuperInvocation(node.name, node.arguments.positional.length,
+        _getNamedArguments(node.arguments), node.arguments.types);
   }
 
-  void registerSuperGet(ir.Name name);
-
   @override
   void handleSuperPropertyGet(
       ir.SuperPropertyGet node, ir.DartType resultType) {
     registerSuperGet(node.name);
   }
 
-  void registerSuperSet(ir.Name name);
-
   @override
   void handleSuperPropertySet(ir.SuperPropertySet node, ir.DartType valueType) {
     registerSuperSet(node.name);
   }
 
-  void registerSuperInitializer(
-      ir.Constructor source, ir.Constructor target, ir.Arguments arguments);
-
   @override
   void handleSuperInitializer(
       ir.SuperInitializer node, ArgumentTypes argumentTypes) {
-    registerSuperInitializer(node.parent, node.target, node.arguments);
+    registerSuperInitializer(
+        node.parent,
+        node.target,
+        node.arguments.positional.length,
+        _getNamedArguments(node.arguments),
+        node.arguments.types);
+  }
+
+  @override
+  Null visitSwitchStatement(ir.SwitchStatement node) {
+    registerSwitchStatementNode(node);
+    return super.visitSwitchStatement(node);
+  }
+
+  void handleRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+      ir.DartType receiverType, ir.DartType argumentType) {
+    registerRuntimeTypeUse(node, kind, receiverType, argumentType);
   }
 }
+
+/// Visitor that builds an [ImpactData] object for the world impact.
+class ImpactBuilder extends ImpactBuilderBase with ImpactRegistryMixin {
+  final bool useAsserts;
+
+  final inferEffectivelyFinalVariableTypes;
+
+  ImpactBuilder(ir.TypeEnvironment typeEnvironment,
+      ir.ClassHierarchy classHierarchy, VariableScopeModel variableScopeModel,
+      {this.useAsserts: false, this.inferEffectivelyFinalVariableTypes: true})
+      : super(typeEnvironment, classHierarchy, variableScopeModel);
+}
+
+/// Return the named arguments names as a list of strings.
+List<String> _getNamedArguments(ir.Arguments arguments) =>
+    arguments.named.map((n) => n.name).toList();
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
new file mode 100644
index 0000000..20bd480
--- /dev/null
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -0,0 +1,1545 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
+
+import '../serialization/serialization.dart';
+import '../util/enumset.dart';
+import 'impact.dart';
+import 'runtime_type_analysis.dart';
+import 'static_type.dart';
+
+/// [ImpactRegistry] that stores registered impact in an [ImpactData] object.
+abstract class ImpactRegistryMixin implements ImpactRegistry {
+  final ImpactDataImpl _data = new ImpactDataImpl();
+
+  ImpactData get impactData => _data;
+
+  void _registerFeature(_Feature feature) {
+    _data._features ??= new EnumSet<_Feature>();
+    _data._features.add(feature);
+  }
+
+  void _registerTypeUse(ir.DartType type, _TypeUseKind kind) {
+    _data._typeUses ??= [];
+    _data._typeUses.add(new _TypeUse(type, kind));
+  }
+
+  @override
+  void registerSuperInitializer(
+      ir.Constructor source,
+      ir.Constructor target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    _data._superInitializers ??= [];
+    _data._superInitializers.add(new _SuperInitializer(
+        source,
+        target,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerSuperSet(ir.Name name) {
+    _data._superSets ??= [];
+    _data._superSets.add(name);
+  }
+
+  @override
+  void registerSuperGet(ir.Name name) {
+    _data._superGets ??= [];
+    _data._superGets.add(name);
+  }
+
+  @override
+  void registerSuperInvocation(ir.Name name, int positionalArguments,
+      List<String> namedArguments, List<ir.DartType> typeArguments) {
+    _data._superInvocations ??= [];
+    _data._superInvocations.add(new _SuperInvocation(
+        name,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerInstanceSet(
+      ir.DartType receiverType, ClassRelation relation, ir.Member target) {
+    _data._instanceSets ??= [];
+    _data._instanceSets
+        .add(new _InstanceAccess(receiverType, relation, target));
+  }
+
+  @override
+  void registerDynamicSet(
+      ir.DartType receiverType, ClassRelation relation, ir.Name name) {
+    _data._dynamicSets ??= [];
+    _data._dynamicSets.add(new _DynamicAccess(receiverType, relation, name));
+  }
+
+  @override
+  void registerInstanceGet(
+      ir.DartType receiverType, ClassRelation relation, ir.Member target) {
+    _data._instanceGets ??= [];
+    _data._instanceGets
+        .add(new _InstanceAccess(receiverType, relation, target));
+  }
+
+  @override
+  void registerDynamicGet(
+      ir.DartType receiverType, ClassRelation relation, ir.Name name) {
+    _data._dynamicGets ??= [];
+    _data._dynamicGets.add(new _DynamicAccess(receiverType, relation, name));
+  }
+
+  @override
+  void registerFunctionInvocation(
+      ir.DartType receiverType,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    _data._functionInvocations ??= [];
+    _data._functionInvocations.add(new _FunctionInvocation(
+        receiverType,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerInstanceInvocation(
+      ir.DartType receiverType,
+      ClassRelation relation,
+      ir.Member target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    _data._instanceInvocations ??= [];
+    _data._instanceInvocations.add(new _InstanceInvocation(
+        receiverType,
+        relation,
+        target,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerDynamicInvocation(
+      ir.DartType receiverType,
+      ClassRelation relation,
+      ir.Name name,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    _data._dynamicInvocations ??= [];
+    _data._dynamicInvocations.add(new _DynamicInvocation(
+        receiverType,
+        relation,
+        name,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerLocalFunctionInvocation(
+      ir.FunctionDeclaration localFunction,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    _data._localFunctionInvocations ??= [];
+    _data._localFunctionInvocations.add(new _LocalFunctionInvocation(
+        localFunction,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerStaticInvocation(
+      ir.Procedure target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments,
+      ir.LibraryDependency import) {
+    _data._staticInvocations ??= [];
+    _data._staticInvocations.add(new _StaticInvocation(
+        target,
+        new _CallStructure(positionalArguments, namedArguments, typeArguments),
+        import));
+  }
+
+  @override
+  void registerNew(
+      ir.Member constructor,
+      ir.InterfaceType type,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments,
+      ir.LibraryDependency import,
+      {bool isConst}) {
+    _data._constructorInvocations ??= [];
+    _data._constructorInvocations.add(new _ConstructorInvocation(
+        constructor,
+        type,
+        new _CallStructure(positionalArguments, namedArguments, typeArguments),
+        import,
+        isConst: isConst));
+  }
+
+  @override
+  void registerLazyField() {
+    _registerFeature(_Feature.lazyField);
+  }
+
+  @override
+  void registerParameterCheck(ir.DartType type) {
+    _registerTypeUse(type, _TypeUseKind.parameterCheck);
+  }
+
+  @override
+  void registerRedirectingInitializer(
+      ir.Constructor constructor,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    _data._redirectingInitializers ??= [];
+    _data._redirectingInitializers.add(new _RedirectingInitializer(
+        constructor,
+        new _CallStructure(
+            positionalArguments, namedArguments, typeArguments)));
+  }
+
+  @override
+  void registerLoadLibrary() {
+    _registerFeature(_Feature.loadLibrary);
+  }
+
+  @override
+  void registerFieldInitializer(ir.Field node) {
+    _data._fieldInitializers ??= [];
+    _data._fieldInitializers.add(node);
+  }
+
+  @override
+  void registerTypeLiteral(ir.DartType type, ir.LibraryDependency import) {
+    _data._typeLiterals ??= [];
+    _data._typeLiterals.add(new _TypeLiteral(type, import));
+  }
+
+  @override
+  void registerCatchType(ir.DartType type) {
+    _registerTypeUse(type, _TypeUseKind.catchType);
+  }
+
+  @override
+  void registerStackTrace() {
+    _registerFeature(_Feature.stackTrace);
+  }
+
+  @override
+  void registerCatch() {
+    _registerFeature(_Feature.catchClause);
+  }
+
+  @override
+  void registerAsyncForIn(ir.DartType iterableType) {
+    _registerTypeUse(iterableType, _TypeUseKind.asyncForIn);
+  }
+
+  @override
+  void registerSyncForIn(ir.DartType iterableType) {
+    _registerTypeUse(iterableType, _TypeUseKind.syncForIn);
+  }
+
+  @override
+  void registerThrow() {
+    _registerFeature(_Feature.throwExpression);
+  }
+
+  @override
+  void registerAsCast(ir.DartType type) {
+    _registerTypeUse(type, _TypeUseKind.asCast);
+  }
+
+  @override
+  void registerImplicitCast(ir.DartType type) {
+    _registerTypeUse(type, _TypeUseKind.implicitCast);
+  }
+
+  @override
+  void registerIsCheck(ir.DartType type) {
+    _registerTypeUse(type, _TypeUseKind.isCheck);
+  }
+
+  @override
+  void registerLocalWithoutInitializer() {
+    _registerFeature(_Feature.localWithoutInitializer);
+  }
+
+  @override
+  void registerLocalFunction(ir.TreeNode node) {
+    _data._localFunctions ??= [];
+    _data._localFunctions.add(node);
+  }
+
+  @override
+  void registerStringConcatenation() {
+    _registerFeature(_Feature.stringConcatenation);
+  }
+
+  @override
+  void registerAsyncStar(ir.DartType elementType) {
+    _registerTypeUse(elementType, _TypeUseKind.asyncStarMarker);
+  }
+
+  @override
+  void registerAsync(ir.DartType elementType) {
+    _registerTypeUse(elementType, _TypeUseKind.asyncMarker);
+  }
+
+  @override
+  void registerSyncStar(ir.DartType elementType) {
+    _registerTypeUse(elementType, _TypeUseKind.syncStarMarker);
+  }
+
+  @override
+  void registerGenericInstantiation(
+      ir.FunctionType expressionType, List<ir.DartType> typeArguments) {
+    _data._genericInstantiations ??= [];
+    _data._genericInstantiations
+        .add(new _GenericInstantiation(expressionType, typeArguments));
+  }
+
+  @override
+  void registerAssert({bool withMessage}) {
+    _registerFeature(withMessage
+        ? _Feature.assertWithMessage
+        : _Feature.assertWithoutMessage);
+  }
+
+  @override
+  void registerStaticSet(ir.Member member, ir.LibraryDependency import) {
+    _data._staticSets ??= [];
+    _data._staticSets.add(new _StaticAccess(member, import));
+  }
+
+  @override
+  void registerStaticGet(ir.Member member, ir.LibraryDependency import) {
+    _data._staticGets ??= [];
+    _data._staticGets.add(new _StaticAccess(member, import));
+  }
+
+  @override
+  void registerStaticTearOff(
+      ir.Procedure procedure, ir.LibraryDependency import) {
+    _data._staticTearOffs ??= [];
+    _data._staticTearOffs.add(new _StaticAccess(procedure, import));
+  }
+
+  @override
+  void registerMapLiteral(ir.DartType keyType, ir.DartType valueType,
+      {bool isConst, bool isEmpty}) {
+    _data._mapLiterals ??= [];
+    _data._mapLiterals.add(new _MapLiteral(keyType, valueType,
+        isConst: isConst, isEmpty: isEmpty));
+  }
+
+  @override
+  void registerListLiteral(ir.DartType elementType,
+      {bool isConst, bool isEmpty}) {
+    _data._listLiterals ??= [];
+    _data._listLiterals.add(
+        new _ContainerLiteral(elementType, isConst: isConst, isEmpty: isEmpty));
+  }
+
+  @override
+  void registerSetLiteral(ir.DartType elementType,
+      {bool isConst, bool isEmpty}) {
+    _data._setLiterals ??= [];
+    _data._setLiterals.add(
+        new _ContainerLiteral(elementType, isConst: isConst, isEmpty: isEmpty));
+  }
+
+  @override
+  void registerNullLiteral() {
+    _registerFeature(_Feature.nullLiteral);
+  }
+
+  @override
+  void registerSymbolLiteral(String value) {
+    _data._symbolLiterals ??= [];
+    _data._symbolLiterals.add(value);
+  }
+
+  @override
+  void registerStringLiteral(String value) {
+    _data._stringLiterals ??= [];
+    _data._stringLiterals.add(value);
+  }
+
+  @override
+  void registerBoolLiteral(bool value) {
+    _data._boolLiterals ??= [];
+    _data._boolLiterals.add(value);
+  }
+
+  @override
+  void registerDoubleLiteral(double value) {
+    _data._doubleLiterals ??= [];
+    _data._doubleLiterals.add(value);
+  }
+
+  @override
+  void registerIntLiteral(int value) {
+    _data._intLiterals ??= [];
+    _data._intLiterals.add(value);
+  }
+
+  @override
+  void registerRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+      ir.DartType receiverType, ir.DartType argumentType) {
+    _data._runtimeTypeUses ??= [];
+    _data._runtimeTypeUses
+        .add(new _RuntimeTypeUse(node, kind, receiverType, argumentType));
+  }
+
+  @override
+  void registerConstructorNode(ir.Constructor node) {
+    _data._constructorNodes ??= [];
+    _data._constructorNodes.add(node);
+  }
+
+  @override
+  void registerFieldNode(ir.Field node) {
+    _data._fieldNodes ??= [];
+    _data._fieldNodes.add(node);
+  }
+
+  @override
+  void registerProcedureNode(ir.Procedure node) {
+    _data._procedureNodes ??= [];
+    _data._procedureNodes.add(node);
+  }
+
+  @override
+  void registerStaticInvocationNode(ir.StaticInvocation node) {
+    _data._staticInvocationNodes ??= [];
+    _data._staticInvocationNodes.add(node);
+  }
+
+  @override
+  void registerSwitchStatementNode(ir.SwitchStatement node) {
+    _data._switchStatementNodes ??= [];
+    _data._switchStatementNodes.add(node);
+  }
+
+  @override
+  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node) {
+    _data._constConstructorInvocationNodes ??= [];
+    _data._constConstructorInvocationNodes.add(node);
+  }
+}
+
+/// Data object that contains the world impact data derived purely from kernel.
+abstract class ImpactData {
+  factory ImpactData.fromDataSource(DataSource source) =
+      ImpactDataImpl.fromDataSource;
+
+  void toDataSink(DataSink sink);
+
+  /// Registers the impact data with [registry].
+  void apply(ImpactRegistry registry);
+}
+
+class ImpactDataImpl implements ImpactData {
+  static const String tag = 'ImpactData';
+
+  List<_SuperInitializer> _superInitializers;
+  List<ir.Name> _superSets;
+  List<ir.Name> _superGets;
+  List<_SuperInvocation> _superInvocations;
+  List<_InstanceAccess> _instanceSets;
+  List<_DynamicAccess> _dynamicSets;
+  List<_InstanceAccess> _instanceGets;
+  List<_DynamicAccess> _dynamicGets;
+  List<_FunctionInvocation> _functionInvocations;
+  List<_InstanceInvocation> _instanceInvocations;
+  List<_DynamicInvocation> _dynamicInvocations;
+  List<_LocalFunctionInvocation> _localFunctionInvocations;
+  List<_StaticInvocation> _staticInvocations;
+  List<_ConstructorInvocation> _constructorInvocations;
+  EnumSet<_Feature> _features;
+  List<_TypeUse> _typeUses;
+  List<_RedirectingInitializer> _redirectingInitializers;
+  List<ir.Field> _fieldInitializers;
+  List<_TypeLiteral> _typeLiterals;
+  List<ir.TreeNode> _localFunctions;
+  List<_GenericInstantiation> _genericInstantiations;
+  List<_StaticAccess> _staticSets;
+  List<_StaticAccess> _staticGets;
+  List<_StaticAccess> _staticTearOffs;
+  List<_MapLiteral> _mapLiterals;
+  List<_ContainerLiteral> _listLiterals;
+  List<_ContainerLiteral> _setLiterals;
+  List<String> _symbolLiterals;
+  List<String> _stringLiterals;
+  List<bool> _boolLiterals;
+  List<double> _doubleLiterals;
+  List<int> _intLiterals;
+  List<_RuntimeTypeUse> _runtimeTypeUses;
+
+  // TODO(johnniwinther): Remove these when CFE provides constants.
+  List<ir.Constructor> _constructorNodes;
+  List<ir.Field> _fieldNodes;
+  List<ir.Procedure> _procedureNodes;
+  List<ir.SwitchStatement> _switchStatementNodes;
+  List<ir.StaticInvocation> _staticInvocationNodes;
+  List<ir.ConstructorInvocation> _constConstructorInvocationNodes;
+
+  ImpactDataImpl();
+
+  ImpactDataImpl.fromDataSource(DataSource source) {
+    source.begin(tag);
+    _superInitializers = source.readList(
+        () => new _SuperInitializer.fromDataSource(source),
+        emptyAsNull: true);
+    _superSets = source.readList(() => source.readName(), emptyAsNull: true);
+    _superGets = source.readList(() => source.readName(), emptyAsNull: true);
+    _superInvocations = source.readList(
+        () => new _SuperInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _instanceSets = source.readList(
+        () => new _InstanceAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _dynamicSets = source.readList(
+        () => new _DynamicAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _instanceGets = source.readList(
+        () => new _InstanceAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _dynamicGets = source.readList(
+        () => new _DynamicAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _functionInvocations = source.readList(
+        () => new _FunctionInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _instanceInvocations = source.readList(
+        () => new _InstanceInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _dynamicInvocations = source.readList(
+        () => new _DynamicInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _localFunctionInvocations = source.readList(
+        () => new _LocalFunctionInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _staticInvocations = source.readList(
+        () => new _StaticInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _constructorInvocations = source.readList(
+        () => new _ConstructorInvocation.fromDataSource(source),
+        emptyAsNull: true);
+    _features = new EnumSet<_Feature>.fromValue(source.readInt());
+    _typeUses = source.readList(() => new _TypeUse.fromDataSource(source),
+        emptyAsNull: true);
+    _redirectingInitializers = source.readList(
+        () => new _RedirectingInitializer.fromDataSource(source),
+        emptyAsNull: true);
+    _fieldInitializers = source.readMemberNodes(emptyAsNull: true);
+    _typeLiterals = source.readList(
+        () => new _TypeLiteral.fromDataSource(source),
+        emptyAsNull: true);
+    _localFunctions = source.readTreeNodes(emptyAsNull: true);
+    _genericInstantiations = source.readList(
+        () => new _GenericInstantiation.fromDataSource(source),
+        emptyAsNull: true);
+    _staticSets = source.readList(
+        () => new _StaticAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _staticGets = source.readList(
+        () => new _StaticAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _staticTearOffs = source.readList(
+        () => new _StaticAccess.fromDataSource(source),
+        emptyAsNull: true);
+    _mapLiterals = source.readList(() => new _MapLiteral.fromDataSource(source),
+        emptyAsNull: true);
+    _listLiterals = source.readList(
+        () => new _ContainerLiteral.fromDataSource(source),
+        emptyAsNull: true);
+    _setLiterals = source.readList(
+        () => new _ContainerLiteral.fromDataSource(source),
+        emptyAsNull: true);
+    _symbolLiterals = source.readStrings(emptyAsNull: true);
+    _stringLiterals = source.readStrings(emptyAsNull: true);
+    _boolLiterals = source.readList(() => source.readBool(), emptyAsNull: true);
+    _doubleLiterals =
+        source.readList(() => source.readDoubleValue(), emptyAsNull: true);
+    _intLiterals =
+        source.readList(() => source.readIntegerValue(), emptyAsNull: true);
+    _runtimeTypeUses = source.readList(
+        () => new _RuntimeTypeUse.fromDataSource(source),
+        emptyAsNull: true);
+
+    // TODO(johnniwinther): Remove these when CFE provides constants.
+    _constructorNodes =
+        source.readMemberNodes<ir.Constructor>(emptyAsNull: true);
+    _fieldNodes = source.readMemberNodes<ir.Field>(emptyAsNull: true);
+    _procedureNodes = source.readMemberNodes<ir.Procedure>(emptyAsNull: true);
+    _switchStatementNodes =
+        source.readTreeNodes<ir.SwitchStatement>(emptyAsNull: true);
+    _staticInvocationNodes =
+        source.readTreeNodes<ir.StaticInvocation>(emptyAsNull: true);
+    _constConstructorInvocationNodes =
+        source.readTreeNodes<ir.ConstructorInvocation>(emptyAsNull: true);
+    source.end(tag);
+  }
+
+  @override
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+
+    sink.writeList(
+        _superInitializers, (_SuperInitializer o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_superSets, sink.writeName, allowNull: true);
+    sink.writeList(_superGets, sink.writeName, allowNull: true);
+    sink.writeList(
+        _superInvocations, (_SuperInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_instanceSets, (_InstanceAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_dynamicSets, (_DynamicAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_instanceGets, (_InstanceAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_dynamicGets, (_DynamicAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(
+        _functionInvocations, (_FunctionInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(
+        _instanceInvocations, (_InstanceInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(
+        _dynamicInvocations, (_DynamicInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_localFunctionInvocations,
+        (_LocalFunctionInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(
+        _staticInvocations, (_StaticInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_constructorInvocations,
+        (_ConstructorInvocation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeInt(_features?.value ?? 0);
+    sink.writeList(_typeUses, (_TypeUse o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_redirectingInitializers,
+        (_RedirectingInitializer o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeMemberNodes(_fieldInitializers, allowNull: true);
+    sink.writeList(_typeLiterals, (_TypeLiteral o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeTreeNodes(_localFunctions, allowNull: true);
+    sink.writeList(
+        _genericInstantiations, (_GenericInstantiation o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_staticSets, (_StaticAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_staticGets, (_StaticAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_staticTearOffs, (_StaticAccess o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_mapLiterals, (_MapLiteral o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_listLiterals, (_ContainerLiteral o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeList(_setLiterals, (_ContainerLiteral o) => o.toDataSink(sink),
+        allowNull: true);
+    sink.writeStrings(_symbolLiterals, allowNull: true);
+    sink.writeStrings(_stringLiterals, allowNull: true);
+    sink.writeList(_boolLiterals, sink.writeBool, allowNull: true);
+    sink.writeList(_doubleLiterals, sink.writeDoubleValue, allowNull: true);
+    sink.writeList(_intLiterals, sink.writeIntegerValue, allowNull: true);
+    sink.writeList(_runtimeTypeUses, (_RuntimeTypeUse o) => o.toDataSink(sink),
+        allowNull: true);
+
+    // TODO(johnniwinther): Remove these when CFE provides constants.
+    sink.writeMemberNodes(_constructorNodes, allowNull: true);
+    sink.writeMemberNodes(_fieldNodes, allowNull: true);
+    sink.writeMemberNodes(_procedureNodes, allowNull: true);
+    sink.writeTreeNodes(_switchStatementNodes, allowNull: true);
+    sink.writeTreeNodes(_staticInvocationNodes, allowNull: true);
+    sink.writeTreeNodes(_constConstructorInvocationNodes, allowNull: true);
+
+    sink.end(tag);
+  }
+
+  @override
+  void apply(ImpactRegistry registry) {
+    if (_superInitializers != null) {
+      for (_SuperInitializer data in _superInitializers) {
+        registry.registerSuperInitializer(
+            data.source,
+            data.target,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_superSets != null) {
+      for (ir.Name data in _superSets) {
+        registry.registerSuperSet(data);
+      }
+    }
+    if (_superGets != null) {
+      for (ir.Name data in _superGets) {
+        registry.registerSuperGet(data);
+      }
+    }
+    if (_superInvocations != null) {
+      for (_SuperInvocation data in _superInvocations) {
+        registry.registerSuperInvocation(
+            data.name,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_instanceSets != null) {
+      for (_InstanceAccess data in _instanceSets) {
+        registry.registerInstanceSet(
+            data.receiverType, data.classRelation, data.target);
+      }
+    }
+    if (_dynamicSets != null) {
+      for (_DynamicAccess data in _dynamicSets) {
+        registry.registerDynamicSet(
+            data.receiverType, data.classRelation, data.name);
+      }
+    }
+    if (_instanceGets != null) {
+      for (_InstanceAccess data in _instanceGets) {
+        registry.registerInstanceGet(
+            data.receiverType, data.classRelation, data.target);
+      }
+    }
+    if (_dynamicGets != null) {
+      for (_DynamicAccess data in _dynamicGets) {
+        registry.registerDynamicGet(
+            data.receiverType, data.classRelation, data.name);
+      }
+    }
+    if (_functionInvocations != null) {
+      for (_FunctionInvocation data in _functionInvocations) {
+        registry.registerFunctionInvocation(
+            data.receiverType,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_instanceInvocations != null) {
+      for (_InstanceInvocation data in _instanceInvocations) {
+        registry.registerInstanceInvocation(
+            data.receiverType,
+            data.classRelation,
+            data.target,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_dynamicInvocations != null) {
+      for (_DynamicInvocation data in _dynamicInvocations) {
+        registry.registerDynamicInvocation(
+            data.receiverType,
+            data.classRelation,
+            data.name,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_localFunctionInvocations != null) {
+      for (_LocalFunctionInvocation data in _localFunctionInvocations) {
+        registry.registerLocalFunctionInvocation(
+            data.localFunction,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_staticInvocations != null) {
+      for (_StaticInvocation data in _staticInvocations) {
+        registry.registerStaticInvocation(
+            data.target,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments,
+            data.import);
+        ;
+      }
+    }
+    if (_constructorInvocations != null) {
+      for (_ConstructorInvocation data in _constructorInvocations) {
+        registry.registerNew(
+            data.constructor,
+            data.type,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments,
+            data.import,
+            isConst: data.isConst);
+      }
+    }
+    if (_features != null) {
+      for (_Feature data in _features.iterable(_Feature.values)) {
+        switch (data) {
+          case _Feature.lazyField:
+            registry.registerLazyField();
+            break;
+          case _Feature.loadLibrary:
+            registry.registerLoadLibrary();
+            break;
+          case _Feature.stackTrace:
+            registry.registerStackTrace();
+            break;
+          case _Feature.catchClause:
+            registry.registerCatch();
+            break;
+          case _Feature.throwExpression:
+            registry.registerThrow();
+            break;
+          case _Feature.localWithoutInitializer:
+            registry.registerLocalWithoutInitializer();
+            break;
+          case _Feature.stringConcatenation:
+            registry.registerStringConcatenation();
+            break;
+          case _Feature.assertWithMessage:
+            registry.registerAssert(withMessage: true);
+            break;
+          case _Feature.assertWithoutMessage:
+            registry.registerAssert(withMessage: false);
+            break;
+          case _Feature.nullLiteral:
+            registry.registerNullLiteral();
+            break;
+        }
+      }
+    }
+    if (_typeUses != null) {
+      for (_TypeUse data in _typeUses) {
+        switch (data.kind) {
+          case _TypeUseKind.parameterCheck:
+            registry.registerParameterCheck(data.type);
+            break;
+          case _TypeUseKind.catchType:
+            registry.registerCatchType(data.type);
+            break;
+          case _TypeUseKind.asyncForIn:
+            registry.registerAsyncForIn(data.type);
+            break;
+          case _TypeUseKind.syncForIn:
+            registry.registerSyncForIn(data.type);
+            break;
+          case _TypeUseKind.asCast:
+            registry.registerAsCast(data.type);
+            break;
+          case _TypeUseKind.implicitCast:
+            registry.registerImplicitCast(data.type);
+            break;
+          case _TypeUseKind.isCheck:
+            registry.registerIsCheck(data.type);
+            break;
+          case _TypeUseKind.asyncStarMarker:
+            registry.registerAsyncStar(data.type);
+            break;
+          case _TypeUseKind.asyncMarker:
+            registry.registerAsync(data.type);
+            break;
+          case _TypeUseKind.syncStarMarker:
+            registry.registerSyncStar(data.type);
+            break;
+        }
+      }
+    }
+    if (_redirectingInitializers != null) {
+      for (_RedirectingInitializer data in _redirectingInitializers) {
+        registry.registerRedirectingInitializer(
+            data.constructor,
+            data.callStructure.positionalArguments,
+            data.callStructure.namedArguments,
+            data.callStructure.typeArguments);
+      }
+    }
+    if (_fieldInitializers != null) {
+      for (ir.Field data in _fieldInitializers) {
+        registry.registerFieldInitializer(data);
+      }
+    }
+    if (_typeLiterals != null) {
+      for (_TypeLiteral data in _typeLiterals) {
+        registry.registerTypeLiteral(data.type, data.import);
+      }
+    }
+    if (_localFunctions != null) {
+      for (ir.TreeNode data in _localFunctions) {
+        registry.registerLocalFunction(data);
+      }
+    }
+    if (_genericInstantiations != null) {
+      for (_GenericInstantiation data in _genericInstantiations) {
+        registry.registerGenericInstantiation(
+            data.expressionType, data.typeArguments);
+      }
+    }
+    if (_staticSets != null) {
+      for (_StaticAccess data in _staticSets) {
+        registry.registerStaticSet(data.target, data.import);
+      }
+    }
+    if (_staticGets != null) {
+      for (_StaticAccess data in _staticGets) {
+        registry.registerStaticGet(data.target, data.import);
+      }
+    }
+    if (_staticTearOffs != null) {
+      for (_StaticAccess data in _staticTearOffs) {
+        registry.registerStaticTearOff(data.target, data.import);
+      }
+    }
+    if (_mapLiterals != null) {
+      for (_MapLiteral data in _mapLiterals) {
+        registry.registerMapLiteral(data.keyType, data.valueType,
+            isConst: data.isConst, isEmpty: data.isEmpty);
+      }
+    }
+    if (_listLiterals != null) {
+      for (_ContainerLiteral data in _listLiterals) {
+        registry.registerListLiteral(data.elementType,
+            isConst: data.isConst, isEmpty: data.isEmpty);
+      }
+    }
+    if (_setLiterals != null) {
+      for (_ContainerLiteral data in _setLiterals) {
+        registry.registerSetLiteral(data.elementType,
+            isConst: data.isConst, isEmpty: data.isEmpty);
+      }
+    }
+    if (_symbolLiterals != null) {
+      for (String data in _symbolLiterals) {
+        registry.registerSymbolLiteral(data);
+      }
+    }
+    if (_stringLiterals != null) {
+      for (String data in _stringLiterals) {
+        registry.registerStringLiteral(data);
+      }
+    }
+    if (_boolLiterals != null) {
+      for (bool data in _boolLiterals) {
+        registry.registerBoolLiteral(data);
+      }
+    }
+    if (_doubleLiterals != null) {
+      for (double data in _doubleLiterals) {
+        registry.registerDoubleLiteral(data);
+      }
+    }
+    if (_intLiterals != null) {
+      for (int data in _intLiterals) {
+        registry.registerIntLiteral(data);
+      }
+    }
+    if (_runtimeTypeUses != null) {
+      for (_RuntimeTypeUse data in _runtimeTypeUses) {
+        registry.registerRuntimeTypeUse(
+            data.node, data.kind, data.receiverType, data.argumentType);
+      }
+    }
+
+    // TODO(johnniwinther): Remove these when CFE provides constants.
+    if (_constructorNodes != null) {
+      for (ir.Constructor data in _constructorNodes) {
+        registry.registerConstructorNode(data);
+      }
+    }
+    if (_fieldNodes != null) {
+      for (ir.Field data in _fieldNodes) {
+        registry.registerFieldNode(data);
+      }
+    }
+    if (_procedureNodes != null) {
+      for (ir.Procedure data in _procedureNodes) {
+        registry.registerProcedureNode(data);
+      }
+    }
+    if (_switchStatementNodes != null) {
+      for (ir.SwitchStatement data in _switchStatementNodes) {
+        registry.registerSwitchStatementNode(data);
+      }
+    }
+    if (_staticInvocationNodes != null) {
+      for (ir.StaticInvocation data in _staticInvocationNodes) {
+        registry.registerStaticInvocationNode(data);
+      }
+    }
+    if (_constConstructorInvocationNodes != null) {
+      for (ir.ConstructorInvocation data in _constConstructorInvocationNodes) {
+        registry.registerConstConstructorInvocationNode(data);
+      }
+    }
+  }
+}
+
+class _CallStructure {
+  static const String tag = '_CallStructure';
+
+  final List<ir.DartType> typeArguments;
+  final int positionalArguments;
+  final List<String> namedArguments;
+
+  _CallStructure.internal(
+      this.typeArguments, this.positionalArguments, this.namedArguments);
+
+  factory _CallStructure(int positionalArguments, List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    return new _CallStructure.internal(
+        typeArguments, positionalArguments, namedArguments);
+  }
+
+  factory _CallStructure.fromDataSource(DataSource source) {
+    source.begin(tag);
+    List<ir.DartType> typeArguments = source.readDartTypeNodes();
+    int positionalArguments = source.readInt();
+    List<String> namedArguments = source.readStrings();
+    source.end(tag);
+    return new _CallStructure.internal(
+        typeArguments, positionalArguments, namedArguments);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNodes(typeArguments);
+    sink.writeInt(positionalArguments);
+    sink.writeStrings(namedArguments);
+    sink.end(tag);
+  }
+}
+
+class _SuperInitializer {
+  static const String tag = '_SuperInitializer';
+
+  final ir.Constructor source;
+  final ir.Constructor target;
+  final _CallStructure callStructure;
+
+  _SuperInitializer(this.source, this.target, this.callStructure);
+
+  factory _SuperInitializer.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.Constructor sourceConstructor = source.readMemberNode();
+    ir.Constructor targetConstructor = source.readMemberNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _SuperInitializer(
+        sourceConstructor, targetConstructor, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeMemberNode(source);
+    sink.writeMemberNode(target);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _SuperInvocation {
+  static const String tag = '_SuperInvocation';
+
+  final ir.Name name;
+  final _CallStructure callStructure;
+
+  _SuperInvocation(this.name, this.callStructure);
+
+  factory _SuperInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.Name name = source.readName();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _SuperInvocation(name, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeName(name);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _InstanceAccess {
+  static const String tag = '_InstanceAccess';
+
+  final ir.DartType receiverType;
+  final ClassRelation classRelation;
+  final ir.Member target;
+
+  _InstanceAccess(this.receiverType, this.classRelation, this.target);
+
+  factory _InstanceAccess.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType receiverType = source.readDartTypeNode();
+    ClassRelation classRelation = source.readEnum(ClassRelation.values);
+    ir.Member target = source.readMemberNode();
+    source.end(tag);
+    return new _InstanceAccess(receiverType, classRelation, target);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(receiverType);
+    sink.writeEnum(classRelation);
+    sink.writeMemberNode(target);
+    sink.end(tag);
+  }
+}
+
+class _DynamicAccess {
+  static const String tag = '_DynamicAccess';
+
+  final ir.DartType receiverType;
+  final ClassRelation classRelation;
+  final ir.Name name;
+
+  _DynamicAccess(this.receiverType, this.classRelation, this.name);
+
+  factory _DynamicAccess.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType receiverType = source.readDartTypeNode();
+    ClassRelation classRelation = source.readEnum(ClassRelation.values);
+    ir.Name name = source.readName();
+    source.end(tag);
+    return new _DynamicAccess(receiverType, classRelation, name);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(receiverType);
+    sink.writeEnum(classRelation);
+    sink.writeName(name);
+    sink.end(tag);
+  }
+}
+
+class _FunctionInvocation {
+  static const String tag = '_FunctionInvocation';
+
+  final ir.DartType receiverType;
+  final _CallStructure callStructure;
+
+  _FunctionInvocation(this.receiverType, this.callStructure);
+
+  factory _FunctionInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType receiverType = source.readDartTypeNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _FunctionInvocation(receiverType, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(receiverType);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _InstanceInvocation {
+  static const String tag = '_InstanceInvocation';
+
+  final ir.DartType receiverType;
+  final ClassRelation classRelation;
+  final ir.Member target;
+  final _CallStructure callStructure;
+
+  _InstanceInvocation(
+      this.receiverType, this.classRelation, this.target, this.callStructure);
+
+  factory _InstanceInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType receiverType = source.readDartTypeNode();
+    ClassRelation classRelation = source.readEnum(ClassRelation.values);
+    ir.Member target = source.readMemberNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _InstanceInvocation(
+        receiverType, classRelation, target, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(receiverType);
+    sink.writeEnum(classRelation);
+    sink.writeMemberNode(target);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _DynamicInvocation {
+  static const String tag = '_DynamicInvocation';
+
+  final ir.DartType receiverType;
+  final ClassRelation classRelation;
+  final ir.Name name;
+  final _CallStructure callStructure;
+
+  _DynamicInvocation(
+      this.receiverType, this.classRelation, this.name, this.callStructure);
+
+  factory _DynamicInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType receiverType = source.readDartTypeNode();
+    ClassRelation classRelation = source.readEnum(ClassRelation.values);
+    ir.Name name = source.readName();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _DynamicInvocation(
+        receiverType, classRelation, name, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(receiverType);
+    sink.writeEnum(classRelation);
+    sink.writeName(name);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _LocalFunctionInvocation {
+  static const String tag = '_LocalFunctionInvocation';
+
+  final ir.FunctionDeclaration localFunction;
+  final _CallStructure callStructure;
+
+  _LocalFunctionInvocation(this.localFunction, this.callStructure);
+
+  factory _LocalFunctionInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.FunctionDeclaration localFunction = source.readTreeNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _LocalFunctionInvocation(localFunction, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeTreeNode(localFunction);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _StaticInvocation {
+  static const String tag = '_StaticInvocation';
+
+  final ir.Procedure target;
+  final _CallStructure callStructure;
+  final ir.LibraryDependency import;
+
+  _StaticInvocation(this.target, this.callStructure, this.import);
+
+  factory _StaticInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.Procedure target = source.readMemberNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
+    source.end(tag);
+    return new _StaticInvocation(target, callStructure, import);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeMemberNode(target);
+    callStructure.toDataSink(sink);
+    sink.writeLibraryDependencyNodeOrNull(import);
+    sink.end(tag);
+  }
+}
+
+class _ConstructorInvocation {
+  static const String tag = '_ConstructorInvocation';
+
+  final ir.Member constructor;
+  final ir.InterfaceType type;
+  final _CallStructure callStructure;
+  final ir.LibraryDependency import;
+  final bool isConst;
+
+  _ConstructorInvocation(
+      this.constructor, this.type, this.callStructure, this.import,
+      {this.isConst});
+
+  factory _ConstructorInvocation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.Member constructor = source.readMemberNode();
+    ir.InterfaceType type = source.readDartTypeNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
+    bool isConst = source.readBool();
+    source.end(tag);
+    return new _ConstructorInvocation(constructor, type, callStructure, import,
+        isConst: isConst);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeMemberNode(constructor);
+    sink.writeDartTypeNode(type);
+    callStructure.toDataSink(sink);
+    sink.writeLibraryDependencyNodeOrNull(import);
+    sink.writeBool(isConst);
+    sink.end(tag);
+  }
+}
+
+enum _Feature {
+  lazyField,
+  loadLibrary,
+  stackTrace,
+  catchClause,
+  throwExpression,
+  localWithoutInitializer,
+  stringConcatenation,
+  assertWithMessage,
+  assertWithoutMessage,
+  nullLiteral,
+}
+
+class _TypeUse {
+  static const String tag = '_TypeUse';
+
+  final ir.DartType type;
+  final _TypeUseKind kind;
+
+  _TypeUse(this.type, this.kind);
+
+  factory _TypeUse.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType type = source.readDartTypeNode();
+    _TypeUseKind kind = source.readEnum(_TypeUseKind.values);
+    source.end(tag);
+    return new _TypeUse(type, kind);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(type);
+    sink.writeEnum(kind);
+    sink.end(tag);
+  }
+}
+
+enum _TypeUseKind {
+  parameterCheck,
+  catchType,
+  asyncForIn,
+  syncForIn,
+  asCast,
+  implicitCast,
+  isCheck,
+  asyncStarMarker,
+  asyncMarker,
+  syncStarMarker,
+}
+
+class _RedirectingInitializer {
+  static const String tag = '_RedirectingInitializer';
+
+  final ir.Constructor constructor;
+  final _CallStructure callStructure;
+
+  _RedirectingInitializer(this.constructor, this.callStructure);
+
+  factory _RedirectingInitializer.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.Constructor constructor = source.readMemberNode();
+    _CallStructure callStructure = new _CallStructure.fromDataSource(source);
+    source.end(tag);
+    return new _RedirectingInitializer(constructor, callStructure);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeMemberNode(constructor);
+    callStructure.toDataSink(sink);
+    sink.end(tag);
+  }
+}
+
+class _TypeLiteral {
+  static const String tag = '_TypeLiteral';
+
+  final ir.DartType type;
+  final ir.LibraryDependency import;
+
+  _TypeLiteral(this.type, this.import);
+
+  factory _TypeLiteral.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType type = source.readDartTypeNode();
+    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
+    source.end(tag);
+    return new _TypeLiteral(type, import);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(type);
+    sink.writeLibraryDependencyNodeOrNull(import);
+    sink.end(tag);
+  }
+}
+
+class _GenericInstantiation {
+  static const String tag = '_GenericInstantiation';
+
+  final ir.FunctionType expressionType;
+  final List<ir.DartType> typeArguments;
+
+  _GenericInstantiation(this.expressionType, this.typeArguments);
+
+  factory _GenericInstantiation.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.FunctionType expressionType = source.readDartTypeNode();
+    List<ir.DartType> typeArguments = source.readDartTypeNodes();
+    source.end(tag);
+    return new _GenericInstantiation(expressionType, typeArguments);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(expressionType);
+    sink.writeDartTypeNodes(typeArguments);
+    sink.end(tag);
+  }
+}
+
+class _StaticAccess {
+  static const String tag = '_StaticAccess';
+
+  final ir.Member target;
+  final ir.LibraryDependency import;
+
+  _StaticAccess(this.target, this.import);
+
+  factory _StaticAccess.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.Member target = source.readMemberNode();
+    ir.LibraryDependency import = source.readLibraryDependencyNodeOrNull();
+    source.end(tag);
+    return new _StaticAccess(target, import);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeMemberNode(target);
+    sink.writeLibraryDependencyNodeOrNull(import);
+    sink.end(tag);
+  }
+}
+
+class _MapLiteral {
+  static const String tag = '_MapLiteral';
+
+  final ir.DartType keyType;
+  final ir.DartType valueType;
+  final bool isConst;
+  final bool isEmpty;
+
+  _MapLiteral(this.keyType, this.valueType, {this.isConst, this.isEmpty});
+
+  factory _MapLiteral.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType keyType = source.readDartTypeNode();
+    ir.DartType valueType = source.readDartTypeNode();
+    bool isConst = source.readBool();
+    bool isEmpty = source.readBool();
+    source.end(tag);
+    return _MapLiteral(keyType, valueType, isConst: isConst, isEmpty: isEmpty);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(keyType);
+    sink.writeDartTypeNode(valueType);
+    sink.writeBool(isConst);
+    sink.writeBool(isEmpty);
+    sink.end(tag);
+  }
+}
+
+class _ContainerLiteral {
+  static const String tag = '_ContainerLiteral';
+
+  final ir.DartType elementType;
+  final bool isConst;
+  final bool isEmpty;
+
+  _ContainerLiteral(this.elementType, {this.isConst, this.isEmpty});
+
+  factory _ContainerLiteral.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.DartType elementType = source.readDartTypeNode();
+    bool isConst = source.readBool();
+    bool isEmpty = source.readBool();
+    return new _ContainerLiteral(elementType,
+        isConst: isConst, isEmpty: isEmpty);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeDartTypeNode(elementType);
+    sink.writeBool(isConst);
+    sink.writeBool(isEmpty);
+    sink.end(tag);
+  }
+}
+
+class _RuntimeTypeUse {
+  static const String tag = '_RuntimeTypeUse';
+
+  final ir.PropertyGet node;
+  final RuntimeTypeUseKind kind;
+  final ir.DartType receiverType;
+  final ir.DartType argumentType;
+
+  _RuntimeTypeUse(this.node, this.kind, this.receiverType, this.argumentType);
+
+  factory _RuntimeTypeUse.fromDataSource(DataSource source) {
+    source.begin(tag);
+    ir.TreeNode node = source.readTreeNode();
+    RuntimeTypeUseKind kind = source.readEnum(RuntimeTypeUseKind.values);
+    ir.DartType receiverType = source.readDartTypeNode();
+    ir.DartType argumentType = source.readDartTypeNode(allowNull: true);
+    return new _RuntimeTypeUse(node, kind, receiverType, argumentType);
+  }
+
+  void toDataSink(DataSink sink) {
+    sink.begin(tag);
+    sink.writeTreeNode(node);
+    sink.writeEnum(kind);
+    sink.writeDartTypeNode(receiverType);
+    sink.writeDartTypeNode(argumentType, allowNull: true);
+    sink.end(tag);
+  }
+}
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 9ddc390..8ec8bad 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -903,6 +903,15 @@
     return super.visitListLiteral(node);
   }
 
+  void handleSetLiteral(ir.SetLiteral node) {}
+
+  @override
+  ir.DartType visitSetLiteral(ir.SetLiteral node) {
+    visitNodes(node.expressions);
+    handleSetLiteral(node);
+    return super.visitSetLiteral(node);
+  }
+
   void handleMapLiteral(ir.MapLiteral node) {}
 
   @override
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index 20cf00c..5cd8001 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -129,6 +129,11 @@
   }
 
   @override
+  ir.DartType visitSetLiteral(ir.SetLiteral node) {
+    return typeEnvironment.literalSetType(node.typeArgument);
+  }
+
+  @override
   ir.DartType visitMapLiteral(ir.MapLiteral node) {
     return typeEnvironment.literalMapType(node.keyType, node.valueType);
   }
diff --git a/pkg/compiler/lib/src/ir/types.dart b/pkg/compiler/lib/src/ir/types.dart
index 9d65dd7..6d0f40d 100644
--- a/pkg/compiler/lib/src/ir/types.dart
+++ b/pkg/compiler/lib/src/ir/types.dart
@@ -97,9 +97,7 @@
 class KernelOrderedTypeSetBuilder extends OrderedTypeSetBuilderBase {
   final IrToElementMap elementMap;
 
-  KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls)
-      : super(cls, elementMap.commonElements.objectType,
-            reporter: elementMap.reporter);
+  KernelOrderedTypeSetBuilder(this.elementMap, ClassEntity cls) : super(cls);
 
   InterfaceType getThisType(ClassEntity cls) {
     return elementMap.getThisType(cls);
diff --git a/pkg/compiler/lib/src/ir/util.dart b/pkg/compiler/lib/src/ir/util.dart
index f286702..0a749db 100644
--- a/pkg/compiler/lib/src/ir/util.dart
+++ b/pkg/compiler/lib/src/ir/util.dart
@@ -20,12 +20,17 @@
   return '(${node.runtimeType}:${node.hashCode})${blockText}';
 }
 
-/// Comparator for the canonical order or named arguments.
+/// Comparator for the canonical order or named parameters.
 // TODO(johnniwinther): Remove this when named parameters are sorted in dill.
 int namedOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
   return a.name.compareTo(b.name);
 }
 
+/// Comparator for the declaration order of parameters.
+int nativeOrdering(ir.VariableDeclaration a, ir.VariableDeclaration b) {
+  return a.fileOffset.compareTo(b.fileOffset);
+}
+
 SourceSpan computeSourceSpanFromTreeNode(ir.TreeNode node) {
   // TODO(johnniwinther): Use [ir.Location] directly as a [SourceSpan].
   Uri uri;
diff --git a/pkg/compiler/lib/src/js_backend/allocator_analysis.dart b/pkg/compiler/lib/src/js_backend/allocator_analysis.dart
index 787e64c..123f627 100644
--- a/pkg/compiler/lib/src/js_backend/allocator_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/allocator_analysis.dart
@@ -5,7 +5,8 @@
 import 'package:kernel/ast.dart' as ir;
 
 import '../constants/values.dart';
-import '../js_model/elements.dart' show JsToFrontendMap, JField;
+import '../js_model/elements.dart' show JField;
+import '../js_model/js_world_builder.dart';
 import '../kernel/element_map.dart';
 import '../kernel/kernel_strategy.dart';
 import '../kernel/kelements.dart' show KClass, KField;
@@ -77,6 +78,9 @@
       _fixedInitializers[_elementMap.getField(fieldNode)] = value;
     });
   }
+
+  ConstantValue getFixedInitializerForTesting(KField field) =>
+      _fixedInitializers[field];
 }
 
 class JAllocatorAnalysis implements AllocatorAnalysis {
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 15db202..5290143 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -11,6 +11,7 @@
 import '../elements/entities.dart';
 import '../kernel/dart2js_target.dart';
 import '../serialization/serialization.dart';
+import '../util/enumset.dart';
 
 /// Returns `true` if inference of parameter types is disabled for [element].
 bool _assumeDynamic(KElementEnvironment elementEnvironment,
@@ -34,14 +35,63 @@
   return false;
 }
 
-enum PragmaAnnotation {
-  noInline,
-  tryInline,
-  disableFinal,
-  noThrows,
-  noSideEffects,
-  trustTypeAnnotations,
-  assumeDynamic,
+class PragmaAnnotation {
+  final int _index;
+  final String name;
+  final bool forFunctionsOnly;
+  final bool forFieldsOnly;
+  final bool internalOnly;
+
+  const PragmaAnnotation(this._index, this.name,
+      {this.forFunctionsOnly: false,
+      this.forFieldsOnly: false,
+      this.internalOnly: false});
+
+  int get index {
+    assert(_index == values.indexOf(this));
+    return _index;
+  }
+
+  static const PragmaAnnotation noInline =
+      const PragmaAnnotation(0, 'noInline', forFunctionsOnly: true);
+
+  static const PragmaAnnotation tryInline =
+      const PragmaAnnotation(1, 'tryInline', forFunctionsOnly: true);
+
+  static const PragmaAnnotation disableFinal = const PragmaAnnotation(
+      2, 'disableFinal',
+      forFunctionsOnly: true, internalOnly: true);
+
+  static const PragmaAnnotation noElision = const PragmaAnnotation(
+      3, 'noElision',
+      forFieldsOnly: true, internalOnly: true);
+
+  static const PragmaAnnotation noThrows = const PragmaAnnotation(4, 'noThrows',
+      forFunctionsOnly: true, internalOnly: true);
+
+  static const PragmaAnnotation noSideEffects = const PragmaAnnotation(
+      5, 'noSideEffects',
+      forFunctionsOnly: true, internalOnly: true);
+
+  // TODO(johnniwinther): Remove this.
+  static const PragmaAnnotation trustTypeAnnotations = const PragmaAnnotation(
+      6, 'trustTypeAnnotations',
+      forFunctionsOnly: true, internalOnly: true);
+
+  static const PragmaAnnotation assumeDynamic = const PragmaAnnotation(
+      7, 'assumeDynamic',
+      forFunctionsOnly: true, internalOnly: true);
+
+  static const List<PragmaAnnotation> values = [
+    noInline,
+    tryInline,
+    disableFinal,
+    noElision,
+    noThrows,
+    noSideEffects,
+    trustTypeAnnotations,
+    assumeDynamic,
+  ];
 }
 
 Set<PragmaAnnotation> processMemberAnnotations(
@@ -50,31 +100,18 @@
     KElementEnvironment elementEnvironment,
     AnnotationsDataBuilder annotationsDataBuilder,
     MemberEntity element) {
-  Set<PragmaAnnotation> values = new Set<PragmaAnnotation>();
-  bool hasNoInline = false;
-  bool hasTryInline = false;
-  bool disableFinal = false;
+  EnumSet<PragmaAnnotation> values = new EnumSet<PragmaAnnotation>();
 
   if (_assumeDynamic(elementEnvironment, commonElements, element)) {
     values.add(PragmaAnnotation.assumeDynamic);
-    annotationsDataBuilder.registerAssumeDynamic(element);
   }
 
-  // TODO(sra): Check for inappropriate annotations on fields.
-  if (element.isField) {
-    return values;
-  }
-
-  FunctionEntity method = element;
   LibraryEntity library = element.library;
   bool platformAnnotationsAllowed = library.canonicalUri.scheme == 'dart' ||
       maybeEnableNative(library.canonicalUri);
 
-  bool hasNoThrows = false;
-  bool hasNoSideEffects = false;
-
   for (ConstantValue constantValue
-      in elementEnvironment.getMemberMetadata(method)) {
+      in elementEnvironment.getMemberMetadata(element)) {
     if (!constantValue.isConstructedObject) continue;
     ConstructedConstantValue value = constantValue;
     ClassEntity cls = value.type.element;
@@ -82,38 +119,65 @@
 
     if (platformAnnotationsAllowed) {
       if (cls == commonElements.forceInlineClass) {
-        hasTryInline = true;
+        values.add(PragmaAnnotation.tryInline);
+        if (element is! FunctionEntity) {
+          reporter.internalError(element,
+              "@TryInline() is only allowed in methods and constructors.");
+        }
       } else if (cls == commonElements.noInlineClass) {
-        hasNoInline = true;
+        values.add(PragmaAnnotation.noInline);
+        if (element is! FunctionEntity) {
+          reporter.internalError(element,
+              "@NoInline() is only allowed in methods and constructors.");
+        }
       } else if (cls == commonElements.noThrowsClass) {
-        hasNoThrows = true;
+        values.add(PragmaAnnotation.noThrows);
         bool isValid = true;
-        if (method.isTopLevel) {
-          isValid = true;
-        } else if (method.isStatic) {
-          isValid = true;
-        } else if (method is ConstructorEntity && method.isFactoryConstructor) {
-          isValid = true;
+        if (element is FunctionEntity) {
+          if (element.isTopLevel) {
+            isValid = true;
+          } else if (element.isStatic) {
+            isValid = true;
+          } else if (element is ConstructorEntity &&
+              element.isFactoryConstructor) {
+            isValid = true;
+          }
+        } else {
+          isValid = false;
         }
         if (!isValid) {
           reporter.internalError(
-              method,
+              element,
               "@NoThrows() is currently limited to top-level"
               " or static functions and factory constructors.");
         }
-        annotationsDataBuilder.registerCannotThrow(method);
       } else if (cls == commonElements.noSideEffectsClass) {
-        hasNoSideEffects = true;
-        annotationsDataBuilder.registerSideEffectsFree(method);
+        values.add(PragmaAnnotation.noSideEffects);
+        if (element is! FunctionEntity) {
+          reporter.internalError(element,
+              "@NoSideEffects() is only allowed in methods and constructors.");
+        }
       }
     }
 
     if (cls == commonElements.expectNoInlineClass) {
-      hasNoInline = true;
+      values.add(PragmaAnnotation.noInline);
+      if (element is! FunctionEntity) {
+        reporter.internalError(element,
+            "@NoInline() is only allowed in methods and constructors.");
+      }
     } else if (cls == commonElements.metaNoInlineClass) {
-      hasNoInline = true;
+      values.add(PragmaAnnotation.noInline);
+      if (element is! FunctionEntity) {
+        reporter.internalError(
+            element, "@noInline is only allowed in methods and constructors.");
+      }
     } else if (cls == commonElements.metaTryInlineClass) {
-      hasTryInline = true;
+      values.add(PragmaAnnotation.tryInline);
+      if (element is! FunctionEntity) {
+        reporter.internalError(
+            element, "@tryInline is only allowed in methods and constructors.");
+      }
     } else if (cls == commonElements.pragmaClass) {
       // Recognize:
       //
@@ -124,64 +188,71 @@
           value.fields[commonElements.pragmaClassNameField];
       if (nameValue == null || !nameValue.isString) continue;
       String name = (nameValue as StringConstantValue).stringValue;
-      if (!name.startsWith('dart2js:')) continue;
+      String prefix = 'dart2js:';
+      if (!name.startsWith(prefix)) continue;
+      String suffix = name.substring(prefix.length);
 
       ConstantValue optionsValue =
           value.fields[commonElements.pragmaClassOptionsField];
-      if (name == 'dart2js:noInline') {
-        if (!optionsValue.isNull) {
-          reporter.reportErrorMessage(element, MessageKind.GENERIC,
-              {'text': "@pragma('$name') annotation does not take options"});
-        }
-        hasNoInline = true;
-      } else if (name == 'dart2js:tryInline') {
-        if (!optionsValue.isNull) {
-          reporter.reportErrorMessage(element, MessageKind.GENERIC,
-              {'text': "@pragma('$name') annotation does not take options"});
-        }
-        hasTryInline = true;
-      } else if (!platformAnnotationsAllowed) {
-        reporter.reportErrorMessage(element, MessageKind.GENERIC,
-            {'text': "Unknown dart2js pragma @pragma('$name')"});
-      } else {
-        // Handle platform-only `@pragma` annotations.
-        if (name == 'dart2js:disableFinal') {
+      bool found = false;
+      for (PragmaAnnotation annotation in PragmaAnnotation.values) {
+        if (annotation.name == suffix) {
+          found = true;
+          values.add(annotation);
+
           if (!optionsValue.isNull) {
             reporter.reportErrorMessage(element, MessageKind.GENERIC,
                 {'text': "@pragma('$name') annotation does not take options"});
           }
-          disableFinal = true;
+          if (annotation.forFunctionsOnly) {
+            if (element is! FunctionEntity) {
+              reporter.reportErrorMessage(element, MessageKind.GENERIC, {
+                'text': "@pragma('$name') annotation is only supported "
+                    "for methods and constructors."
+              });
+            }
+          }
+          if (annotation.forFieldsOnly) {
+            if (element is! FieldEntity) {
+              reporter.reportErrorMessage(element, MessageKind.GENERIC, {
+                'text': "@pragma('$name') annotation is only supported "
+                    "for fields."
+              });
+            }
+          }
+          if (annotation.internalOnly && !platformAnnotationsAllowed) {
+            reporter.reportErrorMessage(element, MessageKind.GENERIC,
+                {'text': "Unrecognized dart2js pragma @pragma('$name')"});
+          }
+          break;
         }
       }
+      if (!found) {
+        reporter.reportErrorMessage(element, MessageKind.GENERIC,
+            {'text': "Unknown dart2js pragma @pragma('$name')"});
+      }
     }
   }
 
-  if (hasTryInline && hasNoInline) {
+  if (values.contains(PragmaAnnotation.tryInline) &&
+      values.contains(PragmaAnnotation.noInline)) {
     reporter.reportErrorMessage(element, MessageKind.GENERIC,
         {'text': '@tryInline must not be used with @noInline.'});
-    hasTryInline = false;
+    values.remove(PragmaAnnotation.tryInline);
   }
-  if (hasNoInline) {
-    values.add(PragmaAnnotation.noInline);
-    annotationsDataBuilder.markAsNonInlinable(method);
-  }
-  if (hasTryInline) {
-    values.add(PragmaAnnotation.tryInline);
-    annotationsDataBuilder.markAsTryInline(method);
-  }
-  if (disableFinal) {
-    values.add(PragmaAnnotation.disableFinal);
-    annotationsDataBuilder.markAsDisableFinal(method);
-  }
-  if (hasNoThrows && !hasNoInline) {
+  if (values.contains(PragmaAnnotation.noThrows) &&
+      !values.contains(PragmaAnnotation.noInline)) {
     reporter.internalError(
-        method, "@NoThrows() should always be combined with @noInline.");
+        element, "@NoThrows() should always be combined with @noInline.");
   }
-  if (hasNoSideEffects && !hasNoInline) {
+  if (values.contains(PragmaAnnotation.noSideEffects) &&
+      !values.contains(PragmaAnnotation.noInline)) {
     reporter.internalError(
-        method, "@NoSideEffects() should always be combined with @noInline.");
+        element, "@NoSideEffects() should always be combined with @noInline.");
   }
-  return values;
+  annotationsDataBuilder.registerPragmaAnnotations(element, values);
+  return new Set<PragmaAnnotation>.from(
+      values.iterable(PragmaAnnotation.values));
 }
 
 abstract class AnnotationsData {
@@ -192,25 +263,43 @@
   /// Serializes this [AnnotationsData] to [sink].
   void writeToDataSink(DataSink sink);
 
-  /// Functions with a `@NoInline()`, `@noInline`, or
+  /// Returns `true` if [member] has an `@AssumeDynamic()` annotation.
+  bool hasAssumeDynamic(MemberEntity member);
+
+  /// Returns `true` if [member] has a `@NoInline()`, `@noInline`, or
   /// `@pragma('dart2js:noInline')` annotation.
-  Iterable<FunctionEntity> get nonInlinableFunctions;
+  bool hasNoInline(MemberEntity member);
 
-  /// Functions with a `@ForceInline()`, `@tryInline`, or
+  /// Returns `true` if [member] has a `@ForceInline()`, `@tryInline`, or
   /// `@pragma('dart2js:tryInline')` annotation.
-  Iterable<FunctionEntity> get tryInlineFunctions;
+  bool hasTryInline(MemberEntity member);
 
-  /// Functions with a `@pragma('dart2js:disable-final')` annotation.
-  Iterable<FunctionEntity> get disableFinalFunctions;
+  /// Returns `true` if [member] has a `@pragma('dart2js:disableFinal')`
+  /// annotation.
+  bool hasDisableFinal(MemberEntity member);
 
-  /// Functions with a `@NoThrows()` annotation.
-  Iterable<FunctionEntity> get cannotThrowFunctions;
+  /// Returns `true` if [member] has a `@pragma('dart2js:noElision')` annotation.
+  bool hasNoElision(MemberEntity member);
 
-  /// Functions with a `@NoSideEffects()` annotation.
-  Iterable<FunctionEntity> get sideEffectFreeFunctions;
+  /// Returns `true` if [member] has a `@NoThrows()` annotation.
+  bool hasNoThrows(MemberEntity member);
 
-  /// Members with a `@AssumeDynamic()` annotation.
-  Iterable<MemberEntity> get assumeDynamicMembers;
+  /// Returns `true` if [member] has a `@NoSideEffects()` annotation.
+  bool hasNoSideEffects(MemberEntity member);
+
+  /// Calls [f] for all functions with a `@NoInline()`, `@noInline`, or
+  /// `@pragma('dart2js:noInline')` annotation.
+  void forEachNoInline(void f(FunctionEntity function));
+
+  /// Calls [f] for all functions with a `@ForceInline()`, `@tryInline`, or
+  /// `@pragma('dart2js:tryInline')` annotation.
+  void forEachTryInline(void f(FunctionEntity function));
+
+  /// Calls [f] for all functions with a `@NoThrows()` annotation.
+  void forEachNoThrows(void f(FunctionEntity function));
+
+  /// Calls [f] for all functions with a `@NoSideEffects()` annotation.
+  void forEachNoSideEffects(void f(FunctionEntity function));
 }
 
 class AnnotationsDataImpl implements AnnotationsData {
@@ -218,118 +307,100 @@
   /// debugging data stream.
   static const String tag = 'annotations-data';
 
-  final Iterable<FunctionEntity> nonInlinableFunctions;
-  final Iterable<FunctionEntity> tryInlineFunctions;
-  final Iterable<FunctionEntity> disableFinalFunctions;
-  final Iterable<FunctionEntity> cannotThrowFunctions;
-  final Iterable<FunctionEntity> sideEffectFreeFunctions;
-  final Iterable<MemberEntity> assumeDynamicMembers;
+  final Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations;
 
-  AnnotationsDataImpl(
-      this.nonInlinableFunctions,
-      this.tryInlineFunctions,
-      this.disableFinalFunctions,
-      this.cannotThrowFunctions,
-      this.sideEffectFreeFunctions,
-      this.assumeDynamicMembers);
+  AnnotationsDataImpl(this.pragmaAnnotations);
 
   factory AnnotationsDataImpl.readFromDataSource(DataSource source) {
     source.begin(tag);
-    Iterable<FunctionEntity> nonInlinableFunctions =
-        source.readMembers<FunctionEntity>(emptyAsNull: true) ??
-            const <FunctionEntity>[];
-    Iterable<FunctionEntity> tryInlineFunctions =
-        source.readMembers<FunctionEntity>(emptyAsNull: true) ??
-            const <FunctionEntity>[];
-    Iterable<FunctionEntity> disableFinalFunctions =
-        source.readMembers<FunctionEntity>(emptyAsNull: true) ??
-            const <FunctionEntity>[];
-    Iterable<FunctionEntity> cannotThrowFunctions =
-        source.readMembers<FunctionEntity>(emptyAsNull: true) ??
-            const <FunctionEntity>[];
-    Iterable<FunctionEntity> sideEffectFreeFunctions =
-        source.readMembers<FunctionEntity>(emptyAsNull: true) ??
-            const <FunctionEntity>[];
-    Iterable<MemberEntity> assumeDynamicMembers =
-        source.readMembers<MemberEntity>(emptyAsNull: true) ??
-            const <MemberEntity>[];
+    Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations =
+        source.readMemberMap(() => new EnumSet.fromValue(source.readInt()));
     source.end(tag);
-    return new AnnotationsDataImpl(
-        nonInlinableFunctions,
-        tryInlineFunctions,
-        disableFinalFunctions,
-        cannotThrowFunctions,
-        sideEffectFreeFunctions,
-        assumeDynamicMembers);
+    return new AnnotationsDataImpl(pragmaAnnotations);
   }
 
   void writeToDataSink(DataSink sink) {
     sink.begin(tag);
-    sink.writeMembers(nonInlinableFunctions);
-    sink.writeMembers(tryInlineFunctions);
-    sink.writeMembers(disableFinalFunctions);
-    sink.writeMembers(cannotThrowFunctions);
-    sink.writeMembers(sideEffectFreeFunctions);
-    sink.writeMembers(assumeDynamicMembers);
+    sink.writeMemberMap(pragmaAnnotations, (EnumSet<PragmaAnnotation> set) {
+      sink.writeInt(set.value);
+    });
     sink.end(tag);
   }
+
+  bool _hasPragma(MemberEntity member, PragmaAnnotation annotation) {
+    EnumSet<PragmaAnnotation> set = pragmaAnnotations[member];
+    return set != null && set.contains(annotation);
+  }
+
+  bool hasAssumeDynamic(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.assumeDynamic);
+
+  bool hasNoInline(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.noInline);
+
+  bool hasTryInline(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.tryInline);
+
+  bool hasDisableFinal(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.disableFinal);
+
+  bool hasNoElision(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.noElision);
+
+  bool hasNoThrows(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.noThrows);
+
+  bool hasNoSideEffects(MemberEntity member) =>
+      _hasPragma(member, PragmaAnnotation.noSideEffects);
+
+  void forEachNoInline(void f(FunctionEntity function)) {
+    pragmaAnnotations
+        .forEach((MemberEntity member, EnumSet<PragmaAnnotation> set) {
+      if (set.contains(PragmaAnnotation.noInline)) {
+        f(member);
+      }
+    });
+  }
+
+  void forEachTryInline(void f(FunctionEntity function)) {
+    pragmaAnnotations
+        .forEach((MemberEntity member, EnumSet<PragmaAnnotation> set) {
+      if (set.contains(PragmaAnnotation.tryInline)) {
+        f(member);
+      }
+    });
+  }
+
+  void forEachNoThrows(void f(FunctionEntity function)) {
+    pragmaAnnotations
+        .forEach((MemberEntity member, EnumSet<PragmaAnnotation> set) {
+      if (set.contains(PragmaAnnotation.noThrows)) {
+        f(member);
+      }
+    });
+  }
+
+  void forEachNoSideEffects(void f(FunctionEntity function)) {
+    pragmaAnnotations
+        .forEach((MemberEntity member, EnumSet<PragmaAnnotation> set) {
+      if (set.contains(PragmaAnnotation.noSideEffects)) {
+        f(member);
+      }
+    });
+  }
 }
 
-class AnnotationsDataBuilder implements AnnotationsData {
-  List<FunctionEntity> _nonInlinableFunctions;
-  List<FunctionEntity> _tryInlinableFunctions;
-  List<FunctionEntity> _disableFinalFunctions;
-  List<FunctionEntity> _cannotThrowFunctions;
-  List<FunctionEntity> _sideEffectFreeFunctions;
-  List<MemberEntity> _trustTypeAnnotationsMembers;
-  List<MemberEntity> _assumeDynamicMembers;
+class AnnotationsDataBuilder {
+  Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations = {};
 
-  void markAsNonInlinable(FunctionEntity function) {
-    _nonInlinableFunctions ??= <FunctionEntity>[];
-    _nonInlinableFunctions.add(function);
+  void registerPragmaAnnotations(
+      MemberEntity member, EnumSet<PragmaAnnotation> annotations) {
+    if (annotations.isNotEmpty) {
+      pragmaAnnotations[member] = annotations;
+    }
   }
 
-  void markAsTryInline(FunctionEntity function) {
-    _tryInlinableFunctions ??= <FunctionEntity>[];
-    _tryInlinableFunctions.add(function);
-  }
-
-  void markAsDisableFinal(FunctionEntity function) {
-    _disableFinalFunctions ??= <FunctionEntity>[];
-    _disableFinalFunctions.add(function);
-  }
-
-  void registerCannotThrow(FunctionEntity function) {
-    _cannotThrowFunctions ??= <FunctionEntity>[];
-    _cannotThrowFunctions.add(function);
-  }
-
-  void registerSideEffectsFree(FunctionEntity function) {
-    _sideEffectFreeFunctions ??= <FunctionEntity>[];
-    _sideEffectFreeFunctions.add(function);
-  }
-
-  void registerAssumeDynamic(MemberEntity member) {
-    _assumeDynamicMembers ??= <MemberEntity>[];
-    _assumeDynamicMembers.add(member);
-  }
-
-  Iterable<FunctionEntity> get nonInlinableFunctions =>
-      _nonInlinableFunctions ?? const <FunctionEntity>[];
-  Iterable<FunctionEntity> get tryInlineFunctions =>
-      _tryInlinableFunctions ?? const <FunctionEntity>[];
-  Iterable<FunctionEntity> get disableFinalFunctions =>
-      _disableFinalFunctions ?? const <FunctionEntity>[];
-  Iterable<FunctionEntity> get cannotThrowFunctions =>
-      _cannotThrowFunctions ?? const <FunctionEntity>[];
-  Iterable<FunctionEntity> get sideEffectFreeFunctions =>
-      _sideEffectFreeFunctions ?? const <FunctionEntity>[];
-  Iterable<MemberEntity> get trustTypeAnnotationsMembers =>
-      _trustTypeAnnotationsMembers ?? const <MemberEntity>[];
-  Iterable<MemberEntity> get assumeDynamicMembers =>
-      _assumeDynamicMembers ?? const <MemberEntity>[];
-
-  void writeToDataSink(DataSink sink) {
-    throw new UnsupportedError('AnnotationsDataBuilder.writeToDataSink');
+  AnnotationsData close() {
+    return new AnnotationsDataImpl(pragmaAnnotations);
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index be118eb..5d868e8 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -95,10 +95,10 @@
   final Set<FunctionEntity> _tryInlineFunctions = new Set<FunctionEntity>();
 
   FunctionInlineCache(AnnotationsData annotationsData) {
-    annotationsData.nonInlinableFunctions.forEach((FunctionEntity function) {
+    annotationsData.forEachNoInline((FunctionEntity function) {
       markAsNonInlinable(function);
     });
-    annotationsData.tryInlineFunctions.forEach((FunctionEntity function) {
+    annotationsData.forEachTryInline((FunctionEntity function) {
       markAsTryInline(function);
     });
   }
@@ -408,6 +408,9 @@
 
   ImpactCacheDeleter get impactCacheDeleter => compiler.impactCacheDeleter;
 
+  KAllocatorAnalysis get allocatorResolutionAnalysisForTesting =>
+      _allocatorResolutionAnalysis;
+
   /// Resolution support for generating table of interceptors and
   /// constructors for custom elements.
   CustomElementsResolutionAnalysis get customElementsResolutionAnalysis {
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index d276f51..57e2fc0 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -173,19 +173,17 @@
     if (type is InterfaceType) {
       impactBuilder.registerTypeUse(new TypeUse.instantiation(type));
       if (_rtiNeed.classNeedsTypeArguments(type.element)) {
+        FunctionEntity helper = _commonElements.setRuntimeTypeInfo;
         impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            // TODO(johnniwinther): Find the right [CallStructure].
-            _commonElements.setRuntimeTypeInfo,
-            null));
+            helper, helper.parameterStructure.callStructure));
       }
       if (type.element == _commonElements.typeLiteralClass) {
         // If we use a type literal in a constant, the compile time
         // constant emitter will generate a call to the createRuntimeType
         // helper so we register a use of that.
+        FunctionEntity helper = _commonElements.createRuntimeType;
         impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            // TODO(johnniwinther): Find the right [CallStructure].
-            _commonElements.createRuntimeType,
-            null));
+            helper, helper.parameterStructure.callStructure));
       }
     }
   }
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 3fb4475..e705bb1 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -224,7 +224,8 @@
     // are in the same order as the members of the class element.
     int emittedArgumentCount = 0;
     _worldBuilder.forEachInstanceField(classElement,
-        (ClassEntity enclosing, FieldEntity field) {
+        (ClassEntity enclosing, FieldEntity field, {bool isElided}) {
+      if (isElided) return;
       if (field.name == JavaScriptMapConstant.LENGTH_NAME) {
         arguments
             .add(new jsAst.LiteralNumber('${constant.keyList.entries.length}'));
@@ -318,7 +319,9 @@
     jsAst.Expression constructor =
         _emitter.constructorAccess(constant.type.element);
     List<jsAst.Expression> fields = <jsAst.Expression>[];
-    _worldBuilder.forEachInstanceField(element, (_, FieldEntity field) {
+    _worldBuilder.forEachInstanceField(element, (_, FieldEntity field,
+        {bool isElided}) {
+      if (isElided) return;
       if (!_allocatorAnalysis.isInitializedInAllocator(field)) {
         fields.add(constantReferenceGenerator(constant.fields[field]));
       }
diff --git a/pkg/compiler/lib/src/js_backend/inferred_data.dart b/pkg/compiler/lib/src/js_backend/inferred_data.dart
index d68b500..ad5be30 100644
--- a/pkg/compiler/lib/src/js_backend/inferred_data.dart
+++ b/pkg/compiler/lib/src/js_backend/inferred_data.dart
@@ -218,8 +218,8 @@
       new Set<FunctionEntity>();
 
   InferredDataBuilderImpl(AnnotationsData annotationsData) {
-    annotationsData.cannotThrowFunctions.forEach(registerCannotThrow);
-    annotationsData.sideEffectFreeFunctions.forEach(registerSideEffectsFree);
+    annotationsData.forEachNoThrows(registerCannotThrow);
+    annotationsData.forEachNoSideEffects(registerSideEffectsFree);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 9e7a95b..51674ab 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -2008,8 +2008,9 @@
 
     // TODO(johnniwinther): This should be accessed from a codegen closed world.
     codegenWorldBuilder.forEachInstanceField(constant.type.element,
-        (_, FieldEntity field) {
+        (_, FieldEntity field, {bool isElided}) {
       if (failed) return;
+      if (isElided) return;
       _visit(constant.fields[field]);
     });
   }
@@ -2147,7 +2148,8 @@
   int visitConstructed(ConstructedConstantValue constant, [_]) {
     int hash = _hashString(3, constant.type.element.name);
     codegenWorldBuilder.forEachInstanceField(constant.type.element,
-        (_, FieldEntity field) {
+        (_, FieldEntity field, {bool isElided}) {
+      if (isElided) return;
       hash = _combine(hash, _visit(constant.fields[field]));
     });
     return hash;
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index 8f18ffb..9c2fc09 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -215,9 +215,7 @@
     } else if (constant.isType) {
       FunctionEntity helper = _commonElements.createRuntimeType;
       impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-          // TODO(johnniwinther): Find the right [CallStructure].
-          helper,
-          null));
+          helper, helper.parameterStructure.callStructure));
       _backendUsage.registerBackendFunctionUse(helper);
       impactBuilder
           .registerTypeUse(new TypeUse.instantiation(_commonElements.typeType));
@@ -232,10 +230,9 @@
         // If we use a type literal in a constant, the compile time
         // constant emitter will generate a call to the createRuntimeType
         // helper so we register a use of that.
+        FunctionEntity helper = _commonElements.createRuntimeType;
         impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            // TODO(johnniwinther): Find the right [CallStructure].
-            _commonElements.createRuntimeType,
-            null));
+            helper, helper.parameterStructure.callStructure));
       }
     }
   }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index ec375e0..b9a0d33 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -813,7 +813,6 @@
   }
 
   bool methodNeedsTypeArguments(FunctionEntity function) {
-    if (function.parameterStructure.typeParameters == 0) return false;
     return methodsNeedingTypeArguments.contains(function);
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index e6fbf87..e44e0a8 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -139,7 +139,8 @@
     // 2. Find the function field access path.
     FieldEntity functionField;
     _codegenWorldBuilder.forEachInstanceField(instantiationClass,
-        (ClassEntity enclosing, FieldEntity field) {
+        (ClassEntity enclosing, FieldEntity field, {bool isElided}) {
+      if (isElided) return;
       if (field.name == '_genericClosure') functionField = field;
     });
     assert(functionField != null,
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 7829d79..9fb47bc 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -384,9 +384,18 @@
 
   final ConstantValue initializerInAllocator;
 
+  final bool isElided;
+
   // TODO(floitsch): support renamed fields.
-  Field(this.element, this.name, this.accessorName, this.getterFlags,
-      this.setterFlags, this.needsCheckedSetter, this.initializerInAllocator);
+  Field(
+      this.element,
+      this.name,
+      this.accessorName,
+      this.getterFlags,
+      this.setterFlags,
+      this.needsCheckedSetter,
+      this.initializerInAllocator,
+      this.isElided);
 
   bool get needsGetter => getterFlags != 0;
   bool get needsUncheckedSetter => setterFlags != 0;
@@ -545,8 +554,9 @@
   /// If a stub's member can not be torn off, the [callName] is `null`.
   js.Name callName;
 
-  ParameterStubMethod(js.Name name, this.callName, js.Expression code)
-      : super(name, code);
+  ParameterStubMethod(js.Name name, this.callName, js.Expression code,
+      {MemberEntity element})
+      : super(name, code, element: element);
 
   String toString() {
     return 'ParameterStubMethod(name=${name.key}, callName=${callName?.key}'
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index ac44280..dd65523 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -226,7 +226,7 @@
     jsAst.Name name = member.isStatic ? null : _namer.invocationName(selector);
     jsAst.Name callName =
         (callSelector != null) ? _namer.invocationName(callSelector) : null;
-    return new ParameterStubMethod(name, callName, function);
+    return new ParameterStubMethod(name, callName, function, element: member);
   }
 
   // We fill the lists depending on possible/invoked selectors. For example,
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 023faf2..b981d83 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
@@ -1072,8 +1072,15 @@
         initializerInAllocator = _allocatorAnalysis.initializerValue(field);
       }
 
-      fields.add(new Field(field, name, accessorName, getterFlags, setterFlags,
-          needsCheckedSetter, initializerInAllocator));
+      fields.add(new Field(
+          field,
+          name,
+          accessorName,
+          getterFlags,
+          setterFlags,
+          needsCheckedSetter,
+          initializerInAllocator,
+          _closedWorld.elidedFields.contains(field)));
     }
 
     FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment,
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 8e5224c..965e232 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -918,8 +918,10 @@
       statements.add(js.js.statement('allocations["$qualifiedName"] = true'));
     }
 
+    List<Field> emittedFields = cls.fields.where((f) => !f.isElided).toList();
+
     // If there are many references to `this`, cache it in a local.
-    if (cls.fields.length + (cls.hasRtiField ? 1 : 0) >= 4) {
+    if (emittedFields.length + (cls.hasRtiField ? 1 : 0) >= 4) {
       // Parameters are named t0, t1, etc, so '_' will not conflict. Forcing '_'
       // in minified mode works because no parameter or local also minifies to
       // '_' (the minifier doesn't know '_' is available).
@@ -945,7 +947,7 @@
       }
     }
 
-    for (Field field in cls.fields) {
+    for (Field field in emittedFields) {
       ConstantValue constant = field.initializerInAllocator;
       if (constant != null) {
         if (constant == previousConstant && chainLength < maxChainLength) {
@@ -1096,17 +1098,22 @@
     assert(field.needsUncheckedSetter);
 
     String template;
-    if (field.needsInterceptedSetterOnReceiver) {
-      template = "function(receiver, val) { return receiver[#] = val; }";
-    } else if (field.needsInterceptedSetterOnThis) {
-      template = "function(receiver, val) { return this[#] = val; }";
+    js.Expression code;
+    if (field.isElided) {
+      code = js.js("function() { }");
     } else {
-      assert(!field.needsInterceptedSetter);
-      template = "function(val) { return this[#] = val; }";
+      if (field.needsInterceptedSetterOnReceiver) {
+        template = "function(receiver, val) { return receiver[#] = val; }";
+      } else if (field.needsInterceptedSetterOnThis) {
+        template = "function(receiver, val) { return this[#] = val; }";
+      } else {
+        assert(!field.needsInterceptedSetter);
+        template = "function(val) { return this[#] = val; }";
+      }
+      js.Expression fieldName = js.quoteName(field.name);
+      code = js.js(template, fieldName);
     }
 
-    js.Expression fieldName = js.quoteName(field.name);
-    js.Expression code = js.js(template, fieldName);
     js.Name setterName = namer.deriveSetterName(field.accessorName);
     return new StubMethod(setterName, code);
   }
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 1afc338..5057b6a 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -13,7 +13,6 @@
 import '../elements/types.dart';
 import '../ir/closure.dart';
 import '../ir/element_map.dart';
-import '../ir/util.dart';
 import '../js_model/element_map.dart';
 import '../js_model/env.dart';
 import '../ordered_typeset.dart';
@@ -1032,7 +1031,7 @@
 }
 
 class ClosureFunctionData extends ClosureMemberData
-    with FunctionDataMixin
+    with FunctionDataTypeVariablesMixin, FunctionDataForEachParameterMixin
     implements FunctionData {
   /// Tag used for identifying serialized [ClosureFunctionData] objects in a
   /// debugging data stream.
@@ -1075,31 +1074,6 @@
     sink.end(tag);
   }
 
-  void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
-    void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
-      DartType type = elementMap.getDartType(node.type);
-      String name = node.name;
-      ConstantValue defaultValue;
-      if (isOptional) {
-        if (node.initializer != null) {
-          defaultValue = elementMap.getConstantValue(node.initializer);
-        } else {
-          defaultValue = new NullConstantValue();
-        }
-      }
-      f(type, name, defaultValue);
-    }
-
-    for (int i = 0; i < functionNode.positionalParameters.length; i++) {
-      handleParameter(functionNode.positionalParameters[i],
-          isOptional: i >= functionNode.requiredParameterCount);
-    }
-    functionNode.namedParameters.toList()
-      ..sort(namedOrdering)
-      ..forEach(handleParameter);
-  }
-
   @override
   FunctionType getFunctionType(IrToElementMap elementMap) {
     return functionType;
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index f0b0efd..b495237 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -524,3 +524,83 @@
   }
   return node.initializer;
 }
+
+void forEachOrderedParameterByFunctionNode(
+    ir.FunctionNode node,
+    ParameterStructure parameterStructure,
+    void f(ir.VariableDeclaration parameter, {bool isOptional, bool isElided}),
+    {bool useNativeOrdering: false}) {
+  for (int position = 0;
+      position < node.positionalParameters.length;
+      position++) {
+    ir.VariableDeclaration variable = node.positionalParameters[position];
+    f(variable,
+        isOptional: position >= parameterStructure.requiredParameters,
+        isElided: position >= parameterStructure.positionalParameters);
+  }
+
+  if (node.namedParameters.isEmpty) {
+    return;
+  }
+
+  List<ir.VariableDeclaration> namedParameters = node.namedParameters.toList();
+  if (useNativeOrdering) {
+    namedParameters.sort(nativeOrdering);
+  } else {
+    namedParameters.sort(namedOrdering);
+  }
+  for (ir.VariableDeclaration variable in namedParameters) {
+    f(variable,
+        isOptional: true,
+        isElided: !parameterStructure.namedParameters.contains(variable.name));
+  }
+}
+
+void forEachOrderedParameter(JsToElementMap elementMap, FunctionEntity function,
+    void f(ir.VariableDeclaration parameter, {bool isElided})) {
+  ParameterStructure parameterStructure = function.parameterStructure;
+
+  void handleParameter(ir.VariableDeclaration parameter,
+      {bool isOptional, bool isElided}) {
+    f(parameter, isElided: isElided);
+  }
+
+  MemberDefinition definition = elementMap.getMemberDefinition(function);
+  switch (definition.kind) {
+    case MemberKind.regular:
+      ir.Node node = definition.node;
+      if (node is ir.Procedure) {
+        forEachOrderedParameterByFunctionNode(
+            node.function, parameterStructure, handleParameter);
+        return;
+      }
+      break;
+    case MemberKind.constructor:
+    case MemberKind.constructorBody:
+      ir.Node node = definition.node;
+      if (node is ir.Procedure) {
+        forEachOrderedParameterByFunctionNode(
+            node.function, parameterStructure, handleParameter);
+        return;
+      } else if (node is ir.Constructor) {
+        forEachOrderedParameterByFunctionNode(
+            node.function, parameterStructure, handleParameter);
+        return;
+      }
+      break;
+    case MemberKind.closureCall:
+      ir.Node node = definition.node;
+      if (node is ir.FunctionDeclaration) {
+        forEachOrderedParameterByFunctionNode(
+            node.function, parameterStructure, handleParameter);
+        return;
+      } else if (node is ir.FunctionExpression) {
+        forEachOrderedParameterByFunctionNode(
+            node.function, parameterStructure, handleParameter);
+        return;
+      }
+      break;
+    default:
+  }
+  failedAt(function, "Unexpected function definition $definition.");
+}
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 47433bc..ad03cc0 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -50,6 +50,7 @@
 import '../serialization/serialization.dart';
 import '../ssa/type_builder.dart';
 import '../universe/call_structure.dart';
+import '../universe/member_usage.dart';
 import '../universe/selector.dart';
 
 import 'closure.dart';
@@ -69,7 +70,8 @@
   /// Calls [f] for each parameter of [function] providing the type and name of
   /// the parameter and the [defaultValue] if the parameter is optional.
   void forEachParameter(FunctionEntity function,
-      void f(DartType type, String name, ConstantValue defaultValue));
+      void f(DartType type, String name, ConstantValue defaultValue),
+      {bool isNative: false});
 }
 
 class JsKernelToElementMap
@@ -143,8 +145,11 @@
 
   Map<IndexedClass, List<IndexedMember>> _injectedClassMembers = {};
 
-  JsKernelToElementMap(this.reporter, Environment environment,
-      KernelToElementMapImpl _elementMap, Iterable<MemberEntity> liveMembers)
+  JsKernelToElementMap(
+      this.reporter,
+      Environment environment,
+      KernelToElementMapImpl _elementMap,
+      Map<MemberEntity, MemberUsage> liveMemberUsage)
       : this.options = _elementMap.options {
     _elementEnvironment = new JsElementEnvironment(this);
     _commonElements = new CommonElementsImpl(_elementEnvironment);
@@ -160,7 +165,7 @@
       KLibraryEnv oldEnv = _elementMap.libraries.getEnv(oldLibrary);
       KLibraryData data = _elementMap.libraries.getData(oldLibrary);
       IndexedLibrary newLibrary = convertLibrary(oldLibrary);
-      JLibraryEnv newEnv = oldEnv.convert(_elementMap, liveMembers);
+      JLibraryEnv newEnv = oldEnv.convert(_elementMap, liveMemberUsage);
       libraryMap[oldEnv.library] =
           libraries.register<IndexedLibrary, JLibraryData, JLibraryEnv>(
               newLibrary, data.convert(), newEnv);
@@ -177,7 +182,7 @@
       IndexedLibrary oldLibrary = oldClass.library;
       LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
       IndexedClass newClass = convertClass(newLibrary, oldClass);
-      JClassEnv newEnv = env.convert(_elementMap, liveMembers);
+      JClassEnv newEnv = env.convert(_elementMap, liveMemberUsage);
       classMap[env.cls] = classes.register(newClass, data.convert(), newEnv);
       assert(newClass.classIndex == oldClass.classIndex);
       libraries.getEnv(newClass.library).registerClass(newClass.name, newEnv);
@@ -205,7 +210,8 @@
         memberIndex < _elementMap.members.length;
         memberIndex++) {
       IndexedMember oldMember = _elementMap.members.getEntity(memberIndex);
-      if (!liveMembers.contains(oldMember)) {
+      MemberUsage memberUsage = liveMemberUsage[oldMember];
+      if (memberUsage == null) {
         members.skipIndex(oldMember.memberIndex);
         continue;
       }
@@ -215,9 +221,14 @@
       LibraryEntity newLibrary = libraries.getEntity(oldLibrary.libraryIndex);
       ClassEntity newClass =
           oldClass != null ? classes.getEntity(oldClass.classIndex) : null;
-      IndexedMember newMember = convertMember(newLibrary, newClass, oldMember);
+      IndexedMember newMember =
+          convertMember(newLibrary, newClass, oldMember, memberUsage);
       members.register(newMember, data.convert());
-      assert(newMember.memberIndex == oldMember.memberIndex);
+      assert(
+          newMember.memberIndex == oldMember.memberIndex,
+          "Member index mismatch: "
+          "Old member $oldMember has index ${oldMember.memberIndex} "
+          "whereas new member $newMember has index ${newMember.memberIndex}");
       if (newMember.isField) {
         fieldMap[data.node] = newMember;
       } else if (newMember.isConstructor) {
@@ -1119,20 +1130,6 @@
         argumentCount, namedArguments, arguments.types.length);
   }
 
-  ParameterStructure getParameterStructure(ir.FunctionNode node,
-      // TODO(johnniwinther): Remove this when type arguments are passed to
-      // constructors like calling a generic method.
-      {bool includeTypeParameters: true}) {
-    // TODO(johnniwinther): Cache the computed function type.
-    int requiredParameters = 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);
-  }
-
   Selector getSelector(ir.Expression node) {
     // TODO(efortuna): This is screaming for a common interface between
     // PropertyGet and SuperPropertyGet (and same for *Get). Talk to kernel
@@ -1479,8 +1476,9 @@
         isFromEnvironmentConstructor: isFromEnvironmentConstructor);
   }
 
-  JConstructorBody createConstructorBody(ConstructorEntity constructor) {
-    return new JConstructorBody(constructor);
+  JConstructorBody createConstructorBody(
+      ConstructorEntity constructor, ParameterStructure parameterStructure) {
+    return new JConstructorBody(constructor, parameterStructure);
   }
 
   JGeneratorBody createGeneratorBody(
@@ -1535,8 +1533,8 @@
     return createTypedef(library, typedef.name);
   }
 
-  MemberEntity convertMember(
-      LibraryEntity library, ClassEntity cls, IndexedMember member) {
+  MemberEntity convertMember(LibraryEntity library, ClassEntity cls,
+      IndexedMember member, MemberUsage memberUsage) {
     Name memberName = new Name(member.memberName.text, library,
         isSetter: member.memberName.isSetter);
     if (member.isField) {
@@ -1550,14 +1548,14 @@
       if (constructor.isFactoryConstructor) {
         // TODO(redemption): This should be a JFunction.
         return createFactoryConstructor(
-            cls, memberName, constructor.parameterStructure,
+            cls, memberName, memberUsage.invokedParameters,
             isExternal: constructor.isExternal,
             isConst: constructor.isConst,
             isFromEnvironmentConstructor:
                 constructor.isFromEnvironmentConstructor);
       } else {
         return createGenerativeConstructor(
-            cls, memberName, constructor.parameterStructure,
+            cls, memberName, memberUsage.invokedParameters,
             isExternal: constructor.isExternal, isConst: constructor.isConst);
       }
     } else if (member.isGetter) {
@@ -1574,8 +1572,8 @@
           isAbstract: setter.isAbstract);
     } else {
       IndexedFunction function = member;
-      return createMethod(library, cls, memberName, function.parameterStructure,
-          function.asyncMarker,
+      return createMethod(library, cls, memberName,
+          memberUsage.invokedParameters, function.asyncMarker,
           isStatic: function.isStatic,
           isExternal: function.isExternal,
           isAbstract: function.isAbstract);
@@ -1695,7 +1693,14 @@
       ir.Constructor node, covariant IndexedConstructor constructor) {
     JConstructorDataImpl data = members.getData(constructor);
     if (data.constructorBody == null) {
-      JConstructorBody constructorBody = createConstructorBody(constructor);
+      /// The constructor calls the constructor body with all parameters.
+      // TODO(johnniwinther): Remove parameters that are not used in the
+      //  constructor body.
+      ParameterStructure parameterStructure =
+          _getParameterStructureFromFunctionNode(node.function);
+
+      JConstructorBody constructorBody =
+          createConstructorBody(constructor, parameterStructure);
       members.register<IndexedFunction, FunctionData>(
           constructorBody,
           new ConstructorBodyDataImpl(
@@ -1744,9 +1749,11 @@
 
   @override
   void forEachParameter(covariant IndexedFunction function,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
+      void f(DartType type, String name, ConstantValue defaultValue),
+      {bool isNative: false}) {
     FunctionData data = members.getData(function);
-    data.forEachParameter(this, f);
+    data.forEachParameter(this, function.parameterStructure, f,
+        isNative: isNative);
   }
 
   void forEachConstructorBody(
@@ -1818,6 +1825,17 @@
           Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
       recordFieldsVisibleInScope.containsKey(local);
 
+  ParameterStructure _getParameterStructureFromFunctionNode(
+      ir.FunctionNode node) {
+    int requiredParameters = 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);
+  }
+
   KernelClosureClassInfo constructClosureClass(
       MemberEntity member,
       ir.FunctionNode node,
@@ -1861,8 +1879,8 @@
       closureEntity = new AnonymousClosureLocal(classEntity);
     }
 
-    IndexedFunction callMethod = new JClosureCallMethod(
-        classEntity, getParameterStructure(node), getAsyncMarker(node));
+    IndexedFunction callMethod = new JClosureCallMethod(classEntity,
+        _getParameterStructureFromFunctionNode(node), getAsyncMarker(node));
     _nestedClosureMap
         .putIfAbsent(member, () => <IndexedFunction>[])
         .add(callMethod);
@@ -2537,39 +2555,6 @@
   bool get enableAssertions => _elementMap.options.enableUserAssertions;
 }
 
-class JsToFrontendMapImpl extends JsToFrontendMapBase
-    implements JsToFrontendMap {
-  final JsKernelToElementMap _backend;
-
-  JsToFrontendMapImpl(this._backend);
-
-  LibraryEntity toBackendLibrary(covariant IndexedLibrary library) {
-    return _backend.libraries.getEntity(library.libraryIndex);
-  }
-
-  ClassEntity toBackendClass(covariant IndexedClass cls) {
-    return _backend.classes.getEntity(cls.classIndex);
-  }
-
-  MemberEntity toBackendMember(covariant IndexedMember member) {
-    return _backend.members.getEntity(member.memberIndex);
-  }
-
-  TypedefEntity toBackendTypedef(covariant IndexedTypedef typedef) {
-    return _backend.typedefs.getEntity(typedef.typedefIndex);
-  }
-
-  TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable) {
-    if (typeVariable is KLocalTypeVariable) {
-      failedAt(
-          typeVariable, "Local function type variables are not supported.");
-    }
-    IndexedTypeVariable indexedTypeVariable = typeVariable;
-    return _backend.typeVariables
-        .getEntity(indexedTypeVariable.typeVariableIndex);
-  }
-}
-
 /// [EntityLookup] implementation used to deserialize [JsKernelToElementMap].
 ///
 /// Since data objects and environments are registered together with their
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index cc98750..4afe45a 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -13,170 +13,6 @@
 import '../universe/class_set.dart' show ClassHierarchyNodesMapKey;
 import 'closure.dart';
 
-/// Map from 'frontend' to 'backend' elements.
-///
-/// Frontend elements are what we read in, these typically represents concepts
-/// in Dart. Backend elements are what we generate, these may include elements
-/// that do not correspond to a Dart concept, such as closure classes.
-///
-/// Querying for the frontend element for a backend-only element throws an
-/// exception.
-abstract class JsToFrontendMap {
-  LibraryEntity toBackendLibrary(LibraryEntity library);
-
-  ClassEntity toBackendClass(ClassEntity cls);
-
-  /// Returns the backend member corresponding to [member]. If a member isn't
-  /// live, it doesn't have a corresponding backend member and `null` is
-  /// returned instead.
-  MemberEntity toBackendMember(MemberEntity member);
-
-  DartType toBackendType(DartType type);
-
-  Set<LibraryEntity> toBackendLibrarySet(Iterable<LibraryEntity> set) {
-    return set.map(toBackendLibrary).toSet();
-  }
-
-  Set<ClassEntity> toBackendClassSet(Iterable<ClassEntity> set) {
-    // TODO(johnniwinther): Filter unused classes.
-    return set.map(toBackendClass).toSet();
-  }
-
-  Set<MemberEntity> toBackendMemberSet(Iterable<MemberEntity> set) {
-    return set.map(toBackendMember).where((MemberEntity member) {
-      // Members that are not live don't have a corresponding backend member.
-      return member != null;
-    }).toSet();
-  }
-
-  Set<FunctionEntity> toBackendFunctionSet(Iterable<FunctionEntity> set) {
-    Set<FunctionEntity> newSet = new Set<FunctionEntity>();
-    for (FunctionEntity element in set) {
-      FunctionEntity backendFunction = toBackendMember(element);
-      if (backendFunction != null) {
-        // Members that are not live don't have a corresponding backend member.
-        newSet.add(backendFunction);
-      }
-    }
-    return newSet;
-  }
-
-  Map<LibraryEntity, V> toBackendLibraryMap<V>(
-      Map<LibraryEntity, V> map, V convert(V value)) {
-    return convertMap(map, toBackendLibrary, convert);
-  }
-
-  Map<ClassEntity, V> toBackendClassMap<V>(
-      Map<ClassEntity, V> map, V convert(V value)) {
-    return convertMap(map, toBackendClass, convert);
-  }
-
-  Map<MemberEntity, V> toBackendMemberMap<V>(
-      Map<MemberEntity, V> map, V convert(V value)) {
-    return convertMap(map, toBackendMember, convert);
-  }
-}
-
-E identity<E>(E element) => element;
-
-Map<K, V> convertMap<K, V>(
-    Map<K, V> map, K convertKey(K key), V convertValue(V value)) {
-  Map<K, V> newMap = <K, V>{};
-  map.forEach((K key, V value) {
-    K newKey = convertKey(key);
-    V newValue = convertValue(value);
-    if (newKey != null && newValue != null) {
-      // Entities that are not used don't have a corresponding backend entity.
-      newMap[newKey] = newValue;
-    }
-  });
-  return newMap;
-}
-
-abstract class JsToFrontendMapBase extends JsToFrontendMap {
-  DartType toBackendType(DartType type) =>
-      type == null ? null : const TypeConverter().visit(type, _toBackendEntity);
-
-  Entity _toBackendEntity(Entity entity) {
-    if (entity is ClassEntity) return toBackendClass(entity);
-    assert(entity is TypeVariableEntity);
-    return toBackendTypeVariable(entity);
-  }
-
-  TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable);
-}
-
-typedef Entity EntityConverter(Entity cls);
-
-class TypeConverter implements DartTypeVisitor<DartType, EntityConverter> {
-  const TypeConverter();
-
-  @override
-  DartType visit(DartType type, EntityConverter converter) {
-    return type.accept(this, converter);
-  }
-
-  List<DartType> visitList(List<DartType> types, EntityConverter converter) {
-    List<DartType> list = <DartType>[];
-    for (DartType type in types) {
-      list.add(visit(type, converter));
-    }
-    return list;
-  }
-
-  @override
-  DartType visitDynamicType(DynamicType type, EntityConverter converter) {
-    return const DynamicType();
-  }
-
-  @override
-  DartType visitInterfaceType(InterfaceType type, EntityConverter converter) {
-    return new InterfaceType(
-        converter(type.element), visitList(type.typeArguments, converter));
-  }
-
-  @override
-  DartType visitTypedefType(TypedefType type, EntityConverter converter) {
-    return new TypedefType(
-        converter(type.element),
-        visitList(type.typeArguments, converter),
-        visit(type.unaliased, converter));
-  }
-
-  @override
-  DartType visitFunctionType(FunctionType type, EntityConverter converter) {
-    return new FunctionType(
-        visit(type.returnType, converter),
-        visitList(type.parameterTypes, converter),
-        visitList(type.optionalParameterTypes, converter),
-        type.namedParameters,
-        visitList(type.namedParameterTypes, converter),
-        type.typeVariables);
-  }
-
-  @override
-  DartType visitTypeVariableType(
-      TypeVariableType type, EntityConverter converter) {
-    return new TypeVariableType(converter(type.element));
-  }
-
-  @override
-  DartType visitFunctionTypeVariable(
-      FunctionTypeVariable type, EntityConverter converter) {
-    return type;
-  }
-
-  @override
-  DartType visitVoidType(VoidType type, EntityConverter converter) {
-    return const VoidType();
-  }
-
-  @override
-  DartType visitFutureOrType(FutureOrType type, EntityConverter converter) {
-    return new FutureOrType(visit(type.typeArgument, converter));
-  }
-}
-
 const String jsElementPrefix = 'j:';
 
 class JLibrary extends IndexedLibrary {
@@ -536,21 +372,18 @@
 
   final JConstructor constructor;
 
-  JConstructorBody(this.constructor)
-      : super(
-            constructor.library,
-            constructor.enclosingClass,
-            constructor.memberName,
-            constructor.parameterStructure,
-            AsyncMarker.SYNC,
-            isStatic: false,
-            isExternal: false);
+  JConstructorBody(this.constructor, ParameterStructure parameterStructure)
+      : super(constructor.library, constructor.enclosingClass,
+            constructor.memberName, parameterStructure, AsyncMarker.SYNC,
+            isStatic: false, isExternal: false);
 
   factory JConstructorBody.readFromDataSource(DataSource source) {
     source.begin(tag);
     JConstructor constructor = source.readMember();
+    ParameterStructure parameterStructure =
+        new ParameterStructure.readFromDataSource(source);
     source.end(tag);
-    return new JConstructorBody(constructor);
+    return new JConstructorBody(constructor, parameterStructure);
   }
 
   @override
@@ -558,6 +391,7 @@
     sink.writeEnum(JMemberKind.constructorBody);
     sink.begin(tag);
     sink.writeMember(constructor);
+    parameterStructure.writeToDataSink(sink);
     sink.end(tag);
   }
 
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index a22112b..17cc2e9 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -15,7 +15,6 @@
 import '../elements/types.dart';
 import '../ir/element_map.dart';
 import '../ir/visitors.dart';
-import '../ir/util.dart';
 import '../js_model/element_map.dart';
 import '../ordered_typeset.dart';
 import '../serialization/serialization.dart';
@@ -565,11 +564,14 @@
 
   List<TypeVariableType> getFunctionTypeVariables(IrToElementMap elementMap);
 
-  void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue));
+  void forEachParameter(
+      JsToElementMap elementMap,
+      ParameterStructure parameterStructure,
+      void f(DartType type, String name, ConstantValue defaultValue),
+      {bool isNative: false});
 }
 
-abstract class FunctionDataMixin implements FunctionData {
+abstract class FunctionDataTypeVariablesMixin implements FunctionData {
   ir.FunctionNode get functionNode;
   List<TypeVariableType> _typeVariables;
 
@@ -597,8 +599,39 @@
   }
 }
 
+abstract class FunctionDataForEachParameterMixin implements FunctionData {
+  ir.FunctionNode get functionNode;
+
+  void forEachParameter(
+      JsToElementMap elementMap,
+      ParameterStructure parameterStructure,
+      void f(DartType type, String name, ConstantValue defaultValue),
+      {bool isNative: false}) {
+    void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
+      DartType type = elementMap.getDartType(node.type);
+      String name = node.name;
+      ConstantValue defaultValue;
+      if (isOptional) {
+        if (node.initializer != null) {
+          defaultValue = elementMap.getConstantValue(node.initializer);
+        } else {
+          defaultValue = new NullConstantValue();
+        }
+      }
+      f(type, name, defaultValue);
+    }
+
+    forEachOrderedParameterByFunctionNode(functionNode, parameterStructure,
+        (ir.VariableDeclaration parameter, {bool isOptional, bool isElided}) {
+      if (!isElided) {
+        handleParameter(parameter, isOptional: isOptional);
+      }
+    }, useNativeOrdering: isNative);
+  }
+}
+
 class FunctionDataImpl extends JMemberDataImpl
-    with FunctionDataMixin
+    with FunctionDataTypeVariablesMixin, FunctionDataForEachParameterMixin
     implements FunctionData {
   /// Tag used for identifying serialized [FunctionDataImpl] objects in a
   /// debugging data stream.
@@ -644,31 +677,6 @@
     return _type ??= elementMap.getFunctionType(functionNode);
   }
 
-  void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
-    void handleParameter(ir.VariableDeclaration node, {bool isOptional: true}) {
-      DartType type = elementMap.getDartType(node.type);
-      String name = node.name;
-      ConstantValue defaultValue;
-      if (isOptional) {
-        if (node.initializer != null) {
-          defaultValue = elementMap.getConstantValue(node.initializer);
-        } else {
-          defaultValue = new NullConstantValue();
-        }
-      }
-      f(type, name, defaultValue);
-    }
-
-    for (int i = 0; i < functionNode.positionalParameters.length; i++) {
-      handleParameter(functionNode.positionalParameters[i],
-          isOptional: i >= functionNode.requiredParameterCount);
-    }
-    functionNode.namedParameters.toList()
-      ..sort(namedOrdering)
-      ..forEach(handleParameter);
-  }
-
   @override
   ClassTypeVariableAccess get classTypeVariableAccess {
     if (node.isInstanceMember) return ClassTypeVariableAccess.property;
@@ -726,8 +734,11 @@
     }).toList();
   }
 
-  void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
+  void forEachParameter(
+      JsToElementMap elementMap,
+      ParameterStructure parameterStructure,
+      void f(DartType type, String name, ConstantValue defaultValue),
+      {bool isNative: false}) {
     throw new UnimplementedError('SignatureData.forEachParameter');
   }
 
@@ -749,9 +760,13 @@
     return baseData.getFunctionTypeVariables(elementMap);
   }
 
-  void forEachParameter(JsToElementMap elementMap,
-      void f(DartType type, String name, ConstantValue defaultValue)) {
-    return baseData.forEachParameter(elementMap, f);
+  void forEachParameter(
+      JsToElementMap elementMap,
+      ParameterStructure parameterStructure,
+      void f(DartType type, String name, ConstantValue defaultValue),
+      {bool isNative: false}) {
+    return baseData.forEachParameter(elementMap, parameterStructure, f,
+        isNative: isNative);
   }
 
   InterfaceType getMemberThisType(JsToElementMap elementMap) {
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 22b6f9d8..8715893 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -64,7 +64,7 @@
         _compiler.reporter,
         _compiler.environment,
         strategy.elementMap,
-        closedWorld.processedMembers);
+        closedWorld.liveMemberUsage);
     GlobalLocalsMap _globalLocalsMap = new GlobalLocalsMap();
     ClosureDataBuilder closureDataBuilder = new ClosureDataBuilder(
         _elementMap, _globalLocalsMap, _compiler.options);
@@ -94,7 +94,11 @@
   @override
   SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend,
       SourceInformationStrategy sourceInformationStrategy) {
-    return new KernelSsaBuilder(task, backend.compiler, elementMap);
+    return new KernelSsaBuilder(
+        task,
+        backend.compiler,
+        // ignore:deprecated_member_use_from_same_package
+        elementMap);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 39e86a0..3f6ca05 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -80,6 +80,7 @@
   final GlobalLocalsMap globalLocalsMap;
   final ClosureData closureDataLookup;
   final OutputUnitData outputUnitData;
+  final Set<FieldEntity> elidedFields;
   Sorter _sorter;
 
   JsClosedWorld(
@@ -102,7 +103,8 @@
       this.annotationsData,
       this.globalLocalsMap,
       this.closureDataLookup,
-      this.outputUnitData) {
+      this.outputUnitData,
+      this.elidedFields) {
     _abstractValueDomain = abstractValueStrategy.createDomain(this);
   }
 
@@ -156,6 +158,8 @@
     OutputUnitData outputUnitData =
         new OutputUnitData.readFromDataSource(source);
 
+    Set<FieldEntity> elidedFields = source.readMembers<FieldEntity>().toSet();
+
     source.end(tag);
 
     return new JsClosedWorld(
@@ -178,7 +182,8 @@
         annotationsData,
         globalLocalsMap,
         closureData,
-        outputUnitData);
+        outputUnitData,
+        elidedFields);
   }
 
   /// Serializes this [JsClosedWorld] to [sink].
@@ -206,6 +211,7 @@
     annotationsData.writeToDataSink(sink);
     closureDataLookup.writeToDataSink(sink);
     outputUnitData.writeToDataSink(sink);
+    sink.writeMembers(elidedFields);
     sink.end(tag);
   }
 
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 552d014..3b39476 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -5,10 +5,12 @@
 import 'package:kernel/ast.dart' as ir;
 
 import '../closure.dart';
+import '../common.dart';
 import '../common_elements.dart';
 import '../constants/values.dart';
 import '../deferred_load.dart';
 import '../elements/entities.dart';
+import '../elements/indexed.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
 import '../inferrer/abstract_value_domain.dart';
@@ -26,6 +28,7 @@
 import '../universe/class_hierarchy.dart';
 import '../universe/class_set.dart';
 import '../universe/feature.dart';
+import '../universe/member_usage.dart';
 import '../universe/selector.dart';
 import '../world.dart';
 import 'closure.dart';
@@ -123,7 +126,7 @@
         map.toBackendClassSet(closedWorld.liveNativeClasses);
 
     Set<MemberEntity> processedMembers =
-        map.toBackendMemberSet(closedWorld.processedMembers);
+        map.toBackendMemberSet(closedWorld.liveMemberUsage.keys);
 
     RuntimeTypesNeed rtiNeed;
 
@@ -192,23 +195,26 @@
     JAllocatorAnalysis allocatorAnalysis =
         JAllocatorAnalysis.from(closedWorld.allocatorAnalysis, map, _options);
 
+    AnnotationsDataImpl oldAnnotationsData = closedWorld.annotationsData;
     AnnotationsData annotationsData = new AnnotationsDataImpl(
-        map.toBackendFunctionSet(
-            closedWorld.annotationsData.nonInlinableFunctions),
-        map.toBackendFunctionSet(
-            closedWorld.annotationsData.tryInlineFunctions),
-        map.toBackendFunctionSet(
-            closedWorld.annotationsData.disableFinalFunctions),
-        map.toBackendFunctionSet(
-            closedWorld.annotationsData.cannotThrowFunctions),
-        map.toBackendFunctionSet(
-            closedWorld.annotationsData.sideEffectFreeFunctions),
-        map.toBackendMemberSet(
-            closedWorld.annotationsData.assumeDynamicMembers));
+        map.toBackendMemberMap(oldAnnotationsData.pragmaAnnotations, identity));
 
     OutputUnitData outputUnitData =
         _convertOutputUnitData(map, kOutputUnitData, closureData);
 
+    Set<FieldEntity> elidedFields = new Set();
+    closedWorld.liveMemberUsage
+        .forEach((MemberEntity member, MemberUsage memberUsage) {
+      // TODO(johnniwinther): Should elided static fields be removed from the
+      // J model? Static setters might still assign to them.
+      if (member.isField &&
+          !memberUsage.hasRead &&
+          !closedWorld.annotationsData.hasNoElision(member) &&
+          !closedWorld.nativeData.isNativeMember(member)) {
+        elidedFields.add(map.toBackendMember(member));
+      }
+    });
+
     return new JsClosedWorld(
         _elementMap,
         nativeData,
@@ -233,7 +239,8 @@
         annotationsData,
         _globalLocalsMap,
         closureData,
-        outputUnitData);
+        outputUnitData,
+        elidedFields);
   }
 
   BackendUsage _convertBackendUsage(
@@ -298,7 +305,12 @@
   NativeData _convertNativeData(
       JsToFrontendMap map, NativeDataImpl nativeData) {
     convertNativeBehaviorType(type) {
-      if (type is DartType) return map.toBackendType(type);
+      if (type is DartType) {
+        // TODO(johnniwinther): Avoid free variables in types. If the type
+        // pulled from a generic function type it might contain a function
+        // type variable that should probably have been replaced by its bound.
+        return map.toBackendType(type, allowFreeVariables: true);
+      }
       assert(type is SpecialType);
       return type;
     }
@@ -447,18 +459,6 @@
 
   OutputUnitData _convertOutputUnitData(JsToFrontendMapImpl map,
       OutputUnitData data, ClosureData closureDataLookup) {
-    Entity toBackendEntity(Entity entity) {
-      if (entity is ClassEntity) return map.toBackendClass(entity);
-      if (entity is MemberEntity) return map.toBackendMember(entity);
-      if (entity is TypedefEntity) return map.toBackendTypedef(entity);
-      if (entity is TypeVariableEntity) {
-        return map.toBackendTypeVariable(entity);
-      }
-      assert(
-          entity is LibraryEntity, 'unexpected entity ${entity.runtimeType}');
-      return map.toBackendLibrary(entity);
-    }
-
     // Convert front-end maps containing K-class and K-local function keys to a
     // backend map using J-classes as keys.
     Map<ClassEntity, OutputUnit> convertClassMap(
@@ -466,7 +466,7 @@
         Map<Local, OutputUnit> localFunctionMap) {
       var result = <ClassEntity, OutputUnit>{};
       classMap.forEach((ClassEntity entity, OutputUnit unit) {
-        ClassEntity backendEntity = toBackendEntity(entity);
+        ClassEntity backendEntity = map.toBackendClass(entity);
         if (backendEntity != null) {
           // If [entity] isn't used it doesn't have a corresponding backend
           // entity.
@@ -491,7 +491,7 @@
         Map<Local, OutputUnit> localFunctionMap) {
       var result = <MemberEntity, OutputUnit>{};
       memberMap.forEach((MemberEntity entity, OutputUnit unit) {
-        MemberEntity backendEntity = toBackendEntity(entity);
+        MemberEntity backendEntity = map.toBackendMember(entity);
         if (backendEntity != null) {
           // If [entity] isn't used it doesn't have a corresponding backend
           // entity.
@@ -509,17 +509,13 @@
       return result;
     }
 
-    ConstantValue toBackendConstant(ConstantValue constant) {
-      return constant.accept(new ConstantConverter(toBackendEntity), null);
-    }
-
     return new OutputUnitData.from(
         data,
         map.toBackendLibrary,
         convertClassMap,
         convertMemberMap,
         (m) => convertMap<ConstantValue, OutputUnit>(
-            m, toBackendConstant, (v) => v));
+            m, map.toBackendConstant, (v) => v));
   }
 }
 
@@ -592,12 +588,259 @@
       rtiNeed.instantiationNeedsTypeArguments(functionType, typeArgumentCount);
 }
 
-class ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
-  final Entity Function(Entity) toBackendEntity;
-  final TypeConverter typeConverter;
+/// Map from 'frontend' to 'backend' elements.
+///
+/// Frontend elements are what we read in, these typically represents concepts
+/// in Dart. Backend elements are what we generate, these may include elements
+/// that do not correspond to a Dart concept, such as closure classes.
+///
+/// Querying for the frontend element for a backend-only element throws an
+/// exception.
+abstract class JsToFrontendMap {
+  LibraryEntity toBackendLibrary(LibraryEntity library);
 
-  ConstantConverter(this.toBackendEntity)
-      : typeConverter = new TypeConverter(toBackendEntity);
+  ClassEntity toBackendClass(ClassEntity cls);
+
+  /// Returns the backend member corresponding to [member]. If a member isn't
+  /// live, it doesn't have a corresponding backend member and `null` is
+  /// returned instead.
+  MemberEntity toBackendMember(MemberEntity member);
+
+  DartType toBackendType(DartType type, {bool allowFreeVariables: false});
+
+  ConstantValue toBackendConstant(ConstantValue value);
+
+  Set<LibraryEntity> toBackendLibrarySet(Iterable<LibraryEntity> set) {
+    return set.map(toBackendLibrary).toSet();
+  }
+
+  Set<ClassEntity> toBackendClassSet(Iterable<ClassEntity> set) {
+    // TODO(johnniwinther): Filter unused classes.
+    return set.map(toBackendClass).toSet();
+  }
+
+  Set<MemberEntity> toBackendMemberSet(Iterable<MemberEntity> set) {
+    return set.map(toBackendMember).where((MemberEntity member) {
+      // Members that are not live don't have a corresponding backend member.
+      return member != null;
+    }).toSet();
+  }
+
+  Set<FieldEntity> toBackendFieldSet(Iterable<FieldEntity> set) {
+    Set<FieldEntity> newSet = new Set<FieldEntity>();
+    for (FieldEntity element in set) {
+      FieldEntity backendField = toBackendMember(element);
+      if (backendField != null) {
+        // Members that are not live don't have a corresponding backend member.
+        newSet.add(backendField);
+      }
+    }
+    return newSet;
+  }
+
+  Set<FunctionEntity> toBackendFunctionSet(Iterable<FunctionEntity> set) {
+    Set<FunctionEntity> newSet = new Set<FunctionEntity>();
+    for (FunctionEntity element in set) {
+      FunctionEntity backendFunction = toBackendMember(element);
+      if (backendFunction != null) {
+        // Members that are not live don't have a corresponding backend member.
+        newSet.add(backendFunction);
+      }
+    }
+    return newSet;
+  }
+
+  Map<LibraryEntity, V> toBackendLibraryMap<V>(
+      Map<LibraryEntity, V> map, V convert(V value)) {
+    return convertMap(map, toBackendLibrary, convert);
+  }
+
+  Map<ClassEntity, V> toBackendClassMap<V>(
+      Map<ClassEntity, V> map, V convert(V value)) {
+    return convertMap(map, toBackendClass, convert);
+  }
+
+  Map<MemberEntity, V> toBackendMemberMap<V>(
+      Map<MemberEntity, V> map, V convert(V value)) {
+    return convertMap(map, toBackendMember, convert);
+  }
+}
+
+E identity<E>(E element) => element;
+
+Map<K, V> convertMap<K, V>(
+    Map<K, V> map, K convertKey(K key), V convertValue(V value)) {
+  Map<K, V> newMap = <K, V>{};
+  map.forEach((K key, V value) {
+    K newKey = convertKey(key);
+    V newValue = convertValue(value);
+    if (newKey != null && newValue != null) {
+      // Entities that are not used don't have a corresponding backend entity.
+      newMap[newKey] = newValue;
+    }
+  });
+  return newMap;
+}
+
+class JsToFrontendMapImpl extends JsToFrontendMap {
+  final JsKernelToElementMap _backend;
+
+  JsToFrontendMapImpl(this._backend);
+
+  DartType toBackendType(DartType type, {bool allowFreeVariables: false}) =>
+      type == null
+          ? null
+          : new _TypeConverter(allowFreeVariables: allowFreeVariables)
+              .visit(type, toBackendEntity);
+
+  Entity toBackendEntity(Entity entity) {
+    if (entity is ClassEntity) return toBackendClass(entity);
+    if (entity is MemberEntity) return toBackendMember(entity);
+    if (entity is TypedefEntity) return toBackendTypedef(entity);
+    if (entity is TypeVariableEntity) {
+      return toBackendTypeVariable(entity);
+    }
+    assert(entity is LibraryEntity, 'unexpected entity ${entity.runtimeType}');
+    return toBackendLibrary(entity);
+  }
+
+  LibraryEntity toBackendLibrary(covariant IndexedLibrary library) {
+    return _backend.libraries.getEntity(library.libraryIndex);
+  }
+
+  ClassEntity toBackendClass(covariant IndexedClass cls) {
+    return _backend.classes.getEntity(cls.classIndex);
+  }
+
+  MemberEntity toBackendMember(covariant IndexedMember member) {
+    return _backend.members.getEntity(member.memberIndex);
+  }
+
+  TypedefEntity toBackendTypedef(covariant IndexedTypedef typedef) {
+    return _backend.typedefs.getEntity(typedef.typedefIndex);
+  }
+
+  TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable) {
+    if (typeVariable is KLocalTypeVariable) {
+      failedAt(
+          typeVariable, "Local function type variables are not supported.");
+    }
+    IndexedTypeVariable indexedTypeVariable = typeVariable;
+    return _backend.typeVariables
+        .getEntity(indexedTypeVariable.typeVariableIndex);
+  }
+
+  ConstantValue toBackendConstant(ConstantValue constant) {
+    return constant.accept(new _ConstantConverter(toBackendEntity), null);
+  }
+}
+
+typedef Entity _EntityConverter(Entity cls);
+
+class _TypeConverter implements DartTypeVisitor<DartType, _EntityConverter> {
+  final bool allowFreeVariables;
+
+  Map<FunctionTypeVariable, FunctionTypeVariable> _functionTypeVariables =
+      <FunctionTypeVariable, FunctionTypeVariable>{};
+
+  _TypeConverter({this.allowFreeVariables: false});
+
+  List<DartType> convertTypes(
+          List<DartType> types, _EntityConverter converter) =>
+      visitList(types, converter);
+
+  @override
+  DartType visit(DartType type, _EntityConverter converter) {
+    return type.accept(this, converter);
+  }
+
+  List<DartType> visitList(List<DartType> types, _EntityConverter converter) {
+    List<DartType> list = <DartType>[];
+    for (DartType type in types) {
+      list.add(visit(type, converter));
+    }
+    return list;
+  }
+
+  @override
+  DartType visitDynamicType(DynamicType type, _EntityConverter converter) {
+    return const DynamicType();
+  }
+
+  @override
+  DartType visitInterfaceType(InterfaceType type, _EntityConverter converter) {
+    return new InterfaceType(
+        converter(type.element), visitList(type.typeArguments, converter));
+  }
+
+  @override
+  DartType visitTypedefType(TypedefType type, _EntityConverter converter) {
+    return new TypedefType(
+        converter(type.element),
+        visitList(type.typeArguments, converter),
+        visit(type.unaliased, converter));
+  }
+
+  @override
+  DartType visitTypeVariableType(
+      TypeVariableType type, _EntityConverter converter) {
+    return new TypeVariableType(converter(type.element));
+  }
+
+  @override
+  DartType visitFunctionType(FunctionType type, _EntityConverter converter) {
+    List<FunctionTypeVariable> typeVariables = <FunctionTypeVariable>[];
+    for (FunctionTypeVariable typeVariable in type.typeVariables) {
+      typeVariables.add(_functionTypeVariables[typeVariable] =
+          new FunctionTypeVariable(typeVariable.index));
+    }
+    for (FunctionTypeVariable typeVariable in type.typeVariables) {
+      _functionTypeVariables[typeVariable].bound = typeVariable.bound != null
+          ? visit(typeVariable.bound, converter)
+          : null;
+    }
+    DartType returnType = visit(type.returnType, converter);
+    List<DartType> parameterTypes = visitList(type.parameterTypes, converter);
+    List<DartType> optionalParameterTypes =
+        visitList(type.optionalParameterTypes, converter);
+    List<DartType> namedParameterTypes =
+        visitList(type.namedParameterTypes, converter);
+    for (FunctionTypeVariable typeVariable in type.typeVariables) {
+      _functionTypeVariables.remove(typeVariable);
+    }
+    return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
+        type.namedParameters, namedParameterTypes, typeVariables);
+  }
+
+  @override
+  DartType visitFunctionTypeVariable(
+      FunctionTypeVariable type, _EntityConverter converter) {
+    DartType result = _functionTypeVariables[type];
+    if (result == null && allowFreeVariables) {
+      return type;
+    }
+    assert(result != null,
+        "Function type variable $type not found in $_functionTypeVariables");
+    return result;
+  }
+
+  @override
+  DartType visitVoidType(VoidType type, _EntityConverter converter) {
+    return const VoidType();
+  }
+
+  @override
+  DartType visitFutureOrType(FutureOrType type, _EntityConverter converter) {
+    return new FutureOrType(visit(type.typeArgument, converter));
+  }
+}
+
+class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
+  final Entity Function(Entity) toBackendEntity;
+  final _TypeConverter typeConverter;
+
+  _ConstantConverter(this.toBackendEntity)
+      : typeConverter = new _TypeConverter();
 
   ConstantValue visitNull(NullConstantValue constant, _) => constant;
   ConstantValue visitInt(IntConstantValue constant, _) => constant;
@@ -608,12 +851,12 @@
   ConstantValue visitNonConstant(NonConstantValue constant, _) => constant;
 
   ConstantValue visitFunction(FunctionConstantValue constant, _) {
-    return new FunctionConstantValue(
-        toBackendEntity(constant.element), typeConverter.visit(constant.type));
+    return new FunctionConstantValue(toBackendEntity(constant.element),
+        typeConverter.visit(constant.type, toBackendEntity));
   }
 
   ConstantValue visitList(ListConstantValue constant, _) {
-    DartType type = typeConverter.visit(constant.type);
+    DartType type = typeConverter.visit(constant.type, toBackendEntity);
     List<ConstantValue> entries = _handleValues(constant.entries);
     if (identical(entries, constant.entries) && type == constant.type) {
       return constant;
@@ -622,7 +865,7 @@
   }
 
   ConstantValue visitMap(MapConstantValue constant, _) {
-    var type = typeConverter.visit(constant.type);
+    var type = typeConverter.visit(constant.type, toBackendEntity);
     List<ConstantValue> keys = _handleValues(constant.keys);
     List<ConstantValue> values = _handleValues(constant.values);
     if (identical(keys, constant.keys) &&
@@ -634,7 +877,7 @@
   }
 
   ConstantValue visitConstructed(ConstructedConstantValue constant, _) {
-    DartType type = typeConverter.visit(constant.type);
+    DartType type = typeConverter.visit(constant.type, toBackendEntity);
     Map<FieldEntity, ConstantValue> fields = {};
     constant.fields.forEach((f, v) {
       FieldEntity backendField = toBackendEntity(f);
@@ -645,8 +888,9 @@
   }
 
   ConstantValue visitType(TypeConstantValue constant, _) {
-    DartType type = typeConverter.visit(constant.type);
-    DartType representedType = typeConverter.visit(constant.representedType);
+    DartType type = typeConverter.visit(constant.type, toBackendEntity);
+    DartType representedType =
+        typeConverter.visit(constant.representedType, toBackendEntity);
     if (type == constant.type && representedType == constant.representedType) {
       return constant;
     }
@@ -668,7 +912,7 @@
   ConstantValue visitInstantiation(InstantiationConstantValue constant, _) {
     ConstantValue function = constant.function.accept(this, null);
     List<DartType> typeArguments =
-        typeConverter.convertTypes(constant.typeArguments);
+        typeConverter.convertTypes(constant.typeArguments, toBackendEntity);
     return new InstantiationConstantValue(typeArguments, function);
   }
 
@@ -685,73 +929,3 @@
     return result ?? values;
   }
 }
-
-class TypeConverter implements DartTypeVisitor<DartType, Null> {
-  final Entity Function(Entity) toBackendEntity;
-
-  TypeConverter(this.toBackendEntity);
-
-  Map<FunctionTypeVariable, FunctionTypeVariable> _functionTypeVariables =
-      <FunctionTypeVariable, FunctionTypeVariable>{};
-
-  DartType visit(DartType type, [_]) => type.accept(this, null);
-
-  List<DartType> convertTypes(List<DartType> types) => _visitList(types);
-
-  DartType visitVoidType(VoidType type, _) => type;
-  DartType visitDynamicType(DynamicType type, _) => type;
-
-  DartType visitTypeVariableType(TypeVariableType type, _) {
-    return new TypeVariableType(toBackendEntity(type.element));
-  }
-
-  DartType visitFunctionTypeVariable(FunctionTypeVariable type, _) {
-    DartType result = _functionTypeVariables[type];
-    assert(result != null,
-        "Function type variable $type not found in $_functionTypeVariables");
-    return result;
-  }
-
-  DartType visitFunctionType(FunctionType type, _) {
-    List<FunctionTypeVariable> typeVariables = <FunctionTypeVariable>[];
-    for (FunctionTypeVariable typeVariable in type.typeVariables) {
-      typeVariables.add(_functionTypeVariables[typeVariable] =
-          new FunctionTypeVariable(typeVariable.index));
-    }
-    for (FunctionTypeVariable typeVariable in type.typeVariables) {
-      _functionTypeVariables[typeVariable].bound =
-          typeVariable.bound?.accept(this, null);
-    }
-    DartType returnType = type.returnType.accept(this, null);
-    List<DartType> parameterTypes = _visitList(type.parameterTypes);
-    List<DartType> optionalParameterTypes =
-        _visitList(type.optionalParameterTypes);
-    List<DartType> namedParameterTypes = _visitList(type.namedParameterTypes);
-    for (FunctionTypeVariable typeVariable in type.typeVariables) {
-      _functionTypeVariables.remove(typeVariable);
-    }
-    return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
-        type.namedParameters, namedParameterTypes, typeVariables);
-  }
-
-  DartType visitInterfaceType(InterfaceType type, _) {
-    ClassEntity element = toBackendEntity(type.element);
-    List<DartType> args = _visitList(type.typeArguments);
-    return new InterfaceType(element, args);
-  }
-
-  DartType visitTypedefType(TypedefType type, _) {
-    TypedefEntity element = toBackendEntity(type.element);
-    List<DartType> args = _visitList(type.typeArguments);
-    DartType unaliased = visit(type.unaliased);
-    return new TypedefType(element, args, unaliased);
-  }
-
-  @override
-  DartType visitFutureOrType(FutureOrType type, _) {
-    return new FutureOrType(visit(type.typeArgument));
-  }
-
-  List<DartType> _visitList(List<DartType> list) =>
-      list.map<DartType>((t) => t.accept(this, null)).toList();
-}
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index cfeede7..2281cd9 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -12,7 +12,6 @@
 import '../elements/indexed.dart';
 import '../elements/jumps.dart';
 import '../elements/types.dart';
-import '../ir/util.dart';
 import '../serialization/serialization.dart';
 
 import 'element_map.dart';
@@ -617,56 +616,14 @@
 
 /// Calls [f] for each parameter in [function] in the canonical order:
 /// Positional parameters by index, then named parameters lexicographically.
-void forEachOrderedParameter(
+void forEachOrderedParameterAsLocal(
     GlobalLocalsMap globalLocalsMap,
     JsToElementMap elementMap,
     FunctionEntity function,
-    void f(Local parameter)) {
+    void f(Local parameter, {bool isElided})) {
   KernelToLocalsMap localsMap = globalLocalsMap.getLocalsMap(function);
-
-  void processFunctionNode(ir.FunctionNode node) {
-    for (ir.VariableDeclaration variable in node.positionalParameters) {
-      f(localsMap.getLocalVariable(variable));
-    }
-    List<ir.VariableDeclaration> namedParameters =
-        new List<ir.VariableDeclaration>.from(node.namedParameters);
-    namedParameters.sort(namedOrdering);
-    for (ir.VariableDeclaration variable in namedParameters) {
-      f(localsMap.getLocalVariable(variable));
-    }
-  }
-
-  MemberDefinition definition = elementMap.getMemberDefinition(function);
-  switch (definition.kind) {
-    case MemberKind.regular:
-      ir.Node node = definition.node;
-      if (node is ir.Procedure) {
-        processFunctionNode(node.function);
-        return;
-      }
-      break;
-    case MemberKind.constructor:
-    case MemberKind.constructorBody:
-      ir.Node node = definition.node;
-      if (node is ir.Procedure) {
-        processFunctionNode(node.function);
-        return;
-      } else if (node is ir.Constructor) {
-        processFunctionNode(node.function);
-        return;
-      }
-      break;
-    case MemberKind.closureCall:
-      ir.Node node = definition.node;
-      if (node is ir.FunctionDeclaration) {
-        processFunctionNode(node.function);
-        return;
-      } else if (node is ir.FunctionExpression) {
-        processFunctionNode(node.function);
-        return;
-      }
-      break;
-    default:
-  }
-  failedAt(function, "Unexpected function definition $definition.");
+  forEachOrderedParameter(elementMap, function,
+      (ir.VariableDeclaration variable, {bool isElided}) {
+    f(localsMap.getLocalVariable(variable), isElided: isElided);
+  });
 }
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 9ab34db..a021418 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -10,6 +10,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/transformations/constants.dart' show ConstantsBackend;
 import 'invocation_mirror_constants.dart';
 
 const Iterable<String> _allowedDartSchemePaths = const <String>[
@@ -74,8 +75,12 @@
   bool get errorOnUnexactWebIntLiterals => true;
 
   @override
-  void performModularTransformationsOnLibraries(ir.Component component,
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<ir.Library> libraries,
+  void performModularTransformationsOnLibraries(
+      ir.Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<ir.Library> libraries,
+      DiagnosticReporter diagnosticReporter,
       {void logger(String msg)}) {}
 
   @override
@@ -134,6 +139,11 @@
     // TODO(sigmund): implement;
     return new ir.InvalidExpression(null);
   }
+
+  // TODO(askesc): Return specialized dart2js constants backend.
+  @override
+  ConstantsBackend constantsBackend(CoreTypes coreTypes) =>
+      new ConstantsBackend();
 }
 
 // TODO(sigmund): this "extraRequiredLibraries" needs to be removed...
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index b6fe609..8fd2d17 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -56,13 +56,10 @@
   /// Returns the [CallStructure] corresponding to the [arguments].
   CallStructure getCallStructure(ir.Arguments arguments);
 
-  /// Returns the [Selector] corresponding to the invocation or getter/setter
-  /// access of [node].
-  Selector getSelector(ir.Expression node);
-
   /// Returns the [Selector] corresponding to the invocation of [name] with
   /// [arguments].
-  Selector getInvocationSelector(ir.Name name, ir.Arguments arguments);
+  Selector getInvocationSelector(ir.Name name, int positionalArguments,
+      List<String> namedArguments, int typeArguments);
 
   /// Returns the [MemberEntity] corresponding to the member [node].
   MemberEntity getMember(ir.Member node);
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 9a8c1d1..343e484 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -30,6 +30,8 @@
 import '../frontend_strategy.dart';
 import '../ir/debug.dart';
 import '../ir/element_map.dart';
+import '../ir/impact.dart';
+import '../ir/impact_data.dart';
 import '../ir/static_type.dart';
 import '../ir/scope.dart';
 import '../ir/types.dart';
@@ -60,6 +62,11 @@
 part 'native_basic_data.dart';
 part 'no_such_method_resolver.dart';
 
+/// If `true` kernel impacts are computed as [ImpactData] directly on kernel
+/// and converted to the K model afterwards. This is a pre-step to modularizing
+/// the world impact computation.
+bool useImpactDataForTesting = false;
+
 /// Implementation of [KernelToElementMap] that only supports world
 /// impact computation.
 class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
@@ -760,32 +767,8 @@
         namedParameters, includeTypeParameters ? typeParameters : 0);
   }
 
-  Selector getSelector(ir.Expression node) {
-    // TODO(efortuna): This is screaming for a common interface between
-    // PropertyGet and SuperPropertyGet (and same for *Get). Talk to kernel
-    // folks.
-    if (node is ir.PropertyGet) {
-      return getGetterSelector(node.name);
-    }
-    if (node is ir.SuperPropertyGet) {
-      return getGetterSelector(node.name);
-    }
-    if (node is ir.PropertySet) {
-      return getSetterSelector(node.name);
-    }
-    if (node is ir.SuperPropertySet) {
-      return getSetterSelector(node.name);
-    }
-    if (node is ir.InvocationExpression) {
-      return getInvocationSelector(node.name, node.arguments);
-    }
-    throw failedAt(
-        CURRENT_ELEMENT_SPANNABLE,
-        "Can only get the selector for a property get or an invocation: "
-        "${node}");
-  }
-
-  Selector getInvocationSelector(ir.Name irName, ir.Arguments arguments) {
+  Selector getInvocationSelector(ir.Name irName, int positionalArguments,
+      List<String> namedArguments, int typeArguments) {
     Name name = getName(irName);
     SelectorKind kind;
     if (Selector.isOperatorName(name.text)) {
@@ -798,7 +781,10 @@
       kind = SelectorKind.CALL;
     }
 
-    CallStructure callStructure = getCallStructure(arguments);
+    CallStructure callStructure = new CallStructure(
+        positionalArguments + namedArguments.length,
+        namedArguments,
+        typeArguments);
     return new Selector(kind, name, callStructure);
   }
 
@@ -1339,15 +1325,34 @@
       Set<PragmaAnnotation> annotations) {
     KMemberData memberData = members.getData(member);
     ir.Member node = memberData.node;
-    KernelImpactBuilder builder = new KernelImpactBuilder(
-        this, member, reporter, options, variableScopeModel, annotations);
-    if (retainDataForTesting) {
-      typeMapsForTesting ??= {};
-      typeMapsForTesting[member] = builder.typeMapsForTesting = {};
+
+    if (useImpactDataForTesting) {
+      ImpactBuilder builder = new ImpactBuilder(
+          typeEnvironment, classHierarchy, variableScopeModel,
+          useAsserts: options.enableUserAssertions,
+          inferEffectivelyFinalVariableTypes:
+              !annotations.contains(PragmaAnnotation.disableFinal));
+      if (retainDataForTesting) {
+        typeMapsForTesting ??= {};
+        typeMapsForTesting[member] = builder.typeMapsForTesting = {};
+      }
+      node.accept(builder);
+      ImpactData impactData = builder.impactData;
+      memberData.staticTypes = builder.cachedStaticTypes;
+      KernelImpactConverter converter =
+          new KernelImpactConverter(this, member, reporter, options);
+      return converter.convert(impactData);
+    } else {
+      KernelImpactBuilder builder = new KernelImpactBuilder(
+          this, member, reporter, options, variableScopeModel, annotations);
+      if (retainDataForTesting) {
+        typeMapsForTesting ??= {};
+        typeMapsForTesting[member] = builder.typeMapsForTesting = {};
+      }
+      node.accept(builder);
+      memberData.staticTypes = builder.cachedStaticTypes;
+      return builder.impactBuilder;
     }
-    node.accept(builder);
-    memberData.staticTypes = builder.cachedStaticTypes;
-    return builder.impactBuilder;
   }
 
   ScopeModel computeScopeModel(KMember member) {
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index f313e3a..7ed64b3 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -25,6 +25,7 @@
 import '../js_model/env.dart';
 import '../ordered_typeset.dart';
 import '../ssa/type_builder.dart';
+import '../universe/member_usage.dart';
 import 'element_map_impl.dart';
 
 /// Environment for fast lookup of component libraries.
@@ -162,8 +163,8 @@
 
   /// Convert this [KLibraryEnv] to a corresponding [JLibraryEnv] containing
   /// only the members in [liveMembers].
-  JLibraryEnv convert(
-      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+  JLibraryEnv convert(IrToElementMap elementMap,
+      Map<MemberEntity, MemberUsage> liveMemberUsage) {
     Map<String, ir.Member> memberMap;
     Map<String, ir.Member> setterMap;
     if (_memberMap == null) {
@@ -172,7 +173,7 @@
       memberMap = <String, ir.Member>{};
       _memberMap.forEach((String name, ir.Member node) {
         MemberEntity member = elementMap.getMember(node);
-        if (liveMembers.contains(member)) {
+        if (liveMemberUsage.containsKey(member)) {
           memberMap[name] = node;
         }
       });
@@ -183,7 +184,7 @@
       setterMap = <String, ir.Member>{};
       _setterMap.forEach((String name, ir.Member node) {
         MemberEntity member = elementMap.getMember(node);
-        if (liveMembers.contains(member)) {
+        if (liveMemberUsage.containsKey(member)) {
           setterMap[name] = node;
         }
       });
@@ -268,8 +269,8 @@
 
   /// Convert this [KClassEnv] to the corresponding [JClassEnv] containing only
   /// the members in [liveMembers].
-  JClassEnv convert(
-      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers);
+  JClassEnv convert(IrToElementMap elementMap,
+      Map<MemberEntity, MemberUsage> liveMemberUsage);
 }
 
 int orderByFileOffset(ir.TreeNode a, ir.TreeNode b) {
@@ -544,8 +545,8 @@
     _constructorBodyList?.forEach(f);
   }
 
-  JClassEnv convert(
-      IrToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+  JClassEnv convert(IrToElementMap elementMap,
+      Map<MemberEntity, MemberUsage> liveMemberUsage) {
     Map<String, ir.Member> constructorMap;
     Map<String, ir.Member> memberMap;
     Map<String, ir.Member> setterMap;
@@ -556,7 +557,7 @@
       constructorMap = <String, ir.Member>{};
       _constructorMap.forEach((String name, ir.Member node) {
         MemberEntity member = elementMap.getMember(node);
-        if (liveMembers.contains(member)) {
+        if (liveMemberUsage.containsKey(member)) {
           constructorMap[name] = node;
         }
       });
@@ -567,7 +568,7 @@
       memberMap = <String, ir.Member>{};
       _memberMap.forEach((String name, ir.Member node) {
         MemberEntity member = elementMap.getMember(node);
-        if (liveMembers.contains(member)) {
+        if (liveMemberUsage.containsKey(member)) {
           memberMap[name] = node;
         }
       });
@@ -578,7 +579,7 @@
       setterMap = <String, ir.Member>{};
       _setterMap.forEach((String name, ir.Member node) {
         MemberEntity member = elementMap.getMember(node);
-        if (liveMembers.contains(member)) {
+        if (liveMemberUsage.containsKey(member)) {
           setterMap[name] = node;
         }
       });
@@ -589,7 +590,7 @@
       members = <ir.Member>[];
       _members.forEach((ir.Member node) {
         MemberEntity member = elementMap.getMember(node);
-        if (liveMembers.contains(member)) {
+        if (liveMemberUsage.containsKey(member)) {
           members.add(node);
         }
       });
diff --git a/pkg/compiler/lib/src/kernel/front_end_adapter.dart b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
index 17b3b15c..169237d 100644
--- a/pkg/compiler/lib/src/kernel/front_end_adapter.dart
+++ b/pkg/compiler/lib/src/kernel/front_end_adapter.dart
@@ -83,32 +83,37 @@
 /// [DiagnosticReporter].
 void reportFrontEndMessage(
     DiagnosticReporter reporter, fe.DiagnosticMessage message) {
-  MessageKind kind = MessageKind.GENERIC;
-  Spannable span;
-  String text;
-  if (message is fe.FormattedMessage) {
-    if (message.uri != null && message.charOffset != -1) {
-      int offset = message.charOffset;
-      span = new SourceSpan(message.uri, offset, offset + message.length);
+  Spannable _getSpannable(fe.DiagnosticMessage message) {
+    Uri uri = fe.getMessageUri(message);
+    int offset = fe.getMessageCharOffset(message);
+    int length = fe.getMessageLength(message);
+    if (uri != null && offset != -1) {
+      return new SourceSpan(uri, offset, offset + length);
     } else {
-      span = NO_LOCATION_SPANNABLE;
+      return NO_LOCATION_SPANNABLE;
     }
-    text = message.message;
-  } else {
-    throw new UnimplementedError(
-        "Unhandled diagnostic message: ${message.runtimeType}");
   }
+
+  DiagnosticMessage _convertMessage(fe.DiagnosticMessage message) {
+    Spannable span = _getSpannable(message);
+    String text = fe.getMessageHeaderText(message);
+    return reporter.createMessage(span, MessageKind.GENERIC, {'text': text});
+  }
+
+  List<fe.DiagnosticMessage> relatedInformation =
+      fe.getMessageRelatedInformation(message);
+  DiagnosticMessage mainMessage = _convertMessage(message);
+  List<DiagnosticMessage> infos = relatedInformation != null
+      ? relatedInformation.map(_convertMessage).toList()
+      : const [];
   switch (message.severity) {
     case fe.Severity.internalProblem:
-      throw text;
+      throw mainMessage.message.computeMessage();
     case fe.Severity.error:
-      reporter.reportErrorMessage(span, kind, {'text': text});
+      reporter.reportError(mainMessage, infos);
       break;
     case fe.Severity.warning:
-      reporter.reportWarningMessage(span, kind, {'text': text});
-      break;
-    case fe.Severity.context:
-      reporter.reportInfo(span, kind, {'text': text});
+      reporter.reportWarning(mainMessage, infos);
       break;
     default:
       throw new UnimplementedError('unhandled severity ${message.severity}');
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index c3b4306..4853aab 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -3,9 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
 import '../common/names.dart';
+import '../common/resolution.dart';
 import '../common_elements.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
@@ -15,6 +17,7 @@
 import '../ir/scope.dart';
 import '../ir/static_type.dart';
 import '../ir/impact.dart';
+import '../ir/impact_data.dart';
 import '../ir/util.dart';
 import '../js_backend/annotations.dart';
 import '../js_backend/native_data.dart';
@@ -27,7 +30,9 @@
 import '../universe/world_builder.dart';
 import 'element_map.dart';
 
-class KernelImpactBuilder extends ImpactBuilder {
+/// Visitor that computes the world impact of a member.
+class KernelImpactBuilder extends ImpactBuilderBase
+    with KernelImpactRegistryMixin {
   final ResolutionWorldImpactBuilder impactBuilder;
   final KernelToElementMap elementMap;
   final DiagnosticReporter reporter;
@@ -50,6 +55,47 @@
 
   bool get inferEffectivelyFinalVariableTypes =>
       !_annotations.contains(PragmaAnnotation.disableFinal);
+}
+
+/// Converts a [ImpactData] object based on kernel to the corresponding
+/// [ResolutionImpact] based on the K model.
+class KernelImpactConverter extends KernelImpactRegistryMixin {
+  final ResolutionWorldImpactBuilder impactBuilder;
+  final KernelToElementMap elementMap;
+  final DiagnosticReporter reporter;
+  final CompilerOptions _options;
+  final MemberEntity currentMember;
+
+  KernelImpactConverter(
+      this.elementMap, this.currentMember, this.reporter, this._options)
+      : this.impactBuilder =
+            new ResolutionWorldImpactBuilder('${currentMember}');
+
+  ir.TypeEnvironment get typeEnvironment => elementMap.typeEnvironment;
+
+  CommonElements get commonElements => elementMap.commonElements;
+
+  NativeBasicData get _nativeBasicData => elementMap.nativeBasicData;
+
+  /// Converts a [ImpactData] object based on kernel to the corresponding
+  /// [ResolutionImpact] based on the K model.
+  ResolutionImpact convert(ImpactData impactData) {
+    impactData.apply(this);
+    return impactBuilder;
+  }
+}
+
+/// [ImpactRegistry] that converts kernel based impact data to world impact
+/// object based on the K model.
+abstract class KernelImpactRegistryMixin implements ImpactRegistry {
+  CompilerOptions get _options;
+  DiagnosticReporter get reporter;
+  KernelToElementMap get elementMap;
+  MemberEntity get currentMember;
+  ResolutionWorldImpactBuilder get impactBuilder;
+  ir.TypeEnvironment get typeEnvironment;
+  CommonElements get commonElements;
+  NativeBasicData get _nativeBasicData;
 
   Object _computeReceiverConstraint(
       ir.DartType receiverType, ClassRelation relation) {
@@ -72,9 +118,9 @@
     }
   }
 
-  List<DartType> _getTypeArguments(ir.Arguments arguments) {
-    if (arguments.types.isEmpty) return null;
-    return arguments.types.map(elementMap.getDartType).toList();
+  List<DartType> _getTypeArguments(List<ir.DartType> types) {
+    if (types.isEmpty) return null;
+    return types.map(elementMap.getDartType).toList();
   }
 
   @override
@@ -83,9 +129,7 @@
   }
 
   @override
-  void handleField(ir.Field field) {
-    super.handleField(field);
-
+  void registerFieldNode(ir.Field field) {
     if (field.isInstanceMember &&
         elementMap.isNativeClass(field.enclosingClass)) {
       MemberEntity member = elementMap.getMember(field);
@@ -98,7 +142,7 @@
   }
 
   @override
-  void handleConstructor(ir.Constructor constructor) {
+  void registerConstructorNode(ir.Constructor constructor) {
     MemberEntity member = elementMap.getMember(constructor);
     if (constructor.isExternal && !commonElements.isForeignHelper(member)) {
       bool isJsInterop = _nativeBasicData.isJsInteropMember(member);
@@ -135,9 +179,7 @@
   }
 
   @override
-  void handleProcedure(ir.Procedure procedure) {
-    super.handleProcedure(procedure);
-
+  void registerProcedureNode(ir.Procedure procedure) {
     MemberEntity member = elementMap.getMember(procedure);
     if (procedure.isExternal && !commonElements.isForeignHelper(member)) {
       bool isJsInterop = _nativeBasicData.isJsInteropMember(member);
@@ -179,29 +221,43 @@
 
   @override
   void registerListLiteral(ir.DartType elementType,
-      {bool isConstant, bool isEmpty}) {
+      {bool isConst, bool isEmpty}) {
     impactBuilder.registerListLiteral(new ListLiteralUse(
         commonElements.listType(elementMap.getDartType(elementType)),
-        isConstant: isConstant,
+        isConstant: isConst,
         isEmpty: isEmpty));
   }
 
   @override
+  void registerSetLiteral(ir.DartType elementType,
+      {bool isConst, bool isEmpty}) {
+    // TODO(johnniwinther,fishythefish): Register set literals.
+  }
+
+  @override
   void registerMapLiteral(ir.DartType keyType, ir.DartType valueType,
-      {bool isConstant, bool isEmpty}) {
+      {bool isConst, bool isEmpty}) {
     impactBuilder.registerMapLiteral(new MapLiteralUse(
         commonElements.mapType(
             elementMap.getDartType(keyType), elementMap.getDartType(valueType)),
-        isConstant: isConstant,
+        isConstant: isConst,
         isEmpty: isEmpty));
   }
 
   @override
-  void registerNew(ir.Member target, ir.InterfaceType type,
-      ir.Arguments arguments, ir.LibraryDependency import,
+  void registerNew(
+      ir.Member target,
+      ir.InterfaceType type,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments,
+      ir.LibraryDependency import,
       {bool isConst}) {
     ConstructorEntity constructor = elementMap.getConstructor(target);
-    CallStructure callStructure = elementMap.getCallStructure(arguments);
+    CallStructure callStructure = new CallStructure(
+        positionalArguments + namedArguments.length,
+        namedArguments,
+        typeArguments.length);
     ImportEntity deferredImport = elementMap.getImport(import);
     impactBuilder.registerStaticUse(isConst
         ? new StaticUse.constConstructorInvoke(constructor, callStructure,
@@ -223,10 +279,14 @@
       // We need to register the external constructor as live below, so don't
       // return here.
     }
+  }
 
-    if (isConst && commonElements.isSymbolConstructor(constructor)) {
+  void registerConstConstructorInvocationNode(ir.ConstructorInvocation node) {
+    assert(node.isConst);
+    ConstructorEntity constructor = elementMap.getConstructor(node.target);
+    if (commonElements.isSymbolConstructor(constructor)) {
       ConstantValue value =
-          elementMap.getConstantValue(arguments.positional.first);
+          elementMap.getConstantValue(node.arguments.positional.first);
       if (!value.isString) {
         // TODO(het): Get the actual span for the Symbol constructor argument
         reporter.reportErrorMessage(
@@ -242,7 +302,11 @@
 
   @override
   void registerSuperInitializer(
-      ir.Constructor source, ir.Constructor target, ir.Arguments arguments) {
+      ir.Constructor source,
+      ir.Constructor target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
     // TODO(johnniwinther): Maybe rewrite `node.target` to point to a
     // synthesized unnamed mixin constructor when needed. This would require us
     // to consider impact building a required pre-step for inference and
@@ -250,29 +314,36 @@
     ConstructorEntity constructor =
         elementMap.getSuperConstructor(source, target);
     impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke(
-        constructor, elementMap.getCallStructure(arguments)));
+        constructor,
+        new CallStructure(positionalArguments + namedArguments.length,
+            namedArguments, typeArguments.length)));
   }
 
   @override
-  void registerStaticInvocation(ir.Procedure procedure, ir.Arguments arguments,
+  void registerStaticInvocation(
+      ir.Procedure procedure,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments,
       ir.LibraryDependency import) {
     FunctionEntity target = elementMap.getMethod(procedure);
-    CallStructure callStructure = elementMap.getCallStructure(arguments);
-    List<DartType> typeArguments = _getTypeArguments(arguments);
+    CallStructure callStructure = new CallStructure(
+        positionalArguments + namedArguments.length,
+        namedArguments,
+        typeArguments.length);
+    List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
     if (commonElements.isExtractTypeArguments(target)) {
-      _handleExtractTypeArguments(target, typeArguments, callStructure);
+      _handleExtractTypeArguments(target, dartTypeArguments, callStructure);
       return;
     } else {
       ImportEntity deferredImport = elementMap.getImport(import);
       impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-          target, callStructure, typeArguments, deferredImport));
+          target, callStructure, dartTypeArguments, deferredImport));
     }
   }
 
-  void handleStaticInvocation(ir.StaticInvocation node,
-      ArgumentTypes argumentTypes, ir.DartType returnType) {
-    super.handleStaticInvocation(node, argumentTypes, returnType);
-
+  @override
+  void registerStaticInvocationNode(ir.StaticInvocation node) {
     switch (elementMap.getForeignKind(node)) {
       case ForeignKind.JS:
         impactBuilder
@@ -346,13 +417,17 @@
   }
 
   @override
-  void registerSuperInvocation(ir.Name name, ir.Arguments arguments) {
+  void registerSuperInvocation(ir.Name name, int positionalArguments,
+      List<String> namedArguments, List<ir.DartType> typeArguments) {
     FunctionEntity method =
         elementMap.getSuperMember(currentMember, name, setter: false);
-    List<DartType> typeArguments = _getTypeArguments(arguments);
+    List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
     if (method != null) {
       impactBuilder.registerStaticUse(new StaticUse.superInvoke(
-          method, elementMap.getCallStructure(arguments), typeArguments));
+          method,
+          new CallStructure(positionalArguments + namedArguments.length,
+              namedArguments, typeArguments.length),
+          dartTypeArguments));
     } else {
       impactBuilder.registerStaticUse(new StaticUse.superInvoke(
           elementMap.getSuperNoSuchMethod(currentMember.enclosingClass),
@@ -399,50 +474,74 @@
 
   @override
   void registerLocalFunctionInvocation(
-      ir.FunctionDeclaration localFunction, ir.Arguments arguments) {
-    CallStructure callStructure = elementMap.getCallStructure(arguments);
-    List<DartType> typeArguments = _getTypeArguments(arguments);
+      ir.FunctionDeclaration localFunction,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    CallStructure callStructure = new CallStructure(
+        positionalArguments + namedArguments.length,
+        namedArguments,
+        typeArguments.length);
+    List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
     // Invocation of a local function. No need for dynamic use, but
     // we need to track the type arguments.
     impactBuilder.registerStaticUse(new StaticUse.closureCall(
         elementMap.getLocalFunction(localFunction),
         callStructure,
-        typeArguments));
+        dartTypeArguments));
     // TODO(johnniwinther): Yet, alas, we need the dynamic use for now. Remove
     // this when kernel adds an `isFunctionCall` flag to
     // [ir.MethodInvocation].
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        callStructure.callSelector, null, typeArguments));
+        callStructure.callSelector, null, dartTypeArguments));
   }
 
   @override
-  void registerDynamicInvocation(ir.DartType receiverType,
-      ClassRelation relation, ir.Name name, ir.Arguments arguments) {
-    Selector selector = elementMap.getInvocationSelector(name, arguments);
-    List<DartType> typeArguments = _getTypeArguments(arguments);
+  void registerDynamicInvocation(
+      ir.DartType receiverType,
+      ClassRelation relation,
+      ir.Name name,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    Selector selector = elementMap.getInvocationSelector(
+        name, positionalArguments, namedArguments, typeArguments.length);
+    List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(selector,
-        _computeReceiverConstraint(receiverType, relation), typeArguments));
+        _computeReceiverConstraint(receiverType, relation), dartTypeArguments));
   }
 
   @override
   void registerFunctionInvocation(
-      ir.DartType receiverType, ir.Arguments arguments) {
-    CallStructure callStructure = elementMap.getCallStructure(arguments);
-    List<DartType> typeArguments = _getTypeArguments(arguments);
+      ir.DartType receiverType,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    CallStructure callStructure = new CallStructure(
+        positionalArguments + namedArguments.length,
+        namedArguments,
+        typeArguments.length);
+    List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
         callStructure.callSelector,
         _computeReceiverConstraint(receiverType, ClassRelation.subtype),
-        typeArguments));
+        dartTypeArguments));
   }
 
   @override
-  void registerInstanceInvocation(ir.DartType receiverType,
-      ClassRelation relation, ir.Member target, ir.Arguments arguments) {
-    List<DartType> typeArguments = _getTypeArguments(arguments);
+  void registerInstanceInvocation(
+      ir.DartType receiverType,
+      ClassRelation relation,
+      ir.Member target,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
+    List<DartType> dartTypeArguments = _getTypeArguments(typeArguments);
     impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
-        elementMap.getInvocationSelector(target.name, arguments),
+        elementMap.getInvocationSelector(target.name, positionalArguments,
+            namedArguments, typeArguments.length),
         _computeReceiverConstraint(receiverType, relation),
-        typeArguments));
+        dartTypeArguments));
   }
 
   @override
@@ -481,7 +580,8 @@
         const <DartType>[]));
   }
 
-  void handleRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
+  @override
+  void registerRuntimeTypeUse(ir.PropertyGet node, RuntimeTypeUseKind kind,
       ir.DartType receiverType, ir.DartType argumentType) {
     DartType receiverDartType = elementMap.getDartType(receiverType);
     DartType argumentDartType =
@@ -562,7 +662,6 @@
   }
 
   @override
-  @override
   void registerThrow() {
     impactBuilder.registerFeature(Feature.THROW_EXPRESSION);
   }
@@ -619,10 +718,15 @@
 
   @override
   void registerRedirectingInitializer(
-      ir.Constructor constructor, ir.Arguments arguments) {
+      ir.Constructor constructor,
+      int positionalArguments,
+      List<String> namedArguments,
+      List<ir.DartType> typeArguments) {
     ConstructorEntity target = elementMap.getConstructor(constructor);
     impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke(
-        target, elementMap.getCallStructure(arguments)));
+        target,
+        new CallStructure(positionalArguments + namedArguments.length,
+            namedArguments, typeArguments.length)));
   }
 
   @override
@@ -633,7 +737,7 @@
   }
 
   @override
-  void handleSwitchStatement(ir.SwitchStatement node) {
+  void registerSwitchStatementNode(ir.SwitchStatement node) {
     // TODO(32557): Remove this when issue 32557 is fixed.
     ir.TreeNode firstCase;
     DartType firstCaseType;
diff --git a/pkg/compiler/lib/src/kernel/kernel_world.dart b/pkg/compiler/lib/src/kernel/kernel_world.dart
index af7cde7..1167b48 100644
--- a/pkg/compiler/lib/src/kernel/kernel_world.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_world.dart
@@ -16,6 +16,7 @@
 import '../js_backend/runtime_types.dart';
 import '../options.dart';
 import '../universe/class_hierarchy.dart';
+import '../universe/member_usage.dart';
 import '../universe/resolution_world_builder.dart';
 import '../world.dart';
 
@@ -46,7 +47,7 @@
 
   final Iterable<ClassEntity> liveNativeClasses;
 
-  final Iterable<MemberEntity> processedMembers;
+  final Map<MemberEntity, MemberUsage> liveMemberUsage;
 
   final ClassHierarchy classHierarchy;
 
@@ -70,7 +71,7 @@
       this.liveNativeClasses,
       this.liveInstanceMembers,
       this.assignedInstanceMembers,
-      this.processedMembers,
+      this.liveMemberUsage,
       this.mixinUses,
       this.typesImplementedBySubclasses,
       this.classHierarchy,
@@ -86,4 +87,7 @@
   bool isImplemented(ClassEntity cls) {
     return _implementedClasses.contains(cls);
   }
+
+  /// Needed for testing.
+  Iterable<MemberEntity> get processedMembers => liveMemberUsage.keys;
 }
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 19891b3..7b56f28 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -13,7 +13,7 @@
 
 import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
 import 'package:kernel/kernel.dart' hide LibraryDependency, Combinator;
-import 'package:kernel/target/targets.dart';
+import 'package:kernel/target/targets.dart' hide DiagnosticReporter;
 
 import '../../compiler_new.dart' as api;
 import '../common/tasks.dart' show CompilerTask, Measurer;
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 61900e4..07e03da 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -38,15 +38,15 @@
 }
 
 /// Description of the exception behaviour of native code.
-///
-/// TODO(sra): Replace with something that better supports specialization on
-/// first argument properties.
 class NativeThrowBehavior {
-  static const NativeThrowBehavior NEVER = const NativeThrowBehavior._(0);
-  static const NativeThrowBehavior MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS =
-      const NativeThrowBehavior._(1);
-  static const NativeThrowBehavior MAY = const NativeThrowBehavior._(2);
-  static const NativeThrowBehavior MUST = const NativeThrowBehavior._(3);
+  static const NativeThrowBehavior NEVER = NativeThrowBehavior._(0);
+  static const NativeThrowBehavior MAY = NativeThrowBehavior._(1);
+
+  /// Throws only if first argument is null.
+  static const NativeThrowBehavior NULL_NSM = NativeThrowBehavior._(2);
+
+  /// Throws if first argument is null, then may throw.
+  static const NativeThrowBehavior NULL_NSM_THEN_MAY = NativeThrowBehavior._(3);
 
   final int _bits;
   const NativeThrowBehavior._(this._bits);
@@ -55,43 +55,73 @@
 
   /// Does this behavior always throw a noSuchMethod check on a null first
   /// argument before any side effect or other exception?
-  // TODO(sra): Extend NativeThrowBehavior with the concept of NSM guard
-  // followed by other potential behavior.
-  bool get isNullNSMGuard => this == MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS;
+  bool get isNullNSMGuard => this == NULL_NSM || this == NULL_NSM_THEN_MAY;
 
   /// Does this behavior always act as a null noSuchMethod check, and has no
   /// other throwing behavior?
-  bool get isOnlyNullNSMGuard =>
-      this == MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS;
+  bool get isOnlyNullNSMGuard => this == NULL_NSM;
 
   /// Returns the behavior if we assume the first argument is not null.
   NativeThrowBehavior get onNonNull {
-    if (this == MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS) return NEVER;
+    if (this == NULL_NSM) return NEVER;
+    if (this == NULL_NSM_THEN_MAY) return MAY;
     return this;
   }
 
   String toString() {
     if (this == NEVER) return 'never';
     if (this == MAY) return 'may';
-    if (this == MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS) return 'null(1)';
-    if (this == MUST) return 'must';
+    if (this == NULL_NSM) return 'null(1)';
+    if (this == NULL_NSM_THEN_MAY) return 'null(1)+may';
     return 'NativeThrowBehavior($_bits)';
   }
 
   /// Canonical list of marker values.
   ///
   /// Added to make [NativeThrowBehavior] enum-like.
-  static const List<NativeThrowBehavior> values = const <NativeThrowBehavior>[
+  static const List<NativeThrowBehavior> values = [
     NEVER,
-    MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS,
     MAY,
-    MUST,
+    NULL_NSM,
+    NULL_NSM_THEN_MAY,
   ];
 
   /// Index to this marker within [values].
   ///
   /// Added to make [NativeThrowBehavior] enum-like.
   int get index => values.indexOf(this);
+
+  /// Deserializer helper.
+  static NativeThrowBehavior _bitsToValue(int bits) {
+    switch (bits) {
+      case 0:
+        return NEVER;
+      case 1:
+        return MAY;
+      case 2:
+        return NULL_NSM;
+      case 3:
+        return NULL_NSM_THEN_MAY;
+      default:
+        return null;
+    }
+  }
+
+  /// Sequence operator.
+  NativeThrowBehavior then(NativeThrowBehavior second) {
+    if (this == NEVER) return second;
+    if (this == MAY) return MAY;
+    if (this == NULL_NSM_THEN_MAY) return NULL_NSM_THEN_MAY;
+    assert(this == NULL_NSM);
+    if (second == NEVER) return this;
+    return NULL_NSM_THEN_MAY;
+  }
+
+  /// Choice operator.
+  NativeThrowBehavior or(NativeThrowBehavior other) {
+    if (this == other) return this;
+    return MAY;
+  }
 }
 
 /// A summary of the behavior of a native element.
@@ -190,21 +220,8 @@
       behavior.codeTemplateText = codeTemplateText;
       behavior.codeTemplate = js.js.parseForeignJS(codeTemplateText);
     }
-    switch (throwBehavior) {
-      case 0:
-        behavior.throwBehavior = NativeThrowBehavior.NEVER;
-        break;
-      case 1:
-        behavior.throwBehavior =
-            NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS;
-        break;
-      case 2:
-        behavior.throwBehavior = NativeThrowBehavior.MAY;
-        break;
-      case 3:
-        behavior.throwBehavior = NativeThrowBehavior.MUST;
-        break;
-    }
+    behavior.throwBehavior = NativeThrowBehavior._bitsToValue(throwBehavior);
+    assert(behavior.throwBehavior._bits == throwBehavior);
     behavior.isAllocation = isAllocation;
     behavior.useGvn = useGvn;
     return behavior;
@@ -319,12 +336,12 @@
   ///    indicated with 'no-static'. The flags 'effects' and 'depends' must be
   ///    used in unison (either both are present or none is).
   ///
-  ///    The <throws-string> values are 'never', 'may', 'must', and 'null(1)'.
-  ///    The default if unspecified is 'may'. 'null(1)' means that the template
-  ///    expression throws if and only if the first template parameter is `null`
-  ///    or `undefined`.
-  ///    TODO(sra): Can we simplify to must/may/never and add null(1) by
-  ///    inspection as an orthogonal attribute?
+  ///    The <throws-string> values are 'never', 'may', 'null(1)', and
+  ///    'null(1)+may'.  The default if unspecified is 'may'. 'null(1)' means
+  ///    that the template expression throws if and only if the first template
+  ///    parameter is `null` or `undefined`, and 'null(1)+may' throws if the
+  ///    first argument is `null` / `undefined`, and then may throw for other
+  ///    reasons.
   ///
   ///    <gvn-string> values are 'true' and 'false'. The default if unspecified
   ///    is 'false'.
@@ -478,14 +495,14 @@
       });
     }
 
-    const throwsOption = const <String, NativeThrowBehavior>{
+    const throwsOption = <String, NativeThrowBehavior>{
       'never': NativeThrowBehavior.NEVER,
-      'null(1)': NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS,
       'may': NativeThrowBehavior.MAY,
-      'must': NativeThrowBehavior.MUST
+      'null(1)': NativeThrowBehavior.NULL_NSM,
+      'null(1)+may': NativeThrowBehavior.NULL_NSM_THEN_MAY,
     };
 
-    const boolOptions = const <String, bool>{'true': true, 'false': false};
+    const boolOptions = <String, bool>{'true': true, 'false': false};
 
     SideEffects sideEffects =
         processEffects(reportError, values['effects'], values['depends']);
diff --git a/pkg/compiler/lib/src/native/js.dart b/pkg/compiler/lib/src/native/js.dart
index 1b065a1..0c83197 100644
--- a/pkg/compiler/lib/src/native/js.dart
+++ b/pkg/compiler/lib/src/native/js.dart
@@ -131,26 +131,18 @@
     return visit(node);
   }
 
-  // TODO(sra): Add [sequence] functionality to NativeThrowBehavior.
   /// Returns the combined behavior of sequential execution of code having
   /// behavior [first] followed by code having behavior [second].
   static NativeThrowBehavior sequence(
       NativeThrowBehavior first, NativeThrowBehavior second) {
-    if (first == NativeThrowBehavior.MUST) return first;
-    if (second == NativeThrowBehavior.MUST) return second;
-    if (second == NativeThrowBehavior.NEVER) return first;
-    if (first == NativeThrowBehavior.NEVER) return second;
-    // Both are one of MAY or MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS.
-    return NativeThrowBehavior.MAY;
+    return first.then(second);
   }
 
-  // TODO(sra): Add [choice] functionality to NativeThrowBehavior.
   /// Returns the combined behavior of a choice between two paths with behaviors
   /// [first] and [second].
   static NativeThrowBehavior choice(
       NativeThrowBehavior first, NativeThrowBehavior second) {
-    if (first == second) return first; // Both paths have same behaviour.
-    return NativeThrowBehavior.MAY;
+    return first.or(second);
   }
 
   NativeThrowBehavior visit(js.Node node) {
@@ -173,12 +165,16 @@
     return NativeThrowBehavior.NEVER;
   }
 
+  NativeThrowBehavior visitArrayInitializer(js.ArrayInitializer node) {
+    return node.elements.map(visit).fold(NativeThrowBehavior.NEVER, sequence);
+  }
+
+  NativeThrowBehavior visitArrayHole(js.ArrayHole node) {
+    return NativeThrowBehavior.NEVER;
+  }
+
   NativeThrowBehavior visitObjectInitializer(js.ObjectInitializer node) {
-    NativeThrowBehavior result = NativeThrowBehavior.NEVER;
-    for (js.Property property in node.properties) {
-      result = sequence(result, visit(property));
-    }
-    return result;
+    return node.properties.map(visit).fold(NativeThrowBehavior.NEVER, sequence);
   }
 
   NativeThrowBehavior visitProperty(js.Property node) {
@@ -191,6 +187,17 @@
   }
 
   NativeThrowBehavior visitCall(js.Call node) {
+    js.Expression target = node.target;
+    if (target is js.PropertyAccess && _isFirstInterpolatedProperty(target)) {
+      // #.f(...): Evaluate selector 'f', dereference, evaluate arguments, and
+      // finally call target.
+      NativeThrowBehavior result =
+          sequence(visit(target.selector), NativeThrowBehavior.NULL_NSM);
+      for (js.Expression argument in node.arguments) {
+        result = sequence(result, visit(argument));
+      }
+      return sequence(result, NativeThrowBehavior.MAY); // Target may throw.
+    }
     return NativeThrowBehavior.MAY;
   }
 
@@ -242,7 +249,7 @@
   }
 
   NativeThrowBehavior visitThrow(js.Throw node) {
-    return NativeThrowBehavior.MUST;
+    return sequence(visit(node.expression), NativeThrowBehavior.MAY);
   }
 
   NativeThrowBehavior visitPrefix(js.Prefix node) {
@@ -269,6 +276,7 @@
     // global names are almost certainly not reference errors, e.g 'Array'.
     switch (node.name) {
       case 'Array':
+      case 'Math':
       case 'Object':
         return NativeThrowBehavior.NEVER;
       default:
@@ -277,20 +285,26 @@
   }
 
   NativeThrowBehavior visitAccess(js.PropertyAccess node) {
-    // TODO(sra): We need a representation where the nsm guard behaviour is
-    // maintained when combined with other throwing behaviour.
     js.Node receiver = node.receiver;
     NativeThrowBehavior first = visit(receiver);
     NativeThrowBehavior second = visit(node.selector);
 
-    if (receiver is js.InterpolatedExpression &&
-        receiver.isPositional &&
-        receiver.nameOrPosition == 0) {
-      first = NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS;
+    if (_isFirstInterpolatedProperty(node)) {
+      first = NativeThrowBehavior.NULL_NSM;
     } else {
       first = NativeThrowBehavior.MAY;
     }
 
     return sequence(first, second);
   }
+
+  bool _isFirstInterpolatedProperty(js.PropertyAccess node) {
+    js.Node receiver = node.receiver;
+    if (receiver is js.InterpolatedExpression &&
+        receiver.isPositional &&
+        receiver.nameOrPosition == 0) {
+      return true;
+    }
+    return false;
+  }
 }
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index 31936b5..f621d9e 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -72,6 +72,12 @@
       // using a JS-call.
       _setNativeName(element);
       return true;
+    } else {
+      String name = _findJsNameFromAnnotation(element);
+      if (name != null) {
+        failedAt(element,
+            '@JSName(...) annotation is not supported for static fields.');
+      }
     }
     return false;
   }
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index e3b4f3e..efec511 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -8,7 +8,6 @@
     show Link, LinkBuilder, LinkEntry;
 
 import 'common.dart';
-import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
 import 'elements/entities.dart';
 import 'elements/types.dart';
 import 'serialization/serialization.dart';
@@ -35,9 +34,8 @@
 
   final List<Link<InterfaceType>> _levels;
   final Link<InterfaceType> types;
-  final Link<InterfaceType> _supertypes;
 
-  OrderedTypeSet.internal(this._levels, this.types, this._supertypes);
+  OrderedTypeSet.internal(this._levels, this.types);
 
   /// Deserializes a [OrderedTypeSet] object from [source].
   factory OrderedTypeSet.readFromDataSource(DataSource source) {
@@ -55,15 +53,6 @@
         typeLinkBuilder.toLink(const Link<InterfaceType>());
     links.add(const Link<InterfaceType>());
 
-    int supertypesCount = source.readInt();
-    LinkBuilder<InterfaceType> supertypeLinkBuilder =
-        new LinkBuilder<InterfaceType>();
-    for (int i = 0; i < supertypesCount; i++) {
-      supertypeLinkBuilder.addLast(source.readDartType());
-    }
-    Link<InterfaceType> supertypes =
-        supertypeLinkBuilder.toLink(const Link<InterfaceType>());
-
     int levelCount = source.readInt();
     List<Link<InterfaceType>> levels =
         new List<Link<InterfaceType>>(levelCount);
@@ -71,7 +60,7 @@
       levels[i] = links[source.readInt()];
     }
     source.end(tag);
-    return new OrderedTypeSet.internal(levels, types, supertypes);
+    return new OrderedTypeSet.internal(levels, types);
   }
 
   /// Serializes this [OrderedTypeSet] to [sink].
@@ -82,11 +71,6 @@
     for (InterfaceType type in typeList) {
       sink.writeDartType(type);
     }
-    List<InterfaceType> supertypeList = _supertypes.toList();
-    sink.writeInt(supertypeList.length);
-    for (InterfaceType supertype in supertypeList) {
-      sink.writeDartType(supertype);
-    }
     List<int> levelList = [];
     Link<InterfaceType> link = types;
     while (link != null) {
@@ -108,8 +92,7 @@
         new LinkEntry<InterfaceType>(type, const Link<InterfaceType>());
     List<Link<InterfaceType>> list = new List<Link<InterfaceType>>(1);
     list[0] = types;
-    return new OrderedTypeSet.internal(
-        list, types, const Link<InterfaceType>());
+    return new OrderedTypeSet.internal(list, types);
   }
 
   /// Creates a new [OrderedTypeSet] for [type] when it directly extends the
@@ -129,11 +112,10 @@
       list[i] = _levels[i];
     }
     list[levels] = extendedTypes;
-    return new OrderedTypeSet.internal(
-        list, extendedTypes, _supertypes.prepend(types.head));
+    return new OrderedTypeSet.internal(list, extendedTypes);
   }
 
-  Link<InterfaceType> get supertypes => _supertypes;
+  Link<InterfaceType> get supertypes => types.tail;
 
   int get levels => _levels.length;
 
@@ -219,16 +201,11 @@
 abstract class OrderedTypeSetBuilderBase implements OrderedTypeSetBuilder {
   Map<int, LinkEntry<InterfaceType>> map =
       new Map<int, LinkEntry<InterfaceType>>();
-  // TODO(15296): Avoid computing this order on the side when member
-  // lookup handles multiply inherited members correctly.
-  LinkBuilder<InterfaceType> allSupertypes = new LinkBuilder<InterfaceType>();
   int maxDepth = -1;
 
-  final DiagnosticReporter reporter;
   final ClassEntity cls;
-  final InterfaceType _objectType;
 
-  OrderedTypeSetBuilderBase(this.cls, this._objectType, {this.reporter});
+  OrderedTypeSetBuilderBase(this.cls);
 
   InterfaceType getThisType(covariant ClassEntity cls);
   InterfaceType substByContext(
@@ -273,21 +250,12 @@
 
   void add(InterfaceType type) {
     if (type.element == cls) {
-      if (type != _objectType) {
-        allSupertypes.addLast(_objectType);
-      }
       _addAtDepth(type, maxDepth + 1);
     } else {
-      if (type != _objectType) {
-        allSupertypes.addLast(type);
-      }
       _addAtDepth(type, getHierarchyDepth(type.element));
     }
   }
 
-  // TODO(sigmund): delete once Issue #31118 is fixed.
-  bool get reportMultiInheritanceIssue => true;
-
   void _addAtDepth(InterfaceType type, int depth) {
     LinkEntry<InterfaceType> prev = null;
     LinkEntry<InterfaceType> link = map[depth];
@@ -295,17 +263,7 @@
       InterfaceType existingType = link.head;
       if (existingType == type) return;
       if (existingType.element == type.element) {
-        if (reporter != null) {
-          if (reportMultiInheritanceIssue) {
-            reporter.reportErrorMessage(cls, MessageKind.MULTI_INHERITANCE, {
-              'thisType': getThisType(cls),
-              'firstType': existingType,
-              'secondType': type
-            });
-          }
-        } else {
-          assert(false, failedAt(cls, 'Invalid ordered typeset for $cls'));
-        }
+        assert(false, failedAt(cls, 'Invalid ordered typeset for $cls'));
         return;
       }
       prev = link;
@@ -327,8 +285,7 @@
     List<Link<InterfaceType>> levels =
         new List<Link<InterfaceType>>(maxDepth + 1);
     if (maxDepth < 0) {
-      return new OrderedTypeSet.internal(
-          levels, const Link<InterfaceType>(), const Link<InterfaceType>());
+      return new OrderedTypeSet.internal(levels, const Link<InterfaceType>());
     }
     Link<InterfaceType> next = const Link<InterfaceType>();
     for (int depth = 0; depth <= maxDepth; depth++) {
@@ -345,8 +302,7 @@
         next = first;
       }
     }
-    return new OrderedTypeSet.internal(
-        levels, levels.last, allSupertypes.toLink(const Link<InterfaceType>()));
+    return new OrderedTypeSet.internal(levels, levels.last);
   }
 
   String toString() {
diff --git a/pkg/compiler/lib/src/serialization/abstract_sink.dart b/pkg/compiler/lib/src/serialization/abstract_sink.dart
index 07116be..d63db8f 100644
--- a/pkg/compiler/lib/src/serialization/abstract_sink.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_sink.dart
@@ -203,7 +203,7 @@
   void writeInt(int value) {
     assert(value != null);
     assert(value >= 0 && value >> 30 == 0);
-    _writeDataKind(DataKind.int);
+    _writeDataKind(DataKind.uint30);
     _writeIntInternal(value);
   }
 
@@ -338,6 +338,31 @@
     _writeConstant(value);
   }
 
+  @override
+  void writeDoubleValue(double value) {
+    _writeDataKind(DataKind.double);
+    _writeDoubleValue(value);
+  }
+
+  void _writeDoubleValue(double value) {
+    ByteData data = new ByteData(8);
+    data.setFloat64(0, value);
+    writeInt(data.getUint16(0));
+    writeInt(data.getUint16(2));
+    writeInt(data.getUint16(4));
+    writeInt(data.getUint16(6));
+  }
+
+  @override
+  void writeIntegerValue(int value) {
+    _writeDataKind(DataKind.int);
+    _writeBigInt(new BigInt.from(value));
+  }
+
+  void _writeBigInt(BigInt value) {
+    writeString(value.toString());
+  }
+
   void _writeConstant(ConstantValue value) {
     _writeEnumInternal(value.kind);
     switch (value.kind) {
@@ -347,16 +372,11 @@
         break;
       case ConstantValueKind.INT:
         IntConstantValue constant = value;
-        writeString(constant.intValue.toString());
+        _writeBigInt(constant.intValue);
         break;
       case ConstantValueKind.DOUBLE:
         DoubleConstantValue constant = value;
-        ByteData data = new ByteData(8);
-        data.setFloat64(0, constant.doubleValue);
-        writeInt(data.getUint16(0));
-        writeInt(data.getUint16(2));
-        writeInt(data.getUint16(4));
-        writeInt(data.getUint16(6));
+        _writeDoubleValue(constant.doubleValue);
         break;
       case ConstantValueKind.STRING:
         StringConstantValue constant = value;
diff --git a/pkg/compiler/lib/src/serialization/abstract_source.dart b/pkg/compiler/lib/src/serialization/abstract_source.dart
index 28fdf8a..792ae23 100644
--- a/pkg/compiler/lib/src/serialization/abstract_source.dart
+++ b/pkg/compiler/lib/src/serialization/abstract_source.dart
@@ -393,7 +393,7 @@
 
   @override
   int readInt() {
-    _checkDataKind(DataKind.int);
+    _checkDataKind(DataKind.uint30);
     return _readIntInternal();
   }
 
@@ -409,6 +409,29 @@
     return _readConstant();
   }
 
+  double readDoubleValue() {
+    _checkDataKind(DataKind.double);
+    return _readDoubleValue();
+  }
+
+  double _readDoubleValue() {
+    ByteData data = new ByteData(8);
+    data.setUint16(0, readInt());
+    data.setUint16(2, readInt());
+    data.setUint16(4, readInt());
+    data.setUint16(6, readInt());
+    return data.getFloat64(0);
+  }
+
+  int readIntegerValue() {
+    _checkDataKind(DataKind.int);
+    return _readBigInt().toInt();
+  }
+
+  BigInt _readBigInt() {
+    return BigInt.parse(readString());
+  }
+
   ConstantValue _readConstant() {
     ConstantValueKind kind = _readEnumInternal(ConstantValueKind.values);
     switch (kind) {
@@ -416,15 +439,10 @@
         bool value = readBool();
         return new BoolConstantValue(value);
       case ConstantValueKind.INT:
-        BigInt value = BigInt.parse(readString());
+        BigInt value = _readBigInt();
         return new IntConstantValue(value);
       case ConstantValueKind.DOUBLE:
-        ByteData data = new ByteData(8);
-        data.setUint16(0, readInt());
-        data.setUint16(2, readInt());
-        data.setUint16(4, readInt());
-        data.setUint16(6, readInt());
-        double value = data.getFloat64(0);
+        double value = _readDoubleValue();
         return new DoubleConstantValue(value);
       case ConstantValueKind.STRING:
         String value = readString();
diff --git a/pkg/compiler/lib/src/serialization/helpers.dart b/pkg/compiler/lib/src/serialization/helpers.dart
index a75b7e3..d6db5f2 100644
--- a/pkg/compiler/lib/src/serialization/helpers.dart
+++ b/pkg/compiler/lib/src/serialization/helpers.dart
@@ -10,7 +10,7 @@
 /// and deserialization.
 enum DataKind {
   bool,
-  int,
+  uint30,
   string,
   enumValue,
   uri,
@@ -25,6 +25,8 @@
   sourceSpan,
   constant,
   import,
+  double,
+  int,
 }
 
 /// Enum used for identifying the enclosing entity of a member in serialization.
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index eb86a2a..be891a1 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -313,6 +313,36 @@
     }
     return map;
   }
+
+  @override
+  List<ir.DartType> readDartTypeNodes({bool emptyAsNull: false}) {
+    int count = readInt();
+    if (count == 0 && emptyAsNull) return null;
+    List<ir.DartType> list = new List<ir.DartType>(count);
+    for (int i = 0; i < count; i++) {
+      list[i] = readDartTypeNode();
+    }
+    return list;
+  }
+
+  @override
+  ir.Name readName() {
+    String text = readString();
+    ir.Library library = readValueOrNull(readLibraryNode);
+    return new ir.Name(text, library);
+  }
+
+  @override
+  ir.LibraryDependency readLibraryDependencyNode() {
+    ir.Library library = readLibraryNode();
+    int index = readInt();
+    return library.dependencies[index];
+  }
+
+  @override
+  ir.LibraryDependency readLibraryDependencyNodeOrNull() {
+    return readValueOrNull(readLibraryDependencyNode);
+  }
 }
 
 /// Mixin that implements all convenience methods of [DataSink].
@@ -643,4 +673,36 @@
       });
     }
   }
+
+  @override
+  void writeDartTypeNodes(Iterable<ir.DartType> values,
+      {bool allowNull: false}) {
+    if (values == null) {
+      assert(allowNull);
+      writeInt(0);
+    } else {
+      writeInt(values.length);
+      for (ir.DartType value in values) {
+        writeDartTypeNode(value);
+      }
+    }
+  }
+
+  @override
+  void writeName(ir.Name value) {
+    writeString(value.name);
+    writeValueOrNull(value.library, writeLibraryNode);
+  }
+
+  @override
+  void writeLibraryDependencyNode(ir.LibraryDependency value) {
+    ir.Library library = value.parent;
+    writeLibraryNode(library);
+    writeInt(library.dependencies.indexOf(value));
+  }
+
+  @override
+  void writeLibraryDependencyNodeOrNull(ir.LibraryDependency value) {
+    writeValueOrNull(value, writeLibraryDependencyNode);
+  }
 }
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 3348edd..c4dab5a 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -75,7 +75,7 @@
   /// Writes the boolean [value] to this data sink.
   void writeBool(bool value);
 
-  /// Writes the non-negative integer [value] to this data sink.
+  /// Writes the non-negative 30 bit integer [value] to this data sink.
   void writeInt(int value);
 
   /// Writes the potentially `null` non-negative [value] to this data sink.
@@ -137,6 +137,16 @@
   /// [DataSource.readMemberNodes].
   void writeMemberNodes(Iterable<ir.Member> values, {bool allowNull: false});
 
+  /// Writes a kernel name node to this data sink.
+  void writeName(ir.Name value);
+
+  /// Writes a kernel library dependency node [value] to this data sink.
+  void writeLibraryDependencyNode(ir.LibraryDependency value);
+
+  /// Writes a potentially `null` kernel library dependency node [value] to
+  /// this data sink.
+  void writeLibraryDependencyNodeOrNull(ir.LibraryDependency value);
+
   /// Writes a reference to the kernel tree node [value] to this data sink.
   void writeTreeNode(ir.TreeNode value);
 
@@ -191,6 +201,14 @@
   /// `true`, [value] is allowed to be `null`.
   void writeDartTypeNode(ir.DartType value, {bool allowNull: false});
 
+  /// Writes the kernel type node [values] to this data sink. If [allowNull] is
+  /// `true`, [values] is allowed to be `null`.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSource.readDartTypeNodes].
+  void writeDartTypeNodes(Iterable<ir.DartType> values,
+      {bool allowNull: false});
+
   /// Writes the source span [value] to this data sink.
   void writeSourceSpan(SourceSpan value);
 
@@ -313,6 +331,15 @@
   void writeConstantMap<V>(Map<ConstantValue, V> map, void f(V value),
       {bool allowNull: false});
 
+  /// Writes a double value to this data sink.
+  void writeDoubleValue(double value);
+
+  /// Writes an integer of arbitrary value to this data sink.
+  ///
+  /// This is should only when the value is not known to be a non-negative
+  /// 30 bit integer. Otherwise [writeInt] should be used.
+  void writeIntegerValue(int value);
+
   /// Writes the import [value] to this data sink.
   void writeImport(ImportEntity value);
 
@@ -380,7 +407,7 @@
   /// Reads a boolean value from this data source.
   bool readBool();
 
-  /// Reads a non-negative integer value from this data source.
+  /// Reads a non-negative 30 bit integer value from this data source.
   int readInt();
 
   /// Reads a potentially `null` non-negative integer value from this data
@@ -448,6 +475,16 @@
   List<ir.Member> readMemberNodes<E extends ir.Member>(
       {bool emptyAsNull: false});
 
+  /// Reads a kernel name node from this data source.
+  ir.Name readName();
+
+  /// Reads a kernel library dependency node from this data source.
+  ir.LibraryDependency readLibraryDependencyNode();
+
+  /// Reads a potentially `null` kernel library dependency node from this data
+  /// source.
+  ir.LibraryDependency readLibraryDependencyNodeOrNull();
+
   /// Reads a reference to a kernel tree node from this data source.
   ir.TreeNode readTreeNode();
 
@@ -497,6 +534,13 @@
   /// returned type is allowed to be `null`.
   ir.DartType readDartTypeNode({bool allowNull: false});
 
+  /// Reads a list of kernel type nodes from this data source. If [emptyAsNull]
+  /// is `true`, `null` is returned instead of an empty list.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSink.writeDartTypeNodes].
+  List<ir.DartType> readDartTypeNodes({bool emptyAsNull: false});
+
   /// Reads a source span from this data source.
   SourceSpan readSourceSpan();
 
@@ -582,6 +626,15 @@
   /// Reads a constant value from this data source.
   ConstantValue readConstant();
 
+  /// Reads a double value from this data source.
+  double readDoubleValue();
+
+  /// Reads an integer of arbitrary value from this data source.
+  ///
+  /// This is should only when the value is not known to be a non-negative
+  /// 30 bit integer. Otherwise [readInt] should be used.
+  int readIntegerValue();
+
   /// Reads a list of constant values from this data source. If [emptyAsNull] is
   /// `true`, `null` is returned instead of an empty list.
   ///
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 1674df2..e8d55ba 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -31,7 +31,7 @@
 import '../js_backend/backend.dart' show FunctionInlineCache, JavaScriptBackend;
 import '../js_backend/runtime_types.dart' show RuntimeTypesSubstitutions;
 import '../js_emitter/js_emitter.dart' show NativeEmitter;
-import '../js_model/locals.dart' show forEachOrderedParameter, JumpVisitor;
+import '../js_model/locals.dart' show JumpVisitor;
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../js_model/element_map.dart';
 import '../js_model/js_strategy.dart';
@@ -63,6 +63,8 @@
   final MemberEntity member;
   final AsyncMarker asyncMarker;
   final KernelToLocalsMap localsMap;
+  // [ir.Let] and [ir.LocalInitializer] bindings.
+  final Map<ir.VariableDeclaration, HInstruction> letBindings;
   final KernelToTypeInferenceMap typeInferenceMap;
   final SourceInformationBuilder sourceInformationBuilder;
   final StaticTypeProvider staticTypeProvider;
@@ -72,6 +74,7 @@
       this.member,
       this.asyncMarker,
       this.localsMap,
+      this.letBindings,
       this.typeInferenceMap,
       this.sourceInformationBuilder,
       this.staticTypeProvider);
@@ -115,10 +118,6 @@
 
   final NativeEmitter nativeEmitter;
 
-  // [ir.Let] and [ir.LocalInitializer] bindings.
-  final Map<ir.VariableDeclaration, HInstruction> letBindings =
-      <ir.VariableDeclaration, HInstruction>{};
-
   /// True if we are visiting the expression of a throw statement; we assume
   /// this is a slow path.
   bool _inExpressionOfThrow = false;
@@ -160,6 +159,9 @@
 
   KernelToLocalsMap get localsMap => _currentFrame.localsMap;
 
+  Map<ir.VariableDeclaration, HInstruction> get letBindings =>
+      _currentFrame.letBindings;
+
   JCommonElements get _commonElements => _elementMap.commonElements;
 
   KernelToTypeInferenceMap get _typeInferenceMap =>
@@ -192,6 +194,7 @@
         member,
         asyncMarker,
         closedWorld.globalLocalsMap.getLocalsMap(member),
+        {},
         new KernelToTypeInferenceMapImpl(member, globalInferenceResults),
         _currentFrame != null
             ? _currentFrame.sourceInformationBuilder
@@ -360,7 +363,9 @@
       graph.entry.addBefore(graph.entry.last, parameter);
       HInstruction value = typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
           parameter, _getDartTypeIfValid(node.type));
-      add(new HFieldSet(abstractValueDomain, field, thisInstruction, value));
+      if (!closedWorld.elidedFields.contains(field)) {
+        add(new HFieldSet(abstractValueDomain, field, thisInstruction, value));
+      }
     } else {
       if (node.initializer != null) {
         node.initializer.accept(this);
@@ -438,25 +443,31 @@
   void _addFunctionTypeVariablesIfNeeded(MemberEntity member) {
     if (member is! FunctionEntity) return;
 
+    FunctionEntity function = member;
     List<TypeVariableType> typeVariables =
-        _elementMap.elementEnvironment.getFunctionTypeVariables(member);
+        _elementMap.elementEnvironment.getFunctionTypeVariables(function);
     if (typeVariables.isEmpty) {
       return;
     }
-    bool needsTypeArguments = rtiNeed.methodNeedsTypeArguments(member);
-    typeVariables.forEach((TypeVariableType typeVariableType) {
+    bool needsTypeArguments = rtiNeed.methodNeedsTypeArguments(function);
+    bool elideTypeParameters = function.parameterStructure.typeParameters == 0;
+    for (TypeVariableType typeVariable
+        in _elementMap.elementEnvironment.getFunctionTypeVariables(function)) {
       HInstruction param;
-      if (needsTypeArguments) {
-        param = addParameter(
-            typeVariableType.element, abstractValueDomain.nonNullType);
+      if (elideTypeParameters) {
+        // Add elided type parameters.
+        param = _computeTypeArgumentDefaultValue(function, typeVariable);
+      } else if (needsTypeArguments) {
+        param =
+            addParameter(typeVariable.element, abstractValueDomain.nonNullType);
       } else {
         // Unused, so bind to `dynamic`.
         param = graph.addConstantNull(closedWorld);
       }
-      Local local = localsHandler.getTypeVariableAsLocal(typeVariableType);
+      Local local = localsHandler.getTypeVariableAsLocal(typeVariable);
       localsHandler.directLocals[local] = param;
       functionTypeParameterLocals.add(local);
-    });
+    }
   }
 
   List<Local> functionTypeParameterLocals = <Local>[];
@@ -495,7 +506,9 @@
 
     if (_inliningStack.isEmpty) {
       openFunction(constructor,
-          functionNode: node.function, checks: TargetChecks.none);
+          functionNode: node.function,
+          parameterStructure: constructor.parameterStructure,
+          checks: TargetChecks.none);
     }
 
     // [constructorData.fieldValues] accumulates the field initializer values,
@@ -511,7 +524,7 @@
     InterfaceType thisType = _elementMap.elementEnvironment.getThisType(cls);
     List<FieldEntity> fields = <FieldEntity>[];
     _worldBuilder.forEachInstanceField(cls,
-        (ClassEntity enclosingClass, FieldEntity member) {
+        (ClassEntity enclosingClass, FieldEntity member, {bool isElided}) {
       HInstruction value = constructorData.fieldValues[member];
       if (value == null) {
         assert(
@@ -520,11 +533,13 @@
                 reporter.hasReportedError,
             'No initializer value for field ${member}');
       } else {
-        fields.add(member);
-        DartType type = _elementMap.elementEnvironment.getFieldType(member);
-        type = localsHandler.substInContext(type);
-        constructorArguments.add(
-            typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type));
+        if (!isElided) {
+          fields.add(member);
+          DartType type = _elementMap.elementEnvironment.getFieldType(member);
+          type = localsHandler.substInContext(type);
+          constructorArguments.add(
+              typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type));
+        }
       }
     });
 
@@ -602,7 +617,12 @@
       inlinedFrom(
           inlinedConstructor, _sourceInformationBuilder.buildCall(body, body),
           () {
-        void handleParameter(ir.VariableDeclaration node) {
+        ConstructorBodyEntity constructorBody =
+            _elementMap.getConstructorBody(body);
+
+        void handleParameter(ir.VariableDeclaration node, {bool isElided}) {
+          if (isElided) return;
+
           Local parameter = localsMap.getLocalVariable(node);
           // If [parameter] is boxed, it will be a field in the box passed as
           // the last parameter. So no need to directly pass it.
@@ -612,21 +632,18 @@
         }
 
         // Provide the parameters to the generative constructor body.
-        body.function.positionalParameters.forEach(handleParameter);
-        body.function.namedParameters.toList()
-          ..sort(namedOrdering)
-          ..forEach(handleParameter);
+        forEachOrderedParameter(_elementMap, constructorBody, handleParameter);
 
         // If there are locals that escape (i.e. mutated in closures), we pass the
         // box to the constructor.
         CapturedScope scopeData =
-            closureDataLookup.getCapturedScope(inlinedConstructor);
+            closureDataLookup.getCapturedScope(constructorBody);
         if (scopeData.requiresContextBox) {
           bodyCallInputs.add(localsHandler.readLocal(scopeData.context));
         }
 
         // Pass type arguments.
-        ClassEntity inlinedConstructorClass = inlinedConstructor.enclosingClass;
+        ClassEntity inlinedConstructorClass = constructorBody.enclosingClass;
         if (closedWorld.rtiNeed
             .classNeedsTypeArguments(inlinedConstructorClass)) {
           InterfaceType thisType = _elementMap.elementEnvironment
@@ -639,8 +656,6 @@
           }
         }
 
-        ConstructorBodyEntity constructorBody =
-            _elementMap.getConstructorBody(body);
         if (!isCustomElement && // TODO(13836): Fix inlining.
             _tryInlineMethod(constructorBody, null, null, bodyCallInputs, null,
                 node, sourceInformation)) {
@@ -717,7 +732,8 @@
   /// [clazz].
   void _collectFieldValues(ir.Class clazz, ConstructorData constructorData) {
     ClassEntity cls = _elementMap.getClass(clazz);
-    _worldBuilder.forEachDirectInstanceField(cls, (FieldEntity field) {
+    _worldBuilder.forEachDirectInstanceField(cls, (FieldEntity field,
+        {bool isElided}) {
       _ensureTypeVariablesForInitializers(
           constructorData, field.enclosingClass);
 
@@ -990,8 +1006,12 @@
 
   /// Builds generative constructor body.
   void buildConstructorBody(ir.Constructor constructor) {
-    openFunction(_elementMap.getConstructorBody(constructor),
-        functionNode: constructor.function, checks: TargetChecks.none);
+    FunctionEntity constructorBody =
+        _elementMap.getConstructorBody(constructor);
+    openFunction(constructorBody,
+        functionNode: constructor.function,
+        parameterStructure: constructorBody.parameterStructure,
+        checks: TargetChecks.none);
     constructor.function.body.accept(this);
     closeFunction();
   }
@@ -1009,7 +1029,9 @@
     // checks.
     // TODO(sra): Instance methods can be generated with reduced checks if
     // called only from non-dynamic call-sites.
-    openFunction(function, functionNode: functionNode);
+    openFunction(function,
+        functionNode: functionNode,
+        parameterStructure: function.parameterStructure);
 
     // If [functionNode] is `operator==` we explicitly add a null check at the
     // beginning of the method. This is to avoid having call sites do the null
@@ -1066,7 +1088,9 @@
   /// per-invocation checks and the body, which is later transformed, contains
   /// the re-entrant 'state machine' code.
   void buildGenerator(FunctionEntity function, ir.FunctionNode functionNode) {
-    openFunction(function, functionNode: functionNode);
+    openFunction(function,
+        functionNode: functionNode,
+        parameterStructure: function.parameterStructure);
 
     // Prepare to tail-call the body.
 
@@ -1082,7 +1106,9 @@
       inputs.add(graph.explicitReceiverParameter);
     }
     for (Local local in parameters.keys) {
-      inputs.add(localsHandler.readLocal(local));
+      if (!elidedParameters.contains(local)) {
+        inputs.add(localsHandler.readLocal(local));
+      }
     }
     for (Local local in functionTypeParameterLocals) {
       inputs.add(localsHandler.readLocal(local));
@@ -1130,7 +1156,10 @@
   void buildGeneratorBody(
       JGeneratorBody function, ir.FunctionNode functionNode) {
     FunctionEntity entry = function.function;
-    openFunction(entry, functionNode: functionNode, checks: TargetChecks.none);
+    openFunction(entry,
+        functionNode: functionNode,
+        parameterStructure: function.parameterStructure,
+        checks: TargetChecks.none);
     graph.needsAsyncRewrite = true;
     if (!function.elementType.containsFreeTypeVariables) {
       // We can generate the element type in place
@@ -1178,6 +1207,7 @@
         return;
       }
       HInstruction newParameter = localsHandler.directLocals[local];
+      assert(newParameter != null, "No initial instruction for ${local}.");
       DartType type = _getDartTypeIfValid(variable.type);
 
       if (targetChecks.checkAllParameters ||
@@ -1225,7 +1255,9 @@
     // TODO(johnniwinther): Non-js-interop external functions should
     // throw a runtime error.
     assert(functionNode.body == null);
-    openFunction(function, functionNode: functionNode);
+    openFunction(function,
+        functionNode: functionNode,
+        parameterStructure: function.parameterStructure);
 
     if (closedWorld.nativeData.isNativeMember(targetElement)) {
       nativeEmitter.nativeMethods.add(targetElement);
@@ -1246,7 +1278,7 @@
                 _sourceInformationBuilder.buildGet(functionNode)));
       }
 
-      for (ir.VariableDeclaration param in functionNode.positionalParameters) {
+      void handleParameter(ir.VariableDeclaration param) {
         templateArguments.add('#');
         Local local = localsMap.getLocalVariable(param);
         // Convert Dart function to JavaScript function.
@@ -1265,6 +1297,23 @@
         inputs.add(argument);
       }
 
+      for (int position = 0;
+          position < function.parameterStructure.positionalParameters;
+          position++) {
+        handleParameter(functionNode.positionalParameters[position]);
+      }
+      if (functionNode.namedParameters.isNotEmpty) {
+        List<ir.VariableDeclaration> namedParameters = functionNode
+            .namedParameters
+            // Filter elided parameters.
+            .where((p) =>
+                function.parameterStructure.namedParameters.contains(p.name))
+            .toList();
+        // Sort by file offset to visit parameters in declaration order.
+        namedParameters.sort(nativeOrdering);
+        namedParameters.forEach(handleParameter);
+      }
+
       String arguments = templateArguments.join(',');
 
       // TODO(sra): Use declared type or NativeBehavior type.
@@ -1307,38 +1356,57 @@
   }
 
   void openFunction(MemberEntity member,
-      {ir.FunctionNode functionNode, TargetChecks checks}) {
+      {ir.FunctionNode functionNode,
+      ParameterStructure parameterStructure,
+      TargetChecks checks}) {
     // TODO(sra): Pass from all sites.
     checks ??= TargetChecks.dynamicChecks;
 
-    Map<Local, AbstractValue> parameterMap = <Local, AbstractValue>{};
+    Map<Local, AbstractValue> parameterMap = {};
+    List<ir.VariableDeclaration> elidedParameters = [];
+    Set<Local> elidedParameterSet = new Set();
     if (functionNode != null) {
-      void handleParameter(ir.VariableDeclaration node) {
+      assert(parameterStructure != null);
+
+      void handleParameter(ir.VariableDeclaration node,
+          {bool isOptional, bool isElided}) {
         Local local = localsMap.getLocalVariable(node);
+        if (isElided) {
+          elidedParameters.add(node);
+          elidedParameterSet.add(local);
+        }
         parameterMap[local] =
             _typeInferenceMap.getInferredTypeOfParameter(local);
       }
 
-      functionNode.positionalParameters.forEach(handleParameter);
-      functionNode.namedParameters.toList()
-        ..sort(namedOrdering)
-        ..forEach(handleParameter);
+      forEachOrderedParameterByFunctionNode(
+          functionNode, parameterStructure, handleParameter);
+
       _returnType = _elementMap.getDartType(functionNode.returnType);
     }
 
     HBasicBlock block = graph.addNewBlock();
+    // Create `graph.entry` as an initially empty block. `graph.entry` is
+    // treated specially (holding parameters, local variables and constants)
+    // but cannot receive constants before it has been closed. By closing it
+    // here, we can use constants in the code that sets up the function.
     open(graph.entry);
+    close(new HGoto(abstractValueDomain)).addSuccessor(block);
+    open(block);
 
     localsHandler.startFunction(
         targetElement,
         closureDataLookup.getScopeInfo(targetElement),
         closureDataLookup.getCapturedScope(targetElement),
         parameterMap,
+        elidedParameterSet,
         _sourceInformationBuilder.buildDeclaration(targetElement),
         isGenerativeConstructorBody: targetElement is ConstructorBodyEntity);
-    close(new HGoto(abstractValueDomain)).addSuccessor(block);
 
-    open(block);
+    for (ir.VariableDeclaration node in elidedParameters) {
+      Local local = localsMap.getLocalVariable(node);
+      localsHandler.updateLocal(local, _defaultValueForParameter(node));
+    }
 
     _addClassTypeVariablesIfNeeded(member);
     _addFunctionTypeVariablesIfNeeded(member);
@@ -1855,8 +1923,15 @@
         _sourceInformationBuilder.buildLoop(node));
 
     void finalizerFunction() {
-      _pushDynamicInvocation(node, null, Selectors.cancel, [streamIterator],
-          const <DartType>[], _sourceInformationBuilder.buildGeneric(node));
+      _pushDynamicInvocation(
+          node,
+          null,
+          Selectors.cancel,
+          [streamIterator],
+          const <DartType>[],
+          _sourceInformationBuilder
+              // ignore:deprecated_member_use_from_same_package
+              .buildGeneric(node));
       add(new HAwait(pop(), abstractValueDomain.dynamicType));
     }
 
@@ -2965,11 +3040,14 @@
           sourceInformation: _sourceInformationBuilder.buildSet(node));
       pop();
     } else {
-      add(new HStaticStore(
-          abstractValueDomain,
-          _elementMap.getMember(staticTarget),
-          typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
-              value, _getDartTypeIfValid(staticTarget.setterType))));
+      MemberEntity target = _elementMap.getMember(staticTarget);
+      if (!closedWorld.elidedFields.contains(target)) {
+        add(new HStaticStore(
+            abstractValueDomain,
+            target,
+            typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+                value, _getDartTypeIfValid(staticTarget.setterType))));
+      }
     }
     stack.add(value);
   }
@@ -3190,12 +3268,8 @@
 
         // Visit named arguments in parameter-position order, selecting provided
         // or default value.
-        // TODO(sra): Ensure the stored order is canonical so we don't have to
-        // sort. The old builder uses CallStructure.makeArgumentList which
-        // depends on the old element model.
-        var namedParameters = target.namedParameters.toList()
-          ..sort((ir.VariableDeclaration a, ir.VariableDeclaration b) =>
-              a.name.compareTo(b.name));
+        var namedParameters = target.namedParameters.toList();
+        namedParameters.sort(nativeOrdering);
         for (ir.VariableDeclaration parameter in namedParameters) {
           HInstruction value = namedValues[parameter.name];
           values.add(value);
@@ -3259,20 +3333,21 @@
   /// filling in the default argument value.
   List<HInstruction> _visitArgumentsForStaticTarget(
       ir.FunctionNode target,
+      ParameterStructure parameterStructure,
       ir.Arguments arguments,
       List<DartType> typeArguments,
       SourceInformation sourceInformation) {
     // Visit arguments in source order, then re-order and fill in defaults.
-    var values = _visitPositionalArguments(arguments);
+    List<HInstruction> values = _visitPositionalArguments(arguments);
 
-    while (values.length < target.positionalParameters.length) {
+    while (values.length < parameterStructure.positionalParameters) {
       ir.VariableDeclaration parameter =
           target.positionalParameters[values.length];
       values.add(_defaultValueForParameter(parameter));
     }
 
-    if (target.namedParameters.isNotEmpty) {
-      var namedValues = <String, HInstruction>{};
+    if (parameterStructure.namedParameters.isNotEmpty) {
+      Map<String, HInstruction> namedValues = {};
       for (ir.NamedExpression argument in arguments.named) {
         argument.value.accept(this);
         namedValues[argument.name] = pop();
@@ -3283,9 +3358,11 @@
       // TODO(sra): Ensure the stored order is canonical so we don't have to
       // sort. The old builder uses CallStructure.makeArgumentList which depends
       // on the old element model.
-      var namedParameters = target.namedParameters.toList()
-        ..sort((ir.VariableDeclaration a, ir.VariableDeclaration b) =>
-            a.name.compareTo(b.name));
+      List<ir.VariableDeclaration> namedParameters = target.namedParameters
+          // Filter elided parameters.
+          .where((p) => parameterStructure.namedParameters.contains(p.name))
+          .toList()
+            ..sort(namedOrdering);
       for (ir.VariableDeclaration parameter in namedParameters) {
         HInstruction value = namedValues[parameter.name];
         if (value == null) {
@@ -3344,7 +3421,11 @@
             .isJsInteropMember(function)
         ? _visitArgumentsForNativeStaticTarget(target.function, node.arguments)
         : _visitArgumentsForStaticTarget(
-            target.function, node.arguments, typeArguments, sourceInformation);
+            target.function,
+            function.parameterStructure,
+            node.arguments,
+            typeArguments,
+            sourceInformation);
 
     // Error in the arguments provided. Do not process further.
     if (arguments == null) {
@@ -4280,12 +4361,22 @@
       // Factory constructor that is syntactic sugar for creating a JavaScript
       // object literal.
       ConstructorEntity constructor = element;
-      ParameterStructure params = constructor.parameterStructure;
       int i = 0;
       int positions = 0;
       var filteredArguments = <HInstruction>[];
       var parameterNameMap = new Map<String, js.Expression>();
-      params.namedParameters.forEach((String parameterName) {
+
+      // Note: we don't use `constructor.parameterStructure` here because
+      // we don't elide parameters to js-interop external static targets
+      // (including factory constructors.)
+      // TODO(johnniwinther): can we elide those parameters? This should be
+      // consistent with what we do with instance methods.
+      ir.Procedure node = _elementMap.getMemberDefinition(constructor).node;
+      List<ir.VariableDeclaration> namedParameters =
+          node.function.namedParameters.toList();
+      namedParameters.sort(nativeOrdering);
+      for (ir.VariableDeclaration variable in namedParameters) {
+        String parameterName = variable.name;
         // TODO(jacobr): consider throwing if parameter names do not match
         // names of properties in the class.
         HInstruction argument = arguments[i];
@@ -4295,7 +4386,7 @@
           parameterNameMap[jsName] = new js.InterpolatedExpression(positions++);
         }
         i++;
-      });
+      }
       var codeTemplate =
           new js.Template(null, js.objectLiteral(parameterNameMap));
 
@@ -4378,7 +4469,8 @@
 
     List<HInstruction> capturedVariables = <HInstruction>[];
     _worldBuilder.forEachInstanceField(closureClassEntity,
-        (_, FieldEntity field) {
+        (_, FieldEntity field, {bool isElided}) {
+      if (isElided) return;
       capturedVariables
           .add(localsHandler.readLocal(closureInfo.getLocalForField(field)));
     });
@@ -4615,8 +4707,13 @@
 
     MemberDefinition targetDefinition = _elementMap.getMemberDefinition(member);
     ir.Procedure target = targetDefinition.node;
+    FunctionEntity function = member;
     List<HInstruction> arguments = _visitArgumentsForStaticTarget(
-        target.function, node.arguments, typeArguments, sourceInformation);
+        target.function,
+        function.parameterStructure,
+        node.arguments,
+        typeArguments,
+        sourceInformation);
     _buildInvokeSuper(
         _elementMap.getSelector(node),
         _elementMap.getClass(_containingClass(node)),
@@ -4679,7 +4776,11 @@
     arguments.addAll(closedWorld.nativeData.isJsInteropMember(constructor)
         ? _visitArgumentsForNativeStaticTarget(target.function, node.arguments)
         : _visitArgumentsForStaticTarget(
-            target.function, node.arguments, typeArguments, sourceInformation));
+            target.function,
+            constructor.parameterStructure,
+            node.arguments,
+            typeArguments,
+            sourceInformation));
     if (commonElements.isSymbolConstructor(constructor)) {
       constructor = commonElements.symbolValidatedConstructor;
     }
@@ -5044,7 +5145,7 @@
     }
 
     bool heuristicSayGoodToGo() {
-      // Don't inline recursively
+      // Don't inline recursively,
       if (_inliningStack.any((entry) => entry.function == function)) {
         return false;
       }
@@ -5290,24 +5391,28 @@
         // Pass type variable bounds as type arguments.
         for (TypeVariableType typeVariable in _elementMap.elementEnvironment
             .getFunctionTypeVariables(function)) {
-          DartType bound = _elementMap.elementEnvironment
-              .getTypeVariableDefaultType(typeVariable.element);
-          if (bound.containsTypeVariables) {
-            // TODO(33422): Support type variables in default
-            // types. Temporarily using the "any" type (encoded as -2) to
-            // avoid failing on bounds checks.
-            compiledArguments[compiledArgumentIndex++] =
-                graph.addConstantInt(-2, closedWorld);
-          } else {
-            compiledArguments[compiledArgumentIndex++] =
-                typeBuilder.analyzeTypeArgument(bound, function);
-          }
+          compiledArguments[compiledArgumentIndex++] =
+              _computeTypeArgumentDefaultValue(function, typeVariable);
         }
       }
     }
     return compiledArguments;
   }
 
+  HInstruction _computeTypeArgumentDefaultValue(
+      FunctionEntity function, TypeVariableType typeVariable) {
+    DartType bound = _elementMap.elementEnvironment
+        .getTypeVariableDefaultType(typeVariable.element);
+    if (bound.containsTypeVariables) {
+      // TODO(33422): Support type variables in default
+      // types. Temporarily using the "any" type (encoded as -2) to
+      // avoid failing on bounds checks.
+      return graph.addConstantInt(-2, closedWorld);
+    } else {
+      return typeBuilder.analyzeTypeArgument(bound, function);
+    }
+  }
+
   /// This method is invoked before inlining the body of [function] into this
   /// [SsaGraphBuilder].
   void _enterInlinedMethod(FunctionEntity function,
@@ -5362,17 +5467,23 @@
     }
 
     bool hasBox = false;
-    forEachOrderedParameter(closedWorld.globalLocalsMap, _elementMap, function,
-        (Local parameter) {
-      if (forGenerativeConstructorBody &&
-          scopeData.isBoxedVariable(parameter)) {
+    KernelToLocalsMap localsMap =
+        closedWorld.globalLocalsMap.getLocalsMap(function);
+    forEachOrderedParameter(_elementMap, function,
+        (ir.VariableDeclaration variable, {bool isElided}) {
+      Local local = localsMap.getLocalVariable(variable);
+      if (isElided) {
+        localsHandler.updateLocal(local, _defaultValueForParameter(variable));
+        return;
+      }
+      if (forGenerativeConstructorBody && scopeData.isBoxedVariable(local)) {
         // The parameter will be a field in the box passed as the last
         // parameter. So no need to have it.
         hasBox = true;
         return;
       }
       HInstruction argument = compiledArguments[argumentIndex++];
-      localsHandler.updateLocal(parameter, argument);
+      localsHandler.updateLocal(local, argument);
     });
 
     if (hasBox) {
@@ -5398,9 +5509,17 @@
       });
     }
     if (rtiNeed.methodNeedsTypeArguments(function)) {
+      bool inlineTypeParameters =
+          function.parameterStructure.typeParameters == 0;
       for (TypeVariableType typeVariable in _elementMap.elementEnvironment
           .getFunctionTypeVariables(function)) {
-        HInstruction argument = compiledArguments[argumentIndex++];
+        HInstruction argument;
+        if (inlineTypeParameters) {
+          // Add inlined type parameters.
+          argument = _computeTypeArgumentDefaultValue(function, typeVariable);
+        } else {
+          argument = compiledArguments[argumentIndex++];
+        }
         localsHandler.updateLocal(
             localsHandler.getTypeVariableAsLocal(typeVariable), argument);
       }
@@ -5524,8 +5643,9 @@
 
     KernelToLocalsMap localsMap =
         closedWorld.globalLocalsMap.getLocalsMap(function);
-    forEachOrderedParameter(closedWorld.globalLocalsMap, _elementMap, function,
-        (Local parameter) {
+    forEachOrderedParameter(_elementMap, function,
+        (ir.VariableDeclaration variable, {bool isElided}) {
+      Local parameter = localsMap.getLocalVariable(variable);
       HInstruction argument = localsHandler.readLocal(parameter);
       DartType type = localsMap.getLocalType(_elementMap, parameter);
       HInstruction checkedOrTrusted;
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index dc941f4..f93696b 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -899,7 +899,9 @@
     if (info.catchBlock != null) {
       void register(ClassEntity classElement) {
         if (classElement != null) {
-          _registry.registerInstantiatedClass(classElement);
+          _registry
+              // ignore:deprecated_member_use_from_same_package
+              .registerInstantiatedClass(classElement);
         }
       }
 
@@ -1832,7 +1834,9 @@
         methodName = 'split';
         // Split returns a List, so we make sure the backend knows the
         // list class is instantiated.
-        _registry.registerInstantiatedClass(_commonElements.listClass);
+        _registry
+            // ignore:deprecated_member_use_from_same_package
+            .registerInstantiatedClass(_commonElements.listClass);
       } else if (_nativeData.isNativeMember(target) &&
           target.isFunction &&
           !node.isInterceptedCall) {
@@ -2256,7 +2260,9 @@
     // function expressions. We have to register their use here, as otherwise
     // code for them might not be emitted.
     if (node.element.isClosure) {
-      _registry.registerInstantiatedClass(node.element);
+      _registry
+          // ignore:deprecated_member_use_from_same_package
+          .registerInstantiatedClass(node.element);
     }
     node.instantiatedTypes?.forEach(_registry.registerInstantiation);
     if (node.callMethod != null) {
@@ -2632,7 +2638,9 @@
   }
 
   void visitLiteralList(HLiteralList node) {
-    _registry.registerInstantiatedClass(_commonElements.listClass);
+    _registry
+        // ignore:deprecated_member_use_from_same_package
+        .registerInstantiatedClass(_commonElements.listClass);
     generateArrayLiteral(node);
   }
 
@@ -3195,7 +3203,9 @@
         // We expect only flat types for the INSTANCE representation.
         assert(
             (type as InterfaceType).typeArguments.length == arguments.length);
-        _registry.registerInstantiatedClass(_commonElements.listClass);
+        _registry
+            // ignore:deprecated_member_use_from_same_package
+            .registerInstantiatedClass(_commonElements.listClass);
         push(new js.ArrayInitializer(arguments)
             .withSourceInformation(node.sourceInformation));
     }
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 7b78b8c..cf71ede 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -153,9 +153,10 @@
   /// [isAborted].
   bool isReachable = true;
 
-  HParameterValue lastAddedParameter;
+  HLocalValue lastAddedParameter;
 
   Map<Local, HInstruction> parameters = <Local, HInstruction>{};
+  Set<Local> elidedParameters;
 
   HBasicBlock addNewBlock() {
     HBasicBlock block = graph.addNewBlock();
@@ -207,8 +208,11 @@
     current.add(instruction);
   }
 
-  HParameterValue addParameter(Entity parameter, AbstractValue type) {
-    HParameterValue result = new HParameterValue(parameter, type);
+  HLocalValue addParameter(Entity parameter, AbstractValue type,
+      {bool isElided: false}) {
+    HLocalValue result = isElided
+        ? new HLocalValue(parameter, type)
+        : new HParameterValue(parameter, type);
     if (lastAddedParameter == null) {
       graph.entry.addBefore(graph.entry.first, result);
     } else {
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 18f2ce2..fb3df50 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -13,6 +13,7 @@
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import '../world.dart' show JClosedWorld;
+import 'logging.dart';
 import 'nodes.dart';
 import 'types.dart';
 
@@ -38,7 +39,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     return null;
   }
 
@@ -120,7 +122,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction receiver = instruction.inputs[1];
     HInstruction index = instruction.inputs[2];
     if (receiver
@@ -142,8 +145,10 @@
         return null;
       }
     }
-    return new HIndexAssign(closedWorld.abstractValueDomain, receiver, index,
-        value, instruction.selector);
+    HIndexAssign converted = new HIndexAssign(closedWorld.abstractValueDomain,
+        receiver, index, value, instruction.selector);
+    log?.registerIndexAssign(instruction, converted);
+    return converted;
   }
 
   /// Returns [true] if [value] meets the requirements for being stored into
@@ -188,13 +193,13 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     if (instruction.inputs[1]
         .isIndexablePrimitive(closedWorld.abstractValueDomain)
         .isPotentiallyFalse) {
       return null;
     }
-    // TODO(johnniwinther): Merge this and the following if statement.
     if (instruction.inputs[2]
             .isInteger(closedWorld.abstractValueDomain)
             .isPotentiallyFalse &&
@@ -206,8 +211,10 @@
         instruction.getDartReceiver(closedWorld).instructionType;
     AbstractValue type = AbstractValueFactory.inferredTypeForSelector(
         instruction.selector, receiverType, results);
-    return new HIndex(instruction.inputs[1], instruction.inputs[2],
+    HIndex converted = new HIndex(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, type);
+    log?.registerIndex(instruction, converted);
+    return converted;
   }
 }
 
@@ -240,14 +247,17 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction input = instruction.inputs[1];
     if (input.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
-      return new HBitNot(
+      HBitNot converted = new HBitNot(
           input,
           instruction.selector,
           computeTypeFromInputTypes(
               instruction, results, options, closedWorld));
+      log?.registerBitNot(instruction, converted);
+      return converted;
     }
     return null;
   }
@@ -293,14 +303,17 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction input = instruction.inputs[1];
     if (input.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
-      return new HNegate(
+      HNegate converted = new HNegate(
           input,
           instruction.selector,
           computeTypeFromInputTypes(
               instruction, results, options, closedWorld));
+      log?.registerUnaryNegate(instruction, converted);
+      return converted;
     }
     return null;
   }
@@ -334,17 +347,23 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction input = instruction.inputs[1];
     if (input.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
-      return new HAbs(
+      HAbs converted = new HAbs(
           input,
           instruction.selector,
           computeTypeFromInputTypes(
               instruction, results, options, closedWorld));
+      log?.registerAbs(instruction, converted);
+      return converted;
     }
     return null;
   }
+
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {}
 }
 
 abstract class BinaryArithmeticSpecializer extends InvokeDynamicSpecializer {
@@ -395,11 +414,17 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     if (isBuiltin(instruction, closedWorld)) {
       HInstruction builtin =
           newBuiltinVariant(instruction, results, options, closedWorld);
-      if (builtin != null) return builtin;
+      if (log != null) {
+        registerOptimization(log, instruction, builtin);
+      }
+      if (builtin != null) {
+        return builtin;
+      }
       // Even if there is no builtin equivalent instruction, we know
       // the instruction does not have any side effect, and that it
       // can be GVN'ed.
@@ -432,6 +457,9 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JClosedWorld closedWorld);
+
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted);
 }
 
 class AddSpecializer extends BinaryArithmeticSpecializer {
@@ -467,6 +495,12 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerAdd(original, converted);
+  }
 }
 
 class DivideSpecializer extends BinaryArithmeticSpecializer {
@@ -497,6 +531,12 @@
     return new HDivide(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, closedWorld.abstractValueDomain.doubleType);
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerDivide(original, converted);
+  }
 }
 
 class ModuloSpecializer extends BinaryArithmeticSpecializer {
@@ -583,6 +623,12 @@
     // don't want to ruin GVN opportunities.
     return null;
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerModulo(original, converted);
+  }
 }
 
 class RemainderSpecializer extends BinaryArithmeticSpecializer {
@@ -615,6 +661,12 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerRemainder(original, converted);
+  }
 }
 
 class MultiplySpecializer extends BinaryArithmeticSpecializer {
@@ -647,6 +699,12 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerMultiply(original, converted);
+  }
 }
 
 class SubtractSpecializer extends BinaryArithmeticSpecializer {
@@ -667,6 +725,12 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerSubtract(original, converted);
+  }
 }
 
 class TruncatingDivideSpecializer extends BinaryArithmeticSpecializer {
@@ -731,7 +795,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction right = instruction.inputs[2];
     if (isBuiltin(instruction, closedWorld)) {
       if (right
@@ -739,12 +804,20 @@
               .isDefinitelyTrue &&
           isNotZero(right)) {
         if (hasUint31Result(instruction, closedWorld)) {
-          return newBuiltinVariant(instruction, results, options, closedWorld);
+          HInstruction converted =
+              newBuiltinVariant(instruction, results, options, closedWorld);
+          if (log != null) {
+            registerOptimization(log, instruction, converted);
+          }
+          return converted;
         }
         // We can call _tdivFast because the rhs is a 32bit integer
         // and not 0, nor -1.
         instruction.selector = renameToOptimizedSelector(
             '_tdivFast', instruction.selector, commonElements);
+        if (log != null) {
+          registerOptimization(log, instruction, null);
+        }
       }
       clearAllSideEffects(instruction);
     }
@@ -762,6 +835,12 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerTruncatingDivide(original, converted);
+  }
 }
 
 abstract class BinaryBitOpSpecializer extends BinaryArithmeticSpecializer {
@@ -826,12 +905,18 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
     if (left.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
       if (argumentLessThan32(right)) {
-        return newBuiltinVariant(instruction, results, options, closedWorld);
+        HInstruction converted =
+            newBuiltinVariant(instruction, results, options, closedWorld);
+        if (log != null) {
+          registerOptimization(log, instruction, converted);
+        }
+        return converted;
       }
       // Even if there is no builtin equivalent instruction, we know
       // the instruction does not have any side effect, and that it
@@ -841,6 +926,9 @@
         instruction.selector = renameToOptimizedSelector(
             '_shlPositive', instruction.selector, commonElements);
       }
+      if (log != null) {
+        registerOptimization(log, instruction, null);
+      }
     }
     return null;
   }
@@ -856,6 +944,12 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerShiftLeft(original, converted);
+  }
 }
 
 class ShiftRightSpecializer extends BinaryBitOpSpecializer {
@@ -880,12 +974,18 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
     if (left.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
       if (argumentLessThan32(right) && isPositive(left, closedWorld)) {
-        return newBuiltinVariant(instruction, results, options, closedWorld);
+        HInstruction converted =
+            newBuiltinVariant(instruction, results, options, closedWorld);
+        if (log != null) {
+          registerOptimization(log, instruction, converted);
+        }
+        return converted;
       }
       // Even if there is no builtin equivalent instruction, we know
       // the instruction does not have any side effect, and that it
@@ -894,13 +994,22 @@
       if (isPositive(right, closedWorld) && isPositive(left, closedWorld)) {
         instruction.selector = renameToOptimizedSelector(
             '_shrBothPositive', instruction.selector, commonElements);
+        if (log != null) {
+          registerOptimization(log, instruction, null);
+        }
       } else if (isPositive(left, closedWorld) &&
           right.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
         instruction.selector = renameToOptimizedSelector(
             '_shrReceiverPositive', instruction.selector, commonElements);
+        if (log != null) {
+          registerOptimization(log, instruction, null);
+        }
       } else if (isPositive(right, closedWorld)) {
         instruction.selector = renameToOptimizedSelector(
             '_shrOtherPositive', instruction.selector, commonElements);
+        if (log != null) {
+          registerOptimization(log, instruction, null);
+        }
       }
     }
     return null;
@@ -921,6 +1030,12 @@
   BinaryOperation operation(ConstantSystem constantSystem) {
     return constantSystem.shiftRight;
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerShiftRight(original, converted);
+  }
 }
 
 class BitOrSpecializer extends BinaryBitOpSpecializer {
@@ -956,6 +1071,11 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerBitOr(original, converted);
+  }
 }
 
 class BitAndSpecializer extends BinaryBitOpSpecializer {
@@ -994,6 +1114,11 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerBitAnd(original, converted);
+  }
 }
 
 class BitXorSpecializer extends BinaryBitOpSpecializer {
@@ -1029,6 +1154,11 @@
         instruction.selector,
         computeTypeFromInputTypes(instruction, results, options, closedWorld));
   }
+
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerBitXor(original, converted);
+  }
 }
 
 abstract class RelationalSpecializer extends InvokeDynamicSpecializer {
@@ -1054,18 +1184,26 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
     if (left.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue &&
         right.isNumber(closedWorld.abstractValueDomain).isDefinitelyTrue) {
-      return newBuiltinVariant(instruction, closedWorld);
+      HInstruction converted = newBuiltinVariant(instruction, closedWorld);
+      if (log != null) {
+        registerOptimization(log, instruction, converted);
+      }
+      return converted;
     }
     return null;
   }
 
   HInstruction newBuiltinVariant(
       HInvokeDynamic instruction, JClosedWorld closedWorld);
+
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted);
 }
 
 class EqualsSpecializer extends RelationalSpecializer {
@@ -1077,7 +1215,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction left = instruction.inputs[1];
     HInstruction right = instruction.inputs[2];
     AbstractValue instructionType = left.instructionType;
@@ -1085,7 +1224,11 @@
         left
             .isPrimitiveOrNull(closedWorld.abstractValueDomain)
             .isDefinitelyTrue) {
-      return newBuiltinVariant(instruction, closedWorld);
+      HInstruction converted = newBuiltinVariant(instruction, closedWorld);
+      if (log != null) {
+        registerOptimization(log, instruction, converted);
+      }
+      return converted;
     }
     if (closedWorld.includesClosureCall(
         instruction.selector, instructionType)) {
@@ -1098,7 +1241,11 @@
     // a regular object or an interceptor.
     if (matches
         .every(closedWorld.commonElements.isDefaultEqualityImplementation)) {
-      return newBuiltinVariant(instruction, closedWorld);
+      HInstruction converted = newBuiltinVariant(instruction, closedWorld);
+      if (log != null) {
+        registerOptimization(log, instruction, converted);
+      }
+      return converted;
     }
     return null;
   }
@@ -1112,6 +1259,12 @@
     return new HIdentity(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, closedWorld.abstractValueDomain.boolType);
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerEquals(original, converted);
+  }
 }
 
 class LessSpecializer extends RelationalSpecializer {
@@ -1126,6 +1279,12 @@
     return new HLess(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, closedWorld.abstractValueDomain.boolType);
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerLess(original, converted);
+  }
 }
 
 class GreaterSpecializer extends RelationalSpecializer {
@@ -1140,6 +1299,12 @@
     return new HGreater(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, closedWorld.abstractValueDomain.boolType);
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerGreater(original, converted);
+  }
 }
 
 class GreaterEqualSpecializer extends RelationalSpecializer {
@@ -1154,6 +1319,12 @@
     return new HGreaterEqual(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, closedWorld.abstractValueDomain.boolType);
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerGreaterEqual(original, converted);
+  }
 }
 
 class LessEqualSpecializer extends RelationalSpecializer {
@@ -1168,6 +1339,12 @@
     return new HLessEqual(instruction.inputs[1], instruction.inputs[2],
         instruction.selector, closedWorld.abstractValueDomain.boolType);
   }
+
+  @override
+  void registerOptimization(
+      OptimizationTestLog log, HInstruction original, HInstruction converted) {
+    log.registerLessEqual(original, converted);
+  }
 }
 
 class CodeUnitAtSpecializer extends InvokeDynamicSpecializer {
@@ -1183,7 +1360,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     // TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index
     // bounds checking optimizations as for HIndex.
     HInstruction receiver = instruction.getDartReceiver(closedWorld);
@@ -1200,6 +1378,7 @@
         instruction.selector = renameToOptimizedSelector(
             '_codeUnitAt', instruction.selector, commonElements);
       }
+      log?.registerCodeUnitAt(instruction);
     }
     return null;
   }
@@ -1214,7 +1393,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction receiver = instruction.getDartReceiver(closedWorld);
     // `compareTo` has no side-effect (other than throwing) and can be GVN'ed
     // for some known types.
@@ -1240,16 +1420,20 @@
                   .isString(closedWorld.abstractValueDomain)
                   .isDefinitelyTrue)) {
         if (identical(receiver.nonCheck(), argument.nonCheck())) {
-          return graph.addConstantInt(0, closedWorld);
+          HInstruction converted = graph.addConstantInt(0, closedWorld);
+          log?.registerCompareTo(instruction, converted);
+          return converted;
         }
       }
       clearAllSideEffects(instruction);
+      log?.registerCompareTo(instruction);
     }
     return null;
   }
 }
 
-class IdempotentStringOperationSpecializer extends InvokeDynamicSpecializer {
+abstract class IdempotentStringOperationSpecializer
+    extends InvokeDynamicSpecializer {
   const IdempotentStringOperationSpecializer();
 
   HInstruction tryConvertToBuiltin(
@@ -1258,7 +1442,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction receiver = instruction.getDartReceiver(closedWorld);
     if (receiver
         .isStringOrNull(closedWorld.abstractValueDomain)
@@ -1266,17 +1451,32 @@
       // String.xxx does not have any side effect (other than throwing), and it
       // can be GVN'ed.
       clearAllSideEffects(instruction);
+      if (log != null) {
+        registerOptimization(log, instruction);
+      }
     }
     return null;
   }
+
+  void registerOptimization(OptimizationTestLog log, HInstruction original);
 }
 
 class SubstringSpecializer extends IdempotentStringOperationSpecializer {
   const SubstringSpecializer();
+
+  @override
+  void registerOptimization(OptimizationTestLog log, HInstruction original) {
+    log.registerSubstring(original);
+  }
 }
 
 class TrimSpecializer extends IdempotentStringOperationSpecializer {
   const TrimSpecializer();
+
+  @override
+  void registerOptimization(OptimizationTestLog log, HInstruction original) {
+    log.registerTrim(original);
+  }
 }
 
 class PatternMatchSpecializer extends InvokeDynamicSpecializer {
@@ -1288,7 +1488,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction receiver = instruction.getDartReceiver(closedWorld);
     HInstruction pattern = instruction.inputs[2];
     if (receiver
@@ -1300,6 +1501,7 @@
       // String.contains(String s) does not have any side effect (other than
       // throwing), and it can be GVN'ed.
       clearAllSideEffects(instruction);
+      log?.registerPatternMatch(instruction);
     }
     return null;
   }
@@ -1318,7 +1520,8 @@
       GlobalTypeInferenceResults results,
       CompilerOptions options,
       JCommonElements commonElements,
-      JClosedWorld closedWorld) {
+      JClosedWorld closedWorld,
+      OptimizationTestLog log) {
     HInstruction receiver = instruction.getDartReceiver(closedWorld);
     if (receiver
         .isNumberOrNull(closedWorld.abstractValueDomain)
@@ -1326,6 +1529,7 @@
       // Even if there is no builtin equivalent instruction, we know the
       // instruction does not have any side effect, and that it can be GVN'ed.
       clearAllSideEffects(instruction);
+      log?.registerRound(instruction);
     }
     return null;
   }
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index ff3ec93..991cef0 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -196,6 +196,7 @@
       ScopeInfo scopeInfo,
       CapturedScope scopeData,
       Map<Local, AbstractValue> parameters,
+      Set<Local> elidedParameters,
       SourceInformation sourceInformation,
       {bool isGenerativeConstructorBody}) {
     this.scopeInfo = scopeInfo;
@@ -208,10 +209,12 @@
           return;
         }
       }
-      HInstruction parameter = builder.addParameter(local, typeMask);
+      HInstruction parameter = builder.addParameter(local, typeMask,
+          isElided: elidedParameters.contains(local));
       builder.parameters[local] = parameter;
       directLocals[local] = parameter;
     });
+    builder.elidedParameters = elidedParameters;
 
     enterScope(scopeData, sourceInformation,
         forGenerativeConstructorBody: isGenerativeConstructorBody);
diff --git a/pkg/compiler/lib/src/ssa/logging.dart b/pkg/compiler/lib/src/ssa/logging.dart
index c213791..68d648f 100644
--- a/pkg/compiler/lib/src/ssa/logging.dart
+++ b/pkg/compiler/lib/src/ssa/logging.dart
@@ -2,30 +2,217 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'nodes.dart';
 import '../util/features.dart';
+import 'nodes.dart';
 
 /// Log used for unit testing optimizations.
-class OptimizationLog {
+class OptimizationTestLog {
   List<OptimizationLogEntry> entries = [];
 
-  void registerFieldGet(HInvokeDynamicGetter node, HFieldGet fieldGet) {
+  Map<String, Set<HInstruction>> _unconverted;
+
+  Features _register(String tag, HInstruction original, HInstruction converted,
+      void f(Features features)) {
+    if (converted == null) {
+      _unconverted ??= {};
+      Set<HInstruction> set = _unconverted[tag] ??= new Set<HInstruction>();
+      if (!set.add(original)) {
+        return null;
+      }
+    }
+    Features features = new Features();
+    f(features);
+    entries.add(new OptimizationLogEntry(tag, features));
+    return features;
+  }
+
+  void registerFieldGet(HInvokeDynamicGetter original, HFieldGet converted) {
     Features features = new Features();
     features['name'] =
-        '${fieldGet.element.enclosingClass.name}.${fieldGet.element.name}';
+        '${converted.element.enclosingClass.name}.${converted.element.name}';
     entries.add(new OptimizationLogEntry('FieldGet', features));
   }
 
-  void registerFieldSet(HInvokeDynamicSetter node, HFieldSet fieldSet) {
+  void registerFieldSet(HInvokeDynamicSetter original, [HFieldSet converted]) {
     Features features = new Features();
-    features['name'] =
-        '${fieldSet.element.enclosingClass.name}.${fieldSet.element.name}';
+    if (converted != null) {
+      features['name'] =
+          '${converted.element.enclosingClass.name}.${converted.element.name}';
+    } else {
+      features['removed'] = original.selector.name;
+    }
     entries.add(new OptimizationLogEntry('FieldSet', features));
   }
 
+  Features _registerSpecializer(
+      HInvokeDynamic original, HInstruction converted, String name,
+      [String unconvertedName]) {
+    assert(!(converted == null && unconvertedName == null));
+    return _register('Specializer', original, converted, (Features features) {
+      if (converted != null) {
+        features.add(name);
+      } else {
+        features.add(unconvertedName);
+      }
+    });
+  }
+
+  void registerIndexAssign(HInvokeDynamic original, HIndexAssign converted) {
+    _registerSpecializer(original, converted, 'IndexAssign');
+  }
+
+  void registerIndex(HInvokeDynamic original, HIndex converted) {
+    _registerSpecializer(original, converted, 'Index');
+  }
+
+  void registerBitNot(HInvokeDynamic original, HBitNot converted) {
+    _registerSpecializer(original, converted, 'BitNot');
+  }
+
+  void registerUnaryNegate(HInvokeDynamic original, HNegate converted) {
+    _registerSpecializer(original, converted, 'Negate');
+  }
+
+  void registerAbs(HInvokeDynamic original, HAbs converted) {
+    _registerSpecializer(original, converted, 'Abs');
+  }
+
+  void registerAdd(HInvokeDynamic original, HAdd converted) {
+    _registerSpecializer(original, converted, 'Add');
+  }
+
+  void registerDivide(HInvokeDynamic original, HDivide converted) {
+    _registerSpecializer(original, converted, 'Divide');
+  }
+
+  void registerModulo(HInvokeDynamic original, [HRemainder converted]) {
+    _registerSpecializer(original, converted, 'Modulo', 'DynamicModulo');
+  }
+
+  void registerRemainder(HInvokeDynamic original, HRemainder converted) {
+    _registerSpecializer(original, converted, 'Remainder');
+  }
+
+  void registerMultiply(HInvokeDynamic original, HMultiply converted) {
+    _registerSpecializer(original, converted, 'Multiply');
+  }
+
+  void registerSubtract(HInvokeDynamic original, HSubtract converted) {
+    _registerSpecializer(original, converted, 'Subtract');
+  }
+
+  void registerTruncatingDivide(
+      HInvokeDynamic original, HTruncatingDivide converted) {
+    _registerSpecializer(original, converted, 'TruncatingDivide',
+        'TruncatingDivide.${original.selector.name}');
+  }
+
+  void registerShiftLeft(HInvokeDynamic original, HShiftLeft converted) {
+    _registerSpecializer(original, converted, 'ShiftLeft',
+        'ShiftLeft.${original.selector.name}');
+  }
+
+  void registerShiftRight(HInvokeDynamic original, HShiftRight converted) {
+    _registerSpecializer(original, converted, 'ShiftRight',
+        'ShiftRight.${original.selector.name}');
+  }
+
+  void registerBitOr(HInvokeDynamic original, HBitOr converted) {
+    _registerSpecializer(original, converted, 'BitOr');
+  }
+
+  void registerBitAnd(HInvokeDynamic original, HBitAnd converted) {
+    _registerSpecializer(original, converted, 'BitAnd');
+  }
+
+  void registerBitXor(HInvokeDynamic original, HBitXor converted) {
+    _registerSpecializer(original, converted, 'BitXor');
+  }
+
+  void registerEquals(HInvokeDynamic original, HIdentity converted) {
+    _registerSpecializer(original, converted, 'Equals');
+  }
+
+  void registerLess(HInvokeDynamic original, HLess converted) {
+    _registerSpecializer(original, converted, 'Less');
+  }
+
+  void registerGreater(HInvokeDynamic original, HGreater converted) {
+    _registerSpecializer(original, converted, 'Greater');
+  }
+
+  void registerLessEqual(HInvokeDynamic original, HLessEqual converted) {
+    _registerSpecializer(original, converted, 'LessEquals');
+  }
+
+  void registerGreaterEqual(HInvokeDynamic original, HGreaterEqual converted) {
+    _registerSpecializer(original, converted, 'GreaterEquals');
+  }
+
+  void registerCodeUnitAt(HInvokeDynamic original) {
+    Features features = new Features();
+    features['name'] = original.selector.name;
+    entries.add(new OptimizationLogEntry('CodeUnitAt', features));
+  }
+
+  void registerCompareTo(HInvokeDynamic original, [HConstant converted]) {
+    Features features = new Features();
+    if (converted != null) {
+      features['constant'] = converted.constant.toDartText();
+    }
+    entries.add(new OptimizationLogEntry('CompareTo', features));
+  }
+
+  void registerSubstring(HInvokeDynamic original) {
+    Features features = new Features();
+    entries.add(new OptimizationLogEntry('Substring', features));
+  }
+
+  void registerTrim(HInvokeDynamic original) {
+    Features features = new Features();
+    entries.add(new OptimizationLogEntry('Trim', features));
+  }
+
+  void registerPatternMatch(HInvokeDynamic original) {
+    Features features = new Features();
+    entries.add(new OptimizationLogEntry('PatternMatch', features));
+  }
+
+  void registerRound(HInvokeDynamic original) {
+    _registerSpecializer(original, null, null, 'Round');
+  }
+
+  void registerTypeConversion(
+      HInstruction original, HTypeConversion converted) {
+    Features features = new Features();
+    switch (converted.kind) {
+      case HTypeConversion.CHECKED_MODE_CHECK:
+        features['kind'] = 'checked';
+        break;
+      case HTypeConversion.ARGUMENT_TYPE_CHECK:
+        features['kind'] = 'argument';
+        break;
+      case HTypeConversion.CAST_TYPE_CHECK:
+        features['kind'] = 'cast';
+        break;
+      case HTypeConversion.BOOLEAN_CONVERSION_CHECK:
+        features['kind'] = 'boolean';
+        break;
+      case HTypeConversion.RECEIVER_TYPE_CHECK:
+        features['kind'] = 'receiver';
+        break;
+    }
+    if (converted.typeExpression != null) {
+      features['type'] = '${converted.typeExpression}';
+    }
+    entries.add(new OptimizationLogEntry('TypeConversion', features));
+  }
+
   String getText() {
     return entries.join(',\n');
   }
+
+  String toString() => 'OptimizationLog(${getText()})';
 }
 
 /// A registered optimization.
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index dc693ef..5b0006f 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -2540,7 +2540,7 @@
 }
 
 class HParameterValue extends HLocalValue {
-  HParameterValue(Entity variable, type) : super(variable, type);
+  HParameterValue(Entity variable, AbstractValue type) : super(variable, type);
 
   // [HParameterValue]s are either the value of the parameter (in fully SSA
   // converted code), or the mutable variable containing the value (in
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 40917cf..007950f 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -14,7 +14,6 @@
 import '../elements/types.dart';
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/types.dart';
-import '../js/js.dart' as js;
 import '../js_backend/allocator_analysis.dart' show JAllocatorAnalysis;
 import '../js_backend/backend.dart';
 import '../js_backend/native_data.dart' show NativeData;
@@ -44,7 +43,7 @@
 
   Map<HInstruction, Range> ranges = <HInstruction, Range>{};
 
-  Map<MemberEntity, OptimizationLog> loggersForTesting;
+  Map<MemberEntity, OptimizationTestLog> loggersForTesting;
 
   SsaOptimizerTask(this._backend) : super(_backend.compiler.measurer);
 
@@ -70,10 +69,10 @@
     SsaCodeMotion codeMotion;
     SsaLoadElimination loadElimination;
 
-    OptimizationLog log;
+    OptimizationTestLog log;
     if (retainDataForTesting) {
       loggersForTesting ??= {};
-      loggersForTesting[work.element] = log = new OptimizationLog();
+      loggersForTesting[work.element] = log = new OptimizationTestLog();
     }
 
     measure(() {
@@ -86,7 +85,7 @@
         new SsaRedundantPhiEliminator(),
         new SsaDeadPhiEliminator(),
         new SsaTypePropagator(globalInferenceResults, _options,
-            closedWorld.commonElements, closedWorld),
+            closedWorld.commonElements, closedWorld, log),
         // After type propagation, more instructions can be
         // simplified.
         new SsaInstructionSimplifier(globalInferenceResults, _options,
@@ -96,7 +95,7 @@
             _rtiSubstitutions, closedWorld, registry, log),
         new SsaCheckInserter(trustPrimitives, closedWorld, boundsChecked),
         new SsaTypePropagator(globalInferenceResults, _options,
-            closedWorld.commonElements, closedWorld),
+            closedWorld.commonElements, closedWorld, log),
         // Run a dead code eliminator before LICM because dead
         // interceptors are often in the way of LICM'able instructions.
         new SsaDeadCodeEliminator(closedWorld, this),
@@ -104,7 +103,7 @@
         // After GVN, some instructions might need their type to be
         // updated because they now have different inputs.
         new SsaTypePropagator(globalInferenceResults, _options,
-            closedWorld.commonElements, closedWorld),
+            closedWorld.commonElements, closedWorld, log),
         codeMotion = new SsaCodeMotion(closedWorld.abstractValueDomain),
         loadElimination = new SsaLoadElimination(_compiler, closedWorld),
         new SsaRedundantPhiEliminator(),
@@ -114,7 +113,7 @@
         // learn from the refined type.
         new SsaTypeConversionInserter(closedWorld),
         new SsaTypePropagator(globalInferenceResults, _options,
-            closedWorld.commonElements, closedWorld),
+            closedWorld.commonElements, closedWorld, log),
         new SsaValueRangeAnalyzer(closedWorld, this),
         // Previous optimizations may have generated new
         // opportunities for instruction simplification.
@@ -137,7 +136,7 @@
           loadElimination.newGvnCandidates) {
         phases = <OptimizationPhase>[
           new SsaTypePropagator(globalInferenceResults, _options,
-              closedWorld.commonElements, closedWorld),
+              closedWorld.commonElements, closedWorld, log),
           new SsaGlobalValueNumberer(closedWorld.abstractValueDomain),
           new SsaCodeMotion(closedWorld.abstractValueDomain),
           new SsaValueRangeAnalyzer(closedWorld, this),
@@ -150,7 +149,7 @@
       } else {
         phases = <OptimizationPhase>[
           new SsaTypePropagator(globalInferenceResults, _options,
-              closedWorld.commonElements, closedWorld),
+              closedWorld.commonElements, closedWorld, log),
           // Run the simplifier to remove unneeded type checks inserted by
           // type propagation.
           new SsaInstructionSimplifier(globalInferenceResults, _options,
@@ -197,7 +196,7 @@
   final RuntimeTypesSubstitutions _rtiSubstitutions;
   final JClosedWorld _closedWorld;
   final CodegenRegistry _registry;
-  final OptimizationLog _log;
+  final OptimizationTestLog _log;
   HGraph _graph;
 
   SsaInstructionSimplifier(this._globalInferenceResults, this._options,
@@ -549,8 +548,11 @@
         _globalInferenceResults,
         _options,
         commonElements,
-        _closedWorld);
-    if (instruction != null) return instruction;
+        _closedWorld,
+        _log);
+    if (instruction != null) {
+      return instruction;
+    }
 
     Selector selector = node.selector;
     AbstractValue mask = node.mask;
@@ -755,50 +757,53 @@
 
   HInstruction tryInlineNativeMethod(
       HInvokeDynamicMethod node, FunctionEntity method) {
-    // Enable direct calls to a native method only if we don't run in checked
-    // mode, where the Dart version may have type annotations on parameters and
-    // return type that it should check.
-    // Also check that the parameters are not functions: it's the callee that
-    // will translate them to JS functions.
-    //
-    // TODO(ngeoffray): There are some cases where we could still inline in
-    // checked mode if we know the arguments have the right type. And we could
-    // do the closure conversion as well as the return type annotation check.
-
+    // We can replace the call to the native class interceptor method (target)
+    // if the target does no conversions or useful type checks.
+    if (_options.disableInlining) return null;
+    if (_closedWorld.annotationsData.hasNoInline(method)) {
+      return null;
+    }
     if (!node.isInterceptedCall) return null;
 
     FunctionType type = _closedWorld.elementEnvironment.getFunctionType(method);
     if (type.namedParameters.isNotEmpty) return null;
 
-    // Return types on native methods don't need to be checked, since the
-    // declaration has to be truthful.
-
     // The call site might omit optional arguments. The inlined code must
     // preserve the number of arguments, so check only the actual arguments.
 
-    List<HInstruction> inputs = node.inputs.sublist(1);
     bool canInline = true;
-    if (_options.parameterCheckPolicy.isEmitted && inputs.length > 1) {
-      // TODO(sra): Check if [input] is guaranteed to pass the parameter
-      // type check.  Consider using a strengthened type check to avoid
-      // passing `null` to primitive types since the native methods usually
-      // have non-nullable primitive parameter types.
-      canInline = false;
-    } else {
-      int inputPosition = 1; // Skip receiver.
-      void checkParameterType(DartType type) {
-        if (inputPosition++ < inputs.length && canInline) {
-          if (type.unaliased.isFunctionType) {
-            canInline = false;
-          }
-        }
+    List<HInstruction> inputs = node.inputs;
+    int inputPosition = 2; // Skip interceptor and receiver.
+
+    void checkParameterType(DartType parameterType) {
+      if (!canInline) return;
+      if (inputPosition >= inputs.length) return;
+      HInstruction input = inputs[inputPosition++];
+      if (parameterType.unaliased.isFunctionType) {
+        // Must call the target since it contains a function conversion.
+        canInline = false;
+        return;
       }
 
-      type.parameterTypes.forEach(checkParameterType);
-      type.optionalParameterTypes.forEach(checkParameterType);
-      type.namedParameterTypes.forEach(checkParameterType);
+      // If the target has no checks don't let a bad type stop us inlining.
+      if (!_options.parameterCheckPolicy.isEmitted) return;
+
+      AbstractValue parameterAbstractValue = _abstractValueDomain
+          .getAbstractValueForNativeMethodParameterType(parameterType);
+
+      if (parameterAbstractValue == null ||
+          _abstractValueDomain
+              .isIn(input.instructionType, parameterAbstractValue)
+              .isPotentiallyFalse) {
+        canInline = false;
+        return;
+      }
     }
 
+    type.parameterTypes.forEach(checkParameterType);
+    type.optionalParameterTypes.forEach(checkParameterType);
+    assert(type.namedParameterTypes.isEmpty);
+
     if (!canInline) return null;
 
     // Strengthen instruction type from annotations to help optimize
@@ -809,7 +814,7 @@
     HInvokeDynamicMethod result = new HInvokeDynamicMethod(
         node.selector,
         node.mask,
-        inputs,
+        inputs.sublist(1), // Drop interceptor.
         returnType,
         node.typeArguments,
         node.sourceInformation);
@@ -1287,11 +1292,16 @@
         value = other;
       }
     }
-    HFieldSet result =
-        new HFieldSet(_abstractValueDomain, field, receiver, value)
-          ..sourceInformation = node.sourceInformation;
-    _log?.registerFieldSet(node, result);
-    return result;
+    if (_closedWorld.elidedFields.contains(field)) {
+      _log?.registerFieldSet(node);
+      return value;
+    } else {
+      HFieldSet result =
+          new HFieldSet(_abstractValueDomain, field, receiver, value)
+            ..sourceInformation = node.sourceInformation;
+      _log?.registerFieldSet(node, result);
+      return result;
+    }
   }
 
   HInstruction visitInvokeClosure(HInvokeClosure node) {
@@ -1359,7 +1369,25 @@
           return argument;
         }
       }
+    } else if (element == commonElements.assertHelper ||
+        element == commonElements.assertTest) {
+      if (node.inputs.length == 1) {
+        HInstruction argument = node.inputs[0];
+        if (argument is HConstant) {
+          ConstantValue constant = argument.constant;
+          if (constant.isBool) {
+            bool value = constant.isTrue;
+            if (element == commonElements.assertTest) {
+              // `assertTest(argument)` effectively negates the argument.
+              return _graph.addConstantBool(!value, _closedWorld);
+            }
+            // `assertHelper(true)` is a no-op, other values throw.
+            if (value) return argument;
+          }
+        }
+      }
     }
+
     return node;
   }
 
@@ -1846,31 +1874,6 @@
     if (foreign.inputs.length < 1) return false;
     if (foreign.inputs.first != receiver) return false;
     if (foreign.throwBehavior.isNullNSMGuard) return true;
-
-    // TODO(sra): Fix NativeThrowBehavior to distinguish MAY from
-    // throws-nsm-on-null-followed-by-MAY and remove all the code below.
-
-    // We look for a template of the form
-    //
-    // #.something -or- #.something()
-    //
-    // where # is substituted by receiver.
-    js.Template template = foreign.codeTemplate;
-    js.Node node = template.ast;
-    // #.something = ...
-    if (node is js.Assignment) {
-      js.Assignment assignment = node;
-      node = assignment.leftHandSide;
-    }
-
-    // #.something
-    if (node is js.PropertyAccess) {
-      js.PropertyAccess access = node;
-      if (access.receiver is js.InterpolatedExpression) {
-        js.InterpolatedExpression hole = access.receiver;
-        return hole.isPositional && hole.nameOrPosition == 0;
-      }
-    }
     return false;
   }
 
@@ -1949,14 +1952,18 @@
     if (!instruction.usedBy.isEmpty) return false;
     if (isTrivialDeadStore(instruction)) return true;
     if (instruction.sideEffects.hasSideEffects()) return false;
-    if (instruction.canThrow(_abstractValueDomain) &&
-        instruction.onlyThrowsNSM() &&
-        hasFollowingThrowingNSM(instruction)) {
-      return true;
+    if (instruction.canThrow(_abstractValueDomain)) {
+      if (instruction.onlyThrowsNSM() && hasFollowingThrowingNSM(instruction)) {
+        // [instruction] is a null reciever guard that is followed by an
+        // instruction that fails the same way (by accessing a property of
+        // `null` or `undefined`).
+        return true;
+      }
+      return false;
     }
-    return !instruction.canThrow(_abstractValueDomain) &&
-        instruction is! HParameterValue &&
-        instruction is! HLocalSet;
+    if (instruction is HParameterValue) return false;
+    if (instruction is HLocalSet) return false;
+    return true;
   }
 
   void visitGraph(HGraph graph) {
@@ -2944,7 +2951,8 @@
     if (shouldTrackInitialValues(instruction)) {
       int argumentIndex = 0;
       compiler.codegenWorldBuilder.forEachInstanceField(instruction.element,
-          (_, FieldEntity member) {
+          (_, FieldEntity member, {bool isElided}) {
+        if (isElided) return;
         if (compiler.elementHasCompileTimeError(
             // ignore: UNNECESSARY_CAST
             member as Entity)) return;
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 492e6ea..8199ed4 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -10,6 +10,7 @@
 import '../options.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show JClosedWorld;
+import 'logging.dart';
 import 'nodes.dart';
 import 'optimize.dart';
 
@@ -39,10 +40,11 @@
   final CompilerOptions options;
   final CommonElements commonElements;
   final JClosedWorld closedWorld;
+  final OptimizationTestLog _log;
   String get name => 'SsaTypePropagator';
 
-  SsaTypePropagator(
-      this.results, this.options, this.commonElements, this.closedWorld);
+  SsaTypePropagator(this.results, this.options, this.commonElements,
+      this.closedWorld, this._log);
 
   AbstractValueDomain get abstractValueDomain =>
       closedWorld.abstractValueDomain;
@@ -280,6 +282,7 @@
         receiverTypeCheckSelector: selector);
     instruction.block.addBefore(instruction, converted);
     input.replaceAllUsersDominatedBy(instruction, converted);
+    _log?.registerTypeConversion(instruction, converted);
   }
 
   bool isCheckEnoughForNsmOrAe(HInstruction instruction, AbstractValue type) {
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index c574ac8..d40a26e 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -86,6 +86,19 @@
       ? this
       : new CallStructure(argumentCount, namedArguments);
 
+  /// Short textual representation use for testing.
+  String get shortText {
+    StringBuffer sb = new StringBuffer();
+    sb.write('(');
+    sb.write(positionalArgumentCount);
+    if (namedArgumentCount > 0) {
+      sb.write(',');
+      sb.write(getOrderedNamedArguments().join(','));
+    }
+    sb.write(')');
+    return sb.toString();
+  }
+
   /// A description of the argument structure.
   String structureToString() {
     StringBuffer sb = new StringBuffer();
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 2c9980d..323bca3 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -37,14 +37,20 @@
   /// Calls [f] with every instance field, together with its declarer, in an
   /// instance of [cls]. All fields inherited from superclasses and mixins are
   /// included.
+  ///
+  /// If [isElided] is `true`, the field is not read and should therefore not
+  /// be emitted.
   void forEachInstanceField(covariant ClassEntity cls,
-      void f(ClassEntity declarer, FieldEntity field));
+      void f(ClassEntity declarer, FieldEntity field, {bool isElided}));
 
   /// Calls [f] with every instance field declared directly in class [cls]
   /// (i.e. no inherited fields). Fields are presented in initialization
   /// (i.e. textual) order.
+  ///
+  /// If [isElided] is `true`, the field is not read and should therefore not
+  /// be emitted.
   void forEachDirectInstanceField(
-      covariant ClassEntity cls, void f(FieldEntity field));
+      covariant ClassEntity cls, void f(FieldEntity field, {bool isElided}));
 
   /// Calls [f] for each parameter of [function] providing the type and name of
   /// the parameter and the [defaultValue] if the parameter is optional.
@@ -302,7 +308,9 @@
         registerDynamicInvocation(
             dynamicUse.selector, dynamicUse.typeArguments);
         if (_registerNewSelector(dynamicUse, _invokedNames)) {
-          _process(_instanceMembersByName, (m) => m.invoke());
+          // We don't track parameters in the codegen world builder, so we
+          // pass `null` instead of the concrete call structure.
+          _process(_instanceMembersByName, (m) => m.invoke(null));
           return true;
         }
         break;
@@ -405,7 +413,6 @@
       case StaticUseKind.GET:
       case StaticUseKind.SET:
       case StaticUseKind.INIT:
-      case StaticUseKind.REFLECT:
         break;
     }
   }
@@ -447,7 +454,6 @@
       case StaticUseKind.GET:
       case StaticUseKind.SET:
       case StaticUseKind.INIT:
-      case StaticUseKind.REFLECT:
         useSet.addAll(usage.normalUse());
         break;
       case StaticUseKind.CONSTRUCTOR_INVOKE:
@@ -458,7 +464,9 @@
       case StaticUseKind.DIRECT_INVOKE:
         MemberEntity member = staticUse.element;
         MemberUsage instanceUsage = _getMemberUsage(member, memberUsed);
-        memberUsed(instanceUsage.entity, instanceUsage.invoke());
+        // We don't track parameters in the codegen world builder, so we
+        // pass `null` instead of the concrete call structure.
+        memberUsed(instanceUsage.entity, instanceUsage.invoke(null));
         _instanceMembersByName[instanceUsage.entity.name]
             ?.remove(instanceUsage);
         useSet.addAll(usage.normalUse());
@@ -514,17 +522,19 @@
         useSet.addAll(usage.write());
       }
       if (!usage.hasInvoke && hasInvocation(member)) {
-        useSet.addAll(usage.invoke());
+        // We don't track parameters in the codegen world builder, so we
+        // pass `null` instead of the concrete call structures.
+        useSet.addAll(usage.invoke(null));
       }
 
-      if (usage.pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)) {
+      if (usage.hasPendingClosurizationUse) {
         // Store the member in [instanceFunctionsByName] to catch
         // getters on the function.
         _instanceFunctionsByName
             .putIfAbsent(usage.entity.name, () => new Set<MemberUsage>())
             .add(usage);
       }
-      if (usage.pendingUse.contains(MemberUse.NORMAL)) {
+      if (usage.hasPendingNormalUse) {
         // The element is not yet used. Add it to the list of instance
         // members to still be processed.
         _instanceMembersByName
@@ -683,26 +693,35 @@
   @override
   void forEachParameter(FunctionEntity function,
       void f(DartType type, String name, ConstantValue defaultValue)) {
-    _elementMap.forEachParameter(function, f);
+    _elementMap.forEachParameter(function, f,
+        isNative: _world.nativeData.isNativeMember(function));
   }
 
   @override
   void forEachParameterAsLocal(
       FunctionEntity function, void f(Local parameter)) {
-    forEachOrderedParameter(_globalLocalsMap, _elementMap, function, f);
-  }
-
-  @override
-  void forEachInstanceField(
-      ClassEntity cls, void f(ClassEntity declarer, FieldEntity field)) {
-    _elementEnvironment.forEachClassMember(cls,
-        (ClassEntity declarer, MemberEntity member) {
-      if (member.isField && member.isInstanceMember) f(declarer, member);
+    forEachOrderedParameterAsLocal(_globalLocalsMap, _elementMap, function,
+        (Local parameter, {bool isElided}) {
+      if (!isElided) {
+        f(parameter);
+      }
     });
   }
 
   @override
-  void forEachDirectInstanceField(ClassEntity cls, void f(FieldEntity field)) {
+  void forEachInstanceField(ClassEntity cls,
+      void f(ClassEntity declarer, FieldEntity field, {bool isElided})) {
+    _elementEnvironment.forEachClassMember(cls,
+        (ClassEntity declarer, MemberEntity member) {
+      if (member.isField && member.isInstanceMember) {
+        f(declarer, member, isElided: _world.elidedFields.contains(member));
+      }
+    });
+  }
+
+  @override
+  void forEachDirectInstanceField(
+      ClassEntity cls, void f(FieldEntity field, {bool isElided})) {
     // TODO(sra): Add ElementEnvironment.forEachDirectInstanceField or
     // parameterize [forEachInstanceField] to filter members to avoid a
     // potentially O(n^2) scan of the superclasses.
@@ -711,7 +730,7 @@
       if (declarer != cls) return;
       if (!member.isField) return;
       if (!member.isInstanceMember) return;
-      f(member);
+      f(member, isElided: _world.elidedFields.contains(member));
     });
   }
 
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index 6b166f8..b0898df 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -2,10 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:math' as Math;
+
 import '../common.dart';
 import '../elements/entities.dart';
 import '../js_model/elements.dart' show JSignatureMethod;
 import '../util/enumset.dart';
+import 'call_structure.dart';
 
 abstract class AbstractUsage<T> {
   final EnumSet<T> _pendingUse = new EnumSet<T>();
@@ -14,9 +17,6 @@
     _pendingUse.addAll(_originalUse);
   }
 
-  /// Returns the possible uses of [entity] that have not yet been registered.
-  EnumSet<T> get pendingUse => _pendingUse;
-
   /// Returns the uses of [entity] that have been registered.
   EnumSet<T> get appliedUse => _originalUse.minus(_pendingUse);
 
@@ -39,7 +39,8 @@
 
   MemberUsage.internal(this.entity);
 
-  factory MemberUsage(MemberEntity member, {bool isNative: false}) {
+  factory MemberUsage(MemberEntity member,
+      {bool isNative: false, bool trackParameters: false}) {
     if (member.isField) {
       if (member.isAssignable) {
         return new FieldUsage(member, isNative: isNative);
@@ -51,13 +52,24 @@
     } else if (member.isSetter) {
       return new SetterUsage(member);
     } else if (member.isConstructor) {
-      return new ConstructorUsage(member);
+      if (trackParameters) {
+        return new ParameterTrackingConstructorUsage(member);
+      } else {
+        return new ConstructorUsage(member);
+      }
     } else {
       assert(member.isFunction, failedAt(member, "Unexpected member: $member"));
-      return new FunctionUsage(member);
+      if (trackParameters) {
+        return new ParameterTrackingFunctionUsage(member);
+      } else {
+        return new FunctionUsage(member);
+      }
     }
   }
 
+  /// `true` if [entity] has been initialized.
+  bool get hasInit => true;
+
   /// `true` if [entity] has been read as a value. For a field this is a normal
   /// read access, for a function this is a closurization.
   bool get hasRead => false;
@@ -70,6 +82,29 @@
   /// followed by an invocation of the function-like value.
   bool get hasInvoke => false;
 
+  /// `true` if all parameters are provided in invocations of [entity].
+  ///
+  /// For method or constructors with no optional arguments this is the same
+  /// as [hasInvoke] but for method or constructors with optional arguments some
+  /// parameters may have been provided in any invocation in which case
+  /// [isFullyInvoked] is `false`.
+  bool get isFullyInvoked => hasInvoke;
+
+  /// Returns the [ParameterStructure] corresponding to the parameters that are
+  /// used in invocations of [entity]. For a field, getter or setter this is
+  /// always `null`.
+  ParameterStructure get invokedParameters => null;
+
+  /// `true` if [entity] has further normal use. For a field this means that
+  /// it hasn't been read from or written to. For a function this means that it
+  /// hasn't been invoked or, when parameter usage is tracked, that some
+  /// parameters haven't been provided in any invocation.
+  bool get hasPendingNormalUse => _pendingUse.contains(MemberUse.NORMAL);
+
+  /// `true` if [entity] hasn't been closurized. This is only used for
+  /// functions.
+  bool get hasPendingClosurizationUse => false;
+
   /// `true` if [entity] has been used in all the ways possible.
   bool get fullyUsed;
 
@@ -96,7 +131,7 @@
   ///
   /// For a function this is a normal invocation, for a field this is a read
   /// access followed by an invocation of the function-like value.
-  EnumSet<MemberUse> invoke() => MemberUses.NONE;
+  EnumSet<MemberUse> invoke(CallStructure callStructure) => MemberUses.NONE;
 
   /// Registers all possible uses of [entity] and returns the new [MemberUse]s
   /// that it caused.
@@ -117,89 +152,136 @@
 }
 
 class FieldUsage extends MemberUsage {
+  bool hasInit = false;
   bool hasRead = false;
   bool hasWrite = false;
 
   FieldUsage(FieldEntity field, {bool isNative: false})
       : super.internal(field) {
+    // TODO(johnniwinther): Track native fields through member usage.
     if (!isNative) {
-      // All field initializers must be resolved as they could
-      // have an observable side-effect (and cannot be tree-shaken
-      // away).
-      fullyUse();
+      init();
     }
   }
 
   @override
-  bool get fullyUsed => hasRead && hasWrite;
+  bool get hasPendingNormalUse => !fullyUsed;
 
   @override
-  EnumSet<MemberUse> init() => read();
+  bool get fullyUsed => hasInit && hasRead && hasWrite;
 
   @override
-  EnumSet<MemberUse> read() {
-    if (fullyUsed) {
+  EnumSet<MemberUse> init() {
+    if (hasInit) {
       return MemberUses.NONE;
     }
-    hasRead = true;
-    return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
-  }
-
-  @override
-  EnumSet<MemberUse> write() {
-    if (fullyUsed) {
-      return MemberUses.NONE;
+    hasInit = true;
+    EnumSet<MemberUse> result = _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    if (!fullyUsed) {
+      result = result.union(MemberUses.PARTIAL_USE_ONLY);
     }
-    hasWrite = true;
-    return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    return result;
   }
 
   @override
-  EnumSet<MemberUse> invoke() => read();
-
-  @override
-  EnumSet<MemberUse> fullyUse() {
-    if (fullyUsed) {
-      return MemberUses.NONE;
-    }
-    hasRead = hasWrite = true;
-    return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
-  }
-}
-
-class FinalFieldUsage extends MemberUsage {
-  bool hasRead = false;
-
-  FinalFieldUsage(FieldEntity field, {bool isNative: false})
-      : super.internal(field) {
-    if (!isNative) {
-      // All field initializers must be resolved as they could
-      // have an observable side-effect (and cannot be tree-shaken
-      // away).
-      read();
-    }
-  }
-
-  @override
-  bool get fullyUsed => hasRead;
-
-  @override
-  EnumSet<MemberUse> init() => read();
-
-  @override
   EnumSet<MemberUse> read() {
     if (hasRead) {
       return MemberUses.NONE;
     }
     hasRead = true;
-    return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    EnumSet<MemberUse> result = _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    if (!fullyUsed) {
+      result = result.union(MemberUses.PARTIAL_USE_ONLY);
+    }
+    return result;
   }
 
   @override
-  EnumSet<MemberUse> invoke() => read();
+  EnumSet<MemberUse> write() {
+    if (hasWrite) {
+      return MemberUses.NONE;
+    }
+    hasWrite = true;
+    EnumSet<MemberUse> result = _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    if (!fullyUsed) {
+      result = result.union(MemberUses.PARTIAL_USE_ONLY);
+    }
+    return result;
+  }
 
   @override
-  EnumSet<MemberUse> fullyUse() => read();
+  EnumSet<MemberUse> invoke(CallStructure callStructure) => read();
+
+  @override
+  EnumSet<MemberUse> fullyUse() {
+    if (fullyUsed) {
+      return MemberUses.NONE;
+    }
+    hasInit = hasRead = hasWrite = true;
+    return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+  }
+
+  String toString() => 'FieldUsage($entity,hasInit=$hasInit,hasRead=$hasRead,'
+      'hasWrite=$hasWrite,pendingUse=${_pendingUse.iterable(MemberUse.values)}';
+}
+
+class FinalFieldUsage extends MemberUsage {
+  bool hasInit = false;
+  bool hasRead = false;
+
+  FinalFieldUsage(FieldEntity field, {bool isNative: false})
+      : super.internal(field) {
+    if (!isNative) {
+      init();
+    }
+  }
+
+  @override
+  bool get hasPendingNormalUse => !fullyUsed;
+
+  @override
+  bool get fullyUsed => hasInit && hasRead;
+
+  @override
+  EnumSet<MemberUse> init() {
+    if (hasInit) {
+      return MemberUses.NONE;
+    }
+    hasInit = true;
+    EnumSet<MemberUse> result = _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    if (!fullyUsed) {
+      result = result.union(MemberUses.PARTIAL_USE_ONLY);
+    }
+    return result;
+  }
+
+  @override
+  EnumSet<MemberUse> read() {
+    if (hasRead) {
+      return MemberUses.NONE;
+    }
+    hasRead = true;
+    EnumSet<MemberUse> result = _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    if (!fullyUsed) {
+      result = result.union(MemberUses.PARTIAL_USE_ONLY);
+    }
+    return result;
+  }
+
+  @override
+  EnumSet<MemberUse> invoke(CallStructure callStructure) => read();
+
+  @override
+  EnumSet<MemberUse> fullyUse() {
+    if (fullyUsed) {
+      return MemberUses.NONE;
+    }
+    hasInit = hasRead = true;
+    return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+  }
+
+  String toString() => 'FinalFieldUsage($entity,hasInit=$hasInit,'
+      'hasRead=$hasRead,pendingUse=${_pendingUse.iterable(MemberUse.values)}';
 }
 
 class FunctionUsage extends MemberUsage {
@@ -211,18 +293,24 @@
       // We mark signature methods as "always used" to prevent them from being
       // optimized away.
       // TODO(johnniwinther): Make this a part of the regular enqueueing.
-      invoke();
+      invoke(function.parameterStructure.callStructure);
     }
   }
 
+  FunctionEntity get entity => super.entity;
+
   EnumSet<MemberUse> get _originalUse =>
       entity.isInstanceMember ? MemberUses.ALL_INSTANCE : MemberUses.ALL_STATIC;
 
+  bool get hasPendingClosurizationUse => entity.isInstanceMember
+      ? _pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)
+      : _pendingUse.contains(MemberUse.CLOSURIZE_STATIC);
+
   @override
   EnumSet<MemberUse> read() => fullyUse();
 
   @override
-  EnumSet<MemberUse> invoke() {
+  EnumSet<MemberUse> invoke(CallStructure callStructure) {
     if (hasInvoke) {
       return MemberUses.NONE;
     }
@@ -254,6 +342,91 @@
 
   @override
   bool get fullyUsed => hasInvoke && hasRead;
+
+  @override
+  ParameterStructure get invokedParameters =>
+      hasInvoke ? entity.parameterStructure : null;
+}
+
+class ParameterTrackingFunctionUsage extends MemberUsage {
+  bool hasRead = false;
+
+  final ParameterUsage _parameterUsage;
+
+  ParameterTrackingFunctionUsage(FunctionEntity function)
+      : _parameterUsage = new ParameterUsage(function.parameterStructure),
+        super.internal(function) {
+    if (function is JSignatureMethod) {
+      // We mark signature methods as "always used" to prevent them from being
+      // optimized away.
+      // TODO(johnniwinther): Make this a part of the regular enqueueing.
+      invoke(CallStructure.NO_ARGS);
+    }
+  }
+
+  bool get hasInvoke => _parameterUsage.hasInvoke;
+
+  bool get hasPendingClosurizationUse => entity.isInstanceMember
+      ? _pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)
+      : _pendingUse.contains(MemberUse.CLOSURIZE_STATIC);
+
+  EnumSet<MemberUse> get _originalUse =>
+      entity.isInstanceMember ? MemberUses.ALL_INSTANCE : MemberUses.ALL_STATIC;
+
+  @override
+  EnumSet<MemberUse> read() => fullyUse();
+
+  @override
+  EnumSet<MemberUse> invoke(CallStructure callStructure) {
+    if (_parameterUsage.isFullyUsed) {
+      return MemberUses.NONE;
+    }
+    bool alreadyHasInvoke = hasInvoke;
+    bool hasPartialChange = _parameterUsage.invoke(callStructure);
+    EnumSet<MemberUse> result;
+    if (alreadyHasInvoke) {
+      result = MemberUses.NONE;
+    } else {
+      result = _pendingUse
+          .removeAll(hasRead ? MemberUses.NONE : MemberUses.NORMAL_ONLY);
+    }
+    return hasPartialChange
+        ? result.union(MemberUses.PARTIAL_USE_ONLY)
+        : result;
+  }
+
+  @override
+  EnumSet<MemberUse> fullyUse() {
+    bool alreadyHasInvoke = hasInvoke;
+    _parameterUsage.fullyUse();
+    if (alreadyHasInvoke) {
+      if (hasRead) {
+        return MemberUses.NONE;
+      }
+      hasRead = true;
+      return _pendingUse.removeAll(entity.isInstanceMember
+          ? MemberUses.CLOSURIZE_INSTANCE_ONLY
+          : MemberUses.CLOSURIZE_STATIC_ONLY);
+    } else if (hasRead) {
+      return _pendingUse.removeAll(MemberUses.NORMAL_ONLY);
+    } else {
+      hasRead = true;
+      return _pendingUse.removeAll(entity.isInstanceMember
+          ? MemberUses.ALL_INSTANCE
+          : MemberUses.ALL_STATIC);
+    }
+  }
+
+  @override
+  bool get hasPendingNormalUse => !isFullyInvoked;
+
+  bool get isFullyInvoked => _parameterUsage.isFullyUsed;
+
+  @override
+  bool get fullyUsed => isFullyInvoked && hasRead;
+
+  @override
+  ParameterStructure get invokedParameters => _parameterUsage.invokedParameters;
 }
 
 class GetterUsage extends MemberUsage {
@@ -274,7 +447,7 @@
   }
 
   @override
-  EnumSet<MemberUse> invoke() => read();
+  EnumSet<MemberUse> invoke(CallStructure callStructure) => read();
 
   @override
   EnumSet<MemberUse> fullyUse() => read();
@@ -306,10 +479,12 @@
 
   ConstructorUsage(ConstructorEntity constructor) : super.internal(constructor);
 
+  ConstructorEntity get entity => super.entity;
+
   EnumSet<MemberUse> get _originalUse => MemberUses.NORMAL_ONLY;
 
   @override
-  EnumSet<MemberUse> invoke() {
+  EnumSet<MemberUse> invoke(CallStructure callStructure) {
     if (hasInvoke) {
       return MemberUses.NONE;
     }
@@ -319,14 +494,83 @@
   }
 
   @override
-  EnumSet<MemberUse> fullyUse() => invoke();
+  EnumSet<MemberUse> fullyUse() =>
+      invoke(entity.parameterStructure.callStructure);
 
   @override
   bool get fullyUsed => hasInvoke;
+
+  @override
+  ParameterStructure get invokedParameters =>
+      hasInvoke ? entity.parameterStructure : null;
+}
+
+class ParameterTrackingConstructorUsage extends MemberUsage {
+  final ParameterUsage _parameterUsage;
+
+  ParameterTrackingConstructorUsage(ConstructorEntity constructor)
+      : _parameterUsage = new ParameterUsage(constructor.parameterStructure),
+        super.internal(constructor);
+
+  ConstructorEntity get entity => super.entity;
+
+  EnumSet<MemberUse> get _originalUse => MemberUses.NORMAL_ONLY;
+
+  @override
+  EnumSet<MemberUse> invoke(CallStructure callStructure) {
+    if (isFullyInvoked) {
+      return MemberUses.NONE;
+    }
+    bool alreadyHasInvoke = hasInvoke;
+    bool hasPartialChange = _parameterUsage.invoke(callStructure);
+    EnumSet<MemberUse> result;
+    if (alreadyHasInvoke) {
+      result = MemberUses.NONE;
+    } else {
+      result = _pendingUse
+          .removeAll(hasRead ? MemberUses.NONE : MemberUses.NORMAL_ONLY);
+    }
+    return hasPartialChange
+        ? result.union(MemberUses.PARTIAL_USE_ONLY)
+        : result;
+  }
+
+  @override
+  EnumSet<MemberUse> fullyUse() =>
+      invoke(entity.parameterStructure.callStructure);
+
+  @override
+  bool get hasInvoke => _parameterUsage.hasInvoke;
+
+  @override
+  bool get fullyUsed => _parameterUsage.isFullyUsed;
+
+  @override
+  bool get hasPendingNormalUse => !isFullyInvoked;
+
+  bool get isFullyInvoked => _parameterUsage.isFullyUsed;
+
+  @override
+  ParameterStructure get invokedParameters => _parameterUsage.invokedParameters;
 }
 
 /// Enum class for the possible kind of use of [MemberEntity] objects.
-enum MemberUse { NORMAL, CLOSURIZE_INSTANCE, CLOSURIZE_STATIC }
+enum MemberUse {
+  /// Read or write of a field, or invocation of a method.
+  NORMAL,
+
+  /// Tear-off of an instance method.
+  CLOSURIZE_INSTANCE,
+
+  /// Tear-off of a static method.
+  CLOSURIZE_STATIC,
+
+  /// Invocation that provides previously unprovided optional parameters.
+  ///
+  /// This is used to check that no partial use is missed by the enqueuer, as
+  /// asserted through the `Enqueuery.checkEnqueuerConsistency` method.
+  PARTIAL_USE,
+}
 
 /// Common [EnumSet]s used for [MemberUse].
 class MemberUses {
@@ -341,6 +585,8 @@
       const EnumSet<MemberUse>.fixed(3);
   static const EnumSet<MemberUse> ALL_STATIC =
       const EnumSet<MemberUse>.fixed(5);
+  static const EnumSet<MemberUse> PARTIAL_USE_ONLY =
+      const EnumSet<MemberUse>.fixed(8);
 }
 
 typedef void MemberUsedCallback(MemberEntity member, EnumSet<MemberUse> useSet);
@@ -418,11 +664,17 @@
 
   EnumSet<MemberUse> write() => normalUse();
 
-  EnumSet<MemberUse> invoke() => normalUse();
+  EnumSet<MemberUse> invoke(CallStructure callStructure) => normalUse();
 
   EnumSet<MemberUse> fullyUse() => normalUse();
 
   @override
+  bool get hasPendingNormalUse => _pendingUse.contains(MemberUse.NORMAL);
+
+  @override
+  bool get isFullyInvoked => hasInvoke;
+
+  @override
   EnumSet<MemberUse> get _originalUse => MemberUses.NORMAL_ONLY;
 
   String toString() => '$entity:${appliedUse.iterable(MemberUse.values)}';
@@ -434,6 +686,9 @@
   EnumSet<MemberUse> tearOff() => normalUse();
 
   @override
+  bool get hasInit => true;
+
+  @override
   bool get fullyUsed => hasNormalUse;
 
   @override
@@ -444,12 +699,23 @@
 
   @override
   bool get hasRead => hasNormalUse;
+
+  @override
+  bool get hasPendingClosurizationUse => false;
+
+  @override
+  ParameterStructure get invokedParameters => null;
 }
 
 class StaticFunctionUsage extends StaticMemberUsage {
   bool hasClosurization = false;
 
-  StaticFunctionUsage(MemberEntity entity) : super.internal(entity);
+  StaticFunctionUsage(FunctionEntity entity) : super.internal(entity);
+
+  FunctionEntity get entity => super.entity;
+
+  @override
+  bool get hasInit => true;
 
   EnumSet<MemberUse> tearOff() {
     if (hasClosurization) {
@@ -463,6 +729,10 @@
   EnumSet<MemberUse> get _originalUse => MemberUses.ALL_STATIC;
 
   @override
+  bool get hasPendingClosurizationUse =>
+      _pendingUse.contains(MemberUse.CLOSURIZE_STATIC);
+
+  @override
   bool get fullyUsed => hasNormalUse && hasClosurization;
 
   @override
@@ -473,4 +743,109 @@
 
   @override
   bool get hasRead => hasClosurization;
+
+  @override
+  ParameterStructure get invokedParameters =>
+      hasInvoke ? entity.parameterStructure : null;
+}
+
+/// Object used for tracking parameter use in constructor and method
+/// invocations.
+class ParameterUsage {
+  /// The original parameter structure of the method or constructor.
+  final ParameterStructure _parameterStructure;
+
+  /// `true` if the method or constructor has at least one invocation.
+  bool _hasInvoke;
+
+  /// The maximum number of (optional) positional parameters provided in
+  /// invocations of the method or constructor.
+  ///
+  /// If all positional parameters having been provided this is set to `null`.
+  int _providedPositionalParameters;
+
+  /// `true` if all type parameters have been provided in at least one
+  /// invocation of the method or constructor.
+  bool _areAllTypeParametersProvided;
+
+  /// The set of named parameters that have not yet been provided in any
+  /// invocation of the method or constructor.
+  ///
+  /// If all named parameters have been provided this is set to `null`.
+  Set<String> _unprovidedNamedParameters;
+
+  ParameterUsage(this._parameterStructure) {
+    _hasInvoke = false;
+    _areAllTypeParametersProvided = _parameterStructure.typeParameters == 0;
+    _providedPositionalParameters = _parameterStructure.positionalParameters ==
+            _parameterStructure.requiredParameters
+        ? null
+        : 0;
+    if (!_parameterStructure.namedParameters.isEmpty) {
+      _unprovidedNamedParameters =
+          new Set<String>.from(_parameterStructure.namedParameters);
+    }
+  }
+
+  bool invoke(CallStructure callStructure) {
+    if (isFullyUsed) return false;
+    _hasInvoke = true;
+    bool changed = false;
+    if (_providedPositionalParameters != null) {
+      int newProvidedPositionalParameters = Math.max(
+          _providedPositionalParameters, callStructure.positionalArgumentCount);
+      changed |=
+          newProvidedPositionalParameters != _providedPositionalParameters;
+      _providedPositionalParameters = newProvidedPositionalParameters;
+      if (_providedPositionalParameters >=
+          _parameterStructure.positionalParameters) {
+        _providedPositionalParameters = null;
+      }
+    }
+    if (_unprovidedNamedParameters != null &&
+        callStructure.namedArguments.isNotEmpty) {
+      int _providedNamedParametersCount = _unprovidedNamedParameters.length;
+      _unprovidedNamedParameters.removeAll(callStructure.namedArguments);
+      changed |=
+          _providedNamedParametersCount != _unprovidedNamedParameters.length;
+      if (_unprovidedNamedParameters.isEmpty) {
+        _unprovidedNamedParameters = null;
+      }
+    }
+    if (!_areAllTypeParametersProvided && callStructure.typeArgumentCount > 0) {
+      _areAllTypeParametersProvided = true;
+      changed = true;
+    }
+    return changed;
+  }
+
+  bool get hasInvoke => _hasInvoke;
+
+  bool get isFullyUsed =>
+      _hasInvoke &&
+      _providedPositionalParameters == null &&
+      _unprovidedNamedParameters == null &&
+      _areAllTypeParametersProvided;
+
+  void fullyUse() {
+    _hasInvoke = true;
+    _providedPositionalParameters = null;
+    _unprovidedNamedParameters = null;
+    _areAllTypeParametersProvided = true;
+  }
+
+  ParameterStructure get invokedParameters {
+    if (!_hasInvoke) return null;
+    if (isFullyUsed) return _parameterStructure;
+    return new ParameterStructure(
+        _parameterStructure.requiredParameters,
+        _providedPositionalParameters ??
+            _parameterStructure.positionalParameters,
+        _unprovidedNamedParameters == null
+            ? _parameterStructure.namedParameters
+            : _parameterStructure.namedParameters
+                .where((n) => !_unprovidedNamedParameters.contains(n))
+                .toList(),
+        _areAllTypeParametersProvided ? _parameterStructure.typeParameters : 0);
+  }
 }
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index fee6d25..da4c609 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -22,11 +22,12 @@
 import '../kernel/kernel_world.dart';
 import '../native/enqueue.dart' show NativeResolutionEnqueuer;
 import '../options.dart';
-import '../universe/class_set.dart';
 import '../util/enumset.dart';
 import '../util/util.dart';
 import '../world.dart' show KClosedWorld, OpenWorld;
+import 'call_structure.dart';
 import 'class_hierarchy.dart' show ClassHierarchyBuilder, ClassQueries;
+import 'class_set.dart';
 import 'member_usage.dart';
 import 'selector.dart' show Selector;
 import 'use.dart'
@@ -328,10 +329,12 @@
 
   Map<ClassEntity, ClassUsage> get classUsageForTesting => _processedClasses;
 
-  /// Map of registered usage of static members of live classes.
+  /// Map of registered usage of members of live classes.
   final Map<MemberEntity, MemberUsage> _memberUsage =
       <MemberEntity, MemberUsage>{};
 
+  Map<MemberEntity, MemberUsage> get memberUsageForTesting => _memberUsage;
+
   Map<MemberEntity, MemberUsage> get staticMemberUsageForTesting {
     Map<MemberEntity, MemberUsage> map = <MemberEntity, MemberUsage>{};
     _memberUsage.forEach((MemberEntity member, MemberUsage usage) {
@@ -352,8 +355,8 @@
     return map;
   }
 
-  /// Map containing instance members of live classes that are not yet live
-  /// themselves.
+  /// Map containing instance members of live classes that are not yet fully
+  /// live themselves.
   final Map<String, Set<MemberUsage>> _instanceMembersByName =
       <String, Set<MemberUsage>>{};
 
@@ -581,6 +584,22 @@
     getInstantiationMap().forEach(f);
   }
 
+  Iterable<CallStructure> _getMatchingCallStructures(
+      Map<Selector, SelectorConstraints> selectors, MemberEntity member) {
+    if (selectors == null) return const <CallStructure>[];
+    Set<CallStructure> callStructures;
+    for (Selector selector in selectors.keys) {
+      if (selector.appliesUnnamed(member)) {
+        SelectorConstraints masks = selectors[selector];
+        if (masks.canHit(member, selector.memberName, this)) {
+          callStructures ??= new Set<CallStructure>();
+          callStructures.add(selector.callStructure);
+        }
+      }
+    }
+    return callStructures ?? const <CallStructure>[];
+  }
+
   bool _hasMatchingSelector(
       Map<Selector, SelectorConstraints> selectors, MemberEntity member) {
     if (selectors == null) return false;
@@ -600,8 +619,8 @@
     return _instantiationInfo;
   }
 
-  bool _hasInvocation(MemberEntity member) {
-    return _hasMatchingSelector(_invokedNames[member.name], member);
+  Iterable<CallStructure> _getInvocationCallStructures(MemberEntity member) {
+    return _getMatchingCallStructures(_invokedNames[member.name], member);
   }
 
   bool _hasInvokedGetter(MemberEntity member) {
@@ -618,14 +637,16 @@
     Selector selector = dynamicUse.selector;
     String methodName = selector.name;
 
-    void _process(Map<String, Set<MemberUsage>> memberMap,
-        EnumSet<MemberUse> action(MemberUsage usage)) {
+    void _process(
+        Map<String, Set<MemberUsage>> memberMap,
+        EnumSet<MemberUse> action(MemberUsage usage),
+        bool shouldBeRemoved(MemberUsage usage)) {
       _processSet(memberMap, methodName, (MemberUsage usage) {
         if (selector.appliesUnnamed(usage.entity) &&
             _selectorConstraintsStrategy.appliedUnnamed(
                 dynamicUse, usage.entity, this)) {
           memberUsed(usage.entity, action(usage));
-          return true;
+          return shouldBeRemoved(usage);
         }
         return false;
       });
@@ -636,18 +657,24 @@
         registerDynamicInvocation(
             dynamicUse.selector, dynamicUse.typeArguments);
         if (_registerNewSelector(dynamicUse, _invokedNames)) {
-          _process(_instanceMembersByName, (m) => m.invoke());
+          _process(
+              _instanceMembersByName,
+              (m) => m.invoke(dynamicUse.selector.callStructure),
+              (u) => !u.hasPendingNormalUse);
         }
         break;
       case DynamicUseKind.GET:
         if (_registerNewSelector(dynamicUse, _invokedGetters)) {
-          _process(_instanceMembersByName, (m) => m.read());
-          _process(_instanceFunctionsByName, (m) => m.read());
+          _process(_instanceMembersByName, (m) => m.read(),
+              (u) => !u.hasPendingNormalUse);
+          _process(_instanceFunctionsByName, (m) => m.read(),
+              (u) => !u.hasPendingClosurizationUse);
         }
         break;
       case DynamicUseKind.SET:
         if (_registerNewSelector(dynamicUse, _invokedSetters)) {
-          _process(_instanceMembersByName, (m) => m.write());
+          _process(_instanceMembersByName, (m) => m.write(),
+              (u) => !u.hasPendingNormalUse);
         }
         break;
     }
@@ -702,7 +729,7 @@
     MemberEntity element = staticUse.element;
     EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
     MemberUsage usage = _memberUsage.putIfAbsent(element, () {
-      MemberUsage usage = new MemberUsage(element);
+      MemberUsage usage = new MemberUsage(element, trackParameters: true);
       useSet.addAll(usage.appliedUse);
       return usage;
     });
@@ -742,20 +769,17 @@
       case StaticUseKind.SET:
         useSet.addAll(usage.write());
         break;
-      case StaticUseKind.REFLECT:
-        useSet.addAll(usage.fullyUse());
-        break;
       case StaticUseKind.INIT:
         useSet.addAll(usage.init());
         break;
       case StaticUseKind.INVOKE:
         registerStaticInvocation(staticUse);
-        useSet.addAll(usage.invoke());
+        useSet.addAll(usage.invoke(staticUse.callStructure));
         break;
       case StaticUseKind.CONSTRUCTOR_INVOKE:
       case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
       case StaticUseKind.REDIRECTION:
-        useSet.addAll(usage.invoke());
+        useSet.addAll(usage.invoke(staticUse.callStructure));
         break;
       case StaticUseKind.DIRECT_INVOKE:
         failedAt(element, 'Direct static use is not supported for resolution.');
@@ -824,7 +848,9 @@
     map[memberName] = new Set<MemberUsage>();
     Set<MemberUsage> remaining = new Set<MemberUsage>();
     for (MemberUsage usage in members) {
-      if (!updateUsage(usage)) remaining.add(usage);
+      if (!updateUsage(usage)) {
+        remaining.add(usage);
+      }
     }
     map[memberName].addAll(remaining);
   }
@@ -845,7 +871,8 @@
       newUsage = true;
       bool isNative = _nativeBasicData.isNativeClass(cls);
       EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
-      MemberUsage usage = new MemberUsage(member, isNative: isNative);
+      MemberUsage usage =
+          new MemberUsage(member, isNative: isNative, trackParameters: true);
       useSet.addAll(usage.appliedUse);
       if (member.isField && isNative) {
         registerUsedElement(member);
@@ -859,21 +886,28 @@
       if (!usage.hasRead && _hasInvokedGetter(member)) {
         useSet.addAll(usage.read());
       }
-      if (!usage.hasInvoke && _hasInvocation(member)) {
-        useSet.addAll(usage.invoke());
+      if (!usage.isFullyInvoked) {
+        Iterable<CallStructure> callStructures =
+            _getInvocationCallStructures(member);
+        for (CallStructure callStructure in callStructures) {
+          useSet.addAll(usage.invoke(callStructure));
+          if (usage.isFullyInvoked) {
+            break;
+          }
+        }
       }
       if (!usage.hasWrite && hasInvokedSetter(member)) {
         useSet.addAll(usage.write());
       }
 
-      if (usage.pendingUse.contains(MemberUse.NORMAL)) {
+      if (usage.hasPendingNormalUse) {
         // The element is not yet used. Add it to the list of instance
         // members to still be processed.
         _instanceMembersByName
             .putIfAbsent(memberName, () => new Set<MemberUsage>())
             .add(usage);
       }
-      if (usage.pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)) {
+      if (usage.hasPendingClosurizationUse) {
         // Store the member in [instanceFunctionsByName] to catch
         // getters on the function.
         _instanceFunctionsByName
@@ -888,16 +922,23 @@
       if (!usage.hasRead && _hasInvokedGetter(member)) {
         useSet.addAll(usage.read());
       }
-      if (!usage.hasInvoke && _hasInvocation(member)) {
-        useSet.addAll(usage.invoke());
+      if (!usage.isFullyInvoked) {
+        Iterable<CallStructure> callStructures =
+            _getInvocationCallStructures(member);
+        for (CallStructure callStructure in callStructures) {
+          useSet.addAll(usage.invoke(callStructure));
+          if (usage.isFullyInvoked) {
+            break;
+          }
+        }
       }
       if (!usage.hasWrite && hasInvokedSetter(member)) {
         useSet.addAll(usage.write());
       }
-      if (!usage.pendingUse.contains(MemberUse.NORMAL)) {
+      if (!usage.hasPendingNormalUse) {
         _instanceMembersByName[memberName]?.remove(usage);
       }
-      if (!usage.pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)) {
+      if (!usage.hasPendingClosurizationUse) {
         _instanceFunctionsByName[memberName]?.remove(usage);
       }
       memberUsed(usage.entity, useSet);
@@ -1027,6 +1068,22 @@
     BackendUsage backendUsage = _backendUsageBuilder.close();
     _closed = true;
 
+    Map<MemberEntity, MemberUsage> liveMemberUsage = {};
+    _memberUsage.forEach((MemberEntity member, MemberUsage memberUsage) {
+      if (memberUsage.hasUse) {
+        liveMemberUsage[member] = memberUsage;
+        assert(_processedMembers.contains(member),
+            "Member $member is used but not processed: $memberUsage.");
+      } else {
+        assert(!_processedMembers.contains(member),
+            "Member $member is processed but not used: $memberUsage.");
+      }
+    });
+    for (MemberEntity member in _processedMembers) {
+      assert(_memberUsage.containsKey(member),
+          "Member $member is processed but has not usage.");
+    }
+
     KClosedWorld closedWorld = new KClosedWorldImpl(_elementMap,
         options: _options,
         elementEnvironment: _elementEnvironment,
@@ -1043,11 +1100,11 @@
         liveNativeClasses: _nativeResolutionEnqueuer.liveNativeClasses,
         liveInstanceMembers: _liveInstanceMembers,
         assignedInstanceMembers: computeAssignedInstanceMembers(),
-        processedMembers: _processedMembers,
+        liveMemberUsage: liveMemberUsage,
         mixinUses: _classHierarchyBuilder.mixinUses,
         typesImplementedBySubclasses: typesImplementedBySubclasses,
         classHierarchy: _classHierarchyBuilder.close(),
-        annotationsData: _annotationsDataBuilder);
+        annotationsData: _annotationsDataBuilder.close());
     if (retainDataForTesting) {
       _closedWorldCache = closedWorld;
     }
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 9ba793f..ab3ffbb 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -64,13 +64,7 @@
       sb.write('>');
     }
     if (selector.isCall) {
-      sb.write('(');
-      sb.write(selector.callStructure.positionalArgumentCount);
-      if (selector.callStructure.namedArgumentCount > 0) {
-        sb.write(',');
-        sb.write(selector.callStructure.getOrderedNamedArguments().join(','));
-      }
-      sb.write(')');
+      sb.write(selector.callStructure.shortText);
     } else if (selector.isSetter) {
       sb.write('=');
     }
@@ -161,7 +155,6 @@
   GET,
   SET,
   INIT,
-  REFLECT,
 }
 
 /// Statically known use of an [Entity].
@@ -249,6 +242,11 @@
             element,
             "Static invoke element $element must be a top-level "
             "or static method."));
+    assert(
+        callStructure != null,
+        failedAt(element,
+            "Not CallStructure for static invocation of element $element."));
+
     return new GenericStaticUse(element, StaticUseKind.INVOKE, callStructure,
         typeArguments, deferredImport);
   }
@@ -322,6 +320,10 @@
         element.isInstanceMember,
         failedAt(element,
             "Super invoke element $element must be an instance method."));
+    assert(
+        callStructure != null,
+        failedAt(element,
+            "Not CallStructure for super invocation of element $element."));
     return new GenericStaticUse(
         element, StaticUseKind.INVOKE, callStructure, typeArguments);
   }
@@ -380,6 +382,12 @@
             element,
             "Constructor invoke element $element must be a "
             "generative constructor."));
+    assert(
+        callStructure != null,
+        failedAt(
+            element,
+            "Not CallStructure for super constructor invocation of element "
+            "$element."));
     return new StaticUse.internal(element, StaticUseKind.INVOKE,
         callStructure: callStructure);
   }
@@ -388,6 +396,12 @@
   /// constructor call with the given [callStructure].
   factory StaticUse.constructorBodyInvoke(
       ConstructorBodyEntity element, CallStructure callStructure) {
+    assert(
+        callStructure != null,
+        failedAt(
+            element,
+            "Not CallStructure for constructor body invocation of element "
+            "$element."));
     return new StaticUse.internal(element, StaticUseKind.INVOKE,
         callStructure: callStructure);
   }
@@ -395,7 +409,8 @@
   /// Direct invocation of a generator (body) [element], as a static call or
   /// through a this or super constructor call.
   factory StaticUse.generatorBodyInvoke(FunctionEntity element) {
-    return new StaticUse.internal(element, StaticUseKind.INVOKE);
+    return new StaticUse.internal(element, StaticUseKind.INVOKE,
+        callStructure: CallStructure.NO_ARGS);
   }
 
   /// Direct invocation of a method [element] with the given [callStructure].
@@ -442,6 +457,12 @@
         element.isConstructor,
         failedAt(element,
             "Constructor invocation element $element must be a constructor."));
+    assert(
+        callStructure != null,
+        failedAt(
+            element,
+            "Not CallStructure for constructor invocation of element "
+            "$element."));
     return new StaticUse.internal(element, StaticUseKind.INVOKE,
         callStructure: callStructure);
   }
@@ -547,15 +568,11 @@
     return new StaticUse.internal(method, StaticUseKind.CALL_METHOD);
   }
 
-  /// Use of [element] through reflection.
-  factory StaticUse.mirrorUse(MemberEntity element) {
-    return new StaticUse.internal(element, StaticUseKind.REFLECT);
-  }
-
   /// Implicit method/constructor invocation of [element] created by the
   /// backend.
   factory StaticUse.implicitInvoke(FunctionEntity element) {
-    return new StaticUse.internal(element, StaticUseKind.INVOKE);
+    return new StaticUse.internal(element, StaticUseKind.INVOKE,
+        callStructure: element.parameterStructure.callStructure);
   }
 
   /// Inlining of [element].
diff --git a/pkg/compiler/lib/src/util/enumset.dart b/pkg/compiler/lib/src/util/enumset.dart
index 97df1a4..e292aa6 100644
--- a/pkg/compiler/lib/src/util/enumset.dart
+++ b/pkg/compiler/lib/src/util/enumset.dart
@@ -54,6 +54,12 @@
     return new EnumSet.fromValue(value & other.value);
   }
 
+  /// Returns a new set containing all values either in this set or in the
+  /// [other] set.
+  EnumSet<E> union(EnumSet<E> other) {
+    return new EnumSet.fromValue(value | other.value);
+  }
+
   /// Returns a new set containing all values in this set that are not in the
   /// [other] set.
   EnumSet<E> minus(EnumSet<E> other) {
diff --git a/pkg/compiler/lib/src/util/features.dart b/pkg/compiler/lib/src/util/features.dart
index 5263b40..d0547d3 100644
--- a/pkg/compiler/lib/src/util/features.dart
+++ b/pkg/compiler/lib/src/util/features.dart
@@ -62,12 +62,15 @@
     return sb.toString();
   }
 
+  String toString() => 'Features(${getText()})';
+
   /// Creates a [Features] object by parse the [text] encoding.
   ///
   /// Single features will be parsed as strings and list features (features
   /// encoded in `[...]` will be parsed as lists of strings.
   static Features fromText(String text) {
     Features features = new Features();
+    if (text == null) return features;
     int index = 0;
     while (index < text.length) {
       int eqPos = text.indexOf('=', index);
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 0ed8695..b674a0b 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -31,6 +31,7 @@
 import 'js_model/locals.dart';
 import 'js_emitter/sorter.dart';
 import 'universe/class_hierarchy.dart';
+import 'universe/member_usage.dart';
 import 'universe/selector.dart' show Selector;
 
 /// Common superinterface for [OpenWorld] and [JClosedWorld].
@@ -201,6 +202,8 @@
   /// Returns the single [MemberEntity] that matches a call to [selector] on the
   /// [receiver]. If multiple targets exist, `null` is returned.
   MemberEntity locateSingleMember(Selector selector, AbstractValue receiver);
+
+  Iterable<FieldEntity> get elidedFields;
 }
 
 abstract class OpenWorld implements World {
@@ -249,7 +252,7 @@
   Iterable<MemberEntity> get assignedInstanceMembers;
 
   Iterable<ClassEntity> get liveNativeClasses;
-  Iterable<MemberEntity> get processedMembers;
+  Map<MemberEntity, MemberUsage> get liveMemberUsage;
   RuntimeTypesNeed get rtiNeed;
   NoSuchMethodData get noSuchMethodData;
 
diff --git a/pkg/dartfix/CHANGELOG.md b/pkg/dartfix/CHANGELOG.md
index 6fcede0..153554b 100644
--- a/pkg/dartfix/CHANGELOG.md
+++ b/pkg/dartfix/CHANGELOG.md
@@ -1,3 +1,10 @@
+# 0.1.5
+* add command line options for selecting/excluding fixes to apply
+* add experimental NNBD migration support
+
+# 0.1.4
+ * update protocol version constraints
+
 # 0.1.3
  * update SDK constraints
 
diff --git a/pkg/dartfix/README.md b/pkg/dartfix/README.md
index 45f61cb..43ed757 100644
--- a/pkg/dartfix/README.md
+++ b/pkg/dartfix/README.md
@@ -1,8 +1,5 @@
-The `dartfix` tool is a command-line interface
-for making automated updates to your Dart code.
-The tool isn't in the Dart SDK;
-instead, it's distributed in the [`dartfix` package.][dartfix]
-
+`dartfix` is a command-line tool for migrating your Dart code
+to use newer syntax styles.
 
 ## Usage
 
@@ -24,13 +21,21 @@
 ```
 
 ## Features
+`dartfix` applies different types of "fixes" to migrate your Dart code.
+By default, all fixes are applied, but you can select only the specific fixes you
+want. See `dartfix --help` for more about the available command line options.
 
-As of release 0.1.3, `dartfix` can make the following changes to your code:
+Some of the fixes that you can apply are "required" in that the Dart language
+is changing and at some point the old syntax will no longer be supported.
+To only apply these changes, pass the `--required` option on the command line.
+The required fixes include:
 
-* Convert code to use the following [features added to Dart in 2.1][]:
-  * Find classes used as mixins, and convert them to use the `mixin` keyword
+* Find classes used as mixins, and convert them to use the `mixin` keyword
     instead of `class`.
-  * Find `double` literals that end in `.0`, and remove the `.0`.
+    Mixin support is one of the [features added to Dart in 2.1][].
+    At some point in the future, the Dart team plans
+    to disallow using classes as mixins.
+
 * Move named constructor type arguments from the name to the type. <br>
   For example, given `class A<T> { A.from(Object obj) { } }`,
   `dartfix` changes constructor invocations in the following way:
@@ -43,6 +48,11 @@
   A<String>.from(anObject) // Same, but the type is directly after `A`.
   ```
 
+Other changes are recommended but not required. These include:
+
+* Find `double` literals that end in `.0`, and remove the `.0`.
+  Language support for this was [added in Dart in 2.1][].
+
 ## Installing and updating dartfix
 
 The easiest way to use `dartfix` is to [globally install][] it,
@@ -56,27 +66,6 @@
 We recommend updating `dartfix` whenever you update your Dart SDK
 or when a new feature is released.
 
-## Options
-
-<dl>
-  <dt><code>--[no-]color</code></dt>
-  <dd> Use colors when printing messages. On by default. </dd>
-
-  <dt><code>-f, --force</code></dt>
-  <dd>Apply the recommended changes even if the input code has errors.
-  </dd>
-
-  <dt><code>-h, --help</code></dt>
-  <dd>See a complete list of `dartfix` options.</dd>
-
-  <dt><code>-v, --verbose</code></dt>
-  <dd>Verbose output.</dd>
-
-  <dt><code>-w, --overwrite</code></dt>
-  <dd>Apply the recommended changes.</dd>
-</dl>
-
-
 ## Filing issues
 
 If you want a new fix, first look at [dartfix issues][]
@@ -85,6 +74,7 @@
 
 [dartfix]: https://pub.dartlang.org/packages/dartfix
 [dartfmt]: https://www.dartlang.org/tools/dartfmt
+[added in Dart in 2.1]: https://github.com/dart-lang/sdk/blob/master/CHANGELOG.md#210---2018-11-15
 [features added to Dart in 2.1]: https://github.com/dart-lang/sdk/blob/master/CHANGELOG.md#210---2018-11-15
 [globally install]: https://www.dartlang.org/tools/pub/cmd/pub-global
 [new issue]: https://github.com/dart-lang/sdk/issues/new?title=dartfix%20request%3A%20%3CSUMMARIZE%20REQUEST%20HERE%3E
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index 1ccc556..ba7cea7 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -19,8 +19,6 @@
 import 'package:pub_semver/pub_semver.dart';
 
 class Driver {
-  static final expectedProtocolVersion = new Version.parse('1.21.1');
-
   Context context;
   _Handler handler;
   Logger logger;
@@ -48,10 +46,15 @@
     if (!await startServer(options)) {
       context.exit(15);
     }
-
     try {
-      final progress = await setupAnalysis(options);
-      result = await requestFixes(options, progress);
+      if (checkSupported(options)) {
+        if (options.listFixes) {
+          await showListOfFixes();
+        } else {
+          final progress = await setupAnalysis(options);
+          result = await requestFixes(options, progress);
+        }
+      }
     } finally {
       await server.stop();
     }
@@ -80,6 +83,39 @@
     return handler.serverConnected(timeLimit: const Duration(seconds: 15));
   }
 
+  /// Check if the specified options is supported by the version of analysis
+  /// server being run and return `true` if they are.
+  /// Display an error message and return `false` if not.
+  bool checkSupported(Options options) {
+    if (handler.serverProtocolVersion.compareTo(new Version(1, 22, 2)) >= 0) {
+      return true;
+    }
+    if (options.excludeFixes.isNotEmpty) {
+      unsupportedOption(excludeOption);
+      return false;
+    }
+    if (options.includeFixes.isNotEmpty) {
+      unsupportedOption(includeOption);
+      return false;
+    }
+    if (options.listFixes) {
+      unsupportedOption(listOption);
+      return false;
+    }
+    if (options.requiredFixes) {
+      unsupportedOption(requiredOption);
+      return false;
+    }
+    return true;
+  }
+
+  void unsupportedOption(String option) {
+    final version = handler.serverProtocolVersion.toString();
+    logger.stderr('''
+The --$option option is not supported by analysis server version $version.
+Please upgrade to a newer version of the Dart SDK to use this option.''');
+  }
+
   Future<Progress> setupAnalysis(Options options) async {
     final progress = logger.progress('${ansi.emphasized('Calculating fixes')}');
     logger.trace('');
@@ -99,8 +135,19 @@
       Options options, Progress progress) async {
     logger.trace('Requesting fixes');
     Future isAnalysisComplete = handler.analysisComplete();
-    Map<String, dynamic> json = await server.send(
-        EDIT_REQUEST_DARTFIX, new EditDartfixParams(options.targets).toJson());
+
+    final params = new EditDartfixParams(options.targets);
+    if (options.excludeFixes.isNotEmpty) {
+      params.excludedFixes = options.excludeFixes;
+    }
+    if (options.includeFixes.isNotEmpty) {
+      params.includedFixes = options.includeFixes;
+    }
+    if (options.requiredFixes) {
+      params.includeRequiredFixes = true;
+    }
+    Map<String, dynamic> json =
+        await server.send(EDIT_REQUEST_DARTFIX, params.toJson());
 
     // TODO(danrubel): This is imprecise signal for determining when all
     // analysis error notifications have been received. Consider adding a new
@@ -186,6 +233,39 @@
     }
     return filePath;
   }
+
+  showListOfFixes() async {
+    final progress =
+        logger.progress('${ansi.emphasized('Getting list of fixes')}');
+    logger.trace('');
+    Map<String, dynamic> json = await server.send(
+        EDIT_REQUEST_GET_DARTFIX_INFO, new EditGetDartfixInfoParams().toJson());
+
+    progress.finish(showTiming: true);
+    ResponseDecoder decoder = new ResponseDecoder(null);
+    final result = EditGetDartfixInfoResult.fromJson(decoder, 'result', json);
+
+    final fixes = new List<DartFix>.from(result.fixes)
+      ..sort((f1, f2) => f1.name.compareTo(f2.name));
+
+    for (DartFix fix in fixes) {
+      String line = fix.name;
+      if (fix.isRequired == true) {
+        line = '$line (required)';
+      }
+      logger.stdout('');
+      logger.stdout(line);
+      if (fix.description != null) {
+        for (String line in indentAndWrapDescription(fix.description)) {
+          logger.stdout(line);
+        }
+      }
+    }
+    return result;
+  }
+
+  List<String> indentAndWrapDescription(String description) =>
+      description.split('\n').map((line) => '    $line').toList();
 }
 
 class _Listener with ServerListener, BadMessageListener {
@@ -207,21 +287,29 @@
   final Driver driver;
   final Logger logger;
   final Server server;
+  Version serverProtocolVersion;
 
   _Handler(this.driver)
       : logger = driver.logger,
         server = driver.server;
 
   @override
+  bool checkServerProtocolVersion(Version version) {
+    serverProtocolVersion = version;
+    return super.checkServerProtocolVersion(version);
+  }
+
+  @override
   void onFailedToConnect() {
     logger.stderr('Failed to connect to server');
   }
 
   @override
   void onProtocolNotSupported(Version version) {
-    logger.stderr('Expected protocol version ${Driver.expectedProtocolVersion},'
+    logger.stderr('Expected protocol version $PROTOCOL_VERSION,'
         ' but found $version');
-    if (version > Driver.expectedProtocolVersion) {
+    final expectedVersion = Version.parse(PROTOCOL_VERSION);
+    if (version > expectedVersion) {
       logger.stdout('''
 This version of dartfix is incompatible with the current Dart SDK. 
 Try installing a newer version of dartfix by running
@@ -240,14 +328,6 @@
   }
 
   @override
-  bool checkServerProtocolVersion(Version version) {
-    // This overrides the default protocol version check to be more narrow
-    // because the edit.dartfix protocol is experimental
-    // and will continue to evolve.
-    return version == Driver.expectedProtocolVersion;
-  }
-
-  @override
   void onServerError(ServerErrorParams params) {
     if (params.isFatal) {
       logger.stderr('Fatal Server Error: ${params.message}');
diff --git a/pkg/dartfix/lib/src/options.dart b/pkg/dartfix/lib/src/options.dart
index 2353b66..a9af28e 100644
--- a/pkg/dartfix/lib/src/options.dart
+++ b/pkg/dartfix/lib/src/options.dart
@@ -16,23 +16,49 @@
 
   List<String> targets;
   final String sdkPath;
+
+  final bool requiredFixes;
+  final List<String> includeFixes;
+  final List<String> excludeFixes;
+
   final bool force;
+  final bool listFixes;
   final bool overwrite;
-  final bool verbose;
   final bool useColor;
+  final bool verbose;
 
   static Options parse(List<String> args, {Context context, Logger logger}) {
     final parser = new ArgParser(allowTrailingOptions: true)
+      ..addSeparator('Choosing fixes to be applied:')
+      ..addMultiOption(includeOption,
+          abbr: 'i', help: 'Include a specific fix.', valueHelp: 'name-of-fix')
+      ..addMultiOption(excludeOption,
+          abbr: 'x', help: 'Exclude a specific fix.', valueHelp: 'name-of-fix')
+      ..addFlag(requiredOption,
+          abbr: 'r',
+          help: 'Apply required fixes.',
+          defaultsTo: false,
+          negatable: false)
+      ..addFlag(listOption,
+          abbr: 'l',
+          help: 'Display a list of fixes that can be applied.',
+          defaultsTo: false,
+          negatable: false)
+      ..addSeparator('Modifying files:')
       ..addFlag(overwriteOption,
           abbr: 'w',
-          help: 'Overwrite files with the recommended changes.',
+          help: 'Overwrite files with the changes.',
           defaultsTo: false,
           negatable: false)
       ..addFlag(forceOption,
           abbr: 'f',
-          help: 'Apply the recommended changes even if there are errors.',
+          help: 'Overwrite files even if there are errors.',
           defaultsTo: false,
           negatable: false)
+      ..addSeparator('Miscelaneous:')
+      ..addFlag(_colorOption,
+          help: 'Use ansi colors when printing messages.',
+          defaultsTo: Ansi.terminalSupportsAnsi)
       ..addFlag(_helpOption,
           abbr: 'h',
           help: 'Display this help message.',
@@ -42,10 +68,7 @@
           abbr: 'v',
           defaultsTo: false,
           help: 'Verbose output.',
-          negatable: false)
-      ..addFlag('color',
-          help: 'Use ansi colors when printing messages.',
-          defaultsTo: Ansi.terminalSupportsAnsi);
+          negatable: false);
 
     context ??= new Context();
 
@@ -80,6 +103,11 @@
       context.exit(1);
     }
 
+    if (options.listFixes) {
+      _showUsage(parser, logger, showListHint: false);
+      return options;
+    }
+
     // Validate the Dart SDK location
     String sdkPath = options.sdkPath;
     if (sdkPath == null) {
@@ -126,12 +154,20 @@
   }
 
   Options._fromArgs(this.context, ArgResults results)
-      : targets = results.rest,
-        force = results[forceOption] as bool,
+      : force = results[forceOption] as bool,
+        includeFixes =
+            (results[includeOption] as List ?? []).cast<String>().toList(),
+        excludeFixes =
+            (results[excludeOption] as List ?? []).cast<String>().toList(),
+        listFixes = results[listOption] as bool,
         overwrite = results[overwriteOption] as bool,
-        verbose = results[_verboseOption] as bool,
-        useColor = results.wasParsed('color') ? results['color'] as bool : null,
-        sdkPath = _getSdkPath();
+        requiredFixes = results[requiredOption] as bool,
+        sdkPath = _getSdkPath(),
+        targets = results.rest,
+        useColor = results.wasParsed(_colorOption)
+            ? results[_colorOption] as bool
+            : null,
+        verbose = results[_verboseOption] as bool;
 
   String makeAbsoluteAndNormalize(String target) {
     if (!path.isAbsolute(target)) {
@@ -146,15 +182,34 @@
         : path.dirname(path.dirname(Platform.resolvedExecutable));
   }
 
-  static _showUsage(ArgParser parser, Logger logger) {
+  static _showUsage(ArgParser parser, Logger logger,
+      {bool showListHint = true}) {
     logger.stderr('Usage: $_binaryName [options...] <directory paths>');
     logger.stderr('');
     logger.stderr(parser.usage);
+    logger.stderr('''
+
+If neither --$includeOption nor --$requiredOption is specified, then all fixes
+will be applied. Any fixes specified using --$excludeOption will not be applied
+regardless of whether they are required or specifed using --$includeOption.''');
+    if (showListHint) {
+      logger.stderr('''
+
+Use --list to display the fixes that can be specified
+using either --$includeOption or --$excludeOption.''');
+    }
   }
 }
 
 const _binaryName = 'dartfix';
+const _colorOption = 'color';
 const forceOption = 'force';
 const _helpOption = 'help';
 const overwriteOption = 'overwrite';
 const _verboseOption = 'verbose';
+
+// options only supported by server 1.22.2 and greater
+const excludeOption = 'exclude';
+const includeOption = 'include';
+const listOption = 'list';
+const requiredOption = 'required';
diff --git a/pkg/dartfix/pubspec.yaml b/pkg/dartfix/pubspec.yaml
index dac0629..88c9dfc 100644
--- a/pkg/dartfix/pubspec.yaml
+++ b/pkg/dartfix/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dartfix
-version: 0.1.3
+version: 0.1.5-dev
 author: Dart Team <misc@dartlang.org>
 description:
   A tool for migrating Dart source to newer versions of the Dart SDK,
@@ -12,7 +12,7 @@
 dependencies:
   # pin to an exact version of analysis_server_client because the edit.dartfix protocol
   # is experimental and will continue to evolve
-  analysis_server_client: 1.1.1
+  analysis_server_client: 1.1.2
   args: ^1.4.0
   cli_util: ^0.1.3
   path: ^1.6.0
diff --git a/pkg/dartfix/test/all.dart b/pkg/dartfix/test/all.dart
index 8fea855..010f047 100644
--- a/pkg/dartfix/test/all.dart
+++ b/pkg/dartfix/test/all.dart
@@ -4,10 +4,20 @@
 
 import 'package:test/test.dart';
 
+import 'src/client_version_test.dart' as client_version_test;
+import 'src/driver_exclude_test.dart' as driver_exclude_test;
+import 'src/driver_include_test.dart' as driver_include_test;
+import 'src/driver_list_test.dart' as driver_list_test;
+import 'src/driver_required_test.dart' as driver_required_test;
 import 'src/driver_test.dart' as driver_test;
 import 'src/options_test.dart' as options_test;
 
 main() {
+  client_version_test.main();
+  group('driver', driver_exclude_test.main);
+  group('driver', driver_include_test.main);
+  group('driver', driver_list_test.main);
+  group('driver', driver_required_test.main);
   group('driver', driver_test.main);
   group('options', options_test.main);
 }
diff --git a/pkg/dartfix/test/src/client_version_test.dart b/pkg/dartfix/test/src/client_version_test.dart
new file mode 100644
index 0000000..790e48b
--- /dev/null
+++ b/pkg/dartfix/test/src/client_version_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+import 'test_context.dart';
+
+main() {
+  test('client version', () {
+    // The edit.dartfix protocol is experimental and will continue to evolve
+    // an so dartfix will only work with this specific version of the
+    // analysis_server_client package.
+    // If the protocol changes, then a new version of both the
+    // analysis_server_client and dartfix packages must be published.
+    expect(clientVersion, clientVersionInDartfixPubspec);
+  });
+}
+
+String get clientVersion =>
+    findValue(findFile('pkg/analysis_server_client/pubspec.yaml'), 'version');
+
+String get clientVersionInDartfixPubspec =>
+    findValue(findFile('pkg/dartfix/pubspec.yaml'), 'analysis_server_client');
diff --git a/pkg/dartfix/test/src/driver_exclude_test.dart b/pkg/dartfix/test/src/driver_exclude_test.dart
new file mode 100644
index 0000000..7cb2020
--- /dev/null
+++ b/pkg/dartfix/test/src/driver_exclude_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:dartfix/src/driver.dart';
+import 'package:test/test.dart';
+
+import 'test_context.dart';
+
+const _debug = false;
+
+main() {
+  File exampleFile;
+  Directory exampleDir;
+
+  test('exclude fix', () async {
+    exampleFile = findFile('pkg/dartfix/example/example.dart');
+    exampleDir = exampleFile.parent;
+
+    final driver = new Driver();
+    final testContext = new TestContext();
+    final testLogger = new TestLogger();
+    String exampleSource = await exampleFile.readAsString();
+
+    await driver.start(['-xuse-mixin', exampleDir.path],
+        testContext: testContext, testLogger: testLogger);
+    if (_debug) {
+      print(testLogger.stderrBuffer.toString());
+      print(testLogger.stdoutBuffer.toString());
+      print('--- original example');
+      print(exampleSource);
+    }
+
+    final suggestions = driver.result.suggestions;
+    expect(suggestions, hasLength(1));
+    expectDoesNotHaveSuggestion(suggestions, 'Convert MyMixin to a mixin');
+    expectHasSuggestion(suggestions, 'Replace a double literal');
+  });
+}
diff --git a/pkg/dartfix/test/src/driver_include_test.dart b/pkg/dartfix/test/src/driver_include_test.dart
new file mode 100644
index 0000000..d25e710
--- /dev/null
+++ b/pkg/dartfix/test/src/driver_include_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:dartfix/src/driver.dart';
+import 'package:test/test.dart';
+
+import 'test_context.dart';
+
+const _debug = false;
+
+main() {
+  File exampleFile;
+  Directory exampleDir;
+
+  test('include fix', () async {
+    exampleFile = findFile('pkg/dartfix/example/example.dart');
+    exampleDir = exampleFile.parent;
+
+    final driver = new Driver();
+    final testContext = new TestContext();
+    final testLogger = new TestLogger();
+    String exampleSource = await exampleFile.readAsString();
+
+    await driver.start(['-iuse-mixin', exampleDir.path],
+        testContext: testContext, testLogger: testLogger);
+    if (_debug) {
+      print(testLogger.stderrBuffer.toString());
+      print(testLogger.stdoutBuffer.toString());
+      print('--- original example');
+      print(exampleSource);
+    }
+
+    final suggestions = driver.result.suggestions;
+    expect(suggestions, hasLength(1));
+    expectHasSuggestion(suggestions, 'Convert MyMixin to a mixin');
+    expectDoesNotHaveSuggestion(suggestions, 'Replace a double literal');
+  });
+}
diff --git a/pkg/dartfix/test/src/driver_list_test.dart b/pkg/dartfix/test/src/driver_list_test.dart
new file mode 100644
index 0000000..372c98b
--- /dev/null
+++ b/pkg/dartfix/test/src/driver_list_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:dartfix/src/driver.dart';
+import 'package:test/test.dart';
+
+import 'test_context.dart';
+
+main() {
+  test('list fixes', () async {
+    final driver = new Driver();
+    final testContext = new TestContext();
+    final testLogger = new TestLogger();
+    await driver.start(['--list'], // list fixes
+        testContext: testContext,
+        testLogger: testLogger);
+    final errText = testLogger.stderrBuffer.toString();
+    final outText = testLogger.stdoutBuffer.toString();
+    print(errText);
+    print(outText);
+    expect(outText, contains('use-mixin'));
+  });
+}
diff --git a/pkg/dartfix/test/src/driver_required_test.dart b/pkg/dartfix/test/src/driver_required_test.dart
new file mode 100644
index 0000000..408cbbf
--- /dev/null
+++ b/pkg/dartfix/test/src/driver_required_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:dartfix/src/driver.dart';
+import 'package:test/test.dart';
+
+import 'test_context.dart';
+
+const _debug = false;
+
+main() {
+  test('required fixes', () async {
+    File exampleFile;
+    Directory exampleDir;
+
+    exampleFile = findFile('pkg/dartfix/example/example.dart');
+    exampleDir = exampleFile.parent;
+
+    final driver = new Driver();
+    final testContext = new TestContext();
+    final testLogger = new TestLogger();
+    String exampleSource = await exampleFile.readAsString();
+
+    await driver.start(['-r', exampleDir.path],
+        testContext: testContext, testLogger: testLogger);
+    if (_debug) {
+      print(testLogger.stderrBuffer.toString());
+      print(testLogger.stdoutBuffer.toString());
+      print('--- original example');
+      print(exampleSource);
+    }
+
+    final suggestions = driver.result.suggestions;
+    expect(suggestions, hasLength(1));
+    expectHasSuggestion(suggestions, 'Convert MyMixin to a mixin');
+    expectDoesNotHaveSuggestion(suggestions, 'Replace a double literal');
+  });
+}
diff --git a/pkg/dartfix/test/src/driver_test.dart b/pkg/dartfix/test/src/driver_test.dart
index 1aa5493..f84e20b 100644
--- a/pkg/dartfix/test/src/driver_test.dart
+++ b/pkg/dartfix/test/src/driver_test.dart
@@ -6,12 +6,11 @@
 
 import 'package:analysis_server_client/protocol.dart';
 import 'package:dartfix/src/driver.dart';
-import 'package:pub_semver/pub_semver.dart';
 import 'package:test/test.dart';
 
 import 'test_context.dart';
 
-const _debug = true;
+const _debug = false;
 const _updateExample = false;
 
 main() {
@@ -25,23 +24,6 @@
     exampleDir = exampleFile.parent;
   });
 
-  test('protocol version', () {
-    // The edit.dartfix protocol is experimental and will continue to evolve
-    // an so dartfix will only work with this specific version of the protocol.
-    // If the protocol changes, then a new version of both the
-    // analysis_server_client and dartfix packages must be published.
-    expect(new Version.parse(PROTOCOL_VERSION), Driver.expectedProtocolVersion);
-  });
-
-  test('client version', () {
-    // The edit.dartfix protocol is experimental and will continue to evolve
-    // an so dartfix will only work with this specific version of the
-    // analysis_server_client package.
-    // If the protocol changes, then a new version of both the
-    // analysis_server_client and dartfix packages must be published.
-    expect(clientVersion, clientVersionInDartfixPubspec);
-  });
-
   test('fix example', () async {
     final driver = new Driver();
     final testContext = new TestContext();
@@ -107,47 +89,6 @@
   });
 }
 
-String get clientVersion =>
-    findValue(findFile('pkg/analysis_server_client/pubspec.yaml'), 'version');
-
-String get clientVersionInDartfixPubspec =>
-    findValue(findFile('pkg/dartfix/pubspec.yaml'), 'analysis_server_client');
-
-File findFile(String relPath) {
-  Directory dir = Directory.current;
-  while (true) {
-    final file = new File.fromUri(dir.uri.resolve(relPath));
-    if (file.existsSync()) {
-      return file;
-    }
-    final parent = dir.parent;
-    if (parent.path == dir.path) {
-      fail('Failed to find $relPath');
-    }
-    dir = parent;
-  }
-}
-
-String findValue(File pubspec, String key) {
-  List<String> lines = pubspec.readAsLinesSync();
-  for (String line in lines) {
-    if (line.trim().startsWith('$key:')) {
-      return line.split(':')[1].trim();
-    }
-  }
-  fail('Failed to find $key in ${pubspec.path}');
-}
-
-void expectHasSuggestion(
-    List<DartFixSuggestion> suggestions, String expectedText) {
-  for (DartFixSuggestion suggestion in suggestions) {
-    if (suggestion.description.contains(expectedText)) {
-      return;
-    }
-  }
-  fail('Failed to find suggestion containing: $expectedText');
-}
-
 String replaceLeadingComment(String source) {
   final out = new StringBuffer('''
 // This file contains code that has been modified by running dartfix.
diff --git a/pkg/dartfix/test/src/options_test.dart b/pkg/dartfix/test/src/options_test.dart
index 7ce0e1a..971517a 100644
--- a/pkg/dartfix/test/src/options_test.dart
+++ b/pkg/dartfix/test/src/options_test.dart
@@ -24,7 +24,11 @@
     String errorOut,
     int exitCode,
     bool force = false,
+    List<String> includeFixes = const <String>[],
+    List<String> excludeFixes = const <String>[],
+    bool listFixes = false,
     String normalOut,
+    bool requiredFixes = false,
     bool overwrite = false,
     List<String> targetSuffixes,
     bool verbose = false,
@@ -47,7 +51,11 @@
       expect(actualExitCode, isNull, reason: 'exit code');
     }
     expect(options.force, force);
+    expect(options.requiredFixes, requiredFixes);
     expect(options.overwrite, overwrite);
+    expect(options.listFixes, listFixes);
+    expect(options.includeFixes, includeFixes);
+    expect(options.excludeFixes, excludeFixes);
     expect(options.verbose, verbose);
     expect(path.isAbsolute(options.sdkPath), isTrue, reason: options.sdkPath);
     for (String target in options.targets) {
@@ -62,6 +70,11 @@
     return options;
   }
 
+  test('exclude fix', () {
+    parse(['--exclude', 'c', '--exclude', 'd', 'foo'],
+        excludeFixes: ['c', 'd'], targetSuffixes: ['foo']);
+  });
+
   test('force', () {
     parse(['--force', 'foo'], force: true, targetSuffixes: ['foo']);
   });
@@ -70,6 +83,11 @@
     parse(['--help'], errorOut: 'Display this help message', exitCode: 1);
   });
 
+  test('include fix', () {
+    parse(['--include', 'a', '--include', 'b', 'foo'],
+        includeFixes: ['a', 'b'], targetSuffixes: ['foo']);
+  });
+
   test('invalid option', () {
     parse(['--foo'],
         errorOut: 'Could not find an option named "foo"', exitCode: 15);
@@ -89,10 +107,18 @@
         errorOut: 'Expected directory, but found', exitCode: 15);
   });
 
+  test('list fixes', () {
+    parse(['--list'], errorOut: 'Display this help message', listFixes: true);
+  });
+
   test('overwrite', () {
     parse(['--overwrite', 'foo'], overwrite: true, targetSuffixes: ['foo']);
   });
 
+  test('required fixes', () {
+    parse(['--required', 'foo'], requiredFixes: true);
+  });
+
   test('simple', () {
     parse(['foo'], targetSuffixes: ['foo']);
   });
diff --git a/pkg/dartfix/test/src/test_context.dart b/pkg/dartfix/test/src/test_context.dart
index 61faf26..39ab0b3 100644
--- a/pkg/dartfix/test/src/test_context.dart
+++ b/pkg/dartfix/test/src/test_context.dart
@@ -2,9 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
+import 'package:analysis_server_client/protocol.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:cli_util/cli_logging.dart';
 import 'package:dartfix/src/context.dart';
+import 'package:test/test.dart';
 
 class TestContext with ResourceProviderMixin implements Context {
   @override
@@ -26,6 +30,9 @@
   final int code;
 
   TestExit(this.code);
+
+  @override
+  String toString() => 'TestExit($code)';
 }
 
 class TestLogger implements Logger {
@@ -59,3 +66,47 @@
   @override
   void trace(String message) {}
 }
+
+void expectHasSuggestion(
+    List<DartFixSuggestion> suggestions, String expectedText) {
+  for (DartFixSuggestion suggestion in suggestions) {
+    if (suggestion.description.contains(expectedText)) {
+      return;
+    }
+  }
+  fail('Failed to find suggestion containing: $expectedText');
+}
+
+void expectDoesNotHaveSuggestion(
+    List<DartFixSuggestion> suggestions, String expectedText) {
+  for (DartFixSuggestion suggestion in suggestions) {
+    if (suggestion.description.contains(expectedText)) {
+      fail('Did not expect to find suggestion containing: $expectedText');
+    }
+  }
+}
+
+File findFile(String relPath) {
+  Directory dir = Directory.current;
+  while (true) {
+    final file = new File.fromUri(dir.uri.resolve(relPath));
+    if (file.existsSync()) {
+      return file;
+    }
+    final parent = dir.parent;
+    if (parent.path == dir.path) {
+      fail('Failed to find $relPath');
+    }
+    dir = parent;
+  }
+}
+
+String findValue(File pubspec, String key) {
+  List<String> lines = pubspec.readAsLinesSync();
+  for (String line in lines) {
+    if (line.trim().startsWith('$key:')) {
+      return line.split(':')[1].trim();
+    }
+  }
+  fail('Failed to find $key in ${pubspec.path}');
+}
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index d8063b5..54e0f0f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -6420,6 +6420,43 @@
   /// Unused, see [_defineClass].
   @override
   visitWithClause(node) => _unreachable(node);
+
+  @override
+  visitForElement(ForElement node) => _unreachable(node);
+
+  @override
+  visitIfElement(IfElement node) => _unreachable(node);
+
+  @override
+  visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) =>
+      _unreachable(node);
+
+  @override
+  visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) =>
+      _unreachable(node);
+
+  @override
+  visitForStatement2(ForStatement2 node) => _unreachable(node);
+
+  @override
+  visitListLiteral2(ListLiteral2 node) => _unreachable(node);
+
+  @override
+  visitMapLiteral2(MapLiteral2 node) => _unreachable(node);
+
+  @override
+  visitSetLiteral2(SetLiteral2 node) => _unreachable(node);
+
+  @override
+  visitSpreadElement(SpreadElement node) => _unreachable(node);
+
+  @override
+  visitForPartsWithDeclarations(ForPartsWithDeclarations node) =>
+      _unreachable(node);
+
+  @override
+  visitForPartsWithExpression(ForPartsWithExpression node) =>
+      _unreachable(node);
 }
 
 /// Choose a canonical name from the [library] element.
@@ -6439,14 +6476,11 @@
     // TODO(vsm): This is not unique if an escaped '/'appears in a filename.
     // E.g., "foo/bar.dart" and "foo$47bar.dart" would collide.
     qualifiedPath = uri.pathSegments.skip(1).join(encodedSeparator);
-  } else if (path.isWithin(libraryRoot, uri.toFilePath())) {
+  } else {
     qualifiedPath = path
         .relative(uri.toFilePath(), from: libraryRoot)
-        .replaceAll(path.separator, encodedSeparator);
-  } else {
-    // We don't have a unique name.
-    throw 'Invalid library root. $libraryRoot does not contain '
-        '${uri.toFilePath()}';
+        .replaceAll(path.separator, encodedSeparator)
+        .replaceAll('..', encodedSeparator);
   }
   return pathToJSIdentifier(qualifiedPath);
 }
@@ -6458,10 +6492,6 @@
   if (uri.scheme == 'dart' || uri.scheme == 'package') return uri.toString();
 
   var filePath = uri.toFilePath();
-  if (!path.isWithin(libraryRoot, filePath)) {
-    throw 'Invalid library root. $libraryRoot does not contain '
-        '${uri.toFilePath()}';
-  }
   // Relative path to the library.
   return path.relative(filePath, from: libraryRoot);
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
index 5c91caa..917daa3 100644
--- a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -311,7 +311,7 @@
 
       var c = Class(
           name: runningName,
-          isAbstract: e.isAbstract,
+          isAbstract: true,
           mixedInType: mixedInType,
           supertype: supertype,
           typeParameters: typeParameters,
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 035611f..cd0af30e 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5120,12 +5120,6 @@
   @override
   visitPartialInstantiationConstant(node) => defaultConstant(node);
   @override
-  visitEnvironmentBoolConstant(node) => defaultConstant(node);
-  @override
-  visitEnvironmentIntConstant(node) => defaultConstant(node);
-  @override
-  visitEnvironmentStringConstant(node) => defaultConstant(node);
-  @override
   visitUnevaluatedConstant(node) => defaultConstant(node);
 }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/constants.dart b/pkg/dev_compiler/lib/src/kernel/constants.dart
index b05b840..0e9d692 100644
--- a/pkg/dev_compiler/lib/src/kernel/constants.dart
+++ b/pkg/dev_compiler/lib/src/kernel/constants.dart
@@ -14,12 +14,13 @@
 /// [evaluate] computes the value of a constant expression, if available.
 class DevCompilerConstants {
   final _ConstantVisitor _visitor;
-  final _ConstantEvaluator _evaluator;
+  final ConstantEvaluator _evaluator;
 
   DevCompilerConstants(
       TypeEnvironment types, Map<String, String> declaredVariables)
       : _visitor = _ConstantVisitor(types.coreTypes),
-        _evaluator = _ConstantEvaluator(types, declaredVariables);
+        _evaluator = ConstantEvaluator(DevCompilerConstantsBackend(),
+            declaredVariables, types, false, const _ErrorReporter());
 
   /// Determines if an expression is constant.
   bool isConstant(Expression e) => _visitor.isConstant(e);
@@ -36,7 +37,7 @@
 
     try {
       var result = cache ? _evaluator.evaluate(e) : e.accept(_evaluator);
-      return identical(result, _evaluator.unavailableConstant) ? null : result;
+      return result is UnevaluatedConstant ? null : result;
     } on _AbortCurrentEvaluation {
       // TODO(jmesserly): the try+catch is necessary because the front end is
       // not issuing sufficient errors, so the constant evaluation can fail.
@@ -167,147 +168,26 @@
   }
 }
 
-/// The visitor that evaluates constants, building on Kernel's
-/// [ConstantEvaluator] class (used by the VM) and fixing some of its behavior
-/// to work better for DDC.
-//
-// TODO(jmesserly): make some changes in the base class to make it a better fit
-// for compilers like DDC?
-class _ConstantEvaluator extends ConstantEvaluator {
-  final Map<String, String> declaredVariables;
-
-  /// Used to denote an unavailable constant value from another module
-  ///
-  // TODO(jmesserly): this happens when we try to evaluate constant values from
-  // an external library, that was from an outline kernel file. The kernel file
-  // does not contain the initializer value of the constant.
-  final Constant unavailableConstant;
-
-  _ConstantEvaluator(TypeEnvironment types, this.declaredVariables,
-      {bool enableAsserts: false})
-      : unavailableConstant = InstanceConstant(null, [], {}),
-        super(_ConstantsBackend(types.coreTypes), types, types.coreTypes,
-            enableAsserts, const _ErrorReporter()) {
-    env = EvaluationEnvironment();
-  }
+/// Implement the class for compiler specific behavior.
+class DevCompilerConstantsBackend extends ConstantsBackend {
+  DevCompilerConstantsBackend();
 
   @override
-  visitVariableGet(node) {
-    // The base evaluator expects that variable declarations are visited during
-    // the transformation step, so it doesn't handle constant variables.
-    // Instead handle them here.
-    if (node.variable.isConst) {
-      return evaluate(node.variable.initializer);
-    }
-    // Fall back to the base evaluator for other cases (e.g. parameters of a
-    // constant constructor).
-    return super.visitVariableGet(node);
-  }
-
-  @override
-  visitStaticGet(StaticGet node) {
-    // Handle unavailable field constants. This happens if an external library
-    // only has its outline available.
-    var target = node.target;
-    if (target is Field &&
-        target.isConst &&
-        target.isInExternalLibrary &&
-        target.initializer == null) {
-      return unavailableConstant;
-    }
-    return super.visitStaticGet(node);
-  }
-
-  @override
-  visitConstructorInvocation(ConstructorInvocation node) {
-    // Handle unavailable constructor bodies.
-    // This happens if an external library only has its outline available.
-    var target = node.target;
-    if (target.isConst &&
-        target.isInExternalLibrary &&
-        target.function.body is EmptyStatement &&
-        target.initializers.isEmpty) {
-      return unavailableConstant;
-    }
-    return super.visitConstructorInvocation(node);
-  }
-
-  @override
-  visitStaticInvocation(node) {
-    // Handle int/bool/String.fromEnvironment constructors.
-    //
-    // (The VM handles this via its `native` calls and implements it in
-    // VmConstantsBackend.buildConstantForNative.)
-    var target = node.target;
-    if (isFromEnvironmentInvocation(coreTypes, node)) {
-      var firstArg = evaluatePositionalArguments(node.arguments)[0];
-      var defaultArg = evaluateNamedArguments(node.arguments)['defaultValue'];
-
-      var varName = (firstArg as StringConstant).value;
-      var value = declaredVariables[varName];
-      var targetClass = target.enclosingClass;
-
-      if (targetClass == coreTypes.stringClass) {
-        if (value != null) return canonicalize(StringConstant(value));
-        return defaultArg ?? nullConstant;
-      } else if (targetClass == coreTypes.intClass) {
-        var intValue = int.tryParse(value ?? '');
-        if (intValue != null) return canonicalize(IntConstant(intValue));
-        return defaultArg ?? nullConstant;
-      } else if (targetClass == coreTypes.boolClass) {
-        if (value == "true") return trueConstant;
-        if (value == "false") return falseConstant;
-        return defaultArg ?? falseConstant;
-      }
-    }
-    return super.visitStaticInvocation(node);
-  }
-
-  @override
-  evaluateBinaryNumericOperation(String op, num a, num b, TreeNode node) {
-    // Use doubles to match JS number semantics.
-    return super
-        .evaluateBinaryNumericOperation(op, a.toDouble(), b.toDouble(), node);
-  }
-
-  @override
-  canonicalize(Constant constant) {
+  Constant lowerConstant(Constant constant) {
     if (constant is DoubleConstant) {
       // Convert to an integer when possible (matching the runtime behavior
       // of `is int`).
       var d = constant.value;
       if (d.isFinite) {
         var i = d.toInt();
-        if (d == i.toDouble()) return super.canonicalize(IntConstant(i));
+        if (d == i.toDouble()) return IntConstant(i);
       }
     }
-    return super.canonicalize(constant);
-  }
-}
-
-/// Implement the class for compiler specific behavior.
-///
-/// This is mostly unused by DDC, because we don't use the global constant
-/// transformer.
-class _ConstantsBackend implements ConstantsBackend {
-  final CoreTypes coreTypes;
-  final Field symbolNameField;
-
-  _ConstantsBackend(this.coreTypes)
-      : symbolNameField = coreTypes.internalSymbolClass.fields
-            .firstWhere((f) => f.name.name == '_name');
-
-  @override
-  buildConstantForNative(nativeName, typeArguments, positionalArguments,
-      namedArguments, context, node, errorReporter, abortEvaluation) {
-    throw StateError('unreachable'); // DDC does not use VM native syntax
+    return constant;
   }
 
-  @override
-  lowerMapConstant(constant) => constant;
-
-  @override
-  lowerListConstant(constant) => constant;
+  // Use doubles to match JS number semantics.
+  num prepareNumericOperand(num operand) => operand.toDouble();
 }
 
 class _ErrorReporter extends SimpleErrorReporter {
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 8652983..75aedd1 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -8,6 +8,8 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/target/targets.dart';
+import 'package:kernel/transformations/constants.dart' show ConstantsBackend;
+import 'constants.dart' show DevCompilerConstantsBackend;
 import 'kernel_helpers.dart';
 
 /// A kernel [Target] to configure the Dart Front End for dartdevc.
@@ -70,8 +72,12 @@
   bool get enableNoSuchMethodForwarders => true;
 
   @override
-  void performModularTransformationsOnLibraries(Component component,
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+  void performModularTransformationsOnLibraries(
+      Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
       {void logger(String msg)}) {
     this.hierarchy = hierarchy;
     for (var library in libraries) {
@@ -142,6 +148,10 @@
     // TODO(sigmund): implement;
     return InvalidExpression(null);
   }
+
+  @override
+  ConstantsBackend constantsBackend(CoreTypes coreTypes) =>
+      new DevCompilerConstantsBackend();
 }
 
 /// Analyzes a component to determine if any covariance checks in private
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 86d997a..ea33a0b 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -1 +1,20 @@
 name: dev_compiler
+publish_to: none
+
+environment:
+  sdk: '>=2.1.0 <3.0.0'
+
+dependencies:
+  analyzer: any
+  bazel_worker: any
+  build_integration:
+    path: ../build_integration
+  cli_util: any
+  source_maps: any
+
+dev_dependencies:
+  sourcemap_testing:
+    path: ../sourcemap_testing
+  test: any
+  testing:
+    path: ../testing
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 98f39aa..ea3a7a5 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -36,6 +36,10 @@
         help: 'Platform to run on (node|d8|chrome).  Default is node.',
         allowed: ['node', 'd8', 'chrome'],
         defaultsTo: 'node')
+    ..addOption('port',
+        abbr: 'p',
+        help: 'Run with the corresponding chrome/V8 debugging port open.',
+        defaultsTo: '9222')
     ..addOption('binary', abbr: 'b', help: 'Runtime binary path.');
 
   var options = parser.parse(args);
@@ -49,6 +53,7 @@
   var debug = options['debug'] as bool;
   var kernel = options['kernel'] as bool;
   var binary = options['binary'] as String;
+  var port = int.parse(options['port'] as String);
 
   var dartBinary = Platform.resolvedExecutable;
   var dartPath = path.dirname(dartBinary);
@@ -175,8 +180,13 @@
     new File(htmlFile).writeAsStringSync(html);
     var tmp = path.join(Directory.systemTemp.path, 'ddc');
 
-    result = Process.runSync(chromeBinary,
-        ['--auto-open-devtools-for-tabs', '--user-data-dir=$tmp', htmlFile]);
+    result = Process.runSync(chromeBinary, [
+      '--auto-open-devtools-for-tabs',
+      '--allow-file-access-from-files',
+      '--remote-debugging-port=$port',
+      '--user-data-dir=$tmp',
+      htmlFile
+    ]);
   } else if (node) {
     var nodePath = '$sdkJsPath:$libRoot';
     var runjs = '''
@@ -202,8 +212,9 @@
     var nodeFile = '$libRoot/$basename.run.js';
     new File(nodeFile).writeAsStringSync(runjs);
     var nodeBinary = binary ?? 'node';
-    result = Process
-        .runSync(nodeBinary, [nodeFile], environment: {'NODE_PATH': nodePath});
+    result = Process.runSync(
+        nodeBinary, ['--inspect=localhost:$port', nodeFile],
+        environment: {'NODE_PATH': nodePath});
     stdout
       ..write(result.stdout)
       ..flush();
diff --git a/pkg/dev_compiler/tool/input_sdk/libraries.dart b/pkg/dev_compiler/tool/input_sdk/libraries.dart
index 6009d0c..1a08e42 100644
--- a/pkg/dev_compiler/tool/input_sdk/libraries.dart
+++ b/pkg/dev_compiler/tool/input_sdk/libraries.dart
@@ -61,6 +61,11 @@
       categories: "Client,Server,Embedded",
       maturity: Maturity.UNSTABLE,
       dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
+  "ffi": const LibraryInfo("ffi/ffi.dart",
+      categories: "Server",
+      // TODO(dacoharkes): Update maturity when we release dart:ffi.
+      // https://github.com/dart-lang/sdk/issues/34452
+      maturity: Maturity.EXPERIMENTAL),
   "html": const LibraryInfo("html/dart2js/html_dart2js.dart",
       categories: "Client",
       maturity: Maturity.WEB_STABLE,
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
index 983bbcd..fe36fea 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
@@ -5,8 +5,7 @@
 // Patch file for the dart:async library.
 
 import 'dart:_js_helper' show notNull, patch, ReifyFunctionTypes;
-import 'dart:_isolate_helper'
-    show TimerImpl, global, leaveJsAsync, enterJsAsync;
+import 'dart:_isolate_helper' show TimerImpl;
 import 'dart:_foreign_helper' show JS, JSExportName;
 import 'dart:_runtime' as dart;
 
@@ -147,32 +146,30 @@
   static _TakeCallback _initializeScheduleImmediate() {
     // TODO(rnystrom): Not needed by dev_compiler.
     // requiresPreamble();
-    if (JS('', '#.scheduleImmediate', global) != null) {
+    if (JS('', '#.scheduleImmediate', dart.global_) != null) {
       return _scheduleImmediateJsOverride;
     }
-    if (JS('', '#.MutationObserver', global) != null &&
-        JS('', '#.document', global) != null) {
+    if (JS('', '#.MutationObserver', dart.global_) != null &&
+        JS('', '#.document', dart.global_) != null) {
       // Use mutationObservers.
-      var div = JS('', '#.document.createElement("div")', global);
-      var span = JS('', '#.document.createElement("span")', global);
+      var div = JS('', '#.document.createElement("div")', dart.global_);
+      var span = JS('', '#.document.createElement("span")', dart.global_);
       _Callback storedCallback;
 
       internalCallback(_) {
-        leaveJsAsync();
         var f = storedCallback;
         storedCallback = null;
+        dart.removeAsyncCallback();
         f();
       }
 
-      ;
-
       var observer =
-          JS('', 'new #.MutationObserver(#)', global, internalCallback);
+          JS('', 'new #.MutationObserver(#)', dart.global_, internalCallback);
       JS('', '#.observe(#, { childList: true })', observer, div);
 
       return (void callback()) {
         assert(storedCallback == null);
-        enterJsAsync();
+        dart.addAsyncCallback();
         storedCallback = callback;
         // Because of a broken shadow-dom polyfill we have to change the
         // children instead a cheap property.
@@ -180,7 +177,7 @@
         JS('', '#.firstChild ? #.removeChild(#): #.appendChild(#)', div, div,
             span, div, span);
       };
-    } else if (JS('', '#.setImmediate', global) != null) {
+    } else if (JS('', '#.setImmediate', dart.global_) != null) {
       return _scheduleImmediateWithSetImmediate;
     }
     // TODO(20055): We should use DOM promises when available.
@@ -189,24 +186,22 @@
 
   static void _scheduleImmediateJsOverride(void callback()) {
     internalCallback() {
-      leaveJsAsync();
+      dart.removeAsyncCallback();
       callback();
     }
 
-    ;
-    enterJsAsync();
-    JS('void', '#.scheduleImmediate(#)', global, internalCallback);
+    dart.addAsyncCallback();
+    JS('void', '#.scheduleImmediate(#)', dart.global_, internalCallback);
   }
 
   static void _scheduleImmediateWithSetImmediate(void callback()) {
     internalCallback() {
-      leaveJsAsync();
+      dart.removeAsyncCallback();
       callback();
     }
 
-    ;
-    enterJsAsync();
-    JS('void', '#.setImmediate(#)', global, internalCallback);
+    dart.addAsyncCallback();
+    JS('void', '#.setImmediate(#)', dart.global_, internalCallback);
   }
 
   static void _scheduleImmediateWithTimer(void callback()) {
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
index 1d3c216..13c6f64 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
@@ -501,6 +501,14 @@
 }
 
 @patch
+class RawSocketOption {
+  @patch
+  static int _getOptionValue(int key) {
+    throw UnsupportedError("RawSocketOption._getOptionValue");
+  }
+}
+
+@patch
 class SecurityContext {
   @patch
   factory SecurityContext({bool withTrustedRoots = false}) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
index 116464a..5eaff1c 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
@@ -181,3 +181,18 @@
   JS('', '#.clear()', constantMaps);
   JS('', '#.clear()', _ignoreSubtypeCache);
 }
+
+/// Marks enqueuing an async operation.
+///
+/// This will be called by library code when enqueuing an async operation
+/// controlled by the JavaScript event handler.
+///
+/// It will also call [removeAsyncCallback] when Dart callback is about to be
+/// executed (note this is called *before* the callback executes, so more
+/// async operations could be added from that).
+void Function() addAsyncCallback = JS('', 'function() {}');
+
+/// Marks leaving a javascript async operation.
+///
+/// See [addAsyncCallback].
+void Function() removeAsyncCallback = JS('', 'function() {}');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/debugger.dart b/pkg/dev_compiler/tool/input_sdk/private/debugger.dart
index 6ee554b..63849d8 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/debugger.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/debugger.dart
@@ -679,7 +679,11 @@
 
   String preview(object) {
     Map map = object;
-    return '${getObjectTypeName(map)} length ${map.length}';
+    try {
+      return '${getObjectTypeName(map)} length ${map.length}';
+    } catch (e) {
+      return safePreview(object, JsonMLConfig.none);
+    }
   }
 
   List<NameValuePair> children(object) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
index 6de83f2..6f98394 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
@@ -8,27 +8,6 @@
 import 'dart:async';
 import 'dart:_foreign_helper' show JS;
 
-/// Marks entering a JavaScript async operation to keep the worker alive.
-///
-/// To be called by library code before starting an async operation controlled
-/// by the JavaScript event handler.
-///
-/// Also call [leaveJsAsync] in all callback handlers marking the end of that
-/// async operation (also error handlers) so the worker can be released.
-///
-/// These functions only has to be called for code that can be run from a
-/// worker-isolate (so not for general dom operations).
-///
-// TODO(jmesserly): we could potentially use this to track when all async
-// operations have completed, for example, to run a bunch of test `main()`
-// methods in batch mode the same V8 process.
-enterJsAsync() {}
-
-/// Marks leaving a javascript async operation.
-///
-/// See [enterJsAsync].
-leaveJsAsync() {}
-
 /// Deprecated way of initializing `main()` in DDC, typically called from JS.
 @deprecated
 void startRootIsolate(main, args) {
@@ -62,12 +41,12 @@
     if (hasTimer()) {
       void internalCallback() {
         _handle = null;
-        leaveJsAsync();
+        dart.removeAsyncCallback();
         _tick = 1;
         callback();
       }
 
-      enterJsAsync();
+      dart.addAsyncCallback();
 
       _handle = JS(
           'int', '#.setTimeout(#, #)', global, internalCallback, milliseconds);
@@ -79,7 +58,7 @@
   TimerImpl.periodic(int milliseconds, void callback(Timer timer))
       : _once = false {
     if (hasTimer()) {
-      enterJsAsync();
+      dart.addAsyncCallback();
       int start = JS('int', 'Date.now()');
       _handle = JS('int', '#.setInterval(#, #)', global, () {
         int tick = this._tick + 1;
@@ -102,7 +81,7 @@
   void cancel() {
     if (hasTimer()) {
       if (_handle == null) return;
-      leaveJsAsync();
+      dart.removeAsyncCallback();
       if (_once) {
         JS('void', '#.clearTimeout(#)', global, _handle);
       } else {
diff --git a/pkg/expect/lib/matchers_lite.dart b/pkg/expect/lib/matchers_lite.dart
new file mode 100644
index 0000000..004e37e
--- /dev/null
+++ b/pkg/expect/lib/matchers_lite.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// This library is supposed help to remove dependencies on package:test from
+/// an existing test.
+///
+/// Feel free to add more matchers, as long as they remain lite. Batteries
+/// aren't included here. This is intended to be used in low-level platform
+/// tests and shouldn't rely on advanced features such as reflection. Using
+/// asynchronous code is acceptable, but only for testing code that is
+/// *already* asynchronous, but try to avoid using "async" and other generators
+/// (it's hard testing the implemention of generators if the test
+/// infrastructure relies on them itself).
+library expect.matchers_lite;
+
+import "expect.dart" show Expect;
+
+typedef Matcher = void Function(Object actual);
+
+void expect(Object actual, Object expected) {
+  if (expected is Matcher) {
+    expected(actual);
+  } else {
+    equals(expected)(actual);
+  }
+}
+
+Matcher unorderedEquals(Iterable<Object> expected) {
+  return (Object actual) => Expect.setEquals(expected, actual);
+}
+
+fail(String message) {
+  Expect.fail(message);
+}
+
+Matcher same(Object expected) {
+  return (Object actual) => Expect.identical(expected, actual);
+}
+
+Matcher equals(Object expected) {
+  if (expected is String) {
+    return (Object actual) => Expect.stringEquals(expected, actual);
+  } else if (expected is Iterable<Object>) {
+    return (dynamic actual) =>
+        Expect.listEquals(expected.toList(), actual.toList());
+  } else {
+    return (Object actual) => Expect.equals(expected, actual);
+  }
+}
+
+final Matcher isEmpty = (dynamic actual) => Expect.isTrue(actual.isEmpty);
+
+final Matcher isNull = (Object actual) => Expect.isNull(actual);
diff --git a/pkg/front_end/analysis_options.yaml b/pkg/front_end/analysis_options.yaml
index ae13d06..2b7dca6 100644
--- a/pkg/front_end/analysis_options.yaml
+++ b/pkg/front_end/analysis_options.yaml
@@ -8,9 +8,3 @@
   errors:
     # Allow having TODOs in the code
     todo: ignore
-
-    # Allow cross-package deprecated calls
-    # TODO(srawlins): clean these up and remove this "ignore."
-    deprecated_member_use: ignore
-    # Allow deprecated calls from within the same package
-    deprecated_member_use_from_same_package: ignore
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 85222be..e867b2c 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -127,6 +127,12 @@
   /// Features not mentioned in the map will have their default value.
   Map<ExperimentalFlag, bool> experimentalFlags = <ExperimentalFlag, bool>{};
 
+  /// Environment map used when evaluating `bool.fromEnvironment`,
+  /// `int.fromEnvironment` and `String.fromEnvironment` during constant
+  /// evaluation. If the map is `null`, all environment constants will be left
+  /// unevaluated and can be evaluated by a constant evaluator later.
+  Map<String, String> environmentDefines = null;
+
   /// The target platform that will consume the compiled code.
   ///
   /// Used to provide platform-specific details to the compiler like:
@@ -161,8 +167,8 @@
   /// Dumped data is printed in stdout.
   bool debugDump = false;
 
-  /// Whether to exclode the platform when serializing the result from a
-  /// 'fasta compile' run.
+  /// Whether to omit the platform when serializing the result from a `fasta
+  /// compile` run.
   bool omitPlatform = false;
 
   /// Whether to set the exit code to non-zero if any problem (including
diff --git a/pkg/front_end/lib/src/api_prototype/diagnostic_message.dart b/pkg/front_end/lib/src/api_prototype/diagnostic_message.dart
index e34b709..47c30f0 100644
--- a/pkg/front_end/lib/src/api_prototype/diagnostic_message.dart
+++ b/pkg/front_end/lib/src/api_prototype/diagnostic_message.dart
@@ -4,7 +4,8 @@
 
 library front_end.diagnostic_message;
 
-import '../fasta/fasta_codes.dart' show Code, FormattedMessage;
+import '../fasta/fasta_codes.dart'
+    show Code, DiagnosticMessageFromJson, FormattedMessage;
 
 import '../fasta/severity.dart' show Severity;
 
@@ -38,7 +39,19 @@
 
 /// This method is subject to change.
 Uri getMessageUri(DiagnosticMessage message) {
-  return message is FormattedMessage ? message.uri : null;
+  return message is FormattedMessage
+      ? message.uri
+      : message is DiagnosticMessageFromJson ? message.uri : null;
+}
+
+/// This method is subject to change.
+int getMessageCharOffset(DiagnosticMessage message) {
+  return message is FormattedMessage ? message.charOffset : null;
+}
+
+/// This method is subject to change.
+int getMessageLength(DiagnosticMessage message) {
+  return message is FormattedMessage ? message.length : null;
 }
 
 /// This method is subject to change.
@@ -60,3 +73,9 @@
 Map<String, dynamic> getMessageArguments(DiagnosticMessage message) {
   return message is FormattedMessage ? message.arguments : null;
 }
+
+/// This method is subject to change.
+Iterable<DiagnosticMessage> getMessageRelatedInformation(
+    DiagnosticMessage message) {
+  return message is FormattedMessage ? message.relatedInformation : null;
+}
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 1441108..a9b772d 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -5,16 +5,22 @@
 // TODO(askesc): Generate this file from a flag specification.
 
 enum ExperimentalFlag {
-  setLiterals,
   constantUpdate2018,
+  controlFlowCollections,
+  setLiterals,
+  spreadCollections,
 }
 
 ExperimentalFlag parseExperimentalFlag(String flag) {
   switch (flag) {
-    case "set-literals":
-      return ExperimentalFlag.setLiterals;
     case "constant-update-2018":
       return ExperimentalFlag.constantUpdate2018;
+    case "control-flow-collections":
+      return ExperimentalFlag.controlFlowCollections;
+    case "set-literals":
+      return ExperimentalFlag.setLiterals;
+    case "spread-collections":
+      return ExperimentalFlag.spreadCollections;
   }
   return null;
 }
diff --git a/pkg/front_end/lib/src/api_prototype/terminal_color_support.dart b/pkg/front_end/lib/src/api_prototype/terminal_color_support.dart
index 4d866f3..17dcc08 100644
--- a/pkg/front_end/lib/src/api_prototype/terminal_color_support.dart
+++ b/pkg/front_end/lib/src/api_prototype/terminal_color_support.dart
@@ -87,7 +87,7 @@
   }
 
   String numberOfColors = lines[0];
-  if (int.parse(numberOfColors, onError: (_) => -1) < 8) {
+  if ((int.tryParse(numberOfColors) ?? -1) < 8) {
     if (debug) {
       print("Not enabling colors, less than 8 colors supported: "
           "${jsonEncode(numberOfColors)}.");
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 188c88b..d716845 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -35,7 +35,14 @@
 export '../api_prototype/compiler_options.dart'
     show CompilerOptions, parseExperimentalFlags;
 
-export '../api_prototype/diagnostic_message.dart' show DiagnosticMessage;
+export '../api_prototype/diagnostic_message.dart'
+    show
+        DiagnosticMessage,
+        getMessageCharOffset,
+        getMessageHeaderText,
+        getMessageLength,
+        getMessageRelatedInformation,
+        getMessageUri;
 
 export '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 
@@ -49,8 +56,6 @@
 export '../compute_platform_binaries_location.dart'
     show computePlatformBinariesLocation;
 
-export '../fasta/fasta_codes.dart' show FormattedMessage;
-
 export '../fasta/kernel/redirecting_factory_body.dart'
     show RedirectingFactoryBody;
 
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index e9c843d..e7c5bcd 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -2,7 +2,8 @@
 // for 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 '../api_prototype/compiler_options.dart' show CompilerOptions;
+export '../api_prototype/compiler_options.dart'
+    show CompilerOptions, parseExperimentalFlags;
 
 export '../api_prototype/diagnostic_message.dart'
     show DiagnosticMessage, DiagnosticMessageHandler, getMessageUri;
@@ -34,6 +35,7 @@
     show
         LocatedMessage,
         Message,
+        messageConstEvalCircularity,
         messageConstEvalContext,
         messageConstEvalFailedAssertion,
         noLength,
@@ -50,7 +52,14 @@
         templateConstEvalNegativeShift,
         templateConstEvalNonConstantLiteral,
         templateConstEvalNonConstantVariableGet,
-        templateConstEvalZeroDivisor;
+        templateConstEvalZeroDivisor,
+        templateFfiFieldAnnotation,
+        templateFfiStructAnnotation,
+        templateFfiNotStatic,
+        templateFfiTypeInvalid,
+        templateFfiTypeMismatch,
+        templateFfiTypeUnsized,
+        templateFfiFieldInitializer;
 
 export '../fasta/hybrid_file_system.dart' show HybridFileSystem;
 
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 4ef234d..82804be 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -177,10 +177,14 @@
   /// The Uri where output is generated, may be null.
   final Uri output;
 
+  final Map<String, String> environmentDefines;
+
   /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
   ProcessedOptions({CompilerOptions options, List<Uri> inputs, this.output})
       : this._raw = options ?? new CompilerOptions(),
         this.inputs = inputs ?? <Uri>[],
+        // TODO(askesc): Copy the map when kernel_service supports that.
+        this.environmentDefines = options?.environmentDefines,
         // TODO(sigmund, ahe): create ticker even earlier or pass in a stopwatch
         // collecting time since the start of the VM.
         this.ticker = new Ticker(isVerbose: options?.verbose ?? false);
@@ -212,14 +216,17 @@
     if (CompilerContext.current.options.setExitCodeOnProblem) {
       exitCode = 1;
     }
-    (_raw.onDiagnostic ??
-        _defaultDiagnosticMessageHandler)(format(message, severity, context));
+    reportDiagnosticMessage(format(message, severity, context));
     if (command_line_reporting.shouldThrowOn(severity)) {
       throw new DebugAbort(
           message.uri, message.charOffset, severity, StackTrace.current);
     }
   }
 
+  void reportDiagnosticMessage(DiagnosticMessage message) {
+    (_raw.onDiagnostic ?? _defaultDiagnosticMessageHandler)(message);
+  }
+
   void _defaultDiagnosticMessageHandler(DiagnosticMessage message) {
     printDiagnosticMessage(message, print);
   }
@@ -300,6 +307,7 @@
 
   bool isExperimentEnabled(ExperimentalFlag flag) {
     // TODO(askesc): Determine default flag value from specification file.
+    if (flag == ExperimentalFlag.setLiterals) return true;
     return _raw.experimentalFlags[flag] ?? false;
   }
 
diff --git a/pkg/front_end/lib/src/compute_platform_binaries_location.dart b/pkg/front_end/lib/src/compute_platform_binaries_location.dart
index a1d1cdb..9ac1f54 100644
--- a/pkg/front_end/lib/src/compute_platform_binaries_location.dart
+++ b/pkg/front_end/lib/src/compute_platform_binaries_location.dart
@@ -2,7 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "dart:io" show Platform;
+import "dart:io" show File, Platform;
+
+import 'package:kernel/ast.dart' show Source;
+
+import 'base/processed_options.dart' show ProcessedOptions;
+
+import 'fasta/compiler_context.dart' show CompilerContext;
 
 /// Computes the location of platform binaries, that is, compiled `.dill` files
 /// of the platform libraries that are used to avoid recompiling those
@@ -22,3 +28,62 @@
     return vmDirectory;
   }
 }
+
+/// Translates an SDK URI ("org-dartlang-sdk:///...") to a file URI.
+Uri translateSdk(Uri uri) {
+  if (CompilerContext.isActive) {
+    if (uri.scheme == "org-dartlang-sdk") {
+      String path = uri.path;
+      if (path.startsWith("/sdk/")) {
+        CompilerContext context = CompilerContext.current;
+        Uri sdkRoot = context.cachedSdkRoot;
+        if (sdkRoot == null) {
+          ProcessedOptions options = context.options;
+          sdkRoot = options.sdkRoot;
+          if (sdkRoot == null) {
+            sdkRoot = options.librariesSpecificationUri?.resolve("../");
+            if (sdkRoot != null) {
+              if (!isExistingFile(sdkRoot.resolve("lib/libraries.json"))) {
+                sdkRoot = null;
+              }
+            }
+          }
+          if (sdkRoot == null) {
+            sdkRoot = (options.sdkSummary ?? computePlatformBinariesLocation())
+                .resolve("../../");
+            if (sdkRoot != null) {
+              if (!isExistingFile(sdkRoot.resolve("lib/libraries.json"))) {
+                if (isExistingFile(sdkRoot.resolve("sdk/lib/libraries.json"))) {
+                  sdkRoot = sdkRoot.resolve("sdk/");
+                } else {
+                  sdkRoot = null;
+                }
+              }
+            }
+          }
+          sdkRoot ??= Uri.parse("org-dartlang-sdk:///sdk/");
+          context.cachedSdkRoot = sdkRoot;
+        }
+        Uri candidate = sdkRoot.resolve(path.substring(5));
+        if (isExistingFile(candidate)) {
+          Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
+          Source source = uriToSource[uri];
+          if (source.source.isEmpty) {
+            uriToSource[uri] = new Source(source.lineStarts,
+                new File.fromUri(candidate).readAsBytesSync());
+          }
+        }
+        return candidate;
+      }
+    }
+  }
+  return uri;
+}
+
+bool isExistingFile(Uri uri) {
+  if (uri.scheme == "file") {
+    return new File.fromUri(uri).existsSync();
+  } else {
+    return false;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/builder.dart b/pkg/front_end/lib/src/fasta/builder/builder.dart
index 70b361c..cce01a4 100644
--- a/pkg/front_end/lib/src/fasta/builder/builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/builder.dart
@@ -30,8 +30,6 @@
 
 export 'formal_parameter_builder.dart' show FormalParameterBuilder;
 
-export 'function_type_alias_builder.dart' show FunctionTypeAliasBuilder;
-
 export 'function_type_builder.dart' show FunctionTypeBuilder;
 
 export 'invalid_type_builder.dart' show InvalidTypeBuilder;
@@ -54,6 +52,8 @@
 
 export 'procedure_builder.dart' show ProcedureBuilder;
 
+export 'type_alias_builder.dart' show TypeAliasBuilder;
+
 export 'type_builder.dart' show TypeBuilder;
 
 export 'type_declaration_builder.dart' show TypeDeclarationBuilder;
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_alias_builder.dart
deleted file mode 100644
index 7abb3f3..0000000
--- a/pkg/front_end/lib/src/fasta/builder/function_type_alias_builder.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.function_type_alias_builder;
-
-import 'builder.dart'
-    show
-        LibraryBuilder,
-        MetadataBuilder,
-        TypeBuilder,
-        TypeDeclarationBuilder,
-        TypeVariableBuilder;
-
-abstract class FunctionTypeAliasBuilder<T extends TypeBuilder, R>
-    extends TypeDeclarationBuilder<T, R> {
-  final T type;
-
-  final List<TypeVariableBuilder> typeVariables;
-
-  FunctionTypeAliasBuilder(List<MetadataBuilder> metadata, String name,
-      this.typeVariables, this.type, LibraryBuilder parent, int charOffset)
-      : super(metadata, null, name, parent, charOffset);
-
-  String get debugName => "FunctionTypeAliasBuilder";
-
-  LibraryBuilder get parent => super.parent;
-
-  int get typeVariablesCount;
-}
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 75fd906..9dbca65 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -14,6 +14,7 @@
 
 import '../messages.dart'
     show
+        FormattedMessage,
         LocatedMessage,
         Message,
         templateInternalProblemConstructorNotFound,
@@ -97,13 +98,19 @@
   ///
   /// See `Loader.addMessage` for an explanation of the
   /// arguments passed to this method.
-  void addProblem(Message message, int charOffset, int length, Uri fileUri,
+  FormattedMessage addProblem(
+      Message message, int charOffset, int length, Uri fileUri,
       {bool wasHandled: false,
       List<LocatedMessage> context,
-      Severity severity}) {
+      Severity severity,
+      bool problemOnLibrary: false}) {
     fileUri ??= this.fileUri;
-    loader.addProblem(message, charOffset, length, fileUri,
-        wasHandled: wasHandled, context: context, severity: severity);
+
+    return loader.addProblem(message, charOffset, length, fileUri,
+        wasHandled: wasHandled,
+        context: context,
+        severity: severity,
+        problemOnLibrary: true);
   }
 
   /// Returns true if the export scope was modified.
diff --git a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
index 16fc417..cb656b4 100644
--- a/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/metadata_builder.dart
@@ -10,20 +10,21 @@
 
 abstract class MetadataBuilder<T extends TypeBuilder> {
   final int charOffset;
+
   MetadataBuilder(Declaration parent, this.charOffset);
 
   factory MetadataBuilder.fromConstructor(
       ConstructorReferenceBuilder constructorReference,
-      List arguments,
+      List<Object> arguments,
       Declaration parent,
       int charOffset) {
-    return new ConstructorMetadataBuilder(
+    return new ConstructorMetadataBuilder<T>(
         constructorReference, arguments, parent, charOffset);
   }
 
   factory MetadataBuilder.fromExpression(
       Object expression, String postfix, Declaration parent, int charOffset) {
-    return new ExpressionMetadataBuilder(
+    return new ExpressionMetadataBuilder<T>(
         expression, postfix, parent, charOffset);
   }
 }
@@ -32,7 +33,7 @@
     extends MetadataBuilder<T> {
   final ConstructorReferenceBuilder constructorReference;
 
-  final List arguments;
+  final List<Object> arguments;
 
   ConstructorMetadataBuilder(this.constructorReference, this.arguments,
       Declaration parent, int charOffset)
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 8baf2e1..1a17041 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -38,6 +38,7 @@
 
   List<T> arguments;
 
+  @override
   TypeDeclarationBuilder<T, R> declaration;
 
   NamedTypeBuilder(this.name, this.arguments);
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
new file mode 100644
index 0000000..e941212
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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.function_type_alias_builder;
+
+import 'builder.dart'
+    show
+        LibraryBuilder,
+        MetadataBuilder,
+        TypeBuilder,
+        TypeDeclarationBuilder,
+        TypeVariableBuilder;
+
+abstract class TypeAliasBuilder<T extends TypeBuilder, R>
+    extends TypeDeclarationBuilder<T, R> {
+  final T type;
+
+  final List<TypeVariableBuilder<T, R>> typeVariables;
+
+  TypeAliasBuilder(
+      List<MetadataBuilder<T>> metadata,
+      String name,
+      this.typeVariables,
+      this.type,
+      LibraryBuilder<T, Object> parent,
+      int charOffset)
+      : super(metadata, null, name, parent, charOffset);
+
+  String get debugName => "TypeAliasBuilder";
+
+  LibraryBuilder<T, Object> get parent => super.parent;
+
+  int get typeVariablesCount;
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index ceb7a59..bebc060 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -12,6 +12,8 @@
 abstract class TypeBuilder {
   const TypeBuilder();
 
+  TypeDeclarationBuilder get declaration => null;
+
   void resolveIn(
       Scope scope, int charOffset, Uri fileUri, LibraryBuilder library) {}
 
diff --git a/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
index e4f8c41..b28cf9f 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_declaration_builder.dart
@@ -14,7 +14,7 @@
 
 abstract class TypeDeclarationBuilder<T extends TypeBuilder, R>
     extends ModifierBuilder {
-  final List<MetadataBuilder> metadata;
+  final List<MetadataBuilder<T>> metadata;
 
   final int modifiers;
 
@@ -34,8 +34,9 @@
 
   int get typeVariablesCount => 0;
 
-  R buildType(LibraryBuilder library, List<T> arguments);
+  R buildType(LibraryBuilder<T, Object> library, List<T> arguments);
 
   /// [arguments] have already been built.
-  R buildTypesWithBuiltArguments(LibraryBuilder library, List<R> arguments);
+  R buildTypesWithBuiltArguments(
+      LibraryBuilder<T, Object> library, List<R> arguments);
 }
diff --git a/pkg/front_end/lib/src/fasta/colors.dart b/pkg/front_end/lib/src/fasta/colors.dart
index 65b2e79..00ae3b6a 100644
--- a/pkg/front_end/lib/src/fasta/colors.dart
+++ b/pkg/front_end/lib/src/fasta/colors.dart
@@ -174,7 +174,7 @@
   }
 
   String numberOfColors = lines[0];
-  if (int.parse(numberOfColors, onError: (_) => -1) < 8) {
+  if ((int.tryParse(numberOfColors) ?? -1) < 8) {
     if (context.options.verbose) {
       print("Not enabling colors, less than 8 colors supported: "
           "${jsonEncode(numberOfColors)}.");
diff --git a/pkg/front_end/lib/src/fasta/command_line_reporting.dart b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
index c191dbb..fbfd9df 100644
--- a/pkg/front_end/lib/src/fasta/command_line_reporting.dart
+++ b/pkg/front_end/lib/src/fasta/command_line_reporting.dart
@@ -14,6 +14,8 @@
 
 import 'package:kernel/ast.dart' show Location;
 
+import '../compute_platform_binaries_location.dart' show translateSdk;
+
 import 'colors.dart' show green, magenta, red;
 
 import 'compiler_context.dart' show CompilerContext;
@@ -72,7 +74,7 @@
     }
 
     if (message.uri != null) {
-      String path = relativizeUri(message.uri);
+      String path = relativizeUri(translateSdk(message.uri));
       int offset = message.charOffset;
       location ??= (offset == -1 ? null : getLocation(message.uri, offset));
       String sourceLine = getSourceLine(location);
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index acb6637..c861e50 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -54,6 +54,8 @@
 
   bool enableColorsCached = null;
 
+  Uri cachedSdkRoot = null;
+
   CompilerContext(this.options);
 
   void disableColors() {
diff --git a/pkg/front_end/lib/src/fasta/crash.dart b/pkg/front_end/lib/src/fasta/crash.dart
index f4745d5..8498da9 100644
--- a/pkg/front_end/lib/src/fasta/crash.dart
+++ b/pkg/front_end/lib/src/fasta/crash.dart
@@ -93,7 +93,7 @@
       int port = request?.connectionInfo?.remotePort;
       await note(" to $host:$port");
       await request
-        ..headers.contentType = ContentType.JSON
+        ..headers.contentType = ContentType.json
         ..write(json);
       await request.close();
       await note(".");
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index bba4295..fd0a4d2 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -41,6 +41,8 @@
             parent,
             cls.fileOffset);
 
+  Uri get fileUri => cls.fileUri;
+
   KernelTypeBuilder get supertype {
     KernelTypeBuilder supertype = super.supertype;
     if (supertype == null) {
@@ -103,6 +105,19 @@
     return computeTypeBuilder(library, cls.mixedInType);
   }
 
+  List<KernelTypeBuilder> get interfaces {
+    if (cls.implementedTypes.isEmpty) return null;
+    if (super.interfaces == null) {
+      List<KernelTypeBuilder> result =
+          new List<KernelTypeBuilder>(cls.implementedTypes.length);
+      for (int i = 0; i < result.length; i++) {
+        result[i] = computeTypeBuilder(library, cls.implementedTypes[i]);
+      }
+      super.interfaces = result;
+    }
+    return super.interfaces;
+  }
+
   void set mixedInType(KernelTypeBuilder mixin) {
     unimplemented("mixedInType=", -1, null);
   }
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 4671069..610dcea 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
@@ -48,25 +48,28 @@
 
 import 'dill_loader.dart' show DillLoader;
 
-import 'dill_typedef_builder.dart' show DillFunctionTypeAliasBuilder;
+import 'dill_type_alias_builder.dart' show DillTypeAliasBuilder;
 
 class DillLibraryBuilder extends LibraryBuilder<KernelTypeBuilder, Library> {
-  final Uri uri;
+  final Library library;
 
   final DillLoader loader;
 
-  Library library;
-
   /// Exports that can't be serialized.
   ///
   /// The elements of this map are documented in
   /// [../kernel/kernel_library_builder.dart].
   Map<String, String> unserializableExports;
 
-  DillLibraryBuilder(this.uri, this.loader)
-      : super(uri, new Scope.top(), new Scope.top());
+  DillLibraryBuilder(this.library, this.loader)
+      : super(library.fileUri, new Scope.top(), new Scope.top());
 
-  Uri get fileUri => uri;
+  @override
+  bool get isSynthetic => library.isSynthetic;
+
+  Uri get uri => library.importUri;
+
+  Uri get fileUri => library.fileUri;
 
   @override
   String get name => library.name;
@@ -132,17 +135,12 @@
   }
 
   void addTypedef(Typedef typedef) {
-    DartType alias = typedef.type;
-    if (alias is FunctionType) {
-      if (alias.typedefType == null) {
-        unhandled("null", "addTypedef", typedef.fileOffset, typedef.fileUri);
-      }
-      addBuilder(typedef.name, new DillFunctionTypeAliasBuilder(typedef, this),
-          typedef.fileOffset);
-    } else {
-      unhandled("${alias.runtimeType}", "addTypedef", typedef.fileOffset,
-          typedef.fileUri);
+    DartType type = typedef.type;
+    if (type is FunctionType && type.typedefType == null) {
+      unhandled("null", "addTypedef", typedef.fileOffset, typedef.fileUri);
     }
+    addBuilder(typedef.name, new DillTypeAliasBuilder(typedef, this),
+        typedef.fileOffset);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 026c070..aa5785b 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -6,37 +6,15 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/ast.dart'
-    show
-        BottomType,
-        Class,
-        Component,
-        DartType,
-        DartTypeVisitor,
-        DynamicType,
-        FunctionType,
-        InterfaceType,
-        InvalidType,
-        Library,
-        Source,
-        TypeParameter,
-        TypeParameterType,
-        TypedefType,
-        VoidType;
+import 'package:kernel/ast.dart' show Class, Component, DartType, Library;
 
 import '../fasta_codes.dart'
     show SummaryTemplate, Template, templateDillOutlineSummary;
 
-import '../compiler_context.dart' show CompilerContext;
-
 import '../kernel/kernel_builder.dart'
-    show
-        DynamicTypeBuilder,
-        KernelNamedTypeBuilder,
-        KernelTypeBuilder,
-        KernelTypeVariableBuilder,
-        LibraryBuilder,
-        VoidTypeBuilder;
+    show KernelClassBuilder, KernelTypeBuilder, LibraryBuilder;
+
+import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
 
 import '../loader.dart' show Loader;
 
@@ -44,20 +22,12 @@
 
 import '../target_implementation.dart' show TargetImplementation;
 
-import 'dill_class_builder.dart' show DillClassBuilder;
-
 import 'dill_library_builder.dart' show DillLibraryBuilder;
 
+import 'dill_target.dart' show DillTarget;
+
 class DillLoader extends Loader<Library> {
-  /// Source targets are compiled against these binary libraries.
-  final libraries = <Library>[];
-
-  /// Sources for all appended components.
-  final Map<Uri, Source> uriToSource;
-
-  DillLoader(TargetImplementation target)
-      : uriToSource = CompilerContext.current.uriToSource,
-        super(target);
+  DillLoader(TargetImplementation target) : super(target);
 
   Template<SummaryTemplate> get outlineSummaryTemplate =>
       templateDillOutlineSummary;
@@ -66,18 +36,25 @@
   /// provided, append only libraries whose [Uri] is accepted by the [filter].
   List<DillLibraryBuilder> appendLibraries(Component component,
       {bool filter(Uri uri), int byteCount: 0}) {
-    var builders = <DillLibraryBuilder>[];
-    for (Library library in component.libraries) {
+    List<Library> componentLibraries = component.libraries;
+    List<Uri> requestedLibraries = <Uri>[];
+    DillTarget target = this.target;
+    for (int i = 0; i < componentLibraries.length; i++) {
+      Library library = componentLibraries[i];
+      Uri uri = library.importUri;
       if (filter == null || filter(library.importUri)) {
         libraries.add(library);
-        DillLibraryBuilder builder = read(library.importUri, -1);
-        builder.library = library;
-        builders.add(builder);
+        target.addLibrary(library);
+        requestedLibraries.add(uri);
       }
     }
-    uriToSource.addAll(component.uriToSource);
+    List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
+    for (int i = 0; i < requestedLibraries.length; i++) {
+      result.add(read(requestedLibraries[i], -1));
+    }
+    target.uriToSource.addAll(component.uriToSource);
     this.byteCount += byteCount;
-    return builders;
+    return result;
   }
 
   Future<Null> buildOutline(DillLibraryBuilder builder) async {
@@ -101,71 +78,15 @@
     });
   }
 
+  @override
+  KernelClassBuilder computeClassBuilderFromTargetClass(Class cls) {
+    Library kernelLibrary = cls.enclosingLibrary;
+    LibraryBuilder library = builders[kernelLibrary.importUri];
+    return library[cls.name];
+  }
+
+  @override
   KernelTypeBuilder computeTypeBuilder(DartType type) {
     return type.accept(new TypeBuilderComputer(this));
   }
 }
-
-class TypeBuilderComputer implements DartTypeVisitor<KernelTypeBuilder> {
-  final DillLoader loader;
-
-  const TypeBuilderComputer(this.loader);
-
-  KernelTypeBuilder defaultDartType(DartType node) {
-    throw "Unsupported";
-  }
-
-  KernelTypeBuilder visitInvalidType(InvalidType node) {
-    throw "Not implemented";
-  }
-
-  KernelTypeBuilder visitDynamicType(DynamicType node) {
-    return new KernelNamedTypeBuilder("dynamic", null)
-      ..bind(new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
-          const DynamicType(), loader.coreLibrary, -1));
-  }
-
-  KernelTypeBuilder visitVoidType(VoidType node) {
-    return new KernelNamedTypeBuilder("dynamic", null)
-      ..bind(new VoidTypeBuilder<KernelTypeBuilder, VoidType>(
-          const VoidType(), loader.coreLibrary, -1));
-  }
-
-  KernelTypeBuilder visitBottomType(BottomType node) {
-    throw "Not implemented";
-  }
-
-  KernelTypeBuilder visitInterfaceType(InterfaceType node) {
-    Class kernelClass = node.classNode;
-    Library kernelLibrary = kernelClass.enclosingLibrary;
-    DillLibraryBuilder library = loader.builders[kernelLibrary.importUri];
-    String name = kernelClass.name;
-    DillClassBuilder cls = library[name];
-    List<KernelTypeBuilder> arguments;
-    List<DartType> kernelArguments = node.typeArguments;
-    if (kernelArguments.isNotEmpty) {
-      arguments = new List<KernelTypeBuilder>(kernelArguments.length);
-      for (int i = 0; i < kernelArguments.length; i++) {
-        arguments[i] = kernelArguments[i].accept(this);
-      }
-    }
-    return new KernelNamedTypeBuilder(name, arguments)..bind(cls);
-  }
-
-  KernelTypeBuilder visitFunctionType(FunctionType node) {
-    throw "Not implemented";
-  }
-
-  KernelTypeBuilder visitTypeParameterType(TypeParameterType node) {
-    TypeParameter parameter = node.parameter;
-    Class kernelClass = parameter.parent;
-    Library kernelLibrary = kernelClass.enclosingLibrary;
-    DillLibraryBuilder library = loader.builders[kernelLibrary.importUri];
-    return new KernelNamedTypeBuilder(parameter.name, null)
-      ..bind(new KernelTypeVariableBuilder.fromKernel(parameter, library));
-  }
-
-  KernelTypeBuilder visitTypedefType(TypedefType node) {
-    throw "Not implemented";
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index 63348b0..4771d2c 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -6,6 +6,8 @@
 
 import 'dart:async' show Future;
 
+import 'package:kernel/ast.dart' show Library;
+
 import 'package:kernel/target/targets.dart' show Target;
 
 import '../kernel/kernel_builder.dart' show ClassBuilder;
@@ -23,7 +25,11 @@
 import 'dill_loader.dart' show DillLoader;
 
 class DillTarget extends TargetImplementation {
+  final Map<Uri, DillLibraryBuilder> libraryBuilders =
+      <Uri, DillLibraryBuilder>{};
+
   bool isLoaded = false;
+
   DillLoader loader;
 
   DillTarget(Ticker ticker, UriTranslator uriTranslator, Target backendTarget)
@@ -54,9 +60,14 @@
   @override
   DillLibraryBuilder createLibraryBuilder(Uri uri, Uri fileUri, origin) {
     assert(origin == null);
-    return new DillLibraryBuilder(uri, loader);
+    return libraryBuilders.remove(uri);
   }
 
   @override
   void breakCycle(ClassBuilder cls) {}
+
+  void addLibrary(Library library) {
+    libraryBuilders[library.importUri] =
+        new DillLibraryBuilder(library, loader);
+  }
 }
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
new file mode 100644
index 0000000..6667e06
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/dill/dill_type_alias_builder.dart
@@ -0,0 +1,68 @@
+// 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 fasta.dill_typedef_builder;
+
+import 'package:kernel/ast.dart' show DartType, Library, Typedef;
+
+import '../kernel/kernel_builder.dart'
+    show
+        KernelTypeAliasBuilder,
+        KernelFunctionTypeBuilder,
+        KernelTypeBuilder,
+        LibraryBuilder,
+        MetadataBuilder;
+
+import '../problems.dart' show unimplemented;
+
+import 'dill_library_builder.dart' show DillLibraryBuilder;
+
+class DillTypeAliasBuilder extends KernelTypeAliasBuilder {
+  DillTypeAliasBuilder(Typedef typedef, DillLibraryBuilder parent)
+      : super(null, typedef.name, null, null, parent, typedef.fileOffset,
+            typedef);
+
+  List<MetadataBuilder<KernelTypeBuilder>> get metadata {
+    return unimplemented("metadata", -1, null);
+  }
+
+  @override
+  int get typeVariablesCount => target.typeParameters.length;
+
+  @override
+  KernelFunctionTypeBuilder get type {
+    return unimplemented("type", -1, null);
+  }
+
+  @override
+  DartType buildThisType(LibraryBuilder<KernelTypeBuilder, Library> library) {
+    return thisType ??= target.type;
+  }
+
+  @override
+  List<DartType> buildTypeArguments(
+      LibraryBuilder<KernelTypeBuilder, Library> library,
+      List<KernelTypeBuilder> arguments) {
+    // For performance reasons, [typeVariables] aren't restored from [target].
+    // So, if [arguments] is null, the default types should be retrieved from
+    // [cls.typeParameters].
+    if (arguments == null) {
+      List<DartType> result = new List<DartType>.filled(
+          target.typeParameters.length, null,
+          growable: true);
+      for (int i = 0; i < result.length; ++i) {
+        result[i] = target.typeParameters[i].defaultType;
+      }
+      return result;
+    }
+
+    // [arguments] != null
+    List<DartType> result =
+        new List<DartType>.filled(arguments.length, null, growable: true);
+    for (int i = 0; i < result.length; ++i) {
+      result[i] = arguments[i].build(library);
+    }
+    return result;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart
deleted file mode 100644
index a395dca..0000000
--- a/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.dill_typedef_builder;
-
-import 'package:kernel/ast.dart' show DartType, Typedef;
-
-import '../kernel/kernel_builder.dart'
-    show
-        KernelFunctionTypeAliasBuilder,
-        KernelFunctionTypeBuilder,
-        KernelTypeBuilder,
-        LibraryBuilder,
-        MetadataBuilder;
-
-import '../problems.dart' show unimplemented;
-
-import 'dill_library_builder.dart' show DillLibraryBuilder;
-
-class DillFunctionTypeAliasBuilder extends KernelFunctionTypeAliasBuilder {
-  DillFunctionTypeAliasBuilder(Typedef typedef, DillLibraryBuilder parent)
-      : super(null, typedef.name, null, null, parent, typedef.fileOffset,
-            typedef);
-
-  List<MetadataBuilder> get metadata {
-    return unimplemented("metadata", -1, null);
-  }
-
-  @override
-  int get typeVariablesCount => target.typeParameters.length;
-
-  @override
-  KernelFunctionTypeBuilder get type {
-    return unimplemented("type", -1, null);
-  }
-
-  @override
-  DartType buildThisType(LibraryBuilder library) => thisType ??= target.type;
-
-  @override
-  List<DartType> buildTypeArguments(
-      LibraryBuilder library, List<KernelTypeBuilder> arguments) {
-    // For performance reasons, [typeVariables] aren't restored from [target].
-    // So, if [arguments] is null, the default types should be retrieved from
-    // [cls.typeParameters].
-    if (arguments == null) {
-      List<DartType> result = new List<DartType>.filled(
-          target.typeParameters.length, null,
-          growable: true);
-      for (int i = 0; i < result.length; ++i) {
-        result[i] = target.typeParameters[i].defaultType;
-      }
-      return result;
-    }
-
-    // [arguments] != null
-    List<DartType> result =
-        new List<DartType>.filled(arguments.length, null, growable: true);
-    for (int i = 0; i < result.length; ++i) {
-      result[i] = arguments[i].build(library);
-    }
-    return result;
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes.dart b/pkg/front_end/lib/src/fasta/fasta_codes.dart
index 2fe4551..322c728 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes.dart
@@ -4,6 +4,8 @@
 
 library fasta.codes;
 
+import 'dart:convert' show JsonEncoder, json;
+
 import 'package:kernel/ast.dart'
     show Constant, DartType, demangleMixinApplicationName;
 
@@ -181,6 +183,65 @@
     // TODO(ahe): Implement this correctly.
     return ansiFormatted;
   }
+
+  Map<String, Object> toJson() {
+    // This should be kept in sync with package:kernel/problems.md
+    return <String, Object>{
+      "ansiFormatted": ansiFormatted.toList(),
+      "plainTextFormatted": plainTextFormatted.toList(),
+      "severity": severity.index,
+      "uri": uri.toString(),
+    };
+  }
+
+  String toJsonString() {
+    JsonEncoder encoder = new JsonEncoder.withIndent("  ");
+    return encoder.convert(this);
+  }
+}
+
+class DiagnosticMessageFromJson implements DiagnosticMessage {
+  @override
+  final Iterable<String> ansiFormatted;
+
+  @override
+  final Iterable<String> plainTextFormatted;
+
+  @override
+  final Severity severity;
+
+  final Uri uri;
+
+  DiagnosticMessageFromJson(
+      this.ansiFormatted, this.plainTextFormatted, this.severity, this.uri);
+
+  factory DiagnosticMessageFromJson.fromJson(String jsonString) {
+    Map<String, Object> decoded = json.decode(jsonString);
+    List<String> ansiFormatted =
+        new List<String>.from(decoded["ansiFormatted"]);
+    List<String> plainTextFormatted =
+        new List<String>.from(decoded["plainTextFormatted"]);
+    Severity severity = Severity.values[decoded["severity"]];
+    Uri uri = Uri.parse(decoded["uri"]);
+
+    return new DiagnosticMessageFromJson(
+        ansiFormatted, plainTextFormatted, severity, uri);
+  }
+
+  Map<String, Object> toJson() {
+    // This should be kept in sync with package:kernel/problems.md
+    return <String, Object>{
+      "ansiFormatted": ansiFormatted.toList(),
+      "plainTextFormatted": plainTextFormatted.toList(),
+      "severity": severity.index,
+      "uri": uri.toString(),
+    };
+  }
+
+  String toJsonString() {
+    JsonEncoder encoder = new JsonEncoder.withIndent("  ");
+    return encoder.convert(this);
+  }
 }
 
 String relativizeUri(Uri uri) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 3712941..e57910c 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -974,6 +974,15 @@
         r"""Constant constructor can't call non-constant super constructors.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstEvalCircularity = messageConstEvalCircularity;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstEvalCircularity = const MessageCode(
+    "ConstEvalCircularity",
+    analyzerCodes: <String>["RECURSIVE_COMPILE_TIME_CONSTANT"],
+    message: r"""Constant expression depends on itself.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeConstEvalContext = messageConstEvalContext;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3338,6 +3347,202 @@
   -h        Display this message (add -v for information about all options).""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(String name)> templateFfiFieldAnnotation = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+    withArguments: _withArgumentsFfiFieldAnnotation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiFieldAnnotation =
+    const Code<Message Function(String name)>(
+  "FfiFieldAnnotation",
+  templateFfiFieldAnnotation,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiFieldAnnotation(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiFieldAnnotation,
+      message:
+          """Field '${name}' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(String name)> templateFfiFieldInitializer = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""Field '#name' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution.""",
+    withArguments: _withArgumentsFfiFieldInitializer);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiFieldInitializer =
+    const Code<Message Function(String name)>(
+  "FfiFieldInitializer",
+  templateFfiFieldInitializer,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiFieldInitializer(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiFieldInitializer,
+      message:
+          """Field '${name}' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(String name)> templateFfiNotStatic = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from c.""",
+    withArguments: _withArgumentsFfiNotStatic);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiNotStatic =
+    const Code<Message Function(String name)>(
+  "FfiNotStatic",
+  templateFfiNotStatic,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiNotStatic(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiNotStatic,
+      message:
+          """${name} expects a static function as parameter. dart:ffi only supports calling static Dart functions from c.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(String name)> templateFfiStructAnnotation = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""Class '#name' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields.""",
+    withArguments: _withArgumentsFfiStructAnnotation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiStructAnnotation =
+    const Code<Message Function(String name)>(
+  "FfiStructAnnotation",
+  templateFfiStructAnnotation,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiStructAnnotation(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeFfiStructAnnotation,
+      message:
+          """Class '${name}' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(DartType _type)> templateFfiTypeInvalid = const Template<
+        Message Function(DartType _type)>(
+    messageTemplate:
+        r"""Expected type '#type' to be a valid and instantiated subtype of 'NativeType'.""",
+    withArguments: _withArgumentsFfiTypeInvalid);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type)> codeFfiTypeInvalid =
+    const Code<Message Function(DartType _type)>(
+  "FfiTypeInvalid",
+  templateFfiTypeInvalid,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiTypeInvalid(DartType _type) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeFfiTypeInvalid,
+      message:
+          """Expected type '${type}' to be a valid and instantiated subtype of 'NativeType'.""" +
+              labeler.originMessages,
+      arguments: {'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        DartType _type,
+        DartType _type2,
+        DartType
+            _type3)> templateFfiTypeMismatch = const Template<
+        Message Function(DartType _type, DartType _type2, DartType _type3)>(
+    messageTemplate:
+        r"""Expected type '#type' to be '#type2', which is the Dart type corresponding to '#type3'.""",
+    withArguments: _withArgumentsFfiTypeMismatch);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, DartType _type2, DartType _type3)>
+    codeFfiTypeMismatch = const Code<
+        Message Function(DartType _type, DartType _type2, DartType _type3)>(
+  "FfiTypeMismatch",
+  templateFfiTypeMismatch,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiTypeMismatch(
+    DartType _type, DartType _type2, DartType _type3) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> typeParts = labeler.labelType(_type);
+  List<Object> type2Parts = labeler.labelType(_type2);
+  List<Object> type3Parts = labeler.labelType(_type3);
+  String type = typeParts.join();
+  String type2 = type2Parts.join();
+  String type3 = type3Parts.join();
+  return new Message(codeFfiTypeMismatch,
+      message:
+          """Expected type '${type}' to be '${type2}', which is the Dart type corresponding to '${type3}'.""" +
+              labeler.originMessages,
+      arguments: {'type': _type, 'type2': _type2, 'type3': _type3});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String name,
+        DartType
+            _type)> templateFfiTypeUnsized = const Template<
+        Message Function(String name, DartType _type)>(
+    messageTemplate:
+        r"""Method '#name' cannot be called on something of type '#type' as this type is unsized.""",
+    withArguments: _withArgumentsFfiTypeUnsized);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, DartType _type)> codeFfiTypeUnsized =
+    const Code<Message Function(String name, DartType _type)>(
+  "FfiTypeUnsized",
+  templateFfiTypeUnsized,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiTypeUnsized(String name, DartType _type) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> typeParts = labeler.labelType(_type);
+  String type = typeParts.join();
+  return new Message(codeFfiTypeUnsized,
+      message:
+          """Method '${name}' cannot be called on something of type '${type}' as this type is unsized.""" +
+              labeler.originMessages,
+      arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeFieldInitializedOutsideDeclaringClass =
     messageFieldInitializedOutsideDeclaringClass;
 
@@ -4619,12 +4824,16 @@
     Message Function(
         String string,
         String string2,
+        String string3,
         Uri
             uri_)> templateInitializeFromDillUnknownProblem = const Template<
-        Message Function(String string, String string2, Uri uri_)>(
+        Message Function(
+            String string, String string2, String string3, Uri uri_)>(
     messageTemplate:
         r"""Tried to initialize from a previous compilation (#string), but couldn't.
-Error message was '#string2'. This might be a bug.
+Error message was '#string2'.
+Stacktrace included '#string3'.
+This might be a bug.
 
 The Dart team would greatly appreciate it if you would take a moment to report this problem at http://dartbug.com/new.
 If you are comfortable with it, it would improve the chances of fixing any bug if you included the file #uri in your error report, but be aware that this file includes your source code.
@@ -4632,61 +4841,77 @@
     withArguments: _withArgumentsInitializeFromDillUnknownProblem);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String string, String string2, Uri uri_)>
-    codeInitializeFromDillUnknownProblem =
-    const Code<Message Function(String string, String string2, Uri uri_)>(
+const Code<
+        Message Function(
+            String string, String string2, String string3, Uri uri_)>
+    codeInitializeFromDillUnknownProblem = const Code<
+            Message Function(
+                String string, String string2, String string3, Uri uri_)>(
         "InitializeFromDillUnknownProblem",
         templateInitializeFromDillUnknownProblem,
         severity: Severity.warning);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 Message _withArgumentsInitializeFromDillUnknownProblem(
-    String string, String string2, Uri uri_) {
+    String string, String string2, String string3, Uri uri_) {
   if (string.isEmpty) throw 'No string provided';
   if (string2.isEmpty) throw 'No string provided';
+  if (string3.isEmpty) throw 'No string provided';
   String uri = relativizeUri(uri_);
   return new Message(codeInitializeFromDillUnknownProblem,
       message:
           """Tried to initialize from a previous compilation (${string}), but couldn't.
-Error message was '${string2}'. This might be a bug.
+Error message was '${string2}'.
+Stacktrace included '${string3}'.
+This might be a bug.
 
 The Dart team would greatly appreciate it if you would take a moment to report this problem at http://dartbug.com/new.
 If you are comfortable with it, it would improve the chances of fixing any bug if you included the file ${uri} in your error report, but be aware that this file includes your source code.
 Either way, you should probably delete the file so it doesn't use unnecessary disk space.""",
-      arguments: {'string': string, 'string2': string2, 'uri': uri_});
+      arguments: {
+        'string': string,
+        'string2': string2,
+        'string3': string3,
+        'uri': uri_
+      });
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String string, String string2)>
-    templateInitializeFromDillUnknownProblemNoDump =
-    const Template<Message Function(String string, String string2)>(
+const Template<Message Function(String string, String string2, String string3)>
+    templateInitializeFromDillUnknownProblemNoDump = const Template<
+            Message Function(String string, String string2, String string3)>(
         messageTemplate:
             r"""Tried to initialize from a previous compilation (#string), but couldn't.
-Error message was '#string2'. This might be a bug.
+Error message was '#string2'.
+Stacktrace included '#string3'.
+This might be a bug.
 
 The Dart team would greatly appreciate it if you would take a moment to report this problem at http://dartbug.com/new.""",
         withArguments: _withArgumentsInitializeFromDillUnknownProblemNoDump);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String string, String string2)>
+const Code<Message Function(String string, String string2, String string3)>
     codeInitializeFromDillUnknownProblemNoDump =
-    const Code<Message Function(String string, String string2)>(
+    const Code<Message Function(String string, String string2, String string3)>(
         "InitializeFromDillUnknownProblemNoDump",
         templateInitializeFromDillUnknownProblemNoDump,
         severity: Severity.warning);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 Message _withArgumentsInitializeFromDillUnknownProblemNoDump(
-    String string, String string2) {
+    String string, String string2, String string3) {
   if (string.isEmpty) throw 'No string provided';
   if (string2.isEmpty) throw 'No string provided';
+  if (string3.isEmpty) throw 'No string provided';
   return new Message(codeInitializeFromDillUnknownProblemNoDump,
       message:
           """Tried to initialize from a previous compilation (${string}), but couldn't.
-Error message was '${string2}'. This might be a bug.
+Error message was '${string2}'.
+Stacktrace included '${string3}'.
+This might be a bug.
 
 The Dart team would greatly appreciate it if you would take a moment to report this problem at http://dartbug.com/new.""",
-      arguments: {'string': string, 'string2': string2});
+      arguments: {'string': string, 'string2': string2, 'string3': string3});
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5314,6 +5539,46 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
+        String name,
+        DartType _type,
+        DartType
+            _type2)> templateIntersectionTypeAsTypeArgument = const Template<
+        Message Function(String name, DartType _type, DartType _type2)>(
+    messageTemplate:
+        r"""Can't infer a type for '#name', it can be either '#type' or '#type2'.""",
+    tipTemplate:
+        r"""Try adding a type argument selecting one of the options.""",
+    withArguments: _withArgumentsIntersectionTypeAsTypeArgument);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, DartType _type, DartType _type2)>
+    codeIntersectionTypeAsTypeArgument =
+    const Code<Message Function(String name, DartType _type, DartType _type2)>(
+  "IntersectionTypeAsTypeArgument",
+  templateIntersectionTypeAsTypeArgument,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIntersectionTypeAsTypeArgument(
+    String name, DartType _type, DartType _type2) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> typeParts = labeler.labelType(_type);
+  List<Object> type2Parts = labeler.labelType(_type2);
+  String type = typeParts.join();
+  String type2 = type2Parts.join();
+  return new Message(codeIntersectionTypeAsTypeArgument,
+      message:
+          """Can't infer a type for '${name}', it can be either '${type}' or '${type2}'.""" +
+              labeler.originMessages,
+      tip: """Try adding a type argument selecting one of the options.""",
+      arguments: {'name': name, 'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
         DartType _type,
         DartType
             _type2)> templateInvalidAssignment = const Template<
@@ -5487,6 +5752,41 @@
     Message Function(
         DartType _type,
         DartType
+            _type2)> templateInvalidCastLiteralSet = const Template<
+        Message Function(DartType _type, DartType _type2)>(
+    messageTemplate:
+        r"""The set literal type '#type' isn't of expected type '#type2'.""",
+    tipTemplate:
+        r"""Change the type of the set literal or the context in which it is used.""",
+    withArguments: _withArgumentsInvalidCastLiteralSet);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, DartType _type2)>
+    codeInvalidCastLiteralSet =
+    const Code<Message Function(DartType _type, DartType _type2)>(
+        "InvalidCastLiteralSet", templateInvalidCastLiteralSet,
+        analyzerCodes: <String>["INVALID_CAST_LITERAL_SET"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsInvalidCastLiteralSet(DartType _type, DartType _type2) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> typeParts = labeler.labelType(_type);
+  List<Object> type2Parts = labeler.labelType(_type2);
+  String type = typeParts.join();
+  String type2 = type2Parts.join();
+  return new Message(codeInvalidCastLiteralSet,
+      message:
+          """The set literal type '${type}' isn't of expected type '${type2}'.""" +
+              labeler.originMessages,
+      tip: """Change the type of the set literal or the context in which it is used.""",
+      arguments: {'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        DartType _type,
+        DartType
             _type2)> templateInvalidCastLocalFunction = const Template<
         Message Function(DartType _type, DartType _type2)>(
     messageTemplate:
@@ -7934,6 +8234,26 @@
     tip: r"""Try re-ordering the modifiers.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeStaticAndInstanceConflict =
+    messageStaticAndInstanceConflict;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageStaticAndInstanceConflict = const MessageCode(
+    "StaticAndInstanceConflict",
+    analyzerCodes: <String>["CONFLICTING_STATIC_AND_INSTANCE"],
+    message: r"""This static member conflicts with an instance member.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeStaticAndInstanceConflictCause =
+    messageStaticAndInstanceConflictCause;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageStaticAndInstanceConflictCause = const MessageCode(
+    "StaticAndInstanceConflictCause",
+    severity: Severity.context,
+    message: r"""This is the instance member.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeStaticConstructor = messageStaticConstructor;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 795a5d9..4155df3 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -56,6 +56,7 @@
 
 import 'fasta_codes.dart'
     show
+        DiagnosticMessageFromJson,
         templateInitializeFromDillNotSelfContained,
         templateInitializeFromDillNotSelfContainedNoDump,
         templateInitializeFromDillUnknownProblem,
@@ -93,6 +94,8 @@
   Component componentToInitializeFrom;
   bool initializedFromDill = false;
   bool hasToCheckPackageUris = false;
+  Map<Uri, List<DiagnosticMessageFromJson>> remainingComponentProblems =
+      new Map<Uri, List<DiagnosticMessageFromJson>>();
 
   KernelTarget userCode;
 
@@ -128,7 +131,7 @@
         if (initializeFromDillUri != null) {
           try {
             bytesLength += await initializeFromDill(uriTranslator, c, data);
-          } catch (e) {
+          } catch (e, st) {
             // We might have loaded x out of y libraries into the component.
             // To avoid any unforeseen problems start over.
             bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
@@ -156,9 +159,11 @@
                     ? templateInitializeFromDillUnknownProblem.withArguments(
                         initializeFromDillUri.toString(),
                         "$e",
+                        "$st",
                         gzInitializedFrom)
                     : templateInitializeFromDillUnknownProblemNoDump
-                        .withArguments(initializeFromDillUri.toString(), "$e");
+                        .withArguments(
+                            initializeFromDillUri.toString(), "$e", "$st");
                 dillLoadedData.loader
                     .addProblem(message, TreeNode.noOffset, 1, null);
               }
@@ -200,10 +205,7 @@
       }
 
       ClassHierarchy hierarchy = userCode?.loader?.hierarchy;
-      Set<LibraryBuilder> notReusedLibraries;
-      if (hierarchy != null) {
-        notReusedLibraries = new Set<LibraryBuilder>();
-      }
+      Set<LibraryBuilder> notReusedLibraries = new Set<LibraryBuilder>();
       List<LibraryBuilder> reusedLibraries = computeReusedLibraries(
           invalidatedUris, uriTranslator,
           notReused: notReusedLibraries);
@@ -215,6 +217,14 @@
         userBuilders?.remove(uri);
       }
 
+      // Remove component problems for libraries we don't reuse.
+      if (remainingComponentProblems.isNotEmpty) {
+        for (LibraryBuilder builder in notReusedLibraries) {
+          Library lib = builder.target;
+          removeLibraryFromRemainingComponentProblems(lib, uriTranslator);
+        }
+      }
+
       if (hierarchy != null) {
         List<Library> removedLibraries = new List<Library>();
         for (LibraryBuilder builder in notReusedLibraries) {
@@ -223,6 +233,7 @@
         }
         hierarchy.applyTreeChanges(removedLibraries, const []);
       }
+      notReusedLibraries = null;
 
       if (userCode != null) {
         ticker.logMs("Decided to reuse ${reusedLibraries.length}"
@@ -250,7 +261,7 @@
         }
       }
 
-      userCode.setEntryPoints(<Uri>[entryPoint]);
+      entryPoint = userCode.setEntryPoints(<Uri>[entryPoint]).single;
       await userCode.buildOutlines();
 
       // This is not the full component. It is the component including all
@@ -272,15 +283,21 @@
           : componentWithDill.mainMethod;
 
       List<Library> outputLibraries;
+      Set<Library> allLibraries;
       if (data.includeUserLoadedLibraries || fullComponent) {
         outputLibraries = computeTransitiveClosure(compiledLibraries,
-            mainMethod, entryPoint, reusedLibraries, hierarchy);
+            entryPoint, reusedLibraries, hierarchy, uriTranslator);
+        allLibraries = outputLibraries.toSet();
       } else {
-        computeTransitiveClosure(compiledLibraries, mainMethod, entryPoint,
-            reusedLibraries, hierarchy);
-        outputLibraries = compiledLibraries;
+        outputLibraries = new List<Library>();
+        allLibraries = computeTransitiveClosure(compiledLibraries, entryPoint,
+                reusedLibraries, hierarchy, uriTranslator, outputLibraries)
+            .toSet();
       }
 
+      List<String> problemsAsJson = reissueComponentProblems(componentWithDill);
+      reissueLibraryProblems(allLibraries, compiledLibraries);
+
       if (componentWithDill == null) {
         userCode.loader.builders.clear();
         userCode = userCodeOld;
@@ -289,31 +306,105 @@
       // This is the incremental component.
       return context.options.target.configureComponent(new Component(
           libraries: outputLibraries,
-          uriToSource: componentWithDill.uriToSource))
-        ..mainMethod = mainMethod;
+          uriToSource: componentWithDill?.uriToSource))
+        ..mainMethod = mainMethod
+        ..problemsAsJson = problemsAsJson;
     });
   }
 
-  List<Library> computeTransitiveClosure(
-      List<Library> inputLibraries,
-      Procedure mainMethod,
-      Uri entry,
-      List<LibraryBuilder> reusedLibraries,
-      ClassHierarchy hierarchy) {
-    List<Library> result = new List<Library>.from(inputLibraries);
-    Map<Uri, Library> libraryMap = <Uri, Library>{};
-    for (Library library in inputLibraries) {
-      libraryMap[library.importUri] = library;
+  void reissueLibraryProblems(
+      Set<Library> allLibraries, List<Library> compiledLibraries) {
+    // The newly-compiled libraries have issued problems already. Re-issue
+    // problems for the libraries that weren't re-compiled.
+    allLibraries.removeAll(compiledLibraries);
+    for (Library library in allLibraries) {
+      if (library.problemsAsJson?.isNotEmpty == true) {
+        for (String jsonString in library.problemsAsJson) {
+          DiagnosticMessageFromJson message =
+              new DiagnosticMessageFromJson.fromJson(jsonString);
+          context.options.reportDiagnosticMessage(message);
+        }
+      }
     }
-    List<Uri> worklist = new List<Uri>.from(libraryMap.keys);
-    worklist.add(mainMethod?.enclosingLibrary?.importUri);
-    if (entry != null) {
-      worklist.add(entry);
+  }
+
+  /// Re-issue problems on the component and return the filtered list.
+  List<String> reissueComponentProblems(Component componentWithDill) {
+    // These problems have already been reported.
+    Set<String> issuedProblems = new Set<String>();
+    if (componentWithDill.problemsAsJson != null) {
+      issuedProblems.addAll(componentWithDill.problemsAsJson);
     }
 
+    // Report old problems that wasn't reported again.
+    for (List<DiagnosticMessageFromJson> messages
+        in remainingComponentProblems.values) {
+      for (int i = 0; i < messages.length; i++) {
+        DiagnosticMessageFromJson message = messages[i];
+        if (issuedProblems.add(message.toJsonString())) {
+          context.options.reportDiagnosticMessage(message);
+        }
+      }
+    }
+
+    // Save any new component-problems.
+    if (componentWithDill.problemsAsJson != null) {
+      for (String jsonString in componentWithDill.problemsAsJson) {
+        DiagnosticMessageFromJson message =
+            new DiagnosticMessageFromJson.fromJson(jsonString);
+        List<DiagnosticMessageFromJson> messages =
+            remainingComponentProblems[message.uri] ??=
+                new List<DiagnosticMessageFromJson>();
+        messages.add(message);
+      }
+    }
+    return new List<String>.from(issuedProblems);
+  }
+
+  Uri getPartFileUri(
+      Uri parentFileUri, LibraryPart part, UriTranslator uriTranslator) {
+    Uri fileUri = parentFileUri.resolve(part.partUri);
+    if (fileUri.scheme == "package") {
+      // Part was specified via package URI and the resolve above thus
+      // did not go as expected. Translate the package URI to get the
+      // actual file URI.
+      fileUri = uriTranslator.translate(fileUri, false);
+    }
+    return fileUri;
+  }
+
+  /// Compute the transitive closure.
+  ///
+  /// As a side-effect, this also cleans-up now-unreferenced builders as well as
+  /// any saved component problems for such builders.
+  List<Library> computeTransitiveClosure(
+      List<Library> inputLibraries,
+      Uri entry,
+      List<LibraryBuilder> reusedLibraries,
+      ClassHierarchy hierarchy,
+      UriTranslator uriTranslator,
+      [List<Library> inputLibrariesFiltered]) {
+    List<Library> result = new List<Library>();
+    Map<Uri, Library> libraryMap = <Uri, Library>{};
     Map<Uri, Library> potentiallyReferencedLibraries = <Uri, Library>{};
+    Map<Uri, Library> potentiallyReferencedInputLibraries = <Uri, Library>{};
+    for (Library library in inputLibraries) {
+      libraryMap[library.importUri] = library;
+      if (library.importUri.scheme == "dart") {
+        result.add(library);
+        inputLibrariesFiltered?.add(library);
+      } else {
+        potentiallyReferencedLibraries[library.importUri] = library;
+        potentiallyReferencedInputLibraries[library.importUri] = library;
+      }
+    }
+
+    List<Uri> worklist = new List<Uri>();
+    worklist.add(entry);
     for (LibraryBuilder library in reusedLibraries) {
-      if (library.uri.scheme == "dart") continue;
+      if (library.uri.scheme == "dart" && !library.isSynthetic) {
+        continue;
+      }
       Library lib = library.target;
       potentiallyReferencedLibraries[library.uri] = lib;
       libraryMap[library.uri] = lib;
@@ -330,6 +421,9 @@
         Library library = potentiallyReferencedLibraries.remove(uri);
         if (library != null) {
           result.add(library);
+          if (potentiallyReferencedInputLibraries.remove(uri) != null) {
+            inputLibrariesFiltered?.add(library);
+          }
         }
       }
     }
@@ -343,6 +437,7 @@
         removedLibraries.add(lib);
         dillLoadedData.loader.builders.remove(uri);
         userBuilders?.remove(uri);
+        removeLibraryFromRemainingComponentProblems(lib, uriTranslator);
       }
     }
     hierarchy?.applyTreeChanges(removedLibraries, const []);
@@ -350,6 +445,16 @@
     return result;
   }
 
+  void removeLibraryFromRemainingComponentProblems(
+      Library lib, UriTranslator uriTranslator) {
+    remainingComponentProblems.remove(lib.fileUri);
+    // Remove parts too.
+    for (LibraryPart part in lib.parts) {
+      Uri partFileUri = getPartFileUri(lib.fileUri, part, uriTranslator);
+      remainingComponentProblems.remove(partFileUri);
+    }
+  }
+
   int prepareSummary(List<int> summaryBytes, UriTranslator uriTranslator,
       CompilerContext c, IncrementalCompilerData data) {
     dillLoadedData = new DillTarget(ticker, uriTranslator, c.options.target);
@@ -402,11 +507,25 @@
         bytesLength += initializationBytes.length;
         data.userLoadedUriMain = data.component.mainMethod;
         data.includeUserLoadedLibraries = true;
+        saveComponentProblems(data);
       }
     }
     return bytesLength;
   }
 
+  void saveComponentProblems(IncrementalCompilerData data) {
+    if (data.component.problemsAsJson != null) {
+      for (String jsonString in data.component.problemsAsJson) {
+        DiagnosticMessageFromJson message =
+            new DiagnosticMessageFromJson.fromJson(jsonString);
+        List<DiagnosticMessageFromJson> messages =
+            remainingComponentProblems[message.uri] ??=
+                new List<DiagnosticMessageFromJson>();
+        messages.add(message);
+      }
+    }
+  }
+
   // This procedure will set up compiler from [componentToInitializeFrom].
   void initializeFromComponent(UriTranslator uriTranslator, CompilerContext c,
       IncrementalCompilerData data) {
@@ -439,6 +558,7 @@
           ..mainMethod = componentToInitializeFrom.mainMethod;
     data.userLoadedUriMain = data.component.mainMethod;
     data.includeUserLoadedLibraries = true;
+    saveComponentProblems(data);
   }
 
   void appendLibraries(IncrementalCompilerData data, int bytesLength) {
@@ -586,7 +706,7 @@
     }
 
     addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library) {
-      if (uri.scheme == "dart") {
+      if (uri.scheme == "dart" && !library.isSynthetic) {
         result.add(library);
         return;
       }
@@ -604,13 +724,9 @@
       } else if (library is DillLibraryBuilder) {
         for (LibraryPart part in library.target.parts) {
           Uri partUri = library.uri.resolve(part.partUri);
-          Uri fileUri = library.library.fileUri.resolve(part.partUri);
-          if (fileUri.scheme == "package") {
-            // Part was specified via package URI and the resolve above thus
-            // did not go as expected. Translate the package URI to get the
-            // actual file URI.
-            fileUri = uriTranslator.translate(partUri, false);
-          }
+          Uri fileUri =
+              getPartFileUri(library.library.fileUri, part, uriTranslator);
+
           if (isInvalidated(partUri, fileUri)) {
             invalidatedImportUris.add(partUri);
             builders[partUri] = library;
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 d023620..d526ee2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -862,8 +862,14 @@
       builder.body = body;
     } else {
       if (body != null) {
-        builder.body =
-            wrapInProblemStatement(body, fasta.messageExternalMethodWithBody);
+        builder.body = new Block(<Statement>[
+          new ExpressionStatementJudgment(desugarSyntheticExpression(
+              buildProblem(fasta.messageExternalMethodWithBody, body.fileOffset,
+                  noLength)))
+            ..fileOffset = body.fileOffset,
+          body,
+        ])
+          ..fileOffset = body.fileOffset;
       }
     }
     Member target = builder.target;
@@ -1118,7 +1124,8 @@
       // TODO(ahe): Change this to a null check.
       int offset = builder.body?.fileOffset ?? builder.charOffset;
       constructor.initializers.add(buildInvalidInitializer(
-          buildProblem(fasta.messageConstructorNotSync, offset, noLength),
+          desugarSyntheticExpression(
+              buildProblem(fasta.messageConstructorNotSync, offset, noLength)),
           offset));
     }
     if (needsImplicitSuperInitializer) {
@@ -2234,10 +2241,47 @@
   }
 
   @override
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
+    push(forKeyword);
+    push(leftParen);
+    push(leftSeparator);
+    push(updateExpressionCount);
+  }
+
+  @override
+  void endForControlFlow(Token token) {
+    debugEvent("endForControlFlow");
+    // TODO(danrubel) implement control flow support
+    var entry = pop();
+
+    int updateExpressionCount = pop();
+    pop(); // left separator
+    pop(); // left parenthesis
+    Token forToken = pop();
+
+    popListForEffect(updateExpressionCount); // updates
+    popStatement(); // condition
+    Object variableOrExpression = pop();
+    buildVariableDeclarations(variableOrExpression); // variables
+
+    push(entry); // push the entry back on the stack and drop the rest
+    handleRecoverableError(
+        fasta.templateUnexpectedToken.withArguments(forToken),
+        forToken,
+        forToken);
+  }
+
+  @override
+  void endForStatement(Token endToken) {
     debugEvent("ForStatement");
     Statement body = popStatement();
+
+    int updateExpressionCount = pop();
+    Token leftSeparator = pop();
+    Token leftParen = pop();
+    Token forKeyword = pop();
+
     List<Expression> updates = popListForEffect(updateExpressionCount);
     Statement conditionStatement = popStatement();
     Object variableOrExpression = pop();
@@ -2361,42 +2405,19 @@
         rightBrace);
     library.checkBoundsInSetLiteral(node, typeEnvironment);
     if (!library.loader.target.enableSetLiterals) {
-      node = wrapInProblem(node, fasta.messageSetLiteralsNotSupported,
-          lengthOfSpan(leftBrace, leftBrace.endGroup));
+      internalProblem(
+          fasta.messageSetLiteralsNotSupported, node.fileOffset, uri);
+      return;
     }
     push(node);
   }
 
   @override
-  void handleEmptyLiteralSetOrMap(
-      Token leftBrace, Token constKeyword, Token rightBrace) {
-    debugEvent("EmptyLiteralSetOrMap");
+  void handleLiteralSetOrMap(
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    debugEvent("LiteralSetOrMap");
     // Treat as map literal - type inference will find the right type.
-    List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
-    assert(typeArguments == null || typeArguments.length > 2);
-    if (typeArguments != null && typeArguments.length > 2) {
-      if (library.loader.target.enableSetLiterals) {
-        addProblem(
-            fasta.messageSetOrMapLiteralTooManyTypeArguments,
-            offsetForToken(leftBrace),
-            lengthOfSpan(leftBrace, leftBrace.endGroup));
-      } else {
-        addProblem(
-            fasta.messageMapLiteralTypeArgumentMismatch,
-            offsetForToken(leftBrace),
-            lengthOfSpan(leftBrace, leftBrace.endGroup));
-      }
-    }
-    DartType implicitTypeArgument = this.implicitTypeArgument;
-    push(forest.literalMap(
-        constKeyword,
-        constKeyword != null || constantContext == ConstantContext.inferred,
-        implicitTypeArgument,
-        implicitTypeArgument,
-        null,
-        leftBrace,
-        <MapEntry>[],
-        rightBrace));
+    handleLiteralMap(count, leftBrace, constKeyword, rightBrace);
   }
 
   @override
@@ -2423,8 +2444,17 @@
   void handleLiteralMap(
       int count, Token leftBrace, Token constKeyword, Token rightBrace) {
     debugEvent("LiteralMap");
-    List<MapEntry> entries =
-        const GrowableList<MapEntry>().pop(stack, count) ?? <MapEntry>[];
+
+    // TODO(danrubel): Revise once spread collection entries are supported.
+    // For now, drop those on the floor
+    // as error(s) have already been reported in handleSpreadExpression.
+    List<MapEntry> entries = <MapEntry>[];
+    const FixedNullableList<dynamic>().pop(stack, count)?.forEach((entry) {
+      if (entry is MapEntry) {
+        entries.add(entry);
+      }
+    });
+
     List<UnresolvedType<KernelTypeBuilder>> typeArguments = pop();
     DartType keyType;
     DartType valueType;
@@ -3495,6 +3525,12 @@
       } else {
         errorName ??= debugName(type.name, name);
       }
+    } else if (type is InvalidTypeBuilder<TypeBuilder, Object>) {
+      LocatedMessage message = type.message;
+      return evaluateArgumentsBefore(
+          arguments,
+          buildProblem(message.messageObject, nameToken.charOffset,
+              nameToken.lexeme.length));
     } else {
       errorName = debugName(getNodeName(type), name);
     }
@@ -3518,6 +3554,46 @@
         token.next, token.offset, Constness.explicitConst);
   }
 
+  void beginIfControlFlow(Token ifToken) {
+    // TODO(danrubel): remove this when control flow support is added
+    push(ifToken);
+  }
+
+  @override
+  void endIfControlFlow(Token token) {
+    debugEvent("endIfControlFlow");
+    // TODO(danrubel) implement control flow support
+    var entry = pop();
+    pop(); // parenthesized expression
+    Token ifToken = pop();
+    push(entry); // push the entry back on the stack and drop the rest
+    handleRecoverableError(
+        fasta.templateUnexpectedToken.withArguments(ifToken), ifToken, ifToken);
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    debugEvent("endIfElseControlFlow");
+    // TODO(danrubel) implement control flow support
+    pop(); // else entry
+    var entry = pop(); // then entry
+    pop(); // parenthesized expression
+    Token ifToken = pop();
+    push(entry); // push the entry back on the stack and drop the rest
+    handleRecoverableError(
+        fasta.templateUnexpectedToken.withArguments(ifToken), ifToken, ifToken);
+  }
+
+  @override
+  void handleSpreadExpression(Token spreadToken) {
+    debugEvent("SpreadExpression");
+    // TODO(danrubel) implement spread expression support
+    handleRecoverableError(
+        fasta.templateUnexpectedToken.withArguments(spreadToken),
+        spreadToken,
+        spreadToken);
+  }
+
   @override
   void endTypeArguments(int count, Token beginToken, Token endToken) {
     debugEvent("TypeArguments");
@@ -3797,10 +3873,42 @@
   }
 
   @override
-  void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
-      Token inKeyword, Token endToken) {
+  void handleForInLoopParts(Token awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {
+    push(awaitToken ?? NullValue.AwaitToken);
+    push(forToken);
+    push(inKeyword);
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    debugEvent("endForInControlFlow");
+    // TODO(danrubel) implement control flow support
+    var entry = pop();
+
+    pop(); // `in` keyword
+    Token forToken = pop();
+    pop(NullValue.AwaitToken); // await token
+
+    popForValue(); // expression
+    pop(); // lvalue
+
+    push(entry); // push the entry back on the stack and drop the rest
+    handleRecoverableError(
+        fasta.templateUnexpectedToken.withArguments(forToken),
+        forToken,
+        forToken);
+  }
+
+  @override
+  void endForIn(Token endToken) {
     debugEvent("ForIn");
     Statement body = popStatement();
+
+    Token inKeyword = pop();
+    Token forToken = pop();
+    Token awaitToken = pop(NullValue.AwaitToken);
+
     Expression expression = popForValue();
     Object lvalue = pop();
     exitLocalScope();
@@ -4454,16 +4562,17 @@
     // TODO(ahe): The following doesn't make sense to Analyzer AST.
     Declaration constructor =
         library.loader.getAbstractClassInstantiationError();
-    return forest.throwExpression(
-        null,
-        buildStaticInvocation(
-            constructor.target,
-            forest.arguments(<Expression>[
-              forest.literalString(className, null)..fileOffset = charOffset
-            ], noLocation)
-              ..fileOffset = charOffset,
-            charOffset: charOffset))
-      ..fileOffset = charOffset;
+    Expression invocation = buildStaticInvocation(
+        constructor.target,
+        forest.arguments(<Expression>[
+          forest.literalString(className, null)..fileOffset = charOffset
+        ], noLocation)
+          ..fileOffset = charOffset,
+        charOffset: charOffset);
+    if (invocation is shadow.SyntheticExpressionJudgment) {
+      invocation = desugarSyntheticExpression(invocation);
+    }
+    return forest.throwExpression(null, invocation)..fileOffset = charOffset;
   }
 
   Statement buildProblemStatement(Message message, int charOffset,
@@ -4558,20 +4667,22 @@
             ]);
         Declaration constructor =
             library.loader.getDuplicatedFieldInitializerError();
+        Expression invocation = buildStaticInvocation(
+            constructor.target,
+            forest.arguments(<Expression>[
+              forest.literalString(name, null)..fileOffset = assignmentOffset
+            ], noLocation)
+              ..fileOffset = assignmentOffset,
+            charOffset: assignmentOffset);
+        if (invocation is shadow.SyntheticExpressionJudgment) {
+          invocation = desugarSyntheticExpression(invocation);
+        }
         return new ShadowInvalidFieldInitializer(
             builder.field,
             expression,
-            new VariableDeclaration.forValue(forest.throwExpression(
-                null,
-                buildStaticInvocation(
-                    constructor.target,
-                    forest.arguments(<Expression>[
-                      forest.literalString(name, null)
-                        ..fileOffset = assignmentOffset
-                    ], noLocation)
-                      ..fileOffset = assignmentOffset,
-                    charOffset: assignmentOffset))
-              ..fileOffset = assignmentOffset))
+            new VariableDeclaration.forValue(
+                forest.throwExpression(null, invocation)
+                  ..fileOffset = assignmentOffset))
           ..fileOffset = assignmentOffset;
       } else {
         if (!legacyMode &&
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 505559d..89f7efa 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
@@ -5,18 +5,37 @@
 library fasta.class_hierarchy_builder;
 
 import 'package:kernel/ast.dart'
-    show Library, Member, Name, Procedure, ProcedureKind;
+    show
+        Class,
+        DartType,
+        InterfaceType,
+        TypeParameter,
+        Library,
+        Member,
+        Name,
+        Procedure,
+        ProcedureKind,
+        Supertype;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
+import 'package:kernel/core_types.dart' show CoreTypes;
+
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+import '../loader.dart' show Loader;
+
 import '../messages.dart'
     show
         LocatedMessage,
+        Message,
         messageDeclaredMemberConflictsWithInheritedMember,
         messageDeclaredMemberConflictsWithInheritedMemberCause,
         messageInheritedMembersConflict,
         messageInheritedMembersConflictCause1,
         messageInheritedMembersConflictCause2,
+        messageStaticAndInstanceConflict,
+        messageStaticAndInstanceConflictCause,
         templateDuplicatedDeclaration,
         templateDuplicatedDeclarationCause,
         templateMissingImplementationCause,
@@ -26,13 +45,28 @@
 
 import '../scope.dart' show Scope;
 
+import '../type_inference/standard_bounds.dart' show StandardBounds;
+
+import '../type_inference/type_constraint_gatherer.dart'
+    show TypeConstraintGatherer;
+
+import '../type_inference/type_inferrer.dart' show MixinInferrer;
+
+import '../type_inference/type_schema.dart' show UnknownType;
+
+import '../type_inference/type_schema_environment.dart' show TypeConstraint;
+
 import 'kernel_builder.dart'
     show
         Declaration,
-        LibraryBuilder,
         KernelClassBuilder,
         KernelNamedTypeBuilder,
-        KernelTypeBuilder;
+        KernelTypeBuilder,
+        LibraryBuilder,
+        TypeBuilder,
+        TypeVariableBuilder;
+
+import 'types.dart' show Types;
 
 int compareDeclarations(Declaration a, Declaration b) {
   return ClassHierarchy.compareMembers(a.target, b.target);
@@ -54,9 +88,13 @@
 /// Language Specification](
 /// ../../../../../../docs/language/dartLangSpec.tex#classMemberConflicts).
 bool isInheritanceConflict(Declaration a, Declaration b) {
+  if (a.isStatic) return true;
+  if (memberKind(a.target) == memberKind(b.target)) return false;
   if (a.isField) return !(b.isField || b.isGetter || b.isSetter);
   if (b.isField) return !(a.isField || a.isGetter || a.isSetter);
-  return memberKind(a.target) != memberKind(b.target);
+  if (a.isSetter) return !(b.isGetter || b.isSetter);
+  if (b.isSetter) return !(a.isGetter || a.isSetter);
+  return true;
 }
 
 bool impliesSetter(Declaration declaration) {
@@ -64,19 +102,130 @@
 }
 
 class ClassHierarchyBuilder {
-  final Map<KernelClassBuilder, ClassHierarchyNode> nodes =
-      <KernelClassBuilder, ClassHierarchyNode>{};
+  final Map<Class, ClassHierarchyNode> nodes = <Class, ClassHierarchyNode>{};
 
   final KernelClassBuilder objectClass;
 
+  final Loader<Library> loader;
+
+  final Class objectKernelClass;
+
+  final Class futureKernelClass;
+
+  final Class futureOrKernelClass;
+
+  final Class functionKernelClass;
+
+  final Class nullKernelClass;
+
+  // TODO(ahe): Remove this.
+  final CoreTypes coreTypes;
+
+  Types types;
+
+  ClassHierarchyBuilder(this.objectClass, this.loader, this.coreTypes)
+      : objectKernelClass = objectClass.target,
+        futureKernelClass = coreTypes.futureClass,
+        futureOrKernelClass = coreTypes.futureOrClass,
+        functionKernelClass = coreTypes.functionClass,
+        nullKernelClass = coreTypes.nullClass {
+    types = new Types(this);
+  }
+
+  ClassHierarchyNode getNodeFromClass(KernelClassBuilder cls) {
+    return nodes[cls.target] ??=
+        new ClassHierarchyNodeBuilder(this, cls).build();
+  }
+
+  ClassHierarchyNode getNodeFromType(KernelTypeBuilder type) {
+    Declaration declaration = type.declaration;
+    return declaration is KernelClassBuilder
+        ? getNodeFromClass(declaration)
+        : null;
+  }
+
+  ClassHierarchyNode getNodeFromKernelClass(Class cls) {
+    return nodes[cls] ??
+        getNodeFromClass(loader.computeClassBuilderFromTargetClass(cls));
+  }
+
+  KernelTypeBuilder asSupertypeOf(Class cls, Class supertype) {
+    ClassHierarchyNode clsNode = getNodeFromKernelClass(cls);
+    if (cls == supertype) {
+      return new KernelNamedTypeBuilder(clsNode.cls.name, null)
+        ..bind(clsNode.cls);
+    }
+    ClassHierarchyNode supertypeNode = getNodeFromKernelClass(supertype);
+    List<KernelTypeBuilder> supertypes = clsNode.superclasses;
+    int depth = supertypeNode.depth;
+    Declaration supertypeDeclaration = supertypeNode.cls;
+    if (depth < supertypes.length) {
+      KernelTypeBuilder asSupertypeOf = supertypes[depth];
+      if (asSupertypeOf.declaration == supertypeDeclaration)
+        return asSupertypeOf;
+    }
+    supertypes = clsNode.interfaces;
+    for (int i = 0; i < supertypes.length; i++) {
+      KernelTypeBuilder type = supertypes[i];
+      if (type.declaration == supertypeDeclaration) return type;
+    }
+    return null;
+  }
+
+  InterfaceType getKernelTypeAsInstanceOf(
+      InterfaceType type, Class superclass) {
+    Class kernelClass = type.classNode;
+    if (kernelClass == superclass) return type;
+    if (kernelClass == nullKernelClass) {
+      if (superclass.typeParameters.isEmpty) {
+        return superclass.rawType;
+      } else {
+        // This is a safe fall-back for dealing with `Null`. It will likely be
+        // faster to check for `Null` before calling this method.
+        return new InterfaceType(
+            superclass,
+            new List<DartType>.filled(
+                superclass.typeParameters.length, nullKernelClass.rawType));
+      }
+    }
+    KernelNamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass);
+    if (supertype == null) return null;
+    if (supertype.arguments == null) return superclass.rawType;
+    return Substitution.fromInterfaceType(type)
+        .substituteType(supertype.build(null));
+  }
+
+  static ClassHierarchyBuilder build(
+      KernelClassBuilder objectClass,
+      List<KernelClassBuilder> classes,
+      Loader<Object> loader,
+      CoreTypes coreTypes) {
+    ClassHierarchyBuilder hierarchy =
+        new ClassHierarchyBuilder(objectClass, loader, coreTypes);
+    for (int i = 0; i < classes.length; i++) {
+      KernelClassBuilder cls = classes[i];
+      hierarchy.nodes[cls.target] =
+          new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+    }
+    return hierarchy;
+  }
+}
+
+class ClassHierarchyNodeBuilder {
+  final ClassHierarchyBuilder hierarchy;
+
+  final KernelClassBuilder cls;
+
   bool hasNoSuchMethod = false;
 
   List<Declaration> abstractMembers = null;
 
-  ClassHierarchyBuilder(this.objectClass);
+  ClassHierarchyNodeBuilder(this.hierarchy, this.cls);
 
-  /// A merge conflict arises when merging two lists that each have an element
-  /// with the same name.
+  KernelClassBuilder get objectClass => hierarchy.objectClass;
+
+  /// When merging `aList` and `bList`, [a] (from `aList`) and [b] (from
+  /// `bList`) each have the same name.
   ///
   /// If [mergeKind] is `MergeKind.superclass`, [a] should override [b].
   ///
@@ -93,10 +242,11 @@
       return a;
     }
     if (isInheritanceConflict(a, b)) {
-      reportInheritanceConflict(cls, a, b, mergeKind);
+      reportInheritanceConflict(cls, a, b);
     }
     Declaration result = a;
-    if (mergeKind == MergeKind.interfaces) {
+    if (mergeKind == MergeKind.accessors) {
+    } else if (mergeKind == MergeKind.interfaces) {
       // TODO(ahe): Combine the signatures of a and b.  See the section named
       // "Combined Member Signatures" in [Dart Programming Language
       // Specification](
@@ -120,28 +270,65 @@
     return result;
   }
 
-  void reportInheritanceConflict(KernelClassBuilder cls, Declaration a,
-      Declaration b, MergeKind mergeKind) {
+  void reportInheritanceConflict(
+      KernelClassBuilder cls, Declaration a, Declaration b) {
     String name = a.fullNameForErrors;
-    if (mergeKind == MergeKind.interfaces) {
-      cls.addProblem(messageInheritedMembersConflict, cls.charOffset,
-          cls.fullNameForErrors.length,
+    if (a.parent != b.parent) {
+      if (a.parent == cls) {
+        cls.addProblem(messageDeclaredMemberConflictsWithInheritedMember,
+            a.charOffset, name.length,
+            context: <LocatedMessage>[
+              messageDeclaredMemberConflictsWithInheritedMemberCause
+                  .withLocation(b.fileUri, b.charOffset, name.length)
+            ]);
+      } else {
+        cls.addProblem(messageInheritedMembersConflict, cls.charOffset,
+            cls.fullNameForErrors.length,
+            context: inheritedConflictContext(a, b));
+      }
+    } else if (a.isStatic != b.isStatic) {
+      Declaration staticMember;
+      Declaration instanceMember;
+      if (a.isStatic) {
+        staticMember = a;
+        instanceMember = b;
+      } else {
+        staticMember = b;
+        instanceMember = a;
+      }
+      cls.library.addProblem(messageStaticAndInstanceConflict,
+          staticMember.charOffset, name.length, staticMember.fileUri,
           context: <LocatedMessage>[
-            messageInheritedMembersConflictCause1.withLocation(
-                a.fileUri, a.charOffset, name.length),
-            messageInheritedMembersConflictCause2.withLocation(
-                b.fileUri, b.charOffset, name.length),
+            messageStaticAndInstanceConflictCause.withLocation(
+                instanceMember.fileUri, instanceMember.charOffset, name.length)
           ]);
     } else {
-      cls.addProblem(messageDeclaredMemberConflictsWithInheritedMember,
-          a.charOffset, name.length,
+      // This message can be reported twice (when merging localMembers with
+      // classSetters, or localSetters with classMembers). By ensuring that
+      // we always report the one with higher charOffset as the duplicate,
+      // the message duplication logic ensures that we only report this
+      // problem once.
+      Declaration existing;
+      Declaration duplicate;
+      assert(a.fileUri == b.fileUri);
+      if (a.charOffset < b.charOffset) {
+        existing = a;
+        duplicate = b;
+      } else {
+        existing = b;
+        duplicate = a;
+      }
+      cls.library.addProblem(templateDuplicatedDeclaration.withArguments(name),
+          duplicate.charOffset, name.length, duplicate.fileUri,
           context: <LocatedMessage>[
-            messageDeclaredMemberConflictsWithInheritedMemberCause.withLocation(
-                b.fileUri, b.charOffset, name.length)
+            templateDuplicatedDeclarationCause.withArguments(name).withLocation(
+                existing.fileUri, existing.charOffset, name.length)
           ]);
     }
   }
 
+  /// When merging `aList` and `bList`, [member] was only found in `aList`.
+  ///
   /// If [mergeKind] is `MergeKind.superclass` [member] is declared in current
   /// class, and isn't overriding a method from the superclass.
   ///
@@ -150,12 +337,13 @@
   /// If [mergeKind] is `MergeKind.supertypes`, [member] isn't
   /// implementing/overriding anything.
   void handleOnlyA(Declaration member, MergeKind mergeKind) {
-    Member target = member.target;
-    if (mergeKind == MergeKind.superclass && target.isAbstract) {
+    if (mergeKind == MergeKind.superclass && member.target.isAbstract) {
       (abstractMembers ??= <Declaration>[]).add(member);
     }
   }
 
+  /// When merging `aList` and `bList`, [member] was only found in `bList`.
+  ///
   /// If [mergeKind] is `MergeKind.superclass` [member] is being inherited from
   /// a superclass.
   ///
@@ -179,79 +367,159 @@
     }
   }
 
-  void add(KernelClassBuilder cls) {
-    assert(!hasNoSuchMethod);
-    assert(abstractMembers == null);
+  ClassHierarchyNode build() {
     if (cls.isPatch) {
       // TODO(ahe): What about patch classes. Have we injected patched members
       // into the class-builder's scope?
-      return;
+      return null;
     }
     ClassHierarchyNode supernode;
     if (objectClass != cls) {
-      supernode = getNode(cls.supertype);
+      supernode = hierarchy.getNodeFromType(cls.supertype);
       if (supernode == null) {
-        supernode = nodes[objectClass];
-        if (supernode == null) {
-          add(objectClass);
-          supernode = nodes[objectClass];
-        }
+        supernode = hierarchy.getNodeFromClass(objectClass);
       }
       assert(supernode != null);
     }
 
     Scope scope = cls.scope;
     if (cls.isMixinApplication) {
-      Declaration mixin = getDeclaration(cls.mixedInType);
+      Declaration mixin = cls.mixedInType.declaration;
+      inferMixinApplication();
+      while (mixin.isNamedMixinApplication) {
+        KernelClassBuilder named = mixin;
+        mixin = named.mixedInType.declaration;
+      }
       if (mixin is KernelClassBuilder) {
-        scope = mixin.scope;
+        scope = mixin.scope.computeMixinScope();
       }
     }
-    // TODO(ahe): Consider if removing static members from [localMembers] and
-    // [localSetters] makes sense. It depends on what semantic checks we need
-    // to perform with respect to static members and inherited members with the
-    // same name.
+
+    /// Members (excluding setters) declared in [cls].
     List<Declaration> localMembers =
         new List<Declaration>.from(scope.local.values)
           ..sort(compareDeclarations);
+
+    /// Setters declared in [cls].
     List<Declaration> localSetters =
         new List<Declaration>.from(scope.setters.values)
           ..sort(compareDeclarations);
+
+    // Add implied setters from fields in [localMembers].
     localSetters = mergeAccessors(cls, localMembers, localSetters);
+
+    /// Members (excluding setters) declared in [cls] or its superclasses. This
+    /// includes static methods of [cls], but not its superclasses.
     List<Declaration> classMembers;
+
+    /// Setters declared in [cls] or its superclasses. This includes static
+    /// setters of [cls], but not its superclasses.
     List<Declaration> classSetters;
+
+    /// Members (excluding setters) inherited from interfaces. This contains no static
+    /// members. Is null if no interfaces are implemented by this class or its
+    /// superclasses.
     List<Declaration> interfaceMembers;
+
+    /// Setters inherited from interfaces. This contains no static setters. Is
+    /// null if no interfaces are implemented by this class or its
+    /// superclasses.
     List<Declaration> interfaceSetters;
+
+    List<KernelTypeBuilder> superclasses;
+
+    List<KernelTypeBuilder> interfaces;
+
     if (supernode == null) {
       // This should be Object.
       classMembers = localMembers;
       classSetters = localSetters;
+      superclasses = new List<KernelTypeBuilder>(0);
+      interfaces = new List<KernelTypeBuilder>(0);
     } else {
+      superclasses =
+          new List<KernelTypeBuilder>(supernode.superclasses.length + 1);
+      superclasses.setRange(0, superclasses.length - 1,
+          substSupertypes(cls.supertype, supernode.superclasses));
+      superclasses[superclasses.length - 1] = cls.supertype;
+
       classMembers = merge(
           cls, localMembers, supernode.classMembers, MergeKind.superclass);
       classSetters = merge(
           cls, localSetters, supernode.classSetters, MergeKind.superclass);
-      List<KernelTypeBuilder> interfaces = cls.interfaces;
-      if (interfaces != null) {
-        MergeResult result = mergeInterfaces(cls, supernode, interfaces);
+
+      // Check if local members conflict with inherited setters. This check has
+      // already been performed in the superclass, so we only need to check the
+      // local members.
+      merge(cls, localMembers, classSetters, MergeKind.accessors);
+
+      // Check if local setters conflict with inherited members. As above, we
+      // only need to check the local setters.
+      merge(cls, localSetters, classMembers, MergeKind.accessors);
+
+      List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+      if (cls.isMixinApplication) {
+        if (directInterfaces == null) {
+          directInterfaces = <KernelTypeBuilder>[cls.mixedInType];
+        } else {
+          directInterfaces = <KernelTypeBuilder>[cls.mixedInType]
+            ..addAll(directInterfaces);
+        }
+      }
+      if (directInterfaces != null) {
+        MergeResult result = mergeInterfaces(cls, supernode, directInterfaces);
         interfaceMembers = result.mergedMembers;
         interfaceSetters = result.mergedSetters;
+        interfaces = <KernelTypeBuilder>[];
+        if (supernode.interfaces != null) {
+          List<KernelTypeBuilder> types =
+              substSupertypes(cls.supertype, supernode.interfaces);
+          for (int i = 0; i < types.length; i++) {
+            addInterface(interfaces, superclasses, types[i]);
+          }
+        }
+        for (int i = 0; i < directInterfaces.length; i++) {
+          addInterface(interfaces, superclasses, directInterfaces[i]);
+          ClassHierarchyNode interfaceNode =
+              hierarchy.getNodeFromType(directInterfaces[i]);
+          if (interfaceNode != null) {
+            List<KernelTypeBuilder> types = substSupertypes(
+                directInterfaces[i], interfaceNode.superclasses);
+            for (int i = 0; i < types.length; i++) {
+              addInterface(interfaces, superclasses, types[i]);
+            }
+
+            if (interfaceNode.interfaces != null) {
+              List<KernelTypeBuilder> types = substSupertypes(
+                  directInterfaces[i], interfaceNode.interfaces);
+              for (int i = 0; i < types.length; i++) {
+                addInterface(interfaces, superclasses, types[i]);
+              }
+            }
+          }
+        }
       } else {
         interfaceMembers = supernode.interfaceMembers;
         interfaceSetters = supernode.interfaceSetters;
+        interfaces = supernode.interfaces;
       }
       if (interfaceMembers != null) {
         interfaceMembers =
             merge(cls, classMembers, interfaceMembers, MergeKind.supertypes);
+
+        // Check if class setters conflict with members inherited from
+        // interfaces.
+        merge(cls, classSetters, interfaceMembers, MergeKind.accessors);
       }
-      if (interfaceMembers != null) {
+      if (interfaceSetters != null) {
         interfaceSetters =
             merge(cls, classSetters, interfaceSetters, MergeKind.supertypes);
+
+        // Check if class members conflict with setters inherited from
+        // interfaces.
+        merge(cls, classMembers, interfaceSetters, MergeKind.accessors);
       }
     }
-    nodes[cls] = new ClassHierarchyNode(cls, scope, classMembers, classSetters,
-        interfaceMembers, interfaceSetters);
-
     if (abstractMembers != null && !cls.isAbstract) {
       if (!hasNoSuchMethod) {
         reportMissingMembers(cls);
@@ -259,8 +527,75 @@
         installNsmHandlers(cls);
       }
     }
-    hasNoSuchMethod = false;
-    abstractMembers = null;
+    return new ClassHierarchyNode(
+      cls,
+      classMembers,
+      classSetters,
+      interfaceMembers,
+      interfaceSetters,
+      superclasses,
+      interfaces,
+    );
+  }
+
+  List<KernelTypeBuilder> substSupertypes(
+      KernelNamedTypeBuilder supertype, List<KernelTypeBuilder> supertypes) {
+    Declaration declaration = supertype.declaration;
+    if (declaration is! KernelClassBuilder) return supertypes;
+    KernelClassBuilder cls = declaration;
+    List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
+        cls.typeVariables;
+    if (typeVariables == null) return supertypes;
+    Map<TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder> substitution =
+        <TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder>{};
+    List<KernelTypeBuilder> arguments =
+        supertype.arguments ?? computeDefaultTypeArguments(supertype);
+    for (int i = 0; i < typeVariables.length; i++) {
+      substitution[typeVariables[i]] = arguments[i];
+    }
+    List<KernelTypeBuilder> result;
+    for (int i = 0; i < supertypes.length; i++) {
+      KernelTypeBuilder supertype = supertypes[i];
+      KernelTypeBuilder substed = supertype.subst(substitution);
+      if (supertype != substed) {
+        result ??= supertypes.toList();
+        result[i] = substed;
+      }
+    }
+    return result ?? supertypes;
+  }
+
+  List<KernelTypeBuilder> computeDefaultTypeArguments(KernelTypeBuilder type) {
+    KernelClassBuilder cls = type.declaration;
+    List<KernelTypeBuilder> result =
+        new List<KernelTypeBuilder>(cls.typeVariables.length);
+    for (int i = 0; i < result.length; ++i) {
+      result[i] = cls.typeVariables[i].defaultType;
+    }
+    return result;
+  }
+
+  KernelTypeBuilder addInterface(List<KernelTypeBuilder> interfaces,
+      List<KernelTypeBuilder> superclasses, KernelTypeBuilder type) {
+    ClassHierarchyNode node = hierarchy.getNodeFromType(type);
+    if (node == null) return null;
+    int depth = node.depth;
+    int myDepth = superclasses.length;
+    if (depth < myDepth && superclasses[depth].declaration == node.cls) {
+      // This is a potential conflict.
+      return superclasses[depth];
+    } else {
+      for (int i = 0; i < interfaces.length; i++) {
+        // This is a quadratic algorithm, but normally, the number of
+        // interfaces is really small.
+        if (interfaces[i].declaration == type.declaration) {
+          // This is a potential conflict.
+          return interfaces[i];
+        }
+      }
+    }
+    interfaces.add(type);
+    return null;
   }
 
   MergeResult mergeInterfaces(KernelClassBuilder cls,
@@ -272,7 +607,8 @@
     memberLists[0] = supernode.interfaceMembers;
     setterLists[0] = supernode.interfaceSetters;
     for (int i = 0; i < interfaces.length; i++) {
-      ClassHierarchyNode interfaceNode = getNode(interfaces[i]);
+      ClassHierarchyNode interfaceNode =
+          hierarchy.getNodeFromType(interfaces[i]);
       if (interfaceNode == null) {
         memberLists[i + 1] = null;
         setterLists[i + 1] = null;
@@ -329,21 +665,6 @@
       final Declaration setter = setters[j];
       final int compare = compareDeclarations(member, setter);
       if (compare == 0) {
-        if (member.isField ? impliesSetter(member) : !member.isGetter) {
-          // [member] conflicts with [setter].
-          final String name = member.fullNameForErrors;
-          cls.library.addProblem(
-              templateDuplicatedDeclaration.withArguments(name),
-              setter.charOffset,
-              name.length,
-              setter.fileUri,
-              context: <LocatedMessage>[
-                templateDuplicatedDeclarationCause
-                    .withArguments(name)
-                    .withLocation(
-                        member.fileUri, member.charOffset, name.length)
-              ]);
-        }
         mergedSetters[storeIndex++] = setter;
         i++;
         j++;
@@ -410,29 +731,6 @@
     // TOOD(ahe): Implement this.
   }
 
-  ClassHierarchyNode getNode(KernelTypeBuilder type) {
-    Declaration declaration = getDeclaration(type);
-    if (declaration is KernelClassBuilder) {
-      ClassHierarchyNode node = nodes[declaration];
-      if (node == null) {
-        bool savedHasNoSuchMethod = hasNoSuchMethod;
-        hasNoSuchMethod = false;
-        List<Declaration> savedAbstractMembers = abstractMembers;
-        abstractMembers = null;
-        add(declaration);
-        hasNoSuchMethod = savedHasNoSuchMethod;
-        abstractMembers = savedAbstractMembers;
-        node = nodes[declaration];
-      }
-      return node;
-    }
-    return null;
-  }
-
-  Declaration getDeclaration(KernelTypeBuilder type) {
-    return type is KernelNamedTypeBuilder ? type.declaration : null;
-  }
-
   List<Declaration> merge(KernelClassBuilder cls, List<Declaration> aList,
       List<Declaration> bList, MergeKind mergeKind) {
     final List<Declaration> result = new List<Declaration>.filled(
@@ -444,7 +742,7 @@
     while (i < aList.length && j < bList.length) {
       final Declaration a = aList[i];
       final Declaration b = bList[j];
-      if (a.isStatic) {
+      if (mergeKind == MergeKind.interfaces && a.isStatic) {
         i++;
         continue;
       }
@@ -469,7 +767,7 @@
     }
     while (i < aList.length) {
       final Declaration a = aList[i];
-      if (!a.isStatic) {
+      if (mergeKind != MergeKind.interfaces || !a.isStatic) {
         handleOnlyA(a, mergeKind);
         result[storeIndex++] = a;
       }
@@ -483,21 +781,39 @@
       }
       j++;
     }
+    if (aList.isEmpty && storeIndex == bList.length) return bList;
+    if (bList.isEmpty && storeIndex == aList.length) return aList;
     return result..length = storeIndex;
   }
+
+  void inferMixinApplication() {
+    if (!hierarchy.loader.target.backendTarget.legacyMode) return;
+    Class kernelClass = cls.target;
+    Supertype kernelMixedInType = kernelClass.mixedInType;
+    if (kernelMixedInType == null) return;
+    List<DartType> typeArguments = kernelMixedInType.typeArguments;
+    if (typeArguments.isEmpty || typeArguments.first is! UnknownType) return;
+    new BuilderMixinInferrer(
+            cls,
+            hierarchy.coreTypes,
+            new TypeBuilderConstraintGatherer(
+                hierarchy, kernelMixedInType.classNode.typeParameters))
+        .infer(kernelClass);
+    List<KernelTypeBuilder> inferredArguments =
+        new List<KernelTypeBuilder>(typeArguments.length);
+    for (int i = 0; i < typeArguments.length; i++) {
+      inferredArguments[i] =
+          hierarchy.loader.computeTypeBuilder(typeArguments[i]);
+    }
+    KernelNamedTypeBuilder mixedInType = cls.mixedInType;
+    mixedInType.arguments = inferredArguments;
+  }
 }
 
 class ClassHierarchyNode {
   /// The class corresponding to this hierarchy node.
   final KernelClassBuilder cls;
 
-  /// The local members of [cls]. For regular classes, this is simply
-  /// `cls.scope`, but for mixin-applications this is the mixed-in type's
-  /// scope. The members are sorted in order of declaration.
-  // TODO(ahe): Do we need to copy the scope from the mixed-in type to remove
-  // static members?
-  final Scope localMembers;
-
   /// All the members of this class including [classMembers] of its
   /// superclasses. The members are sorted by [compareDeclarations].
   final List<Declaration> classMembers;
@@ -510,13 +826,84 @@
   ///
   /// In addition to the members of [classMembers] this also contains members
   /// from interfaces.
+  ///
+  /// This may be null, in which case [classMembers] is the interface members.
   final List<Declaration> interfaceMembers;
 
   /// Similar to [interfaceMembers] but for setters.
+  ///
+  /// This may be null, in which case [classSetters] is the interface setters.
   final List<Declaration> interfaceSetters;
 
-  ClassHierarchyNode(this.cls, this.localMembers, this.classMembers,
-      this.classSetters, this.interfaceMembers, this.interfaceSetters);
+  /// All superclasses of [cls] excluding itself. The classes are sorted by
+  /// depth from the root (Object) in ascending order.
+  final List<KernelTypeBuilder> superclasses;
+
+  /// The list of all classes implemented by [cls] and its supertypes excluding
+  /// any classes from [superclasses].
+  final List<KernelTypeBuilder> interfaces;
+
+  int get depth => superclasses.length;
+
+  ClassHierarchyNode(
+      this.cls,
+      this.classMembers,
+      this.classSetters,
+      this.interfaceMembers,
+      this.interfaceSetters,
+      this.superclasses,
+      this.interfaces);
+
+  String toString([StringBuffer sb]) {
+    sb ??= new StringBuffer();
+    sb
+      ..write(cls.fullNameForErrors)
+      ..writeln(":")
+      ..writeln("  superclasses:");
+    int depth = 0;
+    for (KernelTypeBuilder superclass in superclasses) {
+      sb.write("  " * (depth + 2));
+      if (depth != 0) sb.write("-> ");
+      superclass.printOn(sb);
+      sb.writeln();
+      depth++;
+    }
+    if (interfaces != null) {
+      sb.write("  interfaces:");
+      bool first = true;
+      for (KernelTypeBuilder i in interfaces) {
+        if (!first) sb.write(",");
+        sb.write(" ");
+        i.printOn(sb);
+        first = false;
+      }
+      sb.writeln();
+    }
+    printMembers(classMembers, sb, "classMembers");
+    printMembers(classSetters, sb, "classSetters");
+    if (interfaceMembers != null) {
+      printMembers(interfaceMembers, sb, "interfaceMembers");
+    }
+    if (interfaceSetters != null) {
+      printMembers(interfaceSetters, sb, "interfaceSetters");
+    }
+    return "$sb";
+  }
+
+  void printMembers(
+      List<Declaration> members, StringBuffer sb, String heading) {
+    sb.write("  ");
+    sb.write(heading);
+    sb.writeln(":");
+    for (Declaration member in members) {
+      sb
+        ..write("    ")
+        ..write(member.parent.fullNameForErrors)
+        ..write(".")
+        ..write(member.fullNameForErrors)
+        ..writeln();
+    }
+  }
 }
 
 class MergeResult {
@@ -536,4 +923,124 @@
 
   /// Merging class members with interface members.
   supertypes,
+
+  /// Merging members with inherited setters, or setters with inherited
+  /// members.
+  accessors,
+}
+
+List<LocatedMessage> inheritedConflictContext(Declaration a, Declaration b) {
+  return inheritedConflictContextKernel(
+      a.target, b.target, a.fullNameForErrors.length);
+}
+
+List<LocatedMessage> inheritedConflictContextKernel(
+    Member a, Member b, int length) {
+  // TODO(ahe): Delete this method when it isn't used by [InterfaceResolver].
+  int compare = "${a.fileUri}".compareTo("${b.fileUri}");
+  if (compare == 0) {
+    compare = a.fileOffset.compareTo(b.fileOffset);
+  }
+  Member first;
+  Member second;
+  if (compare < 0) {
+    first = a;
+    second = b;
+  } else {
+    first = b;
+    second = a;
+  }
+  return <LocatedMessage>[
+    messageInheritedMembersConflictCause1.withLocation(
+        first.fileUri, first.fileOffset, length),
+    messageInheritedMembersConflictCause2.withLocation(
+        second.fileUri, second.fileOffset, length),
+  ];
+}
+
+class BuilderMixinInferrer extends MixinInferrer {
+  final KernelClassBuilder cls;
+
+  BuilderMixinInferrer(
+      this.cls, CoreTypes coreTypes, TypeBuilderConstraintGatherer gatherer)
+      : super(coreTypes, gatherer);
+
+  Supertype asInstantiationOf(Supertype type, Class superclass) {
+    InterfaceType interfaceType =
+        gatherer.getTypeAsInstanceOf(type.asInterfaceType, superclass);
+    if (interfaceType == null) return null;
+    return new Supertype(interfaceType.classNode, interfaceType.typeArguments);
+  }
+
+  void reportProblem(Message message, Class kernelClass) {
+    int length = cls.isMixinApplication ? 1 : cls.fullNameForErrors.length;
+    cls.addProblem(message, cls.charOffset, length);
+  }
+}
+
+class TypeBuilderConstraintGatherer extends TypeConstraintGatherer
+    with StandardBounds {
+  final ClassHierarchyBuilder hierarchy;
+
+  TypeBuilderConstraintGatherer(
+      this.hierarchy, Iterable<TypeParameter> typeParameters)
+      : super.subclassing(typeParameters);
+
+  @override
+  Class get objectClass => hierarchy.objectKernelClass;
+
+  @override
+  Class get functionClass => hierarchy.functionKernelClass;
+
+  @override
+  Class get futureOrClass => hierarchy.futureOrKernelClass;
+
+  @override
+  Class get nullClass => hierarchy.nullKernelClass;
+
+  @override
+  InterfaceType get nullType => nullClass.rawType;
+
+  @override
+  InterfaceType get objectType => objectClass.rawType;
+
+  @override
+  InterfaceType get rawFunctionType => functionClass.rawType;
+
+  @override
+  void addLowerBound(TypeConstraint constraint, DartType lower) {
+    constraint.lower = getStandardUpperBound(constraint.lower, lower);
+  }
+
+  @override
+  void addUpperBound(TypeConstraint constraint, DartType upper) {
+    constraint.upper = getStandardLowerBound(constraint.upper, upper);
+  }
+
+  @override
+  Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
+    return null;
+  }
+
+  @override
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
+    return hierarchy.getKernelTypeAsInstanceOf(type, superclass);
+  }
+
+  @override
+  InterfaceType futureType(DartType type) {
+    return new InterfaceType(hierarchy.futureKernelClass, <DartType>[type]);
+  }
+
+  @override
+  bool isSubtypeOf(DartType subtype, DartType supertype) {
+    return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+  }
+
+  @override
+  InterfaceType getLegacyLeastUpperBound(
+      InterfaceType type1, InterfaceType type2) {
+    // TODO(ahe): Compute the actual LUB.
+    return type1;
+  }
 }
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 2a65568..1434f9f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -296,7 +296,10 @@
       Member setter,
       bool isNullAware) {
     if (helper.forest.isThisExpression(receiver)) {
-      return unsupported("ThisExpression", offsetForToken(token), helper.uri);
+      getter ??= helper.lookupInstanceMember(name);
+      setter ??= helper.lookupInstanceMember(name, isSetter: true);
+      return new ThisPropertyAccessGenerator(
+          helper, token, name, getter, setter);
     } else {
       return isNullAware
           ? new NullAwarePropertyAccessGenerator(
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 7d20b9c..470da0c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -4,10 +4,10 @@
 
 part of "kernel_shadow_ast.dart";
 
-class InferenceVistor extends BodyVisitor1<void, DartType> {
+class InferenceVisitor extends BodyVisitor1<void, DartType> {
   final ShadowTypeInferrer inferrer;
 
-  InferenceVistor(this.inferrer);
+  InferenceVisitor(this.inferrer);
 
   @override
   void defaultExpression(Expression node, DartType typeContext) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
index e81a108..eb8a506 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
@@ -28,9 +28,6 @@
 
 export 'kernel_formal_parameter_builder.dart' show KernelFormalParameterBuilder;
 
-export 'kernel_function_type_alias_builder.dart'
-    show KernelFunctionTypeAliasBuilder;
-
 export 'kernel_function_type_builder.dart' show KernelFunctionTypeBuilder;
 
 export 'kernel_invalid_type_builder.dart' show KernelInvalidTypeBuilder;
@@ -51,6 +48,8 @@
         KernelRedirectingFactoryBuilder,
         KernelProcedureBuilder;
 
+export 'kernel_type_alias_builder.dart' show KernelTypeAliasBuilder;
+
 export 'kernel_type_builder.dart' show KernelTypeBuilder;
 
 export 'kernel_type_variable_builder.dart' show KernelTypeVariableBuilder;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 77098cf..e43378a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -75,8 +75,6 @@
         templateIncorrectTypeArgumentInSupertype,
         templateIncorrectTypeArgumentInSupertypeInferred,
         templateInterfaceCheckContext,
-        templateMissingImplementationCause,
-        templateMissingImplementationNotAbstract,
         templateMixinApplicationIncompatibleSupertype,
         templateNamedMixinOverrideContext,
         templateOverriddenMethodCause,
@@ -615,13 +613,12 @@
 
   void checkAbstractMembers(CoreTypes coreTypes, ClassHierarchy hierarchy,
       TypeEnvironment typeEnvironment) {
+    // TODO(ahe): Move this to [ClassHierarchyBuilder].
     if (isAbstract) {
       // Unimplemented members allowed
       return;
     }
 
-    List<LocatedMessage> context = null;
-
     bool mustHaveImplementation(Member member) {
       // Public member
       if (!member.name.isPrivate) return true;
@@ -640,10 +637,6 @@
           isInterfaceCheck: true);
     }
 
-    Member noSuchMethod = hierarchy.getDispatchTarget(cls, noSuchMethodName);
-    bool hasNoSuchMethod = noSuchMethod != null &&
-        noSuchMethod.enclosingClass != coreTypes.objectClass;
-
     void findMissingImplementations({bool setters}) {
       List<Member> dispatchTargets =
           hierarchy.getDispatchTargets(cls, setters: setters);
@@ -679,19 +672,6 @@
                 interfaceMember.enclosingClass)) {
               overridePairCallback(dispatchTarget, interfaceMember, setters);
             }
-          } else if (!hasNoSuchMethod) {
-            Name name = interfaceMember.name;
-            String displayName = name.name + (setters ? "=" : "");
-            if (interfaceMember is Procedure &&
-                interfaceMember.isSyntheticForwarder) {
-              Procedure forwarder = interfaceMember;
-              interfaceMember = forwarder.forwardingStubInterfaceTarget;
-            }
-            context ??= <LocatedMessage>[];
-            context.add(templateMissingImplementationCause
-                .withArguments(displayName)
-                .withLocation(interfaceMember.fileUri,
-                    interfaceMember.fileOffset, name.name.length));
           }
         }
       }
@@ -699,18 +679,6 @@
 
     findMissingImplementations(setters: false);
     findMissingImplementations(setters: true);
-
-    if (context?.isNotEmpty ?? false) {
-      List<String> memberNames = new List<String>.from(
-          context.map((message) => "'${message.arguments["name"]}'"));
-      library.addProblem(
-          templateMissingImplementationNotAbstract.withArguments(
-              cls.name, memberNames),
-          cls.fileOffset,
-          cls.name.length,
-          cls.fileUri,
-          context: context);
-    }
   }
 
   bool hasUserDefinedNoSuchMethod(
@@ -1362,7 +1330,7 @@
   }
 
   String get fullNameForErrors {
-    return isMixinApplication
+    return isMixinApplication && !isNamedMixinApplication
         ? "${supertype.fullNameForErrors} with ${mixedInType.fullNameForErrors}"
         : name;
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
index 06cdc67..6cb0a71 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_constants.dart
@@ -5,65 +5,176 @@
 library fasta.kernel_constants;
 
 import 'package:kernel/ast.dart'
+    show Constant, DartType, IntConstant, Library, Member, Procedure, TreeNode;
+
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+
+import 'package:kernel/transformations/constants.dart' show ErrorReporter;
+
+import '../fasta_codes.dart'
     show
-        Constant,
-        DartType,
-        EnvironmentBoolConstant,
-        EnvironmentIntConstant,
-        EnvironmentStringConstant,
-        ListConstant,
-        MapConstant,
-        NullConstant,
-        StaticInvocation,
-        StringConstant,
-        TreeNode;
+        Message,
+        noLength,
+        messageConstEvalCircularity,
+        messageConstEvalFailedAssertion,
+        templateConstEvalDeferredLibrary,
+        templateConstEvalDuplicateKey,
+        templateConstEvalFailedAssertionWithMessage,
+        templateConstEvalFreeTypeParameter,
+        templateConstEvalInvalidBinaryOperandType,
+        templateConstEvalInvalidMethodInvocation,
+        templateConstEvalInvalidStaticInvocation,
+        templateConstEvalInvalidStringInterpolationOperand,
+        templateConstEvalInvalidSymbolName,
+        templateConstEvalInvalidType,
+        templateConstEvalNegativeShift,
+        templateConstEvalNonConstantLiteral,
+        templateConstEvalNonConstantVariableGet,
+        templateConstEvalZeroDivisor;
 
-import 'package:kernel/transformations/constants.dart'
-    show ConstantsBackend, ErrorReporter;
+import '../loader.dart' show Loader;
 
-import '../problems.dart' show unexpected, unimplemented;
+class KernelConstantErrorReporter extends ErrorReporter {
+  final Loader<Library> loader;
+  final TypeEnvironment typeEnvironment;
 
-class KernelConstantsBackend extends ConstantsBackend {
-  @override
-  Constant lowerListConstant(ListConstant constant) => constant;
+  KernelConstantErrorReporter(this.loader, this.typeEnvironment);
+
+  String addProblem(TreeNode node, Message message) {
+    int offset = getFileOffset(node);
+    Uri uri = getFileUri(node);
+    loader.addProblem(message, offset, noLength, uri);
+    return loader.target.context.format(
+        message.withLocation(uri, offset, noLength), message.code.severity);
+  }
 
   @override
-  Constant lowerMapConstant(MapConstant constant) => constant;
+  String freeTypeParameter(
+      List<TreeNode> context, TreeNode node, DartType type) {
+    return addProblem(
+        node, templateConstEvalFreeTypeParameter.withArguments(type));
+  }
 
   @override
-  Constant buildConstantForNative(
-      String nativeName,
-      List<DartType> typeArguments,
-      List<Constant> positionalArguments,
-      Map<String, Constant> namedArguments,
+  String duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
+    return addProblem(node, templateConstEvalDuplicateKey.withArguments(key));
+  }
+
+  @override
+  String invalidDartType(List<TreeNode> context, TreeNode node,
+      Constant receiver, DartType expectedType) {
+    return addProblem(
+        node,
+        templateConstEvalInvalidType.withArguments(
+            receiver, expectedType, receiver.getType(typeEnvironment)));
+  }
+
+  @override
+  String invalidBinaryOperandType(
       List<TreeNode> context,
-      StaticInvocation node,
-      ErrorReporter errorReporter,
-      void abortEvaluation()) {
-    // VM-specific names of the fromEnvironment factory constructors.
-    if (nativeName == 'Bool_fromEnvironment' ||
-        nativeName == 'Integer_fromEnvironment' ||
-        nativeName == 'String_fromEnvironment') {
-      if (positionalArguments.length == 1 &&
-          positionalArguments.first is StringConstant &&
-          (namedArguments.length == 0 ||
-              (namedArguments.length == 1 &&
-                  namedArguments.containsKey('defaultValue')))) {
-        StringConstant name = positionalArguments.first;
-        Constant defaultValue =
-            namedArguments['defaultValue'] ?? new NullConstant();
-        if (nativeName == 'Bool_fromEnvironment') {
-          return new EnvironmentBoolConstant(name.value, defaultValue);
-        }
-        if (nativeName == 'Integer_fromEnvironment') {
-          return new EnvironmentIntConstant(name.value, defaultValue);
-        }
-        return new EnvironmentStringConstant(name.value, defaultValue);
+      TreeNode node,
+      Constant receiver,
+      String op,
+      DartType expectedType,
+      DartType actualType) {
+    return addProblem(
+        node,
+        templateConstEvalInvalidBinaryOperandType.withArguments(
+            op, receiver, expectedType, actualType));
+  }
+
+  @override
+  String invalidMethodInvocation(
+      List<TreeNode> context, TreeNode node, Constant receiver, String op) {
+    return addProblem(node,
+        templateConstEvalInvalidMethodInvocation.withArguments(op, receiver));
+  }
+
+  @override
+  String invalidStaticInvocation(
+      List<TreeNode> context, TreeNode node, Member target) {
+    // TODO(kmillikin) For an invalid factory invocation we should adopt a
+    // better message.  This will show something like:
+    //
+    // "The invocation of 'List' is not allowed within a const context."
+    //
+    // Which is not quite right when the code was "new List()".
+    String name = target.name.toString();
+    if (target is Procedure && target.isFactory) {
+      if (name.isEmpty) {
+        name = target.enclosingClass.name;
+      } else {
+        name = '${target.enclosingClass.name}.${name}';
       }
-      return unexpected('valid constructor invocation', node.toString(),
-          node.fileOffset, node.location.file);
     }
-    return unimplemented('constant evaluation of ${nativeName}',
-        node.fileOffset, node.location.file);
+    return addProblem(
+        node, templateConstEvalInvalidStaticInvocation.withArguments(name));
+  }
+
+  @override
+  String invalidStringInterpolationOperand(
+      List<TreeNode> context, TreeNode node, Constant constant) {
+    return addProblem(
+        node,
+        templateConstEvalInvalidStringInterpolationOperand
+            .withArguments(constant));
+  }
+
+  @override
+  String invalidSymbolName(
+      List<TreeNode> context, TreeNode node, Constant constant) {
+    return addProblem(
+        node, templateConstEvalInvalidSymbolName.withArguments(constant));
+  }
+
+  @override
+  String zeroDivisor(
+      List<TreeNode> context, TreeNode node, IntConstant receiver, String op) {
+    return addProblem(node,
+        templateConstEvalZeroDivisor.withArguments(op, '${receiver.value}'));
+  }
+
+  @override
+  String negativeShift(List<TreeNode> context, TreeNode node,
+      IntConstant receiver, String op, IntConstant argument) {
+    return addProblem(
+        node,
+        templateConstEvalNegativeShift.withArguments(
+            op, '${receiver.value}', '${argument.value}'));
+  }
+
+  @override
+  String nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+    return addProblem(
+        node, templateConstEvalNonConstantLiteral.withArguments(klass));
+  }
+
+  @override
+  String failedAssertion(List<TreeNode> context, TreeNode node, String string) {
+    return addProblem(
+        node,
+        (string == null)
+            ? messageConstEvalFailedAssertion
+            : templateConstEvalFailedAssertionWithMessage
+                .withArguments(string));
+  }
+
+  @override
+  String nonConstantVariableGet(
+      List<TreeNode> context, TreeNode node, String variableName) {
+    return addProblem(node,
+        templateConstEvalNonConstantVariableGet.withArguments(variableName));
+  }
+
+  @override
+  String deferredLibrary(
+      List<TreeNode> context, TreeNode node, String importName) {
+    return addProblem(
+        node, templateConstEvalDeferredLibrary.withArguments(importName));
+  }
+
+  @override
+  String circularity(List<TreeNode> context, TreeNode node) {
+    return addProblem(node, messageConstEvalCircularity);
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index 38f029e..c2ca617 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -328,11 +328,18 @@
   Expression _makeWrite(Expression value, bool voidContext,
       ComplexAssignmentJudgment complexAssignment) {
     helper.typePromoter?.mutateVariable(variable, helper.functionNestingLevel);
-    var write = variable.isFinal || variable.isConst
-        ? makeInvalidWrite(value)
-        : new VariableSet(variable, value)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
+    Expression write;
+    if (variable.isFinal || variable.isConst) {
+      write = makeInvalidWrite(value);
+      if (complexAssignment != null) {
+        write = helper.desugarSyntheticExpression(write);
+        complexAssignment.write = write;
+      }
+    } else {
+      write = new VariableSet(variable, value)
+        ..fileOffset = offsetForToken(token);
+      complexAssignment?.write = write;
+    }
     return write;
   }
 
@@ -1475,7 +1482,7 @@
         super(helper, token);
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext}) {
+  Expression buildAssignment(Expression value, {bool voidContext: false}) {
     return new PropertySet(receiver, name, value)
       ..fileOffset = offsetForToken(token);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index f67e700..08e5bce 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -302,7 +302,7 @@
   }
 
   Expression buildCompoundAssignment(Name binaryOperator, Expression value,
-      {int offset,
+      {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
       bool isPreIncDec: false,
@@ -312,13 +312,17 @@
   }
 
   Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
     return unsupported(
         "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
   }
 
   Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
     return unsupported(
         "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
   }
@@ -372,7 +376,7 @@
   }
 
   Expression buildCompoundAssignment(Name binaryOperator, Expression value,
-      {int offset,
+      {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
       bool isPreIncDec: false,
@@ -382,13 +386,17 @@
   }
 
   Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
     return unsupported(
         "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
   }
 
   Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset, bool voidContext: false, Procedure interfaceTarget}) {
+      {int offset: TreeNode.noOffset,
+      bool voidContext: false,
+      Procedure interfaceTarget}) {
     return unsupported(
         "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
deleted file mode 100644
index 1e174f4..0000000
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.kernel_function_type_alias_builder;
-
-import 'package:kernel/ast.dart'
-    show
-        DartType,
-        DynamicType,
-        FunctionType,
-        InvalidType,
-        TypeParameter,
-        Typedef,
-        VariableDeclaration;
-
-import 'package:kernel/type_algebra.dart'
-    show FreshTypeParameters, getFreshTypeParameters, substitute;
-
-import '../fasta_codes.dart'
-    show noLength, templateCyclicTypedef, templateTypeArgumentMismatch;
-
-import '../problems.dart' show unhandled;
-
-import 'kernel_builder.dart'
-    show
-        FunctionTypeAliasBuilder,
-        KernelFormalParameterBuilder,
-        KernelFunctionTypeBuilder,
-        KernelLibraryBuilder,
-        KernelTypeBuilder,
-        KernelTypeVariableBuilder,
-        LibraryBuilder,
-        MetadataBuilder,
-        TypeVariableBuilder;
-
-final InvalidType cyclicTypeAliasMarker = new InvalidType();
-
-class KernelFunctionTypeAliasBuilder
-    extends FunctionTypeAliasBuilder<KernelFunctionTypeBuilder, DartType> {
-  final Typedef target;
-
-  DartType thisType;
-
-  KernelFunctionTypeAliasBuilder(
-      List<MetadataBuilder> metadata,
-      String name,
-      List<TypeVariableBuilder> typeVariables,
-      KernelFunctionTypeBuilder type,
-      LibraryBuilder parent,
-      int charOffset,
-      [Typedef target])
-      : target = target ??
-            (new Typedef(name, null,
-                typeParameters:
-                    KernelTypeVariableBuilder.kernelTypeParametersFromBuilders(
-                        typeVariables),
-                fileUri: parent.target.fileUri)
-              ..fileOffset = charOffset),
-        super(metadata, name, typeVariables, type, parent, charOffset);
-
-  Typedef build(LibraryBuilder libraryBuilder) {
-    target..type ??= buildThisType(libraryBuilder);
-
-    if (type != null) {
-      List<TypeParameter> typeParameters =
-          new List<TypeParameter>(type.typeVariables?.length ?? 0);
-      for (int i = 0; i < typeParameters.length; ++i) {
-        KernelTypeVariableBuilder typeVariable = type.typeVariables[i];
-        typeParameters[i] = typeVariable.parameter;
-      }
-      FreshTypeParameters freshTypeParameters =
-          getFreshTypeParameters(typeParameters);
-      target.typeParametersOfFunctionType
-          .addAll(freshTypeParameters.freshTypeParameters);
-
-      if (type.formals != null) {
-        for (KernelFormalParameterBuilder formal in type.formals) {
-          VariableDeclaration parameter = formal.build(libraryBuilder, 0);
-          parameter.type = freshTypeParameters.substitute(parameter.type);
-          if (formal.isNamed) {
-            target.namedParameters.add(parameter);
-          } else {
-            target.positionalParameters.add(parameter);
-          }
-        }
-      }
-    }
-
-    return target;
-  }
-
-  DartType buildThisType(LibraryBuilder library) {
-    if (thisType != null) {
-      if (identical(thisType, cyclicTypeAliasMarker)) {
-        library.addProblem(templateCyclicTypedef.withArguments(name),
-            charOffset, noLength, fileUri);
-        return const InvalidType();
-      }
-      return thisType;
-    }
-    // It is a compile-time error for an alias (typedef) to refer to itself. We
-    // detect cycles by detecting recursive calls to this method using an
-    // instance of InvalidType that isn't identical to `const InvalidType()`.
-    thisType = cyclicTypeAliasMarker;
-    FunctionType builtType = type?.build(library, target.thisType);
-    if (builtType != null) {
-      if (typeVariables != null) {
-        for (KernelTypeVariableBuilder tv in typeVariables) {
-          // Follow bound in order to find all cycles
-          tv.bound?.build(library);
-        }
-      }
-      return thisType = builtType;
-    } else {
-      return thisType = const InvalidType();
-    }
-  }
-
-  /// [arguments] have already been built.
-  DartType buildTypesWithBuiltArguments(
-      LibraryBuilder library, List<DartType> arguments) {
-    var thisType = buildThisType(library);
-    if (const DynamicType() == thisType) return thisType;
-    FunctionType result = thisType;
-    if (target.typeParameters.isEmpty && arguments == null) return result;
-    Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
-    for (int i = 0; i < target.typeParameters.length; i++) {
-      substitution[target.typeParameters[i]] = arguments[i];
-    }
-    return substitute(result, substitution);
-  }
-
-  List<DartType> buildTypeArguments(
-      LibraryBuilder library, List<KernelTypeBuilder> arguments) {
-    if (arguments == null && typeVariables == null) {
-      return <DartType>[];
-    }
-
-    if (arguments == null && typeVariables != null) {
-      List<DartType> result =
-          new List<DartType>.filled(typeVariables.length, null, growable: true);
-      for (int i = 0; i < result.length; ++i) {
-        result[i] = typeVariables[i].defaultType.build(library);
-      }
-      if (library is KernelLibraryBuilder) {
-        library.inferredTypes.addAll(result);
-      }
-      return result;
-    }
-
-    if (arguments != null && arguments.length != (typeVariables?.length ?? 0)) {
-      // That should be caught and reported as a compile-time error earlier.
-      return unhandled(
-          templateTypeArgumentMismatch
-              .withArguments(typeVariables.length)
-              .message,
-          "buildTypeArguments",
-          -1,
-          null);
-    }
-
-    // arguments.length == typeVariables.length
-    List<DartType> result =
-        new List<DartType>.filled(arguments.length, null, growable: true);
-    for (int i = 0; i < result.length; ++i) {
-      result[i] = arguments[i].build(library);
-    }
-    return result;
-  }
-
-  /// If [arguments] are null, the default types for the variables are used.
-  @override
-  int get typeVariablesCount => typeVariables?.length ?? 0;
-
-  @override
-  DartType buildType(
-      LibraryBuilder library, List<KernelTypeBuilder> arguments) {
-    var thisType = buildThisType(library);
-    if (thisType is InvalidType) return thisType;
-    FunctionType result = thisType;
-    if (target.typeParameters.isEmpty && arguments == null) return result;
-    // Otherwise, substitute.
-    return buildTypesWithBuiltArguments(
-        library, buildTypeArguments(library, arguments));
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart
index 916dc20d..d821ca7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart
@@ -35,7 +35,7 @@
   KernelFunctionTypeBuilder(
       KernelTypeBuilder returnType,
       List<TypeVariableBuilder> typeVariables,
-      List<FormalParameterBuilder> formals)
+      List<FormalParameterBuilder<TypeBuilder>> formals)
       : super(returnType, typeVariables, formals);
 
   FunctionType build(LibraryBuilder library, [TypedefType origin]) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 96f2460..4277b49 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -60,6 +60,7 @@
 
 import '../fasta_codes.dart'
     show
+        FormattedMessage,
         LocatedMessage,
         Message,
         messageConflictsWithTypeVariableCause,
@@ -82,6 +83,7 @@
         templateIncorrectTypeArgumentInferred,
         templateIncorrectTypeArgumentQualified,
         templateIncorrectTypeArgumentQualifiedInferred,
+        templateIntersectionTypeAsTypeArgument,
         templateLoadLibraryHidesMember,
         templateLocalDefinitionHidesExport,
         templateLocalDefinitionHidesImport,
@@ -103,6 +105,8 @@
 
 import '../problems.dart' show unexpected, unhandled;
 
+import '../severity.dart' show Severity;
+
 import '../source/source_class_builder.dart' show SourceClassBuilder;
 
 import '../source/source_library_builder.dart'
@@ -128,7 +132,7 @@
         KernelFieldBuilder,
         KernelFormalParameterBuilder,
         KernelFunctionBuilder,
-        KernelFunctionTypeAliasBuilder,
+        KernelTypeAliasBuilder,
         KernelFunctionTypeBuilder,
         KernelInvalidTypeBuilder,
         KernelMixinApplicationBuilder,
@@ -237,6 +241,26 @@
           const VoidType(), this, charOffset));
   }
 
+  @override
+  FormattedMessage addProblem(
+      Message message, int charOffset, int length, Uri fileUri,
+      {bool wasHandled: false,
+      List<LocatedMessage> context,
+      Severity severity,
+      bool problemOnLibrary: false}) {
+    FormattedMessage formattedMessage = super.addProblem(
+        message, charOffset, length, fileUri,
+        wasHandled: wasHandled,
+        context: context,
+        severity: severity,
+        problemOnLibrary: true);
+    if (formattedMessage != null) {
+      target.problemsAsJson ??= <String>[];
+      target.problemsAsJson.add(formattedMessage.toJsonString());
+    }
+    return formattedMessage;
+  }
+
   void addClass(
       String documentationComment,
       List<MetadataBuilder> metadata,
@@ -806,7 +830,7 @@
       List<TypeVariableBuilder> typeVariables,
       covariant KernelFunctionTypeBuilder type,
       int charOffset) {
-    KernelFunctionTypeAliasBuilder typedef = new KernelFunctionTypeAliasBuilder(
+    KernelTypeAliasBuilder typedef = new KernelTypeAliasBuilder(
         metadata, name, typeVariables, type, this, charOffset);
     loader.target.metadataCollector
         ?.setDocumentationComment(typedef.target, documentationComment);
@@ -867,7 +891,7 @@
       member = declaration.build(this)..isStatic = true;
     } else if (declaration is KernelProcedureBuilder) {
       member = declaration.build(this)..isStatic = true;
-    } else if (declaration is KernelFunctionTypeAliasBuilder) {
+    } else if (declaration is KernelTypeAliasBuilder) {
       typedef = declaration.build(this);
     } else if (declaration is KernelEnumBuilder) {
       cls = declaration.build(this, coreLibrary);
@@ -989,6 +1013,7 @@
 
     if (modifyTarget == false) return library;
 
+    library.isSynthetic = isSynthetic;
     addDependencies(library, new Set<KernelLibraryBuilder>());
 
     loader.target.metadataCollector
@@ -1282,7 +1307,7 @@
                 member.typeVariables, legacyMode || issues.isNotEmpty);
           }
         });
-      } else if (declaration is KernelFunctionTypeAliasBuilder) {
+      } else if (declaration is KernelTypeAliasBuilder) {
         List<Object> issues = legacyMode
             ? const <Object>[]
             : getNonSimplicityIssuesForDeclaration(declaration,
@@ -1306,10 +1331,17 @@
   }
 
   @override
-  void includePart(covariant KernelLibraryBuilder part, Set<Uri> usedParts) {
-    super.includePart(part, usedParts);
+  void includePart(
+      covariant KernelLibraryBuilder part, Set<Uri> usedParts, int partOffset) {
+    super.includePart(part, usedParts, partOffset);
     nativeMethods.addAll(part.nativeMethods);
     boundlessTypeVariables.addAll(part.boundlessTypeVariables);
+    // Check that the targets are different. This is not normally a problem
+    // but is for patch files.
+    if (target != part.target && part.target.problemsAsJson != null) {
+      target.problemsAsJson ??= <String>[];
+      target.problemsAsJson.addAll(part.target.problemsAsJson);
+    }
   }
 
   @override
@@ -1429,6 +1461,15 @@
           message = messageGenericFunctionTypeUsedAsActualTypeArgument;
         }
         typeParameter = null;
+      } else if (argument is TypeParameterType &&
+          argument.promotedBound != null) {
+        addProblem(
+            templateIntersectionTypeAsTypeArgument.withArguments(
+                typeParameter.name, argument, argument.promotedBound),
+            offset,
+            noLength,
+            fileUri);
+        continue;
       } else {
         if (issue.enclosingType == null && targetReceiver != null) {
           if (issueInferred) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 21ca7db..7f2d72a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -45,7 +45,7 @@
         templateSwitchExpressionNotAssignable,
         templateWebLiteralCannotBeRepresentedExactly;
 
-import '../problems.dart' show unhandled, unsupported;
+import '../problems.dart' show getFileUri, unhandled, unsupported;
 
 import '../source/source_class_builder.dart' show SourceClassBuilder;
 
@@ -150,7 +150,7 @@
   AssertStatementJudgment get judgment => statement;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitAssertInitializerJudgment(this);
   }
 }
@@ -170,7 +170,7 @@
   Expression get messageJudgment => message;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitAssertStatementJudgment(this);
   }
 }
@@ -182,7 +182,7 @@
   List<Statement> get judgments => statements;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitBlockJudgment(this);
   }
 }
@@ -254,7 +254,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitCascadeJudgment(this, typeContext);
   }
 }
@@ -518,7 +518,7 @@
   SwitchCaseJudgment get targetJudgment => target;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitContinueSwitchJudgment(this);
   }
 }
@@ -533,7 +533,7 @@
   Expression get judgment => body;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitDeferredCheckJudgment(this, typeContext);
   }
 }
@@ -545,7 +545,7 @@
   Expression get conditionJudgment => condition;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitDoJudgment(this);
   }
 }
@@ -557,7 +557,7 @@
   DoubleJudgment(double value) : super(value);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitDoubleJudgment(this, typeContext);
   }
 }
@@ -569,7 +569,7 @@
 
   /// Calls back to [inferrer] to perform type inference for whatever concrete
   /// type of [Expression] this is.
-  void acceptInference(InferenceVistor visitor, DartType typeContext);
+  void acceptInference(InferenceVisitor visitor, DartType typeContext);
 }
 
 /// Concrete shadow object representing an empty statement in kernel form.
@@ -578,7 +578,7 @@
   EmptyStatementJudgment();
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitEmptyStatementJudgment(this);
   }
 }
@@ -591,7 +591,7 @@
   Expression get judgment => expression;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitExpressionStatementJudgment(this);
   }
 }
@@ -610,7 +610,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitFactoryConstructorInvocationJudgment(this, typeContext);
   }
 }
@@ -647,7 +647,7 @@
   ShadowFieldInitializer(Field field, Expression value) : super(field, value);
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitShadowFieldInitializer(this);
   }
 }
@@ -663,7 +663,7 @@
   List<Expression> get updateJudgments => updates.cast();
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitForJudgment(this);
   }
 }
@@ -703,7 +703,7 @@
   FunctionNodeJudgment get functionJudgment => function;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitFunctionDeclarationJudgment(this);
   }
 
@@ -724,7 +724,7 @@
       : super(variable);
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitInvalidSuperInitializerJudgment(this);
   }
 }
@@ -751,7 +751,7 @@
   Expression get rightJudgment => body.then;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitIfNullJudgment(this, typeContext);
   }
 }
@@ -764,7 +764,7 @@
   Expression get conditionJudgment => condition;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitIfJudgment(this);
   }
 }
@@ -782,7 +782,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitIllegalAssignmentJudgment(this, typeContext);
   }
 }
@@ -817,7 +817,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitIndexAssignmentJudgment(this, typeContext);
   }
 }
@@ -827,7 +827,7 @@
 abstract class InitializerJudgment implements Initializer {
   /// Performs type inference for whatever concrete type of [InitializerJudgment]
   /// this is.
-  void acceptInference(InferenceVistor visitor);
+  void acceptInference(InferenceVisitor visitor);
 }
 
 Expression checkWebIntLiteralsErrorIfUnexact(
@@ -867,7 +867,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitIntJudgment(this, typeContext);
   }
 }
@@ -897,7 +897,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitShadowLargeIntLiteral(this, typeContext);
   }
 }
@@ -908,7 +908,7 @@
   ShadowInvalidInitializer(VariableDeclaration variable) : super(variable);
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitShadowInvalidInitializer(this);
   }
 }
@@ -928,7 +928,7 @@
   Expression get judgment => value;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitShadowInvalidFieldInitializer(this);
   }
 }
@@ -943,7 +943,7 @@
         super(expressions, typeArgument: typeArgument, isConst: isConst);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitListLiteralJudgment(this, typeContext);
   }
 }
@@ -958,7 +958,7 @@
         super(expressions, typeArgument: typeArgument, isConst: isConst);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitSetLiteralJudgment(this, typeContext);
   }
 }
@@ -975,7 +975,7 @@
             keyType: keyType, valueType: valueType, isConst: isConst);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitMapLiteralJudgment(this, typeContext);
   }
 }
@@ -1019,7 +1019,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitMethodInvocationJudgment(this, typeContext);
   }
 }
@@ -1043,7 +1043,7 @@
   VariableDeclarationJudgment get variableJudgment => variable;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitNamedFunctionExpressionJudgment(this, typeContext);
   }
 }
@@ -1068,7 +1068,7 @@
   MethodInvocation get _desugaredInvocation => body.otherwise;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitNullAwareMethodInvocationJudgment(this, typeContext);
   }
 }
@@ -1094,7 +1094,7 @@
   Expression get receiverJudgment => variable.initializer;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitNullAwarePropertyGetJudgment(this, typeContext);
   }
 }
@@ -1153,7 +1153,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitPropertyAssignmentJudgment(this, typeContext);
   }
 }
@@ -1169,7 +1169,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitRedirectingInitializerJudgment(this);
   }
 }
@@ -1184,7 +1184,7 @@
   Expression get judgment => expression;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitReturnJudgment(this);
   }
 }
@@ -1194,7 +1194,7 @@
 abstract class StatementJudgment extends Statement {
   /// Calls back to [inferrer] to perform type inference for whatever concrete
   /// type of [StatementJudgment] this is.
-  void acceptInference(InferenceVistor visitor);
+  void acceptInference(InferenceVisitor visitor);
 }
 
 /// Concrete shadow object representing an assignment to a static variable.
@@ -1202,7 +1202,7 @@
   StaticAssignmentJudgment._(Expression rhs) : super._(rhs);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitStaticAssignmentJudgment(this, typeContext);
   }
 }
@@ -1216,7 +1216,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitSuperInitializerJudgment(this);
   }
 }
@@ -1233,7 +1233,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitSuperMethodInvocationJudgment(this, typeContext);
   }
 }
@@ -1247,7 +1247,7 @@
       : super(name, interfaceTarget);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitSuperPropertyGetJudgment(this, typeContext);
   }
 }
@@ -1277,7 +1277,7 @@
   List<SwitchCaseJudgment> get caseJudgments => cases.cast();
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitSwitchStatementJudgment(this);
   }
 }
@@ -1290,7 +1290,7 @@
   SymbolLiteralJudgment(String value) : super(value);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitSymbolLiteralJudgment(this, typeContext);
   }
 }
@@ -1310,7 +1310,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitInvalidConstructorInvocationJudgment(this, typeContext);
   }
 }
@@ -1324,7 +1324,7 @@
       : super._(desugared);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitInvalidWriteJudgment(this, typeContext);
   }
 }
@@ -1350,7 +1350,7 @@
   }
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitSyntheticExpressionJudgment(this, typeContext);
   }
 
@@ -1390,6 +1390,25 @@
       }
     }
   }
+
+  @override
+  accept(ExpressionVisitor v) {
+    // This is designed to throw an exception during serialization. It can also
+    // lead to exceptions during transformations, but we have to accept a
+    // [Transformer] as this is used to implement `replaceChild`.
+    if (v is Transformer) return super.accept(v);
+    unsupported("accept", fileOffset, getFileUri(this));
+  }
+
+  @override
+  accept1(ExpressionVisitor1 v, arg) {
+    unsupported("accept1", fileOffset, getFileUri(this));
+  }
+
+  @override
+  visitChildren(Visitor v) {
+    unsupported("visitChildren", fileOffset, getFileUri(this));
+  }
 }
 
 /// Concrete shadow object representing a catch clause.
@@ -1410,7 +1429,7 @@
   List<CatchJudgment> get catchJudgments => catches.cast();
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitTryCatchJudgment(this);
   }
 }
@@ -1421,7 +1440,7 @@
       : super(body, finalizer);
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitTryFinallyJudgment(this);
   }
 }
@@ -1489,7 +1508,7 @@
     // those subexpressions.
     if (!typeNeeded) return null;
 
-    InferenceVistor visitor = new InferenceVistor(this);
+    InferenceVisitor visitor = new InferenceVisitor(this);
     if (expression is ExpressionJudgment) {
       expression.acceptInference(visitor, typeContext);
     } else {
@@ -1523,7 +1542,7 @@
     // so that the type hierarchy will be simpler (which may speed up "is"
     // checks).
     InitializerJudgment kernelInitializer = initializer;
-    kernelInitializer.acceptInference(new InferenceVistor(this));
+    kernelInitializer.acceptInference(new InferenceVisitor(this));
     this.helper = null;
   }
 
@@ -1539,13 +1558,13 @@
       // TODO(paulberry): experiment to see if dynamic dispatch would be better,
       // so that the type hierarchy will be simpler (which may speed up "is"
       // checks).
-      return statement.acceptInference(new InferenceVistor(this));
+      return statement.acceptInference(new InferenceVisitor(this));
     } else if (statement is ForInStatement) {
-      return statement.accept1(new InferenceVistor(this), null);
+      return statement.accept1(new InferenceVisitor(this), null);
     } else if (statement is LabeledStatement) {
-      return statement.accept1(new InferenceVistor(this), null);
+      return statement.accept1(new InferenceVisitor(this), null);
     } else if (statement is BreakStatement) {
-      return statement.accept1(new InferenceVistor(this), null);
+      return statement.accept1(new InferenceVisitor(this), null);
     } else {
       // Encountered a statement type for which type inference is not yet
       // implemented, so just skip it for now.
@@ -1561,7 +1580,7 @@
   TypeLiteralJudgment(DartType type) : super(type);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitTypeLiteralJudgment(this, typeContext);
   }
 }
@@ -1639,7 +1658,7 @@
   VariableAssignmentJudgment._(Expression rhs) : super._(rhs);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitVariableAssignmentJudgment(this, typeContext);
   }
 }
@@ -1703,7 +1722,7 @@
   Expression get initializerJudgment => initializer;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitVariableDeclarationJudgment(this);
   }
 
@@ -1734,7 +1753,7 @@
       : super._(desugared);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitUnresolvedTargetInvocationJudgment(this, typeContext);
   }
 }
@@ -1750,7 +1769,7 @@
       : super._(desugared);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitUnresolvedVariableAssignmentJudgment(this, typeContext);
   }
 }
@@ -1767,7 +1786,7 @@
       : super(variable);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitVariableGetJudgment(this, typeContext);
   }
 }
@@ -1779,7 +1798,7 @@
   Expression get conditionJudgment => condition;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitWhileJudgment(this);
   }
 }
@@ -1792,7 +1811,7 @@
   Expression get judgment => expression;
 
   @override
-  void acceptInference(InferenceVistor visitor) {
+  void acceptInference(InferenceVisitor visitor) {
     return visitor.visitYieldJudgment(this);
   }
 }
@@ -1808,7 +1827,7 @@
   ArgumentsJudgment get argumentJudgments => arguments;
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitLoadLibraryJudgment(this, typeContext);
   }
 }
@@ -1823,7 +1842,7 @@
   LoadLibraryTearOffJudgment(this.import, Procedure target) : super(target);
 
   @override
-  void acceptInference(InferenceVistor visitor, DartType typeContext) {
+  void acceptInference(InferenceVisitor visitor, DartType typeContext) {
     return visitor.visitLoadLibraryTearOffJudgment(this, typeContext);
   }
 }
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 75f57a8..104f403 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -23,14 +23,12 @@
         InterfaceType,
         InvalidInitializer,
         Library,
-        ListLiteral,
         Name,
         NamedExpression,
         NullLiteral,
         Procedure,
         RedirectingInitializer,
         Source,
-        StringLiteral,
         SuperInitializer,
         TypeParameter,
         TypeParameterType,
@@ -41,10 +39,12 @@
 
 import 'package:kernel/type_algebra.dart' show substitute;
 
+import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
 
 import 'package:kernel/transformations/constants.dart' as constants
-    show SimpleErrorReporter, transformLibraries;
+    show transformLibraries;
 
 import '../../api_prototype/file_system.dart' show FileSystem;
 
@@ -56,9 +56,13 @@
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
+import '../fasta_codes.dart' show Message, LocatedMessage;
+
+import '../loader.dart' show Loader;
+
 import '../messages.dart'
     show
-        LocatedMessage,
+        FormattedMessage,
         messageConstConstructorNonFinalField,
         messageConstConstructorNonFinalFieldCause,
         messageConstConstructorRedirectionToNonConst,
@@ -71,8 +75,6 @@
 
 import '../problems.dart' show unhandled, unimplemented;
 
-import '../severity.dart' show Severity;
-
 import '../scope.dart' show AmbiguousBuilder;
 
 import '../source/source_class_builder.dart' show SourceClassBuilder;
@@ -86,6 +88,7 @@
 import 'kernel_builder.dart'
     show
         ClassBuilder,
+        ClassHierarchyBuilder,
         Declaration,
         InvalidTypeBuilder,
         KernelClassBuilder,
@@ -98,7 +101,7 @@
         TypeBuilder,
         TypeDeclarationBuilder;
 
-import 'kernel_constants.dart' show KernelConstantsBackend;
+import 'kernel_constants.dart' show KernelConstantErrorReporter;
 
 import 'metadata_collector.dart' show MetadataCollector;
 
@@ -113,13 +116,10 @@
 
   final DillTarget dillTarget;
 
-  /// Shared with [CompilerContext].
-  final Map<Uri, Source> uriToSource;
-
   /// The [MetadataCollector] to write metadata to.
   final MetadataCollector metadataCollector;
 
-  SourceLoader<Library> loader;
+  SourceLoader loader;
 
   Component component;
 
@@ -140,22 +140,25 @@
       UriTranslator uriTranslator,
       {MetadataCollector metadataCollector})
       : dillTarget = dillTarget,
-        uriToSource = CompilerContext.current.uriToSource,
         metadataCollector = metadataCollector,
         super(dillTarget.ticker, uriTranslator, dillTarget.backendTarget) {
     loader = createLoader();
   }
 
-  SourceLoader<Library> createLoader() =>
-      new SourceLoader<Library>(fileSystem, includeComments, this);
+  void set builderHierarchy(ClassHierarchyBuilder o) {}
+
+  SourceLoader createLoader() =>
+      new SourceLoader(fileSystem, includeComments, this);
 
   void addSourceInformation(
       Uri uri, List<int> lineStarts, List<int> sourceCode) {
     uriToSource[uri] = new Source(lineStarts, sourceCode);
   }
 
-  void setEntryPoints(List<Uri> entryPoints) {
+  /// Return list of same size as input with possibly translated uris.
+  List<Uri> setEntryPoints(List<Uri> entryPoints) {
     Map<String, Uri> packagesMap;
+    List<Uri> result = new List<Uri>();
     for (Uri entryPoint in entryPoints) {
       String scheme = entryPoint.scheme;
       Uri fileUri;
@@ -186,8 +189,10 @@
             }
           }
       }
+      result.add(entryPoint);
       loader.read(entryPoint, -1, accessor: loader.first, fileUri: fileUri);
     }
+    return result;
   }
 
   @override
@@ -255,7 +260,8 @@
       component =
           link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
       computeCoreTypes();
-      loader.buildClassHierarchy(myClasses, objectClassBuilder);
+      builderHierarchy =
+          loader.buildClassHierarchy(myClasses, objectClassBuilder);
       loader.computeHierarchy();
       loader.performTopLevelInference(myClasses);
       loader.checkSupertypes(myClasses);
@@ -265,6 +271,8 @@
       loader.checkRedirectingFactories(myClasses);
       loader.addNoSuchMethodForwarders(myClasses);
       loader.checkMixins(myClasses);
+      installAllComponentProblems(loader.allComponentProblems);
+      loader.allComponentProblems.clear();
       return component;
     }, () => loader?.currentUriForCrashReporting);
   }
@@ -293,27 +301,20 @@
       runBuildTransformations();
 
       if (verify) this.verify();
-      handleRecoverableErrors(loader.unhandledErrors);
+      installAllComponentProblems(loader.allComponentProblems);
       return component;
     }, () => loader?.currentUriForCrashReporting);
   }
 
-  /// Adds a synthetic field named `#errors` to the main library that contains
-  /// [recoverableErrors] formatted.
-  ///
-  /// If [recoverableErrors] is empty, this method does nothing.
-  void handleRecoverableErrors(List<LocatedMessage> recoverableErrors) {
-    if (recoverableErrors.isEmpty) return;
-    KernelLibraryBuilder mainLibrary = loader.first;
-    if (mainLibrary == null) return;
-    List<Expression> expressions = <Expression>[];
-    for (LocatedMessage error in recoverableErrors) {
-      expressions.add(new StringLiteral(context.format(error, Severity.error)));
+  void installAllComponentProblems(
+      List<FormattedMessage> allComponentProblems) {
+    if (allComponentProblems.isNotEmpty) {
+      component.problemsAsJson ??= <String>[];
     }
-    mainLibrary.library.addMember(new Field(new Name("#errors"),
-        initializer: new ListLiteral(expressions, isConst: true),
-        isConst: true,
-        isStatic: true));
+    for (int i = 0; i < allComponentProblems.length; i++) {
+      FormattedMessage formattedMessage = allComponentProblems[i];
+      component.problemsAsJson.add(formattedMessage.toJsonString());
+    }
   }
 
   /// Creates a component by combining [libraries] with the libraries of
@@ -557,6 +558,7 @@
       "dart:_internal",
       "dart:async",
       "dart:core",
+      "dart:ffi",
       "dart:mirrors"
     ]) {
       Uri uri = Uri.parse(platformLibrary);
@@ -572,8 +574,8 @@
             break;
           }
         }
-        if (!found && uri.path != "mirrors") {
-          // dart:mirrors is optional.
+        if (!found && uri.path != "mirrors" && uri.path != "ffi") {
+          // dart:mirrors and dart:ffi are optional.
           throw "Can't find $uri";
         }
       } else {
@@ -749,17 +751,23 @@
   /// libraries for the first time.
   void runBuildTransformations() {
     if (loader.target.enableConstantUpdate2018) {
+      TypeEnvironment environment = new TypeEnvironment(
+          loader.coreTypes, loader.hierarchy,
+          legacyMode: false);
       constants.transformLibraries(
           loader.libraries,
-          new KernelConstantsBackend(),
-          loader.coreTypes,
-          new TypeEnvironment(loader.coreTypes, loader.hierarchy,
-              legacyMode: false),
-          const constants.SimpleErrorReporter());
+          loader.target.backendTarget.constantsBackend(loader.coreTypes),
+          CompilerContext.current.options.environmentDefines,
+          environment,
+          new KernelConstantErrorReporter(loader, environment));
       ticker.logMs("Evaluated constants");
     }
     backendTarget.performModularTransformationsOnLibraries(
-        component, loader.coreTypes, loader.hierarchy, loader.libraries,
+        component,
+        loader.coreTypes,
+        loader.hierarchy,
+        loader.libraries,
+        new KernelDiagnosticReporter(loader),
         logger: (String msg) => ticker.logMs(msg));
   }
 
@@ -801,6 +809,7 @@
           KernelLibraryBuilder part = library.loader.read(patch, -1,
               origin: library, fileUri: patch, accessor: library);
           first.parts.add(part);
+          first.partOffsets.add(-1);
           part.partOfUri = first.uri;
         }
       }
@@ -824,3 +833,15 @@
   }
   return null;
 }
+
+class KernelDiagnosticReporter
+    extends DiagnosticReporter<Message, LocatedMessage> {
+  final Loader<Library> loader;
+
+  KernelDiagnosticReporter(this.loader);
+
+  void report(Message message, int charOffset, int length, Uri fileUri,
+      {List<LocatedMessage> context}) {
+    loader.addProblem(message, charOffset, noLength, fileUri, context: context);
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_type_alias_builder.dart
new file mode 100644
index 0000000..e9c4064
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_type_alias_builder.dart
@@ -0,0 +1,201 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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.kernel_function_type_alias_builder;
+
+import 'package:kernel/ast.dart'
+    show
+        DartType,
+        DynamicType,
+        FunctionType,
+        InvalidType,
+        Library,
+        TypeParameter,
+        Typedef,
+        VariableDeclaration;
+
+import 'package:kernel/type_algebra.dart'
+    show FreshTypeParameters, getFreshTypeParameters, substitute;
+
+import '../fasta_codes.dart'
+    show noLength, templateCyclicTypedef, templateTypeArgumentMismatch;
+
+import '../problems.dart' show unhandled;
+
+import 'kernel_builder.dart'
+    show
+        TypeAliasBuilder,
+        KernelFormalParameterBuilder,
+        KernelFunctionTypeBuilder,
+        KernelLibraryBuilder,
+        KernelTypeBuilder,
+        KernelTypeVariableBuilder,
+        LibraryBuilder,
+        MetadataBuilder,
+        TypeVariableBuilder;
+
+final InvalidType cyclicTypeAliasMarker = new InvalidType();
+
+class KernelTypeAliasBuilder
+    extends TypeAliasBuilder<KernelTypeBuilder, DartType> {
+  final Typedef target;
+
+  DartType thisType;
+
+  KernelTypeAliasBuilder(
+      List<MetadataBuilder<KernelTypeBuilder>> metadata,
+      String name,
+      List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables,
+      KernelFunctionTypeBuilder type,
+      LibraryBuilder<KernelTypeBuilder, Library> parent,
+      int charOffset,
+      [Typedef target])
+      : target = target ??
+            (new Typedef(name, null,
+                typeParameters:
+                    KernelTypeVariableBuilder.kernelTypeParametersFromBuilders(
+                        typeVariables),
+                fileUri: parent.target.fileUri)
+              ..fileOffset = charOffset),
+        super(metadata, name, typeVariables, type, parent, charOffset);
+
+  Typedef build(KernelLibraryBuilder libraryBuilder) {
+    target..type ??= buildThisType(libraryBuilder);
+
+    KernelTypeBuilder type = this.type;
+    if (type is KernelFunctionTypeBuilder) {
+      List<TypeParameter> typeParameters =
+          new List<TypeParameter>(type.typeVariables?.length ?? 0);
+      for (int i = 0; i < typeParameters.length; ++i) {
+        KernelTypeVariableBuilder typeVariable = type.typeVariables[i];
+        typeParameters[i] = typeVariable.parameter;
+      }
+      FreshTypeParameters freshTypeParameters =
+          getFreshTypeParameters(typeParameters);
+      target.typeParametersOfFunctionType
+          .addAll(freshTypeParameters.freshTypeParameters);
+
+      if (type.formals != null) {
+        for (KernelFormalParameterBuilder formal in type.formals) {
+          VariableDeclaration parameter = formal.build(libraryBuilder, 0);
+          parameter.type = freshTypeParameters.substitute(parameter.type);
+          if (formal.isNamed) {
+            target.namedParameters.add(parameter);
+          } else {
+            target.positionalParameters.add(parameter);
+          }
+        }
+      }
+    } else if (type != null) {
+      unhandled("${type.fullNameForErrors}", "build", charOffset, fileUri);
+    }
+
+    return target;
+  }
+
+  DartType buildThisType(LibraryBuilder<KernelTypeBuilder, Library> library) {
+    if (thisType != null) {
+      if (identical(thisType, cyclicTypeAliasMarker)) {
+        library.addProblem(templateCyclicTypedef.withArguments(name),
+            charOffset, noLength, fileUri);
+        return const InvalidType();
+      }
+      return thisType;
+    }
+    // It is a compile-time error for an alias (typedef) to refer to itself. We
+    // detect cycles by detecting recursive calls to this method using an
+    // instance of InvalidType that isn't identical to `const InvalidType()`.
+    thisType = cyclicTypeAliasMarker;
+    KernelTypeBuilder type = this.type;
+    if (type is KernelFunctionTypeBuilder) {
+      FunctionType builtType = type?.build(library, target.thisType);
+      if (builtType != null) {
+        if (typeVariables != null) {
+          for (KernelTypeVariableBuilder tv in typeVariables) {
+            // Follow bound in order to find all cycles
+            tv.bound?.build(library);
+          }
+        }
+        return thisType = builtType;
+      } else {
+        return thisType = const InvalidType();
+      }
+    } else if (type == null) {
+      return thisType = const InvalidType();
+    } else {
+      return unhandled(
+          "${type.fullNameForErrors}", "buildThisType", charOffset, fileUri);
+    }
+  }
+
+  /// [arguments] have already been built.
+  DartType buildTypesWithBuiltArguments(
+      LibraryBuilder<KernelTypeBuilder, Object> library,
+      List<DartType> arguments) {
+    var thisType = buildThisType(library);
+    if (const DynamicType() == thisType) return thisType;
+    FunctionType result = thisType;
+    if (target.typeParameters.isEmpty && arguments == null) return result;
+    Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
+    for (int i = 0; i < target.typeParameters.length; i++) {
+      substitution[target.typeParameters[i]] = arguments[i];
+    }
+    return substitute(result, substitution);
+  }
+
+  List<DartType> buildTypeArguments(
+      LibraryBuilder<KernelTypeBuilder, Library> library,
+      List<KernelTypeBuilder> arguments) {
+    if (arguments == null && typeVariables == null) {
+      return <DartType>[];
+    }
+
+    if (arguments == null && typeVariables != null) {
+      List<DartType> result =
+          new List<DartType>.filled(typeVariables.length, null, growable: true);
+      for (int i = 0; i < result.length; ++i) {
+        result[i] = typeVariables[i].defaultType.build(library);
+      }
+      if (library is KernelLibraryBuilder) {
+        library.inferredTypes.addAll(result);
+      }
+      return result;
+    }
+
+    if (arguments != null && arguments.length != (typeVariables?.length ?? 0)) {
+      // That should be caught and reported as a compile-time error earlier.
+      return unhandled(
+          templateTypeArgumentMismatch
+              .withArguments(typeVariables.length)
+              .message,
+          "buildTypeArguments",
+          -1,
+          null);
+    }
+
+    // arguments.length == typeVariables.length
+    List<DartType> result =
+        new List<DartType>.filled(arguments.length, null, growable: true);
+    for (int i = 0; i < result.length; ++i) {
+      result[i] = arguments[i].build(library);
+    }
+    return result;
+  }
+
+  /// If [arguments] are null, the default types for the variables are used.
+  @override
+  int get typeVariablesCount => typeVariables?.length ?? 0;
+
+  @override
+  DartType buildType(LibraryBuilder<KernelTypeBuilder, Object> library,
+      List<KernelTypeBuilder> arguments) {
+    var thisType = buildThisType(library);
+    if (thisType is InvalidType) return thisType;
+    FunctionType result = thisType;
+    if (target.typeParameters.isEmpty && arguments == null) return result;
+    // Otherwise, substitute.
+    return buildTypesWithBuiltArguments(
+        library, buildTypeArguments(library, arguments));
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart b/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
index e32f179..abc2f4d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_set_literals.dart
@@ -55,8 +55,7 @@
     return coreTypes.index.getMember('dart:core', 'Set', 'add');
   }
 
-  static Constructor _findUnmodifiableSetConstructor(
-      SourceLoader<Library> loader) {
+  static Constructor _findUnmodifiableSetConstructor(SourceLoader loader) {
     // We should not generally dig into libraries like this, and we should
     // avoid dependencies on libraries other than the ones indexed by
     // CoreTypes. This is a temporary solution until all backends have
@@ -77,7 +76,7 @@
     return null;
   }
 
-  SetLiteralTransformer(SourceLoader<Library> loader)
+  SetLiteralTransformer(SourceLoader loader)
       : coreTypes = loader.coreTypes,
         nullType = new InterfaceType(loader.coreTypes.nullClass, []),
         setFactory = _findSetFactory(loader.coreTypes),
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 eae7bf1..d05e0d8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -25,7 +25,7 @@
     show
         ClassBuilder,
         FormalParameterBuilder,
-        FunctionTypeAliasBuilder,
+        TypeAliasBuilder,
         FunctionTypeBuilder,
         KernelClassBuilder,
         KernelFormalParameterBuilder,
@@ -40,7 +40,7 @@
 
 import '../dill/dill_class_builder.dart' show DillClassBuilder;
 
-import '../dill/dill_typedef_builder.dart' show DillFunctionTypeAliasBuilder;
+import '../dill/dill_type_alias_builder.dart' show DillTypeAliasBuilder;
 
 import '../fasta_codes.dart'
     show
@@ -362,7 +362,7 @@
           typesAndDependencies.add(type);
           typesAndDependencies.add(const <Object>[]);
         }
-      } else if (declaration is DillFunctionTypeAliasBuilder) {
+      } else if (declaration is DillTypeAliasBuilder) {
         bool hasInbound = false;
         List<TypeParameter> typeParameters = declaration.target.typeParameters;
         for (int i = 0; i < typeParameters.length && !hasInbound; ++i) {
@@ -383,7 +383,7 @@
           typesAndDependencies.add(type);
           typesAndDependencies.add(dependencies);
         }
-      } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object>) {
+      } else if (declaration is TypeAliasBuilder<TypeBuilder, Object>) {
         if (declaration.typeVariables != null) {
           List<Object> dependencies =
               findInboundReferences(declaration.typeVariables);
@@ -518,8 +518,7 @@
               }
             }
           }
-        } else if (declaration
-            is FunctionTypeAliasBuilder<TypeBuilder, Object>) {
+        } else if (declaration is TypeAliasBuilder<TypeBuilder, Object>) {
           if (declaration.typeVariables != null) {
             for (TypeVariableBuilder<TypeBuilder, Object> variable
                 in declaration.typeVariables) {
@@ -604,7 +603,7 @@
         }
       }
     }
-  } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object>) {
+  } else if (declaration is TypeAliasBuilder<TypeBuilder, Object>) {
     if (declaration.typeVariables != null) {
       for (TypeVariableBuilder<TypeBuilder, Object> variable
           in declaration.typeVariables) {
@@ -709,7 +708,7 @@
   if (declaration is ClassBuilder<TypeBuilder, Object> &&
       declaration.typeVariables != null) {
     issues.addAll(getInboundReferenceIssues(declaration.typeVariables));
-  } else if (declaration is FunctionTypeAliasBuilder<TypeBuilder, Object> &&
+  } else if (declaration is TypeAliasBuilder<TypeBuilder, Object> &&
       declaration.typeVariables != null) {
     issues.addAll(getInboundReferenceIssues(declaration.typeVariables));
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.dart
new file mode 100644
index 0000000..390f4e4
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/type_builder_computer.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.
+
+library fasta.type_builder_computer;
+
+import 'package:kernel/ast.dart'
+    show
+        BottomType,
+        Class,
+        DartType,
+        DartTypeVisitor,
+        DynamicType,
+        FunctionType,
+        InterfaceType,
+        InvalidType,
+        Library,
+        TypeParameter,
+        TypeParameterType,
+        TypedefType,
+        VoidType;
+
+import '../kernel/kernel_builder.dart'
+    show
+        DynamicTypeBuilder,
+        KernelClassBuilder,
+        KernelNamedTypeBuilder,
+        KernelTypeBuilder,
+        KernelTypeVariableBuilder,
+        LibraryBuilder,
+        VoidTypeBuilder;
+
+import '../loader.dart' show Loader;
+
+class TypeBuilderComputer implements DartTypeVisitor<KernelTypeBuilder> {
+  final Loader<Library> loader;
+
+  const TypeBuilderComputer(this.loader);
+
+  KernelTypeBuilder defaultDartType(DartType node) {
+    throw "Unsupported";
+  }
+
+  KernelTypeBuilder visitInvalidType(InvalidType node) {
+    throw "Not implemented";
+  }
+
+  KernelTypeBuilder visitDynamicType(DynamicType node) {
+    return new KernelNamedTypeBuilder("dynamic", null)
+      ..bind(new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
+          const DynamicType(), loader.coreLibrary, -1));
+  }
+
+  KernelTypeBuilder visitVoidType(VoidType node) {
+    return new KernelNamedTypeBuilder("void", null)
+      ..bind(new VoidTypeBuilder<KernelTypeBuilder, VoidType>(
+          const VoidType(), loader.coreLibrary, -1));
+  }
+
+  KernelTypeBuilder visitBottomType(BottomType node) {
+    throw "Not implemented";
+  }
+
+  KernelTypeBuilder visitInterfaceType(InterfaceType node) {
+    KernelClassBuilder cls =
+        loader.computeClassBuilderFromTargetClass(node.classNode);
+    List<KernelTypeBuilder> arguments;
+    List<DartType> kernelArguments = node.typeArguments;
+    if (kernelArguments.isNotEmpty) {
+      arguments = new List<KernelTypeBuilder>(kernelArguments.length);
+      for (int i = 0; i < kernelArguments.length; i++) {
+        arguments[i] = kernelArguments[i].accept(this);
+      }
+    }
+    return new KernelNamedTypeBuilder(cls.name, arguments)..bind(cls);
+  }
+
+  KernelTypeBuilder visitFunctionType(FunctionType node) {
+    throw "Not implemented";
+  }
+
+  KernelTypeBuilder visitTypeParameterType(TypeParameterType node) {
+    TypeParameter parameter = node.parameter;
+    Class kernelClass = parameter.parent;
+    Library kernelLibrary = kernelClass.enclosingLibrary;
+    LibraryBuilder<KernelTypeBuilder, Library> library =
+        loader.builders[kernelLibrary.importUri];
+    return new KernelNamedTypeBuilder(parameter.name, null)
+      ..bind(new KernelTypeVariableBuilder.fromKernel(parameter, library));
+  }
+
+  KernelTypeBuilder visitTypedefType(TypedefType node) {
+    throw "Not implemented";
+  }
+}
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 38fa92c..c0be105 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -14,9 +14,6 @@
         DartType,
         DoubleConstant,
         DynamicType,
-        EnvironmentBoolConstant,
-        EnvironmentIntConstant,
-        EnvironmentStringConstant,
         Field,
         FunctionType,
         InvalidType,
@@ -243,10 +240,11 @@
   }
 
   void visitInstanceConstant(InstanceConstant node) {
-    new InterfaceType(node.klass, node.typeArguments).accept(this);
+    new InterfaceType(node.classNode, node.typeArguments).accept(this);
     result.add(" {");
     bool first = true;
-    for (Field field in node.klass.fields) {
+    for (Field field in node.classNode.fields) {
+      if (field.isStatic) continue;
       if (!first) result.add(", ");
       result.add("${field.name}: ");
       node.fieldValues[field.reference].accept(this);
@@ -313,18 +311,6 @@
     node.type.accept(this);
   }
 
-  void visitEnvironmentBoolConstant(EnvironmentBoolConstant node) {
-    unsupported('printing unevaluated constants', -1, null);
-  }
-
-  void visitEnvironmentIntConstant(EnvironmentIntConstant node) {
-    unsupported('printing unevaluated constants', -1, null);
-  }
-
-  void visitEnvironmentStringConstant(EnvironmentStringConstant node) {
-    unsupported('printing unevaluated constants', -1, null);
-  }
-
   void visitUnevaluatedConstant(UnevaluatedConstant node) {
     unsupported('printing unevaluated constants', -1, null);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
new file mode 100644
index 0000000..d7207b5
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/types.dart
@@ -0,0 +1,553 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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,
+        NamedType,
+        TypeParameter,
+        TypeParameterType,
+        TypedefType,
+        VoidType;
+
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+import 'kernel_builder.dart' show ClassHierarchyBuilder;
+
+class Types {
+  final ClassHierarchyBuilder hierarchy;
+
+  Types(this.hierarchy);
+
+  /// Returns true if [s] is a subtype of [t].
+  bool isSubtypeOfKernel(DartType s, DartType t) {
+    if (s is BottomType) {
+      return true; // Rule 3.
+    }
+    if (s is InvalidType) {
+      // InvalidType is also a bottom type.
+      return true;
+    }
+    if (t is InvalidType) {
+      return false;
+    }
+    if (t is DynamicType) {
+      return true; // Rule 2.
+    }
+    if (t is VoidType) {
+      return true; // Rule 2.
+    }
+    if (t is BottomType) {
+      return false;
+    }
+    if (t is InterfaceType) {
+      Class cls = t.classNode;
+      if (cls == hierarchy.objectKernelClass) {
+        return true; // Rule 2.
+      }
+      if (cls == hierarchy.futureOrKernelClass) {
+        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.futureOrKernelClass
+              ? 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.futureOrKernelClass
+              ? 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.futureOrKernelClass
+            ? 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.futureOrKernelClass
+              ? 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.futureOrKernelClass
+              ? 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.futureOrKernelClass
+            ? 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 {
+      throw "Unhandled type: ${t.runtimeType}";
+    }
+    throw "Unhandled type combination: ${t.runtimeType} ${s.runtimeType}";
+  }
+
+  /// Returns true if all types in [s] and [t] pairwise are subtypes.
+  bool areSubtypesOfKernel(List<DartType> s, List<DartType> t) {
+    if (s.length != t.length) {
+      throw "Numbers of type arguments don't match $s $t.";
+    }
+    for (int i = 0; i < s.length; i++) {
+      if (!isSubtypeOfKernel(s[i], t[i])) return false;
+    }
+    return true;
+  }
+
+  bool isSameTypeKernel(DartType s, DartType t) {
+    return isSubtypeOfKernel(s, t) && isSubtypeOfKernel(t, s);
+  }
+}
+
+abstract class TypeRelation<T extends DartType> {
+  const TypeRelation();
+
+  bool isDynamicRelated(DynamicType s, T t, Types types);
+
+  bool isVoidRelated(VoidType s, T t, Types types);
+
+  bool isInterfaceRelated(InterfaceType s, T t, Types types);
+
+  bool isIntersectionRelated(TypeParameterType intersection, T t, Types types);
+
+  bool isFunctionRelated(FunctionType s, T t, Types types);
+
+  bool isFutureOrRelated(InterfaceType futureOr, T t, Types types);
+
+  bool isTypeParameterRelated(TypeParameterType s, T t, Types types);
+
+  bool isTypedefRelated(TypedefType s, T t, Types types);
+}
+
+class IsInterfaceSubtypeOf extends TypeRelation<InterfaceType> {
+  const IsInterfaceSubtypeOf();
+
+  @override
+  bool isInterfaceRelated(InterfaceType s, InterfaceType t, Types types) {
+    if (s.classNode == types.hierarchy.nullKernelClass) {
+      // This is an optimization, to avoid instantating unnecessary type
+      // arguments in getKernelTypeAsInstanceOf.
+      return true;
+    }
+    InterfaceType asSupertype =
+        types.hierarchy.getKernelTypeAsInstanceOf(s, t.classNode);
+    if (asSupertype == null) {
+      return false;
+    } else {
+      return types.areSubtypesOfKernel(
+          asSupertype.typeArguments, t.typeArguments);
+    }
+  }
+
+  @override
+  bool isTypeParameterRelated(
+      TypeParameterType s, InterfaceType t, Types types) {
+    return types.isSubtypeOfKernel(s.parameter.bound, t);
+  }
+
+  @override
+  bool isFutureOrRelated(InterfaceType futureOr, InterfaceType t, Types types) {
+    List<DartType> arguments = futureOr.typeArguments;
+    if (!types.isSubtypeOfKernel(arguments.single, t)) {
+      return false; // Rule 7.1
+    }
+    if (!types.isSubtypeOfKernel(
+        new InterfaceType(types.hierarchy.futureKernelClass, arguments), t)) {
+      return false; // Rule 7.2
+    }
+    return true;
+  }
+
+  @override
+  bool isIntersectionRelated(
+      TypeParameterType intersection, InterfaceType t, Types types) {
+    return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
+  }
+
+  @override
+  bool isDynamicRelated(DynamicType s, InterfaceType t, Types types) {
+    return false;
+  }
+
+  @override
+  bool isFunctionRelated(FunctionType s, InterfaceType t, Types types) {
+    return t.classNode == types.hierarchy.functionKernelClass; // Rule 14.
+  }
+
+  @override
+  bool isTypedefRelated(TypedefType s, InterfaceType t, Types types) {
+    return false;
+  }
+
+  @override
+  bool isVoidRelated(VoidType s, InterfaceType t, Types types) {
+    return false;
+  }
+}
+
+class IsFunctionSubtypeOf extends TypeRelation<FunctionType> {
+  const IsFunctionSubtypeOf();
+
+  @override
+  bool isFunctionRelated(FunctionType s, FunctionType t, Types types) {
+    List<TypeParameter> sTypeVariables = s.typeParameters;
+    List<TypeParameter> tTypeVariables = t.typeParameters;
+    if (sTypeVariables.length != tTypeVariables.length) return false;
+    if (sTypeVariables.isNotEmpty) {
+      // If the function types have type variables, we alpha-rename the type
+      // variables of [s] to use those of [t].
+      List<DartType> typeVariableSubstitution = <DartType>[];
+      bool secondBoundsCheckNeeded = false;
+      for (int i = 0; i < sTypeVariables.length; i++) {
+        TypeParameter sTypeVariable = sTypeVariables[i];
+        TypeParameter tTypeVariable = tTypeVariables[i];
+        if (!types.isSameTypeKernel(sTypeVariable.bound, tTypeVariable.bound)) {
+          // If the bounds aren't the same, we need to try again after
+          // computing the substitution of type variables.
+          secondBoundsCheckNeeded = true;
+        }
+        typeVariableSubstitution.add(new TypeParameterType(tTypeVariable));
+      }
+      Substitution substitution =
+          Substitution.fromPairs(sTypeVariables, typeVariableSubstitution);
+      if (secondBoundsCheckNeeded) {
+        for (int i = 0; i < sTypeVariables.length; i++) {
+          TypeParameter sTypeVariable = sTypeVariables[i];
+          TypeParameter tTypeVariable = tTypeVariables[i];
+          if (!types.isSameTypeKernel(
+              substitution.substituteType(sTypeVariable.bound),
+              tTypeVariable.bound)) {
+            return false;
+          }
+        }
+      }
+      s = substitution.substituteType(s.withoutTypeParameters);
+    }
+    if (!types.isSubtypeOfKernel(s.returnType, t.returnType)) return false;
+    List<DartType> sPositional = s.positionalParameters;
+    List<DartType> tPositional = t.positionalParameters;
+    if (s.requiredParameterCount > t.requiredParameterCount) {
+      // Rule 15, n1 <= n2.
+      return false;
+    }
+    if (sPositional.length < tPositional.length) {
+      // Rule 15, n1 + k1 >= n2 + k2.
+      return false;
+    }
+    for (int i = 0; i < tPositional.length; i++) {
+      if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i])) {
+        // Rule 15, Tj <: Sj.
+        return false;
+      }
+    }
+    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 false;
+      if (s.requiredParameterCount != t.requiredParameterCount) return false;
+
+      // 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 false;
+        if (!types.isSubtypeOfKernel(
+            tNamed[tCount].type, sNamed[sCount].type)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  @override
+  bool isInterfaceRelated(InterfaceType s, FunctionType t, Types types) {
+    return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
+  }
+
+  @override
+  bool isDynamicRelated(DynamicType s, FunctionType t, Types types) => false;
+
+  @override
+  bool isFutureOrRelated(InterfaceType futureOr, FunctionType t, Types types) {
+    return false;
+  }
+
+  @override
+  bool isIntersectionRelated(
+      TypeParameterType intersection, FunctionType t, Types types) {
+    // Rule 12.
+    return types.isSubtypeOfKernel(intersection.promotedBound, t);
+  }
+
+  @override
+  bool isTypeParameterRelated(
+      TypeParameterType s, FunctionType t, Types types) {
+    // Rule 13.
+    return types.isSubtypeOfKernel(s.parameter.bound, t);
+  }
+
+  @override
+  bool isTypedefRelated(TypedefType s, FunctionType t, Types types) {
+    // Rule 5.
+    return types.isSubtypeOfKernel(s.unalias, t);
+  }
+
+  @override
+  bool isVoidRelated(VoidType s, FunctionType t, Types types) {
+    return false;
+  }
+}
+
+class IsTypeParameterSubtypeOf extends TypeRelation<TypeParameterType> {
+  const IsTypeParameterSubtypeOf();
+
+  @override
+  bool isTypeParameterRelated(
+      TypeParameterType s, TypeParameterType t, Types types) {
+    return s.parameter == t.parameter;
+  }
+
+  @override
+  bool isIntersectionRelated(
+      TypeParameterType intersection, TypeParameterType t, Types types) {
+    return intersection.parameter == t.parameter; // Rule 8.
+  }
+
+  @override
+  bool isInterfaceRelated(InterfaceType s, TypeParameterType t, Types types) {
+    return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
+  }
+
+  @override
+  bool isDynamicRelated(DynamicType s, TypeParameterType t, Types types) {
+    return false;
+  }
+
+  @override
+  bool isFunctionRelated(FunctionType s, TypeParameterType t, Types types) {
+    return false;
+  }
+
+  @override
+  bool isFutureOrRelated(
+      InterfaceType futureOr, TypeParameterType t, Types types) {
+    return false;
+  }
+
+  @override
+  bool isTypedefRelated(TypedefType s, TypeParameterType t, Types types) {
+    return types.isSubtypeOfKernel(s.unalias, t);
+  }
+
+  @override
+  bool isVoidRelated(VoidType s, TypeParameterType t, Types types) {
+    return false;
+  }
+}
+
+class IsTypedefSubtypeOf extends TypeRelation<TypedefType> {
+  const IsTypedefSubtypeOf();
+
+  @override
+  bool isInterfaceRelated(InterfaceType s, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(s, t.unalias);
+  }
+
+  @override
+  bool isDynamicRelated(DynamicType s, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(s, t.unalias);
+  }
+
+  @override
+  bool isFunctionRelated(FunctionType s, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(s, t.unalias);
+  }
+
+  @override
+  bool isFutureOrRelated(InterfaceType futureOr, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(futureOr, t.unalias);
+  }
+
+  @override
+  bool isIntersectionRelated(
+      TypeParameterType intersection, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(intersection, t.unalias);
+  }
+
+  @override
+  bool isTypeParameterRelated(TypeParameterType s, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(s, t.unalias);
+  }
+
+  @override
+  bool isTypedefRelated(TypedefType s, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(s.unalias, t.unalias);
+  }
+
+  @override
+  bool isVoidRelated(VoidType s, TypedefType t, Types types) {
+    return types.isSubtypeOfKernel(s, t.unalias);
+  }
+}
+
+class IsFutureOrSubtypeOf extends TypeRelation<InterfaceType> {
+  const IsFutureOrSubtypeOf();
+
+  @override
+  bool isInterfaceRelated(
+      InterfaceType s, InterfaceType futureOr, Types types) {
+    List<DartType> arguments = futureOr.typeArguments;
+    if (types.isSubtypeOfKernel(s, arguments.single)) {
+      return true; // Rule 11.
+    }
+    // Rule 10.
+    return types.isSubtypeOfKernel(
+        s, new InterfaceType(types.hierarchy.futureKernelClass, arguments));
+  }
+
+  @override
+  bool isFutureOrRelated(
+      InterfaceType sFutureOr, InterfaceType tFutureOr, Types types) {
+    //return types.isSubtypeOfKernel(
+    //    sFutureOr.typeArguments.single, futureOr.typeArguments.single);
+    // TODO(ahe): Not tested yet.
+    return true;
+  }
+
+  // TODO(ahe): Remove this method.
+  noSuchMethod(invocation) => super.noSuchMethod(invocation);
+}
+
+class IsIntersectionSubtypeOf extends TypeRelation<TypeParameterType> {
+  const IsIntersectionSubtypeOf();
+
+  @override
+  bool isIntersectionRelated(TypeParameterType sIntersection,
+      TypeParameterType tIntersection, Types types) {
+    // Rule 9.
+    return const IsTypeParameterSubtypeOf()
+            .isIntersectionRelated(sIntersection, tIntersection, types) &&
+        types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
+  }
+
+  @override
+  bool isTypeParameterRelated(
+      TypeParameterType s, TypeParameterType intersection, Types types) {
+    // Rule 9.
+    return const IsTypeParameterSubtypeOf()
+            .isTypeParameterRelated(s, intersection, types) &&
+        types.isSubtypeOfKernel(s, intersection.promotedBound);
+  }
+
+  @override
+  bool isInterfaceRelated(
+      InterfaceType s, TypeParameterType intersection, Types types) {
+    return s.classNode == types.hierarchy.nullKernelClass; // Rule 4.
+  }
+
+  // TODO(ahe): Remove this method.
+  noSuchMethod(invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 30686ba..8709bb4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -33,11 +33,13 @@
     {bool libraryFilter(Library library)}) {
   if (component == null) return;
   StringBuffer sb = new StringBuffer();
+  Printer printer = new Printer(sb);
+  printer.writeComponentProblems(component);
   for (Library library in component.libraries) {
     if (libraryFilter != null && !libraryFilter(library)) continue;
-    Printer printer = new Printer(sb);
     printer.writeLibraryFile(library);
   }
+  printer.writeConstantTable(component);
   print(sb);
 }
 
@@ -95,9 +97,12 @@
     }
 
     fakeClass.parent = fakeLibrary;
-    fakeClass.supertype = new Supertype.byReference(
-        realClass.supertype.className,
-        realClass.supertype.typeArguments.map(cloner.visitType).toList());
+    if (realClass.supertype != null) {
+      // supertype is null for Object.
+      fakeClass.supertype = new Supertype.byReference(
+          realClass.supertype.className,
+          realClass.supertype.typeArguments.map(cloner.visitType).toList());
+    }
 
     // Rebind the type parameters in the procedure.
     procedure = procedure.accept(cloner);
diff --git a/pkg/front_end/lib/src/fasta/library_graph.dart b/pkg/front_end/lib/src/fasta/library_graph.dart
index 0d7ab6f..acf183f 100644
--- a/pkg/front_end/lib/src/fasta/library_graph.dart
+++ b/pkg/front_end/lib/src/fasta/library_graph.dart
@@ -4,7 +4,8 @@
 
 library fasta.library_graph;
 
-import 'package:kernel/kernel.dart' show Library, LibraryDependency;
+import 'package:kernel/kernel.dart'
+    show Library, LibraryDependency, LibraryPart;
 
 import 'package:kernel/util/graph.dart' show Graph;
 
@@ -21,7 +22,7 @@
       throw "Library not found: $vertex";
     }
 
-    // Imports and exports
+    // Imports and exports.
     for (LibraryDependency dependency in library.dependencies) {
       Uri uri1 = dependency.targetLibrary.importUri;
       Uri uri2 = dependency.targetLibrary.fileUri;
@@ -33,5 +34,18 @@
         }
       }
     }
+
+    // Parts.
+    // Normally there won't be libraries for these, but if, for instance,
+    // the part didn't exist there will be a synthetic library.
+    for (LibraryPart part in library.parts) {
+      Uri partUri = library.importUri.resolve(part.partUri);
+      Uri fileUri = library.fileUri.resolve(part.partUri);
+      if (libraries.containsKey(partUri)) {
+        yield partUri;
+      } else if (fileUri != partUri && libraries.containsKey(fileUri)) {
+        yield fileUri;
+      }
+    }
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index 8823bfa..da5a124 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -8,12 +8,14 @@
 
 import 'dart:collection' show Queue;
 
-import 'builder/builder.dart' show Declaration, LibraryBuilder;
+import 'builder/builder.dart'
+    show ClassBuilder, Declaration, LibraryBuilder, TypeBuilder;
 
 import 'crash.dart' show firstSourceUri;
 
 import 'messages.dart'
     show
+        FormattedMessage,
         LocatedMessage,
         Message,
         noLength,
@@ -25,8 +27,6 @@
 
 import 'problems.dart' show internalProblem, unhandled;
 
-import 'rewrite_severity.dart' show rewriteSeverity;
-
 import 'severity.dart' show Severity;
 
 import 'target_implementation.dart' show TargetImplementation;
@@ -58,6 +58,10 @@
   /// [handledErrors].
   final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
 
+  /// List of all problems seen so far by libraries loaded by this loader that
+  /// does not belong directly to a library.
+  final List<FormattedMessage> allComponentProblems = <FormattedMessage>[];
+
   final Set<String> seenMessages = new Set<String>();
 
   LibraryBuilder coreLibrary;
@@ -213,34 +217,36 @@
 
   /// Register [message] as a problem with a severity determined by the
   /// intrinsic severity of the message.
-  void addProblem(Message message, int charOffset, int length, Uri fileUri,
+  FormattedMessage addProblem(
+      Message message, int charOffset, int length, Uri fileUri,
       {bool wasHandled: false,
       List<LocatedMessage> context,
-      Severity severity}) {
-    severity ??= message.code.severity;
-    if (severity == Severity.errorLegacyWarning) {
-      severity =
-          target.backendTarget.legacyMode ? Severity.warning : Severity.error;
-    }
-    addMessage(message, charOffset, length, fileUri, severity,
-        wasHandled: wasHandled, context: context);
+      Severity severity,
+      bool problemOnLibrary: false}) {
+    return addMessage(message, charOffset, length, fileUri, severity,
+        wasHandled: wasHandled,
+        context: context,
+        problemOnLibrary: problemOnLibrary);
   }
 
   /// All messages reported by the compiler (errors, warnings, etc.) are routed
   /// through this method.
   ///
-  /// Returns true if the message is new, that is, not previously
+  /// Returns a FormattedMessage if the message is new, that is, not previously
   /// reported. This is important as some parser errors may be reported up to
   /// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
+  /// If the message is not new, [null] is reported.
   ///
   /// If [severity] is `Severity.error`, the message is added to
   /// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
   /// [wasHandled] is false.
-  bool addMessage(Message message, int charOffset, int length, Uri fileUri,
-      Severity severity,
-      {bool wasHandled: false, List<LocatedMessage> context}) {
-    severity = rewriteSeverity(severity, message.code, fileUri);
-    if (severity == Severity.ignored) return false;
+  FormattedMessage addMessage(Message message, int charOffset, int length,
+      Uri fileUri, Severity severity,
+      {bool wasHandled: false,
+      List<LocatedMessage> context,
+      bool problemOnLibrary: false}) {
+    severity = target.fixSeverity(severity, message, fileUri);
+    if (severity == Severity.ignored) return null;
     String trace = """
 message: ${message.message}
 charOffset: $charOffset
@@ -258,7 +264,7 @@
 """;
       }
     }
-    if (!seenMessages.add(trace)) return false;
+    if (!seenMessages.add(trace)) return null;
     if (message.code.severity == Severity.context) {
       internalProblem(
           templateInternalProblemContextSeverity
@@ -275,7 +281,12 @@
       (wasHandled ? handledErrors : unhandledErrors)
           .add(message.withLocation(fileUri, charOffset, length));
     }
-    return true;
+    FormattedMessage formattedMessage = target.createFormattedMessage(
+        message, charOffset, length, fileUri, context, severity);
+    if (!problemOnLibrary) {
+      allComponentProblems.add(formattedMessage);
+    }
+    return formattedMessage;
   }
 
   Declaration getAbstractClassInstantiationError() {
@@ -293,4 +304,9 @@
   void recordMessage(Severity severity, Message message, int charOffset,
       int length, Uri fileUri,
       {List<LocatedMessage> context}) {}
+
+  ClassBuilder<TypeBuilder, Object> computeClassBuilderFromTargetClass(
+      covariant Object cls);
+
+  TypeBuilder computeTypeBuilder(covariant Object type);
 }
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 51e3b9e..585a7b2 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -147,6 +147,11 @@
   }
 
   @override
+  void beginForControlFlow(Token awaitToken, Token forToken) {
+    listener?.beginForControlFlow(awaitToken, forToken);
+  }
+
+  @override
   void beginForInBody(Token token) {
     listener?.beginForInBody(token);
   }
@@ -214,6 +219,11 @@
   }
 
   @override
+  void beginIfControlFlow(Token ifToken) {
+    listener?.beginIfControlFlow(ifToken);
+  }
+
+  @override
   void beginIfStatement(Token token) {
     listener?.beginIfStatement(token);
   }
@@ -559,9 +569,18 @@
   }
 
   @override
-  void endForIn(Token awaitToken, Token forToken, Token leftParen,
-      Token inKeyword, Token endToken) {
-    listener?.endForIn(awaitToken, forToken, leftParen, inKeyword, endToken);
+  void endForControlFlow(Token token) {
+    listener?.endForControlFlow(token);
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    listener?.endForInControlFlow(token);
+  }
+
+  @override
+  void endForIn(Token endToken) {
+    listener?.endForIn(endToken);
   }
 
   @override
@@ -575,10 +594,8 @@
   }
 
   @override
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
-    listener?.endForStatement(
-        forKeyword, leftParen, leftSeparator, updateExpressionCount, endToken);
+  void endForStatement(Token endToken) {
+    listener?.endForStatement(endToken);
   }
 
   @override
@@ -636,6 +653,16 @@
   }
 
   @override
+  void endIfControlFlow(Token token) {
+    listener?.endIfControlFlow(token);
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    listener?.endIfElseControlFlow(token);
+  }
+
+  @override
   void endIfStatement(Token ifToken, Token elseToken) {
     listener?.endIfStatement(ifToken, elseToken);
   }
@@ -971,6 +998,11 @@
   }
 
   @override
+  void handleElseControlFlow(Token elseToken) {
+    listener?.handleElseControlFlow(elseToken);
+  }
+
+  @override
   void handleEmptyStatement(Token token) {
     listener?.handleEmptyStatement(token);
   }
@@ -981,9 +1013,9 @@
   }
 
   @override
-  void handleEmptyLiteralSetOrMap(
-      Token leftBrace, Token constKeyword, Token rightBrace) {
-    listener?.handleEmptyLiteralSetOrMap(leftBrace, constKeyword, rightBrace);
+  void handleLiteralSetOrMap(
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    listener?.handleLiteralSetOrMap(count, leftBrace, constKeyword, rightBrace);
   }
 
   @override
@@ -1200,6 +1232,20 @@
   }
 
   @override
+  void handleForInLoopParts(Token awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {
+    listener?.handleForInLoopParts(
+        awaitToken, forToken, leftParenthesis, inKeyword);
+  }
+
+  @override
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
+    listener?.handleForLoopParts(
+        forKeyword, leftParen, leftSeparator, updateExpressionCount);
+  }
+
+  @override
   void handleNoFieldInitializer(Token token) {
     listener?.handleNoFieldInitializer(token);
   }
@@ -1308,6 +1354,11 @@
   }
 
   @override
+  void handleSpreadExpression(Token spreadToken) {
+    listener?.handleSpreadExpression(spreadToken);
+  }
+
+  @override
   void handleStringJuxtaposition(int literalCount) {
     listener?.handleStringJuxtaposition(literalCount);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index d681804..86036d3 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -323,8 +323,13 @@
   /// [endForStatement] or [endForIn].
   void beginForStatement(Token token) {}
 
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
+  /// Marks the end of parsing the control structure of a for statement
+  /// or for control flow entry up to and including the closing parenthesis.
+  /// `for` `(` initialization `;` condition `;` updaters `)`
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {}
+
+  void endForStatement(Token endToken) {
     logEvent("ForStatement");
   }
 
@@ -334,9 +339,14 @@
     logEvent("ForStatementBody");
   }
 
+  /// Marks the end of parsing the control structure of a for-in statement
+  /// or for control flow entry up to and including the closing parenthesis.
+  /// `for` `(` (type)? identifier `in` iterator `)`
+  void handleForInLoopParts(Token awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {}
+
   // One of the two possible corresponding end events for [beginForStatement].
-  void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
-      Token inKeyword, Token endToken) {
+  void endForIn(Token endToken) {
     logEvent("ForIn");
   }
 
@@ -1074,6 +1084,50 @@
     logEvent("ConstExpression");
   }
 
+  /// Called before parsing a "for" control flow list, set, or map entry.
+  void beginForControlFlow(Token awaitToken, Token forToken) {}
+
+  /// Called after parsing a "for" control flow list, set, or map entry.
+  void endForControlFlow(Token token) {
+    logEvent('endForControlFlow');
+  }
+
+  /// Called after parsing a "for-in" control flow list, set, or map entry.
+  void endForInControlFlow(Token token) {
+    logEvent('endForInControlFlow');
+  }
+
+  /// Called before parsing an `if` control flow list, set, or map entry.
+  void beginIfControlFlow(Token ifToken) {}
+
+  /// Called before parsing the `else` portion of an `if` control flow list,
+  /// set, or map entry.
+  void handleElseControlFlow(Token elseToken) {}
+
+  /// Called after parsing an `if` control flow list, set, or map entry.
+  /// Substructures:
+  /// - if conditional expression
+  /// - expression
+  void endIfControlFlow(Token token) {
+    logEvent("endIfControlFlow");
+  }
+
+  /// Called after parsing an if-else control flow list, set, or map entry.
+  /// Substructures:
+  /// - if conditional expression
+  /// - then expression
+  /// - else expression
+  void endIfElseControlFlow(Token token) {
+    logEvent("endIfElseControlFlow");
+  }
+
+  /// Called after parsing a list, set, or map entry that starts with
+  /// one of the spread collection tokens `...` or `...?`.  Substructures:
+  /// - expression
+  void handleSpreadExpression(Token spreadToken) {
+    logEvent("SpreadExpression");
+  }
+
   /// Handle the start of a function typed formal parameter.  Substructures:
   /// - type variables
   void beginFunctionTypedFormalParameter(Token token) {}
@@ -1156,9 +1210,9 @@
     logEvent("LiteralSet");
   }
 
-  void handleEmptyLiteralSetOrMap(
-      Token leftBrace, Token constKeyword, Token rightBrace) {
-    logEvent('EmptyLiteralSetOrMap');
+  void handleLiteralSetOrMap(
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    logEvent('LiteralSetOrMap');
   }
 
   void handleLiteralNull(Token token) {
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart
new file mode 100644
index 0000000..00bf0a1
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../scanner.dart';
+import 'identifier_context.dart';
+import 'literal_entry_info_impl.dart';
+import 'parser.dart';
+import 'util.dart';
+
+/// [LiteralEntryInfo] represents steps for processing an entry
+/// in a literal list, map, or set. These steps will handle parsing
+/// both control flow and spreadable operators, and indicate
+/// when the client should parse the literal entry.
+///
+/// Clients should parse a single entry in a list, set, or map like this:
+/// ```
+///    LiteralEntryInfo info = computeLiteralEntry(token);
+///    while (info != null) {
+///      if (info.hasEntry) {
+///        ... parse expression (`:` expression)? ...
+///        token = lastConsumedToken;
+///      } else {
+///        token = info.parse(token, parser);
+///      }
+///      info = info.computeNext(token);
+///    }
+/// ```
+class LiteralEntryInfo {
+  /// `true` if an entry should be parsed by the caller
+  /// or `false` if this object's [parse] method should be called.
+  final bool hasEntry;
+
+  const LiteralEntryInfo(this.hasEntry);
+
+  /// Parse the control flow and spread collection aspects of this entry.
+  Token parse(Token token, Parser parser) {
+    throw hasEntry
+        ? 'Internal Error: should not call parse'
+        : 'Internal Error: $runtimeType should implement parse';
+  }
+
+  /// Returns the next step when parsing an entry or `null` if none.
+  LiteralEntryInfo computeNext(Token token) => null;
+}
+
+/// Compute the [LiteralEntryInfo] for the literal list, map, or set entry.
+LiteralEntryInfo computeLiteralEntry(Token token) {
+  Token next = token.next;
+  if (optional('if', next)) {
+    return ifCondition;
+  } else if (optional('for', next) ||
+      (optional('await', next) && optional('for', next.next))) {
+    return new ForCondition();
+  } else if (optional('...', next) || optional('...?', next)) {
+    return spreadOperator;
+  }
+  return simpleEntry;
+}
+
+/// Return `true` if the given [token] should be treated like the start of
+/// a literal entry in a list, set, or map for the purposes of recovery.
+bool looksLikeLiteralEntry(Token token) =>
+    looksLikeExpressionStart(token) ||
+    optional('...', token) ||
+    optional('...?', token) ||
+    optional('if', token) ||
+    optional('for', token) ||
+    (optional('await', token) && optional('for', token.next));
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
new file mode 100644
index 0000000..87bd6ad
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
@@ -0,0 +1,291 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../../scanner/token.dart';
+import 'literal_entry_info.dart';
+import 'parser.dart';
+import 'util.dart';
+
+/// [ifCondition] is the first step for parsing a literal entry
+/// starting with `if` control flow.
+const LiteralEntryInfo ifCondition = const IfCondition();
+
+/// [simpleEntry] is the first step for parsing a literal entry
+/// without any control flow or spread collection operator.
+const LiteralEntryInfo simpleEntry = const LiteralEntryInfo(true);
+
+/// [spreadOperator] is the first step for parsing a literal entry
+/// preceded by a '...' spread operator.
+const LiteralEntryInfo spreadOperator = const SpreadOperator();
+
+/// The first step when processing a `for` control flow collection entry.
+class ForCondition extends LiteralEntryInfo {
+  bool inStyle;
+
+  ForCondition() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    Token next = token.next;
+    Token awaitToken;
+    if (optional('await', next)) {
+      awaitToken = token = next;
+      next = token.next;
+    }
+    final forToken = next;
+    assert(optional('for', forToken));
+    parser.listener.beginForControlFlow(awaitToken, forToken);
+
+    token = parser.parseForLoopPartsStart(awaitToken, forToken);
+    Token identifier = token.next;
+    token = parser.parseForLoopPartsMid(token, awaitToken, forToken);
+
+    if (optional('in', token.next) || optional(':', token.next)) {
+      // Process `for ( ... in ... )`
+      inStyle = true;
+      token = parser.parseForInLoopPartsRest(
+          token, awaitToken, forToken, identifier);
+    } else {
+      // Process `for ( ... ; ... ; ... )`
+      inStyle = false;
+      token = parser.parseForLoopPartsRest(token, forToken, awaitToken);
+    }
+    return token;
+  }
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    Token next = token.next;
+    if (optional('for', next) ||
+        (optional('await', next) && optional('for', next.next))) {
+      return new Nested(
+        new ForCondition(),
+        inStyle ? const ForInComplete() : const ForComplete(),
+      );
+    } else if (optional('if', next)) {
+      return new Nested(
+        ifCondition,
+        inStyle ? const ForInComplete() : const ForComplete(),
+      );
+    } else if (optional('...', next) || optional('...?', next)) {
+      return inStyle ? const ForInSpread() : const ForSpread();
+    }
+    return inStyle ? const ForInEntry() : const ForEntry();
+  }
+}
+
+/// A step for parsing a spread collection
+/// as the "for" control flow's expression.
+class ForSpread extends SpreadOperator {
+  const ForSpread();
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return const ForComplete();
+  }
+}
+
+/// A step for parsing a spread collection
+/// as the "for-in" control flow's expression.
+class ForInSpread extends SpreadOperator {
+  const ForInSpread();
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return const ForInComplete();
+  }
+}
+
+/// A step for parsing a literal list, set, or map entry
+/// as the "for" control flow's expression.
+class ForEntry extends LiteralEntryInfo {
+  const ForEntry() : super(true);
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return const ForComplete();
+  }
+}
+
+/// A step for parsing a literal list, set, or map entry
+/// as the "for-in" control flow's expression.
+class ForInEntry extends LiteralEntryInfo {
+  const ForInEntry() : super(true);
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return const ForInComplete();
+  }
+}
+
+class ForComplete extends LiteralEntryInfo {
+  const ForComplete() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    parser.listener.endForControlFlow(token);
+    return token;
+  }
+}
+
+class ForInComplete extends LiteralEntryInfo {
+  const ForInComplete() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    parser.listener.endForInControlFlow(token);
+    return token;
+  }
+}
+
+/// The first step when processing an `if` control flow collection entry.
+class IfCondition extends LiteralEntryInfo {
+  const IfCondition() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    final ifToken = token.next;
+    assert(optional('if', ifToken));
+    parser.listener.beginIfControlFlow(ifToken);
+    return parser.ensureParenthesizedCondition(ifToken);
+  }
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    Token next = token.next;
+    if (optional('for', next) ||
+        (optional('await', next) && optional('for', next.next))) {
+      return new Nested(new ForCondition(), const IfComplete());
+    } else if (optional('if', next)) {
+      return new Nested(ifCondition, const IfComplete());
+    } else if (optional('...', next) || optional('...?', next)) {
+      return const IfSpread();
+    }
+    return const IfEntry();
+  }
+}
+
+/// A step for parsing a spread collection
+/// as the `if` control flow's then-expression.
+class IfSpread extends SpreadOperator {
+  const IfSpread();
+
+  @override
+  LiteralEntryInfo computeNext(Token token) => const IfComplete();
+}
+
+/// A step for parsing a literal list, set, or map entry
+/// as the `if` control flow's then-expression.
+class IfEntry extends LiteralEntryInfo {
+  const IfEntry() : super(true);
+
+  @override
+  LiteralEntryInfo computeNext(Token token) => const IfComplete();
+}
+
+class IfComplete extends LiteralEntryInfo {
+  const IfComplete() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    if (!optional('else', token.next)) {
+      parser.listener.endIfControlFlow(token);
+    }
+    return token;
+  }
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return optional('else', token.next) ? const IfElse() : null;
+  }
+}
+
+/// A step for parsing the `else` portion of an `if` control flow.
+class IfElse extends LiteralEntryInfo {
+  const IfElse() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    Token elseToken = token.next;
+    assert(optional('else', elseToken));
+    parser.listener.handleElseControlFlow(elseToken);
+    return elseToken;
+  }
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    assert(optional('else', token));
+    Token next = token.next;
+    if (optional('for', next) ||
+        (optional('await', next) && optional('for', next.next))) {
+      return new Nested(new ForCondition(), const IfElseComplete());
+    } else if (optional('if', next)) {
+      return new Nested(ifCondition, const IfElseComplete());
+    } else if (optional('...', next) || optional('...?', next)) {
+      return const ElseSpread();
+    }
+    return const ElseEntry();
+  }
+}
+
+class ElseSpread extends SpreadOperator {
+  const ElseSpread();
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return const IfElseComplete();
+  }
+}
+
+class ElseEntry extends LiteralEntryInfo {
+  const ElseEntry() : super(true);
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    return const IfElseComplete();
+  }
+}
+
+class IfElseComplete extends LiteralEntryInfo {
+  const IfElseComplete() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    parser.listener.endIfElseControlFlow(token);
+    return token;
+  }
+}
+
+/// The first step when processing a spread entry.
+class SpreadOperator extends LiteralEntryInfo {
+  const SpreadOperator() : super(false);
+
+  @override
+  Token parse(Token token, Parser parser) {
+    final operator = token.next;
+    assert(optional('...', operator) || optional('...?', operator));
+    token = parser.parseExpression(operator);
+    parser.listener.handleSpreadExpression(operator);
+    return token;
+  }
+}
+
+class Nested extends LiteralEntryInfo {
+  LiteralEntryInfo nestedStep;
+  final LiteralEntryInfo lastStep;
+
+  Nested(this.nestedStep, this.lastStep) : super(false);
+
+  @override
+  bool get hasEntry => nestedStep.hasEntry;
+
+  @override
+  Token parse(Token token, Parser parser) => nestedStep.parse(token, parser);
+
+  @override
+  LiteralEntryInfo computeNext(Token token) {
+    nestedStep = nestedStep.computeNext(token);
+    return nestedStep != null ? this : lastStep;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index a3a59c2..0baa173 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -68,6 +68,9 @@
 
 import 'listener.dart' show Listener;
 
+import 'literal_entry_info.dart'
+    show computeLiteralEntry, LiteralEntryInfo, looksLikeLiteralEntry;
+
 import 'loop_state.dart' show LoopState;
 
 import 'member_kind.dart' show MemberKind;
@@ -4186,7 +4189,7 @@
         token = next;
         break;
       }
-      token = parseExpression(token);
+      token = parseListOrSetLiteralEntry(token);
       next = token.next;
       ++count;
       if (!optional(',', next)) {
@@ -4196,7 +4199,7 @@
         }
 
         // Recovery
-        if (!looksLikeExpressionStart(next)) {
+        if (!looksLikeLiteralEntry(next)) {
           if (beginToken.endGroup.isSynthetic) {
             // The scanner has already reported an error,
             // but inserted `]` in the wrong place.
@@ -4223,45 +4226,99 @@
     return token;
   }
 
+  Token parseListOrSetLiteralEntry(Token token) {
+    LiteralEntryInfo info = computeLiteralEntry(token);
+    while (info != null) {
+      if (info.hasEntry) {
+        token = parseExpression(token);
+      } else {
+        token = info.parse(token, this);
+      }
+      info = info.computeNext(token);
+    }
+    return token;
+  }
+
   /// This method parses the portion of a set or map literal that starts with
   /// the left curly brace when there are no leading type arguments.
-  Token parseLiteralSetOrMapSuffix(final Token start, Token constKeyword) {
+  Token parseLiteralSetOrMapSuffix(Token token, Token constKeyword) {
     if (!enableSetLiterals) {
       // TODO(danrubel): remove this once set literals are permanent
-      return parseLiteralMapSuffix(start, constKeyword);
+      return parseLiteralMapSuffix(token, constKeyword);
     }
 
-    Token leftBrace = start.next;
+    Token leftBrace = token = token.next;
     assert(optional('{', leftBrace));
-    if (optional('}', leftBrace.next)) {
-      Token rightBrace = leftBrace.next;
-      listener.handleEmptyLiteralSetOrMap(leftBrace, constKeyword, rightBrace);
-      return rightBrace;
-    }
-
-    bool old = mayParseFunctionExpressions;
-    mayParseFunctionExpressions = true;
-    Token token = parseExpression(leftBrace);
-    mayParseFunctionExpressions = old;
-
     Token next = token.next;
     if (optional('}', next)) {
-      listener.handleLiteralSet(1, leftBrace, constKeyword, next);
+      listener.handleLiteralSetOrMap(0, leftBrace, constKeyword, next);
       return next;
-    } else if (optional(',', next)) {
-      return parseLiteralSetRest(token, constKeyword, leftBrace);
-    } else {
-      // TODO(danrubel): Consider better recovery
-      // rather than just assuming this is a literal map.
-      Token colon = ensureColon(token);
+    }
 
-      final old = mayParseFunctionExpressions;
-      mayParseFunctionExpressions = true;
-      token = parseExpression(colon);
-      mayParseFunctionExpressions = old;
+    final old = mayParseFunctionExpressions;
+    mayParseFunctionExpressions = true;
+    int count = 0;
+    bool isMap;
 
-      listener.handleLiteralMapEntry(colon, token.next);
-      return parseLiteralMapRest(token, constKeyword, leftBrace);
+    // Parse entries until we determine it's a map, or set, or no more entries
+    while (true) {
+      LiteralEntryInfo info = computeLiteralEntry(token);
+      while (info != null) {
+        if (info.hasEntry) {
+          token = parseExpression(token);
+          if (isMap == null) {
+            isMap = optional(':', token.next);
+          }
+          if (isMap) {
+            Token colon = ensureColon(token);
+            token = parseExpression(colon);
+            listener.handleLiteralMapEntry(colon, token.next);
+          }
+        } else {
+          token = info.parse(token, this);
+        }
+        info = info.computeNext(token);
+      }
+      ++count;
+      next = token.next;
+
+      if (isMap != null) {
+        mayParseFunctionExpressions = old;
+        return isMap
+            ? parseLiteralMapRest(token, count, constKeyword, leftBrace)
+            : parseLiteralSetRest(token, count, constKeyword, leftBrace);
+      }
+
+      Token comma;
+      if (optional(',', next)) {
+        comma = token = next;
+        next = token.next;
+      }
+      if (optional('}', next)) {
+        listener.handleLiteralSetOrMap(count, leftBrace, constKeyword, next);
+        mayParseFunctionExpressions = old;
+        return next;
+      }
+
+      if (comma == null) {
+        // Recovery
+        if (looksLikeLiteralEntry(next)) {
+          // If this looks like the start of an expression,
+          // then report an error, insert the comma, and continue parsing.
+          token = rewriteAndRecover(
+              token,
+              fasta.templateExpectedButGot.withArguments(','),
+              new SyntheticToken(TokenType.COMMA, next.offset));
+        } else {
+          reportRecoverableError(
+              next, fasta.templateExpectedButGot.withArguments('}'));
+          // Scanner guarantees a closing curly bracket
+          next = leftBrace.endGroup;
+          listener.handleLiteralSetOrMap(count, leftBrace, constKeyword, next);
+          mayParseFunctionExpressions = old;
+          return next;
+        }
+      }
     }
   }
 
@@ -4291,12 +4348,12 @@
     token = parseMapLiteralEntry(token);
     mayParseFunctionExpressions = old;
 
-    return parseLiteralMapRest(token, constKeyword, beginToken);
+    return parseLiteralMapRest(token, 1, constKeyword, beginToken);
   }
 
   /// Parse a literal map after the first entry.
-  Token parseLiteralMapRest(Token token, Token constKeyword, Token beginToken) {
-    int count = 1;
+  Token parseLiteralMapRest(
+      Token token, int count, Token constKeyword, Token beginToken) {
     bool old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
     while (true) {
@@ -4312,7 +4369,7 @@
       }
       if (comma == null) {
         // Recovery
-        if (looksLikeExpressionStart(next)) {
+        if (looksLikeLiteralEntry(next)) {
           // If this looks like the start of an expression,
           // then report an error, insert the comma, and continue parsing.
           token = rewriteAndRecover(
@@ -4364,15 +4421,15 @@
 
     bool old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
-    token = parseExpression(token);
+    token = parseListOrSetLiteralEntry(token);
     mayParseFunctionExpressions = old;
 
-    return parseLiteralSetRest(token, constKeyword, beginToken);
+    return parseLiteralSetRest(token, 1, constKeyword, beginToken);
   }
 
   /// Parse a literal set after the first expression.
-  Token parseLiteralSetRest(Token token, Token constKeyword, Token beginToken) {
-    int count = 1;
+  Token parseLiteralSetRest(
+      Token token, int count, Token constKeyword, Token beginToken) {
     bool old = mayParseFunctionExpressions;
     mayParseFunctionExpressions = true;
     while (true) {
@@ -4388,7 +4445,7 @@
       }
       if (comma == null) {
         // Recovery
-        if (looksLikeExpressionStart(next)) {
+        if (looksLikeLiteralEntry(next)) {
           // If this looks like the start of an expression,
           // then report an error, insert the comma, and continue parsing.
           token = rewriteAndRecover(
@@ -4403,7 +4460,7 @@
           break;
         }
       }
-      token = parseExpression(token);
+      token = parseListOrSetLiteralEntry(token);
       ++count;
     }
     assert(optional('}', token));
@@ -4477,17 +4534,29 @@
 
   /// ```
   /// mapLiteralEntry:
-  ///   expression ':' expression
+  ///   expression ':' expression |
+  ///   'if' '(' expression ')' mapLiteralEntry ( 'else' mapLiteralEntry )? |
+  ///   'await'? 'for' '(' forLoopParts ')' mapLiteralEntry |
+  ///   ( '...' | '...?' ) expression
   /// ;
   /// ```
   Token parseMapLiteralEntry(Token token) {
     // Assume the listener rejects non-string keys.
     // TODO(brianwilkerson): Change the assumption above by moving error
     // checking into the parser, making it possible to recover.
-    token = parseExpression(token);
-    Token colon = ensureColon(token);
-    token = parseExpression(colon);
-    listener.handleLiteralMapEntry(colon, token.next);
+    LiteralEntryInfo info = computeLiteralEntry(token);
+    while (info != null) {
+      if (info.hasEntry) {
+        token = parseExpression(token);
+        Token colon = ensureColon(token);
+        token = parseExpression(colon);
+        // TODO remove unused 2nd parameter
+        listener.handleLiteralMapEntry(colon, token.next);
+      } else {
+        token = info.parse(token, this);
+      }
+      info = info.computeNext(token);
+    }
     return token;
   }
 
@@ -5227,10 +5296,11 @@
   ///   'await'? 'for' '(' forLoopParts ')' statement
   /// ;
   ///
-  /// forLoopParts:
-  ///   forInitializerStatement expression? ';' expressionList? |
-  ///   declaredIdentifier 'in' expression |
-  ///   identifier 'in' expression
+  ///  forLoopParts:
+  ///      localVariableDeclaration ';' expression? ';' expressionList?
+  ///    | expression? ';' expression? ';' expressionList?
+  ///    | localVariableDeclaration 'in' expression
+  ///    | identifier 'in' expression
   /// ;
   ///
   /// forInitializerStatement:
@@ -5239,20 +5309,35 @@
   /// ;
   /// ```
   Token parseForStatement(Token token, Token awaitToken) {
-    Token forKeyword = token = token.next;
+    Token forToken = token = token.next;
     assert(awaitToken == null || optional('await', awaitToken));
     assert(optional('for', token));
-    listener.beginForStatement(forKeyword);
+    listener.beginForStatement(forToken);
 
-    Token leftParenthesis = forKeyword.next;
+    token = parseForLoopPartsStart(awaitToken, forToken);
+    Token identifier = token.next;
+    token = parseForLoopPartsMid(token, awaitToken, forToken);
+    if (optional('in', token.next) || optional(':', token.next)) {
+      // Process `for ( ... in ... )`
+      return parseForInRest(token, awaitToken, forToken, identifier);
+    } else {
+      // Process `for ( ... ; ... ; ... )`
+      return parseForRest(awaitToken, token, forToken);
+    }
+  }
+
+  /// Parse the start of a for loop control structure
+  /// from the open parenthesis up to but not including the identifier.
+  Token parseForLoopPartsStart(Token awaitToken, Token forToken) {
+    Token leftParenthesis = forToken.next;
     if (!optional('(', leftParenthesis)) {
       // Recovery
       reportRecoverableError(
           leftParenthesis, fasta.templateExpectedButGot.withArguments('('));
       int offset = leftParenthesis.offset;
 
-      BeginToken openParen =
-          token.setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
+      BeginToken openParen = forToken
+          .setNext(new SyntheticBeginToken(TokenType.OPEN_PAREN, offset));
 
       Token loopPart;
       if (awaitToken != null) {
@@ -5280,18 +5365,18 @@
 
       leftParenthesis = openParen;
     }
-    token = leftParenthesis;
 
     // Pass `true` so that the [parseExpressionStatementOrDeclaration] only
     // parses the metadata, modifiers, and type of a local variable
     // declaration if it exists. This enables capturing [beforeIdentifier]
     // for later error reporting.
-    token = parseExpressionStatementOrDeclaration(token, true);
-    Token beforeIdentifier = token;
+    return parseExpressionStatementOrDeclaration(forToken.next, true);
+  }
 
-    // Parse the remainder of the local variable declaration
-    // or an expression if no local variable declaration was found.
-    if (token != leftParenthesis) {
+  /// Parse the remainder of the local variable declaration
+  /// or an expression if no local variable declaration was found.
+  Token parseForLoopPartsMid(Token token, Token awaitToken, Token forToken) {
+    if (token != forToken.next) {
       token = parseVariablesDeclarationRest(token, false);
       listener.handleForInitializerLocalVariableDeclaration(token);
     } else if (optional(';', token.next)) {
@@ -5300,58 +5385,53 @@
       token = parseExpression(token);
       listener.handleForInitializerExpressionStatement(token);
     }
-
     Token next = token.next;
-    if (!optional('in', next)) {
+    if (optional(';', next)) {
+      if (awaitToken != null) {
+        reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
+      }
+    } else if (!optional('in', next)) {
+      // Recovery
       if (optional(':', next)) {
-        // Recovery
         reportRecoverableError(next, fasta.messageColonInPlaceOfIn);
-        // Fall through to process `for ( ... in ... )`
-      } else if (awaitToken == null || optional(';', next)) {
-        // Process `for ( ... ; ... ; ... )`
-        if (awaitToken != null) {
-          reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
-        }
-        return parseForRest(token, forKeyword, leftParenthesis);
-      } else {
-        // Recovery
+      } else if (awaitToken != null) {
         reportRecoverableError(
             next, fasta.templateExpectedButGot.withArguments('in'));
-        next = token.setNext(
+        token.setNext(
             new SyntheticKeywordToken(Keyword.IN, next.offset)..setNext(next));
       }
     }
-
-    // Process `for ( ... in ... )`
-    Token identifier = beforeIdentifier.next;
-    if (!identifier.isIdentifier) {
-      reportRecoverableErrorWithToken(
-          identifier, fasta.templateExpectedIdentifier);
-    } else if (identifier != token) {
-      if (optional('=', identifier.next)) {
-        reportRecoverableError(
-            identifier.next, fasta.messageInitializedVariableInForEach);
-      } else {
-        reportRecoverableErrorWithToken(
-            identifier.next, fasta.templateUnexpectedToken);
-      }
-    } else if (awaitToken != null && !inAsync) {
-      reportRecoverableError(next, fasta.messageAwaitForNotAsync);
-    }
-    return parseForInRest(token, awaitToken, forKeyword, leftParenthesis);
+    return token;
   }
 
   /// This method parses the portion of the forLoopParts that starts with the
   /// first semicolon (the one that terminates the forInitializerStatement).
   ///
   /// ```
-  /// forLoopParts:
-  ///   forInitializerStatement expression? ';' expressionList? |
-  ///   declaredIdentifier 'in' expression |
-  ///   identifier 'in' expression
+  ///  forLoopParts:
+  ///      localVariableDeclaration ';' expression? ';' expressionList?
+  ///    | expression? ';' expression? ';' expressionList?
+  ///    | localVariableDeclaration 'in' expression
+  ///    | identifier 'in' expression
   /// ;
   /// ```
-  Token parseForRest(Token token, Token forToken, Token leftParenthesis) {
+  Token parseForRest(Token awaitToken, Token token, Token forToken) {
+    token = parseForLoopPartsRest(token, forToken, awaitToken);
+    listener.beginForStatementBody(token.next);
+    LoopState savedLoopState = loopState;
+    loopState = LoopState.InsideLoop;
+    token = parseStatement(token);
+    loopState = savedLoopState;
+    listener.endForStatementBody(token.next);
+    listener.endForStatement(token.next);
+    return token;
+  }
+
+  Token parseForLoopPartsRest(Token token, Token forToken, Token awaitToken) {
+    Token leftParenthesis = forToken.next;
+    assert(optional('for', forToken));
+    assert(optional('(', leftParenthesis));
+
     Token leftSeparator = ensureSemicolon(token);
     if (optional(';', leftSeparator.next)) {
       token = parseEmptyStatement(leftSeparator);
@@ -5375,14 +5455,8 @@
       reportRecoverableErrorWithToken(token, fasta.templateUnexpectedToken);
       token = leftParenthesis.endGroup;
     }
-    listener.beginForStatementBody(token.next);
-    LoopState savedLoopState = loopState;
-    loopState = LoopState.InsideLoop;
-    token = parseStatement(token);
-    loopState = savedLoopState;
-    listener.endForStatementBody(token.next);
-    listener.endForStatement(
-        forToken, leftParenthesis, leftSeparator, expressionCount, token.next);
+    listener.handleForLoopParts(
+        forToken, leftParenthesis, leftSeparator, expressionCount);
     return token;
   }
 
@@ -5391,28 +5465,55 @@
   /// keyword.
   ///
   /// ```
-  /// forLoopParts:
-  ///   forInitializerStatement expression? ';' expressionList? |
-  ///   declaredIdentifier 'in' expression |
-  ///   identifier 'in' expression
+  ///  forLoopParts:
+  ///      localVariableDeclaration ';' expression? ';' expressionList?
+  ///    | expression? ';' expression? ';' expressionList?
+  ///    | localVariableDeclaration 'in' expression
+  ///    | identifier 'in' expression
   /// ;
   /// ```
   Token parseForInRest(
-      Token token, Token awaitToken, Token forKeyword, Token leftParenthesis) {
-    Token inKeyword = token.next;
-    assert(optional('in', inKeyword) || optional(':', inKeyword));
-    listener.beginForInExpression(inKeyword.next);
-    token = parseExpression(inKeyword);
-    token = ensureCloseParen(token, leftParenthesis);
-    listener.endForInExpression(token);
+      Token token, Token awaitToken, Token forToken, Token identifier) {
+    token = parseForInLoopPartsRest(token, awaitToken, forToken, identifier);
     listener.beginForInBody(token.next);
     LoopState savedLoopState = loopState;
     loopState = LoopState.InsideLoop;
     token = parseStatement(token);
     loopState = savedLoopState;
     listener.endForInBody(token.next);
-    listener.endForIn(
-        awaitToken, forKeyword, leftParenthesis, inKeyword, token.next);
+    listener.endForIn(token.next);
+    return token;
+  }
+
+  Token parseForInLoopPartsRest(
+      Token token, Token awaitToken, Token forToken, Token identifier) {
+    Token inKeyword = token.next;
+    assert(optional('for', forToken));
+    assert(optional('(', forToken.next));
+    assert(optional('in', inKeyword) || optional(':', inKeyword));
+
+    if (!identifier.isIdentifier) {
+      reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+    } else if (identifier != token) {
+      if (optional('=', identifier.next)) {
+        reportRecoverableError(
+            identifier.next, fasta.messageInitializedVariableInForEach);
+      } else {
+        reportRecoverableErrorWithToken(
+            identifier.next, fasta.templateUnexpectedToken);
+      }
+    } else if (awaitToken != null && !inAsync) {
+      // TODO(danrubel): consider reporting the error on awaitToken
+      reportRecoverableError(inKeyword, fasta.messageAwaitForNotAsync);
+    }
+
+    listener.beginForInExpression(inKeyword.next);
+    token = parseExpression(inKeyword);
+    token = ensureCloseParen(token, forToken.next);
+    listener.endForInExpression(token);
+    listener.handleForInLoopParts(
+        awaitToken, forToken, forToken.next, inKeyword);
     return token;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/problems.dart b/pkg/front_end/lib/src/fasta/problems.dart
index bf17812..09ec70c 100644
--- a/pkg/front_end/lib/src/fasta/problems.dart
+++ b/pkg/front_end/lib/src/fasta/problems.dart
@@ -4,6 +4,8 @@
 
 library fasta.problems;
 
+import 'package:kernel/ast.dart' show FileUriNode, TreeNode;
+
 import 'compiler_context.dart' show CompilerContext;
 
 import 'messages.dart'
@@ -72,3 +74,11 @@
       charOffset,
       uri);
 }
+
+Uri getFileUri(TreeNode node) {
+  do {
+    if (node is FileUriNode) return node.fileUri;
+    node = node.parent;
+  } while (node is TreeNode);
+  return null;
+}
diff --git a/pkg/front_end/lib/src/fasta/rewrite_severity.dart b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
index f2dc2fe..5d521bb 100644
--- a/pkg/front_end/lib/src/fasta/rewrite_severity.dart
+++ b/pkg/front_end/lib/src/fasta/rewrite_severity.dart
@@ -60,17 +60,14 @@
       case "builder/dynamic_type_builder.dart":
       case "builder/field_builder.dart":
       case "builder/formal_parameter_builder.dart":
-      case "builder/function_type_alias_builder.dart":
       case "builder/function_type_builder.dart":
       case "builder/library_builder.dart":
       case "builder/member_builder.dart":
-      case "builder/metadata_builder.dart":
       case "builder/mixin_application_builder.dart":
       case "builder/named_type_builder.dart":
       case "builder/prefix_builder.dart":
       case "builder/procedure_builder.dart":
       case "builder/type_builder.dart":
-      case "builder/type_declaration_builder.dart":
       case "builder/type_variable_builder.dart":
       case "builder/unresolved_type.dart":
       case "builder/void_type_builder.dart":
@@ -80,7 +77,6 @@
       case "dill/dill_library_builder.dart":
       case "dill/dill_loader.dart":
       case "dill/dill_target.dart":
-      case "dill/dill_typedef_builder.dart":
       case "entry_points.dart":
       case "export.dart":
       case "fasta_codes.dart":
@@ -96,7 +92,6 @@
       case "kernel/kernel_expression_generator_impl.dart":
       case "kernel/kernel_field_builder.dart":
       case "kernel/kernel_formal_parameter_builder.dart":
-      case "kernel/kernel_function_type_alias_builder.dart":
       case "kernel/kernel_function_type_builder.dart":
       case "kernel/kernel_invalid_type_builder.dart":
       case "kernel/kernel_library_builder.dart":
diff --git a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
index 6ac7640..3377316 100644
--- a/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart
@@ -736,8 +736,20 @@
     if (($0 <= next && next <= $9)) {
       return tokenizeFractionPart(next, start);
     } else if (identical($PERIOD, next)) {
-      return select(
-          $PERIOD, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
+      next = advance();
+      if (identical(next, $PERIOD)) {
+        next = advance();
+        if (identical(next, $QUESTION)) {
+          appendPrecedenceToken(TokenType.PERIOD_PERIOD_PERIOD_QUESTION);
+          return advance();
+        } else {
+          appendPrecedenceToken(TokenType.PERIOD_PERIOD_PERIOD);
+          return next;
+        }
+      } else {
+        appendPrecedenceToken(TokenType.PERIOD_PERIOD);
+        return next;
+      }
     } else {
       appendPrecedenceToken(TokenType.PERIOD);
       return next;
diff --git a/pkg/front_end/lib/src/fasta/scanner/token_constants.dart b/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
index 6ac1842..f29765c 100644
--- a/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/token_constants.dart
@@ -87,3 +87,4 @@
 const int GENERIC_METHOD_TYPE_ASSIGN_TOKEN = QUESTION_QUESTION_EQ_TOKEN + 1;
 const int GENERIC_METHOD_TYPE_LIST_TOKEN = GENERIC_METHOD_TYPE_ASSIGN_TOKEN + 1;
 const int GT_GT_GT_TOKEN = GENERIC_METHOD_TYPE_LIST_TOKEN + 1;
+const int PERIOD_PERIOD_PERIOD_QUESTION_TOKEN = GT_GT_GT_TOKEN + 1;
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index b7c8584..c74cc99 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -284,6 +284,36 @@
     });
     return nestingLevel;
   }
+
+  Scope computeMixinScope() {
+    List<String> names = this.local.keys.toList();
+    Map<String, Declaration> local = <String, Declaration>{};
+    bool needsCopy = false;
+    for (int i = 0; i < names.length; i++) {
+      String name = names[i];
+      Declaration declaration = this.local[name];
+      if (declaration.isStatic) {
+        needsCopy = true;
+      } else {
+        local[name] = declaration;
+      }
+    }
+    names = this.setters.keys.toList();
+    Map<String, Declaration> setters = <String, Declaration>{};
+    for (int i = 0; i < names.length; i++) {
+      String name = names[i];
+      Declaration declaration = this.setters[name];
+      if (declaration.isStatic) {
+        needsCopy = true;
+      } else {
+        setters[name] = declaration;
+      }
+    }
+    return needsCopy
+        ? new Scope(local, setters, parent, classNameOrDebugName,
+            isModifiable: isModifiable)
+        : this;
+  }
 }
 
 class ScopeBuilder {
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 276b0c3..88edaba 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -39,15 +39,17 @@
 
 import '../kernel/kernel_body_builder.dart' show KernelBodyBuilder;
 
-import '../kernel/kernel_formal_parameter_builder.dart'
-    show KernelFormalParameterBuilder;
-
-import '../kernel/kernel_function_type_alias_builder.dart'
-    show KernelFunctionTypeAliasBuilder;
+import '../kernel/kernel_builder.dart'
+    show
+        KernelFormalParameterBuilder,
+        KernelFunctionTypeBuilder,
+        KernelTypeAliasBuilder,
+        KernelTypeBuilder;
 
 import '../parser.dart' show Assert, MemberKind, Parser, optional;
 
-import '../problems.dart' show DebugAbort, internalProblem, unexpected;
+import '../problems.dart'
+    show DebugAbort, internalProblem, unexpected, unhandled;
 
 import '../type_inference/type_inference_engine.dart' show TypeInferenceEngine;
 
@@ -241,37 +243,44 @@
 
     Declaration typedefBuilder = lookupBuilder(typedefKeyword, null, name);
     parseMetadata(typedefBuilder, metadata, typedefBuilder.target);
-    if (typedefBuilder is KernelFunctionTypeAliasBuilder &&
-        typedefBuilder.type != null &&
-        typedefBuilder.type.formals != null) {
-      for (int i = 0; i < typedefBuilder.type.formals.length; ++i) {
-        KernelFormalParameterBuilder formal = typedefBuilder.type.formals[i];
-        List<MetadataBuilder> metadata = formal.metadata;
-        if (metadata != null && metadata.length > 0) {
-          // [parseMetadata] is using [Parser.parseMetadataStar] under the hood,
-          // so we only need the offset of the first annotation.
-          Token metadataToken =
-              tokenForOffset(typedefKeyword, endToken, metadata[0].charOffset);
-          List<Expression> annotations =
-              parseMetadata(typedefBuilder, metadataToken, null);
-          if (formal.isPositional) {
-            VariableDeclaration parameter =
-                typedefBuilder.target.positionalParameters[i];
-            for (Expression annotation in annotations) {
-              parameter.addAnnotation(annotation);
-            }
-          } else {
-            for (VariableDeclaration named
-                in typedefBuilder.target.namedParameters) {
-              if (named.name == formal.name) {
+    if (typedefBuilder is KernelTypeAliasBuilder) {
+      KernelTypeBuilder type = typedefBuilder.type;
+      if (type is KernelFunctionTypeBuilder) {
+        List<FormalParameterBuilder<TypeBuilder>> formals = type.formals;
+        if (formals != null) {
+          for (int i = 0; i < formals.length; ++i) {
+            KernelFormalParameterBuilder formal = formals[i];
+            List<MetadataBuilder> metadata = formal.metadata;
+            if (metadata != null && metadata.length > 0) {
+              // [parseMetadata] is using [Parser.parseMetadataStar] under the
+              // hood, so we only need the offset of the first annotation.
+              Token metadataToken = tokenForOffset(
+                  typedefKeyword, endToken, metadata[0].charOffset);
+              List<Expression> annotations =
+                  parseMetadata(typedefBuilder, metadataToken, null);
+              if (formal.isPositional) {
+                VariableDeclaration parameter =
+                    typedefBuilder.target.positionalParameters[i];
                 for (Expression annotation in annotations) {
-                  named.addAnnotation(annotation);
+                  parameter.addAnnotation(annotation);
+                }
+              } else {
+                for (VariableDeclaration named
+                    in typedefBuilder.target.namedParameters) {
+                  if (named.name == formal.name) {
+                    for (Expression annotation in annotations) {
+                      named.addAnnotation(annotation);
+                    }
+                  }
                 }
               }
             }
           }
         }
       }
+    } else if (typedefBuilder != null) {
+      unhandled("${typedefBuilder.fullNameForErrors}", "endFunctionTypeAlias",
+          typedefKeyword.charOffset, uri);
     }
 
     checkEmpty(typedefKeyword.charOffset);
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 d5c1cd8..362b102 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -4,12 +4,10 @@
 
 library fasta.outline_builder;
 
-import 'package:kernel/ast.dart' show ProcedureKind;
+import 'package:kernel/ast.dart' show DartType, Library, ProcedureKind;
 
 import '../builder/builder.dart';
 
-import '../builder/metadata_builder.dart' show ExpressionMetadataBuilder;
-
 import '../combinator.dart' show Combinator;
 
 import '../configuration.dart' show Configuration;
@@ -98,7 +96,7 @@
 }
 
 class OutlineBuilder extends StackListener {
-  final SourceLibraryBuilder library;
+  final SourceLibraryBuilder<KernelTypeBuilder, Library> library;
 
   final bool enableNative;
   final bool stringExpectedAfterNative;
@@ -108,7 +106,7 @@
 
   String nativeMethodName;
 
-  OutlineBuilder(SourceLibraryBuilder library)
+  OutlineBuilder(SourceLibraryBuilder<KernelTypeBuilder, Library> library)
       : library = library,
         enableNative =
             library.loader.target.backendTarget.enableNative(library.uri),
@@ -146,7 +144,7 @@
     if (arguments == null) {
       pop(); // charOffset
       Object expression = pop();
-      push(new MetadataBuilder.fromExpression(
+      push(new MetadataBuilder<KernelTypeBuilder>.fromExpression(
           expression, postfix, library, beginToken.charOffset));
     } else {
       int charOffset = pop();
@@ -154,7 +152,7 @@
       if (typeName is ParserRecovery) {
         push(typeName);
       } else {
-        push(new MetadataBuilder.fromConstructor(
+        push(new MetadataBuilder<KernelTypeBuilder>.fromConstructor(
             library.addConstructorReference(
                 typeName, typeArguments, postfix, charOffset),
             arguments,
@@ -167,7 +165,7 @@
   @override
   void endMetadataStar(int count) {
     debugEvent("MetadataStar");
-    push(const FixedNullableList<ExpressionMetadataBuilder<TypeBuilder>>()
+    push(const FixedNullableList<MetadataBuilder<KernelTypeBuilder>>()
             .pop(stack, count) ??
         NullValue.Metadata);
   }
@@ -214,7 +212,7 @@
     List<Configuration> configurations = pop();
     int uriOffset = popCharOffset();
     String uri = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     library.addExport(metadata, uri, configurations, combinators,
         exportKeyword.charOffset, uriOffset);
     checkEmpty(exportKeyword.charOffset);
@@ -242,7 +240,7 @@
     List<Configuration> configurations = pop();
     int uriOffset = popCharOffset();
     String uri = pop(); // For a conditional import, this is the default URI.
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(importKeyword.charOffset);
     if (prefix is ParserRecovery) return;
     library.addImport(
@@ -306,7 +304,7 @@
     debugEvent("Part");
     int charOffset = popCharOffset();
     String uri = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     library.addPart(metadata, uri, charOffset);
     checkEmpty(partKeyword.charOffset);
   }
@@ -329,7 +327,7 @@
   void handleIdentifier(Token token, IdentifierContext context) {
     if (context == IdentifierContext.enumValueDeclaration) {
       debugEvent("handleIdentifier");
-      List<MetadataBuilder> metadata = pop();
+      List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
       if (token.isSynthetic) {
         push(new ParserRecovery(token.charOffset));
       } else {
@@ -437,7 +435,7 @@
     popCharOffset();
     String documentationComment = getDocumentationComment(libraryKeyword);
     Object name = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     library.documentationComment = documentationComment;
     if (name is! ParserRecovery) {
       library.name = flattenName(name, offsetForToken(libraryKeyword), uri);
@@ -454,7 +452,8 @@
   @override
   void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
     debugEvent("beginNamedMixinApplication");
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     push(typeVariables ?? NullValue.TypeVariables);
     library.currentDeclaration
       ..name = name.lexeme
@@ -466,7 +465,8 @@
   @override
   void beginMixinDeclaration(Token mixinKeyword, Token name) {
     debugEvent("beginMixinDeclaration");
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     push(typeVariables ?? NullValue.TypeVariables);
     library.currentDeclaration
       ..name = name.lexeme
@@ -488,7 +488,8 @@
   void beginNamedMixinApplication(
       Token begin, Token abstractToken, Token name) {
     debugEvent("beginNamedMixinApplication");
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     push(typeVariables ?? NullValue.TypeVariables);
     library.currentDeclaration
       ..name = name.lexeme
@@ -543,13 +544,14 @@
     int supertypeOffset = pop();
     TypeBuilder supertype = nullIfParserRecovery(pop());
     int modifiers = pop();
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     int charOffset = pop();
     Object name = pop();
     if (typeVariables != null && supertype is MixinApplicationBuilder) {
       supertype.typeVariables = typeVariables;
     }
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(beginToken.charOffset);
     if (name is ParserRecovery) {
       library.endNestedDeclaration("<syntax-error>");
@@ -583,10 +585,11 @@
     String documentationComment = getDocumentationComment(mixinToken);
     List<TypeBuilder> interfaces = pop(NullValue.TypeBuilderList);
     List<KernelTypeBuilder> supertypeConstraints = nullIfParserRecovery(pop());
-    List<TypeVariableBuilder> typeVariables = pop(NullValue.TypeVariables);
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop(NullValue.TypeVariables);
     int nameOffset = pop();
     Object name = pop();
-    List<MetadataBuilder> metadata = pop(NullValue.Metadata);
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop(NullValue.Metadata);
     checkEmpty(mixinToken.charOffset);
     if (name is ParserRecovery) {
       library.endNestedDeclaration("<syntax-error>");
@@ -637,7 +640,8 @@
     MethodBody kind = pop();
     List<FormalParameterBuilder> formals = pop();
     int formalsOffset = pop();
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     int charOffset = pop();
     Object name = pop();
     TypeBuilder returnType = pop();
@@ -653,7 +657,7 @@
     if (isAbstract) {
       modifiers |= abstractMask;
     }
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(beginToken.charOffset);
     library
         .endNestedDeclaration("#method")
@@ -772,7 +776,8 @@
     }
     List<FormalParameterBuilder> formals = pop();
     int formalsOffset = pop();
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     int charOffset = pop();
     Object nameOrOperator = pop();
     if (Operator.subtract == nameOrOperator && formals == null) {
@@ -838,7 +843,7 @@
     }
     bool isConst = (modifiers & constMask) != 0;
     int varFinalOrConstOffset = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     String documentationComment = getDocumentationComment(beginToken);
     library
         .endNestedDeclaration("#method")
@@ -929,10 +934,11 @@
     List<TypeBuilder> interfaces = popIfNotNull(implementsKeyword);
     Object mixinApplication = pop();
     int modifiers = pop();
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     int charOffset = pop();
     Object name = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(beginToken.charOffset);
     if (name is ParserRecovery || mixinApplication is ParserRecovery) {
       library.endNestedDeclaration("<syntax-error>");
@@ -1008,7 +1014,7 @@
     Object name = pop();
     TypeBuilder type = nullIfParserRecovery(pop());
     int modifiers = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     if (name is ParserRecovery) {
       push(name);
     } else {
@@ -1159,7 +1165,7 @@
         const FixedNullableList<EnumConstantInfo>().pop(stack, count);
     int charOffset = pop();
     Object name = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(enumKeyword.charOffset);
     if (name is ParserRecovery) return;
     library.addEnum(documentationComment, metadata, name, enumConstantInfos,
@@ -1190,7 +1196,8 @@
     List<FormalParameterBuilder> formals = pop();
     pop(); // formals offset
     TypeBuilder returnType = pop();
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     push(library.addFunctionType(
         returnType, typeVariables, formals, functionToken.charOffset));
   }
@@ -1201,7 +1208,8 @@
     List<FormalParameterBuilder> formals = pop();
     int formalsOffset = pop();
     TypeBuilder returnType = pop();
-    List<TypeVariableBuilder> typeVariables = pop();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables =
+        pop();
     push(library.addFunctionType(
         returnType, typeVariables, formals, formalsOffset));
   }
@@ -1211,7 +1219,7 @@
       Token typedefKeyword, Token equals, Token endToken) {
     debugEvent("endFunctionTypeAlias");
     String documentationComment = getDocumentationComment(typedefKeyword);
-    List<TypeVariableBuilder> typeVariables;
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeVariables;
     Object name;
     int charOffset;
     FunctionTypeBuilder functionType;
@@ -1254,7 +1262,7 @@
         addProblem(messageTypedefNotFunction, equals.charOffset, equals.length);
       }
     }
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(typedefKeyword.charOffset);
     library.addFunctionTypeAlias(documentationComment, metadata, name,
         typeVariables, functionType, charOffset);
@@ -1269,7 +1277,7 @@
     int modifiers = (staticToken != null ? staticMask : 0) |
         (covariantToken != null ? covariantMask : 0) |
         Modifier.validateVarFinalOrConst(varFinalOrConst?.lexeme);
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     checkEmpty(beginToken.charOffset);
     if (fieldInfos == null) return;
     String documentationComment = getDocumentationComment(beginToken);
@@ -1293,7 +1301,7 @@
           varFinalOrConst.length);
       modifiers &= ~constMask;
     }
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     if (fieldInfos == null) return;
     String documentationComment = getDocumentationComment(beginToken);
     library.addFields(
@@ -1327,7 +1335,7 @@
     Object name = pop();
     // TODO(paulberry): type variable metadata should not be ignored.  See
     // dartbug.com/28981.
-    /* List<MetadataBuilder> metadata = */ pop();
+    /* List<MetadataBuilder<KernelTypeBuilder>> metadata = */ pop();
     if (name is ParserRecovery) {
       push(name);
     } else {
@@ -1339,7 +1347,9 @@
   void handleTypeVariablesDefined(Token token, int count) {
     debugEvent("TypeVariablesDefined");
     assert(count > 0);
-    push(const FixedNullableList<TypeVariableBuilder>().pop(stack, count) ??
+    push(const FixedNullableList<
+                TypeVariableBuilder<KernelTypeBuilder, DartType>>()
+            .pop(stack, count) ??
         NullValue.TypeVariables);
   }
 
@@ -1348,7 +1358,8 @@
     debugEvent("endTypeVariable");
     TypeBuilder bound = nullIfParserRecovery(pop());
     // Peek to leave type parameters on top of stack.
-    List<TypeVariableBuilder> typeParameters = peek();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeParameters =
+        peek();
     if (typeParameters != null) {
       typeParameters[index].bound = bound;
     }
@@ -1359,7 +1370,8 @@
     debugEvent("endTypeVariables");
 
     // Peek to leave type parameters on top of stack.
-    List<TypeVariableBuilder> typeParameters = peek();
+    List<TypeVariableBuilder<KernelTypeBuilder, DartType>> typeParameters =
+        peek();
 
     Map<String, TypeVariableBuilder> typeVariablesByName;
     if (typeParameters != null) {
@@ -1419,7 +1431,7 @@
     debugEvent("endPartOf");
     int charOffset = popCharOffset();
     Object containingLibrary = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     if (hasName) {
       library.addPartOf(metadata,
           flattenName(containingLibrary, charOffset, uri), null, charOffset);
@@ -1469,7 +1481,7 @@
     int charOffset = pop();
     Object name = pop();
     int modifiers = pop();
-    List<MetadataBuilder> metadata = pop();
+    List<MetadataBuilder<KernelTypeBuilder>> metadata = pop();
     if (name is ParserRecovery) {
       library.endNestedDeclaration("<syntax-error>");
       return;
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 2fa5d91..1d33fb1 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
@@ -669,7 +669,9 @@
 
   void includeParts(Set<Uri> usedParts) {
     Set<Uri> seenParts = new Set<Uri>();
-    for (SourceLibraryBuilder<T, R> part in parts) {
+    for (int i = 0; i < parts.length; i++) {
+      SourceLibraryBuilder<T, R> part = parts[i];
+      int partOffset = partOffsets[i];
       if (part == this) {
         addProblem(messagePartOfSelf, -1, noLength, fileUri);
       } else if (seenParts.add(part.fileUri)) {
@@ -687,7 +689,7 @@
           } else {
             usedParts.add(part.uri);
           }
-          includePart(part, usedParts);
+          includePart(part, usedParts, partOffset);
         }
       } else {
         addProblem(templatePartTwice.withArguments(part.fileUri), -1, noLength,
@@ -696,45 +698,53 @@
     }
   }
 
-  void includePart(SourceLibraryBuilder<T, R> part, Set<Uri> usedParts) {
+  void includePart(
+      SourceLibraryBuilder<T, R> part, Set<Uri> usedParts, int partOffset) {
     if (part.partOfUri != null) {
       if (uriIsValid(part.partOfUri) && part.partOfUri != uri) {
-        // This is a warning, but the part is still included.
+        // This is an error, but the part is not removed from the list of parts,
+        // so that metadata annotations can be associated with it.
         addProblem(
             templatePartOfUriMismatch.withArguments(
                 part.fileUri, uri, part.partOfUri),
-            -1,
+            partOffset,
             noLength,
             fileUri);
+        return;
       }
     } else if (part.partOfName != null) {
       if (name != null) {
         if (part.partOfName != name) {
-          // This is a warning, but the part is still included.
+          // This is an error, but the part is not removed from the list of
+          // parts, so that metadata annotations can be associated with it.
           addProblem(
               templatePartOfLibraryNameMismatch.withArguments(
                   part.fileUri, name, part.partOfName),
-              -1,
+              partOffset,
               noLength,
               fileUri);
+          return;
         }
       } else {
-        // This is a warning, but the part is still included.
+        // This is an error, but the part is not removed from the list of parts,
+        // so that metadata annotations can be associated with it.
         addProblem(
             templatePartOfUseUri.withArguments(
                 part.fileUri, fileUri, part.partOfName),
-            -1,
+            partOffset,
             noLength,
             fileUri);
+        return;
       }
     } else {
-      // This is an error, but the part is still included, so that
-      // metadata annotations can be associated with it.
+      // This is an error, but the part is not removed from the list of parts,
+      // so that metadata annotations can be associated with it.
       assert(!part.isPart);
       if (uriIsValid(part.fileUri)) {
-        addProblem(templateMissingPartOf.withArguments(part.fileUri), -1,
-            noLength, fileUri);
+        addProblem(templateMissingPartOf.withArguments(part.fileUri),
+            partOffset, noLength, fileUri);
       }
+      return;
     }
     part.validatePart(this, usedParts);
     NameIterator partDeclarations = part.nameIterator;
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 64ee146..05cc836 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -79,8 +79,10 @@
         ClassHierarchyBuilder,
         Declaration,
         EnumBuilder,
+        KernelClassBuilder,
         KernelFieldBuilder,
         KernelProcedureBuilder,
+        KernelTypeBuilder,
         LibraryBuilder,
         NamedTypeBuilder,
         TypeBuilder;
@@ -91,6 +93,8 @@
 
 import '../kernel/transform_set_literals.dart' show SetLiteralTransformer;
 
+import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
+
 import '../loader.dart' show Loader, untranslatableUriScheme;
 
 import '../parser/class_member_parser.dart' show ClassMemberParser;
@@ -106,7 +110,7 @@
 import '../type_inference/interface_resolver.dart' show InterfaceResolver;
 
 import '../type_inference/type_inferrer.dart'
-    show LegacyModeMixinInferrer, StrongModeMixinInferrer;
+    show KernelHierarchyMixinInferrerCallback;
 
 import 'diet_listener.dart' show DietListener;
 
@@ -118,7 +122,7 @@
 
 import 'source_library_builder.dart' show SourceLibraryBuilder;
 
-class SourceLoader<L> extends Loader<L> {
+class SourceLoader extends Loader<Library> {
   /// The [FileSystem] which should be used to access files.
   final FileSystem fileSystem;
 
@@ -753,8 +757,8 @@
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (library.loader == this) {
         SourceLibraryBuilder sourceLibrary = library;
-        L target = sourceLibrary.build(coreLibrary);
-        if (!library.isPatch && !library.isSynthetic) {
+        Library target = sourceLibrary.build(coreLibrary);
+        if (!library.isPatch) {
           libraries.add(target);
         }
       }
@@ -767,7 +771,7 @@
     List<Library> workList = <Library>[];
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (!library.isPatch &&
-          (library.loader == this || library.fileUri.scheme == "dart")) {
+          (library.loader == this || library.uri.scheme == "dart")) {
         if (libraries.add(library.target)) {
           workList.add(library.target);
         }
@@ -795,11 +799,12 @@
     if (hierarchy == null) {
       hierarchy = new ClassHierarchy(computeFullComponent(),
           onAmbiguousSupertypes: onAmbiguousSupertypes,
-          mixinInferrer: target.legacyMode
-              ? new LegacyModeMixinInferrer()
-              : new StrongModeMixinInferrer(this));
+          mixinInferrer: new KernelHierarchyMixinInferrerCallback(
+              this, target.legacyMode));
     } else {
       hierarchy.onAmbiguousSupertypes = onAmbiguousSupertypes;
+      hierarchy.mixinInferrer =
+          new KernelHierarchyMixinInferrerCallback(this, target.legacyMode);
       Component component = computeFullComponent();
       hierarchy.applyTreeChanges(const [], component.libraries,
           reissueAmbiguousSupertypesFor: component);
@@ -926,16 +931,12 @@
     ticker.logMs("Checked mixin declaration applications");
   }
 
-  void buildClassHierarchy(
+  ClassHierarchyBuilder buildClassHierarchy(
       List<SourceClassBuilder> sourceClasses, ClassBuilder objectClass) {
-    if (!target.legacyMode) return;
-    ticker.logMs("Building class hierarchy");
-    ClassHierarchyBuilder classHierarchyBuilder =
-        new ClassHierarchyBuilder(objectClass);
-    for (int i = 0; i < sourceClasses.length; i++) {
-      classHierarchyBuilder.add(sourceClasses[i]);
-    }
+    ClassHierarchyBuilder hierarchy = ClassHierarchyBuilder.build(
+        objectClass, sourceClasses, this, coreTypes);
     ticker.logMs("Built class hierarchy");
+    return hierarchy;
   }
 
   void createTypeInferenceEngine() {
@@ -1110,6 +1111,18 @@
     hierarchy = null;
     typeInferenceEngine = null;
   }
+
+  @override
+  KernelClassBuilder computeClassBuilderFromTargetClass(Class cls) {
+    Library kernelLibrary = cls.enclosingLibrary;
+    LibraryBuilder library = builders[kernelLibrary.importUri];
+    return library[cls.name];
+  }
+
+  @override
+  KernelTypeBuilder computeTypeBuilder(DartType type) {
+    return type.accept(new TypeBuilderComputer(this));
+  }
 }
 
 /// A minimal implementation of dart:core that is sufficient to create an
@@ -1118,6 +1131,8 @@
 import 'dart:_internal';
 import 'dart:async';
 
+export 'dart:async' show Future, Stream;
+
 print(object) {}
 
 class Iterator {}
@@ -1167,6 +1182,8 @@
   var _current;
   var _yieldEachIterable;
 }
+
+class Function {}
 """;
 
 /// A minimal implementation of dart:async that is sufficient to create an
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index ea5e9b7..db6a7cd 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -31,6 +31,7 @@
 enum NullValue {
   Arguments,
   As,
+  AwaitToken,
   Block,
   BreakTarget,
   CascadeReceiver,
diff --git a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
index 5ba2c51..c78a6a1 100644
--- a/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/type_promotion_look_ahead_listener.dart
@@ -376,6 +376,37 @@
     doConstuctorInvocation(token, true);
   }
 
+  @override
+  void endForControlFlow(Token token) {
+    // TODO(danrubel) add support for for control flow collection entries
+    // but for now this is ignored and an error reported in the body builder.
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    // TODO(danrubel) add support for for control flow collection entries
+    // but for now this is ignored and an error reported in the body builder.
+  }
+
+  @override
+  void endIfControlFlow(Token token) {
+    // TODO(danrubel) add support for if control flow collection entries
+    // but for now this is ignored and an error reported in the body builder.
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    // TODO(danrubel) add support for if control flow collection entries
+    // but for now this is ignored and an error reported in the body builder.
+  }
+
+  @override
+  void handleSpreadExpression(Token spreadToken) {
+    // TODO(danrubel) add support for spread collections
+    // but for now this is ignored and an error reported in the body builder.
+    // The top of stack is the spread collection expression.
+  }
+
   void doConstuctorInvocation(Token token, bool isConst) {
     state.pop(); // Arguments.
     state.popPushNull(token.lexeme, token); // Constructor reference.
@@ -522,9 +553,8 @@
   }
 
   @override
-  void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
-      Token inKeyword, Token endToken) {
-    debugEvent("ForIn", awaitToken);
+  void endForIn(Token endToken) {
+    debugEvent("ForIn", endToken);
   }
 
   @override
@@ -555,13 +585,18 @@
   }
 
   @override
-  void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
-      int updateExpressionCount, Token endToken) {
-    debugEvent("ForStatement", forKeyword);
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
+    debugEvent("handleForLoopParts", forKeyword);
     state.discard(updateExpressionCount);
   }
 
   @override
+  void endForStatement(Token endToken) {
+    debugEvent("ForStatement", endToken);
+  }
+
+  @override
   void endForStatementBody(Token token) {
     debugEvent("ForStatementBody", token);
   }
@@ -852,9 +887,10 @@
   }
 
   @override
-  void handleEmptyLiteralSetOrMap(
-      Token leftBrace, Token constKeyword, Token rightBrace) {
-    debugEvent("EmptyLiteralSetOrMap", leftBrace);
+  void handleLiteralSetOrMap(
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    debugEvent("LiteralSetOrMap", leftBrace);
+    state.discard(count);
     state.pushNull("{}", leftBrace);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 2705f16..037e74e 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -4,14 +4,24 @@
 
 library fasta.target_implementation;
 
+import 'package:kernel/ast.dart' show Source;
+
 import 'package:kernel/target/targets.dart' as backend show Target;
 
+import '../base/processed_options.dart' show ProcessedOptions;
+
 import 'builder/builder.dart' show Declaration, ClassBuilder, LibraryBuilder;
 
 import 'compiler_context.dart' show CompilerContext;
 
 import 'loader.dart' show Loader;
 
+import 'messages.dart' show FormattedMessage, LocatedMessage, Message;
+
+import 'rewrite_severity.dart' show rewriteSeverity;
+
+import 'severity.dart' show Severity;
+
 import 'target.dart' show Target;
 
 import 'ticker.dart' show Ticker;
@@ -28,6 +38,9 @@
 
   final CompilerContext context = CompilerContext.current;
 
+  /// Shared with [CompilerContext].
+  final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
+
   Declaration cachedAbstractClassInstantiationError;
   Declaration cachedCompileTimeError;
   Declaration cachedDuplicatedFieldInitializerError;
@@ -35,14 +48,20 @@
   Declaration cachedNativeAnnotation;
   Declaration cachedNativeExtensionAnnotation;
 
-  bool enableSetLiterals;
   bool enableConstantUpdate2018;
+  bool enableControlFlowCollections;
+  bool enableSetLiterals;
+  bool enableSpreadCollections;
 
   TargetImplementation(Ticker ticker, this.uriTranslator, this.backendTarget)
-      : enableSetLiterals = CompilerContext.current.options
-            .isExperimentEnabled(ExperimentalFlag.setLiterals),
-        enableConstantUpdate2018 = CompilerContext.current.options
+      : enableConstantUpdate2018 = CompilerContext.current.options
             .isExperimentEnabled(ExperimentalFlag.constantUpdate2018),
+        enableControlFlowCollections = CompilerContext.current.options
+            .isExperimentEnabled(ExperimentalFlag.controlFlowCollections),
+        enableSetLiterals = CompilerContext.current.options
+            .isExperimentEnabled(ExperimentalFlag.setLiterals),
+        enableSpreadCollections = CompilerContext.current.options
+            .isExperimentEnabled(ExperimentalFlag.spreadCollections),
         super(ticker);
 
   /// Creates a [LibraryBuilder] corresponding to [uri], if one doesn't exist
@@ -115,4 +134,26 @@
       Uri uri, List<int> lineStarts, List<int> sourceCode);
 
   void readPatchFiles(covariant LibraryBuilder library) {}
+
+  FormattedMessage createFormattedMessage(
+      Message message,
+      int charOffset,
+      int length,
+      Uri fileUri,
+      List<LocatedMessage> messageContext,
+      Severity severity) {
+    ProcessedOptions processedOptions = context.options;
+    return processedOptions.format(
+        message.withLocation(fileUri, charOffset, length),
+        severity,
+        messageContext);
+  }
+
+  Severity fixSeverity(Severity severity, Message message, Uri fileUri) {
+    severity ??= message.code.severity;
+    if (severity == Severity.errorLegacyWarning) {
+      severity = backendTarget.legacyMode ? Severity.warning : Severity.error;
+    }
+    return rewriteSeverity(severity, message.code, fileUri);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 0533d88..92c4884 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -10,8 +10,7 @@
 
 import 'dart:typed_data' show Uint8List;
 
-import 'package:kernel/ast.dart'
-    show Component, Field, Library, ListLiteral, StringLiteral;
+import 'package:kernel/ast.dart' show Component, Library;
 
 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 
@@ -34,13 +33,16 @@
         TextSerializationVerifier;
 
 import 'package:testing/testing.dart'
-    show ChainContext, Result, StdioProcess, Step;
+    show ChainContext, Expectation, ExpectationSet, Result, StdioProcess, Step;
 
 import '../../api_prototype/compiler_options.dart'
     show CompilerOptions, DiagnosticMessage;
 
 import '../../base/processed_options.dart' show ProcessedOptions;
 
+import '../../compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+
 import '../compiler_context.dart' show CompilerContext;
 
 import '../kernel/verifier.dart' show verifyComponent;
@@ -50,6 +52,75 @@
 import '../fasta_codes.dart'
     show templateInternalProblemUnhandled, templateUnspecified;
 
+import '../util/relativize.dart' show relativizeUri;
+
+final Uri platformBinariesLocation = computePlatformBinariesLocation();
+
+abstract class MatchContext implements ChainContext {
+  bool get updateExpectations;
+
+  ExpectationSet get expectationSet;
+
+  Expectation get expectationFileMismatch =>
+      expectationSet["ExpectationFileMismatch"];
+
+  Expectation get expectationFileMissing =>
+      expectationSet["ExpectationFileMissing"];
+
+  Future<Result<O>> match<O>(
+    String suffix,
+    String actual,
+    Uri uri,
+    O output,
+  ) async {
+    actual = actual.trim();
+    if (actual.isNotEmpty) {
+      actual += "\n";
+    }
+    File expectedFile = new File("${uri.toFilePath()}$suffix");
+    if (await expectedFile.exists()) {
+      String expected = await expectedFile.readAsString();
+      if (expected != actual) {
+        if (updateExpectations) {
+          return updateExpectationFile<O>(expectedFile.uri, actual, output);
+        }
+        String diff = await runDiff(expectedFile.uri, actual);
+        return new Result<O>(output, expectationFileMismatch,
+            "$uri doesn't match ${expectedFile.uri}\n$diff", null);
+      } else {
+        return new Result<O>.pass(output);
+      }
+    } else {
+      if (actual.isEmpty) return new Result<O>.pass(output);
+      if (updateExpectations) {
+        return updateExpectationFile(expectedFile.uri, actual, output);
+      }
+      return new Result<O>(
+          output,
+          expectationFileMissing,
+          """
+Please create file ${expectedFile.path} with this content:
+$actual""",
+          null);
+    }
+  }
+
+  Future<Result<O>> updateExpectationFile<O>(
+    Uri uri,
+    String actual,
+    O output,
+  ) async {
+    if (actual.isEmpty) {
+      await new File.fromUri(uri).delete();
+    } else {
+      await openWrite(uri, (IOSink sink) {
+        sink.write(actual);
+      });
+    }
+    return new Result<O>.pass(output);
+  }
+}
+
 class Print extends Step<Component, Component, ChainContext> {
   const Print();
 
@@ -60,13 +131,14 @@
     await CompilerContext.runWithDefaultOptions((compilerContext) async {
       compilerContext.uriToSource.addAll(component.uriToSource);
 
+      Printer printer = new Printer(sb);
       for (Library library in component.libraries) {
-        Printer printer = new Printer(sb);
         if (library.importUri.scheme != "dart" &&
             library.importUri.scheme != "package") {
           printer.writeLibraryFile(library);
         }
       }
+      printer.writeConstantTable(component);
     });
     print("$sb");
     return pass(component);
@@ -132,80 +204,45 @@
   }
 }
 
-class MatchExpectation extends Step<Component, Component, ChainContext> {
+class MatchExpectation extends Step<Component, Component, MatchContext> {
   final String suffix;
 
-  // TODO(ahe): This is true by default which doesn't match well with the class
-  // name.
-  final bool updateExpectations;
-
-  const MatchExpectation(this.suffix, {this.updateExpectations: false});
+  const MatchExpectation(this.suffix);
 
   String get name => "match expectations";
 
-  Future<Result<Component>> run(Component component, dynamic context) async {
-    StringBuffer messages = context.componentToDiagnostics[component];
-    Uri uri = component.uriToSource.keys
-        .firstWhere((uri) => uri != null && uri.scheme == "file");
-    Library library = component.libraries
-        .firstWhere((Library library) => library.importUri.scheme != "dart");
+  Future<Result<Component>> run(Component component, MatchContext context) {
+    StringBuffer messages =
+        (context as dynamic).componentToDiagnostics[component];
+    Uri uri =
+        component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
+    Iterable<Library> libraries = component.libraries.where(
+        ((Library library) =>
+            library.importUri.scheme != "dart" &&
+            library.importUri.scheme != "package"));
     Uri base = uri.resolve(".");
     Uri dartBase = Uri.base;
     StringBuffer buffer = new StringBuffer();
-    if (messages.isNotEmpty) {
-      buffer.write("// Formatted problems:\n//");
-      for (String line in "${messages}".split("\n")) {
-        buffer.write("\n// $line".trimRight());
-      }
-      buffer.write("\n\n");
-      messages.clear();
+    messages.clear();
+    Printer printer = new Printer(buffer)
+      ..writeProblemsAsJson("Problems in component", component.problemsAsJson);
+    libraries.forEach((Library library) {
+      printer.writeLibraryFile(library);
+      printer.endLine();
+    });
+    String actual = "$buffer";
+    String binariesPath = relativizeUri(platformBinariesLocation);
+    if (binariesPath.endsWith("/dart-sdk/lib/_internal/")) {
+      // We are running from the built SDK.
+      actual = actual.replaceAll(
+          binariesPath.substring(
+              0, binariesPath.length - "lib/_internal/".length),
+          "sdk/");
     }
-    for (Field field in library.fields) {
-      if (field.name.name != "#errors") continue;
-      ListLiteral list = field.initializer;
-      buffer.write("// Unhandled errors:");
-      for (StringLiteral string in list.expressions) {
-        buffer.write("\n//");
-        for (String line in string.value.split("\n")) {
-          buffer.write("\n// $line");
-        }
-      }
-      buffer.write("\n\n");
-    }
-    new ErrorPrinter(buffer).writeLibraryFile(library);
-    String actual = "$buffer".replaceAll("$base", "org-dartlang-testcase:///");
+    actual = actual.replaceAll("$base", "org-dartlang-testcase:///");
     actual = actual.replaceAll("$dartBase", "org-dartlang-testcase-sdk:///");
     actual = actual.replaceAll("\\n", "\n");
-    File expectedFile = new File("${uri.toFilePath()}$suffix");
-    if (await expectedFile.exists()) {
-      String expected = await expectedFile.readAsString();
-      if (expected.trim() != actual.trim()) {
-        if (!updateExpectations) {
-          String diff = await runDiff(expectedFile.uri, actual);
-          return new Result<Component>(
-              component,
-              context.expectationSet["ExpectationFileMismatch"],
-              "$uri doesn't match ${expectedFile.uri}\n$diff",
-              null);
-        }
-      } else {
-        return pass(component);
-      }
-    }
-    if (updateExpectations) {
-      await openWrite(expectedFile.uri, (IOSink sink) {
-        sink.writeln(actual.trim());
-      });
-      return pass(component);
-    } else {
-      return new Result<Component>(
-          component,
-          context.expectationSet["ExpectationFileMissing"],
-          """
-Please create file ${expectedFile.path} with this content:
-$actual""",
-          null);
-    }
+    return context.match<Component>(suffix, actual, uri, component);
   }
 }
 
@@ -375,30 +412,3 @@
   }
   print("Wrote $uri");
 }
-
-class ErrorPrinter extends Printer {
-  ErrorPrinter(StringSink sink, {Object importTable, Object metadata})
-      : super(sink, importTable: importTable, metadata: metadata);
-
-  ErrorPrinter._inner(ErrorPrinter parent, Object importTable, Object metadata)
-      : super(parent.sink,
-            importTable: importTable,
-            metadata: metadata,
-            syntheticNames: parent.syntheticNames,
-            annotator: parent.annotator,
-            showExternal: parent.showExternal,
-            showOffsets: parent.showOffsets,
-            showMetadata: parent.showMetadata);
-
-  @override
-  ErrorPrinter createInner(importTable, metadata) {
-    return new ErrorPrinter._inner(this, importTable, metadata);
-  }
-
-  @override
-  visitField(Field node) {
-    if (node.name.name != "#errors") {
-      super.visitField(node);
-    }
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index 3c999dc..96b90c3 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -56,11 +56,6 @@
 
 import '../messages.dart'
     show
-        messageDeclaredMemberConflictsWithInheritedMember,
-        messageDeclaredMemberConflictsWithInheritedMemberCause,
-        messageInheritedMembersConflict,
-        messageInheritedMembersConflictCause1,
-        messageInheritedMembersConflictCause2,
         noLength,
         templateCantInferTypeDueToCircularity,
         templateCantInferTypeDueToInconsistentOverrides;
@@ -833,92 +828,12 @@
     // and static members, use a map from names to lists of members.  There can
     // be more than one static member with a given name, e.g., if there is a
     // getter and a setter.  We will report both conflicts.
-    Map<Name, List<Member>> staticMembers = {};
-    for (var procedure in class_.procedures) {
-      if (procedure.isStatic && !procedure.isFactory) {
-        staticMembers.putIfAbsent(procedure.name, () => []).add(procedure);
-      }
-    }
-    for (var field in class_.fields) {
-      if (field.isStatic) {
-        staticMembers.putIfAbsent(field.name, () => []).add(field);
-      }
-    }
     forEachApiMember(candidates, (int start, int end, Name name) {
       Procedure member = candidates[start];
-      // We should not have a method, getter, or setter in our interface that
-      // conflicts with a static method, getter, or setter declared in the
-      // class.
-      List<Member> conflicts = staticMembers[name];
-      if (conflicts != null) {
-        for (var conflict in conflicts) {
-          library.addProblem(messageDeclaredMemberConflictsWithInheritedMember,
-              conflict.fileOffset, noLength, conflict.fileUri,
-              context: [
-                messageDeclaredMemberConflictsWithInheritedMemberCause
-                    .withLocation(member.fileUri, member.fileOffset, noLength)
-              ]);
-        }
-        return;
-      }
       ProcedureKind kind = _kindOf(member);
       if (kind != ProcedureKind.Getter && kind != ProcedureKind.Setter) {
         for (int i = start + 1; i < end; ++i) {
-          if (_kindOf(candidates[i]) != kind) {
-            // We've seen a getter or setter.  If it's a getter conflicting
-            // with a method and both are declared in the same class, then that
-            // has already been signaled as a duplicated definition.
-            Procedure conflict = candidates[i];
-            if (conflict.enclosingClass != member.enclosingClass) {
-              if (member.enclosingClass == class_) {
-                library.addProblem(
-                    messageDeclaredMemberConflictsWithInheritedMember,
-                    member.fileOffset,
-                    noLength,
-                    member.fileUri,
-                    context: [
-                      messageDeclaredMemberConflictsWithInheritedMemberCause
-                          .withLocation(
-                              conflict.fileUri, conflict.fileOffset, noLength)
-                    ]);
-              } else if (conflict.enclosingClass == class_) {
-                library.addProblem(
-                    messageDeclaredMemberConflictsWithInheritedMember,
-                    conflict.fileOffset,
-                    noLength,
-                    conflict.fileUri,
-                    context: [
-                      messageDeclaredMemberConflictsWithInheritedMemberCause
-                          .withLocation(
-                              member.fileUri, member.fileOffset, noLength)
-                    ]);
-              } else {
-                library.addProblem(messageInheritedMembersConflict,
-                    class_.fileOffset, noLength, class_.fileUri,
-                    context: [
-                      messageInheritedMembersConflictCause1.withLocation(
-                          member.fileUri, member.fileOffset, noLength),
-                      messageInheritedMembersConflictCause2.withLocation(
-                          conflict.fileUri, conflict.fileOffset, noLength)
-                    ]);
-              }
-            } else {
-              // If it's a setter conflicting with a method and both are
-              // declared in the same class, it hasn't been signaled as a
-              // duplicated definition so it's reported here.
-              library.addProblem(
-                  messageDeclaredMemberConflictsWithInheritedMember,
-                  member.fileOffset,
-                  noLength,
-                  member.fileUri,
-                  context: [
-                    messageDeclaredMemberConflictsWithInheritedMemberCause
-                        .withLocation(
-                            conflict.fileUri, conflict.fileOffset, noLength)
-                  ]);
-            }
-            return;
-          }
+          if (_kindOf(candidates[i]) != kind) return;
         }
         if (member.enclosingClass == class_ && _requiresTypeInference(member)) {
           inferMethodType(library, class_, member, candidates, start + 1, end);
@@ -945,33 +860,7 @@
         while (++getterEnd < end) {
           ProcedureKind currentKind = _kindOf(candidates[getterEnd]);
           if (currentKind == ProcedureKind.Setter) break;
-          if (currentKind != ProcedureKind.Getter) {
-            Procedure conflict = candidates[getterEnd];
-            if (conflict.enclosingClass != member.enclosingClass) {
-              if (member.enclosingClass == class_) {
-                library.addProblem(
-                    messageDeclaredMemberConflictsWithInheritedMember,
-                    member.fileOffset,
-                    noLength,
-                    member.fileUri,
-                    context: [
-                      messageDeclaredMemberConflictsWithInheritedMemberCause
-                          .withLocation(
-                              conflict.fileUri, conflict.fileOffset, noLength)
-                    ]);
-              } else {
-                library.addProblem(messageInheritedMembersConflict,
-                    class_.fileOffset, noLength, class_.fileUri,
-                    context: [
-                      messageInheritedMembersConflictCause1.withLocation(
-                          member.fileUri, member.fileOffset, noLength),
-                      messageInheritedMembersConflictCause2.withLocation(
-                          conflict.fileUri, conflict.fileOffset, noLength)
-                    ]);
-              }
-            }
-            return;
-          }
+          if (currentKind != ProcedureKind.Getter) return;
         }
       }
 
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
new file mode 100644
index 0000000..2d5cb3a
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -0,0 +1,446 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'dart:math' as math;
+
+import 'package:kernel/ast.dart'
+    show
+        BottomType,
+        Class,
+        DartType,
+        DynamicType,
+        FunctionType,
+        InterfaceType,
+        NamedType,
+        TypeParameterType,
+        VoidType;
+
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+import 'type_schema.dart' show UnknownType;
+
+abstract class StandardBounds {
+  Class get functionClass;
+  InterfaceType get nullType;
+  InterfaceType get objectType;
+  InterfaceType get rawFunctionType;
+
+  bool isSubtypeOf(DartType subtype, DartType supertype);
+
+  InterfaceType getLegacyLeastUpperBound(
+      InterfaceType type1, InterfaceType type2);
+
+  /// Computes the standard lower bound of [type1] and [type2].
+  ///
+  /// Standard lower bound is a lower bound function that imposes an
+  /// ordering on the top types `void`, `dynamic`, and `object`.  This function
+  /// additionally handles the unknown type that appears during type inference.
+  DartType getStandardLowerBound(DartType type1, DartType type2) {
+    // For all types T, SLB(T,T) = T.  Note that we don't test for equality
+    // because we don't want to make the algorithm quadratic.  This is ok
+    // because the check is not needed for correctness; it's just a speed
+    // optimization.
+    if (identical(type1, type2)) {
+      return type1;
+    }
+
+    // For any type T, SLB(?, T) = SLB(T, ?) = T.
+    if (type1 is UnknownType) {
+      return type2;
+    }
+    if (type2 is UnknownType) {
+      return type1;
+    }
+
+    // SLB(void, T) = SLB(T, void) = T.
+    if (type1 is VoidType) {
+      return type2;
+    }
+    if (type2 is VoidType) {
+      return type1;
+    }
+
+    // SLB(dynamic, T) = SLB(T, dynamic) = T if T is not void.
+    if (type1 is DynamicType) {
+      return type2;
+    }
+    if (type2 is DynamicType) {
+      return type1;
+    }
+
+    // SLB(Object, T) = SLB(T, Object) = T if T is not void or dynamic.
+    if (type1 == objectType) {
+      return type2;
+    }
+    if (type2 == objectType) {
+      return type1;
+    }
+
+    // SLB(bottom, T) = SLB(T, bottom) = bottom.
+    if (type1 is BottomType) return type1;
+    if (type2 is BottomType) return type2;
+    if (type1 == nullType) return type1;
+    if (type2 == nullType) return type2;
+
+    // Function types have structural lower bounds.
+    if (type1 is FunctionType && type2 is FunctionType) {
+      return _functionStandardLowerBound(type1, type2);
+    }
+
+    // Otherwise, the lower bounds  of two types is one of them it if it is a
+    // subtype of the other.
+    if (isSubtypeOf(type1, type2)) {
+      return type1;
+    }
+
+    if (isSubtypeOf(type2, type1)) {
+      return type2;
+    }
+
+    // No subtype relation, so the lower bound is bottom.
+    return const BottomType();
+  }
+
+  /// Computes the standard upper bound of two types.
+  ///
+  /// Standard upper bound is an upper bound function that imposes an ordering
+  /// on the top types 'void', 'dynamic', and `object`.  This function
+  /// additionally handles the unknown type that appears during type inference.
+  DartType getStandardUpperBound(DartType type1, DartType type2) {
+    // For all types T, SUB(T,T) = T.  Note that we don't test for equality
+    // because we don't want to make the algorithm quadratic.  This is ok
+    // because the check is not needed for correctness; it's just a speed
+    // optimization.
+    if (identical(type1, type2)) {
+      return type1;
+    }
+
+    // For any type T, SUB(?, T) = SUB(T, ?) = T.
+    if (type1 is UnknownType) {
+      return type2;
+    }
+    if (type2 is UnknownType) {
+      return type1;
+    }
+
+    // SUB(void, T) = SUB(T, void) = void.
+    if (type1 is VoidType) {
+      return type1;
+    }
+    if (type2 is VoidType) {
+      return type2;
+    }
+
+    // SUB(dynamic, T) = SUB(T, dynamic) = dynamic if T is not void.
+    if (type1 is DynamicType) {
+      return type1;
+    }
+    if (type2 is DynamicType) {
+      return type2;
+    }
+
+    // SUB(Obect, T) = SUB(T, Object) = Object if T is not void or dynamic.
+    if (type1 == objectType) {
+      return type1;
+    }
+    if (type2 == objectType) {
+      return type2;
+    }
+
+    // SUB(bottom, T) = SUB(T, bottom) = T.
+    if (type1 is BottomType) return type2;
+    if (type2 is BottomType) return type1;
+    if (type1 == nullType) return type2;
+    if (type2 == nullType) return type1;
+
+    if (type1 is TypeParameterType || type2 is TypeParameterType) {
+      return _typeParameterStandardUpperBound(type1, type2);
+    }
+
+    // The standard upper bound of a function type and an interface type T is
+    // the standard upper bound of Function and T.
+    if (type1 is FunctionType && type2 is InterfaceType) {
+      type1 = rawFunctionType;
+    }
+    if (type2 is FunctionType && type1 is InterfaceType) {
+      type2 = rawFunctionType;
+    }
+
+    // At this point type1 and type2 should both either be interface types or
+    // function types.
+    if (type1 is InterfaceType && type2 is InterfaceType) {
+      return _interfaceStandardUpperBound(type1, type2);
+    }
+
+    if (type1 is FunctionType && type2 is FunctionType) {
+      return _functionStandardUpperBound(type1, type2);
+    }
+
+    // Should never happen. As a defensive measure, return the dynamic type.
+    assert(false);
+    return const DynamicType();
+  }
+
+  /// Compute the standard lower bound of function types [f] and [g].
+  ///
+  /// The spec rules for SLB on function types, informally, are pretty simple:
+  ///
+  /// - If a parameter is required in both, it stays required.
+  ///
+  /// - If a positional parameter is optional or missing in one, it becomes
+  ///   optional.  (This is because we're trying to build a function type which
+  ///   is a subtype of both [f] and [g], meaning it accepts all possible inputs
+  ///   that [f] and [g] accept.)
+  ///
+  /// - Named parameters are unioned together.
+  ///
+  /// - For any parameter that exists in both functions, use the SUB of them as
+  ///   the resulting parameter type.
+  ///
+  /// - Use the SLB of their return types.
+  DartType _functionStandardLowerBound(FunctionType f, FunctionType g) {
+    // TODO(rnystrom,paulberry): Right now, this assumes f and g do not have any
+    // type parameters. Revisit that in the presence of generic methods.
+
+    // Calculate the SUB of each corresponding pair of parameters.
+    int totalPositional =
+        math.max(f.positionalParameters.length, g.positionalParameters.length);
+    var positionalParameters = new List<DartType>(totalPositional);
+    for (int i = 0; i < totalPositional; i++) {
+      if (i < f.positionalParameters.length) {
+        var fType = f.positionalParameters[i];
+        if (i < g.positionalParameters.length) {
+          var gType = g.positionalParameters[i];
+          positionalParameters[i] = getStandardUpperBound(fType, gType);
+        } else {
+          positionalParameters[i] = fType;
+        }
+      } else {
+        positionalParameters[i] = g.positionalParameters[i];
+      }
+    }
+
+    // Parameters that are required in both functions are required in the
+    // result.  Parameters that are optional or missing in either end up
+    // optional.
+    int requiredParameterCount =
+        math.min(f.requiredParameterCount, g.requiredParameterCount);
+    bool hasPositional = requiredParameterCount < totalPositional;
+
+    // Union the named parameters together.
+    List<NamedType> namedParameters = [];
+    {
+      int i = 0;
+      int j = 0;
+      while (true) {
+        if (i < f.namedParameters.length) {
+          if (j < g.namedParameters.length) {
+            var fName = f.namedParameters[i].name;
+            var gName = g.namedParameters[j].name;
+            int order = fName.compareTo(gName);
+            if (order < 0) {
+              namedParameters.add(f.namedParameters[i++]);
+            } else if (order > 0) {
+              namedParameters.add(g.namedParameters[j++]);
+            } else {
+              namedParameters.add(new NamedType(
+                  fName,
+                  getStandardUpperBound(f.namedParameters[i++].type,
+                      g.namedParameters[j++].type)));
+            }
+          } else {
+            namedParameters.addAll(f.namedParameters.skip(i));
+            break;
+          }
+        } else {
+          namedParameters.addAll(g.namedParameters.skip(j));
+          break;
+        }
+      }
+    }
+    bool hasNamed = namedParameters.isNotEmpty;
+
+    // Edge case. Dart does not support functions with both optional positional
+    // and named parameters. If we would synthesize that, give up.
+    if (hasPositional && hasNamed) return const BottomType();
+
+    // Calculate the SLB of the return type.
+    DartType returnType = getStandardLowerBound(f.returnType, g.returnType);
+    return new FunctionType(positionalParameters, returnType,
+        namedParameters: namedParameters,
+        requiredParameterCount: requiredParameterCount);
+  }
+
+  /// Compute the standard upper bound of function types [f] and [g].
+  ///
+  /// The rules for SUB on function types, informally, are pretty simple:
+  ///
+  /// - If the functions don't have the same number of required parameters,
+  ///   always return `Function`.
+  ///
+  /// - Discard any optional named or positional parameters the two types do not
+  ///   have in common.
+  ///
+  /// - Compute the SLB of each corresponding pair of parameter types, and the
+  ///   SUB of the return types.  Return a function type with those types.
+  DartType _functionStandardUpperBound(FunctionType f, FunctionType g) {
+    // TODO(rnystrom): Right now, this assumes f and g do not have any type
+    // parameters. Revisit that in the presence of generic methods.
+
+    // If F and G differ in their number of required parameters, then the
+    // standard upper bound of F and G is Function.
+    // TODO(paulberry): We could do better here, e.g.:
+    //   SUB(([int]) -> void, (int) -> void) = (int) -> void
+    if (f.requiredParameterCount != g.requiredParameterCount) {
+      return functionClass.rawType;
+    }
+    int requiredParameterCount = f.requiredParameterCount;
+
+    // Calculate the SLB of each corresponding pair of parameters.
+    // Ignore any extra optional positional parameters if one has more than the
+    // other.
+    int totalPositional =
+        math.min(f.positionalParameters.length, g.positionalParameters.length);
+    var positionalParameters = new List<DartType>(totalPositional);
+    for (int i = 0; i < totalPositional; i++) {
+      positionalParameters[i] = getStandardLowerBound(
+          f.positionalParameters[i], g.positionalParameters[i]);
+    }
+
+    // Intersect the named parameters.
+    List<NamedType> namedParameters = [];
+    {
+      int i = 0;
+      int j = 0;
+      while (true) {
+        if (i < f.namedParameters.length) {
+          if (j < g.namedParameters.length) {
+            var fName = f.namedParameters[i].name;
+            var gName = g.namedParameters[j].name;
+            int order = fName.compareTo(gName);
+            if (order < 0) {
+              i++;
+            } else if (order > 0) {
+              j++;
+            } else {
+              namedParameters.add(new NamedType(
+                  fName,
+                  getStandardLowerBound(f.namedParameters[i++].type,
+                      g.namedParameters[j++].type)));
+            }
+          } else {
+            break;
+          }
+        } else {
+          break;
+        }
+      }
+    }
+
+    // Calculate the SUB of the return type.
+    DartType returnType = getStandardUpperBound(f.returnType, g.returnType);
+    return new FunctionType(positionalParameters, returnType,
+        namedParameters: namedParameters,
+        requiredParameterCount: requiredParameterCount);
+  }
+
+  DartType _interfaceStandardUpperBound(
+      InterfaceType type1, InterfaceType type2) {
+    // This currently does not implement a very complete standard 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, then take the
+    //    pointwise standard upper bound of the type arguments.  This is again
+    //    the best result, except that the recursive calls may not return
+    //    the true standard 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).
+    // 3. Otherwise return the spec-defined standard upper bound.  This will
+    //    be an upper bound, might (or might not) be least, and might
+    //    (or might not) be a well-formed type.
+    if (isSubtypeOf(type1, type2)) {
+      return type2;
+    }
+    if (isSubtypeOf(type2, type1)) {
+      return type1;
+    }
+    if (type1 is InterfaceType &&
+        type2 is InterfaceType &&
+        identical(type1.classNode, type2.classNode)) {
+      List<DartType> tArgs1 = type1.typeArguments;
+      List<DartType> tArgs2 = type2.typeArguments;
+
+      assert(tArgs1.length == tArgs2.length);
+      List<DartType> tArgs = new List(tArgs1.length);
+      for (int i = 0; i < tArgs1.length; i++) {
+        tArgs[i] = getStandardUpperBound(tArgs1[i], tArgs2[i]);
+      }
+      return new InterfaceType(type1.classNode, tArgs);
+    }
+    return getLegacyLeastUpperBound(type1, type2);
+  }
+
+  DartType _typeParameterStandardUpperBound(DartType type1, DartType type2) {
+    // This currently just implements a simple standard upper bound to
+    // handle some common cases.  It also avoids some termination issues
+    // with the naive spec algorithm.  The standard upper bound of two types
+    // (at least one of which is a type parameter) is computed here as:
+    // 1. If either type is a supertype of the other, return it.
+    // 2. If the first type is a type parameter, replace it with its bound,
+    //    with recursive occurrences of itself replaced with Object.
+    //    The second part of this should ensure termination.  Informally,
+    //    each type variable instantiation in one of the arguments to the
+    //    standard upper bound algorithm now strictly reduces the number
+    //    of bound variables in scope in that argument position.
+    // 3. If the second type is a type parameter, do the symmetric operation
+    //    to #2.
+    //
+    // It's not immediately obvious why this is symmetric in the case that both
+    // of them are type parameters.  For #1, symmetry holds since subtype
+    // is antisymmetric.  For #2, it's clearly not symmetric if upper bounds of
+    // bottom are allowed.  Ignoring this (for various reasons, not least
+    // of which that there's no way to write it), there's an informal
+    // argument (that might even be right) that you will always either
+    // end up expanding both of them or else returning the same result no matter
+    // which order you expand them in.  A key observation is that
+    // identical(expand(type1), type2) => subtype(type1, type2)
+    // and hence the contra-positive.
+    //
+    // TODO(leafp): Think this through and figure out what's the right
+    // definition.  Be careful about termination.
+    //
+    // I suspect in general a reasonable algorithm is to expand the innermost
+    // type variable first.  Alternatively, you could probably choose to treat
+    // it as just an instance of the interface type upper bound problem, with
+    // the "inheritance" chain extended by the bounds placed on the variables.
+    if (isSubtypeOf(type1, type2)) {
+      return type2;
+    }
+    if (isSubtypeOf(type2, type1)) {
+      return type1;
+    }
+    if (type1 is TypeParameterType) {
+      // TODO(paulberry): Analyzer collapses simple bounds in one step, i.e. for
+      // C<T extends U, U extends List>, T gets resolved directly to List.  Do
+      // we need to replicate that behavior?
+      return getStandardUpperBound(
+          Substitution.fromMap({type1.parameter: objectType})
+              .substituteType(type1.parameter.bound),
+          type2);
+    } else if (type2 is TypeParameterType) {
+      return getStandardUpperBound(
+          type1,
+          Substitution.fromMap({type2.parameter: objectType})
+              .substituteType(type2.parameter.bound));
+    } else {
+      // We should only be called when at least one of the types is a
+      // TypeParameterType
+      assert(false);
+      return const DynamicType();
+    }
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index 91df6f16..a10dea0 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -4,10 +4,13 @@
 
 import 'package:kernel/ast.dart'
     show
+        Class,
         DartType,
         DynamicType,
         FunctionType,
         InterfaceType,
+        Member,
+        Name,
         NamedType,
         Procedure,
         TypeParameter,
@@ -29,19 +32,39 @@
 
 /// Creates a collection of [TypeConstraint]s corresponding to type parameters,
 /// based on an attempt to make one type schema a subtype of another.
-class TypeConstraintGatherer {
-  final TypeSchemaEnvironment environment;
-
+abstract class TypeConstraintGatherer {
   final _protoConstraints = <_ProtoConstraint>[];
 
   final List<TypeParameter> _parametersToConstrain;
 
   /// Creates a [TypeConstraintGatherer] which is prepared to gather type
   /// constraints for the given [typeParameters].
-  TypeConstraintGatherer(
-      this.environment, Iterable<TypeParameter> typeParameters)
+  TypeConstraintGatherer.subclassing(Iterable<TypeParameter> typeParameters)
       : _parametersToConstrain = typeParameters.toList();
 
+  factory TypeConstraintGatherer(TypeSchemaEnvironment environment,
+      Iterable<TypeParameter> typeParameters) {
+    return new TypeSchemaConstraintGatherer(environment, typeParameters);
+  }
+
+  Class get objectClass;
+
+  Class get functionClass;
+
+  Class get futureOrClass;
+
+  Class get nullClass;
+
+  void addUpperBound(TypeConstraint constraint, DartType upper);
+
+  void addLowerBound(TypeConstraint constraint, DartType lower);
+
+  Member getInterfaceMember(Class class_, Name name, {bool setter: false});
+
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass);
+
+  InterfaceType futureType(DartType type);
+
   /// Returns the set of type constraints that was gathered.
   Map<TypeParameter, TypeConstraint> computeConstraints() {
     var result = <TypeParameter, TypeConstraint>{};
@@ -50,11 +73,9 @@
     }
     for (var protoConstraint in _protoConstraints) {
       if (protoConstraint.isUpper) {
-        environment.addUpperBound(
-            result[protoConstraint.parameter], protoConstraint.bound);
+        addUpperBound(result[protoConstraint.parameter], protoConstraint.bound);
       } else {
-        environment.addLowerBound(
-            result[protoConstraint.parameter], protoConstraint.bound);
+        addLowerBound(result[protoConstraint.parameter], protoConstraint.bound);
       }
     }
     return result;
@@ -181,7 +202,7 @@
     // above is irrelevant; we just need to find the matched superclass,
     // substitute, and then iterate through type variables.
     var matchingSupertypeOfSubtype =
-        environment.getTypeAsInstanceOf(subtype, supertype.classNode);
+        getTypeAsInstanceOf(subtype, supertype.classNode);
     if (matchingSupertypeOfSubtype == null) return false;
     for (int i = 0; i < supertype.classNode.typeParameters.length; i++) {
       if (!_isSubtypeMatch(matchingSupertypeOfSubtype.typeArguments[i],
@@ -197,8 +218,7 @@
     // it return `true` for both Null and bottom types?  Revisit this once
     // enough functionality is implemented that we can compare the behavior with
     // the old analyzer-based implementation.
-    return type is InterfaceType &&
-        identical(type.classNode, environment.coreTypes.nullClass);
+    return type is InterfaceType && identical(type.classNode, nullClass);
   }
 
   /// Attempts to match [subtype] as a subtype of [supertype], gathering any
@@ -245,10 +265,10 @@
 
     // Handle FutureOr<T> union type.
     if (subtype is InterfaceType &&
-        identical(subtype.classNode, environment.futureOrClass)) {
+        identical(subtype.classNode, futureOrClass)) {
       var subtypeArg = subtype.typeArguments[0];
       if (supertype is InterfaceType &&
-          identical(supertype.classNode, environment.futureOrClass)) {
+          identical(supertype.classNode, futureOrClass)) {
         // `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to
         // `L` under constraints `C`:
         // - If `P` is a subtype match for `Q` with respect to `L` under
@@ -263,13 +283,13 @@
       //   constraints `C0`.
       // - And `P` is a subtype match for `Q` with respect to `L` under
       //   constraints `C1`.
-      var subtypeFuture = environment.futureType(subtypeArg);
+      var subtypeFuture = futureType(subtypeArg);
       return _isSubtypeMatch(subtypeFuture, supertype) &&
           _isSubtypeMatch(subtypeArg, supertype);
     }
 
     if (supertype is InterfaceType &&
-        identical(supertype.classNode, environment.futureOrClass)) {
+        identical(supertype.classNode, futureOrClass)) {
       // `P` is a subtype match for `FutureOr<Q>` with respect to `L` under
       // constraints `C`:
       // - If `P` is a subtype match for `Future<Q>` with respect to `L` under
@@ -279,7 +299,7 @@
       //   - And `P` is a subtype match for `Q` with respect to `L` under
       //     constraints `C`
       var supertypeArg = supertype.typeArguments[0];
-      var supertypeFuture = environment.futureType(supertypeArg);
+      var supertypeFuture = futureType(supertypeArg);
       return trySubtypeMatch(subtype, supertypeFuture) ||
           _isSubtypeMatch(subtype, supertypeArg);
     }
@@ -310,9 +330,8 @@
     }
     if (subtype is FunctionType) {
       if (supertype is InterfaceType) {
-        return identical(
-                supertype.classNode, environment.coreTypes.functionClass) ||
-            identical(supertype.classNode, environment.coreTypes.objectClass);
+        return identical(supertype.classNode, functionClass) ||
+            identical(supertype.classNode, objectClass);
       } else if (supertype is FunctionType) {
         return _isFunctionSubtypeMatch(subtype, supertype);
       }
@@ -323,8 +342,7 @@
     //   and `F` is a subtype match for a type `Q` with respect to `L` under
     //   constraints `C`.
     if (subtype is InterfaceType) {
-      var callMember =
-          environment.hierarchy.getInterfaceMember(subtype.classNode, callName);
+      var callMember = getInterfaceMember(subtype.classNode, callName);
       if (callMember is Procedure && !callMember.isGetter) {
         var callType = callMember.getterType;
         if (callType != null) {
@@ -346,8 +364,7 @@
   bool _isTop(DartType type) =>
       type is DynamicType ||
       type is VoidType ||
-      (type is InterfaceType &&
-          identical(type.classNode, environment.coreTypes.objectClass));
+      (type is InterfaceType && identical(type.classNode, objectClass));
 
   /// Given two lists of function type formal parameters, checks that their
   /// bounds are compatible.
@@ -382,6 +399,52 @@
   }
 }
 
+class TypeSchemaConstraintGatherer extends TypeConstraintGatherer {
+  final TypeSchemaEnvironment environment;
+
+  TypeSchemaConstraintGatherer(
+      this.environment, Iterable<TypeParameter> typeParameters)
+      : super.subclassing(typeParameters);
+
+  @override
+  Class get objectClass => environment.coreTypes.objectClass;
+
+  @override
+  Class get functionClass => environment.coreTypes.functionClass;
+
+  @override
+  Class get futureOrClass => environment.coreTypes.futureOrClass;
+
+  @override
+  Class get nullClass => environment.coreTypes.nullClass;
+
+  @override
+  void addUpperBound(TypeConstraint constraint, DartType upper) {
+    environment.addUpperBound(constraint, upper);
+  }
+
+  @override
+  void addLowerBound(TypeConstraint constraint, DartType lower) {
+    environment.addLowerBound(constraint, lower);
+  }
+
+  @override
+  Member getInterfaceMember(Class class_, Name name, {bool setter: false}) {
+    return environment.hierarchy
+        .getInterfaceMember(class_, name, setter: setter);
+  }
+
+  @override
+  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
+    return environment.getTypeAsInstanceOf(type, superclass);
+  }
+
+  @override
+  InterfaceType futureType(DartType type) {
+    return environment.futureType(type);
+  }
+}
+
 /// Tracks a single constraint on a single type variable.
 ///
 /// This is called "_ProtoConstraint" to distinguish from [TypeConstraint],
@@ -397,4 +460,10 @@
   _ProtoConstraint.lower(this.parameter, this.bound) : isUpper = false;
 
   _ProtoConstraint.upper(this.parameter, this.bound) : isUpper = true;
+
+  String toString() {
+    return isUpper
+        ? "${parameter.name} <: $bound"
+        : "$bound <: ${parameter.name}";
+  }
 }
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 393c70b..d719e07 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
@@ -35,6 +35,7 @@
         PropertyGet,
         PropertySet,
         ReturnStatement,
+        SetLiteral,
         Statement,
         StaticGet,
         SuperMethodInvocation,
@@ -49,7 +50,9 @@
         VariableGet,
         VoidType;
 
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy, MixinInferrer;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
+import 'package:kernel/class_hierarchy.dart' as kernel show MixinInferrer;
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
@@ -83,6 +86,7 @@
         templateInvalidCastFunctionExpr,
         templateInvalidCastLiteralList,
         templateInvalidCastLiteralMap,
+        templateInvalidCastLiteralSet,
         templateInvalidCastLocalFunction,
         templateInvalidCastNewExpr,
         templateInvalidCastStaticMethod,
@@ -109,14 +113,14 @@
         getExplicitTypeArguments,
         getInferredType;
 
+import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
+
 import '../names.dart' show callName, unaryMinusName;
 
 import '../problems.dart' show internalProblem, unexpected, unhandled;
 
 import '../source/source_loader.dart' show SourceLoader;
 
-import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
-
 import 'inference_helper.dart' show InferenceHelper;
 
 import 'interface_resolver.dart' show ForwardingNode, SyntheticAccessor;
@@ -769,14 +773,10 @@
       }
       expression.parent.replaceChild(
           expression,
-          new Let(
-              new VariableDeclaration.forValue(receiver)
-                ..fileOffset = receiver.fileOffset,
-              helper.desugarSyntheticExpression(helper.buildProblem(
-                  errorTemplate.withArguments(name.name, receiverType),
-                  fileOffset,
-                  length)))
-            ..fileOffset = fileOffset);
+          helper.desugarSyntheticExpression(helper.buildProblem(
+              errorTemplate.withArguments(name.name, receiverType),
+              fileOffset,
+              length)));
     }
     return interfaceMember;
   }
@@ -1676,12 +1676,7 @@
 
   /// Modifies a type as appropriate when inferring a closure return type.
   DartType inferReturnType(DartType returnType) {
-    if (returnType == null) {
-      // Analyzer infers `Null` if there is no `return` expression; the spec
-      // says to return `void`.  TODO(paulberry): resolve this difference.
-      return coreTypes.nullClass.rawType;
-    }
-    return returnType;
+    return returnType ?? typeSchemaEnvironment.nullType;
   }
 
   /// Performs type inference on the given [statement].
@@ -1869,6 +1864,9 @@
     if (expression is MapLiteral) {
       return templateInvalidCastLiteralMap;
     }
+    if (expression is SetLiteral) {
+      return templateInvalidCastLiteralSet;
+    }
     if (expression is FunctionExpression) {
       return templateInvalidCastFunctionExpr;
     }
@@ -1911,28 +1909,41 @@
   }
 }
 
-class LegacyModeMixinInferrer implements MixinInferrer {
+// TODO(ahe): I'm working on removing this.
+class KernelHierarchyMixinInferrerCallback implements kernel.MixinInferrer {
+  final SourceLoader loader;
+  final bool legacyMode;
+
+  KernelHierarchyMixinInferrerCallback(this.loader, this.legacyMode);
+
+  @override
   void infer(ClassHierarchy hierarchy, Class classNode) {
+    if (legacyMode) return;
     Supertype mixedInType = classNode.mixedInType;
-    if (mixedInType.typeArguments.isNotEmpty &&
-        mixedInType.typeArguments.first == const UnknownType()) {
-      assert(mixedInType.typeArguments.every((t) => t == const UnknownType()));
-      for (int i = 0; i < mixedInType.typeArguments.length; ++i) {
-        mixedInType.typeArguments[i] = const DynamicType();
-      }
-    }
+    List<DartType> typeArguments = mixedInType.typeArguments;
+    if (typeArguments.isEmpty || typeArguments.first is! UnknownType) return;
+    new KernelHierarchyMixinInferrer(
+            hierarchy,
+            loader,
+            new TypeConstraintGatherer(
+                new TypeSchemaEnvironment(loader.coreTypes, hierarchy),
+                mixedInType.classNode.typeParameters))
+        .infer(classNode);
   }
 }
 
-class StrongModeMixinInferrer implements MixinInferrer {
+abstract class MixinInferrer {
   final CoreTypes coreTypes;
-  final SourceLoader loader;
-  TypeConstraintGatherer gatherer;
+  final TypeConstraintGatherer gatherer;
 
-  StrongModeMixinInferrer(this.loader) : coreTypes = loader.coreTypes;
+  MixinInferrer(this.coreTypes, this.gatherer);
 
-  void generateConstraints(ClassHierarchy hierarchy, Class mixinClass,
-      Supertype baseType, Supertype mixinSupertype) {
+  Supertype asInstantiationOf(Supertype type, Class superclass);
+
+  void reportProblem(Message message, Class cls);
+
+  void generateConstraints(
+      Class mixinClass, Supertype baseType, Supertype mixinSupertype) {
     if (mixinSupertype.typeArguments.isEmpty) {
       // The supertype constraint isn't generic; it doesn't constrain anything.
     } else if (mixinSupertype.classNode.isAnonymousMixin) {
@@ -1990,20 +2001,18 @@
       }
       s0 = substitution.substituteSupertype(s0);
       s1 = substitution.substituteSupertype(s1);
-      generateConstraints(hierarchy, mixinClass, baseType, s0);
-      generateConstraints(hierarchy, mixinClass, baseType, s1);
+      generateConstraints(mixinClass, baseType, s0);
+      generateConstraints(mixinClass, baseType, s1);
     } else {
       // Find the type U0 which is baseType as an instance of mixinSupertype's
       // class.
       Supertype supertype =
-          hierarchy.asInstantiationOf(baseType, mixinSupertype.classNode);
+          asInstantiationOf(baseType, mixinSupertype.classNode);
       if (supertype == null) {
-        loader.addProblem(
+        reportProblem(
             templateMixinInferenceNoMatchingClass.withArguments(mixinClass.name,
                 baseType.classNode.name, mixinSupertype.asInterfaceType),
-            mixinClass.fileOffset,
-            noLength,
-            mixinClass.fileUri);
+            mixinClass);
         return;
       }
       InterfaceType u0 = Substitution.fromSupertype(baseType)
@@ -2018,62 +2027,70 @@
     }
   }
 
-  void infer(ClassHierarchy hierarchy, Class classNode) {
+  void infer(Class classNode) {
     Supertype mixedInType = classNode.mixedInType;
-    if (mixedInType.typeArguments.isNotEmpty &&
-        mixedInType.typeArguments.first == const UnknownType()) {
-      assert(mixedInType.typeArguments.every((t) => t == const UnknownType()));
-      // Note that we have no anonymous mixin applications, they have all
-      // been named.  Note also that mixin composition has been translated
-      // so that we only have mixin applications of the form `S with M`.
-      Supertype baseType = classNode.supertype;
-      Class mixinClass = mixedInType.classNode;
-      Supertype mixinSupertype = mixinClass.supertype;
-      gatherer = new TypeConstraintGatherer(
-          new TypeSchemaEnvironment(loader.coreTypes, hierarchy),
-          mixinClass.typeParameters);
-      // Generate constraints based on the mixin's supertype.
-      generateConstraints(hierarchy, mixinClass, baseType, mixinSupertype);
-      // Solve them to get a map from type parameters to upper and lower
-      // bounds.
-      var result = gatherer.computeConstraints();
-      // Generate new type parameters with the solution as bounds.
-      List<TypeParameter> parameters = mixinClass.typeParameters.map((p) {
-        var constraint = result[p];
-        // Because we solved for equality, a valid solution has a parameter
-        // either unconstrained or else with identical upper and lower bounds.
-        if (constraint != null && constraint.upper != constraint.lower) {
-          loader.addProblem(
-              templateMixinInferenceNoMatchingClass.withArguments(
-                  mixinClass.name,
-                  baseType.classNode.name,
-                  mixinSupertype.asInterfaceType),
-              mixinClass.fileOffset,
-              noLength,
-              mixinClass.fileUri);
-          return p;
-        }
-        assert(constraint == null || constraint.upper == constraint.lower);
-        bool exact =
-            constraint != null && constraint.upper != const UnknownType();
-        return new TypeParameter(
-            p.name, exact ? constraint.upper : p.bound, p.defaultType);
-      }).toList();
-      // Bounds might mention the mixin class's type parameters so we have to
-      // substitute them before calling instantiate to bounds.
-      var substitution = Substitution.fromPairs(mixinClass.typeParameters,
-          parameters.map((p) => new TypeParameterType(p)).toList());
-      for (var p in parameters) {
-        p.bound = substitution.substituteType(p.bound);
+    assert(mixedInType.typeArguments.every((t) => t == const UnknownType()));
+    // Note that we have no anonymous mixin applications, they have all
+    // been named.  Note also that mixin composition has been translated
+    // so that we only have mixin applications of the form `S with M`.
+    Supertype baseType = classNode.supertype;
+    Class mixinClass = mixedInType.classNode;
+    Supertype mixinSupertype = mixinClass.supertype;
+    // Generate constraints based on the mixin's supertype.
+    generateConstraints(mixinClass, baseType, mixinSupertype);
+    // Solve them to get a map from type parameters to upper and lower
+    // bounds.
+    var result = gatherer.computeConstraints();
+    // Generate new type parameters with the solution as bounds.
+    List<TypeParameter> parameters = mixinClass.typeParameters.map((p) {
+      var constraint = result[p];
+      // Because we solved for equality, a valid solution has a parameter
+      // either unconstrained or else with identical upper and lower bounds.
+      if (constraint != null && constraint.upper != constraint.lower) {
+        reportProblem(
+            templateMixinInferenceNoMatchingClass.withArguments(mixinClass.name,
+                baseType.classNode.name, mixinSupertype.asInterfaceType),
+            mixinClass);
+        return p;
       }
-      // Use instantiate to bounds.
-      List<DartType> bounds =
-          calculateBounds(parameters, loader.coreTypes.objectClass);
-      for (int i = 0; i < mixedInType.typeArguments.length; ++i) {
-        mixedInType.typeArguments[i] = bounds[i];
-      }
-      gatherer = null;
+      assert(constraint == null || constraint.upper == constraint.lower);
+      bool exact =
+          constraint != null && constraint.upper != const UnknownType();
+      return new TypeParameter(
+          p.name, exact ? constraint.upper : p.bound, p.defaultType);
+    }).toList();
+    // Bounds might mention the mixin class's type parameters so we have to
+    // substitute them before calling instantiate to bounds.
+    var substitution = Substitution.fromPairs(mixinClass.typeParameters,
+        parameters.map((p) => new TypeParameterType(p)).toList());
+    for (var p in parameters) {
+      p.bound = substitution.substituteType(p.bound);
     }
+    // Use instantiate to bounds.
+    List<DartType> bounds = calculateBounds(parameters, coreTypes.objectClass);
+    for (int i = 0; i < mixedInType.typeArguments.length; ++i) {
+      mixedInType.typeArguments[i] = bounds[i];
+    }
+  }
+}
+
+// TODO(ahe): I'm working on removing this.
+class KernelHierarchyMixinInferrer extends MixinInferrer {
+  final ClassHierarchy hierarchy;
+  final SourceLoader loader;
+
+  KernelHierarchyMixinInferrer(
+      this.hierarchy, this.loader, TypeConstraintGatherer gatherer)
+      : super(loader.coreTypes, gatherer);
+
+  @override
+  Supertype asInstantiationOf(Supertype type, Class superclass) {
+    return hierarchy.asInstantiationOf(type, superclass);
+  }
+
+  @override
+  void reportProblem(Message message, Class cls) {
+    loader.addProblem(message, cls.fileOffset, noLength, cls.fileUri);
   }
 }
 
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 3aa0279..46d023e 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
@@ -2,20 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE.md file.
 
-import 'dart:math' as math;
-
 import 'package:kernel/ast.dart'
     show
-        BottomType,
+        Class,
         DartType,
         DynamicType,
         FunctionType,
         InterfaceType,
         NamedType,
         Procedure,
-        TypeParameter,
-        TypeParameterType,
-        VoidType;
+        TypeParameter;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
@@ -26,6 +22,8 @@
 import 'package:kernel/src/hierarchy_based_type_environment.dart'
     show HierarchyBasedTypeEnvironment;
 
+import 'standard_bounds.dart' show StandardBounds;
+
 import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
 
 import 'type_schema.dart' show UnknownType, typeSchemaToString, isKnown;
@@ -90,10 +88,18 @@
       '${typeSchemaToString(lower)} <: <type> <: ${typeSchemaToString(upper)}';
 }
 
-class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment {
+class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment
+    with StandardBounds {
   TypeSchemaEnvironment(CoreTypes coreTypes, ClassHierarchy hierarchy)
       : super(coreTypes, hierarchy);
 
+  Class get functionClass => coreTypes.functionClass;
+
+  InterfaceType getLegacyLeastUpperBound(
+      InterfaceType type1, InterfaceType type2) {
+    return hierarchy.getLegacyLeastUpperBound(type1, type2);
+  }
+
   /// Modify the given [constraint]'s lower bound to include [lower].
   void addLowerBound(TypeConstraint constraint, DartType lower) {
     constraint.lower = getStandardUpperBound(constraint.lower, lower);
@@ -104,161 +110,6 @@
     constraint.upper = getStandardLowerBound(constraint.upper, upper);
   }
 
-  /// Computes the standard lower bound of [type1] and [type2].
-  ///
-  /// Standard lower bound is a lower bound function that imposes an
-  /// ordering on the top types `void`, `dynamic`, and `object`.  This function
-  /// additionally handles the unknown type that appears during type inference.
-  DartType getStandardLowerBound(DartType type1, DartType type2) {
-    // For all types T, SLB(T,T) = T.  Note that we don't test for equality
-    // because we don't want to make the algorithm quadratic.  This is ok
-    // because the check is not needed for correctness; it's just a speed
-    // optimization.
-    if (identical(type1, type2)) {
-      return type1;
-    }
-
-    // For any type T, SLB(?, T) = SLB(T, ?) = T.
-    if (type1 is UnknownType) {
-      return type2;
-    }
-    if (type2 is UnknownType) {
-      return type1;
-    }
-
-    // SLB(void, T) = SLB(T, void) = T.
-    if (type1 is VoidType) {
-      return type2;
-    }
-    if (type2 is VoidType) {
-      return type1;
-    }
-
-    // SLB(dynamic, T) = SLB(T, dynamic) = T if T is not void.
-    if (type1 is DynamicType) {
-      return type2;
-    }
-    if (type2 is DynamicType) {
-      return type1;
-    }
-
-    // SLB(Object, T) = SLB(T, Object) = T if T is not void or dynamic.
-    if (type1 == objectType) {
-      return type2;
-    }
-    if (type2 == objectType) {
-      return type1;
-    }
-
-    // SLB(bottom, T) = SLB(T, bottom) = bottom.
-    if (isBottom(type1)) {
-      return type1;
-    }
-    if (isBottom(type2)) {
-      return type2;
-    }
-
-    // Function types have structural lower bounds.
-    if (type1 is FunctionType && type2 is FunctionType) {
-      return _functionStandardLowerBound(type1, type2);
-    }
-
-    // Otherwise, the lower bounds  of two types is one of them it if it is a
-    // subtype of the other.
-    if (isSubtypeOf(type1, type2)) {
-      return type1;
-    }
-
-    if (isSubtypeOf(type2, type1)) {
-      return type2;
-    }
-
-    // No subtype relation, so the lower bound is bottom.
-    return const BottomType();
-  }
-
-  /// Computes the standard upper bound of two types.
-  ///
-  /// Standard upper bound is an upper bound function that imposes an ordering
-  /// on the top types 'void', 'dynamic', and `object`.  This function
-  /// additionally handles the unknown type that appears during type inference.
-  DartType getStandardUpperBound(DartType type1, DartType type2) {
-    // For all types T, SUB(T,T) = T.  Note that we don't test for equality
-    // because we don't want to make the algorithm quadratic.  This is ok
-    // because the check is not needed for correctness; it's just a speed
-    // optimization.
-    if (identical(type1, type2)) {
-      return type1;
-    }
-
-    // For any type T, SUB(?, T) = SUB(T, ?) = T.
-    if (type1 is UnknownType) {
-      return type2;
-    }
-    if (type2 is UnknownType) {
-      return type1;
-    }
-
-    // SUB(void, T) = SUB(T, void) = void.
-    if (type1 is VoidType) {
-      return type1;
-    }
-    if (type2 is VoidType) {
-      return type2;
-    }
-
-    // SUB(dynamic, T) = SUB(T, dynamic) = dynamic if T is not void.
-    if (type1 is DynamicType) {
-      return type1;
-    }
-    if (type2 is DynamicType) {
-      return type2;
-    }
-
-    // SUB(Obect, T) = SUB(T, Object) = Object if T is not void or dynamic.
-    if (type1 == objectType) {
-      return type1;
-    }
-    if (type2 == objectType) {
-      return type2;
-    }
-
-    // SUB(bottom, T) = SUB(T, bottom) = T.
-    if (isBottom(type1)) {
-      return type2;
-    }
-    if (isBottom(type2)) {
-      return type1;
-    }
-
-    if (type1 is TypeParameterType || type2 is TypeParameterType) {
-      return _typeParameterStandardUpperBound(type1, type2);
-    }
-
-    // The standard upper bound of a function type and an interface type T is
-    // the standard upper bound of Function and T.
-    if (type1 is FunctionType && type2 is InterfaceType) {
-      type1 = rawFunctionType;
-    }
-    if (type2 is FunctionType && type1 is InterfaceType) {
-      type2 = rawFunctionType;
-    }
-
-    // At this point type1 and type2 should both either be interface types or
-    // function types.
-    if (type1 is InterfaceType && type2 is InterfaceType) {
-      return _interfaceStandardUpperBound(type1, type2);
-    }
-
-    if (type1 is FunctionType && type2 is FunctionType) {
-      return _functionStandardUpperBound(type1, type2);
-    }
-
-    // Should never happen. As a defensive measure, return the dynamic type.
-    assert(false);
-    return const DynamicType();
-  }
-
   @override
   DartType getTypeOfOverloadedArithmetic(DartType type1, DartType type2) {
     // TODO(paulberry): this matches what is defined in the spec.  It would be
@@ -431,12 +282,10 @@
   }
 
   @override
-  bool isBottom(DartType t) {
-    if (t is UnknownType) {
-      return true;
-    } else {
-      return super.isBottom(t);
-    }
+  bool isSubtypeOf(DartType subtype, DartType supertype) {
+    if (subtype is UnknownType) return true;
+    if (subtype == Null && supertype is UnknownType) return true;
+    return super.isSubtypeOf(subtype, supertype);
   }
 
   bool isEmptyContext(DartType context) {
@@ -508,169 +357,6 @@
         isSubtypeOf(type, constraint.upper);
   }
 
-  /// Compute the standard lower bound of function types [f] and [g].
-  ///
-  /// The spec rules for SLB on function types, informally, are pretty simple:
-  ///
-  /// - If a parameter is required in both, it stays required.
-  ///
-  /// - If a positional parameter is optional or missing in one, it becomes
-  ///   optional.  (This is because we're trying to build a function type which
-  ///   is a subtype of both [f] and [g], meaning it accepts all possible inputs
-  ///   that [f] and [g] accept.)
-  ///
-  /// - Named parameters are unioned together.
-  ///
-  /// - For any parameter that exists in both functions, use the SUB of them as
-  ///   the resulting parameter type.
-  ///
-  /// - Use the SLB of their return types.
-  DartType _functionStandardLowerBound(FunctionType f, FunctionType g) {
-    // TODO(rnystrom,paulberry): Right now, this assumes f and g do not have any
-    // type parameters. Revisit that in the presence of generic methods.
-
-    // Calculate the SUB of each corresponding pair of parameters.
-    int totalPositional =
-        math.max(f.positionalParameters.length, g.positionalParameters.length);
-    var positionalParameters = new List<DartType>(totalPositional);
-    for (int i = 0; i < totalPositional; i++) {
-      if (i < f.positionalParameters.length) {
-        var fType = f.positionalParameters[i];
-        if (i < g.positionalParameters.length) {
-          var gType = g.positionalParameters[i];
-          positionalParameters[i] = getStandardUpperBound(fType, gType);
-        } else {
-          positionalParameters[i] = fType;
-        }
-      } else {
-        positionalParameters[i] = g.positionalParameters[i];
-      }
-    }
-
-    // Parameters that are required in both functions are required in the
-    // result.  Parameters that are optional or missing in either end up
-    // optional.
-    int requiredParameterCount =
-        math.min(f.requiredParameterCount, g.requiredParameterCount);
-    bool hasPositional = requiredParameterCount < totalPositional;
-
-    // Union the named parameters together.
-    List<NamedType> namedParameters = [];
-    {
-      int i = 0;
-      int j = 0;
-      while (true) {
-        if (i < f.namedParameters.length) {
-          if (j < g.namedParameters.length) {
-            var fName = f.namedParameters[i].name;
-            var gName = g.namedParameters[j].name;
-            int order = fName.compareTo(gName);
-            if (order < 0) {
-              namedParameters.add(f.namedParameters[i++]);
-            } else if (order > 0) {
-              namedParameters.add(g.namedParameters[j++]);
-            } else {
-              namedParameters.add(new NamedType(
-                  fName,
-                  getStandardUpperBound(f.namedParameters[i++].type,
-                      g.namedParameters[j++].type)));
-            }
-          } else {
-            namedParameters.addAll(f.namedParameters.skip(i));
-            break;
-          }
-        } else {
-          namedParameters.addAll(g.namedParameters.skip(j));
-          break;
-        }
-      }
-    }
-    bool hasNamed = namedParameters.isNotEmpty;
-
-    // Edge case. Dart does not support functions with both optional positional
-    // and named parameters. If we would synthesize that, give up.
-    if (hasPositional && hasNamed) return const BottomType();
-
-    // Calculate the SLB of the return type.
-    DartType returnType = getStandardLowerBound(f.returnType, g.returnType);
-    return new FunctionType(positionalParameters, returnType,
-        namedParameters: namedParameters,
-        requiredParameterCount: requiredParameterCount);
-  }
-
-  /// Compute the standard upper bound of function types [f] and [g].
-  ///
-  /// The rules for SUB on function types, informally, are pretty simple:
-  ///
-  /// - If the functions don't have the same number of required parameters,
-  ///   always return `Function`.
-  ///
-  /// - Discard any optional named or positional parameters the two types do not
-  ///   have in common.
-  ///
-  /// - Compute the SLB of each corresponding pair of parameter types, and the
-  ///   SUB of the return types.  Return a function type with those types.
-  DartType _functionStandardUpperBound(FunctionType f, FunctionType g) {
-    // TODO(rnystrom): Right now, this assumes f and g do not have any type
-    // parameters. Revisit that in the presence of generic methods.
-
-    // If F and G differ in their number of required parameters, then the
-    // standard upper bound of F and G is Function.
-    // TODO(paulberry): We could do better here, e.g.:
-    //   SUB(([int]) -> void, (int) -> void) = (int) -> void
-    if (f.requiredParameterCount != g.requiredParameterCount) {
-      return coreTypes.functionClass.rawType;
-    }
-    int requiredParameterCount = f.requiredParameterCount;
-
-    // Calculate the SLB of each corresponding pair of parameters.
-    // Ignore any extra optional positional parameters if one has more than the
-    // other.
-    int totalPositional =
-        math.min(f.positionalParameters.length, g.positionalParameters.length);
-    var positionalParameters = new List<DartType>(totalPositional);
-    for (int i = 0; i < totalPositional; i++) {
-      positionalParameters[i] = getStandardLowerBound(
-          f.positionalParameters[i], g.positionalParameters[i]);
-    }
-
-    // Intersect the named parameters.
-    List<NamedType> namedParameters = [];
-    {
-      int i = 0;
-      int j = 0;
-      while (true) {
-        if (i < f.namedParameters.length) {
-          if (j < g.namedParameters.length) {
-            var fName = f.namedParameters[i].name;
-            var gName = g.namedParameters[j].name;
-            int order = fName.compareTo(gName);
-            if (order < 0) {
-              i++;
-            } else if (order > 0) {
-              j++;
-            } else {
-              namedParameters.add(new NamedType(
-                  fName,
-                  getStandardLowerBound(f.namedParameters[i++].type,
-                      g.namedParameters[j++].type)));
-            }
-          } else {
-            break;
-          }
-        } else {
-          break;
-        }
-      }
-    }
-
-    // Calculate the SUB of the return type.
-    DartType returnType = getStandardUpperBound(f.returnType, g.returnType);
-    return new FunctionType(positionalParameters, returnType,
-        namedParameters: namedParameters,
-        requiredParameterCount: requiredParameterCount);
-  }
-
   DartType _inferTypeParameterFromAll(DartType typeFromContextInference,
       TypeConstraint constraint, DartType extendsConstraint) {
     // See if we already fixed this type from downwards inference.
@@ -708,105 +394,6 @@
     }
     return t;
   }
-
-  DartType _interfaceStandardUpperBound(
-      InterfaceType type1, InterfaceType type2) {
-    // This currently does not implement a very complete standard 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, then take the
-    //    pointwise standard upper bound of the type arguments.  This is again
-    //    the best result, except that the recursive calls may not return
-    //    the true standard 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).
-    // 3. Otherwise return the spec-defined standard upper bound.  This will
-    //    be an upper bound, might (or might not) be least, and might
-    //    (or might not) be a well-formed type.
-    if (isSubtypeOf(type1, type2)) {
-      return type2;
-    }
-    if (isSubtypeOf(type2, type1)) {
-      return type1;
-    }
-    if (type1 is InterfaceType &&
-        type2 is InterfaceType &&
-        identical(type1.classNode, type2.classNode)) {
-      List<DartType> tArgs1 = type1.typeArguments;
-      List<DartType> tArgs2 = type2.typeArguments;
-
-      assert(tArgs1.length == tArgs2.length);
-      List<DartType> tArgs = new List(tArgs1.length);
-      for (int i = 0; i < tArgs1.length; i++) {
-        tArgs[i] = getStandardUpperBound(tArgs1[i], tArgs2[i]);
-      }
-      return new InterfaceType(type1.classNode, tArgs);
-    }
-    return hierarchy.getLegacyLeastUpperBound(type1, type2);
-  }
-
-  DartType _typeParameterStandardUpperBound(DartType type1, DartType type2) {
-    // This currently just implements a simple standard upper bound to
-    // handle some common cases.  It also avoids some termination issues
-    // with the naive spec algorithm.  The standard upper bound of two types
-    // (at least one of which is a type parameter) is computed here as:
-    // 1. If either type is a supertype of the other, return it.
-    // 2. If the first type is a type parameter, replace it with its bound,
-    //    with recursive occurrences of itself replaced with Object.
-    //    The second part of this should ensure termination.  Informally,
-    //    each type variable instantiation in one of the arguments to the
-    //    standard upper bound algorithm now strictly reduces the number
-    //    of bound variables in scope in that argument position.
-    // 3. If the second type is a type parameter, do the symmetric operation
-    //    to #2.
-    //
-    // It's not immediately obvious why this is symmetric in the case that both
-    // of them are type parameters.  For #1, symmetry holds since subtype
-    // is antisymmetric.  For #2, it's clearly not symmetric if upper bounds of
-    // bottom are allowed.  Ignoring this (for various reasons, not least
-    // of which that there's no way to write it), there's an informal
-    // argument (that might even be right) that you will always either
-    // end up expanding both of them or else returning the same result no matter
-    // which order you expand them in.  A key observation is that
-    // identical(expand(type1), type2) => subtype(type1, type2)
-    // and hence the contra-positive.
-    //
-    // TODO(leafp): Think this through and figure out what's the right
-    // definition.  Be careful about termination.
-    //
-    // I suspect in general a reasonable algorithm is to expand the innermost
-    // type variable first.  Alternatively, you could probably choose to treat
-    // it as just an instance of the interface type upper bound problem, with
-    // the "inheritance" chain extended by the bounds placed on the variables.
-    if (isSubtypeOf(type1, type2)) {
-      return type2;
-    }
-    if (isSubtypeOf(type2, type1)) {
-      return type1;
-    }
-    if (type1 is TypeParameterType) {
-      // TODO(paulberry): Analyzer collapses simple bounds in one step, i.e. for
-      // C<T extends U, U extends List>, T gets resolved directly to List.  Do
-      // we need to replicate that behavior?
-      return getStandardUpperBound(
-          Substitution.fromMap({type1.parameter: objectType})
-              .substituteType(type1.parameter.bound),
-          type2);
-    } else if (type2 is TypeParameterType) {
-      return getStandardUpperBound(
-          type1,
-          Substitution.fromMap({type2.parameter: objectType})
-              .substituteType(type2.parameter.bound));
-    } else {
-      // We should only be called when at least one of the types is a
-      // TypeParameterType
-      assert(false);
-      return const DynamicType();
-    }
-  }
 }
 
 class TypeVariableEliminator extends Substitution {
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index 119006f..3b01015 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -1422,6 +1422,12 @@
   static const TokenType PERIOD_PERIOD_PERIOD = const TokenType(
       '...', 'PERIOD_PERIOD_PERIOD', NO_PRECEDENCE, PERIOD_PERIOD_PERIOD_TOKEN);
 
+  static const TokenType PERIOD_PERIOD_PERIOD_QUESTION = const TokenType(
+      '...?',
+      'PERIOD_PERIOD_PERIOD_QUESTION',
+      NO_PRECEDENCE,
+      PERIOD_PERIOD_PERIOD_QUESTION_TOKEN);
+
   static const TokenType AS = Keyword.AS;
 
   static const TokenType IS = Keyword.IS;
@@ -1513,6 +1519,7 @@
     TokenType.BACKPING,
     TokenType.BACKSLASH,
     TokenType.PERIOD_PERIOD_PERIOD,
+    TokenType.PERIOD_PERIOD_PERIOD_QUESTION,
 
     // TODO(danrubel): Should these be added to the "all" list?
     //TokenType.IS,
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 20e3338..9303b17 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -56,6 +56,7 @@
 ConstConstructorNonFinalField/example: Fail
 ConstConstructorRedirectionToNonConst/analyzerCode: Fail # The analyzer doesn't report this error.
 ConstConstructorWithNonConstSuper/example: Fail
+ConstEvalCircularity/example: Fail
 ConstEvalContext/analyzerCode: Fail # This is just used for displaying the context.
 ConstEvalContext/example: Fail # This is just used for displaying the context.
 ConstEvalDeferredLibrary/example: Fail
@@ -172,6 +173,13 @@
 FastaUsageLong/example: Fail
 FastaUsageShort/analyzerCode: Fail
 FastaUsageShort/example: Fail
+FfiFieldAnnotation/analyzerCode: Fail
+FfiFieldInitializer/analyzerCode: Fail
+FfiNotStatic/analyzerCode: Fail
+FfiStructAnnotation/analyzerCode: Fail
+FfiTypeInvalid/analyzerCode: Fail
+FfiTypeMismatch/analyzerCode: Fail
+FfiTypeUnsized/analyzerCode: Fail
 FieldInitializedOutsideDeclaringClass/script1: Fail
 FieldInitializerOutsideConstructor/script1: Fail
 FinalAndCovariant/script2: Fail
@@ -207,11 +215,13 @@
 InputFileNotFound/example: Fail
 IntegerLiteralIsOutOfRange/example: Fail
 InterpolationInUri/example: Fail
+IntersectionTypeAsTypeArgument/analyzerCode: Fail # Analyzer doesn't catch this error.
 InvalidBreakTarget/analyzerCode: Fail
 InvalidBreakTarget/example: Fail
 InvalidCastFunctionExpr/example: Fail
 InvalidCastLiteralList/example: Fail
 InvalidCastLiteralMap/example: Fail
+InvalidCastLiteralSet/example: Fail
 InvalidCastLocalFunction/example: Fail
 InvalidCastNewExpr/example: Fail
 InvalidCastStaticMethod/example: Fail
@@ -315,6 +325,7 @@
 SetLiteralTooManyTypeArguments/analyzerCode: Fail
 SetLiteralTooManyTypeArguments/example: Fail
 SetLiteralsNotSupported/analyzerCode: Fail
+SetLiteralsNotSupported/example: Fail
 SetOrMapLiteralTooManyTypeArguments/analyzerCode: Fail
 SetOrMapLiteralTooManyTypeArguments/example: Fail
 SetterNotFound/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index a885932..023e1d2 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -146,6 +146,10 @@
 ConstEvalFreeTypeParameter:
   template: "The type '#type' is not a constant because it depends on a type parameter, only instantiated types are allowed."
 
+ConstEvalCircularity:
+  template: "Constant expression depends on itself."
+  analyzerCode: RECURSIVE_COMPILE_TIME_CONSTANT
+
 NotConstantExpression:
   template: "#string is not a constant expression."
   analyzerCode: NOT_CONSTANT_EXPRESSION
@@ -1455,7 +1459,6 @@
 
 SetLiteralsNotSupported:
   template: "Set literals are not supported yet."
-  script: "var s = { 24 };"
 
 LoadLibraryTakesNoArguments:
   template: "'loadLibrary' takes no arguments."
@@ -2830,6 +2833,11 @@
   tip: "Change the type of the map literal or the context in which it is used."
   analyzerCode: INVALID_CAST_LITERAL_MAP
 
+InvalidCastLiteralSet:
+  template: "The set literal type '#type' isn't of expected type '#type2'."
+  tip: "Change the type of the set literal or the context in which it is used."
+  analyzerCode: INVALID_CAST_LITERAL_SET
+
 InvalidCastLocalFunction:
   template: "The local function has type '#type' that isn't of expected type '#type2'."
   tip: "Change the type of the function or the context in which it is used."
@@ -3002,7 +3010,9 @@
 InitializeFromDillUnknownProblem:
   template: |
     Tried to initialize from a previous compilation (#string), but couldn't.
-    Error message was '#string2'. This might be a bug.
+    Error message was '#string2'.
+    Stacktrace included '#string3'.
+    This might be a bug.
 
     The Dart team would greatly appreciate it if you would take a moment to report this problem at http://dartbug.com/new.
     If you are comfortable with it, it would improve the chances of fixing any bug if you included the file #uri in your error report, but be aware that this file includes your source code.
@@ -3015,7 +3025,9 @@
 InitializeFromDillUnknownProblemNoDump:
   template: |
     Tried to initialize from a previous compilation (#string), but couldn't.
-    Error message was '#string2'. This might be a bug.
+    Error message was '#string2'.
+    Stacktrace included '#string3'.
+    This might be a bug.
 
     The Dart team would greatly appreciate it if you would take a moment to report this problem at http://dartbug.com/new.
 
@@ -3317,6 +3329,15 @@
   template: "This is the type variable whose bound isn't conformed to."
   severity: CONTEXT
 
+IntersectionTypeAsTypeArgument:
+  template: "Can't infer a type for '#name', it can be either '#type' or '#type2'."
+  tip: "Try adding a type argument selecting one of the options."
+  script: |
+    class A {}
+    class B extends A {}
+    f<T>(T t) => null;
+    g<S>(S t) => t is B ? f(t) : null;
+
 InferredPackageUri:
   template: "Interpreting this as package URI, '#uri'."
   severity: WARNING
@@ -3386,3 +3407,57 @@
   template: "The class 'Object' can't use mixins."
   frontendInternal: true
   external: test/fasta/object_supertype_test.dart
+
+StaticAndInstanceConflict:
+  template: "This static member conflicts with an instance member."
+  script:
+    - |
+      class C {
+        set foo(value) {}
+        static get foo => 42;
+      }
+    - |
+      class C {
+        static set foo(value) {}
+        get foo => 42;
+      }
+  analyzerCode: CONFLICTING_STATIC_AND_INSTANCE
+
+StaticAndInstanceConflictCause:
+  template: "This is the instance member."
+  severity: CONTEXT
+
+FfiTypeMismatch:
+  # Used by dart:ffi
+  template: "Expected type '#type' to be '#type2', which is the Dart type corresponding to '#type3'."
+  external: test/ffi_test.dart
+
+FfiTypeInvalid:
+  # Used by dart:ffi
+  template: "Expected type '#type' to be a valid and instantiated subtype of 'NativeType'."
+  external: test/ffi_test.dart
+
+FfiTypeUnsized:
+  # Used by dart:ffi
+  template: "Method '#name' cannot be called on something of type '#type' as this type is unsized."
+  external: test/ffi_test.dart
+
+FfiFieldAnnotation:
+  # Used by dart:ffi
+  template: "Field '#name' requires exactly one annotation to declare its C++ type, which cannot be Void. dart:ffi structs (Pointer<Void>) cannot have regular Dart fields."
+  external: test/ffi_test.dart
+
+FfiNotStatic:
+  # Used by dart:ffi
+  template: "#name expects a static function as parameter. dart:ffi only supports calling static Dart functions from c."
+  external: test/ffi_test.dart
+
+FfiFieldInitializer:
+  # Used by dart:ffi
+  template: "Field '#name' is a dart:ffi Pointer to a struct field and therefore cannot be initialized before constructor execution."
+  external: test/ffi_test.dart
+
+FfiStructAnnotation:
+  # Used by dart:ffi
+  template: "Class '#name' is a dart:ffi Pointer but has no struct annotation. Only struct Pointers can have fields."
+  external: test/ffi_test.dart
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 86cecb5..4928c97 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,7 +1,7 @@
 name: front_end
 # Currently, front_end API is not stable and users should not
 # depend on semver semantics when depending on this package.
-version: 0.1.8
+version: 0.1.11
 author: Dart Team <misc@dartlang.org>
 description: Front end for compilation of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
@@ -11,14 +11,14 @@
   charcode: '^1.1.1'
   convert: '^2.0.1'
   crypto: '^2.0.2'
-  kernel: 0.3.8
+  kernel: 0.3.11
   meta: '^1.1.1'
   package_config: '^1.0.1'
   path: '^1.3.9'
   source_span: '^1.2.3'
   yaml: '^2.1.12'
 dev_dependencies:
-  analyzer: 0.34.1
+  analyzer: 0.35.1
   args: '>=0.13.0 <2.0.0'
   build_integration:
     path: ../build_integration
diff --git a/pkg/front_end/test/fasta/fast_legacy_test.dart b/pkg/front_end/test/fasta/fast_legacy_test.dart
new file mode 100644
index 0000000..60eb337
--- /dev/null
+++ b/pkg/front_end/test/fasta/fast_legacy_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.md file.
+
+library fasta.test.fast_legacy_test;
+
+import 'dart:async' show Future;
+
+import 'dart:io' show Platform;
+
+import 'testing/suite.dart';
+
+Future<FastaContext> createContext(
+    Chain suite, Map<String, String> environment) {
+  environment[ENABLE_FULL_COMPILE] = "";
+  environment[LEGACY_MODE] = "";
+  environment["skipVm"] = "true";
+  return FastaContext.create(suite, environment);
+}
+
+main([List<String> arguments = const []]) => runMe(arguments, createContext,
+    "../../testing.json", Platform.script.resolve("legacy_test.dart"));
diff --git a/pkg/front_end/test/fasta/fast_strong_test.dart b/pkg/front_end/test/fasta/fast_strong_test.dart
new file mode 100644
index 0000000..6c1464c
--- /dev/null
+++ b/pkg/front_end/test/fasta/fast_strong_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.md file.
+
+library fasta.test.fast_strong_test;
+
+import 'dart:async' show Future;
+
+import 'dart:io' show Platform;
+
+import 'testing/suite.dart';
+
+Future<FastaContext> createContext(
+    Chain suite, Map<String, String> environment) {
+  environment[ENABLE_FULL_COMPILE] = "";
+  environment["skipVm"] = "true";
+  return FastaContext.create(suite, environment);
+}
+
+main([List<String> arguments = const []]) => runMe(arguments, createContext,
+    "../../testing.json", Platform.script.resolve("strong_test.dart"));
diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
new file mode 100644
index 0000000..0da8a6c
--- /dev/null
+++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
@@ -0,0 +1,1088 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/fasta/messages.dart';
+import 'package:front_end/src/fasta/parser.dart';
+import 'package:front_end/src/fasta/parser/async_modifier.dart';
+import 'package:front_end/src/fasta/scanner.dart';
+import 'package:front_end/src/scanner/token.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(CollectionElementTest);
+    defineReflectiveTests(MapElementTest);
+  });
+}
+
+@reflectiveTest
+class CollectionElementTest {
+  test_closingBrace() {
+    parseEntry(
+      'before }',
+      [
+        'handleIdentifier  expression',
+        'handleNoTypeArguments }',
+        'handleNoArguments }',
+        'handleSend  }',
+      ],
+      errors: [error(codeExpectedIdentifier, 7, 1)],
+      expectAfter: '}',
+    );
+  }
+
+  test_comma() {
+    parseEntry(
+      'before ,',
+      [
+        'handleIdentifier  expression',
+        'handleNoTypeArguments ,',
+        'handleNoArguments ,',
+        'handleSend  ,',
+      ],
+      errors: [error(codeExpectedIdentifier, 7, 1)],
+      expectAfter: ',',
+    );
+  }
+
+  test_expression() {
+    parseEntry(
+      'before x',
+      [
+        'handleIdentifier x expression',
+        'handleNoTypeArguments ',
+        'handleNoArguments ',
+        'handleSend x ',
+      ],
+    );
+  }
+
+  test_for() {
+    parseEntry(
+      'before for (var i = 0; i < 10; ++i) 2',
+      [
+        'beginForControlFlow null for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration i var',
+        'handleIdentifier i localVariableDeclaration',
+        'beginInitializedIdentifier i',
+        'beginVariableInitializer =',
+        'handleLiteralInt 0',
+        'endVariableInitializer =',
+        'endInitializedIdentifier i',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration 0',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments <',
+        'handleNoArguments <',
+        'handleSend i <',
+        'beginBinaryExpression <',
+        'handleLiteralInt 10',
+        'endBinaryExpression <',
+        'handleExpressionStatement ;',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend i )',
+        'handleUnaryPrefixAssignmentExpression ++',
+        'handleForInitializerExpressionStatement for ( ; 1',
+        'handleLiteralInt 2',
+        'endForControlFlow 2',
+      ],
+    );
+  }
+
+  test_forForFor() {
+    parseEntry(
+      'before for (var i = 0; i < 10; ++i) for (x in y) for (var a in [6]) 2',
+      [
+        // for (var i = 0; i < 10; ++i)
+        'beginForControlFlow null for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration i var',
+        'handleIdentifier i localVariableDeclaration',
+        'beginInitializedIdentifier i',
+        'beginVariableInitializer =',
+        'handleLiteralInt 0',
+        'endVariableInitializer =',
+        'endInitializedIdentifier i',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration 0',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments <',
+        'handleNoArguments <',
+        'handleSend i <',
+        'beginBinaryExpression <',
+        'handleLiteralInt 10',
+        'endBinaryExpression <',
+        'handleExpressionStatement ;',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend i )',
+        'handleUnaryPrefixAssignmentExpression ++',
+        'handleForInitializerExpressionStatement for ( ; 1',
+        // nested for (x in y)
+        'beginForControlFlow null for',
+        'handleIdentifier x expression',
+        'handleNoTypeArguments in',
+        'handleNoArguments in',
+        'handleSend x in',
+        'handleForInitializerExpressionStatement x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        // nested for (var a in [6])
+        'beginForControlFlow null for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration a var',
+        'handleIdentifier a localVariableDeclaration',
+        'beginInitializedIdentifier a',
+        'handleNoVariableInitializer in',
+        'endInitializedIdentifier a',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration a',
+        'beginForInExpression [',
+        'handleNoTypeArguments [',
+        'handleLiteralInt 6',
+        'handleLiteralList 1, [, null, ]',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        // entry
+        'handleLiteralInt 2',
+        // end nested for
+        'endForInControlFlow 2',
+        // end nested for
+        'endForInControlFlow 2',
+        // end for
+        'endForControlFlow 2',
+      ],
+    );
+  }
+
+  test_forIfForElse() {
+    parseEntry(
+      'before await for (var x in y) if (a) for (b in c) 2 else 7',
+      [
+        // await for (var x in y)
+        'beginForControlFlow await for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration x var',
+        'handleIdentifier x localVariableDeclaration',
+        'beginInitializedIdentifier x',
+        'handleNoVariableInitializer in',
+        'endInitializedIdentifier x',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts await for ( in',
+        // nested if (a)
+        'beginIfControlFlow if',
+        'handleIdentifier a expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend a )',
+        'handleParenthesizedCondition (',
+        // nested for (b in c)
+        'beginForControlFlow null for',
+        'handleIdentifier b expression',
+        'handleNoTypeArguments in',
+        'handleNoArguments in',
+        'handleSend b in',
+        'handleForInitializerExpressionStatement b',
+        'beginForInExpression c',
+        'handleIdentifier c expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend c )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        // for-if-for-entry
+        'handleLiteralInt 2',
+        // end nested for
+        'endForInControlFlow 2',
+        // nested else
+        'handleElseControlFlow else',
+        // nested if-else-entry
+        'handleLiteralInt 7',
+        // end nested else
+        'endIfElseControlFlow 7',
+        // end for
+        'endForInControlFlow 7',
+      ],
+      inAsync: true,
+    );
+  }
+
+  test_forIn() {
+    parseEntry(
+      'before await for (var x in y) 2',
+      [
+        'beginForControlFlow await for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration x var',
+        'handleIdentifier x localVariableDeclaration',
+        'beginInitializedIdentifier x',
+        'handleNoVariableInitializer in',
+        'endInitializedIdentifier x',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts await for ( in',
+        'handleLiteralInt 2',
+        'endForInControlFlow 2',
+      ],
+      inAsync: true,
+    );
+  }
+
+  test_forInSpread() {
+    parseEntry(
+      'before for (var x in y) ...[2]',
+      [
+        'beginForControlFlow null for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration x var',
+        'handleIdentifier x localVariableDeclaration',
+        'beginInitializedIdentifier x',
+        'handleNoVariableInitializer in',
+        'endInitializedIdentifier x',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        'handleNoTypeArguments [',
+        'handleLiteralInt 2',
+        'handleLiteralList 1, [, null, ]',
+        'handleSpreadExpression ...',
+        'endForInControlFlow ]',
+      ],
+    );
+  }
+
+  test_forSpreadQ() {
+    parseEntry(
+      'before for (i = 0; i < 10; ++i) ...[2]',
+      [
+        'beginForControlFlow null for',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments =',
+        'handleNoArguments =',
+        'handleSend i =',
+        'handleLiteralInt 0',
+        'handleAssignmentExpression =',
+        'handleForInitializerExpressionStatement 0',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments <',
+        'handleNoArguments <',
+        'handleSend i <',
+        'beginBinaryExpression <',
+        'handleLiteralInt 10',
+        'endBinaryExpression <',
+        'handleExpressionStatement ;',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend i )',
+        'handleUnaryPrefixAssignmentExpression ++',
+        'handleForInitializerExpressionStatement for ( ; 1',
+        'handleNoTypeArguments [',
+        'handleLiteralInt 2',
+        'handleLiteralList 1, [, null, ]',
+        'handleSpreadExpression ...',
+        'endForControlFlow ]',
+      ],
+    );
+  }
+
+  test_if() {
+    parseEntry(
+      'before if (true) 2',
+      [
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        'handleLiteralInt 2',
+        'endIfControlFlow 2',
+      ],
+    );
+  }
+
+  test_ifElse() {
+    parseEntry(
+      'before if (true) 2 else 5',
+      [
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        'handleLiteralInt 2',
+        'handleElseControlFlow else',
+        'handleLiteralInt 5',
+        'endIfElseControlFlow 5',
+      ],
+    );
+  }
+
+  test_ifFor() {
+    parseEntry(
+      'before if (true) for (x in y) 2',
+      [
+        // if (true)
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        // nested for (x in y)
+        'beginForControlFlow null for',
+        'handleIdentifier x expression',
+        'handleNoTypeArguments in',
+        'handleNoArguments in',
+        'handleSend x in',
+        'handleForInitializerExpressionStatement x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        // if-for-entry
+        'handleLiteralInt 2',
+        // end nested for
+        'endForInControlFlow 2',
+        // end if
+        'endIfControlFlow 2',
+      ],
+    );
+  }
+
+  test_ifForElseIfFor() {
+    parseEntry(
+      'before if (true) for (a in b) 2 else if (c) for (d in e) 5',
+      [
+        // if (true)
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        // nested for (a in b)
+        'beginForControlFlow null for',
+        'handleIdentifier a expression',
+        'handleNoTypeArguments in',
+        'handleNoArguments in',
+        'handleSend a in',
+        'handleForInitializerExpressionStatement a',
+        'beginForInExpression b',
+        'handleIdentifier b expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend b )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        // if-for-entry
+        'handleLiteralInt 2',
+        // end nested for
+        'endForInControlFlow 2',
+        // else
+        'handleElseControlFlow else',
+        // nested if (c)
+        'beginIfControlFlow if',
+        'handleIdentifier c expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend c )',
+        'handleParenthesizedCondition (',
+        // nested for (d in e)
+        'beginForControlFlow null for',
+        'handleIdentifier d expression',
+        'handleNoTypeArguments in',
+        'handleNoArguments in',
+        'handleSend d in',
+        'handleForInitializerExpressionStatement d',
+        'beginForInExpression e',
+        'handleIdentifier e expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend e )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        // else-if-for-entry
+        'handleLiteralInt 5',
+        // end nested for
+        'endForInControlFlow 5',
+        // end nested if
+        'endIfControlFlow 5',
+        // end else
+        'endIfElseControlFlow 5',
+      ],
+    );
+  }
+
+  test_ifSpreadQ() {
+    parseEntry(
+      'before if (true) ...?[2]',
+      [
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        'handleNoTypeArguments [',
+        'handleLiteralInt 2',
+        'handleLiteralList 1, [, null, ]',
+        'handleSpreadExpression ...?',
+        'endIfControlFlow ]',
+      ],
+    );
+  }
+
+  test_ifElseSpreadQ() {
+    parseEntry(
+      'before if (true) ...?[2] else ... const {5}',
+      [
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        'handleNoTypeArguments [',
+        'handleLiteralInt 2',
+        'handleLiteralList 1, [, null, ]',
+        'handleSpreadExpression ...?',
+        'handleElseControlFlow else',
+        'beginConstLiteral {',
+        'handleNoTypeArguments {',
+        'handleLiteralInt 5',
+        'handleLiteralSet 1, {, const, }',
+        'endConstLiteral ',
+        'handleSpreadExpression ...',
+        'endIfElseControlFlow }',
+      ],
+    );
+  }
+
+  test_intLiteral() {
+    parseEntry('before 1', [
+      'handleLiteralInt 1',
+    ]);
+  }
+
+  test_spread() {
+    parseEntry('before ...[1]', [
+      'handleNoTypeArguments [',
+      'handleLiteralInt 1',
+      'handleLiteralList 1, [, null, ]',
+      'handleSpreadExpression ...',
+    ]);
+  }
+
+  test_spreadQ() {
+    parseEntry('before ...?[1]', [
+      'handleNoTypeArguments [',
+      'handleLiteralInt 1',
+      'handleLiteralList 1, [, null, ]',
+      'handleSpreadExpression ...?',
+    ]);
+  }
+
+  void parseEntry(String source, List<String> expectedCalls,
+      {bool inAsync, List<ExpectedError> errors, String expectAfter}) {
+    final start = scanString(source).tokens;
+    final listener = new TestInfoListener();
+    final parser = new Parser(listener);
+    if (inAsync != null) parser.asyncState = AsyncModifier.Async;
+    final lastConsumed = parser.parseListOrSetLiteralEntry(start);
+
+    expect(listener.errors, errors);
+    try {
+      expect(listener.calls, expectedCalls, reason: source);
+    } catch (e) {
+      listener.calls.forEach((line) => print("  '$line',"));
+      throw e;
+    }
+    if (expectAfter != null) {
+      expect(lastConsumed.next.lexeme, expectAfter);
+    } else {
+      expect(lastConsumed.next.isEof, isTrue, reason: lastConsumed.lexeme);
+    }
+  }
+}
+
+@reflectiveTest
+class MapElementTest {
+  test_closingBrace() {
+    parseEntry(
+      'before }',
+      [
+        'handleIdentifier  expression',
+        'handleNoTypeArguments }',
+        'handleNoArguments }',
+        'handleSend  }',
+        'handleIdentifier  expression',
+        'handleNoTypeArguments }',
+        'handleNoArguments }',
+        'handleSend  }',
+        'handleLiteralMapEntry :, }',
+      ],
+      errors: [
+        error(codeExpectedIdentifier, 7, 1),
+        error(codeExpectedButGot, 7, 1),
+        error(codeExpectedIdentifier, 7, 1),
+      ],
+      expectAfter: '}',
+    );
+  }
+
+  test_comma() {
+    parseEntry(
+      'before ,',
+      [
+        'handleIdentifier  expression',
+        'handleNoTypeArguments ,',
+        'handleNoArguments ,',
+        'handleSend  ,',
+        'handleIdentifier  expression',
+        'handleNoTypeArguments ,',
+        'handleNoArguments ,',
+        'handleSend  ,',
+        'handleLiteralMapEntry :, ,',
+      ],
+      errors: [
+        error(codeExpectedIdentifier, 7, 1),
+        error(codeExpectedButGot, 7, 1),
+        error(codeExpectedIdentifier, 7, 1),
+      ],
+      expectAfter: ',',
+    );
+  }
+
+  test_expression() {
+    parseEntry(
+      'before x:y',
+      [
+        'handleIdentifier x expression',
+        'handleNoTypeArguments :',
+        'handleNoArguments :',
+        'handleSend x :',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments ',
+        'handleNoArguments ',
+        'handleSend y ',
+        'handleLiteralMapEntry :, ',
+      ],
+    );
+  }
+
+  test_for() {
+    parseEntry(
+      'before for (var i = 0; i < 10; ++i) 2:3',
+      [
+        'beginForControlFlow null for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration i var',
+        'handleIdentifier i localVariableDeclaration',
+        'beginInitializedIdentifier i',
+        'beginVariableInitializer =',
+        'handleLiteralInt 0',
+        'endVariableInitializer =',
+        'endInitializedIdentifier i',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration 0',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments <',
+        'handleNoArguments <',
+        'handleSend i <',
+        'beginBinaryExpression <',
+        'handleLiteralInt 10',
+        'endBinaryExpression <',
+        'handleExpressionStatement ;',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend i )',
+        'handleUnaryPrefixAssignmentExpression ++',
+        'handleForInitializerExpressionStatement for ( ; 1',
+        'handleLiteralInt 2',
+        'handleLiteralInt 3',
+        'handleLiteralMapEntry :, ',
+        'endForControlFlow 3',
+      ],
+    );
+  }
+
+  test_forIn() {
+    parseEntry(
+      'before await for (var x in y) 2:3',
+      [
+        'beginForControlFlow await for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration x var',
+        'handleIdentifier x localVariableDeclaration',
+        'beginInitializedIdentifier x',
+        'handleNoVariableInitializer in',
+        'endInitializedIdentifier x',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts await for ( in',
+        'handleLiteralInt 2',
+        'handleLiteralInt 3',
+        'handleLiteralMapEntry :, ',
+        'endForInControlFlow 3',
+      ],
+      inAsync: true,
+    );
+  }
+
+  test_forInSpread() {
+    parseEntry(
+      'before for (var x in y) ...{2:3}',
+      [
+        'beginForControlFlow null for',
+        'beginMetadataStar var',
+        'endMetadataStar 0',
+        'handleNoTypeArguments var',
+        'beginVariablesDeclaration x var',
+        'handleIdentifier x localVariableDeclaration',
+        'beginInitializedIdentifier x',
+        'handleNoVariableInitializer in',
+        'endInitializedIdentifier x',
+        'endVariablesDeclaration 1 null',
+        'handleForInitializerLocalVariableDeclaration x',
+        'beginForInExpression y',
+        'handleIdentifier y expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend y )',
+        'endForInExpression )',
+        'handleForInLoopParts null for ( in',
+        'handleNoTypeArguments {',
+        'handleLiteralInt 2',
+        'handleLiteralInt 3',
+        'handleLiteralMapEntry :, }',
+        'handleLiteralMap 1, {, null, }',
+        'handleSpreadExpression ...',
+        'endForInControlFlow }',
+      ],
+    );
+  }
+
+  test_forSpreadQ() {
+    parseEntry(
+      'before for (i = 0; i < 10; ++i) ...?{2:7}',
+      [
+        'beginForControlFlow null for',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments =',
+        'handleNoArguments =',
+        'handleSend i =',
+        'handleLiteralInt 0',
+        'handleAssignmentExpression =',
+        'handleForInitializerExpressionStatement 0',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments <',
+        'handleNoArguments <',
+        'handleSend i <',
+        'beginBinaryExpression <',
+        'handleLiteralInt 10',
+        'endBinaryExpression <',
+        'handleExpressionStatement ;',
+        'handleIdentifier i expression',
+        'handleNoTypeArguments )',
+        'handleNoArguments )',
+        'handleSend i )',
+        'handleUnaryPrefixAssignmentExpression ++',
+        'handleForInitializerExpressionStatement for ( ; 1',
+        'handleNoTypeArguments {',
+        'handleLiteralInt 2',
+        'handleLiteralInt 7',
+        'handleLiteralMapEntry :, }',
+        'handleLiteralMap 1, {, null, }',
+        'handleSpreadExpression ...?',
+        'endForControlFlow }',
+      ],
+    );
+  }
+
+  test_if() {
+    parseEntry(
+      'before if (true) 2:3',
+      [
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        'handleLiteralInt 2',
+        'handleLiteralInt 3',
+        'handleLiteralMapEntry :, ',
+        'endIfControlFlow 3',
+      ],
+    );
+  }
+
+  test_ifSpread() {
+    parseEntry(
+      'before if (true) ...{2:3}',
+      [
+        'beginIfControlFlow if',
+        'handleLiteralBool true',
+        'handleParenthesizedCondition (',
+        'handleNoTypeArguments {',
+        'handleLiteralInt 2',
+        'handleLiteralInt 3',
+        'handleLiteralMapEntry :, }',
+        'handleLiteralMap 1, {, null, }',
+        'handleSpreadExpression ...',
+        'endIfControlFlow }',
+      ],
+    );
+  }
+
+  test_intLiteral() {
+    parseEntry('before 1:2', [
+      'handleLiteralInt 1',
+      'handleLiteralInt 2',
+      'handleLiteralMapEntry :, ',
+    ]);
+  }
+
+  test_spread() {
+    parseEntry('before ...const {1:2}', [
+      'beginConstLiteral {',
+      'handleNoTypeArguments {',
+      'handleLiteralInt 1',
+      'handleLiteralInt 2',
+      'handleLiteralMapEntry :, }',
+      'handleLiteralMap 1, {, const, }',
+      'endConstLiteral ',
+      'handleSpreadExpression ...',
+    ]);
+  }
+
+  test_spreadQ() {
+    parseEntry('before ...?const {1:3}', [
+      'beginConstLiteral {',
+      'handleNoTypeArguments {',
+      'handleLiteralInt 1',
+      'handleLiteralInt 3',
+      'handleLiteralMapEntry :, }',
+      'handleLiteralMap 1, {, const, }',
+      'endConstLiteral ',
+      'handleSpreadExpression ...?',
+    ]);
+  }
+
+  void parseEntry(String source, List<String> expectedCalls,
+      {bool inAsync, List<ExpectedError> errors, String expectAfter}) {
+    final start = scanString(source).tokens;
+    final listener = new TestInfoListener();
+    final parser = new Parser(listener);
+    if (inAsync != null) parser.asyncState = AsyncModifier.Async;
+    final lastConsumed = parser.parseMapLiteralEntry(start);
+
+    expect(listener.errors, errors);
+    try {
+      expect(listener.calls, expectedCalls, reason: source);
+    } catch (e) {
+      listener.calls.forEach((line) => print("  '$line',"));
+      throw e;
+    }
+    if (expectAfter != null) {
+      expect(lastConsumed.next.lexeme, expectAfter);
+    } else {
+      expect(lastConsumed.next.isEof, isTrue, reason: lastConsumed.lexeme);
+    }
+  }
+}
+
+class TestInfoListener implements Listener {
+  List<String> calls = <String>[];
+  List<ExpectedError> errors;
+
+  @override
+  void beginBinaryExpression(Token token) {
+    calls.add('beginBinaryExpression $token');
+  }
+
+  @override
+  void beginConstLiteral(Token token) {
+    calls.add('beginConstLiteral $token');
+  }
+
+  @override
+  void beginForControlFlow(Token awaitToken, Token forToken) {
+    calls.add('beginForControlFlow $awaitToken $forToken');
+  }
+
+  @override
+  void beginForInExpression(Token token) {
+    calls.add('beginForInExpression $token');
+  }
+
+  @override
+  void beginIfControlFlow(Token ifToken) {
+    calls.add('beginIfControlFlow $ifToken');
+  }
+
+  @override
+  void beginInitializedIdentifier(Token token) {
+    calls.add('beginInitializedIdentifier $token');
+  }
+
+  @override
+  void beginMetadataStar(Token token) {
+    calls.add('beginMetadataStar $token');
+  }
+
+  @override
+  void beginVariablesDeclaration(Token token, Token varFinalOrConst) {
+    calls.add('beginVariablesDeclaration $token $varFinalOrConst');
+  }
+
+  @override
+  void beginVariableInitializer(Token token) {
+    calls.add('beginVariableInitializer $token');
+  }
+
+  @override
+  void endBinaryExpression(Token token) {
+    calls.add('endBinaryExpression $token');
+  }
+
+  @override
+  void endConstLiteral(Token token) {
+    calls.add('endConstLiteral $token');
+  }
+
+  @override
+  void endForControlFlow(Token token) {
+    calls.add('endForControlFlow $token');
+  }
+
+  @override
+  void endForInControlFlow(Token token) {
+    calls.add('endForInControlFlow $token');
+  }
+
+  @override
+  void endForInExpression(Token token) {
+    calls.add('endForInExpression $token');
+  }
+
+  @override
+  void endIfControlFlow(Token token) {
+    calls.add('endIfControlFlow $token');
+  }
+
+  @override
+  void endIfElseControlFlow(Token token) {
+    calls.add('endIfElseControlFlow $token');
+  }
+
+  @override
+  void endInitializedIdentifier(Token nameToken) {
+    calls.add('endInitializedIdentifier $nameToken');
+  }
+
+  @override
+  void endMetadataStar(int count) {
+    calls.add('endMetadataStar $count');
+  }
+
+  @override
+  void endVariablesDeclaration(int count, Token endToken) {
+    calls.add('endVariablesDeclaration $count $endToken');
+  }
+
+  @override
+  void endVariableInitializer(Token assignmentOperator) {
+    calls.add('endVariableInitializer $assignmentOperator');
+  }
+
+  @override
+  void handleAssignmentExpression(Token token) {
+    calls.add('handleAssignmentExpression $token');
+  }
+
+  @override
+  void handleElseControlFlow(Token elseToken) {
+    calls.add('handleElseControlFlow $elseToken');
+  }
+
+  @override
+  void handleExpressionStatement(Token token) {
+    calls.add('handleExpressionStatement $token');
+  }
+
+  @override
+  void handleForInitializerExpressionStatement(Token token) {
+    calls.add('handleForInitializerExpressionStatement $token');
+  }
+
+  @override
+  void handleForInitializerLocalVariableDeclaration(Token token) {
+    calls.add('handleForInitializerLocalVariableDeclaration $token');
+  }
+
+  @override
+  void handleForInLoopParts(Token awaitToken, Token forToken,
+      Token leftParenthesis, Token inKeyword) {
+    calls.add('handleForInLoopParts '
+        '$awaitToken $forToken $leftParenthesis $inKeyword');
+  }
+
+  @override
+  void handleForLoopParts(Token forKeyword, Token leftParen,
+      Token leftSeparator, int updateExpressionCount) {
+    calls.add('handleForInitializerExpressionStatement '
+        '$forKeyword $leftParen $leftSeparator $updateExpressionCount');
+  }
+
+  @override
+  void handleIdentifier(Token token, IdentifierContext context) {
+    calls.add('handleIdentifier $token $context');
+  }
+
+  @override
+  void handleLiteralBool(Token token) {
+    calls.add('handleLiteralBool $token');
+  }
+
+  @override
+  void handleLiteralInt(Token token) {
+    calls.add('handleLiteralInt $token');
+  }
+
+  @override
+  void handleLiteralList(
+      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
+    calls.add(
+        'handleLiteralList $count, $leftBracket, $constKeyword, $rightBracket');
+  }
+
+  @override
+  void handleLiteralMap(
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
+    calls
+        .add('handleLiteralMap $count, $leftBrace, $constKeyword, $rightBrace');
+  }
+
+  @override
+  void handleLiteralMapEntry(Token colon, Token endToken) {
+    calls.add('handleLiteralMapEntry $colon, $endToken');
+  }
+
+  @override
+  void handleLiteralSet(
+      int count, Token beginToken, Token constKeyword, Token token) {
+    calls.add('handleLiteralSet $count, $beginToken, $constKeyword, $token');
+  }
+
+  @override
+  void handleNoArguments(Token token) {
+    calls.add('handleNoArguments $token');
+  }
+
+  @override
+  void handleParenthesizedCondition(Token token) {
+    calls.add('handleParenthesizedCondition $token');
+  }
+
+  @override
+  void handleNoType(Token lastConsumed) {
+    calls.add('handleNoTypeArguments $lastConsumed');
+  }
+
+  @override
+  void handleNoTypeArguments(Token token) {
+    calls.add('handleNoTypeArguments $token');
+  }
+
+  @override
+  void handleNoVariableInitializer(Token token) {
+    calls.add('handleNoVariableInitializer $token');
+  }
+
+  @override
+  void handleRecoverableError(
+      Message message, Token startToken, Token endToken) {
+    errors ??= <ExpectedError>[];
+    int offset = startToken.charOffset;
+    errors.add(error(message.code, offset, endToken.charEnd - offset));
+  }
+
+  @override
+  void handleSend(Token beginToken, Token endToken) {
+    calls.add('handleSend $beginToken $endToken');
+  }
+
+  @override
+  void handleSpreadExpression(Token spreadToken) {
+    calls.add('handleSpreadExpression $spreadToken');
+  }
+
+  @override
+  void handleUnaryPrefixAssignmentExpression(Token token) {
+    calls.add('handleUnaryPrefixAssignmentExpression $token');
+  }
+
+  noSuchMethod(Invocation invocation) {
+    throw '${invocation.memberName} should not be called.';
+  }
+}
+
+ExpectedError error(Code code, int start, int length) =>
+    new ExpectedError(code, start, length);
+
+class ExpectedError {
+  final Code code;
+  final int start;
+  final int length;
+
+  ExpectedError(this.code, this.start, this.length);
+
+  @override
+  bool operator ==(other) =>
+      other is ExpectedError &&
+      code == other.code &&
+      start == other.start &&
+      length == other.length;
+
+  @override
+  String toString() => 'error(code${code.name}, $start, $length)';
+}
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index 2f13cfe..eced64d 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -140,7 +140,7 @@
     final TypeInfoListener listener = new TypeInfoListener();
 
     expect(noType.ensureTypeNotVoid(start, new Parser(listener)),
-        new isInstanceOf<SyntheticStringToken>());
+        const TypeMatcher<SyntheticStringToken>());
     expect(listener.calls, [
       'handleIdentifier  typeReference',
       'handleNoTypeArguments ;',
@@ -154,7 +154,7 @@
     final TypeInfoListener listener = new TypeInfoListener();
 
     expect(noType.ensureTypeOrVoid(start, new Parser(listener)),
-        new isInstanceOf<SyntheticStringToken>());
+        const TypeMatcher<SyntheticStringToken>());
     expect(listener.calls, [
       'handleIdentifier  typeReference',
       'handleNoTypeArguments ;',
@@ -2478,7 +2478,7 @@
 }
 
 void expectNestedComplexInfo(String source) {
-  expectNestedInfo(const isInstanceOf<ComplexTypeInfo>(), source);
+  expectNestedInfo(const TypeMatcher<ComplexTypeInfo>(), source);
 }
 
 TypeInfo compute(expectedInfo, String source, Token start, bool required,
@@ -2502,7 +2502,7 @@
     List<ExpectedError> expectedErrors) {
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   ComplexTypeInfo typeInfo = compute(
-      const isInstanceOf<ComplexTypeInfo>(), source, start, required,
+      const TypeMatcher<ComplexTypeInfo>(), source, start, required,
       inDeclaration: inDeclaration);
   expect(typeInfo.start, start.next, reason: source);
   expect(typeInfo.couldBeExpression, couldBeExpression);
@@ -2530,7 +2530,7 @@
   Token start = scan(source);
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
-      const isInstanceOf<ComplexTypeParamOrArgInfo>(),
+      const TypeMatcher<ComplexTypeParamOrArgInfo>(),
       source,
       start,
       inDeclaration);
@@ -2564,7 +2564,7 @@
   Token start = scan(source);
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
-      const isInstanceOf<ComplexTypeParamOrArgInfo>(),
+      const TypeMatcher<ComplexTypeParamOrArgInfo>(),
       source,
       start,
       inDeclaration);
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 2934b93..6689d9f 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -18,7 +18,8 @@
 
 import 'package:kernel/kernel.dart' show loadComponentFromBytes;
 
-import 'package:kernel/target/targets.dart' show TargetFlags;
+import 'package:kernel/target/targets.dart'
+    show TargetFlags, DiagnosticReporter;
 
 import 'package:testing/testing.dart'
     show
@@ -55,12 +56,19 @@
 
 import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
 
+import 'package:front_end/src/fasta/kernel/class_hierarchy_builder.dart'
+    show ClassHierarchyNode;
+
+import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
+    show ClassHierarchyBuilder;
+
 import 'package:front_end/src/fasta/kernel/kernel_target.dart'
     show KernelTarget;
 
 import 'package:front_end/src/fasta/testing/kernel_chain.dart'
     show
         KernelTextSerialization,
+        MatchContext,
         MatchExpectation,
         Print,
         TypeCheck,
@@ -111,28 +119,36 @@
 
 const String KERNEL_TEXT_SERIALIZATION = " kernel text serialization ";
 
+final Expectation runtimeError = ExpectationSet.Default["RuntimeError"];
+
 String generateExpectationName(bool legacyMode) {
   return legacyMode ? "legacy" : "strong";
 }
 
-class FastaContext extends ChainContext {
+class FastaContext extends ChainContext with MatchContext {
   final UriTranslator uriTranslator;
   final List<Step> steps;
   final Uri vm;
   final bool legacyMode;
   final bool onlyCrashes;
   final bool enableSetLiterals;
+  final bool skipVm;
   final Map<Component, KernelTarget> componentToTarget =
       <Component, KernelTarget>{};
   final Map<Component, StringBuffer> componentToDiagnostics =
       <Component, StringBuffer>{};
   final Uri platformBinaries;
-  Uri platformUri;
-  Component platform;
 
+  @override
+  final bool updateExpectations;
+
+  @override
   final ExpectationSet expectationSet =
       new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
-  Expectation verificationError;
+
+  Uri platformUri;
+
+  Component platform;
 
   FastaContext(
       this.vm,
@@ -141,9 +157,9 @@
       this.onlyCrashes,
       this.enableSetLiterals,
       bool ignoreExpectations,
-      bool updateExpectations,
+      this.updateExpectations,
       bool updateComments,
-      bool skipVm,
+      this.skipVm,
       bool kernelTextSerialization,
       this.uriTranslator,
       bool fullCompile)
@@ -152,13 +168,10 @@
           const Print(),
           new Verify(fullCompile)
         ] {
-    verificationError = expectationSet["VerificationError"];
     if (!ignoreExpectations) {
-      steps.add(new MatchExpectation(
-          fullCompile
-              ? ".${generateExpectationName(legacyMode)}.expect"
-              : ".outline.expect",
-          updateExpectations: updateExpectations));
+      steps.add(new MatchExpectation(fullCompile
+          ? ".${generateExpectationName(legacyMode)}.expect"
+          : ".outline.expect"));
     }
     if (!legacyMode) {
       steps.add(const TypeCheck());
@@ -167,21 +180,26 @@
     if (kernelTextSerialization) {
       steps.add(const KernelTextSerialization());
     }
-    if (fullCompile && !skipVm) {
+    if (legacyMode && !fullCompile) {
+      steps.add(new MatchHierarchy());
+    }
+    if (fullCompile) {
       steps.add(const Transform());
       if (!ignoreExpectations) {
-        steps.add(new MatchExpectation(
-            fullCompile
-                ? ".${generateExpectationName(legacyMode)}.transformed.expect"
-                : ".outline.transformed.expect",
-            updateExpectations: updateExpectations));
+        steps.add(new MatchExpectation(fullCompile
+            ? ".${generateExpectationName(legacyMode)}.transformed.expect"
+            : ".outline.transformed.expect"));
       }
       steps.add(const EnsureNoErrors());
-      steps.add(const WriteDill());
-      steps.add(const Run());
+      if (!skipVm) {
+        steps.add(const WriteDill());
+        steps.add(const Run());
+      }
     }
   }
 
+  Expectation get verificationError => expectationSet["VerificationError"];
+
   Future ensurePlatformUris() async {
     if (platformUri == null) {
       platformUri = platformBinaries
@@ -211,6 +229,15 @@
     return super.processTestResult(description, result, last);
   }
 
+  @override
+  Set<Expectation> processExpectedOutcomes(Set<Expectation> outcomes) {
+    if (skipVm && outcomes.length == 1 && outcomes.single == runtimeError) {
+      return new Set<Expectation>.from([Expectation.Pass]);
+    } else {
+      return outcomes;
+    }
+  }
+
   static Future<FastaContext> create(
       Chain suite, Map<String, String> environment) async {
     Uri sdk = Uri.base.resolve("sdk/");
@@ -331,7 +358,7 @@
       UriTranslator uriTranslator = new UriTranslator(
           const TargetLibrariesSpecification('vm'),
           context.uriTranslator.packages);
-      KernelTarget sourceTarget = new KernelTarget(
+      KernelTarget sourceTarget = new KernelTestingTarget(
           StandardFileSystem.instance, false, dillTarget, uriTranslator);
 
       sourceTarget.setEntryPoints(<Uri>[description.uri]);
@@ -397,12 +424,16 @@
   String get name => "vm";
 
   @override
-  void performModularTransformationsOnLibraries(Component component,
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+  void performModularTransformationsOnLibraries(
+      Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
       {void logger(String msg)}) {
     if (enabled) {
       super.performModularTransformationsOnLibraries(
-          component, coreTypes, hierarchy, libraries,
+          component, coreTypes, hierarchy, libraries, diagnosticReporter,
           logger: logger);
     }
   }
@@ -421,3 +452,32 @@
         : fail(component, """Unexpected errors:\n$buffer""");
   }
 }
+
+class KernelTestingTarget extends KernelTarget {
+  @override
+  ClassHierarchyBuilder builderHierarchy;
+
+  KernelTestingTarget(StandardFileSystem fileSystem, bool includeComments,
+      DillTarget dillTarget, UriTranslator uriTranslator)
+      : super(fileSystem, includeComments, dillTarget, uriTranslator);
+}
+
+class MatchHierarchy extends Step<Component, Component, FastaContext> {
+  const MatchHierarchy();
+
+  String get name => "check hierarchy";
+
+  Future<Result<Component>> run(
+      Component component, FastaContext context) async {
+    Uri uri =
+        component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
+    KernelTestingTarget target = context.componentToTarget[component];
+    ClassHierarchyBuilder hierarchy = target.builderHierarchy;
+    StringBuffer sb = new StringBuffer();
+    for (ClassHierarchyNode node in hierarchy.nodes.values) {
+      node.toString(sb);
+      sb.writeln();
+    }
+    return context.match<Component>(".hierarchy.expect", "$sb", uri, component);
+  }
+}
diff --git a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
index d34cb01..0b6ee37 100644
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
@@ -220,7 +220,7 @@
     var field = makeField();
     var class_ = makeClass(fields: [field]);
     var candidate = getCandidate(class_, false);
-    expect(candidate, new isInstanceOf<SyntheticAccessor>());
+    expect(candidate, const TypeMatcher<SyntheticAccessor>());
     expect(candidate.parent, same(class_));
     expect(candidate.name, field.name);
     expect(candidate.kind, ProcedureKind.Getter);
@@ -233,7 +233,7 @@
     var field = makeField();
     var class_ = makeClass(fields: [field]);
     var candidate = getCandidate(class_, true);
-    expect(candidate, new isInstanceOf<SyntheticAccessor>());
+    expect(candidate, const TypeMatcher<SyntheticAccessor>());
     expect(candidate.parent, same(class_));
     expect(candidate.name, field.name);
     expect(candidate.kind, ProcedureKind.Setter);
diff --git a/pkg/front_end/test/fasta/type_promotion_look_ahead_test.dart b/pkg/front_end/test/fasta/type_promotion_look_ahead_test.dart
index 9fe6f56..d4a75fb 100644
--- a/pkg/front_end/test/fasta/type_promotion_look_ahead_test.dart
+++ b/pkg/front_end/test/fasta/type_promotion_look_ahead_test.dart
@@ -4,8 +4,6 @@
 
 import 'dart:convert' show jsonDecode;
 
-import 'dart:io' show File, IOSink;
-
 import 'package:front_end/src/base/processed_options.dart'
     show ProcessedOptions;
 
@@ -29,7 +27,7 @@
         UnspecifiedDeclaration;
 
 import 'package:front_end/src/fasta/testing/kernel_chain.dart'
-    show openWrite, runDiff;
+    show MatchContext;
 
 import 'package:front_end/src/fasta/testing/scanner_chain.dart'
     show Read, Scan, ScannedFile;
@@ -64,7 +62,7 @@
       context, environment["updateExpectations"] == "true");
 }
 
-class TypePromotionLookAheadContext extends ChainContext {
+class TypePromotionLookAheadContext extends ChainContext with MatchContext {
   final CompilerContext context;
 
   final List<Step> steps = const <Step>[
@@ -80,12 +78,6 @@
       new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
 
   TypePromotionLookAheadContext(this.context, this.updateExpectations);
-
-  Expectation get expectationFileMismatch =>
-      expectationSet["ExpectationFileMismatch"];
-
-  Expectation get expectationFileMissing =>
-      expectationSet["ExpectationFileMissing"];
 }
 
 class TypePromotionLookAheadStep extends Step<ScannedFile, TypePromotionResult,
@@ -228,48 +220,9 @@
   String get name => "Check Type Promotion Result";
 
   Future<Result<Null>> run(
-      TypePromotionResult result, TypePromotionLookAheadContext context) async {
-    Uri uri = result.uri;
-    String actual = result.trace.trim();
-    if (actual.isNotEmpty) {
-      actual += "\n";
-    }
-    File expectedFile = new File("${uri.toFilePath()}.type_promotion.expect");
-    if (await expectedFile.exists()) {
-      String expected = await expectedFile.readAsString();
-      if (expected != actual) {
-        if (context.updateExpectations) {
-          return updateExpectationFile(expectedFile.uri, actual);
-        }
-        String diff = await runDiff(expectedFile.uri, actual);
-        return new Result<Null>(null, context.expectationFileMismatch,
-            "$uri doesn't match ${expectedFile.uri}\n$diff", null);
-      }
-      return pass(null);
-    } else {
-      if (actual.isEmpty) return pass(null);
-      if (context.updateExpectations) {
-        return updateExpectationFile(expectedFile.uri, actual);
-      }
-      return new Result<Null>(
-          null,
-          context.expectationFileMissing,
-          """
-Please create file ${expectedFile.path} with this content:
-$actual""",
-          null);
-    }
-  }
-
-  Future<Result<Null>> updateExpectationFile(Uri uri, String actual) async {
-    if (actual.isEmpty) {
-      await new File.fromUri(uri).delete();
-    } else {
-      await openWrite(uri, (IOSink sink) {
-        sink.write(actual);
-      });
-    }
-    return pass(null);
+      TypePromotionResult result, TypePromotionLookAheadContext context) {
+    return context.match<Null>(
+        ".type_promotion.expect", result.trace, result.uri, null);
   }
 }
 
diff --git a/pkg/front_end/test/fasta/types/fasta_types_test.dart b/pkg/front_end/test/fasta/types/fasta_types_test.dart
new file mode 100644
index 0000000..7f50ad6
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/fasta_types_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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" show asyncTest;
+
+import "package:kernel/ast.dart" show Component, DartType;
+
+import "package:kernel/core_types.dart" show CoreTypes;
+
+import "package:kernel/target/targets.dart" show NoneTarget, TargetFlags;
+
+import "package:front_end/src/api_prototype/compiler_options.dart"
+    show CompilerOptions;
+
+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/dill/dill_loader.dart" show DillLoader;
+
+import "package:front_end/src/fasta/dill/dill_target.dart" show DillTarget;
+
+import "package:front_end/src/fasta/kernel/kernel_builder.dart"
+    show ClassHierarchyBuilder, KernelClassBuilder;
+
+import "package:front_end/src/fasta/ticker.dart" show Ticker;
+
+import "kernel_type_parser.dart" show KernelEnvironment, KernelFromParsedType;
+
+import "kernel_type_parser_test.dart" show parseSdk;
+
+import "shared_type_tests.dart" show SubtypeTest;
+
+import "type_parser.dart" as type_parser show parse, parseTypeVariables;
+
+main() {
+  final Ticker ticker = Ticker();
+  final CompilerContext context = new CompilerContext(new ProcessedOptions(
+      options: new CompilerOptions()
+        ..packagesFileUri = Uri.base.resolve(".packages")));
+  final Uri uri = Uri.parse("dart:core");
+  final KernelEnvironment environment = new KernelEnvironment(uri, uri);
+  final Component sdk = parseSdk(uri, environment);
+  Future<void> doIt(_) async {
+    DillTarget target = new DillTarget(
+        ticker,
+        await context.options.getUriTranslator(),
+        new NoneTarget(new TargetFlags()));
+    final DillLoader loader = target.loader;
+    loader.appendLibraries(sdk);
+    await target.buildOutlines();
+    KernelClassBuilder objectClass = loader.coreLibrary["Object"];
+    ClassHierarchyBuilder hierarchy =
+        new ClassHierarchyBuilder(objectClass, loader, new CoreTypes(sdk));
+    new FastaTypesTest(hierarchy, environment).run();
+  }
+
+  asyncTest(() => context.runInContext<void>(doIt));
+}
+
+class FastaTypesTest extends SubtypeTest<DartType, KernelEnvironment> {
+  final ClassHierarchyBuilder hierarchy;
+
+  final KernelEnvironment environment;
+
+  FastaTypesTest(this.hierarchy, this.environment);
+
+  DartType toType(String text, KernelEnvironment environment) {
+    return environment.kernelFromParsedType(type_parser.parse(text).single);
+  }
+
+  bool isSubtypeImpl(DartType subtype, DartType supertype) {
+    return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+  }
+
+  KernelEnvironment extend(String typeParameters) {
+    if (typeParameters?.isEmpty ?? true) return environment;
+    return const KernelFromParsedType()
+        .computeTypeParameterEnvironment(
+            type_parser.parseTypeVariables("<$typeParameters>"), environment)
+        .environment;
+  }
+}
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser.dart b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
new file mode 100644
index 0000000..86f8a68
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser.dart
@@ -0,0 +1,297 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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"
+    show
+        BottomType,
+        Class,
+        DartType,
+        DynamicType,
+        FunctionType,
+        InterfaceType,
+        Library,
+        NamedType,
+        Node,
+        Supertype,
+        TreeNode,
+        TypeParameter,
+        TypeParameterType,
+        Typedef,
+        TypedefType,
+        VoidType,
+        setParents;
+
+import "package:kernel/src/bounds_checks.dart" show calculateBounds;
+
+import "type_parser.dart" as type_parser show parse;
+
+import "type_parser.dart"
+    show
+        ParsedClass,
+        ParsedIntersectionType,
+        ParsedFunctionType,
+        ParsedInterfaceType,
+        ParsedType,
+        ParsedTypeVariable,
+        ParsedTypedef,
+        ParsedVoidType,
+        Visitor;
+
+Library parseLibrary(Uri uri, String text,
+    {Uri fileUri, KernelEnvironment environment}) {
+  fileUri ??= uri;
+  environment ??= new KernelEnvironment(uri, fileUri);
+  Library library =
+      new Library(uri, fileUri: fileUri, name: uri.path.replaceAll("/", "."));
+  for (ParsedType type in type_parser.parse(text)) {
+    Node node = environment.kernelFromParsedType(type);
+    if (node is Class) {
+      library.addClass(node);
+    } else if (node is Typedef) {
+      library.addTypedef(node);
+    } else {
+      throw "Unsupported: $node";
+    }
+  }
+  return library;
+}
+
+class KernelEnvironment {
+  final Uri uri;
+
+  final Uri fileUri;
+
+  final Map<String, TreeNode> declarations = <String, TreeNode>{};
+
+  KernelEnvironment(this.uri, this.fileUri);
+
+  Node kernelFromParsedType(ParsedType type) {
+    Node node = type.accept(const KernelFromParsedType(), this);
+    return node;
+  }
+
+  bool isObject(String name) => name == "Object" && "$uri" == "dart:core";
+
+  Class get objectClass => this["Object"];
+
+  TreeNode operator [](String name) {
+    return declarations[name] ?? (throw "Not found: $name");
+  }
+
+  void operator []=(String name, TreeNode declaration) {
+    TreeNode existing = declarations[name];
+    if (existing != null) {
+      throw "Duplicated declaration: $name";
+    }
+    declarations[name] = declaration;
+  }
+
+  KernelEnvironment extend(Map<String, TreeNode> declarations) {
+    return new KernelEnvironment(uri, fileUri)
+      ..declarations.addAll(this.declarations)
+      ..declarations.addAll(declarations);
+  }
+}
+
+class KernelFromParsedType implements Visitor<Node, KernelEnvironment> {
+  const KernelFromParsedType();
+
+  DartType visitInterfaceType(
+      ParsedInterfaceType node, KernelEnvironment environment) {
+    String name = node.name;
+    if (name == "dynamic") {
+      // Don't return a const object to ensure we test implementations that use
+      // identical.
+      return new DynamicType();
+    } else if (name == "void") {
+      // Don't return a const object to ensure we test implementations that use
+      // identical.
+      return new VoidType();
+    } else if (name == "bottom") {
+      // Don't return a const object to ensure we test implementations that use
+      // identical.
+      return new BottomType();
+    }
+    TreeNode declaration = environment[name];
+    List<ParsedType> arguments = node.arguments;
+    List<DartType> kernelArguments =
+        new List<DartType>.filled(arguments.length, null);
+    for (int i = 0; i < arguments.length; i++) {
+      kernelArguments[i] =
+          arguments[i].accept<Node, KernelEnvironment>(this, environment);
+    }
+    if (declaration is Class) {
+      List<TypeParameter> typeVariables = declaration.typeParameters;
+      if (kernelArguments.isEmpty && typeVariables.isNotEmpty) {
+        kernelArguments = new List<DartType>.filled(typeVariables.length, null);
+        for (int i = 0; i < typeVariables.length; i++) {
+          kernelArguments[i] = typeVariables[i].defaultType;
+        }
+      } else if (kernelArguments.length != typeVariables.length) {
+        throw "Expected ${typeVariables.length} type arguments: $node";
+      }
+      return new InterfaceType(declaration, kernelArguments);
+    } else if (declaration is TypeParameter) {
+      if (arguments.isNotEmpty) {
+        throw "Type variable can't have arguments (${node.name})";
+      }
+      return new TypeParameterType(declaration);
+    } else if (declaration is Typedef) {
+      return new TypedefType(declaration, kernelArguments);
+    } else {
+      throw "Unhandled ${declaration.runtimeType}";
+    }
+  }
+
+  Class visitClass(ParsedClass node, KernelEnvironment environment) {
+    String name = node.name;
+    Class cls =
+        environment[name] = new Class(fileUri: environment.fileUri, name: name);
+    ParameterEnvironment parameterEnvironment =
+        computeTypeParameterEnvironment(node.typeVariables, environment);
+    List<TypeParameter> parameters = parameterEnvironment.parameters;
+    setParents(parameters, cls);
+    cls.typeParameters.addAll(parameters);
+    {
+      KernelEnvironment environment = parameterEnvironment.environment;
+      InterfaceType type =
+          node.supertype?.accept<Node, KernelEnvironment>(this, environment);
+      if (type == null) {
+        if (!environment.isObject(name)) {
+          cls.supertype = environment.objectClass.asRawSupertype;
+        }
+      } else {
+        cls.supertype = toSupertype(type);
+      }
+      List<ParsedType> interfaces = node.interfaces;
+      for (int i = 0; i < interfaces.length; i++) {
+        cls.implementedTypes.add(toSupertype(
+            interfaces[i].accept<Node, KernelEnvironment>(this, environment)));
+      }
+    }
+    return cls;
+  }
+
+  Typedef visitTypedef(ParsedTypedef node, KernelEnvironment environment) {
+    String name = node.name;
+    Typedef def = environment[name] =
+        new Typedef(name, null, fileUri: environment.fileUri);
+    ParameterEnvironment parameterEnvironment =
+        computeTypeParameterEnvironment(node.typeVariables, environment);
+    def.typeParameters.addAll(parameterEnvironment.parameters);
+    DartType type;
+    {
+      KernelEnvironment environment = parameterEnvironment.environment;
+      type = node.type.accept<Node, KernelEnvironment>(this, environment);
+      if (type is FunctionType) {
+        FunctionType f = type;
+        type = new FunctionType(f.positionalParameters, f.returnType,
+            namedParameters: f.namedParameters,
+            typeParameters: f.typeParameters,
+            requiredParameterCount: f.requiredParameterCount,
+            typedefType: def.thisType);
+      }
+    }
+    return def..type = type;
+  }
+
+  FunctionType visitFunctionType(
+      ParsedFunctionType node, KernelEnvironment environment) {
+    ParameterEnvironment parameterEnvironment =
+        computeTypeParameterEnvironment(node.typeVariables, environment);
+    List<DartType> positionalParameters = <DartType>[];
+    List<NamedType> namedParameters = <NamedType>[];
+    DartType returnType;
+    {
+      KernelEnvironment environment = parameterEnvironment.environment;
+      returnType =
+          node.returnType?.accept<Node, KernelEnvironment>(this, environment);
+      for (ParsedType argument in node.arguments.required) {
+        positionalParameters
+            .add(argument.accept<Node, KernelEnvironment>(this, environment));
+      }
+      List<Object> optional = node.arguments.optional;
+      for (int i = 0; i < optional.length; i++) {
+        ParsedType parsedType = optional[i];
+        DartType type =
+            parsedType.accept<Node, KernelEnvironment>(this, environment);
+        if (node.arguments.optionalAreNamed) {
+          namedParameters.add(new NamedType(optional[++i], type));
+        } else {
+          positionalParameters.add(type);
+        }
+      }
+    }
+    namedParameters.sort();
+    return new FunctionType(positionalParameters, returnType,
+        namedParameters: namedParameters,
+        requiredParameterCount: node.arguments.required.length,
+        typeParameters: parameterEnvironment.parameters);
+  }
+
+  VoidType visitVoidType(ParsedVoidType node, KernelEnvironment environment) {
+    return const VoidType();
+  }
+
+  TypeParameter visitTypeVariable(
+      ParsedTypeVariable node, KernelEnvironment environment) {
+    throw "not implemented: $node";
+  }
+
+  TypeParameterType visitIntersectionType(
+      ParsedIntersectionType node, KernelEnvironment environment) {
+    TypeParameterType type =
+        node.a.accept<Node, KernelEnvironment>(this, environment);
+    DartType bound = node.b.accept<Node, KernelEnvironment>(this, environment);
+    return new TypeParameterType(type.parameter, bound);
+  }
+
+  Supertype toSupertype(InterfaceType type) {
+    return new Supertype.byReference(type.className, type.typeArguments);
+  }
+
+  ParameterEnvironment computeTypeParameterEnvironment(
+      List<ParsedTypeVariable> typeVariables, KernelEnvironment environment) {
+    List<TypeParameter> typeParameters =
+        new List<TypeParameter>.filled(typeVariables.length, null);
+    Map<String, TypeParameter> typeParametersByName = <String, TypeParameter>{};
+    for (int i = 0; i < typeVariables.length; i++) {
+      String name = typeVariables[i].name;
+      typeParametersByName[name] = typeParameters[i] = new TypeParameter(name);
+    }
+    KernelEnvironment nestedEnvironment =
+        environment.extend(typeParametersByName);
+    Class objectClass = environment.objectClass;
+    for (int i = 0; i < typeVariables.length; i++) {
+      ParsedType bound = typeVariables[i].bound;
+      TypeParameter typeParameter = typeParameters[i];
+      if (bound == null) {
+        typeParameter
+          ..bound = objectClass.rawType
+          ..defaultType = const DynamicType();
+      } else {
+        DartType type =
+            bound.accept<Node, KernelEnvironment>(this, nestedEnvironment);
+        typeParameter
+          ..bound = type
+          // The default type will be overridden below, but we need to set it
+          // so [calculateBounds] can destinquish between explicit and implicit
+          // bounds.
+          ..defaultType = type;
+      }
+    }
+    List<DartType> defaultTypes = calculateBounds(typeParameters, objectClass);
+    for (int i = 0; i < typeParameters.length; i++) {
+      typeParameters[i].defaultType = defaultTypes[i];
+    }
+    return new ParameterEnvironment(typeParameters, nestedEnvironment);
+  }
+}
+
+class ParameterEnvironment {
+  final List<TypeParameter> parameters;
+  final KernelEnvironment environment;
+
+  const ParameterEnvironment(this.parameters, this.environment);
+}
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
new file mode 100644
index 0000000..ea220ac
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
@@ -0,0 +1,122 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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" show Expect;
+
+import "package:kernel/ast.dart" show Component, DartType, Library;
+
+import "package:kernel/class_hierarchy.dart" show ClassHierarchy;
+
+import "package:kernel/core_types.dart" show CoreTypes;
+
+import "package:kernel/text/ast_to_text.dart" show Printer;
+
+import "package:kernel/type_environment.dart" show TypeEnvironment;
+
+import "kernel_type_parser.dart"
+    show KernelEnvironment, KernelFromParsedType, parseLibrary;
+
+import "shared_type_tests.dart" show SubtypeTest;
+
+import "type_parser.dart" as type_parser show parse, parseTypeVariables;
+
+const String testSdk = """
+class Object;
+class Comparable<T>;
+class num implements Comparable<num>;
+class int extends num;
+class double extends num;
+class Iterable<T>;
+class List<T> extends Iterable<T>;
+class Future<T>;
+class FutureOr<T>;
+class Null;
+class Function;
+typedef Typedef<T> <S>(T) -> S;
+typedef VoidFunction () -> void;
+class DefaultTypes<S, T extends Object, U extends List<S>, V extends List<T>, W extends Comparable<W>, X extends (W) -> void, Y extends () -> W>;
+typedef TestDefaultTypes () -> DefaultTypes;
+typedef Id<T> T;
+typedef TestSorting ({int c, int b, int a}) -> void;
+""";
+
+const String expectedSdk = """
+library core;
+import self as self;
+
+typedef Typedef<T extends self::Object = dynamic> = <S extends self::Object = dynamic>(T) → S;
+typedef VoidFunction = () → void;
+typedef TestDefaultTypes = () → self::DefaultTypes<dynamic, self::Object, self::List<dynamic>, self::List<self::Object>, self::Comparable<dynamic>, (<BottomType>) → void, () → self::Comparable<dynamic>>;
+typedef Id<T extends self::Object = dynamic> = T;
+typedef TestSorting = ({a: self::int, b: self::int, c: self::int}) → void;
+class Object {
+}
+class Comparable<T extends self::Object = dynamic> extends self::Object {
+}
+class num extends self::Object implements self::Comparable<self::num> {
+}
+class int extends self::num {
+}
+class double extends self::num {
+}
+class Iterable<T extends self::Object = dynamic> extends self::Object {
+}
+class List<T extends self::Object = dynamic> extends self::Iterable<self::List::T> {
+}
+class Future<T extends self::Object = dynamic> extends self::Object {
+}
+class FutureOr<T extends self::Object = dynamic> extends self::Object {
+}
+class Null extends self::Object {
+}
+class Function extends self::Object {
+}
+class DefaultTypes<S extends self::Object = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S> = self::List<dynamic>, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>, X extends (self::DefaultTypes::W) → void = (<BottomType>) → void, Y extends () → self::DefaultTypes::W = () → self::Comparable<dynamic>> extends self::Object {
+}
+""";
+
+Component parseSdk(Uri uri, KernelEnvironment environment) {
+  Library library = parseLibrary(uri, testSdk, environment: environment);
+  StringBuffer sb = new StringBuffer();
+  Printer printer = new Printer(sb);
+  printer.writeLibraryFile(library);
+  Expect.stringEquals(expectedSdk, "$sb");
+  return new Component(libraries: <Library>[library]);
+}
+
+main() {
+  Uri uri = Uri.parse("dart:core");
+  KernelEnvironment environment = new KernelEnvironment(uri, uri);
+  Component component = parseSdk(uri, environment);
+  ClassHierarchy hierarchy = new ClassHierarchy(component);
+  CoreTypes coreTypes = new CoreTypes(component);
+  new KernelSubtypeTest(coreTypes, hierarchy, environment).run();
+}
+
+class KernelSubtypeTest extends SubtypeTest<DartType, KernelEnvironment> {
+  final CoreTypes coreTypes;
+
+  final ClassHierarchy hierarchy;
+
+  final KernelEnvironment environment;
+
+  KernelSubtypeTest(this.coreTypes, this.hierarchy, this.environment);
+
+  DartType toType(String text, KernelEnvironment environment) {
+    return environment.kernelFromParsedType(type_parser.parse(text).single);
+  }
+
+  bool isSubtypeImpl(DartType subtype, DartType supertype) {
+    return new TypeEnvironment(coreTypes, hierarchy)
+        .isSubtypeOf(subtype, supertype);
+  }
+
+  KernelEnvironment extend(String typeParameters) {
+    if (typeParameters?.isEmpty ?? true) return environment;
+    return const KernelFromParsedType()
+        .computeTypeParameterEnvironment(
+            type_parser.parseTypeVariables("<$typeParameters>"), environment)
+        .environment;
+  }
+}
diff --git a/pkg/front_end/test/fasta/types/legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/legacy_upper_bound_test.dart
new file mode 100644
index 0000000..24b04d2
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/legacy_upper_bound_test.dart
@@ -0,0 +1,292 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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/matchers_lite.dart";
+
+import "package:kernel/ast.dart";
+import "package:kernel/class_hierarchy.dart";
+import "package:kernel/core_types.dart";
+import "package:kernel/testing/mock_sdk_component.dart";
+import "package:kernel/text/ast_to_text.dart";
+import "package:kernel/type_algebra.dart";
+
+main() {
+  new LegacyUpperBoundTest().test_getLegacyLeastUpperBound_expansive();
+
+  new LegacyUpperBoundTest().test_getLegacyLeastUpperBound_generic();
+
+  new LegacyUpperBoundTest().test_getLegacyLeastUpperBound_nonGeneric();
+}
+
+class LegacyUpperBoundTest {
+  final Component component = createMockSdkComponent();
+
+  CoreTypes coreTypes;
+
+  final Library library =
+      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');
+
+  ClassHierarchy _hierarchy;
+
+  LegacyUpperBoundTest() {
+    coreTypes = new CoreTypes(component);
+    library.parent = component;
+    component.libraries.add(library);
+  }
+
+  Class get objectClass => coreTypes.objectClass;
+
+  Supertype get objectSuper => coreTypes.objectClass.asThisSupertype;
+
+  ClassHierarchy get hierarchy {
+    return _hierarchy ??= createClassHierarchy(component);
+  }
+
+  Class addClass(Class c) {
+    if (_hierarchy != null) {
+      fail('The classs hierarchy has already been created.');
+    }
+    library.addClass(c);
+    return c;
+  }
+
+  /// Assert that the test [library] has the [expectedText] presentation.
+  /// The presentation is close, but not identical to the normal Kernel one.
+  void _assertTestLibraryText(String expectedText) {
+    _assertLibraryText(library, expectedText);
+  }
+
+  void _assertLibraryText(Library lib, String expectedText) {
+    StringBuffer sb = new StringBuffer();
+    Printer printer = new Printer(sb);
+    printer.writeLibraryFile(lib);
+
+    String actualText = sb.toString();
+
+    // Clean up the text a bit.
+    const oftenUsedPrefix = '''
+library test;
+import self as self;
+import "dart:core" as core;
+
+''';
+    if (actualText.startsWith(oftenUsedPrefix)) {
+      actualText = actualText.substring(oftenUsedPrefix.length);
+    }
+    actualText = actualText.replaceAll('{\n}', '{}');
+    actualText = actualText.replaceAll(' extends core::Object', '');
+
+    if (actualText != expectedText) {
+      print('-------- Actual --------');
+      print(actualText + '------------------------');
+    }
+
+    expect(actualText, expectedText);
+  }
+
+  ClassHierarchy createClassHierarchy(Component component) {
+    return new ClassHierarchy(component);
+  }
+
+  /// Add a new generic class with the given [name] and [typeParameterNames].
+  /// The [TypeParameterType]s corresponding to [typeParameterNames] are
+  /// passed to optional [extends_] and [implements_] callbacks.
+  Class addGenericClass(String name, List<String> typeParameterNames,
+      {Supertype extends_(List<DartType> typeParameterTypes),
+      List<Supertype> implements_(List<DartType> typeParameterTypes)}) {
+    var typeParameters = typeParameterNames
+        .map((name) => new TypeParameter(name, objectClass.rawType))
+        .toList();
+    var typeParameterTypes = typeParameters
+        .map((parameter) => new TypeParameterType(parameter))
+        .toList();
+    var supertype =
+        extends_ != null ? extends_(typeParameterTypes) : objectSuper;
+    var implementedTypes =
+        implements_ != null ? implements_(typeParameterTypes) : <Supertype>[];
+    return addClass(new Class(
+        name: name,
+        typeParameters: typeParameters,
+        supertype: supertype,
+        implementedTypes: implementedTypes));
+  }
+
+  /// Add a new class with the given [name] that extends `Object` and
+  /// [implements_] the given classes.
+  Class addImplementsClass(String name, List<Class> implements_) {
+    return addClass(new Class(
+        name: name,
+        supertype: objectSuper,
+        implementedTypes: implements_.map((c) => c.asThisSupertype).toList()));
+  }
+
+  /// Copy of the tests/language/least_upper_bound_expansive_test.dart test.
+  void test_getLegacyLeastUpperBound_expansive() {
+    var int = coreTypes.intClass.rawType;
+    var string = coreTypes.stringClass.rawType;
+
+    // class N<T> {}
+    var NT = new TypeParameter('T', objectClass.rawType);
+    var N = addClass(
+        new Class(name: 'N', typeParameters: [NT], supertype: objectSuper));
+
+    // class C1<T> extends N<N<C1<T>>> {}
+    Class C1;
+    {
+      var T = new TypeParameter('T', objectClass.rawType);
+      C1 = addClass(
+          new Class(name: 'C1', typeParameters: [T], supertype: objectSuper));
+      DartType C1_T = Substitution.fromMap({T: new TypeParameterType(T)})
+          .substituteType(C1.thisType);
+      DartType N_C1_T =
+          Substitution.fromMap({NT: C1_T}).substituteType(N.thisType);
+      Supertype N_N_C1_T = Substitution.fromMap({NT: N_C1_T})
+          .substituteSupertype(N.asThisSupertype);
+      C1.supertype = N_N_C1_T;
+    }
+
+    // class C2<T> extends N<N<C2<N<C2<T>>>>> {}
+    Class C2;
+    {
+      var T = new TypeParameter('T', objectClass.rawType);
+      C2 = addClass(
+          new Class(name: 'C2', typeParameters: [T], supertype: objectSuper));
+      DartType C2_T = Substitution.fromMap({T: new TypeParameterType(T)})
+          .substituteType(C2.thisType);
+      DartType N_C2_T =
+          Substitution.fromMap({NT: C2_T}).substituteType(N.thisType);
+      DartType C2_N_C2_T =
+          Substitution.fromMap({T: N_C2_T}).substituteType(C2.thisType);
+      DartType N_C2_N_C2_T =
+          Substitution.fromMap({NT: C2_N_C2_T}).substituteType(N.thisType);
+      Supertype N_N_C2_N_C2_T = Substitution.fromMap({NT: N_C2_N_C2_T})
+          .substituteSupertype(N.asThisSupertype);
+      C2.supertype = N_N_C2_N_C2_T;
+    }
+
+    _assertTestLibraryText('''
+class N<T> {}
+class C1<T> extends self::N<self::N<self::C1<self::C1::T>>> {}
+class C2<T> extends self::N<self::N<self::C2<self::N<self::C2<self::C2::T>>>>> {}
+''');
+
+    // The least upper bound of C1<int> and N<C1<String>> is Object since the
+    // supertypes are
+    //     {C1<int>, N<N<C1<int>>>, Object} for C1<int> and
+    //     {N<C1<String>>, Object} for N<C1<String>> and
+    // Object is the most specific type in the intersection of the supertypes.
+    expect(
+        hierarchy.getLegacyLeastUpperBound(
+            new InterfaceType(C1, [int]),
+            new InterfaceType(N, [
+              new InterfaceType(C1, [string])
+            ])),
+        objectClass.thisType);
+
+    // The least upper bound of C2<int> and N<C2<String>> is Object since the
+    // supertypes are
+    //     {C2<int>, N<N<C2<N<C2<int>>>>>, Object} for C2<int> and
+    //     {N<C2<String>>, Object} for N<C2<String>> and
+    // Object is the most specific type in the intersection of the supertypes.
+    expect(
+        hierarchy.getLegacyLeastUpperBound(
+            new InterfaceType(C2, [int]),
+            new InterfaceType(N, [
+              new InterfaceType(C2, [string])
+            ])),
+        objectClass.thisType);
+  }
+
+  void test_getLegacyLeastUpperBound_generic() {
+    var int = coreTypes.intClass.rawType;
+    var double = coreTypes.doubleClass.rawType;
+    var bool = coreTypes.boolClass.rawType;
+
+    var a = addGenericClass('A', []);
+    var b =
+        addGenericClass('B', ['T'], implements_: (_) => [a.asThisSupertype]);
+    var c =
+        addGenericClass('C', ['U'], implements_: (_) => [a.asThisSupertype]);
+    var d = addGenericClass('D', ['T', 'U'], implements_: (typeParameterTypes) {
+      var t = typeParameterTypes[0];
+      var u = typeParameterTypes[1];
+      return [
+        new Supertype(b, [t]),
+        new Supertype(c, [u])
+      ];
+    });
+    var e = addGenericClass('E', [],
+        implements_: (_) => [
+              new Supertype(d, [int, double])
+            ]);
+    var f = addGenericClass('F', [],
+        implements_: (_) => [
+              new Supertype(d, [int, bool])
+            ]);
+
+    _assertTestLibraryText('''
+class A {}
+class B<T> implements self::A {}
+class C<U> implements self::A {}
+class D<T, U> implements self::B<self::D::T>, self::C<self::D::U> {}
+class E implements self::D<core::int, core::double> {}
+class F implements self::D<core::int, core::bool> {}
+''');
+
+    expect(
+        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
+            new InterfaceType(d, [int, double])),
+        new InterfaceType(d, [int, double]));
+    expect(
+        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
+            new InterfaceType(d, [int, bool])),
+        new InterfaceType(b, [int]));
+    expect(
+        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
+            new InterfaceType(d, [bool, double])),
+        new InterfaceType(c, [double]));
+    expect(
+        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
+            new InterfaceType(d, [bool, int])),
+        a.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(e.rawType, f.rawType),
+        new InterfaceType(b, [int]));
+  }
+
+  void test_getLegacyLeastUpperBound_nonGeneric() {
+    var a = addImplementsClass('A', []);
+    var b = addImplementsClass('B', []);
+    var c = addImplementsClass('C', [a]);
+    var d = addImplementsClass('D', [a]);
+    var e = addImplementsClass('E', [a]);
+    var f = addImplementsClass('F', [c, d]);
+    var g = addImplementsClass('G', [c, d]);
+    var h = addImplementsClass('H', [c, d, e]);
+    var i = addImplementsClass('I', [c, d, e]);
+
+    _assertTestLibraryText('''
+class A {}
+class B {}
+class C implements self::A {}
+class D implements self::A {}
+class E implements self::A {}
+class F implements self::C, self::D {}
+class G implements self::C, self::D {}
+class H implements self::C, self::D, self::E {}
+class I implements self::C, self::D, self::E {}
+''');
+
+    expect(hierarchy.getLegacyLeastUpperBound(a.rawType, b.rawType),
+        objectClass.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(a.rawType, objectClass.rawType),
+        objectClass.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(objectClass.rawType, b.rawType),
+        objectClass.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(c.rawType, d.rawType), a.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(c.rawType, a.rawType), a.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(a.rawType, d.rawType), a.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(f.rawType, g.rawType), a.rawType);
+    expect(hierarchy.getLegacyLeastUpperBound(h.rawType, i.rawType), a.rawType);
+  }
+}
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
new file mode 100644
index 0000000..38093c4
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -0,0 +1,351 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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" show Expect;
+
+abstract class SubtypeTest<T, E> {
+  void isSubtype(String subtypeString, String supertypeString,
+      {String typeParameters}) {
+    E environment = extend(typeParameters);
+    T subtype = toType(subtypeString, environment);
+    T supertype = toType(supertypeString, environment);
+    Expect.isTrue(isSubtypeImpl(subtype, supertype),
+        "$subtypeString should be a subtype of $supertypeString.");
+  }
+
+  void isNotSubtype(String subtypeString, String supertypeString,
+      {String typeParameters}) {
+    E environment = extend(typeParameters);
+    T subtype = toType(subtypeString, environment);
+    T supertype = toType(supertypeString, environment);
+    Expect.isFalse(isSubtypeImpl(subtype, supertype),
+        "$subtypeString shouldn't be a subtype of $supertypeString.");
+  }
+
+  T toType(String text, E environment);
+
+  bool isSubtypeImpl(T subtype, T supertype);
+
+  E extend(String typeParameters);
+
+  void run() {
+    isSubtype('int', 'num');
+    isSubtype('int', 'Comparable<num>');
+    isSubtype('int', 'Comparable<Object>');
+    isSubtype('int', 'Object');
+    isSubtype('double', 'num');
+
+    isNotSubtype('int', 'double');
+    isNotSubtype('int', 'Comparable<int>');
+    isNotSubtype('int', 'Iterable<int>');
+    isNotSubtype('Comparable<int>', 'Iterable<int>');
+
+    isSubtype('List<int>', 'List<int>');
+    isSubtype('List<int>', 'Iterable<int>');
+    isSubtype('List<int>', 'List<num>');
+    isSubtype('List<int>', 'Iterable<num>');
+    isSubtype('List<int>', 'List<Object>');
+    isSubtype('List<int>', 'Iterable<Object>');
+    isSubtype('List<int>', 'Object');
+    isSubtype('List<int>', 'List<Comparable<Object>>');
+    isSubtype('List<int>', 'List<Comparable<num>>');
+    isSubtype('List<int>', 'List<Comparable<Comparable<num>>>');
+
+    isNotSubtype('List<int>', 'List<double>');
+    isNotSubtype('List<int>', 'Iterable<double>');
+    isNotSubtype('List<int>', 'Comparable<int>');
+    isNotSubtype('List<int>', 'List<Comparable<int>>');
+    isNotSubtype('List<int>', 'List<Comparable<Comparable<int>>>');
+
+    isSubtype('(num) -> num', '(int) -> num');
+    isSubtype('(num) -> int', '(num) -> num');
+    isSubtype('(num) -> int', '(int) -> num');
+    isNotSubtype('(int) -> int', '(num) -> num');
+    isSubtype('Null', '(int) -> num');
+
+    isSubtype('(num) -> (num) -> num', '(num) -> (int) -> num');
+    isNotSubtype('(num) -> (int) -> int', '(num) -> (num) -> num');
+
+    isSubtype('({num x}) -> num', '({int x}) -> num'); // named parameters
+    isSubtype('(num, {num x}) -> num', '(int, {int x}) -> num');
+    isSubtype('({num x}) -> int', '({num x}) -> num');
+    isNotSubtype('({int x}) -> int', '({num x}) -> num');
+
+    isSubtype('<E>(E) -> int', '<E>(E) -> num'); // type parameters
+    isSubtype('<E>(num) -> E', '<E>(int) -> E');
+    isSubtype('<E>(E,num) -> E', '<E>(E,int) -> E');
+    isNotSubtype('<E>(E,num) -> E', '<E>(E,E) -> E');
+
+    isSubtype('<E>(E) -> (E) -> E', '<F>(F) -> (F) -> F');
+    isSubtype('<E>(E, (int,E) -> E) -> E', '<E>(E, (int,E) -> E) -> E');
+    isSubtype('<E>(E, (int,E) -> E) -> E', '<E>(E, (num,E) -> E) -> E');
+    isNotSubtype('<E,F>(E) -> (F) -> E', '<E>(E) -> <F>(F) -> E');
+    isNotSubtype('<E,F>(E) -> (F) -> E', '<F,E>(E) -> (F) -> E');
+
+    isNotSubtype('<E>(E,num) -> E', '<E extends num>(E,E) -> E');
+    isNotSubtype('<E extends num>(E) -> int', '<E extends int>(E) -> int');
+    isNotSubtype('<E extends num>(E) -> E', '<E extends int>(E) -> E');
+    isNotSubtype('<E extends num>(int) -> E', '<E extends int>(int) -> E');
+    isSubtype('<E extends num>(E) -> E', '<F extends num>(F) -> num');
+    isSubtype('<E extends int>(E) -> E', '<F extends int>(F) -> num');
+    isSubtype('<E extends int>(E) -> E', '<F extends int>(F) -> int');
+    isNotSubtype('<E>(int) -> int', '(int) -> int');
+    isNotSubtype('<E,F>(int) -> int', '<E>(int) -> int');
+
+    isSubtype('<E extends List<E>>(E) -> E', '<F extends List<F>>(F) -> F');
+    isNotSubtype(
+        '<E extends Iterable<E>>(E) -> E', '<F extends List<F>>(F) -> F');
+    isNotSubtype('<E>(E,List<Object>) -> E', '<F extends List<F>>(F,F) -> F');
+    isNotSubtype(
+        '<E>(E,List<Object>) -> List<E>', '<F extends List<F>>(F,F) -> F');
+    isNotSubtype('<E>(E,List<Object>) -> int', '<F extends List<F>>(F,F) -> F');
+    isNotSubtype(
+        '<E>(E,List<Object>) -> E', '<F extends List<F>>(F,F) -> void');
+
+    isSubtype('int', 'FutureOr<int>');
+    isSubtype('int', 'FutureOr<num>');
+    isSubtype('Future<int>', 'FutureOr<int>');
+    isSubtype('Future<int>', 'FutureOr<num>');
+    isSubtype('Future<int>', 'FutureOr<Object>');
+    isSubtype('FutureOr<int>', 'FutureOr<int>');
+    isSubtype('FutureOr<int>', 'FutureOr<num>');
+    isSubtype('FutureOr<int>', 'Object');
+    isNotSubtype('int', 'FutureOr<double>');
+    isNotSubtype('FutureOr<double>', 'int');
+    isNotSubtype('FutureOr<int>', 'Future<num>');
+    isNotSubtype('FutureOr<int>', 'num');
+    isSubtype('Null', 'FutureOr<int>');
+    isSubtype('Null', 'Future<int>');
+
+    // T & B <: T & A if B <: A
+    isSubtype('T & int', 'T & int', typeParameters: 'T');
+    isSubtype('T & int', 'T & num', typeParameters: 'T');
+    isSubtype('T & num', 'T & num', typeParameters: 'T');
+    isNotSubtype('T & num', 'T & int', typeParameters: 'T');
+    isSubtype('Null', 'T & num', typeParameters: 'T');
+
+    // T & B <: T extends A if B <: A
+    // (Trivially satisfied since promoted bounds are always a isSubtype of the
+    // original bound)
+    isSubtype('T & int', 'T', typeParameters: 'T extends int');
+    isSubtype('T & int', 'T', typeParameters: 'T extends num');
+    isSubtype('T & num', 'T', typeParameters: 'T extends num');
+
+    // T extends B <: T & A if B <: A
+    isSubtype('T', 'T & int', typeParameters: 'T extends int');
+    isSubtype('T', 'T & num', typeParameters: 'T extends int');
+    isSubtype('T', 'T & num', typeParameters: 'T extends num');
+    isNotSubtype('T', 'T & int', typeParameters: 'T extends num');
+
+    // T extends A <: T extends A
+    isSubtype('T', 'T', typeParameters: 'T extends num');
+
+    // S & B <: A if B <: A, A is not S (or a promotion thereof)
+    isSubtype('S & int', 'int', typeParameters: 'S');
+    isSubtype('S & int', 'num', typeParameters: 'S');
+    isSubtype('S & num', 'num', typeParameters: 'S');
+    isNotSubtype('S & num', 'int', typeParameters: 'S');
+    isNotSubtype('S & num', 'T', typeParameters: 'S, T');
+    isNotSubtype('S & num', 'T & num', typeParameters: 'S, T');
+
+    // S extends B <: A if B <: A, A is not S (or a promotion thereof)
+    isSubtype('S', 'int', typeParameters: 'S extends int');
+    isSubtype('S', 'num', typeParameters: 'S extends int');
+    isSubtype('S', 'num', typeParameters: 'S extends num');
+    isNotSubtype('S', 'int', typeParameters: 'S extends num');
+    isNotSubtype('S', 'T', typeParameters: 'S extends num, T');
+    isNotSubtype('S', 'T & num', typeParameters: 'S extends num, T');
+
+    isNotSubtype('dynamic', 'int');
+    isNotSubtype('void', 'int');
+    isNotSubtype('() -> int', 'int');
+    isNotSubtype('Typedef<Object>', 'int');
+    isSubtype('() -> int', 'Function');
+    isSubtype('() -> int', 'Object');
+
+    isNotSubtype('Null', 'bottom');
+    isSubtype('Null', 'Object');
+    isSubtype('Null', 'void');
+    isSubtype('Null', 'dynamic');
+    isSubtype('Null', 'double');
+    isSubtype('Null', 'Comparable<Object>');
+    isSubtype('Null', 'Typedef<Object>');
+    isSubtype('Null', 'T', typeParameters: 'T');
+
+    isSubtype('Null', 'Null');
+    isSubtype('bottom', 'bottom');
+    isSubtype('Object', 'Object');
+    isSubtype('Object', 'dynamic');
+    isSubtype('Object', 'void');
+    isSubtype('dynamic', 'Object');
+    isSubtype('dynamic', 'dynamic');
+    isSubtype('dynamic', 'void');
+    isSubtype('void', 'Object');
+    isSubtype('void', 'dynamic');
+    isSubtype('void', 'void');
+
+    // Check that the top types are equivalent.
+    isSubtype('<S extends Object, T extends void>(S, T) -> void',
+        '<U extends dynamic, V extends Object>(U, V) -> void');
+
+    {
+      String f = '<T extends dynamic>() -> T';
+      String g = '<T extends Object>() -> T';
+      isSubtype(f, g);
+      isSubtype(g, f);
+    }
+
+    {
+      String h = '<T extends List<dynamic>>() -> T';
+      String i = '<T extends List<Object>>() -> T';
+      String j = '<T extends List<void>>() -> T';
+      isSubtype(h, i);
+      isSubtype(h, j);
+      isSubtype(i, h);
+      isSubtype(i, j);
+      isSubtype(j, h);
+      isSubtype(j, i);
+    }
+
+    isNotSubtype('dynamic', '() -> dynamic');
+    isNotSubtype('FutureOr<() -> void>', '() -> void');
+    isSubtype('T & () -> void', '() -> void', typeParameters: 'T');
+    isSubtype('T & () -> void', '() -> dynamic', typeParameters: 'T');
+    isSubtype('T & () -> void', '() -> Object', typeParameters: 'T');
+
+    isSubtype('T & (void) -> void', '(void) -> void', typeParameters: 'T');
+    isSubtype('T & (void) -> void', '(dynamic) -> dynamic',
+        typeParameters: 'T');
+    isSubtype('T & (void) -> void', '(Object) -> Object', typeParameters: 'T');
+
+    isSubtype('T & (void) -> void', '(void) -> void', typeParameters: 'T');
+    isSubtype('T & (void) -> void', '(Iterable<int>) -> dynamic',
+        typeParameters: 'T');
+    isSubtype('T & (void) -> void', '(int) -> Object', typeParameters: 'T');
+
+    isNotSubtype('T & (void) -> void', '(int) -> int', typeParameters: 'T');
+
+    isSubtype('T', '() -> void', typeParameters: 'T extends () -> void');
+    isNotSubtype('T', '() -> void', typeParameters: 'T');
+    isNotSubtype('Typedef<void>', '() -> void');
+    isSubtype('VoidFunction', '() -> void');
+    isNotSubtype(
+        'DefaultTypes<void, void, List<void>, List<void>, int, (int) -> void, () -> int>',
+        '() -> void');
+    isNotSubtype('void', '() -> void');
+
+    isNotSubtype('dynamic', 'T', typeParameters: 'T');
+    isNotSubtype('Iterable<T>', 'T', typeParameters: 'T');
+    isNotSubtype('() -> void', 'T', typeParameters: 'T');
+    isNotSubtype('FutureOr<T>', 'T', typeParameters: 'T');
+    isSubtype('Id<T>', 'T', typeParameters: 'T');
+    isNotSubtype('VoidFunction', 'T', typeParameters: 'T extends () -> void');
+    isNotSubtype('void', 'T', typeParameters: 'T extends void');
+
+    isSubtype('dynamic', 'Id<dynamic>');
+    isNotSubtype('dynamic', 'Id<int>');
+    isSubtype('() -> void', 'Id<() -> void>');
+    isNotSubtype('() -> void', 'Id<() -> int>');
+    isNotSubtype('FutureOr<() -> void>', 'Id<() -> void>');
+    isSubtype('FutureOr<() -> void>', 'Id<FutureOr<() -> void>>');
+    isSubtype('int', 'Id<int>');
+    isSubtype('T & () -> void', 'Id<() -> void>', typeParameters: 'T');
+    isSubtype('T & () -> void', 'Id<() -> dynamic>', typeParameters: 'T');
+    isSubtype('T & () -> void', 'Id<() -> Object>', typeParameters: 'T');
+
+    isSubtype('T & (void) -> void', 'Id<(void) -> void>', typeParameters: 'T');
+    isSubtype('T & (void) -> void', 'Id<(dynamic) -> dynamic>',
+        typeParameters: 'T');
+    isSubtype('T & (void) -> void', 'Id<(Object) -> Object>',
+        typeParameters: 'T');
+
+    isSubtype('T & (void) -> void', 'Id<(void) -> void>', typeParameters: 'T');
+    isSubtype('T & (void) -> void', 'Id<(Iterable<int>) -> dynamic>',
+        typeParameters: 'T');
+    isSubtype('T & (void) -> void', 'Id<(int) -> Object>', typeParameters: 'T');
+
+    isNotSubtype('T & (void) -> void', 'Id<(int) -> int>', typeParameters: 'T');
+
+    isSubtype('T', 'Id<T>', typeParameters: 'T');
+    isSubtype('T', 'Id<Object>', typeParameters: 'T');
+    isNotSubtype('T', 'Id<Comparable<int>>', typeParameters: 'T');
+    isSubtype('T', 'Id<Comparable<int>>',
+        typeParameters: 'T extends Comparable<int>');
+
+    isSubtype('Id<int>', 'Id<int>');
+    isSubtype('Id<int>', 'Id<Object>');
+    isNotSubtype('Id<Object>', 'Id<int>');
+    isSubtype('Id<() -> int>', 'Id<() -> int>');
+    isSubtype('Id<() -> int>', 'Id<() -> Object>');
+    isNotSubtype('Id<() -> Object>', 'Id<() -> int>');
+
+    isSubtype('void', 'Id<void>');
+    isNotSubtype('void', 'Id<Null>');
+
+    // The following function type tests are derived from
+    // ../../../../../tests/compiler/dart2js/model/subtype_test.dart.
+    isSubtype("() -> int", 'Function');
+    isNotSubtype('Function', "() -> int");
+
+    isSubtype("() -> dynamic", "() -> dynamic");
+    isSubtype("() -> dynamic", "() -> void");
+    isSubtype("() -> void", "() -> dynamic");
+
+    isSubtype("() -> int", "() -> void");
+    isNotSubtype("() -> void", "() -> int");
+    isSubtype("() -> void", "() -> void");
+    isSubtype("() -> int", "() -> int");
+    isSubtype("() -> int", "() -> Object");
+    isNotSubtype("() -> int", "() -> double");
+    isNotSubtype("() -> int", "(int) -> void");
+    isNotSubtype("() -> void", "(int) -> int");
+    isNotSubtype("() -> void", "(int) -> void");
+    isSubtype("(int) -> int", "(int) -> int");
+    isSubtype("(Object) -> int", "(int) -> Object");
+    isNotSubtype("(int) -> int", "(double) -> int");
+    isNotSubtype("() -> int", "(int) -> int");
+    isNotSubtype("(int) -> int", "(int, int) -> int");
+    isNotSubtype("(int, int) -> int", "(int) -> int");
+    isNotSubtype("(() -> void) -> void", "((int) -> void) -> void");
+    isNotSubtype("((int) -> void) -> void", "(() -> void) -> void");
+
+    // Optional positional parameters.
+    isSubtype("([int]) -> void", "() -> void");
+    isSubtype("([int]) -> void", "(int) -> void");
+    isNotSubtype("(int) -> void", "([int]) -> void");
+    isSubtype("([int]) -> void", "([int]) -> void");
+    isSubtype("([Object]) -> void", "([int]) -> void");
+    isNotSubtype("([int]) -> void", "([Object]) -> void");
+    isSubtype("(int, [int]) -> void", "(int) -> void");
+    isSubtype("(int, [int]) -> void", "(int, [int]) -> void");
+    isNotSubtype("(int) -> void", "([int]) -> void");
+    isSubtype("([int, int]) -> void", "(int) -> void");
+    isSubtype("([int, int]) -> void", "(int, [int]) -> void");
+    isNotSubtype("([int, int]) -> void", "(int, [int, int]) -> void");
+    isSubtype("([int, int, int]) -> void", "(int, [int, int]) -> void");
+    isNotSubtype("([int]) -> void", "(double) -> void");
+    isNotSubtype("([int]) -> void", "([int, int]) -> void");
+    isSubtype("([int, int]) -> void", "([int]) -> void");
+    isSubtype("([Object, int]) -> void", "([int]) -> void");
+
+    // Optional named parameters.
+    isSubtype("({int a}) -> void", "() -> void");
+    isNotSubtype("({int a}) -> void", "(int) -> void");
+    isNotSubtype("(int) -> void", "({int a}) -> void");
+    isSubtype("({int a}) -> void", "({int a}) -> void");
+    isNotSubtype("({int a}) -> void", "({int b}) -> void");
+    isSubtype("({Object a}) -> void", "({int a}) -> void");
+    isNotSubtype("({int a}) -> void", "({Object a}) -> void");
+    isSubtype("(int, {int a}) -> void", "(int, {int a}) -> void");
+    isNotSubtype("({int a}) -> void", "({double a}) -> void");
+    isNotSubtype("({int a}) -> void", "({int a, int b}) -> void");
+    isSubtype("({int a, int b}) -> void", "({int a}) -> void");
+    isSubtype("({int a, int b, int c}) -> void", "({int a, int c}) -> void");
+    isSubtype("({int c, int b, int a}) -> void", "({int a, int c}) -> void");
+    isSubtype("({int a, int b, int c}) -> void", "({int b, int c}) -> void");
+    isSubtype("({int c, int b, int a}) -> void", "({int b, int c}) -> void");
+    isSubtype("({int a, int b, int c}) -> void", "({int c}) -> void");
+    isSubtype("({int c, int b, int a}) -> void", "({int c}) -> void");
+  }
+}
diff --git a/pkg/front_end/test/fasta/types/type_parser.dart b/pkg/front_end/test/fasta/types/type_parser.dart
new file mode 100644
index 0000000..1e72c17
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/type_parser.dart
@@ -0,0 +1,470 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:front_end/src/fasta/scanner.dart" show scanString, Token;
+
+import "package:front_end/src/fasta/parser/type_info_impl.dart"
+    show splitCloser;
+
+abstract class ParsedType {
+  R accept<R, A>(Visitor<R, A> visitor, [A a]);
+}
+
+class ParsedInterfaceType extends ParsedType {
+  final String name;
+
+  final List<ParsedType> arguments;
+
+  ParsedInterfaceType(this.name, this.arguments);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write(name);
+    if (arguments.isNotEmpty) {
+      sb.write("<");
+      sb.writeAll(arguments, ", ");
+      sb.write(">");
+    }
+    return "$sb";
+  }
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitInterfaceType(this, a);
+  }
+}
+
+abstract class ParsedDeclaration extends ParsedType {
+  final String name;
+
+  ParsedDeclaration(this.name);
+}
+
+class ParsedClass extends ParsedDeclaration {
+  final List<ParsedTypeVariable> typeVariables;
+  final ParsedInterfaceType supertype;
+  final List<ParsedType> interfaces;
+  final ParsedFunctionType callableType;
+
+  ParsedClass(String name, this.typeVariables, this.supertype, this.interfaces,
+      this.callableType)
+      : super(name);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("class ");
+    sb.write(name);
+    if (typeVariables.isNotEmpty) {
+      sb.write("<");
+      sb.writeAll(typeVariables, ", ");
+      sb.write(">");
+    }
+    if (supertype != null) {
+      sb.write(" extends ");
+      sb.write(supertype);
+    }
+    if (interfaces.isNotEmpty) {
+      sb.write(" implements ");
+      sb.writeAll(interfaces, ", ");
+    }
+    if (callableType != null) {
+      sb.write("{\n  ");
+      sb.write(callableType);
+      sb.write("\n}");
+    } else {
+      sb.write(";");
+    }
+    return "$sb";
+  }
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitClass(this, a);
+  }
+}
+
+class ParsedTypedef extends ParsedDeclaration {
+  final List<ParsedTypeVariable> typeVariables;
+
+  final ParsedType type;
+
+  ParsedTypedef(String name, this.typeVariables, this.type) : super(name);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("typedef ");
+    sb.write(name);
+    if (typeVariables.isNotEmpty) {
+      sb.write("<");
+      sb.writeAll(typeVariables, ", ");
+      sb.write(">");
+    }
+    sb.write(" ");
+    sb.write(type);
+    return "$sb;";
+  }
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitTypedef(this, a);
+  }
+}
+
+class ParsedFunctionType extends ParsedType {
+  final List<ParsedTypeVariable> typeVariables;
+
+  final ParsedType returnType;
+
+  final ParsedArguments arguments;
+
+  ParsedFunctionType(this.typeVariables, this.returnType, this.arguments);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    if (typeVariables.isNotEmpty) {
+      sb.write("<");
+      sb.writeAll(typeVariables, ", ");
+      sb.write(">");
+    }
+    sb.write(arguments);
+    sb.write(" -> ");
+    sb.write(returnType);
+    return "$sb";
+  }
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitFunctionType(this, a);
+  }
+}
+
+class ParsedVoidType extends ParsedType {
+  String toString() => "void";
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitVoidType(this, a);
+  }
+}
+
+class ParsedTypeVariable extends ParsedType {
+  final String name;
+
+  final ParsedType bound;
+
+  ParsedTypeVariable(this.name, this.bound);
+
+  String toString() {
+    if (bound == null) return name;
+    StringBuffer sb = new StringBuffer();
+    sb.write(name);
+    sb.write(" extends ");
+    sb.write(bound);
+    return "$sb";
+  }
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitTypeVariable(this, a);
+  }
+}
+
+class ParsedIntersectionType extends ParsedType {
+  final ParsedType a;
+
+  final ParsedType b;
+
+  ParsedIntersectionType(this.a, this.b);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write(a);
+    sb.write(" & ");
+    sb.write(b);
+    return "$sb";
+  }
+
+  R accept<R, A>(Visitor<R, A> visitor, [A a]) {
+    return visitor.visitIntersectionType(this, a);
+  }
+}
+
+class ParsedArguments {
+  final List<ParsedType> required;
+  final List optional;
+  final bool optionalAreNamed;
+
+  ParsedArguments(this.required, this.optional, this.optionalAreNamed);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write("(");
+    sb.writeAll(required, ", ");
+    if (optional.isNotEmpty) {
+      if (required.isNotEmpty) {
+        sb.write(", ");
+      }
+      if (optionalAreNamed) {
+        sb.write("{");
+        for (int i = 0; i < optional.length; i += 2) {
+          if (i != 0) {
+            sb.write(", ");
+          }
+          sb.write(optional[i]);
+          sb.write(" ");
+          sb.write(optional[i + 1]);
+        }
+        sb.write("}");
+      } else {
+        sb.write("[");
+        sb.writeAll(optional, ", ");
+        sb.write("]");
+      }
+    }
+    sb.write(")");
+    return "$sb";
+  }
+}
+
+class Parser {
+  Token peek;
+
+  String source;
+
+  Parser(this.peek, this.source);
+
+  bool get atEof => peek.isEof;
+
+  void advance() {
+    peek = peek.next;
+  }
+
+  String computeLocation() {
+    return "${source.substring(0, peek.charOffset)}\n>>>"
+        "\n${source.substring(peek.charOffset)}";
+  }
+
+  void expect(String string) {
+    if (!identical(string, peek.stringValue)) {
+      throw "Expected '$string', but got '${peek.lexeme}'\n${computeLocation()}";
+    }
+    advance();
+  }
+
+  bool optional(String value) {
+    return identical(value, peek.stringValue);
+  }
+
+  bool optionalAdvance(String value) {
+    if (optional(value)) {
+      advance();
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  ParsedType parseType() {
+    if (optional("class")) return parseClass();
+    if (optional("typedef")) return parseTypedef();
+    ParsedType result;
+    do {
+      ParsedType type;
+      if (optional("(") || optional("<")) {
+        type = parseFunctionType();
+      } else if (optionalAdvance("void")) {
+        type = new ParsedInterfaceType("void", <ParsedType>[]);
+      } else {
+        String name = parseName();
+        List<ParsedType> arguments = <ParsedType>[];
+        if (optional("<")) {
+          advance();
+          arguments.add(parseType());
+          while (optional(",")) {
+            advance();
+            arguments.add(parseType());
+          }
+          peek = splitCloser(peek) ?? peek;
+          expect(">");
+        }
+        type = new ParsedInterfaceType(name, arguments);
+      }
+      if (result == null) {
+        result = type;
+      } else {
+        result = new ParsedIntersectionType(result, type);
+      }
+    } while (optionalAdvance("&"));
+    return result;
+  }
+
+  ParsedType parseReturnType() {
+    if (optionalAdvance("void")) return new ParsedVoidType();
+    return parseType();
+  }
+
+  ParsedFunctionType parseFunctionType() {
+    List<ParsedTypeVariable> typeVariables = parseTypeVariablesOpt();
+    ParsedArguments arguments = parseArguments();
+    expect("-");
+    expect(">");
+    ParsedType returnType = parseReturnType();
+    return new ParsedFunctionType(typeVariables, returnType, arguments);
+  }
+
+  String parseName() {
+    if (!peek.isIdentifier) {
+      throw "Expected a name, but got '${peek.stringValue}'\n${computeLocation()}";
+    }
+    String result = peek.lexeme;
+    advance();
+    return result;
+  }
+
+  ParsedArguments parseArguments() {
+    List<ParsedType> requiredArguments = <ParsedType>[];
+    List optionalArguments = [];
+    bool optionalAreNamed = false;
+    expect("(");
+    do {
+      if (optional(")")) break;
+      if (optionalAdvance("[")) {
+        do {
+          optionalArguments.add(parseType());
+        } while (optionalAdvance(","));
+        expect("]");
+        break;
+      } else if (optionalAdvance("{")) {
+        optionalAreNamed = true;
+        do {
+          optionalArguments.add(parseType());
+          optionalArguments.add(parseName());
+        } while (optionalAdvance(","));
+        expect("}");
+        break;
+      } else {
+        requiredArguments.add(parseType());
+      }
+    } while (optionalAdvance(","));
+    expect(")");
+    return new ParsedArguments(
+        requiredArguments, optionalArguments, optionalAreNamed);
+  }
+
+  List<ParsedTypeVariable> parseTypeVariablesOpt() {
+    List<ParsedTypeVariable> typeVariables = <ParsedTypeVariable>[];
+    if (optionalAdvance("<")) {
+      do {
+        typeVariables.add(parseTypeVariable());
+      } while (optionalAdvance(","));
+      peek = splitCloser(peek) ?? peek;
+      expect(">");
+    }
+    return typeVariables;
+  }
+
+  ParsedTypeVariable parseTypeVariable() {
+    String name = parseName();
+    ParsedType bound;
+    if (optionalAdvance("extends")) {
+      bound = parseType();
+    }
+    return new ParsedTypeVariable(name, bound);
+  }
+
+  ParsedClass parseClass() {
+    expect("class");
+    String name = parseName();
+    List<ParsedTypeVariable> typeVariables = parseTypeVariablesOpt();
+    ParsedType supertype;
+    if (optionalAdvance("extends")) {
+      supertype = parseType();
+    }
+    List<ParsedType> interfaces = <ParsedType>[];
+    if (optionalAdvance("implements")) {
+      do {
+        interfaces.add(parseType());
+      } while (optionalAdvance(","));
+    }
+    ParsedFunctionType callableType;
+    if (optionalAdvance("{")) {
+      callableType = parseFunctionType();
+      expect("}");
+    } else {
+      expect(";");
+    }
+    return new ParsedClass(
+        name, typeVariables, supertype, interfaces, callableType);
+  }
+
+  /// This parses a general typedef on this form:
+  ///
+  ///     typedef <name> <type-variables-opt> <type> ;
+  ///
+  /// This is unlike Dart typedef.
+  ParsedTypedef parseTypedef() {
+    expect("typedef");
+    String name = parseName();
+    List<ParsedTypeVariable> typeVariables = parseTypeVariablesOpt();
+    ParsedType type = parseType();
+    expect(";");
+    return new ParsedTypedef(name, typeVariables, type);
+  }
+}
+
+List<ParsedType> parse(String text) {
+  Parser parser = new Parser(scanString(text).tokens, text);
+  List<ParsedType> types = <ParsedType>[];
+  while (!parser.atEof) {
+    types.add(parser.parseType());
+  }
+  return types;
+}
+
+List<ParsedTypeVariable> parseTypeVariables(String text) {
+  Parser parser = new Parser(scanString(text).tokens, text);
+  List<ParsedType> result = parser.parseTypeVariablesOpt();
+  if (!parser.atEof) {
+    throw "Expected EOF, but got '${parser.peek.stringValue}'\n"
+        "${parser.computeLocation()}";
+  }
+  return result;
+}
+
+abstract class DefaultAction<R, A> {
+  R defaultAction(ParsedType node, A a);
+
+  static perform<R, A>(Visitor<R, A> visitor, ParsedType node, A a) {
+    if (visitor is DefaultAction<R, A>) {
+      DefaultAction<R, A> defaultAction = visitor as DefaultAction<R, A>;
+      return defaultAction.defaultAction(node, a);
+    } else {
+      return null;
+    }
+  }
+}
+
+abstract class Visitor<R, A> {
+  R visitInterfaceType(ParsedInterfaceType node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+
+  R visitClass(ParsedClass node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+
+  R visitTypedef(ParsedTypedef node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+
+  R visitFunctionType(ParsedFunctionType node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+
+  R visitVoidType(ParsedVoidType node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+
+  R visitTypeVariable(ParsedTypeVariable node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+
+  R visitIntersectionType(ParsedIntersectionType node, A a) {
+    return DefaultAction.perform<R, A>(this, node, a);
+  }
+}
diff --git a/pkg/front_end/test/fasta/types/type_parser_test.dart b/pkg/front_end/test/fasta/types/type_parser_test.dart
new file mode 100644
index 0000000..8a0233d
--- /dev/null
+++ b/pkg/front_end/test/fasta/types/type_parser_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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" show Expect;
+
+import "type_parser.dart";
+
+testParse(String text) {
+  Expect.stringEquals(text.trim(), "${parse(text).join('\n')}");
+}
+
+main() {
+  testParse("""
+() -> void
+(int) -> dynamic
+([int]) -> int
+({double parameter}) -> int
+(num, [int]) -> int
+(num, {double parameter}) -> int
+class Object;
+class Comparable<T>;
+class num implements Comparable<num>;
+class int extends num;
+class double extends num;
+class Function;
+class Iterable<E>;
+class EfficientLength;
+class List<E> implements Iterable<E>, EfficientLength;
+class Intersection implements Comparable<int>, Comparable<double>;
+typedef OtherObject Object;
+typedef MyList<T> List<T>;
+typedef StringList List<String>;
+typedef VoidFunction () -> void;
+typedef GenericFunction<T> () -> T;
+List<List<Object>>
+List<List<List<Object>>>
+class A<T extends List<Object>>;
+class B<T extends List<List<Object>>>;
+<E>(E) -> int
+S & T
+class C;
+<E>(E) -> int & <E>(E) -> void
+""");
+}
diff --git a/pkg/front_end/test/ffi_test.dart b/pkg/front_end/test/ffi_test.dart
new file mode 100644
index 0000000..f032f75
--- /dev/null
+++ b/pkg/front_end/test/ffi_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+main() {
+  // TODO(dacoharkes): implement dart:ffi tests
+  Expect.isTrue(true);
+}
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index 0e1d3a8..682f362 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -25,11 +25,9 @@
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
 
-import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
-
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
-import 'package:kernel/kernel.dart' show Component;
+import 'package:kernel/kernel.dart' show Component, Library;
 
 import 'package:kernel/target/targets.dart' show TargetFlags;
 
@@ -44,6 +42,9 @@
 
 import "incremental_utils.dart" as util;
 
+import 'package:front_end/src/fasta/fasta_codes.dart'
+    show DiagnosticMessageFromJson, FormattedMessage;
+
 main([List<String> arguments = const []]) =>
     runMe(arguments, createContext, "../testing.json");
 
@@ -192,7 +193,8 @@
   final List<int> sdkSummaryData =
       await new File.fromUri(platformUri).readAsBytes();
 
-  List<int> newestWholeComponent;
+  List<int> newestWholeComponentData;
+  Component newestWholeComponent;
   MemoryFileSystem fs;
   Map<String, String> sourceFiles;
   CompilerOptions options;
@@ -208,8 +210,11 @@
     }
     fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryData);
     bool expectInitializeFromDill = false;
-    if (newestWholeComponent != null && newestWholeComponent.isNotEmpty) {
-      fs.entityForUri(initializeFrom).writeAsBytesSync(newestWholeComponent);
+    if (newestWholeComponentData != null &&
+        newestWholeComponentData.isNotEmpty) {
+      fs
+          .entityForUri(initializeFrom)
+          .writeAsBytesSync(newestWholeComponentData);
       expectInitializeFromDill = true;
     }
     if (world["expectInitializeFromDill"] != null) {
@@ -218,7 +223,8 @@
     if (brandNewWorld) {
       sourceFiles = new Map<String, String>.from(world["sources"]);
     } else {
-      sourceFiles.addAll(new Map<String, String>.from(world["sources"]));
+      sourceFiles.addAll(
+          new Map<String, String>.from(world["sources"] ?? <String, String>{}));
     }
     Uri packagesUri;
     for (String filename in sourceFiles.keys) {
@@ -240,23 +246,38 @@
       }
     }
     bool gotError = false;
-    final List<String> formattedErrors = <String>[];
+    final Set<String> formattedErrors = Set<String>();
     bool gotWarning = false;
-    final List<String> formattedWarnings = <String>[];
+    final Set<String> formattedWarnings = Set<String>();
 
     options.onDiagnostic = (DiagnosticMessage message) {
+      String stringId = message.ansiFormatted.join("\n");
+      if (message is FormattedMessage) {
+        stringId = message.toJsonString();
+      } else if (message is DiagnosticMessageFromJson) {
+        stringId = message.toJsonString();
+      }
       if (message.severity == Severity.error) {
         gotError = true;
-        formattedErrors.addAll(message.plainTextFormatted);
+        if (!formattedErrors.add(stringId)) {
+          Expect.fail("Got the same message twice: ${stringId}");
+        }
       } else if (message.severity == Severity.warning) {
         gotWarning = true;
-        formattedWarnings.addAll(message.plainTextFormatted);
+        if (!formattedWarnings.add(stringId)) {
+          Expect.fail("Got the same message twice: ${stringId}");
+        }
       }
     };
 
     Uri entry = base.resolve(world["entry"]);
     if (brandNewWorld) {
-      compiler = new TestIncrementalCompiler(options, entry, initializeFrom);
+      if (world["fromComponent"] == true) {
+        compiler = new TestIncrementalCompiler.fromComponent(
+            options, entry, newestWholeComponent);
+      } else {
+        compiler = new TestIncrementalCompiler(options, entry, initializeFrom);
+      }
     }
 
     List<Uri> invalidated = new List<Uri>();
@@ -275,15 +296,28 @@
         world, gotError, formattedErrors, gotWarning, formattedWarnings);
     util.throwOnEmptyMixinBodies(component);
     print("Compile took ${stopwatch.elapsedMilliseconds} ms");
-    newestWholeComponent = serializeComponent(component);
+    newestWholeComponentData = util.postProcess(component);
+    newestWholeComponent = component;
     print("*****\n\ncomponent:\n${componentToString(component)}\n\n\n");
-    if (component.libraries.length != world["expectedLibraryCount"]) {
-      throw "Expected ${world["expectedLibraryCount"]} libraries, "
-          "got ${component.libraries.length}";
+
+    int nonSyntheticLibraries = countNonSyntheticLibraries(component);
+    int syntheticLibraries = countSyntheticLibraries(component);
+    if (nonSyntheticLibraries != world["expectedLibraryCount"]) {
+      throw "Expected ${world["expectedLibraryCount"]} non-synthetic "
+          "libraries, got ${nonSyntheticLibraries}";
     }
-    if (component.libraries[0].importUri != entry) {
-      throw "Expected the first library to have uri $entry but was "
-          "${component.libraries[0].importUri}";
+    if (world["expectedSyntheticLibraryCount"] != null) {
+      if (syntheticLibraries != world["expectedSyntheticLibraryCount"]) {
+        throw "Expected ${world["expectedSyntheticLibraryCount"]} synthetic "
+            "libraries, got ${syntheticLibraries}";
+      }
+    }
+    List<Library> entryLib = component.libraries
+        .where((Library lib) => lib.importUri == entry || lib.fileUri == entry)
+        .toList();
+    if (entryLib.length != 1) {
+      throw "Expected the entry to become a library. Got ${entryLib.length} "
+          "libraries for it.";
     }
     if (compiler.initializedFromDill != expectInitializeFromDill) {
       throw "Expected that initializedFromDill would be "
@@ -307,6 +341,8 @@
     }
 
     {
+      Set<String> prevFormattedErrors = formattedErrors.toSet();
+      Set<String> prevFormattedWarnings = formattedWarnings.toSet();
       gotError = false;
       formattedErrors.clear();
       gotWarning = false;
@@ -314,19 +350,58 @@
       Component component2 = await compiler.computeDelta(fullComponent: true);
       performErrorAndWarningCheck(
           world, gotError, formattedErrors, gotWarning, formattedWarnings);
-      List<int> thisWholeComponent = serializeComponent(component2);
+      List<int> thisWholeComponent = util.postProcess(component2);
       print("*****\n\ncomponent2:\n${componentToString(component2)}\n\n\n");
-      checkIsEqual(newestWholeComponent, thisWholeComponent);
+      checkIsEqual(newestWholeComponentData, thisWholeComponent);
+      if (prevFormattedErrors.length != formattedErrors.length) {
+        Expect.fail("Previously had ${prevFormattedErrors.length} errors, "
+            "now had ${formattedErrors.length}.\n\n"
+            "Before:\n"
+            "${prevFormattedErrors.join("\n")}"
+            "\n\n"
+            "Now:\n"
+            "${formattedErrors.join("\n")}");
+      }
+      if ((prevFormattedErrors.toSet()..removeAll(formattedErrors))
+          .isNotEmpty) {
+        Expect.fail("Previously got error messages $prevFormattedErrors, "
+            "now had ${formattedErrors}.");
+      }
+      if (prevFormattedWarnings.length != formattedWarnings.length) {
+        Expect.fail("Previously had ${prevFormattedWarnings.length} errors, "
+            "now had ${formattedWarnings.length}.");
+      }
+      if ((prevFormattedWarnings.toSet()..removeAll(formattedWarnings))
+          .isNotEmpty) {
+        Expect.fail("Previously got error messages $prevFormattedWarnings, "
+            "now had ${formattedWarnings}.");
+      }
     }
   }
 }
 
+int countNonSyntheticLibraries(Component c) {
+  int result = 0;
+  for (Library lib in c.libraries) {
+    if (!lib.isSynthetic) result++;
+  }
+  return result;
+}
+
+int countSyntheticLibraries(Component c) {
+  int result = 0;
+  for (Library lib in c.libraries) {
+    if (lib.isSynthetic) result++;
+  }
+  return result;
+}
+
 void performErrorAndWarningCheck(
     YamlMap world,
     bool gotError,
-    List<String> formattedErrors,
+    Set<String> formattedErrors,
     bool gotWarning,
-    List<String> formattedWarnings) {
+    Set<String> formattedWarnings) {
   if (world["errors"] == true && !gotError) {
     throw "Expected error, but didn't get any.";
   } else if (world["errors"] != true && gotError) {
@@ -456,21 +531,23 @@
 
   /// Filter out the automatically added entryPoint, unless it's explicitly
   /// specified as being invalidated.
+  /// Also filter out uris with "nonexisting.dart" in the name as synthetic
+  /// libraries are invalidated automatically too.
   /// This is not perfect, but works for what it's currently used for.
   Set<Uri> getFilteredInvalidatedImportUrisForTesting(
       List<Uri> invalidatedUris) {
     if (invalidatedImportUrisForTesting == null) return null;
+
     Set<String> invalidatedFilenames =
         invalidatedUris.map((uri) => uri.pathSegments.last).toSet();
-    if (invalidatedFilenames.contains(entryPoint.pathSegments.last)) {
-      return invalidatedImportUrisForTesting;
-    }
-
     Set<Uri> result = new Set<Uri>();
     for (Uri uri in invalidatedImportUrisForTesting) {
-      if (invalidatedFilenames.contains(uri.pathSegments.last)) result.add(uri);
+      if (uri.pathSegments.last == "nonexisting.dart") continue;
+      if (invalidatedFilenames.contains(entryPoint.pathSegments.last) ||
+          invalidatedFilenames.contains(uri.pathSegments.last)) result.add(uri);
     }
-    return result;
+
+    return result.isEmpty ? null : result;
   }
 
   TestIncrementalCompiler(CompilerOptions options, this.entryPoint,
@@ -480,6 +557,13 @@
                 new ProcessedOptions(options: options, inputs: [entryPoint])),
             initializeFrom);
 
+  TestIncrementalCompiler.fromComponent(CompilerOptions options,
+      this.entryPoint, Component componentToInitializeFrom)
+      : super.fromComponent(
+            new CompilerContext(
+                new ProcessedOptions(options: options, inputs: [entryPoint])),
+            componentToInitializeFrom);
+
   @override
   void recordInvalidatedImportUrisForTesting(List<Uri> uris) {
     invalidatedImportUrisForTesting = uris.isEmpty ? null : uris.toSet();
diff --git a/pkg/front_end/test/memory_file_system_test.dart b/pkg/front_end/test/memory_file_system_test.dart
index 366d2a1..c62dbc3 100644
--- a/pkg/front_end/test/memory_file_system_test.dart
+++ b/pkg/front_end/test/memory_file_system_test.dart
@@ -25,8 +25,8 @@
   });
 }
 
-const Matcher _throwsFileSystemException =
-    const Throws(const isInstanceOf<FileSystemException>());
+final Matcher _throwsFileSystemException =
+    throwsA(const TypeMatcher<FileSystemException>());
 
 @reflectiveTest
 class FileTest extends _BaseTestNative {
@@ -233,7 +233,7 @@
     ]) {
       if (!uri.path.startsWith('/')) {
         expect(() => fileSystem.entityForUri(uri),
-            throwsA(new isInstanceOf<Error>()));
+            throwsA(const TypeMatcher<Error>()));
       }
     }
   }
diff --git a/pkg/front_end/test/messages_json_test.dart b/pkg/front_end/test/messages_json_test.dart
new file mode 100644
index 0000000..0756f80
--- /dev/null
+++ b/pkg/front_end/test/messages_json_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/api_prototype/diagnostic_message.dart'
+    show DiagnosticMessage, getMessageUri;
+
+import 'package:front_end/src/fasta/fasta_codes.dart'
+    show DiagnosticMessageFromJson, FormattedMessage, LocatedMessage;
+
+import 'package:front_end/src/fasta/severity.dart' show Severity;
+
+/// Test that turning a message into json and back again retains the wanted
+/// information.
+main() {
+  for (int i = 0; i < Severity.values.length; i++) {
+    Severity severity = Severity.values[i];
+    LocatedMessage locatedMessage1 =
+        new LocatedMessage(Uri.parse("what:ever/fun_1.dart"), 117, 2, null);
+    FormattedMessage formattedMessage2 = new FormattedMessage(
+        null, "Formatted string #2", 13, 2, Severity.error, []);
+    FormattedMessage formattedMessage3 = new FormattedMessage(
+        null, "Formatted string #3", 313, 32, Severity.error, []);
+
+    FormattedMessage formattedMessage1 = new FormattedMessage(
+        locatedMessage1,
+        "Formatted string",
+        42,
+        86,
+        severity,
+        [formattedMessage2, formattedMessage3]);
+
+    DiagnosticMessageFromJson diagnosticMessageFromJson =
+        new DiagnosticMessageFromJson.fromJson(
+            formattedMessage1.toJsonString());
+    compareMessages(formattedMessage1, diagnosticMessageFromJson);
+
+    DiagnosticMessageFromJson diagnosticMessageFromJson2 =
+        new DiagnosticMessageFromJson.fromJson(
+            diagnosticMessageFromJson.toJsonString());
+    compareMessages(diagnosticMessageFromJson, diagnosticMessageFromJson2);
+
+    expect(diagnosticMessageFromJson2.toJsonString(),
+        formattedMessage1.toJsonString());
+  }
+}
+
+void compareMessages(DiagnosticMessage a, DiagnosticMessage b) {
+  List<String> list1 = a.ansiFormatted.toList();
+  List<String> list2 = b.ansiFormatted.toList();
+  expect(list1.length, list2.length);
+  for (int i = 0; i < list1.length; i++) {
+    expect(list1[i], list2[i]);
+  }
+
+  list1 = a.plainTextFormatted.toList();
+  list2 = b.plainTextFormatted.toList();
+  expect(list1.length, list2.length);
+  for (int i = 0; i < list1.length; i++) {
+    expect(list1[i], list2[i]);
+  }
+
+  expect(a.severity, b.severity);
+  expect(getMessageUri(a), getMessageUri(b));
+}
+
+void expect(Object actual, Object expect) {
+  if (expect != actual) throw "Expected $expect got $actual";
+}
diff --git a/pkg/front_end/test/precedence_info_test.dart b/pkg/front_end/test/precedence_info_test.dart
index 3d6ee26..169f67c 100644
--- a/pkg/front_end/test/precedence_info_test.dart
+++ b/pkg/front_end/test/precedence_info_test.dart
@@ -28,7 +28,7 @@
     }
 
     for (TokenType type in TokenType.all) {
-      assertLexeme(type.value);
+      assertLexeme(type.lexeme);
     }
     assertLexeme('1.0'); // DOUBLE
     assertLexeme('0xA'); // HEXADECIMAL
@@ -357,6 +357,7 @@
     assertName('`', 'BACKPING');
     assertName('\\', 'BACKSLASH');
     assertName('...', 'PERIOD_PERIOD_PERIOD');
+    assertName('...?', 'PERIOD_PERIOD_PERIOD_QUESTION');
   }
 
   /// Assert precedence as per the Dart language spec
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index 4b68911..1305b34 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -324,6 +324,15 @@
     }
   }
 
+  void test_spread_operators() {
+    ErrorListener listener = new ErrorListener();
+    Token openBracket = scanWithListener('[ 1, ...[2], ...?[3], ]', listener);
+    Token spreadToken = openBracket.next.next.next;
+    expect(spreadToken.lexeme, '...');
+    Token spreadQToken = spreadToken.next.next.next.next.next;
+    expect(spreadQToken.lexeme, '...?');
+  }
+
   @override
   void test_unmatched_openers() {
     ErrorListener listener = new ErrorListener();
diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
index a9f0b70..aa227f1 100644
--- a/pkg/front_end/test/scanner_replacement_test.dart
+++ b/pkg/front_end/test/scanner_replacement_test.dart
@@ -242,7 +242,7 @@
         token = token.next;
       }
     }
-    var isNotErrorToken = isNot(new isInstanceOf<fasta.ErrorToken>());
+    var isNotErrorToken = isNot(const TypeMatcher<fasta.ErrorToken>());
     while (!token.isEof) {
       if (errorsFirst) expect(token, isNotErrorToken);
       previous = token;
diff --git a/pkg/front_end/test/scanner_test.dart b/pkg/front_end/test/scanner_test.dart
index 936ad38..67a212b 100644
--- a/pkg/front_end/test/scanner_test.dart
+++ b/pkg/front_end/test/scanner_test.dart
@@ -113,7 +113,7 @@
     if (lessThan is BeginToken) {
       expect(lessThan.endToken, greaterThan);
     }
-    expect(greaterThan, isNot(new isInstanceOf<BeginToken>()));
+    expect(greaterThan, isNot(const TypeMatcher<BeginToken>()));
   }
 
   void test_async_star() {
diff --git a/pkg/front_end/test/severity_index_test.dart b/pkg/front_end/test/severity_index_test.dart
new file mode 100644
index 0000000..3070f73
--- /dev/null
+++ b/pkg/front_end/test/severity_index_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.
+
+import 'package:front_end/src/fasta/severity.dart' show Severity;
+
+/// Test that Severity has the expected indexes. Note that this is important
+/// and shouldn't be changed lightly because we use it in serialization!
+main() {
+  expect(Severity.context.index, 0);
+  expect(Severity.error.index, 1);
+  expect(Severity.internalProblem.index, 4);
+  expect(Severity.warning.index, 5);
+
+  expect(Severity.values[0], Severity.context);
+  expect(Severity.values[1], Severity.error);
+  expect(Severity.values[4], Severity.internalProblem);
+  expect(Severity.values[5], Severity.warning);
+}
+
+void expect(Object actual, Object expect) {
+  if (expect != actual) throw "Expected $expect got $actual";
+}
diff --git a/pkg/front_end/test/standard_file_system_test.dart b/pkg/front_end/test/standard_file_system_test.dart
index bd67f3b..5644c98 100644
--- a/pkg/front_end/test/standard_file_system_test.dart
+++ b/pkg/front_end/test/standard_file_system_test.dart
@@ -25,8 +25,8 @@
   });
 }
 
-const Matcher _throwsFileSystemException =
-    const Throws(const isInstanceOf<FileSystemException>());
+final Matcher _throwsFileSystemException =
+    throwsA(const TypeMatcher<FileSystemException>());
 
 @reflectiveTest
 class DirectoryTest extends _BaseTest {
@@ -197,7 +197,7 @@
     ]) {
       if (!uri.path.startsWith('/')) {
         expect(() => StandardFileSystem.instance.entityForUri(uri),
-            throwsA(new isInstanceOf<Error>()));
+            throwsA(const TypeMatcher<Error>()));
       }
     }
   }
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index 4b39e62..686c789 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -46,22 +46,22 @@
     Token comment = nextComment();
     expect(comment.lexeme, contains('Single line dartdoc comment'));
     expect(comment.type, TokenType.SINGLE_LINE_COMMENT);
-    expect(comment, new isInstanceOf<DocumentationCommentToken>());
+    expect(comment, const TypeMatcher<DocumentationCommentToken>());
 
     comment = nextComment();
     expect(comment.lexeme, contains('Multi-line dartdoc comment'));
     expect(comment.type, TokenType.MULTI_LINE_COMMENT);
-    expect(comment, new isInstanceOf<DocumentationCommentToken>());
+    expect(comment, const TypeMatcher<DocumentationCommentToken>());
 
     comment = nextComment();
     expect(comment.lexeme, contains('Single line comment'));
     expect(comment.type, TokenType.SINGLE_LINE_COMMENT);
-    expect(comment, new isInstanceOf<CommentToken>());
+    expect(comment, const TypeMatcher<CommentToken>());
 
     comment = nextComment();
     expect(comment.lexeme, contains('Multi-line comment'));
     expect(comment.type, TokenType.MULTI_LINE_COMMENT);
-    expect(comment, new isInstanceOf<CommentToken>());
+    expect(comment, const TypeMatcher<CommentToken>());
   }
 
   void test_isSynthetic() {
diff --git a/pkg/front_end/testcases/DeltaBlue.dart.hierarchy.expect b/pkg/front_end/testcases/DeltaBlue.dart.hierarchy.expect
new file mode 100644
index 0000000..bdad7e9
--- /dev/null
+++ b/pkg/front_end/testcases/DeltaBlue.dart.hierarchy.expect
@@ -0,0 +1,408 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+DeltaBlue:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    DeltaBlue.run
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Strength:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Strength.weakest
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Strength.nextWeaker
+    Strength.value
+    Strength.stronger
+    Object._instanceOf
+    Strength.name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Strength.weaker
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Strength.strongest
+  classSetters:
+
+Constraint:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Constraint.markUnsatisfied
+    Constraint.chooseMethod
+    Constraint.addToGraph
+    Object.toString
+    Constraint.isInput
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    Constraint.inputsKnown
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    Constraint.markInputs
+    Object._identityHashCode
+    Constraint.recalculate
+    Constraint.execute
+    Constraint.output
+    Constraint.addConstraint
+    Constraint.isSatisfied
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Constraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+
+UnaryConstraint:
+  superclasses:
+    Object
+      -> Constraint
+  interfaces:
+  classMembers:
+    UnaryConstraint.markUnsatisfied
+    UnaryConstraint.chooseMethod
+    UnaryConstraint.addToGraph
+    Object.toString
+    Constraint.isInput
+    UnaryConstraint.myOutput
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    UnaryConstraint.inputsKnown
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    UnaryConstraint.markInputs
+    Object._identityHashCode
+    UnaryConstraint.recalculate
+    Constraint.execute
+    UnaryConstraint.output
+    Constraint.addConstraint
+    UnaryConstraint.isSatisfied
+    Object.hashCode
+    UnaryConstraint.satisfied
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    UnaryConstraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+    UnaryConstraint.satisfied
+
+StayConstraint:
+  superclasses:
+    Object
+      -> Constraint
+        -> UnaryConstraint
+  interfaces:
+  classMembers:
+    UnaryConstraint.markUnsatisfied
+    UnaryConstraint.chooseMethod
+    UnaryConstraint.addToGraph
+    Object.toString
+    Constraint.isInput
+    UnaryConstraint.myOutput
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    UnaryConstraint.inputsKnown
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    UnaryConstraint.markInputs
+    Object._identityHashCode
+    UnaryConstraint.recalculate
+    StayConstraint.execute
+    UnaryConstraint.output
+    Constraint.addConstraint
+    UnaryConstraint.isSatisfied
+    Object.hashCode
+    UnaryConstraint.satisfied
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    UnaryConstraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+    UnaryConstraint.satisfied
+
+EditConstraint:
+  superclasses:
+    Object
+      -> Constraint
+        -> UnaryConstraint
+  interfaces:
+  classMembers:
+    UnaryConstraint.markUnsatisfied
+    UnaryConstraint.chooseMethod
+    UnaryConstraint.addToGraph
+    Object.toString
+    EditConstraint.isInput
+    UnaryConstraint.myOutput
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    UnaryConstraint.inputsKnown
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    UnaryConstraint.markInputs
+    Object._identityHashCode
+    UnaryConstraint.recalculate
+    EditConstraint.execute
+    UnaryConstraint.output
+    Constraint.addConstraint
+    UnaryConstraint.isSatisfied
+    Object.hashCode
+    UnaryConstraint.satisfied
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    UnaryConstraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+    UnaryConstraint.satisfied
+
+BinaryConstraint:
+  superclasses:
+    Object
+      -> Constraint
+  interfaces:
+  classMembers:
+    BinaryConstraint.markUnsatisfied
+    BinaryConstraint.chooseMethod
+    BinaryConstraint.addToGraph
+    Object.toString
+    Constraint.isInput
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    BinaryConstraint.v2
+    BinaryConstraint.inputsKnown
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    BinaryConstraint.markInputs
+    Object._identityHashCode
+    BinaryConstraint.recalculate
+    Constraint.execute
+    BinaryConstraint.output
+    Constraint.addConstraint
+    BinaryConstraint.isSatisfied
+    Object.hashCode
+    BinaryConstraint.input
+    BinaryConstraint.direction
+    BinaryConstraint.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    BinaryConstraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+    BinaryConstraint.v2
+    BinaryConstraint.direction
+    BinaryConstraint.v1
+
+ScaleConstraint:
+  superclasses:
+    Object
+      -> Constraint
+        -> BinaryConstraint
+  interfaces:
+  classMembers:
+    BinaryConstraint.markUnsatisfied
+    BinaryConstraint.chooseMethod
+    ScaleConstraint.addToGraph
+    Object.toString
+    Constraint.isInput
+    ScaleConstraint.scale
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    BinaryConstraint.v2
+    BinaryConstraint.inputsKnown
+    ScaleConstraint.offset
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    ScaleConstraint.markInputs
+    Object._identityHashCode
+    ScaleConstraint.recalculate
+    ScaleConstraint.execute
+    BinaryConstraint.output
+    Constraint.addConstraint
+    BinaryConstraint.isSatisfied
+    Object.hashCode
+    BinaryConstraint.input
+    BinaryConstraint.direction
+    BinaryConstraint.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    ScaleConstraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+    BinaryConstraint.v2
+    BinaryConstraint.direction
+    BinaryConstraint.v1
+
+EqualityConstraint:
+  superclasses:
+    Object
+      -> Constraint
+        -> BinaryConstraint
+  interfaces:
+  classMembers:
+    BinaryConstraint.markUnsatisfied
+    BinaryConstraint.chooseMethod
+    BinaryConstraint.addToGraph
+    Object.toString
+    Constraint.isInput
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Constraint.satisfy
+    BinaryConstraint.v2
+    BinaryConstraint.inputsKnown
+    Object._instanceOf
+    Object.noSuchMethod
+    Constraint.destroyConstraint
+    BinaryConstraint.markInputs
+    Object._identityHashCode
+    BinaryConstraint.recalculate
+    EqualityConstraint.execute
+    BinaryConstraint.output
+    Constraint.addConstraint
+    BinaryConstraint.isSatisfied
+    Object.hashCode
+    BinaryConstraint.input
+    BinaryConstraint.direction
+    BinaryConstraint.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    BinaryConstraint.removeFromGraph
+    Constraint.strength
+  classSetters:
+    BinaryConstraint.v2
+    BinaryConstraint.direction
+    BinaryConstraint.v1
+
+Variable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Variable.mark
+    Variable.stay
+    Object.toString
+    Variable.constraints
+    Variable.walkStrength
+    Variable.determinedBy
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Variable.value
+    Object._instanceOf
+    Variable.name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Variable.removeConstraint
+    Variable.addConstraint
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Variable.mark
+    Variable.stay
+    Variable.constraints
+    Variable.walkStrength
+    Variable.determinedBy
+    Variable.value
+
+Planner:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Planner.addConstraintsConsumingTo
+    Planner.removePropagateFrom
+    Object.toString
+    Planner.incrementalRemove
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Planner.newMark
+    Planner.addPropagate
+    Planner.currentMark
+    Planner.incrementalAdd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Planner.makePlan
+    Planner.extractPlanFromConstraints
+  classSetters:
+    Planner.currentMark
+
+Plan:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Plan.size
+    Plan.list
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Plan.execute
+    Plan.addConstraint
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Plan.list
diff --git a/pkg/front_end/testcases/abstract_members.dart b/pkg/front_end/testcases/abstract_members.dart
index 058cbe9..127c6fc 100644
--- a/pkg/front_end/testcases/abstract_members.dart
+++ b/pkg/front_end/testcases/abstract_members.dart
@@ -55,4 +55,44 @@
   noSuchMethod(_);
 }
 
+class C {
+  void interfaceMethod1(_) {}
+}
+
+// This class should have an error, the method C.interfaceMethod1 conflicts
+// with the field Interface2.interfaceMethod1.
+abstract class D extends C implements Interface2 {}
+
+class E {
+  void set interfaceMethod1(_) {}
+}
+
+// This class should have an error, the setter E.interfaceMethod1 conflicts
+// with the method Interface1.interfaceMethod1.
+abstract class F extends E implements Interface1 {}
+
+class Foo {
+  void foo() {}
+}
+
+class G {
+  Object get foo => null;
+}
+
+// This class should have an error, the getter G.foo conflicts with the method
+// Foo.foo.
+abstract class H extends G implements Foo {}
+
+class Bar {
+  Object get foo => null;
+}
+
+class I {
+  Object foo() {}
+}
+
+// This class should have an error, the getter Bar.foo conflicts with the
+// method I.foo.
+abstract class J extends I implements Bar {}
+
 main() {}
diff --git a/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect b/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
new file mode 100644
index 0000000..dad4f9b
--- /dev/null
+++ b/pkg/front_end/testcases/abstract_members.dart.hierarchy.expect
@@ -0,0 +1,608 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Interface1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Interface2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Interface2.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Interface2.interfaceMethod1
+
+Interface3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Interface3.interfaceMethod3
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: Interface1, Interface2, Interface3
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    A.aMethod
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    A.abstractMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.property3
+    A.property1
+    A.property2
+  interfaceMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    A.aMethod
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    A.abstractMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Interface3.interfaceMethod3
+  interfaceSetters:
+    A.property3
+    Interface2.interfaceMethod1
+    A.property1
+    A.property2
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces: Interface1, Interface2, Interface3
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    Object.noSuchMethod
+    A.abstractMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+  classSetters:
+    A.property3
+    A.property1
+    A.property2
+  interfaceMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    Object.noSuchMethod
+    A.abstractMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+    Interface3.interfaceMethod3
+  interfaceSetters:
+    A.property3
+    Interface2.interfaceMethod1
+    A.property1
+    A.property2
+
+MyClass:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces: Interface1, Interface2, Interface3
+  classMembers:
+    MyClass.aaMethod
+    Object.toString
+    Object.runtimeType
+    MyClass.aMethod
+    Object._simpleInstanceOf
+    MyClass.bMethod
+    Object._instanceOf
+    MyClass.cMethod
+    Object.noSuchMethod
+    A.abstractMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+    MyClass.property2
+  classSetters:
+    A.property3
+    A.property1
+    MyClass.property2
+  interfaceMembers:
+    MyClass.aaMethod
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    MyClass.aMethod
+    Object._simpleInstanceOf
+    MyClass.bMethod
+    Object._instanceOf
+    MyClass.cMethod
+    Object.noSuchMethod
+    A.abstractMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+    Interface3.interfaceMethod3
+    MyClass.property2
+  interfaceSetters:
+    A.property3
+    Interface2.interfaceMethod1
+    A.property1
+    MyClass.property2
+
+MyMock1:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces: Interface1, Interface2, Interface3
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    MyMock1.noSuchMethod
+    A.abstractMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+  classSetters:
+    A.property3
+    A.property1
+    A.property2
+  interfaceMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    MyMock1.noSuchMethod
+    A.abstractMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+    Interface3.interfaceMethod3
+  interfaceSetters:
+    A.property3
+    Interface2.interfaceMethod1
+    A.property1
+    A.property2
+
+MyMock2:
+  superclasses:
+    Object
+      -> A
+        -> B
+          -> MyMock1
+  interfaces: Interface1, Interface2, Interface3
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    MyMock1.noSuchMethod
+    A.abstractMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+  classSetters:
+    A.property3
+    A.property1
+    A.property2
+  interfaceMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    MyMock1.noSuchMethod
+    A.abstractMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+    Interface3.interfaceMethod3
+  interfaceSetters:
+    A.property3
+    Interface2.interfaceMethod1
+    A.property1
+    A.property2
+
+MyMock3:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces: Interface1, Interface2, Interface3
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    Object.noSuchMethod
+    A.abstractMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+  classSetters:
+    A.property3
+    A.property1
+    A.property2
+  interfaceMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    B.aMethod
+    Object._simpleInstanceOf
+    B.bMethod
+    Object._instanceOf
+    Object.noSuchMethod
+    A.abstractMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.property1
+    Interface3.interfaceMethod3
+  interfaceSetters:
+    A.property3
+    Interface2.interfaceMethod1
+    A.property1
+    A.property2
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: Interface2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Interface2.interfaceMethod2
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Interface2.interfaceMethod1
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.interfaceMethod1
+
+F:
+  superclasses:
+    Object
+      -> E
+  interfaces: Interface1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.interfaceMethod1
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Interface1.interfaceMethod1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.interfaceMethod1
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+H:
+  superclasses:
+    Object
+      -> G
+  interfaces: Foo
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Bar.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+J:
+  superclasses:
+    Object
+      -> I
+  interfaces: Bar
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
index 0c85dd2..5a3c3d0 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
 // abstract class A implements Interface1, Interface2, Interface3 {
@@ -89,49 +91,47 @@
 // pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
 //   void interfaceMethod3() {}
 //        ^^^^^^^^^^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
-// abstract class A implements Interface1, Interface2, Interface3 {
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
 //                ^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is one inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is the other inherited member.
+//   void interfaceMethod1(_) {}
+//        ^^^^^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
-//  - A.abstractMethod
-//  - A.property1=
-//  - A.property3=
-//  - Interface1.interfaceMethod1
-//  - Interface2.interfaceMethod1
-//  - Interface2.interfaceMethod2
-//  - Interface3.interfaceMethod3
-// Try to either
-//  - provide an implementation,
-//  - inherit an implementation from a superclass or mixin,
-//  - mark the class as abstract, or
-//  - provide a 'noSuchMethod' implementation.
-// 
-// class MyClass extends B {
-//       ^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:72:16: Error: Can't inherit members that conflict with each other.
+// abstract class F extends E implements Interface1 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:67:12: Context: This is the other inherited member.
+//   void set interfaceMethod1(_) {}
+//            ^^^^^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/abstract_members.dart:54:7: Error: The non-abstract class 'MyMock3' is missing implementations for these members:
-//  - A.abstractMethod
-//  - A.property1=
-//  - A.property2=
-//  - A.property3=
-//  - Interface1.interfaceMethod1
-//  - Interface2.interfaceMethod1
-//  - Interface2.interfaceMethod2
-//  - Interface3.interfaceMethod3
-// Try to either
-//  - provide an implementation,
-//  - inherit an implementation from a superclass or mixin,
-//  - mark the class as abstract, or
-//  - provide a 'noSuchMethod' implementation.
-// 
-// class MyMock3 extends B {
-//       ^^^^^^^
-
-library;
+// pkg/front_end/testcases/abstract_members.dart:84:16: Error: Can't inherit members that conflict with each other.
+// abstract class H extends G implements Foo {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:75:8: Context: This is one inherited member.
+//   void foo() {}
+//        ^^^
+// pkg/front_end/testcases/abstract_members.dart:79:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is one inherited member.
+//   Object get foo => null;
+//              ^^^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is the other inherited member.
+//   Object foo() {}
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -235,4 +235,62 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method interfaceMethod1(dynamic _) → void {}
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  set interfaceMethod1(dynamic _) → void {}
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    : super self::E::•()
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  method foo() → void {}
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    : super self::G::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method foo() → core::Object {}
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    : super self::I::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
index 7e489f3..5a3c3d0 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
@@ -1,8 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
 // abstract class A implements Interface1, Interface2, Interface3 {
 //                ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
 //  - A.abstractMethod
@@ -17,9 +25,30 @@
 //  - inherit an implementation from a superclass or mixin,
 //  - mark the class as abstract, or
 //  - provide a 'noSuchMethod' implementation.
-// 
+//
 // class MyClass extends B {
 //       ^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'A.abstractMethod' is defined here.
+//   abstractMethod();
+//   ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'A.property1=' is defined here.
+//   void set property1(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'A.property3=' is defined here.
+//   void set property3(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'Interface1.interfaceMethod1' is defined here.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'Interface2.interfaceMethod1' is defined here.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'Interface2.interfaceMethod2' is defined here.
+//   void interfaceMethod2() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
+//   void interfaceMethod3() {}
+//        ^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/abstract_members.dart:54:7: Error: The non-abstract class 'MyMock3' is missing implementations for these members:
 //  - A.abstractMethod
@@ -35,11 +64,74 @@
 //  - inherit an implementation from a superclass or mixin,
 //  - mark the class as abstract, or
 //  - provide a 'noSuchMethod' implementation.
-// 
+//
 // class MyMock3 extends B {
 //       ^^^^^^^
-
-library;
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'A.abstractMethod' is defined here.
+//   abstractMethod();
+//   ^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'A.property1=' is defined here.
+//   void set property1(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:23:12: Context: 'A.property2=' is defined here.
+//   void set property2(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'A.property3=' is defined here.
+//   void set property3(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'Interface1.interfaceMethod1' is defined here.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'Interface2.interfaceMethod1' is defined here.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'Interface2.interfaceMethod2' is defined here.
+//   void interfaceMethod2() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
+//   void interfaceMethod3() {}
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is one inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is the other inherited member.
+//   void interfaceMethod1(_) {}
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:72:16: Error: Can't inherit members that conflict with each other.
+// abstract class F extends E implements Interface1 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:67:12: Context: This is the other inherited member.
+//   void set interfaceMethod1(_) {}
+//            ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:84:16: Error: Can't inherit members that conflict with each other.
+// abstract class H extends G implements Foo {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:75:8: Context: This is one inherited member.
+//   void foo() {}
+//        ^^^
+// pkg/front_end/testcases/abstract_members.dart:79:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is one inherited member.
+//   Object get foo => null;
+//              ^^^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is the other inherited member.
+//   Object foo() {}
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -143,4 +235,62 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method interfaceMethod1(dynamic _) → void {}
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  set interfaceMethod1(dynamic _) → void {}
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    : super self::E::•()
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  method foo() → void {}
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    : super self::G::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method foo() → core::Object {}
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    : super self::I::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_members.dart.outline.expect b/pkg/front_end/testcases/abstract_members.dart.outline.expect
index e2bf105..ad1e730 100644
--- a/pkg/front_end/testcases/abstract_members.dart.outline.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
 // abstract class A implements Interface1, Interface2, Interface3 {
@@ -89,8 +91,47 @@
 // pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
 //   void interfaceMethod3() {}
 //        ^^^^^^^^^^^^^^^^
-
-library;
+//
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is one inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is the other inherited member.
+//   void interfaceMethod1(_) {}
+//        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:72:16: Error: Can't inherit members that conflict with each other.
+// abstract class F extends E implements Interface1 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:67:12: Context: This is the other inherited member.
+//   void set interfaceMethod1(_) {}
+//            ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:84:16: Error: Can't inherit members that conflict with each other.
+// abstract class H extends G implements Foo {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:75:8: Context: This is one inherited member.
+//   void foo() {}
+//        ^^^
+// pkg/front_end/testcases/abstract_members.dart:79:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is one inherited member.
+//   Object get foo => null;
+//              ^^^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is the other inherited member.
+//   Object foo() {}
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -195,5 +236,57 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  method interfaceMethod1(dynamic _) → void
+    ;
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    ;
+  set interfaceMethod1(dynamic _) → void
+    ;
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    ;
+  method foo() → void
+    ;
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    ;
+  get foo() → core::Object
+    ;
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    ;
+  get foo() → core::Object
+    ;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    ;
+  method foo() → core::Object
+    ;
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    ;
+}
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/abstract_members.dart.strong.expect b/pkg/front_end/testcases/abstract_members.dart.strong.expect
index c568386..0322fcb 100644
--- a/pkg/front_end/testcases/abstract_members.dart.strong.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.strong.expect
@@ -1,24 +1,25 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
 // abstract class A implements Interface1, Interface2, Interface3 {
 //                ^
 // pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
 //   void interfaceMethod1() {}
-//        ^
+//        ^^^^^^^^^^^^^^^^
 // pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
 //   var interfaceMethod1;
-//       ^
+//       ^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
-//  - 'interfaceMethod2'
-//  - 'abstractMethod'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod3'
-//  - 'property3='
-//  - 'interfaceMethod1='
-//  - 'property1='
+//  - A.abstractMethod
+//  - A.property1=
+//  - A.property3=
+//  - Interface1.interfaceMethod1
+//  - Interface2.interfaceMethod1
+//  - Interface2.interfaceMethod2
+//  - Interface3.interfaceMethod3
 // Try to either
 //  - provide an implementation,
 //  - inherit an implementation from a superclass or mixin,
@@ -27,41 +28,37 @@
 //
 // class MyClass extends B {
 //       ^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'interfaceMethod2' is defined here.
-//   void interfaceMethod2() {}
-//        ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'abstractMethod' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'A.abstractMethod' is defined here.
 //   abstractMethod();
 //   ^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'interfaceMethod1' is defined here.
-//   void interfaceMethod1() {}
-//        ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'interfaceMethod1' is defined here.
-//   var interfaceMethod1;
-//       ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'interfaceMethod3' is defined here.
-//   void interfaceMethod3() {}
-//        ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'property3=' is defined here.
-//   void set property3(_);
-//            ^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'interfaceMethod1=' is defined here.
-//   var interfaceMethod1;
-//       ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'property1=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'A.property1=' is defined here.
 //   void set property1(_);
 //            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'A.property3=' is defined here.
+//   void set property3(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'Interface1.interfaceMethod1' is defined here.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'Interface2.interfaceMethod1' is defined here.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'Interface2.interfaceMethod2' is defined here.
+//   void interfaceMethod2() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
+//   void interfaceMethod3() {}
+//        ^^^^^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/abstract_members.dart:54:7: Error: The non-abstract class 'MyMock3' is missing implementations for these members:
-//  - 'interfaceMethod2'
-//  - 'abstractMethod'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod3'
-//  - 'property3='
-//  - 'interfaceMethod1='
-//  - 'property1='
-//  - 'property2='
+//  - A.abstractMethod
+//  - A.property1=
+//  - A.property2=
+//  - A.property3=
+//  - Interface1.interfaceMethod1
+//  - Interface2.interfaceMethod1
+//  - Interface2.interfaceMethod2
+//  - Interface3.interfaceMethod3
 // Try to either
 //  - provide an implementation,
 //  - inherit an implementation from a superclass or mixin,
@@ -70,78 +67,71 @@
 //
 // class MyMock3 extends B {
 //       ^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'interfaceMethod2' is defined here.
-//   void interfaceMethod2() {}
-//        ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'abstractMethod' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:21:3: Context: 'A.abstractMethod' is defined here.
 //   abstractMethod();
 //   ^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'interfaceMethod1' is defined here.
-//   void interfaceMethod1() {}
-//        ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'interfaceMethod1' is defined here.
-//   var interfaceMethod1;
-//       ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'interfaceMethod3' is defined here.
-//   void interfaceMethod3() {}
-//        ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'property3=' is defined here.
-//   void set property3(_);
-//            ^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'interfaceMethod1=' is defined here.
-//   var interfaceMethod1;
-//       ^^^^^^^^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'property1=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:22:12: Context: 'A.property1=' is defined here.
 //   void set property1(_);
 //            ^^^^^^^^^
-// pkg/front_end/testcases/abstract_members.dart:23:12: Context: 'property2=' is defined here.
+// pkg/front_end/testcases/abstract_members.dart:23:12: Context: 'A.property2=' is defined here.
 //   void set property2(_);
 //            ^^^^^^^^^
-
-// Unhandled errors:
+// pkg/front_end/testcases/abstract_members.dart:24:12: Context: 'A.property3=' is defined here.
+//   void set property3(_);
+//            ^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: 'Interface1.interfaceMethod1' is defined here.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: 'Interface2.interfaceMethod1' is defined here.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:10:8: Context: 'Interface2.interfaceMethod2' is defined here.
+//   void interfaceMethod2() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
+//   void interfaceMethod3() {}
+//        ^^^^^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/abstract_members.dart:19:16: Error: Can't inherit members that conflict with each other.
-// abstract class A implements Interface1, Interface2, Interface3 {
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
 //                ^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is one inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is the other inherited member.
+//   void interfaceMethod1(_) {}
+//        ^^^^^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
-//  - 'interfaceMethod2'
-//  - 'abstractMethod'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod3'
-//  - 'property3='
-//  - 'interfaceMethod1='
-//  - 'property1='
-// Try to either
-//  - provide an implementation,
-//  - inherit an implementation from a superclass or mixin,
-//  - mark the class as abstract, or
-//  - provide a 'noSuchMethod' implementation.
-// 
-// class MyClass extends B {
-//       ^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:72:16: Error: Can't inherit members that conflict with each other.
+// abstract class F extends E implements Interface1 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+//   void interfaceMethod1() {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:67:12: Context: This is the other inherited member.
+//   void set interfaceMethod1(_) {}
+//            ^^^^^^^^^^^^^^^^
 //
-// pkg/front_end/testcases/abstract_members.dart:54:7: Error: The non-abstract class 'MyMock3' is missing implementations for these members:
-//  - 'interfaceMethod2'
-//  - 'abstractMethod'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod1'
-//  - 'interfaceMethod3'
-//  - 'property3='
-//  - 'interfaceMethod1='
-//  - 'property1='
-//  - 'property2='
-// Try to either
-//  - provide an implementation,
-//  - inherit an implementation from a superclass or mixin,
-//  - mark the class as abstract, or
-//  - provide a 'noSuchMethod' implementation.
-// 
-// class MyMock3 extends B {
-//       ^^^^^^^
-
-library;
+// pkg/front_end/testcases/abstract_members.dart:84:16: Error: Can't inherit members that conflict with each other.
+// abstract class H extends G implements Foo {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:75:8: Context: This is one inherited member.
+//   void foo() {}
+//        ^^^
+// pkg/front_end/testcases/abstract_members.dart:79:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is one inherited member.
+//   Object get foo => null;
+//              ^^^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is the other inherited member.
+//   Object foo() {}
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -245,4 +235,62 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method interfaceMethod1(dynamic _) → void {}
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  set interfaceMethod1(dynamic _) → void {}
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    : super self::E::•()
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  method foo() → void {}
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    : super self::G::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method foo() → core::Object {}
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    : super self::I::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/accessors.dart.hierarchy.expect b/pkg/front_end/testcases/accessors.dart.hierarchy.expect
new file mode 100644
index 0000000..390a1b2
--- /dev/null
+++ b/pkg/front_end/testcases/accessors.dart.hierarchy.expect
@@ -0,0 +1,61 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.testD
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.testC
+  classSetters:
+    C.onlySetter
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    C.testD
+    D.onlySetter
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.testC
+  classSetters:
+    D.onlySetter
diff --git a/pkg/front_end/testcases/accessors.dart.legacy.expect b/pkg/front_end/testcases/accessors.dart.legacy.expect
index 9d3bdd4..7de21a4 100644
--- a/pkg/front_end/testcases/accessors.dart.legacy.expect
+++ b/pkg/front_end/testcases/accessors.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/accessors.dart:16:13: Warning: Getter not found: 'onlySetter'.
 //       print(onlySetter);
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/accessors.dart:40:11: Warning: Getter not found: 'onlySetter'.
 //     print(onlySetter);
 //           ^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/accessors.dart.legacy.transformed.expect b/pkg/front_end/testcases/accessors.dart.legacy.transformed.expect
index c6c025f..7de21a4 100644
--- a/pkg/front_end/testcases/accessors.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/accessors.dart.legacy.transformed.expect
@@ -1,4 +1,19 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/accessors.dart:16:13: Warning: Getter not found: 'onlySetter'.
+//       print(onlySetter);
+//             ^^^^^^^^^^
+//
+// pkg/front_end/testcases/accessors.dart:25:11: Warning: Getter not found: 'onlySetter'.
+//     print(onlySetter);
+//           ^^^^^^^^^^
+//
+// pkg/front_end/testcases/accessors.dart:40:11: Warning: Getter not found: 'onlySetter'.
+//     print(onlySetter);
+//           ^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/accessors.dart.strong.expect b/pkg/front_end/testcases/accessors.dart.strong.expect
index 866b083..45fbbc5 100644
--- a/pkg/front_end/testcases/accessors.dart.strong.expect
+++ b/pkg/front_end/testcases/accessors.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
 //       print(onlySetter);
@@ -23,18 +25,7 @@
 // pkg/front_end/testcases/accessors.dart:40:11: Error: Getter not found: 'onlySetter'.
 //     print(onlySetter);
 //           ^^^^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
-//       print(onlySetter);
-//             ^^^^^^^^^^
-//
-// pkg/front_end/testcases/accessors.dart:25:11: Error: Getter not found: 'onlySetter'.
-//     print(onlySetter);
-//           ^^^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -47,7 +38,7 @@
   }
   method testC() → dynamic {
     try {
-      core::print(let final dynamic #t1 = this in invalid-expression "pkg/front_end/testcases/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
+      core::print(invalid-expression "pkg/front_end/testcases/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/accessors.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
       print(onlySetter);
@@ -60,7 +51,7 @@
     this.{self::C::onlySetter} = "hest";
   }
   method testD() → dynamic {
-    core::print(let final dynamic #t2 = this in invalid-expression "pkg/front_end/testcases/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
+    core::print(invalid-expression "pkg/front_end/testcases/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/accessors.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
     print(onlySetter);
diff --git a/pkg/front_end/testcases/accessors.dart.strong.transformed.expect b/pkg/front_end/testcases/accessors.dart.strong.transformed.expect
index 69ee9a5..45fbbc5 100644
--- a/pkg/front_end/testcases/accessors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/accessors.dart.strong.transformed.expect
@@ -1,14 +1,31 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/accessors.dart:16:13: Error: Getter not found: 'onlySetter'.
 //       print(onlySetter);
 //             ^^^^^^^^^^
 //
+// pkg/front_end/testcases/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/accessors.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
+//       print(onlySetter);
+//             ^^^^^^^^^^
+//
 // pkg/front_end/testcases/accessors.dart:25:11: Error: Getter not found: 'onlySetter'.
 //     print(onlySetter);
 //           ^^^^^^^^^^
-
-library;
+//
+// pkg/front_end/testcases/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/accessors.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
+//     print(onlySetter);
+//           ^^^^^^^^^^
+//
+// pkg/front_end/testcases/accessors.dart:40:11: Error: Getter not found: 'onlySetter'.
+//     print(onlySetter);
+//           ^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -21,7 +38,7 @@
   }
   method testC() → dynamic {
     try {
-      core::print(let final self::C #t1 = this in invalid-expression "pkg/front_end/testcases/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
+      core::print(invalid-expression "pkg/front_end/testcases/accessors.dart:16:13: Error: The getter 'onlySetter' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/accessors.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
       print(onlySetter);
@@ -34,7 +51,7 @@
     this.{self::C::onlySetter} = "hest";
   }
   method testD() → dynamic {
-    core::print(let final self::C #t2 = this in invalid-expression "pkg/front_end/testcases/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
+    core::print(invalid-expression "pkg/front_end/testcases/accessors.dart:25:11: Error: The getter 'onlySetter' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/accessors.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'onlySetter'.
     print(onlySetter);
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.legacy.expect b/pkg/front_end/testcases/ambiguous_exports.dart.legacy.expect
index c3c8517..f098443 100644
--- a/pkg/front_end/testcases/ambiguous_exports.dart.legacy.expect
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.legacy.expect
@@ -1,16 +1,30 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
-// export 'map.dart' show main;
-// ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
-// export 'map.dart' show main;
-// ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
+// export 'map.dart' show main;
+// ^
+//
 import self as self;
 
+export "org-dartlang-testcase:///hello.dart";
+export "org-dartlang-testcase:///map.dart";
+
 static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(core::Map::•<dynamic, dynamic>());
+}
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.legacy.transformed.expect b/pkg/front_end/testcases/ambiguous_exports.dart.legacy.transformed.expect
index b993c56..f098443 100644
--- a/pkg/front_end/testcases/ambiguous_exports.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.legacy.transformed.expect
@@ -1,10 +1,30 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
 // export 'map.dart' show main;
 // ^
-
-library;
+//
 import self as self;
 
+export "org-dartlang-testcase:///hello.dart";
+export "org-dartlang-testcase:///map.dart";
+
 static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(core::Map::•<dynamic, dynamic>());
+}
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.outline.expect b/pkg/front_end/testcases/ambiguous_exports.dart.outline.expect
index dc412d7..a158644 100644
--- a/pkg/front_end/testcases/ambiguous_exports.dart.outline.expect
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.outline.expect
@@ -1,10 +1,26 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
 // export 'map.dart' show main;
 // ^
-
-library;
+//
 import self as self;
 
+export "org-dartlang-testcase:///hello.dart";
+export "org-dartlang-testcase:///map.dart";
+
 static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
+
+library;
+import self as self2;
+
+static method main() → dynamic
+  ;
+
+library;
+import self as self3;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.strong.expect b/pkg/front_end/testcases/ambiguous_exports.dart.strong.expect
index c3c8517..f098443 100644
--- a/pkg/front_end/testcases/ambiguous_exports.dart.strong.expect
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.strong.expect
@@ -1,16 +1,30 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
-// export 'map.dart' show main;
-// ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
-// export 'map.dart' show main;
-// ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
+// export 'map.dart' show main;
+// ^
+//
 import self as self;
 
+export "org-dartlang-testcase:///hello.dart";
+export "org-dartlang-testcase:///map.dart";
+
 static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(core::Map::•<dynamic, dynamic>());
+}
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect b/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect
index b993c56..f098443 100644
--- a/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect
@@ -1,10 +1,30 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
 // export 'map.dart' show main;
 // ^
-
-library;
+//
 import self as self;
 
+export "org-dartlang-testcase:///hello.dart";
+export "org-dartlang-testcase:///map.dart";
+
 static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(core::Map::•<dynamic, dynamic>());
+}
diff --git a/pkg/front_end/testcases/annotation_eof.dart.legacy.expect b/pkg/front_end/testcases/annotation_eof.dart.legacy.expect
index 5acfc4b..b1392cc 100644
--- a/pkg/front_end/testcases/annotation_eof.dart.legacy.expect
+++ b/pkg/front_end/testcases/annotation_eof.dart.legacy.expect
@@ -1,12 +1,9 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/annotation_eof.dart.legacy.transformed.expect b/pkg/front_end/testcases/annotation_eof.dart.legacy.transformed.expect
index 1be62d2..b1392cc 100644
--- a/pkg/front_end/testcases/annotation_eof.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/annotation_eof.dart.legacy.transformed.expect
@@ -1,8 +1,9 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/annotation_eof.dart.outline.expect b/pkg/front_end/testcases/annotation_eof.dart.outline.expect
index 464bbee..92138e7 100644
--- a/pkg/front_end/testcases/annotation_eof.dart.outline.expect
+++ b/pkg/front_end/testcases/annotation_eof.dart.outline.expect
@@ -1,8 +1,9 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/annotation_eof.dart.strong.expect b/pkg/front_end/testcases/annotation_eof.dart.strong.expect
index 5acfc4b..b1392cc 100644
--- a/pkg/front_end/testcases/annotation_eof.dart.strong.expect
+++ b/pkg/front_end/testcases/annotation_eof.dart.strong.expect
@@ -1,12 +1,9 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect b/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect
index 1be62d2..b1392cc 100644
--- a/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect
@@ -1,8 +1,9 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''.
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart.hierarchy.expect b/pkg/front_end/testcases/annotation_on_enum_values.dart.hierarchy.expect
new file mode 100644
index 0000000..6abd62f
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Fisk.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.bar
+    Foo.cafebabe
+    Foo.toString
+    Foo.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Foo.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Foo.baz
+  classSetters:
diff --git a/pkg/front_end/testcases/annotation_top.dart.hierarchy.expect b/pkg/front_end/testcases/annotation_top.dart.hierarchy.expect
new file mode 100644
index 0000000..ad9c025
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_top.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart.hierarchy.expect b/pkg/front_end/testcases/annotation_variable_declaration.dart.hierarchy.expect
new file mode 100644
index 0000000..b37c1fd
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Baz:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Baz.hest
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Baz.fisk
+  classSetters:
diff --git a/pkg/front_end/testcases/argument.dart.hierarchy.expect b/pkg/front_end/testcases/argument.dart.hierarchy.expect
new file mode 100644
index 0000000..0d45c08
--- /dev/null
+++ b/pkg/front_end/testcases/argument.dart.hierarchy.expect
@@ -0,0 +1,90 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Baz:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.legacy.expect b/pkg/front_end/testcases/argument_mismatch.dart.legacy.expect
index 3716c84..d836fc0 100644
--- a/pkg/front_end/testcases/argument_mismatch.dart.legacy.expect
+++ b/pkg/front_end/testcases/argument_mismatch.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/argument_mismatch.dart:10:34: Warning: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/argument_mismatch.dart:7:29: Context: Found this candidate, but the arguments don't match.
 // /*@context=CandidateFound*/ foo() {}
 //                             ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.legacy.transformed.expect b/pkg/front_end/testcases/argument_mismatch.dart.legacy.transformed.expect
index 5f3f9aa..d836fc0 100644
--- a/pkg/front_end/testcases/argument_mismatch.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/argument_mismatch.dart.legacy.transformed.expect
@@ -1,4 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/argument_mismatch.dart:10:34: Warning: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+//   /*@warning=MethodNotFound*/ foo(null);
+//                                  ^
+// pkg/front_end/testcases/argument_mismatch.dart:7:29: Context: Found this candidate, but the arguments don't match.
+// /*@context=CandidateFound*/ foo() {}
+//                             ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/async_function.dart.legacy.expect b/pkg/front_end/testcases/async_function.dart.legacy.expect
index 6a9bffa..0510556 100644
--- a/pkg/front_end/testcases/async_function.dart.legacy.expect
+++ b/pkg/front_end/testcases/async_function.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field core::List<core::String> stringList = <dynamic>["bar"];
 static method asyncString() → asy::Future<core::String> async {
   return "foo";
diff --git a/pkg/front_end/testcases/async_function.dart.legacy.transformed.expect b/pkg/front_end/testcases/async_function.dart.legacy.transformed.expect
index c4a5b51..2ac15d8 100644
--- a/pkg/front_end/testcases/async_function.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/async_function.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field core::List<core::String> stringList = <dynamic>["bar"];
 static method asyncString() → asy::Future<core::String> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
diff --git a/pkg/front_end/testcases/async_function.dart.outline.expect b/pkg/front_end/testcases/async_function.dart.outline.expect
index e1bc747..d9c5589 100644
--- a/pkg/front_end/testcases/async_function.dart.outline.expect
+++ b/pkg/front_end/testcases/async_function.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field core::List<core::String> stringList;
 static method asyncString() → asy::Future<core::String>
   ;
diff --git a/pkg/front_end/testcases/async_function.dart.strong.expect b/pkg/front_end/testcases/async_function.dart.strong.expect
index 4cbc5e0..b4babf8 100644
--- a/pkg/front_end/testcases/async_function.dart.strong.expect
+++ b/pkg/front_end/testcases/async_function.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field core::List<core::String> stringList = <core::String>["bar"];
 static method asyncString() → asy::Future<core::String> async {
   return "foo";
diff --git a/pkg/front_end/testcases/async_function.dart.strong.transformed.expect b/pkg/front_end/testcases/async_function.dart.strong.transformed.expect
index a57a753..d2dffb7 100644
--- a/pkg/front_end/testcases/async_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/async_function.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field core::List<core::String> stringList = <core::String>["bar"];
 static method asyncString() → asy::Future<core::String> /* originally async */ {
   final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
diff --git a/pkg/front_end/testcases/async_nested.dart.hierarchy.expect b/pkg/front_end/testcases/async_nested.dart.hierarchy.expect
new file mode 100644
index 0000000..3ec82b1
--- /dev/null
+++ b/pkg/front_end/testcases/async_nested.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Node:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Node.toSimpleString
+    Node.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Node.name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Node.nested
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/async_nested.dart.legacy.expect b/pkg/front_end/testcases/async_nested.dart.legacy.expect
index b1f76d3..363de24 100644
--- a/pkg/front_end/testcases/async_nested.dart.legacy.expect
+++ b/pkg/front_end/testcases/async_nested.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Node extends core::Object {
   final field core::List<self::Node> nested;
   final field core::String name;
diff --git a/pkg/front_end/testcases/async_nested.dart.legacy.transformed.expect b/pkg/front_end/testcases/async_nested.dart.legacy.transformed.expect
index ad071a1..c0e22cb 100644
--- a/pkg/front_end/testcases/async_nested.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/async_nested.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Node extends core::Object {
   final field core::List<self::Node> nested;
   final field core::String name;
diff --git a/pkg/front_end/testcases/async_nested.dart.outline.expect b/pkg/front_end/testcases/async_nested.dart.outline.expect
index 1511915..57d0f20 100644
--- a/pkg/front_end/testcases/async_nested.dart.outline.expect
+++ b/pkg/front_end/testcases/async_nested.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class Node extends core::Object {
   final field core::List<self::Node> nested;
   final field core::String name;
diff --git a/pkg/front_end/testcases/async_nested.dart.strong.expect b/pkg/front_end/testcases/async_nested.dart.strong.expect
index d207e896..d51ca15 100644
--- a/pkg/front_end/testcases/async_nested.dart.strong.expect
+++ b/pkg/front_end/testcases/async_nested.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Node extends core::Object {
   final field core::List<self::Node> nested;
   final field core::String name;
diff --git a/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect
index b5b0c4b..246f441 100644
--- a/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/async_nested.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Node extends core::Object {
   final field core::List<self::Node> nested;
   final field core::String name;
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.hierarchy.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.hierarchy.expect
new file mode 100644
index 0000000..2c47c23
--- /dev/null
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
+    A.d
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.a
+    B.d
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
index 80e3471..e84ce6f 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -37,20 +39,7 @@
 // pkg/front_end/testcases/bad_setter_abstract.dart:66:9: Warning: The class 'B' is abstract and can't be instantiated.
 //     new B();
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
-// Try adding {}.
-// set b();
-//        ^
-//
-// pkg/front_end/testcases/bad_setter_abstract.dart:7:12: Error: Expected a function body or '=>'.
-// Try adding {}.
-// set c(x, y);
-//            ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
index cd9945f..e84ce6f 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -9,8 +11,35 @@
 // Try adding {}.
 // set c(x, y);
 //            ^
-
-library;
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
+// set b();
+//      ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
+// set c(x, y);
+//      ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
+//   set a();
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
+//   set d(x, y);
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
+//   set a();
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
+//   set d(x, y);
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:66:9: Warning: The class 'B' is abstract and can't be instantiated.
+//     new B();
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
index a9bb871..68dcc4d 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -9,8 +11,7 @@
 // Try adding {}.
 // set c(x, y);
 //            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.strong.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.strong.expect
index 0334820..493d45f 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.strong.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -37,24 +39,7 @@
 // pkg/front_end/testcases/bad_setter_abstract.dart:66:9: Error: The class 'B' is abstract and can't be instantiated.
 //     new B();
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
-// Try adding {}.
-// set b();
-//        ^
-//
-// pkg/front_end/testcases/bad_setter_abstract.dart:7:12: Error: Expected a function body or '=>'.
-// Try adding {}.
-// set c(x, y);
-//            ^
-//
-// pkg/front_end/testcases/bad_setter_abstract.dart:66:9: Error: The class 'B' is abstract and can't be instantiated.
-//     new B();
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect
index a9335aa..493d45f 100644
--- a/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -10,11 +12,34 @@
 // set c(x, y);
 //            ^
 //
+// pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
+// set b();
+//      ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
+// set c(x, y);
+//      ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
+//   set a();
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
+//   set d(x, y);
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
+//   set a();
+//        ^
+//
+// pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
+//   set d(x, y);
+//        ^
+//
 // pkg/front_end/testcases/bad_setter_abstract.dart:66:9: Error: The class 'B' is abstract and can't be instantiated.
 //     new B();
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bad_store.dart.hierarchy.expect b/pkg/front_end/testcases/bad_store.dart.hierarchy.expect
new file mode 100644
index 0000000..1c6019a
--- /dev/null
+++ b/pkg/front_end/testcases/bad_store.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.field
diff --git a/pkg/front_end/testcases/bounds_check_depends_on_inference.dart.hierarchy.expect b/pkg/front_end/testcases/bounds_check_depends_on_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..91f36e2
--- /dev/null
+++ b/pkg/front_end/testcases/bounds_check_depends_on_inference.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/bug21938.dart.strong.expect b/pkg/front_end/testcases/bug21938.dart.strong.expect
index 5e1d794..25e833b 100644
--- a/pkg/front_end/testcases/bug21938.dart.strong.expect
+++ b/pkg/front_end/testcases/bug21938.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug21938.dart:10:4: Error: The method 'call' isn't defined for the class 'Object'.
 //  - 'Object' is from 'dart:core'.
@@ -17,26 +19,25 @@
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //   x. /*@error=UndefinedMethod*/ call();
 //                                 ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
 static method test() → dynamic {
   core::Object x;
   core::Function f;
-  let final dynamic #t1 = x in invalid-expression "pkg/front_end/testcases/bug21938.dart:10:4: Error: The method 'call' isn't defined for the class 'Object'.
+  invalid-expression "pkg/front_end/testcases/bug21938.dart:10:4: Error: The method 'call' isn't defined for the class 'Object'.
  - 'Object' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   x /*@error=UndefinedMethod*/ ();
    ^";
-  let final dynamic #t2 = x in invalid-expression "pkg/front_end/testcases/bug21938.dart:11:4: Error: The method 'call' isn't defined for the class 'Object'.
+  invalid-expression "pkg/front_end/testcases/bug21938.dart:11:4: Error: The method 'call' isn't defined for the class 'Object'.
  - 'Object' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   x /*@error=UndefinedMethod*/ (3);
    ^";
   f.call(5, 2);
-  let final dynamic #t3 = x in invalid-expression "pkg/front_end/testcases/bug21938.dart:13:33: Error: The method 'call' isn't defined for the class 'Object'.
+  invalid-expression "pkg/front_end/testcases/bug21938.dart:13:33: Error: The method 'call' isn't defined for the class 'Object'.
  - 'Object' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   x. /*@error=UndefinedMethod*/ call();
diff --git a/pkg/front_end/testcases/bug30695.dart.hierarchy.expect b/pkg/front_end/testcases/bug30695.dart.hierarchy.expect
new file mode 100644
index 0000000..94fa588
--- /dev/null
+++ b/pkg/front_end/testcases/bug30695.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
diff --git a/pkg/front_end/testcases/bug30695.dart.legacy.expect b/pkg/front_end/testcases/bug30695.dart.legacy.expect
index d1a2129..139b859 100644
--- a/pkg/front_end/testcases/bug30695.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug30695.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug30695.dart:11:3: Error: Can't declare a member that conflicts with an inherited one.
 //   foo() => 42;
@@ -6,14 +8,7 @@
 // pkg/front_end/testcases/bug30695.dart:6:7: Context: This is the inherited member.
 //   var foo = 42;
 //       ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/bug30695.dart:11:3: Error: Can't declare a member that conflicts with an inherited one.
-//   foo() => 42;
-//   ^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug30695.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug30695.dart.legacy.transformed.expect
index 998f289..139b859 100644
--- a/pkg/front_end/testcases/bug30695.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug30695.dart.legacy.transformed.expect
@@ -1,10 +1,14 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug30695.dart:11:3: Error: Can't declare a member that conflicts with an inherited one.
 //   foo() => 42;
 //   ^^^
-
-library;
+// pkg/front_end/testcases/bug30695.dart:6:7: Context: This is the inherited member.
+//   var foo = 42;
+//       ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug30695.dart.outline.expect b/pkg/front_end/testcases/bug30695.dart.outline.expect
index a4ad123..81e64a5 100644
--- a/pkg/front_end/testcases/bug30695.dart.outline.expect
+++ b/pkg/front_end/testcases/bug30695.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug30695.dart:11:3: Error: Can't declare a member that conflicts with an inherited one.
 //   foo() => 42;
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/bug30695.dart:6:7: Context: This is the inherited member.
 //   var foo = 42;
 //       ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug30695.dart.strong.expect b/pkg/front_end/testcases/bug30695.dart.strong.expect
index d03c5e3..30a8c8a 100644
--- a/pkg/front_end/testcases/bug30695.dart.strong.expect
+++ b/pkg/front_end/testcases/bug30695.dart.strong.expect
@@ -1,19 +1,14 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug30695.dart:11:3: Error: Can't declare a member that conflicts with an inherited one.
 //   foo() => 42;
-//   ^
+//   ^^^
 // pkg/front_end/testcases/bug30695.dart:6:7: Context: This is the inherited member.
 //   var foo = 42;
-//       ^
-
-// Unhandled errors:
+//       ^^^
 //
-// pkg/front_end/testcases/bug30695.dart:11:3: Error: Can't declare a member that conflicts with an inherited one.
-//   foo() => 42;
-//   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug31124.dart.legacy.expect b/pkg/front_end/testcases/bug31124.dart.legacy.expect
index 90dd470..2e4b5ac 100644
--- a/pkg/front_end/testcases/bug31124.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug31124.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -11,19 +13,7 @@
 // pkg/front_end/testcases/bug31124.dart:1:5: Context: Previous declaration of 'a'.
 // var a = () => 'b';a();
 //     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
-// Try adding {}.
-// var a = () => 'b';a();
-//                      ^
-//
-// pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
-// var a = () => 'b';a();
-//                   ^
-
-library;
 import self as self;
 
 static field dynamic a;
diff --git a/pkg/front_end/testcases/bug31124.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug31124.dart.legacy.transformed.expect
index b75686c..2e4b5ac 100644
--- a/pkg/front_end/testcases/bug31124.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug31124.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -8,8 +10,10 @@
 // pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
 // var a = () => 'b';a();
 //                   ^
-
-library;
+// pkg/front_end/testcases/bug31124.dart:1:5: Context: Previous declaration of 'a'.
+// var a = () => 'b';a();
+//     ^
+//
 import self as self;
 
 static field dynamic a;
diff --git a/pkg/front_end/testcases/bug31124.dart.outline.expect b/pkg/front_end/testcases/bug31124.dart.outline.expect
index 6634364..2e4b5ac 100644
--- a/pkg/front_end/testcases/bug31124.dart.outline.expect
+++ b/pkg/front_end/testcases/bug31124.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/bug31124.dart:1:5: Context: Previous declaration of 'a'.
 // var a = () => 'b';a();
 //     ^
-
-library;
+//
 import self as self;
 
 static field dynamic a;
diff --git a/pkg/front_end/testcases/bug31124.dart.strong.expect b/pkg/front_end/testcases/bug31124.dart.strong.expect
index 71f519f..08413bb 100644
--- a/pkg/front_end/testcases/bug31124.dart.strong.expect
+++ b/pkg/front_end/testcases/bug31124.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -11,19 +13,7 @@
 // pkg/front_end/testcases/bug31124.dart:1:5: Context: Previous declaration of 'a'.
 // var a = () => 'b';a();
 //     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
-// Try adding {}.
-// var a = () => 'b';a();
-//                      ^
-//
-// pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
-// var a = () => 'b';a();
-//                   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect b/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect
index 90fd8c8..08413bb 100644
--- a/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug31124.dart:1:22: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -8,8 +10,10 @@
 // pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
 // var a = () => 'b';a();
 //                   ^
-
-library;
+// pkg/front_end/testcases/bug31124.dart:1:5: Context: Previous declaration of 'a'.
+// var a = () => 'b';a();
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug32414a.dart.strong.expect b/pkg/front_end/testcases/bug32414a.dart.strong.expect
index 5b9c638..6a9c726 100644
--- a/pkg/front_end/testcases/bug32414a.dart.strong.expect
+++ b/pkg/front_end/testcases/bug32414a.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug32414a.dart:10:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   b = 42;
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect b/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect
index 13b27e0..6a9c726 100644
--- a/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug32414a.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/bug32414a.dart:10:7: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   b = 42;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug32426.dart.hierarchy.expect b/pkg/front_end/testcases/bug32426.dart.hierarchy.expect
new file mode 100644
index 0000000..9e96032
--- /dev/null
+++ b/pkg/front_end/testcases/bug32426.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    I.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/bug32629.dart.hierarchy.expect b/pkg/front_end/testcases/bug32629.dart.hierarchy.expect
new file mode 100644
index 0000000..9aca183
--- /dev/null
+++ b/pkg/front_end/testcases/bug32629.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/bug32866.dart.hierarchy.expect b/pkg/front_end/testcases/bug32866.dart.hierarchy.expect
new file mode 100644
index 0000000..74b5528
--- /dev/null
+++ b/pkg/front_end/testcases/bug32866.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/bug33099.dart.hierarchy.expect b/pkg/front_end/testcases/bug33099.dart.hierarchy.expect
new file mode 100644
index 0000000..883d29c
--- /dev/null
+++ b/pkg/front_end/testcases/bug33099.dart.hierarchy.expect
@@ -0,0 +1,117 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_FailingTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+MyTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyTest.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with MyTest:
+  superclasses:
+    Object
+  interfaces: MyTest
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyTest.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyTest.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+MyTest2:
+  superclasses:
+    Object
+      -> _MyTest2&Object&MyTest
+  interfaces: MyTest
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyTest.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyTest.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/bug33099.dart.outline.expect b/pkg/front_end/testcases/bug33099.dart.outline.expect
index 94c81bb..42a5b20 100644
--- a/pkg/front_end/testcases/bug33099.dart.outline.expect
+++ b/pkg/front_end/testcases/bug33099.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:mirrors" as mir;
 
+import "dart:mirrors";
+
 class _FailingTest extends core::Object {
   const constructor •() → self::_FailingTest
     ;
diff --git a/pkg/front_end/testcases/bug33099.dart.strong.expect b/pkg/front_end/testcases/bug33099.dart.strong.expect
index 4fb89b3..978c12b 100644
--- a/pkg/front_end/testcases/bug33099.dart.strong.expect
+++ b/pkg/front_end/testcases/bug33099.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:mirrors" as mir;
 
+import "dart:mirrors";
+
 class _FailingTest extends core::Object {
   const constructor •() → self::_FailingTest
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/bug33099.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33099.dart.strong.transformed.expect
index 5ad81b8..1a0aaa1 100644
--- a/pkg/front_end/testcases/bug33099.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug33099.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:mirrors" as mir;
 
+import "dart:mirrors";
+
 class _FailingTest extends core::Object {
   const constructor •() → self::_FailingTest
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/bug33196.dart.legacy.expect b/pkg/front_end/testcases/bug33196.dart.legacy.expect
index 4baad60..70357f0 100644
--- a/pkg/front_end/testcases/bug33196.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug33196.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method main() → dynamic {
   dynamic result = self::returnsString();
   core::print(result.runtimeType);
diff --git a/pkg/front_end/testcases/bug33196.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug33196.dart.legacy.transformed.expect
index 8f79612..00e49aa 100644
--- a/pkg/front_end/testcases/bug33196.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug33196.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method main() → dynamic {
   dynamic result = self::returnsString();
   core::print(result.runtimeType);
diff --git a/pkg/front_end/testcases/bug33196.dart.outline.expect b/pkg/front_end/testcases/bug33196.dart.outline.expect
index e640af1..09ab950 100644
--- a/pkg/front_end/testcases/bug33196.dart.outline.expect
+++ b/pkg/front_end/testcases/bug33196.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic
   ;
 static method returnsString() → asy::FutureOr<core::String>
diff --git a/pkg/front_end/testcases/bug33196.dart.strong.expect b/pkg/front_end/testcases/bug33196.dart.strong.expect
index d8e9475..95912f8 100644
--- a/pkg/front_end/testcases/bug33196.dart.strong.expect
+++ b/pkg/front_end/testcases/bug33196.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic {
   asy::FutureOr<core::String> result = self::returnsString();
   core::print(result.{core::Object::runtimeType});
diff --git a/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect
index 1b395b7..6e20cd1 100644
--- a/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic {
   asy::FutureOr<core::String> result = self::returnsString();
   core::print(result.{core::Object::runtimeType});
diff --git a/pkg/front_end/testcases/bug33206.dart.hierarchy.expect b/pkg/front_end/testcases/bug33206.dart.hierarchy.expect
new file mode 100644
index 0000000..84bd4d6
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    X.y
+    X.toString
+    X.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Y:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Y.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/bug33206.dart.legacy.expect b/pkg/front_end/testcases/bug33206.dart.legacy.expect
index 504c440..b0dba95 100644
--- a/pkg/front_end/testcases/bug33206.dart.legacy.expect
+++ b/pkg/front_end/testcases/bug33206.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class X extends core::Object {
   final field dynamic x;
   final field dynamic y;
diff --git a/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect b/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
index e19e82a..2a26c19 100644
--- a/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/bug33206.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class X extends core::Object {
   final field dynamic x;
   final field dynamic y;
diff --git a/pkg/front_end/testcases/bug33206.dart.outline.expect b/pkg/front_end/testcases/bug33206.dart.outline.expect
index ecb824e..95d83e8 100644
--- a/pkg/front_end/testcases/bug33206.dart.outline.expect
+++ b/pkg/front_end/testcases/bug33206.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class X extends core::Object {
   final field dynamic x;
   final field dynamic y;
diff --git a/pkg/front_end/testcases/bug33206.dart.strong.expect b/pkg/front_end/testcases/bug33206.dart.strong.expect
index 77e20c5..a95aaef 100644
--- a/pkg/front_end/testcases/bug33206.dart.strong.expect
+++ b/pkg/front_end/testcases/bug33206.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class X extends core::Object {
   final field dynamic x;
   final field dynamic y;
diff --git a/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
index 217f7b0..750e012 100644
--- a/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class X extends core::Object {
   final field dynamic x;
   final field dynamic y;
diff --git a/pkg/front_end/testcases/bug33298.dart.hierarchy.expect b/pkg/front_end/testcases/bug33298.dart.hierarchy.expect
new file mode 100644
index 0000000..874d1b7
--- /dev/null
+++ b/pkg/front_end/testcases/bug33298.dart.hierarchy.expect
@@ -0,0 +1,73 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/bug33298.dart.strong.expect b/pkg/front_end/testcases/bug33298.dart.strong.expect
index ec9f90e..05c9f38 100644
--- a/pkg/front_end/testcases/bug33298.dart.strong.expect
+++ b/pkg/front_end/testcases/bug33298.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
 // Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
 //   List<String> list6 = ['a', 'b', 'c'].map(c).toList();
 //                                            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug33298.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33298.dart.strong.transformed.expect
index dd96420..05c9f38 100644
--- a/pkg/front_end/testcases/bug33298.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/bug33298.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/bug33298.dart:28:44: Error: The argument type 'T Function<T>(T)' can't be assigned to the parameter type 'dynamic Function(String)'.
+// Try changing the type of the parameter, or casting the argument to 'dynamic Function(String)'.
+//   List<String> list6 = ['a', 'b', 'c'].map(c).toList();
+//                                            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/bug34511.dart.hierarchy.expect b/pkg/front_end/testcases/bug34511.dart.hierarchy.expect
new file mode 100644
index 0000000..60cd20b
--- /dev/null
+++ b/pkg/front_end/testcases/bug34511.dart.hierarchy.expect
@@ -0,0 +1,95 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with A<() -> Z>:
+  superclasses:
+    Object
+  interfaces: A<() -> Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B:
+  superclasses:
+    Object
+      -> _B&Object&A<Z>
+  interfaces: A<() -> Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/bug35470.dart.hierarchy.expect b/pkg/front_end/testcases/bug35470.dart.hierarchy.expect
new file mode 100644
index 0000000..be0da75
--- /dev/null
+++ b/pkg/front_end/testcases/bug35470.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<dynamic>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/call.dart.hierarchy.expect b/pkg/front_end/testcases/call.dart.hierarchy.expect
new file mode 100644
index 0000000..b10a126
--- /dev/null
+++ b/pkg/front_end/testcases/call.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Callable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Callable.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+CallableGetter:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    CallableGetter.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/call.dart.strong.expect b/pkg/front_end/testcases/call.dart.strong.expect
index 03a252d..56f00c1 100644
--- a/pkg/front_end/testcases/call.dart.strong.expect
+++ b/pkg/front_end/testcases/call.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/call.dart:29:31: 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/call.dart'.
@@ -43,42 +45,7 @@
 // Try changing 'call' to a method or explicitly invoke 'call'.
 //   var nothing9 = callableGetter();
 //                                ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/call.dart:34:25: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing1 = closure();
-//                         ^
-//
-// pkg/front_end/testcases/call.dart:35:30: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing2 = closure.call();
-//                              ^
-//
-// pkg/front_end/testcases/call.dart:36:35: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing3 = closure.call.call();
-//                                   ^
-//
-// pkg/front_end/testcases/call.dart:37:40: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing4 = closure.call.call.call();
-//                                        ^
-//
-// pkg/front_end/testcases/call.dart:39:26: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing5 = callable();
-//                          ^
-//
-// pkg/front_end/testcases/call.dart:40:31: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing6 = callable.call();
-//                               ^
-//
-// pkg/front_end/testcases/call.dart:41:36: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing7 = callable.call.call();
-//                                    ^
-//
-// pkg/front_end/testcases/call.dart:42:41: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing8 = callable.call.call.call();
-//                                         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/cascade.dart.strong.expect b/pkg/front_end/testcases/cascade.dart.strong.expect
index 9595c80..410fa63 100644
--- a/pkg/front_end/testcases/cascade.dart.strong.expect
+++ b/pkg/front_end/testcases/cascade.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
 //  - 'List' is from 'dart:core'.
@@ -20,8 +22,7 @@
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
 //     ..[0].last.toString();
 //           ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -36,15 +37,15 @@
  - 'List' is from 'dart:core'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
     [1]
-    ^" in <core::int>[1] as{TypeError} core::int] in let final dynamic #t15 = (let final dynamic #t16 = #t13.{core::Iterable::first} in invalid-expression "pkg/front_end/testcases/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
+    ^" in <core::int>[1] as{TypeError} core::int] in let final dynamic #t15 = invalid-expression "pkg/front_end/testcases/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
     ..first.last.toString()
-            ^^^^").{core::Object::toString}() in let final dynamic #t17 = (let final dynamic #t18 = #t13.{core::Iterable::first} in invalid-expression "pkg/front_end/testcases/cascade.dart:29:12: Error: The method '[]' isn't defined for the class 'int'.
+            ^^^^".{core::Object::toString}() in let final dynamic #t16 = invalid-expression "pkg/front_end/testcases/cascade.dart:29:12: Error: The method '[]' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named '[]'.
     ..first[0].toString()
-           ^^").{core::Object::toString}() in let final dynamic #t19 = (let final dynamic #t20 = #t13.{core::List::[]}(0) in invalid-expression "pkg/front_end/testcases/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
+           ^^".{core::Object::toString}() in let final dynamic #t17 = invalid-expression "pkg/front_end/testcases/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
     ..[0].last.toString();
-          ^^^^").{core::Object::toString}() in #t13;
+          ^^^^".{core::Object::toString}() in #t13;
   core::print(list);
 }
diff --git a/pkg/front_end/testcases/cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/cascade.dart.strong.transformed.expect
index 896f686..0c5c75b 100644
--- a/pkg/front_end/testcases/cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/cascade.dart.strong.transformed.expect
@@ -1,4 +1,28 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/cascade.dart:26:5: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     [1]
+//     ^
+//
+// pkg/front_end/testcases/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
+//     ..first.last.toString()
+//             ^^^^
+//
+// pkg/front_end/testcases/cascade.dart:29:12: Error: The method '[]' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named '[]'.
+//     ..first[0].toString()
+//            ^^
+//
+// pkg/front_end/testcases/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
+//     ..[0].last.toString();
+//           ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -13,15 +37,15 @@
  - 'List' is from 'dart:core'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
     [1]
-    ^" in <core::int>[1] as{TypeError} core::int] in let final core::String #t15 = (let final core::int #t16 = #t13.{core::Iterable::first} in invalid-expression "pkg/front_end/testcases/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
+    ^" in <core::int>[1] as{TypeError} core::int] in let final core::String #t15 = invalid-expression "pkg/front_end/testcases/cascade.dart:28:13: Error: The getter 'last' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
     ..first.last.toString()
-            ^^^^").{core::Object::toString}() in let final core::String #t17 = (let final core::int #t18 = #t13.{core::Iterable::first} in invalid-expression "pkg/front_end/testcases/cascade.dart:29:12: Error: The method '[]' isn't defined for the class 'int'.
+            ^^^^".{core::Object::toString}() in let final core::String #t16 = invalid-expression "pkg/front_end/testcases/cascade.dart:29:12: Error: The method '[]' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named '[]'.
     ..first[0].toString()
-           ^^").{core::Object::toString}() in let final core::String #t19 = (let final core::int #t20 = #t13.{core::List::[]}(0) in invalid-expression "pkg/front_end/testcases/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
+           ^^".{core::Object::toString}() in let final core::String #t17 = invalid-expression "pkg/front_end/testcases/cascade.dart:30:11: Error: The getter 'last' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'last'.
     ..[0].last.toString();
-          ^^^^").{core::Object::toString}() in #t13;
+          ^^^^".{core::Object::toString}() in #t13;
   core::print(list);
 }
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect
index 25dc9b8..5167dc9 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect
index 25dc9b8..5167dc9 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.legacy.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
index 25dc9b8..799a3cd 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
index d62c43e..494d25e 100644
--- a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.expect
index e585f88..6418d22 100644
--- a/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.expect
@@ -1,15 +1,34 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Warning: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
 //   x as lib.C;
 //        ^^^^^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   x as invalid-type;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.transformed.expect
index d17f162..6418d22 100644
--- a/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.legacy.transformed.expect
@@ -1,7 +1,34 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Warning: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
+//   x as lib.C;
+//        ^^^^^
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   x as invalid-type;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect
index dc16c61..830d284 100644
--- a/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test(dynamic x) → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect
index 36f0884..a3e98a8 100644
--- a/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect
@@ -1,23 +1,34 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
-//   x as lib.C;
-//        ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
-//   x as lib.C;
-//        ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
+//   x as lib.C;
+//        ^^^^^
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   x as invalid-type;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect
index 0535600..a3e98a8 100644
--- a/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect
@@ -1,15 +1,34 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
 //   x as lib.C;
 //        ^^^^^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   x as invalid-type;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect
index 0ff5bf9..908e7aa 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2();
@@ -9,3 +11,19 @@
 }
 static method m2() → dynamic
   return 1;
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect
index 0ff5bf9..908e7aa 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2();
@@ -9,3 +11,19 @@
 }
 static method m2() → dynamic
   return 1;
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect
index 8140e58..c9dc58d 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect
@@ -1,9 +1,26 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
 static method m2() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
index 3748727..b570941 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
@@ -3,6 +3,8 @@
 import "./deferred_lib.dart" as def;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2() as{TypeError} core::int;
@@ -10,3 +12,19 @@
 }
 static method m2() → dynamic
   return 1;
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
index 0cf7c47..1ea2a3f 100644
--- a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2() as{TypeError} core::int;
@@ -10,3 +12,19 @@
 }
 static method m2() → dynamic
   return 1;
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect
index 5b1c7ee..e9712c6 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic async {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(await LoadLibrary(lib));
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect
index f04ef3d..7f12556 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
@@ -33,3 +35,19 @@
   :async_completer.start(:async_op);
   return :async_completer.{asy::Completer::future};
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
index 5b1c7ee..db0bb07 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic async {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(await LoadLibrary(lib));
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
index 6821c33..5ac3a08 100644
--- a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
@@ -4,6 +4,8 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
@@ -34,3 +36,19 @@
   :async_completer.start(:async_op);
   return :async_completer.{asy::Completer::future};
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect
index 9aef4cf..2a8fcd5 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect
index 9aef4cf..2a8fcd5 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.legacy.transformed.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
index 9aef4cf..a4a8839 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
index 1eb7ae1..2b6f45a 100644
--- a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect
index 2b7ef3d..d1bc459 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect
index 2b7ef3d..d1bc459 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.legacy.transformed.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
index 2b7ef3d..cf5fce5 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
@@ -2,7 +2,25 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
index d51e9f3..a6a7f4a 100644
--- a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.expect
index 05661c8..0c3eb41 100644
--- a/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.expect
@@ -1,16 +1,35 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Warning: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
 //   print(x is lib.C);
 //              ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   core::print(x is invalid-type);
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.transformed.expect
index 8fa0c48..0c3eb41 100644
--- a/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.legacy.transformed.expect
@@ -1,8 +1,35 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Warning: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
+//   print(x is lib.C);
+//              ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   core::print(x is invalid-type);
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect
index dc16c61..830d284 100644
--- a/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test(dynamic x) → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect
index 1daf3c3..66f4760 100644
--- a/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect
@@ -1,24 +1,35 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
-//   print(x is lib.C);
-//              ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
-//   print(x is lib.C);
-//              ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
+//   print(x is lib.C);
+//              ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   core::print(x is invalid-type);
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect
index 8065802..66f4760 100644
--- a/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect
@@ -1,16 +1,35 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
 //   print(x is lib.C);
 //              ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test(dynamic x) → dynamic {
   core::print(x is invalid-type);
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_read.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect
index 5fd285b..175fa7c 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.legacy.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print((let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x).+(1));
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect
index 5fd285b..175fa7c 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.legacy.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print((let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x).+(1));
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.outline.expect b/pkg/front_end/testcases/check_deferred_read.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
index 9c00ad0..1af399d 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print((let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x).{core::num::+}(1));
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
index f01fe12..daa8674 100644
--- a/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print((let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::x).{core::num::+}(1));
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect
index 7b3c2df..60e13fd 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect
index 7b3c2df..60e13fd 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.legacy.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
index 7b3c2df..90d44a4 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
index a3557a6..ed7f244 100644
--- a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect
index 4c3620c..3982934 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect
index 4c3620c..3982934 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.legacy.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
index 4c3620c..d62739e 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
index 555229f..747f240 100644
--- a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::C);
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect
index 05236e5..a054b09 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect
index 05236e5..a054b09 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.legacy.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
index 05236e5..6ee7c79 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
index c5ab3c3..cfe8c33 100644
--- a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
@@ -3,7 +3,25 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
 }
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.hierarchy.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.expect
index a97b88b..28e75e9 100644
--- a/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.expect
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.expect
@@ -1,16 +1,35 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Warning: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
 //   lib.C x = null;
 //   ^^^^^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   return self::test();
 static method test() → dynamic {
   invalid-type x = null;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.transformed.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.transformed.expect
index fe4fe2e..28e75e9 100644
--- a/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.legacy.transformed.expect
@@ -1,8 +1,35 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Warning: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
+//   lib.C x = null;
+//   ^^^^^
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   return self::test();
 static method test() → dynamic {
   invalid-type x = null;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect
index 7a4d537..6a4b7e5 100644
--- a/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect
@@ -1,7 +1,24 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → self2::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect
index f52f89c..923df91 100644
--- a/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect
@@ -1,24 +1,35 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
-//   lib.C x = null;
-//   ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
-//   lib.C x = null;
-//   ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
+//   lib.C x = null;
+//   ^^^^^
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   return self::test();
 static method test() → dynamic {
   invalid-type x = null;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect
index 71debcb..923df91 100644
--- a/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect
@@ -1,16 +1,35 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Error: The type 'C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'lib' or use a supertype of 'C' that isn't deferred.
 //   lib.C x = null;
 //   ^^^^^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   return self::test();
 static method test() → dynamic {
   invalid-type x = null;
 }
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.hierarchy.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.hierarchy.expect
new file mode 100644
index 0000000..0f300a8
--- /dev/null
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect
index 4dd15b2..f034fa3 100644
--- a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/circularity-via-initializing-formal.dart:15:3: Error: Can't infer the type of 'C._circular': circularity found during type inference.
-// Specify the type explicitly.
-//   C._circular(this.f);
-//   ^^^^^^^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/circularity-via-initializing-formal.dart:15:3: Error: Can't infer the type of 'C._circular': circularity found during type inference.
-// Specify the type explicitly.
-//   C._circular(this.f);
-//   ^^^^^^^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/circularity-via-initializing-formal.dart:15:3: Error: Can't infer the type of 'C._circular': circularity found during type inference.
+// Specify the type explicitly.
+//   C._circular(this.f);
+//   ^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect
index 7ec754c..f034fa3 100644
--- a/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/circularity-via-initializing-formal.dart.strong.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/circularity-via-initializing-formal.dart:15:3: Error: Can't infer the type of 'C._circular': circularity found during type inference.
 // Specify the type explicitly.
 //   C._circular(this.f);
 //   ^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/classes.dart.hierarchy.expect b/pkg/front_end/testcases/classes.dart.hierarchy.expect
new file mode 100644
index 0000000..e6e65a3
--- /dev/null
+++ b/pkg/front_end/testcases/classes.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/clone_function_type.dart.hierarchy.expect b/pkg/front_end/testcases/clone_function_type.dart.hierarchy.expect
new file mode 100644
index 0000000..aa9301e
--- /dev/null
+++ b/pkg/front_end/testcases/clone_function_type.dart.hierarchy.expect
@@ -0,0 +1,2953 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Am1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with Am1<(null) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Bm1:
+  superclasses:
+    Object
+      -> _Bm1&Object&Am1<Z>
+  interfaces: Am1<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<(x) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Cm1:
+  superclasses:
+    Object
+      -> _Cm1&Object&Am1<Z>
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<() -> int, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<() -> int, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Dm1:
+  superclasses:
+    Object
+      -> _Dm1&Object&Am1<Z>
+  interfaces: Am1<() -> int, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<() -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Em1:
+  superclasses:
+    Object
+      -> _Em1&Object&Am1<Z>
+  interfaces: Am1<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<() -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Fm1:
+  superclasses:
+    Object
+      -> _Fm1&Object&Am1<Z>
+  interfaces: Am1<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<(x) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Gm1:
+  superclasses:
+    Object
+      -> _Gm1&Object&Am1<Z>
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<(null) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Hm1:
+  superclasses:
+    Object
+      -> _Hm1&Object&Am1<Z>
+  interfaces: Am1<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<(x) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Im1:
+  superclasses:
+    Object
+      -> _Im1&Object&Am1<Z>
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<Function, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<Function, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Jm1:
+  superclasses:
+    Object
+      -> _Jm1&Object&Am1<Z>
+  interfaces: Am1<Function, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<(Function) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<(Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Km1:
+  superclasses:
+    Object
+      -> _Km1&Object&Am1<Z>
+  interfaces: Am1<(Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am1<() -> (Function) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am1<() -> (Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Lm1:
+  superclasses:
+    Object
+      -> _Lm1&Object&Am1<Z>
+  interfaces: Am1<() -> (Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Mm1:
+  superclasses:
+    Object
+  interfaces: Am1<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Nm1:
+  superclasses:
+    Object
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Om1:
+  superclasses:
+    Object
+  interfaces: Am1<() -> int, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Pm1:
+  superclasses:
+    Object
+  interfaces: Am1<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Qm1:
+  superclasses:
+    Object
+  interfaces: Am1<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Rm1:
+  superclasses:
+    Object
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Sm1:
+  superclasses:
+    Object
+  interfaces: Am1<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Tm1:
+  superclasses:
+    Object
+  interfaces: Am1<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Um1:
+  superclasses:
+    Object
+  interfaces: Am1<Function, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Vm1:
+  superclasses:
+    Object
+  interfaces: Am1<(Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Wm1:
+  superclasses:
+    Object
+  interfaces: Am1<() -> (Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Am2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with Am2<(null) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Bm2:
+  superclasses:
+    Object
+      -> _Bm2&Object&Am2<Z>
+  interfaces: Am2<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<(x) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Cm2:
+  superclasses:
+    Object
+      -> _Cm2&Object&Am2<Z>
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<() -> int, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<() -> int, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Dm2:
+  superclasses:
+    Object
+      -> _Dm2&Object&Am2<Z>
+  interfaces: Am2<() -> int, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<() -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Em2:
+  superclasses:
+    Object
+      -> _Em2&Object&Am2<Z>
+  interfaces: Am2<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<() -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Fm2:
+  superclasses:
+    Object
+      -> _Fm2&Object&Am2<Z>
+  interfaces: Am2<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<(x) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Gm2:
+  superclasses:
+    Object
+      -> _Gm2&Object&Am2<Z>
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<(null) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Hm2:
+  superclasses:
+    Object
+      -> _Hm2&Object&Am2<Z>
+  interfaces: Am2<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<(x) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Im2:
+  superclasses:
+    Object
+      -> _Im2&Object&Am2<Z>
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<Function, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<Function, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Jm2:
+  superclasses:
+    Object
+      -> _Jm2&Object&Am2<Z>
+  interfaces: Am2<Function, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<(Function) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<(Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Km2:
+  superclasses:
+    Object
+      -> _Km2&Object&Am2<Z>
+  interfaces: Am2<(Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am2<() -> (Function) -> null, Z>:
+  superclasses:
+    Object
+  interfaces: Am2<() -> (Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Lm2:
+  superclasses:
+    Object
+      -> _Lm2&Object&Am2<Z>
+  interfaces: Am2<() -> (Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Mm2:
+  superclasses:
+    Object
+  interfaces: Am2<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Nm2:
+  superclasses:
+    Object
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Om2:
+  superclasses:
+    Object
+  interfaces: Am2<() -> int, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Pm2:
+  superclasses:
+    Object
+  interfaces: Am2<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Qm2:
+  superclasses:
+    Object
+  interfaces: Am2<() -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Rm2:
+  superclasses:
+    Object
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Sm2:
+  superclasses:
+    Object
+  interfaces: Am2<(null) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Tm2:
+  superclasses:
+    Object
+  interfaces: Am2<(x) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Um2:
+  superclasses:
+    Object
+  interfaces: Am2<Function, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Vm2:
+  superclasses:
+    Object
+  interfaces: Am2<(Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Wm2:
+  superclasses:
+    Object
+  interfaces: Am2<() -> (Function) -> null, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Am3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with Am3<TdB, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdB, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Bm3:
+  superclasses:
+    Object
+      -> _Bm3&Object&Am3<Z>
+  interfaces: Am3<TdB, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdC, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdC, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Cm3:
+  superclasses:
+    Object
+      -> _Cm3&Object&Am3<Z>
+  interfaces: Am3<TdC, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdD, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdD, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Dm3:
+  superclasses:
+    Object
+      -> _Dm3&Object&Am3<Z>
+  interfaces: Am3<TdD, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdE, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdE, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Em3:
+  superclasses:
+    Object
+      -> _Em3&Object&Am3<Z>
+  interfaces: Am3<TdE, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdF, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdF, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Fm3:
+  superclasses:
+    Object
+      -> _Fm3&Object&Am3<Z>
+  interfaces: Am3<TdF, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdG, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdG, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Gm3:
+  superclasses:
+    Object
+      -> _Gm3&Object&Am3<Z>
+  interfaces: Am3<TdG, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdH, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdH, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Hm3:
+  superclasses:
+    Object
+      -> _Hm3&Object&Am3<Z>
+  interfaces: Am3<TdH, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdI, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdI, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Im3:
+  superclasses:
+    Object
+      -> _Im3&Object&Am3<Z>
+  interfaces: Am3<TdI, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdJ, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdJ, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Jm3:
+  superclasses:
+    Object
+      -> _Jm3&Object&Am3<Z>
+  interfaces: Am3<TdJ, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with Am3<TdK, Z>:
+  superclasses:
+    Object
+  interfaces: Am3<TdK, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Km3:
+  superclasses:
+    Object
+      -> _Km3&Object&Am3<Z>
+  interfaces: Am3<TdK, Z>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Af1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bf1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Cf1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Df1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Ef1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Ff1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Gf1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hf1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+If1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Jf1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Kf1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bf2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Cf2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Df2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Ef2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Ff2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Gf2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hf2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+If2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Jf2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Kf2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/clone_function_type.dart.legacy.expect b/pkg/front_end/testcases/clone_function_type.dart.legacy.expect
index ef2a4c6..3b90c1f 100644
--- a/pkg/front_end/testcases/clone_function_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/clone_function_type.dart.legacy.expect
@@ -1,56 +1,31 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
-// class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:46:45: Error: Expected an identifier, but got '}'.
-// class Qm1<Z> = Object with Am1<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:77:51: Error: Expected an identifier, but got '}'.
-// class Fm2<Z> extends Object with Am2<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:105:45: Error: Expected an identifier, but got '}'.
-// class Qm2<Z> = Object with Am2<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:134:28: Error: Expected an identifier, but got '}'.
-// typedef TdF = Function({int});
-//                            ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
-// class Ef1<X extends Function({int})> {
-//                                  ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
-// class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:46:45: Error: Expected an identifier, but got '}'.
-// class Qm1<Z> = Object with Am1<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:77:51: Error: Expected an identifier, but got '}'.
-// class Fm2<Z> extends Object with Am2<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:105:45: Error: Expected an identifier, but got '}'.
-// class Qm2<Z> = Object with Am2<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:134:28: Error: Expected an identifier, but got '}'.
-// typedef TdF = Function({int});
-//                            ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
-// class Ef1<X extends Function({int})> {
-//                                  ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
+// class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
+//                                                   ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:46:45: Error: Expected an identifier, but got '}'.
+// class Qm1<Z> = Object with Am1<Function({int}), Z>;
+//                                             ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:77:51: Error: Expected an identifier, but got '}'.
+// class Fm2<Z> extends Object with Am2<Function({int}), Z> {}
+//                                                   ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:105:45: Error: Expected an identifier, but got '}'.
+// class Qm2<Z> = Object with Am2<Function({int}), Z>;
+//                                             ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:134:28: Error: Expected an identifier, but got '}'.
+// typedef TdF = Function({int});
+//                            ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
+// class Ef1<X extends Function({int})> {
+//                                  ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/clone_function_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/clone_function_type.dart.legacy.transformed.expect
index 5523c08..69865bd 100644
--- a/pkg/front_end/testcases/clone_function_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/clone_function_type.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
 // class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
 // class Ef1<X extends Function({int})> {
 //                                  ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/clone_function_type.dart.outline.expect b/pkg/front_end/testcases/clone_function_type.dart.outline.expect
index 6d46fb3..38d30b8 100644
--- a/pkg/front_end/testcases/clone_function_type.dart.outline.expect
+++ b/pkg/front_end/testcases/clone_function_type.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
 // class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
 // class Ef1<X extends Function({int})> {
 //                                  ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/clone_function_type.dart.strong.expect b/pkg/front_end/testcases/clone_function_type.dart.strong.expect
index 993f5a8..8263903 100644
--- a/pkg/front_end/testcases/clone_function_type.dart.strong.expect
+++ b/pkg/front_end/testcases/clone_function_type.dart.strong.expect
@@ -1,168 +1,99 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
-// class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:46:45: Error: Expected an identifier, but got '}'.
-// class Qm1<Z> = Object with Am1<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:77:51: Error: Expected an identifier, but got '}'.
-// class Fm2<Z> extends Object with Am2<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:105:45: Error: Expected an identifier, but got '}'.
-// class Qm2<Z> = Object with Am2<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:134:28: Error: Expected an identifier, but got '}'.
-// typedef TdF = Function({int});
-//                            ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
-// class Ef1<X extends Function({int})> {
-//                                  ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:67:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Bm2<Z> extends Object with Am2<Function(int), Z> {}
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:70:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Cm2<Z> extends Object with Am2<Function(int x), Z> {}
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:86:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Jm2<Z> extends Object with Am2<Function, Z> {}
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:89:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Km2<Z> extends Object with Am2<Function(Function Function), Z> {}
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:95:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Mm2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Mm2<Z> = Object with Am2<Function(int), Z>;
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:98:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Nm2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Nm2<Z> = Object with Am2<Function(int x), Z>;
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:114:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Um2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Um2<Z> = Object with Am2<Function, Z>;
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:117:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Vm2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Vm2<Z> = Object with Am2<Function(Function Function), Z>;
-//       ^
-// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
-// class Am2<X extends Function(), Y> {}
-//           ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
-// class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:46:45: Error: Expected an identifier, but got '}'.
-// class Qm1<Z> = Object with Am1<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:77:51: Error: Expected an identifier, but got '}'.
-// class Fm2<Z> extends Object with Am2<Function({int}), Z> {}
-//                                                   ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:105:45: Error: Expected an identifier, but got '}'.
-// class Qm2<Z> = Object with Am2<Function({int}), Z>;
-//                                             ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:134:28: Error: Expected an identifier, but got '}'.
-// typedef TdF = Function({int});
-//                            ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
-// class Ef1<X extends Function({int})> {
-//                                  ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:67:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Bm2<Z> extends Object with Am2<Function(int), Z> {}
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:70:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Cm2<Z> extends Object with Am2<Function(int x), Z> {}
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:86:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Jm2<Z> extends Object with Am2<Function, Z> {}
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:89:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Km2<Z> extends Object with Am2<Function(Function Function), Z> {}
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:95:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Mm2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Mm2<Z> = Object with Am2<Function(int), Z>;
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:98:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Nm2'.
-// Try changing type arguments so that they conform to the bounds.
-// class Nm2<Z> = Object with Am2<Function(int x), Z>;
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:114:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Um2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Um2<Z> = Object with Am2<Function, Z>;
-//       ^
-//
-// pkg/front_end/testcases/clone_function_type.dart:117:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Vm2'.
-//  - 'Function' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class Vm2<Z> = Object with Am2<Function(Function Function), Z>;
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
+// class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
+//                                                   ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:46:45: Error: Expected an identifier, but got '}'.
+// class Qm1<Z> = Object with Am1<Function({int}), Z>;
+//                                             ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:77:51: Error: Expected an identifier, but got '}'.
+// class Fm2<Z> extends Object with Am2<Function({int}), Z> {}
+//                                                   ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:105:45: Error: Expected an identifier, but got '}'.
+// class Qm2<Z> = Object with Am2<Function({int}), Z>;
+//                                             ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:134:28: Error: Expected an identifier, but got '}'.
+// typedef TdF = Function({int});
+//                            ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:190:34: Error: Expected an identifier, but got '}'.
+// class Ef1<X extends Function({int})> {
+//                                  ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:67:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
+// Try changing type arguments so that they conform to the bounds.
+// class Bm2<Z> extends Object with Am2<Function(int), Z> {}
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:70:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
+// Try changing type arguments so that they conform to the bounds.
+// class Cm2<Z> extends Object with Am2<Function(int x), Z> {}
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:86:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
+//  - 'Function' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+// class Jm2<Z> extends Object with Am2<Function, Z> {}
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:89:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
+//  - 'Function' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+// class Km2<Z> extends Object with Am2<Function(Function Function), Z> {}
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:95:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Mm2'.
+// Try changing type arguments so that they conform to the bounds.
+// class Mm2<Z> = Object with Am2<Function(int), Z>;
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:98:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Nm2'.
+// Try changing type arguments so that they conform to the bounds.
+// class Nm2<Z> = Object with Am2<Function(int x), Z>;
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:114:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Um2'.
+//  - 'Function' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+// class Um2<Z> = Object with Am2<Function, Z>;
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
+// pkg/front_end/testcases/clone_function_type.dart:117:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Vm2'.
+//  - 'Function' is from 'dart:core'.
+// Try changing type arguments so that they conform to the bounds.
+// class Vm2<Z> = Object with Am2<Function(Function Function), Z>;
+//       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/clone_function_type.dart.strong.transformed.expect b/pkg/front_end/testcases/clone_function_type.dart.strong.transformed.expect
index 6c6a057..30416cc 100644
--- a/pkg/front_end/testcases/clone_function_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/clone_function_type.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/clone_function_type.dart:22:51: Error: Expected an identifier, but got '}'.
 // class Fm1<Z> extends Object with Am1<Function({int}), Z> {}
@@ -28,47 +30,70 @@
 // Try changing type arguments so that they conform to the bounds.
 // class Bm2<Z> extends Object with Am2<Function(int), Z> {}
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:70:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
 // Try changing type arguments so that they conform to the bounds.
 // class Cm2<Z> extends Object with Am2<Function(int x), Z> {}
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:86:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
 //  - 'Function' is from 'dart:core'.
 // Try changing type arguments so that they conform to the bounds.
 // class Jm2<Z> extends Object with Am2<Function, Z> {}
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:89:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Object with Am2'.
 //  - 'Function' is from 'dart:core'.
 // Try changing type arguments so that they conform to the bounds.
 // class Km2<Z> extends Object with Am2<Function(Function Function), Z> {}
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:95:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Mm2'.
 // Try changing type arguments so that they conform to the bounds.
 // class Mm2<Z> = Object with Am2<Function(int), Z>;
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:98:7: Error: Type argument 'dynamic Function(int)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Nm2'.
 // Try changing type arguments so that they conform to the bounds.
 // class Nm2<Z> = Object with Am2<Function(int x), Z>;
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:114:7: Error: Type argument 'Function' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Um2'.
 //  - 'Function' is from 'dart:core'.
 // Try changing type arguments so that they conform to the bounds.
 // class Um2<Z> = Object with Am2<Function, Z>;
 //       ^
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
 //
 // pkg/front_end/testcases/clone_function_type.dart:117:7: Error: Type argument 'dynamic Function(Function)' doesn't conform to the bound 'dynamic Function()' of the type variable 'X' on 'Am2' in the supertype 'Am2' of class 'Vm2'.
 //  - 'Function' is from 'dart:core'.
 // Try changing type arguments so that they conform to the bounds.
 // class Vm2<Z> = Object with Am2<Function(Function Function), Z>;
 //       ^
-
-library;
+// pkg/front_end/testcases/clone_function_type.dart:64:11: Context: This is the type variable whose bound isn't conformed to.
+// class Am2<X extends Function(), Y> {}
+//           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/closure.dart.hierarchy.expect b/pkg/front_end/testcases/closure.dart.hierarchy.expect
new file mode 100644
index 0000000..986244a
--- /dev/null
+++ b/pkg/front_end/testcases/closure.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo._field
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.hierarchy.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.expect
index 7c45077..519be36 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
 // class B {}
@@ -10,18 +12,7 @@
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Context: Previous declaration of 'A'.
 // class A {
 //       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
-// class B {}
-// ^^^^^
-//
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
-// A()
-// ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.transformed.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.transformed.expect
index df8e79d..519be36 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
 // class B {}
@@ -7,8 +9,10 @@
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
 // A()
 // ^
-
-library;
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Context: Previous declaration of 'A'.
+// class A {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
index 0091954..ea4f386 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
 // class B {}
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Context: Previous declaration of 'A'.
 // class A {
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
index 7c45077..519be36 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
 // class B {}
@@ -10,18 +12,7 @@
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Context: Previous declaration of 'A'.
 // class A {
 //       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
-// class B {}
-// ^^^^^
-//
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
-// A()
-// ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect
index df8e79d..519be36 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:21:1: Error: Expected '{' before this.
 // class B {}
@@ -7,8 +9,10 @@
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
 // A()
 // ^
-
-library;
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Context: Previous declaration of 'A'.
+// class A {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart b/pkg/front_end/testcases/complex_class_hierarchy.dart
new file mode 100644
index 0000000..86dba1e
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.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.
+
+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 {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.hierarchy.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.hierarchy.expect
new file mode 100644
index 0000000..b3c7b13
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.hierarchy.expect
@@ -0,0 +1,459 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> A
+        -> B
+          -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+GB:
+  superclasses:
+    Object
+      -> G<B>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+GC:
+  superclasses:
+    Object
+      -> G<C>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+GD:
+  superclasses:
+    Object
+      -> G<D>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Y:
+  superclasses:
+    Object
+      -> X
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Z:
+  superclasses:
+    Object
+  interfaces: Y, X, A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+W:
+  superclasses:
+    Object
+  interfaces: Z, Y, X, A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+GX:
+  superclasses:
+    Object
+  interfaces: G<A>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+GY:
+  superclasses:
+    Object
+      -> X
+  interfaces: A, GB, G<B>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+GZ:
+  superclasses:
+    Object
+  interfaces: Y, X, A, GC, G<C>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+GW:
+  superclasses:
+    Object
+  interfaces: Z, Y, X, A, GD, G<D>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+GU:
+  superclasses:
+    Object
+      -> GW
+  interfaces: Z, Y, X, A, GD, G<D>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+GV:
+  superclasses:
+    Object
+      -> GW
+        -> GU
+  interfaces: Z, Y, X, A, GD, G<D>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.expect
new file mode 100644
index 0000000..faa6b6d
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class G<T extends self::A = dynamic> extends core::Object {
+  synthetic constructor •() → self::G<self::G::T>
+    : super core::Object::•()
+    ;
+}
+class GB extends self::G<self::B> {
+  synthetic constructor •() → self::GB
+    : super self::G::•()
+    ;
+}
+class GC extends self::G<self::C> {
+  synthetic constructor •() → self::GC
+    : super self::G::•()
+    ;
+}
+class GD extends self::G<self::D> {
+  synthetic constructor •() → self::GD
+    : super self::G::•()
+    ;
+}
+class X extends core::Object implements self::A {
+  synthetic constructor •() → self::X
+    : super core::Object::•()
+    ;
+}
+class Y extends self::X {
+  synthetic constructor •() → self::Y
+    : super self::X::•()
+    ;
+}
+class Z extends core::Object implements self::Y {
+  synthetic constructor •() → self::Z
+    : super core::Object::•()
+    ;
+}
+class W extends core::Object implements self::Z {
+  synthetic constructor •() → self::W
+    : super core::Object::•()
+    ;
+}
+class GX extends core::Object implements self::G<self::A> {
+  synthetic constructor •() → self::GX
+    : super core::Object::•()
+    ;
+}
+class GY extends self::X implements self::GB {
+  synthetic constructor •() → self::GY
+    : super self::X::•()
+    ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+  synthetic constructor •() → self::GZ
+    : super core::Object::•()
+    ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+  synthetic constructor •() → self::GW
+    : super core::Object::•()
+    ;
+}
+class GU extends self::GW {
+  synthetic constructor •() → self::GU
+    : super self::GW::•()
+    ;
+}
+class GV extends self::GU implements self::GW {
+  synthetic constructor •() → self::GV
+    : super self::GU::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.transformed.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.transformed.expect
new file mode 100644
index 0000000..faa6b6d
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.legacy.transformed.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class G<T extends self::A = dynamic> extends core::Object {
+  synthetic constructor •() → self::G<self::G::T>
+    : super core::Object::•()
+    ;
+}
+class GB extends self::G<self::B> {
+  synthetic constructor •() → self::GB
+    : super self::G::•()
+    ;
+}
+class GC extends self::G<self::C> {
+  synthetic constructor •() → self::GC
+    : super self::G::•()
+    ;
+}
+class GD extends self::G<self::D> {
+  synthetic constructor •() → self::GD
+    : super self::G::•()
+    ;
+}
+class X extends core::Object implements self::A {
+  synthetic constructor •() → self::X
+    : super core::Object::•()
+    ;
+}
+class Y extends self::X {
+  synthetic constructor •() → self::Y
+    : super self::X::•()
+    ;
+}
+class Z extends core::Object implements self::Y {
+  synthetic constructor •() → self::Z
+    : super core::Object::•()
+    ;
+}
+class W extends core::Object implements self::Z {
+  synthetic constructor •() → self::W
+    : super core::Object::•()
+    ;
+}
+class GX extends core::Object implements self::G<self::A> {
+  synthetic constructor •() → self::GX
+    : super core::Object::•()
+    ;
+}
+class GY extends self::X implements self::GB {
+  synthetic constructor •() → self::GY
+    : super self::X::•()
+    ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+  synthetic constructor •() → self::GZ
+    : super core::Object::•()
+    ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+  synthetic constructor •() → self::GW
+    : super core::Object::•()
+    ;
+}
+class GU extends self::GW {
+  synthetic constructor •() → self::GU
+    : super self::GW::•()
+    ;
+}
+class GV extends self::GU implements self::GW {
+  synthetic constructor •() → self::GV
+    : super self::GU::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.outline.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.outline.expect
new file mode 100644
index 0000000..f1265b2
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.outline.expect
@@ -0,0 +1,78 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → self::D
+    ;
+}
+class G<T extends self::A = dynamic> extends core::Object {
+  synthetic constructor •() → self::G<self::G::T>
+    ;
+}
+class GB extends self::G<self::B> {
+  synthetic constructor •() → self::GB
+    ;
+}
+class GC extends self::G<self::C> {
+  synthetic constructor •() → self::GC
+    ;
+}
+class GD extends self::G<self::D> {
+  synthetic constructor •() → self::GD
+    ;
+}
+class X extends core::Object implements self::A {
+  synthetic constructor •() → self::X
+    ;
+}
+class Y extends self::X {
+  synthetic constructor •() → self::Y
+    ;
+}
+class Z extends core::Object implements self::Y {
+  synthetic constructor •() → self::Z
+    ;
+}
+class W extends core::Object implements self::Z {
+  synthetic constructor •() → self::W
+    ;
+}
+class GX extends core::Object implements self::G<self::A> {
+  synthetic constructor •() → self::GX
+    ;
+}
+class GY extends self::X implements self::GB {
+  synthetic constructor •() → self::GY
+    ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+  synthetic constructor •() → self::GZ
+    ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+  synthetic constructor •() → self::GW
+    ;
+}
+class GU extends self::GW {
+  synthetic constructor •() → self::GU
+    ;
+}
+class GV extends self::GU implements self::GW {
+  synthetic constructor •() → self::GV
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.expect
new file mode 100644
index 0000000..1bca20f
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class G<T extends self::A = self::A> extends core::Object {
+  synthetic constructor •() → self::G<self::G::T>
+    : super core::Object::•()
+    ;
+}
+class GB extends self::G<self::B> {
+  synthetic constructor •() → self::GB
+    : super self::G::•()
+    ;
+}
+class GC extends self::G<self::C> {
+  synthetic constructor •() → self::GC
+    : super self::G::•()
+    ;
+}
+class GD extends self::G<self::D> {
+  synthetic constructor •() → self::GD
+    : super self::G::•()
+    ;
+}
+class X extends core::Object implements self::A {
+  synthetic constructor •() → self::X
+    : super core::Object::•()
+    ;
+}
+class Y extends self::X {
+  synthetic constructor •() → self::Y
+    : super self::X::•()
+    ;
+}
+class Z extends core::Object implements self::Y {
+  synthetic constructor •() → self::Z
+    : super core::Object::•()
+    ;
+}
+class W extends core::Object implements self::Z {
+  synthetic constructor •() → self::W
+    : super core::Object::•()
+    ;
+}
+class GX extends core::Object implements self::G<self::A> {
+  synthetic constructor •() → self::GX
+    : super core::Object::•()
+    ;
+}
+class GY extends self::X implements self::GB {
+  synthetic constructor •() → self::GY
+    : super self::X::•()
+    ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+  synthetic constructor •() → self::GZ
+    : super core::Object::•()
+    ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+  synthetic constructor •() → self::GW
+    : super core::Object::•()
+    ;
+}
+class GU extends self::GW {
+  synthetic constructor •() → self::GU
+    : super self::GW::•()
+    ;
+}
+class GV extends self::GU implements self::GW {
+  synthetic constructor •() → self::GV
+    : super self::GU::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.transformed.expect b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.transformed.expect
new file mode 100644
index 0000000..1bca20f
--- /dev/null
+++ b/pkg/front_end/testcases/complex_class_hierarchy.dart.strong.transformed.expect
@@ -0,0 +1,95 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class G<T extends self::A = self::A> extends core::Object {
+  synthetic constructor •() → self::G<self::G::T>
+    : super core::Object::•()
+    ;
+}
+class GB extends self::G<self::B> {
+  synthetic constructor •() → self::GB
+    : super self::G::•()
+    ;
+}
+class GC extends self::G<self::C> {
+  synthetic constructor •() → self::GC
+    : super self::G::•()
+    ;
+}
+class GD extends self::G<self::D> {
+  synthetic constructor •() → self::GD
+    : super self::G::•()
+    ;
+}
+class X extends core::Object implements self::A {
+  synthetic constructor •() → self::X
+    : super core::Object::•()
+    ;
+}
+class Y extends self::X {
+  synthetic constructor •() → self::Y
+    : super self::X::•()
+    ;
+}
+class Z extends core::Object implements self::Y {
+  synthetic constructor •() → self::Z
+    : super core::Object::•()
+    ;
+}
+class W extends core::Object implements self::Z {
+  synthetic constructor •() → self::W
+    : super core::Object::•()
+    ;
+}
+class GX extends core::Object implements self::G<self::A> {
+  synthetic constructor •() → self::GX
+    : super core::Object::•()
+    ;
+}
+class GY extends self::X implements self::GB {
+  synthetic constructor •() → self::GY
+    : super self::X::•()
+    ;
+}
+class GZ extends core::Object implements self::Y, self::GC {
+  synthetic constructor •() → self::GZ
+    : super core::Object::•()
+    ;
+}
+class GW extends core::Object implements self::Z, self::GD {
+  synthetic constructor •() → self::GW
+    : super core::Object::•()
+    ;
+}
+class GU extends self::GW {
+  synthetic constructor •() → self::GU
+    : super self::GW::•()
+    ;
+}
+class GV extends self::GU implements self::GW {
+  synthetic constructor •() → self::GV
+    : super self::GU::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/constructor_const_inference.dart.hierarchy.expect b/pkg/front_end/testcases/constructor_const_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..2a49e5e
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_const_inference.dart.hierarchy.expect
@@ -0,0 +1,75 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Y:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/constructor_cycle.dart.hierarchy.expect b/pkg/front_end/testcases/constructor_cycle.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_cycle.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/constructor_cycle.dart.legacy.expect b/pkg/front_end/testcases/constructor_cycle.dart.legacy.expect
index a2ba137..e972c9c 100644
--- a/pkg/front_end/testcases/constructor_cycle.dart.legacy.expect
+++ b/pkg/front_end/testcases/constructor_cycle.dart.legacy.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A.bar() : this.foo();
-//                  ^^^
-//
-// pkg/front_end/testcases/constructor_cycle.dart:9:9: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A() : this();
-//         ^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A.bar() : this.foo();
-//                  ^^^
-//
-// pkg/front_end/testcases/constructor_cycle.dart:9:9: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A() : this();
-//         ^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
+// Try to have all constructors eventually redirect to a non-redirecting constructor.
+//   A.bar() : this.foo();
+//                  ^^^
+//
+// pkg/front_end/testcases/constructor_cycle.dart:9:9: Error: Redirecting constructers can't be cyclic.
+// Try to have all constructors eventually redirect to a non-redirecting constructor.
+//   A() : this();
+//         ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_cycle.dart.legacy.transformed.expect b/pkg/front_end/testcases/constructor_cycle.dart.legacy.transformed.expect
index 89c1886..e972c9c 100644
--- a/pkg/front_end/testcases/constructor_cycle.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/constructor_cycle.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
 // Try to have all constructors eventually redirect to a non-redirecting constructor.
@@ -9,8 +11,7 @@
 // Try to have all constructors eventually redirect to a non-redirecting constructor.
 //   A() : this();
 //         ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_cycle.dart.strong.expect b/pkg/front_end/testcases/constructor_cycle.dart.strong.expect
index a2ba137..e972c9c 100644
--- a/pkg/front_end/testcases/constructor_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_cycle.dart.strong.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A.bar() : this.foo();
-//                  ^^^
-//
-// pkg/front_end/testcases/constructor_cycle.dart:9:9: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A() : this();
-//         ^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A.bar() : this.foo();
-//                  ^^^
-//
-// pkg/front_end/testcases/constructor_cycle.dart:9:9: Error: Redirecting constructers can't be cyclic.
-// Try to have all constructors eventually redirect to a non-redirecting constructor.
-//   A() : this();
-//         ^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
+// Try to have all constructors eventually redirect to a non-redirecting constructor.
+//   A.bar() : this.foo();
+//                  ^^^
+//
+// pkg/front_end/testcases/constructor_cycle.dart:9:9: Error: Redirecting constructers can't be cyclic.
+// Try to have all constructors eventually redirect to a non-redirecting constructor.
+//   A() : this();
+//         ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_cycle.dart.strong.transformed.expect
index 89c1886..e972c9c 100644
--- a/pkg/front_end/testcases/constructor_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_cycle.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_cycle.dart:7:18: Error: Redirecting constructers can't be cyclic.
 // Try to have all constructors eventually redirect to a non-redirecting constructor.
@@ -9,8 +11,7 @@
 // Try to have all constructors eventually redirect to a non-redirecting constructor.
 //   A() : this();
 //         ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_function_types.dart.hierarchy.expect b/pkg/front_end/testcases/constructor_function_types.dart.hierarchy.expect
new file mode 100644
index 0000000..d59504d
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_function_types.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/constructor_initializer_invalid.dart.hierarchy.expect b/pkg/front_end/testcases/constructor_initializer_invalid.dart.hierarchy.expect
new file mode 100644
index 0000000..55483de
--- /dev/null
+++ b/pkg/front_end/testcases/constructor_initializer_invalid.dart.hierarchy.expect
@@ -0,0 +1,76 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C1.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C1.f
+
+C2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C2.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C2.f
+
+C3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C3.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C3.f
diff --git a/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.expect b/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.expect
index 6b42a4b..af3c198 100644
--- a/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.expect
+++ b/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
 // class C1 { int f; C1() : ; }
@@ -17,24 +19,7 @@
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:7:26: Error: Can't access 'this' in a field initializer to read 'f'.
 // class C3 { int f; C3() : f++; }
 //                          ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
-// class C1 { int f; C1() : ; }
-//                        ^
-//
-// pkg/front_end/testcases/constructor_initializer_invalid.dart:6:26: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-// class C2 { int f; C2() : f; }
-//                          ^
-//
-// pkg/front_end/testcases/constructor_initializer_invalid.dart:7:26: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-// class C3 { int f; C3() : f++; }
-//                          ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.transformed.expect b/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.transformed.expect
index 8d747d5..af3c198 100644
--- a/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/constructor_initializer_invalid.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
 // class C1 { int f; C1() : ; }
@@ -13,8 +15,11 @@
 // To initialize a field, use the syntax 'name = value'.
 // class C3 { int f; C3() : f++; }
 //                          ^
-
-library;
+//
+// pkg/front_end/testcases/constructor_initializer_invalid.dart:7:26: Error: Can't access 'this' in a field initializer to read 'f'.
+// class C3 { int f; C3() : f++; }
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_initializer_invalid.dart.outline.expect b/pkg/front_end/testcases/constructor_initializer_invalid.dart.outline.expect
index 407b220..38148ab 100644
--- a/pkg/front_end/testcases/constructor_initializer_invalid.dart.outline.expect
+++ b/pkg/front_end/testcases/constructor_initializer_invalid.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
 // class C1 { int f; C1() : ; }
@@ -13,8 +15,7 @@
 // To initialize a field, use the syntax 'name = value'.
 // class C3 { int f; C3() : f++; }
 //                          ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.expect b/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.expect
index 5e45093..eb5062e 100644
--- a/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.expect
+++ b/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
 // class C1 { int f; C1() : ; }
@@ -17,24 +19,7 @@
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:7:26: Error: Can't access 'this' in a field initializer to read 'f'.
 // class C3 { int f; C3() : f++; }
 //                          ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
-// class C1 { int f; C1() : ; }
-//                        ^
-//
-// pkg/front_end/testcases/constructor_initializer_invalid.dart:6:26: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-// class C2 { int f; C2() : f; }
-//                          ^
-//
-// pkg/front_end/testcases/constructor_initializer_invalid.dart:7:26: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-// class C3 { int f; C3() : f++; }
-//                          ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.transformed.expect b/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.transformed.expect
index bfe868c..eb5062e 100644
--- a/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/constructor_initializer_invalid.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/constructor_initializer_invalid.dart:5:24: Error: Expected an initializer.
 // class C1 { int f; C1() : ; }
@@ -13,8 +15,11 @@
 // To initialize a field, use the syntax 'name = value'.
 // class C3 { int f; C3() : f++; }
 //                          ^
-
-library;
+//
+// pkg/front_end/testcases/constructor_initializer_invalid.dart:7:26: Error: Can't access 'this' in a field initializer to read 'f'.
+// class C3 { int f; C3() : f++; }
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/continue_inference_after_error.dart.hierarchy.expect b/pkg/front_end/testcases/continue_inference_after_error.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/continue_inference_after_error.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.expect b/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.expect
index f613c96..cc8231e 100644
--- a/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.expect
+++ b/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.expect
@@ -1,13 +1,16 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/continue_inference_after_error.dart:10:3: Error: A prefix can't be used as an expression.
 //   lib(new C().missing());
 //   ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///continue_inference_after_error_lib.dart" as lib;
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
@@ -19,3 +22,6 @@
   ^^^" in let final core::Object #t2 = new self::C::•().missing() in null;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.transformed.expect b/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.transformed.expect
index fab5a56..cc8231e 100644
--- a/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/continue_inference_after_error.dart.legacy.transformed.expect
@@ -1,7 +1,16 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/continue_inference_after_error.dart:10:3: Error: A prefix can't be used as an expression.
+//   lib(new C().missing());
+//   ^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///continue_inference_after_error_lib.dart" as lib;
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
@@ -13,3 +22,6 @@
   ^^^" in let final core::Object #t2 = new self::C::•().missing() in null;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/continue_inference_after_error.dart.outline.expect b/pkg/front_end/testcases/continue_inference_after_error.dart.outline.expect
index e2e68b1..a03ecdb 100644
--- a/pkg/front_end/testcases/continue_inference_after_error.dart.outline.expect
+++ b/pkg/front_end/testcases/continue_inference_after_error.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///continue_inference_after_error_lib.dart" as lib;
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     ;
@@ -10,3 +12,6 @@
   ;
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/continue_inference_after_error.dart.strong.expect b/pkg/front_end/testcases/continue_inference_after_error.dart.strong.expect
index 861dd2f..c8d3090 100644
--- a/pkg/front_end/testcases/continue_inference_after_error.dart.strong.expect
+++ b/pkg/front_end/testcases/continue_inference_after_error.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/continue_inference_after_error.dart:10:3: Error: A prefix can't be used as an expression.
 //   lib(new C().missing());
@@ -9,11 +11,12 @@
 // Try correcting the name to the name of an existing method, or defining a method named 'missing'.
 //   lib(new C().missing());
 //               ^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///continue_inference_after_error_lib.dart" as lib;
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
@@ -22,10 +25,13 @@
 static method test() → dynamic {
   let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/continue_inference_after_error.dart:10:3: Error: A prefix can't be used as an expression.
   lib(new C().missing());
-  ^^^" in let final core::Object #t2 = let final dynamic #t3 = new self::C::•() in invalid-expression "pkg/front_end/testcases/continue_inference_after_error.dart:10:15: Error: The method 'missing' isn't defined for the class 'C'.
+  ^^^" in let final core::Object #t2 = invalid-expression "pkg/front_end/testcases/continue_inference_after_error.dart:10:15: Error: The method 'missing' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/continue_inference_after_error.dart'.
 Try correcting the name to the name of an existing method, or defining a method named 'missing'.
   lib(new C().missing());
               ^^^^^^^" in null;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/continue_inference_after_error.dart.strong.transformed.expect b/pkg/front_end/testcases/continue_inference_after_error.dart.strong.transformed.expect
index 80d02fa..c8d3090 100644
--- a/pkg/front_end/testcases/continue_inference_after_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/continue_inference_after_error.dart.strong.transformed.expect
@@ -1,7 +1,22 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/continue_inference_after_error.dart:10:3: Error: A prefix can't be used as an expression.
+//   lib(new C().missing());
+//   ^^^
+//
+// pkg/front_end/testcases/continue_inference_after_error.dart:10:15: Error: The method 'missing' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/continue_inference_after_error.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'missing'.
+//   lib(new C().missing());
+//               ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///continue_inference_after_error_lib.dart" as lib;
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
@@ -10,10 +25,13 @@
 static method test() → dynamic {
   let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/continue_inference_after_error.dart:10:3: Error: A prefix can't be used as an expression.
   lib(new C().missing());
-  ^^^" in let final core::Object #t2 = let final self::C #t3 = new self::C::•() in invalid-expression "pkg/front_end/testcases/continue_inference_after_error.dart:10:15: Error: The method 'missing' isn't defined for the class 'C'.
+  ^^^" in let final core::Object #t2 = invalid-expression "pkg/front_end/testcases/continue_inference_after_error.dart:10:15: Error: The method 'missing' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/continue_inference_after_error.dart'.
 Try correcting the name to the name of an existing method, or defining a method named 'missing'.
   lib(new C().missing());
               ^^^^^^^" in null;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/covariant_generic.dart.hierarchy.expect b/pkg/front_end/testcases/covariant_generic.dart.hierarchy.expect
new file mode 100644
index 0000000..76a979e
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_generic.dart.hierarchy.expect
@@ -0,0 +1,45 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.callbackField
+    Foo.mutableCallbackField
+    Foo.mutableField
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.withCallback
+    Foo.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Foo.finalField
+  classSetters:
+    Foo.mutableCallbackField
+    Foo.mutableField
+    Foo.setter
diff --git a/pkg/front_end/testcases/cycles.dart.hierarchy.expect b/pkg/front_end/testcases/cycles.dart.hierarchy.expect
new file mode 100644
index 0000000..5865e60
--- /dev/null
+++ b/pkg/front_end/testcases/cycles.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/cycles.dart.legacy.expect b/pkg/front_end/testcases/cycles.dart.legacy.expect
index 4ee0331..74c43d4 100644
--- a/pkg/front_end/testcases/cycles.dart.legacy.expect
+++ b/pkg/front_end/testcases/cycles.dart.legacy.expect
@@ -1,32 +1,19 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
-// class A implements C {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself.
-// class B extends A {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
-// class C extends B implements D {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
-// class A implements C {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself.
-// class B extends A {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
-// class C extends B implements D {}
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
+// class A implements C {}
+//       ^
+//
+// pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself.
+// class B extends A {}
+//       ^
+//
+// pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
+// class C extends B implements D {}
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/cycles.dart.legacy.transformed.expect b/pkg/front_end/testcases/cycles.dart.legacy.transformed.expect
index 08a24b3..74c43d4 100644
--- a/pkg/front_end/testcases/cycles.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/cycles.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
 // class A implements C {}
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
 // class C extends B implements D {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/cycles.dart.outline.expect b/pkg/front_end/testcases/cycles.dart.outline.expect
index b1b0614..6c6bd27 100644
--- a/pkg/front_end/testcases/cycles.dart.outline.expect
+++ b/pkg/front_end/testcases/cycles.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
 // class A implements C {}
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
 // class C extends B implements D {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/cycles.dart.strong.expect b/pkg/front_end/testcases/cycles.dart.strong.expect
index 4ee0331..74c43d4 100644
--- a/pkg/front_end/testcases/cycles.dart.strong.expect
+++ b/pkg/front_end/testcases/cycles.dart.strong.expect
@@ -1,32 +1,19 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
-// class A implements C {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself.
-// class B extends A {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
-// class C extends B implements D {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
-// class A implements C {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself.
-// class B extends A {}
-//       ^
-//
-// pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
-// class C extends B implements D {}
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
+// class A implements C {}
+//       ^
+//
+// pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself.
+// class B extends A {}
+//       ^
+//
+// pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
+// class C extends B implements D {}
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/cycles.dart.strong.transformed.expect b/pkg/front_end/testcases/cycles.dart.strong.transformed.expect
index 08a24b3..74c43d4 100644
--- a/pkg/front_end/testcases/cycles.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/cycles.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself.
 // class A implements C {}
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself.
 // class C extends B implements D {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.hierarchy.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.hierarchy.expect
new file mode 100644
index 0000000..ea44c4f
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect
index a826409..423412d 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.expect
@@ -1,14 +1,33 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Warning: The type 'C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'd' or use a supertype of 'C' that isn't deferred.
 // bad(d.C x) {}
 //     ^^^
-
-library;
+//
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
+
 static method bad(def::C x) → dynamic {}
 static method main() → dynamic {}
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect
index 8e7b027..423412d 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.legacy.transformed.expect
@@ -1,6 +1,33 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Warning: The type 'C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'd' or use a supertype of 'C' that isn't deferred.
+// bad(d.C x) {}
+//     ^^^
+//
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
+
 static method bad(def::C x) → dynamic {}
 static method main() → dynamic {}
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field dynamic x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
index 15a1fa3..7693576 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.outline.expect
@@ -2,7 +2,24 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
+
 static method bad(def::C x) → dynamic
   ;
 static method main() → dynamic
   ;
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y;
+  synthetic constructor •() → def::C
+    ;
+  static method m() → core::int
+    ;
+}
+static field dynamic x;
+static method m(dynamic x) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
index f58ad49..6be11a9 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.expect
@@ -1,22 +1,33 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Error: The type 'C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'd' or use a supertype of 'C' that isn't deferred.
-// bad(d.C x) {}
-//     ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Error: The type 'C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
-//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
-// Try removing 'deferred' from the import of 'd' or use a supertype of 'C' that isn't deferred.
-// bad(d.C x) {}
-//     ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Error: The type 'C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
+//  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
+// Try removing 'deferred' from the import of 'd' or use a supertype of 'C' that isn't deferred.
+// bad(d.C x) {}
+//     ^^^
+//
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
+
 static method bad(def::C x) → dynamic {}
 static method main() → dynamic {}
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
index 6bfd545..6be11a9 100644
--- a/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/deferred_type_annotation.dart.strong.transformed.expect
@@ -1,14 +1,33 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/deferred_type_annotation.dart:7:5: Error: The type 'C' is deferred loaded via prefix 'd' and can't be used as a type annotation.
 //  - 'C' is from 'pkg/front_end/testcases/deferred_lib.dart'.
 // Try removing 'deferred' from the import of 'd' or use a supertype of 'C' that isn't deferred.
 // bad(d.C x) {}
 //     ^^^
-
-library;
+//
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as d;
+
 static method bad(def::C x) → dynamic {}
 static method main() → dynamic {}
+
+library;
+import self as def;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::int y = 1;
+  synthetic constructor •() → def::C
+    : super core::Object::•()
+    ;
+  static method m() → core::int
+    return 2;
+}
+static field core::int x = 0;
+static method m(dynamic x) → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/duplicated_bad_prefix.dart.hierarchy.expect b/pkg/front_end/testcases/duplicated_bad_prefix.dart.hierarchy.expect
new file mode 100644
index 0000000..8d3d333
--- /dev/null
+++ b/pkg/front_end/testcases/duplicated_bad_prefix.dart.hierarchy.expect
@@ -0,0 +1,108 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Dupe:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Dupe:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.d
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.b
+    C.d
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.expect b/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.expect
index bb80ade..8d79e12 100644
--- a/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.expect
+++ b/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
@@ -18,17 +20,13 @@
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Warning: 'Dupe.a' isn't a type.
 //   Dupe.a b;
 //   ^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
-// class Dupe {}
-//       ^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib1.dart" as dupe;
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib2.dart" as dupe;
+
 class Dupe#1 extends core::Object {
   synthetic constructor •() → self::Dupe#1
     : super core::Object::•()
@@ -47,3 +45,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self3::C
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.transformed.expect b/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.transformed.expect
index c095d13..8d79e12 100644
--- a/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_bad_prefix.dart.legacy.transformed.expect
@@ -1,13 +1,32 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
 //       ^^^^
-
-library;
+// pkg/front_end/testcases/duplicated_bad_prefix.dart:8:7: Context: Previous declaration of 'Dupe'.
+// class Dupe {}
+//       ^^^^
+//
+// pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Warning: Type 'Dupe.a' not found.
+//   Dupe.a b;
+//   ^^^^^^
+//
+// pkg/front_end/testcases/duplicated_bad_prefix.dart:6:45: Warning: 'C' is imported from both 'pkg/front_end/testcases/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/duplicated_bad_prefix_lib2.dart'.
+// import 'duplicated_bad_prefix_lib2.dart' as dupe;
+//                                             ^
+//
+// pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Warning: 'Dupe.a' isn't a type.
+//   Dupe.a b;
+//   ^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib1.dart" as dupe;
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib2.dart" as dupe;
+
 class Dupe#1 extends core::Object {
   synthetic constructor •() → self::Dupe#1
     : super core::Object::•()
@@ -26,3 +45,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self3::C
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/duplicated_bad_prefix.dart.outline.expect b/pkg/front_end/testcases/duplicated_bad_prefix.dart.outline.expect
index 28dac21..1fee0d1 100644
--- a/pkg/front_end/testcases/duplicated_bad_prefix.dart.outline.expect
+++ b/pkg/front_end/testcases/duplicated_bad_prefix.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
@@ -14,11 +16,13 @@
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:6:45: Warning: 'C' is imported from both 'pkg/front_end/testcases/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/duplicated_bad_prefix_lib2.dart'.
 // import 'duplicated_bad_prefix_lib2.dart' as dupe;
 //                                             ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib1.dart" as dupe;
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib2.dart" as dupe;
+
 class Dupe#1 extends core::Object {
   synthetic constructor •() → self::Dupe#1
     ;
@@ -35,3 +39,21 @@
 }
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self3::C
+    ;
+}
diff --git a/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.expect b/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.expect
index a2b97c5..9f72e139 100644
--- a/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
@@ -18,29 +20,13 @@
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Error: 'Dupe.a' isn't a type.
 //   Dupe.a b;
 //   ^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
-// class Dupe {}
-//       ^^^^
-//
-// pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Error: Type 'Dupe.a' not found.
-//   Dupe.a b;
-//   ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_bad_prefix.dart:6:45: Error: 'C' is imported from both 'pkg/front_end/testcases/duplicated_bad_prefix_lib1.dart' and 'pkg/front_end/testcases/duplicated_bad_prefix_lib2.dart'.
-// import 'duplicated_bad_prefix_lib2.dart' as dupe;
-//                                             ^
-//
-// pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Error: 'Dupe.a' isn't a type.
-//   Dupe.a b;
-//   ^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib1.dart" as dupe;
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib2.dart" as dupe;
+
 class Dupe#1 extends core::Object {
   synthetic constructor •() → self::Dupe#1
     : super core::Object::•()
@@ -59,3 +45,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self3::C
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.transformed.expect
index ff27603..9f72e139 100644
--- a/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_bad_prefix.dart.strong.transformed.expect
@@ -1,8 +1,13 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:10:7: Error: 'Dupe' is already declared in this scope.
 // class Dupe {}
 //       ^^^^
+// pkg/front_end/testcases/duplicated_bad_prefix.dart:8:7: Context: Previous declaration of 'Dupe'.
+// class Dupe {}
+//       ^^^^
 //
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Error: Type 'Dupe.a' not found.
 //   Dupe.a b;
@@ -15,11 +20,13 @@
 // pkg/front_end/testcases/duplicated_bad_prefix.dart:13:3: Error: 'Dupe.a' isn't a type.
 //   Dupe.a b;
 //   ^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib1.dart" as dupe;
+import "org-dartlang-testcase:///duplicated_bad_prefix_lib2.dart" as dupe;
+
 class Dupe#1 extends core::Object {
   synthetic constructor •() → self::Dupe#1
     : super core::Object::•()
@@ -38,3 +45,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self2::C
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self3::C
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.hierarchy.expect b/pkg/front_end/testcases/duplicated_declarations.dart.hierarchy.expect
new file mode 100644
index 0000000..b6c3f46
--- /dev/null
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.hierarchy.expect
@@ -0,0 +1,268 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    C.s
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.field
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.field
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    C.s
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.field
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.field
+
+Sub:
+  superclasses:
+    C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Sub.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Enum:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Enum.a
+    Enum.toString
+    Enum.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Enum._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Enum.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Enum:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Enum.b
+    Enum.a
+    Enum.toString
+    Enum.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Enum._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Enum.c
+    Object.hashCode
+    Enum.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Enum:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Enum.b
+    Enum.a
+    Enum.toString
+    Enum.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Enum._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Enum.Enum
+    Object.hashCode
+    Enum.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Enum:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Enum.b
+    Enum.a
+    Enum.toString
+    Enum.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Enum._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Enum.c
+    Object.hashCode
+    Enum.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Enum:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Enum.b
+    Enum.a
+    Enum.toString
+    Enum.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Enum._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Enum.Enum
+    Object.hashCode
+    Enum.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AnotherEnum:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    AnotherEnum.b
+    AnotherEnum.a
+    AnotherEnum.toString
+    AnotherEnum.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    AnotherEnum._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    AnotherEnum.c
+    Object.hashCode
+    AnotherEnum.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
index f387607..f1e837f 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
 // Try moving the import directives before the part directives.
@@ -124,6 +126,48 @@
 // enum AnotherEnum {
 //      ^^^^^^^^^^^
 //
+// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
+// typedef Typedef = void Function();
+//         ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = Object Function();
+//         ^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
+// typedef void OldTypedef();
+//              ^^^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
+// typedef Object OldTypedef();
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
+// var field = "3rd";
+//     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
+// var field = "2nd";
+//     ^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
+// main() {
+// ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
+// class C {
+//       ^
+// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
+// enum Enum {
+//      ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
+// enum Enum {
+//      ^^^^
+//
 // pkg/front_end/testcases/duplicated_declarations_part.dart:7:1: Error: The part-of directive must be the only directive in a part.
 // Try removing the other directives, or moving them to the library for which this is a part.
 // import 'duplicated_declarations_lib.dart' as Typedef;
@@ -248,48 +292,6 @@
 // enum Enum {
 //      ^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = void Function();
-//         ^^^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
-// typedef void OldTypedef();
-//              ^^^^^^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
-// var field = "3rd";
-//     ^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
-// var field = "2nd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
-// enum Enum {
-//      ^^^^
-//
 // pkg/front_end/testcases/duplicated_declarations.dart:7:46: Error: 'Typedef' is already declared in this scope.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 //                                              ^^^^^^^
@@ -345,203 +347,18 @@
 // pkg/front_end/testcases/duplicated_declarations_part.dart:62:17: Error: Can't use 's' because it is declared more than once.
 //   static f() => s;
 //                 ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
-// Try moving the import directives before the part directives.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives.
-// Try moving the import directives before the part directives.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:15:1: Error: Directives must appear before any declarations.
-// Try moving the directive before any declarations.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Error: 'OldTypedef' is already declared in this scope.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Error: 'field' is already declared in this scope.
-// var field = "2nd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:41:3: Error: 'C' is already declared in this scope.
-//   C(a, b);
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:44:7: Error: 'field' is already declared in this scope.
-//   var field = "2nd";
-//       ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:50:3: Error: 'm' is already declared in this scope.
-//   m() {
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:58:10: Error: 's' is already declared in this scope.
-//   static s() {
-//          ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:75:3: Error: Name of enum constant 'Enum' can't be the same as the enum's own name.
-//   Enum,
-//   ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:77:3: Error: 'a' is already declared in this scope.
-//   a,
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:91:3: Error: '_name' is already declared in this scope.
-//   _name,
-//   ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:92:3: Error: 'index' is already declared in this scope.
-//   index,
-//   ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:93:3: Error: 'toString' is already declared in this scope.
-//   toString,
-//   ^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:94:3: Error: 'values' is already declared in this scope.
-//   values,
-//   ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:7:1: Error: The part-of directive must be the only directive in a part.
-// Try removing the other directives, or moving them to the library for which this is a part.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:9:1: Error: The part-of directive must be the only directive in a part.
-// Try removing the other directives, or moving them to the library for which this is a part.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:13:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:15:1: Error: The part-of directive must be the only directive in a part.
-// Try removing the other directives, or moving them to the library for which this is a part.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:19:16: Error: 'OldTypedef' is already declared in this scope.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:23:5: Error: 'field' is already declared in this scope.
-// var field = 4;
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:25:5: Error: 'field' is already declared in this scope.
-// var field = 5.0;
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:31:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:35:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:41:3: Error: 'C' is already declared in this scope.
-//   C(a, b);
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:44:7: Error: 'field' is already declared in this scope.
-//   var field = "2nd";
-//       ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:50:3: Error: 'm' is already declared in this scope.
-//   m() {
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:58:10: Error: 's' is already declared in this scope.
-//   static s() {
-//          ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:65:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:69:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:74:3: Error: Name of enum constant 'Enum' can't be the same as the enum's own name.
-//   Enum,
-//   ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:76:3: Error: 'a' is already declared in this scope.
-//   a,
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:80:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:86:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = void Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
-// typedef void OldTypedef();
-//              ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
-// var field = "3rd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:7:46: Error: 'Typedef' is already declared in this scope.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-//                                              ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
-// class Sub extends C {
-//                   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+
+part duplicated_declarations_part.dart;
 typedef Typedef = () → void;
 typedef OldTypedef = () → void;
 class C#4 extends core::Object { // from org-dartlang-testcase:///duplicated_declarations_part.dart
@@ -700,3 +517,6 @@
     \"AnotherEnum.values\": AnotherEnum.values,
                                       ^^^^^^"};
 }
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
index 50cee56..f1e837f 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
 // Try moving the import directives before the part directives.
@@ -13,6 +15,9 @@
 // pkg/front_end/testcases/duplicated_declarations.dart:13:9: Error: 'Typedef' is already declared in this scope.
 // typedef Typedef = Object Function();
 //         ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:11:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = void Function();
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:15:1: Error: Directives must appear before any declarations.
 // Try moving the directive before any declarations.
@@ -22,34 +27,58 @@
 // pkg/front_end/testcases/duplicated_declarations.dart:19:16: Error: 'OldTypedef' is already declared in this scope.
 // typedef Object OldTypedef();
 //                ^^^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:17:14: Context: Previous declaration of 'OldTypedef'.
+// typedef void OldTypedef();
+//              ^^^^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:23:5: Error: 'field' is already declared in this scope.
 // var field = "2nd";
 //     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:21:5: Context: Previous declaration of 'field'.
+// var field = "1st";
+//     ^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:29:1: Error: 'main' is already declared in this scope.
 // main() {
 // ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:25:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:41:3: Error: 'C' is already declared in this scope.
 //   C(a, b);
 //   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:40:3: Context: Previous declaration of 'C'.
+//   C(a);
+//   ^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:44:7: Error: 'field' is already declared in this scope.
 //   var field = "2nd";
 //       ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:42:7: Context: Previous declaration of 'field'.
+//   var field = "1st";
+//       ^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:50:3: Error: 'm' is already declared in this scope.
 //   m() {
 //   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:46:3: Context: Previous declaration of 'm'.
+//   m() {
+//   ^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:58:10: Error: 's' is already declared in this scope.
 //   static s() {
 //          ^
+// pkg/front_end/testcases/duplicated_declarations.dart:54:10: Context: Previous declaration of 's'.
+//   static s() {
+//          ^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:70:7: Error: 'C' is already declared in this scope.
 // class C {
 //       ^
+// pkg/front_end/testcases/duplicated_declarations.dart:39:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:75:3: Error: Name of enum constant 'Enum' can't be the same as the enum's own name.
 //   Enum,
@@ -58,26 +87,86 @@
 // pkg/front_end/testcases/duplicated_declarations.dart:77:3: Error: 'a' is already declared in this scope.
 //   a,
 //   ^
+// pkg/front_end/testcases/duplicated_declarations.dart:76:3: Context: Previous declaration of 'a'.
+//   a,
+//   ^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:81:6: Error: 'Enum' is already declared in this scope.
 // enum Enum {
 //      ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:74:6: Context: Previous declaration of 'Enum'.
+// enum Enum {
+//      ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:91:3: Error: '_name' is already declared in this scope.
 //   _name,
 //   ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:87:6: Context: Previous declaration of '_name' is implied by this definition.
+// enum AnotherEnum {
+//      ^^^^^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:92:3: Error: 'index' is already declared in this scope.
 //   index,
 //   ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:87:6: Context: Previous declaration of 'index' is implied by this definition.
+// enum AnotherEnum {
+//      ^^^^^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:93:3: Error: 'toString' is already declared in this scope.
 //   toString,
 //   ^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:87:6: Context: Previous declaration of 'toString' is implied by this definition.
+// enum AnotherEnum {
+//      ^^^^^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:94:3: Error: 'values' is already declared in this scope.
 //   values,
 //   ^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:87:6: Context: Previous declaration of 'values' is implied by this definition.
+// enum AnotherEnum {
+//      ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
+// typedef Typedef = void Function();
+//         ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = Object Function();
+//         ^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
+// typedef void OldTypedef();
+//              ^^^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
+// typedef Object OldTypedef();
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
+// var field = "3rd";
+//     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
+// var field = "2nd";
+//     ^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
+// main() {
+// ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
+// class C {
+//       ^
+// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
+// enum Enum {
+//      ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
+// enum Enum {
+//      ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:7:1: Error: The part-of directive must be the only directive in a part.
 // Try removing the other directives, or moving them to the library for which this is a part.
@@ -92,6 +181,9 @@
 // pkg/front_end/testcases/duplicated_declarations_part.dart:13:9: Error: 'Typedef' is already declared in this scope.
 // typedef Typedef = Object Function();
 //         ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = void Function();
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:15:1: Error: The part-of directive must be the only directive in a part.
 // Try removing the other directives, or moving them to the library for which this is a part.
@@ -101,46 +193,79 @@
 // pkg/front_end/testcases/duplicated_declarations_part.dart:19:16: Error: 'OldTypedef' is already declared in this scope.
 // typedef Object OldTypedef();
 //                ^^^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Context: Previous declaration of 'OldTypedef'.
+// typedef void OldTypedef();
+//              ^^^^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:23:5: Error: 'field' is already declared in this scope.
 // var field = 4;
 //     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Context: Previous declaration of 'field'.
+// var field = "3rd";
+//     ^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:25:5: Error: 'field' is already declared in this scope.
 // var field = 5.0;
 //     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:23:5: Context: Previous declaration of 'field'.
+// var field = 4;
+//     ^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:31:1: Error: 'main' is already declared in this scope.
 // main() {
 // ^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:35:1: Error: 'main' is already declared in this scope.
 // main() {
 // ^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:31:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:41:3: Error: 'C' is already declared in this scope.
 //   C(a, b);
 //   ^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:40:3: Context: Previous declaration of 'C'.
+//   C(a);
+//   ^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:44:7: Error: 'field' is already declared in this scope.
 //   var field = "2nd";
 //       ^^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:42:7: Context: Previous declaration of 'field'.
+//   var field = "1st";
+//       ^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:50:3: Error: 'm' is already declared in this scope.
 //   m() {
 //   ^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:46:3: Context: Previous declaration of 'm'.
+//   m() {
+//   ^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:58:10: Error: 's' is already declared in this scope.
 //   static s() {
 //          ^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:54:10: Context: Previous declaration of 's'.
+//   static s() {
+//          ^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:65:7: Error: 'C' is already declared in this scope.
 // class C {
 //       ^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:69:7: Error: 'C' is already declared in this scope.
 // class C {
 //       ^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:65:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:74:3: Error: Name of enum constant 'Enum' can't be the same as the enum's own name.
 //   Enum,
@@ -149,51 +274,91 @@
 // pkg/front_end/testcases/duplicated_declarations_part.dart:76:3: Error: 'a' is already declared in this scope.
 //   a,
 //   ^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:75:3: Context: Previous declaration of 'a'.
+//   a,
+//   ^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:80:6: Error: 'Enum' is already declared in this scope.
 // enum Enum {
 //      ^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Context: Previous declaration of 'Enum'.
+// enum Enum {
+//      ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations_part.dart:86:6: Error: 'Enum' is already declared in this scope.
 // enum Enum {
 //      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = void Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
-// typedef void OldTypedef();
-//              ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
-// var field = "3rd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
+// pkg/front_end/testcases/duplicated_declarations_part.dart:80:6: Context: Previous declaration of 'Enum'.
 // enum Enum {
 //      ^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:7:46: Error: 'Typedef' is already declared in this scope.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 //                                              ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations_part.dart:13:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = Object Function();
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
 // class Sub extends C {
 //                   ^
-
-library;
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:34:3: Error: Can't use 'main' because it is declared more than once.
+//   main();
+//   ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:35:9: Error: Can't use 'field' because it is declared more than once.
+//   print(field);
+//         ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:36:3: Error: Can't use 'C' because it is declared more than once.
+//   C.s();
+//   ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:62:17: Error: Can't use 's' because it is declared more than once.
+//   static f() => s;
+//                 ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:66:16: Warning: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+//   Sub() : super(null);
+//                ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:67:16: Warning: Superclass has no method named 'm'.
+//   m() => super.m();
+//                ^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:102:38: Error: Can't use '_name' because it is declared more than once.
+//     "AnotherEnum._name": AnotherEnum._name,
+//                                      ^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:103:38: Error: Can't use 'index' because it is declared more than once.
+//     "AnotherEnum.index": AnotherEnum.index,
+//                                      ^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:104:41: Error: Can't use 'toString' because it is declared more than once.
+//     "AnotherEnum.toString": AnotherEnum.toString,
+//                                         ^^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations.dart:105:39: Error: Can't use 'values' because it is declared more than once.
+//     "AnotherEnum.values": AnotherEnum.values,
+//                                       ^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:62:17: Error: Can't use 's' because it is declared more than once.
+//   static f() => s;
+//                 ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+
+part duplicated_declarations_part.dart;
 typedef Typedef = () → void;
 typedef OldTypedef = () → void;
 class C#4 extends core::Object { // from org-dartlang-testcase:///duplicated_declarations_part.dart
@@ -352,3 +517,6 @@
     \"AnotherEnum.values\": AnotherEnum.values,
                                       ^^^^^^"};
 }
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
index 4aebbb6..63f345e 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
 // Try moving the import directives before the part directives.
@@ -124,6 +126,48 @@
 // enum AnotherEnum {
 //      ^^^^^^^^^^^
 //
+// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
+// typedef Typedef = void Function();
+//         ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = Object Function();
+//         ^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
+// typedef void OldTypedef();
+//              ^^^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
+// typedef Object OldTypedef();
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
+// var field = "3rd";
+//     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
+// var field = "2nd";
+//     ^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
+// main() {
+// ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
+// class C {
+//       ^
+// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
+// enum Enum {
+//      ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
+// enum Enum {
+//      ^^^^
+//
 // pkg/front_end/testcases/duplicated_declarations_part.dart:7:1: Error: The part-of directive must be the only directive in a part.
 // Try removing the other directives, or moving them to the library for which this is a part.
 // import 'duplicated_declarations_lib.dart' as Typedef;
@@ -248,48 +292,6 @@
 // enum Enum {
 //      ^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = void Function();
-//         ^^^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
-// typedef void OldTypedef();
-//              ^^^^^^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
-// var field = "3rd";
-//     ^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
-// var field = "2nd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
-// enum Enum {
-//      ^^^^
-//
 // pkg/front_end/testcases/duplicated_declarations.dart:7:46: Error: 'Typedef' is already declared in this scope.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 //                                              ^^^^^^^
@@ -300,11 +302,18 @@
 // pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
 // class Sub extends C {
 //                   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+
+part duplicated_declarations_part.dart;
 typedef Typedef = () → void;
 typedef OldTypedef = () → void;
 class C#4 extends core::Object { // from org-dartlang-testcase:///duplicated_declarations_part.dart
@@ -430,3 +439,6 @@
   ;
 static method useAnotherEnum() → dynamic
   ;
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
index 99a1f04..a51c4ba 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
 // Try moving the import directives before the part directives.
@@ -124,6 +126,48 @@
 // enum AnotherEnum {
 //      ^^^^^^^^^^^
 //
+// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
+// typedef Typedef = void Function();
+//         ^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
+// typedef Typedef = Object Function();
+//         ^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
+// typedef void OldTypedef();
+//              ^^^^^^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
+// typedef Object OldTypedef();
+//                ^^^^^^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
+// var field = "3rd";
+//     ^^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
+// var field = "2nd";
+//     ^^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
+// main() {
+// ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
+// main() {
+// ^^^^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
+// class C {
+//       ^
+// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
+// class C {
+//       ^
+//
+// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
+// enum Enum {
+//      ^^^^
+// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
+// enum Enum {
+//      ^^^^
+//
 // pkg/front_end/testcases/duplicated_declarations_part.dart:7:1: Error: The part-of directive must be the only directive in a part.
 // Try removing the other directives, or moving them to the library for which this is a part.
 // import 'duplicated_declarations_lib.dart' as Typedef;
@@ -248,48 +292,6 @@
 // enum Enum {
 //      ^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = void Function();
-//         ^^^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Context: Previous declaration of 'Typedef'.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
-// typedef void OldTypedef();
-//              ^^^^^^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Context: Previous declaration of 'OldTypedef'.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
-// var field = "3rd";
-//     ^^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Context: Previous declaration of 'field'.
-// var field = "2nd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Context: Previous declaration of 'main'.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Context: Previous declaration of 'C'.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Context: Previous declaration of 'Enum'.
-// enum Enum {
-//      ^^^^
-//
 // pkg/front_end/testcases/duplicated_declarations.dart:7:46: Error: 'Typedef' is already declared in this scope.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 //                                              ^^^^^^^
@@ -345,207 +347,18 @@
 // pkg/front_end/testcases/duplicated_declarations_part.dart:62:17: Error: Can't use 's' because it is declared more than once.
 //   static f() => s;
 //                 ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
-// Try moving the import directives before the part directives.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives.
-// Try moving the import directives before the part directives.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:13:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:15:1: Error: Directives must appear before any declarations.
-// Try moving the directive before any declarations.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:19:16: Error: 'OldTypedef' is already declared in this scope.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:23:5: Error: 'field' is already declared in this scope.
-// var field = "2nd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:29:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:41:3: Error: 'C' is already declared in this scope.
-//   C(a, b);
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:44:7: Error: 'field' is already declared in this scope.
-//   var field = "2nd";
-//       ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:50:3: Error: 'm' is already declared in this scope.
-//   m() {
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:58:10: Error: 's' is already declared in this scope.
-//   static s() {
-//          ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:70:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:75:3: Error: Name of enum constant 'Enum' can't be the same as the enum's own name.
-//   Enum,
-//   ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:77:3: Error: 'a' is already declared in this scope.
-//   a,
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:81:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:91:3: Error: '_name' is already declared in this scope.
-//   _name,
-//   ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:92:3: Error: 'index' is already declared in this scope.
-//   index,
-//   ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:93:3: Error: 'toString' is already declared in this scope.
-//   toString,
-//   ^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:94:3: Error: 'values' is already declared in this scope.
-//   values,
-//   ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:7:1: Error: The part-of directive must be the only directive in a part.
-// Try removing the other directives, or moving them to the library for which this is a part.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:9:1: Error: The part-of directive must be the only directive in a part.
-// Try removing the other directives, or moving them to the library for which this is a part.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:13:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = Object Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:15:1: Error: The part-of directive must be the only directive in a part.
-// Try removing the other directives, or moving them to the library for which this is a part.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-// ^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:19:16: Error: 'OldTypedef' is already declared in this scope.
-// typedef Object OldTypedef();
-//                ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:23:5: Error: 'field' is already declared in this scope.
-// var field = 4;
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:25:5: Error: 'field' is already declared in this scope.
-// var field = 5.0;
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:31:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:35:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:41:3: Error: 'C' is already declared in this scope.
-//   C(a, b);
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:44:7: Error: 'field' is already declared in this scope.
-//   var field = "2nd";
-//       ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:50:3: Error: 'm' is already declared in this scope.
-//   m() {
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:58:10: Error: 's' is already declared in this scope.
-//   static s() {
-//          ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:65:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:69:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:74:3: Error: Name of enum constant 'Enum' can't be the same as the enum's own name.
-//   Enum,
-//   ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:76:3: Error: 'a' is already declared in this scope.
-//   a,
-//   ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:80:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:86:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:11:9: Error: 'Typedef' is already declared in this scope.
-// typedef Typedef = void Function();
-//         ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:17:14: Error: 'OldTypedef' is already declared in this scope.
-// typedef void OldTypedef();
-//              ^^^^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:21:5: Error: 'field' is already declared in this scope.
-// var field = "3rd";
-//     ^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:27:1: Error: 'main' is already declared in this scope.
-// main() {
-// ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:39:7: Error: 'C' is already declared in this scope.
-// class C {
-//       ^
-//
-// pkg/front_end/testcases/duplicated_declarations_part.dart:73:6: Error: 'Enum' is already declared in this scope.
-// enum Enum {
-//      ^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:7:46: Error: 'Typedef' is already declared in this scope.
-// import 'duplicated_declarations_lib.dart' as Typedef;
-//                                              ^^^^^^^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:65:19: Error: 'C' isn't a type.
-// class Sub extends C {
-//                   ^
-//
-// pkg/front_end/testcases/duplicated_declarations.dart:67:16: Error: Superclass has no method named 'm'.
-//   m() => super.m();
-//                ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+import "org-dartlang-testcase:///duplicated_declarations_lib.dart" as Typedef;
+
+part duplicated_declarations_part.dart;
 typedef Typedef = () → void;
 typedef OldTypedef = () → void;
 class C#4 extends core::Object { // from org-dartlang-testcase:///duplicated_declarations_part.dart
@@ -707,3 +520,6 @@
     \"AnotherEnum.values\": AnotherEnum.values,
                                       ^^^^^^"};
 }
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/duplicated_field_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/duplicated_field_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..eef7d41
--- /dev/null
+++ b/pkg/front_end/testcases/duplicated_field_initializer.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
diff --git a/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.expect b/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.expect
index a61a36d..9be85c0 100644
--- a/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.expect
+++ b/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
 //   int a;
@@ -10,14 +12,7 @@
 // pkg/front_end/testcases/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
 //   A(this.a);
 //          ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
-//   int a;
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.transformed.expect b/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.transformed.expect
index 97c35dc..9be85c0 100644
--- a/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_field_initializer.dart.legacy.transformed.expect
@@ -1,10 +1,18 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
 //   int a;
 //       ^
-
-library;
+// pkg/front_end/testcases/duplicated_field_initializer.dart:6:7: Context: Previous declaration of 'a'.
+//   int a;
+//       ^
+//
+// pkg/front_end/testcases/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
+//   A(this.a);
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/duplicated_field_initializer.dart.outline.expect b/pkg/front_end/testcases/duplicated_field_initializer.dart.outline.expect
index 230dc5e..dd9b512 100644
--- a/pkg/front_end/testcases/duplicated_field_initializer.dart.outline.expect
+++ b/pkg/front_end/testcases/duplicated_field_initializer.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
 //   int a;
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/duplicated_field_initializer.dart:6:7: Context: Previous declaration of 'a'.
 //   int a;
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.expect b/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.expect
index 2c39c5e..f272e6c 100644
--- a/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
 //   int a;
@@ -10,14 +12,7 @@
 // pkg/front_end/testcases/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
 //   A(this.a);
 //          ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
-//   int a;
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.transformed.expect
index b3fa279..f272e6c 100644
--- a/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_field_initializer.dart.strong.transformed.expect
@@ -1,10 +1,18 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_field_initializer.dart:7:7: Error: 'a' is already declared in this scope.
 //   int a;
 //       ^
-
-library;
+// pkg/front_end/testcases/duplicated_field_initializer.dart:6:7: Context: Previous declaration of 'a'.
+//   int a;
+//       ^
+//
+// pkg/front_end/testcases/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
+//   A(this.a);
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/duplicated_named_args_3.dart.hierarchy.expect b/pkg/front_end/testcases/duplicated_named_args_3.dart.hierarchy.expect
new file mode 100644
index 0000000..62a1574
--- /dev/null
+++ b/pkg/front_end/testcases/duplicated_named_args_3.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect
index 6ff96e9..42c312a 100644
--- a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/duplicated_named_args_3.dart:13:13: Error: Duplicated named argument 'a'.
 //   C.m(a: 1, a: 2, a: 3);
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/duplicated_named_args_3.dart:13:19: Error: Duplicated named argument 'a'.
 //   C.m(a: 1, a: 2, a: 3);
 //                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect
index e65bd84..42c312a 100644
--- a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect
@@ -1,4 +1,15 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/duplicated_named_args_3.dart:13:13: Error: Duplicated named argument 'a'.
+//   C.m(a: 1, a: 2, a: 3);
+//             ^
+//
+// pkg/front_end/testcases/duplicated_named_args_3.dart:13:19: Error: Duplicated named argument 'a'.
+//   C.m(a: 1, a: 2, a: 3);
+//                   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/dynamic_and_void.dart.legacy.expect b/pkg/front_end/testcases/dynamic_and_void.dart.legacy.expect
index 81f6e95..3760ddb 100644
--- a/pkg/front_end/testcases/dynamic_and_void.dart.legacy.expect
+++ b/pkg/front_end/testcases/dynamic_and_void.dart.legacy.expect
@@ -1,12 +1,15 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/dynamic_and_void.dart:12:27: Warning: Type 'dynamic' not found.
 // /*@warning=TypeNotFound*/ dynamic testDynamic() => 0;
 //                           ^^^^^^^
-
-library;
+//
 import self as self;
 
+import "dart:core";
+
 static method testDynamic() → invalid-type
   return 0;
 static method testVoid() → void {}
diff --git a/pkg/front_end/testcases/dynamic_and_void.dart.legacy.transformed.expect b/pkg/front_end/testcases/dynamic_and_void.dart.legacy.transformed.expect
index 4b7b5f6..3760ddb 100644
--- a/pkg/front_end/testcases/dynamic_and_void.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/dynamic_and_void.dart.legacy.transformed.expect
@@ -1,6 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/dynamic_and_void.dart:12:27: Warning: Type 'dynamic' not found.
+// /*@warning=TypeNotFound*/ dynamic testDynamic() => 0;
+//                           ^^^^^^^
+//
 import self as self;
 
+import "dart:core";
+
 static method testDynamic() → invalid-type
   return 0;
 static method testVoid() → void {}
diff --git a/pkg/front_end/testcases/dynamic_and_void.dart.outline.expect b/pkg/front_end/testcases/dynamic_and_void.dart.outline.expect
index 593529d..f080c68 100644
--- a/pkg/front_end/testcases/dynamic_and_void.dart.outline.expect
+++ b/pkg/front_end/testcases/dynamic_and_void.dart.outline.expect
@@ -1,12 +1,15 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/dynamic_and_void.dart:12:27: Warning: Type 'dynamic' not found.
 // /*@warning=TypeNotFound*/ dynamic testDynamic() => 0;
 //                           ^^^^^^^
-
-library;
+//
 import self as self;
 
+import "dart:core";
+
 static method testDynamic() → invalid-type
   ;
 static method testVoid() → void
diff --git a/pkg/front_end/testcases/escape.dart.hierarchy.expect b/pkg/front_end/testcases/escape.dart.hierarchy.expect
new file mode 100644
index 0000000..07af593
--- /dev/null
+++ b/pkg/front_end/testcases/escape.dart.hierarchy.expect
@@ -0,0 +1,107 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.field
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.field
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    C.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces: A, B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    X.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    X.field
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    X.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    X.field
diff --git a/pkg/front_end/testcases/export_main.dart.legacy.expect b/pkg/front_end/testcases/export_main.dart.legacy.expect
index 9227cd5..1f4d73b 100644
--- a/pkg/front_end/testcases/export_main.dart.legacy.expect
+++ b/pkg/front_end/testcases/export_main.dart.legacy.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./hello.dart" as hel;
 additionalExports = (hel::main)
+
+
+export "org-dartlang-testcase:///hello.dart";
+
+
+library;
+import self as hel;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect b/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect
index 9227cd5..1f4d73b 100644
--- a/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/export_main.dart.legacy.transformed.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./hello.dart" as hel;
 additionalExports = (hel::main)
+
+
+export "org-dartlang-testcase:///hello.dart";
+
+
+library;
+import self as hel;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/export_main.dart.outline.expect b/pkg/front_end/testcases/export_main.dart.outline.expect
index 9227cd5..349482d 100644
--- a/pkg/front_end/testcases/export_main.dart.outline.expect
+++ b/pkg/front_end/testcases/export_main.dart.outline.expect
@@ -2,3 +2,13 @@
 import self as self;
 import "./hello.dart" as hel;
 additionalExports = (hel::main)
+
+
+export "org-dartlang-testcase:///hello.dart";
+
+
+library;
+import self as hel;
+
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/export_main.dart.strong.expect b/pkg/front_end/testcases/export_main.dart.strong.expect
index 9227cd5..1f4d73b 100644
--- a/pkg/front_end/testcases/export_main.dart.strong.expect
+++ b/pkg/front_end/testcases/export_main.dart.strong.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./hello.dart" as hel;
 additionalExports = (hel::main)
+
+
+export "org-dartlang-testcase:///hello.dart";
+
+
+library;
+import self as hel;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/export_main.dart.strong.transformed.expect b/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
index 9227cd5..1f4d73b 100644
--- a/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./hello.dart" as hel;
 additionalExports = (hel::main)
+
+
+export "org-dartlang-testcase:///hello.dart";
+
+
+library;
+import self as hel;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/export_test.dart.legacy.expect b/pkg/front_end/testcases/export_test.dart.legacy.expect
index 40ce1cc..cf3dd78 100644
--- a/pkg/front_end/testcases/export_test.dart.legacy.expect
+++ b/pkg/front_end/testcases/export_test.dart.legacy.expect
@@ -4,6 +4,10 @@
 import "dart:developer" as dev;
 additionalExports = (core::print)
 
+
+import "dart:profiler";
+export "dart:core";
+
 static method main() → dynamic {
   core::print(dev::UserTag);
 }
diff --git a/pkg/front_end/testcases/export_test.dart.legacy.transformed.expect b/pkg/front_end/testcases/export_test.dart.legacy.transformed.expect
index 40ce1cc..cf3dd78 100644
--- a/pkg/front_end/testcases/export_test.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/export_test.dart.legacy.transformed.expect
@@ -4,6 +4,10 @@
 import "dart:developer" as dev;
 additionalExports = (core::print)
 
+
+import "dart:profiler";
+export "dart:core";
+
 static method main() → dynamic {
   core::print(dev::UserTag);
 }
diff --git a/pkg/front_end/testcases/export_test.dart.outline.expect b/pkg/front_end/testcases/export_test.dart.outline.expect
index bf0347a..e337eae 100644
--- a/pkg/front_end/testcases/export_test.dart.outline.expect
+++ b/pkg/front_end/testcases/export_test.dart.outline.expect
@@ -3,5 +3,9 @@
 import "dart:core" as core;
 additionalExports = (core::print)
 
+
+import "dart:profiler";
+export "dart:core";
+
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/export_test.dart.strong.expect b/pkg/front_end/testcases/export_test.dart.strong.expect
index 40ce1cc..cf3dd78 100644
--- a/pkg/front_end/testcases/export_test.dart.strong.expect
+++ b/pkg/front_end/testcases/export_test.dart.strong.expect
@@ -4,6 +4,10 @@
 import "dart:developer" as dev;
 additionalExports = (core::print)
 
+
+import "dart:profiler";
+export "dart:core";
+
 static method main() → dynamic {
   core::print(dev::UserTag);
 }
diff --git a/pkg/front_end/testcases/export_test.dart.strong.transformed.expect b/pkg/front_end/testcases/export_test.dart.strong.transformed.expect
index 40ce1cc..cf3dd78 100644
--- a/pkg/front_end/testcases/export_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/export_test.dart.strong.transformed.expect
@@ -4,6 +4,10 @@
 import "dart:developer" as dev;
 additionalExports = (core::print)
 
+
+import "dart:profiler";
+export "dart:core";
+
 static method main() → dynamic {
   core::print(dev::UserTag);
 }
diff --git a/pkg/front_end/testcases/expression/regress_34224.expression.yaml b/pkg/front_end/testcases/expression/regress_34224.expression.yaml
new file mode 100644
index 0000000..a399aaf
--- /dev/null
+++ b/pkg/front_end/testcases/expression/regress_34224.expression.yaml
@@ -0,0 +1,9 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+entry_point: "main.dart"
+definitions: []
+position: "dart:core#Object"
+expression: |
+  toString()
\ No newline at end of file
diff --git a/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect b/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect
new file mode 100644
index 0000000..d107580
--- /dev/null
+++ b/pkg/front_end/testcases/expression/regress_34224.expression.yaml.expect
@@ -0,0 +1,4 @@
+Errors: {
+}
+method /* from org-dartlang-debug:synthetic_debug_expression */ debugExpr() → dynamic
+  return this.{dart.core::Object::toString}();
diff --git a/pkg/front_end/testcases/expressions.dart.legacy.expect b/pkg/front_end/testcases/expressions.dart.legacy.expect
index 158f1ec..5676a4d 100644
--- a/pkg/front_end/testcases/expressions.dart.legacy.expect
+++ b/pkg/front_end/testcases/expressions.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/expressions.dart:74:16: Warning: Method not found: 'int.toString'.
 //     print(int?.toString());
 //                ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/expressions.dart.legacy.transformed.expect b/pkg/front_end/testcases/expressions.dart.legacy.transformed.expect
index 04022a3..5a549bb 100644
--- a/pkg/front_end/testcases/expressions.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/expressions.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/expressions.dart:74:16: Warning: Method not found: 'int.toString'.
+//     print(int?.toString());
+//                ^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/expressions.dart.strong.expect b/pkg/front_end/testcases/expressions.dart.strong.expect
index 4b86fde..2a658a7 100644
--- a/pkg/front_end/testcases/expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/expressions.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/expressions.dart:74:16: Error: Method not found: 'int.toString'.
 //     print(int?.toString());
 //                ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/expressions.dart.strong.transformed.expect
index 65212a2..2732cf4 100644
--- a/pkg/front_end/testcases/expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/expressions.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/expressions.dart:74:16: Error: Method not found: 'int.toString'.
+//     print(int?.toString());
+//                ^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/external.dart.legacy.expect b/pkg/front_end/testcases/external.dart.legacy.expect
index 273c277..12cc7b1 100644
--- a/pkg/front_end/testcases/external.dart.legacy.expect
+++ b/pkg/front_end/testcases/external.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:isolate" as iso;
 
+import "dart:isolate";
+
 static field dynamic subscription;
 static method onData(dynamic x) → void {
   core::print(x);
diff --git a/pkg/front_end/testcases/external.dart.legacy.transformed.expect b/pkg/front_end/testcases/external.dart.legacy.transformed.expect
index 273c277..12cc7b1 100644
--- a/pkg/front_end/testcases/external.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/external.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:isolate" as iso;
 
+import "dart:isolate";
+
 static field dynamic subscription;
 static method onData(dynamic x) → void {
   core::print(x);
diff --git a/pkg/front_end/testcases/external.dart.outline.expect b/pkg/front_end/testcases/external.dart.outline.expect
index 7c62be8..1c44d50 100644
--- a/pkg/front_end/testcases/external.dart.outline.expect
+++ b/pkg/front_end/testcases/external.dart.outline.expect
@@ -1,6 +1,8 @@
 library;
 import self as self;
 
+import "dart:isolate";
+
 static field dynamic subscription;
 static method onData(dynamic x) → void
   ;
diff --git a/pkg/front_end/testcases/external.dart.strong.expect b/pkg/front_end/testcases/external.dart.strong.expect
index e4daff6..8025ecf 100644
--- a/pkg/front_end/testcases/external.dart.strong.expect
+++ b/pkg/front_end/testcases/external.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:isolate" as iso;
 
+import "dart:isolate";
+
 static field dynamic subscription;
 static method onData(dynamic x) → void {
   core::print(x);
diff --git a/pkg/front_end/testcases/external.dart.strong.transformed.expect b/pkg/front_end/testcases/external.dart.strong.transformed.expect
index e4daff6..8025ecf 100644
--- a/pkg/front_end/testcases/external.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/external.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:isolate" as iso;
 
+import "dart:isolate";
+
 static field dynamic subscription;
 static method onData(dynamic x) → void {
   core::print(x);
diff --git a/pkg/front_end/testcases/for_in_without_declaration.dart b/pkg/front_end/testcases/for_in_without_declaration.dart
index 2e0951b..127f33b 100644
--- a/pkg/front_end/testcases/for_in_without_declaration.dart
+++ b/pkg/front_end/testcases/for_in_without_declaration.dart
@@ -42,6 +42,8 @@
       print(x);
       print(y);
     }
+    const int constant = 0;
+    for (constant in []) {}
   }
 }
 
diff --git a/pkg/front_end/testcases/for_in_without_declaration.dart.hierarchy.expect b/pkg/front_end/testcases/for_in_without_declaration.dart.hierarchy.expect
new file mode 100644
index 0000000..c2dd5c8
--- /dev/null
+++ b/pkg/front_end/testcases/for_in_without_declaration.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Super:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Super.superInstanceField
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Super.untypedSuperInstanceField
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Super.superInstanceField
+    Super.untypedSuperInstanceField
+
+C:
+  superclasses:
+    Object
+      -> Super
+  interfaces:
+  classMembers:
+    Object.toString
+    Super.superInstanceField
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.untypedInstanceField
+    Object._instanceOf
+    C.staticField
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.untypedStaticField
+    C.instanceField
+    Object._simpleInstanceOfFalse
+    Super.untypedSuperInstanceField
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Super.superInstanceField
+    C.untypedInstanceField
+    C.staticField
+    C.untypedStaticField
+    C.instanceField
+    Super.untypedSuperInstanceField
diff --git a/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.expect b/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.expect
index 2aab6ce..8e5c9f4 100644
--- a/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.expect
+++ b/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/for_in_without_declaration.dart:32:10: Error: Expected an identifier, but got 'super'.
 //     for (super.superInstanceField in []) {}
@@ -47,42 +49,11 @@
 // pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
 //     for (var x, y in <int>[]) {
 //          ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/for_in_without_declaration.dart:32:10: Error: Expected an identifier, but got 'super'.
-//     for (super.superInstanceField in []) {}
-//          ^^^^^
+// pkg/front_end/testcases/for_in_without_declaration.dart:46:10: Warning: Setter not found: 'constant'.
+//     for (constant in []) {}
+//          ^^^^^^^^
 //
-// pkg/front_end/testcases/for_in_without_declaration.dart:33:10: Error: Expected an identifier, but got 'super'.
-//     for (super.untypedSuperInstanceField in []) {}
-//          ^^^^^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:35:11: Error: Unexpected token '.'.
-//     for (c.instanceField in []) {}
-//           ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:36:11: Error: Unexpected token '.'.
-//     for (c.untypedSuperInstanceField in []) {}
-//           ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
-//     for (unresolved.foo in []) {}
-//                    ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:39:11: Error: Unexpected token '.'.
-//     for (c.unresolved in []) {}
-//           ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:40:14: Error: Unexpected token '('.
-//     for (main() in []) {}
-//              ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:41:15: Error: Unexpected token ','.
-//     for (var x, y in <int>[]) {
-//               ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -177,6 +148,10 @@
         }
       }
     }
+    const core::int constant = 0;
+    for (final dynamic #t18 in <dynamic>[]) {
+      throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#constant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t18]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    }
   }
 }
 static field core::bool topLevelField;
diff --git a/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.transformed.expect b/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.transformed.expect
index 88f2996..8e5c9f4 100644
--- a/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/for_in_without_declaration.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/for_in_without_declaration.dart:32:10: Error: Expected an identifier, but got 'super'.
 //     for (super.superInstanceField in []) {}
@@ -16,6 +18,14 @@
 //     for (c.untypedSuperInstanceField in []) {}
 //           ^
 //
+// pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Warning: Setter not found: 'unresolved'.
+//     for (unresolved in []) {}
+//          ^^^^^^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:38:10: Warning: Getter not found: 'unresolved'.
+//     for (unresolved.foo in []) {}
+//          ^^^^^^^^^^
+//
 // pkg/front_end/testcases/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
 //     for (unresolved.foo in []) {}
 //                    ^
@@ -28,11 +38,22 @@
 //     for (main() in []) {}
 //              ^
 //
+// pkg/front_end/testcases/for_in_without_declaration.dart:40:10: Error: Can't assign to this, so it can't be used in a for-in loop.
+//     for (main() in []) {}
+//          ^^^^
+//
 // pkg/front_end/testcases/for_in_without_declaration.dart:41:15: Error: Unexpected token ','.
 //     for (var x, y in <int>[]) {
 //               ^
-
-library;
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
+//     for (var x, y in <int>[]) {
+//          ^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:46:10: Warning: Setter not found: 'constant'.
+//     for (constant in []) {}
+//          ^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -127,6 +148,10 @@
         }
       }
     }
+    const core::int constant = 0;
+    for (final dynamic #t18 in <dynamic>[]) {
+      throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#constant, 34, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[#t18]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    }
   }
 }
 static field core::bool topLevelField;
diff --git a/pkg/front_end/testcases/for_in_without_declaration.dart.strong.expect b/pkg/front_end/testcases/for_in_without_declaration.dart.strong.expect
index e672743..cc7b291 100644
--- a/pkg/front_end/testcases/for_in_without_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/for_in_without_declaration.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/for_in_without_declaration.dart:32:10: Error: Expected an identifier, but got 'super'.
 //     for (super.superInstanceField in []) {}
@@ -48,6 +50,10 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
+// pkg/front_end/testcases/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+//     for (constant in []) {}
+//          ^^^^^^^^
+//
 // pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: The setter 'unresolved' isn't defined for the class 'C'.
 //  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
@@ -65,50 +71,7 @@
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
 //     for (c.unresolved in []) {}
 //            ^^^^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/for_in_without_declaration.dart:32:10: Error: Expected an identifier, but got 'super'.
-//     for (super.superInstanceField in []) {}
-//          ^^^^^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:33:10: Error: Expected an identifier, but got 'super'.
-//     for (super.untypedSuperInstanceField in []) {}
-//          ^^^^^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:35:11: Error: Unexpected token '.'.
-//     for (c.instanceField in []) {}
-//           ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:36:11: Error: Unexpected token '.'.
-//     for (c.untypedSuperInstanceField in []) {}
-//           ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: Setter not found: 'unresolved'.
-//     for (unresolved in []) {}
-//          ^^^^^^^^^^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:38:10: Error: Getter not found: 'unresolved'.
-//     for (unresolved.foo in []) {}
-//          ^^^^^^^^^^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
-//     for (unresolved.foo in []) {}
-//                    ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:39:11: Error: Unexpected token '.'.
-//     for (c.unresolved in []) {}
-//           ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:40:14: Error: Unexpected token '('.
-//     for (main() in []) {}
-//              ^
-//
-// pkg/front_end/testcases/for_in_without_declaration.dart:41:15: Error: Unexpected token ','.
-//     for (var x, y in <int>[]) {
-//               ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -168,21 +131,21 @@
       c.{self::Super::untypedSuperInstanceField} = #t12;
     }
     for (final dynamic #t13 in <dynamic>[]) {
-      let final dynamic #t14 = this in invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: The setter 'unresolved' isn't defined for the class 'C'.
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: The setter 'unresolved' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
     for (unresolved in []) {}
          ^^^^^^^^^^";
     }
-    for (final dynamic #t15 in <dynamic>[]) {
-      let final dynamic #t16 = this.unresolved in invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:38:21: Error: The setter 'foo' isn't defined for the class 'C'.
+    for (final dynamic #t14 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:38:21: Error: The setter 'foo' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
     for (unresolved.foo in []) {}
                     ^^^";
     }
-    for (final dynamic #t17 in <dynamic>[]) {
-      let final dynamic #t18 = c in invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:39:12: Error: The setter 'unresolved' isn't defined for the class 'C'.
+    for (final dynamic #t15 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:39:12: Error: The setter 'unresolved' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
     for (c.unresolved in []) {}
@@ -192,7 +155,7 @@
       invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:40:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (main() in []) {}
          ^^^^";
-      for (final dynamic #t19 in <dynamic>[]) {
+      for (final dynamic #t16 in <dynamic>[]) {
         invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:40:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (main() in []) {}
          ^^^^";
@@ -203,7 +166,7 @@
       invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
     for (var x, y in <int>[]) {
          ^^^";
-      for (final core::int #t20 in <core::int>[]) {
+      for (final core::int #t17 in <core::int>[]) {
         invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
     for (var x, y in <int>[]) {
          ^^^";
@@ -215,6 +178,12 @@
         }
       }
     }
+    const core::int constant = 0;
+    for (final dynamic #t18 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+    for (constant in []) {}
+         ^^^^^^^^";
+    }
   }
 }
 static field core::bool topLevelField;
diff --git a/pkg/front_end/testcases/for_in_without_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/for_in_without_declaration.dart.strong.transformed.expect
new file mode 100644
index 0000000..cc7b291
--- /dev/null
+++ b/pkg/front_end/testcases/for_in_without_declaration.dart.strong.transformed.expect
@@ -0,0 +1,191 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:32:10: Error: Expected an identifier, but got 'super'.
+//     for (super.superInstanceField in []) {}
+//          ^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:33:10: Error: Expected an identifier, but got 'super'.
+//     for (super.untypedSuperInstanceField in []) {}
+//          ^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:35:11: Error: Unexpected token '.'.
+//     for (c.instanceField in []) {}
+//           ^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:36:11: Error: Unexpected token '.'.
+//     for (c.untypedSuperInstanceField in []) {}
+//           ^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: Setter not found: 'unresolved'.
+//     for (unresolved in []) {}
+//          ^^^^^^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:38:10: Error: Getter not found: 'unresolved'.
+//     for (unresolved.foo in []) {}
+//          ^^^^^^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:38:20: Error: Unexpected token '.'.
+//     for (unresolved.foo in []) {}
+//                    ^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:39:11: Error: Unexpected token '.'.
+//     for (c.unresolved in []) {}
+//           ^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:40:14: Error: Unexpected token '('.
+//     for (main() in []) {}
+//              ^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:40:10: Error: Can't assign to this, so it can't be used in a for-in loop.
+//     for (main() in []) {}
+//          ^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:41:15: Error: Unexpected token ','.
+//     for (var x, y in <int>[]) {
+//               ^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
+//     for (var x, y in <int>[]) {
+//          ^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+//     for (constant in []) {}
+//          ^^^^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: The setter 'unresolved' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
+//     for (unresolved in []) {}
+//          ^^^^^^^^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:38:21: Error: The setter 'foo' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+//     for (unresolved.foo in []) {}
+//                     ^^^
+//
+// pkg/front_end/testcases/for_in_without_declaration.dart:39:12: Error: The setter 'unresolved' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
+//     for (c.unresolved in []) {}
+//            ^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Super extends core::Object {
+  field core::int superInstanceField = null;
+  field dynamic untypedSuperInstanceField = null;
+  synthetic constructor •() → self::Super
+    : super core::Object::•()
+    ;
+}
+class C extends self::Super {
+  field core::int instanceField = null;
+  field dynamic untypedInstanceField = null;
+  static field core::double staticField = null;
+  static field dynamic untypedStaticField = null;
+  synthetic constructor •() → self::C
+    : super self::Super::•()
+    ;
+  method m() → dynamic {
+    core::String local;
+    dynamic untypedLocal;
+    for (final core::String #t1 in <core::String>[]) {
+      local = #t1;
+    }
+    for (final dynamic #t2 in <dynamic>[]) {
+      untypedLocal = #t2;
+    }
+    for (final core::int #t3 in <core::int>[]) {
+      this.{self::C::instanceField} = #t3;
+    }
+    for (final dynamic #t4 in <dynamic>[]) {
+      this.{self::C::untypedInstanceField} = #t4;
+    }
+    for (final core::double #t5 in <core::double>[]) {
+      self::C::staticField = #t5;
+    }
+    for (final dynamic #t6 in <dynamic>[]) {
+      self::C::untypedStaticField = #t6;
+    }
+    for (final core::bool #t7 in <core::bool>[]) {
+      self::topLevelField = #t7;
+    }
+    for (final dynamic #t8 in <dynamic>[]) {
+      self::untypedTopLevelField = #t8;
+    }
+    for (final core::int #t9 in <core::int>[]) {
+      super.{self::Super::superInstanceField} = #t9;
+    }
+    for (final dynamic #t10 in <dynamic>[]) {
+      super.{self::Super::untypedSuperInstanceField} = #t10;
+    }
+    self::C c = new self::C::•();
+    for (final core::int #t11 in <core::int>[]) {
+      c.{self::C::instanceField} = #t11;
+    }
+    for (final dynamic #t12 in <dynamic>[]) {
+      c.{self::Super::untypedSuperInstanceField} = #t12;
+    }
+    for (final dynamic #t13 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:37:10: Error: The setter 'unresolved' isn't defined for the class 'C'.
+ - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
+    for (unresolved in []) {}
+         ^^^^^^^^^^";
+    }
+    for (final dynamic #t14 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:38:21: Error: The setter 'foo' isn't defined for the class 'C'.
+ - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'foo'.
+    for (unresolved.foo in []) {}
+                    ^^^";
+    }
+    for (final dynamic #t15 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:39:12: Error: The setter 'unresolved' isn't defined for the class 'C'.
+ - 'C' is from 'pkg/front_end/testcases/for_in_without_declaration.dart'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'unresolved'.
+    for (c.unresolved in []) {}
+           ^^^^^^^^^^";
+    }
+    {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:40:10: Error: Can't assign to this, so it can't be used in a for-in loop.
+    for (main() in []) {}
+         ^^^^";
+      for (final dynamic #t16 in <dynamic>[]) {
+        invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:40:10: Error: Can't assign to this, so it can't be used in a for-in loop.
+    for (main() in []) {}
+         ^^^^";
+        self::main();
+      }
+    }
+    {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
+    for (var x, y in <int>[]) {
+         ^^^";
+      for (final core::int #t17 in <core::int>[]) {
+        invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:41:10: Error: A for-in loop can't have more than one loop variable.
+    for (var x, y in <int>[]) {
+         ^^^";
+        dynamic x;
+        dynamic y;
+        {
+          core::print(x);
+          core::print(y);
+        }
+      }
+    }
+    const core::int constant = 0;
+    for (final dynamic #t18 in <dynamic>[]) {
+      invalid-expression "pkg/front_end/testcases/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+    for (constant in []) {}
+         ^^^^^^^^";
+    }
+  }
+}
+static field core::bool topLevelField;
+static field dynamic untypedTopLevelField;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.strong.expect b/pkg/front_end/testcases/function_type_assignments.dart.strong.expect
index a7d04c0..47dadba 100644
--- a/pkg/front_end/testcases/function_type_assignments.dart.strong.expect
+++ b/pkg/front_end/testcases/function_type_assignments.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -16,8 +18,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 // String z = identityList; // List<T> bound
 //            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect
index f945f65..47dadba 100644
--- a/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/function_type_assignments.dart.strong.transformed.expect
@@ -1,4 +1,24 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/function_type_assignments.dart:11:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// String x = identity; // No bound
+//            ^
+//
+// pkg/front_end/testcases/function_type_assignments.dart:12:12: Error: A value of type 'T Function<T extends Object>(T)' can't be assigned to a variable of type 'String'.
+//  - 'Object' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// String y = identityObject; // Object bound
+//            ^
+//
+// pkg/front_end/testcases/function_type_assignments.dart:13:12: Error: A value of type 'T Function<T extends List<T>>(T)' can't be assigned to a variable of type 'String'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+// String z = identityList; // List<T> bound
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect b/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect
index ba53ef3..17bf98f 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
 // void Function({obj: Object}) x;
@@ -11,18 +13,7 @@
 // pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: 'obj' isn't a type.
 // void Function({obj: Object}) x;
 //                ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
-// void Function({obj: Object}) x;
-//                   ^
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Can't have a default value in a function type.
-// void Function({obj: Object}) x;
-//                   ^
-
-library;
 import self as self;
 
 static field () → void x;
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect b/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect
index 1e5f712..17bf98f 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
 // void Function({obj: Object}) x;
@@ -7,8 +9,11 @@
 // pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Can't have a default value in a function type.
 // void Function({obj: Object}) x;
 //                   ^
-
-library;
+//
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Warning: 'obj' isn't a type.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 import self as self;
 
 static field () → void x;
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.outline.expect b/pkg/front_end/testcases/function_type_default_value.dart.outline.expect
index 8512a58..ce8fac7 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.outline.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
 // void Function({obj: Object}) x;
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Can't have a default value in a function type.
 // void Function({obj: Object}) x;
 //                   ^
-
-library;
+//
 import self as self;
 
 static field () → void x;
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.strong.expect b/pkg/front_end/testcases/function_type_default_value.dart.strong.expect
index 1d5c09e..dd48e08 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.strong.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.strong.expect
@@ -1,32 +1,19 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
-// void Function({obj: Object}) x;
-//                   ^
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Can't have a default value in a function type.
-// void Function({obj: Object}) x;
-//                   ^
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: 'obj' isn't a type.
-// void Function({obj: Object}) x;
-//                ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
-// void Function({obj: Object}) x;
-//                   ^
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Can't have a default value in a function type.
-// void Function({obj: Object}) x;
-//                   ^
-//
-// pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: 'obj' isn't a type.
-// void Function({obj: Object}) x;
-//                ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
+// void Function({obj: Object}) x;
+//                   ^
+//
+// pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Can't have a default value in a function type.
+// void Function({obj: Object}) x;
+//                   ^
+//
+// pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: 'obj' isn't a type.
+// void Function({obj: Object}) x;
+//                ^^^
+//
 import self as self;
 
 static field () → void x;
diff --git a/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect
index de199db..dd48e08 100644
--- a/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/function_type_default_value.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_default_value.dart:5:19: Error: Expected an identifier, but got ':'.
 // void Function({obj: Object}) x;
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/function_type_default_value.dart:5:16: Error: 'obj' isn't a type.
 // void Function({obj: Object}) x;
 //                ^^^
-
-library;
+//
 import self as self;
 
 static field () → void x;
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.hierarchy.expect b/pkg/front_end/testcases/function_type_is_check.dart.hierarchy.expect
new file mode 100644
index 0000000..98d4425
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_is_check.dart.hierarchy.expect
@@ -0,0 +1,433 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.legacy.expect b/pkg/front_end/testcases/function_type_is_check.dart.legacy.expect
index 47e3281..f34e7d0 100644
--- a/pkg/front_end/testcases/function_type_is_check.dart.legacy.expect
+++ b/pkg/front_end/testcases/function_type_is_check.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic f) → dynamic {
   if(f is (core::Object, core::StackTrace) → void)
     return 1;
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.legacy.transformed.expect b/pkg/front_end/testcases/function_type_is_check.dart.legacy.transformed.expect
index 47e3281..f34e7d0 100644
--- a/pkg/front_end/testcases/function_type_is_check.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/function_type_is_check.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic f) → dynamic {
   if(f is (core::Object, core::StackTrace) → void)
     return 1;
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.outline.expect b/pkg/front_end/testcases/function_type_is_check.dart.outline.expect
index b9650b8..8278f14 100644
--- a/pkg/front_end/testcases/function_type_is_check.dart.outline.expect
+++ b/pkg/front_end/testcases/function_type_is_check.dart.outline.expect
@@ -1,6 +1,8 @@
 library;
 import self as self;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic f) → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.strong.expect b/pkg/front_end/testcases/function_type_is_check.dart.strong.expect
index f827885..5fa7a1a 100644
--- a/pkg/front_end/testcases/function_type_is_check.dart.strong.expect
+++ b/pkg/front_end/testcases/function_type_is_check.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic f) → dynamic {
   if(f is (core::Object, core::StackTrace) → void)
     return 1;
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect
index f827885..5fa7a1a 100644
--- a/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic f) → dynamic {
   if(f is (core::Object, core::StackTrace) → void)
     return 1;
diff --git a/pkg/front_end/testcases/function_type_recovery.dart.outline.expect b/pkg/front_end/testcases/function_type_recovery.dart.outline.expect
index 244b4eb..ec474f1 100644
--- a/pkg/front_end/testcases/function_type_recovery.dart.outline.expect
+++ b/pkg/front_end/testcases/function_type_recovery.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_recovery.dart:8:31: Error: Inline function types cannot be used for parameters in a generic function type.
 // Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
 // typedef F = int Function(int f(String x));
 //                               ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/function_type_recovery.dart.strong.expect b/pkg/front_end/testcases/function_type_recovery.dart.strong.expect
index ff7a407..4d646a1 100644
--- a/pkg/front_end/testcases/function_type_recovery.dart.strong.expect
+++ b/pkg/front_end/testcases/function_type_recovery.dart.strong.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/function_type_recovery.dart:8:31: Error: Inline function types cannot be used for parameters in a generic function type.
-// Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
-// typedef F = int Function(int f(String x));
-//                               ^
-//
-// pkg/front_end/testcases/function_type_recovery.dart:12:27: Error: Inline function types cannot be used for parameters in a generic function type.
-// Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
-//   String Function(String g(int y)) g = null;
-//                           ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/function_type_recovery.dart:8:31: Error: Inline function types cannot be used for parameters in a generic function type.
-// Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
-// typedef F = int Function(int f(String x));
-//                               ^
-//
-// pkg/front_end/testcases/function_type_recovery.dart:12:27: Error: Inline function types cannot be used for parameters in a generic function type.
-// Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
-//   String Function(String g(int y)) g = null;
-//                           ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/function_type_recovery.dart:8:31: Error: Inline function types cannot be used for parameters in a generic function type.
+// Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
+// typedef F = int Function(int f(String x));
+//                               ^
+//
+// pkg/front_end/testcases/function_type_recovery.dart:12:27: Error: Inline function types cannot be used for parameters in a generic function type.
+// Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
+//   String Function(String g(int y)) g = null;
+//                           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/function_type_recovery.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_recovery.dart.strong.transformed.expect
index cc3bac0..4d646a1 100644
--- a/pkg/front_end/testcases/function_type_recovery.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/function_type_recovery.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/function_type_recovery.dart:8:31: Error: Inline function types cannot be used for parameters in a generic function type.
 // Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
@@ -9,8 +11,7 @@
 // Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').
 //   String Function(String g(int y)) g = null;
 //                           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/future_or_test.dart.hierarchy.expect b/pkg/front_end/testcases/future_or_test.dart.hierarchy.expect
new file mode 100644
index 0000000..5279442
--- /dev/null
+++ b/pkg/front_end/testcases/future_or_test.dart.hierarchy.expect
@@ -0,0 +1,77 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.bar
+    B.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.a
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.baz
+  classSetters:
+    C.b
diff --git a/pkg/front_end/testcases/future_or_test.dart.legacy.expect b/pkg/front_end/testcases/future_or_test.dart.legacy.expect
index 6006dfc..4845918 100644
--- a/pkg/front_end/testcases/future_or_test.dart.legacy.expect
+++ b/pkg/front_end/testcases/future_or_test.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/future_or_test.dart.legacy.transformed.expect b/pkg/front_end/testcases/future_or_test.dart.legacy.transformed.expect
index e7939ce..05de994 100644
--- a/pkg/front_end/testcases/future_or_test.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/future_or_test.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/future_or_test.dart.outline.expect b/pkg/front_end/testcases/future_or_test.dart.outline.expect
index d5d8729..b603181 100644
--- a/pkg/front_end/testcases/future_or_test.dart.outline.expect
+++ b/pkg/front_end/testcases/future_or_test.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
diff --git a/pkg/front_end/testcases/future_or_test.dart.strong.expect b/pkg/front_end/testcases/future_or_test.dart.strong.expect
index 0406605..f0d3199 100644
--- a/pkg/front_end/testcases/future_or_test.dart.strong.expect
+++ b/pkg/front_end/testcases/future_or_test.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect b/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect
index 91c8f82..4df4a38 100644
--- a/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.expect b/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.expect
index 79cb600..725841d 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
-//   var x = void f<T>(T t) {};
-//                ^
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
-//   print(void g<T>(T t) {});
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
-//   var x = void f<T>(T t) {};
-//                ^
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
-//   print(void g<T>(T t) {});
-//              ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
+//   var x = void f<T>(T t) {};
+//                ^
+//
+// pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
+//   print(void g<T>(T t) {});
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.transformed.expect
index 9627a6e8..725841d 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
 //   var x = void f<T>(T t) {};
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
 //   print(void g<T>(T t) {});
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.expect b/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.expect
index 0fbf026..0be54a8 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
-//   var x = void f<T>(T t) {};
-//                ^
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
-//   print(void g<T>(T t) {});
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
-//   var x = void f<T>(T t) {};
-//                ^
-//
-// pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
-//   print(void g<T>(T t) {});
-//              ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
+//   var x = void f<T>(T t) {};
+//                ^
+//
+// pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
+//   print(void g<T>(T t) {});
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect
index 0f485bc..0be54a8 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
 //   var x = void f<T>(T t) {};
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
 //   print(void g<T>(T t) {});
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.expect b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.expect
index a8247f6..8469fb4 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
-//   print(void f() {});
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
-//   print(void f() {});
-//              ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
+//   print(void f() {});
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.transformed.expect
index 9df8705..8469fb4 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
 //   print(void f() {});
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.expect b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.expect
index eb14ed2..bb2aa3b 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
-//   print(void f() {});
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
-//   print(void f() {});
-//              ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
+//   print(void f() {});
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect
index 546d092..bb2aa3b 100644
--- a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
 //   print(void f() {});
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/implicit_const_with_static_fields.dart.hierarchy.expect b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.hierarchy.expect
new file mode 100644
index 0000000..62f92d8
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_const_with_static_fields.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.constField
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/implicit_new.dart.hierarchy.expect b/pkg/front_end/testcases/implicit_new.dart.hierarchy.expect
new file mode 100644
index 0000000..9d1c34f
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_new.dart.hierarchy.expect
@@ -0,0 +1,74 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Foo.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Bar.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+IndexTester:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    IndexTester.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    IndexTester.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/implicit_new.dart.legacy.expect b/pkg/front_end/testcases/implicit_new.dart.legacy.expect
index d2fd4b41..2b438cf 100644
--- a/pkg/front_end/testcases/implicit_new.dart.legacy.expect
+++ b/pkg/front_end/testcases/implicit_new.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/implicit_new.dart:18:18: Warning: Method not found: 'Bar'.
 //   var y = prefix.Bar();
@@ -7,11 +9,12 @@
 // pkg/front_end/testcases/implicit_new.dart:19:10: Warning: Method not found: 'Bar'.
 //   prefix.Bar();
 //          ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///implicit_new.dart" as prefix;
+
 class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_new.dart.legacy.transformed.expect b/pkg/front_end/testcases/implicit_new.dart.legacy.transformed.expect
index 5a42d71..2b438cf 100644
--- a/pkg/front_end/testcases/implicit_new.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/implicit_new.dart.legacy.transformed.expect
@@ -1,7 +1,20 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/implicit_new.dart:18:18: Warning: Method not found: 'Bar'.
+//   var y = prefix.Bar();
+//                  ^^^
+//
+// pkg/front_end/testcases/implicit_new.dart:19:10: Warning: Method not found: 'Bar'.
+//   prefix.Bar();
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///implicit_new.dart" as prefix;
+
 class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_new.dart.outline.expect b/pkg/front_end/testcases/implicit_new.dart.outline.expect
index 1553a2d..d976e78 100644
--- a/pkg/front_end/testcases/implicit_new.dart.outline.expect
+++ b/pkg/front_end/testcases/implicit_new.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///implicit_new.dart" as prefix;
+
 class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     ;
diff --git a/pkg/front_end/testcases/implicit_new.dart.strong.expect b/pkg/front_end/testcases/implicit_new.dart.strong.expect
index 1ca7013..c1c5e91 100644
--- a/pkg/front_end/testcases/implicit_new.dart.strong.expect
+++ b/pkg/front_end/testcases/implicit_new.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/implicit_new.dart:18:18: Error: Method not found: 'Bar'.
 //   var y = prefix.Bar();
@@ -7,11 +9,12 @@
 // pkg/front_end/testcases/implicit_new.dart:19:10: Error: Method not found: 'Bar'.
 //   prefix.Bar();
 //          ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///implicit_new.dart" as prefix;
+
 class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect b/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect
index 4a56e31..c1c5e91 100644
--- a/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect
@@ -1,7 +1,20 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/implicit_new.dart:18:18: Error: Method not found: 'Bar'.
+//   var y = prefix.Bar();
+//                  ^^^
+//
+// pkg/front_end/testcases/implicit_new.dart:19:10: Error: Method not found: 'Bar'.
+//   prefix.Bar();
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///implicit_new.dart" as prefix;
+
 class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.hierarchy.expect b/pkg/front_end/testcases/implicit_scope_test.dart.hierarchy.expect
new file mode 100644
index 0000000..336c761
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.hierarchy.expect
@@ -0,0 +1,452 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ImplicitScopeTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    ImplicitScopeTest.alwaysTrue
+    Object._instanceOf
+    ImplicitScopeTest.testMain
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.legacy.expect b/pkg/front_end/testcases/implicit_scope_test.dart.legacy.expect
index c4b1074..8f8e6ea 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.legacy.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class ImplicitScopeTest extends core::Object {
   synthetic constructor •() → self::ImplicitScopeTest
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.legacy.transformed.expect b/pkg/front_end/testcases/implicit_scope_test.dart.legacy.transformed.expect
index c4b1074..8f8e6ea 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class ImplicitScopeTest extends core::Object {
   synthetic constructor •() → self::ImplicitScopeTest
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.outline.expect b/pkg/front_end/testcases/implicit_scope_test.dart.outline.expect
index f9c385c..9257345 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.outline.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class ImplicitScopeTest extends core::Object {
   synthetic constructor •() → self::ImplicitScopeTest
     ;
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect b/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
index f74eec3..bc625bc 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class ImplicitScopeTest extends core::Object {
   synthetic constructor •() → self::ImplicitScopeTest
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect b/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
index f74eec3..bc625bc 100644
--- a/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class ImplicitScopeTest extends core::Object {
   synthetic constructor •() → self::ImplicitScopeTest
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/implicit_this.dart.hierarchy.expect b/pkg/front_end/testcases/implicit_this.dart.hierarchy.expect
new file mode 100644
index 0000000..a5e82af
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_this.dart.hierarchy.expect
@@ -0,0 +1,59 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.testC
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    D.testD
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.testC
+  classSetters:
diff --git a/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.hierarchy.expect b/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.expect b/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.expect
index 9b7ba9d..47ea45a 100644
--- a/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.expect
@@ -1,56 +1,31 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected '.' before this.
-//   C.a(this);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected an identifier, but got ')'.
-//   C.a(this);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:7:12: Error: Expected an identifier, but got ')'.
-//   C.b(this.);
-//            ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:8:11: Error: Expected '.' before this.
-//   C.c(this, p);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:8:11: Error: Expected an identifier, but got ','.
-//   C.c(this, p);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:9:12: Error: Expected an identifier, but got ','.
-//   C.d(this., p);
-//            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected '.' before this.
-//   C.a(this);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected an identifier, but got ')'.
-//   C.a(this);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:7:12: Error: Expected an identifier, but got ')'.
-//   C.b(this.);
-//            ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:8:11: Error: Expected '.' before this.
-//   C.c(this, p);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:8:11: Error: Expected an identifier, but got ','.
-//   C.c(this, p);
-//           ^
-//
-// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:9:12: Error: Expected an identifier, but got ','.
-//   C.d(this., p);
-//            ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected '.' before this.
+//   C.a(this);
+//           ^
+//
+// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected an identifier, but got ')'.
+//   C.a(this);
+//           ^
+//
+// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:7:12: Error: Expected an identifier, but got ')'.
+//   C.b(this.);
+//            ^
+//
+// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:8:11: Error: Expected '.' before this.
+//   C.c(this, p);
+//           ^
+//
+// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:8:11: Error: Expected an identifier, but got ','.
+//   C.c(this, p);
+//           ^
+//
+// pkg/front_end/testcases/incomplete_field_formal_parameter.dart:9:12: Error: Expected an identifier, but got ','.
+//   C.d(this., p);
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.transformed.expect
index 6bcd2e6..47ea45a 100644
--- a/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/incomplete_field_formal_parameter.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/incomplete_field_formal_parameter.dart:6:11: Error: Expected '.' before this.
 //   C.a(this);
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/incomplete_field_formal_parameter.dart:9:12: Error: Expected an identifier, but got ','.
 //   C.d(this., p);
 //            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/incremental_bulk_compiler_full.status b/pkg/front_end/testcases/incremental_bulk_compiler_full.status
index 9ceffba..acb1629 100644
--- a/pkg/front_end/testcases/incremental_bulk_compiler_full.status
+++ b/pkg/front_end/testcases/incremental_bulk_compiler_full.status
@@ -1,13 +1,3 @@
 # 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.
-language_2/deferred_super_dependency_test: Crash # missing "#errors"
-language_2/duplicate_export_collision_test: Crash # missing '#errors'
-language_2/import_nonexisting_dart_uri_test: Crash # missing '#errors'
-language_2/internal_library_test: Crash # non-identical '#errors'
-language_2/missing_part_of_tag_test: Crash # missing empty library that shouldn't have been there in the first place
-language_2/mixin_type_parameter_inference_error_test: Crash # non-identical '#errors'
-language_2/part_of_multiple_libs_test: Crash # missing "#errors"
-language_2/part_refers_to_core_library_test: Crash # non-identical '#errors'
-language_2/script1_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
-language_2/script2_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
diff --git a/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status b/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status
index 959cc51..acb1629 100644
--- a/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status
+++ b/pkg/front_end/testcases/incremental_bulk_compiler_smoke.status
@@ -1,8 +1,3 @@
 # 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.
-
-language_2/deferred_super_dependency_test: Crash # missing "#errors"
-language_2/missing_part_of_tag_test: Crash # missing empty library that shouldn't have been there in the first place
-language_2/script1_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
-language_2/script2_negative_test: Crash # missing "#errors", missing empty library that shouldn't have been there in the first place
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
new file mode 100644
index 0000000..5bd270e
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main.yaml
@@ -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.md file.
+
+# When the entry is not given as a package-url, but is intepreted as one
+# (Interpreting this as package URI, 'package:untitled/main.dart'.) the library
+# should still be included in the output.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        main() {
+        }
+      .packages: untitled:/
+    expectedLibraryCount: 1
+    errors: false
+    warnings: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
new file mode 100644
index 0000000..2360641
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_main_with_errors.yaml
@@ -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.md file.
+
+# When the entry is not given as a package-url, but is intepreted as one
+# (Interpreting this as package URI, 'package:untitled/main.dart'.) the library
+# should still be included in the output - even if there's errors in main.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        main() {
+          asdf;
+        }
+      .packages: untitled:/
+    expectedLibraryCount: 1
+    errors: true
+    warnings: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
new file mode 100644
index 0000000..02a57de
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/entry_not_package_url_no_main.yaml
@@ -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.md file.
+
+# When the entry is not given as a package-url, but is intepreted as one
+# (Interpreting this as package URI, 'package:untitled/main.dart'.) the library
+# should still be included in the output - even if there's no main.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        notMain() {}
+      .packages: untitled:/
+    expectedLibraryCount: 1
+    errors: false
+    warnings: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
new file mode 100644
index 0000000..9fbdf62
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/load_from_component_explicitly_import_dart_core.yaml
@@ -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.md file.
+
+# Initialize from component, where the component is linked to one sdk, and where
+# the incremental compiler loads another sdk. Risk when doing this: Having two
+# definitions of the same thing (e.g. the class 'String'), which could lead to
+# errors such as "The argument type 'dart.core::String' can't be assigned to
+# the parameter type 'dart.core::String'".
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    errors: false
+    warnings: false
+    sources:
+      main.dart: |
+        import "b.dart";
+
+        main() {
+          useString("hello");
+        }
+      b.dart: |
+        import "dart:core";
+
+        void useString(String s) {
+          print("Hello from useString: $s");
+        }
+    expectedLibraryCount: 2
+  - entry: main.dart
+    errors: false
+    warnings: false
+    fromComponent: true
+    invalidate:
+      - main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+
+        main() {
+          useString("hello");
+        }
+      b.dart: |
+        import "dart:core";
+
+        void useString(String s) {
+          print("Hello from useString: $s");
+        }
+    expectedLibraryCount: 2
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
new file mode 100644
index 0000000..e571850
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/mixin_inferrer_error.yaml
@@ -0,0 +1,18 @@
+# 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.
+
+# Test that errors issued by the hierarchy mixinInferrer are in fact reported,
+# and now swallowed somewhere when done in the incremental compiler.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        abstract class A<T> {}
+        mixin M<T> on A<T> {}
+        class C extends Object with M {}
+    expectedLibraryCount: 1
+    errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
new file mode 100644
index 0000000..0be7810
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_1.yaml
@@ -0,0 +1,56 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application with errors in it, then - without fixing the errors -
+# recompile. Make sure we still get errors. As long as we don't fix the error,
+# we keep getting errors. Once we fix it, we no longer get errors.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+      b.dart: |
+        asdf
+    expectedLibraryCount: 2
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    expectInitializeFromDill: false
+    expectedLibraryCount: 2
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+      b.dart: |
+        asdf
+    expectedLibraryCount: 2
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 2
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    invalidate:
+      - b.dart
+    sources:
+      b.dart: |
+        asdf;
+    expectedLibraryCount: 2
+  - entry: main.dart
+    errors: false
+    worldType: updated
+    invalidate:
+      - b.dart
+    sources:
+      b.dart: |
+        asdf() {}
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
new file mode 100644
index 0000000..468566d
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_2.yaml
@@ -0,0 +1,66 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application with errors in it, then - without fixing the errors -
+# recompile. Make sure we still get errors. As long as we don't fix the error,
+# we keep getting errors. Once we fix it, we no longer get errors.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+
+        class A extends B {}
+      b.dart: |
+        import "nonexisting.dart";
+
+        class B extends A {}
+    expectedLibraryCount: 2
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    expectInitializeFromDill: false
+    expectedLibraryCount: 2
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+
+        class A extends B {}
+      b.dart: |
+        import "nonexisting.dart";
+
+        class B extends A {}
+    expectedLibraryCount: 2
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 2
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    invalidate:
+      - b.dart
+    sources:
+      b.dart: |
+        import "main.dart";
+
+        class B extends A {}
+    expectedLibraryCount: 2
+  - entry: main.dart
+    errors: false
+    worldType: updated
+    invalidate:
+      - b.dart
+    sources:
+      b.dart: |
+        class B extends Object {}
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
new file mode 100644
index 0000000..5375fd6
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_3.yaml
@@ -0,0 +1,65 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application with errors in it, then - without fixing the errors -
+# recompile. Make sure we still get errors. As long as we don't fix the error,
+# we keep getting errors. Once we fix it, we no longer get errors.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      .packages: mypackage:mypackage
+      main.dart: |
+        import "package:mypackage/a.dart";
+      mypackage/a.dart: |
+        import "package:mypackage/b.dart";
+
+        class Foo<T> {}
+        class Bar<T> extends Foo<T> {}
+      mypackage/b.dart: |
+        import "package:mypackage/a.dart";
+
+        class Baz extends Bar<int> implements Foo<String> {}
+    expectedLibraryCount: 3
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    expectInitializeFromDill: false
+    expectedLibraryCount: 3
+  - entry: main.dart
+    sources:
+      .packages: mypackage:mypackage
+      main.dart: |
+        import "package:mypackage/a.dart";
+      mypackage/a.dart: |
+        import "package:mypackage/b.dart";
+
+        class Foo<T> {}
+        class Bar<T> extends Foo<T> {}
+      mypackage/b.dart: |
+        import "package:mypackage/a.dart";
+
+        class Baz extends Bar<int> implements Foo<String> {}
+    expectedLibraryCount: 3
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 3
+  - entry: main.dart
+    errors: false
+    worldType: updated
+    invalidate:
+      - mypackage/b.dart
+    sources:
+      mypackage/b.dart: |
+        import "package:mypackage/a.dart";
+
+        class Baz extends Bar<int> {}
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
new file mode 100644
index 0000000..994f2c6
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/reissue_errors_4.yaml
@@ -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.md file.
+
+# Compile an application with errors in it, then - without fixing the errors -
+# recompile. Make sure we still get errors. As long as we don't fix the error,
+# we keep getting errors. Once we fix it, we no longer get errors.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      .packages: mypackage:mypackage
+      main.dart: |
+        import "package:mypackage/a.dart";
+      mypackage/a.dart: |
+        import "package:mypackage/b.dart";
+
+        class Foo<T> {}
+        class Bar<T> extends Foo<T> {}
+      mypackage/b.dart: |
+        import "package:mypackage/a.dart";
+        part "package:mypackage/c.dart";
+      mypackage/c.dart: |
+        part of "package:mypackage/b.dart";
+
+        class Baz extends Bar<int> implements Foo<String> {}
+    expectedLibraryCount: 3
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    expectInitializeFromDill: false
+    expectedLibraryCount: 3
+  - entry: main.dart
+    sources:
+      .packages: mypackage:mypackage
+      main.dart: |
+        import "package:mypackage/a.dart";
+      mypackage/a.dart: |
+        import "package:mypackage/b.dart";
+
+        class Foo<T> {}
+        class Bar<T> extends Foo<T> {}
+      mypackage/b.dart: |
+        import "package:mypackage/a.dart";
+        part "package:mypackage/c.dart";
+      mypackage/c.dart: |
+        part of "package:mypackage/b.dart";
+
+        class Baz extends Bar<int> implements Foo<String> {}
+    expectedLibraryCount: 3
+    errors: true
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 3
+  - entry: main.dart
+    errors: false
+    worldType: updated
+    invalidate:
+      - mypackage/c.dart
+    sources:
+      mypackage/b.dart: |
+        import "package:mypackage/a.dart";
+        part "package:mypackage/c.dart";
+      mypackage/c.dart: |
+        part of "package:mypackage/b.dart";
+
+        class Baz extends Bar<int> {}
+    expectedLibraryCount: 3
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/status.status b/pkg/front_end/testcases/incremental_initialize_from_dill/status.status
index f3d01d2..003bd93 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/status.status
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/status.status
@@ -3,3 +3,5 @@
 # BSD-style license that can be found in the LICENSE.md file.
 
 # Status file for the test suite ../test/incremental_load_from_dill_yaml_test.dart.
+
+load_from_component_explicitly_import_dart_core: Crash
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
new file mode 100644
index 0000000..14b0a58
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_1.yaml
@@ -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.md file.
+
+# Compile an application that includes a non-existing file.
+# Make sure the output includes a synthetic library.
+# Loading from such a dill is ok too.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+      b.dart: |
+        import "nonexisting.dart";
+    expectedLibraryCount: 2
+    expectedSyntheticLibraryCount: 1
+    errors: true
+  - entry: main.dart
+    invalidate:
+      - main.dart
+    sources:
+      main.dart: |
+        import "b.dart";
+      b.dart: |
+        import "nonexisting.dart";
+    expectedLibraryCount: 2
+    expectedSyntheticLibraryCount: 1
+    errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
new file mode 100644
index 0000000..bbcc110
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_2.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application that includes a non-existing file from dart:.
+# Make sure the output includes a synthetic library.
+# Loading from such a dill is ok too.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "dart:foo/nonexisting.dart";
+    expectedLibraryCount: 1
+    expectedSyntheticLibraryCount: 1
+    errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
new file mode 100644
index 0000000..0402343
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_3.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application that includes a non-existing file from dart: as a part.
+# Make sure the output includes a synthetic library.
+# Loading from such a dill is ok too.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        part "dart:foo/nonexisting.dart";
+    expectedLibraryCount: 1
+    expectedSyntheticLibraryCount: 1
+    errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
new file mode 100644
index 0000000..df8a598
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_4.yaml
@@ -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.md file.
+
+# Compile an application that includes a non-existing file
+# from package: as a part.
+# Make sure the output includes a synthetic library.
+# Loading from such a dill is ok too.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        part "package:foo/nonexisting.dart";
+    expectedLibraryCount: 1
+    expectedSyntheticLibraryCount: 1
+    errors: true
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
new file mode 100644
index 0000000..bd55d81
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/working_with_synthetic_libraries_5.yaml
@@ -0,0 +1,18 @@
+# Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+# Compile an application that includes a non-existing file from package:.
+# Make sure the output includes a synthetic library.
+# Loading from such a dill is ok too.
+
+type: newworld
+strong: true
+worlds:
+  - entry: main.dart
+    sources:
+      main.dart: |
+        import "package:foo/nonexisting.dart";
+    expectedLibraryCount: 1
+    expectedSyntheticLibraryCount: 1
+    errors: true
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.hierarchy.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.hierarchy.expect
new file mode 100644
index 0000000..db47d25b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.expect
index 1f9b70e..a9fa8e3 100644
--- a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/abstract_class_instantiation.dart:15:27: Warning: The class 'C' is abstract and can't be instantiated.
 //   var /*@type=C*/ x = new C();
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/inference/abstract_class_instantiation.dart:17:48: Warning: The class 'D' is abstract and can't be instantiated.
 //   D<List<int>> z = new /*@typeArgs=List<int>*/ D(/*@typeArgs=int*/ []);
 //                                                ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.transformed.expect
index 50af77d..a9fa8e3 100644
--- a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.legacy.transformed.expect
@@ -1,4 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/abstract_class_instantiation.dart:15:27: Warning: The class 'C' is abstract and can't be instantiated.
+//   var /*@type=C*/ x = new C();
+//                           ^
+//
+// pkg/front_end/testcases/inference/abstract_class_instantiation.dart:16:50: Warning: The class 'D' is abstract and can't be instantiated.
+//   var /*@type=D<int>*/ y = new /*@typeArgs=int*/ D(1);
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/abstract_class_instantiation.dart:17:48: Warning: The class 'D' is abstract and can't be instantiated.
+//   D<List<int>> z = new /*@typeArgs=List<int>*/ D(/*@typeArgs=int*/ []);
+//                                                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.hierarchy.expect b/pkg/front_end/testcases/inference/assign_local.dart.hierarchy.expect
new file mode 100644
index 0000000..38e2563
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/async_await.dart.hierarchy.expect b/pkg/front_end/testcases/inference/async_await.dart.hierarchy.expect
new file mode 100644
index 0000000..494e3cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.hierarchy.expect
@@ -0,0 +1,82 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/async_await.dart.legacy.expect b/pkg/front_end/testcases/inference/async_await.dart.legacy.expect
index 18f91dd..6d20979 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → self::MyFuture
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/async_await.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.legacy.transformed.expect
index 939d401..22a8d1b 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → self::MyFuture
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/async_await.dart.outline.expect b/pkg/front_end/testcases/inference/async_await.dart.outline.expect
index 8642f8d..5d3783f 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → self::MyFuture
     ;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.expect
index 89f497e..7efb511 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → self::MyFuture
     : super core::Object::•()
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 a6dc499..2da1ed0 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyFuture extends core::Object implements asy::Future<core::int> {
   synthetic constructor •() → self::MyFuture
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.expect
index 3b30c6a..90a4155 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::Future<core::int> futureInt = null;
 static field dynamic f = () → dynamic => self::futureInt;
 static field dynamic g = () → asy::Future<dynamic> async => self::futureInt;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.transformed.expect
index 32f482b..87a2f0b 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::Future<core::int> futureInt = null;
 static field dynamic f = () → dynamic => self::futureInt;
 static field dynamic g = () → asy::Future<dynamic> /* originally async */ {
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.expect
index 752d085..7f0e444 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::Future<core::int> futureInt = null;
 static field () → asy::Future<core::int> f = () → asy::Future<core::int> => self::futureInt;
 static field () → asy::Future<core::int> g = () → asy::Future<core::int> async => self::futureInt;
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 f94e9db..7f13592 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::Future<core::int> futureInt = null;
 static field () → asy::Future<core::int> f = () → asy::Future<core::int> => self::futureInt;
 static field () → asy::Future<core::int> g = () → asy::Future<core::int> /* originally async */ {
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.expect
index 3697d56..ff10a71 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::FutureOr<core::int> futureOrInt = null;
 static field dynamic f = () → dynamic => self::futureOrInt;
 static field dynamic g = () → asy::Future<dynamic> async => self::futureOrInt;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.transformed.expect
index 694b2f2..8b46926 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::FutureOr<core::int> futureOrInt = null;
 static field dynamic f = () → dynamic => self::futureOrInt;
 static field dynamic g = () → asy::Future<dynamic> /* originally async */ {
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.expect
index fec1fb6..bceae13 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::FutureOr<core::int> futureOrInt = null;
 static field () → asy::FutureOr<core::int> f = () → asy::FutureOr<core::int> => self::futureOrInt;
 static field () → asy::Future<core::int> g = () → asy::Future<core::int> async => self::futureOrInt;
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 b6536b0..25456f3 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static field asy::FutureOr<core::int> futureOrInt = null;
 static field () → asy::FutureOr<core::int> f = () → asy::FutureOr<core::int> => self::futureOrInt;
 static field () → asy::Future<core::int> g = () → asy::Future<core::int> /* originally async */ {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.expect
index 90e7864..227f268 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.expect
@@ -4,6 +4,9 @@
 import "dart:math" as math;
 import "dart:core" as core;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   dynamic f = () → asy::Future<dynamic> async {
     if(math::Random::•().nextBool()) {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.transformed.expect
index 298fc06..355fa11 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.legacy.transformed.expect
@@ -4,6 +4,9 @@
 import "dart:math" as math;
 import "dart:core" as core;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   dynamic f = () → asy::Future<dynamic> /* originally async */ {
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.expect
index 0eff7a3..87021eb 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.expect
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   () → asy::Future<core::num> f = () → asy::Future<core::num> async {
     if(math::Random::•().{math::Random::nextBool}()) {
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 28def78..3f27c99 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
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   () → asy::Future<core::num> f = () → asy::Future<core::num> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.expect
index 2c7a171..18357b5 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.expect
@@ -4,6 +4,9 @@
 import "dart:math" as math;
 import "dart:core" as core;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   dynamic f = () → asy::Future<dynamic> async {
     if(math::Random::•().nextBool()) {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.transformed.expect
index 860e645..658637a 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.legacy.transformed.expect
@@ -4,6 +4,9 @@
 import "dart:math" as math;
 import "dart:core" as core;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   dynamic f = () → asy::Future<dynamic> /* originally async */ {
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.expect
index 566fd3c..ec4bf15 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.expect
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   () → asy::Future<core::num> f = () → asy::Future<core::num> async {
     if(math::Random::•().{math::Random::nextBool}()) {
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 3a4d495..c8353ca 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
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   () → asy::Future<core::num> f = () → asy::Future<core::num> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.expect
index 5999ef5..8c5aa92 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.expect
@@ -4,6 +4,9 @@
 import "dart:math" as math;
 import "dart:core" as core;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   dynamic f = () → asy::Future<dynamic> async {
     if(math::Random::•().nextBool()) {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.transformed.expect
index 128abb0..29946ed 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.legacy.transformed.expect
@@ -4,6 +4,9 @@
 import "dart:math" as math;
 import "dart:core" as core;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   dynamic f = () → asy::Future<dynamic> /* originally async */ {
     final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.expect
index 68329ac..a97c985 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.expect
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   () → asy::Future<core::num> f = () → asy::Future<core::num> async {
     if(math::Random::•().{math::Random::nextBool}()) {
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 85a11ea..d8b9241 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
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:async";
+import "dart:math";
+
 static method test() → dynamic {
   () → asy::Future<core::num> f = () → asy::Future<core::num> /* originally async */ {
     final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.expect
index 05fe8e3..fa2ff35 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   dynamic f = () → asy::Stream<dynamic> async* {
     yield 1;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.transformed.expect
index bb41996..7b996c1 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   dynamic f = () → asy::Stream<dynamic> /* originally async* */ {
     asy::_AsyncStarStreamController<dynamic> :controller;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.expect
index 01265c43..87f7807 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   () → asy::Stream<core::num> f = () → asy::Stream<core::num> async* {
     yield 1;
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 e1ccc6b..1d6f5b6 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   () → asy::Stream<core::num> f = () → asy::Stream<core::num> /* originally async* */ {
     asy::_AsyncStarStreamController<core::num> :controller;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect
index 664ce90..c5376ec 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //     return /*error:RETURN_OF_INVALID_TYPE*/ 1;
 //                                             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
index 373dc38..c5376ec 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//     return /*error:RETURN_OF_INVALID_TYPE*/ 1;
+//                                             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.expect
index d11fb99..ff309bc 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic async {
   dynamic f = () → asy::Future<dynamic> async {
     return null;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.transformed.expect
index 3ebd45f..a10c9be 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect
index 5918e90..04005e7 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic async {
   () → asy::Future<core::Null> f = () → asy::Future<core::Null> async {
     return null;
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 aab7652..a3f1182 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.expect
index c0fdd3c..371ba6c 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic async {
   dynamic f = () → asy::Stream<dynamic> async* {
     yield null;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.transformed.expect
index 35c6546..0930327 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect
index 99f3a43..8df15e6 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic async {
   () → asy::Stream<core::Null> f = () → asy::Stream<core::Null> async* {
     yield null;
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 bb70985..f5fafd0 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.expect
index 3f1899b..b489cb1 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method test2() → dynamic {
   core::List<core::num> o;
   dynamic y = o.map((dynamic x) → dynamic {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.transformed.expect
index 3f1899b..b489cb1 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method test2() → dynamic {
   core::List<core::num> o;
   dynamic y = o.map((dynamic x) → dynamic {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.expect
index 6c27cd0..3387e96 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method test2() → dynamic {
   core::List<core::num> o;
   core::Iterable<core::num> y = o.{core::Iterable::map}<core::num>((core::num x) → core::num {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect
index 6c27cd0..3387e96 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method test2() → dynamic {
   core::List<core::num> o;
   core::Iterable<core::num> y = o.{core::Iterable::map}<core::num>((core::num x) → core::num {
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect
index 30ce298..a4231bb 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart:35:44: Warning: Must explicitly return a value from a non-void function.
 //       /*@warning=ReturnWithoutExpression*/ return;
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart:65:44: Warning: Must explicitly return a value from a non-void function.
 //       /*@warning=ReturnWithoutExpression*/ return;
 //                                            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
index 5e2379c..a4231bb 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
@@ -1,4 +1,15 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart:35:44: Warning: Must explicitly return a value from a non-void function.
+//       /*@warning=ReturnWithoutExpression*/ return;
+//                                            ^
+//
+// pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart:65:44: Warning: Must explicitly return a value from a non-void function.
+//       /*@warning=ReturnWithoutExpression*/ return;
+//                                            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.hierarchy.expect b/pkg/front_end/testcases/inference/bug30251.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.hierarchy.expect b/pkg/front_end/testcases/inference/bug30620.dart.hierarchy.expect
new file mode 100644
index 0000000..7fb975d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.hierarchy.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.hierarchy.expect
new file mode 100644
index 0000000..7fb975d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.hierarchy.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.hierarchy.expect
new file mode 100644
index 0000000..7fb975d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.hierarchy.expect b/pkg/front_end/testcases/inference/bug30624.dart.hierarchy.expect
new file mode 100644
index 0000000..adbe429
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.hierarchy.expect
@@ -0,0 +1,43 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.barD
+    C.barE
+    C._default
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.barA
+    C.barF
+    Object._instanceOf
+    Object.noSuchMethod
+    C.barB
+    Object._identityHashCode
+    C.barC
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.hierarchy.expect b/pkg/front_end/testcases/inference/bug31132.dart.hierarchy.expect
new file mode 100644
index 0000000..de1cf73
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.z
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.hierarchy.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.hierarchy.expect
new file mode 100644
index 0000000..c0122ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.hierarchy.expect
@@ -0,0 +1,78 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    D.getB
+    Object.runtimeType
+    Object._simpleInstanceOf
+    D.fieldA
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.getA
+    Object._simpleInstanceOfFalse
+    D.fieldB
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.fieldA
+    D.fieldB
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.expect
index b088986..3c29fc6 100644
--- a/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/call_corner_cases.dart:27:69: Error: 'fieldB' isn't a function or method and can't be invoked.
 //   var /*@type=dynamic*/ callFieldB = new D(). /*@target=D::fieldB*/ fieldB();
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/inference/call_corner_cases.dart:28:65: Error: 'getB' isn't a function or method and can't be invoked.
 //   var /*@type=dynamic*/ callGetB = new D(). /*@target=D::getB*/ getB();
 //                                                                 ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect
index 3bcb5f4..3c29fc6 100644
--- a/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect
@@ -1,4 +1,15 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/call_corner_cases.dart:27:69: Error: 'fieldB' isn't a function or method and can't be invoked.
+//   var /*@type=dynamic*/ callFieldB = new D(). /*@target=D::fieldB*/ fieldB();
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/call_corner_cases.dart:28:65: Error: 'getB' isn't a function or method and can't be invoked.
+//   var /*@type=dynamic*/ callGetB = new D(). /*@target=D::getB*/ getB();
+//                                                                 ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.hierarchy.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.hierarchy.expect
new file mode 100644
index 0000000..3b58d02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.hierarchy.expect
@@ -0,0 +1,72 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ActionDispatcher:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    ActionDispatcher.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+FooActions:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    FooActions.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.hierarchy.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..8d43f04
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.expect
index 658bd51..f6fc387 100644
--- a/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
-// abstract class A extends B {
-//                ^
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
-// abstract class B extends A {
-//                ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
-// abstract class A extends B {
-//                ^
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
-// abstract class B extends A {
-//                ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
+// abstract class A extends B {
+//                ^
+//
+// pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
+// abstract class B extends A {
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.transformed.expect
index fa9873c..f6fc387 100644
--- a/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
 // abstract class A extends B {
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
 // abstract class B extends A {
 //                ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.outline.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.outline.expect
index bd72e73..10e9611 100644
--- a/pkg/front_end/testcases/inference/circular_method_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
 // abstract class A extends B {
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
 // abstract class B extends A {
 //                ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.expect
index 658bd51..f6fc387 100644
--- a/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
-// abstract class A extends B {
-//                ^
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
-// abstract class B extends A {
-//                ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
-// abstract class A extends B {
-//                ^
-//
-// pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
-// abstract class B extends A {
-//                ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
+// abstract class A extends B {
+//                ^
+//
+// pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
+// abstract class B extends A {
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect
index fa9873c..f6fc387 100644
--- a/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself.
 // abstract class A extends B {
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself.
 // abstract class B extends A {
 //                ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
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 a71159f..5b3b71c 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
 import self as self;
 
 static field dynamic x = () → dynamic => self::y;
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 adfe785..5b3b71c 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/circular_reference_via_closures.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 // var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
 //                                                                   ^
-
-library test;
+//
 import self as self;
 
 static field dynamic x = () → dynamic => self::y;
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 3bf5411..a4e4a26 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
 import self as self;
 
 static field dynamic x = () → dynamic => self::y;
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 6ac80a6..a4e4a26 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 // var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
 //                                                                   ^
-
-library test;
+//
 import self as self;
 
 static field dynamic x = () → dynamic => self::y;
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.hierarchy.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.hierarchy.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.hierarchy.expect
new file mode 100644
index 0000000..652977b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.hierarchy.expect
@@ -0,0 +1,158 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    I1.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I1.x
+
+I2:
+  superclasses:
+    Object
+      -> I1
+  interfaces:
+  classMembers:
+    I2.y
+    Object.toString
+    I1.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I2.y
+    I1.x
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces: A, B
+  classMembers:
+    C1.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    C1.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C2:
+  superclasses:
+    Object
+  interfaces: B, A
+  classMembers:
+    C2.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    C2.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
index 94fb0d1..1812788 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.strong.expect
@@ -1,88 +1,53 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
-// Specify the type explicitly.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
-// Specify the type explicitly.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
-//   final I1 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
-//   final I2 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
-//   final I2 a = null;
-//            ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
-//   final I1 a = null;
-//            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
-// Specify the type explicitly.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
-// Specify the type explicitly.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I2'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
-// Change to a subtype of 'I1'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
+// Specify the type explicitly.
+//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
+//                                                                                                                                                                   ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
+// Specify the type explicitly.
+//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
+//                                                                                                                                                                   ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
+//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
+// Change to a subtype of 'I1'.
+//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
+//   final I1 a = null;
+//            ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:25:163: Error: The return type of the method 'C1.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
+//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
+// Change to a subtype of 'I2'.
+//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
+//   final I2 a = null;
+//            ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
+//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
+// Change to a subtype of 'I2'.
+//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:21:12: Context: This is the overridden method ('a').
+//   final I2 a = null;
+//            ^
+//
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:31:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
+//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen.dart'.
+// Change to a subtype of 'I1'.
+//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/conflicts_can_happen.dart:17:12: Context: This is the overridden method ('a').
+//   final I1 a = null;
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.hierarchy.expect
new file mode 100644
index 0000000..bee47d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.hierarchy.expect
@@ -0,0 +1,192 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    I1.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I1.x
+
+I2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I2.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I2.y
+
+I3:
+  superclasses:
+    Object
+  interfaces: I1, I2
+  classMembers:
+    I3.y
+    Object.toString
+    I3.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I3.y
+    I3.x
+  interfaceMembers:
+    I3.y
+    Object.toString
+    I3.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    I3.y
+    I3.x
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces: A, B
+  classMembers:
+    C1.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    C1.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C2:
+  superclasses:
+    Object
+  interfaces: A, B
+  classMembers:
+    C2.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    C2.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
index 1231802..9b5a480 100644
--- a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
 // Specify the type explicitly.
@@ -22,27 +24,7 @@
 // pkg/front_end/testcases/inference/conflicts_can_happen2.dart:26:12: Context: This is the overridden method ('a').
 //   final I2 a = null;
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:163: Error: Can't infer the type of 'a': overridden members must all have the same type.
-// Specify the type explicitly.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I1'.
-//  - 'I1' is from 'pkg/front_end/testcases/inference/conflicts_can_happen2.dart'.
-// Change to a subtype of 'I1'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/conflicts_can_happen2.dart:34:163: Error: The return type of the method 'C2.a' is 'dynamic', which does not match the return type of the overridden method, 'I2'.
-//  - 'I2' is from 'pkg/front_end/testcases/inference/conflicts_can_happen2.dart'.
-// Change to a subtype of 'I2'.
-//   get /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ a =>
-//                                                                                                                                                                   ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.hierarchy.expect
new file mode 100644
index 0000000..92187bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.hierarchy.expect
new file mode 100644
index 0000000..dc723b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
index 511aafd..eff3c30 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
 //                                                        ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
index 67464db..daed8df 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+//                                                        ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.hierarchy.expect
new file mode 100644
index 0000000..2b00288
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+NotA:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.strong.expect
index be82a2e..d1fa08b 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.strong.expect
@@ -1,42 +1,27 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:22:56: Error: Inferred type argument 'NotA' doesn't conform to the bound 'A' of the type variable 'T' on 'C'.
-//  - 'NotA' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//       new /*error:COULD_NOT_INFER*/ /*@typeArgs=NotA*/ C(myF);
-//                                                        ^
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:12:9: Context: This is the type variable whose bound isn't conformed to.
-// class C<T extends A> {
-//         ^
-//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:21:25: Error: Inferred type argument 'NotA' doesn't conform to the bound 'A' of the type variable 'T' on 'C'.
-//  - 'NotA' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   var /*@type=C<NotA>*/ x =
-//                         ^
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:12:9: Context: This is the type variable whose bound isn't conformed to.
-// class C<T extends A> {
-//         ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:22:56: Error: Inferred type argument 'NotA' doesn't conform to the bound 'A' of the type variable 'T' on 'C'.
-//  - 'NotA' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//       new /*error:COULD_NOT_INFER*/ /*@typeArgs=NotA*/ C(myF);
-//                                                        ^
-//
-// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:21:25: Error: Inferred type argument 'NotA' doesn't conform to the bound 'A' of the type variable 'T' on 'C'.
-//  - 'NotA' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   var /*@type=C<NotA>*/ x =
-//                         ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:22:56: Error: Inferred type argument 'NotA' doesn't conform to the bound 'A' of the type variable 'T' on 'C'.
+//  - 'NotA' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//       new /*error:COULD_NOT_INFER*/ /*@typeArgs=NotA*/ C(myF);
+//                                                        ^
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:12:9: Context: This is the type variable whose bound isn't conformed to.
+// class C<T extends A> {
+//         ^
+//
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:21:25: Error: Inferred type argument 'NotA' doesn't conform to the bound 'A' of the type variable 'T' on 'C'.
+//  - 'NotA' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   var /*@type=C<NotA>*/ x =
+//                         ^
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart:12:9: Context: This is the type variable whose bound isn't conformed to.
+// class C<T extends A> {
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.hierarchy.expect
new file mode 100644
index 0000000..3c1d5a8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..a9ee54f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.hierarchy.expect
new file mode 100644
index 0000000..dc723b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
index db3029e..0593a65 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
 //                                                        ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
index 203627e..0593a65 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+//                                                        ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..897d3ef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.f
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.hierarchy.expect
new file mode 100644
index 0000000..dc723b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.hierarchy.expect
new file mode 100644
index 0000000..dc723b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.hierarchy.expect
new file mode 100644
index 0000000..dc723b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.hierarchy.expect
new file mode 100644
index 0000000..0590bd0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.hierarchy.expect
@@ -0,0 +1,73 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
+    C._redirecting#
+
+CImpl:
+  superclasses:
+    Object
+  interfaces: C<T>
+  classMembers:
+    CImpl.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    CImpl.t
+  interfaceMembers:
+    CImpl.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    CImpl.t
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.hierarchy.expect
new file mode 100644
index 0000000..0590bd0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.hierarchy.expect
@@ -0,0 +1,73 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
+    C._redirecting#
+
+CImpl:
+  superclasses:
+    Object
+  interfaces: C<T>
+  classMembers:
+    CImpl.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    CImpl.t
+  interfaceMembers:
+    CImpl.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    CImpl.t
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.hierarchy.expect
new file mode 100644
index 0000000..60cd348
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Clonable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Pair:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Pair.t
+    Object.toString
+    Pair.reversed
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Pair.u
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Pair.t
+    Pair.u
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
index ae1f9cc..fa12dec 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Inferred type argument 'Clonable<dynamic>' doesn't conform to the bound 'Clonable<T>' of the type variable 'T' on 'Pair'.
 //  - 'Clonable' is from 'pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart'.
@@ -17,22 +19,7 @@
 // pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:10:35: Context: This is the type variable whose bound isn't conformed to.
 // class Pair<T extends Clonable<T>, U extends Clonable<U>> {
 //                                   ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Inferred type argument 'Clonable<dynamic>' doesn't conform to the bound 'Clonable<T>' of the type variable 'T' on 'Pair'.
-//  - 'Clonable' is from 'pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//       new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
-//                                                                                                              ^
-//
-// pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Inferred type argument 'Clonable<dynamic>' doesn't conform to the bound 'Clonable<U>' of the type variable 'U' on 'Pair'.
-//  - 'Clonable' is from 'pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//       new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
-//                                                                                                              ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
index b56a3a6..fa12dec 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
@@ -1,18 +1,25 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Inferred type argument 'Clonable<dynamic>' doesn't conform to the bound 'Clonable<T>' of the type variable 'T' on 'Pair'.
 //  - 'Clonable' is from 'pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //       new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
 //                                                                                                              ^
+// pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:10:12: Context: This is the type variable whose bound isn't conformed to.
+// class Pair<T extends Clonable<T>, U extends Clonable<U>> {
+//            ^
 //
 // pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Inferred type argument 'Clonable<dynamic>' doesn't conform to the bound 'Clonable<U>' of the type variable 'U' on 'Pair'.
 //  - 'Clonable' is from 'pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //       new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
 //                                                                                                              ^
-
-library test;
+// pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:10:35: Context: This is the type variable whose bound isn't conformed to.
+// class Pair<T extends Clonable<T>, U extends Clonable<U>> {
+//                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.hierarchy.expect
new file mode 100644
index 0000000..9a06944
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.hierarchy.expect
@@ -0,0 +1,41 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Pair:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Pair.t
+    Object.toString
+    Pair.reversed
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Pair.u
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Pair.t
+    Pair.u
diff --git a/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.hierarchy.expect b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_too_many_positional_arguments.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.hierarchy.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.hierarchy.expect
new file mode 100644
index 0000000..50432e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.strong.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.strong.expect
index 50b1b8c..a20bdce 100644
--- a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart:13:49: Error: The return type of the method 'B.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
 // Change to a subtype of 'int'.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart:9:13: Context: This is the overridden method ('x').
 //   final int x = 2;
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart:13:49: Error: The return type of the method 'B.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
-// Change to a subtype of 'int'.
-//   /*error:INVALID_METHOD_OVERRIDE*/ dynamic get x => 3;
-//                                                 ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.hierarchy.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.hierarchy.expect
new file mode 100644
index 0000000..57a735c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.hierarchy.expect
@@ -0,0 +1,44 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    A.x2
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.y2
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+    A.x2
+    A.y2
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.expect
index c510acf..52cb80e 100644
--- a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method f() → dynamic {
   core::num x;
   dynamic y;
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.transformed.expect
index c510acf..52cb80e 100644
--- a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method f() → dynamic {
   core::num x;
   dynamic y;
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.outline.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.outline.expect
index b08cbd0..4cd4875 100644
--- a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.outline.expect
@@ -1,6 +1,8 @@
 library test;
 import self as self;
 
+import "dart:math";
+
 static method f() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.expect
index 1a9cd62..ff6c037 100644
--- a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.expect
@@ -1,32 +1,23 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:21:63: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   dynamic c = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(x, y);
-//                                                               ^
-//
-// pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:22:77: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   var /*@type=dynamic*/ d = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(
-//                                                                             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:21:63: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   dynamic c = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(x, y);
-//                                                               ^
-//
-// pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:22:77: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//   var /*@type=dynamic*/ d = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(
-//                                                                             ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:21:63: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   dynamic c = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(x, y);
+//                                                               ^
+//
+// pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:22:77: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//   var /*@type=dynamic*/ d = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(
+//                                                                             ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method f() → dynamic {
   core::num x;
   dynamic y;
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect
index 77c4e5f..ff6c037 100644
--- a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart:21:63: Error: Inferred type argument 'dynamic' doesn't conform to the bound 'num' of the type variable 'T' on 'max'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
@@ -9,12 +11,13 @@
 // Try specifying type arguments explicitly so that they conform to the bounds.
 //   var /*@type=dynamic*/ d = /*error:COULD_NOT_INFER*/ /*@typeArgs=dynamic*/ max(
 //                                                                             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method f() → dynamic {
   core::num x;
   dynamic y;
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.hierarchy.expect
new file mode 100644
index 0000000..804e9c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.hierarchy.expect
new file mode 100644
index 0000000..824f22f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.hierarchy.expect
new file mode 100644
index 0000000..d4e27f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Baz:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.hierarchy.expect
new file mode 100644
index 0000000..2e442e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Bar.f
+    Object.toString
+    Bar.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Bar.x
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.hierarchy.expect
new file mode 100644
index 0000000..fe2bd42
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.hierarchy.expect
new file mode 100644
index 0000000..4a798de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect
index 32b1bb8..c65e4ae 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   l = /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"];
 //                                                                     ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
index 4acd615..c65e4ae 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   l = /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"];
+//                                                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.expect
index db7cc1a..62b013b 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → asy::Future<dynamic> async {
   dynamic d;
   core::List<core::int> l0 = await<dynamic>[d];
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.transformed.expect
index b10f37a..313a2ae 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → asy::Future<dynamic> /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.expect
index cbb6f9f..63f6749 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → asy::Future<dynamic> async {
   dynamic d;
   core::List<core::int> l0 = await<core::int>[d as{TypeError} core::int];
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 64565b5..4a8a371 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → asy::Future<dynamic> /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.hierarchy.expect
new file mode 100644
index 0000000..6392bea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.hierarchy.expect
@@ -0,0 +1,129 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Stream:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Stream.asyncExpand
+    Stream.listen
+    Stream.map
+    Stream.pipe
+    Stream.cast
+    Stream.skip
+    Stream.join
+    Stream.asyncMap
+    Stream.toSet
+    Stream.asBroadcastStream
+    Object.toString
+    Stream.handleError
+    Stream.forEach
+    Stream.length
+    Stream.firstWhere
+    Object.runtimeType
+    Stream.isBroadcast
+    Stream.timeout
+    Object._simpleInstanceOf
+    Stream.isEmpty
+    Stream.take
+    Stream.any
+    Stream.transform
+    Stream.where
+    Object._instanceOf
+    Stream.skipWhile
+    Stream.castFrom
+    Stream.toList
+    Object.noSuchMethod
+    Stream.fold
+    Stream.drain
+    Stream.elementAt
+    Stream.distinct
+    Stream.expand
+    Stream.takeWhile
+    Stream.first
+    Object._identityHashCode
+    Object.hashCode
+    Stream.reduce
+    Stream.lastWhere
+    Stream.last
+    Object._simpleInstanceOfFalse
+    Stream.single
+    Stream.every
+    Stream.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Stream.singleWhere
+  classSetters:
+
+MyStream:
+  superclasses:
+    Object
+      -> Stream<T>
+  interfaces:
+  classMembers:
+    Stream.asyncExpand
+    Stream.listen
+    Stream.map
+    Stream.pipe
+    Stream.cast
+    Stream.skip
+    Stream.join
+    Stream.asyncMap
+    Stream.toSet
+    Stream.asBroadcastStream
+    Object.toString
+    Stream.handleError
+    Stream.forEach
+    Stream.length
+    Stream.firstWhere
+    Object.runtimeType
+    Stream.isBroadcast
+    Stream.timeout
+    Object._simpleInstanceOf
+    Stream.isEmpty
+    Stream.take
+    Stream.any
+    Stream.transform
+    Stream.where
+    Object._instanceOf
+    Stream.skipWhile
+    Stream.toList
+    Object.noSuchMethod
+    Stream.fold
+    Stream.drain
+    Stream.elementAt
+    Stream.distinct
+    Stream.expand
+    Stream.takeWhile
+    Stream.first
+    Object._identityHashCode
+    Object.hashCode
+    Stream.reduce
+    Stream.lastWhere
+    Stream.last
+    Object._simpleInstanceOfFalse
+    Stream.single
+    Stream.every
+    Stream.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Stream.singleWhere
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.expect
index 7a1ba88..9fb31e6 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.transformed.expect
index 4c365f3..ac63b98 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.expect
index ad5f6d8..1c565f6 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
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 852887c..498f778 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.hierarchy.expect
new file mode 100644
index 0000000..3de5ead
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Foo.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.x
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.hierarchy.expect
new file mode 100644
index 0000000..69ec6ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.b
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.hierarchy.expect
new file mode 100644
index 0000000..30533d0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F0:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect
index 2e45dc8..9eda7db 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -49,8 +51,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
index 7a852a4..9eda7db 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
@@ -1,4 +1,57 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:51:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:62:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:65:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:74:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:77:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect
index c4111f5..00e805a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:68: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -49,8 +51,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
index fbf4cc4..00e805a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
@@ -1,4 +1,57 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:68: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   f0(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:17:68: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   f0(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello", 3]);
+//                                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:21:71: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   f1(a: /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                       ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:23:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:29:68: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   f2(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:30:68: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   f2(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello", 3]);
+//                                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:37:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:40:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:49:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:52:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
index 979504b..1788de2 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:66: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
@@ -55,8 +57,7 @@
 // Try correcting the name to the name of an existing method, or defining a method named 'substring'.
 //             .substring(3);
 //              ^^^^^^^^^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -126,10 +127,10 @@
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
             x;
             ^" in x as{TypeError} core::String;
-    (core::int) → core::String l3 = (core::int x) → core::String => (let final dynamic #t11 = x in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
+    (core::int) → core::String l3 = (core::int x) → core::String => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'substring'.
             .substring(3);
-             ^^^^^^^^^") as{TypeError} core::String;
+             ^^^^^^^^^" as{TypeError} core::String;
     (core::String) → core::String l4 = (core::String x) → core::String => x.{core::String::substring}(3);
   }
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
index 3d5f44a..1788de2 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
@@ -1,4 +1,63 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:66: Error: A value of type 'String Function(String)' can't be assigned to a variable of type 'String Function(int)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String Function(int)'.
+//         l2 = /*error:INVALID_ASSIGNMENT*/ /*@returnType=String*/ (String x) =>
+//                                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:18:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//         l3 = /*error:INVALID_ASSIGNMENT*/ /*@returnType=String*/ (int x) => 3;
+//                                                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:20:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//             3;
+//             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:31:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:34:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       return /*error:RETURN_OF_INVALID_TYPE*/ x;
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:72: Error: A value of type 'List<String> Function(String)' can't be assigned to a variable of type 'List<String> Function(int)'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function(int)'.
+//         l2 = /*error:INVALID_ASSIGNMENT*/ /*@returnType=List<String>*/ (String
+//                                                                        ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:46:58: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//               /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                          ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:60:13: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//             x;
+//             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'substring'.
+//             .substring(3);
+//              ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -68,10 +127,10 @@
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
             x;
             ^" in x as{TypeError} core::String;
-    (core::int) → core::String l3 = (core::int x) → core::String => (let final core::int #t11 = x in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
+    (core::int) → core::String l3 = (core::int x) → core::String => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'substring'.
             .substring(3);
-             ^^^^^^^^^") as{TypeError} core::String;
+             ^^^^^^^^^" as{TypeError} core::String;
     (core::String) → core::String l4 = (core::String x) → core::String => x.{core::String::substring}(3);
   }
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.hierarchy.expect
new file mode 100644
index 0000000..52c072a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.hierarchy.expect
new file mode 100644
index 0000000..30533d0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F0:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect
index 1098360..7a7d29f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -49,8 +51,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
index 6578cb4..7a7d29f 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
@@ -1,4 +1,57 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:51:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]);
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:62:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:65:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:74:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"]
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:77:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"],
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
index 734c5ca..c0a2ae8 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:65: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
@@ -55,8 +57,7 @@
 // Try correcting the name to the name of an existing method, or defining a method named 'substring'.
 //         .substring(3);
 //          ^^^^^^^^^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -142,10 +143,10 @@
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
         x;
         ^" in x as{TypeError} core::String;
-    y = <T extends core::Object = dynamic>(core::int x) → core::String => (let final dynamic #t11 = x in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
+    y = <T extends core::Object = dynamic>(core::int x) → core::String => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'substring'.
         .substring(3);
-         ^^^^^^^^^") as{TypeError} core::String;
+         ^^^^^^^^^" as{TypeError} core::String;
     <T extends core::Object = dynamic>(core::String) → core::String z = string2String;
     z = <T extends core::Object = dynamic>(core::String x) → core::String => x.{core::String::substring}(3);
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
index 0df8be8..c0a2ae8 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
@@ -1,4 +1,63 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:65: Error: A value of type 'String Function<T>(String)' can't be assigned to a variable of type 'String Function<S>(int)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String Function<S>(int)'.
+//     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@returnType=String*/ (String x) =>
+//                                                                 ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:16:76: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@returnType=String*/ (int x) => 3;
+//                                                                            ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:18:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//         3;
+//         ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:30:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:33:47: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       return /*error:RETURN_OF_INVALID_TYPE*/ x;
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:71: Error: A value of type 'List<String> Function<T>(String)' can't be assigned to a variable of type 'List<String> Function<S>(int)'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'List<String> Function<S>(int)'.
+//     v = /*error:INVALID_ASSIGNMENT*/ <T> /*@returnType=List<String>*/ (String
+//                                                                       ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:46:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                      ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:50:52: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//         /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:64:9: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//         x;
+//         ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'substring'.
+//         .substring(3);
+//          ^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -84,10 +143,10 @@
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
         x;
         ^" in x as{TypeError} core::String;
-    y = <T extends core::Object = dynamic>(core::int x) → core::String => (let final core::int #t11 = x in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
+    y = <T extends core::Object = dynamic>(core::int x) → core::String => invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'substring'.
         .substring(3);
-         ^^^^^^^^^") as{TypeError} core::String;
+         ^^^^^^^^^" as{TypeError} core::String;
     <T extends core::Object = dynamic>(core::String) → core::String z = string2String;
     z = <T extends core::Object = dynamic>(core::String x) → core::String => x.{core::String::substring}(3);
   }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.hierarchy.expect
new file mode 100644
index 0000000..bb9d22e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.hierarchy.expect
@@ -0,0 +1,152 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A<T, S>
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+C:
+  superclasses:
+    Object
+      -> A<T, S>
+        -> B<S, S>
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+D:
+  superclasses:
+    Object
+      -> A<T, S>
+        -> B<T, int>
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+E:
+  superclasses:
+    Object
+      -> A<C<S>, T>
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+F:
+  superclasses:
+    Object
+      -> A<S, T>
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
index 722f65a..8ca9a95 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:46:50: Error: The constructor returns type 'A<int, dynamic>' that isn't of expected type 'A<int, String>'.
 //  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
@@ -138,8 +140,7 @@
 // Try changing the type of the parameter, or casting the argument to 'int'.
 //         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
 //                                                ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
index 39595b3..8ca9a95 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
@@ -1,4 +1,146 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:46:50: Error: The constructor returns type 'A<int, dynamic>' that isn't of expected type 'A<int, String>'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Change the type of the object being constructed or the context in which it is used.
+//         a4 = /*error:INVALID_CAST_NEW_EXPR*/ new A<int, dynamic>(3, "hello");
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:48:50: Error: The constructor returns type 'A<dynamic, dynamic>' that isn't of expected type 'A<int, String>'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Change the type of the object being constructed or the context in which it is used.
+//         a5 = /*error:INVALID_CAST_NEW_EXPR*/ new A<dynamic, dynamic>.named(
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:53:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:54:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:56:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:57:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:65:47: Error: A value of type 'B<String, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
+//  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
+//         a4 = /*error:INVALID_ASSIGNMENT*/ new B<String, dynamic>("hello", 3);
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:67:47: Error: A value of type 'B<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
+//  - 'B' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
+//         a5 = /*error:INVALID_ASSIGNMENT*/ new B<dynamic, dynamic>.named(
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:72:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:73:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:75:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:76:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:83:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
+//  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
+//     A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>(3);
+//                                                       ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:84:55: Error: A value of type 'C<dynamic>' can't be assigned to a variable of type 'A<int, int>'.
+//  - 'C' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A<int, int>'.
+//     A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>.named(3);
+//                                                       ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:88:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:90:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:98:47: Error: A value of type 'D<num, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
+//  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
+//         a4 = /*error:INVALID_ASSIGNMENT*/ new D<num, dynamic>("hello");
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:100:47: Error: A value of type 'D<dynamic, dynamic>' can't be assigned to a variable of type 'A<int, String>'.
+//  - 'D' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+//  - 'A' is from 'pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A<int, String>'.
+//         a5 = /*error:INVALID_ASSIGNMENT*/ new D<dynamic, dynamic>.named(
+//                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:105:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:107:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:118:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                      ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:121:54: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//           /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                      ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:129:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:130:48: Error: The argument type 'int' can't be assigned to the parameter type 'String'.
+// Try changing the type of the parameter, or casting the argument to 'String'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+//                                                ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:134:48: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//         /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ "hello");
+//                                                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect
index 16af88a..c7a14c1 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -68,8 +70,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
 //                                                                                         ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
index 99954ce..c7a14c1 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
@@ -1,4 +1,76 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42
+//                                                                                         ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:19:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:22:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:33:61: Error: The list literal type 'List<num>' isn't of expected type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+// Change the type of the list literal or the context in which it is used.
+//     List<int> l0 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[];
+//                                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:34:61: Error: The list literal type 'List<num>' isn't of expected type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+// Change the type of the list literal or the context in which it is used.
+//     List<int> l1 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[3];
+//                                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:36:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:35:61: Error: The list literal type 'List<num>' isn't of expected type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+// Change the type of the list literal or the context in which it is used.
+//     List<int> l2 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
+//                                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:39:50: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:38:61: Error: The list literal type 'List<num>' isn't of expected type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+// Change the type of the list literal or the context in which it is used.
+//     List<int> l3 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
+//                                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:47:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:50:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:58:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello"
+//                                                                                         ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:61:89: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ "hello",
+//                                                                                         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.hierarchy.expect
new file mode 100644
index 0000000..7daea18
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.hierarchy.expect
@@ -0,0 +1,81 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+DartType:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.method
+    C.assertDOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.assertBOf
+    Object._identityHashCode
+    C.assertCOf
+    C.assertAOf
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.assertBOf
+    C.assertAOf
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    G.method
+    G.assertDOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    G.assertAOf
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    G.assertAOf
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect
index 6a9da87..de242ae 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -82,8 +84,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
 //                                                                                       ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
index 08e5b5e..de242ae 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
@@ -1,4 +1,90 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
+//                                                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:20:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": "hello"
+//                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:23:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:27:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
+//                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:28:51: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:48:50: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                  ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:52:56: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       "hello": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                        ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:59:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": "hello"
+//                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:64:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello": 3
+//                                             ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:68:76: Error: The map literal type 'Map<num, dynamic>' isn't of expected type 'Map<int, String>'.
+//  - 'Map' is from 'dart:core'.
+// Change the type of the map literal or the context in which it is used.
+//     Map<int, String> l0 = /*error:INVALID_CAST_LITERAL_MAP*/ <num, dynamic>{};
+//                                                                            ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:69:76: Error: The map literal type 'Map<num, dynamic>' isn't of expected type 'Map<int, String>'.
+//  - 'Map' is from 'dart:core'.
+// Change the type of the map literal or the context in which it is used.
+//     Map<int, String> l1 = /*error:INVALID_CAST_LITERAL_MAP*/ <num, dynamic>{
+//                                                                            ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:72:76: Error: The map literal type 'Map<num, dynamic>' isn't of expected type 'Map<int, String>'.
+//  - 'Map' is from 'dart:core'.
+// Change the type of the map literal or the context in which it is used.
+//     Map<int, String> l3 = /*error:INVALID_CAST_LITERAL_MAP*/ <num, dynamic>{
+//                                                                            ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:80:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
+//                                                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:84:86: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//       3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                                                      ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:88:79: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
+//                                                                               ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:89:87: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//           /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+//                                                                                       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.hierarchy.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.hierarchy.expect
new file mode 100644
index 0000000..6392bea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.hierarchy.expect
@@ -0,0 +1,129 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Stream:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Stream.asyncExpand
+    Stream.listen
+    Stream.map
+    Stream.pipe
+    Stream.cast
+    Stream.skip
+    Stream.join
+    Stream.asyncMap
+    Stream.toSet
+    Stream.asBroadcastStream
+    Object.toString
+    Stream.handleError
+    Stream.forEach
+    Stream.length
+    Stream.firstWhere
+    Object.runtimeType
+    Stream.isBroadcast
+    Stream.timeout
+    Object._simpleInstanceOf
+    Stream.isEmpty
+    Stream.take
+    Stream.any
+    Stream.transform
+    Stream.where
+    Object._instanceOf
+    Stream.skipWhile
+    Stream.castFrom
+    Stream.toList
+    Object.noSuchMethod
+    Stream.fold
+    Stream.drain
+    Stream.elementAt
+    Stream.distinct
+    Stream.expand
+    Stream.takeWhile
+    Stream.first
+    Object._identityHashCode
+    Object.hashCode
+    Stream.reduce
+    Stream.lastWhere
+    Stream.last
+    Object._simpleInstanceOfFalse
+    Stream.single
+    Stream.every
+    Stream.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Stream.singleWhere
+  classSetters:
+
+MyStream:
+  superclasses:
+    Object
+      -> Stream<T>
+  interfaces:
+  classMembers:
+    Stream.asyncExpand
+    Stream.listen
+    Stream.map
+    Stream.pipe
+    Stream.cast
+    Stream.skip
+    Stream.join
+    Stream.asyncMap
+    Stream.toSet
+    Stream.asBroadcastStream
+    Object.toString
+    Stream.handleError
+    Stream.forEach
+    Stream.length
+    Stream.firstWhere
+    Object.runtimeType
+    Stream.isBroadcast
+    Stream.timeout
+    Object._simpleInstanceOf
+    Stream.isEmpty
+    Stream.take
+    Stream.any
+    Stream.transform
+    Stream.where
+    Object._instanceOf
+    Stream.skipWhile
+    Stream.toList
+    Object.noSuchMethod
+    Stream.fold
+    Stream.drain
+    Stream.elementAt
+    Stream.distinct
+    Stream.expand
+    Stream.takeWhile
+    Stream.first
+    Object._identityHashCode
+    Object.hashCode
+    Stream.reduce
+    Stream.lastWhere
+    Stream.last
+    Object._simpleInstanceOfFalse
+    Stream.single
+    Stream.every
+    Stream.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Stream.singleWhere
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.expect
index 4a22da5..af2285b 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.transformed.expect
index 4d12a56..25939a6 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
index 5504acd..001564a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:67: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
 //  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
@@ -27,12 +29,13 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'Iterable<Map<int, int>>'.
 //   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@typeArgs=dynamic, dynamic*/ Map();
 //                                                                             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
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 4ff259f..c318392 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
@@ -1,8 +1,41 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:16:67: Error: A value of type 'MyStream<dynamic>' can't be assigned to a variable of type 'List<int>'.
+//  - 'MyStream' is from 'pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'List<int>'.
+//   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@typeArgs=dynamic*/ MyStream();
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:17:68: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Stream<List<int>>'.
+//  - 'List' is from 'dart:core'.
+//  - 'Stream' is from 'dart:async'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Stream<List<int>>'.
+//   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@typeArgs=dynamic*/ List();
+//                                                                    ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:23:67: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'Map<int, int>'.
+//  - 'List' is from 'dart:core'.
+//  - 'Map' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Map<int, int>'.
+//   yield /*error:YIELD_OF_INVALID_TYPE*/ new /*@typeArgs=dynamic*/ List();
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart:24:77: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'Iterable<Map<int, int>>'.
+//  - 'Map' is from 'dart:core'.
+//  - 'Iterable' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Iterable<Map<int, int>>'.
+//   yield* /*error:YIELD_OF_INVALID_TYPE*/ new /*@typeArgs=dynamic, dynamic*/ Map();
+//                                                                             ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class MyStream<T extends core::Object = dynamic> extends asy::Stream<self::MyStream::T> {
   static factory •<T extends core::Object = dynamic>() → self::MyStream<self::MyStream::•::T>
     return null;
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.hierarchy.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.hierarchy.expect
new file mode 100644
index 0000000..35e1300
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
index b709a6f..3b2679a 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/dynamic_methods.dart:16:39: Error: 'hashCode' isn't a function or method and can't be invoked.
 //       d. /*@target=Object::hashCode*/ hashCode();
 //                                       ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
index 49e07c8..3b2679a 100644
--- a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/dynamic_methods.dart:16:39: Error: 'hashCode' isn't a function or method and can't be invoked.
+//       d. /*@target=Object::hashCode*/ hashCode();
+//                                       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.hierarchy.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.hierarchy.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.hierarchy.expect
new file mode 100644
index 0000000..00b2c95
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.hierarchy.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..f750a07
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C._x
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.expect
index 2654b7e..6af7018 100644
--- a/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method add(core::int x) → void {}
 static method add2(core::int y) → dynamic {}
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.transformed.expect
index 2654b7e..6af7018 100644
--- a/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method add(core::int x) → void {}
 static method add2(core::int y) → dynamic {}
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.expect
index 4f6fa47..0f5a59a 100644
--- a/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method add(core::int x) → void {}
 static method add2(core::int y) → dynamic {}
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect
index 4f6fa47..0f5a59a 100644
--- a/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method add(core::int x) → void {}
 static method add2(core::int y) → dynamic {}
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/future_then.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
index 42e0878..1d88ee8 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
index 2523367..4f27ec5 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.outline.expect b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
index 267d4ac..96beacd 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 cfca0bf..3fb8754 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_2.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
index ca0ee79..67aa4fb 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
index 5305928..a9f33b6 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
index 119e050..15aa74b 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 16a1cda..091e194 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_3.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
index d621b5a..0f44112 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
index a8a5bcf..8bca318 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
index feb8958..5895ddd 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 ebec13e..5fcbec7 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_4.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
index 8d980f1..f659f1f 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
index ec60686..56334ca 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
index c46d088..0f07ba1 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 b9f26c5..caa8542 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_5.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
index f3a0609..e9987cb 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
index 3652669..25dacbf 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
index df5f492..a09ade0 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 aa2b0b1..5c16f21 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_6.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
index 0b55043..44e0272 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
index df4e351..bde8fe5 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
index d1adeb0..fc6869c 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 3895fa1..5025976 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
index d6c5b10..4ddf6a7 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
index d665857..0fc63fc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
index 56e16e5..149f271 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 acbce4c..aafd0f203 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
index 6e9bb31..df550a5 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
index cae1f2d..6885ac4 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
index a058e1d..7c89757 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 3f3e26c..fb7974e 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
index 8d97d69..9932aa3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
index 2288861..c7618fd 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
index 0b6b963..fd97d69 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 6e76891..3a4604a 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
index 492312e..7658f20 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
index 97a50ab..9abcfd0 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
index 6dc7c84..3d33f4a 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 c07cdcb..ed935aa 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
index 2ae1c89..09a4b7b 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
index c58e4b1..2f416f7 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
index 177f02c..b29bf54 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 a74751a..396dabd 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
index d91dff0..24ff832 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
index 69471c1..65684a7 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
index d9b1879..2a444d6 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 16db4a6..cf2964e 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.expect
index 5c1094c..fa81e87 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> f;
   asy::Future<core::List<core::int>> b = f.then((dynamic x) → dynamic => <dynamic>[]).whenComplete(() → dynamic {});
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.transformed.expect
index 5c1094c..fa81e87 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> f;
   asy::Future<core::List<core::int>> b = f.then((dynamic x) → dynamic => <dynamic>[]).whenComplete(() → dynamic {});
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect
index 8e85697..666bc54 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect
@@ -1,6 +1,8 @@
 library test;
 import self as self;
 
+import "dart:async";
+
 static method test() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect
index ce86786..7a94f25 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> f;
   asy::Future<core::List<core::int>> b = f.{asy::Future::then}<core::List<dynamic>>((core::int x) → core::List<dynamic> => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null {}) as{TypeError} asy::Future<core::List<core::int>>;
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
index ce86786..7a94f25 100644
--- a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> f;
   asy::Future<core::List<core::int>> b = f.{asy::Future::then}<core::List<dynamic>>((core::int x) → core::List<dynamic> => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null {}) as{TypeError} asy::Future<core::List<core::int>>;
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.expect
index 3b31e56..70f2705 100644
--- a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method m1() → dynamic {
   asy::Future<core::int> f;
   dynamic x = f.then<asy::Future<core::List<core::int>>>((dynamic x) → dynamic => <dynamic>[]);
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.transformed.expect
new file mode 100644
index 0000000..70f2705
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+import "dart:async";
+
+static method m1() → dynamic {
+  asy::Future<core::int> f;
+  dynamic x = f.then<asy::Future<core::List<core::int>>>((dynamic x) → dynamic => <dynamic>[]);
+  asy::Future<core::List<core::int>> y = x;
+}
+static method m2() → dynamic {
+  asy::Future<core::int> f;
+  dynamic x = f.then<core::List<core::int>>((dynamic x) → dynamic => <dynamic>[]);
+  asy::Future<core::List<core::int>> y = x;
+}
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect
index 50d546c..2d680ba 100644
--- a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect
@@ -1,6 +1,8 @@
 library test;
 import self as self;
 
+import "dart:async";
+
 static method m1() → dynamic
   ;
 static method m2() → dynamic
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
index a252de0..57222ab 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
index 816cc71..557fab9 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
index c21b27b..5e26f10 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
index 0496959..fa51936 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 aa278ac..8bc362f 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
index 00a6e6a..3b3f456 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
index 00a6e6a..3b3f456 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
index 803eefd..e9cb911 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
index 577085e..0e8e4f6 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'Future<int>'.
 //  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards.dart'.
@@ -6,12 +8,13 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
 //   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                 ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
index cbcb2db..0e8e4f6 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
@@ -1,8 +1,20 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'Future<int>'.
+//  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards.dart'.
+//  - 'Future' is from 'dart:async'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
+//   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
+//                                                 ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
index 794ef2c..f0dc55f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
index 794ef2c..f0dc55f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
index 803eefd..e9cb911 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
index 30b1ac3..8b99590 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
@@ -1,16 +1,19 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'MyFuture<int>'.
 //  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
 // Try changing the type of the left hand side, or casting the right hand side to 'MyFuture<int>'.
 //   MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
index 064084c..8b99590 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
@@ -1,8 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'MyFuture<double>' can't be assigned to a variable of type 'MyFuture<int>'.
+//  - 'MyFuture' is from 'pkg/front_end/testcases/inference/future_then_upwards_2.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'MyFuture<int>'.
+//   MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
+//                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
index 4ba6477..e868c2d 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
index 4ba6477..e868c2d 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
index 4c720d7..cdfda19 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
index a20ab5b..54ab95a 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
@@ -1,16 +1,19 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'Future<double>' can't be assigned to a variable of type 'Future<int>'.
 //  - 'Future' is from 'dart:async'.
 // Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
 //   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
 //                                                 ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
index 32706f4..54ab95a 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
@@ -1,8 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'Future<double>' can't be assigned to a variable of type 'Future<int>'.
+//  - 'Future' is from 'dart:async'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Future<int>'.
+//   Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
+//                                                 ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.expect
index 799443c..d593943 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> base;
   dynamic f = base.then((dynamic x) → dynamic {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.transformed.expect
index 799443c..d593943 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> base;
   dynamic f = base.then((dynamic x) → dynamic {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect
index 8e85697..666bc54 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect
@@ -1,6 +1,8 @@
 library test;
 import self as self;
 
+import "dart:async";
+
 static method test() → dynamic
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.expect
index 4c45b42..4ce6f50 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> base;
   asy::Future<core::bool> f = base.{asy::Future::then}<core::bool>((core::int x) → core::bool {
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect
index 4c45b42..4ce6f50 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method test() → dynamic {
   asy::Future<core::int> base;
   asy::Future<core::bool> f = base.{asy::Future::then}<core::bool>((core::int x) → core::bool {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
index b05e030..42ac544 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
index 23aa903..7cb03fb 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
index ec0d528..0e45bdd 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
index 52d35d7..a5ac737 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 a0d28bb1..a660035 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
index 9d62fa5..0985390 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
index f292acd..6eb70db 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
index ec0d528..0e45bdd 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
index d47b27d..5d5be70 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 84da7bd..596a21b 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
index 02761c2..5ca32db 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
index 62fcaa6..9c918a1 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
index 81c3bd1..10cd1f0 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
index ee2dc78..f4aa39ea 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
@@ -1,16 +1,19 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
 //  - 'FutureOr' is from 'dart:async'.
 // Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
 //         new /*@typeArgs=int*/ Future.value('hi'));
 //                                            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 53247c8..b7defba 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
@@ -1,8 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
+//  - 'FutureOr' is from 'dart:async'.
+// Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
+//         new /*@typeArgs=int*/ Future.value('hi'));
+//                                            ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
index 5eb63ec..8471190 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
index a332fc2..a165015 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
index 81c3bd1..10cd1f0 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
index ccc03d0..d17cf61 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 1e11465..41be920 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
index 9fba481..a2acf08 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
index 704909d..f4d6505 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
index cea415b..58b3b85 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
index 82b86ca..2d9895a 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
@@ -1,16 +1,19 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
 //  - 'FutureOr' is from 'dart:async'.
 // Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
 //         new /*@typeArgs=int*/ Future.value('hi'));
 //                                            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 3e0356f..7c40213 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
@@ -1,8 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: The argument type 'String' can't be assigned to the parameter type 'FutureOr<int>'.
+//  - 'FutureOr' is from 'dart:async'.
+// Try changing the type of the parameter, or casting the argument to 'FutureOr<int>'.
+//         new /*@typeArgs=int*/ Future.value('hi'));
+//                                            ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.hierarchy.expect
new file mode 100644
index 0000000..06d97d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Future:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Future._falseFuture
+    Future.catchError
+    Object.toString
+    Future._kTrue
+    Future.forEach
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Future.any
+    Object._instanceOf
+    Object.noSuchMethod
+    Future.then
+    Object._identityHashCode
+    Future.doWhile
+    Future._nullFuture
+    Object.hashCode
+    Future.wait
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  classSetters:
+
+MyFuture:
+  superclasses:
+    Object
+  interfaces: Future<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Future.catchError
+    Object.toString
+    Future.whenComplete
+    Object.runtimeType
+    Future.timeout
+    Object._simpleInstanceOf
+    Object._instanceOf
+    MyFuture.noSuchMethod
+    MyFuture.then
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Future.asStream
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
index b8bf3a1..4efea1b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
index 598ecd1..b6eba1b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
index cea415b..58b3b85 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
index 63ab7cf..0de77a6 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
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 4232dc3..028521e 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class MyFuture<T extends core::Object = dynamic> extends core::Object implements asy::Future<self::MyFuture::T> {
   constructor •() → self::MyFuture<self::MyFuture::T>
     : super core::Object::•() {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.expect
index cf2b682..ef7f24c 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.transformed.expect
index c0244b3..7f5bbe8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect
index eef0789..fa4dfd8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.expect
index 2d452ee..69a6b1a 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
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 45afa71..74f247a 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.expect
index cee5b68..2ddfc1a 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method id<T extends core::Object = dynamic>(self::id::T x) → self::id::T
   return x;
 static method test() → dynamic async {
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.transformed.expect
index fc9ead3..69fc341 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method id<T extends core::Object = dynamic>(self::id::T x) → self::id::T
   return x;
 static method test() → dynamic /* originally async */ {
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect
index 92d9692..59f0925 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method id<T extends core::Object = dynamic>(self::id::T x) → self::id::T
   ;
 static method test() → dynamic
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.expect
index 39e445a..82aa55a 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method id<T extends core::Object = dynamic>(self::id::T x) → self::id::T
   return x;
 static method test() → dynamic async {
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 8e23bd8..8b0ab47 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method id<T extends core::Object = dynamic>(self::id::T x) → self::id::T
   return x;
 static method test() → dynamic /* originally async */ {
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.hierarchy.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.hierarchy.expect
new file mode 100644
index 0000000..56ea0e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.hierarchy.expect
@@ -0,0 +1,72 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.expect
index 3259450..0324c10 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.transformed.expect
index f6baa93..4769915 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect
index 4d89361..cf47daa 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.expect
index 56ab63d..e6d8003 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
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 e55e2bc..53cd071 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.legacy.expect b/pkg/front_end/testcases/inference/generator_closure.dart.legacy.expect
index e9984fd..bd8ed88 100644
--- a/pkg/front_end/testcases/inference/generator_closure.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method foo(() → asy::Stream<core::int> values) → void {}
 static method main() → void {
   self::foo(() → asy::Stream<dynamic> async* {
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generator_closure.dart.legacy.transformed.expect
index a8834af..a5312fc 100644
--- a/pkg/front_end/testcases/inference/generator_closure.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method foo(() → asy::Stream<core::int> values) → void {}
 static method main() → void {
   self::foo(() → asy::Stream<dynamic> /* originally async* */ {
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.outline.expect b/pkg/front_end/testcases/inference/generator_closure.dart.outline.expect
index caa562f..d8e3037 100644
--- a/pkg/front_end/testcases/inference/generator_closure.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method foo(() → asy::Stream<core::int> values) → void
   ;
 static method main() → void
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.strong.expect b/pkg/front_end/testcases/inference/generator_closure.dart.strong.expect
index 57bbcb0..57d4fe9 100644
--- a/pkg/front_end/testcases/inference/generator_closure.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method foo(() → asy::Stream<core::int> values) → void {}
 static method main() → void {
   self::foo(() → asy::Stream<core::int> 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 5c81566..003313d 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
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method foo(() → asy::Stream<core::int> values) → void {}
 static method main() → void {
   self::foo(() → asy::Stream<core::int> /* originally async* */ {
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..3da2e02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
index 2fec18a..fce5b7e 100644
--- a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.strong.expect
@@ -1,20 +1,13 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart:26:77: Error: Inferred type argument 'int' doesn't conform to the bound 'String' of the type variable 'U' on 'Foo<String>.method'.
-//  - 'Foo' is from 'pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//       . /*error:COULD_NOT_INFER*/ /*@typeArgs=int*/ /*@target=Foo::method*/ method(
-//                                                                             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart:26:77: Error: Inferred type argument 'int' doesn't conform to the bound 'String' of the type variable 'U' on 'Foo<String>.method'.
-//  - 'Foo' is from 'pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-//       . /*error:COULD_NOT_INFER*/ /*@typeArgs=int*/ /*@target=Foo::method*/ method(
-//                                                                             ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart:26:77: Error: Inferred type argument 'int' doesn't conform to the bound 'String' of the type variable 'U' on 'Foo<String>.method'.
+//  - 'Foo' is from 'pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart'.
+// Try specifying type arguments explicitly so that they conform to the bounds.
+//       . /*error:COULD_NOT_INFER*/ /*@typeArgs=int*/ /*@target=Foo::method*/ method(
+//                                                                             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.expect
index 7e5ac84..cdd6a99 100644
--- a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method printInt(core::int x) → void
   return core::print(x);
 static method printDouble(core::double x) → void
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.transformed.expect
index 7e5ac84..cdd6a99 100644
--- a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method printInt(core::int x) → void
   return core::print(x);
 static method printDouble(core::double x) → void
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect
index d2c81cf..13f3e92 100644
--- a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:28:69: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
 // Try changing the type of the parameter, or casting the argument to 'int'.
@@ -19,12 +21,13 @@
 // Try changing the type of the parameter, or casting the argument to 'int'.
 //       /*@error=ArgumentTypeNotAssignable*/ "there"));
 //                                            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method printInt(core::int x) → void
   return core::print(x);
 static method printDouble(core::double x) → void
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
index c7f9ea6..13f3e92 100644
--- a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
@@ -1,8 +1,33 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:28:69: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//       /*@typeArgs=int*/ max(1, /*@error=ArgumentTypeNotAssignable*/ 2.0));
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:30:69: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//       /*@typeArgs=int*/ min(1, /*@error=ArgumentTypeNotAssignable*/ 2.0));
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:38:44: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//       /*@error=ArgumentTypeNotAssignable*/ "hi",
+//                                            ^
+//
+// pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:39:44: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//       /*@error=ArgumentTypeNotAssignable*/ "there"));
+//                                            ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math";
+
 static method printInt(core::int x) → void
   return core::print(x);
 static method printDouble(core::double x) → void
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6aff
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
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 a4f9811..9b3d956 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
@@ -1,40 +1,26 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:14:64: Error: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
-// /*@error=OverrideTypeMismatchReturnType*/ /*@topType=dynamic*/ m(
-//                                                                ^
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:9:5: Context: This is the overridden method ('m').
-//   T m<T>(T x) => x;
-//     ^
-//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:14:64: Error: The return type of the method 'D.m' is 'dynamic', which does not match the return type of the overridden method, 'T'.
-// Change to a subtype of 'T'.
-// /*@error=OverrideTypeMismatchReturnType*/ /*@topType=dynamic*/ m(
-//                                                                ^
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:9:5: Context: This is the overridden method ('m').
-//   T m<T>(T x) => x;
-//     ^
-//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:21:106: Error: Expected 0 type arguments.
-//       . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ /*@error=TypeArgumentMismatch*/ m<
-//                                                                                                          ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:14:64: Error: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
-// /*@error=OverrideTypeMismatchReturnType*/ /*@topType=dynamic*/ m(
-//                                                                ^
-//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:14:64: Error: The return type of the method 'D.m' is 'dynamic', which does not match the return type of the overridden method, 'T'.
-// Change to a subtype of 'T'.
-// /*@error=OverrideTypeMismatchReturnType*/ /*@topType=dynamic*/ m(
-//                                                                ^
-//
-// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:21:106: Error: Expected 0 type arguments.
-//       . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ /*@error=TypeArgumentMismatch*/ m<
-//                                                                                                          ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:14:64: Error: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
+// /*@error=OverrideTypeMismatchReturnType*/ /*@topType=dynamic*/ m(
+//                                                                ^
+// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:9:5: Context: This is the overridden method ('m').
+//   T m<T>(T x) => x;
+//     ^
+//
+// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:14:64: Error: The return type of the method 'D.m' is 'dynamic', which does not match the return type of the overridden method, 'T'.
+// Change to a subtype of 'T'.
+// /*@error=OverrideTypeMismatchReturnType*/ /*@topType=dynamic*/ m(
+//                                                                ^
+// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:9:5: Context: This is the overridden method ('m').
+//   T m<T>(T x) => x;
+//     ^
+//
+// pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart:21:106: Error: Expected 0 type arguments.
+//       . /*error:WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD*/ /*@target=D::m*/ /*@error=TypeArgumentMismatch*/ m<
+//                                                                                                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect
index 36362be..3266060 100644
--- a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:76: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           /*@typeArgs=String*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
 //                                                                            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
index a0de68d..3266060 100644
--- a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:76: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//           /*@typeArgs=String*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
+//                                                                            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.hierarchy.expect
new file mode 100644
index 0000000..8efc4cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.expect
index 44e5758..2b9e694 100644
--- a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Warning: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
 //   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
@@ -13,8 +15,7 @@
 // pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Context: This is the overridden method ('g').
 //   dynamic g(int x) => x;
 //           ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.transformed.expect
index 9cd9ef8..2b9e694 100644
--- a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.legacy.transformed.expect
@@ -1,4 +1,21 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Warning: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
+//   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
+//                                              ^
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Context: This is the overridden method ('m').
+//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
+//                        ^
+//
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:17:46: Warning: Declared type variables of 'D.g' doesn't match those on overridden method 'C.g'.
+//   T /*@error=OverrideTypeVariablesMismatch*/ g<T>(
+//                                              ^
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Context: This is the overridden method ('g').
+//   dynamic g(int x) => x;
+//           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.strong.expect
index 7df8c64..5d175fa 100644
--- a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.strong.expect
@@ -1,56 +1,37 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Error: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
-//   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
-//                                              ^
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Context: This is the overridden method ('m').
-//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
-//                        ^
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:15:54: Error: The parameter 'x' of the method 'D.m' has type 'T', which does not match the corresponding type in the overridden method, 'dynamic'.
-// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
-//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
-//                                                      ^
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Context: This is the overridden method ('m').
-//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
-//                        ^
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:17:46: Error: Declared type variables of 'D.g' doesn't match those on overridden method 'C.g'.
-//   T /*@error=OverrideTypeVariablesMismatch*/ g<T>(
-//                                              ^
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Context: This is the overridden method ('g').
-//   dynamic g(int x) => x;
-//           ^
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:18:54: Error: The parameter 'x' of the method 'D.g' has type 'T', which does not match the corresponding type in the overridden method, 'int'.
-// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
-//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
-//                                                      ^
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Context: This is the overridden method ('g').
-//   dynamic g(int x) => x;
-//           ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Error: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
-//   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
-//                                              ^
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:15:54: Error: The parameter 'x' of the method 'D.m' has type 'T', which does not match the corresponding type in the overridden method, 'dynamic'.
-// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
-//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
-//                                                      ^
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:17:46: Error: Declared type variables of 'D.g' doesn't match those on overridden method 'C.g'.
-//   T /*@error=OverrideTypeVariablesMismatch*/ g<T>(
-//                                              ^
-//
-// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:18:54: Error: The parameter 'x' of the method 'D.g' has type 'T', which does not match the corresponding type in the overridden method, 'int'.
-// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
-//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
-//                                                      ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:14:46: Error: Declared type variables of 'D.m' doesn't match those on overridden method 'C.m'.
+//   T /*@error=OverrideTypeVariablesMismatch*/ m<T>(
+//                                              ^
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Context: This is the overridden method ('m').
+//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
+//                        ^
+//
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:15:54: Error: The parameter 'x' of the method 'D.m' has type 'T', which does not match the corresponding type in the overridden method, 'dynamic'.
+// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
+//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
+//                                                      ^
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:9:24: Context: This is the overridden method ('m').
+//   /*@topType=dynamic*/ m(/*@topType=dynamic*/ x) => x;
+//                        ^
+//
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:17:46: Error: Declared type variables of 'D.g' doesn't match those on overridden method 'C.g'.
+//   T /*@error=OverrideTypeVariablesMismatch*/ g<T>(
+//                                              ^
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Context: This is the overridden method ('g').
+//   dynamic g(int x) => x;
+//           ^
+//
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:18:54: Error: The parameter 'x' of the method 'D.g' has type 'T', which does not match the corresponding type in the overridden method, 'int'.
+// Change to a supertype of 'int', or, for a covariant parameter, a subtype.
+//           T /*@error=OverrideTypeMismatchParameter*/ x) =>
+//                                                      ^
+// pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart:10:11: Context: This is the overridden method ('g').
+//   dynamic g(int x) => x;
+//           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.hierarchy.expect
new file mode 100644
index 0000000..973bb22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.hierarchy.expect
new file mode 100644
index 0000000..973bb22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.hierarchy.expect
new file mode 100644
index 0000000..973bb22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.hierarchy.expect
new file mode 100644
index 0000000..62a1574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.expect
index b797686..4b8fab7 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.expect
@@ -3,6 +3,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math" as math;
+import "dart:math";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.transformed.expect
index b797686..4b8fab7 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.legacy.transformed.expect
@@ -3,6 +3,9 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math" as math;
+import "dart:math";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
index 688f2c8..599ce81 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
 // Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
@@ -29,12 +31,14 @@
 // Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
 //           . /*@target=C::m*/ m);
 //                              ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math" as math;
+import "dart:math";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
index 8aea3c4..599ce81 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
@@ -1,8 +1,44 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
+//       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
+//                                                                         ^
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:30:73: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
+//       /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
+//                                                                         ^
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:46:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
+//   takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
+//                                                                        ^
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:47:72: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
+//   takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
+//                                                                        ^
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'int Function(double, int)'.
+// Try changing the type of the parameter, or casting the argument to 'int Function(double, int)'.
+//           . /*@target=C::m*/ m);
+//                              ^
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: The argument type 'num Function(num, num)' can't be assigned to the parameter type 'double Function(int, double)'.
+// Try changing the type of the parameter, or casting the argument to 'double Function(int, double)'.
+//           . /*@target=C::m*/ m);
+//                              ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math" as math;
+import "dart:math";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6aff
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.expect
index 5b0e517..24d0db0 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.expect
@@ -1,13 +1,11 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Can't access platform private library.
 // /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
 //                                          ^
 //
-// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Not found: 'dart:_foreign_helper'
-// /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
-//                                          ^
-//
 // pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:11:43: Warning: Method not found: 'JS'.
 //   String x = /*error:INVALID_ASSIGNMENT*/ JS('int', '42');
 //                                           ^^
@@ -15,21 +13,12 @@
 // pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:12:28: Warning: Method not found: 'JS'.
 //   var /*@type=String*/ y = JS('String', '"hello"');
 //                            ^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Can't access platform private library.
-// /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
-//                                          ^
-//
-// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Not found: 'dart:_foreign_helper'
-// /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
-//                                          ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
+import "dart:_foreign_helper";
+
 static method main() → dynamic {
   core::String x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#JS, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>["int", "42"]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
   dynamic y = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#JS, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>["String", "\"hello\""]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.transformed.expect
index 89adde8..24d0db0 100644
--- a/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart.legacy.transformed.expect
@@ -1,17 +1,24 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Can't access platform private library.
 // /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
 //                                          ^
 //
-// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Not found: 'dart:_foreign_helper'
-// /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
-//                                          ^
-
-library test;
+// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:11:43: Warning: Method not found: 'JS'.
+//   String x = /*error:INVALID_ASSIGNMENT*/ JS('int', '42');
+//                                           ^^
+//
+// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:12:28: Warning: Method not found: 'JS'.
+//   var /*@type=String*/ y = JS('String', '"hello"');
+//                            ^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:_foreign_helper";
+
 static method main() → dynamic {
   core::String x = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#JS, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>["int", "42"]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
   dynamic y = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#JS, 32, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>["String", "\"hello\""]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
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 ce6b792..bc9e0ea 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,15 +1,14 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Can't access platform private library.
 // /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
 //                                          ^
 //
-// pkg/front_end/testcases/inference/generic_methods_infer_js_builtin.dart:8:42: Error: Not found: 'dart:_foreign_helper'
-// /*error:IMPORT_INTERNAL_LIBRARY*/ import 'dart:_foreign_helper' show JS;
-//                                          ^
-
-library test;
 import self as self;
 
+import "dart:_foreign_helper";
+
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect
index d2d0114..9b6c3be 100644
--- a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //           1.0);
 //           ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
index fed97ff..9b6c3be 100644
--- a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//           1.0);
+//           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.expect
index cda283f..b8c72dc 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method make(core::int x) → asy::Future<core::int>
   return asy::Future::•<dynamic>(() → dynamic => x);
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.transformed.expect
index cda283f..b8c72dc 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method make(core::int x) → asy::Future<core::int>
   return asy::Future::•<dynamic>(() → dynamic => x);
 static method test() → dynamic {
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect
index 292cf85..6181d32 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'FutureOr<String>'.
 //  - 'FutureOr' is from 'dart:async'.
@@ -11,23 +13,24 @@
 // Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
 //                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@returnType=String*/ (String
 //                                                                                                            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method make(core::int x) → asy::Future<core::int>
   return asy::Future::•<core::int>(() → core::int => x);
 static method test() → dynamic {
   core::Iterable<asy::Future<core::int>> list = <core::int>[1, 2, 3].{core::Iterable::map}<asy::Future<core::int>>(self::make);
   asy::Future<core::List<core::int>> results = asy::Future::wait<core::int>(list);
-  asy::Future<core::String> results2 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", (asy::FutureOr<core::String> x, core::int y) → asy::FutureOr<core::String> => (let final dynamic #t1 = x in invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'FutureOr<String>'.
+  asy::Future<core::String> results2 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", (asy::FutureOr<core::String> x, core::int y) → asy::FutureOr<core::String> => invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'FutureOr<String>'.
  - 'FutureOr' is from 'dart:async'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
                           /*@type=int*/ y) => /*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/ x /*error:UNDEFINED_OPERATOR*/ +
-                                                                                                                       ^") as{TypeError} asy::FutureOr<core::String>));
-  asy::Future<core::String> results3 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:108: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
+                                                                                                                       ^" as{TypeError} asy::FutureOr<core::String>));
+  asy::Future<core::String> results3 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:108: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
  - 'FutureOr' is from 'dart:async'.
 Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@returnType=String*/ (String
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
index 10a7227..6181d32 100644
--- a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
@@ -1,19 +1,36 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'FutureOr<String>'.
+//  - 'FutureOr' is from 'dart:async'.
+// Try correcting the name to the name of an existing method, or defining a method named '+'.
+//                           /*@type=int*/ y) => /*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/ x /*error:UNDEFINED_OPERATOR*/ +
+//                                                                                                                        ^
+//
+// pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:108: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
+//  - 'FutureOr' is from 'dart:async'.
+// Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
+//                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@returnType=String*/ (String
+//                                                                                                            ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 static method make(core::int x) → asy::Future<core::int>
   return asy::Future::•<core::int>(() → core::int => x);
 static method test() → dynamic {
   core::Iterable<asy::Future<core::int>> list = <core::int>[1, 2, 3].{core::Iterable::map}<asy::Future<core::int>>(self::make);
   asy::Future<core::List<core::int>> results = asy::Future::wait<core::int>(list);
-  asy::Future<core::String> results2 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", (asy::FutureOr<core::String> x, core::int y) → asy::FutureOr<core::String> => (let final asy::FutureOr<core::String> #t1 = x in invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'FutureOr<String>'.
+  asy::Future<core::String> results2 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", (asy::FutureOr<core::String> x, core::int y) → asy::FutureOr<core::String> => invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'FutureOr<String>'.
  - 'FutureOr' is from 'dart:async'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
                           /*@type=int*/ y) => /*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/ x /*error:UNDEFINED_OPERATOR*/ +
-                                                                                                                       ^") as{TypeError} asy::FutureOr<core::String>));
-  asy::Future<core::String> results3 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:108: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
+                                                                                                                       ^" as{TypeError} asy::FutureOr<core::String>));
+  asy::Future<core::String> results3 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:108: Error: The argument type 'String Function(String, int)' can't be assigned to the parameter type 'FutureOr<String> Function(FutureOr<String>, int)'.
  - 'FutureOr' is from 'dart:async'.
 Try changing the type of the parameter, or casting the argument to 'FutureOr<String> Function(FutureOr<String>, int)'.
                   /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@returnType=String*/ (String
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.hierarchy.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.hierarchy.expect
new file mode 100644
index 0000000..ca9315e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Trace:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Trace.frames
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Trace.frames
+
+Frame:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Frame.location
+  classSetters:
+    Frame.location
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.expect
index da47f03..260f1f1 100644
--- a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math" as math;
+
 class Trace extends core::Object {
   field core::List<self::Frame> frames = <self::Frame>[];
   synthetic constructor •() → self::Trace
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect
index da47f03..260f1f1 100644
--- a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:math" as math;
 
+import "dart:math" as math;
+
 class Trace extends core::Object {
   field core::List<self::Frame> frames = <self::Frame>[];
   synthetic constructor •() → self::Trace
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.hierarchy.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.hierarchy.expect
new file mode 100644
index 0000000..592e452
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.sort
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C._compareAny
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.sort2
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.hierarchy.expect
new file mode 100644
index 0000000..f7551a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: I
+  classMembers:
+    D.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    D.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.hierarchy.expect
new file mode 100644
index 0000000..f7551a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: I
+  classMembers:
+    D.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    D.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.hierarchy.expect
new file mode 100644
index 0000000..0d0e29f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+A:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+  interfaceMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.hierarchy.expect
new file mode 100644
index 0000000..315581c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Test.member
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..03e1145
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.hierarchy.expect
@@ -0,0 +1,79 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Test1.t
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Test2.t
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Test3.test3
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Test3.t
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.hierarchy.expect
new file mode 100644
index 0000000..6e9f0e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.hierarchy.expect
@@ -0,0 +1,118 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.hierarchy.expect
new file mode 100644
index 0000000..0d88d4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.hierarchy.expect
@@ -0,0 +1,138 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.hierarchy.expect
new file mode 100644
index 0000000..6e9f0e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.hierarchy.expect
@@ -0,0 +1,118 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.hierarchy.expect
new file mode 100644
index 0000000..103f020
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.hierarchy.expect
@@ -0,0 +1,81 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.hierarchy.expect
new file mode 100644
index 0000000..315581c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Test.member
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.hierarchy.expect
new file mode 100644
index 0000000..315581c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Test.member
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..d489c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.hierarchy.expect
@@ -0,0 +1,79 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Test1.prop
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Test2.prop
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Test3.test3
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Test3.prop
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.hierarchy.expect
new file mode 100644
index 0000000..7cf7949
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.hierarchy.expect
@@ -0,0 +1,121 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.member
+
+Test:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Base.member
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..2c693c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.hierarchy.expect
@@ -0,0 +1,117 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
+
+Test1:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
+
+Test2:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
+
+Test3:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Test3.test3
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..d489c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.hierarchy.expect
@@ -0,0 +1,79 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Test1.prop
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Test2.prop
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Test3.test3
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Test3.prop
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.hierarchy.expect
new file mode 100644
index 0000000..5ab98e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.f
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.hierarchy.expect
new file mode 100644
index 0000000..9240a15
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.staticVariable
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+    B.staticVariable
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.hierarchy.expect
new file mode 100644
index 0000000..57dce92
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect
index bd2face..0998224 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_consts_transitively_2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
 static const field dynamic m1 = inf::a1;
 static const field dynamic m2 = inf::a2;
 static method foo() → dynamic {
@@ -10,3 +12,23 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "./infer_consts_transitively_2.dart" as self;
+import "./infer_consts_transitively_2_b.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
+static const field dynamic a1 = self::m2;
+static const field dynamic a2 = inf2::b1;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+
+static const field dynamic b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect
index bd2face..0998224 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_consts_transitively_2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
 static const field dynamic m1 = inf::a1;
 static const field dynamic m2 = inf::a2;
 static method foo() → dynamic {
@@ -10,3 +12,23 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "./infer_consts_transitively_2.dart" as self;
+import "./infer_consts_transitively_2_b.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
+static const field dynamic a1 = self::m2;
+static const field dynamic a2 = inf2::b1;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+
+static const field dynamic b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect
index 964f93d..3530a86 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_consts_transitively_2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
 static const field core::int m1 = inf::a1;
 static const field core::int m2 = inf::a2;
 static method foo() → dynamic {
@@ -10,3 +12,25 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_consts_transitively_2.dart" as self;
+import "./infer_consts_transitively_2_b.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
+static const field core::int a1 = self::m2;
+static const field core::int a2 = inf2::b1;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+static const field core::int b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
index 964f93d..3530a86 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_consts_transitively_2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
 static const field core::int m1 = inf::a1;
 static const field core::int m2 = inf::a2;
 static method foo() → dynamic {
@@ -10,3 +12,25 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_consts_transitively_2.dart" as self;
+import "./infer_consts_transitively_2_b.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
+static const field core::int a1 = self::m2;
+static const field core::int a2 = inf2::b1;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+static const field core::int b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect
index 49f30fa..c06662b 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.expect
@@ -3,6 +3,32 @@
 import "./infer_consts_transitively_2.dart" as test;
 import "./infer_consts_transitively_2_b.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
 static const field dynamic a1 = test::m2;
 static const field dynamic a2 = inf::b1;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_consts_transitively_2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
+static const field dynamic m1 = self::a1;
+static const field dynamic m2 = self::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static const field dynamic b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect
index 49f30fa..c06662b 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.legacy.transformed.expect
@@ -3,6 +3,32 @@
 import "./infer_consts_transitively_2.dart" as test;
 import "./infer_consts_transitively_2_b.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
 static const field dynamic a1 = test::m2;
 static const field dynamic a2 = inf::b1;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_consts_transitively_2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
+static const field dynamic m1 = self::a1;
+static const field dynamic m2 = self::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static const field dynamic b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect
index 169b4c2..cbafa8c 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.expect
@@ -4,6 +4,33 @@
 import "./infer_consts_transitively_2.dart" as test;
 import "./infer_consts_transitively_2_b.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
 static const field core::int a1 = test::m2;
 static const field core::int a2 = inf::b1;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_consts_transitively_2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
+static const field core::int m1 = self::a1;
+static const field core::int m2 = self::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static const field core::int b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
index 169b4c2..cbafa8c 100644
--- a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
@@ -4,6 +4,33 @@
 import "./infer_consts_transitively_2.dart" as test;
 import "./infer_consts_transitively_2_b.dart" as inf;
 
+import "org-dartlang-testcase:///infer_consts_transitively_2.dart";
+import "org-dartlang-testcase:///infer_consts_transitively_2_b.dart";
+
 static const field core::int a1 = test::m2;
 static const field core::int a2 = inf::b1;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_consts_transitively_2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_consts_transitively_2_a.dart";
+
+static const field core::int m1 = self::a1;
+static const field core::int m2 = self::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static const field core::int b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.hierarchy.expect
new file mode 100644
index 0000000..8f8ffaf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+    A.z
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.w
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    B.x
+    B.w
+    B.z
+  interfaceMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.w
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B.y
+    B.x
+    B.w
+    B.z
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
index f159ba8..5c42083 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:26:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
@@ -14,8 +16,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
 //                                                              ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
index 3972ad0..5c42083 100644
--- a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:26:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
+//                                                              ^
+//
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:28:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
+//                                                              ^
+//
+// pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:32:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
+//                                                              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.hierarchy.expect
new file mode 100644
index 0000000..0d0e29f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+A:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+  interfaceMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..fab6c77
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: C
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: B, C
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+  interfaceMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..06440ff
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+B:
+  superclasses:
+    Object
+  interfaces: C
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B.x
+
+A:
+  superclasses:
+    Object
+  interfaces: B, C
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+  interfaceMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.hierarchy.expect
new file mode 100644
index 0000000..e7b6812
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.hierarchy.expect
@@ -0,0 +1,227 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> A
+  interfaces: B
+  classMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+  interfaceMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.x
+
+F:
+  superclasses:
+    Object
+      -> A
+  interfaces: C
+  classMembers:
+    Object.toString
+    F.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    F.x
+  interfaceMembers:
+    Object.toString
+    F.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    F.x
+
+G:
+  superclasses:
+    Object
+      -> A
+  interfaces: D
+  classMembers:
+    Object.toString
+    G.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    G.x
+  interfaceMembers:
+    Object.toString
+    G.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    G.x
+
+H:
+  superclasses:
+    Object
+      -> C
+  interfaces: D
+  classMembers:
+    Object.toString
+    H.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    H.x
+  interfaceMembers:
+    Object.toString
+    H.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    H.x
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
index 3f402e0..a48dc1a 100644
--- a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.strong.expect
@@ -1,116 +1,70 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
-// Change to a subtype of 'int'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
-//   int get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type of the overridden method, 'num'.
-// Change to a subtype of 'num'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
-//   num get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
-// Change to a subtype of 'int'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
-//   int get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type of the overridden method, 'double'.
-// Change to a subtype of 'double'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
-//   double get x;
-//              ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type of the overridden method, 'num'.
-// Change to a subtype of 'num'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
-//   num get x;
-//           ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type of the overridden method, 'double'.
-// Change to a subtype of 'double'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
-//   double get x;
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
-// Change to a subtype of 'int'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type of the overridden method, 'num'.
-// Change to a subtype of 'num'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
-// Change to a subtype of 'int'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type of the overridden method, 'double'.
-// Change to a subtype of 'double'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type of the overridden method, 'num'.
-// Change to a subtype of 'num'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-//
-// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type of the overridden method, 'double'.
-// Change to a subtype of 'double'.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
-//                                                                                                                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
+// Specify the type explicitly.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
+// Specify the type explicitly.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: Can't infer the type of 'x': overridden members must all have the same type.
+// Specify the type explicitly.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
+// Change to a subtype of 'int'.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
+//   int get x;
+//           ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:32:163: Error: The return type of the method 'F.x' is 'dynamic', which does not match the return type of the overridden method, 'num'.
+// Change to a subtype of 'num'.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
+//   num get x;
+//           ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
+// Change to a subtype of 'int'.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:9:11: Context: This is the overridden method ('x').
+//   int get x;
+//           ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:36:163: Error: The return type of the method 'G.x' is 'dynamic', which does not match the return type of the overridden method, 'double'.
+// Change to a subtype of 'double'.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
+//   double get x;
+//              ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type of the overridden method, 'num'.
+// Change to a subtype of 'num'.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:17:11: Context: This is the overridden method ('x').
+//   num get x;
+//           ^
+//
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:40:163: Error: The return type of the method 'H.x' is 'dynamic', which does not match the return type of the overridden method, 'double'.
+// Change to a subtype of 'double'.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ /*@error=OverrideTypeMismatchReturnType*/ /*@error=OverrideTypeMismatchReturnType*/ x;
+//                                                                                                                                                                   ^
+// pkg/front_end/testcases/inference/infer_field_override_multiple.dart:21:14: Context: This is the overridden method ('x').
+//   double get x;
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.hierarchy.expect
new file mode 100644
index 0000000..2eb49ae
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.hierarchy.expect
@@ -0,0 +1,77 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..746e3e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.hierarchy.expect
@@ -0,0 +1,64 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.z
+
+B:
+  superclasses:
+    Object
+      -> A<int>
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    B.x
+    B.z
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..d7a8370
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.hierarchy.expect
@@ -0,0 +1,226 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+  interfaceMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.x
+
+F:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    F.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    F.x
+  interfaceMembers:
+    Object.toString
+    F.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    F.x
+
+Object with B:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+G:
+  superclasses:
+    Object
+      -> _G&Object&B
+  interfaces: B
+  classMembers:
+    Object.toString
+    G.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    G.x
+  interfaceMembers:
+    Object.toString
+    G.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    G.x
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..20d7855
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.hierarchy.expect
@@ -0,0 +1,226 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+  interfaceMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.x
+
+F:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    F.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    F.x
+  interfaceMembers:
+    Object.toString
+    F.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    F.x
+
+Object with B:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B.x
+
+G:
+  superclasses:
+    Object
+      -> _G&Object&B
+  interfaces: B
+  classMembers:
+    Object.toString
+    G.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    G.x
+  interfaceMembers:
+    Object.toString
+    G.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    G.x
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.hierarchy.expect
new file mode 100644
index 0000000..a07ab7b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.hierarchy.expect
@@ -0,0 +1,77 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..cb61bed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.hierarchy.expect
new file mode 100644
index 0000000..1ed3281
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.hierarchy.expect
new file mode 100644
index 0000000..a2d0d01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.hierarchy.expect
new file mode 100644
index 0000000..fb0a620
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.expect
index c1990f1..7ccc813 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:61: Warning: Getter not found: 'x'.
 // var /*@topType=B*/ b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:21:34: Warning: Getter not found: 'x'.
 //   /*error:UNDEFINED_IDENTIFIER*/ x
 //                                  ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.transformed.expect
index 9c6ee49..7ccc813 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.legacy.transformed.expect
@@ -1,4 +1,15 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:61: Warning: Getter not found: 'x'.
+// var /*@topType=B*/ b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
+//                                                             ^
+//
+// pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:21:34: Warning: Getter not found: 'x'.
+//   /*error:UNDEFINED_IDENTIFIER*/ x
+//                                  ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
index 9075c6f..0b2998b 100644
--- a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:61: Error: Getter not found: 'x'.
 // var /*@topType=B*/ b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
@@ -81,8 +83,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'B'.
 //   j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
 //                                                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
@@ -113,53 +114,53 @@
 static field core::int f = 2.{core::num::+}(3);
 static field core::int g = 3.{core::int::unary-}();
 static field self::B h = new self::A::•().{self::A::+}(3);
-static field dynamic i = let final dynamic #t3 = new self::A::•() in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:34:79: Error: The method 'unary-' isn't defined for the class 'A'.
+static field dynamic i = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:34:79: Error: The method 'unary-' isn't defined for the class 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try correcting the name to the name of an existing method, or defining a method named 'unary-'.
 var /*@topType=dynamic*/ i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
                                                                               ^";
 static field self::B j = null as self::B;
 static method test1() → dynamic {
-  self::a = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
+  self::a = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try changing the type of the left hand side, or casting the right hand side to 'A'.
   a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} self::A;
   self::a = new self::B::•(3);
-  self::b = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:40:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
+  self::b = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:40:36: Error: A value of type 'String' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try changing the type of the left hand side, or casting the right hand side to 'B'.
   b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
                                    ^" in "hi" as{TypeError} self::B;
   self::b = new self::B::•(3);
   self::c1 = <dynamic>[];
-  self::c1 = let final core::Set<dynamic> #t6 = col::LinkedHashSet::•<dynamic>() in #t6;
+  self::c1 = let final core::Set<dynamic> #t5 = col::LinkedHashSet::•<dynamic>() in #t5;
   self::c2 = <dynamic>[];
-  self::c2 = let final core::Set<dynamic> #t7 = col::LinkedHashSet::•<dynamic>() in #t7;
+  self::c2 = let final core::Set<dynamic> #t6 = col::LinkedHashSet::•<dynamic>() in #t6;
   self::d = <dynamic, dynamic>{};
-  self::d = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
+  self::d = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:36: Error: A value of type 'int' can't be assigned to a variable of type 'Map<dynamic, dynamic>'.
  - 'Map' is from 'dart:core'.
 Try changing the type of the left hand side, or casting the right hand side to 'Map<dynamic, dynamic>'.
   d = /*error:INVALID_ASSIGNMENT*/ 3;
                                    ^" in 3 as{TypeError} core::Map<dynamic, dynamic>;
   self::e = new self::A::•();
-  self::e = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
+  self::e = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:67: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'A'.
  - 'Map' is from 'dart:core'.
  - 'A' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try changing the type of the left hand side, or casting the right hand side to 'A'.
   e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
                                                                   ^" in <dynamic, dynamic>{} as{TypeError} self::A;
   self::f = 3;
-  self::f = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+  self::f = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   f = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} core::int;
   self::g = 1;
-  self::g = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:53:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
+  self::g = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:53:36: Error: A value of type 'bool' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   g = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} core::int;
-  self::h = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:54:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+  self::h = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:54:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try changing the type of the left hand side, or casting the right hand side to 'B'.
   h = /*error:INVALID_ASSIGNMENT*/ false;
@@ -167,12 +168,12 @@
   self::h = new self::B::•("b");
   self::i = false;
   self::j = new self::B::•("b");
-  self::j = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:58:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
+  self::j = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:58:36: Error: A value of type 'bool' can't be assigned to a variable of type 'B'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try changing the type of the left hand side, or casting the right hand side to 'B'.
   j = /*error:INVALID_ASSIGNMENT*/ false;
                                    ^" in false as{TypeError} self::B;
-  self::j = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:59:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
+  self::j = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:59:58: Error: A value of type 'List<dynamic>' can't be assigned to a variable of type 'B'.
  - 'List' is from 'dart:core'.
  - 'B' is from 'pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart'.
 Try changing the type of the left hand side, or casting the right hand side to 'B'.
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.hierarchy.expect
new file mode 100644
index 0000000..e03c302
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B.x
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.hierarchy.expect
new file mode 100644
index 0000000..50432e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.hierarchy.expect
new file mode 100644
index 0000000..dcb1bc3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect
index bb04180..4ea1232 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
+
 static field dynamic y = inf::x;
 static method test1() → dynamic {
   core::int t = 3;
@@ -10,3 +12,45 @@
   t = self::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+static field dynamic x = 2;
+static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field dynamic y = inf2::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf2::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect
index bb04180..4ea1232 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
+
 static field dynamic y = inf::x;
 static method test1() → dynamic {
   core::int t = 3;
@@ -10,3 +12,45 @@
   t = self::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+static field dynamic x = 2;
+static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field dynamic y = inf2::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf2::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect
index a5f2279..c251bf8 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
+
 static field core::int y = inf::x;
 static method test1() → dynamic {
   core::int t = 3;
@@ -10,3 +12,46 @@
   t = self::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+static field core::int x = 2;
+static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field core::int y = inf2::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf2::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
index a5f2279..c251bf8 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart";
+
 static field core::int y = inf::x;
 static method test1() → dynamic {
   core::int t = 3;
@@ -10,3 +12,46 @@
   t = self::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+static field core::int x = 2;
+static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field core::int y = inf2::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf2::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.hierarchy.expect
new file mode 100644
index 0000000..dcb1bc3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect
index b941bf6..878a97d 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
 class B extends core::Object {
   static field dynamic y = inf::A::x;
   synthetic constructor •() → self::B
@@ -15,3 +17,17 @@
   t = self::B::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect
index b941bf6..878a97d 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
 class B extends core::Object {
   static field dynamic y = inf::A::x;
   synthetic constructor •() → self::B
@@ -15,3 +17,17 @@
   t = self::B::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect
index 04a0cbb..28ec8b4 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
 class B extends core::Object {
   static field core::int y = inf::A::x;
   synthetic constructor •() → self::B
@@ -15,3 +17,17 @@
   t = self::B::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
index 04a0cbb..28ec8b4 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
 class B extends core::Object {
   static field core::int y = inf::A::x;
   synthetic constructor •() → self::B
@@ -15,3 +17,17 @@
   t = self::B::y;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.hierarchy.expect
new file mode 100644
index 0000000..9b26581
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect
index b2d87e2..9af84b2 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 class A extends core::Object {
   static field dynamic x = 2;
   synthetic constructor •() → self::A
@@ -9,3 +11,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field dynamic y = self::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = self::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect
index b2d87e2..9af84b2 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 class A extends core::Object {
   static field dynamic x = 2;
   synthetic constructor •() → self::A
@@ -9,3 +11,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field dynamic y = self::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = self::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect
index 8aca87e..5112e7e 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 class A extends core::Object {
   static field core::int x = 2;
   synthetic constructor •() → self::A
@@ -9,3 +11,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field core::int y = self::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = self::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
index 8aca87e..5112e7e 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 class A extends core::Object {
   static field core::int x = 2;
   synthetic constructor •() → self::A
@@ -9,3 +11,23 @@
     ;
 }
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field core::int y = self::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = self::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.hierarchy.expect
new file mode 100644
index 0000000..dcb1bc3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect
index c198bc7..ad43ba3 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.expect
@@ -1,5 +1,41 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 static field dynamic x = 2;
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field dynamic y = inf::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect
index c198bc7..ad43ba3 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.legacy.transformed.expect
@@ -1,5 +1,41 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 static field dynamic x = 2;
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field dynamic y = inf::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect
index bcc0a02..f5cd011 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.expect
@@ -2,5 +2,41 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 static field core::int x = 2;
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field core::int y = inf::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
index bcc0a02..f5cd011 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
@@ -2,5 +2,41 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
 static field core::int x = 2;
 static method main() → dynamic {}
+
+library test;
+import self as self2;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart";
+
+class B extends core::Object {
+  static field core::int y = inf::A::x;
+  synthetic constructor •() → self2::B
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::A::x;
+  t = self2::B::y;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_from_variables_in_cycle_libs_when_flag_is_on2.dart";
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect
index 7471980..d442d47 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.expect
@@ -2,9 +2,19 @@
 import self as self;
 import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
+
 static field dynamic y = inf::x;
 static method test1() → dynamic {
   inf::x = "hi";
   self::y = "hi";
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static field dynamic x = 2;
+static method main() → dynamic {
+  inf::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect
index 7471980..d442d47 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.legacy.transformed.expect
@@ -2,9 +2,19 @@
 import self as self;
 import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
+
 static field dynamic y = inf::x;
 static method test1() → dynamic {
   inf::x = "hi";
   self::y = "hi";
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static field dynamic x = 2;
+static method main() → dynamic {
+  inf::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
index e47986c..ebfe694 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -9,12 +11,13 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   y = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
-
-library test;
+//
 import self as self;
 import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
+
 static field core::int y = inf::x;
 static method test1() → dynamic {
   inf::x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
@@ -27,3 +30,12 @@
                                    ^" in "hi" as{TypeError} core::int;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static field core::int x = 2;
+static method main() → dynamic {
+  inf::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
index bc3de58..ebfe694 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
@@ -1,8 +1,23 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
+// pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:14:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   y = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
 import self as self;
 import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag_a.dart";
+
 static field core::int y = inf::x;
 static method test1() → dynamic {
   inf::x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
@@ -15,3 +30,12 @@
                                    ^" in "hi" as{TypeError} core::int;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static field core::int x = 2;
+static method main() → dynamic {
+  inf::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.hierarchy.expect
new file mode 100644
index 0000000..dcb1bc3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect
index 73d5704..db58bcd 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
+
 class B extends core::Object {
   static field dynamic y = inf::A::x;
   synthetic constructor •() → self::B
@@ -14,3 +16,15 @@
   self::B::y = "hi";
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect
index 73d5704..db58bcd 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
+
 class B extends core::Object {
   static field dynamic y = inf::A::x;
   synthetic constructor •() → self::B
@@ -14,3 +16,15 @@
   self::B::y = "hi";
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
index 8ab19bb..2af44de 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -9,12 +11,13 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   B.y = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
+
 class B extends core::Object {
   static field core::int y = inf::A::x;
   synthetic constructor •() → self::B
@@ -32,3 +35,15 @@
                                      ^" in "hi" as{TypeError} core::int;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
index 0f7d3b6..2af44de 100644
--- a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
@@ -1,8 +1,23 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   A.x = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                      ^
+//
+// pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   B.y = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                      ^
+//
 import self as self;
 import "dart:core" as core;
 import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_from_variables_in_non_cycle_imports_with_flag2_a.dart";
+
 class B extends core::Object {
   static field core::int y = inf::A::x;
   synthetic constructor •() → self::B
@@ -20,3 +35,15 @@
                                      ^" in "hi" as{TypeError} core::int;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.hierarchy.expect
new file mode 100644
index 0000000..804e9c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.hierarchy.expect
new file mode 100644
index 0000000..62a1574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.hierarchy.expect
new file mode 100644
index 0000000..62a1574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.hierarchy.expect
new file mode 100644
index 0000000..62a1574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.hierarchy.expect
new file mode 100644
index 0000000..62a1574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..a2d0d01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..31b4162
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.hierarchy.expect
@@ -0,0 +1,99 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: C
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: B, C
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.hierarchy.expect
new file mode 100644
index 0000000..52366ab
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Resource:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Folder:
+  superclasses:
+    Object
+      -> Resource
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.expect
index 45294a7..a11e748 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Warning: Method not found: 'g'.
 //   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Context: Previous use of 'g'.
 //   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
 //                                                                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.transformed.expect
index 9071805..a11e748 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.legacy.transformed.expect
@@ -1,4 +1,18 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Warning: Method not found: 'g'.
+//   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+//                                                                          ^
+//
+// pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+//   g() => 0;
+//   ^
+// pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Context: Previous use of 'g'.
+//   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+//                                                                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
index 360c490..ed09f8b 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
 //   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Context: Previous use of 'g'.
 //   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
 //                                                                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
index 7159770..ed09f8b 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
@@ -1,4 +1,18 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
+//   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+//                                                                          ^
+//
+// pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+//   g() => 0;
+//   ^
+// pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Context: Previous use of 'g'.
+//   /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+//                                                                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.hierarchy.expect
new file mode 100644
index 0000000..1ed3281
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.hierarchy.expect
new file mode 100644
index 0000000..69c8242
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.hierarchy.expect
@@ -0,0 +1,94 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.h
+    Object.hashCode
+    A.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.h
+    Object.hashCode
+    B.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: A, B
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
index 8d85497..1738d37 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:61: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
 //   /*@topType=int*/ /*@error=OverrideMoreRequiredArguments*/ f(
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
 //   int f(int x);
 //       ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
index ce0baed..1738d37 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.legacy.transformed.expect
@@ -1,4 +1,14 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:61: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
+//   /*@topType=int*/ /*@error=OverrideMoreRequiredArguments*/ f(
+//                                                             ^
+// pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
+//   int f(int x);
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
index 4768ea2..5e0625d 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:61: Warning: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
 //   /*@topType=int*/ /*@error=OverrideMoreRequiredArguments*/ f(
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
 //   int f(int x);
 //       ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.strong.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.strong.expect
index 24fae77..c73b3ed 100644
--- a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_method_missing_params.dart:25:79: Error: Can't infer the type of 'y': overridden members must all have the same type.
 // Specify the type explicitly.
@@ -21,29 +23,7 @@
 // pkg/front_end/testcases/inference/infer_method_missing_params.dart:17:7: Context: This is the overridden method ('f').
 //   int f(int x);
 //       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:25:79: Error: Can't infer the type of 'y': overridden members must all have the same type.
-// Specify the type explicitly.
-//       /*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ y);
-//                                                                               ^
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:29:80: Error: Can't infer the type of 'y': overridden members must all have the same type.
-// Specify the type explicitly.
-//       {/*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ y});
-//                                                                                ^
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:27:80: Error: Can't infer the type of 'y': overridden members must all have the same type.
-// Specify the type explicitly.
-//       [/*@topType=dynamic*/ /*@error=CantInferTypeDueToInconsistentOverrides*/ y]);
-//                                                                                ^
-//
-// pkg/front_end/testcases/inference/infer_method_missing_params.dart:23:61: Error: The method 'C.f' has more required arguments than those of overridden method 'B.f'.
-//   /*@topType=int*/ /*@error=OverrideMoreRequiredArguments*/ f(
-//                                                             ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.hierarchy.expect
new file mode 100644
index 0000000..152e57e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.foo
+
+C:
+  superclasses:
+    Object
+      -> D
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.foo
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..d198772
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.foo
+
+C:
+  superclasses:
+    Object
+      -> D
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.foo
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.hierarchy.expect
new file mode 100644
index 0000000..1100455
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    A.~
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..9a9be82
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.foo
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..d1d7261
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..368c13e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.hierarchy.expect
@@ -0,0 +1,99 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+B:
+  superclasses:
+    Object
+  interfaces: C
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B.x
+
+A:
+  superclasses:
+    Object
+  interfaces: B, C
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.hierarchy.expect
new file mode 100644
index 0000000..82ba085
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.hierarchy.expect
new file mode 100644
index 0000000..82ba085
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.hierarchy.expect
new file mode 100644
index 0000000..c4b1d23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.a2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect
index 7e6a5f6..094adfb 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_transitively_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
 static final field dynamic m1 = inf::a1;
 static final field dynamic m2 = inf::A::a2;
 static method foo() → dynamic {
@@ -10,3 +12,29 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf2;
+import "./infer_statics_transitively.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field dynamic a2 = inf2::b1;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static final field dynamic a1 = self::m2;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect
index 7e6a5f6..094adfb 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_transitively_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
 static final field dynamic m1 = inf::a1;
 static final field dynamic m2 = inf::A::a2;
 static method foo() → dynamic {
@@ -10,3 +12,29 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf2;
+import "./infer_statics_transitively.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field dynamic a2 = inf2::b1;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static final field dynamic a1 = self::m2;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect
index bab2515..7d3fd79 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_transitively_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
 static final field core::int m1 = inf::a1;
 static final field core::int m2 = inf::A::a2;
 static method foo() → dynamic {
@@ -10,3 +12,30 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf2;
+import "./infer_statics_transitively.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field core::int a2 = inf2::b1;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static final field core::int a1 = self::m2;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
index bab2515..7d3fd79 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_transitively_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
 static final field core::int m1 = inf::a1;
 static final field core::int m2 = inf::A::a2;
 static method foo() → dynamic {
@@ -10,3 +12,30 @@
   i = self::m1;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf2;
+import "./infer_statics_transitively.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field core::int a2 = inf2::b1;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static final field core::int a1 = self::m2;
+static method main() → dynamic {}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  inf2::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.hierarchy.expect
new file mode 100644
index 0000000..acc7e81
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    A.a3
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect
index a75b04b..c14e037 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.expect
@@ -3,6 +3,9 @@
 import "dart:core" as core;
 import "./infer_statics_transitively3_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
+
 static const field dynamic t1 = 1;
 static const field dynamic t2 = self::t1;
 static const field dynamic t3 = inf::a1;
@@ -17,3 +20,17 @@
   i = self::t4;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static const field dynamic a3 = null;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static const field dynamic a1 = 3;
+static const field dynamic a2 = 4;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect
index a75b04b..c14e037 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.legacy.transformed.expect
@@ -3,6 +3,9 @@
 import "dart:core" as core;
 import "./infer_statics_transitively3_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
+
 static const field dynamic t1 = 1;
 static const field dynamic t2 = self::t1;
 static const field dynamic t3 = inf::a1;
@@ -17,3 +20,17 @@
   i = self::t4;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static const field dynamic a3 = null;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static const field dynamic a1 = 3;
+static const field dynamic a2 = 4;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect
index 497e52d..8554b53 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.expect
@@ -3,6 +3,9 @@
 import "dart:core" as core;
 import "./infer_statics_transitively3_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
+
 static const field core::int t1 = 1;
 static const field core::int t2 = self::t1;
 static const field core::int t3 = inf::a1;
@@ -17,3 +20,17 @@
   i = self::t4;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static const field dynamic a3 = null;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static const field core::int a1 = 3;
+static const field core::int a2 = 4;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
index 497e52d..8554b53 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
@@ -3,6 +3,9 @@
 import "dart:core" as core;
 import "./infer_statics_transitively3_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart";
+import "org-dartlang-testcase:///infer_statics_transitively3_a.dart" as p;
+
 static const field core::int t1 = 1;
 static const field core::int t2 = self::t1;
 static const field core::int t3 = inf::a1;
@@ -17,3 +20,17 @@
   i = self::t4;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static const field dynamic a3 = null;
+  synthetic constructor •() → inf::A
+    : super core::Object::•()
+    ;
+}
+static const field core::int a1 = 3;
+static const field core::int a2 = 4;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.hierarchy.expect
new file mode 100644
index 0000000..acc7e81
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    A.a3
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.hierarchy.expect
new file mode 100644
index 0000000..4171333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.a2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.a2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect
index 3f90aff..041ca29 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field dynamic a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -14,3 +17,44 @@
 static method main() → dynamic {
   self::a1;
 }
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field dynamic m1 = inf2::a1;
+static final field dynamic m2 = inf2::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field dynamic a2 = inf::b1;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static final field dynamic a1 = test::m2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect
index 3f90aff..041ca29 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.legacy.transformed.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field dynamic a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -14,3 +17,44 @@
 static method main() → dynamic {
   self::a1;
 }
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field dynamic m1 = inf2::a1;
+static final field dynamic m2 = inf2::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field dynamic a2 = inf::b1;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static final field dynamic a1 = test::m2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect
index 2cff8e9..295510c 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field core::int a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -14,3 +17,45 @@
 static method main() → dynamic {
   self::a1;
 }
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field core::int m1 = inf2::a1;
+static final field core::int m2 = inf2::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field core::int a2 = inf::b1;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static final field core::int a1 = test::m2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
index 2cff8e9..295510c 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field core::int a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -14,3 +17,45 @@
 static method main() → dynamic {
   self::a1;
 }
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as inf2;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field core::int m1 = inf2::a1;
+static final field core::int m2 = inf2::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
+
+library;
+import self as inf2;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
+class A extends core::Object {
+  static final field core::int a2 = inf::b1;
+  synthetic constructor •() → inf2::A
+    : super core::Object::•()
+    ;
+}
+static final field core::int a1 = test::m2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.hierarchy.expect
new file mode 100644
index 0000000..c4b1d23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.a2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect
index f814b99..e1f6bf9 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field dynamic a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -12,3 +15,26 @@
 }
 static final field dynamic a1 = test::m2;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field dynamic m1 = self::a1;
+static final field dynamic m2 = self::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect
index f814b99..e1f6bf9 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.legacy.transformed.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field dynamic a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -12,3 +15,26 @@
 }
 static final field dynamic a1 = test::m2;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field dynamic m1 = self::a1;
+static final field dynamic m2 = self::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect
index e0d7ab9..e5c5eb0 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field core::int a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -12,3 +15,27 @@
 }
 static final field core::int a1 = test::m2;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field core::int m1 = self::a1;
+static final field core::int m2 = self::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
index e0d7ab9..e5c5eb0 100644
--- a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
@@ -4,6 +4,9 @@
 import "./infer_statics_transitively_b.dart" as inf;
 import "./infer_statics_transitively.dart" as test;
 
+import "org-dartlang-testcase:///infer_statics_transitively.dart";
+import "org-dartlang-testcase:///infer_statics_transitively_b.dart";
+
 class A extends core::Object {
   static final field core::int a2 = inf::b1;
   synthetic constructor •() → self::A
@@ -12,3 +15,27 @@
 }
 static final field core::int a1 = test::m2;
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_statics_transitively_a.dart";
+
+static final field core::int m1 = self::a1;
+static final field core::int m2 = self::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = test::m1;
+}
+static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  inf::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.hierarchy.expect
new file mode 100644
index 0000000..9b02f6b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+T:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    T.foo
+    Object.noSuchMethod
+    T.m1
+    Object._identityHashCode
+    T.m2
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect
index 52c6c06..cdad9fa 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_with_method_invocations_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
+
 class T extends core::Object {
   static final field self::T foo = self::T::m1(self::T::m2(inf::m3("", "")));
   synthetic constructor •() → self::T
@@ -16,3 +18,10 @@
   }
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static method m3(core::String a, core::String b, [dynamic a1 = null, dynamic a2 = null]) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect
index 52c6c06..cdad9fa 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_with_method_invocations_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
+
 class T extends core::Object {
   static final field self::T foo = self::T::m1(self::T::m2(inf::m3("", "")));
   synthetic constructor •() → self::T
@@ -16,3 +18,10 @@
   }
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static method m3(core::String a, core::String b, [dynamic a1 = null, dynamic a2 = null]) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect
index 52c6c06..cdad9fa 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_with_method_invocations_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
+
 class T extends core::Object {
   static final field self::T foo = self::T::m1(self::T::m2(inf::m3("", "")));
   synthetic constructor •() → self::T
@@ -16,3 +18,10 @@
   }
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static method m3(core::String a, core::String b, [dynamic a1 = null, dynamic a2 = null]) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
index 52c6c06..cdad9fa 100644
--- a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_statics_with_method_invocations_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_statics_with_method_invocations_a.dart";
+
 class T extends core::Object {
   static final field self::T foo = self::T::m1(self::T::m2(inf::m3("", "")));
   synthetic constructor •() → self::T
@@ -16,3 +18,10 @@
   }
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+
+static method m3(core::String a, core::String b, [dynamic a1 = null, dynamic a2 = null]) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.hierarchy.expect
new file mode 100644
index 0000000..cb61bed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
index fbd3aab..38bb5e2 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
index 61b9117..38bb5e2 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
+//                                                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.hierarchy.expect
new file mode 100644
index 0000000..50432e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
index 74cff0d..9e7b8a7 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
index 3bd82ef..9e7b8a7 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
+//                                                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect
index 14b8127..de2349d 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
index a1f848e..de2349d 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect
index dfcda1a..d986721 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
index f7b38a9..d986721 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.hierarchy.expect
new file mode 100644
index 0000000..b588741
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.hierarchy.expect
@@ -0,0 +1,42 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    A.test1
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.z
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect
index da23c2d..4ed1521 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -14,8 +16,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     c = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                      ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
index 550faa1..4ed1521 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     a = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                      ^
+//
+// pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:16:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     b = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                      ^
+//
+// pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:19:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//     c = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                      ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect
index 552c53a..e3486c1 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -14,8 +16,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   c = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
index 129fcba..e3486c1 100644
--- a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   a = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
+// pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:15:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   b = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
+// pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:18:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   c = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.hierarchy.expect
new file mode 100644
index 0000000..49e8e22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.hierarchy.expect
@@ -0,0 +1,76 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
index 915ca9c..4302f4f 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
 class C extends inf::B {
   synthetic constructor •() → self::C
     : super inf::B::•()
@@ -24,3 +26,16 @@
 static method main() → dynamic {
   self::foo();
 }
+
+library;
+import self as inf;
+import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
+class B extends self::A {
+  synthetic constructor •() → inf::B
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
index 915ca9c..4302f4f 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
 class C extends inf::B {
   synthetic constructor •() → self::C
     : super inf::B::•()
@@ -24,3 +26,16 @@
 static method main() → dynamic {
   self::foo();
 }
+
+library;
+import self as inf;
+import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
+class B extends self::A {
+  synthetic constructor •() → inf::B
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
index 1d5ecf9..1f0fd34 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.expect
@@ -1,15 +1,18 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
 //                                                                     ^
-
-library test;
+//
 import self as self;
 import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
 class C extends inf::B {
   synthetic constructor •() → self::C
     : super inf::B::•()
@@ -34,3 +37,16 @@
 static method main() → dynamic {
   self::foo();
 }
+
+library;
+import self as inf;
+import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
+class B extends self::A {
+  synthetic constructor •() → inf::B
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
index 39f4588..1f0fd34 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
@@ -1,8 +1,18 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+//                                                                     ^
+//
 import self as self;
 import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
 class C extends inf::B {
   synthetic constructor •() → self::C
     : super inf::B::•()
@@ -27,3 +37,16 @@
 static method main() → dynamic {
   self::foo();
 }
+
+library;
+import self as inf;
+import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as self;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
+class B extends self::A {
+  synthetic constructor •() → inf::B
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.hierarchy.expect
new file mode 100644
index 0000000..49e8e22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.hierarchy.expect
@@ -0,0 +1,76 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
index 8459af2..2e91f62 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.expect
@@ -2,9 +2,40 @@
 import self as self;
 import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
 class B extends test::A {
   synthetic constructor •() → self::B
     : super test::A::•()
     ;
 }
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
+class C extends self::B {
+  synthetic constructor •() → test::C
+    : super self::B::•()
+    ;
+  get x() → dynamic
+    return null;
+}
+class A extends core::Object {
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static method foo() → dynamic {
+  core::int y = new test::C::•().x;
+  core::String z = new test::C::•().x;
+}
+static method main() → dynamic {
+  test::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
index 8459af2..2e91f62 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.legacy.transformed.expect
@@ -2,9 +2,40 @@
 import self as self;
 import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
 class B extends test::A {
   synthetic constructor •() → self::B
     : super test::A::•()
     ;
 }
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
+class C extends self::B {
+  synthetic constructor •() → test::C
+    : super self::B::•()
+    ;
+  get x() → dynamic
+    return null;
+}
+class A extends core::Object {
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static method foo() → dynamic {
+  core::int y = new test::C::•().x;
+  core::String z = new test::C::•().x;
+}
+static method main() → dynamic {
+  test::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
index 5e99efe..fe03c30 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.expect
@@ -1,17 +1,52 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
-//                                                                     ^
-
 library;
 import self as self;
 import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
 class B extends test::A {
   synthetic constructor •() → self::B
     : super test::A::•()
     ;
 }
 static method main() → dynamic {}
+
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+//                                                                     ^
+//
+import self as test;
+import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
+class C extends self::B {
+  synthetic constructor •() → test::C
+    : super self::B::•()
+    ;
+  get x() → core::int
+    return null;
+}
+class A extends core::Object {
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static method foo() → dynamic {
+  core::int y = new test::C::•().{test::C::x};
+  core::String z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+                                                                    ^" in new test::C::•().{test::C::x} as{TypeError} core::String;
+}
+static method main() → dynamic {
+  test::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
index 8459af2..fe03c30 100644
--- a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
@@ -2,9 +2,51 @@
 import self as self;
 import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
 
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles.dart";
+
 class B extends test::A {
   synthetic constructor •() → self::B
     : super test::A::•()
     ;
 }
 static method main() → dynamic {}
+
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+//                                                                     ^
+//
+import self as test;
+import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_type_regardless_of_declaration_order_or_cycles_b.dart";
+
+class C extends self::B {
+  synthetic constructor •() → test::C
+    : super self::B::•()
+    ;
+  get x() → core::int
+    return null;
+}
+class A extends core::Object {
+  synthetic constructor •() → test::A
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static method foo() → dynamic {
+  core::int y = new test::C::•().{test::C::x};
+  core::String z = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+                                                                    ^" in new test::C::•().{test::C::x} as{TypeError} core::String;
+}
+static method main() → dynamic {
+  test::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.hierarchy.expect
new file mode 100644
index 0000000..9fc3911
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.hierarchy.expect
@@ -0,0 +1,71 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.w
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A<int>
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.w
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.w
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
index 86d529f..2ac925a 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -9,8 +11,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
 //                                                                     ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
index f668981..2ac925a 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
@@ -1,4 +1,17 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   get /*@topType=int*/ w => /*error:RETURN_OF_INVALID_TYPE*/ "hello";
+//                                                              ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
+//                                                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.hierarchy.expect
new file mode 100644
index 0000000..4b24e03
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A<E>
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    A.x
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
index 0fcc9ad..f6074a4 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
 //                                                                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
index 52feedf..f6074a4 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
+//                                                                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.hierarchy.expect
new file mode 100644
index 0000000..9ec66d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.hierarchy.expect
@@ -0,0 +1,120 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: I<E>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<E>
+  interfaces: I<E>, M
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
index eeb1a65..ea55404 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=B::m*/ m(null, null);
 //                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
index 3f8ac59..ea55404 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       . /*@target=B::m*/ m(null, null);
+//                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.hierarchy.expect
new file mode 100644
index 0000000..7c7a4274
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.hierarchy.expect
@@ -0,0 +1,123 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: I<E>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    I.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<E>
+  interfaces: I<E>, M
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
index daa2859..2f73c7b 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
 abstract class A<E extends core::Object = dynamic> extends core::Object implements inf::I<self::A::E> {
   final field self::A::E value = null;
   const constructor •() → self::A<self::A::E>
@@ -28,3 +30,18 @@
   core::String z = new self::B::•<core::String>().m(null, null).value;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
+abstract class I<E extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → inf::I<inf::I::E>
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, core::int) → core::String f) → self::A<inf::I::E>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
index daa2859..2f73c7b 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
 abstract class A<E extends core::Object = dynamic> extends core::Object implements inf::I<self::A::E> {
   final field self::A::E value = null;
   const constructor •() → self::A<self::A::E>
@@ -28,3 +30,18 @@
   core::String z = new self::B::•<core::String>().m(null, null).value;
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
+abstract class I<E extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → inf::I<inf::I::E>
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, core::int) → core::String f) → self::A<inf::I::E>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
index e65ce67..af26f52 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.expect
@@ -1,15 +1,18 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //       . /*@target=A::value*/ value;
 //                              ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
 abstract class A<E extends core::Object = dynamic> extends core::Object implements inf::I<self::A::E> {
   final field self::A::E value = null;
   const constructor •() → self::A<self::A::E>
@@ -38,3 +41,18 @@
   core::String z = new self::B::•<core::String>().{self::B::m}(null, null).{self::A::value};
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
+abstract class I<E extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → inf::I<inf::I::E>
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, core::int) → core::String f) → self::A<inf::I::E>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
index d770c53..af26f52 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
@@ -1,8 +1,18 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       . /*@target=A::value*/ value;
+//                              ^
+//
 import self as self;
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
 abstract class A<E extends core::Object = dynamic> extends core::Object implements inf::I<self::A::E> {
   final field self::A::E value = null;
   const constructor •() → self::A<self::A::E>
@@ -31,3 +41,18 @@
   core::String z = new self::B::•<core::String>().{self::B::m}(null, null).{self::A::value};
 }
 static method main() → dynamic {}
+
+library;
+import self as inf;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
+abstract class I<E extends core::Object = dynamic> extends core::Object {
+  synthetic constructor •() → inf::I<inf::I::E>
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, core::int) → core::String f) → self::A<inf::I::E>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.hierarchy.expect
new file mode 100644
index 0000000..43b2564
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.hierarchy.expect
@@ -0,0 +1,123 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: I<E>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    I.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<E>
+  interfaces: I<E>, M
+  classMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.value
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
index 999c28e..c8150f5 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
 abstract class I<E extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::I<self::I::E>
     : super core::Object::•()
@@ -10,3 +12,36 @@
   abstract method m(dynamic a, (dynamic, core::int) → core::String f) → test::A<self::I::E>;
 }
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
+abstract class A<E extends core::Object = dynamic> extends core::Object implements self::I<test::A::E> {
+  final field test::A::E value = null;
+  const constructor •() → test::A<test::A::E>
+    : super core::Object::•()
+    ;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → test::M
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object = dynamic> extends test::A<test::B::E> implements test::M {
+  const constructor •() → test::B<test::B::E>
+    : super test::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+}
+static method foo() → dynamic {
+  core::int y = new test::B::•<core::String>().m(null, null).value;
+  core::String z = new test::B::•<core::String>().m(null, null).value;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
index 999c28e..c8150f5 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
 abstract class I<E extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::I<self::I::E>
     : super core::Object::•()
@@ -10,3 +12,36 @@
   abstract method m(dynamic a, (dynamic, core::int) → core::String f) → test::A<self::I::E>;
 }
 static method main() → dynamic {}
+
+library test;
+import self as test;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
+abstract class A<E extends core::Object = dynamic> extends core::Object implements self::I<test::A::E> {
+  final field test::A::E value = null;
+  const constructor •() → test::A<test::A::E>
+    : super core::Object::•()
+    ;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → test::M
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object = dynamic> extends test::A<test::B::E> implements test::M {
+  const constructor •() → test::B<test::B::E>
+    : super test::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+}
+static method foo() → dynamic {
+  core::int y = new test::B::•<core::String>().m(null, null).value;
+  core::String z = new test::B::•<core::String>().m(null, null).value;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
index 314ae7f..09436d7 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.expect
@@ -1,15 +1,10 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-//       . /*@target=A::value*/ value;
-//                              ^
-
 library;
 import self as self;
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
 abstract class I<E extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::I<self::I::E>
     : super core::Object::•()
@@ -17,3 +12,47 @@
   abstract method m(dynamic a, (dynamic, core::int) → core::String f) → test::A<self::I::E>;
 }
 static method main() → dynamic {}
+
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       . /*@target=A::value*/ value;
+//                              ^
+//
+import self as test;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
+abstract class A<E extends core::Object = dynamic> extends core::Object implements self::I<test::A::E> {
+  final field test::A::E value = null;
+  const constructor •() → test::A<test::A::E>
+    : super core::Object::•()
+    ;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → test::M
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object = dynamic> extends test::A<test::B::E> implements test::M {
+  const constructor •() → test::B<test::B::E>
+    : super test::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → test::A<test::B::E> {}
+}
+static method foo() → dynamic {
+  core::int y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+      . /*@target=A::value*/ value;
+                             ^" in new test::B::•<core::String>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int;
+  core::String z = new test::B::•<core::String>().{test::B::m}(null, null).{test::A::value};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
index 999c28e..09436d7 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
 
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle.dart";
+
 abstract class I<E extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::I<self::I::E>
     : super core::Object::•()
@@ -10,3 +12,47 @@
   abstract method m(dynamic a, (dynamic, core::int) → core::String f) → test::A<self::I::E>;
 }
 static method main() → dynamic {}
+
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       . /*@target=A::value*/ value;
+//                              ^
+//
+import self as test;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as self;
+
+import "org-dartlang-testcase:///infer_types_on_generic_instantiations_in_library_cycle_a.dart";
+
+abstract class A<E extends core::Object = dynamic> extends core::Object implements self::I<test::A::E> {
+  final field test::A::E value = null;
+  const constructor •() → test::A<test::A::E>
+    : super core::Object::•()
+    ;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → test::M
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object = dynamic> extends test::A<test::B::E> implements test::M {
+  const constructor •() → test::B<test::B::E>
+    : super test::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → test::A<test::B::E> {}
+}
+static method foo() → dynamic {
+  core::int y = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+      . /*@target=A::value*/ value;
+                             ^" in new test::B::•<core::String>().{test::B::m}(null, null).{test::A::value} as{TypeError} core::int;
+  core::String z = new test::B::•<core::String>().{test::B::m}(null, null).{test::A::value};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.hierarchy.expect
new file mode 100644
index 0000000..169f654
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.hierarchy.expect
@@ -0,0 +1,68 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A<int>
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.strong.expect
index 2583a3f..a901909 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart:13:49: Error: The return type of the method 'B.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
 // Change to a subtype of 'int'.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart:9:11: Context: This is the overridden method ('x').
 //   final T x = null;
 //           ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart:13:49: Error: The return type of the method 'B.x' is 'dynamic', which does not match the return type of the overridden method, 'int'.
-// Change to a subtype of 'int'.
-//   /*error:INVALID_METHOD_OVERRIDE*/ dynamic get x => 3;
-//                                                 ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.hierarchy.expect
new file mode 100644
index 0000000..d70dd37
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.hierarchy.expect
@@ -0,0 +1,74 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.bar
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Bar.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Baz:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Baz.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect
index 2adcee0..d7b891f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -28,8 +30,7 @@
 //  - 'Iterable' is from 'dart:core'.
 //   for (var /*@type=dynamic*/ x in /*error:FOR_IN_OF_INVALID_TYPE*/ map) {
 //                                                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
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 b0fe058..d7b891f 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
@@ -1,4 +1,36 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       int x = /*error:INVALID_ASSIGNMENT*/ i;
+//                                            ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:23:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       int x = /*error:INVALID_ASSIGNMENT*/ i;
+//                                            ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:32:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
+//  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//     String y = /*error:INVALID_ASSIGNMENT*/ x;
+//                                             ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:39:15: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
+//  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart'.
+// Try changing the type of the variable.
+//   for (String x in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/ list) {
+//               ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:60:68: 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'.
+//   for (var /*@type=dynamic*/ x in /*error:FOR_IN_OF_INVALID_TYPE*/ map) {
+//                                                                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.hierarchy.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.hierarchy.expect
new file mode 100644
index 0000000..ee3b085
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.hierarchy.expect
@@ -0,0 +1,184 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.bar
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Bar.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Baz:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Baz.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Stream:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Stream.asyncExpand
+    Stream.listen
+    Stream.map
+    Stream.pipe
+    Stream.cast
+    Stream.skip
+    Stream.join
+    Stream.asyncMap
+    Stream.toSet
+    Stream.asBroadcastStream
+    Object.toString
+    Stream.handleError
+    Stream.forEach
+    Stream.length
+    Stream.firstWhere
+    Object.runtimeType
+    Stream.isBroadcast
+    Stream.timeout
+    Object._simpleInstanceOf
+    Stream.isEmpty
+    Stream.take
+    Stream.any
+    Stream.transform
+    Stream.where
+    Object._instanceOf
+    Stream.skipWhile
+    Stream.castFrom
+    Stream.toList
+    Object.noSuchMethod
+    Stream.fold
+    Stream.drain
+    Stream.elementAt
+    Stream.distinct
+    Stream.expand
+    Stream.takeWhile
+    Stream.first
+    Object._identityHashCode
+    Object.hashCode
+    Stream.reduce
+    Stream.lastWhere
+    Stream.last
+    Object._simpleInstanceOfFalse
+    Stream.single
+    Stream.every
+    Stream.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Stream.singleWhere
+  classSetters:
+
+MyStream:
+  superclasses:
+    Object
+      -> Stream<T>
+  interfaces:
+  classMembers:
+    Stream.asyncExpand
+    Stream.listen
+    Stream.map
+    Stream.pipe
+    Stream.cast
+    Stream.skip
+    Stream.join
+    Stream.asyncMap
+    Stream.toSet
+    Stream.asBroadcastStream
+    Object.toString
+    Stream.handleError
+    Stream.forEach
+    Stream.length
+    Stream.firstWhere
+    Object.runtimeType
+    Stream.isBroadcast
+    Stream.timeout
+    Object._simpleInstanceOf
+    Stream.isEmpty
+    Stream.take
+    Stream.any
+    Stream.transform
+    Stream.where
+    Object._instanceOf
+    Stream.skipWhile
+    Stream.toList
+    Object.noSuchMethod
+    Stream.fold
+    Stream.drain
+    Stream.elementAt
+    Stream.distinct
+    Stream.expand
+    Stream.takeWhile
+    Stream.first
+    Object._identityHashCode
+    Object.hashCode
+    Stream.reduce
+    Stream.lastWhere
+    Stream.last
+    Object._simpleInstanceOfFalse
+    Stream.single
+    Stream.every
+    Stream.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Stream.singleWhere
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.expect
index 6137f92..0d7e2c9 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Foo extends core::Object {
   field core::int bar = 42;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.transformed.expect
index 22b3803..2cc1d41 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Foo extends core::Object {
   field core::int bar = 42;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.outline.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.outline.expect
index 4fc4a13..70778c8 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Foo extends core::Object {
   field core::int bar;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect
index 2a2bfbc..8d6871f 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -28,12 +30,13 @@
 //  - 'Stream' is from 'dart:async'.
 //   await for (var /*@type=dynamic*/ x in /*error:FOR_IN_OF_INVALID_TYPE*/ map) {
 //                                                                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Foo extends core::Object {
   field core::int bar = 42;
   synthetic constructor •() → self::Foo
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 d01610c..e8b37cd 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
@@ -1,8 +1,42 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       int x = /*error:INVALID_ASSIGNMENT*/ i;
+//                                            ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       int x = /*error:INVALID_ASSIGNMENT*/ i;
+//                                            ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
+//  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//     String y = /*error:INVALID_ASSIGNMENT*/ x;
+//                                             ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:45:21: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
+//  - 'Foo' is from 'pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart'.
+// Try changing the type of the variable.
+//   await for (String x in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/ myStream) {
+//                     ^
+//
+// pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:66:74: 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'.
+//   await for (var /*@type=dynamic*/ x in /*error:FOR_IN_OF_INVALID_TYPE*/ map) {
+//                                                                          ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class Foo extends core::Object {
   field core::int bar = 42;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.hierarchy.expect
new file mode 100644
index 0000000..3de5ead
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Foo.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.x
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect
index 3918cc1..b340fe0 100644
--- a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ "1"]);
 //                                              ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
index a634ff2..b340fe0 100644
--- a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   Foo([this.x = /*error:INVALID_ASSIGNMENT*/ "1"]);
+//                                              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.hierarchy.expect
new file mode 100644
index 0000000..f79ec8d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
+    C.x
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.hierarchy.expect
new file mode 100644
index 0000000..d80d95e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.hierarchy.expect
new file mode 100644
index 0000000..8f2062f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.hierarchy.expect
@@ -0,0 +1,41 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.b
+    A.a
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.hierarchy.expect
new file mode 100644
index 0000000..c3cf689
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.*
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..08a9f1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.hierarchy.expect
@@ -0,0 +1,67 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    I.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    I.*
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.hierarchy.expect
new file mode 100644
index 0000000..946de54
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..20990c1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.hierarchy.expect
@@ -0,0 +1,67 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    I.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    I.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.hierarchy.expect
new file mode 100644
index 0000000..80fc858
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..18886a1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.hierarchy.expect
@@ -0,0 +1,67 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    I.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    I.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.hierarchy.expect
new file mode 100644
index 0000000..9d314fc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..8815edf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.hierarchy.expect
@@ -0,0 +1,67 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    I.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    I.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.hierarchy.expect
new file mode 100644
index 0000000..9d314fc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..8815edf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.hierarchy.expect
@@ -0,0 +1,67 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    I.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    I.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.hierarchy.expect
new file mode 100644
index 0000000..2e814a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    E.toString
+    E.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    E._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    E.values
+    E.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.hierarchy.expect
new file mode 100644
index 0000000..2e814a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    E.toString
+    E.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    E._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    E.values
+    E.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.hierarchy.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.hierarchy.expect
new file mode 100644
index 0000000..f852cff
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.hierarchy.expect
@@ -0,0 +1,86 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    I1.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    I2.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I1, I2
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.hierarchy.expect
new file mode 100644
index 0000000..d5ffbd0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect
index 4c1044d..68e9b92 100644
--- a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart:10:12: Error: A value of type 'T Function<T>(T)' can't be assigned to a variable of type 'int Function(int)'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //   func = f.call;
 //            ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.hierarchy.expect
new file mode 100644
index 0000000..947e951
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.hierarchy.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
index a6e5a15..219a1ea 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
 // Try changing the type of the parameter, or casting the argument to 'int'.
@@ -14,8 +16,7 @@
 // Try changing the type of the parameter, or casting the argument to 'num'.
 //   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                       ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
index b8c82a7..219a1ea 100644
--- a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+//                                                                       ^
+//
+// pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+//                                                                       ^
+//
+// pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// Try changing the type of the parameter, or casting the argument to 'num'.
+//   x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+//                                                                       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
index e251619..763b151 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
 // Try changing the type of the parameter, or casting the argument to 'int'.
@@ -14,8 +16,7 @@
 // Try changing the type of the parameter, or casting the argument to 'num'.
 //   x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
 //                                                                        ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
index 1079583..763b151 100644
--- a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
@@ -1,4 +1,22 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: The argument type 'String' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+//                                                                        ^
+//
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: The argument type 'double' can't be assigned to the parameter type 'int'.
+// Try changing the type of the parameter, or casting the argument to 'int'.
+//   x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+//                                                                        ^
+//
+// pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: The argument type 'String' can't be assigned to the parameter type 'num'.
+// Try changing the type of the parameter, or casting the argument to 'num'.
+//   x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+//                                                                        ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.hierarchy.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.hierarchy.expect
new file mode 100644
index 0000000..dc723b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.t
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.expect
index 5625713..329a161 100644
--- a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic {
   asy::Future<core::int> futureInt = null;
   dynamic x = futureInt;
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.transformed.expect
index 5625713..329a161 100644
--- a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic {
   asy::Future<core::int> futureInt = null;
   dynamic x = futureInt;
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.outline.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.outline.expect
index 09dc88c..55e2ed1 100644
--- a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.outline.expect
@@ -1,5 +1,7 @@
 library test;
 import self as self;
 
+import "dart:async";
+
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.expect
index 072ead2..37687ca 100644
--- a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic {
   asy::Future<core::int> futureInt = null;
   asy::Future<core::int> x = futureInt;
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect
index 072ead2..37687ca 100644
--- a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 static method main() → dynamic {
   asy::Future<core::int> futureInt = null;
   asy::Future<core::int> x = futureInt;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.expect
index 110cf0f..6c8bac5 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method main() → dynamic {
   function a() → (core::int) → core::int {
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.transformed.expect
index a138755..6ceeed3 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method main() → dynamic {
   function a() → (core::int) → core::int {
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.outline.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.outline.expect
index 23a7b37..d57e83e 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method main() → dynamic
   ;
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 056c9cb..4445a49 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
@@ -1,16 +1,19 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/local_return_and_yield.dart:19:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
 //  - 'FutureOr' is from 'dart:async'.
 // Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
 //     return /*@returnType=dynamic*/ (/*@type=dynamic*/ x) => x;
 //                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method main() → dynamic {
   function a() → (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 bba0bec..d16c079 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
@@ -1,8 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/local_return_and_yield.dart:19:36: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+//  - 'FutureOr' is from 'dart:async'.
+// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
+//     return /*@returnType=dynamic*/ (/*@type=dynamic*/ x) => x;
+//                                    ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method main() → dynamic {
   function a() → (core::int) → core::int {
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.hierarchy.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.hierarchy.expect
new file mode 100644
index 0000000..af58758
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.hierarchy.expect
@@ -0,0 +1,73 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    C.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.a
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
index bed99dc..7b89247 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -25,8 +27,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
 //   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
index 8ecf212..7b89247 100644
--- a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
@@ -1,4 +1,33 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+//                                              ^
+//
+// pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+//                                              ^
+//
+// pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+//                                                             ^
+//
+// pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+//       /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+//                                              ^
+//
+// pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+//  - 'Pattern' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+//   x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+//                                                             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
index ee5e9fd..29bcc2c 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/map_literals_top_level.dart:14:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -25,8 +27,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
 //   x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
 //                                                              ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
index ffd8868..29bcc2c 100644
--- a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
@@ -1,4 +1,33 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:14:67: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:15:67: Error: A value of type 'double' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:16:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+//                                                              ^
+//
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:27:67: Error: A value of type 'String' can't be assigned to a variable of type 'num'.
+// Try changing the type of the left hand side, or casting the right hand side to 'num'.
+//   x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference/map_literals_top_level.dart:29:62: Error: A value of type 'int' can't be assigned to a variable of type 'Pattern'.
+//  - 'Pattern' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'Pattern'.
+//   x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+//                                                              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.hierarchy.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.hierarchy.expect
new file mode 100644
index 0000000..92135a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.hierarchy.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.hierarchy.expect
new file mode 100644
index 0000000..92135a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.hierarchy.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.hierarchy.expect
new file mode 100644
index 0000000..92135a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.hierarchy.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.hierarchy.expect
new file mode 100644
index 0000000..130aed5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.hierarchy.expect
new file mode 100644
index 0000000..06b9b49
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.hierarchy.expect
@@ -0,0 +1,144 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<X>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces: I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1 with M0<int, String>:
+  superclasses:
+    Object
+      -> M1
+  interfaces: I<int>, M0<int, String>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> M1
+        -> _A&M1&M0
+  interfaces: I<int>, M0<int, String>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.expect
index 68141d0..2fa7bf9 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.expect
@@ -1,27 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -41,7 +17,7 @@
     : super core::Object::•()
     ;
 }
-abstract class _A&M1&M0 = self::M1 with self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 = self::M1 with self::M0<core::int, core::String> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.transformed.expect
index d53ce70..2aeb31d 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.legacy.transformed.expect
@@ -1,15 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -29,7 +17,7 @@
     : super core::Object::•()
     ;
 }
-abstract class _A&M1&M0 extends self::M1 implements self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 extends self::M1 implements self::M0<core::int, core::String> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.outline.expect
index 47cf040..2af7824 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.outline.expect
@@ -1,15 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -26,7 +14,7 @@
   synthetic constructor •() → self::M1
     ;
 }
-abstract class _A&M1&M0 = self::M1 with self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 = self::M1 with self::M0<core::int, core::String> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.hierarchy.expect
new file mode 100644
index 0000000..3f48b79
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.hierarchy.expect
@@ -0,0 +1,144 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<X>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces: I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1 with M0<int, int>:
+  superclasses:
+    Object
+      -> M1
+  interfaces: I<int>, M0<int, int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> M1
+        -> _A&M1&M0
+  interfaces: I<int>, M0<int, int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.expect
index b7e2c17..db552ee 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.expect
@@ -1,27 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -41,7 +17,7 @@
     : super core::Object::•()
     ;
 }
-abstract class _A&M1&M0 = self::M1 with self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 = self::M1 with self::M0<core::int, core::int> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.transformed.expect
index 353900f..6459244 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.legacy.transformed.expect
@@ -1,15 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -29,7 +17,7 @@
     : super core::Object::•()
     ;
 }
-abstract class _A&M1&M0 extends self::M1 implements self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 extends self::M1 implements self::M0<core::int, core::int> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.outline.expect
index 490e127f..f91df74 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.outline.expect
@@ -1,15 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -26,7 +14,7 @@
   synthetic constructor •() → self::M1
     ;
 }
-abstract class _A&M1&M0 = self::M1 with self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 = self::M1 with self::M0<core::int, core::int> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.hierarchy.expect
new file mode 100644
index 0000000..7daaa837
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.hierarchy.expect
@@ -0,0 +1,144 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<X>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces: I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1 with M0<int, Comparable<dynamic>>:
+  superclasses:
+    Object
+      -> M1
+  interfaces: I<int>, M0<int, Comparable<dynamic>>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> M1
+        -> _A&M1&M0
+  interfaces: I<int>, M0<int, Comparable<dynamic>>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.expect
index 751f33d..7c6712b 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.expect
@@ -1,27 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -41,7 +17,7 @@
     : super core::Object::•()
     ;
 }
-abstract class _A&M1&M0 = self::M1 with self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 = self::M1 with self::M0<core::int, core::Comparable<dynamic>> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.transformed.expect
index e98e8f6..47f9f64 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.legacy.transformed.expect
@@ -1,15 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -29,7 +17,7 @@
     : super core::Object::•()
     ;
 }
-abstract class _A&M1&M0 extends self::M1 implements self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 extends self::M1 implements self::M0<core::int, core::Comparable<dynamic>> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.outline.expect
index 9ec413d..5e19f97 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.outline.expect
@@ -1,15 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'M1 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart'.
-// class A extends M1 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -26,7 +14,7 @@
   synthetic constructor •() → self::M1
     ;
 }
-abstract class _A&M1&M0 = self::M1 with self::M0<dynamic, dynamic> {
+abstract class _A&M1&M0 = self::M1 with self::M0<core::int, core::Comparable<dynamic>> {
   synthetic constructor •() → self::_A&M1&M0
     : super self::M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.expect
index 7d0cb03..78b8e48 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: Type argument 'Comparable<dynamic>' doesn't conform to the bound 'Comparable<Y>' of the type variable 'Y' on 'M0' in the supertype 'M0' of class 'M1 with M0'.
 //  - 'Comparable' is from 'dart:core'.
@@ -8,16 +10,7 @@
 // pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:7:13: Context: This is the type variable whose bound isn't conformed to.
 // class M0<X, Y extends Comparable<Y>> extends I<X> {}
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: Type argument 'Comparable<dynamic>' doesn't conform to the bound 'Comparable<Y>' of the type variable 'Y' on 'M0' in the supertype 'M0' of class 'M1 with M0'.
-//  - 'Comparable' is from 'dart:core'.
-// Try changing type arguments so that they conform to the bounds.
-// class A extends M1 with M0 {}
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect
index fe9fd8d..cecd07c 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect
@@ -1,12 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:13:7: Error: Type argument 'Comparable<dynamic>' doesn't conform to the bound 'Comparable<Y>' of the type variable 'Y' on 'M0' in the supertype 'M0' of class 'M1 with M0'.
 //  - 'Comparable' is from 'dart:core'.
 // Try changing type arguments so that they conform to the bounds.
 // class A extends M1 with M0 {}
 //       ^
-
-library;
+// pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart:7:13: Context: This is the type variable whose bound isn't conformed to.
+// class M0<X, Y extends Comparable<Y>> extends I<X> {}
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.hierarchy.expect
new file mode 100644
index 0000000..eebc3a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.hierarchy.expect
@@ -0,0 +1,236 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+J:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I<X> with J<Y>:
+  superclasses:
+    Object
+      -> I<X>
+  interfaces: J<Y>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<X>
+        -> _M0&I&J<X, Y>
+  interfaces: J<Y>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces: I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M2:
+  superclasses:
+    Object
+      -> M1
+  interfaces: I<int>, J<double>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M2 with M0<int, double>:
+  superclasses:
+    Object
+      -> M1
+        -> M2
+  interfaces: I<int>, J<double>, M0<int, double>, _M0&I&J<int, double>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> M1
+        -> M2
+          -> _A&M2&M0
+  interfaces: I<int>, J<double>, M0<int, double>, _M0&I&J<int, double>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.expect
index 1066a51..9fe7a0a 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.expect
@@ -1,47 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -76,7 +32,7 @@
     : super self::M1::•()
     ;
 }
-abstract class _A&M2&M0 = self::M2 with self::M0<dynamic, dynamic> {
+abstract class _A&M2&M0 = self::M2 with self::M0<core::int, core::double> {
   synthetic constructor •() → self::_A&M2&M0
     : super self::M2::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.transformed.expect
index ed90883..435ce3b 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.legacy.transformed.expect
@@ -1,25 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -54,7 +32,7 @@
     : super self::M1::•()
     ;
 }
-abstract class _A&M2&M0 extends self::M2 implements self::M0<dynamic, dynamic> {
+abstract class _A&M2&M0 extends self::M2 implements self::M0<core::int, core::double> {
   synthetic constructor •() → self::_A&M2&M0
     : super self::M2::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.outline.expect
index d265daa..da0d2c6 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.outline.expect
@@ -1,25 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'M2 with M0' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart:16:7: Error: 'A' can't implement both 'J<double>' and 'J<dynamic>'
-//  - 'J' is from 'pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart'.
-// class A extends M2 with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -49,7 +27,7 @@
   synthetic constructor •() → self::M2
     ;
 }
-abstract class _A&M2&M0 = self::M2 with self::M0<dynamic, dynamic> {
+abstract class _A&M2&M0 = self::M2 with self::M0<core::int, core::double> {
   synthetic constructor •() → self::_A&M2&M0
     : super self::M2::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.hierarchy.expect
new file mode 100644
index 0000000..5e81312
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.hierarchy.expect
@@ -0,0 +1,156 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<List<T>>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+      -> I<List<T>>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M2:
+  superclasses:
+    Object
+      -> I<List<Map<T, T>>>
+        -> M1<Map<T, T>>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M2<int> with M0<Map<int, int>>:
+  superclasses:
+    Object
+      -> I<List<Map<int, int>>>
+        -> M1<Map<int, int>>
+          -> M2<int>
+  interfaces: M0<Map<int, int>>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> I<List<Map<int, int>>>
+        -> M1<Map<int, int>>
+          -> M2<int>
+            -> _A&M2&M0
+  interfaces: M0<Map<int, int>>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.expect
index 1886407..1030f6b 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.expect
@@ -1,35 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'M2 with M0' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'A' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'M2 with M0' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'A' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -54,7 +22,7 @@
     : super self::M1::•()
     ;
 }
-abstract class _A&M2&M0 = self::M2<core::int> with self::M0<dynamic> {
+abstract class _A&M2&M0 = self::M2<core::int> with self::M0<core::Map<core::int, core::int>> {
   synthetic constructor •() → self::_A&M2&M0
     : super self::M2::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.transformed.expect
index 41fb098..3eabc8f 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.legacy.transformed.expect
@@ -1,19 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'M2 with M0' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'A' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -38,7 +22,7 @@
     : super self::M1::•()
     ;
 }
-abstract class _A&M2&M0 extends self::M2<core::int> implements self::M0<dynamic> {
+abstract class _A&M2&M0 extends self::M2<core::int> implements self::M0<core::Map<core::int, core::int>> {
   synthetic constructor •() → self::_A&M2&M0
     : super self::M2::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.outline.expect
index 8a0d0f9..75b4f9d 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.outline.expect
@@ -1,19 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'M2 with M0' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart:14:7: Error: 'A' can't implement both 'I<List<Map<int, int>>>' and 'I<List<dynamic>>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart'.
-//  - 'List' is from 'dart:core'.
-//  - 'Map' is from 'dart:core'.
-// class A extends M2<int> with M0 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -34,7 +18,7 @@
   synthetic constructor •() → self::M2<self::M2::T>
     ;
 }
-abstract class _A&M2&M0 = self::M2<core::int> with self::M0<dynamic> {
+abstract class _A&M2&M0 = self::M2<core::int> with self::M0<core::Map<core::int, core::int>> {
   synthetic constructor •() → self::_A&M2&M0
     : super self::M2::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.hierarchy.expect
new file mode 100644
index 0000000..992d270
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.hierarchy.expect
@@ -0,0 +1,135 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0<int> with M1<int>:
+  superclasses:
+    Object
+      -> I<int>
+        -> M0<int>
+  interfaces: M1<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> I<int>
+        -> M0<int>
+          -> _A&M0&M1
+  interfaces: M1<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.expect
index bf40fc9..b336c68 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.expect
@@ -1,27 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -41,7 +17,7 @@
     : super self::I::•()
     ;
 }
-abstract class _A&M0&M1 = self::M0<core::int> with self::M1<dynamic> {
+abstract class _A&M0&M1 = self::M0<core::int> with self::M1<core::int> {
   synthetic constructor •() → self::_A&M0&M1
     : super self::M0::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.transformed.expect
index 7a1c8c2..75ebf9d 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.legacy.transformed.expect
@@ -1,15 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -29,7 +17,7 @@
     : super self::I::•()
     ;
 }
-abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<dynamic> {
+abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<core::int> {
   synthetic constructor •() → self::_A&M0&M1
     : super self::M0::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.outline.expect
index 3378125..641b87b 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.outline.expect
@@ -1,15 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart:12:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart'.
-// class A extends M0<int> with M1 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -26,7 +14,7 @@
   synthetic constructor •() → self::M1<self::M1::T>
     ;
 }
-abstract class _A&M0&M1 = self::M0<core::int> with self::M1<dynamic> {
+abstract class _A&M0&M1 = self::M0<core::int> with self::M1<core::int> {
   synthetic constructor •() → self::_A&M0&M1
     : super self::M0::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.hierarchy.expect
new file mode 100644
index 0000000..2113b02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.hierarchy.expect
@@ -0,0 +1,186 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M2:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0<int> with M1<int>:
+  superclasses:
+    Object
+      -> I<int>
+        -> M0<int>
+  interfaces: M1<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A&M0&M1 with M2<int>:
+  superclasses:
+    Object
+      -> I<int>
+        -> M0<int>
+          -> _A&M0&M1
+  interfaces: M1<int>, M2<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> I<int>
+        -> M0<int>
+          -> _A&M0&M1
+            -> _A&M0&M1&M2
+  interfaces: M1<int>, M2<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.expect
index 231fbf6d..d133391 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.expect
@@ -1,37 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1, M2' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1, M2' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -56,12 +22,12 @@
     : super self::I::•()
     ;
 }
-abstract class _A&M0&M1 = self::M0<core::int> with self::M1<dynamic> {
+abstract class _A&M0&M1 = self::M0<core::int> with self::M1<core::int> {
   synthetic constructor •() → self::_A&M0&M1
     : super self::M0::•()
     ;
 }
-abstract class _A&M0&M1&M2 = self::_A&M0&M1 with self::M2<dynamic> {
+abstract class _A&M0&M1&M2 = self::_A&M0&M1 with self::M2<core::int> {
   synthetic constructor •() → self::_A&M0&M1&M2
     : super self::_A&M0&M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.transformed.expect
index 6079249..d4edaee 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.legacy.transformed.expect
@@ -1,20 +1,3 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1, M2' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -39,12 +22,12 @@
     : super self::I::•()
     ;
 }
-abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<dynamic> {
+abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<core::int> {
   synthetic constructor •() → self::_A&M0&M1
     : super self::M0::•()
     ;
 }
-abstract class _A&M0&M1&M2 extends self::_A&M0&M1 implements self::M2<dynamic> {
+abstract class _A&M0&M1&M2 extends self::_A&M0&M1 implements self::M2<core::int> {
   synthetic constructor •() → self::_A&M0&M1&M2
     : super self::_A&M0&M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.outline.expect
index 491fd65..7456cbf 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.outline.expect
@@ -1,20 +1,3 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'M0 with M1, M2' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart:15:7: Error: 'A' can't implement both 'I<int>' and 'I<dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart'.
-// class A extends M0<int> with M1, M2 {}
-//       ^
-
 library;
 import self as self;
 import "dart:core" as core;
@@ -35,12 +18,12 @@
   synthetic constructor •() → self::M2<self::M2::T>
     ;
 }
-abstract class _A&M0&M1 = self::M0<core::int> with self::M1<dynamic> {
+abstract class _A&M0&M1 = self::M0<core::int> with self::M1<core::int> {
   synthetic constructor •() → self::_A&M0&M1
     : super self::M0::•()
     ;
 }
-abstract class _A&M0&M1&M2 = self::_A&M0&M1 with self::M2<dynamic> {
+abstract class _A&M0&M1&M2 = self::_A&M0&M1 with self::M2<core::int> {
   synthetic constructor •() → self::_A&M0&M1&M2
     : super self::_A&M0&M1::•()
     ;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.hierarchy.expect
new file mode 100644
index 0000000..45aa225
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.hierarchy.expect
@@ -0,0 +1,173 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+  interfaces: I<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with M0<dynamic>:
+  superclasses:
+    Object
+  interfaces: M0<dynamic>, I<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A&Object&M0 with M1<int>:
+  superclasses:
+    Object
+      -> _A&Object&M0
+  interfaces: M0<dynamic>, I<dynamic>, M1<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&M0
+        -> _A&Object&M0&M1
+  interfaces: M0<dynamic>, I<dynamic>, M1<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.expect
index 397be08..890adf5 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
@@ -9,19 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic>' and 'I<int>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.transformed.expect
index 2c73250..2b7b8f2 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.legacy.transformed.expect
@@ -1,4 +1,5 @@
-// Unhandled errors:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
@@ -9,7 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.outline.expect
index 51eab20..6452cea 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.outline.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
@@ -9,7 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.strong.expect
index 397be08..890adf5 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.strong.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
@@ -9,19 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic>' and 'I<int>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:69: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.hierarchy.expect
new file mode 100644
index 0000000..1d1e2f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.hierarchy.expect
@@ -0,0 +1,173 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+  interfaces: I<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1:
+  superclasses:
+    Object
+      -> I<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with M0<dynamic>:
+  superclasses:
+    Object
+  interfaces: M0<dynamic>, I<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A&Object&M0 with M1<dynamic>:
+  superclasses:
+    Object
+      -> _A&Object&M0
+  interfaces: M0<dynamic>, I<dynamic>, M1<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&M0
+        -> _A&Object&M0&M1
+  interfaces: M0<dynamic>, I<dynamic>, M1<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.expect
index 31db2ea..fb172cf 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.expect
@@ -1,17 +1,11 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart'.
 // class /*@error=AmbiguousSupertypes*/ A extends Object
 //                                      ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart'.
-// class /*@error=AmbiguousSupertypes*/ A extends Object
-//                                      ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.transformed.expect
index 6042159..17ece57 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart'.
 // class /*@error=AmbiguousSupertypes*/ A extends Object
 //                                      ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.outline.expect
index b9461de..bae1a11 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart'.
 // class /*@error=AmbiguousSupertypes*/ A extends Object
 //                                      ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.strong.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.strong.expect
index 31db2ea..fb172cf 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.strong.expect
@@ -1,17 +1,11 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart'.
 // class /*@error=AmbiguousSupertypes*/ A extends Object
 //                                      ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both 'I<dynamic>' and 'I<int>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart'.
-// class /*@error=AmbiguousSupertypes*/ A extends Object
-//                                      ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.hierarchy.expect
new file mode 100644
index 0000000..9e4e1b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.hierarchy.expect
@@ -0,0 +1,184 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+  interfaces: I<T, int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces: I<String, T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with M0<dynamic>:
+  superclasses:
+    Object
+  interfaces: M0<dynamic>, I<dynamic, int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A&Object&M0 with M1<dynamic>:
+  superclasses:
+    Object
+      -> _A&Object&M0
+  interfaces: M0<dynamic>, I<dynamic, int>, M1<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&M0
+        -> _A&Object&M0&M1
+  interfaces: M0<dynamic>, I<dynamic, int>, M1<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.expect
index 7583b60..a776b09 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
@@ -9,19 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'A' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.transformed.expect
index 30ac8b5..06aab2c 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.legacy.transformed.expect
@@ -1,4 +1,5 @@
-// Unhandled errors:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
@@ -9,7 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.outline.expect
index 365b0b9..ab6dd91 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.outline.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
@@ -9,7 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.strong.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.strong.expect
index 7583b60..a776b09 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.strong.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
@@ -9,19 +10,7 @@
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:69: Error: 'A' can't implement both 'I<dynamic, int>' and 'I<String, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_1.dart'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.hierarchy.expect
new file mode 100644
index 0000000..e8cc39f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.hierarchy.expect
@@ -0,0 +1,184 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M0:
+  superclasses:
+    Object
+  interfaces: I<T, List<T>>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces: I<List<T>, T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with M0<dynamic>:
+  superclasses:
+    Object
+  interfaces: M0<dynamic>, I<dynamic, List<dynamic>>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A&Object&M0 with M1<dynamic>:
+  superclasses:
+    Object
+      -> _A&Object&M0
+  interfaces: M0<dynamic>, I<dynamic, List<dynamic>>, M1<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&M0
+        -> _A&Object&M0&M1
+  interfaces: M0<dynamic>, I<dynamic, List<dynamic>>, M1<dynamic>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.expect
index 2da56f2..6e2e1ab7 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
@@ -11,21 +12,7 @@
 //  - 'List' is from 'dart:core'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
-//  - 'List' is from 'dart:core'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'A' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
-//  - 'List' is from 'dart:core'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.transformed.expect
index 04b8a12..da13f1a 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.legacy.transformed.expect
@@ -1,4 +1,5 @@
-// Unhandled errors:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
@@ -11,7 +12,7 @@
 //  - 'List' is from 'dart:core'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.outline.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.outline.expect
index 738f378..1e1142a 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.outline.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
@@ -11,7 +12,7 @@
 //  - 'List' is from 'dart:core'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
+//
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.strong.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.strong.expect
index 2da56f2..6e2e1ab7 100644
--- a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.strong.expect
@@ -1,4 +1,5 @@
-// Formatted problems:
+//
+// Problems in component:
 //
 // pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
 //  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
@@ -11,21 +12,7 @@
 //  - 'List' is from 'dart:core'.
 // class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
 //                                                                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'Object with M0, M1' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
-//  - 'List' is from 'dart:core'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:69: Error: 'A' can't implement both 'I<dynamic, List<dynamic>>' and 'I<List<dynamic>, dynamic>'
-//  - 'I' is from 'pkg/front_end/testcases/inference/mixin_inference_unification_2.dart'.
-//  - 'List' is from 'dart:core'.
-// class /*@error=AmbiguousSupertypes*/ /*@error=AmbiguousSupertypes*/ A
-//                                                                     ^
-
 library;
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.hierarchy.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.hierarchy.expect
new file mode 100644
index 0000000..052819e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.hierarchy.expect
@@ -0,0 +1,62 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.v4
+    Foo.v7
+    Object.toString
+    Foo.v3
+    Object.runtimeType
+    Foo.v6
+    Object._simpleInstanceOf
+    Foo.v9
+    Foo.v2
+    Object._instanceOf
+    Foo.v5
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Foo.v1
+    Object._simpleInstanceOfFalse
+    Foo.v8
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..7f29764
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.hierarchy.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.hierarchy.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.hierarchy.expect
new file mode 100644
index 0000000..7f29764
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.hierarchy.expect b/pkg/front_end/testcases/inference/override_equals.dart.hierarchy.expect
new file mode 100644
index 0000000..187143e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+NullEquality:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    NullEquality.==
+  classSetters:
+
+SubNullEquality:
+  superclasses:
+    Object
+      -> NullEquality
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    NullEquality.==
+    SubNullEquality.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.hierarchy.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.hierarchy.expect
new file mode 100644
index 0000000..f6e8245
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    C.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.hierarchy.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.hierarchy.expect
new file mode 100644
index 0000000..804e9c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.hierarchy.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.hierarchy.expect
new file mode 100644
index 0000000..804e9c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.hierarchy.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.hierarchy.expect
new file mode 100644
index 0000000..804e9c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
index d448f5a7..58c7f14 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -9,8 +11,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
 //                                                         ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
index 275dfa6..58c7f14 100644
--- a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
@@ -1,4 +1,17 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                                         ^
+//
+// pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ "hi";
+//                                                         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.hierarchy.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.hierarchy.expect
new file mode 100644
index 0000000..fb5ffdc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.hierarchy.expect
@@ -0,0 +1,95 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.a
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.b
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    D.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.c
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.hierarchy.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.hierarchy.expect
new file mode 100644
index 0000000..38a3d58
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.getter
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.function
+    C.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.field
diff --git a/pkg/front_end/testcases/inference/property_set.dart.hierarchy.expect b/pkg/front_end/testcases/inference/property_set.dart.hierarchy.expect
new file mode 100644
index 0000000..8c4141b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..ff03b6a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.expect
index 8eced30..a0997b0 100644
--- a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/property_set_bad_setter.dart:9:13: Error: A setter should have exactly one formal parameter.
 //   void set x() {}
 //             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.transformed.expect
index 55e2dc6..a0997b0 100644
--- a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/property_set_bad_setter.dart:9:13: Error: A setter should have exactly one formal parameter.
+//   void set x() {}
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.expect
index b0a4fa1..3d09e75 100644
--- a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/property_set_bad_setter.dart:9:13: Error: A setter should have exactly one formal parameter.
 //   void set x() {}
 //             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect
index 710fdf3..3d09e75 100644
--- a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/property_set_bad_setter.dart:9:13: Error: A setter should have exactly one formal parameter.
+//   void set x() {}
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.hierarchy.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.hierarchy.expect
new file mode 100644
index 0000000..c87ed81
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.op
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.a
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.hierarchy.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.hierarchy.expect
new file mode 100644
index 0000000..6a7837d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.op
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.opEq
+  classSetters:
+    C.a
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.hierarchy.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.hierarchy.expect
new file mode 100644
index 0000000..6a7837d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.op
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.opEq
+  classSetters:
+    C.a
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.hierarchy.expect
new file mode 100644
index 0000000..dce0b22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.x
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.hierarchy.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.hierarchy.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.hierarchy.expect
new file mode 100644
index 0000000..7f29764
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_index_set.dart.hierarchy.expect
new file mode 100644
index 0000000..48600ff
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    C.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.legacy.expect b/pkg/front_end/testcases/inference/super_index_set.dart.legacy.expect
index 4ce9e5d..8ecdb24 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_index_set.dart.legacy.transformed.expect
index 4ce9e5d..8ecdb24 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.outline.expect b/pkg/front_end/testcases/inference/super_index_set.dart.outline.expect
index 77116ab..2def119 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     ;
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect b/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect
index 81b2549f..1728494 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.strong.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
index 81b2549f..1728494 100644
--- a/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..0b3c5c1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<Future<U>>
+  interfaces:
+  classMembers:
+    C.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
index 778ae64..5bbe4de 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class B<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::B<self::B::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
index 778ae64..5bbe4de 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class B<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::B<self::B::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
index d6e96c8..a7cf483 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class B<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::B<self::B::T>
     ;
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect
index 2cbc33d..bc2d428 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class B<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::B<self::B::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
index 2cbc33d..bc2d428 100644
--- a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class B<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::B<self::B::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..adce63a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..7d7e374
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<List<U>>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.hierarchy.expect
new file mode 100644
index 0000000..8d4308a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..3f44585
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.hierarchy.expect
@@ -0,0 +1,92 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<Future<U>>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
index 8e95ed1..b0a8223 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
index 8e95ed1..b0a8223 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
index 42544c1..27eacb9 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     ;
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.expect
index 3c47c55..494df6b 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect
index 3c47c55..494df6b 100644
--- a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_property_get.dart.hierarchy.expect
new file mode 100644
index 0000000..cb03014
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.hierarchy.expect
@@ -0,0 +1,59 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.hierarchy.expect
new file mode 100644
index 0000000..c9f8b8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.hierarchy.expect
@@ -0,0 +1,59 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.hierarchy.expect
new file mode 100644
index 0000000..2fcbd94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.hierarchy.expect
@@ -0,0 +1,77 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+CallableClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    CallableClass.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..dc64786
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.hierarchy.expect
@@ -0,0 +1,94 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+      -> B<Future<U>>
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
index 120a5be..23680d0 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
index 120a5be..23680d0 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
index 5166d46..bc7d92d 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     ;
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.expect
index da8f484..a65e554 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect
index da8f484..a65e554 100644
--- a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.hierarchy.expect
new file mode 100644
index 0000000..8d4308a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    D.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..dc64786
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.hierarchy.expect
@@ -0,0 +1,94 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+      -> B<Future<U>>
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
index 82217ec..696b98f 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
index 82217ec..696b98f 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
index f157db0..886a4fd 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     ;
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.expect
index 67484aa..bd20e55 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect
index 67484aa..bd20e55 100644
--- a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.hierarchy.expect b/pkg/front_end/testcases/inference/this_reference.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.expect
index 7a615f9..c9d9f66 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method a() → (core::int) → core::int {
   return (dynamic x) → dynamic => x;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.transformed.expect
index 5058c0e..ecceca5 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method a() → (core::int) → core::int {
   return (dynamic x) → dynamic => x;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.outline.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.outline.expect
index 5a11fa5..a5e2303 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method a() → (core::int) → core::int
   ;
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 4fced41..f39cc43 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
@@ -1,16 +1,19 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:34: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
 //  - 'FutureOr' is from 'dart:async'.
 // Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
 //   return /*@returnType=dynamic*/ (/*@type=dynamic*/ x) => x;
 //                                  ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method a() → (core::int) → core::int {
   return (core::int x) → core::int => x;
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 ae67a0b..b6ef4f9 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
@@ -1,8 +1,19 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:34: Error: A value of type 'dynamic Function(dynamic)' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
+//  - 'FutureOr' is from 'dart:async'.
+// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<int Function(int)>'.
+//   return /*@returnType=dynamic*/ (/*@type=dynamic*/ x) => x;
+//                                  ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 typedef IntToInt = (core::int) → core::int;
 static method a() → (core::int) → core::int {
   return (core::int x) → core::int => x;
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.hierarchy.expect b/pkg/front_end/testcases/inference/try_catch.dart.hierarchy.expect
new file mode 100644
index 0000000..525f424
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.hierarchy.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.hierarchy.expect
new file mode 100644
index 0000000..525f424
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
new file mode 100644
index 0000000..148400f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.hierarchy.expect
@@ -0,0 +1,90 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+StackTrace:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    StackTrace.current
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> StackTrace
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.hierarchy.expect b/pkg/front_end/testcases/inference/type_cast.dart.hierarchy.expect
new file mode 100644
index 0000000..dfd3e72
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.hierarchy.expect
new file mode 100644
index 0000000..b628c46
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.expect
index fafdf1d..e054d56 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/unresolved_super.dart:12:38: Warning: Superclass has no method named 'foo'.
 //     var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
@@ -19,8 +21,7 @@
 // pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Warning: Superclass has no method named '[]='.
 //     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
 //                                     ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.transformed.expect
index 50d794f..e054d56 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.legacy.transformed.expect
@@ -1,4 +1,27 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:12:38: Warning: Superclass has no method named 'foo'.
+//     var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
+//                                      ^^^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:13:38: Warning: Superclass has no getter named 'bar'.
+//     var /*@type=dynamic*/ v2 = super.bar;
+//                                      ^^^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:14:37: Warning: Superclass has no method named '[]'.
+//     var /*@type=dynamic*/ v3 = super[0];
+//                                     ^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:15:38: Warning: Superclass has no setter named 'bar'.
+//     var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();
+//                                      ^^^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Warning: Superclass has no method named '[]='.
+//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
+//                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
index d8ed4e6..eeae7d5 100644
--- a/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.strong.expect
@@ -1,48 +1,27 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:12:38: Error: Superclass has no method named 'foo'.
-//     var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
-//                                      ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:13:38: Error: Superclass has no getter named 'bar'.
-//     var /*@type=dynamic*/ v2 = super.bar;
-//                                      ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:14:37: Error: Superclass has no method named '[]'.
-//     var /*@type=dynamic*/ v3 = super[0];
-//                                     ^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:15:38: Error: Superclass has no setter named 'bar'.
-//     var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();
-//                                      ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:12:38: Error: Superclass has no method named 'foo'.
-//     var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
-//                                      ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:13:38: Error: Superclass has no getter named 'bar'.
-//     var /*@type=dynamic*/ v2 = super.bar;
-//                                      ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:14:37: Error: Superclass has no method named '[]'.
-//     var /*@type=dynamic*/ v3 = super[0];
-//                                     ^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:15:38: Error: Superclass has no setter named 'bar'.
-//     var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();
-//                                      ^^^
-//
-// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
-//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
-//                                     ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:12:38: Error: Superclass has no method named 'foo'.
+//     var /*@type=dynamic*/ v1 = super.foo(/*@typeArgs=dynamic*/ f());
+//                                      ^^^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:13:38: Error: Superclass has no getter named 'bar'.
+//     var /*@type=dynamic*/ v2 = super.bar;
+//                                      ^^^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:14:37: Error: Superclass has no method named '[]'.
+//     var /*@type=dynamic*/ v3 = super[0];
+//                                     ^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:15:38: Error: Superclass has no setter named 'bar'.
+//     var /*@type=dynamic*/ v4 = super.bar = /*@typeArgs=dynamic*/ f();
+//                                      ^^^
+//
+// pkg/front_end/testcases/inference/unresolved_super.dart:16:37: Error: Superclass has no method named '[]='.
+//     var /*@type=dynamic*/ v5 = super[0] = /*@typeArgs=dynamic*/ f();
+//                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.expect
index f304027..361c9d3 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.expect
@@ -1,26 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:39: Error: An equality expression can't be an operand of another equality expression.
-// Try re-writing the expression.
-// var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
-//                                       ^
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:40: Error: Expected an identifier, but got ')'.
-// var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
-//                                        ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:39: Error: An equality expression can't be an operand of another equality expression.
-// Try re-writing the expression.
-// var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
-//                                       ^
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:40: Error: Expected an identifier, but got ')'.
-// var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
-//                                        ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:39: Error: An equality expression can't be an operand of another equality expression.
+// Try re-writing the expression.
+// var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
+//                                       ^
+//
+// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:40: Error: Expected an identifier, but got ')'.
+// var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
+//                                        ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.transformed.expect
index 3b1f5af..361c9d3 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:39: Error: An equality expression can't be an operand of another equality expression.
 // Try re-writing the expression.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:40: Error: Expected an identifier, but got ')'.
 // var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
 //                                        ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect
index c2f5ee2..58e5d4b 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:39: Error: An equality expression can't be an operand of another equality expression.
 // Try re-writing the expression.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1.dart:9:40: Error: Expected an identifier, but got ')'.
 // var /*@topType=dynamic*/v = (f<dynamic>)(() { return 1; });
 //                                        ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.expect
index 4565b79..4492f7c 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.expect
@@ -1,26 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:35: Error: An equality expression can't be an operand of another equality expression.
-// Try re-writing the expression.
-// var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
-//                                   ^
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:36: Error: Expected an identifier, but got ')'.
-// var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
-//                                    ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:35: Error: An equality expression can't be an operand of another equality expression.
-// Try re-writing the expression.
-// var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
-//                                   ^
-//
-// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:36: Error: Expected an identifier, but got ')'.
-// var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
-//                                    ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:35: Error: An equality expression can't be an operand of another equality expression.
+// Try re-writing the expression.
+// var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
+//                                   ^
+//
+// pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:36: Error: Expected an identifier, but got ')'.
+// var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
+//                                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.transformed.expect
index ddd2acd..4492f7c 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:35: Error: An equality expression can't be an operand of another equality expression.
 // Try re-writing the expression.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:36: Error: Expected an identifier, but got ')'.
 // var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
 //                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect
index e272c4b..6f5ce50 100644
--- a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:35: Error: An equality expression can't be an operand of another equality expression.
 // Try re-writing the expression.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr1.dart:9:36: Error: Expected an identifier, but got ')'.
 // var /*@topType=dynamic*/v = (f<int>)(() { return 1; });
 //                                    ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.hierarchy.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.hierarchy.expect
new file mode 100644
index 0000000..052819e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.hierarchy.expect
@@ -0,0 +1,62 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.v4
+    Foo.v7
+    Object.toString
+    Foo.v3
+    Object.runtimeType
+    Foo.v6
+    Object._simpleInstanceOf
+    Foo.v9
+    Foo.v2
+    Object._instanceOf
+    Foo.v5
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Foo.v1
+    Object._simpleInstanceOfFalse
+    Foo.v8
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.hierarchy.expect
new file mode 100644
index 0000000..295e36b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
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 819f137..637a638 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:67: Error: Can't infer the type of 'c': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ c = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:67: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:67: Error: Can't infer the type of 'c': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ c = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:67: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:67: Error: Can't infer the type of 'c': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ c = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:67: Error: Can't infer the type of 'b': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
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 475f95f..637a638 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:67: Error: Can't infer the type of 'c': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 // var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
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 5820a4e..d2d6d0d 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:17:67: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = a();
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:67: Error: Can't infer the type of 'a': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ a = /*@returnType=num*/ () =>
-//                                                                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:17:67: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = a();
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:67: Error: Can't infer the type of 'a': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ a = /*@returnType=num*/ () =>
-//                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:17:67: Error: Can't infer the type of 'b': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = a();
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:67: Error: Can't infer the type of 'a': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ a = /*@returnType=num*/ () =>
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
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 085c83e..d2d6d0d 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:17:67: Error: Can't infer the type of 'b': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 // var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ a = /*@returnType=num*/ () =>
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.hierarchy.expect
new file mode 100644
index 0000000..69ec6ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.b
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.hierarchy.expect
new file mode 100644
index 0000000..451a9dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.hierarchy.expect
@@ -0,0 +1,62 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.y
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.y
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    B.x
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 ec6e74e..0d47f0c 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:69: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:19:69: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x;
-//                                                                     ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:69: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:19:69: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x;
-//                                                                     ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:69: Error: Can't infer the type of 'x': circularity found during type inference.
+// Specify the type explicitly.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference_new/field_inference_circularity.dart:19:69: Error: Can't infer the type of 'x': circularity found during type inference.
+// Specify the type explicitly.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x;
+//                                                                     ^
+//
 import self as self;
 import "dart:core" as core;
 
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 2635fe5..0d47f0c 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:69: Error: Can't infer the type of 'x': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 //   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x;
 //                                                                     ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.hierarchy.expect
new file mode 100644
index 0000000..4faaf13
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.aField
+    C.test
+  classSetters:
+    C.aSetter
+    C.aField
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.expect
index 139d9e9..a921371 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:53: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
@@ -19,8 +21,7 @@
 //  - 'Stream' is from 'dart:async'.
 //   await for (y in /*@error=ForInLoopTypeNotIterable*/ s) {}
 //                                                       ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
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 062ec9e..e1b9af6 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
@@ -1,4 +1,27 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:53: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+//  - 'Iterable' is from 'dart:core'.
+//   for (int x in /*@error=ForInLoopTypeNotIterable*/ s) {}
+//                                                     ^
+//
+// pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:11:59: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+//  - 'Stream' is from 'dart:async'.
+//   await for (int x in /*@error=ForInLoopTypeNotIterable*/ s) {}
+//                                                           ^
+//
+// pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:13:49: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+//  - 'Iterable' is from 'dart:core'.
+//   for (y in /*@error=ForInLoopTypeNotIterable*/ s) {}
+//                                                 ^
+//
+// pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:14:55: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+//  - 'Stream' is from 'dart:async'.
+//   await for (y in /*@error=ForInLoopTypeNotIterable*/ s) {}
+//                                                       ^
+//
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.hierarchy.expect
new file mode 100644
index 0000000..fe2fcf5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.expect
index 8a33d3b..5ee26f2 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.transformed.expect
index a974308..5f786d8 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.outline.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.outline.expect
index 07214ac..6a8d7ac 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.expect
index 2662ee0..eed185f 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:26:55: Error: A value of type 'A' can't be assigned to a variable of type 'int'.
 //  - 'A' is from 'pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart'.
@@ -11,12 +13,13 @@
 // Try changing the type of the variable.
 //   await for (i /*@error=ForInLoopElementTypeNotAssignable*/ in stream) {}
 //                                                             ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
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 b77def2..d924c02 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
@@ -1,8 +1,25 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:26:55: Error: A value of type 'A' can't be assigned to a variable of type 'int'.
+//  - 'A' is from 'pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart'.
+// Try changing the type of the variable.
+//   for (i /*@error=ForInLoopElementTypeNotAssignable*/ in iterable) {}
+//                                                       ^
+//
+// pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:27:61: Error: A value of type 'A' can't be assigned to a variable of type 'int'.
+//  - 'A' is from 'pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart'.
+// Try changing the type of the variable.
+//   await for (i /*@error=ForInLoopElementTypeNotAssignable*/ in stream) {}
+//                                                             ^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.hierarchy.expect
new file mode 100644
index 0000000..ca39dc1fc
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.hierarchy.expect
@@ -0,0 +1,147 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    A.*
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    G.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    G.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.hierarchy.expect
new file mode 100644
index 0000000..315581c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Test.member
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..03e1145
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.hierarchy.expect
@@ -0,0 +1,79 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Test1.t
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Test2.t
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Test3.test3
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Test3.t
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.hierarchy.expect
new file mode 100644
index 0000000..6e9f0e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.hierarchy.expect
@@ -0,0 +1,118 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.hierarchy.expect
new file mode 100644
index 0000000..4292b72
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.hierarchy.expect
@@ -0,0 +1,185 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> A
+        -> B
+          -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> A
+        -> B
+          -> C
+            -> D
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+      -> A
+        -> B
+          -> C
+            -> D
+              -> E
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.hierarchy.expect
new file mode 100644
index 0000000..0d88d4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.hierarchy.expect
@@ -0,0 +1,138 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..39baee4
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.hierarchy.expect
@@ -0,0 +1,247 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+      -> Base<int, int>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+
+Test2:
+  superclasses:
+    Object
+      -> Base<int, num>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+
+Test3:
+  superclasses:
+    Object
+      -> Base<int, double>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test3.test
+  classSetters:
+
+Test4:
+  superclasses:
+    Object
+      -> Base<num, int>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test4.test
+  classSetters:
+
+Test5:
+  superclasses:
+    Object
+      -> Base<num, num>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test5.test
+  classSetters:
+
+Test6:
+  superclasses:
+    Object
+      -> Base<num, double>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test6.test
+  classSetters:
+
+Test7:
+  superclasses:
+    Object
+      -> Base<double, int>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test7.test
+  classSetters:
+
+Test8:
+  superclasses:
+    Object
+      -> Base<double, num>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test8.test
+  classSetters:
+
+Test9:
+  superclasses:
+    Object
+      -> Base<double, double>
+  interfaces:
+  classMembers:
+    Base.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.setValue
+    Base.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test9.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
index d69052b..58dc48e 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart:55:62: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
 // Try changing the type of the left hand side, or casting the right hand side to 'double'.
@@ -34,8 +36,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     var /*@type=double*/ v11 = super /*@target=Base::[]=*/ ['x']++;
 //                                                                 ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.hierarchy.expect
new file mode 100644
index 0000000..6e9f0e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.hierarchy.expect
@@ -0,0 +1,118 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Index:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..8bd8660
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.hierarchy.expect
@@ -0,0 +1,199 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test1.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test2.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test3.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test3.test
+  classSetters:
+
+Test4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test4.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test4.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test4.test
+  classSetters:
+
+Test5:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test5.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test5.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test5.test
+  classSetters:
+
+Test6:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test6.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test6.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test6.test
+  classSetters:
+
+Test7:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test7.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test7.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test7.test
+  classSetters:
+
+Test8:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test8.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test8.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test8.test
+  classSetters:
+
+Test9:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test9.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test9.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test9.test
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
index 53307d7..135f152 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart:56:62: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
 // Try changing the type of the left hand side, or casting the right hand side to 'double'.
@@ -34,8 +36,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //     var /*@type=double*/ v11 = this /*@target=Test7::[]=*/ ['x']++;
 //                                                                 ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..38b0b8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Test.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
index eb0925f..784bbce 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart:47:56: Error: A value of type 'int' can't be assigned to a variable of type 'double'.
 // Try changing the type of the left hand side, or casting the right hand side to 'double'.
@@ -34,8 +36,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var /*@type=double*/ v11 = t /*@target=Test::[]=*/ ['x']++;
 //                                                           ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.hierarchy.expect
new file mode 100644
index 0000000..103f020
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.hierarchy.expect
@@ -0,0 +1,81 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.hierarchy.expect
new file mode 100644
index 0000000..5ab98e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.f
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.hierarchy.expect
new file mode 100644
index 0000000..220819f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.a
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
index 5b13bca..0299145 100644
--- a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:37: Error: A value of type 'int' can't be assigned to a variable of type 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart'.
@@ -23,8 +25,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'A'.
 // var /*@topType=A*/ v_postfix_mm = (new B(). /*@target=B::a*/ a--);
 //                                                               ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.hierarchy.expect
new file mode 100644
index 0000000..315581c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Test.member
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.hierarchy.expect
new file mode 100644
index 0000000..315581c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Test.member
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..d489c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.hierarchy.expect
@@ -0,0 +1,79 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Test1.prop
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Test2.prop
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Test3.test3
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Test3.prop
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.hierarchy.expect
new file mode 100644
index 0000000..7cf7949
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.hierarchy.expect
@@ -0,0 +1,121 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.member
+
+Test:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.member
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test.test
+  classSetters:
+    Base.member
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..2c693c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.hierarchy.expect
@@ -0,0 +1,117 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
+
+Test1:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
+
+Test2:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
+
+Test3:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Base.intProp
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.numProp
+    Test3.test3
+    Base.doubleProp
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.intProp
+    Base.numProp
+    Base.doubleProp
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.hierarchy.expect
new file mode 100644
index 0000000..d489c28
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.hierarchy.expect
@@ -0,0 +1,79 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test1.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test1.test
+  classSetters:
+    Test1.prop
+
+Test2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test2.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Test2.test
+  classSetters:
+    Test2.prop
+
+Test3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Test3.prop
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Test3.test3
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Test3.prop
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.hierarchy.expect
new file mode 100644
index 0000000..5ab98e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.f
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.hierarchy.expect
new file mode 100644
index 0000000..9240a15
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.staticVariable
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+    B.staticVariable
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.&
+    B.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
new file mode 100644
index 0000000..7848afa
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
index cd1113c..fe82b93 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:24: Error: The return type of the method 'B.x' is 'int', which does not match the return type of the overridden method, 'double'.
 // Change to a subtype of 'double'.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:10:12: Context: This is the overridden method ('x').
 //   void set x(double value);
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart:16:24: Error: The return type of the method 'B.x' is 'int', which does not match the return type of the overridden method, 'double'.
-// Change to a subtype of 'double'.
-//   var /*@topType=int*/ x;
-//                        ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..167e1f9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.hierarchy.expect
@@ -0,0 +1,78 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
index 0dbade9..57b6ceb 100644
--- a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:24: Error: The return type of the method 'C.x' is 'int', which does not match the return type of the overridden method, 'num'.
 // Change to a subtype of 'num'.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:9:12: Context: This is the overridden method ('x').
 //   void set x(num value);
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart:19:24: Error: The return type of the method 'C.x' is 'int', which does not match the return type of the overridden method, 'num'.
-// Change to a subtype of 'num'.
-//   var /*@topType=int*/ x;
-//                        ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..3dbfb21
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.hierarchy.expect
@@ -0,0 +1,78 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.hierarchy.expect
new file mode 100644
index 0000000..17adc4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.hierarchy.expect
@@ -0,0 +1,92 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.b
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.c
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.hierarchy.expect
new file mode 100644
index 0000000..17adc4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.hierarchy.expect
@@ -0,0 +1,92 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.b
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.c
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.hierarchy.expect
new file mode 100644
index 0000000..f609d2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.b
+    A.c
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 cb12150..c125a14 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:69: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:69: Error: Can't infer the type of 'b': circularity found during type inference.
-// Specify the type explicitly.
-//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
-//                                                                     ^
-//
-// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:69: Error: Can't infer the type of 'b': circularity found during type inference.
+// Specify the type explicitly.
+//   var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
+//                                                                     ^
+//
+// pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
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 68e3c75..c125a14 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:69: Error: Can't infer the type of 'b': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 // var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.hierarchy.expect
new file mode 100644
index 0000000..3bf59e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect
index ecb2ddf..28a9284 100644
--- a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart:9:62: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 // var /*@topType=String*/ x = i = /*@error=InvalidAssignment*/ s;
 //                                                              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
new file mode 100644
index 0000000..4e3fcb5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.hierarchy.expect
@@ -0,0 +1,179 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I1.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I2.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I1, I2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    I1.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: I1, I2
+  classMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces: I2, I1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    I2.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+F:
+  superclasses:
+    Object
+      -> E
+  interfaces: I2, I1
+  classMembers:
+    F.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    F.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.hierarchy.expect
new file mode 100644
index 0000000..b8aaea1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.hierarchy.expect
@@ -0,0 +1,147 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    A.*
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    G.target
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    G.target
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.hierarchy.expect
new file mode 100644
index 0000000..38a3d58
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.getter
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.function
+    C.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.field
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.hierarchy.expect
new file mode 100644
index 0000000..ddb6412
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.hierarchy.expect
@@ -0,0 +1,128 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    A.*
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.*
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.expect
index e40ce71..6f86a2f 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
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-//
-// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
-// Specify the type explicitly.
-// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
-//                                                                   ^
-
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
+// pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
+// Specify the type explicitly.
+// var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+//                                                                   ^
+//
 import self as self;
 import "dart:core" as core;
 
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 322965f..6f86a2f 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
 // Specify the type explicitly.
@@ -9,8 +11,7 @@
 // Specify the type explicitly.
 // var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
 //                                                                   ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.hierarchy.expect
new file mode 100644
index 0000000..adf6a6f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    C.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.expect
index 5fd35e9..102ef4c 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.transformed.expect
index 5fd35e9..102ef4c 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.outline.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.outline.expect
index 1f9dc25..516bba1 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     ;
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.expect
index ac5ee20..8f00549 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect
index ac5ee20..8f00549 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..1c8f791
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.hierarchy.expect
@@ -0,0 +1,92 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> D<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<Future<U>>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    C.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
index b86486e..b5345da 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
index b86486e..b5345da 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
index 4e092ba..44d6487 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     ;
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.expect
index 641bd99..48903a6 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect
index 641bd99..48903a6 100644
--- a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class D<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/switch.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
new file mode 100644
index 0000000..a0eaeca
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.hierarchy.expect
@@ -0,0 +1,189 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    E.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    F.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces: D, E, F
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+H:
+  superclasses:
+    Object
+      -> G
+  interfaces: D, E, F
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    H.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    H.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.hierarchy.expect
new file mode 100644
index 0000000..8f839c1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.hierarchy.expect
new file mode 100644
index 0000000..8130575
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.expect
index 0587f95..7e320fc 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.transformed.expect
index 0587f95..7e320fc 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.outline.expect
index 6d52cfc..ec44385 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.expect
index 4da975b..3ca1d7b 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect
index 4da975b..3ca1d7b 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.hierarchy.expect
new file mode 100644
index 0000000..94d8ef3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.hierarchy.expect
new file mode 100644
index 0000000..b51e6a0
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.fun
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.hierarchy.expect
new file mode 100644
index 0000000..94d8ef3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..4096970
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.fun
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.expect
index 5047782..3119f18 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.transformed.expect
index 5047782..3119f18 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.outline.expect
index 4649dbc..d328d90 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.expect
index 5047782..3119f18 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect
index 5047782..3119f18 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.hierarchy.expect
new file mode 100644
index 0000000..94d8ef3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.hierarchy.expect
new file mode 100644
index 0000000..0ed6368
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.hierarchy.expect
new file mode 100644
index 0000000..19920ef
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.fun
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.hierarchy.expect
new file mode 100644
index 0000000..0ed6368
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..3805794
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.hierarchy.expect
new file mode 100644
index 0000000..3805794
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.hierarchy.expect
new file mode 100644
index 0000000..29eb6df
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..29eb6df
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.hierarchy.expect
new file mode 100644
index 0000000..25856d1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..25856d1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.hierarchy.expect
new file mode 100644
index 0000000..08d4da1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..08d4da1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.hierarchy.expect
new file mode 100644
index 0000000..f8844e4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..f8844e4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.expect
index a3c9999..3f67f69 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.expect
@@ -2,5 +2,7 @@
 import self as self;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 static field col::LinkedListEntry<dynamic> y;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.transformed.expect
index a3c9999..3f67f69 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.legacy.transformed.expect
@@ -2,5 +2,7 @@
 import self as self;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 static field col::LinkedListEntry<dynamic> y;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.outline.expect
index de12238..def491a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 static field col::LinkedListEntry<dynamic> y;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.expect
index 2a54655..dd129de 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.expect
@@ -2,5 +2,7 @@
 import self as self;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 static field col::LinkedListEntry<col::LinkedListEntry<dynamic>> y;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect
index 2a54655..dd129de 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect
@@ -2,5 +2,7 @@
 import self as self;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 static field col::LinkedListEntry<col::LinkedListEntry<dynamic>> y;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.hierarchy.expect
new file mode 100644
index 0000000..38e2563
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.hierarchy.expect
new file mode 100644
index 0000000..9bc4745
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect
index e284a0c..09bfacb 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:11:13: Error: Inferred type argument 'Comparable<dynamic>' doesn't conform to the bound 'Comparable<T>' of the type variable 'T' on 'B'.
 //  - 'Comparable' is from 'dart:core'.
@@ -8,16 +10,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:9:9: Context: This is the type variable whose bound isn't conformed to.
 // class B<T extends Comparable<T>> {}
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:11:13: Error: Inferred type argument 'Comparable<dynamic>' doesn't conform to the bound 'Comparable<T>' of the type variable 'T' on 'B'.
-//  - 'Comparable' is from 'dart:core'.
-// Try specifying type arguments explicitly so that they conform to the bounds.
-// var y = new B();
-//             ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
index 59eda90..09bfacb 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
@@ -1,12 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:11:13: Error: Inferred type argument 'Comparable<dynamic>' doesn't conform to the bound 'Comparable<T>' of the type variable 'T' on 'B'.
 //  - 'Comparable' is from 'dart:core'.
 // Try specifying type arguments explicitly so that they conform to the bounds.
 // var y = new B();
 //             ^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:9:9: Context: This is the type variable whose bound isn't conformed to.
+// class B<T extends Comparable<T>> {}
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.hierarchy.expect
new file mode 100644
index 0000000..792b563
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.hierarchy.expect
new file mode 100644
index 0000000..792b563
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.hierarchy.expect
new file mode 100644
index 0000000..3dc67d6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.hierarchy.expect
@@ -0,0 +1,189 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+H:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+J:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.expect
index 8b55dbe..54c9d27 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.expect
@@ -1,48 +1,27 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//         ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//                      ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                            ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                                         ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//         ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//                      ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                            ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                                         ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+//         ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+//                      ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//     X extends Function(V), Y extends Z, Z extends T> {}
+//                            ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//     X extends Function(V), Y extends Z, Z extends T> {}
+//                                         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.transformed.expect
index 7af2967..54c9d27 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
 // Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
@@ -19,8 +21,7 @@
 // Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
 //     X extends Function(V), Y extends Z, Z extends T> {}
 //                                         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.outline.expect
index 3a0c08a..717342c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
 // Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
@@ -19,8 +21,7 @@
 // Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
 //     X extends Function(V), Y extends Z, Z extends T> {}
 //                                         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.expect
index 27c679f..a41b0e8 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.expect
@@ -1,48 +1,27 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//         ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//                      ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                            ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                                         ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//         ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
-//                      ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                            ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
-// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
-//     X extends Function(V), Y extends Z, Z extends T> {}
-//                                         ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+//         ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
+//                      ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//     X extends Function(V), Y extends Z, Z extends T> {}
+//                            ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
+// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
+//     X extends Function(V), Y extends Z, Z extends T> {}
+//                                         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect
index 9d8065d..a41b0e8 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:9: Error: Type 'T' is a bound of itself via 'U', 'Y', 'Z'.
 // Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
@@ -19,8 +21,7 @@
 // Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
 //     X extends Function(V), Y extends Z, Z extends T> {}
 //                                         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.hierarchy.expect
new file mode 100644
index 0000000..dff169d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.hierarchy.expect
@@ -0,0 +1,189 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..dff169d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.hierarchy.expect
@@ -0,0 +1,189 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D4:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.hierarchy.expect
new file mode 100644
index 0000000..8fea0c9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.expect
index e89a46a..8d64011 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart:12:9: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'A' here.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart:10:16: Context: Bound of this variable references variable 'TypeT' from the same declaration.
 // class A<TypeT, TypeS extends TypeT> {}
 //                ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart:12:9: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'A' here.
-// class B<TypeU extends A> {}
-//         ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.transformed.expect
index c3579fe..8d64011 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart.strong.transformed.expect
@@ -1,11 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart:12:9: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'A' here.
 // class B<TypeU extends A> {}
 //         ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_non_simple.dart:10:16: Context: Bound of this variable references variable 'TypeT' from the same declaration.
+// class A<TypeT, TypeS extends TypeT> {}
+//                ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.expect
index 9118cd2..4e815e9 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart:11:9: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'A' here.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart:9:16: Context: Bound of this variable references variable 'TypeT' from the same declaration.
 // class A<TypeT, TypeS extends TypeT> {}
 //                ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart:11:9: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'A' here.
-// class B<TypeU extends A> {}
-//         ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.transformed.expect
index d926c68..4e815e9 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart.strong.transformed.expect
@@ -1,11 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart:11:9: Error: Generic type 'A' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'A' here.
 // class B<TypeU extends A> {}
 //         ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_bound_due_to_variables.dart:9:16: Context: Bound of this variable references variable 'TypeT' from the same declaration.
+// class A<TypeT, TypeS extends TypeT> {}
+//                ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect
index d1f9062..c7037fd 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:11:9: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
@@ -10,15 +12,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:9:12: Context: Bound of this variable references raw type 'Fisk'.
 // class Hest<TypeX extends Fisk> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:11:9: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
-// Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
-// typedef Fisk = void Function<TypeY extends Hest>();
-//         ^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect
index bd3dbbb..c7037fd 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart.strong.transformed.expect
@@ -1,11 +1,18 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:11:9: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
 // typedef Fisk = void Function<TypeY extends Hest>();
 //         ^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:11:30: Context: Bound of this variable references raw type 'Hest'.
+// typedef Fisk = void Function<TypeY extends Hest>();
+//                              ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle.dart:9:12: Context: Bound of this variable references raw type 'Fisk'.
+// class Hest<TypeX extends Fisk> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
index b12ba48..e3cf58b 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:10:14: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
@@ -10,15 +12,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:8:12: Context: Bound of this variable references raw type 'Fisk'.
 // class Hest<TypeX extends Fisk> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:10:14: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
-// Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
-// typedef void Fisk<TypeY extends Hest>();
-//              ^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
index dfe5718..e3cf58b 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart.strong.transformed.expect
@@ -1,11 +1,18 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:10:14: Error: Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
 // typedef void Fisk<TypeY extends Hest>();
 //              ^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:10:19: Context: Bound of this variable references raw type 'Hest'.
+// typedef void Fisk<TypeY extends Hest>();
+//                   ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_class_typedef_cycle.dart:8:12: Context: Bound of this variable references raw type 'Fisk'.
+// class Hest<TypeX extends Fisk> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect
index 62dc787..5600160 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Hest> {}
-//            ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Hest> {}
-//            ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'Hest' here.
+// class Hest<TypeX extends Hest> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect
index a35f146..5600160 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart.strong.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
 // Try providing type arguments to 'Hest' here.
 // class Hest<TypeX extends Hest> {}
 //            ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect
index 6b66d03..c5e07d0 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Hest, TypeY extends Hest> {}
-//            ^^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:32: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Hest, TypeY extends Hest> {}
-//                                ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Hest, TypeY extends Hest> {}
-//            ^^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:32: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Hest, TypeY extends Hest> {}
-//                                ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'Hest' here.
+// class Hest<TypeX extends Hest, TypeY extends Hest> {}
+//            ^^^^^
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:32: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'Hest' here.
+// class Hest<TypeX extends Hest, TypeY extends Hest> {}
+//                                ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect
index 6594227..c5e07d0 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_for_each.dart:8:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
 // Try providing type arguments to 'Hest' here.
@@ -9,8 +11,7 @@
 // Try providing type arguments to 'Hest' here.
 // class Hest<TypeX extends Hest, TypeY extends Hest> {}
 //                                ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect
index 673dbbd..834692d 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart:9:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Map<Hest, Hest>> {}
-//            ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart:9:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
-// Try providing type arguments to 'Hest' here.
-// class Hest<TypeX extends Map<Hest, Hest>> {}
-//            ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart:9:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'Hest' here.
+// class Hest<TypeX extends Map<Hest, Hest>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect
index bfd0570..834692d 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart.strong.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_co_inductive_no_dup.dart:9:12: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables.
 // Try providing type arguments to 'Hest' here.
 // class Hest<TypeX extends Map<Hest, Hest>> {}
 //            ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.hierarchy.expect
new file mode 100644
index 0000000..988b2c4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_folded_regress.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.hierarchy.expect
new file mode 100644
index 0000000..988b2c4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.expect
index 143c0fc..326f710 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.expect
@@ -1,34 +1,23 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
-//            ^^^^^
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
-// class Hest<TypeX extends Hest<TypeX>> {}
-//            ^^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:32: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
-//                                ^^^^^
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
-// class Hest<TypeX extends Hest<TypeX>> {}
-//            ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
-//            ^^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:32: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
-//                                ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'Hest' here.
+// class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
+//            ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:32: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'Hest' here.
+// class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
+//                                ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.transformed.expect
index c98d064..326f710 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart.strong.transformed.expect
@@ -1,16 +1,23 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
 // class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
 //            ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:11:32: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
 // class Fisk<TypeY extends Hest, TypeZ extends Hest> {}
 //                                ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_for_each.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.expect
index b77b4f5..e6a55cc 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:collection" as col;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class Hest<X extends col::LinkedListEntry<dynamic> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::X>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.transformed.expect
index b77b4f5..e6a55cc 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:collection" as col;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class Hest<X extends col::LinkedListEntry<dynamic> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::X>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.outline.expect
index 446d326..d3b7084 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:collection" as col;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class Hest<X extends col::LinkedListEntry<dynamic> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::X>
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
index 4dbf4e5..dbf94d5 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.expect
@@ -1,34 +1,24 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Generic type 'LinkedListEntry' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'LinkedListEntry' here.
-// class Hest<X extends LinkedListEntry> {}
-//            ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
-//  - 'LinkedListEntry' is from 'dart:collection'.
-// Try changing type arguments so that they conform to the bounds.
-// class Hest<X extends LinkedListEntry> {}
-//            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Generic type 'LinkedListEntry' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'LinkedListEntry' here.
-// class Hest<X extends LinkedListEntry> {}
-//            ^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
-//  - 'LinkedListEntry' is from 'dart:collection'.
-// Try changing type arguments so that they conform to the bounds.
-// class Hest<X extends LinkedListEntry> {}
-//            ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Generic type 'LinkedListEntry' can't be used without type arguments in a type variable bound.
+// Try providing type arguments to 'LinkedListEntry' here.
+// class Hest<X extends LinkedListEntry> {}
+//            ^
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Type argument 'LinkedListEntry<dynamic>' doesn't conform to the bound 'LinkedListEntry<E>' of the type variable 'E' on 'LinkedListEntry'.
+//  - 'LinkedListEntry' is from 'dart:collection'.
+// Try changing type arguments so that they conform to the bounds.
+// class Hest<X extends LinkedListEntry> {}
+//            ^
+//
 import self as self;
 import "dart:collection" as col;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class Hest<X extends col::LinkedListEntry<col::LinkedListEntry<dynamic>> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::X>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
index 5e791e7..dbf94d5 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_from_compiled.dart:15:12: Error: Generic type 'LinkedListEntry' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'LinkedListEntry' here.
@@ -10,12 +12,13 @@
 // Try changing type arguments so that they conform to the bounds.
 // class Hest<X extends LinkedListEntry> {}
 //            ^
-
-library;
+//
 import self as self;
 import "dart:collection" as col;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class Hest<X extends col::LinkedListEntry<col::LinkedListEntry<dynamic>> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::X>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.hierarchy.expect
new file mode 100644
index 0000000..988b2c4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.expect
index 02af574..6fa7b7c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart:11:12: Error: Type variables can't have generic function types in their bounds.
-// class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
-//            ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart:11:12: Error: Type variables can't have generic function types in their bounds.
-// class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
-//            ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart:11:12: Error: Type variables can't have generic function types in their bounds.
+// class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.transformed.expect
index 4bf5fbc..6fa7b7c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_generic_function_in_bound_regress.dart:11:12: Error: Type variables can't have generic function types in their bounds.
 // class Fisk<TypeY extends Function<TypeZ extends Hest<Null>>(TypeZ)> {}
 //            ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.hierarchy.expect
new file mode 100644
index 0000000..6c3a2f6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Naebdyr:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.expect
index ad61fa0..8f7b853 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:12:15: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
@@ -15,20 +17,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:10:12: Context: Bound of this variable references variable 'TypeY' from the same declaration.
 // class Fisk<TypeY extends Fisk<TypeY>> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:12:15: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
-//               ^^^^^
-//
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:12:15: Error: Generic type 'Fisk' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Fisk' here.
-// class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
-//               ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.transformed.expect
index e5de63c..8f7b853 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart.strong.transformed.expect
@@ -1,16 +1,23 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:12:15: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
 // class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
 //               ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:8:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:12:15: Error: Generic type 'Fisk' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Fisk' here.
 // class Naebdyr<TypeZ extends Map<Hest, Fisk>> {}
 //               ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many.dart:10:12: Context: Bound of this variable references variable 'TypeY' from the same declaration.
+// class Fisk<TypeY extends Fisk<TypeY>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.hierarchy.expect
new file mode 100644
index 0000000..ae72487
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect
index 5691a75..34e8860 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.expect
@@ -3,9 +3,24 @@
 import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
+
 class Hest<TypeX extends non::Hest<dynamic> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::TypeX>
     : super core::Object::•()
     ;
 }
 static method main() → dynamic {}
+
+library non_simple_many_libs_same_name_cycle_lib;
+import self as non;
+import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
+
+class Hest<TypeY extends self::Hest<dynamic> = dynamic> extends core::Object {
+  synthetic constructor •() → non::Hest<non::Hest::TypeY>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect
index 5691a75..34e8860 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.legacy.transformed.expect
@@ -3,9 +3,24 @@
 import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
+
 class Hest<TypeX extends non::Hest<dynamic> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::TypeX>
     : super core::Object::•()
     ;
 }
 static method main() → dynamic {}
+
+library non_simple_many_libs_same_name_cycle_lib;
+import self as non;
+import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
+
+class Hest<TypeY extends self::Hest<dynamic> = dynamic> extends core::Object {
+  synthetic constructor •() → non::Hest<non::Hest::TypeY>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect
index 436437e..63b417d 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.outline.expect
@@ -3,9 +3,23 @@
 import "./non_simple_many_libs_same_name_cycle_lib.dart" as non;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
+
 class Hest<TypeX extends non::Hest<dynamic> = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::TypeX>
     ;
 }
 static method main() → dynamic
   ;
+
+library non_simple_many_libs_same_name_cycle_lib;
+import self as non;
+import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
+
+class Hest<TypeY extends self::Hest<dynamic> = dynamic> extends core::Object {
+  synthetic constructor •() → non::Hest<non::Hest::TypeY>
+    ;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
index 13d4805..aa390f4 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart:11:7: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
@@ -10,21 +12,28 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:16:12: Context: Bound of this variable references raw type 'Hest'.
 // class Hest<TypeY extends lib.Hest> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart:11:7: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
-// Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
-// class Hest<TypeX extends lib.Hest> {}
-//       ^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
+
 class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::TypeX>
     : super core::Object::•()
     ;
 }
 static method main() → dynamic {}
+
+library non_simple_many_libs_same_name_cycle_lib;
+import self as self2;
+import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
+
+class Hest<TypeY extends self::Hest<dynamic> = self::Hest<dynamic>> extends core::Object {
+  synthetic constructor •() → self2::Hest<self2::Hest::TypeY>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
index 9b12ea3..aa390f4 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
@@ -1,17 +1,39 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart:11:7: Error: Generic type 'Hest' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
 // Try providing type arguments to 'Hest' here or to some other raw types in the bounds along the reference chain.
 // class Hest<TypeX extends lib.Hest> {}
 //       ^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart:11:12: Context: Bound of this variable references raw type 'Hest'.
+// class Hest<TypeX extends lib.Hest> {}
+//            ^^^^^
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:16:12: Context: Bound of this variable references raw type 'Hest'.
+// class Hest<TypeY extends lib.Hest> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle_lib.dart" as lib;
+
 class Hest<TypeX extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::Hest<self::Hest::TypeX>
     : super core::Object::•()
     ;
 }
 static method main() → dynamic {}
+
+library non_simple_many_libs_same_name_cycle_lib;
+import self as self2;
+import "./non_simple_many_libs_same_name_cycle.dart" as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///non_simple_many_libs_same_name_cycle.dart" as lib;
+
+class Hest<TypeY extends self::Hest<dynamic> = self::Hest<dynamic>> extends core::Object {
+  synthetic constructor •() → self2::Hest<self2::Hest::TypeY>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.hierarchy.expect
new file mode 100644
index 0000000..988b2c4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.expect
index 061e900..1e42409 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
 // class Hest<TypeX extends Hest<TypeX>> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Map<Hest, Hest>> {}
-//            ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.transformed.expect
index dd60b38..1e42409 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart.strong.transformed.expect
@@ -1,11 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
 // class Fisk<TypeY extends Map<Hest, Hest>> {}
 //            ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_no_dup.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.hierarchy.expect
new file mode 100644
index 0000000..6c3a2f6
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Naebdyr:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.expect
index c4fbe14..ae65387 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
 // class Hest<TypeX extends Hest<TypeX>> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Hest> {}
-//            ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.transformed.expect
index 56452e6..ae65387 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart.strong.transformed.expect
@@ -1,11 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart:11:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
 // class Fisk<TypeY extends Hest> {}
 //            ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_suppress_consequence.dart:9:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.hierarchy.expect
new file mode 100644
index 0000000..988b2c4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.expect
index a5b4ddf..b94bb61 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart:12:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
@@ -7,15 +9,7 @@
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart:10:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
 // class Hest<TypeX extends Hest<TypeX>> {}
 //            ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart:12:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
-// Try providing type arguments to 'Hest' here.
-// class Fisk<TypeY extends Hest> {}
-//            ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.transformed.expect
index 5953737..b94bb61 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart.strong.transformed.expect
@@ -1,11 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart:12:12: Error: Generic type 'Hest' can't be used without type arguments in a type variable bound.
 // Try providing type arguments to 'Hest' here.
 // class Fisk<TypeY extends Hest> {}
 //            ^^^^^
-
-library;
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_variables_from_same.dart:10:12: Context: Bound of this variable references variable 'TypeX' from the same declaration.
+// class Hest<TypeX extends Hest<TypeX>> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..c693c0a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.baz
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.expect
index 72ed2b5..ba39350 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.transformed.expect
index 72ed2b5..ba39350 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.outline.expect
index 7e226db..3077c8b5 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.expect
index 72ed2b5..ba39350 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect
index 72ed2b5..ba39350 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:collection";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..523e0f4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.hierarchy.expect
new file mode 100644
index 0000000..196e56d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.hierarchy.expect
new file mode 100644
index 0000000..1931b4d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.hierarchy.expect
@@ -0,0 +1,485 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Y:
+  superclasses:
+    Object
+      -> X
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.expect
index bb127b8..03d4d75 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.transformed.expect
index bb127b8..03d4d75 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.outline.expect
index f1a08ad..302cab4 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     ;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.expect
index ed391ab..b431071 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect
index ed391ab..b431071 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.hierarchy.expect
new file mode 100644
index 0000000..fb8e258
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.hierarchy.expect
new file mode 100644
index 0000000..fb8e258
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..3805794
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.hierarchy.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.hierarchy.expect
new file mode 100644
index 0000000..9bc4745
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/invalid_assignment.dart.hierarchy.expect b/pkg/front_end/testcases/invalid_assignment.dart.hierarchy.expect
new file mode 100644
index 0000000..ff2fa4d
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_assignment.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/invalid_assignment.dart.strong.expect b/pkg/front_end/testcases/invalid_assignment.dart.strong.expect
index e32b7ae..c15f6aa 100644
--- a/pkg/front_end/testcases/invalid_assignment.dart.strong.expect
+++ b/pkg/front_end/testcases/invalid_assignment.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/invalid_assignment.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
@@ -15,8 +17,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'A'.
 //   a /*@error=InvalidAssignment*/ += 1;
 //                                  ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect
index 9ec525b..c15f6aa 100644
--- a/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect
@@ -1,4 +1,23 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/invalid_assignment.dart:13:36: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   i = /*@error=InvalidAssignment*/ s;
+//                                    ^
+//
+// pkg/front_end/testcases/invalid_assignment.dart:15:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   i ??= /*@error=InvalidAssignment*/ s;
+//                                      ^
+//
+// pkg/front_end/testcases/invalid_assignment.dart:17:34: Error: A value of type 'String' can't be assigned to a variable of type 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/invalid_assignment.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'A'.
+//   a /*@error=InvalidAssignment*/ += 1;
+//                                  ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invalid_cast.dart.hierarchy.expect b/pkg/front_end/testcases/invalid_cast.dart.hierarchy.expect
new file mode 100644
index 0000000..1e37782
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_cast.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.staticFunction
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._redirecting#
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/invalid_cast.dart.strong.expect b/pkg/front_end/testcases/invalid_cast.dart.strong.expect
index 9dbe0db..254485f 100644
--- a/pkg/front_end/testcases/invalid_cast.dart.strong.expect
+++ b/pkg/front_end/testcases/invalid_cast.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/invalid_cast.dart:22:60: Error: The list literal type 'List<Object>' isn't of expected type 'List<int>'.
 //  - 'List' is from 'dart:core'.
@@ -58,8 +60,7 @@
 // Change the type of the function or the context in which it is used.
 //   void Function(Object) k = /*@error=InvalidCastLocalFunction*/ localFunction;
 //                                                                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect b/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect
index acceaa9..a04133c 100644
--- a/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect
@@ -1,4 +1,66 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/invalid_cast.dart:22:60: Error: The list literal type 'List<Object>' isn't of expected type 'List<int>'.
+//  - 'List' is from 'dart:core'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the list literal or the context in which it is used.
+//   List<int> a = <Object> /*@error=InvalidCastLiteralList*/ [];
+//                                                            ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:23:74: Error: The map literal type 'Map<Object, String>' isn't of expected type 'Map<int, String>'.
+//  - 'Map' is from 'dart:core'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the map literal or the context in which it is used.
+//   Map<int, String> b = <Object, String> /*@error=InvalidCastLiteralMap*/ {};
+//                                                                          ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:24:71: Error: The map literal type 'Map<int, Object>' isn't of expected type 'Map<int, String>'.
+//  - 'Map' is from 'dart:core'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the map literal or the context in which it is used.
+//   Map<int, String> c = <int, Object> /*@error=InvalidCastLiteralMap*/ {};
+//                                                                       ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:25:63: Error: The function expression type 'int Function(int)' isn't of expected type 'int Function(Object)'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the function expression or the context in which it is used.
+//   int Function(Object) d = /*@error=InvalidCastFunctionExpr*/ (int i) => i;
+//                                                               ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:28:43: Error: The constructor returns type 'C' that isn't of expected type 'D'.
+//  - 'C' is from 'pkg/front_end/testcases/invalid_cast.dart'.
+//  - 'D' is from 'pkg/front_end/testcases/invalid_cast.dart'.
+// Change the type of the object being constructed or the context in which it is used.
+//   D g = new /*@error=InvalidCastNewExpr*/ C.nonFact();
+//                                           ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:29:43: Error: The constructor returns type 'C' that isn't of expected type 'D'.
+//  - 'C' is from 'pkg/front_end/testcases/invalid_cast.dart'.
+//  - 'D' is from 'pkg/front_end/testcases/invalid_cast.dart'.
+// Change the type of the object being constructed or the context in which it is used.
+//   D h = new /*@error=InvalidCastNewExpr*/ C.nonFact2();
+//                                           ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:31:45: Error: The static method has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the method or the context in which it is used.
+//       C. /*@error=InvalidCastStaticMethod*/ staticFunction;
+//                                             ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:33:50: Error: The top level function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the function or the context in which it is used.
+//       j = /*@error=InvalidCastTopLevelFunction*/ topLevelFunction;
+//                                                  ^
+//
+// pkg/front_end/testcases/invalid_cast.dart:34:65: Error: The local function has type 'void Function(int)' that isn't of expected type 'void Function(Object)'.
+//  - 'Object' is from 'dart:core'.
+// Change the type of the function or the context in which it is used.
+//   void Function(Object) k = /*@error=InvalidCastLocalFunction*/ localFunction;
+//                                                                 ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invalid_type.dart.hierarchy.expect b/pkg/front_end/testcases/invalid_type.dart.hierarchy.expect
new file mode 100644
index 0000000..3805794
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_type.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/invalid_type.dart.legacy.expect b/pkg/front_end/testcases/invalid_type.dart.legacy.expect
index ec2dd21..06c896f 100644
--- a/pkg/front_end/testcases/invalid_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/invalid_type.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/invalid_type.dart:7:5: Error: Expected identifier, but got 'this'.
 //     this.bar();
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/invalid_type.dart:12:12: Warning: 'Missing' isn't a type.
 //   (null as Missing).bar();
 //            ^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invalid_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/invalid_type.dart.legacy.transformed.expect
index bc547fb..06c896f 100644
--- a/pkg/front_end/testcases/invalid_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/invalid_type.dart.legacy.transformed.expect
@@ -1,4 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/invalid_type.dart:7:5: Error: Expected identifier, but got 'this'.
+//     this.bar();
+//     ^^^^
+//
+// pkg/front_end/testcases/invalid_type.dart:12:12: Warning: 'Missing' isn't a type.
+//   (null as Missing).bar();
+//            ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invalid_type.dart.strong.expect b/pkg/front_end/testcases/invalid_type.dart.strong.expect
index 072f0ee..f26928f 100644
--- a/pkg/front_end/testcases/invalid_type.dart.strong.expect
+++ b/pkg/front_end/testcases/invalid_type.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/invalid_type.dart:7:5: Error: Expected identifier, but got 'this'.
 //     this.bar();
@@ -12,14 +14,7 @@
 // Try correcting the name to the name of an existing method, or defining a method named 'bar'.
 //   null.bar();
 //        ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/invalid_type.dart:12:12: Error: 'Missing' isn't a type.
-//   (null as Missing).bar();
-//            ^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -35,7 +30,7 @@
 }
 static method test() → dynamic {
   (null as invalid-type).bar();
-  let final dynamic #t1 = null in invalid-expression "pkg/front_end/testcases/invalid_type.dart:13:8: Error: The method 'bar' isn't defined for the class 'Null'.
+  invalid-expression "pkg/front_end/testcases/invalid_type.dart:13:8: Error: The method 'bar' isn't defined for the class 'Null'.
 Try correcting the name to the name of an existing method, or defining a method named 'bar'.
   null.bar();
        ^^^";
diff --git a/pkg/front_end/testcases/invocations.dart.strong.expect b/pkg/front_end/testcases/invocations.dart.strong.expect
index 9bfb838..ee55950 100644
--- a/pkg/front_end/testcases/invocations.dart.strong.expect
+++ b/pkg/front_end/testcases/invocations.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/invocations.dart:7:3: Error: Method not found: 'z'.
 //   z("Hello, World!");
@@ -35,8 +37,7 @@
 // pkg/front_end/testcases/invocations.dart:13:7: Error: This expression has type 'void' and can't be used.
 //       print("Hello, World!") +
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/invocations.dart.strong.transformed.expect
index 773afe1..ee55950 100644
--- a/pkg/front_end/testcases/invocations.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/invocations.dart.strong.transformed.expect
@@ -1,4 +1,43 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/invocations.dart:7:3: Error: Method not found: 'z'.
+//   z("Hello, World!");
+//   ^
+//
+// pkg/front_end/testcases/invocations.dart:8:3: Error: Getter not found: 'z'.
+//   z.print("Hello, World!");
+//   ^
+//
+// pkg/front_end/testcases/invocations.dart:9:3: Error: Getter not found: 'y'.
+//   y.z.print("Hello, World!");
+//   ^
+//
+// pkg/front_end/testcases/invocations.dart:10:3: Error: Getter not found: 'x'.
+//   x.y.z.print("Hello, World!");
+//   ^
+//
+// pkg/front_end/testcases/invocations.dart:14:7: Error: Method not found: 'z'.
+//       z("Hello, World!") +
+//       ^
+//
+// pkg/front_end/testcases/invocations.dart:15:7: Error: Getter not found: 'z'.
+//       z.print("Hello, World!") +
+//       ^
+//
+// pkg/front_end/testcases/invocations.dart:16:7: Error: Getter not found: 'y'.
+//       y.z.print("Hello, World!") +
+//       ^
+//
+// pkg/front_end/testcases/invocations.dart:17:7: Error: Getter not found: 'x'.
+//       x.y.z.print("Hello, World!");
+//       ^
+//
+// pkg/front_end/testcases/invocations.dart:13:7: Error: This expression has type 'void' and can't be used.
+//       print("Hello, World!") +
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/issue34515.dart b/pkg/front_end/testcases/issue34515.dart
new file mode 100644
index 0000000..829ce3b
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.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 "issue34515_lib1.dart";
+import "issue34515_lib2.dart";
+
+void test() {
+  ImportedClass(1);
+  ImportedClass("a");
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/issue34515.dart.hierarchy.expect b/pkg/front_end/testcases/issue34515.dart.hierarchy.expect
new file mode 100644
index 0000000..32f2c5e
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ImportedClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ImportedClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/issue34515.dart.legacy.expect b/pkg/front_end/testcases/issue34515.dart.legacy.expect
new file mode 100644
index 0000000..528e442
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.dart.legacy.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/issue34515.dart:9:3: Warning: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass(1);
+//   ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/issue34515.dart:10:3: Warning: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass("a");
+//   ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue34515_lib1.dart";
+import "org-dartlang-testcase:///issue34515_lib2.dart";
+
+static method test() → void {
+  let final core::Object #t1 = 1 in invalid-expression "pkg/front_end/testcases/issue34515.dart:9:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(1);
+  ^^^^^^^^^^^^^";
+  let final core::Object #t2 = "a" in invalid-expression "pkg/front_end/testcases/issue34515.dart:10:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(\"a\");
+  ^^^^^^^^^^^^^";
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::int a) → self2::ImportedClass
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::String a) → self3::ImportedClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/issue34515.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue34515.dart.legacy.transformed.expect
new file mode 100644
index 0000000..528e442
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.dart.legacy.transformed.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/issue34515.dart:9:3: Warning: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass(1);
+//   ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/issue34515.dart:10:3: Warning: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass("a");
+//   ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue34515_lib1.dart";
+import "org-dartlang-testcase:///issue34515_lib2.dart";
+
+static method test() → void {
+  let final core::Object #t1 = 1 in invalid-expression "pkg/front_end/testcases/issue34515.dart:9:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(1);
+  ^^^^^^^^^^^^^";
+  let final core::Object #t2 = "a" in invalid-expression "pkg/front_end/testcases/issue34515.dart:10:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(\"a\");
+  ^^^^^^^^^^^^^";
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::int a) → self2::ImportedClass
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::String a) → self3::ImportedClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/issue34515.dart.outline.expect b/pkg/front_end/testcases/issue34515.dart.outline.expect
new file mode 100644
index 0000000..1c038cb
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.dart.outline.expect
@@ -0,0 +1,28 @@
+library;
+import self as self;
+
+import "org-dartlang-testcase:///issue34515_lib1.dart";
+import "org-dartlang-testcase:///issue34515_lib2.dart";
+
+static method test() → void
+  ;
+static method main() → dynamic
+  ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::int a) → self2::ImportedClass
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::String a) → self3::ImportedClass
+    ;
+}
diff --git a/pkg/front_end/testcases/issue34515.dart.strong.expect b/pkg/front_end/testcases/issue34515.dart.strong.expect
new file mode 100644
index 0000000..d8a23b4
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.dart.strong.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/issue34515.dart:9:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass(1);
+//   ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/issue34515.dart:10:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass("a");
+//   ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue34515_lib1.dart";
+import "org-dartlang-testcase:///issue34515_lib2.dart";
+
+static method test() → void {
+  let final core::Object #t1 = 1 in invalid-expression "pkg/front_end/testcases/issue34515.dart:9:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(1);
+  ^^^^^^^^^^^^^";
+  let final core::Object #t2 = "a" in invalid-expression "pkg/front_end/testcases/issue34515.dart:10:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(\"a\");
+  ^^^^^^^^^^^^^";
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::int a) → self2::ImportedClass
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::String a) → self3::ImportedClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/issue34515.dart.strong.transformed.expect b/pkg/front_end/testcases/issue34515.dart.strong.transformed.expect
new file mode 100644
index 0000000..d8a23b4
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515.dart.strong.transformed.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/issue34515.dart:9:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass(1);
+//   ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/issue34515.dart:10:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+//   ImportedClass("a");
+//   ^^^^^^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///issue34515_lib1.dart";
+import "org-dartlang-testcase:///issue34515_lib2.dart";
+
+static method test() → void {
+  let final core::Object #t1 = 1 in invalid-expression "pkg/front_end/testcases/issue34515.dart:9:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(1);
+  ^^^^^^^^^^^^^";
+  let final core::Object #t2 = "a" in invalid-expression "pkg/front_end/testcases/issue34515.dart:10:3: Error: 'ImportedClass' is imported from both 'pkg/front_end/testcases/issue34515_lib1.dart' and 'pkg/front_end/testcases/issue34515_lib2.dart'.
+  ImportedClass(\"a\");
+  ^^^^^^^^^^^^^";
+}
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::int a) → self2::ImportedClass
+    : super core::Object::•()
+    ;
+}
+
+library;
+import self as self3;
+import "dart:core" as core;
+
+class ImportedClass extends core::Object {
+  constructor •(core::String a) → self3::ImportedClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/issue34515_lib1.dart b/pkg/front_end/testcases/issue34515_lib1.dart
new file mode 100644
index 0000000..00f9340
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515_lib1.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.
+
+class ImportedClass {
+  ImportedClass(int a);
+}
diff --git a/pkg/front_end/testcases/issue34515_lib2.dart b/pkg/front_end/testcases/issue34515_lib2.dart
new file mode 100644
index 0000000..2ec64bb
--- /dev/null
+++ b/pkg/front_end/testcases/issue34515_lib2.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.
+
+class ImportedClass {
+  ImportedClass(String a);
+}
diff --git a/pkg/front_end/testcases/issue34899.dart.hierarchy.expect b/pkg/front_end/testcases/issue34899.dart.hierarchy.expect
new file mode 100644
index 0000000..988b29a
--- /dev/null
+++ b/pkg/front_end/testcases/issue34899.dart.hierarchy.expect
@@ -0,0 +1,96 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.t
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.call
+    Object._instanceOf
+    Foo.quux
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.t
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Bar.garply
+    Object.toString
+    Object.runtimeType
+    Bar.quuz
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Bar.corge
+    Object._simpleInstanceOfTrue
+    Object.==
+    Bar.qux
+  classSetters:
+    Bar.qux
+
+Baz:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Grault:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/issue35875.dart b/pkg/front_end/testcases/issue35875.dart
new file mode 100644
index 0000000..53cd8a0
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.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.
+
+class A {
+  int a;
+  A(int a) {
+    (this).a = a;
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/issue35875.dart.hierarchy.expect b/pkg/front_end/testcases/issue35875.dart.hierarchy.expect
new file mode 100644
index 0000000..eef7d41
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
diff --git a/pkg/front_end/testcases/issue35875.dart.legacy.expect b/pkg/front_end/testcases/issue35875.dart.legacy.expect
new file mode 100644
index 0000000..ee54528
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.dart.legacy.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a = null;
+  constructor •(core::int a) → self::A
+    : super core::Object::•() {
+    this.{self::A::a} = a;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue35875.dart.legacy.transformed.expect b/pkg/front_end/testcases/issue35875.dart.legacy.transformed.expect
new file mode 100644
index 0000000..ee54528
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.dart.legacy.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a = null;
+  constructor •(core::int a) → self::A
+    : super core::Object::•() {
+    this.{self::A::a} = a;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue35875.dart.outline.expect b/pkg/front_end/testcases/issue35875.dart.outline.expect
new file mode 100644
index 0000000..305f440
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.dart.outline.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a;
+  constructor •(core::int a) → self::A
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/issue35875.dart.strong.expect b/pkg/front_end/testcases/issue35875.dart.strong.expect
new file mode 100644
index 0000000..ee54528
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.dart.strong.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a = null;
+  constructor •(core::int a) → self::A
+    : super core::Object::•() {
+    this.{self::A::a} = a;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/issue35875.dart.strong.transformed.expect b/pkg/front_end/testcases/issue35875.dart.strong.transformed.expect
new file mode 100644
index 0000000..ee54528
--- /dev/null
+++ b/pkg/front_end/testcases/issue35875.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a = null;
+  constructor •(core::int a) → self::A
+    : super core::Object::•() {
+    this.{self::A::a} = a;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status
index e603fd2..686bf31 100644
--- a/pkg/front_end/testcases/legacy.status
+++ b/pkg/front_end/testcases/legacy.status
@@ -19,7 +19,7 @@
 inference/bug31436: RuntimeError # Test exercises Dart 2.0 semantics
 inference/constructors_too_many_positional_arguments: Fail
 inference/downwards_inference_annotations_locals: Fail # Issue #30031
-inference/future_then_explicit_future: Fail
+inference/future_then_explicit_future: RuntimeError
 inference/generic_methods_infer_js_builtin: RuntimeError # Test attempts to access platform-private library leading to NSM.
 inference/infer_assign_to_index: Fail
 inference/infer_assign_to_property: Fail
@@ -49,7 +49,7 @@
 rasta/breaking_bad: Fail
 rasta/class_hierarchy: Fail
 rasta/class_member: Fail
-rasta/constant_get_and_invoke: Fail
+rasta/constant_get_and_invoke: RuntimeError
 rasta/deferred_lib: Fail
 rasta/deferred_load: Fail
 rasta/duplicated_mixin: RuntimeError # Expected, this file has no main method.
@@ -69,7 +69,7 @@
 rasta/issue_000043: Fail
 rasta/issue_000044: Fail
 rasta/issue_000045: Fail
-rasta/issue_000046: Fail
+rasta/issue_000046: RuntimeError
 rasta/issue_000047: Fail
 rasta/issue_000081: Fail
 rasta/malformed_const_constructor: Fail
@@ -126,6 +126,7 @@
 runtime_checks_new/mixin_forwarding_stub_setter: RuntimeError # Test exercises strong mode semantics
 runtime_checks_new/stub_checked_via_target: RuntimeError # Test exercises strong mode semantics
 set_literals/disambiguation_rule: RuntimeError
+spread_collection: RuntimeError
 type_variable_as_super: Fail
 uninitialized_fields: Fail # Fasta and dartk disagree on static initializers
 void_methods: Fail # Bad return from setters.
diff --git a/pkg/front_end/testcases/magic_const.dart.hierarchy.expect b/pkg/front_end/testcases/magic_const.dart.hierarchy.expect
new file mode 100644
index 0000000..0a8f0ef
--- /dev/null
+++ b/pkg/front_end/testcases/magic_const.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Constant:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+NotConstant:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/magic_const.dart.legacy.expect b/pkg/front_end/testcases/magic_const.dart.legacy.expect
index 36d6c67..78ce95a 100644
--- a/pkg/front_end/testcases/magic_const.dart.legacy.expect
+++ b/pkg/front_end/testcases/magic_const.dart.legacy.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 // Try using a constructor or factory that is 'const'.
 //   const NotConstant();
 //         ^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/magic_const.dart.legacy.transformed.expect b/pkg/front_end/testcases/magic_const.dart.legacy.transformed.expect
index 9a97877..78ce95a 100644
--- a/pkg/front_end/testcases/magic_const.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/magic_const.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const NotConstant();
+//         ^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.expect b/pkg/front_end/testcases/magic_const.dart.strong.expect
index 07f6812..e5aa39c 100644
--- a/pkg/front_end/testcases/magic_const.dart.strong.expect
+++ b/pkg/front_end/testcases/magic_const.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
 // Try using a constructor or factory that is 'const'.
 //   const NotConstant();
 //         ^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
index c4404ef..e5aa39c 100644
--- a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/magic_const.dart:18:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const NotConstant();
+//         ^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/many_errors.dart b/pkg/front_end/testcases/many_errors.dart
new file mode 100644
index 0000000..b689662
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.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.
+
+class A {
+  final x = null;
+
+  const A.named1() sync* {}
+
+  const A.named2() : x = new Object();
+}
+
+external foo(String x) {
+  return x.length;
+}
+
+class B {}
+
+class C {
+  B b;
+}
+
+abstract class AbstractClass {
+  const AbstractClass.id();
+}
+
+m() {
+  const AbstractClass.id();
+  (new C()?.b ??= new B()).b;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/many_errors.dart.hierarchy.expect b/pkg/front_end/testcases/many_errors.dart.hierarchy.expect
new file mode 100644
index 0000000..ef14d0e
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.dart.hierarchy.expect
@@ -0,0 +1,90 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.b
+
+AbstractClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/many_errors.dart.legacy.expect b/pkg/front_end/testcases/many_errors.dart.legacy.expect
new file mode 100644
index 0000000..07f53cf
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.dart.legacy.expect
@@ -0,0 +1,94 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/many_errors.dart:8:3: Error: A const constructor can't have a body.
+// Try removing either the 'const' keyword or the body.
+//   const A.named1() sync* {}
+//   ^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:13:1: Error: An external or native method can't have a body.
+// external foo(String x) {
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+//   const A.named1() sync* {}
+//                          ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
+//   const A.named2() : x = new Object();
+//                          ^^^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Warning: 'x' is a final instance variable that has already been initialized.
+//   const A.named2() : x = new Object();
+//                        ^
+// pkg/front_end/testcases/many_errors.dart:6:9: Context: 'x' was initialized here.
+//   final x = null;
+//         ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const A.named2() : x = new Object();
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+// external foo(String x) {
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: The class 'AbstractClass' is abstract and can't be instantiated.
+//   const AbstractClass.id();
+//         ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const AbstractClass.id();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x = null;
+  constructor named1() → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+  const A.named1() sync* {}
+                         ^" {}
+  const constructor named2() → self::A
+    : final dynamic #t2 = throw invalid-expression "pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const A.named2() : x = new Object();
+                       ^", super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  const constructor id() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+external static method foo(core::String x) → dynamic {
+  invalid-expression "pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+external foo(String x) {
+                       ^";
+  {
+    return x.length;
+  }
+}
+static method m() → dynamic {
+  throw invalid-expression "pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const AbstractClass.id();
+        ^";
+  (let final dynamic #t3 = new self::C::•() in #t3.==(null) ? null : let final dynamic #t4 = #t3.b in #t4.==(null) ? #t3.b = new self::B::•() : #t4).b;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/many_errors.dart.legacy.transformed.expect b/pkg/front_end/testcases/many_errors.dart.legacy.transformed.expect
new file mode 100644
index 0000000..07f53cf
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.dart.legacy.transformed.expect
@@ -0,0 +1,94 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/many_errors.dart:8:3: Error: A const constructor can't have a body.
+// Try removing either the 'const' keyword or the body.
+//   const A.named1() sync* {}
+//   ^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:13:1: Error: An external or native method can't have a body.
+// external foo(String x) {
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+//   const A.named1() sync* {}
+//                          ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
+//   const A.named2() : x = new Object();
+//                          ^^^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Warning: 'x' is a final instance variable that has already been initialized.
+//   const A.named2() : x = new Object();
+//                        ^
+// pkg/front_end/testcases/many_errors.dart:6:9: Context: 'x' was initialized here.
+//   final x = null;
+//         ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const A.named2() : x = new Object();
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+// external foo(String x) {
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: The class 'AbstractClass' is abstract and can't be instantiated.
+//   const AbstractClass.id();
+//         ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const AbstractClass.id();
+//         ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x = null;
+  constructor named1() → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+  const A.named1() sync* {}
+                         ^" {}
+  const constructor named2() → self::A
+    : final dynamic #t2 = throw invalid-expression "pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const A.named2() : x = new Object();
+                       ^", super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  const constructor id() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+external static method foo(core::String x) → dynamic {
+  invalid-expression "pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+external foo(String x) {
+                       ^";
+  {
+    return x.length;
+  }
+}
+static method m() → dynamic {
+  throw invalid-expression "pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const AbstractClass.id();
+        ^";
+  (let final dynamic #t3 = new self::C::•() in #t3.==(null) ? null : let final dynamic #t4 = #t3.b in #t4.==(null) ? #t3.b = new self::B::•() : #t4).b;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/many_errors.dart.outline.expect b/pkg/front_end/testcases/many_errors.dart.outline.expect
new file mode 100644
index 0000000..4efbcd6
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.dart.outline.expect
@@ -0,0 +1,41 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/many_errors.dart:8:3: Error: A const constructor can't have a body.
+// Try removing either the 'const' keyword or the body.
+//   const A.named1() sync* {}
+//   ^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:13:1: Error: An external or native method can't have a body.
+// external foo(String x) {
+// ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x;
+  constructor named1() → self::A
+    ;
+  const constructor named2() → self::A
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+}
+class C extends core::Object {
+  field self::B b;
+  synthetic constructor •() → self::C
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  const constructor id() → self::AbstractClass
+    ;
+}
+external static method foo(core::String x) → dynamic;
+static method m() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/many_errors.dart.strong.expect b/pkg/front_end/testcases/many_errors.dart.strong.expect
new file mode 100644
index 0000000..37fcff8
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.dart.strong.expect
@@ -0,0 +1,104 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/many_errors.dart:8:3: Error: A const constructor can't have a body.
+// Try removing either the 'const' keyword or the body.
+//   const A.named1() sync* {}
+//   ^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:13:1: Error: An external or native method can't have a body.
+// external foo(String x) {
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+//   const A.named1() sync* {}
+//                          ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
+//   const A.named2() : x = new Object();
+//                          ^^^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Error: 'x' is a final instance variable that has already been initialized.
+//   const A.named2() : x = new Object();
+//                        ^
+// pkg/front_end/testcases/many_errors.dart:6:9: Context: 'x' was initialized here.
+//   final x = null;
+//         ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const A.named2() : x = new Object();
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+// external foo(String x) {
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: The class 'AbstractClass' is abstract and can't be instantiated.
+//   const AbstractClass.id();
+//         ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const AbstractClass.id();
+//         ^
+//
+// pkg/front_end/testcases/many_errors.dart:29:28: Error: The getter 'b' isn't defined for the class 'B'.
+//  - 'B' is from 'pkg/front_end/testcases/many_errors.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'b'.
+//   (new C()?.b ??= new B()).b;
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x = null;
+  constructor named1() → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+  const A.named1() sync* {}
+                         ^" {}
+  const constructor named2() → self::A
+    : final dynamic #t2 = throw invalid-expression "pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const A.named2() : x = new Object();
+                       ^", super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  const constructor id() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+external static method foo(core::String x) → dynamic {
+  invalid-expression "pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+external foo(String x) {
+                       ^";
+  {
+    return x.{core::String::length};
+  }
+}
+static method m() → dynamic {
+  throw invalid-expression "pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const AbstractClass.id();
+        ^";
+  invalid-expression "pkg/front_end/testcases/many_errors.dart:29:28: Error: The getter 'b' isn't defined for the class 'B'.
+ - 'B' is from 'pkg/front_end/testcases/many_errors.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'b'.
+  (new C()?.b ??= new B()).b;
+                           ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/many_errors.dart.strong.transformed.expect b/pkg/front_end/testcases/many_errors.dart.strong.transformed.expect
new file mode 100644
index 0000000..37fcff8
--- /dev/null
+++ b/pkg/front_end/testcases/many_errors.dart.strong.transformed.expect
@@ -0,0 +1,104 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/many_errors.dart:8:3: Error: A const constructor can't have a body.
+// Try removing either the 'const' keyword or the body.
+//   const A.named1() sync* {}
+//   ^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:13:1: Error: An external or native method can't have a body.
+// external foo(String x) {
+// ^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+//   const A.named1() sync* {}
+//                          ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
+//   const A.named2() : x = new Object();
+//                          ^^^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Error: 'x' is a final instance variable that has already been initialized.
+//   const A.named2() : x = new Object();
+//                        ^
+// pkg/front_end/testcases/many_errors.dart:6:9: Context: 'x' was initialized here.
+//   final x = null;
+//         ^
+//
+// pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const A.named2() : x = new Object();
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+// external foo(String x) {
+//                        ^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: The class 'AbstractClass' is abstract and can't be instantiated.
+//   const AbstractClass.id();
+//         ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const AbstractClass.id();
+//         ^
+//
+// pkg/front_end/testcases/many_errors.dart:29:28: Error: The getter 'b' isn't defined for the class 'B'.
+//  - 'B' is from 'pkg/front_end/testcases/many_errors.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'b'.
+//   (new C()?.b ??= new B()).b;
+//                            ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x = null;
+  constructor named1() → self::A
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
+  const A.named1() sync* {}
+                         ^" {}
+  const constructor named2() → self::A
+    : final dynamic #t2 = throw invalid-expression "pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const A.named2() : x = new Object();
+                       ^", super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+abstract class AbstractClass extends core::Object {
+  const constructor id() → self::AbstractClass
+    : super core::Object::•()
+    ;
+}
+external static method foo(core::String x) → dynamic {
+  invalid-expression "pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
+external foo(String x) {
+                       ^";
+  {
+    return x.{core::String::length};
+  }
+}
+static method m() → dynamic {
+  throw invalid-expression "pkg/front_end/testcases/many_errors.dart:28:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+Try using a constructor or factory that is 'const'.
+  const AbstractClass.id();
+        ^";
+  invalid-expression "pkg/front_end/testcases/many_errors.dart:29:28: Error: The getter 'b' isn't defined for the class 'B'.
+ - 'B' is from 'pkg/front_end/testcases/many_errors.dart'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'b'.
+  (new C()?.b ??= new B()).b;
+                           ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/metadata_enum.dart.hierarchy.expect b/pkg/front_end/testcases/metadata_enum.dart.hierarchy.expect
new file mode 100644
index 0000000..07b5939
--- /dev/null
+++ b/pkg/front_end/testcases/metadata_enum.dart.hierarchy.expect
@@ -0,0 +1,42 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    E.toString
+    E.E1
+    E.index
+    Object.runtimeType
+    Object._simpleInstanceOf
+    E.E2
+    Object._instanceOf
+    E._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    E.E3
+    Object.hashCode
+    E.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/metadata_named_mixin_application.dart.hierarchy.expect b/pkg/front_end/testcases/metadata_named_mixin_application.dart.hierarchy.expect
new file mode 100644
index 0000000..08e508c
--- /dev/null
+++ b/pkg/front_end/testcases/metadata_named_mixin_application.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> D
+  interfaces: E
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/micro.dart.hierarchy.expect b/pkg/front_end/testcases/micro.dart.hierarchy.expect
new file mode 100644
index 0000000..f582dc5
--- /dev/null
+++ b/pkg/front_end/testcases/micro.dart.hierarchy.expect
@@ -0,0 +1,164 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Foo.instanceMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExternalValue:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Bar.externalInstanceMethod
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Box:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Box.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Box.field
+
+FinalBox:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    FinalBox.finalField
+  classSetters:
+
+SubFinalBox:
+  superclasses:
+    Object
+      -> FinalBox
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    FinalBox.finalField
+  classSetters:
+
+DynamicReceiver1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    DynamicReceiver1.dynamicallyCalled
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+DynamicReceiver2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    DynamicReceiver2.dynamicallyCalled
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/minimum_int.dart.outline.expect b/pkg/front_end/testcases/minimum_int.dart.outline.expect
index e4f3929..6a28c0d 100644
--- a/pkg/front_end/testcases/minimum_int.dart.outline.expect
+++ b/pkg/front_end/testcases/minimum_int.dart.outline.expect
@@ -3,4 +3,3 @@
 
 static method main() → dynamic
   ;
-
diff --git a/pkg/front_end/testcases/missing_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/missing_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..662f599
--- /dev/null
+++ b/pkg/front_end/testcases/missing_constructor.dart.hierarchy.expect
@@ -0,0 +1,149 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Super:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Sub:
+  superclasses:
+    Object
+      -> Super
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bad:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Super with M:
+  superclasses:
+    Object
+      -> Super
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+MixinApplication:
+  superclasses:
+    Object
+      -> Super
+        -> _MixinApplication&Super&M
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/missing_constructor.dart.legacy.expect b/pkg/front_end/testcases/missing_constructor.dart.legacy.expect
index a886bd4..f6911cc 100644
--- a/pkg/front_end/testcases/missing_constructor.dart.legacy.expect
+++ b/pkg/front_end/testcases/missing_constructor.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/missing_constructor.dart:10:11: Warning: Superclass has no constructor named 'Super'.
 //   Sub() : super();
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/missing_constructor.dart:23:28: Warning: Superclass has no constructor named 'Super.foo'.
 //   MixinApplication.foo() : super.foo();
 //                            ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/missing_constructor.dart.legacy.transformed.expect b/pkg/front_end/testcases/missing_constructor.dart.legacy.transformed.expect
index 37a1c85..518277f 100644
--- a/pkg/front_end/testcases/missing_constructor.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/missing_constructor.dart.legacy.transformed.expect
@@ -1,4 +1,31 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/missing_constructor.dart:10:11: Warning: Superclass has no constructor named 'Super'.
+//   Sub() : super();
+//           ^^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:11:15: Warning: Superclass has no constructor named 'Super.foo'.
+//   Sub.foo() : super.foo();
+//               ^^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:15:15: Warning: Couldn't find constructor 'Bad'.
+//   Bad.foo() : this();
+//               ^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:16:15: Warning: Couldn't find constructor 'Bad.baz'.
+//   Bad.bar() : this.baz();
+//               ^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:22:24: Warning: Superclass has no constructor named 'Super'.
+//   MixinApplication() : super();
+//                        ^^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:23:28: Warning: Superclass has no constructor named 'Super.foo'.
+//   MixinApplication.foo() : super.foo();
+//                            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/missing_constructor.dart.strong.expect b/pkg/front_end/testcases/missing_constructor.dart.strong.expect
index 2102137d..171f082 100644
--- a/pkg/front_end/testcases/missing_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/missing_constructor.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/missing_constructor.dart:10:11: Error: Superclass has no constructor named 'Super'.
 //   Sub() : super();
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/missing_constructor.dart:23:28: Error: Superclass has no constructor named 'Super.foo'.
 //   MixinApplication.foo() : super.foo();
 //                            ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/missing_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/missing_constructor.dart.strong.transformed.expect
index 1b4681e..3c5ca61 100644
--- a/pkg/front_end/testcases/missing_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/missing_constructor.dart.strong.transformed.expect
@@ -1,4 +1,31 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/missing_constructor.dart:10:11: Error: Superclass has no constructor named 'Super'.
+//   Sub() : super();
+//           ^^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:11:15: Error: Superclass has no constructor named 'Super.foo'.
+//   Sub.foo() : super.foo();
+//               ^^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:15:15: Error: Couldn't find constructor 'Bad'.
+//   Bad.foo() : this();
+//               ^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:16:15: Error: Couldn't find constructor 'Bad.baz'.
+//   Bad.bar() : this.baz();
+//               ^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:22:24: Error: Superclass has no constructor named 'Super'.
+//   MixinApplication() : super();
+//                        ^^^^^
+//
+// pkg/front_end/testcases/missing_constructor.dart:23:28: Error: Superclass has no constructor named 'Super.foo'.
+//   MixinApplication.foo() : super.foo();
+//                            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/mixin.dart.hierarchy.expect b/pkg/front_end/testcases/mixin.dart.hierarchy.expect
new file mode 100644
index 0000000..a86326c
--- /dev/null
+++ b/pkg/front_end/testcases/mixin.dart.hierarchy.expect
@@ -0,0 +1,328 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with M1:
+  superclasses:
+    Object
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_C&Object&M1 with M2:
+  superclasses:
+    Object
+      -> _C&Object&M1
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C:
+  superclasses:
+    Object
+      -> _C&Object&M1
+        -> _C&Object&M1&M2
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+G1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with G1<S>:
+  superclasses:
+    Object
+  interfaces: G1<S>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+      -> _D&Object&G1<S>
+  interfaces: G1<S>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    G1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with M1:
+  superclasses:
+    Object
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B&Object&M1 with M2:
+  superclasses:
+    Object
+      -> _B&Object&M1
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B:
+  superclasses:
+    Object
+      -> _B&Object&M1
+        -> _B&Object&M1&M2
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M2.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
new file mode 100644
index 0000000..8351797
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_application_override.dart.hierarchy.expect
@@ -0,0 +1,1301 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+S:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+MX:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A0:
+  superclasses:
+    Object
+      -> S
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A1:
+  superclasses:
+    Object
+      -> S
+        -> _A1&S&M1
+  interfaces: M1, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A2&S&M1 with M2:
+  superclasses:
+    Object
+      -> S
+        -> _A2&S&M1
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A2:
+  superclasses:
+    Object
+      -> S
+        -> _A2&S&M1
+          -> _A2&S&M1&M2
+  interfaces: M1, M2, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M:
+  superclasses:
+    Object
+      -> S
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A0X:
+  superclasses:
+    Object
+      -> S
+        -> _A0X&S&M
+  interfaces: M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A1X&S&M1 with M:
+  superclasses:
+    Object
+      -> S
+        -> _A1X&S&M1
+  interfaces: M1, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A1X:
+  superclasses:
+    Object
+      -> S
+        -> _A1X&S&M1
+          -> _A1X&S&M1&M
+  interfaces: M1, M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A2X&S&M1 with M2:
+  superclasses:
+    Object
+      -> S
+        -> _A2X&S&M1
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_A2X&S&M1&M2 with M:
+  superclasses:
+    Object
+      -> S
+        -> _A2X&S&M1
+          -> _A2X&S&M1&M2
+  interfaces: M1, M2, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A2X:
+  superclasses:
+    Object
+      -> S
+        -> _A2X&S&M1
+          -> _A2X&S&M1&M2
+            -> _A2X&S&M1&M2&M
+  interfaces: M1, M2, M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M:
+  superclasses:
+    Object
+      -> S
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B0:
+  superclasses:
+    Object
+      -> S
+        -> _B0&S&M
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B1&S&M1 with M:
+  superclasses:
+    Object
+      -> S
+        -> _B1&S&M1
+  interfaces: M1, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B1:
+  superclasses:
+    Object
+      -> S
+        -> _B1&S&M1
+          -> _B1&S&M1&M
+  interfaces: M1, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B2&S&M1 with M2:
+  superclasses:
+    Object
+      -> S
+        -> _B2&S&M1
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B2&S&M1&M2 with M:
+  superclasses:
+    Object
+      -> S
+        -> _B2&S&M1
+          -> _B2&S&M1&M2
+  interfaces: M1, M2, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B2:
+  superclasses:
+    Object
+      -> S
+        -> _B2&S&M1
+          -> _B2&S&M1&M2
+            -> _B2&S&M1&M2&M
+  interfaces: M1, M2, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M:
+  superclasses:
+    Object
+      -> S
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B0X&S&M with MX:
+  superclasses:
+    Object
+      -> S
+        -> _B0X&S&M
+  interfaces: M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B0X:
+  superclasses:
+    Object
+      -> S
+        -> _B0X&S&M
+          -> _B0X&S&M&MX
+  interfaces: M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B1X&S&M1 with M:
+  superclasses:
+    Object
+      -> S
+        -> _B1X&S&M1
+  interfaces: M1, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B1X&S&M1&M with MX:
+  superclasses:
+    Object
+      -> S
+        -> _B1X&S&M1
+          -> _B1X&S&M1&M
+  interfaces: M1, M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B1X:
+  superclasses:
+    Object
+      -> S
+        -> _B1X&S&M1
+          -> _B1X&S&M1&M
+            -> _B1X&S&M1&M&MX
+  interfaces: M1, M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+S with M1:
+  superclasses:
+    Object
+      -> S
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B2X&S&M1 with M2:
+  superclasses:
+    Object
+      -> S
+        -> _B2X&S&M1
+  interfaces: M1, M2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    S.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B2X&S&M1&M2 with M:
+  superclasses:
+    Object
+      -> S
+        -> _B2X&S&M1
+          -> _B2X&S&M1&M2
+  interfaces: M1, M2, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+_B2X&S&M1&M2&M with MX:
+  superclasses:
+    Object
+      -> S
+        -> _B2X&S&M1
+          -> _B2X&S&M1&M2
+            -> _B2X&S&M1&M2&M
+  interfaces: M1, M2, M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B2X:
+  superclasses:
+    Object
+      -> S
+        -> _B2X&S&M1
+          -> _B2X&S&M1&M2
+            -> _B2X&S&M1&M2&M
+              -> _B2X&S&M1&M2&M&MX
+  interfaces: M1, M2, M, MX
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect b/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
index 52129f0..b5c4a61 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
 //   foo() {}
@@ -119,8 +121,7 @@
 // pkg/front_end/testcases/mixin_application_override.dart:39:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
 // class B2X extends S with M1, M2, M, MX {}
 //       ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
index 381523a..c5a8827 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.legacy.transformed.expect
@@ -1,4 +1,127 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:21:7: Context: Override was introduced in the mixin application class 'A0'.
+// class A0 = S with M;
+//       ^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:22:7: Context: Override was introduced in the mixin application class 'A1'.
+// class A1 = S with M1, M;
+//       ^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:23:7: Context: Override was introduced in the mixin application class 'A2'.
+// class A2 = S with M1, M2, M;
+//       ^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:25:7: Context: Override was introduced when the mixin 'M' was applied to 'S'.
+// class A0X = S with M, MX;
+//       ^^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:26:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1'.
+// class A1X = S with M1, M, MX;
+//       ^^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:27:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
+// class A2X = S with M1, M2, M, MX;
+//       ^^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:29:7: Context: Override was introduced when the mixin 'M' was applied to 'S'.
+// class B0 extends S with M {}
+//       ^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:31:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1'.
+// class B1 extends S with M1, M {}
+//       ^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:33:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
+// class B2 extends S with M1, M2, M {}
+//       ^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:35:7: Context: Override was introduced when the mixin 'M' was applied to 'S'.
+// class B0X extends S with M, MX {}
+//       ^^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:37:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1'.
+// class B1X extends S with M1, M, MX {}
+//       ^^^
+//
+// pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
+//   foo() {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:8:3: Context: This is the overridden method ('foo').
+//   foo([x]) {}
+//   ^
+// pkg/front_end/testcases/mixin_application_override.dart:39:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
+// class B2X extends S with M1, M2, M, MX {}
+//       ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.outline.expect b/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
index 7d607e6..9983cfb 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/mixin_application_override.dart:12:3: Warning: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
 //   foo() {}
@@ -119,8 +121,7 @@
 // pkg/front_end/testcases/mixin_application_override.dart:39:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
 // class B2X extends S with M1, M2, M, MX {}
 //       ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/mixin_application_override.dart.strong.expect b/pkg/front_end/testcases/mixin_application_override.dart.strong.expect
index c8c6a90..879c4c0 100644
--- a/pkg/front_end/testcases/mixin_application_override.dart.strong.expect
+++ b/pkg/front_end/testcases/mixin_application_override.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
 //   foo() {}
@@ -119,58 +121,7 @@
 // pkg/front_end/testcases/mixin_application_override.dart:39:7: Context: Override was introduced when the mixin 'M' was applied to 'S with M1, M2'.
 // class B2X extends S with M1, M2, M, MX {}
 //       ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-//
-// pkg/front_end/testcases/mixin_application_override.dart:12:3: Error: The method 'M.foo' has fewer positional arguments than those of overridden method 'S.foo'.
-//   foo() {}
-//   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart b/pkg/front_end/testcases/mixin_conflicts.dart
new file mode 100644
index 0000000..6afebe0
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 class has no problems.
+class M {
+  foo() {}
+}
+
+// This class has no problems.
+class N = Object with M;
+
+// This class has no problems.
+class C extends Object with N {}
+
+// This class has no problems.
+abstract class M2 implements M {
+  bar() {}
+}
+
+// This class has an error as it lacks an implementation of M.foo.
+class N2 = Object with M2;
+
+// This class lacks an implementation of M.foo, but it is abstract so there's
+// no error.
+abstract class N3 = Object with M2;
+
+// This class has an error as it lacks an implementation of M.foo.
+class C2 extends Object with M2 {}
+
+// This class lacks an implementation of M.foo, but it is abstract so there's
+// no error.
+abstract class C3 extends Object with M2 {}
+
+main() {}
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_conflicts.dart.hierarchy.expect
new file mode 100644
index 0000000..d311de4
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart.hierarchy.expect
@@ -0,0 +1,357 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+N:
+  superclasses:
+    Object
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with N:
+  superclasses:
+    Object
+  interfaces: N, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C:
+  superclasses:
+    Object
+      -> _C&Object&N
+  interfaces: N, M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+M2:
+  superclasses:
+    Object
+  interfaces: M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+N2:
+  superclasses:
+    Object
+  interfaces: M2, M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+N3:
+  superclasses:
+    Object
+  interfaces: M2, M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with M2:
+  superclasses:
+    Object
+  interfaces: M2, M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C2:
+  superclasses:
+    Object
+      -> _C2&Object&M2
+  interfaces: M2, M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with M2:
+  superclasses:
+    Object
+  interfaces: M2, M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C3:
+  superclasses:
+    Object
+      -> _C3&Object&M2
+  interfaces: M2, M
+  classMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M2.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart.legacy.expect b/pkg/front_end/testcases/mixin_conflicts.dart.legacy.expect
new file mode 100644
index 0000000..7c2bfa7
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart.legacy.expect
@@ -0,0 +1,93 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:22:7: Error: The non-abstract class 'N2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class N2 = Object with M2;
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:29:7: Error: The non-abstract class 'C2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C2 extends Object with M2 {}
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+class N = core::Object with self::M {
+  const synthetic constructor •() → self::N
+    : super core::Object::•()
+    ;
+}
+abstract class _C&Object&N = core::Object with self::N {
+  const synthetic constructor •() → self::_C&Object&N
+    : super core::Object::•()
+    ;
+}
+class C extends self::_C&Object&N {
+  synthetic constructor •() → self::C
+    : super self::_C&Object&N::•()
+    ;
+}
+abstract class M2 extends core::Object implements self::M {
+  synthetic constructor •() → self::M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+class N2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::N2
+    : super core::Object::•()
+    ;
+}
+abstract class N3 = core::Object with self::M2 {
+  const synthetic constructor •() → self::N3
+    : super core::Object::•()
+    ;
+}
+abstract class _C2&Object&M2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::_C2&Object&M2
+    : super core::Object::•()
+    ;
+}
+class C2 extends self::_C2&Object&M2 {
+  synthetic constructor •() → self::C2
+    : super self::_C2&Object&M2::•()
+    ;
+}
+abstract class _C3&Object&M2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::_C3&Object&M2
+    : super core::Object::•()
+    ;
+}
+abstract class C3 extends self::_C3&Object&M2 {
+  synthetic constructor •() → self::C3
+    : super self::_C3&Object&M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_conflicts.dart.legacy.transformed.expect
new file mode 100644
index 0000000..7ab1118
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart.legacy.transformed.expect
@@ -0,0 +1,99 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:22:7: Error: The non-abstract class 'N2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class N2 = Object with M2;
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:29:7: Error: The non-abstract class 'C2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C2 extends Object with M2 {}
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+class N extends core::Object implements self::M {
+  const synthetic constructor •() → self::N
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+abstract class _C&Object&N extends core::Object implements self::N {
+  const synthetic constructor •() → self::_C&Object&N
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+class C extends self::_C&Object&N {
+  synthetic constructor •() → self::C
+    : super self::_C&Object&N::•()
+    ;
+}
+abstract class M2 extends core::Object implements self::M {
+  synthetic constructor •() → self::M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+class N2 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::N2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+abstract class N3 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::N3
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+abstract class _C2&Object&M2 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::_C2&Object&M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+class C2 extends self::_C2&Object&M2 {
+  synthetic constructor •() → self::C2
+    : super self::_C2&Object&M2::•()
+    ;
+}
+abstract class _C3&Object&M2 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::_C3&Object&M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+abstract class C3 extends self::_C3&Object&M2 {
+  synthetic constructor •() → self::C3
+    : super self::_C3&Object&M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart.outline.expect b/pkg/front_end/testcases/mixin_conflicts.dart.outline.expect
new file mode 100644
index 0000000..50f14af
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart.outline.expect
@@ -0,0 +1,91 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:22:7: Error: The non-abstract class 'N2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class N2 = Object with M2;
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:29:7: Error: The non-abstract class 'C2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C2 extends Object with M2 {}
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    ;
+  method foo() → dynamic
+    ;
+}
+class N = core::Object with self::M {
+  const synthetic constructor •() → self::N
+    : super core::Object::•()
+    ;
+}
+abstract class _C&Object&N = core::Object with self::N {
+  const synthetic constructor •() → self::_C&Object&N
+    : super core::Object::•()
+    ;
+}
+class C extends self::_C&Object&N {
+  synthetic constructor •() → self::C
+    ;
+}
+abstract class M2 extends core::Object implements self::M {
+  synthetic constructor •() → self::M2
+    ;
+  method bar() → dynamic
+    ;
+}
+class N2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::N2
+    : super core::Object::•()
+    ;
+}
+abstract class N3 = core::Object with self::M2 {
+  const synthetic constructor •() → self::N3
+    : super core::Object::•()
+    ;
+}
+abstract class _C2&Object&M2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::_C2&Object&M2
+    : super core::Object::•()
+    ;
+}
+class C2 extends self::_C2&Object&M2 {
+  synthetic constructor •() → self::C2
+    ;
+}
+abstract class _C3&Object&M2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::_C3&Object&M2
+    : super core::Object::•()
+    ;
+}
+abstract class C3 extends self::_C3&Object&M2 {
+  synthetic constructor •() → self::C3
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart.strong.expect b/pkg/front_end/testcases/mixin_conflicts.dart.strong.expect
new file mode 100644
index 0000000..7c2bfa7
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart.strong.expect
@@ -0,0 +1,93 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:22:7: Error: The non-abstract class 'N2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class N2 = Object with M2;
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:29:7: Error: The non-abstract class 'C2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C2 extends Object with M2 {}
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+class N = core::Object with self::M {
+  const synthetic constructor •() → self::N
+    : super core::Object::•()
+    ;
+}
+abstract class _C&Object&N = core::Object with self::N {
+  const synthetic constructor •() → self::_C&Object&N
+    : super core::Object::•()
+    ;
+}
+class C extends self::_C&Object&N {
+  synthetic constructor •() → self::C
+    : super self::_C&Object&N::•()
+    ;
+}
+abstract class M2 extends core::Object implements self::M {
+  synthetic constructor •() → self::M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+class N2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::N2
+    : super core::Object::•()
+    ;
+}
+abstract class N3 = core::Object with self::M2 {
+  const synthetic constructor •() → self::N3
+    : super core::Object::•()
+    ;
+}
+abstract class _C2&Object&M2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::_C2&Object&M2
+    : super core::Object::•()
+    ;
+}
+class C2 extends self::_C2&Object&M2 {
+  synthetic constructor •() → self::C2
+    : super self::_C2&Object&M2::•()
+    ;
+}
+abstract class _C3&Object&M2 = core::Object with self::M2 {
+  const synthetic constructor •() → self::_C3&Object&M2
+    : super core::Object::•()
+    ;
+}
+abstract class C3 extends self::_C3&Object&M2 {
+  synthetic constructor •() → self::C3
+    : super self::_C3&Object&M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/mixin_conflicts.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_conflicts.dart.strong.transformed.expect
new file mode 100644
index 0000000..7ab1118
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_conflicts.dart.strong.transformed.expect
@@ -0,0 +1,99 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:22:7: Error: The non-abstract class 'N2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class N2 = Object with M2;
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+// pkg/front_end/testcases/mixin_conflicts.dart:29:7: Error: The non-abstract class 'C2' is missing implementations for these members:
+//  - M.foo
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C2 extends Object with M2 {}
+//       ^^
+// pkg/front_end/testcases/mixin_conflicts.dart:7:3: Context: 'M.foo' is defined here.
+//   foo() {}
+//   ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+class N extends core::Object implements self::M {
+  const synthetic constructor •() → self::N
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+abstract class _C&Object&N extends core::Object implements self::N {
+  const synthetic constructor •() → self::_C&Object&N
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {}
+}
+class C extends self::_C&Object&N {
+  synthetic constructor •() → self::C
+    : super self::_C&Object&N::•()
+    ;
+}
+abstract class M2 extends core::Object implements self::M {
+  synthetic constructor •() → self::M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+class N2 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::N2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+abstract class N3 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::N3
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+abstract class _C2&Object&M2 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::_C2&Object&M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+class C2 extends self::_C2&Object&M2 {
+  synthetic constructor •() → self::C2
+    : super self::_C2&Object&M2::•()
+    ;
+}
+abstract class _C3&Object&M2 extends core::Object implements self::M2 {
+  const synthetic constructor •() → self::_C3&Object&M2
+    : super core::Object::•()
+    ;
+  method bar() → dynamic {}
+}
+abstract class C3 extends self::_C3&Object&M2 {
+  synthetic constructor •() → self::C3
+    : super self::_C3&Object&M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.hierarchy.expect
new file mode 100644
index 0000000..78bd7cb
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.hierarchy.expect
@@ -0,0 +1,607 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.trace
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C<String>
+  interfaces: M
+  classMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.trace
+  interfaceMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.trace
+
+E:
+  superclasses:
+    Object
+      -> C<String>
+        -> D
+  interfaces: M
+  classMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.trace
+  interfaceMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.trace
+
+C<int> with M:
+  superclasses:
+    Object
+      -> C<int>
+  interfaces: M
+  classMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.trace
+  interfaceMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.trace
+
+F:
+  superclasses:
+    Object
+      -> C<int>
+        -> _F&C&M
+  interfaces: M
+  classMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.trace
+  interfaceMembers:
+    C.trace
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.trace
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.expect b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.expect
index b9d9373..0e4502f 100644
--- a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.expect
+++ b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class C<T extends core::Object = dynamic> extends core::Object {
   field core::String trace;
   constructor •({dynamic a = 0, dynamic b = self::C::T}) → self::C<self::C::T>
diff --git a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.transformed.expect
index 3e9f1e9..7809f36 100644
--- a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class C<T extends core::Object = dynamic> extends core::Object {
   field core::String trace;
   constructor •({dynamic a = 0, dynamic b = self::C::T}) → self::C<self::C::T>
diff --git a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.outline.expect b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.outline.expect
index 69f8aca..897a4aa 100644
--- a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.outline.expect
+++ b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class C<T extends core::Object = dynamic> extends core::Object {
   field core::String trace;
   constructor •({dynamic a, dynamic b}) → self::C<self::C::T>
diff --git a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.expect b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.expect
index 67701f2..883e7fe 100644
--- a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.expect
+++ b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class C<T extends core::Object = dynamic> extends core::Object {
   field core::String trace;
   constructor •({dynamic a = 0, dynamic b = self::C::T}) → self::C<self::C::T>
diff --git a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.transformed.expect
index e52a7ff..298c8c8 100644
--- a/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/mixin_constructors_with_default_values.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class C<T extends core::Object = dynamic> extends core::Object {
   field core::String trace;
   constructor •({dynamic a = 0, dynamic b = self::C::T}) → self::C<self::C::T>
diff --git a/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.hierarchy.expect
new file mode 100644
index 0000000..56969f8
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.hierarchy.expect
@@ -0,0 +1,166 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._field
+
+D:
+  superclasses:
+    Object
+      -> C<B>
+  interfaces:
+  classMembers:
+    C._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._field
+
+Object with C<B>:
+  superclasses:
+    Object
+  interfaces: C<B>
+  classMembers:
+    C._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._field
+  interfaceMembers:
+    C._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C._field
+
+Foo:
+  superclasses:
+    Object
+      -> _Foo&Object&C
+  interfaces: C<B>
+  classMembers:
+    C._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._field
+  interfaceMembers:
+    C._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C._field
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/mixin_super_repeated.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_super_repeated.dart.hierarchy.expect
new file mode 100644
index 0000000..869bb76
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_super_repeated.dart.hierarchy.expect
@@ -0,0 +1,190 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.m
+
+N:
+  superclasses:
+    Object
+      -> M
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    N.superM
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.m
+    N.superM
+
+S:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+S with M:
+  superclasses:
+    Object
+      -> S
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.m
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.m
+
+_Named&S&M with N:
+  superclasses:
+    Object
+      -> S
+        -> _Named&S&M
+  interfaces: M, N
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    N.superM
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.m
+    N.superM
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    N.superM
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.m
+    N.superM
+
+Named:
+  superclasses:
+    Object
+      -> S
+        -> _Named&S&M
+          -> _Named&S&M&N
+  interfaces: M, N
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    N.superM
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.m
+    N.superM
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    N.superM
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.m
+    N.superM
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart b/pkg/front_end/testcases/mixin_with_static_member.dart
new file mode 100644
index 0000000..27ce9da
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.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.
+
+class A extends B with M {}
+
+class B {
+  final Object m = null;
+}
+
+class M {
+  static Object m() => null;
+}
+
+main() {
+  new A();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.hierarchy.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.hierarchy.expect
new file mode 100644
index 0000000..6eaae17
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.hierarchy.expect
@@ -0,0 +1,120 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B with M:
+  superclasses:
+    Object
+      -> B
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> B
+        -> _A&B&M
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.expect
new file mode 100644
index 0000000..8c1ae5e
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M = self::B with self::M {
+  synthetic constructor •() → self::_A&B&M
+    : super self::B::•()
+    ;
+}
+class A extends self::_A&B&M {
+  synthetic constructor •() → self::A
+    : super self::_A&B&M::•()
+    ;
+}
+class B extends core::Object {
+  final field core::Object m = null;
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  static method m() → core::Object
+    return null;
+}
+static method main() → dynamic {
+  new self::A::•();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.transformed.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.transformed.expect
new file mode 100644
index 0000000..e243b45
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.legacy.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M extends self::B implements self::M {
+  synthetic constructor •() → self::_A&B&M
+    : super self::B::•()
+    ;
+  static method m() → core::Object
+    return null;
+}
+class A extends self::_A&B&M {
+  synthetic constructor •() → self::A
+    : super self::_A&B&M::•()
+    ;
+}
+class B extends core::Object {
+  final field core::Object m = null;
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  static method m() → core::Object
+    return null;
+}
+static method main() → dynamic {
+  new self::A::•();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.outline.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.outline.expect
new file mode 100644
index 0000000..2de8dc52
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.outline.expect
@@ -0,0 +1,26 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M = self::B with self::M {
+  synthetic constructor •() → self::_A&B&M
+    : super self::B::•()
+    ;
+}
+class A extends self::_A&B&M {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends core::Object {
+  final field core::Object m;
+  synthetic constructor •() → self::B
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    ;
+  static method m() → core::Object
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.strong.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.expect
new file mode 100644
index 0000000..8c1ae5e
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M = self::B with self::M {
+  synthetic constructor •() → self::_A&B&M
+    : super self::B::•()
+    ;
+}
+class A extends self::_A&B&M {
+  synthetic constructor •() → self::A
+    : super self::_A&B&M::•()
+    ;
+}
+class B extends core::Object {
+  final field core::Object m = null;
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  static method m() → core::Object
+    return null;
+}
+static method main() → dynamic {
+  new self::A::•();
+}
diff --git a/pkg/front_end/testcases/mixin_with_static_member.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.transformed.expect
new file mode 100644
index 0000000..e243b45
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_with_static_member.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _A&B&M extends self::B implements self::M {
+  synthetic constructor •() → self::_A&B&M
+    : super self::B::•()
+    ;
+  static method m() → core::Object
+    return null;
+}
+class A extends self::_A&B&M {
+  synthetic constructor •() → self::A
+    : super self::_A&B&M::•()
+    ;
+}
+class B extends core::Object {
+  final field core::Object m = null;
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → self::M
+    : super core::Object::•()
+    ;
+  static method m() → core::Object
+    return null;
+}
+static method main() → dynamic {
+  new self::A::•();
+}
diff --git a/pkg/front_end/testcases/named_function_scope.dart.hierarchy.expect b/pkg/front_end/testcases/named_function_scope.dart.hierarchy.expect
new file mode 100644
index 0000000..34408aa
--- /dev/null
+++ b/pkg/front_end/testcases/named_function_scope.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+T:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+V:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/named_function_scope.dart.legacy.expect b/pkg/front_end/testcases/named_function_scope.dart.legacy.expect
index 434f796..5bc6572 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.legacy.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
 //     var x = /*@error=NamedFunctionExpression*/ T() {};
@@ -78,22 +80,7 @@
 // pkg/front_end/testcases/named_function_scope.dart:83:32: Warning: 'T' isn't a type.
 //     void T(/*@error=NotAType*/ T t) {}
 //                                ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
-//     var x = /*@error=NamedFunctionExpression*/ T() {};
-//                                                ^
-//
-// pkg/front_end/testcases/named_function_scope.dart:48:9: Error: A function expression can't have a name.
-//         T() {};
-//         ^
-//
-// pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/named_function_scope.dart.legacy.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.legacy.transformed.expect
index 5a63c13..5bc6572 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.legacy.transformed.expect
@@ -1,18 +1,86 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
 //     var x = /*@error=NamedFunctionExpression*/ T() {};
 //                                                ^
 //
+// pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+//     var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+//                                                 ^
+// pkg/front_end/testcases/named_function_scope.dart:31:52: Context: Previous use of 'V'.
+//     /*@context=DuplicatedNamePreviouslyUsedCause*/ V  v;
+//                                                    ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+//     var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+//                                                 ^
+// pkg/front_end/testcases/named_function_scope.dart:36:52: Context: Previous use of 'V'.
+//     /*@context=DuplicatedNamePreviouslyUsedCause*/ V  v;
+//                                                    ^
+//
 // pkg/front_end/testcases/named_function_scope.dart:48:9: Error: A function expression can't have a name.
 //         T() {};
 //         ^
 //
+// pkg/front_end/testcases/named_function_scope.dart:48:9: Error: Can't declare 'T' because it was already used in this scope.
+//         T() {};
+//         ^
+// pkg/front_end/testcases/named_function_scope.dart:45:9: Context: Previous use of 'T'.
+//         T
+//         ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:54:47: Error: Can't declare 'V' because it was already used in this scope.
+//     V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:54:5: Context: Previous use of 'V'.
+//     V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+//     ^
+//
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
 //         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
-
-library;
+//
+// pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
+//         ^
+// pkg/front_end/testcases/named_function_scope.dart:62:52: Context: Previous declaration of 'T'.
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
+//                                                    ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:67:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:66:5: Context: Previous use of 'T'.
+//     T t;
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:71:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:71:5: Context: Previous use of 'T'.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:76:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:75:5: Context: Previous use of 'T'.
+//     T t;
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:80:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:80:5: Context: Previous use of 'T'.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:83:32: Warning: 'T' isn't a type.
+//     void T(/*@error=NotAType*/ T t) {}
+//                                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
index 4a5f48d..d898d98 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
 //     var x = /*@error=NamedFunctionExpression*/ T() {};
@@ -78,26 +80,7 @@
 // pkg/front_end/testcases/named_function_scope.dart:83:32: Error: 'T' isn't a type.
 //     void T(/*@error=NotAType*/ T t) {}
 //                                ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
-//     var x = /*@error=NamedFunctionExpression*/ T() {};
-//                                                ^
-//
-// pkg/front_end/testcases/named_function_scope.dart:48:9: Error: A function expression can't have a name.
-//         T() {};
-//         ^
-//
-// pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
-//         ^
-//
-// pkg/front_end/testcases/named_function_scope.dart:83:32: Error: 'T' isn't a type.
-//     void T(/*@error=NotAType*/ T t) {}
-//                                ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
index d3e6f09..d898d98 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
@@ -1,22 +1,86 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/named_function_scope.dart:28:48: Error: A function expression can't have a name.
 //     var x = /*@error=NamedFunctionExpression*/ T() {};
 //                                                ^
 //
+// pkg/front_end/testcases/named_function_scope.dart:33:49: Error: Can't declare 'V' because it was already used in this scope.
+//     var /*@error=DuplicatedNamePreviouslyUsed*/ V;
+//                                                 ^
+// pkg/front_end/testcases/named_function_scope.dart:31:52: Context: Previous use of 'V'.
+//     /*@context=DuplicatedNamePreviouslyUsedCause*/ V  v;
+//                                                    ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:38:49: Error: Can't declare 'V' because it was already used in this scope.
+//     var /*@error=DuplicatedNamePreviouslyUsed*/ V = null;
+//                                                 ^
+// pkg/front_end/testcases/named_function_scope.dart:36:52: Context: Previous use of 'V'.
+//     /*@context=DuplicatedNamePreviouslyUsedCause*/ V  v;
+//                                                    ^
+//
 // pkg/front_end/testcases/named_function_scope.dart:48:9: Error: A function expression can't have a name.
 //         T() {};
 //         ^
 //
+// pkg/front_end/testcases/named_function_scope.dart:48:9: Error: Can't declare 'T' because it was already used in this scope.
+//         T() {};
+//         ^
+// pkg/front_end/testcases/named_function_scope.dart:45:9: Context: Previous use of 'T'.
+//         T
+//         ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:54:47: Error: Can't declare 'V' because it was already used in this scope.
+//     V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:54:5: Context: Previous use of 'V'.
+//     V /*@error=DuplicatedNamePreviouslyUsed*/ V;
+//     ^
+//
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
 //         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 //
+// pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
+//         ^
+// pkg/front_end/testcases/named_function_scope.dart:62:52: Context: Previous declaration of 'T'.
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
+//                                                    ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:67:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:66:5: Context: Previous use of 'T'.
+//     T t;
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:71:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:71:5: Context: Previous use of 'T'.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:76:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:75:5: Context: Previous use of 'T'.
+//     T t;
+//     ^
+//
+// pkg/front_end/testcases/named_function_scope.dart:80:47: Error: Can't declare 'T' because it was already used in this scope.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+//                                               ^
+// pkg/front_end/testcases/named_function_scope.dart:80:5: Context: Previous use of 'T'.
+//     T /*@error=DuplicatedNamePreviouslyUsed*/ T(T t) {}
+//     ^
+//
 // pkg/front_end/testcases/named_function_scope.dart:83:32: Error: 'T' isn't a type.
 //     void T(/*@error=NotAType*/ T t) {}
 //                                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/named_parameters.dart.hierarchy.expect b/pkg/front_end/testcases/named_parameters.dart.hierarchy.expect
new file mode 100644
index 0000000..13669a9
--- /dev/null
+++ b/pkg/front_end/testcases/named_parameters.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Superclass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Superclass.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Superclass.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Superclass.namedCallback
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Subclass:
+  superclasses:
+    Object
+      -> Superclass
+  interfaces:
+  classMembers:
+    Subclass.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Subclass.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Subclass.namedCallback
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/native_as_name.dart.hierarchy.expect b/pkg/front_end/testcases/native_as_name.dart.hierarchy.expect
new file mode 100644
index 0000000..cd4caa8
--- /dev/null
+++ b/pkg/front_end/testcases/native_as_name.dart.hierarchy.expect
@@ -0,0 +1,113 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+W:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    W.native
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    W.native
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    X.native
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Y1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Y1.native
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Y2:
+  superclasses:
+    Object
+      -> Y1
+  interfaces:
+  classMembers:
+    Y2.native
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Z:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Z.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Z.f
+    Z.native
diff --git a/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.hierarchy.expect b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.hierarchy.expect
new file mode 100644
index 0000000..305e6c8
--- /dev/null
+++ b/pkg/front_end/testcases/nested_implicit_const_with_env_var.dart.hierarchy.expect
@@ -0,0 +1,73 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    B.baz
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.fun
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.hierarchy.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.hierarchy.expect
new file mode 100644
index 0000000..81e33f7
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.hierarchy.expect
new file mode 100644
index 0000000..0482f3b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I.foo
+
+A:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    I.foo
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    I.foo
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.hierarchy.expect
new file mode 100644
index 0000000..785f78b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_arent_mixed_in.dart.hierarchy.expect
@@ -0,0 +1,134 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.foo
+
+Object with B:
+  superclasses:
+    Object
+  interfaces: B, A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.foo
+
+C:
+  superclasses:
+    Object
+      -> _C&Object&B
+  interfaces: B, A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.foo
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.hierarchy.expect
new file mode 100644
index 0000000..20bc332
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_one_defined.dart.hierarchy.expect
@@ -0,0 +1,168 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.foo
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.foo
+
+D:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    D.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.foo
+
+E:
+  superclasses:
+    Object
+      -> D
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.foo
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    D.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.foo
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.hierarchy.expect
new file mode 100644
index 0000000..71bf144
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_accessors_from_field_with_substitution.dart.hierarchy.expect
@@ -0,0 +1,69 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
+
+B:
+  superclasses:
+    Object
+  interfaces: A<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    A.foo
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.hierarchy.expect
new file mode 100644
index 0000000..6261d75
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/abstract_interface_nsm_inherited.dart.hierarchy.expect
@@ -0,0 +1,85 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.hierarchy.expect
new file mode 100644
index 0000000..5b5669e
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/concrete_method_over_forwarder_in_mixin_application.dart.hierarchy.expect
@@ -0,0 +1,150 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A with B:
+  superclasses:
+    Object
+      -> A
+  interfaces: B, I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> _C&A&B
+  interfaces: B, I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    B.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.hierarchy.expect
new file mode 100644
index 0000000..9c42ba3
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/default_argument_values.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.hest
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.hest
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.hierarchy.expect
new file mode 100644
index 0000000..c3d12b3
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/duplicated_abstract_method.dart.hierarchy.expect
@@ -0,0 +1,85 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I1.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I2.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces: I1, I2
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I1.foo
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.hierarchy.expect
new file mode 100644
index 0000000..2cea300
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/forwarders_not_assumed_from_mixin.dart.hierarchy.expect
@@ -0,0 +1,128 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with A:
+  superclasses:
+    Object
+  interfaces: A, I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B:
+  superclasses:
+    Object
+      -> _B&Object&A
+  interfaces: A, I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.hierarchy.expect
new file mode 100644
index 0000000..6261d75
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_concrete.dart.hierarchy.expect
@@ -0,0 +1,85 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.hierarchy.expect
new file mode 100644
index 0000000..8b453b8
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/interface_with_nsm.dart.hierarchy.expect
@@ -0,0 +1,174 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    I.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with M:
+  superclasses:
+    Object
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&M
+  interfaces: M, I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Object with M:
+  superclasses:
+    Object
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B:
+  superclasses:
+    Object
+      -> _B&Object&M
+  interfaces: M, I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.hierarchy.expect
new file mode 100644
index 0000000..a8ba41a
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.hierarchy.expect
new file mode 100644
index 0000000..5d65360
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/no_forwarders_for_abstract_classes_chain.dart.hierarchy.expect
@@ -0,0 +1,97 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> A
+        -> B
+          -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.hierarchy.expect
new file mode 100644
index 0000000..19ca4af
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_inherited.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+      -> M
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.call
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.hierarchy.expect
new file mode 100644
index 0000000..254f85b
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/nsm_mixed_in.dart.hierarchy.expect
@@ -0,0 +1,97 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with A:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+B:
+  superclasses:
+    Object
+      -> _B&Object&A
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.hierarchy.expect
new file mode 100644
index 0000000..1f17e70
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.hierarchy.expect
@@ -0,0 +1,118 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Fisk._hest
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+      -> Foo
+  interfaces: Fisk
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Fisk._hest
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Baz:
+  superclasses:
+    Object
+      -> Foo
+  interfaces: Fisk
+  classMembers:
+    Baz._hest
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Baz._hest
+    Fisk._hest
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect
index 4c251bf..214711b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_module.dart" as pri;
 
+import "org-dartlang-testcase:///private_module.dart";
+
 abstract class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -27,3 +29,15 @@
     return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
+
+library private_module;
+import self as pri;
+import "dart:core" as core;
+
+abstract class Fisk extends core::Object {
+  synthetic constructor •() → pri::Fisk
+    : super core::Object::•()
+    ;
+  abstract method _hest() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect
index 4c251bf..214711b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_module.dart" as pri;
 
+import "org-dartlang-testcase:///private_module.dart";
+
 abstract class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -27,3 +29,15 @@
     return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
+
+library private_module;
+import self as pri;
+import "dart:core" as core;
+
+abstract class Fisk extends core::Object {
+  synthetic constructor •() → pri::Fisk
+    : super core::Object::•()
+    ;
+  abstract method _hest() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
index 86c64e1..6270b7f 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_module.dart" as pri;
 
+import "org-dartlang-testcase:///private_module.dart";
+
 abstract class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     ;
@@ -25,3 +27,15 @@
 }
 static method main() → dynamic
   ;
+
+library private_module;
+import self as pri;
+import "dart:core" as core;
+
+abstract class Fisk extends core::Object {
+  synthetic constructor •() → pri::Fisk
+    ;
+  abstract method _hest() → void;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
index 4c251bf..214711b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_module.dart" as pri;
 
+import "org-dartlang-testcase:///private_module.dart";
+
 abstract class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -27,3 +29,15 @@
     return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
+
+library private_module;
+import self as pri;
+import "dart:core" as core;
+
+abstract class Fisk extends core::Object {
+  synthetic constructor •() → pri::Fisk
+    : super core::Object::•()
+    ;
+  abstract method _hest() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
index 4c251bf..214711b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_module.dart" as pri;
 
+import "org-dartlang-testcase:///private_module.dart";
+
 abstract class Foo extends core::Object {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -27,3 +29,15 @@
     return this.{self::Foo::noSuchMethod}(new core::_InvocationMirror::_withType(#_hest, 0, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
 static method main() → dynamic {}
+
+library private_module;
+import self as pri;
+import "dart:core" as core;
+
+abstract class Fisk extends core::Object {
+  synthetic constructor •() → pri::Fisk
+    : super core::Object::•()
+    ;
+  abstract method _hest() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.hierarchy.expect
new file mode 100644
index 0000000..085b915
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_module.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Fisk._hest
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.hierarchy.expect
new file mode 100644
index 0000000..df52b51
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/private_same.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo._foo
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+      -> Foo
+  interfaces:
+  classMembers:
+    Foo._foo
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Bar.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/same.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.hierarchy.expect
new file mode 100644
index 0000000..9553f89
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/same.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.hierarchy.expect
new file mode 100644
index 0000000..c2e82ad
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.foo
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.expect
index 6742c9b..8fef0c1 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Error: 'foo' is already declared in this scope.
 //   void set foo(int x);
@@ -6,14 +8,7 @@
 // pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Context: Previous declaration of 'foo'.
 //   void foo(int x) {}
 //        ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Error: 'foo' is already declared in this scope.
-//   void set foo(int x);
-//            ^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.transformed.expect
index e9e7677..8fef0c1 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.legacy.transformed.expect
@@ -1,10 +1,14 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Error: 'foo' is already declared in this scope.
 //   void set foo(int x);
 //            ^^^
-
-library;
+// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Context: Previous declaration of 'foo'.
+//   void foo(int x) {}
+//        ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.outline.expect
index d8c8b38..f87c303 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Error: 'foo' is already declared in this scope.
 //   void set foo(int x);
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Context: Previous declaration of 'foo'.
 //   void foo(int x) {}
 //        ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.expect
index e055260..8fef0c1 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.expect
@@ -1,19 +1,14 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Error: Can't declare a member that conflicts with an inherited one.
-//   void foo(int x) {}
-//        ^
-// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Context: This is the inherited member.
-//   void set foo(int x);
-//            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Error: Can't declare a member that conflicts with an inherited one.
-//   void foo(int x) {}
-//        ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Error: 'foo' is already declared in this scope.
+//   void set foo(int x);
+//            ^^^
+// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Context: Previous declaration of 'foo'.
+//   void foo(int x) {}
+//        ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.transformed.expect
index f8ff1c7..8fef0c1 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart.strong.transformed.expect
@@ -1,10 +1,14 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Error: Can't declare a member that conflicts with an inherited one.
-//   void foo(int x) {}
-//        ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:12:12: Error: 'foo' is already declared in this scope.
+//   void set foo(int x);
+//            ^^^
+// pkg/front_end/testcases/no_such_method_forwarders/setter_not_shadowed_by_method.dart:10:8: Context: Previous declaration of 'foo'.
+//   void foo(int x) {}
+//        ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.hierarchy.expect
new file mode 100644
index 0000000..3227a6f
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.hierarchy.expect
@@ -0,0 +1,114 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Object with M:
+  superclasses:
+    Object
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&M
+  interfaces: M, I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    I.foo
+    M.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.hierarchy.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..dba9cc0
--- /dev/null
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.hierarchy.expect
@@ -0,0 +1,69 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Bar._x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Bar._x
+
+Foo:
+  superclasses:
+    Object
+  interfaces: Bar
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Bar._x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Bar._x
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect
index 11bb91d..52f88c4 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./no_such_method_private_setter_lib.dart" as no_;
 
+import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
+
 class Foo extends core::Object implements no_::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -15,3 +17,17 @@
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
 }
+
+library;
+import self as no_;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  field core::int _x = null;
+  synthetic constructor •() → no_::Bar
+    : super core::Object::•()
+    ;
+}
+static method baz(no_::Bar bar) → void {
+  return;
+}
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect
index 11bb91d..52f88c4 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./no_such_method_private_setter_lib.dart" as no_;
 
+import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
+
 class Foo extends core::Object implements no_::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -15,3 +17,17 @@
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
 }
+
+library;
+import self as no_;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  field core::int _x = null;
+  synthetic constructor •() → no_::Bar
+    : super core::Object::•()
+    ;
+}
+static method baz(no_::Bar bar) → void {
+  return;
+}
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect
index 52f1cb7..78df3aa 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./no_such_method_private_setter_lib.dart" as no_;
 
+import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
+
 class Foo extends core::Object implements no_::Bar {
   synthetic constructor •() → self::Foo
     ;
@@ -13,3 +15,15 @@
 }
 static method main() → dynamic
   ;
+
+library;
+import self as no_;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  field core::int _x;
+  synthetic constructor •() → no_::Bar
+    ;
+}
+static method baz(no_::Bar bar) → void
+  ;
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect
index 11bb91d..52f88c4 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./no_such_method_private_setter_lib.dart" as no_;
 
+import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
+
 class Foo extends core::Object implements no_::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -15,3 +17,17 @@
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
 }
+
+library;
+import self as no_;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  field core::int _x = null;
+  synthetic constructor •() → no_::Bar
+    : super core::Object::•()
+    ;
+}
+static method baz(no_::Bar bar) → void {
+  return;
+}
diff --git a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect
index 11bb91d..52f88c4 100644
--- a/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_private_setter.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./no_such_method_private_setter_lib.dart" as no_;
 
+import "org-dartlang-testcase:///no_such_method_private_setter_lib.dart";
+
 class Foo extends core::Object implements no_::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -15,3 +17,17 @@
 static method main() → dynamic {
   no_::baz(new self::Foo::•());
 }
+
+library;
+import self as no_;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  field core::int _x = null;
+  synthetic constructor •() → no_::Bar
+    : super core::Object::•()
+    ;
+}
+static method baz(no_::Bar bar) → void {
+  return;
+}
diff --git a/pkg/front_end/testcases/null_aware.dart.hierarchy.expect b/pkg/front_end/testcases/null_aware.dart.hierarchy.expect
new file mode 100644
index 0000000..a148c36
--- /dev/null
+++ b/pkg/front_end/testcases/null_aware.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.field
+    Object._instanceOf
+    Foo.staticField
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.field
+    Foo.staticField
diff --git a/pkg/front_end/testcases/operators.dart.hierarchy.expect b/pkg/front_end/testcases/operators.dart.hierarchy.expect
new file mode 100644
index 0000000..dbcbcec
--- /dev/null
+++ b/pkg/front_end/testcases/operators.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Operators:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Operators.~/
+    Operators.<=
+    Operators.<
+    Operators.[]=
+    Object.toString
+    Operators.+
+    Operators.unary-
+    Operators.>=
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Operators./
+    Operators.|
+    Operators.<<
+    Object._instanceOf
+    Operators.%
+    Operators.>>
+    Object.noSuchMethod
+    Object._identityHashCode
+    Operators.>
+    Operators.[]
+    Object.hashCode
+    Operators.^
+    Operators.&
+    Operators.-
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Operators.==
+    Operators.*
+    Operators.~
+  classSetters:
diff --git a/pkg/front_end/testcases/optional.dart.hierarchy.expect b/pkg/front_end/testcases/optional.dart.hierarchy.expect
new file mode 100644
index 0000000..7cc8746
--- /dev/null
+++ b/pkg/front_end/testcases/optional.dart.hierarchy.expect
@@ -0,0 +1,130 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+External:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    External.externalMethod
+    External.listen
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Listener:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Listener.event
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+TestListener:
+  superclasses:
+    Object
+      -> Listener
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    TestListener.event
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExtendedListener:
+  superclasses:
+    Object
+      -> Listener
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    ExtendedListener.event
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+InvalidListener:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    InvalidListener.event
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/optional.dart.strong.expect b/pkg/front_end/testcases/optional.dart.strong.expect
index 2cb7a7c..d74b9fc 100644
--- a/pkg/front_end/testcases/optional.dart.strong.expect
+++ b/pkg/front_end/testcases/optional.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/optional.dart:47:21: Error: The argument type 'InvalidListener' can't be assigned to the parameter type 'Listener'.
 //  - 'InvalidListener' is from 'pkg/front_end/testcases/optional.dart'.
@@ -24,28 +26,7 @@
 // Try removing the extra positional arguments.
 //   var nothing4 = extern.externalMethod(1, 2, 3, 4);
 //                                       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/optional.dart:49:28: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing1 = foo.method();
-//                            ^
-//
-// pkg/front_end/testcases/optional.dart:50:28: Error: Too many positional arguments: 3 allowed, but 4 found.
-// Try removing the extra positional arguments.
-//   var nothing2 = foo.method(1, 2, 3, 4);
-//                            ^
-//
-// pkg/front_end/testcases/optional.dart:51:39: Error: Too few positional arguments: 1 required, 0 given.
-//   var nothing3 = extern.externalMethod();
-//                                       ^
-//
-// pkg/front_end/testcases/optional.dart:52:39: Error: Too many positional arguments: 3 allowed, but 4 found.
-// Try removing the extra positional arguments.
-//   var nothing4 = extern.externalMethod(1, 2, 3, 4);
-//                                       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/override.dart.hierarchy.expect b/pkg/front_end/testcases/override.dart.hierarchy.expect
new file mode 100644
index 0000000..94de712
--- /dev/null
+++ b/pkg/front_end/testcases/override.dart.hierarchy.expect
@@ -0,0 +1,91 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+      -> Foo
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Base.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Sub:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Sub.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..4329ec3
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.hierarchy.expect
@@ -0,0 +1,135 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    D.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    E.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+
+F:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    F.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    F.x
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.strong.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.strong.expect
index 12a28da..e11b390 100644
--- a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/override_check_accessor_after_inference.dart:28:51: Error: The return type of the method 'F.y' is 'A', which does not match the return type of the overridden method, 'B'.
 //  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_after_inference.dart'.
@@ -19,24 +21,7 @@
 // pkg/front_end/testcases/override_check_accessor_after_inference.dart:17:12: Context: This is the overridden method ('x').
 //   void set x(value) {} // Inferred type: A
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/override_check_accessor_after_inference.dart:28:51: Error: The return type of the method 'F.y' is 'A', which does not match the return type of the overridden method, 'B'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_after_inference.dart'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_accessor_after_inference.dart'.
-// Change to a subtype of 'B'.
-//   A get /*@error=OverrideTypeMismatchReturnType*/ y => null;
-//                                                   ^
-//
-// pkg/front_end/testcases/override_check_accessor_after_inference.dart:27:57: Error: The parameter 'value' of the method 'F.x' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_accessor_after_inference.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_after_inference.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void set x(B /*@error=OverrideTypeMismatchParameter*/ value) {}
-//                                                         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/override_check_accessor_basic.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_accessor_basic.dart.hierarchy.expect
new file mode 100644
index 0000000..44256be
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_accessor_basic.dart.hierarchy.expect
@@ -0,0 +1,113 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    D.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    E.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
diff --git a/pkg/front_end/testcases/override_check_accessor_basic.dart.strong.expect b/pkg/front_end/testcases/override_check_accessor_basic.dart.strong.expect
index edd9a2f..055f4f6 100644
--- a/pkg/front_end/testcases/override_check_accessor_basic.dart.strong.expect
+++ b/pkg/front_end/testcases/override_check_accessor_basic.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/override_check_accessor_basic.dart:23:56: Error: The return type of the method 'E.y' is 'Object', which does not match the return type of the overridden method, 'A'.
 //  - 'Object' is from 'dart:core'.
@@ -19,24 +21,7 @@
 // pkg/front_end/testcases/override_check_accessor_basic.dart:12:12: Context: This is the overridden method ('x').
 //   void set x(A value) {}
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/override_check_accessor_basic.dart:23:56: Error: The return type of the method 'E.y' is 'Object', which does not match the return type of the overridden method, 'A'.
-//  - 'Object' is from 'dart:core'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_basic.dart'.
-// Change to a subtype of 'A'.
-//   Object get /*@error=OverrideTypeMismatchReturnType*/ y => null;
-//                                                        ^
-//
-// pkg/front_end/testcases/override_check_accessor_basic.dart:22:57: Error: The parameter 'value' of the method 'E.x' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_accessor_basic.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_basic.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void set x(B /*@error=OverrideTypeMismatchParameter*/ value) {}
-//                                                         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.hierarchy.expect
new file mode 100644
index 0000000..354b6fb
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x4
+    C.x6
+    C.x3
+    C.x2
+    C.x5
+    C.x1
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x4
+    D.x6
+    D.x3
+    D.x2
+    D.x5
+    D.x1
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.strong.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.strong.expect
index 4481746..5fa7ead 100644
--- a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.strong.expect
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart:25:50: Error: The parameter 'value' of the method 'D.x4' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
 //  - 'B' is from 'pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart'.
@@ -18,23 +20,7 @@
 // pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart:16:12: Context: This is the overridden method ('x5').
 //   void set x5(covariant A value) {}
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart:25:50: Error: The parameter 'value' of the method 'D.x4' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//       B /*@error=OverrideTypeMismatchParameter*/ value) {} // Not covariant
-//                                                  ^
-//
-// pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart:27:65: Error: The parameter 'value' of the method 'D.x5' has type 'String', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//       covariant String /*@error=OverrideTypeMismatchParameter*/ value) {}
-//                                                                 ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_after_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..41e4732
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.hierarchy.expect
@@ -0,0 +1,131 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    E.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    F.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.strong.expect b/pkg/front_end/testcases/override_check_after_inference.dart.strong.expect
index d99ce0b..5e5e5ac 100644
--- a/pkg/front_end/testcases/override_check_after_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/override_check_after_inference.dart:24:53: Error: The parameter 'x' of the method 'F.f' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
 //  - 'B' is from 'pkg/front_end/testcases/override_check_after_inference.dart'.
@@ -9,17 +11,7 @@
 // pkg/front_end/testcases/override_check_after_inference.dart:16:8: Context: This is the overridden method ('f').
 //   void f(x) {} // Inferred type: (A) -> void
 //        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/override_check_after_inference.dart:24:53: Error: The parameter 'x' of the method 'F.f' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_after_inference.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_after_inference.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void f(B /*@error=OverrideTypeMismatchParameter*/ x) {}
-//                                                     ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/override_check_basic.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_basic.dart.hierarchy.expect
new file mode 100644
index 0000000..95f961a
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_basic.dart.hierarchy.expect
@@ -0,0 +1,119 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.f4
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f3
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    D.f4
+    Object._instanceOf
+    Object.noSuchMethod
+    D.f3
+    D.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.f2
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    E.f4
+    Object._instanceOf
+    Object.noSuchMethod
+    E.f3
+    E.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    E.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/override_check_basic.dart.strong.expect b/pkg/front_end/testcases/override_check_basic.dart.strong.expect
index c30602c..7810d9b 100644
--- a/pkg/front_end/testcases/override_check_basic.dart.strong.expect
+++ b/pkg/front_end/testcases/override_check_basic.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/override_check_basic.dart:29:52: Error: The return type of the method 'E.f4' is 'Object', which does not match the return type of the overridden method, 'A'.
 //  - 'Object' is from 'dart:core'.
@@ -39,38 +41,7 @@
 // pkg/front_end/testcases/override_check_basic.dart:13:8: Context: This is the overridden method ('f2').
 //   void f2([A x]) {}
 //        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/override_check_basic.dart:29:52: Error: The return type of the method 'E.f4' is 'Object', which does not match the return type of the overridden method, 'A'.
-//  - 'Object' is from 'dart:core'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-// Change to a subtype of 'A'.
-//   Object /*@error=OverrideTypeMismatchReturnType*/ f4() {}
-//                                                    ^
-//
-// pkg/front_end/testcases/override_check_basic.dart:28:55: Error: The parameter 'x' of the method 'E.f3' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void f3({B /*@error=OverrideTypeMismatchParameter*/ x}) {}
-//                                                       ^
-//
-// pkg/front_end/testcases/override_check_basic.dart:26:54: Error: The parameter 'x' of the method 'E.f1' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void f1(B /*@error=OverrideTypeMismatchParameter*/ x) {}
-//                                                      ^
-//
-// pkg/front_end/testcases/override_check_basic.dart:27:55: Error: The parameter 'x' of the method 'E.f2' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_basic.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void f2([B /*@error=OverrideTypeMismatchParameter*/ x]) {}
-//                                                       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.hierarchy.expect
new file mode 100644
index 0000000..98db882
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_generic_method_f_bounded.dart.hierarchy.expect
@@ -0,0 +1,85 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Bar.fisk
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces: Bar
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Hest.fisk
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Hest.fisk
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.hierarchy.expect
new file mode 100644
index 0000000..5f6f0b2
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A<String>
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.hierarchy.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.hierarchy.expect
new file mode 100644
index 0000000..c4eb6f1
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.hierarchy.expect
@@ -0,0 +1,101 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f6
+    Object.toString
+    C.f5
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.f4
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f3
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    D.f6
+    Object.toString
+    D.f5
+    Object.runtimeType
+    Object._simpleInstanceOf
+    D.f4
+    Object._instanceOf
+    Object.noSuchMethod
+    D.f3
+    D.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.strong.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.strong.expect
index fc5cda4..96fcfd3 100644
--- a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.strong.expect
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/override_check_with_covariant_modifier.dart:25:69: Error: The parameter 'x' of the method 'D.f5' has type 'String', which does not match the corresponding type in the overridden method, 'A'.
 //  - 'A' is from 'pkg/front_end/testcases/override_check_with_covariant_modifier.dart'.
@@ -18,23 +20,7 @@
 // pkg/front_end/testcases/override_check_with_covariant_modifier.dart:15:8: Context: This is the overridden method ('f4').
 //   void f4(A x) {}
 //        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/override_check_with_covariant_modifier.dart:25:69: Error: The parameter 'x' of the method 'D.f5' has type 'String', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_with_covariant_modifier.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void f5(covariant String /*@error=OverrideTypeMismatchParameter*/ x) {}
-//                                                                     ^
-//
-// pkg/front_end/testcases/override_check_with_covariant_modifier.dart:24:54: Error: The parameter 'x' of the method 'D.f4' has type 'B', which does not match the corresponding type in the overridden method, 'A'.
-//  - 'B' is from 'pkg/front_end/testcases/override_check_with_covariant_modifier.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/override_check_with_covariant_modifier.dart'.
-// Change to a supertype of 'A', or, for a covariant parameter, a subtype.
-//   void f4(B /*@error=OverrideTypeMismatchParameter*/ x) {} // Not covariant
-//                                                      ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/part_as_entry_point.dart.legacy.expect b/pkg/front_end/testcases/part_as_entry_point.dart.legacy.expect
index fea7b39..b77b0c2 100644
--- a/pkg/front_end/testcases/part_as_entry_point.dart.legacy.expect
+++ b/pkg/front_end/testcases/part_as_entry_point.dart.legacy.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part part_as_entry_point.dart;
 static method main() → dynamic {
   core::print("Hello, World!");
 }
diff --git a/pkg/front_end/testcases/part_as_entry_point.dart.legacy.transformed.expect b/pkg/front_end/testcases/part_as_entry_point.dart.legacy.transformed.expect
index fea7b39..b77b0c2 100644
--- a/pkg/front_end/testcases/part_as_entry_point.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/part_as_entry_point.dart.legacy.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part part_as_entry_point.dart;
 static method main() → dynamic {
   core::print("Hello, World!");
 }
diff --git a/pkg/front_end/testcases/part_as_entry_point.dart.outline.expect b/pkg/front_end/testcases/part_as_entry_point.dart.outline.expect
index 6a28c0d..1d93518 100644
--- a/pkg/front_end/testcases/part_as_entry_point.dart.outline.expect
+++ b/pkg/front_end/testcases/part_as_entry_point.dart.outline.expect
@@ -1,5 +1,6 @@
 library;
 import self as self;
 
+part part_as_entry_point.dart;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/part_as_entry_point.dart.strong.expect b/pkg/front_end/testcases/part_as_entry_point.dart.strong.expect
index fea7b39..b77b0c2 100644
--- a/pkg/front_end/testcases/part_as_entry_point.dart.strong.expect
+++ b/pkg/front_end/testcases/part_as_entry_point.dart.strong.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part part_as_entry_point.dart;
 static method main() → dynamic {
   core::print("Hello, World!");
 }
diff --git a/pkg/front_end/testcases/part_as_entry_point.dart.strong.transformed.expect b/pkg/front_end/testcases/part_as_entry_point.dart.strong.transformed.expect
index fea7b39..b77b0c2 100644
--- a/pkg/front_end/testcases/part_as_entry_point.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/part_as_entry_point.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part part_as_entry_point.dart;
 static method main() → dynamic {
   core::print("Hello, World!");
 }
diff --git a/pkg/front_end/testcases/part_not_part_of.dart b/pkg/front_end/testcases/part_not_part_of.dart
new file mode 100644
index 0000000..a4d4873
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'part_not_part_of_lib2.dart';
+
+@override
+part 'part_not_part_of_lib1.dart';
+
+main() {}
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect b/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect
new file mode 100644
index 0000000..a057f8b
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of.dart.legacy.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of.dart:8:6: Error: Can't use 'pkg/front_end/testcases/part_not_part_of_lib1.dart' as a part, because it has no 'part of' declaration.
+// part 'part_not_part_of_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_lib2.dart";
+
+@core::override
+part part_not_part_of_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "./part_not_part_of_lib1.dart" as par;
+
+import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
+
+static method methodFromLib2() → dynamic {
+  par::methodFromLib1();
+}
+
+library;
+import self as par;
+
+static method methodFromLib1() → dynamic {}
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect b/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect
new file mode 100644
index 0000000..a057f8b
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of.dart.legacy.transformed.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of.dart:8:6: Error: Can't use 'pkg/front_end/testcases/part_not_part_of_lib1.dart' as a part, because it has no 'part of' declaration.
+// part 'part_not_part_of_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_lib2.dart";
+
+@core::override
+part part_not_part_of_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "./part_not_part_of_lib1.dart" as par;
+
+import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
+
+static method methodFromLib2() → dynamic {
+  par::methodFromLib1();
+}
+
+library;
+import self as par;
+
+static method methodFromLib1() → dynamic {}
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.outline.expect b/pkg/front_end/testcases/part_not_part_of.dart.outline.expect
new file mode 100644
index 0000000..7e879ea
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of.dart:8:6: Error: Can't use 'pkg/front_end/testcases/part_not_part_of_lib1.dart' as a part, because it has no 'part of' declaration.
+// part 'part_not_part_of_lib1.dart';
+//      ^
+//
+import self as self;
+
+import "org-dartlang-testcase:///part_not_part_of_lib2.dart";
+
+part part_not_part_of_lib1.dart;
+static method main() → dynamic
+  ;
+
+library;
+import self as self2;
+
+import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
+
+static method methodFromLib2() → dynamic
+  ;
+
+library;
+import self as self3;
+
+static method methodFromLib1() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.strong.expect b/pkg/front_end/testcases/part_not_part_of.dart.strong.expect
new file mode 100644
index 0000000..a057f8b
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of.dart.strong.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of.dart:8:6: Error: Can't use 'pkg/front_end/testcases/part_not_part_of_lib1.dart' as a part, because it has no 'part of' declaration.
+// part 'part_not_part_of_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_lib2.dart";
+
+@core::override
+part part_not_part_of_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "./part_not_part_of_lib1.dart" as par;
+
+import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
+
+static method methodFromLib2() → dynamic {
+  par::methodFromLib1();
+}
+
+library;
+import self as par;
+
+static method methodFromLib1() → dynamic {}
diff --git a/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect b/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect
new file mode 100644
index 0000000..a057f8b
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of.dart:8:6: Error: Can't use 'pkg/front_end/testcases/part_not_part_of_lib1.dart' as a part, because it has no 'part of' declaration.
+// part 'part_not_part_of_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_lib2.dart";
+
+@core::override
+part part_not_part_of_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+import "./part_not_part_of_lib1.dart" as par;
+
+import "org-dartlang-testcase:///part_not_part_of_lib1.dart";
+
+static method methodFromLib2() → dynamic {
+  par::methodFromLib1();
+}
+
+library;
+import self as par;
+
+static method methodFromLib1() → dynamic {}
diff --git a/pkg/front_end/testcases/part_not_part_of_lib1.dart b/pkg/front_end/testcases/part_not_part_of_lib1.dart
new file mode 100644
index 0000000..08b4fd0
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_lib1.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+methodFromLib1() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_not_part_of_lib2.dart b/pkg/front_end/testcases/part_not_part_of_lib2.dart
new file mode 100644
index 0000000..1892ce6
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_lib2.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 "part_not_part_of_lib1.dart";
+
+methodFromLib2() {
+  methodFromLib1();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library.dart b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart
new file mode 100644
index 0000000..e7efc6c
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '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/part_not_part_of_same_named_library.dart.legacy.expect b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.legacy.expect
new file mode 100644
index 0000000..4a5e01d
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.legacy.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of_same_named_library.dart:8:6: Warning: Using 'pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart' as part of 'pkg/front_end/testcases/part_not_part_of_same_named_library.dart' but its 'part of' declaration says 'foo'.
+// Try changing the 'part of' declaration to use a relative file name.
+// part 'part_not_part_of_same_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_same_named_library_lib2.dart";
+
+@core::override
+part part_not_part_of_same_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library foo;
+import self as self2;
+
+part part_not_part_of_same_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_not_part_of_same_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.legacy.transformed.expect b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.legacy.transformed.expect
new file mode 100644
index 0000000..4a5e01d
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.legacy.transformed.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of_same_named_library.dart:8:6: Warning: Using 'pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart' as part of 'pkg/front_end/testcases/part_not_part_of_same_named_library.dart' but its 'part of' declaration says 'foo'.
+// Try changing the 'part of' declaration to use a relative file name.
+// part 'part_not_part_of_same_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_same_named_library_lib2.dart";
+
+@core::override
+part part_not_part_of_same_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library foo;
+import self as self2;
+
+part part_not_part_of_same_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_not_part_of_same_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.outline.expect b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.outline.expect
new file mode 100644
index 0000000..a32297c
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.outline.expect
@@ -0,0 +1,25 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of_same_named_library.dart:8:6: Warning: Using 'pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart' as part of 'pkg/front_end/testcases/part_not_part_of_same_named_library.dart' but its 'part of' declaration says 'foo'.
+// Try changing the 'part of' declaration to use a relative file name.
+// part 'part_not_part_of_same_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+
+import "org-dartlang-testcase:///part_not_part_of_same_named_library_lib2.dart";
+
+part part_not_part_of_same_named_library_lib1.dart;
+static method main() → dynamic
+  ;
+
+library foo;
+import self as self2;
+
+part part_not_part_of_same_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_not_part_of_same_named_library_lib1.dart */ methodFromLib1() → dynamic
+  ;
+static method methodFromLib2() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.strong.expect b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.strong.expect
new file mode 100644
index 0000000..7426670
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.strong.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of_same_named_library.dart:8:6: Error: Using 'pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart' as part of 'pkg/front_end/testcases/part_not_part_of_same_named_library.dart' but its 'part of' declaration says 'foo'.
+// Try changing the 'part of' declaration to use a relative file name.
+// part 'part_not_part_of_same_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_same_named_library_lib2.dart";
+
+@core::override
+part part_not_part_of_same_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library foo;
+import self as self2;
+
+part part_not_part_of_same_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_not_part_of_same_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.strong.transformed.expect b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.strong.transformed.expect
new file mode 100644
index 0000000..7426670
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_not_part_of_same_named_library.dart:8:6: Error: Using 'pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart' as part of 'pkg/front_end/testcases/part_not_part_of_same_named_library.dart' but its 'part of' declaration says 'foo'.
+// Try changing the 'part of' declaration to use a relative file name.
+// part 'part_not_part_of_same_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_not_part_of_same_named_library_lib2.dart";
+
+@core::override
+part part_not_part_of_same_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library foo;
+import self as self2;
+
+part part_not_part_of_same_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_not_part_of_same_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart b/pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.dart
new file mode 100644
index 0000000..00b69ee
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library_lib1.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.
+
+part of foo;
+
+methodFromLib1() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_not_part_of_same_named_library_lib2.dart b/pkg/front_end/testcases/part_not_part_of_same_named_library_lib2.dart
new file mode 100644
index 0000000..97fffd5
--- /dev/null
+++ b/pkg/front_end/testcases/part_not_part_of_same_named_library_lib2.dart
@@ -0,0 +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.
+
+library foo;
+
+part "part_not_part_of_same_named_library_lib1.dart";
+
+methodFromLib2() {
+  methodFromLib1();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart
new file mode 100644
index 0000000..07ccc7a
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '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/part_part_of_different_unnamed_library.dart.legacy.expect b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.legacy.expect
new file mode 100644
index 0000000..85e680d
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.legacy.expect
@@ -0,0 +1,25 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_different_unnamed_library.dart:8:6: Warning: Using 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart' as part of 'pkg/front_end/testcases/part_part_of_different_unnamed_library.dart' but its 'part of' declaration says 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart'.
+// part 'part_part_of_different_unnamed_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_different_unnamed_library_lib2.dart";
+
+@core::override
+part part_part_of_different_unnamed_library_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+part part_part_of_different_unnamed_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_different_unnamed_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.legacy.transformed.expect b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.legacy.transformed.expect
new file mode 100644
index 0000000..85e680d
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.legacy.transformed.expect
@@ -0,0 +1,25 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_different_unnamed_library.dart:8:6: Warning: Using 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart' as part of 'pkg/front_end/testcases/part_part_of_different_unnamed_library.dart' but its 'part of' declaration says 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart'.
+// part 'part_part_of_different_unnamed_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_different_unnamed_library_lib2.dart";
+
+@core::override
+part part_part_of_different_unnamed_library_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+part part_part_of_different_unnamed_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_different_unnamed_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.outline.expect b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.outline.expect
new file mode 100644
index 0000000..fbd6f45
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.outline.expect
@@ -0,0 +1,24 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_different_unnamed_library.dart:8:6: Warning: Using 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart' as part of 'pkg/front_end/testcases/part_part_of_different_unnamed_library.dart' but its 'part of' declaration says 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart'.
+// part 'part_part_of_different_unnamed_library_lib1.dart';
+//      ^
+//
+import self as self;
+
+import "org-dartlang-testcase:///part_part_of_different_unnamed_library_lib2.dart";
+
+part part_part_of_different_unnamed_library_lib1.dart;
+static method main() → dynamic
+  ;
+
+library;
+import self as self2;
+
+part part_part_of_different_unnamed_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_different_unnamed_library_lib1.dart */ methodFromLib1() → dynamic
+  ;
+static method methodFromLib2() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.strong.expect b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.strong.expect
new file mode 100644
index 0000000..1fb79ff
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.strong.expect
@@ -0,0 +1,25 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_different_unnamed_library.dart:8:6: Error: Using 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart' as part of 'pkg/front_end/testcases/part_part_of_different_unnamed_library.dart' but its 'part of' declaration says 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart'.
+// part 'part_part_of_different_unnamed_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_different_unnamed_library_lib2.dart";
+
+@core::override
+part part_part_of_different_unnamed_library_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+part part_part_of_different_unnamed_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_different_unnamed_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.strong.transformed.expect b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.strong.transformed.expect
new file mode 100644
index 0000000..1fb79ff
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_different_unnamed_library.dart:8:6: Error: Using 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart' as part of 'pkg/front_end/testcases/part_part_of_different_unnamed_library.dart' but its 'part of' declaration says 'pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart'.
+// part 'part_part_of_different_unnamed_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_different_unnamed_library_lib2.dart";
+
+@core::override
+part part_part_of_different_unnamed_library_lib1.dart;
+static method main() → dynamic {}
+
+library;
+import self as self2;
+
+part part_part_of_different_unnamed_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_different_unnamed_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart b/pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.dart
new file mode 100644
index 0000000..5aef25d
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library_lib1.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.
+
+part of "part_part_of_different_unnamed_library_lib2.dart";
+
+methodFromLib1() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart b/pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.dart
new file mode 100644
index 0000000..e5617f2
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_different_unnamed_library_lib2.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.
+
+part "part_part_of_different_unnamed_library_lib1.dart";
+
+methodFromLib2() {
+  methodFromLib1();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library.dart b/pkg/front_end/testcases/part_part_of_differently_named_library.dart
new file mode 100644
index 0000000..c084850
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library.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.
+
+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/part_part_of_differently_named_library.dart.legacy.expect b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.legacy.expect
new file mode 100644
index 0000000..14fe275
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.legacy.expect
@@ -0,0 +1,25 @@
+library foo;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_differently_named_library.dart:10:6: Warning: Using 'pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart' as part of 'foo' but its 'part of' declaration says 'bar'.
+// part 'part_part_of_differently_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_differently_named_library_lib2.dart";
+
+@core::override
+part part_part_of_differently_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library bar;
+import self as self2;
+
+part part_part_of_differently_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_differently_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library.dart.legacy.transformed.expect b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.legacy.transformed.expect
new file mode 100644
index 0000000..14fe275
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.legacy.transformed.expect
@@ -0,0 +1,25 @@
+library foo;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_differently_named_library.dart:10:6: Warning: Using 'pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart' as part of 'foo' but its 'part of' declaration says 'bar'.
+// part 'part_part_of_differently_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_differently_named_library_lib2.dart";
+
+@core::override
+part part_part_of_differently_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library bar;
+import self as self2;
+
+part part_part_of_differently_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_differently_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library.dart.outline.expect b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.outline.expect
new file mode 100644
index 0000000..27348fa
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.outline.expect
@@ -0,0 +1,24 @@
+library foo;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_differently_named_library.dart:10:6: Warning: Using 'pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart' as part of 'foo' but its 'part of' declaration says 'bar'.
+// part 'part_part_of_differently_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+
+import "org-dartlang-testcase:///part_part_of_differently_named_library_lib2.dart";
+
+part part_part_of_differently_named_library_lib1.dart;
+static method main() → dynamic
+  ;
+
+library bar;
+import self as self2;
+
+part part_part_of_differently_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_differently_named_library_lib1.dart */ methodFromLib1() → dynamic
+  ;
+static method methodFromLib2() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library.dart.strong.expect b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.strong.expect
new file mode 100644
index 0000000..f506b84
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.strong.expect
@@ -0,0 +1,25 @@
+library foo;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_differently_named_library.dart:10:6: Error: Using 'pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart' as part of 'foo' but its 'part of' declaration says 'bar'.
+// part 'part_part_of_differently_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_differently_named_library_lib2.dart";
+
+@core::override
+part part_part_of_differently_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library bar;
+import self as self2;
+
+part part_part_of_differently_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_differently_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library.dart.strong.transformed.expect b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.strong.transformed.expect
new file mode 100644
index 0000000..f506b84
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library foo;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/part_part_of_differently_named_library.dart:10:6: Error: Using 'pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart' as part of 'foo' but its 'part of' declaration says 'bar'.
+// part 'part_part_of_differently_named_library_lib1.dart';
+//      ^
+//
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///part_part_of_differently_named_library_lib2.dart";
+
+@core::override
+part part_part_of_differently_named_library_lib1.dart;
+static method main() → dynamic {}
+
+library bar;
+import self as self2;
+
+part part_part_of_differently_named_library_lib1.dart;
+static method /* from org-dartlang-testcase:///part_part_of_differently_named_library_lib1.dart */ methodFromLib1() → dynamic {}
+static method methodFromLib2() → dynamic {
+  self2::methodFromLib1();
+}
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart b/pkg/front_end/testcases/part_part_of_differently_named_library_lib1.dart
new file mode 100644
index 0000000..8e33c02
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library_lib1.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.
+
+part of bar;
+
+methodFromLib1() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/part_part_of_differently_named_library_lib2.dart b/pkg/front_end/testcases/part_part_of_differently_named_library_lib2.dart
new file mode 100644
index 0000000..55171ca
--- /dev/null
+++ b/pkg/front_end/testcases/part_part_of_differently_named_library_lib2.dart
@@ -0,0 +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.
+
+library bar;
+
+part "part_part_of_differently_named_library_lib1.dart";
+
+methodFromLib2() {
+  methodFromLib1();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/prefer_baseclass.dart.hierarchy.expect b/pkg/front_end/testcases/prefer_baseclass.dart.hierarchy.expect
new file mode 100644
index 0000000..446c5bd
--- /dev/null
+++ b/pkg/front_end/testcases/prefer_baseclass.dart.hierarchy.expect
@@ -0,0 +1,173 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AB1:
+  superclasses:
+    Object
+      -> A
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+AB2:
+  superclasses:
+    Object
+      -> A
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+BA1:
+  superclasses:
+    Object
+      -> B
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+BA2:
+  superclasses:
+    Object
+      -> B
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.hierarchy.expect b/pkg/front_end/testcases/private_method_tearoff.dart.hierarchy.expect
new file mode 100644
index 0000000..6906912
--- /dev/null
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.hierarchy.expect
@@ -0,0 +1,98 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Bar._f
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces: Bar
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Bar._f
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Baz:
+  superclasses:
+    Object
+      -> Foo
+  interfaces: Bar
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Bar._f
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect
index 511c1e6..2355e10 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_method_tearoff_lib.dart" as pri;
 
+import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
+
 class Foo extends core::Object implements pri::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -18,3 +20,17 @@
 static method main() → dynamic {
   pri::baz(new self::Foo::•());
 }
+
+library;
+import self as pri;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pri::Bar
+    : super core::Object::•()
+    ;
+  method _f() → void {}
+}
+static method baz(pri::Bar bar) → void {
+  core::print("${bar._f.runtimeType}");
+}
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect
index 511c1e6..2355e10 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_method_tearoff_lib.dart" as pri;
 
+import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
+
 class Foo extends core::Object implements pri::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -18,3 +20,17 @@
 static method main() → dynamic {
   pri::baz(new self::Foo::•());
 }
+
+library;
+import self as pri;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pri::Bar
+    : super core::Object::•()
+    ;
+  method _f() → void {}
+}
+static method baz(pri::Bar bar) → void {
+  core::print("${bar._f.runtimeType}");
+}
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect b/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect
index 4e06821..d1c7b20 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_method_tearoff_lib.dart" as pri;
 
+import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
+
 class Foo extends core::Object implements pri::Bar {
   synthetic constructor •() → self::Foo
     ;
@@ -15,3 +17,16 @@
 }
 static method main() → dynamic
   ;
+
+library;
+import self as pri;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pri::Bar
+    ;
+  method _f() → void
+    ;
+}
+static method baz(pri::Bar bar) → void
+  ;
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect b/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect
index 511c1e6..cb76ba8 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_method_tearoff_lib.dart" as pri;
 
+import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
+
 class Foo extends core::Object implements pri::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -18,3 +20,17 @@
 static method main() → dynamic {
   pri::baz(new self::Foo::•());
 }
+
+library;
+import self as pri;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pri::Bar
+    : super core::Object::•()
+    ;
+  method _f() → void {}
+}
+static method baz(pri::Bar bar) → void {
+  core::print("${bar.{pri::Bar::_f}.{core::Object::runtimeType}}");
+}
diff --git a/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect
index 511c1e6..cb76ba8 100644
--- a/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/private_method_tearoff.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./private_method_tearoff_lib.dart" as pri;
 
+import "org-dartlang-testcase:///private_method_tearoff_lib.dart";
+
 class Foo extends core::Object implements pri::Bar {
   synthetic constructor •() → self::Foo
     : super core::Object::•()
@@ -18,3 +20,17 @@
 static method main() → dynamic {
   pri::baz(new self::Foo::•());
 }
+
+library;
+import self as pri;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pri::Bar
+    : super core::Object::•()
+    ;
+  method _f() → void {}
+}
+static method baz(pri::Bar bar) → void {
+  core::print("${bar.{pri::Bar::_f}.{core::Object::runtimeType}}");
+}
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.hierarchy.expect b/pkg/front_end/testcases/public_method_tearoff.dart.hierarchy.expect
new file mode 100644
index 0000000..a5b947e
--- /dev/null
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Bar.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+      -> Bar
+  interfaces:
+  classMembers:
+    Bar.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect
index 12c4ea4..f4aa6fe 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "./public_method_tearoff_lib.dart" as pub;
 
+import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
+
 class Foo extends pub::Bar {
   synthetic constructor •() → self::Foo
     : super pub::Bar::•()
@@ -10,3 +12,17 @@
 static method main() → void {
   pub::baz(new self::Foo::•());
 }
+
+library;
+import self as pub;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pub::Bar
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+static method baz(pub::Bar bar) → void {
+  core::print("${bar.f.runtimeType}");
+}
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect
index 12c4ea4..f4aa6fe 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "./public_method_tearoff_lib.dart" as pub;
 
+import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
+
 class Foo extends pub::Bar {
   synthetic constructor •() → self::Foo
     : super pub::Bar::•()
@@ -10,3 +12,17 @@
 static method main() → void {
   pub::baz(new self::Foo::•());
 }
+
+library;
+import self as pub;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pub::Bar
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+static method baz(pub::Bar bar) → void {
+  core::print("${bar.f.runtimeType}");
+}
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect b/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect
index 23f16e8..2df3cac 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.outline.expect
@@ -2,9 +2,24 @@
 import self as self;
 import "./public_method_tearoff_lib.dart" as pub;
 
+import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
+
 class Foo extends pub::Bar {
   synthetic constructor •() → self::Foo
     ;
 }
 static method main() → void
   ;
+
+library;
+import self as pub;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pub::Bar
+    ;
+  method f() → void
+    ;
+}
+static method baz(pub::Bar bar) → void
+  ;
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect b/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect
index 12c4ea4..a7c45ab 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.strong.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "./public_method_tearoff_lib.dart" as pub;
 
+import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
+
 class Foo extends pub::Bar {
   synthetic constructor •() → self::Foo
     : super pub::Bar::•()
@@ -10,3 +12,17 @@
 static method main() → void {
   pub::baz(new self::Foo::•());
 }
+
+library;
+import self as pub;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pub::Bar
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+static method baz(pub::Bar bar) → void {
+  core::print("${bar.{pub::Bar::f}.{core::Object::runtimeType}}");
+}
diff --git a/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect
index 12c4ea4..a7c45ab 100644
--- a/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/public_method_tearoff.dart.strong.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "./public_method_tearoff_lib.dart" as pub;
 
+import "org-dartlang-testcase:///public_method_tearoff_lib.dart";
+
 class Foo extends pub::Bar {
   synthetic constructor •() → self::Foo
     : super pub::Bar::•()
@@ -10,3 +12,17 @@
 static method main() → void {
   pub::baz(new self::Foo::•());
 }
+
+library;
+import self as pub;
+import "dart:core" as core;
+
+class Bar extends core::Object {
+  synthetic constructor •() → pub::Bar
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+static method baz(pub::Bar bar) → void {
+  core::print("${bar.{pub::Bar::f}.{core::Object::runtimeType}}");
+}
diff --git a/pkg/front_end/testcases/qualified.dart.hierarchy.expect b/pkg/front_end/testcases/qualified.dart.hierarchy.expect
new file mode 100644
index 0000000..2d45ad2
--- /dev/null
+++ b/pkg/front_end/testcases/qualified.dart.hierarchy.expect
@@ -0,0 +1,198 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bad:
+  superclasses:
+    qualified-name(lib, Missing)
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Bad.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+IllegalSupertype:
+  superclasses:
+    qualified-name(lib, VoidFunction)
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._redirecting#
+
+C:
+  superclasses:
+    Object
+      -> qualified-name(main, C)<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._redirecting#
+
+Supertype:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Supertype.supertypeMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+qualified-name(lib, Supertype) with qualified-name(lib, Mixin):
+  superclasses:
+    Object
+      -> qualified-name(lib, Supertype)
+  interfaces: qualified-name(lib, Mixin)
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Supertype.supertypeMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Supertype.supertypeMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+WithMixin:
+  superclasses:
+    Object
+      -> qualified-name(lib, Supertype)
+        -> _WithMixin&Supertype&Mixin
+  interfaces: qualified-name(lib, Mixin)
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Supertype.supertypeMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Supertype.supertypeMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/qualified.dart.legacy.expect b/pkg/front_end/testcases/qualified.dart.legacy.expect
index a54701c..9abbf6a 100644
--- a/pkg/front_end/testcases/qualified.dart.legacy.expect
+++ b/pkg/front_end/testcases/qualified.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test.qualified.main;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
 //   factory WrongName() {}
@@ -18,26 +20,14 @@
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
-//   factory WrongName() {}
-//           ^^^^^^^^^
-//
-// pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
-// class Bad extends lib.Missing {
-//                   ^^^^^^^^^^^
-//
-// pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
-// class IllegalSupertype extends lib.VoidFunction {}
-//       ^
-
-library test.qualified.main;
 import self as self;
 import "dart:core" as core;
 import "./qualified_lib.dart" as lib;
 
+import "org-dartlang-testcase:///qualified_lib.dart" as lib;
+
+part qualified_part.dart;
 class Bad extends core::Object {
   method method() → invalid-type {}
   static factory WrongName() → self::Bad {}
@@ -79,3 +69,39 @@
   new self::WithMixin::•().foo();
   new self::IllegalSupertype::•();
 }
+
+library test.qualified.lib;
+import self as lib;
+import "dart:core" as core;
+import "./qualified.dart" as self;
+
+import "org-dartlang-testcase:///qualified.dart" as main;
+
+typedef VoidFunction = () → void;
+class C<T extends core::Object = dynamic> extends self::C<lib::C::T> {
+  static field dynamic _redirecting# = <dynamic>[lib::C::b];
+  constructor •() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  constructor a() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  static factory b<T extends core::Object = dynamic>() → lib::C<lib::C::b::T>
+    let dynamic #redirecting_factory = lib::C::a in let lib::C::b::T #typeArg0 = null in invalid-expression;
+}
+class Supertype extends core::Object {
+  synthetic constructor •() → lib::Supertype
+    : super core::Object::•()
+    ;
+  method supertypeMethod() → dynamic {
+    core::print("I'm supertypeMethod form lib.Supertype");
+  }
+}
+abstract class Mixin extends core::Object {
+  synthetic constructor •() → lib::Mixin
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::print("I'm Mixin.foo");
+  }
+}
diff --git a/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect b/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
index 20d9d18..6f18b56 100644
--- a/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.legacy.transformed.expect
@@ -1,8 +1,17 @@
-// Unhandled errors:
+library test.qualified.main;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
 //   factory WrongName() {}
 //           ^^^^^^^^^
+// pkg/front_end/testcases/qualified.dart:11:7: Context: The name of the enclosing class is 'Bad'.
+// class Bad extends lib.Missing {
+//       ^^^
+//
+// pkg/front_end/testcases/qualified.dart:12:3: Warning: Type 'lib.Missing' not found.
+//   lib.Missing method() {}
+//   ^^^^^^^^^^^
 //
 // pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
 // class Bad extends lib.Missing {
@@ -11,12 +20,14 @@
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
-
-library test.qualified.main;
+//
 import self as self;
 import "dart:core" as core;
 import "./qualified_lib.dart" as lib;
 
+import "org-dartlang-testcase:///qualified_lib.dart" as lib;
+
+part qualified_part.dart;
 class Bad extends core::Object {
   method method() → invalid-type {}
   static factory WrongName() → self::Bad {}
@@ -61,3 +72,39 @@
   new self::WithMixin::•().foo();
   new self::IllegalSupertype::•();
 }
+
+library test.qualified.lib;
+import self as lib;
+import "dart:core" as core;
+import "./qualified.dart" as self;
+
+import "org-dartlang-testcase:///qualified.dart" as main;
+
+typedef VoidFunction = () → void;
+class C<T extends core::Object = dynamic> extends self::C<lib::C::T> {
+  static field dynamic _redirecting# = <dynamic>[lib::C::b];
+  constructor •() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  constructor a() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  static factory b<T extends core::Object = dynamic>() → lib::C<lib::C::b::T>
+    let dynamic #redirecting_factory = lib::C::a in let lib::C::b::T #typeArg0 = null in invalid-expression;
+}
+class Supertype extends core::Object {
+  synthetic constructor •() → lib::Supertype
+    : super core::Object::•()
+    ;
+  method supertypeMethod() → dynamic {
+    core::print("I'm supertypeMethod form lib.Supertype");
+  }
+}
+abstract class Mixin extends core::Object {
+  synthetic constructor •() → lib::Mixin
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::print("I'm Mixin.foo");
+  }
+}
diff --git a/pkg/front_end/testcases/qualified.dart.outline.expect b/pkg/front_end/testcases/qualified.dart.outline.expect
index fb0b74d..a8b09cd 100644
--- a/pkg/front_end/testcases/qualified.dart.outline.expect
+++ b/pkg/front_end/testcases/qualified.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test.qualified.main;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
 //   factory WrongName() {}
@@ -18,12 +20,14 @@
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
-
-library test.qualified.main;
+//
 import self as self;
 import "dart:core" as core;
 import "./qualified_lib.dart" as lib;
 
+import "org-dartlang-testcase:///qualified_lib.dart" as lib;
+
+part qualified_part.dart;
 class Bad extends core::Object {
   method method() → invalid-type
     ;
@@ -54,3 +58,33 @@
 }
 static method main() → dynamic
   ;
+
+library test.qualified.lib;
+import self as lib;
+import "dart:core" as core;
+import "./qualified.dart" as self;
+
+import "org-dartlang-testcase:///qualified.dart" as main;
+
+typedef VoidFunction = () → void;
+class C<T extends core::Object = dynamic> extends self::C<lib::C::T> {
+  static field dynamic _redirecting# = <dynamic>[lib::C::b];
+  constructor •() → lib::C<lib::C::T>
+    ;
+  constructor a() → lib::C<lib::C::T>
+    ;
+  static factory b<T extends core::Object = dynamic>() → lib::C<lib::C::b::T>
+    let dynamic #redirecting_factory = lib::C::a in let lib::C::b::T #typeArg0 = null in invalid-expression;
+}
+class Supertype extends core::Object {
+  synthetic constructor •() → lib::Supertype
+    ;
+  method supertypeMethod() → dynamic
+    ;
+}
+abstract class Mixin extends core::Object {
+  synthetic constructor •() → lib::Mixin
+    ;
+  method foo() → dynamic
+    ;
+}
diff --git a/pkg/front_end/testcases/qualified.dart.strong.expect b/pkg/front_end/testcases/qualified.dart.strong.expect
index 4ad22bd..2844fc6 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test.qualified.main;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
 //   factory WrongName() {}
@@ -18,30 +20,14 @@
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
-//   factory WrongName() {}
-//           ^^^^^^^^^
-//
-// pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
-//   lib.Missing method() {}
-//   ^^^^^^^^^^^
-//
-// pkg/front_end/testcases/qualified.dart:11:19: Error: Type 'lib.Missing' not found.
-// class Bad extends lib.Missing {
-//                   ^^^^^^^^^^^
-//
-// pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
-// class IllegalSupertype extends lib.VoidFunction {}
-//       ^
-
-library test.qualified.main;
 import self as self;
 import "dart:core" as core;
 import "./qualified_lib.dart" as lib;
 
+import "org-dartlang-testcase:///qualified_lib.dart" as lib;
+
+part qualified_part.dart;
 class Bad extends core::Object {
   method method() → invalid-type {}
   static factory WrongName() → self::Bad {}
@@ -83,3 +69,39 @@
   new self::WithMixin::•().{lib::Mixin::foo}();
   new self::IllegalSupertype::•();
 }
+
+library test.qualified.lib;
+import self as lib;
+import "dart:core" as core;
+import "./qualified.dart" as self;
+
+import "org-dartlang-testcase:///qualified.dart" as main;
+
+typedef VoidFunction = () → void;
+class C<T extends core::Object = dynamic> extends self::C<lib::C::T> {
+  static field dynamic _redirecting# = <dynamic>[lib::C::b];
+  constructor •() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  constructor a() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  static factory b<T extends core::Object = dynamic>() → lib::C<lib::C::b::T>
+    let dynamic #redirecting_factory = lib::C::a in let lib::C::b::T #typeArg0 = null in invalid-expression;
+}
+class Supertype extends core::Object {
+  synthetic constructor •() → lib::Supertype
+    : super core::Object::•()
+    ;
+  method supertypeMethod() → dynamic {
+    core::print("I'm supertypeMethod form lib.Supertype");
+  }
+}
+abstract class Mixin extends core::Object {
+  synthetic constructor •() → lib::Mixin
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::print("I'm Mixin.foo");
+  }
+}
diff --git a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
index 937b2a4..807fc74 100644
--- a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
@@ -1,8 +1,13 @@
-// Unhandled errors:
+library test.qualified.main;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/qualified.dart:13:11: Error: The name of a constructor must match the name of the enclosing class.
 //   factory WrongName() {}
 //           ^^^^^^^^^
+// pkg/front_end/testcases/qualified.dart:11:7: Context: The name of the enclosing class is 'Bad'.
+// class Bad extends lib.Missing {
+//       ^^^
 //
 // pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
 //   lib.Missing method() {}
@@ -15,12 +20,14 @@
 // pkg/front_end/testcases/qualified.dart:18:7: Error: The type 'lib.VoidFunction' can't be used as supertype.
 // class IllegalSupertype extends lib.VoidFunction {}
 //       ^
-
-library test.qualified.main;
+//
 import self as self;
 import "dart:core" as core;
 import "./qualified_lib.dart" as lib;
 
+import "org-dartlang-testcase:///qualified_lib.dart" as lib;
+
+part qualified_part.dart;
 class Bad extends core::Object {
   method method() → invalid-type {}
   static factory WrongName() → self::Bad {}
@@ -65,3 +72,39 @@
   new self::WithMixin::•().{lib::Mixin::foo}();
   new self::IllegalSupertype::•();
 }
+
+library test.qualified.lib;
+import self as lib;
+import "dart:core" as core;
+import "./qualified.dart" as self;
+
+import "org-dartlang-testcase:///qualified.dart" as main;
+
+typedef VoidFunction = () → void;
+class C<T extends core::Object = dynamic> extends self::C<lib::C::T> {
+  static field dynamic _redirecting# = <dynamic>[lib::C::b];
+  constructor •() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  constructor a() → lib::C<lib::C::T>
+    : super self::C::•()
+    ;
+  static factory b<T extends core::Object = dynamic>() → lib::C<lib::C::b::T>
+    let<BottomType> #redirecting_factory = lib::C::a in let lib::C::b::T #typeArg0 = null in invalid-expression;
+}
+class Supertype extends core::Object {
+  synthetic constructor •() → lib::Supertype
+    : super core::Object::•()
+    ;
+  method supertypeMethod() → dynamic {
+    core::print("I'm supertypeMethod form lib.Supertype");
+  }
+}
+abstract class Mixin extends core::Object {
+  synthetic constructor •() → lib::Mixin
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::print("I'm Mixin.foo");
+  }
+}
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.expect
index f288f84..32a8cd2 100644
--- a/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/abstract_constructor.dart:8:7: Error: The class 'C' is abstract and can't be instantiated.
-//   new C();
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/abstract_constructor.dart:8:7: Error: The class 'C' is abstract and can't be instantiated.
-//   new C();
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/abstract_constructor.dart:8:7: Error: The class 'C' is abstract and can't be instantiated.
+//   new C();
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.transformed.expect
index e2f40b5..32a8cd2 100644
--- a/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/abstract_constructor.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/abstract_constructor.dart:8:7: Error: The class 'C' is abstract and can't be instantiated.
 //   new C();
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.expect
index dca2096..cfe717a 100644
--- a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_constructor_redirection.dart:6:21: Error: Too many positional arguments: 0 allowed, but 1 found.
 // Try removing the extra positional arguments.
 //   const C() : this.x(1);
 //                     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.transformed.expect
index 34a5b09..cfe717a 100644
--- a/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_constructor_redirection.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_constructor_redirection.dart:6:21: Error: Too many positional arguments: 0 allowed, but 1 found.
+// Try removing the extra positional arguments.
+//   const C() : this.x(1);
+//                     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_continue.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_continue.dart.strong.expect
index 5ceeb3a..755a3f3 100644
--- a/pkg/front_end/testcases/rasta/bad_continue.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_continue.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_continue.dart:6:3: Error: A continue statement can't be used outside of a loop or switch statement.
 // Try removing the continue statement.
@@ -14,20 +16,7 @@
 // Try removing the continue statement.
 //   label: continue label;
 //          ^^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/bad_continue.dart:6:3: Error: A continue statement can't be used outside of a loop or switch statement.
-// Try removing the continue statement.
-//   continue here;
-//   ^^^^^^^^
-//
-// pkg/front_end/testcases/rasta/bad_continue.dart:7:10: Error: A continue statement can't be used outside of a loop or switch statement.
-// Try removing the continue statement.
-//   label: continue label;
-//          ^^^^^^^^
-
-library;
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/bad_continue.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_continue.dart.strong.transformed.expect
index 4d870d0..755a3f3 100644
--- a/pkg/front_end/testcases/rasta/bad_continue.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_continue.dart.strong.transformed.expect
@@ -1,16 +1,22 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_continue.dart:6:3: Error: A continue statement can't be used outside of a loop or switch statement.
 // Try removing the continue statement.
 //   continue here;
 //   ^^^^^^^^
 //
+// pkg/front_end/testcases/rasta/bad_continue.dart:6:12: Error: Can't find label 'here'.
+// Try defining the label, or correcting the name to match an existing label.
+//   continue here;
+//            ^
+//
 // pkg/front_end/testcases/rasta/bad_continue.dart:7:10: Error: A continue statement can't be used outside of a loop or switch statement.
 // Try removing the continue statement.
 //   label: continue label;
 //          ^^^^^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/bad_default_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..fe2fcf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_default_constructor.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..fe2fcf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.expect
index 627bb4bb..6d07372 100644
--- a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Warning: Too few positional arguments: 1 required, 0 given.
 //   const B() : super();
 //                    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.transformed.expect
index 145398b..6d07372 100644
--- a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Warning: Too few positional arguments: 1 required, 0 given.
+//   const B() : super();
+//                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.expect
index 94e3c44..122893d 100644
--- a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
 //   const B() : super();
 //                    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.transformed.expect
index 145398b..122893d 100644
--- a/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
+//   const B() : super();
+//                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..fe2fcf5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.expect
index 815d322..5f6b84a 100644
--- a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
 //   A(this.x);
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
 //   const B();
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.transformed.expect
index e218a4f..5f6b84a 100644
--- a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.legacy.transformed.expect
@@ -1,4 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
+//   A(this.x);
+//          ^
+//
+// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
+//   const B();
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.expect
index 815d322..5f6b84a 100644
--- a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
 //   A(this.x);
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
 //   const B();
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.transformed.expect
index e218a4f..5f6b84a 100644
--- a/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart.strong.transformed.expect
@@ -1,4 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:6:10: Error: 'x' isn't an instance field of this class.
+//   A(this.x);
+//          ^
+//
+// pkg/front_end/testcases/rasta/bad_implicit_super_constructor.dart:10:9: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
+//   const B();
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_interpolation.dart.outline.expect b/pkg/front_end/testcases/rasta/bad_interpolation.dart.outline.expect
index f08449b..2622e7c 100644
--- a/pkg/front_end/testcases/rasta/bad_interpolation.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/bad_interpolation.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
 //   print(" $x.);
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
 //   print(" $x.);
 //        ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.expect
index 6d6a791..36fe259 100644
--- a/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
 //   print(" $x.);
@@ -15,22 +17,7 @@
 // pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: Expected ';' after this.
 //   print(" $x.);
 //             ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
-//   print(" $x.);
-//             ^^^
-//
-// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:8: Error: Can't find ')' to match '('.
-//   print(" $x.);
-//        ^
-//
-// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: Expected ';' after this.
-//   print(" $x.);
-//             ^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.transformed.expect
index 7e1cc73..36fe259 100644
--- a/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_interpolation.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: String starting with " must end with ".
 //   print(" $x.);
@@ -8,11 +10,14 @@
 //   print(" $x.);
 //        ^
 //
+// pkg/front_end/testcases/rasta/bad_interpolation.dart:6:12: Error: Getter not found: 'x'.
+//   print(" $x.);
+//            ^
+//
 // pkg/front_end/testcases/rasta/bad_interpolation.dart:6:13: Error: Expected ';' after this.
 //   print(" $x.);
 //             ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_redirection.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/bad_redirection.dart.hierarchy.expect
new file mode 100644
index 0000000..a37fb7b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_redirection.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+      -> Foo
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/bad_redirection.dart.outline.expect b/pkg/front_end/testcases/rasta/bad_redirection.dart.outline.expect
index 06f511e..9bed78b 100644
--- a/pkg/front_end/testcases/rasta/bad_redirection.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/bad_redirection.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_redirection.dart:6:9: Error: Only factory constructor can specify '=' redirection.
 // Try making this a factory constructor, or remove the redirection.
 //   Foo() = Bar;
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.expect
index b9c7876..134d8c3 100644
--- a/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_redirection.dart:6:9: Error: Only factory constructor can specify '=' redirection.
 // Try making this a factory constructor, or remove the redirection.
@@ -14,20 +16,7 @@
 // Try removing the return type.
 //   Foo() = Bar;
 //           ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/bad_redirection.dart:6:9: Error: Only factory constructor can specify '=' redirection.
-// Try making this a factory constructor, or remove the redirection.
-//   Foo() = Bar;
-//         ^
-//
-// pkg/front_end/testcases/rasta/bad_redirection.dart:6:9: Error: Expected a function body or '=>'.
-// Try adding {}.
-//   Foo() = Bar;
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.transformed.expect
index 016f9e1..134d8c3 100644
--- a/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_redirection.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_redirection.dart:6:9: Error: Only factory constructor can specify '=' redirection.
 // Try making this a factory constructor, or remove the redirection.
@@ -9,8 +11,12 @@
 // Try adding {}.
 //   Foo() = Bar;
 //         ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/bad_redirection.dart:6:11: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   Foo() = Bar;
+//           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..274a6b4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.field
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
index 9cf944e..5a47079 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_setter_initializer.dart:6:9: Error: 'field' isn't an instance field of this class.
 //   C() : field = null;
 //         ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
index ee2c69c..5a47079 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_setter_initializer.dart:6:9: Error: 'field' isn't an instance field of this class.
+//   C() : field = null;
+//         ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.expect
index e77acb3..ad364e1 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_setter_initializer.dart:6:9: Error: 'field' isn't an instance field of this class.
 //   C() : field = null;
 //         ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.transformed.expect
index 692c97d..ad364e1 100644
--- a/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_setter_initializer.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_setter_initializer.dart:6:9: Error: 'field' isn't an instance field of this class.
+//   C() : field = null;
+//         ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.expect b/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.expect
index c35015a..749bace 100644
--- a/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/bad_unicode.dart:6:10: Error: An escape sequence starting with '\u' must be followed by 4 hexadecimal digits or from 1 to 6 digits between '{' and '}'.
-//   print("\u00"); // Bad Unicode escape, must have 4 hex digits.
-//          ^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/bad_unicode.dart:6:10: Error: An escape sequence starting with '\u' must be followed by 4 hexadecimal digits or from 1 to 6 digits between '{' and '}'.
-//   print("\u00"); // Bad Unicode escape, must have 4 hex digits.
-//          ^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/bad_unicode.dart:6:10: Error: An escape sequence starting with '\u' must be followed by 4 hexadecimal digits or from 1 to 6 digits between '{' and '}'.
+//   print("\u00"); // Bad Unicode escape, must have 4 hex digits.
+//          ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.transformed.expect
index 5a2277d..749bace 100644
--- a/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/bad_unicode.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/bad_unicode.dart:6:10: Error: An escape sequence starting with '\u' must be followed by 4 hexadecimal digits or from 1 to 6 digits between '{' and '}'.
 //   print("\u00"); // Bad Unicode escape, must have 4 hex digits.
 //          ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.expect b/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.expect
index 583a90e..b2fb346 100644
--- a/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/breaking_bad.dart:6:3: Error: A break statement can't be used outside of a loop or switch statement.
-// Try removing the break statement.
-//   break;
-//   ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/breaking_bad.dart:6:3: Error: A break statement can't be used outside of a loop or switch statement.
-// Try removing the break statement.
-//   break;
-//   ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/breaking_bad.dart:6:3: Error: A break statement can't be used outside of a loop or switch statement.
+// Try removing the break statement.
+//   break;
+//   ^^^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.transformed.expect
index 5401bce..b2fb346 100644
--- a/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/breaking_bad.dart.strong.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/breaking_bad.dart:6:3: Error: A break statement can't be used outside of a loop or switch statement.
 // Try removing the break statement.
 //   break;
 //   ^^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/cascades.dart.hierarchy.expect
new file mode 100644
index 0000000..10e4f4c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/cascades.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    A.add
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.hierarchy.expect
new file mode 100644
index 0000000..89063bc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.hierarchy.expect
@@ -0,0 +1,89 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Missing
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D._redirecting#
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect
index e9ad29f..a6ec9b4 100644
--- a/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
 // class C = Object with Missing;
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:12:11: Warning: Redirection constructor target not found: 'Missing'
 //   factory D() = Missing;
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect
index 6ea6019..d874733 100644
--- a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
 // class C = Object with Missing;
@@ -27,34 +29,7 @@
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:12:11: Error: Method not found: 'Missing'.
 //   factory D() = Missing;
 //           ^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
-// class C = Object with Missing;
-//       ^
-//
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:5:17: Error: Type 'Missing' not found.
-// class A extends Missing {}
-//                 ^^^^^^^
-//
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:7:20: Error: Type 'Missing' not found.
-// class B implements Missing {}
-//                    ^^^^^^^
-//
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:9:23: Error: Type 'Missing' not found.
-// class C = Object with Missing;
-//                       ^^^^^^^
-//
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:12:17: Error: Couldn't find constructor 'Missing'.
-//   factory D() = Missing;
-//                 ^
-//
-// pkg/front_end/testcases/rasta/class_hierarchy.dart:12:11: Error: Redirection constructor target not found: 'Missing'
-//   factory D() = Missing;
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect
index 7426197..94f01e5 100644
--- a/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/class_hierarchy.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:9:7: Error: The type 'Missing' can't be mixed in.
 // class C = Object with Missing;
@@ -23,8 +25,11 @@
 // pkg/front_end/testcases/rasta/class_hierarchy.dart:12:11: Error: Redirection constructor target not found: 'Missing'
 //   factory D() = Missing;
 //           ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/class_hierarchy.dart:12:11: Error: Method not found: 'Missing'.
+//   factory D() = Missing;
+//           ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/class_member.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/class_member.dart.hierarchy.expect
new file mode 100644
index 0000000..72d81b5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/class_member.dart.hierarchy.expect
@@ -0,0 +1,45 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.b
+    Foo.field1
+    Foo.a
+    Object.toString
+    Foo.field2
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Foo.c
+    Object.hashCode
+    Foo.field3
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.field1
+    Foo.field2
+    Foo.field3
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.legacy.transformed.expect
new file mode 100644
index 0000000..eb9688c
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.legacy.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static const field dynamic c = 1;
+static method main() → dynamic {
+  self::c;
+  self::c.call();
+}
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.expect
index 0176956..cecd01b 100644
--- a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.expect
@@ -1,18 +1,19 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/constant_get_and_invoke.dart:8:4: Error: The method 'call' isn't defined for the class 'int'.
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //   c();
 //    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
 static const field core::int c = 1;
 static method main() → dynamic {
   self::c;
-  let final dynamic #t1 = self::c in invalid-expression "pkg/front_end/testcases/rasta/constant_get_and_invoke.dart:8:4: Error: The method 'call' isn't defined for the class 'int'.
+  invalid-expression "pkg/front_end/testcases/rasta/constant_get_and_invoke.dart:8:4: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   c();
    ^";
diff --git a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.transformed.expect
index ca99349..cecd01b 100644
--- a/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/constant_get_and_invoke.dart.strong.transformed.expect
@@ -1,11 +1,19 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/constant_get_and_invoke.dart:8:4: Error: The method 'call' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'call'.
+//   c();
+//    ^
+//
 import self as self;
 import "dart:core" as core;
 
 static const field core::int c = 1;
 static method main() → dynamic {
   self::c;
-  let final core::int #t1 = self::c in invalid-expression "pkg/front_end/testcases/rasta/constant_get_and_invoke.dart:8:4: Error: The method 'call' isn't defined for the class 'int'.
+  invalid-expression "pkg/front_end/testcases/rasta/constant_get_and_invoke.dart:8:4: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
   c();
    ^";
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.legacy.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.legacy.expect
index d7651c0..84bbb0d 100644
--- a/pkg/front_end/testcases/rasta/deferred_load.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.legacy.expect
@@ -1,8 +1,18 @@
 library;
 import self as self;
-import "dart:core" as core;
+import "dart:async" as asy;
+
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
 
 static method main() → dynamic {
-  throw new core::NoSuchMethodError::•(null, #loadLibrary, <dynamic>[], <dynamic, dynamic>{}, null);
-  throw new core::NoSuchMethodError::•(null, #lib.loadLibrary, <dynamic>[], <dynamic, dynamic>{}, null);
+  self::__loadLibrary_lib;
+  LoadLibrary(lib);
 }
+static method __loadLibrary_lib() → asy::Future<dynamic>
+  return LoadLibrary(lib);
+
+library deferred_lib;
+import self as self2;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.outline.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.outline.expect
index 6a28c0d..7fe8d37 100644
--- a/pkg/front_end/testcases/rasta/deferred_load.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.outline.expect
@@ -1,5 +1,13 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
+
+library deferred_lib;
+import self as self2;
+
+static method foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.strong.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.strong.expect
index f076a51..84bbb0d 100644
--- a/pkg/front_end/testcases/rasta/deferred_load.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.strong.expect
@@ -2,9 +2,17 @@
 import self as self;
 import "dart:async" as asy;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {
   self::__loadLibrary_lib;
   LoadLibrary(lib);
 }
 static method __loadLibrary_lib() → asy::Future<dynamic>
   return LoadLibrary(lib);
+
+library deferred_lib;
+import self as self2;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/deferred_load.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/deferred_load.dart.strong.transformed.expect
index f076a51..84bbb0d 100644
--- a/pkg/front_end/testcases/rasta/deferred_load.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/deferred_load.dart.strong.transformed.expect
@@ -2,9 +2,17 @@
 import self as self;
 import "dart:async" as asy;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {
   self::__loadLibrary_lib;
   LoadLibrary(lib);
 }
 static method __loadLibrary_lib() → asy::Future<dynamic>
   return LoadLibrary(lib);
+
+library deferred_lib;
+import self as self2;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.hierarchy.expect
new file mode 100644
index 0000000..ee525c0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.hierarchy.expect
@@ -0,0 +1,140 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+
+Object with Mixin:
+  superclasses:
+    Object
+  interfaces: Mixin
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.field
+
+_A&Object&Mixin with Mixin:
+  superclasses:
+    Object
+      -> _A&Object&Mixin
+  interfaces: Mixin
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.field
+
+A:
+  superclasses:
+    Object
+      -> _A&Object&Mixin
+        -> _A&Object&Mixin&Mixin
+  interfaces: Mixin
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.field
diff --git a/pkg/front_end/testcases/rasta/enum.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/enum.dart.hierarchy.expect
new file mode 100644
index 0000000..5365e25
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/enum.dart.hierarchy.expect
@@ -0,0 +1,41 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.ec2
+    Foo.toString
+    Foo.index
+    Foo.ec1
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo._name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Foo.values
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/export.dart.legacy.expect b/pkg/front_end/testcases/rasta/export.dart.legacy.expect
index 07bcd0f..467d2a4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.legacy.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./foo.dart" as foo;
 additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect
index 07bcd0f..467d2a4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.legacy.transformed.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./foo.dart" as foo;
 additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/export.dart.outline.expect b/pkg/front_end/testcases/rasta/export.dart.outline.expect
index 07bcd0f..7c8cd4d 100644
--- a/pkg/front_end/testcases/rasta/export.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.outline.expect
@@ -2,3 +2,13 @@
 import self as self;
 import "./foo.dart" as foo;
 additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+
+static method foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/export.dart.strong.expect b/pkg/front_end/testcases/rasta/export.dart.strong.expect
index 07bcd0f..467d2a4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.strong.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./foo.dart" as foo;
 additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
index 07bcd0f..467d2a4 100644
--- a/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
@@ -2,3 +2,15 @@
 import self as self;
 import "./foo.dart" as foo;
 additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.hierarchy.expect
new file mode 100644
index 0000000..c01709a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.hierarchy.expect
@@ -0,0 +1,128 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> A<S>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B._redirecting#
+
+C:
+  superclasses:
+    Object
+      -> A<U>
+        -> B<U>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.outline.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.outline.expect
index 312b830..aa25435 100644
--- a/pkg/front_end/testcases/rasta/generic_factory.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/generic_factory.dart:16:19: Warning: Couldn't find constructor 'Missing'.
 //   factory A.c() = Missing;
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/generic_factory.dart:16:11: Warning: Redirection constructor target not found: 'Missing'
 //   factory A.c() = Missing;
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.strong.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.strong.expect
index c0465b0..c4616c2 100644
--- a/pkg/front_end/testcases/rasta/generic_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/generic_factory.dart:16:19: Error: Couldn't find constructor 'Missing'.
 //   factory A.c() = Missing;
@@ -25,32 +27,7 @@
 // pkg/front_end/testcases/rasta/generic_factory.dart:16:11: Error: Method not found: 'Missing'.
 //   factory A.c() = Missing;
 //           ^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/generic_factory.dart:16:19: Error: Couldn't find constructor 'Missing'.
-//   factory A.c() = Missing;
-//                   ^
-//
-// pkg/front_end/testcases/rasta/generic_factory.dart:16:11: Error: Redirection constructor target not found: 'Missing'
-//   factory A.c() = Missing;
-//           ^
-//
-// pkg/front_end/testcases/rasta/generic_factory.dart:15:19: Error: The constructor function type 'B<C1> Function()' isn't a subtype of 'A<T> Function()'.
-//  - 'B' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
-//  - 'C1' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
-//  - 'A' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
-//   factory A.b() = B<C1>.a;
-//                   ^
-//
-// pkg/front_end/testcases/rasta/generic_factory.dart:23:19: Error: The constructor function type 'C<C2> Function()' isn't a subtype of 'B<S> Function()'.
-//  - 'C' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
-//  - 'C2' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
-//  - 'B' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
-//   factory B.b() = C<C2>;
-//                   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect
index d931017..0cb3c06 100644
--- a/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/generic_factory.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/generic_factory.dart:16:19: Error: Couldn't find constructor 'Missing'.
 //   factory A.c() = Missing;
@@ -21,8 +23,11 @@
 //  - 'B' is from 'pkg/front_end/testcases/rasta/generic_factory.dart'.
 //   factory B.b() = C<C2>;
 //                   ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/generic_factory.dart:16:11: Error: Method not found: 'Missing'.
+//   factory A.c() = Missing;
+//           ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect b/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect
index 64dfcdc..33c77ad 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.legacy.expect
@@ -2,6 +2,25 @@
 import self as self;
 import "./foo.dart" as foo;
 
+import "org-dartlang-testcase:///export.dart";
+
 static method main() → dynamic {
   foo::foo();
 }
+
+library export;
+import self as self2;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect
index 64dfcdc..33c77ad 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.legacy.transformed.expect
@@ -2,6 +2,25 @@
 import self as self;
 import "./foo.dart" as foo;
 
+import "org-dartlang-testcase:///export.dart";
+
 static method main() → dynamic {
   foo::foo();
 }
+
+library export;
+import self as self2;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.outline.expect b/pkg/front_end/testcases/rasta/import_export.dart.outline.expect
index 6a28c0d..d1a411b 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.outline.expect
@@ -1,5 +1,22 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///export.dart";
+
 static method main() → dynamic
   ;
+
+library export;
+import self as self2;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+
+static method foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.strong.expect b/pkg/front_end/testcases/rasta/import_export.dart.strong.expect
index 64dfcdc..33c77ad 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.strong.expect
@@ -2,6 +2,25 @@
 import self as self;
 import "./foo.dart" as foo;
 
+import "org-dartlang-testcase:///export.dart";
+
 static method main() → dynamic {
   foo::foo();
 }
+
+library export;
+import self as self2;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
index 64dfcdc..33c77ad 100644
--- a/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
@@ -2,6 +2,25 @@
 import self as self;
 import "./foo.dart" as foo;
 
+import "org-dartlang-testcase:///export.dart";
+
 static method main() → dynamic {
   foo::foo();
 }
+
+library export;
+import self as self2;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
+
+
+export "org-dartlang-testcase:///foo.dart";
+
+
+library foo;
+import self as foo;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000001.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000001.dart.strong.expect
index d435a39..aa235f1 100644
--- a/pkg/front_end/testcases/rasta/issue_000001.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000001.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000001.dart:11:8: Error: Too many positional arguments: 1 allowed, but 2 found.
 // Try removing the extra positional arguments.
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/issue_000001.dart:5:1: Context: Found this candidate, but the arguments don't match.
 // test0(x) {
 // ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000001.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000001.dart.strong.transformed.expect
index 0f8dca8..aa235f1 100644
--- a/pkg/front_end/testcases/rasta/issue_000001.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000001.dart.strong.transformed.expect
@@ -1,4 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000001.dart:11:8: Error: Too many positional arguments: 1 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   test0(0, 1);
+//        ^
+// pkg/front_end/testcases/rasta/issue_000001.dart:5:1: Context: Found this candidate, but the arguments don't match.
+// test0(x) {
+// ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.hierarchy.expect
new file mode 100644
index 0000000..87c1e96
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.hierarchy.expect
@@ -0,0 +1,451 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.value
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.outline.expect
index ed8e416..6e63e38 100644
--- a/pkg/front_end/testcases/rasta/issue_000002.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.outline.expect
@@ -2,6 +2,9 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
 class Foo extends core::Object {
   final field dynamic value;
   constructor •(dynamic value) → self::Foo
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.strong.expect
index cb9d36e..25e236d 100644
--- a/pkg/front_end/testcases/rasta/issue_000002.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.strong.expect
@@ -4,6 +4,9 @@
 import "package:expect/expect.dart" as exp;
 import "dart:typed_data" as typ;
 
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
 class Foo extends core::Object {
   final field dynamic value;
   constructor •(dynamic value) → self::Foo
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.strong.transformed.expect
index cb9d36e..25e236d 100644
--- a/pkg/front_end/testcases/rasta/issue_000002.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.strong.transformed.expect
@@ -4,6 +4,9 @@
 import "package:expect/expect.dart" as exp;
 import "dart:typed_data" as typ;
 
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
 class Foo extends core::Object {
   final field dynamic value;
   constructor •(dynamic value) → self::Foo
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.hierarchy.expect
new file mode 100644
index 0000000..98d4425
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.hierarchy.expect
@@ -0,0 +1,433 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.expect
index 4c7bdc0..4e2ee79 100644
--- a/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static field dynamic global;
 static method fact4() → dynamic {
   dynamic f = 1;
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.transformed.expect
index 4c7bdc0..4e2ee79 100644
--- a/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static field dynamic global;
 static method fact4() → dynamic {
   dynamic f = 1;
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.outline.expect
index cf199f8f..8358cbc 100644
--- a/pkg/front_end/testcases/rasta/issue_000004.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.outline.expect
@@ -1,6 +1,8 @@
 library;
 import self as self;
 
+import "package:expect/expect.dart";
+
 static field dynamic global;
 static method fact4() → dynamic
   ;
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.strong.expect
index faa041e..6126127 100644
--- a/pkg/front_end/testcases/rasta/issue_000004.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static field dynamic global;
 static method fact4() → dynamic {
   core::int f = 1;
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 faa041e..6126127 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static field dynamic global;
 static method fact4() → dynamic {
   core::int f = 1;
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.hierarchy.expect
new file mode 100644
index 0000000..cb9f404
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.hierarchy.expect
@@ -0,0 +1,119 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base with Mixin:
+  superclasses:
+    Object
+      -> Base
+  interfaces: Mixin
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Sub:
+  superclasses:
+    Object
+      -> Base
+        -> _Sub&Base&Mixin
+  interfaces: Mixin
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000008.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000008.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000008.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000012.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000012.dart.hierarchy.expect
new file mode 100644
index 0000000..298c7be
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000012.dart.hierarchy.expect
@@ -0,0 +1,59 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.field
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.field
+    Object._instanceOf
+    B.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.field
diff --git a/pkg/front_end/testcases/rasta/issue_000026.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000026.dart.hierarchy.expect
new file mode 100644
index 0000000..e369ba5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000026.dart.hierarchy.expect
@@ -0,0 +1,65 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.b
+    C.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.b
+    C.a
+    C.c
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    D.b
+    D.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    D.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.b
+    D.a
+    D.c
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.legacy.expect
index f284b26..2f72170 100644
--- a/pkg/front_end/testcases/rasta/issue_000031.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.legacy.expect
@@ -1,6 +1,17 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
+//   math..toString();
+//   ^^^^
+//
 import self as self;
 
+import "dart:math" as math;
+
 static method main() → dynamic {
-  let final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000031.dart: Error: A library can't be used as an expression." in let final dynamic #t2 = #t1.toString() in #t1;
+  let final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
+  math..toString();
+  ^^^^" in let final dynamic #t2 = #t1.toString() in #t1;
 }
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.outline.expect
index 6a28c0d..d5e36cb 100644
--- a/pkg/front_end/testcases/rasta/issue_000031.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.outline.expect
@@ -1,5 +1,7 @@
 library;
 import self as self;
 
+import "dart:math" as math;
+
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect
index 8894cf7..6c371c1 100644
--- a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.expect
@@ -1,12 +1,15 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
 //   math..toString();
 //   ^^^^
-
-library;
+//
 import self as self;
 
+import "dart:math" as math;
+
 static method main() → dynamic {
   let final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
   math..toString();
diff --git a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect
index 3042bd3..bd752a1 100644
--- a/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000031.dart.strong.transformed.expect
@@ -1,7 +1,16 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
+//   math..toString();
+//   ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:math" as math;
+
 static method main() → dynamic {
   let final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000031.dart:8:3: Error: A prefix can't be used as an expression.
   math..toString();
diff --git a/pkg/front_end/testcases/rasta/issue_000032.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000032.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000032.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000032.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000032.dart.outline.expect
index 80c2638..3e08a90 100644
--- a/pkg/front_end/testcases/rasta/issue_000032.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000032.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000032.dart:7:1: Error: Expected an identifier, but got '}'.
 // }
@@ -16,8 +18,7 @@
 // pkg/front_end/testcases/rasta/issue_000032.dart:7:1: Error: Expected '{' before this.
 // }
 // ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000032.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000032.dart.strong.expect
index 6e2309c..c9b5781 100644
--- a/pkg/front_end/testcases/rasta/issue_000032.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000032.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000032.dart:7:1: Error: Expected an identifier, but got '}'.
 // }
@@ -30,35 +32,7 @@
 // Try correcting the name to the name of an existing method, or defining a method named '<'.
 //   C<
 //    ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000032.dart:7:1: Error: Expected an identifier, but got '}'.
-// }
-// ^
-//
-// pkg/front_end/testcases/rasta/issue_000032.dart:6:4: Error: Constructors can't have type parameters.
-//   C<
-//    ^^...
-//
-// pkg/front_end/testcases/rasta/issue_000032.dart:6:3: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   C<
-//   ^
-//
-// pkg/front_end/testcases/rasta/issue_000032.dart:7:1: Error: Expected '{' before this.
-// }
-// ^
-//
-// pkg/front_end/testcases/rasta/issue_000032.dart:11:1: Error: Expected an identifier, but got '}'.
-// }
-// ^
-//
-// pkg/front_end/testcases/rasta/issue_000032.dart:11:1: Error: Expected ';' after this.
-// }
-// ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -67,7 +41,7 @@
     : super core::Object::•() {}
 }
 static method main() → dynamic {
-  let final dynamic #t1 = self::C in invalid-expression "pkg/front_end/testcases/rasta/issue_000032.dart:10:4: Error: The method '<' isn't defined for the class 'Type'.
+  invalid-expression "pkg/front_end/testcases/rasta/issue_000032.dart:10:4: Error: The method '<' isn't defined for the class 'Type'.
  - 'Type' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named '<'.
   C<
diff --git a/pkg/front_end/testcases/rasta/issue_000032.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000032.dart.strong.transformed.expect
index 296395e..c9b5781 100644
--- a/pkg/front_end/testcases/rasta/issue_000032.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000032.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000032.dart:7:1: Error: Expected an identifier, but got '}'.
 // }
@@ -24,8 +26,13 @@
 // pkg/front_end/testcases/rasta/issue_000032.dart:11:1: Error: Expected ';' after this.
 // }
 // ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000032.dart:10:4: Error: The method '<' isn't defined for the class 'Type'.
+//  - 'Type' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named '<'.
+//   C<
+//    ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -34,7 +41,7 @@
     : super core::Object::•() {}
 }
 static method main() → dynamic {
-  let final core::Type #t1 = self::C in invalid-expression "pkg/front_end/testcases/rasta/issue_000032.dart:10:4: Error: The method '<' isn't defined for the class 'Type'.
+  invalid-expression "pkg/front_end/testcases/rasta/issue_000032.dart:10:4: Error: The method '<' isn't defined for the class 'Type'.
  - 'Type' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named '<'.
   C<
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.expect
index 19ba3b1..5af59e6 100644
--- a/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Warning: Method not found: 'JS'.
 // @JS()
 //  ^^
-
-library;
+//
 import self as self;
 
 @invalid-expression "pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.transformed.expect
index 99c583e..5af59e6 100644
--- a/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Warning: Method not found: 'JS'.
+// @JS()
+//  ^^
+//
 import self as self;
 
 @invalid-expression "pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.strong.expect
index 894663d..7774711 100644
--- a/pkg/front_end/testcases/rasta/issue_000033.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
 // @JS()
 //  ^^
-
-library;
+//
 import self as self;
 
 @invalid-expression "pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.strong.transformed.expect
index 99c583e..7774711 100644
--- a/pkg/front_end/testcases/rasta/issue_000033.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
+// @JS()
+//  ^^
+//
 import self as self;
 
 @invalid-expression "pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.expect
index 01973e9..6a631bc 100644
--- a/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
@@ -8,15 +10,7 @@
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Can't access 'this' in a field initializer.
 //   const C() : this.x;
 //               ^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-//   const C() : this.x;
-//               ^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.transformed.expect
index e4532bb..6a631bc 100644
--- a/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.legacy.transformed.expect
@@ -1,11 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
 //   const C() : this.x;
 //               ^^^^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Can't access 'this' in a field initializer.
+//   const C() : this.x;
+//               ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.outline.expect
index c482cf9..7e1b270 100644
--- a/pkg/front_end/testcases/rasta/issue_000034.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
 //   const C() : this.x;
 //               ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.strong.expect
index 01973e9..6a631bc 100644
--- a/pkg/front_end/testcases/rasta/issue_000034.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
@@ -8,15 +10,7 @@
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Can't access 'this' in a field initializer.
 //   const C() : this.x;
 //               ^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-//   const C() : this.x;
-//               ^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000034.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000034.dart.strong.transformed.expect
index e4532bb..6a631bc 100644
--- a/pkg/front_end/testcases/rasta/issue_000034.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000034.dart.strong.transformed.expect
@@ -1,11 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
 //   const C() : this.x;
 //               ^^^^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Can't access 'this' in a field initializer.
+//   const C() : this.x;
+//               ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000035.dart.hierarchy.expect
new file mode 100644
index 0000000..83fc051
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000035.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.æøC
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.expect
index 50d18b1..793cade 100644
--- a/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -23,31 +25,7 @@
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Context: 'C.æøC' is defined here.
 // class C {æøC();}
 //          ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-// class C {æøC();}
-//          ^
-//
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:11: Error: The non-ASCII character 'ø' (U+00F8) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-// class C {æøC();}
-//           ^
-//
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
-//  - C.æøC
-// Try to either
-//  - provide an implementation,
-//  - inherit an implementation from a superclass or mixin,
-//  - mark the class as abstract, or
-//  - provide a 'noSuchMethod' implementation.
-// 
-// class C {æøC();}
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.transformed.expect
index 05fecd8..793cade 100644
--- a/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -17,11 +19,13 @@
 //  - inherit an implementation from a superclass or mixin,
 //  - mark the class as abstract, or
 //  - provide a 'noSuchMethod' implementation.
-// 
+//
 // class C {æøC();}
 //       ^
-
-library;
+// pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Context: 'C.æøC' is defined here.
+// class C {æøC();}
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000035.dart.outline.expect
index 9df0e68..70748ad 100644
--- a/pkg/front_end/testcases/rasta/issue_000035.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Context: 'C.æøC' is defined here.
 // class C {æøC();}
 //          ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000035.dart.strong.expect
index e30cdd8..793cade 100644
--- a/pkg/front_end/testcases/rasta/issue_000035.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -11,7 +13,7 @@
 //           ^
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
-//  - 'æøC'
+//  - C.æøC
 // Try to either
 //  - provide an implementation,
 //  - inherit an implementation from a superclass or mixin,
@@ -20,34 +22,10 @@
 //
 // class C {æøC();}
 //       ^
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Context: 'æøC' is defined here.
+// pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Context: 'C.æøC' is defined here.
 // class C {æøC();}
 //          ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-// class C {æøC();}
-//          ^
-//
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:11: Error: The non-ASCII character 'ø' (U+00F8) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-// class C {æøC();}
-//           ^
-//
-// pkg/front_end/testcases/rasta/issue_000035.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
-//  - 'æøC'
-// Try to either
-//  - provide an implementation,
-//  - inherit an implementation from a superclass or mixin,
-//  - mark the class as abstract, or
-//  - provide a 'noSuchMethod' implementation.
-// 
-// class C {æøC();}
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000035.dart.strong.transformed.expect
index 62a78a7..793cade 100644
--- a/pkg/front_end/testcases/rasta/issue_000035.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Error: The non-ASCII character 'æ' (U+00E6) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -11,17 +13,19 @@
 //           ^
 //
 // pkg/front_end/testcases/rasta/issue_000035.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
-//  - 'æøC'
+//  - C.æøC
 // Try to either
 //  - provide an implementation,
 //  - inherit an implementation from a superclass or mixin,
 //  - mark the class as abstract, or
 //  - provide a 'noSuchMethod' implementation.
-// 
+//
 // class C {æøC();}
 //       ^
-
-library;
+// pkg/front_end/testcases/rasta/issue_000035.dart:5:10: Context: 'C.æøC' is defined here.
+// class C {æøC();}
+//          ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035a.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000035a.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000035a.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.expect
index 96ddc05..6e7d2e5 100644
--- a/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//         ^
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//          ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//         ^
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//          ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
+// class C{

C();}
+//         ^
+//
+// pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
+// class C{

C();}
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.transformed.expect
index 5b57ed6..6e7d2e5 100644
--- a/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035a.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
 // class C{

C();}
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
 // class C{

C();}
 //          ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035a.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000035a.dart.outline.expect
index 4ad8bee..b67d8e0 100644
--- a/pkg/front_end/testcases/rasta/issue_000035a.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035a.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
 // class C{

C();}
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
 // class C{

C();}
 //          ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.expect
index 96ddc05..6e7d2e5 100644
--- a/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//         ^
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//          ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//         ^
-//
-// pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
-// class C{

C();}
-//          ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
+// class C{

C();}
+//         ^
+//
+// pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
+// class C{

C();}
+//          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.transformed.expect
index 5b57ed6..6e7d2e5 100644
--- a/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000035a.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000035a.dart:5:9: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
 // class C{

C();}
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/rasta/issue_000035a.dart:5:10: Error: The non-ASCII space character U+2028 can only be used in strings and comments.
 // class C{

C();}
 //          ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000036.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000036.dart.outline.expect
index b1d01f2..14f3ce3 100644
--- a/pkg/front_end/testcases/rasta/issue_000036.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000036.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000036.dart:5:14: Error: Expected an identifier, but got '-'.
 // main() => a. - 5;
 //              ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000036.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000036.dart.strong.expect
index 52166ab..c46dc5c 100644
--- a/pkg/front_end/testcases/rasta/issue_000036.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000036.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000036.dart:5:14: Error: Expected an identifier, but got '-'.
 // main() => a. - 5;
@@ -7,14 +9,7 @@
 // pkg/front_end/testcases/rasta/issue_000036.dart:5:14: Error: Expected an identifier, but got ''.
 // main() => a. - 5;
 //              ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000036.dart:5:14: Error: Expected an identifier, but got '-'.
-// main() => a. - 5;
-//              ^
-
-library;
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000036.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000036.dart.strong.transformed.expect
index a3dffd2..c46dc5c 100644
--- a/pkg/front_end/testcases/rasta/issue_000036.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000036.dart.strong.transformed.expect
@@ -1,10 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000036.dart:5:14: Error: Expected an identifier, but got '-'.
 // main() => a. - 5;
 //              ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000036.dart:5:14: Error: Expected an identifier, but got ''.
+// main() => a. - 5;
+//              ^
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000039.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000039.dart.hierarchy.expect
new file mode 100644
index 0000000..40c7594
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000039.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.hierarchy.expect
new file mode 100644
index 0000000..b628c46
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.expect
index e53681c..252265a 100644
--- a/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000041.dart:7:9: Error: '+' is not a prefix operator.
 // Try removing '+'.
@@ -9,15 +11,7 @@
 // To delegate a constructor to a super constructor, put the super call as an initializer.
 //     use(+super);
 //          ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000041.dart:7:9: Error: '+' is not a prefix operator.
-// Try removing '+'.
-//     use(+super);
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.transformed.expect
index 96e8ae6..252265a 100644
--- a/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.legacy.transformed.expect
@@ -1,11 +1,17 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000041.dart:7:9: Error: '+' is not a prefix operator.
 // Try removing '+'.
 //     use(+super);
 //         ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000041.dart:7:10: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//     use(+super);
+//          ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.strong.expect
index 8d033ce..f53740d 100644
--- a/pkg/front_end/testcases/rasta/issue_000041.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000041.dart:7:9: Error: '+' is not a prefix operator.
 // Try removing '+'.
@@ -9,15 +11,7 @@
 // To delegate a constructor to a super constructor, put the super call as an initializer.
 //     use(+super);
 //          ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000041.dart:7:9: Error: '+' is not a prefix operator.
-// Try removing '+'.
-//     use(+super);
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000041.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000041.dart.strong.transformed.expect
index e597329..f53740d 100644
--- a/pkg/front_end/testcases/rasta/issue_000041.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000041.dart.strong.transformed.expect
@@ -1,11 +1,17 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000041.dart:7:9: Error: '+' is not a prefix operator.
 // Try removing '+'.
 //     use(+super);
 //         ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000041.dart:7:10: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//     use(+super);
+//          ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000042.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000042.dart.strong.expect
index ff7ce50..356e6a0 100644
--- a/pkg/front_end/testcases/rasta/issue_000042.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000042.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000042.dart:6:13: Error: Unexpected token ','.
 //   for (var x, y in []) {}
@@ -17,24 +19,7 @@
 // Try removing the continue statement.
 //   L: if (true) { continue L; }
 //                  ^^^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000042.dart:6:13: Error: Unexpected token ','.
-//   for (var x, y in []) {}
-//             ^
-//
-// pkg/front_end/testcases/rasta/issue_000042.dart:7:8: Error: A continue statement can't be used outside of a loop or switch statement.
-// Try removing the continue statement.
-//   L: { continue L; }
-//        ^^^^^^^^
-//
-// pkg/front_end/testcases/rasta/issue_000042.dart:8:18: Error: A continue statement can't be used outside of a loop or switch statement.
-// Try removing the continue statement.
-//   L: if (true) { continue L; }
-//                  ^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
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 f64ff50..356e6a0 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
@@ -1,9 +1,15 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000042.dart:6:13: Error: Unexpected token ','.
 //   for (var x, y in []) {}
 //             ^
 //
+// pkg/front_end/testcases/rasta/issue_000042.dart:6:8: Error: A for-in loop can't have more than one loop variable.
+//   for (var x, y in []) {}
+//        ^^^
+//
 // pkg/front_end/testcases/rasta/issue_000042.dart:7:8: Error: A continue statement can't be used outside of a loop or switch statement.
 // Try removing the continue statement.
 //   L: { continue L; }
@@ -13,8 +19,7 @@
 // Try removing the continue statement.
 //   L: if (true) { continue L; }
 //                  ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000043.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000043.dart.hierarchy.expect
new file mode 100644
index 0000000..79662a4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000043.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.hierarchy.expect
new file mode 100644
index 0000000..bd39d02
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.notEvenAConstructor
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._redirecting#
diff --git a/pkg/front_end/testcases/rasta/issue_000044.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000044.dart.outline.expect
index 684d860..5d12971 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000044.dart:7:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -22,8 +24,7 @@
 // pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Warning: Couldn't find constructor 'h'.
 //   C notEvenAConstructor(a) = h;
 //                              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
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 699adf1..801849b 100644
--- a/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000044.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000044.dart:7:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -60,47 +62,7 @@
 // Try using a constructor or factory that is 'const'.
 //   print(const C.missingFactoryKeyword());
 //               ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000044.dart:7:8: Error: Expected a function body or '=>'.
-// Try adding {}.
-// a b(c) = d;
-//        ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:14:29: Error: Only factory constructor can specify '=' redirection.
-// Try making this a factory constructor, or remove the redirection.
-//   C.missingFactoryKeyword() = C.constant;
-//                             ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:21:28: Error: Only factory constructor can specify '=' redirection.
-// Try making this a factory constructor, or remove the redirection.
-//   C notEvenAConstructor(a) = h;
-//                            ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:7:1: Error: Type 'a' not found.
-// a b(c) = d;
-// ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Couldn't find constructor 'h'.
-//   C notEvenAConstructor(a) = h;
-//                              ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:14:29: Error: Expected a function body or '=>'.
-// Try adding {}.
-//   C.missingFactoryKeyword() = C.constant;
-//                             ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:21:28: Error: Expected a function body or '=>'.
-// Try adding {}.
-//   C notEvenAConstructor(a) = h;
-//                            ^
-//
-// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Getter not found: 'h'.
-//   C notEvenAConstructor(a) = h;
-//                              ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -118,11 +80,11 @@
   static factory good() → self::C
     let dynamic #redirecting_factory = self::C::constant in invalid-expression;
   method notEvenAConstructor(dynamic a) → self::C
-    return (let final dynamic #t1 = this in invalid-expression "pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
+    return invalid-expression "pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
   C notEvenAConstructor(a) = h;
-                             ^") as{TypeError} self::C;
+                             ^" as{TypeError} self::C;
 }
 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'.
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 0f4b3f6..6ea0318 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000044.dart:7:8: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -23,11 +25,24 @@
 //   C notEvenAConstructor(a) = h;
 //                              ^
 //
+// pkg/front_end/testcases/rasta/issue_000044.dart:7:10: Error: Getter not found: 'd'.
+// a b(c) = d;
+//          ^
+//
 // pkg/front_end/testcases/rasta/issue_000044.dart:14:29: Error: Expected a function body or '=>'.
 // Try adding {}.
 //   C.missingFactoryKeyword() = C.constant;
 //                             ^
 //
+// pkg/front_end/testcases/rasta/issue_000044.dart:14:33: Error: Getter not found: 'constant'.
+//   C.missingFactoryKeyword() = C.constant;
+//                                 ^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/issue_000044.dart:14:31: Error: Constructors can't have a return type.
+// Try removing the return type.
+//   C.missingFactoryKeyword() = C.constant;
+//                               ^
+//
 // pkg/front_end/testcases/rasta/issue_000044.dart:21:28: Error: Expected a function body or '=>'.
 // Try adding {}.
 //   C notEvenAConstructor(a) = h;
@@ -36,8 +51,18 @@
 // pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: Getter not found: 'h'.
 //   C notEvenAConstructor(a) = h;
 //                              ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
+//   C notEvenAConstructor(a) = h;
+//                              ^
+//
+// pkg/front_end/testcases/rasta/issue_000044.dart:27:15: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   print(const C.missingFactoryKeyword());
+//               ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -55,11 +80,11 @@
   static factory good() → self::C
     let<BottomType> #redirecting_factory = self::C::constant in invalid-expression;
   method notEvenAConstructor(dynamic a) → self::C
-    return (let final self::C #t1 = this in invalid-expression "pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
+    return invalid-expression "pkg/front_end/testcases/rasta/issue_000044.dart:21:30: Error: The getter 'h' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/rasta/issue_000044.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'h'.
   C notEvenAConstructor(a) = h;
-                             ^") as{TypeError} self::C;
+                             ^" as{TypeError} self::C;
 }
 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'.
diff --git a/pkg/front_end/testcases/rasta/issue_000045.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000045.dart.strong.expect
index 8540011..389cb09 100644
--- a/pkg/front_end/testcases/rasta/issue_000045.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000045.dart.strong.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: String starting with """ must end with """.
-// main() => """${1}
-//                  ^...
-//
-// pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: Expected ';' after this.
-// main() => """${1}
-//                  ^...
-//
-// pkg/front_end/testcases/rasta/issue_000045.dart:6:1: Error: Unexpected token ''.
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: String starting with """ must end with """.
-// main() => """${1}
-//                  ^...
-//
-// pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: Expected ';' after this.
-// main() => """${1}
-//                  ^...
-//
-// pkg/front_end/testcases/rasta/issue_000045.dart:6:1: Error: Unexpected token ''.
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: String starting with """ must end with """.
+// main() => """${1}
+//                  ^...
+//
+// pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: Expected ';' after this.
+// main() => """${1}
+//                  ^...
+//
+// pkg/front_end/testcases/rasta/issue_000045.dart:6:1: Error: Unexpected token ''.
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000045.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000045.dart.strong.transformed.expect
index cfd867a..389cb09 100644
--- a/pkg/front_end/testcases/rasta/issue_000045.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000045.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000045.dart:5:18: Error: String starting with """ must end with """.
 // main() => """${1}
@@ -9,8 +11,7 @@
 //                  ^...
 //
 // pkg/front_end/testcases/rasta/issue_000045.dart:6:1: Error: Unexpected token ''.
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.hierarchy.expect
new file mode 100644
index 0000000..76379344
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.c
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.expect
index 433743b..03e6bea 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.expect
@@ -1,40 +1,23 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
-//   C c = new Object)();
-//             ^^^^^^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
-//   C c = new Object)();
-//                   ^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
-//   C c = new Object)();
-//                   ^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
-//   C c = new Object)();
-//                    ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
-//   C c = new Object)();
-//             ^^^^^^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
-//   C c = new Object)();
-//                   ^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
-//   C c = new Object)();
-//                   ^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
-//   C c = new Object)();
-//                    ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
+//   C c = new Object)();
+//             ^^^^^^
+//
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
+//   C c = new Object)();
+//                   ^
+//
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
+//   C c = new Object)();
+//                   ^
+//
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
+//   C c = new Object)();
+//                    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.transformed.expect
index f92e78d..03e6bea 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
 //   C c = new Object)();
@@ -15,8 +17,7 @@
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
 //   C c = new Object)();
 //                    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.outline.expect
index 5151357..dace12b 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
 //   C c = new Object)();
@@ -15,8 +17,7 @@
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
 //   C c = new Object)();
 //                    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.strong.expect
index 6e4cf81..5bc1e07 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
 //   C c = new Object)();
@@ -22,26 +24,7 @@
 // Change the type of the object being constructed or the context in which it is used.
 //   C c = new Object)();
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
-//   C c = new Object)();
-//             ^^^^^^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected ';' after this.
-//   C c = new Object)();
-//                   ^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:19: Error: Expected a class member, but got ')'.
-//   C c = new Object)();
-//                   ^
-//
-// pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
-//   C c = new Object)();
-//                    ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000046.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000046.dart.strong.transformed.expect
index bb3c37b..5bc1e07 100644
--- a/pkg/front_end/testcases/rasta/issue_000046.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000046.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: Expected '(' after this.
 //   C c = new Object)();
@@ -15,8 +17,14 @@
 // pkg/front_end/testcases/rasta/issue_000046.dart:6:20: Error: Expected an identifier, but got '('.
 //   C c = new Object)();
 //                    ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/issue_000046.dart:6:13: Error: The constructor returns type 'Object' that isn't of expected type 'C'.
+//  - 'Object' is from 'dart:core'.
+//  - 'C' is from 'pkg/front_end/testcases/rasta/issue_000046.dart'.
+// Change the type of the object being constructed or the context in which it is used.
+//   C c = new Object)();
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/issue_000047.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000047.dart.strong.expect
index 0805396..2683e8b 100644
--- a/pkg/front_end/testcases/rasta/issue_000047.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000047.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/issue_000047.dart:5:17: Error: Expected ')' before this.
-// typedef void T(C<C>);
-//                 ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/issue_000047.dart:5:17: Error: Expected ')' before this.
-// typedef void T(C<C>);
-//                 ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/issue_000047.dart:5:17: Error: Expected ')' before this.
+// typedef void T(C<C>);
+//                 ^
+//
 import self as self;
 
 typedef T = (dynamic) → void;
diff --git a/pkg/front_end/testcases/rasta/issue_000047.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000047.dart.strong.transformed.expect
index 1209acc..2683e8b 100644
--- a/pkg/front_end/testcases/rasta/issue_000047.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000047.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/issue_000047.dart:5:17: Error: Expected ')' before this.
 // typedef void T(C<C>);
 //                 ^
-
-library;
+//
 import self as self;
 
 typedef T = (dynamic) → void;
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
new file mode 100644
index 0000000..6fe92fb
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.hierarchy.expect
@@ -0,0 +1,97 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.v2
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.v2
+    A.v1
+
+M1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    M1.v2
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M1.v2
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces: M1
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    M1.v2
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M1.v2
+    A.v1
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    M1.v2
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    A.v1
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M1.v2
+    A.v1
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.hierarchy.expect
new file mode 100644
index 0000000..1901380
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    C.==
+    C.test
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.hierarchy.expect
new file mode 100644
index 0000000..705a7e3
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.hierarchy.expect
@@ -0,0 +1,494 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.m
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.m
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._redirecting#
+
+D:
+  superclasses:
+    Object
+      -> A
+        -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.expect
index dac4315..ad715d1 100644
--- a/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::foo];
   constructor •() → self::A
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.transformed.expect
index dac4315..ad715d1 100644
--- a/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::foo];
   constructor •() → self::A
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.outline.expect
index cda502f..2416e8c 100644
--- a/pkg/front_end/testcases/rasta/issue_000067.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::foo];
   constructor •() → self::A
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.strong.expect
index b685cab..936c23e 100644
--- a/pkg/front_end/testcases/rasta/issue_000067.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::foo];
   constructor •() → self::A
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.strong.transformed.expect
index 5d95998..25a5efa 100644
--- a/pkg/front_end/testcases/rasta/issue_000067.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::foo];
   constructor •() → self::A
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.hierarchy.expect
new file mode 100644
index 0000000..9a18fb1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.hierarchy.expect
@@ -0,0 +1,504 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+G:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.expect
index eeadf14..8148c18 100644
--- a/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class G<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::G<self::G::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.transformed.expect
index eeadf14..8148c18 100644
--- a/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class G<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::G<self::G::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.outline.expect
index 3ed2a46..ba0bd39 100644
--- a/pkg/front_end/testcases/rasta/issue_000068.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class G<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::G<self::G::T>
     ;
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.strong.expect
index eeadf14..8148c18 100644
--- a/pkg/front_end/testcases/rasta/issue_000068.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class G<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::G<self::G::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.strong.transformed.expect
index eeadf14..8148c18 100644
--- a/pkg/front_end/testcases/rasta/issue_000068.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class G<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::G<self::G::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.hierarchy.expect
new file mode 100644
index 0000000..c2b7ee7
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.hierarchy.expect
@@ -0,0 +1,488 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.getter
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.setter
+
+J:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+      -> J<C, K>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.expect
index a4e0188..cb5054f 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<N extends core::Object = dynamic, S extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
   final field core::List<self::A::U> field;
   constructor •(self::A::N n, self::A::S s) → self::A<self::A::N, self::A::S, self::A::U>
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.transformed.expect
index 1acca31..24788b5 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<N extends core::Object = dynamic, S extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
   final field core::List<self::A::U> field;
   constructor •(self::A::N n, self::A::S s) → self::A<self::A::N, self::A::S, self::A::U>
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect
index acc739a..3f08fac 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class A<N extends core::Object = dynamic, S extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
   final field core::List<self::A::U> field;
   constructor •(self::A::N n, self::A::S s) → self::A<self::A::N, self::A::S, self::A::U>
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
index 0f3241e..82beacc 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<N extends core::Object = dynamic, S extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
   final field core::List<self::A::U> field;
   constructor •(self::A::N n, self::A::S s) → self::A<self::A::N, self::A::S, self::A::U>
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
index 1fd973c..e99b7e6 100644
--- a/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<N extends core::Object = dynamic, S extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
   final field core::List<self::A::U> field;
   constructor •(self::A::N n, self::A::S s) → self::A<self::A::N, self::A::S, self::A::U>
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.hierarchy.expect
new file mode 100644
index 0000000..76d68ab
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.hierarchy.expect
@@ -0,0 +1,112 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+
+Object with Mixin:
+  superclasses:
+    Object
+  interfaces: Mixin
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.field
+
+Foo:
+  superclasses:
+    Object
+      -> _Foo&Object&Mixin
+  interfaces: Mixin
+  classMembers:
+    Foo.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Foo.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.field
+  interfaceMembers:
+    Foo.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.field
+    Object._instanceOf
+    Foo.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.field
diff --git a/pkg/front_end/testcases/rasta/issue_000081.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/issue_000081.dart.hierarchy.expect
new file mode 100644
index 0000000..8077a1b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000081.dart.hierarchy.expect
@@ -0,0 +1,59 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Base.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.hashCode
+
+Sub:
+  superclasses:
+    Object
+      -> Base
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Sub.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Sub.hashCode
+    Sub._hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Base.hashCode
+    Sub._hashCode
diff --git a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..804e9c5
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.outline.expect b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.outline.expect
index e94468a..d9be9b4 100644
--- a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_const_constructor.dart:8:5: Error: Expected '{' before this.
 //     : x = 'foo'
@@ -17,8 +19,7 @@
 // Try adding the name of the type of the variable or the keyword 'var'.
 //     : x = 'foo'
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.expect b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.expect
index 28a0ed7..f279790 100644
--- a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_const_constructor.dart:8:5: Error: Expected '{' before this.
 //     : x = 'foo'
@@ -22,28 +24,7 @@
 // Try using a constructor or factory that is 'const'.
 //   const A();
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/malformed_const_constructor.dart:8:5: Error: Expected '{' before this.
-//     : x = 'foo'
-//     ^
-//
-// pkg/front_end/testcases/rasta/malformed_const_constructor.dart:6:3: Error: A const constructor can't have a body.
-// Try removing either the 'const' keyword or the body.
-//   const A()
-//   ^^^^^
-//
-// pkg/front_end/testcases/rasta/malformed_const_constructor.dart:8:5: Error: Expected a class member, but got ':'.
-//     : x = 'foo'
-//     ^
-//
-// pkg/front_end/testcases/rasta/malformed_const_constructor.dart:8:7: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
-// Try adding the name of the type of the variable or the keyword 'var'.
-//     : x = 'foo'
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.transformed.expect
index 58f81f6..f279790 100644
--- a/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_const_constructor.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_const_constructor.dart:8:5: Error: Expected '{' before this.
 //     : x = 'foo'
@@ -17,8 +19,12 @@
 // Try adding the name of the type of the variable or the keyword 'var'.
 //     : x = 'foo'
 //       ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/malformed_const_constructor.dart:13:9: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
+// Try using a constructor or factory that is 'const'.
+//   const A();
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function.dart.strong.expect b/pkg/front_end/testcases/rasta/malformed_function.dart.strong.expect
index f964b8b..35bc1cd 100644
--- a/pkg/front_end/testcases/rasta/malformed_function.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_function.dart:7:8: Error: Can't assign to a parenthesized expression.
 //   (null) = null;
 //        ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/malformed_function.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function.dart.strong.transformed.expect
index caf6bf2..35bc1cd 100644
--- a/pkg/front_end/testcases/rasta/malformed_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/malformed_function.dart:7:8: Error: Can't assign to a parenthesized expression.
+//   (null) = null;
+//        ^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.expect
index ffb842a..a560042 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
-// typedef Handle Handle(String command);
-//                ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
-// typedef Handle Handle(String command);
-//                ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
+// typedef Handle Handle(String command);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.transformed.expect
index a51b1d7..a560042 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.outline.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.outline.expect
index 6591886..b38e97e 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect
index ffb842a..a560042 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
-// typedef Handle Handle(String command);
-//                ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
-// typedef Handle Handle(String command);
-//                ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
+// typedef Handle Handle(String command);
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect
index a51b1d7..a560042 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.outline.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.outline.expect
index fde9d1b..bf1b2a6 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:16: Error: Non-optional parameters can't have a default value.
 // Try removing the default value or making the parameter optional.
 // main(arguments = [x]) {
 //                ^
-
-library;
+//
 import self as self;
 
 static method main(dynamic arguments) → dynamic
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
index 16c7815..f49eacf 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:16: Error: Non-optional parameters can't have a default value.
 // Try removing the default value or making the parameter optional.
@@ -8,15 +10,7 @@
 // pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
 // main(arguments = [x]) {
 //                   ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:16: Error: Non-optional parameters can't have a default value.
-// Try removing the default value or making the parameter optional.
-// main(arguments = [x]) {
-//                ^
-
-library;
 import self as self;
 
 static method main(dynamic arguments = <dynamic>[invalid-expression "pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
diff --git a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
index 060ab4d..f49eacf 100644
--- a/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart.strong.transformed.expect
@@ -1,11 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:16: Error: Non-optional parameters can't have a default value.
 // Try removing the default value or making the parameter optional.
 // main(arguments = [x]) {
 //                ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
+// main(arguments = [x]) {
+//                   ^
+//
 import self as self;
 
 static method main(dynamic arguments = <dynamic>[invalid-expression "pkg/front_end/testcases/rasta/mandatory_parameter_initializer.dart:5:19: Error: Getter not found: 'x'.
diff --git a/pkg/front_end/testcases/rasta/mixin_library.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/mixin_library.dart.hierarchy.expect
new file mode 100644
index 0000000..14e36fa
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/mixin_library.dart.hierarchy.expect
@@ -0,0 +1,50 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Mixin.y
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
diff --git a/pkg/front_end/testcases/rasta/mixin_library.dart.strong.expect b/pkg/front_end/testcases/rasta/mixin_library.dart.strong.expect
index eadddb5..e919718 100644
--- a/pkg/front_end/testcases/rasta/mixin_library.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/mixin_library.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
-//   foo() => super.foo() + f();
-//                  ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
-//   foo() => super.foo() + f();
-//                  ^^^
-
 library test.mixin_library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
+//   foo() => super.foo() + f();
+//                  ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/native_is_illegal.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/native_is_illegal.dart.hierarchy.expect
new file mode 100644
index 0000000..a6345cf
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/native_is_illegal.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Bar.f
+    Object.toString
+    Bar.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Bar.x
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/parser_error.dart.hierarchy.expect
new file mode 100644
index 0000000..98d4425
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.hierarchy.expect
@@ -0,0 +1,433 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.legacy.expect b/pkg/front_end/testcases/rasta/parser_error.dart.legacy.expect
index 12c517d..43a8c2d 100644
--- a/pkg/front_end/testcases/rasta/parser_error.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.legacy.expect
@@ -1,10 +1,34 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: Expected an identifier, but got '?'.
+//   if (?b) return b;  /// 01: compile-time error
+//       ^
+//
+// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected ':' before this.
+//   if (?b) return b;  /// 01: compile-time error
+//         ^
+//
+// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected an identifier, but got ')'.
+//   if (?b) return b;  /// 01: compile-time error
+//         ^
+//
 import self as self;
-import "package:expect/expect.dart" as exp;
 import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
 
-static method test() → dynamic
-  invalid-statement;
+import "package:expect/expect.dart";
+
+static method test(dynamic a, {dynamic b = null, dynamic c = null}) → core::int {
+  if(invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: This couldn't be parsed.
+  if (?b) return b;  /// 01: compile-time error
+      ^" ? b : invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: This couldn't be parsed.
+  if (?b) return b;  /// 01: compile-time error
+        ^")
+    return b;
+  return a.+(b).+(c);
+}
 static method main() → dynamic {
-  exp::Expect::equals(6, throw core::_genericNoSuchMethod(null, #test, <dynamic>[1], <dynamic, dynamic>{#b: 2, #c: 3}, <dynamic>[]));
+  exp::Expect::equals(6, self::test(1, b: 2, c: 3));
 }
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.outline.expect b/pkg/front_end/testcases/rasta/parser_error.dart.outline.expect
index 4d53b67..58835f8 100644
--- a/pkg/front_end/testcases/rasta/parser_error.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic a, {dynamic b, dynamic c}) → core::int
   ;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.strong.expect b/pkg/front_end/testcases/rasta/parser_error.dart.strong.expect
index 9b575d7..1e7100e 100644
--- a/pkg/front_end/testcases/rasta/parser_error.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.strong.expect
@@ -1,36 +1,25 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: Expected an identifier, but got '?'.
-//   if (?b) return b;  /// 01: compile-time error
-//       ^
-//
-// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected ':' before this.
-//   if (?b) return b;  /// 01: compile-time error
-//         ^
-//
-// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected an identifier, but got ')'.
-//   if (?b) return b;  /// 01: compile-time error
-//         ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: Expected an identifier, but got '?'.
-//   if (?b) return b;  /// 01: compile-time error
-//       ^
-//
-// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected ':' before this.
-//   if (?b) return b;  /// 01: compile-time error
-//         ^
-//
-// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected an identifier, but got ')'.
-//   if (?b) return b;  /// 01: compile-time error
-//         ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: Expected an identifier, but got '?'.
+//   if (?b) return b;  /// 01: compile-time error
+//       ^
+//
+// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected ':' before this.
+//   if (?b) return b;  /// 01: compile-time error
+//         ^
+//
+// pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected an identifier, but got ')'.
+//   if (?b) return b;  /// 01: compile-time error
+//         ^
+//
 import self as self;
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic a, {dynamic b = null, dynamic c = null}) → core::int {
   if((invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: This couldn't be parsed.
   if (?b) return b;  /// 01: compile-time error
diff --git a/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect
index 1e72f8b..1e7100e 100644
--- a/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/parser_error.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: Expected an identifier, but got '?'.
 //   if (?b) return b;  /// 01: compile-time error
@@ -11,12 +13,13 @@
 // pkg/front_end/testcases/rasta/parser_error.dart:10:9: Error: Expected an identifier, but got ')'.
 //   if (?b) return b;  /// 01: compile-time error
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 static method test(dynamic a, {dynamic b = null, dynamic c = null}) → core::int {
   if((invalid-expression "pkg/front_end/testcases/rasta/parser_error.dart:10:7: Error: This couldn't be parsed.
   if (?b) return b;  /// 01: compile-time error
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect
index f479708..a4ac799 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.expect
@@ -2,7 +2,15 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::foo();
 }
+
+library deferred_lib;
+import self as def;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect
index f479708..a4ac799 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.legacy.transformed.expect
@@ -2,7 +2,15 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::foo();
 }
+
+library deferred_lib;
+import self as def;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect
index 7a4d537..c800260 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect
@@ -1,7 +1,15 @@
 library;
 import self as self;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic
   ;
 static method test() → dynamic
   ;
+
+library deferred_lib;
+import self as self2;
+
+static method foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
index f479708..a4ac799 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
@@ -2,7 +2,15 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::foo();
 }
+
+library deferred_lib;
+import self as def;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
index 935b4fb..52df70f 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
@@ -3,7 +3,15 @@
 import "dart:core" as core;
 import "./deferred_lib.dart" as def;
 
+import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
+
 static method main() → dynamic {}
 static method test() → dynamic {
   let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::foo();
 }
+
+library deferred_lib;
+import self as def;
+
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/rasta/static.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/static.dart.hierarchy.expect
new file mode 100644
index 0000000..088ac67
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/static.dart.hierarchy.expect
@@ -0,0 +1,42 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Foo.staticConstant
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Foo.staticFunction
+    Object._instanceOf
+    Foo.staticField
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    Foo.staticGetter
+  classSetters:
+    Foo.staticSetter
+    Foo.staticField
diff --git a/pkg/front_end/testcases/rasta/static.dart.legacy.expect b/pkg/front_end/testcases/rasta/static.dart.legacy.expect
index 202c04a..70d0f8c 100644
--- a/pkg/front_end/testcases/rasta/static.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/static.dart:28:9: Warning: Getter not found: 'staticSetter'.
 //     Foo.staticSetter;
@@ -135,8 +137,7 @@
 // pkg/front_end/testcases/rasta/static.dart:84:13: Warning: Getter not found: 'staticSetter'.
 //     use(Foo.staticSetter ??= 87);
 //             ^^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
index 1147ce7..70d0f8c 100644
--- a/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.legacy.transformed.expect
@@ -1,4 +1,143 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/static.dart:28:9: Warning: Getter not found: 'staticSetter'.
+//     Foo.staticSetter;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:29:13: Warning: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:31:9: Warning: Setter not found: 'staticConstant'.
+//     Foo.staticConstant++;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:32:13: Warning: Setter not found: 'staticConstant'.
+//     use(Foo.staticConstant++);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:35:9: Warning: Setter not found: 'staticFunction'.
+//     Foo.staticFunction++;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:36:13: Warning: Setter not found: 'staticFunction'.
+//     use(Foo.staticFunction++);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:37:9: Warning: Setter not found: 'staticGetter'.
+//     Foo.staticGetter++;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:38:13: Warning: Setter not found: 'staticGetter'.
+//     use(Foo.staticGetter++);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:39:9: Warning: Getter not found: 'staticSetter'.
+//     Foo.staticSetter++;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:40:13: Warning: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter++);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:42:11: Warning: Setter not found: 'staticConstant'.
+//     ++Foo.staticConstant;
+//           ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:43:15: Warning: Setter not found: 'staticConstant'.
+//     use(++Foo.staticConstant);
+//               ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:46:11: Warning: Setter not found: 'staticFunction'.
+//     ++Foo.staticFunction;
+//           ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:47:15: Warning: Setter not found: 'staticFunction'.
+//     use(++Foo.staticFunction);
+//               ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:48:11: Warning: Setter not found: 'staticGetter'.
+//     ++Foo.staticGetter;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:49:15: Warning: Setter not found: 'staticGetter'.
+//     use(++Foo.staticGetter);
+//               ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:50:11: Warning: Getter not found: 'staticSetter'.
+//     ++Foo.staticSetter;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:51:15: Warning: Getter not found: 'staticSetter'.
+//     use(++Foo.staticSetter);
+//               ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:61:9: Warning: Getter not found: 'staticSetter'.
+//     Foo.staticSetter();
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:62:13: Warning: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter());
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:64:9: Warning: Setter not found: 'staticConstant'.
+//     Foo.staticConstant = 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:65:13: Warning: Setter not found: 'staticConstant'.
+//     use(Foo.staticConstant = 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:68:9: Warning: Setter not found: 'staticFunction'.
+//     Foo.staticFunction = 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:69:13: Warning: Setter not found: 'staticFunction'.
+//     use(Foo.staticFunction = 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:70:9: Warning: Setter not found: 'staticGetter'.
+//     Foo.staticGetter = 87;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:71:13: Warning: Setter not found: 'staticGetter'.
+//     use(Foo.staticGetter = 87);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:75:9: Warning: Setter not found: 'staticConstant'.
+//     Foo.staticConstant ??= 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:76:13: Warning: Setter not found: 'staticConstant'.
+//     use(Foo.staticConstant ??= 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:79:9: Warning: Setter not found: 'staticFunction'.
+//     Foo.staticFunction ??= 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:80:13: Warning: Setter not found: 'staticFunction'.
+//     use(Foo.staticFunction ??= 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:81:9: Warning: Setter not found: 'staticGetter'.
+//     Foo.staticGetter ??= 87;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:82:13: Warning: Setter not found: 'staticGetter'.
+//     use(Foo.staticGetter ??= 87);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:83:9: Warning: Getter not found: 'staticSetter'.
+//     Foo.staticSetter ??= 87;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:84:13: Warning: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter ??= 87);
+//             ^^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/static.dart.strong.expect b/pkg/front_end/testcases/rasta/static.dart.strong.expect
index 5efd7f0..34a6ee1 100644
--- a/pkg/front_end/testcases/rasta/static.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/static.dart:28:9: Error: Getter not found: 'staticSetter'.
 //     Foo.staticSetter;
@@ -175,8 +177,7 @@
 // Try correcting the name to the name of an existing method, or defining a method named 'call'.
 //     use(Foo.staticField());
 //                        ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -263,19 +264,19 @@
     self::use(self::Foo::staticSetter = invalid-expression "pkg/front_end/testcases/rasta/static.dart:51:15: Error: Getter not found: 'staticSetter'.
     use(++Foo.staticSetter);
               ^^^^^^^^^^^^".+(1));
-    let final dynamic #t11 = self::Foo::staticConstant in invalid-expression "pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
+    invalid-expression "pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     Foo.staticConstant();
                       ^";
-    self::use(let final dynamic #t12 = self::Foo::staticConstant in invalid-expression "pkg/front_end/testcases/rasta/static.dart:54:27: Error: The method 'call' isn't defined for the class 'int'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/static.dart:54:27: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     use(Foo.staticConstant());
                           ^");
-    let final dynamic #t13 = self::Foo::staticField in invalid-expression "pkg/front_end/testcases/rasta/static.dart:55:20: Error: The method 'call' isn't defined for the class 'int'.
+    invalid-expression "pkg/front_end/testcases/rasta/static.dart:55:20: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     Foo.staticField();
                    ^";
-    self::use(let final dynamic #t14 = self::Foo::staticField in invalid-expression "pkg/front_end/testcases/rasta/static.dart:56:24: Error: The method 'call' isn't defined for the class 'int'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/static.dart:56:24: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     use(Foo.staticField());
                        ^");
@@ -314,29 +315,29 @@
     self::Foo::staticConstant.{core::Object::==}(null) ?{core::int} invalid-expression "pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
     Foo.staticConstant ??= 87;
         ^^^^^^^^^^^^^^" : null;
-    self::use(let final core::int #t15 = self::Foo::staticConstant in #t15.{core::Object::==}(null) ?{core::int} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
+    self::use(let final core::int #t11 = self::Foo::staticConstant in #t11.{core::Object::==}(null) ?{core::int} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
     use(Foo.staticConstant ??= 87);
-            ^^^^^^^^^^^^^^" : #t15);
+            ^^^^^^^^^^^^^^" : #t11);
     self::Foo::staticField.{core::num::==}(null) ?{core::int} self::Foo::staticField = 87 : null;
-    self::use(let final core::int #t16 = self::Foo::staticField in #t16.{core::num::==}(null) ?{core::int} self::Foo::staticField = 87 : #t16);
+    self::use(let final core::int #t12 = self::Foo::staticField in #t12.{core::num::==}(null) ?{core::int} self::Foo::staticField = 87 : #t12);
     self::Foo::staticFunction.{core::Object::==}(null) ?{core::Object} invalid-expression "pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
     Foo.staticFunction ??= 87;
         ^^^^^^^^^^^^^^" : null;
-    self::use(let final () → dynamic #t17 = self::Foo::staticFunction in #t17.{core::Object::==}(null) ?{core::Object} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
+    self::use(let final () → dynamic #t13 = self::Foo::staticFunction in #t13.{core::Object::==}(null) ?{core::Object} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
     use(Foo.staticFunction ??= 87);
-            ^^^^^^^^^^^^^^" : #t17);
+            ^^^^^^^^^^^^^^" : #t13);
     self::Foo::staticGetter.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:81:9: Error: Setter not found: 'staticGetter'.
     Foo.staticGetter ??= 87;
         ^^^^^^^^^^^^" : null;
-    self::use(let final dynamic #t18 = self::Foo::staticGetter in #t18.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:82:13: Error: Setter not found: 'staticGetter'.
+    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:82:13: Error: Setter not found: 'staticGetter'.
     use(Foo.staticGetter ??= 87);
-            ^^^^^^^^^^^^" : #t18);
+            ^^^^^^^^^^^^" : #t14);
     invalid-expression "pkg/front_end/testcases/rasta/static.dart:83:9: Error: Getter not found: 'staticSetter'.
     Foo.staticSetter ??= 87;
         ^^^^^^^^^^^^".{core::Object::==}(null) ?{dynamic} self::Foo::staticSetter = 87 : null;
-    self::use(let final dynamic #t19 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:84:13: Error: Getter not found: 'staticSetter'.
+    self::use(let final dynamic #t15 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:84:13: Error: Getter not found: 'staticSetter'.
     use(Foo.staticSetter ??= 87);
-            ^^^^^^^^^^^^" in #t19.{core::Object::==}(null) ?{dynamic} self::Foo::staticSetter = 87 : #t19);
+            ^^^^^^^^^^^^" in #t15.{core::Object::==}(null) ?{dynamic} self::Foo::staticSetter = 87 : #t15);
   }
   on core::NoSuchMethodError catch(no-exception-var) {
   }
diff --git a/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect
index 4ac004a..34a6ee1 100644
--- a/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/static.dart.strong.transformed.expect
@@ -1,4 +1,183 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/static.dart:28:9: Error: Getter not found: 'staticSetter'.
+//     Foo.staticSetter;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:29:13: Error: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:31:9: Error: Setter not found: 'staticConstant'.
+//     Foo.staticConstant++;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:32:13: Error: Setter not found: 'staticConstant'.
+//     use(Foo.staticConstant++);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:35:9: Error: Setter not found: 'staticFunction'.
+//     Foo.staticFunction++;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:36:13: Error: Setter not found: 'staticFunction'.
+//     use(Foo.staticFunction++);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:37:9: Error: Setter not found: 'staticGetter'.
+//     Foo.staticGetter++;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:38:13: Error: Setter not found: 'staticGetter'.
+//     use(Foo.staticGetter++);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:39:9: Error: Getter not found: 'staticSetter'.
+//     Foo.staticSetter++;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:40:13: Error: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter++);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:42:11: Error: Setter not found: 'staticConstant'.
+//     ++Foo.staticConstant;
+//           ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:43:15: Error: Setter not found: 'staticConstant'.
+//     use(++Foo.staticConstant);
+//               ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:46:11: Error: Setter not found: 'staticFunction'.
+//     ++Foo.staticFunction;
+//           ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:47:15: Error: Setter not found: 'staticFunction'.
+//     use(++Foo.staticFunction);
+//               ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:48:11: Error: Setter not found: 'staticGetter'.
+//     ++Foo.staticGetter;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:49:15: Error: Setter not found: 'staticGetter'.
+//     use(++Foo.staticGetter);
+//               ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:50:11: Error: Getter not found: 'staticSetter'.
+//     ++Foo.staticSetter;
+//           ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:51:15: Error: Getter not found: 'staticSetter'.
+//     use(++Foo.staticSetter);
+//               ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:61:9: Error: Getter not found: 'staticSetter'.
+//     Foo.staticSetter();
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:62:13: Error: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter());
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:64:9: Error: Setter not found: 'staticConstant'.
+//     Foo.staticConstant = 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:65:13: Error: Setter not found: 'staticConstant'.
+//     use(Foo.staticConstant = 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:68:9: Error: Setter not found: 'staticFunction'.
+//     Foo.staticFunction = 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:69:13: Error: Setter not found: 'staticFunction'.
+//     use(Foo.staticFunction = 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:70:9: Error: Setter not found: 'staticGetter'.
+//     Foo.staticGetter = 87;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:71:13: Error: Setter not found: 'staticGetter'.
+//     use(Foo.staticGetter = 87);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
+//     Foo.staticConstant ??= 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
+//     use(Foo.staticConstant ??= 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
+//     Foo.staticFunction ??= 87;
+//         ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
+//     use(Foo.staticFunction ??= 87);
+//             ^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:81:9: Error: Setter not found: 'staticGetter'.
+//     Foo.staticGetter ??= 87;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:82:13: Error: Setter not found: 'staticGetter'.
+//     use(Foo.staticGetter ??= 87);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:83:9: Error: Getter not found: 'staticSetter'.
+//     Foo.staticSetter ??= 87;
+//         ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:84:13: Error: Getter not found: 'staticSetter'.
+//     use(Foo.staticSetter ??= 87);
+//             ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/static.dart:35:23: Error: The method '+' isn't defined for the class 'dynamic Function()'.
+// Try correcting the name to the name of an existing method, or defining a method named '+'.
+//     Foo.staticFunction++;
+//                       ^
+//
+// pkg/front_end/testcases/rasta/static.dart:36:27: Error: The method '+' isn't defined for the class 'dynamic Function()'.
+// Try correcting the name to the name of an existing method, or defining a method named '+'.
+//     use(Foo.staticFunction++);
+//                           ^
+//
+// pkg/front_end/testcases/rasta/static.dart:46:5: Error: The method '+' isn't defined for the class 'dynamic Function()'.
+// Try correcting the name to the name of an existing method, or defining a method named '+'.
+//     ++Foo.staticFunction;
+//     ^
+//
+// pkg/front_end/testcases/rasta/static.dart:47:9: Error: The method '+' isn't defined for the class 'dynamic Function()'.
+// Try correcting the name to the name of an existing method, or defining a method named '+'.
+//     use(++Foo.staticFunction);
+//         ^
+//
+// pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'call'.
+//     Foo.staticConstant();
+//                       ^
+//
+// pkg/front_end/testcases/rasta/static.dart:54:27: Error: The method 'call' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'call'.
+//     use(Foo.staticConstant());
+//                           ^
+//
+// pkg/front_end/testcases/rasta/static.dart:55:20: Error: The method 'call' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'call'.
+//     Foo.staticField();
+//                    ^
+//
+// pkg/front_end/testcases/rasta/static.dart:56:24: Error: The method 'call' isn't defined for the class 'int'.
+// Try correcting the name to the name of an existing method, or defining a method named 'call'.
+//     use(Foo.staticField());
+//                        ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -85,19 +264,19 @@
     self::use(self::Foo::staticSetter = invalid-expression "pkg/front_end/testcases/rasta/static.dart:51:15: Error: Getter not found: 'staticSetter'.
     use(++Foo.staticSetter);
               ^^^^^^^^^^^^".+(1));
-    let final core::int #t11 = self::Foo::staticConstant in invalid-expression "pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
+    invalid-expression "pkg/front_end/testcases/rasta/static.dart:53:23: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     Foo.staticConstant();
                       ^";
-    self::use(let final core::int #t12 = self::Foo::staticConstant in invalid-expression "pkg/front_end/testcases/rasta/static.dart:54:27: Error: The method 'call' isn't defined for the class 'int'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/static.dart:54:27: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     use(Foo.staticConstant());
                           ^");
-    let final core::int #t13 = self::Foo::staticField in invalid-expression "pkg/front_end/testcases/rasta/static.dart:55:20: Error: The method 'call' isn't defined for the class 'int'.
+    invalid-expression "pkg/front_end/testcases/rasta/static.dart:55:20: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     Foo.staticField();
                    ^";
-    self::use(let final core::int #t14 = self::Foo::staticField in invalid-expression "pkg/front_end/testcases/rasta/static.dart:56:24: Error: The method 'call' isn't defined for the class 'int'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/static.dart:56:24: Error: The method 'call' isn't defined for the class 'int'.
 Try correcting the name to the name of an existing method, or defining a method named 'call'.
     use(Foo.staticField());
                        ^");
@@ -136,29 +315,29 @@
     self::Foo::staticConstant.{core::Object::==}(null) ?{core::int} invalid-expression "pkg/front_end/testcases/rasta/static.dart:75:9: Error: Setter not found: 'staticConstant'.
     Foo.staticConstant ??= 87;
         ^^^^^^^^^^^^^^" : null;
-    self::use(let final core::int #t15 = self::Foo::staticConstant in #t15.{core::Object::==}(null) ?{core::int} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
+    self::use(let final core::int #t11 = self::Foo::staticConstant in #t11.{core::Object::==}(null) ?{core::int} invalid-expression "pkg/front_end/testcases/rasta/static.dart:76:13: Error: Setter not found: 'staticConstant'.
     use(Foo.staticConstant ??= 87);
-            ^^^^^^^^^^^^^^" : #t15);
+            ^^^^^^^^^^^^^^" : #t11);
     self::Foo::staticField.{core::num::==}(null) ?{core::int} self::Foo::staticField = 87 : null;
-    self::use(let final core::int #t16 = self::Foo::staticField in #t16.{core::num::==}(null) ?{core::int} self::Foo::staticField = 87 : #t16);
+    self::use(let final core::int #t12 = self::Foo::staticField in #t12.{core::num::==}(null) ?{core::int} self::Foo::staticField = 87 : #t12);
     self::Foo::staticFunction.{core::Object::==}(null) ?{core::Object} invalid-expression "pkg/front_end/testcases/rasta/static.dart:79:9: Error: Setter not found: 'staticFunction'.
     Foo.staticFunction ??= 87;
         ^^^^^^^^^^^^^^" : null;
-    self::use(let final () → dynamic #t17 = self::Foo::staticFunction in #t17.{core::Object::==}(null) ?{core::Object} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
+    self::use(let final () → dynamic #t13 = self::Foo::staticFunction in #t13.{core::Object::==}(null) ?{core::Object} invalid-expression "pkg/front_end/testcases/rasta/static.dart:80:13: Error: Setter not found: 'staticFunction'.
     use(Foo.staticFunction ??= 87);
-            ^^^^^^^^^^^^^^" : #t17);
+            ^^^^^^^^^^^^^^" : #t13);
     self::Foo::staticGetter.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:81:9: Error: Setter not found: 'staticGetter'.
     Foo.staticGetter ??= 87;
         ^^^^^^^^^^^^" : null;
-    self::use(let final dynamic #t18 = self::Foo::staticGetter in #t18.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:82:13: Error: Setter not found: 'staticGetter'.
+    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/static.dart:82:13: Error: Setter not found: 'staticGetter'.
     use(Foo.staticGetter ??= 87);
-            ^^^^^^^^^^^^" : #t18);
+            ^^^^^^^^^^^^" : #t14);
     invalid-expression "pkg/front_end/testcases/rasta/static.dart:83:9: Error: Getter not found: 'staticSetter'.
     Foo.staticSetter ??= 87;
         ^^^^^^^^^^^^".{core::Object::==}(null) ?{dynamic} self::Foo::staticSetter = 87 : null;
-    self::use(let final dynamic #t19 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:84:13: Error: Getter not found: 'staticSetter'.
+    self::use(let final dynamic #t15 = invalid-expression "pkg/front_end/testcases/rasta/static.dart:84:13: Error: Getter not found: 'staticSetter'.
     use(Foo.staticSetter ??= 87);
-            ^^^^^^^^^^^^" in #t19.{core::Object::==}(null) ?{dynamic} self::Foo::staticSetter = 87 : #t19);
+            ^^^^^^^^^^^^" in #t15.{core::Object::==}(null) ?{dynamic} self::Foo::staticSetter = 87 : #t15);
   }
   on core::NoSuchMethodError catch(no-exception-var) {
   }
diff --git a/pkg/front_end/testcases/rasta/super.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/super.dart.hierarchy.expect
new file mode 100644
index 0000000..48669bd
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super.dart.hierarchy.expect
@@ -0,0 +1,139 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.b
+    A.f
+    A.a
+    A.[]=
+    Object.toString
+    A.e
+    A.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.n
+    A.i
+    Object._instanceOf
+    A.d
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.c
+    A.h
+    A.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+    A.~
+  classSetters:
+    A.b
+    A.a
+    A.n
+    A.d
+    A.c
+    A.h
+    A.g
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    B.b
+    A.f
+    A.a
+    A.[]=
+    Object.toString
+    A.e
+    A.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.n
+    A.i
+    Object._instanceOf
+    B.d
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.c
+    A.h
+    A.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+    A.~
+  classSetters:
+    A.b
+    A.a
+    A.n
+    B.i
+    A.d
+    B.c
+    A.h
+    A.g
+
+C:
+  superclasses:
+    Object
+      -> A
+        -> B
+  interfaces:
+  classMembers:
+    B.b
+    A.f
+    A.a
+    A.[]=
+    Object.toString
+    A.e
+    A.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.n
+    A.i
+    Object._instanceOf
+    B.d
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.c
+    A.h
+    A.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    A.==
+    A.~
+    C.test
+  classSetters:
+    A.b
+    A.a
+    A.n
+    B.i
+    A.d
+    B.c
+    A.h
+    A.g
diff --git a/pkg/front_end/testcases/rasta/super.dart.legacy.expect b/pkg/front_end/testcases/rasta/super.dart.legacy.expect
index 473cece..55dfd57 100644
--- a/pkg/front_end/testcases/rasta/super.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/super.dart:27:7: Error: 'n' is already declared in this scope.
 //   set n(_) {}
@@ -236,34 +238,7 @@
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/super.dart:27:7: Error: 'n' is already declared in this scope.
-//   set n(_) {}
-//       ^
-//
-// pkg/front_end/testcases/rasta/super.dart:43:5: Error: '+' is not a prefix operator.
-// Try removing '+'.
-//     +super;
-//     ^
-//
-// pkg/front_end/testcases/rasta/super.dart:44:9: Error: '+' is not a prefix operator.
-// Try removing '+'.
-//     use(+super);
-//         ^
-//
-// pkg/front_end/testcases/rasta/super.dart:11:9: Error: Final field 'f' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final f;
-//         ^
-//
-// pkg/front_end/testcases/rasta/super.dart:33:9: Error: Final field 'd' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final d;
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
index f92047d..55dfd57 100644
--- a/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.legacy.transformed.expect
@@ -1,19 +1,234 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/super.dart:27:7: Error: 'n' is already declared in this scope.
 //   set n(_) {}
 //       ^
+// pkg/front_end/testcases/rasta/super.dart:26:8: Context: Previous declaration of 'n'.
+//   void n() {}
+//        ^
 //
 // pkg/front_end/testcases/rasta/super.dart:43:5: Error: '+' is not a prefix operator.
 // Try removing '+'.
 //     +super;
 //     ^
 //
+// pkg/front_end/testcases/rasta/super.dart:43:6: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//     +super;
+//      ^^^^^
+//
 // pkg/front_end/testcases/rasta/super.dart:44:9: Error: '+' is not a prefix operator.
 // Try removing '+'.
 //     use(+super);
 //         ^
 //
+// pkg/front_end/testcases/rasta/super.dart:44:10: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//     use(+super);
+//          ^^^^^
+//
+// pkg/front_end/testcases/rasta/super.dart:62:11: Warning: Superclass has no getter named 'g'.
+//     super.g;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:63:15: Warning: Superclass has no getter named 'g'.
+//     use(super.g);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:83:11: Warning: Superclass has no setter named 'e'.
+//     super.e++;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:84:15: Warning: Superclass has no setter named 'e'.
+//     use(super.e++);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:85:11: Warning: Superclass has no setter named 'f'.
+//     super.f++;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:86:15: Warning: Superclass has no setter named 'f'.
+//     use(super.f++);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:87:11: Warning: Superclass has no getter named 'g'.
+//     super.g++;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:88:15: Warning: Superclass has no getter named 'g'.
+//     use(super.g++);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:95:11: Warning: Superclass has no setter named 'm'.
+//     super.m++;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:96:15: Warning: Superclass has no setter named 'm'.
+//     use(super.m++);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:108:13: Warning: Superclass has no setter named 'e'.
+//     ++super.e;
+//             ^
+//
+// pkg/front_end/testcases/rasta/super.dart:109:17: Warning: Superclass has no setter named 'e'.
+//     use(++super.e);
+//                 ^
+//
+// pkg/front_end/testcases/rasta/super.dart:110:13: Warning: Superclass has no setter named 'f'.
+//     ++super.f;
+//             ^
+//
+// pkg/front_end/testcases/rasta/super.dart:111:17: Warning: Superclass has no setter named 'f'.
+//     use(++super.f);
+//                 ^
+//
+// pkg/front_end/testcases/rasta/super.dart:112:13: Warning: Superclass has no getter named 'g'.
+//     ++super.g;
+//             ^
+//
+// pkg/front_end/testcases/rasta/super.dart:113:17: Warning: Superclass has no getter named 'g'.
+//     use(++super.g);
+//                 ^
+//
+// pkg/front_end/testcases/rasta/super.dart:120:13: Warning: Superclass has no setter named 'm'.
+//     ++super.m;
+//             ^
+//
+// pkg/front_end/testcases/rasta/super.dart:121:17: Warning: Superclass has no setter named 'm'.
+//     use(++super.m);
+//                 ^
+//
+// pkg/front_end/testcases/rasta/super.dart:137:11: Warning: Superclass has no method named 'g'.
+//     super.g();
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:138:15: Warning: Superclass has no method named 'g'.
+//     use(super.g());
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:160:11: Warning: Superclass has no setter named 'e'.
+//     super.e = 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:161:15: Warning: Superclass has no setter named 'e'.
+//     use(super.e = 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:162:11: Warning: Superclass has no setter named 'f'.
+//     super.f = 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:163:15: Warning: Superclass has no setter named 'f'.
+//     use(super.f = 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:172:11: Warning: Superclass has no setter named 'm'.
+//     super.m = 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:173:15: Warning: Superclass has no setter named 'm'.
+//     use(super.m = 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:185:11: Warning: Superclass has no setter named 'e'.
+//     super.e ??= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:186:15: Warning: Superclass has no setter named 'e'.
+//     use(super.e ??= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:187:11: Warning: Superclass has no setter named 'f'.
+//     super.f ??= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:188:15: Warning: Superclass has no setter named 'f'.
+//     use(super.f ??= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:189:11: Warning: Superclass has no getter named 'g'.
+//     super.g ??= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:190:15: Warning: Superclass has no getter named 'g'.
+//     use(super.g ??= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:197:11: Warning: Superclass has no setter named 'm'.
+//     super.m ??= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:198:15: Warning: Superclass has no setter named 'm'.
+//     use(super.m ??= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:210:11: Warning: Superclass has no setter named 'e'.
+//     super.e += 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:211:15: Warning: Superclass has no setter named 'e'.
+//     use(super.e += 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:212:11: Warning: Superclass has no setter named 'f'.
+//     super.f += 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:213:15: Warning: Superclass has no setter named 'f'.
+//     use(super.f += 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:214:11: Warning: Superclass has no getter named 'g'.
+//     super.g += 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:215:15: Warning: Superclass has no getter named 'g'.
+//     use(super.g += 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:222:11: Warning: Superclass has no setter named 'm'.
+//     super.m += 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:223:15: Warning: Superclass has no setter named 'm'.
+//     use(super.m += 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:235:11: Warning: Superclass has no setter named 'e'.
+//     super.e -= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:236:15: Warning: Superclass has no setter named 'e'.
+//     use(super.e -= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:237:11: Warning: Superclass has no setter named 'f'.
+//     super.f -= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:238:15: Warning: Superclass has no setter named 'f'.
+//     use(super.f -= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:239:11: Warning: Superclass has no getter named 'g'.
+//     super.g -= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:240:15: Warning: Superclass has no getter named 'g'.
+//     use(super.g -= 42);
+//               ^
+//
+// pkg/front_end/testcases/rasta/super.dart:247:11: Warning: Superclass has no setter named 'm'.
+//     super.m -= 42;
+//           ^
+//
+// pkg/front_end/testcases/rasta/super.dart:248:15: Warning: Superclass has no setter named 'm'.
+//     use(super.m -= 42);
+//               ^
+//
 // pkg/front_end/testcases/rasta/super.dart:11:9: Error: Final field 'f' is not initialized.
 // Try to initialize the field in the declaration or in every constructor.
 //   final f;
@@ -23,8 +238,7 @@
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/super.dart.outline.expect b/pkg/front_end/testcases/rasta/super.dart.outline.expect
index c3496aa..d668783 100644
--- a/pkg/front_end/testcases/rasta/super.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/super.dart:27:7: Error: 'n' is already declared in this scope.
 //   set n(_) {}
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/rasta/super.dart:26:8: Context: Previous declaration of 'n'.
 //   void n() {}
 //        ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/super.dart.strong.expect b/pkg/front_end/testcases/rasta/super.dart.strong.expect
index ade1e132..72a069a 100644
--- a/pkg/front_end/testcases/rasta/super.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.strong.expect
@@ -1,11 +1,13 @@
-// Formatted problems:
+library;
 //
-// pkg/front_end/testcases/rasta/super.dart:26:8: Error: Can't declare a member that conflicts with an inherited one.
-//   void n() {}
-//        ^
-// pkg/front_end/testcases/rasta/super.dart:27:7: Context: This is the inherited member.
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/super.dart:27:7: Error: 'n' is already declared in this scope.
 //   set n(_) {}
 //       ^
+// pkg/front_end/testcases/rasta/super.dart:26:8: Context: Previous declaration of 'n'.
+//   void n() {}
+//        ^
 //
 // pkg/front_end/testcases/rasta/super.dart:43:5: Error: '+' is not a prefix operator.
 // Try removing '+'.
@@ -348,254 +350,7 @@
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/super.dart:26:8: Error: Can't declare a member that conflicts with an inherited one.
-//   void n() {}
-//        ^
-//
-// pkg/front_end/testcases/rasta/super.dart:43:5: Error: '+' is not a prefix operator.
-// Try removing '+'.
-//     +super;
-//     ^
-//
-// pkg/front_end/testcases/rasta/super.dart:44:9: Error: '+' is not a prefix operator.
-// Try removing '+'.
-//     use(+super);
-//         ^
-//
-// pkg/front_end/testcases/rasta/super.dart:62:11: Error: Superclass has no getter named 'g'.
-//     super.g;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:63:15: Error: Superclass has no getter named 'g'.
-//     use(super.g);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:83:11: Error: Superclass has no setter named 'e'.
-//     super.e++;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:84:15: Error: Superclass has no setter named 'e'.
-//     use(super.e++);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:85:11: Error: Superclass has no setter named 'f'.
-//     super.f++;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:86:15: Error: Superclass has no setter named 'f'.
-//     use(super.f++);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:87:11: Error: Superclass has no getter named 'g'.
-//     super.g++;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:88:15: Error: Superclass has no getter named 'g'.
-//     use(super.g++);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:95:11: Error: Superclass has no setter named 'm'.
-//     super.m++;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:96:15: Error: Superclass has no setter named 'm'.
-//     use(super.m++);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:108:13: Error: Superclass has no setter named 'e'.
-//     ++super.e;
-//             ^
-//
-// pkg/front_end/testcases/rasta/super.dart:109:17: Error: Superclass has no setter named 'e'.
-//     use(++super.e);
-//                 ^
-//
-// pkg/front_end/testcases/rasta/super.dart:110:13: Error: Superclass has no setter named 'f'.
-//     ++super.f;
-//             ^
-//
-// pkg/front_end/testcases/rasta/super.dart:111:17: Error: Superclass has no setter named 'f'.
-//     use(++super.f);
-//                 ^
-//
-// pkg/front_end/testcases/rasta/super.dart:112:13: Error: Superclass has no getter named 'g'.
-//     ++super.g;
-//             ^
-//
-// pkg/front_end/testcases/rasta/super.dart:113:17: Error: Superclass has no getter named 'g'.
-//     use(++super.g);
-//                 ^
-//
-// pkg/front_end/testcases/rasta/super.dart:120:13: Error: Superclass has no setter named 'm'.
-//     ++super.m;
-//             ^
-//
-// pkg/front_end/testcases/rasta/super.dart:121:17: Error: Superclass has no setter named 'm'.
-//     use(++super.m);
-//                 ^
-//
-// pkg/front_end/testcases/rasta/super.dart:137:11: Error: Superclass has no method named 'g'.
-//     super.g();
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:138:15: Error: Superclass has no method named 'g'.
-//     use(super.g());
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:160:11: Error: Superclass has no setter named 'e'.
-//     super.e = 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:161:15: Error: Superclass has no setter named 'e'.
-//     use(super.e = 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:162:11: Error: Superclass has no setter named 'f'.
-//     super.f = 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:163:15: Error: Superclass has no setter named 'f'.
-//     use(super.f = 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:172:11: Error: Superclass has no setter named 'm'.
-//     super.m = 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:173:15: Error: Superclass has no setter named 'm'.
-//     use(super.m = 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:185:11: Error: Superclass has no setter named 'e'.
-//     super.e ??= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:186:15: Error: Superclass has no setter named 'e'.
-//     use(super.e ??= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:187:11: Error: Superclass has no setter named 'f'.
-//     super.f ??= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:188:15: Error: Superclass has no setter named 'f'.
-//     use(super.f ??= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:189:11: Error: Superclass has no getter named 'g'.
-//     super.g ??= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:190:15: Error: Superclass has no getter named 'g'.
-//     use(super.g ??= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:197:11: Error: Superclass has no setter named 'm'.
-//     super.m ??= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:198:15: Error: Superclass has no setter named 'm'.
-//     use(super.m ??= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:210:11: Error: Superclass has no setter named 'e'.
-//     super.e += 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:211:15: Error: Superclass has no setter named 'e'.
-//     use(super.e += 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:212:11: Error: Superclass has no setter named 'f'.
-//     super.f += 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:213:15: Error: Superclass has no setter named 'f'.
-//     use(super.f += 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:214:11: Error: Superclass has no getter named 'g'.
-//     super.g += 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:215:15: Error: Superclass has no getter named 'g'.
-//     use(super.g += 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:222:11: Error: Superclass has no setter named 'm'.
-//     super.m += 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:223:15: Error: Superclass has no setter named 'm'.
-//     use(super.m += 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:235:11: Error: Superclass has no setter named 'e'.
-//     super.e -= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:236:15: Error: Superclass has no setter named 'e'.
-//     use(super.e -= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:237:11: Error: Superclass has no setter named 'f'.
-//     super.f -= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:238:15: Error: Superclass has no setter named 'f'.
-//     use(super.f -= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:239:11: Error: Superclass has no getter named 'g'.
-//     super.g -= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:240:15: Error: Superclass has no getter named 'g'.
-//     use(super.g -= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:247:11: Error: Superclass has no setter named 'm'.
-//     super.m -= 42;
-//           ^
-//
-// pkg/front_end/testcases/rasta/super.dart:248:15: Error: Superclass has no setter named 'm'.
-//     use(super.m -= 42);
-//               ^
-//
-// pkg/front_end/testcases/rasta/super.dart:147:12: Error: Too many positional arguments: 0 allowed, but 1 found.
-// Try removing the extra positional arguments.
-//     super.m(87);
-//            ^
-//
-// pkg/front_end/testcases/rasta/super.dart:148:16: Error: Too many positional arguments: 0 allowed, but 1 found.
-// Try removing the extra positional arguments.
-//     use(super.m(87));
-//                ^
-//
-// pkg/front_end/testcases/rasta/super.dart:149:12: Error: Too many positional arguments: 0 allowed, but 1 found.
-// Try removing the extra positional arguments.
-//     super.n(87);
-//            ^
-//
-// pkg/front_end/testcases/rasta/super.dart:150:16: Error: Too many positional arguments: 0 allowed, but 1 found.
-// Try removing the extra positional arguments.
-//     use(super.n(87));
-//                ^
-//
-// pkg/front_end/testcases/rasta/super.dart:11:9: Error: Final field 'f' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final f;
-//         ^
-//
-// pkg/front_end/testcases/rasta/super.dart:33:9: Error: Final field 'd' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final d;
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -708,22 +463,22 @@
     self::use(let final dynamic #t17 = super.{self::A::i} in let final dynamic #t18 = super.{self::B::i} = #t17.+(1) in #t17);
     let final core::int #t19 = 87 in super.{self::A::[]=}(#t19, super.{self::A::[]}(#t19).+(1));
     self::use(let final core::int #t20 = 87 in let final dynamic #t21 = super.{self::A::[]}(#t20) in let final void #t22 = super.{self::A::[]=}(#t20, #t21.+(1)) in #t21);
-    super.m = let final dynamic #t23 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:95:12: Error: The method '+' isn't defined for the class 'void Function()'.
+    super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:95:12: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     super.m++;
            ^";
-    self::use(let final () → void #t24 = super.{self::A::m} in let final dynamic #t25 = super.m = let final dynamic #t26 = #t24 in invalid-expression "pkg/front_end/testcases/rasta/super.dart:96:16: Error: The method '+' isn't defined for the class 'void Function()'.
+    self::use(let final () → void #t23 = super.{self::A::m} in let final dynamic #t24 = super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:96:16: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     use(super.m++);
-               ^" in #t24);
-    super.{self::A::n} = let final dynamic #t27 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:97:12: Error: The method '+' isn't defined for the class 'void Function()'.
+               ^" in #t23);
+    super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:97:12: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     super.n++;
            ^";
-    self::use(let final () → void #t28 = super.{self::A::n} in let final dynamic #t29 = super.{self::A::n} = let final dynamic #t30 = #t28 in invalid-expression "pkg/front_end/testcases/rasta/super.dart:98:16: Error: The method '+' isn't defined for the class 'void Function()'.
+    self::use(let final () → void #t25 = super.{self::A::n} in let final dynamic #t26 = super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:98:16: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     use(super.n++);
-               ^" in #t28);
+               ^" in #t25);
     super.{self::A::a} = super.{self::A::a}.+(1);
     self::use(super.{self::A::a} = super.{self::A::a}.+(1));
     super.{self::A::b} = super.{self::B::b}.+(1);
@@ -742,21 +497,21 @@
     self::use(super.{self::A::h} = super.{self::A::h}.+(1));
     super.{self::B::i} = super.{self::A::i}.+(1);
     self::use(super.{self::B::i} = super.{self::A::i}.+(1));
-    let final core::int #t31 = 87 in let final dynamic #t32 = super.{self::A::[]}(#t31).+(1) in let final void #t33 = super.{self::A::[]=}(#t31, #t32) in #t32;
-    self::use(let final core::int #t34 = 87 in let final dynamic #t35 = super.{self::A::[]}(#t34).+(1) in let final void #t36 = super.{self::A::[]=}(#t34, #t35) in #t35);
-    super.m = let final dynamic #t37 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:120:5: Error: The method '+' isn't defined for the class 'void Function()'.
+    let final core::int #t27 = 87 in let final dynamic #t28 = super.{self::A::[]}(#t27).+(1) in let final void #t29 = super.{self::A::[]=}(#t27, #t28) in #t28;
+    self::use(let final core::int #t30 = 87 in let final dynamic #t31 = super.{self::A::[]}(#t30).+(1) in let final void #t32 = super.{self::A::[]=}(#t30, #t31) in #t31);
+    super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:120:5: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     ++super.m;
     ^";
-    self::use(super.m = let final dynamic #t38 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:121:9: Error: The method '+' isn't defined for the class 'void Function()'.
+    self::use(super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:121:9: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     use(++super.m);
         ^");
-    super.{self::A::n} = let final dynamic #t39 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:122:5: Error: The method '+' isn't defined for the class 'void Function()'.
+    super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:122:5: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     ++super.n;
     ^";
-    self::use(super.{self::A::n} = let final dynamic #t40 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:123:9: Error: The method '+' isn't defined for the class 'void Function()'.
+    self::use(super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:123:9: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     use(++super.n);
         ^");
@@ -781,15 +536,15 @@
     super.{self::A::[]}(87).call();
     self::use(super.{self::A::[]}(87).call());
     super.{self::A::m}();
-    self::use(let final<BottomType> #t41 = invalid-expression "pkg/front_end/testcases/rasta/super.dart:146:15: Error: This expression has type 'void' and can't be used.
+    self::use(let final<BottomType> #t33 = invalid-expression "pkg/front_end/testcases/rasta/super.dart:146:15: Error: This expression has type 'void' and can't be used.
     use(super.m());
               ^" in super.{self::A::m}());
     super.{self::A::m}(87);
-    self::use(let final<BottomType> #t42 = invalid-expression "pkg/front_end/testcases/rasta/super.dart:148:15: Error: This expression has type 'void' and can't be used.
+    self::use(let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/rasta/super.dart:148:15: Error: This expression has type 'void' and can't be used.
     use(super.m(87));
               ^" in super.{self::A::m}(87));
     super.{self::A::n}(87);
-    self::use(let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/rasta/super.dart:150:15: Error: This expression has type 'void' and can't be used.
+    self::use(let final<BottomType> #t35 = invalid-expression "pkg/front_end/testcases/rasta/super.dart:150:15: Error: This expression has type 'void' and can't be used.
     use(super.n(87));
               ^" in super.{self::A::n}(87));
     super.{self::A::a} = 42;
@@ -811,35 +566,35 @@
     super.{self::B::i} = 42;
     self::use(super.{self::B::i} = 42);
     super.{self::A::[]=}(87, 42);
-    self::use(let final core::int #t44 = 87 in let final core::int #t45 = 42 in let final void #t46 = super.{self::A::[]=}(#t44, #t45) in #t45);
+    self::use(let final core::int #t36 = 87 in let final core::int #t37 = 42 in let final void #t38 = super.{self::A::[]=}(#t36, #t37) in #t37);
     super.m = 42;
     self::use(super.m = 42);
     super.{self::A::n} = 42;
     self::use(super.{self::A::n} = 42);
     super.{self::A::a}.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : null;
-    self::use(let final dynamic #t47 = super.{self::A::a} in #t47.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : #t47);
+    self::use(let final dynamic #t39 = super.{self::A::a} in #t39.{core::Object::==}(null) ?{dynamic} super.{self::A::a} = 42 : #t39);
     super.{self::B::b}.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : null;
-    self::use(let final dynamic #t48 = super.{self::B::b} in #t48.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : #t48);
+    self::use(let final dynamic #t40 = super.{self::B::b} in #t40.{core::Object::==}(null) ?{dynamic} super.{self::A::b} = 42 : #t40);
     super.{self::A::c}.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : null;
-    self::use(let final dynamic #t49 = super.{self::A::c} in #t49.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : #t49);
+    self::use(let final dynamic #t41 = super.{self::A::c} in #t41.{core::Object::==}(null) ?{dynamic} super.{self::B::c} = 42 : #t41);
     super.{self::B::d}.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : null;
-    self::use(let final dynamic #t50 = super.{self::B::d} in #t50.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : #t50);
+    self::use(let final dynamic #t42 = super.{self::B::d} in #t42.{core::Object::==}(null) ?{dynamic} super.{self::A::d} = 42 : #t42);
     super.{self::A::e}.{core::Object::==}(null) ?{dynamic} super.e = 42 : null;
-    self::use(let final dynamic #t51 = super.{self::A::e} in #t51.{core::Object::==}(null) ?{dynamic} super.e = 42 : #t51);
+    self::use(let final dynamic #t43 = super.{self::A::e} in #t43.{core::Object::==}(null) ?{dynamic} super.e = 42 : #t43);
     super.{self::A::f}.{core::Object::==}(null) ?{dynamic} super.f = 42 : null;
-    self::use(let final dynamic #t52 = super.{self::A::f} in #t52.{core::Object::==}(null) ?{dynamic} super.f = 42 : #t52);
+    self::use(let final dynamic #t44 = super.{self::A::f} in #t44.{core::Object::==}(null) ?{dynamic} super.f = 42 : #t44);
     super.g.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : null;
-    self::use(let final dynamic #t53 = super.g in #t53.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : #t53);
+    self::use(let final dynamic #t45 = super.g in #t45.{core::Object::==}(null) ?{dynamic} super.{self::A::g} = 42 : #t45);
     super.{self::A::h}.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : null;
-    self::use(let final dynamic #t54 = super.{self::A::h} in #t54.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : #t54);
+    self::use(let final dynamic #t46 = super.{self::A::h} in #t46.{core::Object::==}(null) ?{dynamic} super.{self::A::h} = 42 : #t46);
     super.{self::A::i}.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : null;
-    self::use(let final dynamic #t55 = super.{self::A::i} in #t55.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : #t55);
-    let final core::int #t56 = 87 in super.{self::A::[]}(#t56).{core::Object::==}(null) ?{dynamic} let final core::int #t57 = 42 in let final void #t58 = super.{self::A::[]=}(#t56, #t57) in #t57 : null;
-    self::use(let final core::int #t59 = 87 in let final dynamic #t60 = super.{self::A::[]}(#t59) in #t60.{core::Object::==}(null) ?{dynamic} let final core::int #t61 = 42 in let final void #t62 = super.{self::A::[]=}(#t59, #t61) in #t61 : #t60);
+    self::use(let final dynamic #t47 = super.{self::A::i} in #t47.{core::Object::==}(null) ?{dynamic} super.{self::B::i} = 42 : #t47);
+    let final core::int #t48 = 87 in super.{self::A::[]}(#t48).{core::Object::==}(null) ?{dynamic} let final core::int #t49 = 42 in let final void #t50 = super.{self::A::[]=}(#t48, #t49) in #t49 : null;
+    self::use(let final core::int #t51 = 87 in let final dynamic #t52 = super.{self::A::[]}(#t51) in #t52.{core::Object::==}(null) ?{dynamic} let final core::int #t53 = 42 in let final void #t54 = super.{self::A::[]=}(#t51, #t53) in #t53 : #t52);
     super.{self::A::m}.{core::Object::==}(null) ?{core::Object} super.m = 42 : null;
-    self::use(let final () → void #t63 = super.{self::A::m} in #t63.{core::Object::==}(null) ?{core::Object} super.m = 42 : #t63);
+    self::use(let final () → void #t55 = super.{self::A::m} in #t55.{core::Object::==}(null) ?{core::Object} super.m = 42 : #t55);
     super.{self::A::n}.{core::Object::==}(null) ?{core::Object} super.{self::A::n} = 42 : null;
-    self::use(let final () → void #t64 = super.{self::A::n} in #t64.{core::Object::==}(null) ?{core::Object} super.{self::A::n} = 42 : #t64);
+    self::use(let final () → void #t56 = super.{self::A::n} in #t56.{core::Object::==}(null) ?{core::Object} super.{self::A::n} = 42 : #t56);
     super.{self::A::a} = super.{self::A::a}.+(42);
     self::use(super.{self::A::a} = super.{self::A::a}.+(42));
     super.{self::A::b} = super.{self::B::b}.+(42);
@@ -858,21 +613,21 @@
     self::use(super.{self::A::h} = super.{self::A::h}.+(42));
     super.{self::B::i} = super.{self::A::i}.+(42);
     self::use(super.{self::B::i} = super.{self::A::i}.+(42));
-    let final core::int #t65 = 87 in super.{self::A::[]=}(#t65, super.{self::A::[]}(#t65).+(42));
-    self::use(let final core::int #t66 = 87 in let final dynamic #t67 = super.{self::A::[]}(#t66).+(42) in let final void #t68 = super.{self::A::[]=}(#t66, #t67) in #t67);
-    super.m = let final dynamic #t69 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:222:13: Error: The method '+' isn't defined for the class 'void Function()'.
+    let final core::int #t57 = 87 in super.{self::A::[]=}(#t57, super.{self::A::[]}(#t57).+(42));
+    self::use(let final core::int #t58 = 87 in let final dynamic #t59 = super.{self::A::[]}(#t58).+(42) in let final void #t60 = super.{self::A::[]=}(#t58, #t59) in #t59);
+    super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:222:13: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     super.m += 42;
             ^";
-    self::use(super.m = let final dynamic #t70 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:223:17: Error: The method '+' isn't defined for the class 'void Function()'.
+    self::use(super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:223:17: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     use(super.m += 42);
                 ^");
-    super.{self::A::n} = let final dynamic #t71 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:224:13: Error: The method '+' isn't defined for the class 'void Function()'.
+    super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:224:13: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     super.n += 42;
             ^";
-    self::use(super.{self::A::n} = let final dynamic #t72 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:225:17: Error: The method '+' isn't defined for the class 'void Function()'.
+    self::use(super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:225:17: Error: The method '+' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '+'.
     use(super.n += 42);
                 ^");
@@ -894,21 +649,21 @@
     self::use(super.{self::A::h} = super.{self::A::h}.-(42));
     super.{self::B::i} = super.{self::A::i}.-(42);
     self::use(super.{self::B::i} = super.{self::A::i}.-(42));
-    let final core::int #t73 = 87 in super.{self::A::[]=}(#t73, super.{self::A::[]}(#t73).-(42));
-    self::use(let final core::int #t74 = 87 in let final dynamic #t75 = super.{self::A::[]}(#t74).-(42) in let final void #t76 = super.{self::A::[]=}(#t74, #t75) in #t75);
-    super.m = let final dynamic #t77 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:247:13: Error: The method '-' isn't defined for the class 'void Function()'.
+    let final core::int #t61 = 87 in super.{self::A::[]=}(#t61, super.{self::A::[]}(#t61).-(42));
+    self::use(let final core::int #t62 = 87 in let final dynamic #t63 = super.{self::A::[]}(#t62).-(42) in let final void #t64 = super.{self::A::[]=}(#t62, #t63) in #t63);
+    super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:247:13: Error: The method '-' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '-'.
     super.m -= 42;
             ^";
-    self::use(super.m = let final dynamic #t78 = super.{self::A::m} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:248:17: Error: The method '-' isn't defined for the class 'void Function()'.
+    self::use(super.m = invalid-expression "pkg/front_end/testcases/rasta/super.dart:248:17: Error: The method '-' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '-'.
     use(super.m -= 42);
                 ^");
-    super.{self::A::n} = let final dynamic #t79 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:249:13: Error: The method '-' isn't defined for the class 'void Function()'.
+    super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:249:13: Error: The method '-' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '-'.
     super.n -= 42;
             ^";
-    self::use(super.{self::A::n} = let final dynamic #t80 = super.{self::A::n} in invalid-expression "pkg/front_end/testcases/rasta/super.dart:250:17: Error: The method '-' isn't defined for the class 'void Function()'.
+    self::use(super.{self::A::n} = invalid-expression "pkg/front_end/testcases/rasta/super.dart:250:17: Error: The method '-' isn't defined for the class 'void Function()'.
 Try correcting the name to the name of an existing method, or defining a method named '-'.
     use(super.n -= 42);
                 ^");
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..6b547e4
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Super:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Sub:
+  superclasses:
+    Object
+      -> Super
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Sub.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Sub.field
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.strong.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.strong.expect
index 04047ee..c1c4755 100644
--- a/pkg/front_end/testcases/rasta/super_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/super_initializer.dart:14:15: Error: Can't have initializers after 'super'.
 //       : super.arg0(),
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/rasta/super_initializer.dart:20:15: Error: Can't have initializers after 'super'.
 //       : super.arg2(a, b),
 //               ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/super_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/super_initializer.dart.strong.transformed.expect
index ab3a0b9..c1c4755 100644
--- a/pkg/front_end/testcases/rasta/super_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/super_initializer.dart.strong.transformed.expect
@@ -1,4 +1,19 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/super_initializer.dart:14:15: Error: Can't have initializers after 'super'.
+//       : super.arg0(),
+//               ^
+//
+// pkg/front_end/testcases/rasta/super_initializer.dart:17:15: Error: Can't have initializers after 'super'.
+//       : super.arg1(a),
+//               ^
+//
+// pkg/front_end/testcases/rasta/super_initializer.dart:20:15: Error: Can't have initializers after 'super'.
+//       : super.arg2(a, b),
+//               ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.hierarchy.expect
new file mode 100644
index 0000000..ff7667f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.hierarchy.expect
@@ -0,0 +1,431 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Super:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Super.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Super.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Mixin.y
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+
+Super<V> with Mixin<V>:
+  superclasses:
+    Object
+      -> Super<V>
+  interfaces: Mixin<V>
+  classMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+  interfaceMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+
+C:
+  superclasses:
+    Object
+      -> Super<V>
+        -> _C&Super&Mixin<V>
+  interfaces: Mixin<V>
+  classMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+  interfaceMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+
+Super with Mixin<dynamic>:
+  superclasses:
+    Object
+      -> Super
+  interfaces: Mixin<dynamic>
+  classMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+  interfaceMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+
+D:
+  superclasses:
+    Object
+      -> Super
+        -> _D&Super&Mixin
+  interfaces: Mixin<dynamic>
+  classMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+  interfaceMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+
+C2:
+  superclasses:
+    Object
+      -> Super<V>
+  interfaces: Mixin<V>
+  classMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+  interfaceMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+
+D2:
+  superclasses:
+    Object
+      -> Super
+  interfaces: Mixin<dynamic>
+  classMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
+  interfaceMembers:
+    Mixin.y
+    Super.f
+    Mixin.t
+    Object.toString
+    Mixin.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Mixin.publicMethod
+    Mixin._privateMethod
+    Object._instanceOf
+    Mixin.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Mixin.h
+    Object.hashCode
+    Mixin.g
+    Mixin.z
+    Mixin.l
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Mixin.y
+    Mixin.t
+    Mixin.x
+    Mixin.z
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect
index 5aca9d3..bf05d13 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.expect
@@ -1,14 +1,10 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Warning: Superclass has no method named 'foo'.
-//   foo() => super.foo() + f();
-//                  ^^^
-
 library;
 import self as self;
 import "dart:core" as core;
 import "./mixin_library.dart" as mix;
 
+import "org-dartlang-testcase:///mixin_library.dart";
+
 class Super<S extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::Super<self::Super::S>
     : super core::Object::•()
@@ -52,3 +48,44 @@
   core::print(new self::C::•<dynamic>().foo());
   core::print(new self::C2::•<dynamic>().foo());
 }
+
+library test.mixin_library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Warning: Superclass has no method named 'foo'.
+//   foo() => super.foo() + f();
+//                  ^^^
+//
+import self as mix;
+import "dart:core" as core;
+
+class Mixin<T extends core::Object = dynamic> extends core::Object {
+  field dynamic x = mix::f();
+  field dynamic y = null;
+  field dynamic z = null;
+  field mix::Mixin::T t = null;
+  synthetic constructor •() → mix::Mixin<mix::Mixin::T>
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return super.foo().+(mix::f());
+  method g(mix::Mixin::T a) → mix::Mixin::T
+    return null;
+  method h() → dynamic
+    return mix::V();
+  method l() → dynamic
+    return mix::_private();
+  method _privateMethod() → dynamic
+    return 49;
+  method publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+static method f() → dynamic
+  return 2;
+static method V() → dynamic
+  return 87;
+static method _private() → dynamic
+  return 117;
+static method foo(dynamic m) → dynamic
+  return m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect
index 97f3b5a..f68ab12 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./mixin_library.dart" as mix;
 
+import "org-dartlang-testcase:///mixin_library.dart";
+
 class Super<S extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::Super<self::Super::S>
     : super core::Object::•()
@@ -110,3 +112,44 @@
   core::print(new self::C::•<dynamic>().foo());
   core::print(new self::C2::•<dynamic>().foo());
 }
+
+library test.mixin_library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Warning: Superclass has no method named 'foo'.
+//   foo() => super.foo() + f();
+//                  ^^^
+//
+import self as mix;
+import "dart:core" as core;
+
+class Mixin<T extends core::Object = dynamic> extends core::Object {
+  field dynamic x = mix::f();
+  field dynamic y = null;
+  field dynamic z = null;
+  field mix::Mixin::T t = null;
+  synthetic constructor •() → mix::Mixin<mix::Mixin::T>
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return super.foo().+(mix::f());
+  method g(mix::Mixin::T a) → mix::Mixin::T
+    return null;
+  method h() → dynamic
+    return mix::V();
+  method l() → dynamic
+    return mix::_private();
+  method _privateMethod() → dynamic
+    return 49;
+  method publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+static method f() → dynamic
+  return 2;
+static method V() → dynamic
+  return 87;
+static method _private() → dynamic
+  return 117;
+static method foo(dynamic m) → dynamic
+  return m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect
index 372c093..3463b57 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./mixin_library.dart" as mix;
 
+import "org-dartlang-testcase:///mixin_library.dart";
+
 class Super<S extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::Super<self::Super::S>
     ;
@@ -41,3 +43,36 @@
 }
 static method main() → dynamic
   ;
+
+library test.mixin_library;
+import self as mix;
+import "dart:core" as core;
+
+class Mixin<T extends core::Object = dynamic> extends core::Object {
+  field dynamic x;
+  field dynamic y;
+  field dynamic z;
+  field mix::Mixin::T t;
+  synthetic constructor •() → mix::Mixin<mix::Mixin::T>
+    ;
+  method foo() → dynamic
+    ;
+  method g(mix::Mixin::T a) → mix::Mixin::T
+    ;
+  method h() → dynamic
+    ;
+  method l() → dynamic
+    ;
+  method _privateMethod() → dynamic
+    ;
+  method publicMethod() → dynamic
+    ;
+}
+static method f() → dynamic
+  ;
+static method V() → dynamic
+  ;
+static method _private() → dynamic
+  ;
+static method foo(dynamic m) → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect
index ac00fc5..5ecf3b5 100644
--- a/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.strong.expect
@@ -1,20 +1,10 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
-//   foo() => super.foo() + f();
-//                  ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
-//   foo() => super.foo() + f();
-//                  ^^^
-
 library;
 import self as self;
 import "dart:core" as core;
 import "./mixin_library.dart" as mix;
 
+import "org-dartlang-testcase:///mixin_library.dart";
+
 class Super<S extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::Super<self::Super::S>
     : super core::Object::•()
@@ -58,3 +48,44 @@
   core::print(new self::C::•<dynamic>().{mix::Mixin::foo}());
   core::print(new self::C2::•<dynamic>().{mix::Mixin::foo}());
 }
+
+library test.mixin_library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
+//   foo() => super.foo() + f();
+//                  ^^^
+//
+import self as mix;
+import "dart:core" as core;
+
+class Mixin<T extends core::Object = dynamic> extends core::Object {
+  field dynamic x = mix::f();
+  field dynamic y = null;
+  field dynamic z = null;
+  generic-covariant-impl field mix::Mixin::T t = null;
+  synthetic constructor •() → mix::Mixin<mix::Mixin::T>
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return super.foo().+(mix::f());
+  method g(generic-covariant-impl mix::Mixin::T a) → mix::Mixin::T
+    return null;
+  method h() → dynamic
+    return mix::V();
+  method l() → dynamic
+    return mix::_private();
+  method _privateMethod() → dynamic
+    return 49;
+  method publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+static method f() → dynamic
+  return 2;
+static method V() → dynamic
+  return 87;
+static method _private() → dynamic
+  return 117;
+static method foo(dynamic m) → dynamic
+  return m._privateMethod();
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/super_operator.dart.hierarchy.expect
new file mode 100644
index 0000000..2ab30e2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.hierarchy.expect
@@ -0,0 +1,78 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.[]=
+    Object.toString
+    A.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    A.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    B.[]=
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Autobianchi:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Autobianchi.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/super_operator.dart.strong.expect b/pkg/front_end/testcases/rasta/super_operator.dart.strong.expect
index 152b391..c49d683 100644
--- a/pkg/front_end/testcases/rasta/super_operator.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super_operator.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/super_operator.dart:22:15: Error: Superclass has no method named '[]'.
-//   g() => super[0];
-//               ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/super_operator.dart:22:15: Error: Superclass has no method named '[]'.
-//   g() => super[0];
-//               ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/super_operator.dart:22:15: Error: Superclass has no method named '[]'.
+//   g() => super[0];
+//               ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.expect
index fbd4248..3dec981 100644
--- a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:35:5: Warning: Switch case may fall through to the next case.
 //     case 2:  result = 2; /// static warning - case fall-through, see "Switch"
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:46:5: Warning: Switch case may fall through to the next case.
 //     case 1:
 //     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.transformed.expect
index 8c84e9b..3dec981 100644
--- a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.legacy.transformed.expect
@@ -1,4 +1,19 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:35:5: Warning: Switch case may fall through to the next case.
+//     case 2:  result = 2; /// static warning - case fall-through, see "Switch"
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:36:5: Warning: Switch case may fall through to the next case.
+//     case 3:  result = 3; /// static warning - case fall-through, see "Switch"
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:46:5: Warning: Switch case may fall through to the next case.
+//     case 1:
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.expect
index dd4fb5e..4ad744c 100644
--- a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.expect
@@ -1,32 +1,19 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:35:5: Error: Switch case may fall through to the next case.
-//     case 2:  result = 2; /// static warning - case fall-through, see "Switch"
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:36:5: Error: Switch case may fall through to the next case.
-//     case 3:  result = 3; /// static warning - case fall-through, see "Switch"
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:46:5: Error: Switch case may fall through to the next case.
-//     case 1:
-//     ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:35:5: Error: Switch case may fall through to the next case.
-//     case 2:  result = 2; /// static warning - case fall-through, see "Switch"
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:36:5: Error: Switch case may fall through to the next case.
-//     case 3:  result = 3; /// static warning - case fall-through, see "Switch"
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:46:5: Error: Switch case may fall through to the next case.
-//     case 1:
-//     ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:35:5: Error: Switch case may fall through to the next case.
+//     case 2:  result = 2; /// static warning - case fall-through, see "Switch"
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:36:5: Error: Switch case may fall through to the next case.
+//     case 3:  result = 3; /// static warning - case fall-through, see "Switch"
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:46:5: Error: Switch case may fall through to the next case.
+//     case 1:
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.transformed.expect
index a0e9c4f..4ad744c 100644
--- a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:35:5: Error: Switch case may fall through to the next case.
 //     case 2:  result = 2; /// static warning - case fall-through, see "Switch"
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/rasta/switch_execution_case_t02.dart:46:5: Error: Switch case may fall through to the next case.
 //     case 1:
 //     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.expect
index d2d8a68..917a871 100644
--- a/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/switch_fall_through.dart:7:5: Warning: Switch case may fall through to the next case.
 //     case 1:
@@ -19,8 +21,7 @@
 // pkg/front_end/testcases/rasta/switch_fall_through.dart:31:5: Warning: Switch case may fall through to the next case.
 //     case 5:
 //     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.transformed.expect
index bbdd5fa..917a871 100644
--- a/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.legacy.transformed.expect
@@ -1,4 +1,27 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:7:5: Warning: Switch case may fall through to the next case.
+//     case 1:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:13:5: Warning: Switch case may fall through to the next case.
+//     case 2:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:20:5: Warning: Switch case may fall through to the next case.
+//     case 3:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:26:5: Warning: Switch case may fall through to the next case.
+//     case 4:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:31:5: Warning: Switch case may fall through to the next case.
+//     case 5:
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.expect
index 04d25f9..4370b01 100644
--- a/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.expect
@@ -1,48 +1,27 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:7:5: Error: Switch case may fall through to the next case.
-//     case 1:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:13:5: Error: Switch case may fall through to the next case.
-//     case 2:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:20:5: Error: Switch case may fall through to the next case.
-//     case 3:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:26:5: Error: Switch case may fall through to the next case.
-//     case 4:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:31:5: Error: Switch case may fall through to the next case.
-//     case 5:
-//     ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:7:5: Error: Switch case may fall through to the next case.
-//     case 1:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:13:5: Error: Switch case may fall through to the next case.
-//     case 2:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:20:5: Error: Switch case may fall through to the next case.
-//     case 3:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:26:5: Error: Switch case may fall through to the next case.
-//     case 4:
-//     ^
-//
-// pkg/front_end/testcases/rasta/switch_fall_through.dart:31:5: Error: Switch case may fall through to the next case.
-//     case 5:
-//     ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:7:5: Error: Switch case may fall through to the next case.
+//     case 1:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:13:5: Error: Switch case may fall through to the next case.
+//     case 2:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:20:5: Error: Switch case may fall through to the next case.
+//     case 3:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:26:5: Error: Switch case may fall through to the next case.
+//     case 4:
+//     ^
+//
+// pkg/front_end/testcases/rasta/switch_fall_through.dart:31:5: Error: Switch case may fall through to the next case.
+//     case 5:
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.transformed.expect
index 242d0e4..4370b01 100644
--- a/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/switch_fall_through.dart:7:5: Error: Switch case may fall through to the next case.
 //     case 1:
@@ -19,8 +21,7 @@
 // pkg/front_end/testcases/rasta/switch_fall_through.dart:31:5: Error: Switch case may fall through to the next case.
 //     case 5:
 //     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/this_invoke.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/this_invoke.dart.hierarchy.expect
new file mode 100644
index 0000000..cd5ee43
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/this_invoke.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.call
+    Object._instanceOf
+    C.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/try_label.dart.strong.expect b/pkg/front_end/testcases/rasta/try_label.dart.strong.expect
index 0f4e271..14f6249 100644
--- a/pkg/front_end/testcases/rasta/try_label.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/try_label.dart.strong.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/try_label.dart:9:5: Error: A continue statement can't be used outside of a loop or switch statement.
-// Try removing the continue statement.
-//     continue L;
-//     ^^^^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/try_label.dart:9:5: Error: A continue statement can't be used outside of a loop or switch statement.
-// Try removing the continue statement.
-//     continue L;
-//     ^^^^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/try_label.dart:9:5: Error: A continue statement can't be used outside of a loop or switch statement.
+// Try removing the continue statement.
+//     continue L;
+//     ^^^^^^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/try_label.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/try_label.dart.strong.transformed.expect
index 8de56dd..14f6249 100644
--- a/pkg/front_end/testcases/rasta/try_label.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/try_label.dart.strong.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/try_label.dart:9:5: Error: A continue statement can't be used outside of a loop or switch statement.
 // Try removing the continue statement.
 //     continue L;
 //     ^^^^^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/type_literals.dart.hierarchy.expect
new file mode 100644
index 0000000..b628c46
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect b/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
index a0834cd24..c0e22e1 100644
--- a/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/type_literals.dart:22:5: Error: Method not found: 'dynamic'.
 //     dynamic();
@@ -279,8 +281,7 @@
 // pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
 //     use(Func -= 42);
 //         ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.hierarchy.expect
new file mode 100644
index 0000000..f0bc0b1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.i
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.i
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.expect
index fac7d19..e5baaab 100644
--- a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/type_with_parse_error.dart:21:7: Error: Expected ';' after this.
-//   int i
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/type_with_parse_error.dart:21:7: Error: Expected ';' after this.
-//   int i
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/type_with_parse_error.dart:21:7: Error: Expected ';' after this.
+//   int i
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.transformed.expect
index b8b11cc..e5baaab 100644
--- a/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/type_with_parse_error.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/type_with_parse_error.dart:21:7: Error: Expected ';' after this.
 //   int i
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.strong.expect b/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
index 6a68f69..d703c59 100644
--- a/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
 //   Foo = null;
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/rasta/typedef.dart:11:3: Error: Method not found: 'Foo'.
 //   Foo();
 //   ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/unresolved.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved.dart.strong.expect
index d596412..bc52a62 100644
--- a/pkg/front_end/testcases/rasta/unresolved.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/unresolved.dart:6:7: Error: Method not found: 'Missing'.
 //   new Missing();
 //       ^^^^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/unresolved.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unresolved.dart.strong.transformed.expect
index ffc54e6..bc52a62 100644
--- a/pkg/front_end/testcases/rasta/unresolved.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/unresolved.dart:6:7: Error: Method not found: 'Missing'.
+//   new Missing();
+//       ^^^^^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.expect
index f97fa23..0173ed6 100644
--- a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/unresolved_constructor.dart:10:10: Error: Too few positional arguments: 2 required, 0 given.
 //   new Foo();
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/rasta/unresolved_constructor.dart:11:11: Error: Method not found: 'Foo.notHere'.
 //   new Foo.notHere();
 //           ^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.transformed.expect
index 80c63ba..0173ed6 100644
--- a/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_constructor.dart.strong.transformed.expect
@@ -1,4 +1,18 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/unresolved_constructor.dart:10:10: Error: Too few positional arguments: 2 required, 0 given.
+//   new Foo();
+//          ^
+// pkg/front_end/testcases/rasta/unresolved_constructor.dart:6:3: Context: Found this candidate, but the arguments don't match.
+//   Foo(x, y);
+//   ^
+//
+// pkg/front_end/testcases/rasta/unresolved_constructor.dart:11:11: Error: Method not found: 'Foo.notHere'.
+//   new Foo.notHere();
+//           ^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.hierarchy.expect
new file mode 100644
index 0000000..a30fc97
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Fisk:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Fisk.it1
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.expect
index 907292f..ceda317 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Warning: Getter not found: 'key'.
 //       print(key);
@@ -71,21 +73,12 @@
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
 //   for (1 in arguments) {
 //        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected an identifier, but got '1'.
-//     for (1 in x) {
-//          ^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected an identifier, but got '1'.
-//   for (1 in arguments) {
-//        ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection" as collection;
+
 typedef VoidFunction = () → void;
 class Fisk extends core::Object {
   synthetic constructor •() → self::Fisk
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.transformed.expect
index 4629221..ceda317 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.legacy.transformed.expect
@@ -1,17 +1,84 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Warning: Getter not found: 'key'.
+//       print(key);
+//             ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Warning: Setter not found: 'key'.
+//     for (key in x) {
+//          ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Warning: Setter not found: 'Fisk'.
+//     for (Fisk in x) {
+//          ^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:18:13: Error: A prefix can't be used as an expression.
+//       print(collection);
+//             ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: A prefix can't be used as an expression.
+//     for (collection in x) {
+//          ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Warning: Setter not found: 'VoidFunction'.
+//     for (VoidFunction in x) {
+//          ^^^^^^^^^^^^
 //
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected an identifier, but got '1'.
 //     for (1 in x) {
 //          ^
 //
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Warning: Getter not found: 'key'.
+//       print(key);
+//             ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
+//     for (1 in x) {
+//          ^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:32:11: Warning: Getter not found: 'key'.
+//     print(key);
+//           ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:31:8: Warning: Setter not found: 'key'.
+//   for (key in arguments) {
+//        ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Warning: Setter not found: 'Fisk'.
+//   for (Fisk in arguments) {
+//        ^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:38:11: Error: A prefix can't be used as an expression.
+//     print(collection);
+//           ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: A prefix can't be used as an expression.
+//   for (collection in arguments) {
+//        ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Warning: Setter not found: 'VoidFunction'.
+//   for (VoidFunction in arguments) {
+//        ^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected an identifier, but got '1'.
 //   for (1 in arguments) {
 //        ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:44:11: Warning: Getter not found: 'key'.
+//     print(key);
+//           ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
+//   for (1 in arguments) {
+//        ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection" as collection;
+
 typedef VoidFunction = () → void;
 class Fisk extends core::Object {
   synthetic constructor •() → self::Fisk
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.outline.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.outline.expect
index dde777f..a27da5c 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection" as collection;
+
 typedef VoidFunction = () → void;
 class Fisk extends core::Object {
   synthetic constructor •() → self::Fisk
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
index 31ad421..54fcd03 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
 //       print(key);
@@ -89,33 +91,12 @@
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
 //   for (1 in arguments) {
 //        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
-//       print(key);
-//             ^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: Setter not found: 'key'.
-//     for (key in x) {
-//          ^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected an identifier, but got '1'.
-//     for (1 in x) {
-//          ^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: Getter not found: 'key'.
-//       print(key);
-//             ^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected an identifier, but got '1'.
-//   for (1 in arguments) {
-//        ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection" as collection;
+
 typedef VoidFunction = () → void;
 class Fisk extends core::Object {
   synthetic constructor •() → self::Fisk
@@ -123,24 +104,24 @@
     ;
   method it1(dynamic x) → dynamic {
     for (final dynamic #t1 in x as{TypeError} core::Iterable<dynamic>) {
-      let final dynamic #t2 = this in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: The setter 'key' isn't defined for the class 'Fisk'.
+      invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: The setter 'key' isn't defined for the class 'Fisk'.
  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'key'.
     for (key in x) {
          ^^^";
-      core::print(let final dynamic #t3 = this in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
+      core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'key'.
       print(key);
             ^^^");
     }
-    for (final dynamic #t4 in x as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t2 in x as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
     for (Fisk in x) {
          ^^^^";
       core::print(self::Fisk);
     }
-    for (final dynamic #t5 in x as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t3 in x as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: A prefix can't be used as an expression.
     for (collection in x) {
          ^^^^^^^^^^";
@@ -148,7 +129,7 @@
       print(collection);
             ^^^^^^^^^^");
     }
-    for (final dynamic #t6 in x as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t4 in x as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
     for (VoidFunction in x) {
          ^^^^^^^^^^^^";
@@ -158,12 +139,12 @@
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (1 in x) {
          ^";
-      for (final dynamic #t7 in x as{TypeError} core::Iterable<dynamic>) {
+      for (final dynamic #t5 in x as{TypeError} core::Iterable<dynamic>) {
         invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (1 in x) {
          ^";
         1;
-        core::print(let final dynamic #t8 = this in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
+        core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'key'.
       print(key);
@@ -174,7 +155,7 @@
 }
 static method main(dynamic arguments) → dynamic {
   new self::Fisk::•();
-  for (final dynamic #t9 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t6 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:31:8: Error: Setter not found: 'key'.
   for (key in arguments) {
        ^^^";
@@ -182,13 +163,13 @@
     print(key);
           ^^^");
   }
-  for (final dynamic #t10 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t7 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
   for (Fisk in arguments) {
        ^^^^";
     core::print(self::Fisk);
   }
-  for (final dynamic #t11 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t8 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: A prefix can't be used as an expression.
   for (collection in arguments) {
        ^^^^^^^^^^";
@@ -196,7 +177,7 @@
     print(collection);
           ^^^^^^^^^^");
   }
-  for (final dynamic #t12 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t9 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
   for (VoidFunction in arguments) {
        ^^^^^^^^^^^^";
@@ -206,7 +187,7 @@
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
   for (1 in arguments) {
        ^";
-    for (final dynamic #t13 in arguments as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t10 in arguments as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
   for (1 in arguments) {
        ^";
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 9316b38..54fcd03 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: Getter not found: 'key'.
 //       print(key);
@@ -8,6 +10,22 @@
 //     for (key in x) {
 //          ^^^
 //
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
+//     for (Fisk in x) {
+//          ^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:18:13: Error: A prefix can't be used as an expression.
+//       print(collection);
+//             ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: A prefix can't be used as an expression.
+//     for (collection in x) {
+//          ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
+//     for (VoidFunction in x) {
+//          ^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected an identifier, but got '1'.
 //     for (1 in x) {
 //          ^
@@ -16,14 +34,69 @@
 //       print(key);
 //             ^^^
 //
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
+//     for (1 in x) {
+//          ^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: The setter 'key' isn't defined for the class 'Fisk'.
+//  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'key'.
+//     for (key in x) {
+//          ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
+//  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'key'.
+//       print(key);
+//             ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
+//  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'key'.
+//       print(key);
+//             ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:32:11: Error: Getter not found: 'key'.
+//     print(key);
+//           ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:31:8: Error: Setter not found: 'key'.
+//   for (key in arguments) {
+//        ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
+//   for (Fisk in arguments) {
+//        ^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:38:11: Error: A prefix can't be used as an expression.
+//     print(collection);
+//           ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: A prefix can't be used as an expression.
+//   for (collection in arguments) {
+//        ^^^^^^^^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
+//   for (VoidFunction in arguments) {
+//        ^^^^^^^^^^^^
+//
 // pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected an identifier, but got '1'.
 //   for (1 in arguments) {
 //        ^
-
-library;
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:44:11: Error: Getter not found: 'key'.
+//     print(key);
+//           ^^^
+//
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
+//   for (1 in arguments) {
+//        ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection" as collection;
+
 typedef VoidFunction = () → void;
 class Fisk extends core::Object {
   synthetic constructor •() → self::Fisk
@@ -31,24 +104,24 @@
     ;
   method it1(dynamic x) → dynamic {
     for (final dynamic #t1 in x as{TypeError} core::Iterable<dynamic>) {
-      let final self::Fisk #t2 = this in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: The setter 'key' isn't defined for the class 'Fisk'.
+      invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:11:10: Error: The setter 'key' isn't defined for the class 'Fisk'.
  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'key'.
     for (key in x) {
          ^^^";
-      core::print(let final self::Fisk #t3 = this in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
+      core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:12:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'key'.
       print(key);
             ^^^");
     }
-    for (final dynamic #t4 in x as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t2 in x as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
     for (Fisk in x) {
          ^^^^";
       core::print(self::Fisk);
     }
-    for (final dynamic #t5 in x as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t3 in x as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: A prefix can't be used as an expression.
     for (collection in x) {
          ^^^^^^^^^^";
@@ -56,7 +129,7 @@
       print(collection);
             ^^^^^^^^^^");
     }
-    for (final dynamic #t6 in x as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t4 in x as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
     for (VoidFunction in x) {
          ^^^^^^^^^^^^";
@@ -66,12 +139,12 @@
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (1 in x) {
          ^";
-      for (final dynamic #t7 in x as{TypeError} core::Iterable<dynamic>) {
+      for (final dynamic #t5 in x as{TypeError} core::Iterable<dynamic>) {
         invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Can't assign to this, so it can't be used in a for-in loop.
     for (1 in x) {
          ^";
         1;
-        core::print(let final self::Fisk #t8 = this in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
+        core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:24:13: Error: The getter 'key' isn't defined for the class 'Fisk'.
  - 'Fisk' is from 'pkg/front_end/testcases/rasta/unresolved_for_in.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'key'.
       print(key);
@@ -82,7 +155,7 @@
 }
 static method main(dynamic arguments) → dynamic {
   new self::Fisk::•();
-  for (final dynamic #t9 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t6 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:31:8: Error: Setter not found: 'key'.
   for (key in arguments) {
        ^^^";
@@ -90,13 +163,13 @@
     print(key);
           ^^^");
   }
-  for (final dynamic #t10 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t7 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
   for (Fisk in arguments) {
        ^^^^";
     core::print(self::Fisk);
   }
-  for (final dynamic #t11 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t8 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: A prefix can't be used as an expression.
   for (collection in arguments) {
        ^^^^^^^^^^";
@@ -104,7 +177,7 @@
     print(collection);
           ^^^^^^^^^^");
   }
-  for (final dynamic #t12 in arguments as{TypeError} core::Iterable<dynamic>) {
+  for (final dynamic #t9 in arguments as{TypeError} core::Iterable<dynamic>) {
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
   for (VoidFunction in arguments) {
        ^^^^^^^^^^^^";
@@ -114,7 +187,7 @@
     invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
   for (1 in arguments) {
        ^";
-    for (final dynamic #t13 in arguments as{TypeError} core::Iterable<dynamic>) {
+    for (final dynamic #t10 in arguments as{TypeError} core::Iterable<dynamic>) {
       invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Can't assign to this, so it can't be used in a for-in loop.
   for (1 in arguments) {
        ^";
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.hierarchy.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.hierarchy.expect
new file mode 100644
index 0000000..20323e6
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    E.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect
index 77aeb40..bcaa50f 100644
--- a/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_recovery.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
 //     super[4] = 42;
@@ -39,42 +41,7 @@
 // pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:24: Error: Expected ';' after this.
 //   on Exception catch (e) { }
 //                        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:7:10: Error: Superclass has no method named '[]='.
-//     super[4] = 42;
-//          ^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]'.
-//     super[4] += 5;
-//          ^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:8:10: Error: Superclass has no method named '[]='.
-//     super[4] += 5;
-//          ^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:9:17: Error: Superclass has no method named '[]'.
-//     return super[2];
-//                 ^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:3: Error: 'on' isn't a type.
-//   on Exception catch (e) { }
-//   ^^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:6: Error: Expected ';' after this.
-//   on Exception catch (e) { }
-//      ^^^^^^^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:16: Error: Expected an identifier, but got 'catch'.
-//   on Exception catch (e) { }
-//                ^^^^^
-//
-// pkg/front_end/testcases/rasta/unresolved_recovery.dart:20:24: Error: Expected ';' after this.
-//   on Exception catch (e) { }
-//                        ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.expect
index c6efc4b..22b2878 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.expect
@@ -1,16 +1,7 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
 library;
 import self as self;
 
+import "dart:html";
+import "dart:io";
+
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.transformed.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.transformed.expect
index b3ae1f4..22b2878 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.legacy.transformed.expect
@@ -1,10 +1,7 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
 library;
 import self as self;
 
+import "dart:html";
+import "dart:io";
+
 static method main() → dynamic {}
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 9edee97..d2b8d3d 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,11 +1,8 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
 library;
 import self as self;
 
+import "dart:html";
+import "dart:io";
+
 static method main() → dynamic
   ;
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 c6efc4b..22b2878 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,16 +1,7 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
 library;
 import self as self;
 
+import "dart:html";
+import "dart:io";
+
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect
index b3ae1f4..22b2878 100644
--- a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.strong.transformed.expect
@@ -1,10 +1,7 @@
-// Unhandled errors:
-//
-// pkg/front_end/testcases/rasta/unsupported_platform_library.dart:5:8: Error: Not found: 'dart:html'
-// import 'dart:html';
-//        ^
-
 library;
 import self as self;
 
+import "dart:html";
+import "dart:io";
+
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/redirecting_constructor.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_constructor.dart.hierarchy.expect
new file mode 100644
index 0000000..c79ac19
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_constructor.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/redirecting_factory.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory.dart.hierarchy.expect
new file mode 100644
index 0000000..a3bb376
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory.dart.hierarchy.expect
@@ -0,0 +1,269 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+FooBase:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    FooBase.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    FooBase._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    FooBase._redirecting#
+
+Foo:
+  superclasses:
+    Object
+  interfaces: FooBase
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo._redirecting#
+  interfaceMembers:
+    Object.toString
+    FooBase.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Foo._redirecting#
+
+Bar:
+  superclasses:
+    Object
+  interfaces: Foo<Tb>, FooBase
+  classMembers:
+    Object.toString
+    Bar.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Bar.x
+  interfaceMembers:
+    Object.toString
+    Bar.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    Bar.x
+
+Builder:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Builder.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+SimpleCase:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    SimpleCase._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    SimpleCase._redirecting#
+
+SimpleCaseImpl:
+  superclasses:
+    Object
+  interfaces: SimpleCase<Ai, Bi>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    SimpleCaseImpl._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    SimpleCaseImpl._redirecting#
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    SimpleCaseImpl._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    SimpleCaseImpl._redirecting#
+
+SimpleCaseImpl2:
+  superclasses:
+    Object
+  interfaces: SimpleCaseImpl<Ai2, Bi2>, SimpleCase<Ai2, Bi2>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mixin:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Mix:
+  superclasses:
+    Object
+      -> Base<M>
+  interfaces: Mixin<M>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/redirecting_factory.dart.strong.expect b/pkg/front_end/testcases/redirecting_factory.dart.strong.expect
index bcf4fb8..76a019a 100644
--- a/pkg/front_end/testcases/redirecting_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/redirecting_factory.dart.strong.expect
@@ -1,20 +1,13 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/redirecting_factory.dart:7:28: Error: The constructor function type 'Foo<Tf> Function(int)' isn't a subtype of 'FooBase<Tf> Function(int)'.
-//  - 'Foo' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
-//  - 'FooBase' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
-//   factory FooBase(int x) = Foo<Tf>;
-//                            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/redirecting_factory.dart:7:28: Error: The constructor function type 'Foo<Tf> Function(int)' isn't a subtype of 'FooBase<Tf> Function(int)'.
-//  - 'Foo' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
-//  - 'FooBase' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
-//   factory FooBase(int x) = Foo<Tf>;
-//                            ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/redirecting_factory.dart:7:28: Error: The constructor function type 'Foo<Tf> Function(int)' isn't a subtype of 'FooBase<Tf> Function(int)'.
+//  - 'Foo' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
+//  - 'FooBase' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
+//   factory FooBase(int x) = Foo<Tf>;
+//                            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/redirecting_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/redirecting_factory.dart.strong.transformed.expect
index 4885beb..ab86769 100644
--- a/pkg/front_end/testcases/redirecting_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/redirecting_factory.dart.strong.transformed.expect
@@ -1,12 +1,13 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/redirecting_factory.dart:7:28: Error: The constructor function type 'Foo<Tf> Function(int)' isn't a subtype of 'FooBase<Tf> Function(int)'.
 //  - 'Foo' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
 //  - 'FooBase' is from 'pkg/front_end/testcases/redirecting_factory.dart'.
 //   factory FooBase(int x) = Foo<Tf>;
 //                            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/redirecting_factory_chain_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_chain_test.dart.hierarchy.expect
new file mode 100644
index 0000000..abc4300
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_chain_test.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
diff --git a/pkg/front_end/testcases/redirecting_factory_const_inference.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_const_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..8645346
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_const_inference.dart.hierarchy.expect
@@ -0,0 +1,106 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    _X._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    _X._redirecting#
+
+_Y:
+  superclasses:
+    Object
+  interfaces: _X<T>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+      -> A<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
diff --git a/pkg/front_end/testcases/redirecting_factory_metadata.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_metadata.dart.hierarchy.expect
new file mode 100644
index 0000000..2c671bd
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_metadata.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo._redirecting#
diff --git a/pkg/front_end/testcases/redirecting_factory_simple_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_simple_test.dart.hierarchy.expect
new file mode 100644
index 0000000..abc4300
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_simple_test.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
diff --git a/pkg/front_end/testcases/redirecting_factory_typeargs_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_typeargs_test.dart.hierarchy.expect
new file mode 100644
index 0000000..13dab79
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_typeargs_test.dart.hierarchy.expect
@@ -0,0 +1,91 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Y:
+  superclasses:
+    Object
+      -> X
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/redirecting_factory_typeparam_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_typeparam_test.dart.hierarchy.expect
new file mode 100644
index 0000000..abc4300
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_typeparam_test.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
diff --git a/pkg/front_end/testcases/redirecting_factory_typeparambounds_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_factory_typeparambounds_test.dart.hierarchy.expect
new file mode 100644
index 0000000..8d11fc8
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_factory_typeparambounds_test.dart.hierarchy.expect
@@ -0,0 +1,73 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Y:
+  superclasses:
+    Object
+      -> X
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.hierarchy.expect
new file mode 100644
index 0000000..eedd000
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+X:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Foo.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.x
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.hierarchy.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.hierarchy.expect
new file mode 100644
index 0000000..3de5ead
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Foo.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.x
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.expect
index 3a358ad..2856067 100644
--- a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.expect
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/redirecting_initializer_arguments_test.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'T'.
 // Try changing the type of the parameter, or casting the argument to 'T'.
 //   Foo.from(String _init) : this._internal(x: _init);
 //                                              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect
index 4a7fde2..2856067 100644
--- a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/redirecting_initializer_arguments_test.dart:12:46: Error: The argument type 'String' can't be assigned to the parameter type 'T'.
+// Try changing the type of the parameter, or casting the argument to 'T'.
+//   Foo.from(String _init) : this._internal(x: _init);
+//                                              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.hierarchy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.hierarchy.expect
new file mode 100644
index 0000000..6e0f389
--- /dev/null
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.hierarchy.expect
@@ -0,0 +1,491 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> A<U>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B._redirecting#
+
+C:
+  superclasses:
+    Object
+      -> A<V>
+        -> B<V, S>
+  interfaces:
+  classMembers:
+    C.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
index 90b0fbf..bba4f23 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
index 90b0fbf..bba4f23 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
index 1454cdb..3b0ee19 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.expect
index 530eceb..32a5b17 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.transformed.expect
index d2d7128..5e6a996 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.hierarchy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.hierarchy.expect
new file mode 100644
index 0000000..6e0f389
--- /dev/null
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.hierarchy.expect
@@ -0,0 +1,491 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> A<U>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B._redirecting#
+
+C:
+  superclasses:
+    Object
+      -> A<V>
+        -> B<V, S>
+  interfaces:
+  classMembers:
+    C.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
index 6eb52f4..cee4e10 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 abstract class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
index 6eb52f4..cee4e10 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 abstract class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
index 2be51bd..2b481ac 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 abstract class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.expect
index 981ccb8..09e1d27 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 abstract class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.transformed.expect b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.transformed.expect
index f2d09cc..eae9cec 100644
--- a/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/redirection_chain_type_arguments_subst.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 abstract class A<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   constructor empty() → self::A<self::A::T>
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.hierarchy.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.hierarchy.expect
new file mode 100644
index 0000000..80cea1b
--- /dev/null
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.hierarchy.expect
@@ -0,0 +1,470 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    B.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Expect:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Expect.identical
+    Expect.throwsCastError
+    Expect._fail
+    Expect.notIdentical
+    Expect.isNotNull
+    Expect._getMessage
+    Expect.allIdentical
+    Expect._escapeSubstring
+    Expect.fail
+    Expect._truncateString
+    Expect.isFalse
+    Expect.isTrue
+    Object.toString
+    Expect.subtype
+    Expect.throwsRangeError
+    Expect._stringDifference
+    Expect.throwsArgumentError
+    Expect.stringEquals
+    Object.runtimeType
+    Expect.testError
+    Expect.throwsStateError
+    Object._simpleInstanceOf
+    Expect.isNull
+    Expect.approxEquals
+    Expect.equals
+    Object._instanceOf
+    Expect.allDistinct
+    Expect.throwsTypeError
+    Expect._subtypeAtRuntime
+    Expect.setEquals
+    Object.noSuchMethod
+    Expect.notEquals
+    Expect.listEquals
+    Expect._findEquivalences
+    Expect.mapEquals
+    Object._identityHashCode
+    Expect.throwsUnsupportedError
+    Expect.notType
+    Expect.deepEquals
+    Expect._escapeString
+    Expect.type
+    Object.hashCode
+    Expect.throwsNoSuchMethodError
+    Expect.notSubtype
+    Expect.throws
+    Object._simpleInstanceOfFalse
+    Expect._writeEquivalences
+    Expect.throwsAssertionError
+    Object._simpleInstanceOfTrue
+    Object.==
+    Expect.throwsFormatException
+  classSetters:
+
+Exception:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExpectException:
+  superclasses:
+    Object
+  interfaces: Exception
+  classMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ExpectException.message
+    ExpectException.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+NoInline:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+AssumeDynamic:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Immutable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Immutable.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Required:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Required.reason
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_AlwaysThrows:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Checked:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Experimental:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Factory:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_IsTestGroup:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Literal:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_MustCallSuper:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_OptionalTypeArgs:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Protected:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Sealed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_Virtual:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForOverriding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+_VisibleForTesting:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
index 3f0dbf7..2fff34d 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   const constructor empty() → self::A
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
index 3f0dbf7..2fff34d 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   const constructor empty() → self::A
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
index e6e3790..4e65df8 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   const constructor empty() → self::A
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.strong.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.strong.expect
index 2e533bd..0dc1e9e 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   const constructor empty() → self::A
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect
index a388ba6..d3d9485 100644
--- a/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class A extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::A::•];
   const constructor empty() → self::A
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29937.dart.legacy.expect
index be87a73..c900857 100644
--- a/pkg/front_end/testcases/regress/issue_29937.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
-//   [f() {}];
-//    ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
-//   [f() {}];
-//    ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
+//   [f() {}];
+//    ^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29937.dart.legacy.transformed.expect
index 3232e26..c900857 100644
--- a/pkg/front_end/testcases/regress/issue_29937.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
 //   [f() {}];
 //    ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect
index 6872ff5..5f4a24f 100644
--- a/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
-//   [f() {}];
-//    ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
-//   [f() {}];
-//    ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
+//   [f() {}];
+//    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
index 87fc344..5f4a24f 100644
--- a/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
 //   [f() {}];
 //    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29940.dart.legacy.expect
index 4a7fdf3..83c805a 100644
--- a/pkg/front_end/testcases/regress/issue_29940.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29940.dart:7:3: Warning: 'a.b' can't be used as a type because 'a' doesn't refer to an import prefix.
 //   a.b c = null;
 //   ^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29940.dart.legacy.transformed.expect
index b13d5e8..83c805a 100644
--- a/pkg/front_end/testcases/regress/issue_29940.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29940.dart:7:3: Warning: 'a.b' can't be used as a type because 'a' doesn't refer to an import prefix.
+//   a.b c = null;
+//   ^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29940.dart.strong.expect
index 00641a9..106be2a 100644
--- a/pkg/front_end/testcases/regress/issue_29940.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29940.dart:7:3: Error: 'a.b' can't be used as a type because 'a' doesn't refer to an import prefix.
-//   a.b c = null;
-//   ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29940.dart:7:3: Error: 'a.b' can't be used as a type because 'a' doesn't refer to an import prefix.
-//   a.b c = null;
-//   ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29940.dart:7:3: Error: 'a.b' can't be used as a type because 'a' doesn't refer to an import prefix.
+//   a.b c = null;
+//   ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect
index 0d0ae79..106be2a 100644
--- a/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29940.dart:7:3: Error: 'a.b' can't be used as a type because 'a' doesn't refer to an import prefix.
 //   a.b c = null;
 //   ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29941.dart.legacy.expect
index 7d8e0ac..37a2a3e 100644
--- a/pkg/front_end/testcases/regress/issue_29941.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29941.dart:7:5: Error: Expected an identifier, but got '""'.
 //   a."";
 //     ^^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29941.dart.legacy.transformed.expect
index eea6787..37a2a3e 100644
--- a/pkg/front_end/testcases/regress/issue_29941.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29941.dart:7:5: Error: Expected an identifier, but got '""'.
+//   a."";
+//     ^^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29941.dart.strong.expect
index 8d219da..d9bc977 100644
--- a/pkg/front_end/testcases/regress/issue_29941.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29941.dart:7:5: Error: Expected an identifier, but got '""'.
 //   a."";
 //     ^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect
index 5c24424..d9bc977 100644
--- a/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29941.dart:7:5: Error: Expected an identifier, but got '""'.
+//   a."";
+//     ^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29942.dart.legacy.expect
index f278bcd..e96195a 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.legacy.expect
@@ -1,26 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
-// Try adding {}.
-// f() =
-//     ^
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
-// h() => null;
-// ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
-// Try adding {}.
-// f() =
-//     ^
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
-// h() => null;
-// ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
+// Try adding {}.
+// f() =
+//     ^
+//
+// pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
+// h() => null;
+// ^
+//
 import self as self;
 
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29942.dart.legacy.transformed.expect
index b45be16..e96195a 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
 // h() => null;
 // ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29942.dart.outline.expect
index cedaf70..1f16ad6 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
 // h() => null;
 // ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect
index 39a4246..277a448 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.strong.expect
@@ -1,26 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
-// Try adding {}.
-// f() =
-//     ^
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
-// h() => null;
-// ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
-// Try adding {}.
-// f() =
-//     ^
-//
-// pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
-// h() => null;
-// ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
+// Try adding {}.
+// f() =
+//     ^
+//
+// pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
+// h() => null;
+// ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
index ef6dd3f..277a448 100644
--- a/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
 // h() => null;
 // ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29943.dart.legacy.expect
index 163bc19..4684ec6 100644
--- a/pkg/front_end/testcases/regress/issue_29943.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29943.dart:6:5: Error: Expected an identifier, but got '('.
 //   x.(null);
 //     ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29943.dart.legacy.transformed.expect
index 69b4062..4684ec6 100644
--- a/pkg/front_end/testcases/regress/issue_29943.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29943.dart:6:5: Error: Expected an identifier, but got '('.
+//   x.(null);
+//     ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29943.dart.strong.expect
index 163bc19..4684ec6 100644
--- a/pkg/front_end/testcases/regress/issue_29943.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29943.dart:6:5: Error: Expected an identifier, but got '('.
 //   x.(null);
 //     ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect
index 69b4062..4684ec6 100644
--- a/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29943.dart:6:5: Error: Expected an identifier, but got '('.
+//   x.(null);
+//     ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_29944.dart.hierarchy.expect
new file mode 100644
index 0000000..6ed478b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.C
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.C
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29944.dart.legacy.expect
index e6a419d..f598d94 100644
--- a/pkg/front_end/testcases/regress/issue_29944.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
-//   var C;
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
-//   var C;
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
+//   var C;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29944.dart.legacy.transformed.expect
index d3ab9b2..f598d94 100644
--- a/pkg/front_end/testcases/regress/issue_29944.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
 //   var C;
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29944.dart.outline.expect
index cc5aa07..33037ab 100644
--- a/pkg/front_end/testcases/regress/issue_29944.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
 //   var C;
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29944.dart.strong.expect
index e6a419d..f598d94 100644
--- a/pkg/front_end/testcases/regress/issue_29944.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
-//   var C;
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
-//   var C;
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
+//   var C;
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect
index d3ab9b2..f598d94 100644
--- a/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
 //   var C;
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29945.dart.legacy.expect
index 34da2814..7a2f7d1 100644
--- a/pkg/front_end/testcases/regress/issue_29945.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29945.dart:6:3: Warning: 's.bool' can't be used as a type because 's' isn't defined.
 //   s.bool x = null;
 //   ^^^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29945.dart.legacy.transformed.expect
index 186616b..7a2f7d1 100644
--- a/pkg/front_end/testcases/regress/issue_29945.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29945.dart:6:3: Warning: 's.bool' can't be used as a type because 's' isn't defined.
+//   s.bool x = null;
+//   ^^^^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29945.dart.strong.expect
index 0215a73..038a3a7 100644
--- a/pkg/front_end/testcases/regress/issue_29945.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29945.dart:6:3: Error: 's.bool' can't be used as a type because 's' isn't defined.
-//   s.bool x = null;
-//   ^^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29945.dart:6:3: Error: 's.bool' can't be used as a type because 's' isn't defined.
-//   s.bool x = null;
-//   ^^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29945.dart:6:3: Error: 's.bool' can't be used as a type because 's' isn't defined.
+//   s.bool x = null;
+//   ^^^^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect
index da35f2c..038a3a7 100644
--- a/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29945.dart:6:3: Error: 's.bool' can't be used as a type because 's' isn't defined.
 //   s.bool x = null;
 //   ^^^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect
index c49120e..4ebde45 100644
--- a/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29975.dart:6:14: Error: 'F' is already declared in this scope.
 // typedef void F();
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/regress/issue_29975.dart:5:14: Context: Previous declaration of 'F'.
 // typedef void F();
 //              ^
-
-library;
+//
 import self as self;
 
 typedef F = () → void;
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29975.dart.strong.expect
index 93d444f..44014e5 100644
--- a/pkg/front_end/testcases/regress/issue_29975.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29975.dart:6:14: Error: 'F' is already declared in this scope.
 // typedef void F();
@@ -6,14 +8,7 @@
 // pkg/front_end/testcases/regress/issue_29975.dart:5:14: Context: Previous declaration of 'F'.
 // typedef void F();
 //              ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29975.dart:6:14: Error: 'F' is already declared in this scope.
-// typedef void F();
-//              ^
-
-library;
 import self as self;
 
 typedef F = () → void;
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29975.dart.strong.transformed.expect
index 6dc716b..44014e5 100644
--- a/pkg/front_end/testcases/regress/issue_29975.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.strong.transformed.expect
@@ -1,10 +1,14 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29975.dart:6:14: Error: 'F' is already declared in this scope.
 // typedef void F();
 //              ^
-
-library;
+// pkg/front_end/testcases/regress/issue_29975.dart:5:14: Context: Previous declaration of 'F'.
+// typedef void F();
+//              ^
+//
 import self as self;
 
 typedef F = () → void;
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29976.dart.legacy.expect
index f434e4b..467f45c 100644
--- a/pkg/front_end/testcases/regress/issue_29976.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -34,41 +36,7 @@
 // pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected ';' after this.
 //   )
 //   ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-//     "x${x*"'"é'}x
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:15: Error: String starting with ' must end with '.
-//     "x${x*"'"é'}x
-//               ^^^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:7: Error: Can't find '}' to match '${'.
-//     "x${x*"'"é'}x
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:5: Error: String starting with " must end with ".
-//     "x${x*"'"é'}x
-//     ^^^^^^^^^^^^^^...
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:12:1: Error: Expected a declaration, but got ''.
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: Expected '}' before this.
-//     "x${x*"'"é'}x
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected a String, but got ')'.
-//   )
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected ';' after this.
-//   )
-//   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29976.dart.legacy.transformed.expect
index ea4c4a8..467f45c 100644
--- a/pkg/front_end/testcases/regress/issue_29976.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -27,11 +29,14 @@
 //   )
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_29976.dart:8:3: Warning: Method not found: 'f'.
+//   f(
+//   ^
+//
 // pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected ';' after this.
 //   )
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29976.dart.outline.expect
index b796c52..e1cb793 100644
--- a/pkg/front_end/testcases/regress/issue_29976.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -18,8 +20,7 @@
 //     ^^^^^^^^^^^^^^...
 //
 // pkg/front_end/testcases/regress/issue_29976.dart:12:1: Error: Expected a declaration, but got ''.
-
-library;
+//
 import self as self;
 
 static get x() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29976.dart.strong.expect
index 72e0f84..b65bb80 100644
--- a/pkg/front_end/testcases/regress/issue_29976.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -34,41 +36,7 @@
 // pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected ';' after this.
 //   )
 //   ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-//     "x${x*"'"é'}x
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:15: Error: String starting with ' must end with '.
-//     "x${x*"'"é'}x
-//               ^^^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:7: Error: Can't find '}' to match '${'.
-//     "x${x*"'"é'}x
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:5: Error: String starting with " must end with ".
-//     "x${x*"'"é'}x
-//     ^^^^^^^^^^^^^^...
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:12:1: Error: Expected a declaration, but got ''.
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: Expected '}' before this.
-//     "x${x*"'"é'}x
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected a String, but got ')'.
-//   )
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected ';' after this.
-//   )
-//   ^
-
-library;
 import self as self;
 
 static get x() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect
index 8c288dc..b65bb80 100644
--- a/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29976.dart:9:14: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -27,11 +29,14 @@
 //   )
 //   ^
 //
+// pkg/front_end/testcases/regress/issue_29976.dart:8:3: Error: Method not found: 'f'.
+//   f(
+//   ^
+//
 // pkg/front_end/testcases/regress/issue_29976.dart:10:3: Error: Expected ';' after this.
 //   )
 //   ^
-
-library;
+//
 import self as self;
 
 static get x() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29977.dart.legacy.expect
index 2e676e4..b940300 100644
--- a/pkg/front_end/testcases/regress/issue_29977.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.legacy.expect
@@ -1,18 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
-//   Invalid MIME type.
-// import 'data:async';
-//                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
-//   Invalid MIME type.
-// import 'data:async';
-//                   ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
+//   Invalid MIME type.
+// import 'data:async';
+//                   ^
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?data%3Aasync";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29977.dart.legacy.transformed.expect
index 262ff05..b940300 100644
--- a/pkg/front_end/testcases/regress/issue_29977.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.legacy.transformed.expect
@@ -1,11 +1,17 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
 //   Invalid MIME type.
 // import 'data:async';
 //                   ^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?data%3Aasync";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29977.dart.outline.expect
index 33e2d4e..7c9a95c 100644
--- a/pkg/front_end/testcases/regress/issue_29977.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.outline.expect
@@ -1,12 +1,18 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
 //   Invalid MIME type.
 // import 'data:async';
 //                   ^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?data%3Aasync";
+
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29977.dart.strong.expect
index 2e676e4..b940300 100644
--- a/pkg/front_end/testcases/regress/issue_29977.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.strong.expect
@@ -1,18 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
-//   Invalid MIME type.
-// import 'data:async';
-//                   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
-//   Invalid MIME type.
-// import 'data:async';
-//                   ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
+//   Invalid MIME type.
+// import 'data:async';
+//                   ^
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?data%3Aasync";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect
index 262ff05..b940300 100644
--- a/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect
@@ -1,11 +1,17 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
 //   Invalid MIME type.
 // import 'data:async';
 //                   ^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?data%3Aasync";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29978.dart.legacy.expect
index e883dbf..fee49f7 100644
--- a/pkg/front_end/testcases/regress/issue_29978.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
-//   foo(null, f() {});
-//             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
-//   foo(null, f() {});
-//             ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
+//   foo(null, f() {});
+//             ^
+//
 import self as self;
 
 static method foo(dynamic a, dynamic b) → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29978.dart.legacy.transformed.expect
index 62cb849..fee49f7 100644
--- a/pkg/front_end/testcases/regress/issue_29978.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
 //   foo(null, f() {});
 //             ^
-
-library;
+//
 import self as self;
 
 static method foo(dynamic a, dynamic b) → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect
index a15db2b..e9b8c86 100644
--- a/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
-//   foo(null, f() {});
-//             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
-//   foo(null, f() {});
-//             ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
+//   foo(null, f() {});
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
index 6a94d34..e9b8c86 100644
--- a/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
 //   foo(null, f() {});
 //             ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29979.dart.legacy.expect
index 2df3c7c..a77e172 100644
--- a/pkg/front_end/testcases/regress/issue_29979.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
-//   (f() {})();
-//    ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
-//   (f() {})();
-//    ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
+//   (f() {})();
+//    ^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29979.dart.legacy.transformed.expect
index f556c17..a77e172 100644
--- a/pkg/front_end/testcases/regress/issue_29979.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
 //   (f() {})();
 //    ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect
index e9dc062..c9e4888 100644
--- a/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
-//   (f() {})();
-//    ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
-//   (f() {})();
-//    ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
+//   (f() {})();
+//    ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
index aafb742..c9e4888 100644
--- a/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
 //   (f() {})();
 //    ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29980.dart.legacy.expect
index c2b6598..23d7054 100644
--- a/pkg/front_end/testcases/regress/issue_29980.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29980.dart:6:3: Warning: 'x.y' can't be used as a type because 'x' isn't defined.
 //   x.y z;
 //   ^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29980.dart.legacy.transformed.expect
index 15d1958..23d7054 100644
--- a/pkg/front_end/testcases/regress/issue_29980.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29980.dart:6:3: Warning: 'x.y' can't be used as a type because 'x' isn't defined.
+//   x.y z;
+//   ^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29980.dart.strong.expect
index d313908..1e683cf 100644
--- a/pkg/front_end/testcases/regress/issue_29980.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29980.dart:6:3: Error: 'x.y' can't be used as a type because 'x' isn't defined.
-//   x.y z;
-//   ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29980.dart:6:3: Error: 'x.y' can't be used as a type because 'x' isn't defined.
-//   x.y z;
-//   ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29980.dart:6:3: Error: 'x.y' can't be used as a type because 'x' isn't defined.
+//   x.y z;
+//   ^^^
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect
index c271e3e..1e683cf 100644
--- a/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29980.dart:6:3: Error: 'x.y' can't be used as a type because 'x' isn't defined.
 //   x.y z;
 //   ^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_29981.dart.hierarchy.expect
new file mode 100644
index 0000000..2ac662a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.field
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.field
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29981.dart.legacy.expect
index 2d805d8..1019310 100644
--- a/pkg/front_end/testcases/regress/issue_29981.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29981.dart:6:3: Warning: Expected 1 type arguments.
 //   C<String, String> field;
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29981.dart.legacy.transformed.expect
index 483a0c4..1019310 100644
--- a/pkg/front_end/testcases/regress/issue_29981.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29981.dart:6:3: Warning: Expected 1 type arguments.
+//   C<String, String> field;
+//   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29981.dart.strong.expect
index d746374..02e45d1 100644
--- a/pkg/front_end/testcases/regress/issue_29981.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29981.dart:6:3: Error: Expected 1 type arguments.
-//   C<String, String> field;
-//   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29981.dart:6:3: Error: Expected 1 type arguments.
-//   C<String, String> field;
-//   ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29981.dart:6:3: Error: Expected 1 type arguments.
+//   C<String, String> field;
+//   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect
index a4f22b0..02e45d1 100644
--- a/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29981.dart:6:3: Error: Expected 1 type arguments.
 //   C<String, String> field;
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29982.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29982.dart.legacy.expect
index e361b02..e7b79bd 100644
--- a/pkg/front_end/testcases/regress/issue_29982.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29982.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -34,41 +36,7 @@
 // pkg/front_end/testcases/regress/issue_29982.dart:7:21: Error: Expected a String, but got ')'.
 //   print('${eh[éh']}');
 //                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-//   print('${eh[éh']}');
-//               ^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:14: Error: Can't find ']' to match '['.
-//   print('${eh[éh']}');
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:10: Error: Can't find '}' to match '${'.
-//   print('${eh[éh']}');
-//          ^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:11: Error: String starting with ' must end with '.
-//   print('${eh[éh']}');
-//           ^^^^^^^^^^^^^...
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:9:1: Error: Expected a declaration, but got ''.
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:17: Error: Expected ']' before this.
-//   print('${eh[éh']}');
-//                 ^^^^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:17: Error: Expected '}' before this.
-//   print('${eh[éh']}');
-//                 ^^^^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:21: Error: Expected a String, but got ')'.
-//   print('${eh[éh']}');
-//                     ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29982.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29982.dart.legacy.transformed.expect
index f419a37..e7b79bd 100644
--- a/pkg/front_end/testcases/regress/issue_29982.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29982.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -23,6 +25,10 @@
 //   print('${eh[éh']}');
 //                 ^^^^
 //
+// pkg/front_end/testcases/regress/issue_29982.dart:7:15: Warning: Getter not found: 'éh'.
+//   print('${eh[éh']}');
+//               ^^
+//
 // pkg/front_end/testcases/regress/issue_29982.dart:7:17: Error: Expected '}' before this.
 //   print('${eh[éh']}');
 //                 ^^^^
@@ -30,8 +36,7 @@
 // pkg/front_end/testcases/regress/issue_29982.dart:7:21: Error: Expected a String, but got ')'.
 //   print('${eh[éh']}');
 //                     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29982.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29982.dart.outline.expect
index 28ba42c..2b7388c 100644
--- a/pkg/front_end/testcases/regress/issue_29982.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29982.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -18,8 +20,7 @@
 //           ^^^^^^^^^^^^^...
 //
 // pkg/front_end/testcases/regress/issue_29982.dart:9:1: Error: Expected a declaration, but got ''.
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29982.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29982.dart.strong.expect
index cbd79b7..b69a45b 100644
--- a/pkg/front_end/testcases/regress/issue_29982.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29982.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -34,41 +36,7 @@
 // pkg/front_end/testcases/regress/issue_29982.dart:7:21: Error: Expected a String, but got ')'.
 //   print('${eh[éh']}');
 //                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-//   print('${eh[éh']}');
-//               ^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:14: Error: Can't find ']' to match '['.
-//   print('${eh[éh']}');
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:10: Error: Can't find '}' to match '${'.
-//   print('${eh[éh']}');
-//          ^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:11: Error: String starting with ' must end with '.
-//   print('${eh[éh']}');
-//           ^^^^^^^^^^^^^...
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:9:1: Error: Expected a declaration, but got ''.
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:17: Error: Expected ']' before this.
-//   print('${eh[éh']}');
-//                 ^^^^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:17: Error: Expected '}' before this.
-//   print('${eh[éh']}');
-//                 ^^^^
-//
-// pkg/front_end/testcases/regress/issue_29982.dart:7:21: Error: Expected a String, but got ')'.
-//   print('${eh[éh']}');
-//                     ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29982.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29982.dart.strong.transformed.expect
index e9542e0..b69a45b 100644
--- a/pkg/front_end/testcases/regress/issue_29982.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29982.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: The non-ASCII character 'é' (U+00E9) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -23,6 +25,10 @@
 //   print('${eh[éh']}');
 //                 ^^^^
 //
+// pkg/front_end/testcases/regress/issue_29982.dart:7:15: Error: Getter not found: 'éh'.
+//   print('${eh[éh']}');
+//               ^^
+//
 // pkg/front_end/testcases/regress/issue_29982.dart:7:17: Error: Expected '}' before this.
 //   print('${eh[éh']}');
 //                 ^^^^
@@ -30,8 +36,7 @@
 // pkg/front_end/testcases/regress/issue_29982.dart:7:21: Error: Expected a String, but got ')'.
 //   print('${eh[éh']}');
 //                     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29983.dart.legacy.expect
index 0043c08..a1d160d 100644
--- a/pkg/front_end/testcases/regress/issue_29983.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29983.dart:7:10: Warning: Getter not found: 'missing'.
 //   return missing;
@@ -15,8 +17,7 @@
 // pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
 // g() sync* => dummy;
 //              ^
-
-library;
+//
 import self as self;
 
 static method f() → dynamic sync* {
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29983.dart.legacy.transformed.expect
index 21d9fec..61df937 100644
--- a/pkg/front_end/testcases/regress/issue_29983.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.legacy.transformed.expect
@@ -1,4 +1,23 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:7:10: Warning: Getter not found: 'missing'.
+//   return missing;
+//          ^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:7:3: Error: 'sync*' and 'async*' can't return a value.
+//   return missing;
+//   ^
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:11:14: Warning: Getter not found: 'dummy'.
+// g() sync* => dummy;
+//              ^^^^^
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
+// g() sync* => dummy;
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29983.dart.strong.expect
index 448582e..0d6e066 100644
--- a/pkg/front_end/testcases/regress/issue_29983.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29983.dart:7:10: Error: Getter not found: 'missing'.
 //   return missing;
@@ -15,8 +17,7 @@
 // pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
 // g() sync* => dummy;
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
index d3d95c2..fbf6dd3 100644
--- a/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
@@ -1,4 +1,23 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:7:10: Error: Getter not found: 'missing'.
+//   return missing;
+//          ^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:7:3: Error: 'sync*' and 'async*' can't return a value.
+//   return missing;
+//   ^
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: Getter not found: 'dummy'.
+// g() sync* => dummy;
+//              ^^^^^
+//
+// pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
+// g() sync* => dummy;
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29984.dart.legacy.expect
index b8e39cc..bbf49cd 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29984.dart:6:16: Warning: Getter not found: 'i'.
 //   for (int i = i;; false) {}
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/regress/issue_29984.dart:6:16: Context: Previous use of 'i'.
 //   for (int i = i;; false) {}
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.legacy.transformed.expect
index 8b75d05..bbf49cd 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.legacy.transformed.expect
@@ -1,4 +1,18 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29984.dart:6:16: Warning: Getter not found: 'i'.
+//   for (int i = i;; false) {}
+//                ^
+//
+// pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+//   for (int i = i;; false) {}
+//            ^
+// pkg/front_end/testcases/regress/issue_29984.dart:6:16: Context: Previous use of 'i'.
+//   for (int i = i;; false) {}
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
index 2b6c35c..d7f4891 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
 //   for (int i = i;; false) {}
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/regress/issue_29984.dart:6:16: Context: Previous use of 'i'.
 //   for (int i = i;; false) {}
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
index f86f79b..d7f4891 100644
--- a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
@@ -1,4 +1,18 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
+//   for (int i = i;; false) {}
+//                ^
+//
+// pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+//   for (int i = i;; false) {}
+//            ^
+// pkg/front_end/testcases/regress/issue_29984.dart:6:16: Context: Previous use of 'i'.
+//   for (int i = i;; false) {}
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29985.dart.legacy.expect
index d6e6130..f483f0394 100644
--- a/pkg/front_end/testcases/regress/issue_29985.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -12,19 +14,7 @@
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Warning: Getter not found: '🔛'.
 //   🔛
 //   ^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-//   🔛
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Expected ';' after this.
-//   🔛
-//   ^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29985.dart.legacy.transformed.expect
index 52f90dd..f483f0394 100644
--- a/pkg/front_end/testcases/regress/issue_29985.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -8,8 +10,11 @@
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Expected ';' after this.
 //   🔛
 //   ^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_29985.dart:6:3: Warning: Getter not found: '🔛'.
+//   🔛
+//   ^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29985.dart.outline.expect
index 355a2a5..69da87f 100644
--- a/pkg/front_end/testcases/regress/issue_29985.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
 //   🔛
 //   ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29985.dart.strong.expect
index f74e906..eff9615 100644
--- a/pkg/front_end/testcases/regress/issue_29985.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -12,19 +14,7 @@
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Getter not found: '🔛'.
 //   🔛
 //   ^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
-// Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
-//   🔛
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Expected ';' after this.
-//   🔛
-//   ^^
-
-library;
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect
index 02cc98e0..eff9615 100644
--- a/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '🔛' (U+1F51B) can't be used in identifiers, only in strings and comments.
 // Try using an US-ASCII letter, a digit, '_' (an underscore), or '$' (a dollar sign).
@@ -8,8 +10,11 @@
 // pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Expected ';' after this.
 //   🔛
 //   ^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Getter not found: '🔛'.
+//   🔛
+//   ^^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29986.dart.legacy.expect
index 095bbbf..f0b03d5 100644
--- a/pkg/front_end/testcases/regress/issue_29986.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.legacy.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
-// Try adding {}.
-// C(this.name);
-//             ^
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: Field formal parameters can only be used in a constructor.
-// Try removing 'this.'.
-// C(this.name);
-//   ^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
-// Try adding {}.
-// C(this.name);
-//             ^
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: Field formal parameters can only be used in a constructor.
-// Try removing 'this.'.
-// C(this.name);
-//   ^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
+// Try adding {}.
+// C(this.name);
+//             ^
+//
+// pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: Field formal parameters can only be used in a constructor.
+// Try removing 'this.'.
+// C(this.name);
+//   ^^^^
+//
 import self as self;
 
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29986.dart.legacy.transformed.expect
index 7c524d5..f0b03d5 100644
--- a/pkg/front_end/testcases/regress/issue_29986.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -9,8 +11,7 @@
 // Try removing 'this.'.
 // C(this.name);
 //   ^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29986.dart.outline.expect
index 2fe2ce6..6556bc9 100644
--- a/pkg/front_end/testcases/regress/issue_29986.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
 // Try adding {}.
 // C(this.name);
 //             ^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29986.dart.strong.expect
index 095bbbf..f0b03d5 100644
--- a/pkg/front_end/testcases/regress/issue_29986.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.strong.expect
@@ -1,28 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
-// Try adding {}.
-// C(this.name);
-//             ^
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: Field formal parameters can only be used in a constructor.
-// Try removing 'this.'.
-// C(this.name);
-//   ^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
-// Try adding {}.
-// C(this.name);
-//             ^
-//
-// pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: Field formal parameters can only be used in a constructor.
-// Try removing 'this.'.
-// C(this.name);
-//   ^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
+// Try adding {}.
+// C(this.name);
+//             ^
+//
+// pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: Field formal parameters can only be used in a constructor.
+// Try removing 'this.'.
+// C(this.name);
+//   ^^^^
+//
 import self as self;
 
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect
index 7c524d5..f0b03d5 100644
--- a/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
 // Try adding {}.
@@ -9,8 +11,7 @@
 // Try removing 'this.'.
 // C(this.name);
 //   ^^^^
-
-library;
+//
 import self as self;
 
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_29987.dart.legacy.expect
index 6273432..1a60106 100644
--- a/pkg/front_end/testcases/regress/issue_29987.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.legacy.expect
@@ -1,18 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
-//   Illegal scheme character.
-// import "dart_:core";
-//             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
-//   Illegal scheme character.
-// import "dart_:core";
-//             ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
+//   Illegal scheme character.
+// import "dart_:core";
+//             ^
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?dart_%3Acore";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_29987.dart.legacy.transformed.expect
index 99b37bf..1a60106 100644
--- a/pkg/front_end/testcases/regress/issue_29987.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.legacy.transformed.expect
@@ -1,11 +1,17 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
 //   Illegal scheme character.
 // import "dart_:core";
 //             ^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?dart_%3Acore";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29987.dart.outline.expect
index d226574..31663c2 100644
--- a/pkg/front_end/testcases/regress/issue_29987.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.outline.expect
@@ -1,12 +1,18 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
 //   Illegal scheme character.
 // import "dart_:core";
 //             ^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?dart_%3Acore";
+
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.strong.expect b/pkg/front_end/testcases/regress/issue_29987.dart.strong.expect
index 6273432..1a60106 100644
--- a/pkg/front_end/testcases/regress/issue_29987.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.strong.expect
@@ -1,18 +1,17 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
-//   Illegal scheme character.
-// import "dart_:core";
-//             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
-//   Illegal scheme character.
-// import "dart_:core";
-//             ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
+//   Illegal scheme character.
+// import "dart_:core";
+//             ^
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?dart_%3Acore";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect
index 99b37bf..1a60106 100644
--- a/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect
@@ -1,11 +1,17 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
 //   Illegal scheme character.
 // import "dart_:core";
 //             ^
-
-library;
+//
 import self as self;
 
+import "org-dartlang-malformed-uri:?dart_%3Acore";
+
 static method main() → dynamic {}
+
+library;
+import self as self2;
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_30834.dart.hierarchy.expect
new file mode 100644
index 0000000..e75291f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.A
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
index f2504e8..d90c580 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   set A(v) {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   set A(v) {}
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
+//   set A(v) {}
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
index 6e15af0..d90c580 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
 //   set A(v) {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
index 5e79dad..b7a0c48 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
 //   set A(v) {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect
index 41f5529..5a1e38f 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   set A(v) {}
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   set A(v) {}
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
+//   set A(v) {}
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect
index ef4ea19..5a1e38f 100644
--- a/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30834.dart:6:7: Error: A class member can't have the same name as the enclosing class.
 //   set A(v) {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_30836.dart.hierarchy.expect
new file mode 100644
index 0000000..81e33f7
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    A.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_30836.dart.legacy.expect
index 57441e0..5d14926 100644
--- a/pkg/front_end/testcases/regress/issue_30836.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.legacy.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final int x;
-//             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final int x;
-//             ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
+// Try to initialize the field in the declaration or in every constructor.
+//   final int x;
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_30836.dart.legacy.transformed.expect
index 40ac4eb..5d14926 100644
--- a/pkg/front_end/testcases/regress/issue_30836.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.legacy.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
 // Try to initialize the field in the declaration or in every constructor.
 //   final int x;
 //             ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30836.dart.strong.expect
index 57441e0..5d14926 100644
--- a/pkg/front_end/testcases/regress/issue_30836.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.strong.expect
@@ -1,18 +1,12 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final int x;
-//             ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final int x;
-//             ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
+// Try to initialize the field in the declaration or in every constructor.
+//   final int x;
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect
index 40ac4eb..5d14926 100644
--- a/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect
@@ -1,11 +1,12 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30836.dart:6:13: Error: Final field 'x' is not initialized.
 // Try to initialize the field in the declaration or in every constructor.
 //   final int x;
 //             ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_30838.dart.hierarchy.expect
new file mode 100644
index 0000000..b042f94
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    A.test
+  classSetters:
+    A.f
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_30981.dart.hierarchy.expect
new file mode 100644
index 0000000..c5c305b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.A
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_30981.dart.legacy.expect
index 7bed291..8a1164f 100644
--- a/pkg/front_end/testcases/regress/issue_30981.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   get A {
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   get A {
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
+//   get A {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_30981.dart.legacy.transformed.expect
index e1e9e01..8a1164f 100644
--- a/pkg/front_end/testcases/regress/issue_30981.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
 //   get A {
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30981.dart.outline.expect
index 67b74d0..e9dde73 100644
--- a/pkg/front_end/testcases/regress/issue_30981.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
 //   get A {
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30981.dart.strong.expect
index 7bed291..8a1164f 100644
--- a/pkg/front_end/testcases/regress/issue_30981.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   get A {
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
-//   get A {
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
+//   get A {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect
index e1e9e01..8a1164f 100644
--- a/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
 //   get A {
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_30994.dart.legacy.expect
index ce9d891..99b330c 100644
--- a/pkg/front_end/testcases/regress/issue_30994.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.legacy.expect
@@ -1,64 +1,69 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
-// part '$foo';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
-// part '$foo/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
-// part '$for/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
-// part '${true}';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
-// part 'the${1}thing';
-//          ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
-// part 'part_$foo${'a'}.dart';
-//            ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
-// part 'part_${'a'}_$foo.dart';
-//            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
-// part '$foo';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
-// part '$foo/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
-// part '$for/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
-// part '${true}';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
-// part 'the${1}thing';
-//          ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
-// part 'part_$foo${'a'}.dart';
-//            ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
-// part 'part_${'a'}_$foo.dart';
-//            ^
-
 library lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
+// part '$foo';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
+// part '$foo/bar';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
+// part '$for/bar';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
+// part '${true}';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
+// part 'the${1}thing';
+//          ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
+// part 'part_$foo${'a'}.dart';
+//            ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
+// part 'part_${'a'}_$foo.dart';
+//            ^
+//
 import self as self;
 
+part org-dartlang-malformed-uri:bad235;
+part org-dartlang-malformed-uri:bad248;
+part org-dartlang-malformed-uri:bad265;
+part org-dartlang-malformed-uri:bad282;
+part org-dartlang-malformed-uri:bad298;
+part org-dartlang-malformed-uri:bad319;
+part org-dartlang-malformed-uri:bad348;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+
+
+library;
+import self as self3;
+
+
+library;
+import self as self4;
+
+
+library;
+import self as self5;
+
+
+library;
+import self as self6;
+
+
+library;
+import self as self7;
+
+
+library;
+import self as self8;
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_30994.dart.legacy.transformed.expect
index 9fa56bb..99b330c 100644
--- a/pkg/front_end/testcases/regress/issue_30994.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library lib;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
 // part '$foo';
@@ -27,8 +29,41 @@
 // pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
 // part 'part_${'a'}_$foo.dart';
 //            ^
-
-library lib;
+//
 import self as self;
 
+part org-dartlang-malformed-uri:bad235;
+part org-dartlang-malformed-uri:bad248;
+part org-dartlang-malformed-uri:bad265;
+part org-dartlang-malformed-uri:bad282;
+part org-dartlang-malformed-uri:bad298;
+part org-dartlang-malformed-uri:bad319;
+part org-dartlang-malformed-uri:bad348;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+
+
+library;
+import self as self3;
+
+
+library;
+import self as self4;
+
+
+library;
+import self as self5;
+
+
+library;
+import self as self6;
+
+
+library;
+import self as self7;
+
+
+library;
+import self as self8;
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30994.dart.outline.expect
index 849db7f..468c487 100644
--- a/pkg/front_end/testcases/regress/issue_30994.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library lib;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
 // part '$foo';
@@ -27,9 +29,42 @@
 // pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
 // part 'part_${'a'}_$foo.dart';
 //            ^
-
-library lib;
+//
 import self as self;
 
+part org-dartlang-malformed-uri:bad235;
+part org-dartlang-malformed-uri:bad248;
+part org-dartlang-malformed-uri:bad265;
+part org-dartlang-malformed-uri:bad282;
+part org-dartlang-malformed-uri:bad298;
+part org-dartlang-malformed-uri:bad319;
+part org-dartlang-malformed-uri:bad348;
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
+
+
+library;
+import self as self3;
+
+
+library;
+import self as self4;
+
+
+library;
+import self as self5;
+
+
+library;
+import self as self6;
+
+
+library;
+import self as self7;
+
+
+library;
+import self as self8;
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30994.dart.strong.expect
index ce9d891..99b330c 100644
--- a/pkg/front_end/testcases/regress/issue_30994.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.strong.expect
@@ -1,64 +1,69 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
-// part '$foo';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
-// part '$foo/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
-// part '$for/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
-// part '${true}';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
-// part 'the${1}thing';
-//          ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
-// part 'part_$foo${'a'}.dart';
-//            ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
-// part 'part_${'a'}_$foo.dart';
-//            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
-// part '$foo';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
-// part '$foo/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
-// part '$for/bar';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
-// part '${true}';
-//       ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
-// part 'the${1}thing';
-//          ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
-// part 'part_$foo${'a'}.dart';
-//            ^
-//
-// pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
-// part 'part_${'a'}_$foo.dart';
-//            ^
-
 library lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
+// part '$foo';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
+// part '$foo/bar';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
+// part '$for/bar';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
+// part '${true}';
+//       ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
+// part 'the${1}thing';
+//          ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
+// part 'part_$foo${'a'}.dart';
+//            ^
+//
+// pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
+// part 'part_${'a'}_$foo.dart';
+//            ^
+//
 import self as self;
 
+part org-dartlang-malformed-uri:bad235;
+part org-dartlang-malformed-uri:bad248;
+part org-dartlang-malformed-uri:bad265;
+part org-dartlang-malformed-uri:bad282;
+part org-dartlang-malformed-uri:bad298;
+part org-dartlang-malformed-uri:bad319;
+part org-dartlang-malformed-uri:bad348;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+
+
+library;
+import self as self3;
+
+
+library;
+import self as self4;
+
+
+library;
+import self as self5;
+
+
+library;
+import self as self6;
+
+
+library;
+import self as self7;
+
+
+library;
+import self as self8;
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect
index 9fa56bb..99b330c 100644
--- a/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library lib;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
 // part '$foo';
@@ -27,8 +29,41 @@
 // pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
 // part 'part_${'a'}_$foo.dart';
 //            ^
-
-library lib;
+//
 import self as self;
 
+part org-dartlang-malformed-uri:bad235;
+part org-dartlang-malformed-uri:bad248;
+part org-dartlang-malformed-uri:bad265;
+part org-dartlang-malformed-uri:bad282;
+part org-dartlang-malformed-uri:bad298;
+part org-dartlang-malformed-uri:bad319;
+part org-dartlang-malformed-uri:bad348;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+
+
+library;
+import self as self3;
+
+
+library;
+import self as self4;
+
+
+library;
+import self as self5;
+
+
+library;
+import self as self6;
+
+
+library;
+import self as self7;
+
+
+library;
+import self as self8;
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31155.dart.hierarchy.expect
new file mode 100644
index 0000000..e323a87
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.hierarchy.expect
@@ -0,0 +1,75 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.>
+    Object.hashCode
+    C.B
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
+    C.B
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
index 7168787..8130bfc 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
@@ -1,52 +1,29 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
-//   var f = Map<A, B> {};
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
-// Try adding the keyword 'operator'.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
-//   var f = Map<A, B> {};
-//                       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
-//   var f = Map<A, B> {};
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
-// Try adding the keyword 'operator'.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
-//   var f = Map<A, B> {};
-//                       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
+//   var f = Map<A, B> {};
+//                  ^
+//
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
+// Try adding the keyword 'operator'.
+//   var f = Map<A, B> {};
+//                   ^
+//
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   var f = Map<A, B> {};
+//                   ^
+//
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
+//   var f = Map<A, B> {};
+//                   ^
+//
+// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
+//   var f = Map<A, B> {};
+//                       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
index 9265bb3..8130bfc 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
 //   var f = Map<A, B> {};
@@ -21,8 +23,7 @@
 // pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
 //   var f = Map<A, B> {};
 //                       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
index 44a0931..31866e5 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
 //   var f = Map<A, B> {};
@@ -21,8 +23,7 @@
 // pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
 //   var f = Map<A, B> {};
 //                       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
index 6eb5512..f9e661a 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
 //   var f = Map<A, B> {};
@@ -27,32 +29,7 @@
 // Try correcting the name to the name of an existing method, or defining a method named '<'.
 //   var f = Map<A, B> {};
 //              ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
-//   var f = Map<A, B> {};
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
-// Try adding the keyword 'operator'.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator '>' should have exactly one parameter.
-//   var f = Map<A, B> {};
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
-//   var f = Map<A, B> {};
-//                       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -67,7 +44,7 @@
     ;
 }
 class C extends core::Object {
-  field dynamic f = let final dynamic #t1 = core::Map<dynamic, dynamic> in invalid-expression "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The method '<' isn't defined for the class 'Type'.
+  field dynamic f = invalid-expression "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The method '<' isn't defined for the class 'Type'.
  - 'Type' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named '<'.
   var f = Map<A, B> {};
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
index acf1ad1..f9e661a 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31155.dart:11:18: Error: Expected ';' after this.
 //   var f = Map<A, B> {};
@@ -21,8 +23,13 @@
 // pkg/front_end/testcases/regress/issue_31155.dart:11:23: Error: Expected a class member, but got ';'.
 //   var f = Map<A, B> {};
 //                       ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The method '<' isn't defined for the class 'Type'.
+//  - 'Type' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named '<'.
+//   var f = Map<A, B> {};
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -37,7 +44,7 @@
     ;
 }
 class C extends core::Object {
-  field dynamic f = let final core::Type #t1 = core::Map<dynamic, dynamic> in invalid-expression "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The method '<' isn't defined for the class 'Type'.
+  field dynamic f = invalid-expression "pkg/front_end/testcases/regress/issue_31155.dart:11:14: Error: The method '<' isn't defined for the class 'Type'.
  - 'Type' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named '<'.
   var f = Map<A, B> {};
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31157.dart.legacy.expect
index 8a84bd6..f102486 100644
--- a/pkg/front_end/testcases/regress/issue_31157.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31157.dart:6:16: Error: Expected an identifier, but got '('.
 //   return null?.(1);
 //                ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31157.dart.legacy.transformed.expect
index 895f75f..f102486 100644
--- a/pkg/front_end/testcases/regress/issue_31157.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31157.dart:6:16: Error: Expected an identifier, but got '('.
+//   return null?.(1);
+//                ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31157.dart.strong.expect
index 8a84bd6..f102486 100644
--- a/pkg/front_end/testcases/regress/issue_31157.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31157.dart:6:16: Error: Expected an identifier, but got '('.
 //   return null?.(1);
 //                ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect
index 895f75f..f102486 100644
--- a/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31157.dart:6:16: Error: Expected an identifier, but got '('.
+//   return null?.(1);
+//                ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31171.dart.legacy.expect
index 54e067f..9be6ce1 100644
--- a/pkg/front_end/testcases/regress/issue_31171.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
 // typedef F = Map<String, dynamic> Function();
@@ -11,22 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
 // typedef T =
 //           ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
-// typedef F = Map<String, dynamic> Function();
-// ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected ';' after this.
-// typedef F = Map<String, dynamic> Function();
-// ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
-// typedef T = 
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31171.dart.legacy.transformed.expect
index ad9b787..9be6ce1 100644
--- a/pkg/front_end/testcases/regress/issue_31171.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
 // typedef F = Map<String, dynamic> Function();
@@ -9,10 +11,9 @@
 // ^^^^^^^
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
-// typedef T = 
+// typedef T =
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31171.dart.outline.expect
index 772c92d..796d473 100644
--- a/pkg/front_end/testcases/regress/issue_31171.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
 // typedef F = Map<String, dynamic> Function();
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
 // typedef T =
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31171.dart.strong.expect
index 54e067f..9be6ce1 100644
--- a/pkg/front_end/testcases/regress/issue_31171.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
 // typedef F = Map<String, dynamic> Function();
@@ -11,22 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
 // typedef T =
 //           ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
-// typedef F = Map<String, dynamic> Function();
-// ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected ';' after this.
-// typedef F = Map<String, dynamic> Function();
-// ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
-// typedef T = 
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31171.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31171.dart.strong.transformed.expect
index ad9b787..9be6ce1 100644
--- a/pkg/front_end/testcases/regress/issue_31171.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31171.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:8:1: Error: Expected a type, but got 'typedef'.
 // typedef F = Map<String, dynamic> Function();
@@ -9,10 +11,9 @@
 // ^^^^^^^
 //
 // pkg/front_end/testcases/regress/issue_31171.dart:7:11: Error: Can't create typedef from non-function type.
-// typedef T = 
+// typedef T =
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31180.dart.legacy.expect
index 1223575..b503b42 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
 //   return null?.[1];
 //                ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31180.dart.legacy.transformed.expect
index 624821f2..b503b42 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+//   return null?.[1];
+//                ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
index 1223575..b503b42 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
 //   return null?.[1];
 //                ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
index 624821f2..b503b42 100644
--- a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+//   return null?.[1];
+//                ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31183.dart.hierarchy.expect
new file mode 100644
index 0000000..80fc858
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.unary-
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31183.dart.legacy.expect
index cf6950e..aac5171 100644
--- a/pkg/front_end/testcases/regress/issue_31183.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.legacy.expect
@@ -1,26 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
-//   operator unary- => 0;
-//            ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   operator unary- => 0;
-//                 ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
-//   operator unary- => 0;
-//            ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   operator unary- => 0;
-//                 ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
+//   operator unary- => 0;
+//            ^^^^^
+//
+// pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   operator unary- => 0;
+//                 ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31183.dart.legacy.transformed.expect
index a0f201d..aac5171 100644
--- a/pkg/front_end/testcases/regress/issue_31183.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
 //   operator unary- => 0;
@@ -8,8 +10,7 @@
 // Try adding a parameter list to the method declaration.
 //   operator unary- => 0;
 //                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31183.dart.outline.expect
index 5635a433..5b125a0 100644
--- a/pkg/front_end/testcases/regress/issue_31183.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
 //   operator unary- => 0;
@@ -8,8 +10,7 @@
 // Try adding a parameter list to the method declaration.
 //   operator unary- => 0;
 //                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31183.dart.strong.expect
index cf6950e..aac5171 100644
--- a/pkg/front_end/testcases/regress/issue_31183.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.strong.expect
@@ -1,26 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
-//   operator unary- => 0;
-//            ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   operator unary- => 0;
-//                 ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
-//   operator unary- => 0;
-//            ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-//   operator unary- => 0;
-//                 ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
+//   operator unary- => 0;
+//            ^^^^^
+//
+// pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+//   operator unary- => 0;
+//                 ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect
index a0f201d..aac5171 100644
--- a/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Unexpected token 'unary'.
 //   operator unary- => 0;
@@ -8,8 +10,7 @@
 // Try adding a parameter list to the method declaration.
 //   operator unary- => 0;
 //                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31184.dart.legacy.expect
index e6ca181..6b6b0e4 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
 //   for (int i = 0, i > 10; i++) {}
@@ -14,18 +16,7 @@
 // pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
 //   for (int i = 0, i > 10; i++) {}
 //                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: Expected ';' after this.
-//   for (int i = 0, i > 10; i++) {}
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
-//   for (int i = 0, i > 10; i++) {}
-//                     ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31184.dart.legacy.transformed.expect
index b02bd88..6b6b0e4 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.legacy.transformed.expect
@@ -1,4 +1,13 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
+//   for (int i = 0, i > 10; i++) {}
+//                   ^
+// pkg/front_end/testcases/regress/issue_31184.dart:6:12: Context: Previous declaration of 'i'.
+//   for (int i = 0, i > 10; i++) {}
+//            ^
 //
 // pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: Expected ';' after this.
 //   for (int i = 0, i > 10; i++) {}
@@ -7,8 +16,7 @@
 // pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
 //   for (int i = 0, i > 10; i++) {}
 //                     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
index 310a49e..a3c59b2 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
 //   for (int i = 0, i > 10; i++) {}
@@ -14,18 +16,7 @@
 // pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
 //   for (int i = 0, i > 10; i++) {}
 //                     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: Expected ';' after this.
-//   for (int i = 0, i > 10; i++) {}
-//                   ^
-//
-// pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
-//   for (int i = 0, i > 10; i++) {}
-//                     ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect
index 8de07cd..a3c59b2 100644
--- a/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.strong.transformed.expect
@@ -1,4 +1,13 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' is already declared in this scope.
+//   for (int i = 0, i > 10; i++) {}
+//                   ^
+// pkg/front_end/testcases/regress/issue_31184.dart:6:12: Context: Previous declaration of 'i'.
+//   for (int i = 0, i > 10; i++) {}
+//            ^
 //
 // pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: Expected ';' after this.
 //   for (int i = 0, i > 10; i++) {}
@@ -7,8 +16,7 @@
 // pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
 //   for (int i = 0, i > 10; i++) {}
 //                     ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31185.dart.legacy.expect
index bc5ace6..53b6c90 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31185.dart:8:12: Error: Expected ';' after this.
 //   return i ++ (i);
@@ -11,18 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
 //   return (i) ++ (i);
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31185.dart:8:12: Error: Expected ';' after this.
-//   return i ++ (i);
-//            ^^
-//
-// pkg/front_end/testcases/regress/issue_31185.dart:12:14: Error: Expected ';' after this.
-//   return (i) ++ (i);
-//              ^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31185.dart.legacy.transformed.expect
index 4494677..53b6c90 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31185.dart:8:12: Error: Expected ';' after this.
 //   return i ++ (i);
@@ -7,8 +9,11 @@
 // pkg/front_end/testcases/regress/issue_31185.dart:12:14: Error: Expected ';' after this.
 //   return (i) ++ (i);
 //              ^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
+//   return (i) ++ (i);
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect
index 3255194..f399b3a 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31185.dart:8:12: Error: Expected ';' after this.
 //   return i ++ (i);
@@ -11,18 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
 //   return (i) ++ (i);
 //            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31185.dart:8:12: Error: Expected ';' after this.
-//   return i ++ (i);
-//            ^^
-//
-// pkg/front_end/testcases/regress/issue_31185.dart:12:14: Error: Expected ';' after this.
-//   return (i) ++ (i);
-//              ^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
index 9b0d784..d1b5634 100644
--- a/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31185.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31185.dart:8:12: Error: Expected ';' after this.
 //   return i ++ (i);
@@ -7,8 +9,11 @@
 // pkg/front_end/testcases/regress/issue_31185.dart:12:14: Error: Expected ';' after this.
 //   return (i) ++ (i);
 //              ^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_31185.dart:12:12: Error: Can't assign to a parenthesized expression.
+//   return (i) ++ (i);
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31186.dart.legacy.expect
index 79db460..8f46e0f 100644
--- a/pkg/front_end/testcases/regress/issue_31186.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31186.dart:6:16: Error: Expected an identifier, but got 'true'.
 //   return null?.true;
 //                ^^^^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31186.dart.legacy.transformed.expect
index db52098..8f46e0f 100644
--- a/pkg/front_end/testcases/regress/issue_31186.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31186.dart:6:16: Error: Expected an identifier, but got 'true'.
+//   return null?.true;
+//                ^^^^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31186.dart.strong.expect
index 79db460..8f46e0f 100644
--- a/pkg/front_end/testcases/regress/issue_31186.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31186.dart:6:16: Error: Expected an identifier, but got 'true'.
 //   return null?.true;
 //                ^^^^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect
index db52098..8f46e0f 100644
--- a/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31186.dart:6:16: Error: Expected an identifier, but got 'true'.
+//   return null?.true;
+//                ^^^^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31187.dart.legacy.expect
index 4b86241..6126225 100644
--- a/pkg/front_end/testcases/regress/issue_31187.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.legacy.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31187.dart:6:16: Error: Expected an identifier, but got '1'.
 //   return null?.1;
 //                ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31187.dart.legacy.transformed.expect
index df2ebb4..6126225 100644
--- a/pkg/front_end/testcases/regress/issue_31187.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.legacy.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31187.dart:6:16: Error: Expected an identifier, but got '1'.
+//   return null?.1;
+//                ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31187.dart.strong.expect
index 4b86241..6126225 100644
--- a/pkg/front_end/testcases/regress/issue_31187.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.strong.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31187.dart:6:16: Error: Expected an identifier, but got '1'.
 //   return null?.1;
 //                ^
-
-library;
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect
index df2ebb4..6126225 100644
--- a/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect
@@ -1,4 +1,11 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31187.dart:6:16: Error: Expected an identifier, but got '1'.
+//   return null?.1;
+//                ^
+//
 import self as self;
 
 static method bad() → dynamic {
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect
index b43e742..ee42a18 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
 // type T = Map<A, B>
@@ -19,18 +21,7 @@
 // pkg/front_end/testcases/regress/issue_31188.dart:7:1: Warning: 'type' isn't a type.
 // type T = Map<A, B>
 // ^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
-// type T = Map<A, B>
-//                 ^
-//
-// pkg/front_end/testcases/regress/issue_31188.dart:7:18: Error: Expected a declaration, but got '>'.
-// type T = Map<A, B>
-//                  ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect
index 17bbd41..ee42a18 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
 // type T = Map<A, B>
@@ -7,8 +9,19 @@
 // pkg/front_end/testcases/regress/issue_31188.dart:7:18: Error: Expected a declaration, but got '>'.
 // type T = Map<A, B>
 //                  ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Warning: Type 'type' not found.
+// type T = Map<A, B>
+// ^^^^
+//
+// pkg/front_end/testcases/regress/issue_31188.dart:7:14: Warning: Getter not found: 'A'.
+// type T = Map<A, B>
+//              ^
+//
+// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Warning: 'type' isn't a type.
+// type T = Map<A, B>
+// ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31188.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31188.dart.outline.expect
index 8808453..c60e8a0 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
 // type T = Map<A, B>
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31188.dart:7:1: Warning: Type 'type' not found.
 // type T = Map<A, B>
 // ^^^^
-
-library;
+//
 import self as self;
 
 static field invalid-type T;
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 166f5be..104418a 100644
--- a/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31188.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
 // type T = Map<A, B>
@@ -25,30 +27,10 @@
 // pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
 // type T = Map<A, B>
 // ^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
-// type T = Map<A, B>
-//                 ^
-//
-// pkg/front_end/testcases/regress/issue_31188.dart:7:18: Error: Expected a declaration, but got '>'.
-// type T = Map<A, B>
-//                  ^
-//
-// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: Type 'type' not found.
-// type T = Map<A, B>
-// ^^^^
-//
-// pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
-// type T = Map<A, B>
-// ^^^^
-
-library;
 import self as self;
-import "dart:core" as core;
 
-static field invalid-type T = let final dynamic #t1 = core::Map<dynamic, dynamic> in invalid-expression "pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
+static field invalid-type T = invalid-expression "pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
  - 'Type' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named '<'.
 type T = Map<A, B>
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 780a726..104418a 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31188.dart:7:17: Error: Expected ';' after this.
 // type T = Map<A, B>
@@ -12,15 +14,23 @@
 // type T = Map<A, B>
 // ^^^^
 //
+// pkg/front_end/testcases/regress/issue_31188.dart:7:14: Error: Getter not found: 'A'.
+// type T = Map<A, B>
+//              ^
+//
+// pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
+//  - 'Type' is from 'dart:core'.
+// Try correcting the name to the name of an existing method, or defining a method named '<'.
+// type T = Map<A, B>
+//             ^
+//
 // pkg/front_end/testcases/regress/issue_31188.dart:7:1: Error: 'type' isn't a type.
 // type T = Map<A, B>
 // ^^^^
-
-library;
+//
 import self as self;
-import "dart:core" as core;
 
-static field invalid-type T = let final core::Type #t1 = core::Map<dynamic, dynamic> in invalid-expression "pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
+static field invalid-type T = invalid-expression "pkg/front_end/testcases/regress/issue_31188.dart:7:13: Error: The method '<' isn't defined for the class 'Type'.
  - 'Type' is from 'dart:core'.
 Try correcting the name to the name of an existing method, or defining a method named '<'.
 type T = Map<A, B>
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31190.dart.hierarchy.expect
new file mode 100644
index 0000000..606b757
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Typed:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Typed.v
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Typed.v
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect
index e46d9d8..22dd31b 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31190.dart:6:3: Warning: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
@@ -12,8 +14,7 @@
 // pkg/front_end/testcases/regress/issue_31190.dart:6:3: Warning: Expected 0 type arguments.
 //   T<U> v;
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect
index ae55cb3..22dd31b 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.legacy.transformed.expect
@@ -1,4 +1,20 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Warning: Can't use type arguments with type variable 'T'.
+// Try removing the type arguments.
+//   T<U> v;
+//   ^
+//
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Warning: 'U' isn't a type.
+//   T<U> v;
+//     ^
+//
+// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Warning: Expected 0 type arguments.
+//   T<U> v;
+//   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect
index b8af511..1d72ade 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31190.dart:6:3: Warning: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
 //   T<U> v;
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect
index 76b114c..20196d3 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.strong.expect
@@ -1,34 +1,20 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Can't use type arguments with type variable 'T'.
-// Try removing the type arguments.
-//   T<U> v;
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: 'U' isn't a type.
-//   T<U> v;
-//     ^
-//
-// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Expected 0 type arguments.
-//   T<U> v;
-//   ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Can't use type arguments with type variable 'T'.
-// Try removing the type arguments.
-//   T<U> v;
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: 'U' isn't a type.
-//   T<U> v;
-//     ^
-//
-// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Expected 0 type arguments.
-//   T<U> v;
-//   ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Can't use type arguments with type variable 'T'.
+// Try removing the type arguments.
+//   T<U> v;
+//   ^
+//
+// pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: 'U' isn't a type.
+//   T<U> v;
+//     ^
+//
+// pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Expected 0 type arguments.
+//   T<U> v;
+//   ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
index 8965f65..20196d3 100644
--- a/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Can't use type arguments with type variable 'T'.
 // Try removing the type arguments.
@@ -12,8 +14,7 @@
 // pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: Expected 0 type arguments.
 //   T<U> v;
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31192.dart.hierarchy.expect
new file mode 100644
index 0000000..bd09d33
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Increment:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Increment.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Increment.x
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31192.dart.legacy.expect
index be20748..5e16fda 100644
--- a/pkg/front_end/testcases/regress/issue_31192.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
@@ -8,15 +10,7 @@
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Can't access 'this' in a field initializer to read 'x'.
 //   Increment() : x++ {}
 //                 ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-//   Increment() : x++ {}
-//                 ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31192.dart.legacy.transformed.expect
index 66b40c3..5e16fda 100644
--- a/pkg/front_end/testcases/regress/issue_31192.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.legacy.transformed.expect
@@ -1,11 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
 //   Increment() : x++ {}
 //                 ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Can't access 'this' in a field initializer to read 'x'.
+//   Increment() : x++ {}
+//                 ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31192.dart.outline.expect
index b416833..42415db 100644
--- a/pkg/front_end/testcases/regress/issue_31192.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
 //   Increment() : x++ {}
 //                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31192.dart.strong.expect
index be20748..5e16fda 100644
--- a/pkg/front_end/testcases/regress/issue_31192.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
@@ -8,15 +10,7 @@
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Can't access 'this' in a field initializer to read 'x'.
 //   Increment() : x++ {}
 //                 ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
-// To initialize a field, use the syntax 'name = value'.
-//   Increment() : x++ {}
-//                 ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect
index 66b40c3..5e16fda 100644
--- a/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect
@@ -1,11 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
 // To initialize a field, use the syntax 'name = value'.
 //   Increment() : x++ {}
 //                 ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Can't access 'this' in a field initializer to read 'x'.
+//   Increment() : x++ {}
+//                 ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31198.dart.hierarchy.expect
new file mode 100644
index 0000000..fe2fcf5
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.hierarchy.expect
@@ -0,0 +1,54 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31198.dart.legacy.expect
index 3cf0eb0..895d3bb 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.
 // To delegate a constructor to a super constructor, put the super call as an initializer.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/regress/issue_31198.dart:8:16: Error: Expected an initializer.
 //   B(): super().foo() {}
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31198.dart.legacy.transformed.expect
index 807896b..895d3bb 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.legacy.transformed.expect
@@ -1,4 +1,16 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   B(): super().foo() {}
+//        ^
+//
+// pkg/front_end/testcases/regress/issue_31198.dart:8:16: Error: Expected an initializer.
+//   B(): super().foo() {}
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
index 3cf0eb0..895d3bb 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.
 // To delegate a constructor to a super constructor, put the super call as an initializer.
@@ -8,8 +10,7 @@
 // pkg/front_end/testcases/regress/issue_31198.dart:8:16: Error: Expected an initializer.
 //   B(): super().foo() {}
 //                ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect
index 807896b..895d3bb 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect
@@ -1,4 +1,16 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//   B(): super().foo() {}
+//        ^
+//
+// pkg/front_end/testcases/regress/issue_31198.dart:8:16: Error: Expected an initializer.
+//   B(): super().foo() {}
+//                ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31299.dart.hierarchy.expect
new file mode 100644
index 0000000..4d0ea0c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.m
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31299.dart.legacy.expect
index f670776..00cb07e 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31299.dart:18:12: Warning: Too many positional arguments: 0 allowed, but 2 found.
 // Try removing the extra positional arguments.
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/regress/issue_31299.dart:10:3: Context: Found this candidate, but the arguments don't match.
 //   A.foo() : m = 2;
 //   ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31299.dart.legacy.transformed.expect
index 8f696fe..00cb07e 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.legacy.transformed.expect
@@ -1,4 +1,15 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_31299.dart:18:12: Warning: Too many positional arguments: 0 allowed, but 2 found.
+// Try removing the extra positional arguments.
+//   new A.foo(1, 2);
+//            ^
+// pkg/front_end/testcases/regress/issue_31299.dart:10:3: Context: Found this candidate, but the arguments don't match.
+//   A.foo() : m = 2;
+//   ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
index 3d0577f..f42f82a 100644
--- a/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_31299.dart:18:12: Error: Too many positional arguments: 0 allowed, but 2 found.
 // Try removing the extra positional arguments.
@@ -11,14 +13,7 @@
 // pkg/front_end/testcases/regress/issue_31299.dart:15:14: Error: Too few positional arguments: 2 required, 0 given.
 //   new A().foo();
 //              ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_31299.dart:15:14: Error: Too few positional arguments: 2 required, 0 given.
-//   new A().foo();
-//              ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31766.dart.hierarchy.expect
new file mode 100644
index 0000000..8130575
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_31996.dart.hierarchy.expect
new file mode 100644
index 0000000..8e9e795
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.hierarchy.expect
@@ -0,0 +1,142 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Base:
+  superclasses:
+    Object
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Child1:
+  superclasses:
+    Object
+      -> Base
+  interfaces: B, C<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+Child2:
+  superclasses:
+    Object
+      -> Base
+  interfaces: B, C<double>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32182.dart.hierarchy.expect
new file mode 100644
index 0000000..c28125f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.hierarchy.expect
@@ -0,0 +1,119 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A<qualified-name(self, A)> with M:
+  superclasses:
+    Object
+      -> A<qualified-name(self, A)>
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C:
+  superclasses:
+    Object
+      -> A<qualified-name(self, A)>
+        -> _C&A&M
+  interfaces: M
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_32182.dart.legacy.expect
index 2b0e26e..628ada3 100644
--- a/pkg/front_end/testcases/regress/issue_32182.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.legacy.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32182.dart" as self;
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_32182.dart.legacy.transformed.expect
index a9c10f4..1ce00d2 100644
--- a/pkg/front_end/testcases/regress/issue_32182.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.legacy.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32182.dart" as self;
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.outline.expect b/pkg/front_end/testcases/regress/issue_32182.dart.outline.expect
index c5ce030..96244c9 100644
--- a/pkg/front_end/testcases/regress/issue_32182.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32182.dart" as self;
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     ;
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32182.dart.strong.expect
index ccec30c..e0b348f 100644
--- a/pkg/front_end/testcases/regress/issue_32182.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.strong.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32182.dart" as self;
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect
index 063d09c..5b387e9 100644
--- a/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32182.dart" as self;
+
 class A<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32196.dart.hierarchy.expect
new file mode 100644
index 0000000..6d21e9a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.name
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32200.dart.hierarchy.expect
new file mode 100644
index 0000000..891ea94
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.self
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.self
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_32200.dart.legacy.expect
index d4f6b1b..4e36d19 100644
--- a/pkg/front_end/testcases/regress/issue_32200.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.legacy.expect
@@ -1,13 +1,16 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32200.dart:8:3: Warning: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
 //   self.Foo self;
 //   ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32200.dart" as self;
+
 class Foo extends core::Object {
   field invalid-type self = null;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_32200.dart.legacy.transformed.expect
index 6e1ee25..4e36d19 100644
--- a/pkg/front_end/testcases/regress/issue_32200.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.legacy.transformed.expect
@@ -1,7 +1,16 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32200.dart:8:3: Warning: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
+//   self.Foo self;
+//   ^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32200.dart" as self;
+
 class Foo extends core::Object {
   field invalid-type self = null;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.outline.expect b/pkg/front_end/testcases/regress/issue_32200.dart.outline.expect
index 90c080c..d111290 100644
--- a/pkg/front_end/testcases/regress/issue_32200.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.outline.expect
@@ -1,13 +1,16 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32200.dart:8:3: Warning: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
 //   self.Foo self;
 //   ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32200.dart" as self;
+
 class Foo extends core::Object {
   field invalid-type self;
   synthetic constructor •() → self::Foo
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 3eaa5d1..3316d53 100644
--- a/pkg/front_end/testcases/regress/issue_32200.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32200.dart:8:3: Error: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
 //   self.Foo self;
@@ -9,17 +11,12 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'invalid-type'.
 //   instance.self = instance;
 //                   ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_32200.dart:8:3: Error: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
-//   self.Foo self;
-//   ^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32200.dart" as self;
+
 class Foo extends core::Object {
   field invalid-type self = null;
   synthetic constructor •() → self::Foo
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 7e77e11..3316d53 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
@@ -1,13 +1,22 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32200.dart:8:3: Error: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
 //   self.Foo self;
 //   ^^^^^^^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_32200.dart:13:19: Error: A value of type 'Foo' can't be assigned to a variable of type 'invalid-type'.
+//  - 'Foo' is from 'pkg/front_end/testcases/regress/issue_32200.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'invalid-type'.
+//   instance.self = instance;
+//                   ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_32200.dart" as self;
+
 class Foo extends core::Object {
   field invalid-type self = null;
   synthetic constructor •() → self::Foo
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
new file mode 100644
index 0000000..5c7b6fa
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.hierarchy.expect
@@ -0,0 +1,124 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> A
+  interfaces: B
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    C.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    C.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> D
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.foo
+    E.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
index 4848bf0..910fc65 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
 //   foo(int x) => x;
@@ -19,18 +21,7 @@
 // pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
 // class E extends D {
 //       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
-//   foo(int x) => x;
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
-//   foo(int x) => x;
-//   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
index 86d1097..910fc65 100644
--- a/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32660.dart.strong.transformed.expect
@@ -1,14 +1,27 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32660.dart:6:3: Error: The method 'A.foo' has fewer named arguments than those of overridden method 'B.foo'.
 //   foo(int x) => x;
 //   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:10:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y}) => y;
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:13:7: Context: Both members are inherited by the non-abstract class 'C'.
+// class C extends A implements B {
+//       ^
 //
 // pkg/front_end/testcases/regress/issue_32660.dart:21:3: Error: The method 'D.foo' has fewer named arguments than those of overridden method 'E.foo'.
 //   foo(int x) => x;
 //   ^
-
-library;
+// pkg/front_end/testcases/regress/issue_32660.dart:25:3: Context: This is the overridden method ('foo').
+//   foo(int x, {int y});
+//   ^
+// pkg/front_end/testcases/regress/issue_32660.dart:24:7: Context: Both members are inherited by the non-abstract class 'E'.
+// class E extends D {
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_32972.dart.hierarchy.expect
new file mode 100644
index 0000000..818484b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Foo.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_32972.dart.legacy.expect
index eef01df..d112e29 100644
--- a/pkg/front_end/testcases/regress/issue_32972.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32972.dart:22:3: Warning: Expected 1 type arguments.
 //   foo<String, String>("hello world");
@@ -20,8 +22,7 @@
 // pkg/front_end/testcases/regress/issue_32972.dart:19:7: Context: The class 'Bar' has a constructor that takes no arguments.
 // class Bar<X, Y> {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_32972.dart.legacy.transformed.expect
index 5f60828..d112e29 100644
--- a/pkg/front_end/testcases/regress/issue_32972.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.legacy.transformed.expect
@@ -1,4 +1,28 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_32972.dart:22:3: Warning: Expected 1 type arguments.
+//   foo<String, String>("hello world");
+//   ^
+// pkg/front_end/testcases/regress/issue_32972.dart:5:6: Context: Found this candidate, but the arguments don't match.
+// void foo<X>(X i) {
+//      ^^^
+//
+// pkg/front_end/testcases/regress/issue_32972.dart:24:7: Warning: Expected 1 type arguments.
+//   Foo.foo<int, int>(42);
+//       ^
+// pkg/front_end/testcases/regress/issue_32972.dart:10:10: Context: Found this candidate, but the arguments don't match.
+//   static foo<X>(X i) {
+//          ^^^
+//
+// pkg/front_end/testcases/regress/issue_32972.dart:29:7: Warning: Expected 2 type arguments.
+//   new Bar<String>();
+//       ^
+// pkg/front_end/testcases/regress/issue_32972.dart:19:7: Context: The class 'Bar' has a constructor that takes no arguments.
+// class Bar<X, Y> {}
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_32972.dart.strong.expect b/pkg/front_end/testcases/regress/issue_32972.dart.strong.expect
index d6a1208..28ddd81 100644
--- a/pkg/front_end/testcases/regress/issue_32972.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_32972.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_32972.dart:22:3: Error: Expected 1 type arguments.
 //   foo<String, String>("hello world");
@@ -24,14 +26,7 @@
 // pkg/front_end/testcases/regress/issue_32972.dart:27:5: Error: Expected 1 type arguments.
 //   f.bar<double, double>(42.42);
 //     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_32972.dart:27:5: Error: Expected 1 type arguments.
-//   f.bar<double, double>(42.42);
-//     ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_33452.dart.hierarchy.expect
new file mode 100644
index 0000000..56edc45
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ExistingClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_33452.dart.legacy.expect
index 1b94419..12ba7ad 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_33452.dart:10:29: Warning: Method not found: 'ExistingClass.nonExistingConstructor'.
 //   var x = new ExistingClass.nonExistingConstructor();
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/regress/issue_33452.dart:15:11: Warning: Method not found: 'NonExistingClass'.
 //   x = new NonExistingClass();
 //           ^^^^^^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_33452.dart.legacy.transformed.expect
index 22a417b..12ba7ad 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.legacy.transformed.expect
@@ -1,4 +1,31 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:10:29: Warning: Method not found: 'ExistingClass.nonExistingConstructor'.
+//   var x = new ExistingClass.nonExistingConstructor();
+//                             ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:11:11: Warning: Method not found: 'ExistingClass'.
+//   x = new ExistingClass();
+//           ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:12:11: Warning: Method not found: 'ExistingClass'.
+//   x = new ExistingClass<String>();
+//           ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:13:33: Warning: Method not found: 'ExistingClass.nonExistingConstructor'.
+//   x = new ExistingClass<String>.nonExistingConstructor();
+//                                 ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:14:41: Warning: Method not found: 'ExistingClass.nonExistingConstructor'.
+//   x = new ExistingClass<String, String>.nonExistingConstructor();
+//                                         ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:15:11: Warning: Method not found: 'NonExistingClass'.
+//   x = new NonExistingClass();
+//           ^^^^^^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect b/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect
index 6dc7b76..ef7a4f5 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_33452.dart:10:29: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
 //   var x = new ExistingClass.nonExistingConstructor();
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/regress/issue_33452.dart:15:11: Error: Method not found: 'NonExistingClass'.
 //   x = new NonExistingClass();
 //           ^^^^^^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect
index e7c037a..ef7a4f5 100644
--- a/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_33452.dart.strong.transformed.expect
@@ -1,4 +1,31 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:10:29: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+//   var x = new ExistingClass.nonExistingConstructor();
+//                             ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:11:11: Error: Method not found: 'ExistingClass'.
+//   x = new ExistingClass();
+//           ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:12:11: Error: Method not found: 'ExistingClass'.
+//   x = new ExistingClass<String>();
+//           ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:13:33: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+//   x = new ExistingClass<String>.nonExistingConstructor();
+//                                 ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:14:41: Error: Method not found: 'ExistingClass.nonExistingConstructor'.
+//   x = new ExistingClass<String, String>.nonExistingConstructor();
+//                                         ^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_33452.dart:15:11: Error: Method not found: 'NonExistingClass'.
+//   x = new NonExistingClass();
+//           ^^^^^^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34225.dart.hierarchy.expect
new file mode 100644
index 0000000..bd55f9e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.C
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.D
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
index 0735fd9..24e8a2a 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
-//   static set C(v) {} //# 01: compile-time error
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
-//   set D(v) {} //# 02: compile-time error
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
-//   static set C(v) {} //# 01: compile-time error
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
-//   set D(v) {} //# 02: compile-time error
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
+//   static set C(v) {} //# 01: compile-time error
+//              ^
+//
+// pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
+//   set D(v) {} //# 02: compile-time error
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
index 69eb56f..24e8a2a 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
 //   static set C(v) {} //# 01: compile-time error
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
 //   set D(v) {} //# 02: compile-time error
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
index b4677c5..4582fae 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
 //   static set C(v) {} //# 01: compile-time error
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
 //   set D(v) {} //# 02: compile-time error
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34225.dart.strong.expect
index 2c6e340..413e604 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
 //   static set C(v) {} //# 01: compile-time error
@@ -13,18 +15,7 @@
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'C'.
 //   c.C = 5;
 //     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
-//   static set C(v) {} //# 01: compile-time error
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
-//   set D(v) {} //# 02: compile-time error
-//       ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -42,7 +33,7 @@
 }
 static method main() → dynamic {
   self::C c = new self::C::•();
-  let final dynamic #t1 = c in invalid-expression "pkg/front_end/testcases/regress/issue_34225.dart:15:5: Error: The setter 'C' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/regress/issue_34225.dart:15:5: Error: The setter 'C' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/regress/issue_34225.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'C'.
   c.C = 5;
diff --git a/pkg/front_end/testcases/regress/issue_34225.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34225.dart.strong.transformed.expect
index d6f9092..413e604 100644
--- a/pkg/front_end/testcases/regress/issue_34225.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34225.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34225.dart:6:14: Error: A class member can't have the same name as the enclosing class.
 //   static set C(v) {} //# 01: compile-time error
@@ -7,8 +9,13 @@
 // pkg/front_end/testcases/regress/issue_34225.dart:10:7: Error: A class member can't have the same name as the enclosing class.
 //   set D(v) {} //# 02: compile-time error
 //       ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_34225.dart:15:5: Error: The setter 'C' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/regress/issue_34225.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'C'.
+//   c.C = 5;
+//     ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -26,7 +33,7 @@
 }
 static method main() → dynamic {
   self::C c = new self::C::•();
-  let final self::C #t1 = c in invalid-expression "pkg/front_end/testcases/regress/issue_34225.dart:15:5: Error: The setter 'C' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/regress/issue_34225.dart:15:5: Error: The setter 'C' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/regress/issue_34225.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'C'.
   c.C = 5;
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34291.dart.hierarchy.expect
new file mode 100644
index 0000000..947e951
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.hierarchy.expect
@@ -0,0 +1,53 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect
index bc156cf..b75366e 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./issue_34291_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
@@ -10,3 +12,13 @@
 }
 static method foo() → iss::A {}
 static method main() → dynamic {}
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → iss::A
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect
index bc156cf..b75366e 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./issue_34291_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
@@ -10,3 +12,13 @@
 }
 static method foo() → iss::A {}
 static method main() → dynamic {}
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → iss::A
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect
index f3be0ec..a72a23c 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.outline.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "./issue_34291_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     ;
@@ -11,3 +13,12 @@
   ;
 static method main() → dynamic
   ;
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → iss::A
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34291.dart.strong.expect
index 84cab9dc..1fe88d2 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.strong.expect
@@ -1,19 +1,16 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34291.dart:9:1: Error: Expected 0 type arguments.
-// lib.A<B> foo() {}
-// ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34291.dart:9:1: Error: Expected 0 type arguments.
-// lib.A<B> foo() {}
-// ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34291.dart:9:1: Error: Expected 0 type arguments.
+// lib.A<B> foo() {}
+// ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
@@ -21,3 +18,13 @@
 }
 static method foo() → invalid-type {}
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34291.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34291.dart.strong.transformed.expect
index 35951e5..1fe88d2 100644
--- a/pkg/front_end/testcases/regress/issue_34291.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34291.dart.strong.transformed.expect
@@ -1,13 +1,16 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34291.dart:9:1: Error: Expected 0 type arguments.
 // lib.A<B> foo() {}
 // ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34291_lib.dart" as lib;
+
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
@@ -15,3 +18,13 @@
 }
 static method foo() → invalid-type {}
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self2::A
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34403.dart.hierarchy.expect
new file mode 100644
index 0000000..9e4da85
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+F:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect
index b7f8bf9..4bc0e99 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.expect
@@ -1,172 +1,93 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c1 = C.bar<int>();
-//              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:18:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c2 = new C.bar<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:20:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c3 = C<String>.bar<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:22:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c4 = new C<String>.bar<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:25:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d1 = D.foo<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:27:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d2 = const D.foo<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:29:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d3 = D<String>.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:31:30: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d4 = const D<String>.foo<int>();
-//                              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:34:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e1 = p.E.bar<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:36:20: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e2 = new p.E.bar<int>();
-//                    ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:38:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e3 = p.E<String>.bar<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:40:28: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e4 = new p.E<String>.bar<int>();
-//                            ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:43:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f1 = p.F.foo<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:45:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f2 = const p.F.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:47:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f3 = p.F<String>.foo<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:49:32: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f4 = const p.F<String>.foo<int>();
-//                                ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c1 = C.bar<int>();
-//              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:18:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c2 = new C.bar<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:20:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c3 = C<String>.bar<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:22:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c4 = new C<String>.bar<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:25:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d1 = D.foo<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:27:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d2 = const D.foo<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:29:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d3 = D<String>.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:31:30: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d4 = const D<String>.foo<int>();
-//                              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:34:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e1 = p.E.bar<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:36:20: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e2 = new p.E.bar<int>();
-//                    ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:38:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e3 = p.E<String>.bar<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:40:28: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e4 = new p.E<String>.bar<int>();
-//                            ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:43:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f1 = p.F.foo<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:45:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f2 = const p.F.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:47:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f3 = p.F<String>.foo<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:49:32: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f4 = const p.F<String>.foo<int>();
-//                                ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c1 = C.bar<int>();
+//              ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:18:18: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c2 = new C.bar<int>();
+//                  ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:20:22: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c3 = C<String>.bar<int>();
+//                      ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:22:26: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c4 = new C<String>.bar<int>();
+//                          ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:25:16: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d1 = D.foo<int>();
+//                ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:27:22: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d2 = const D.foo<int>();
+//                      ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:29:24: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d3 = D<String>.foo<int>();
+//                        ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:31:30: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d4 = const D<String>.foo<int>();
+//                              ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:34:16: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e1 = p.E.bar<int>();
+//                ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:36:20: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e2 = new p.E.bar<int>();
+//                    ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:38:24: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e3 = p.E<String>.bar<int>();
+//                        ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:40:28: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e4 = new p.E<String>.bar<int>();
+//                            ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:43:18: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f1 = p.F.foo<int>();
+//                  ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:45:24: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f2 = const p.F.foo<int>();
+//                        ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:47:26: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f3 = p.F<String>.foo<int>();
+//                          ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:49:32: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f4 = const p.F<String>.foo<int>();
+//                                ^^^
+//
 import self as self;
 import "dart:core" as core;
 import "./issue_34403_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   constructor bar() → self::C<self::C::T>
     : super core::Object::•()
@@ -211,3 +132,18 @@
   const dynamic f4 = const iss::F::foo<core::String>();
   f4.toString();
 }
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class E<T extends core::Object = dynamic> extends core::Object {
+  constructor bar() → iss::E<iss::E::T>
+    : super core::Object::•()
+    ;
+}
+class F<T extends core::Object = dynamic> extends core::Object {
+  const constructor foo() → iss::F<iss::F::T>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect
index 0c20e23..4bc0e99 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
 // Try to place the type arguments on the class name.
@@ -79,12 +81,13 @@
 // Try to place the type arguments on the class name.
 //   const f4 = const p.F<String>.foo<int>();
 //                                ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 import "./issue_34403_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   constructor bar() → self::C<self::C::T>
     : super core::Object::•()
@@ -129,3 +132,18 @@
   const dynamic f4 = const iss::F::foo<core::String>();
   f4.toString();
 }
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class E<T extends core::Object = dynamic> extends core::Object {
+  constructor bar() → iss::E<iss::E::T>
+    : super core::Object::•()
+    ;
+}
+class F<T extends core::Object = dynamic> extends core::Object {
+  const constructor foo() → iss::F<iss::F::T>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34403.dart.outline.expect
index 405b23c..e33bf06 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   constructor bar() → self::C<self::C::T>
     ;
@@ -12,3 +14,16 @@
 }
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class E<T extends core::Object = dynamic> extends core::Object {
+  constructor bar() → self2::E<self2::E::T>
+    ;
+}
+class F<T extends core::Object = dynamic> extends core::Object {
+  const constructor foo() → self2::F<self2::F::T>
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect
index c932348..67776e6 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.strong.expect
@@ -1,172 +1,93 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c1 = C.bar<int>();
-//              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:18:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c2 = new C.bar<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:20:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c3 = C<String>.bar<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:22:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c4 = new C<String>.bar<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:25:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d1 = D.foo<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:27:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d2 = const D.foo<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:29:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d3 = D<String>.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:31:30: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d4 = const D<String>.foo<int>();
-//                              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:34:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e1 = p.E.bar<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:36:20: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e2 = new p.E.bar<int>();
-//                    ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:38:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e3 = p.E<String>.bar<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:40:28: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e4 = new p.E<String>.bar<int>();
-//                            ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:43:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f1 = p.F.foo<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:45:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f2 = const p.F.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:47:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f3 = p.F<String>.foo<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:49:32: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f4 = const p.F<String>.foo<int>();
-//                                ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c1 = C.bar<int>();
-//              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:18:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c2 = new C.bar<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:20:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c3 = C<String>.bar<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:22:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var c4 = new C<String>.bar<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:25:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d1 = D.foo<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:27:22: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d2 = const D.foo<int>();
-//                      ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:29:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d3 = D<String>.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:31:30: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const d4 = const D<String>.foo<int>();
-//                              ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:34:16: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e1 = p.E.bar<int>();
-//                ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:36:20: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e2 = new p.E.bar<int>();
-//                    ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:38:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e3 = p.E<String>.bar<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:40:28: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   var e4 = new p.E<String>.bar<int>();
-//                            ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:43:18: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f1 = p.F.foo<int>();
-//                  ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:45:24: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f2 = const p.F.foo<int>();
-//                        ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:47:26: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f3 = p.F<String>.foo<int>();
-//                          ^^^
-//
-// pkg/front_end/testcases/regress/issue_34403.dart:49:32: Error: A constructor invocation can't have type arguments on the constructor name.
-// Try to place the type arguments on the class name.
-//   const f4 = const p.F<String>.foo<int>();
-//                                ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c1 = C.bar<int>();
+//              ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:18:18: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c2 = new C.bar<int>();
+//                  ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:20:22: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c3 = C<String>.bar<int>();
+//                      ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:22:26: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var c4 = new C<String>.bar<int>();
+//                          ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:25:16: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d1 = D.foo<int>();
+//                ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:27:22: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d2 = const D.foo<int>();
+//                      ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:29:24: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d3 = D<String>.foo<int>();
+//                        ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:31:30: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const d4 = const D<String>.foo<int>();
+//                              ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:34:16: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e1 = p.E.bar<int>();
+//                ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:36:20: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e2 = new p.E.bar<int>();
+//                    ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:38:24: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e3 = p.E<String>.bar<int>();
+//                        ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:40:28: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   var e4 = new p.E<String>.bar<int>();
+//                            ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:43:18: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f1 = p.F.foo<int>();
+//                  ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:45:24: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f2 = const p.F.foo<int>();
+//                        ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:47:26: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f3 = p.F<String>.foo<int>();
+//                          ^^^
+//
+// pkg/front_end/testcases/regress/issue_34403.dart:49:32: Error: A constructor invocation can't have type arguments on the constructor name.
+// Try to place the type arguments on the class name.
+//   const f4 = const p.F<String>.foo<int>();
+//                                ^^^
+//
 import self as self;
 import "dart:core" as core;
 import "./issue_34403_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   constructor bar() → self::C<self::C::T>
     : super core::Object::•()
@@ -211,3 +132,18 @@
   const iss::F<core::String> f4 = const iss::F::foo<core::String>();
   f4.{core::Object::toString}();
 }
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class E<T extends core::Object = dynamic> extends core::Object {
+  constructor bar() → iss::E<iss::E::T>
+    : super core::Object::•()
+    ;
+}
+class F<T extends core::Object = dynamic> extends core::Object {
+  const constructor foo() → iss::F<iss::F::T>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect
index 40fdb58..67776e6 100644
--- a/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34403.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34403.dart:16:14: Error: A constructor invocation can't have type arguments on the constructor name.
 // Try to place the type arguments on the class name.
@@ -79,12 +81,13 @@
 // Try to place the type arguments on the class name.
 //   const f4 = const p.F<String>.foo<int>();
 //                                ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 import "./issue_34403_lib.dart" as iss;
 
+import "org-dartlang-testcase:///issue_34403_lib.dart" as p;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   constructor bar() → self::C<self::C::T>
     : super core::Object::•()
@@ -129,3 +132,18 @@
   const iss::F<core::String> f4 = const iss::F::foo<core::String>();
   f4.{core::Object::toString}();
 }
+
+library;
+import self as iss;
+import "dart:core" as core;
+
+class E<T extends core::Object = dynamic> extends core::Object {
+  constructor bar() → iss::E<iss::E::T>
+    : super core::Object::•()
+    ;
+}
+class F<T extends core::Object = dynamic> extends core::Object {
+  const constructor foo() → iss::F<iss::F::T>
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34498.dart.hierarchy.expect
new file mode 100644
index 0000000..2907509
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.hierarchy.expect
@@ -0,0 +1,95 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.bar
+    Object.toString
+    A.lib
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    A.bar
+    Object.toString
+    A.lib
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+MyClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect
index ac8eb61..6efe51f 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34498.dart:8:3: Warning: 'lib.MyClass' can't be used as a type because 'lib' doesn't refer to an import prefix.
 //   lib.MyClass get lib => null; // (1)
@@ -19,11 +21,12 @@
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34498_lib.dart" as lib;
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
@@ -46,3 +49,13 @@
 }
 static final field self::A a = null;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class MyClass extends core::Object {
+  synthetic constructor •() → self2::MyClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect
index 9b365bf..6efe51f 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.legacy.transformed.expect
@@ -1,7 +1,32 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34498.dart:8:3: Warning: 'lib.MyClass' can't be used as a type because 'lib' doesn't refer to an import prefix.
+//   lib.MyClass get lib => null; // (1)
+//   ^^^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_34498.dart:10:3: Warning: 'foo' isn't a type.
+//   foo foo() {}
+//   ^^^
+// pkg/front_end/testcases/regress/issue_34498.dart:10:7: Context: This isn't a type.
+//   foo foo() {}
+//       ^^^
+//
+// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Warning: Type 'Missing' not found.
+//   Missing bar() {}
+//   ^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_34498.dart:20:3: Warning: Can't use type arguments with type variable 'T'.
+// Try removing the type arguments.
+//   T<String> foo() {}
+//   ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34498_lib.dart" as lib;
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
@@ -24,3 +49,13 @@
 }
 static final field self::A a = null;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class MyClass extends core::Object {
+  synthetic constructor •() → self2::MyClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect
index 394d76e..23a4800 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34498.dart:8:3: Warning: 'lib.MyClass' can't be used as a type because 'lib' doesn't refer to an import prefix.
 //   lib.MyClass get lib => null; // (1)
@@ -19,11 +21,12 @@
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34498_lib.dart" as lib;
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     ;
@@ -47,3 +50,12 @@
 static final field self::A a;
 static method main() → dynamic
   ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class MyClass extends core::Object {
+  synthetic constructor •() → self2::MyClass
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect
index 2bb5096..f90b74b 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34498.dart:8:3: Error: 'lib.MyClass' can't be used as a type because 'lib' doesn't refer to an import prefix.
 //   lib.MyClass get lib => null; // (1)
@@ -19,30 +21,12 @@
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_34498.dart:8:3: Error: 'lib.MyClass' can't be used as a type because 'lib' doesn't refer to an import prefix.
-//   lib.MyClass get lib => null; // (1)
-//   ^^^^^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34498.dart:10:3: Error: 'foo' isn't a type.
-//   foo foo() {}
-//   ^^^
-//
-// pkg/front_end/testcases/regress/issue_34498.dart:12:3: Error: Type 'Missing' not found.
-//   Missing bar() {}
-//   ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34498.dart:20:3: Error: Can't use type arguments with type variable 'T'.
-// Try removing the type arguments.
-//   T<String> foo() {}
-//   ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34498_lib.dart" as lib;
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
@@ -65,3 +49,13 @@
 }
 static final field self::A a = null;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class MyClass extends core::Object {
+  synthetic constructor •() → self2::MyClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect
index c2f20c6..f90b74b 100644
--- a/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34498.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34498.dart:8:3: Error: 'lib.MyClass' can't be used as a type because 'lib' doesn't refer to an import prefix.
 //   lib.MyClass get lib => null; // (1)
@@ -7,6 +9,9 @@
 // pkg/front_end/testcases/regress/issue_34498.dart:10:3: Error: 'foo' isn't a type.
 //   foo foo() {}
 //   ^^^
+// pkg/front_end/testcases/regress/issue_34498.dart:10:7: Context: This isn't a type.
+//   foo foo() {}
+//       ^^^
 //
 // pkg/front_end/testcases/regress/issue_34498.dart:12:3: Error: Type 'Missing' not found.
 //   Missing bar() {}
@@ -16,11 +21,12 @@
 // Try removing the type arguments.
 //   T<String> foo() {}
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "org-dartlang-testcase:///issue_34498_lib.dart" as lib;
+
 class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
@@ -43,3 +49,13 @@
 }
 static final field self::A a = null;
 static method main() → dynamic {}
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+class MyClass extends core::Object {
+  synthetic constructor •() → self2::MyClass
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34563.dart.hierarchy.expect
new file mode 100644
index 0000000..0486fad
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.hierarchy.expect
@@ -0,0 +1,123 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    M1.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C1:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C1.c
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C2:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C3:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34563.dart.legacy.expect
index 5ff2161..d287b8c 100644
--- a/pkg/front_end/testcases/regress/issue_34563.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.legacy.expect
@@ -1,40 +1,23 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
-// mixin M2 extend M1 {}
-//          ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:11:10: Error: Expected 'on' instead of this.
-// mixin M3 extends M1 {}
-//          ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:17:10: Error: Expected 'extends' instead of this.
-// class C2 extend C1 with M2 {}
-//          ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
-// class C3 on C1 with M3 {}
-//          ^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
-// mixin M2 extend M1 {}
-//          ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:11:10: Error: Expected 'on' instead of this.
-// mixin M3 extends M1 {}
-//          ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:17:10: Error: Expected 'extends' instead of this.
-// class C2 extend C1 with M2 {}
-//          ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
-// class C3 on C1 with M3 {}
-//          ^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
+// mixin M2 extend M1 {}
+//          ^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:11:10: Error: Expected 'on' instead of this.
+// mixin M3 extends M1 {}
+//          ^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:17:10: Error: Expected 'extends' instead of this.
+// class C2 extend C1 with M2 {}
+//          ^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
+// class C3 on C1 with M3 {}
+//          ^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34563.dart.legacy.transformed.expect
index 3e681c4..d287b8c 100644
--- a/pkg/front_end/testcases/regress/issue_34563.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
 // mixin M2 extend M1 {}
@@ -15,8 +17,7 @@
 // pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
 // class C3 on C1 with M3 {}
 //          ^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34563.dart.outline.expect
index 0b65eb9..7e6e9d9 100644
--- a/pkg/front_end/testcases/regress/issue_34563.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
 // mixin M2 extend M1 {}
@@ -15,8 +17,7 @@
 // pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
 // class C3 on C1 with M3 {}
 //          ^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34563.dart.strong.expect
index add69c6..a1ba851 100644
--- a/pkg/front_end/testcases/regress/issue_34563.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
 // mixin M2 extend M1 {}
@@ -39,26 +41,7 @@
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
 //   c3.m + c3.c;
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
-// mixin M2 extend M1 {}
-//          ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:11:10: Error: Expected 'on' instead of this.
-// mixin M3 extends M1 {}
-//          ^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:17:10: Error: Expected 'extends' instead of this.
-// class C2 extend C1 with M2 {}
-//          ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
-// class C3 on C1 with M3 {}
-//          ^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
@@ -89,21 +72,21 @@
 }
 static method main() → dynamic {
   self::C2 c2 = new self::C2::•();
-  (let final dynamic #t1 = c2 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:6: Error: The getter 'm' isn't defined for the class 'C2'.
+  invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:6: Error: The getter 'm' isn't defined for the class 'C2'.
  - 'C2' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'm'.
   c2.m + c2.c;
-     ^").+(let final dynamic #t2 = c2 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:13: Error: The getter 'c' isn't defined for the class 'C2'.
+     ^".+(invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:13: Error: The getter 'c' isn't defined for the class 'C2'.
  - 'C2' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
   c2.m + c2.c;
             ^");
   self::C3 c3 = new self::C3::•();
-  (let final dynamic #t3 = c3 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:6: Error: The getter 'm' isn't defined for the class 'C3'.
+  invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:6: Error: The getter 'm' isn't defined for the class 'C3'.
  - 'C3' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'm'.
   c3.m + c3.c;
-     ^").+(let final dynamic #t4 = c3 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:13: Error: The getter 'c' isn't defined for the class 'C3'.
+     ^".+(invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:13: Error: The getter 'c' isn't defined for the class 'C3'.
  - 'C3' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
   c3.m + c3.c;
diff --git a/pkg/front_end/testcases/regress/issue_34563.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34563.dart.strong.transformed.expect
index 98e20c3..a1ba851 100644
--- a/pkg/front_end/testcases/regress/issue_34563.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34563.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34563.dart:9:10: Error: Expected 'on' instead of this.
 // mixin M2 extend M1 {}
@@ -15,8 +17,31 @@
 // pkg/front_end/testcases/regress/issue_34563.dart:19:10: Error: Expected 'extends' instead of this.
 // class C3 on C1 with M3 {}
 //          ^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:23:6: Error: The getter 'm' isn't defined for the class 'C2'.
+//  - 'C2' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm'.
+//   c2.m + c2.c;
+//      ^
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:23:13: Error: The getter 'c' isn't defined for the class 'C2'.
+//  - 'C2' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
+//   c2.m + c2.c;
+//             ^
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:25:6: Error: The getter 'm' isn't defined for the class 'C3'.
+//  - 'C3' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'm'.
+//   c3.m + c3.c;
+//      ^
+//
+// pkg/front_end/testcases/regress/issue_34563.dart:25:13: Error: The getter 'c' isn't defined for the class 'C3'.
+//  - 'C3' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
+//   c3.m + c3.c;
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -47,21 +72,21 @@
 }
 static method main() → dynamic {
   self::C2 c2 = new self::C2::•();
-  (let final self::C2 #t1 = c2 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:6: Error: The getter 'm' isn't defined for the class 'C2'.
+  invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:6: Error: The getter 'm' isn't defined for the class 'C2'.
  - 'C2' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'm'.
   c2.m + c2.c;
-     ^").+(let final self::C2 #t2 = c2 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:13: Error: The getter 'c' isn't defined for the class 'C2'.
+     ^".+(invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:23:13: Error: The getter 'c' isn't defined for the class 'C2'.
  - 'C2' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
   c2.m + c2.c;
             ^");
   self::C3 c3 = new self::C3::•();
-  (let final self::C3 #t3 = c3 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:6: Error: The getter 'm' isn't defined for the class 'C3'.
+  invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:6: Error: The getter 'm' isn't defined for the class 'C3'.
  - 'C3' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'm'.
   c3.m + c3.c;
-     ^").+(let final self::C3 #t4 = c3 in invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:13: Error: The getter 'c' isn't defined for the class 'C3'.
+     ^".+(invalid-expression "pkg/front_end/testcases/regress/issue_34563.dart:25:13: Error: The getter 'c' isn't defined for the class 'C3'.
  - 'C3' is from 'pkg/front_end/testcases/regress/issue_34563.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'c'.
   c3.m + c3.c;
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34610.dart.hierarchy.expect
new file mode 100644
index 0000000..d7adf4b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.hierarchy.expect
@@ -0,0 +1,75 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.bar
+    A.A
+    Object.toString
+    A.named
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.bar
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34610.dart.legacy.expect
index ceb8d46..6a16c4e 100644
--- a/pkg/front_end/testcases/regress/issue_34610.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
 // class A { get A.named => null; get bar => 1; }
@@ -31,37 +33,7 @@
 // Try removing the return type.
 // class C { C.named => null; get bar => 1; }
 //                      ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
-// class A { get A.named => null; get bar => 1; }
-//                ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:5:15: Error: A class member can't have the same name as the enclosing class.
-// class A { get A.named => null; get bar => 1; }
-//               ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected a class member, but got '.'.
-// class A { get A.named => null; get bar => 1; }
-//                ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:5:17: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class A { get A.named => null; get bar => 1; }
-//                 ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:7:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class B { B.named : super(); get bar => 1; }
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:9:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class C { C.named => null; get bar => 1; }
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34610.dart.legacy.transformed.expect
index fb45946..6a16c4e 100644
--- a/pkg/front_end/testcases/regress/issue_34610.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
 // class A { get A.named => null; get bar => 1; }
@@ -26,8 +28,12 @@
 // Try adding a parameter list to the method declaration.
 // class C { C.named => null; get bar => 1; }
 //           ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_34610.dart:9:22: Error: Constructors can't have a return type.
+// Try removing the return type.
+// class C { C.named => null; get bar => 1; }
+//                      ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34610.dart.outline.expect
index 7e39069..6f92c1f 100644
--- a/pkg/front_end/testcases/regress/issue_34610.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
 // class A { get A.named => null; get bar => 1; }
@@ -26,8 +28,7 @@
 // Try adding a parameter list to the method declaration.
 // class C { C.named => null; get bar => 1; }
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34610.dart.strong.expect
index 568654c..c127bbc 100644
--- a/pkg/front_end/testcases/regress/issue_34610.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
 // class A { get A.named => null; get bar => 1; }
@@ -31,37 +33,7 @@
 // Try removing the return type.
 // class C { C.named => null; get bar => 1; }
 //                      ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
-// class A { get A.named => null; get bar => 1; }
-//                ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:5:15: Error: A class member can't have the same name as the enclosing class.
-// class A { get A.named => null; get bar => 1; }
-//               ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected a class member, but got '.'.
-// class A { get A.named => null; get bar => 1; }
-//                ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:5:17: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class A { get A.named => null; get bar => 1; }
-//                 ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:7:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class B { B.named : super(); get bar => 1; }
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_34610.dart:9:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class C { C.named => null; get bar => 1; }
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34610.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34610.dart.strong.transformed.expect
index ca2cebe..c127bbc 100644
--- a/pkg/front_end/testcases/regress/issue_34610.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34610.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34610.dart:5:16: Error: Expected '{' before this.
 // class A { get A.named => null; get bar => 1; }
@@ -26,8 +28,12 @@
 // Try adding a parameter list to the method declaration.
 // class C { C.named => null; get bar => 1; }
 //           ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_34610.dart:9:22: Error: Constructors can't have a return type.
+// Try removing the return type.
+// class C { C.named => null; get bar => 1; }
+//                      ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_34614.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34614.dart.legacy.expect
index 004bcd9..702299b 100644
--- a/pkg/front_end/testcases/regress/issue_34614.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.legacy.expect
@@ -1,34 +1,20 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
-// class C { C. }
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class C { C. }
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
-// class C { C. }
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
-// class C { C. }
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class C { C. }
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
-// class C { C. }
-//              ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
+// class C { C. }
+//              ^
+//
+// pkg/front_end/testcases/regress/issue_34614.dart:5:11: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// class C { C. }
+//           ^
+//
+// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
+// class C { C. }
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34614.dart.legacy.transformed.expect
index 85f5296..702299b 100644
--- a/pkg/front_end/testcases/regress/issue_34614.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
 // class C { C. }
@@ -12,8 +14,7 @@
 // pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
 // class C { C. }
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34614.dart.outline.expect
index 6cd7c77..2b58976 100644
--- a/pkg/front_end/testcases/regress/issue_34614.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
 // class C { C. }
@@ -12,8 +14,7 @@
 // pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
 // class C { C. }
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34614.dart.strong.expect
index d36a30c..a8a4eff 100644
--- a/pkg/front_end/testcases/regress/issue_34614.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.strong.expect
@@ -1,34 +1,20 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
-// class C { C. }
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class C { C. }
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
-// class C { C. }
-//              ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
-// class C { C. }
-//              ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:11: Error: A method declaration needs an explicit list of parameters.
-// Try adding a parameter list to the method declaration.
-// class C { C. }
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
-// class C { C. }
-//              ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
+// class C { C. }
+//              ^
+//
+// pkg/front_end/testcases/regress/issue_34614.dart:5:11: Error: A method declaration needs an explicit list of parameters.
+// Try adding a parameter list to the method declaration.
+// class C { C. }
+//           ^
+//
+// pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
+// class C { C. }
+//              ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34614.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34614.dart.strong.transformed.expect
index 225711f..a8a4eff 100644
--- a/pkg/front_end/testcases/regress/issue_34614.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34614.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected an identifier, but got '}'.
 // class C { C. }
@@ -12,8 +14,7 @@
 // pkg/front_end/testcases/regress/issue_34614.dart:5:14: Error: Expected '{' before this.
 // class C { C. }
 //              ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_34850.dart.legacy.expect
index a866654..477d5fd 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
 // <foo<
@@ -39,35 +41,7 @@
 // pkg/front_end/testcases/regress/issue_34850.dart:12:1: Context: This isn't a type.
 // Future<List<int>> f2() async => null;
 // ^^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
-// <foo<
-// ^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:7:1: Error: Expected '>' after this.
-// int f1() {
-// ^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:8: Error: Expected '>' after this.
-// Future<List<int>> f2() async => null;
-//        ^^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Error: A function declaration needs an explicit list of parameters.
-// Try adding a parameter list to the function declaration.
-// Future<List<int>> f2() async => null;
-// ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:19: Error: Expected '{' before this.
-// Future<List<int>> f2() async => null;
-//                   ^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:14:13: Error: Expected a type, but got '>>'.
-// Future<List<>> f3() async {
-//             ^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_34850.dart.legacy.transformed.expect
index 38947f8..e3ef37d 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
 // <foo<
@@ -24,8 +26,22 @@
 // pkg/front_end/testcases/regress/issue_34850.dart:14:13: Error: Expected a type, but got '>>'.
 // Future<List<>> f3() async {
 //             ^^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:5:2: Warning: Type 'foo' not found.
+// <foo<
+//  ^^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:11:1: Warning: Type 'foo' not found.
+// foo
+// ^^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:14:1: Warning: 'Future' isn't a type.
+// Future<List<>> f3() async {
+// ^^^^^^
+// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Context: This isn't a type.
+// Future<List<int>> f2() async => null;
+// ^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.outline.expect b/pkg/front_end/testcases/regress/issue_34850.dart.outline.expect
index 1bd0032..d7332cd 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
 // <foo<
@@ -39,8 +41,7 @@
 // pkg/front_end/testcases/regress/issue_34850.dart:12:1: Context: This isn't a type.
 // Future<List<int>> f2() async => null;
 // ^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
index 1f1bd88..f3100e5 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.expect
@@ -1,90 +1,48 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
-// <foo<
-// ^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:7:1: Error: Expected '>' after this.
-// int f1() {
-// ^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:8: Error: Expected '>' after this.
-// Future<List<int>> f2() async => null;
-//        ^^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Error: A function declaration needs an explicit list of parameters.
-// Try adding a parameter list to the function declaration.
-// Future<List<int>> f2() async => null;
-// ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:19: Error: Expected '{' before this.
-// Future<List<int>> f2() async => null;
-//                   ^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:14:13: Error: Expected a type, but got '>>'.
-// Future<List<>> f3() async {
-//             ^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Expected 0 type arguments.
-// <foo<
-//  ^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:11:1: Error: Type 'foo' not found.
-// foo
-// ^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: Expected 0 type arguments.
-// 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 {
-//                ^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
-// <foo<
-// ^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:7:1: Error: Expected '>' after this.
-// int f1() {
-// ^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:8: Error: Expected '>' after this.
-// Future<List<int>> f2() async => null;
-//        ^^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Error: A function declaration needs an explicit list of parameters.
-// Try adding a parameter list to the function declaration.
-// Future<List<int>> f2() async => null;
-// ^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:12:19: Error: Expected '{' before this.
-// Future<List<int>> f2() async => null;
-//                   ^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:14:13: Error: Expected a type, but got '>>'.
-// Future<List<>> f3() async {
-//             ^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Expected 0 type arguments.
-// <foo<
-//  ^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:11:1: Error: Type 'foo' not found.
-// foo
-// ^^^
-//
-// pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: Expected 0 type arguments.
-// 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 {
-//                ^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
+// <foo<
+// ^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:7:1: Error: Expected '>' after this.
+// int f1() {
+// ^^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:12:8: Error: Expected '>' after this.
+// Future<List<int>> f2() async => null;
+//        ^^^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:12:1: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// Future<List<int>> f2() async => null;
+// ^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:12:19: Error: Expected '{' before this.
+// Future<List<int>> f2() async => null;
+//                   ^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:14:13: Error: Expected a type, but got '>>'.
+// Future<List<>> f3() async {
+//             ^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:5:2: Error: Expected 0 type arguments.
+// <foo<
+//  ^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:11:1: Error: Type 'foo' not found.
+// foo
+// ^^^
+//
+// pkg/front_end/testcases/regress/issue_34850.dart:14:1: Error: Expected 0 type arguments.
+// 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 72bac6c..22df880 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
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_34850.dart:5:1: Error: Expected a declaration, but got '<'.
 // <foo<
@@ -40,8 +42,7 @@
 // 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 {
 //                ^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_35151.dart.hierarchy.expect
new file mode 100644
index 0000000..897a155
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.hierarchy.expect
@@ -0,0 +1,75 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    A.a
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.a
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35151.dart.legacy.expect
index de1108c..29b35f0 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
@@ -13,15 +15,7 @@
 // pkg/front_end/testcases/regress/issue_35151.dart:14:9: Error: Can't access 'super' in a field initializer.
 //   C() : super = 42;
 //         ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
-// Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
-//   B() : super.a = 42;
-//               ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35151.dart.legacy.transformed.expect
index 8b2425d..29b35f0 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.legacy.transformed.expect
@@ -1,11 +1,21 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
 //   B() : super.a = 42;
 //               ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+//   B() : super.a = 42;
+//               ^
+//
+// pkg/front_end/testcases/regress/issue_35151.dart:14:9: Error: Can't access 'super' in a field initializer.
+//   C() : super = 42;
+//         ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect
index 0699365..314a508 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.outline.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
 //   B() : super.a = 42;
 //               ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect
index 6f8a3c8..b8a15c7 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
@@ -13,15 +15,7 @@
 // pkg/front_end/testcases/regress/issue_35151.dart:14:9: Error: Can't access 'super' in a field initializer.
 //   C() : super = 42;
 //         ^^^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
-// Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
-//   B() : super.a = 42;
-//               ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect
index de1b159..b8a15c7 100644
--- a/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35151.dart.strong.transformed.expect
@@ -1,11 +1,21 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: A field can only be initialized in it's declaring class
 // Try passing a value into the superclass constructor, or moving the initialization into the constructor body.
 //   B() : super.a = 42;
 //               ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_35151.dart:10:15: Error: Not a valid initializer.
+// To initialize a field, use the syntax 'name = value'.
+//   B() : super.a = 42;
+//               ^
+//
+// pkg/front_end/testcases/regress/issue_35151.dart:14:9: Error: Can't access 'super' in a field initializer.
+//   C() : super = 42;
+//         ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35177.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35177.dart.legacy.expect
index 67a4d3d..7e392f3 100644
--- a/pkg/front_end/testcases/regress/issue_35177.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35177.dart.legacy.expect
@@ -6,4 +6,3 @@
   () → dynamic f;
   f.call().call<core::int>();
 }
-
diff --git a/pkg/front_end/testcases/regress/issue_35177.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35177.dart.legacy.transformed.expect
index 67a4d3d..7e392f3 100644
--- a/pkg/front_end/testcases/regress/issue_35177.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35177.dart.legacy.transformed.expect
@@ -6,4 +6,3 @@
   () → dynamic f;
   f.call().call<core::int>();
 }
-
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35213.dart.legacy.expect
index 1280dd9..59d39ba 100644
--- a/pkg/front_end/testcases/regress/issue_35213.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.legacy.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
-// f(int a int b) { }
-//         ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
-// f(int a int b) { }
-//         ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
+// f(int a int b) { }
+//         ^^^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -18,4 +13,3 @@
 static method main() → dynamic {
   self::f(2, 3);
 }
-
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35213.dart.legacy.transformed.expect
index a66ce9c..59d39ba 100644
--- a/pkg/front_end/testcases/regress/issue_35213.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.legacy.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
 // f(int a int b) { }
 //         ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -12,4 +13,3 @@
 static method main() → dynamic {
   self::f(2, 3);
 }
-
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35213.dart.outline.expect
index 040a0f3..27fe4c0 100644
--- a/pkg/front_end/testcases/regress/issue_35213.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
 // f(int a int b) { }
 //         ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35213.dart.strong.expect
index cd5fe47..59d39ba 100644
--- a/pkg/front_end/testcases/regress/issue_35213.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
-// f(int a int b) { }
-//         ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
-// f(int a int b) { }
-//         ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
+// f(int a int b) { }
+//         ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35213.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35213.dart.strong.transformed.expect
index 1f16d48..59d39ba 100644
--- a/pkg/front_end/testcases/regress/issue_35213.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35213.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35213.dart:5:9: Error: Expected ',' before this.
 // f(int a int b) { }
 //         ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_35258.dart.hierarchy.expect
new file mode 100644
index 0000000..29f4cd3
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.d
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35258.dart.legacy.expect
index dd57ef3..f3cf819 100644
--- a/pkg/front_end/testcases/regress/issue_35258.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
 //   C(this.d) {}
@@ -15,19 +17,7 @@
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
-//   C(this.d) {}
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_35258.dart:10:9: Error: Final field 'd' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final d;
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35258.dart.legacy.transformed.expect
index 89e7a08..f3cf819 100644
--- a/pkg/front_end/testcases/regress/issue_35258.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.legacy.transformed.expect
@@ -1,15 +1,23 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
 //   C(this.d) {}
 //   ^
+// pkg/front_end/testcases/regress/issue_35258.dart:12:3: Context: Previous declaration of 'C'.
+//   C() {}
+//   ^
+//
+// pkg/front_end/testcases/regress/issue_35258.dart:6:7: Error: Can't use 'C' because it is declared more than once.
+//   new C(42);
+//       ^
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:10:9: Error: Final field 'd' is not initialized.
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35258.dart.outline.expect
index 6573c01..1d44eb7 100644
--- a/pkg/front_end/testcases/regress/issue_35258.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
 //   C(this.d) {}
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/regress/issue_35258.dart:12:3: Context: Previous declaration of 'C'.
 //   C() {}
 //   ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35258.dart.strong.expect
index ee9cdb0..cd8f0cb 100644
--- a/pkg/front_end/testcases/regress/issue_35258.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
 //   C(this.d) {}
@@ -15,19 +17,7 @@
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
-//   C(this.d) {}
-//   ^
-//
-// pkg/front_end/testcases/regress/issue_35258.dart:10:9: Error: Final field 'd' is not initialized.
-// Try to initialize the field in the declaration or in every constructor.
-//   final d;
-//         ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35258.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35258.dart.strong.transformed.expect
index dc46e1b..cd8f0cb 100644
--- a/pkg/front_end/testcases/regress/issue_35258.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35258.dart.strong.transformed.expect
@@ -1,15 +1,23 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:13:3: Error: 'C' is already declared in this scope.
 //   C(this.d) {}
 //   ^
+// pkg/front_end/testcases/regress/issue_35258.dart:12:3: Context: Previous declaration of 'C'.
+//   C() {}
+//   ^
+//
+// pkg/front_end/testcases/regress/issue_35258.dart:6:7: Error: Can't use 'C' because it is declared more than once.
+//   new C(42);
+//       ^
 //
 // pkg/front_end/testcases/regress/issue_35258.dart:10:9: Error: Final field 'd' is not initialized.
 // Try to initialize the field in the declaration or in every constructor.
 //   final d;
 //         ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_35259.dart.hierarchy.expect
new file mode 100644
index 0000000..9a92dd9
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Supertype:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Supertype._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Supertype._redirecting#
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35259.dart.legacy.expect
index cdee012..0360cf4 100644
--- a/pkg/front_end/testcases/regress/issue_35259.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = Unresolved;
@@ -26,14 +28,7 @@
 // pkg/front_end/testcases/regress/issue_35259.dart:11:13: Error: Can't use 'Supertype' because it is declared more than once.
 //   print(new Supertype());
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
-//   factory Supertype() = Unresolved;
-//           ^^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35259.dart.legacy.transformed.expect
index b95387a..0360cf4 100644
--- a/pkg/front_end/testcases/regress/issue_35259.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.legacy.transformed.expect
@@ -1,10 +1,34 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = Unresolved;
 //           ^^^^^^^^^
-
-library;
+// pkg/front_end/testcases/regress/issue_35259.dart:6:11: Context: Previous declaration of 'Supertype'.
+//   factory Supertype() = Unresolved;
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_35259.dart:6:25: Warning: Couldn't find constructor 'Unresolved'.
+//   factory Supertype() = Unresolved;
+//                         ^
+//
+// pkg/front_end/testcases/regress/issue_35259.dart:7:25: Warning: Couldn't find constructor 'Unresolved'.
+//   factory Supertype() = Unresolved;
+//                         ^
+//
+// pkg/front_end/testcases/regress/issue_35259.dart:7:11: Warning: Redirection constructor target not found: 'Unresolved'
+//   factory Supertype() = Unresolved;
+//           ^
+//
+// pkg/front_end/testcases/regress/issue_35259.dart:6:11: Warning: Redirection constructor target not found: 'Unresolved'
+//   factory Supertype() = Unresolved;
+//           ^
+//
+// pkg/front_end/testcases/regress/issue_35259.dart:11:13: Error: Can't use 'Supertype' because it is declared more than once.
+//   print(new Supertype());
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35259.dart.outline.expect
index 93650ba..7137976 100644
--- a/pkg/front_end/testcases/regress/issue_35259.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = Unresolved;
@@ -22,8 +24,7 @@
 // pkg/front_end/testcases/regress/issue_35259.dart:6:11: Warning: Redirection constructor target not found: 'Unresolved'
 //   factory Supertype() = Unresolved;
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35259.dart.strong.expect
index c803a06..f3d633c 100644
--- a/pkg/front_end/testcases/regress/issue_35259.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = Unresolved;
@@ -26,30 +28,7 @@
 // pkg/front_end/testcases/regress/issue_35259.dart:11:13: Error: Can't use 'Supertype' because it is declared more than once.
 //   print(new Supertype());
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
-//   factory Supertype() = Unresolved;
-//           ^^^^^^^^^
-//
-// pkg/front_end/testcases/regress/issue_35259.dart:6:25: Error: Couldn't find constructor 'Unresolved'.
-//   factory Supertype() = Unresolved;
-//                         ^
-//
-// pkg/front_end/testcases/regress/issue_35259.dart:7:25: Error: Couldn't find constructor 'Unresolved'.
-//   factory Supertype() = Unresolved;
-//                         ^
-//
-// pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: Redirection constructor target not found: 'Unresolved'
-//   factory Supertype() = Unresolved;
-//           ^
-//
-// pkg/front_end/testcases/regress/issue_35259.dart:6:11: Error: Redirection constructor target not found: 'Unresolved'
-//   factory Supertype() = Unresolved;
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35259.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35259.dart.strong.transformed.expect
index ff84c51..6b7b15d 100644
--- a/pkg/front_end/testcases/regress/issue_35259.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35259.dart.strong.transformed.expect
@@ -1,8 +1,13 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35259.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = Unresolved;
 //           ^^^^^^^^^
+// pkg/front_end/testcases/regress/issue_35259.dart:6:11: Context: Previous declaration of 'Supertype'.
+//   factory Supertype() = Unresolved;
+//           ^^^^^^^^^
 //
 // pkg/front_end/testcases/regress/issue_35259.dart:6:25: Error: Couldn't find constructor 'Unresolved'.
 //   factory Supertype() = Unresolved;
@@ -19,8 +24,11 @@
 // pkg/front_end/testcases/regress/issue_35259.dart:6:11: Error: Redirection constructor target not found: 'Unresolved'
 //   factory Supertype() = Unresolved;
 //           ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_35259.dart:11:13: Error: Can't use 'Supertype' because it is declared more than once.
+//   print(new Supertype());
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_35260.dart.hierarchy.expect
new file mode 100644
index 0000000..4158779
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.hierarchy.expect
@@ -0,0 +1,67 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Supertype:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Supertype._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Supertype._redirecting#
+
+X:
+  superclasses:
+    Object
+  interfaces: Supertype
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35260.dart.legacy.expect
index 37f976f..381ea3c 100644
--- a/pkg/front_end/testcases/regress/issue_35260.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = X;
@@ -10,14 +12,7 @@
 // pkg/front_end/testcases/regress/issue_35260.dart:15:13: Error: Can't use 'Supertype' because it is declared more than once.
 //   X x = new Supertype();
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
-//   factory Supertype() = X;
-//           ^^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35260.dart.legacy.transformed.expect
index 64871ce..381ea3c 100644
--- a/pkg/front_end/testcases/regress/issue_35260.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.legacy.transformed.expect
@@ -1,10 +1,18 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = X;
 //           ^^^^^^^^^
-
-library;
+// pkg/front_end/testcases/regress/issue_35260.dart:6:11: Context: Previous declaration of 'Supertype'.
+//   factory Supertype() = X;
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_35260.dart:15:13: Error: Can't use 'Supertype' because it is declared more than once.
+//   X x = new Supertype();
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35260.dart.outline.expect
index 4f6b056..a489ec3 100644
--- a/pkg/front_end/testcases/regress/issue_35260.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = X;
@@ -6,8 +8,7 @@
 // pkg/front_end/testcases/regress/issue_35260.dart:6:11: Context: Previous declaration of 'Supertype'.
 //   factory Supertype() = X;
 //           ^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35260.dart.strong.expect
index 25f0614..d65aef7 100644
--- a/pkg/front_end/testcases/regress/issue_35260.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = X;
@@ -10,14 +12,7 @@
 // pkg/front_end/testcases/regress/issue_35260.dart:15:13: Error: Can't use 'Supertype' because it is declared more than once.
 //   X x = new Supertype();
 //             ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
-//   factory Supertype() = X;
-//           ^^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect
index 42e3f3a..bedcb24 100644
--- a/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35260.dart.strong.transformed.expect
@@ -1,10 +1,18 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35260.dart:7:11: Error: 'Supertype' is already declared in this scope.
 //   factory Supertype() = X;
 //           ^^^^^^^^^
-
-library;
+// pkg/front_end/testcases/regress/issue_35260.dart:6:11: Context: Previous declaration of 'Supertype'.
+//   factory Supertype() = X;
+//           ^^^^^^^^^
+//
+// pkg/front_end/testcases/regress/issue_35260.dart:15:13: Error: Can't use 'Supertype' because it is declared more than once.
+//   X x = new Supertype();
+//             ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_35266.dart.hierarchy.expect
new file mode 100644
index 0000000..2171f54
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._redirecting#
+
+B:
+  superclasses:
+    Object
+      -> C<T>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B._redirecting#
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B._redirecting#
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_35266.dart.legacy.expect
index aba6888..7821553 100644
--- a/pkg/front_end/testcases/regress/issue_35266.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
 //   factory B.foo() = B<T>;
@@ -14,18 +16,7 @@
 // pkg/front_end/testcases/regress/issue_35266.dart:13:11: Warning: Method not found: 'B.foo'.
 //   factory C.bar() = B<K>.foo;
 //           ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
-//   factory B.foo() = B<T>;
-//           ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Can't use 'B.foo' because it is declared more than once.
-//   factory C.bar() = B<K>.foo;
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_35266.dart.legacy.transformed.expect
index 65c513f..7821553 100644
--- a/pkg/front_end/testcases/regress/issue_35266.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.legacy.transformed.expect
@@ -1,14 +1,22 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
 //   factory B.foo() = B<T>;
 //           ^^^^^
+// pkg/front_end/testcases/regress/issue_35266.dart:7:11: Context: Previous declaration of 'B.foo'.
+//   factory B.foo() = B<T>;
+//           ^^^^^
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Can't use 'B.foo' because it is declared more than once.
 //   factory C.bar() = B<K>.foo;
 //           ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_35266.dart:13:11: Warning: Method not found: 'B.foo'.
+//   factory C.bar() = B<K>.foo;
+//           ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.outline.expect b/pkg/front_end/testcases/regress/issue_35266.dart.outline.expect
index c7faea7..1ea14fd 100644
--- a/pkg/front_end/testcases/regress/issue_35266.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
 //   factory B.foo() = B<T>;
@@ -10,8 +12,7 @@
 // pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Can't use 'B.foo' because it is declared more than once.
 //   factory C.bar() = B<K>.foo;
 //           ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.strong.expect b/pkg/front_end/testcases/regress/issue_35266.dart.strong.expect
index 7ae1045..edf8e9a 100644
--- a/pkg/front_end/testcases/regress/issue_35266.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
 //   factory B.foo() = B<T>;
@@ -14,18 +16,7 @@
 // pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Method not found: 'B.foo'.
 //   factory C.bar() = B<K>.foo;
 //           ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
-//   factory B.foo() = B<T>;
-//           ^^^^^
-//
-// pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Can't use 'B.foo' because it is declared more than once.
-//   factory C.bar() = B<K>.foo;
-//           ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/regress/issue_35266.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_35266.dart.strong.transformed.expect
index dbe98fd..82b4544 100644
--- a/pkg/front_end/testcases/regress/issue_35266.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_35266.dart.strong.transformed.expect
@@ -1,14 +1,22 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:8:11: Error: 'B.foo' is already declared in this scope.
 //   factory B.foo() = B<T>;
 //           ^^^^^
+// pkg/front_end/testcases/regress/issue_35266.dart:7:11: Context: Previous declaration of 'B.foo'.
+//   factory B.foo() = B<T>;
+//           ^^^^^
 //
 // pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Can't use 'B.foo' because it is declared more than once.
 //   factory C.bar() = B<K>.foo;
 //           ^
-
-library;
+//
+// pkg/front_end/testcases/regress/issue_35266.dart:13:11: Error: Method not found: 'B.foo'.
+//   factory C.bar() = B<K>.foo;
+//           ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.hierarchy.expect b/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.hierarchy.expect
new file mode 100644
index 0000000..efc780c
--- /dev/null
+++ b/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Hest:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.expect b/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.expect
index f7c017d..5cbc6bf 100644
--- a/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.expect
+++ b/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.expect
@@ -1,16 +1,11 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart:8:12: Error: Type variables can't have generic function types in their bounds.
-// class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
-//            ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart:8:12: Error: Type variables can't have generic function types in their bounds.
-// class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
-//            ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart:8:12: Error: Type variables can't have generic function types in their bounds.
+// class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
+//            ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.transformed.expect
index be82e20..5cbc6bf 100644
--- a/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart.strong.transformed.expect
@@ -1,10 +1,11 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/reject_generic_function_types_in_bounds.dart:8:12: Error: Type variables can't have generic function types in their bounds.
 // class Hest<TypeX extends TypeY Function<TypeY>(TypeY)> {}
 //            ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.hierarchy.expect
new file mode 100644
index 0000000..11f7b3e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.h
+    Object.hashCode
+    C.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.hierarchy.expect
new file mode 100644
index 0000000..3e0221a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.hierarchy.expect
new file mode 100644
index 0000000..f629112
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
+    C.y
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.hierarchy.expect
new file mode 100644
index 0000000..8397602
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.hierarchy.expect
new file mode 100644
index 0000000..8397602
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.expect
index b88dd51..b806941 100644
--- a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.expect
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.transformed.expect
index b88dd51..b806941 100644
--- a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.legacy.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.outline.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.outline.expect
index 3f4889b..c1ceccf 100644
--- a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.outline.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:async";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     ;
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.expect
index 5140370..ee98bf3 100644
--- a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect
index 5140370..ee98bf3 100644
--- a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class C extends core::Object {
   synthetic constructor •() → self::C
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.hierarchy.expect
new file mode 100644
index 0000000..eaaef92
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.hierarchy.expect
new file mode 100644
index 0000000..7b50101
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.hierarchy.expect
new file mode 100644
index 0000000..7b50101
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.hierarchy.expect
new file mode 100644
index 0000000..3f28571
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    C._x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C._x
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..eaaef92
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.hierarchy.expect
new file mode 100644
index 0000000..7b50101
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.hierarchy.expect
new file mode 100644
index 0000000..7b50101
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.hierarchy.expect
new file mode 100644
index 0000000..466f6ef
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.g1
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
index ab8ad33..4b7f896 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: The argument type 'double' can't be assigned to the parameter type 'U'.
 // Try changing the type of the parameter, or casting the argument to 'U'.
@@ -10,16 +12,7 @@
 // Try changing type arguments so that they conform to the bounds.
 //   new C<int>().g1<num>();
 //                ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:20:16: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'U' on 'C<int>.g1'.
-//  - 'C' is from 'pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart'.
-// Try changing type arguments so that they conform to the bounds.
-//   new C<int>().g1<num>();
-//                ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
index fd9ec58..4b7f896 100644
--- a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -1,12 +1,18 @@
-// Unhandled errors:
+library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:15: Error: The argument type 'double' can't be assigned to the parameter type 'U'.
+// Try changing the type of the parameter, or casting the argument to 'U'.
+//     this.f<U>(1.5);
+//               ^
 //
 // pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:20:16: Error: Type argument 'num' doesn't conform to the bound 'int' of the type variable 'U' on 'C<int>.g1'.
 //  - 'C' is from 'pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart'.
 // Try changing type arguments so that they conform to the bounds.
 //   new C<int>().g1<num>();
 //                ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.hierarchy.expect
new file mode 100644
index 0000000..c59ab56
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.f4
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f3
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..570f5d0
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.hierarchy.expect
@@ -0,0 +1,105 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    I.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    I.f2
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+      -> C<U>
+  interfaces: I<int>
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    D.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.f2
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    D.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.f2
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
new file mode 100644
index 0000000..6ad21c9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.hierarchy.expect
@@ -0,0 +1,105 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: M, I<int>
+  classMembers:
+    M.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    M.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
new file mode 100644
index 0000000..c6a5468
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I<int>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
new file mode 100644
index 0000000..3b034c6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: M, I<int>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.hierarchy.expect
new file mode 100644
index 0000000..7b50101
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.hierarchy.expect
new file mode 100644
index 0000000..9f0d2f3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.hierarchy.expect
@@ -0,0 +1,76 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    D.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    E.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.hierarchy.expect
new file mode 100644
index 0000000..a0755f9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+  interfaces: C
+  classMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+  interfaceMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+  interfaces: D, C
+  classMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+  interfaceMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.x
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..a0755f9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.hierarchy.expect
@@ -0,0 +1,104 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+  interfaces: C
+  classMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+  interfaceMembers:
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+  interfaces: D, C
+  classMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+  interfaceMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.x
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..0fba878
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.hierarchy.expect
@@ -0,0 +1,76 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.hierarchy.expect
new file mode 100644
index 0000000..7a4dfeb
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.hierarchy.expect
@@ -0,0 +1,89 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.x
+
+E:
+  superclasses:
+    Object
+  interfaces: D, C
+  classMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.x
+  interfaceMembers:
+    Object.toString
+    E.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.x
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..f13de1a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.hierarchy.expect
new file mode 100644
index 0000000..840a542
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    C.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C<num>
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    D.f1
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.f2
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.hierarchy.expect
new file mode 100644
index 0000000..e4a9a22
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..0f300a8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.f
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
new file mode 100644
index 0000000..1153bca
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.hierarchy.expect
@@ -0,0 +1,91 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: B<num>
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+  interfaceMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
new file mode 100644
index 0000000..389c831
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.hierarchy.expect
@@ -0,0 +1,100 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    B._x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.g
+    B.check
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B._x
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    I.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I<num>
+  classMembers:
+    B.f
+    Object.toString
+    B._x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.g
+    B.check
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B._x
+  interfaceMembers:
+    B.f
+    Object.toString
+    B._x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    B.g
+    B.check
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B._x
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
new file mode 100644
index 0000000..c6a5468
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I<int>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.hierarchy.expect
new file mode 100644
index 0000000..be3c79b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.hierarchy.expect
@@ -0,0 +1,111 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
+    C.x
+
+D:
+  superclasses:
+    Object
+  interfaces: C<num>
+  classMembers:
+    D.y
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.y
+    D.x
+  interfaceMembers:
+    D.y
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.y
+    D.x
+
+E:
+  superclasses:
+    Object
+  interfaces: C<num>
+  classMembers:
+    E.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    E.y
+    E.x
+  interfaceMembers:
+    E.y
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    E.y
+    E.x
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.hierarchy.expect
new file mode 100644
index 0000000..11d6411
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.hierarchy.expect
@@ -0,0 +1,107 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.x
+
+B:
+  superclasses:
+    Object
+  interfaces: A
+  classMembers:
+    B.f
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+  interfaceMembers:
+    B.f
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+  interfaces: B, A
+  classMembers:
+    C.f
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+  interfaceMembers:
+    C.f
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..ba00015
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.hierarchy.expect
new file mode 100644
index 0000000..ffdc90c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.b
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.b
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
new file mode 100644
index 0000000..c844506
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I<num>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.hierarchy.expect
new file mode 100644
index 0000000..9928ab6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.g1
+    Object._instanceOf
+    C.g2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g4
+    Object._simpleInstanceOfFalse
+    C.g3
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+      -> C<int>
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.g1
+    Object._instanceOf
+    C.g2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g4
+    Object._simpleInstanceOfFalse
+    C.g3
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+E:
+  superclasses:
+    Object
+      -> C<num>
+  interfaces:
+  classMembers:
+    E.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.g1
+    Object._instanceOf
+    C.g2
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.g4
+    Object._simpleInstanceOfFalse
+    C.g3
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.hierarchy.expect
new file mode 100644
index 0000000..5275de2
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.y
+    C.[]=
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.hierarchy.expect
new file mode 100644
index 0000000..d44831f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.plusResult
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+D:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    D.value
+    D.getValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    D.setValue
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.value
+    D.setValue
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
index d811656..4e19f32 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:49:41: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
@@ -9,8 +11,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
 //     d.value /*@checkReturn=(num) -> num*/ += 1;
 //                                           ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
index 8b14a49..4e19f32 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
@@ -1,4 +1,17 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:49:41: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
+//   d.value /*@checkReturn=(num) -> num*/ += 1;
+//                                         ^
+//
+// pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:53:43: Error: A value of type 'num Function(num)' can't be assigned to a variable of type 'int Function(int)'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int Function(int)'.
+//     d.value /*@checkReturn=(num) -> num*/ += 1;
+//                                           ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.hierarchy.expect
new file mode 100644
index 0000000..b777652
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
index 1cba00a..8b146df 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:49: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
 //  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
@@ -23,8 +25,7 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
 //   var z = c. /*@checkReturn=B<(num) -> void>*/ x ??= new B<num>();
 //                                                          ^
-
-library test;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
index b7a05a6..4f445ca 100644
--- a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
@@ -1,4 +1,31 @@
 library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:20:49: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+//  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+//   c. /*@checkReturn=B<(num) -> void>*/ x += new B<num>();
+//                                                 ^
+//
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:57: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+//  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+//   var y = c. /*@checkReturn=B<(num) -> void>*/ x += new B<num>();
+//                                                         ^
+//
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:50: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+//  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+//   c. /*@checkReturn=B<(num) -> void>*/ x ??= new B<num>();
+//                                                  ^
+//
+// pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:58: Error: A value of type 'B<num>' can't be assigned to a variable of type 'B<void Function(num)>'.
+//  - 'B' is from 'pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart'.
+// Try changing the type of the left hand side, or casting the right hand side to 'B<void Function(num)>'.
+//   var z = c. /*@checkReturn=B<(num) -> void>*/ x ??= new B<num>();
+//                                                          ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.hierarchy.expect
new file mode 100644
index 0000000..b854250
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.hierarchy.expect
@@ -0,0 +1,56 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.+
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.hierarchy.expect
new file mode 100644
index 0000000..946de54
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.[]
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.hierarchy.expect
new file mode 100644
index 0000000..e5581ef
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.hierarchy.expect
@@ -0,0 +1,60 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.h
+    Object.hashCode
+    B.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<int>
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    B.h
+    Object.hashCode
+    B.g
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.hierarchy.expect
new file mode 100644
index 0000000..6a9568c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.hierarchy.expect
@@ -0,0 +1,58 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+      -> B<num>
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
new file mode 100644
index 0000000..d6381e8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.hierarchy.expect
@@ -0,0 +1,91 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: B
+  classMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
+  interfaceMembers:
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.hierarchy.expect
new file mode 100644
index 0000000..deb6bc8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.hierarchy.expect
@@ -0,0 +1,43 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.staticField
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    C.instanceField
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    C.test
+  classSetters:
+    C.staticSetter
+    C.staticField
+    C.instanceSetter
+    C.instanceField
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..7b54720
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.hierarchy.expect
@@ -0,0 +1,114 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    B.x
+
+C:
+  superclasses:
+    Object
+  interfaces: B<num>
+  classMembers:
+    C.y
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.y
+    C.x
+  interfaceMembers:
+    C.y
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    C.y
+    C.x
+
+D:
+  superclasses:
+    Object
+  interfaces: B<T>
+  classMembers:
+    D.y
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    D.y
+    D.x
+  interfaceMembers:
+    D.y
+    Object.toString
+    D.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    D.y
+    D.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.hierarchy.expect
new file mode 100644
index 0000000..92c8c0c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.hierarchy.expect
@@ -0,0 +1,40 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.staticValue
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.instanceValue
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.staticValue
+    C.instanceValue
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
new file mode 100644
index 0000000..94c8b5c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.hierarchy.expect
@@ -0,0 +1,120 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    B.x
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.y
+    Object.toString
+    I.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I.y
+    I.x
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.y
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.y
+    M.x
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: M, I<int>
+  classMembers:
+    M.y
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.y
+    M.x
+  interfaceMembers:
+    M.y
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.y
+    M.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
index 70f2971..61b9f49 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:48:7: Error: The return type of the method 'M.y' is 'int', which does not match the return type of the overridden method, 'Object'.
 //  - 'Object' is from 'dart:core'.
@@ -11,16 +13,7 @@
 // pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:54:5: Context: Override was introduced in the mixin application class 'C'.
 //     C = B with M implements I<int>;
 //     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart:48:7: Error: The return type of the method 'M.y' is 'int', which does not match the return type of the overridden method, 'Object'.
-//  - 'Object' is from 'dart:core'.
-// Change to a subtype of 'Object'.
-//   int y;
-//       ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.hierarchy.expect
new file mode 100644
index 0000000..e32d429
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.hierarchy.expect
@@ -0,0 +1,150 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.x
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    I.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I.x
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.f
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.x
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: M<F<T>>, I<T>
+  classMembers:
+    M.f
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.x
+  interfaceMembers:
+    M.f
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.x
+
+D:
+  superclasses:
+    Object
+      -> B
+        -> C<int>
+  interfaces: M<F<T>>, I<T>
+  classMembers:
+    D.f
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.x
+  interfaceMembers:
+    D.f
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.strong.expect
index 45084df..b92f411 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart:39:9: Error: The return type of the method 'M.x' is 'void Function(T)', which does not match the return type of the overridden method, 'void Function(int)'.
 // Change to a subtype of 'void Function(int)'.
@@ -10,15 +12,7 @@
 // pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart:47:16: Context: Override was introduced in the mixin application class 'C'.
 // abstract class C<T> = B with M<F<T>> implements I<T>;
 //                ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart:39:9: Error: The return type of the method 'M.x' is 'void Function(T)', which does not match the return type of the overridden method, 'void Function(int)'.
-// Change to a subtype of 'void Function(int)'.
-//   T get x => f();
-//         ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..94c8b5c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.hierarchy.expect
@@ -0,0 +1,120 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.y
+    Object.toString
+    B.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    B.y
+    B.x
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.y
+    Object.toString
+    I.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    I.y
+    I.x
+
+M:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    M.y
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.y
+    M.x
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: M, I<int>
+  classMembers:
+    M.y
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    M.y
+    M.x
+  interfaceMembers:
+    M.y
+    Object.toString
+    M.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+    M.y
+    M.x
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
index 92e6517..47119ca 100644
--- a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library test;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:53:18: Error: The parameter 'value' of the method 'M.y' has type 'int', which does not match the corresponding type in the overridden method, 'Object'.
 //  - 'Object' is from 'dart:core'.
@@ -11,16 +13,7 @@
 // pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:61:5: Context: Override was introduced in the mixin application class 'C'.
 //     C = B with M implements I<int>;
 //     ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart:53:18: Error: The parameter 'value' of the method 'M.y' has type 'int', which does not match the corresponding type in the overridden method, 'Object'.
-//  - 'Object' is from 'dart:core'.
-// Change to a supertype of 'Object', or, for a covariant parameter, a subtype.
-//   void set y(int value) {
-//                  ^
-
-library test;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
new file mode 100644
index 0000000..5459bc4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_contravariant_from_class.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_contravariant_from_class.dart.hierarchy.expect
new file mode 100644
index 0000000..6f7dc10
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_contravariant_from_class.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<F<T>>
+  interfaces: I<F<T>>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.hierarchy.expect
new file mode 100644
index 0000000..6f7dc10
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<F<T>>
+  interfaces: I<F<T>>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..c6a5468
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I<int>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
new file mode 100644
index 0000000..2defd9d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<int>
+  interfaces: I
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantInterface_from_class.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantInterface_from_class.dart.hierarchy.expect
new file mode 100644
index 0000000..86cc21b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantInterface_from_class.dart.hierarchy.expect
@@ -0,0 +1,131 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    A.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces: A<F<T>>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces: A<F<T>>
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+C:
+  superclasses:
+    Object
+      -> B<F<T>>
+  interfaces: A<F<F<T>>>, I<F<T>>
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
new file mode 100644
index 0000000..5459bc4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
new file mode 100644
index 0000000..5459bc4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.hierarchy.expect
@@ -0,0 +1,87 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    I.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: I
+  classMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    B.f
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart b/pkg/front_end/testcases/sdk_diagnostic.dart
new file mode 100644
index 0000000..f8f4723
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.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.
+
+class C extends Iterable<Object> {
+  // Missing implementation of [iterator] leads to diagnostic which refers to
+  // the SDK. This test is intended to test that such references are displayed
+  // correctly.
+}
+
+test() {
+  print(incorrectArgument: "fisk");
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.hierarchy.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.hierarchy.expect
new file mode 100644
index 0000000..e93765a
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.hierarchy.expect
@@ -0,0 +1,115 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Iterable:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Iterable.iterator
+    Iterable.map
+    Iterable.cast
+    Iterable.skip
+    Iterable.join
+    Iterable.toSet
+    Iterable.toString
+    Iterable.forEach
+    Iterable.length
+    Iterable.firstWhere
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Iterable.isEmpty
+    Iterable.take
+    Iterable.any
+    Iterable.isNotEmpty
+    Iterable.whereType
+    Iterable.where
+    Object._instanceOf
+    Iterable.skipWhile
+    Iterable.castFrom
+    Iterable.toList
+    Object.noSuchMethod
+    Iterable.fold
+    Iterable.elementAt
+    Iterable.expand
+    Iterable.takeWhile
+    Iterable.first
+    Object._identityHashCode
+    Object.hashCode
+    Iterable.reduce
+    Iterable.lastWhere
+    Iterable.last
+    Object._simpleInstanceOfFalse
+    Iterable.single
+    Iterable.every
+    Iterable.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Iterable.followedBy
+    Iterable.singleWhere
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> Iterable<Object>
+  interfaces:
+  classMembers:
+    Iterable.iterator
+    Iterable.map
+    Iterable.cast
+    Iterable.skip
+    Iterable.join
+    Iterable.toSet
+    Iterable.toString
+    Iterable.forEach
+    Iterable.length
+    Iterable.firstWhere
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Iterable.isEmpty
+    Iterable.take
+    Iterable.any
+    Iterable.isNotEmpty
+    Iterable.whereType
+    Iterable.where
+    Object._instanceOf
+    Iterable.skipWhile
+    Iterable.toList
+    Object.noSuchMethod
+    Iterable.fold
+    Iterable.elementAt
+    Iterable.expand
+    Iterable.takeWhile
+    Iterable.first
+    Object._identityHashCode
+    Object.hashCode
+    Iterable.reduce
+    Iterable.lastWhere
+    Iterable.last
+    Object._simpleInstanceOfFalse
+    Iterable.single
+    Iterable.every
+    Iterable.contains
+    Object._simpleInstanceOfTrue
+    Object.==
+    Iterable.followedBy
+    Iterable.singleWhere
+  classSetters:
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect
new file mode 100644
index 0000000..15c2801
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.expect
@@ -0,0 +1,37 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
+//  - Iterable.iterator
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C extends Iterable<Object> {
+//       ^
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Warning: Too few positional arguments: 1 required, 0 given.
+//   print(incorrectArgument: "fisk");
+//        ^
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// void print(Object object) {
+//      ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Iterable<core::Object> {
+  synthetic constructor •() → self::C
+    : super core::Iterable::•()
+    ;
+}
+static method test() → dynamic {
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#print, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#incorrectArgument: "fisk"})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect
new file mode 100644
index 0000000..15c2801
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.legacy.transformed.expect
@@ -0,0 +1,37 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
+//  - Iterable.iterator
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C extends Iterable<Object> {
+//       ^
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Warning: Too few positional arguments: 1 required, 0 given.
+//   print(incorrectArgument: "fisk");
+//        ^
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// void print(Object object) {
+//      ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Iterable<core::Object> {
+  synthetic constructor •() → self::C
+    : super core::Iterable::•()
+    ;
+}
+static method test() → dynamic {
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#print, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(<core::Symbol, dynamic>{#incorrectArgument: "fisk"})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect
new file mode 100644
index 0000000..a472835
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
+//  - Iterable.iterator
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C extends Iterable<Object> {
+//       ^
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Iterable<core::Object> {
+  synthetic constructor •() → self::C
+    ;
+}
+static method test() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect
new file mode 100644
index 0000000..eb45ae6
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
+//  - Iterable.iterator
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C extends Iterable<Object> {
+//       ^
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
+//   print(incorrectArgument: "fisk");
+//        ^
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// void print(Object object) {
+//      ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Iterable<core::Object> {
+  synthetic constructor •() → self::C
+    : super core::Iterable::•()
+    ;
+}
+static method test() → dynamic {
+  invalid-expression "pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
+  print(incorrectArgument: \"fisk\");
+       ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect
new file mode 100644
index 0000000..eb45ae6
--- /dev/null
+++ b/pkg/front_end/testcases/sdk_diagnostic.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:5:7: Error: The non-abstract class 'C' is missing implementations for these members:
+//  - Iterable.iterator
+// Try to either
+//  - provide an implementation,
+//  - inherit an implementation from a superclass or mixin,
+//  - mark the class as abstract, or
+//  - provide a 'noSuchMethod' implementation.
+//
+// class C extends Iterable<Object> {
+//       ^
+// sdk/lib/core/iterable.dart:154:19: Context: 'Iterable.iterator' is defined here.
+//   Iterator<E> get iterator;
+//                   ^^^^^^^^
+//
+// pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
+//   print(incorrectArgument: "fisk");
+//        ^
+// sdk/lib/core/print.dart:8:6: Context: Found this candidate, but the arguments don't match.
+// void print(Object object) {
+//      ^^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Iterable<core::Object> {
+  synthetic constructor •() → self::C
+    : super core::Iterable::•()
+    ;
+}
+static method test() → dynamic {
+  invalid-expression "pkg/front_end/testcases/sdk_diagnostic.dart:12:8: Error: Too few positional arguments: 1 required, 0 given.
+  print(incorrectArgument: \"fisk\");
+       ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.expect
index 932c7ea..08f59f7 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.expect
@@ -4,6 +4,9 @@
 import "dart:collection" as col;
 import "dart:async" as asy;
 
+import "dart:async";
+import "dart:collection";
+
 static method main() → dynamic async {
   core::Map<core::int, core::bool> m = <dynamic, dynamic>{};
   core::Set<core::int> s = <dynamic, dynamic>{};
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.transformed.expect
index 7ed15e3..192875a 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.legacy.transformed.expect
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:async";
+import "dart:collection";
+
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.outline.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.outline.expect
index 4c67211..3267afb 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.outline.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.outline.expect
@@ -4,6 +4,9 @@
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:async";
+import "dart:collection";
+
 static method main() → dynamic
   ;
 static method mapfun() → asy::Future<core::Map<core::int, core::bool>>
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 e5e3a65..2e3dd40 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
@@ -1,4 +1,13 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:13:28: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+//  - '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.
+//   LinkedHashSet<int> lhs = {};
+//                            ^
 //
 // pkg/front_end/testcases/set_literals/disambiguation_rule.dart:14:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
 //  - 'Map' is from 'dart:core'.
@@ -7,6 +16,13 @@
 //   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>'.
+//  - '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>'.
 //  - 'Map' is from 'dart:core'.
 //  - 'LinkedHashMap' is from 'dart:collection'.
@@ -29,19 +45,26 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashMap<int, bool>>'.
 // FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
 //                                                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:collection" as col;
 import "dart:async" as asy;
 
+import "dart:async";
+import "dart:collection";
+
 static method main() → dynamic async {
   core::Map<core::int, core::bool> m = <core::int, core::bool>{};
   core::Set<core::int> s = let final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>() in #t1;
   core::Iterable<core::int> i = let final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>() in #t2;
-  col::LinkedHashSet<core::int> lhs = (let final core::Set<dynamic> #t3 = col::LinkedHashSet::•<dynamic>() in #t3) as{TypeError} col::LinkedHashSet<core::int>;
-  col::LinkedHashMap<core::int, core::bool> lhm = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:14:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+  col::LinkedHashSet<core::int> lhs = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:13:28: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+ - '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.
+  LinkedHashSet<int> lhs = {};
+                           ^" in let final core::Set<dynamic> #t4 = col::LinkedHashSet::•<dynamic>() in #t4;
+  col::LinkedHashMap<core::int, core::bool> lhm = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:14:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
  - '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.
@@ -61,13 +84,18 @@
 static method mapfun() → asy::Future<core::Map<core::int, core::bool>> async 
   return <core::int, core::bool>{};
 static method setfun() → asy::Future<core::Set<core::int>> async 
-  return let final core::Set<core::int> #t5 = col::LinkedHashSet::•<core::int>() in #t5;
-static method iterablefun() → asy::Future<core::Iterable<core::int>> async 
   return let final core::Set<core::int> #t6 = col::LinkedHashSet::•<core::int>() in #t6;
+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 core::Set<dynamic> #t7 = col::LinkedHashSet::•<dynamic>() in #t7) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int>>;
+  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>'.
+ - '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> #t8 = 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 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
  - '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.
@@ -76,19 +104,19 @@
 static method mapfun2() → asy::FutureOr<core::Map<core::int, core::bool>>
   return <core::int, core::bool>{};
 static method setfun2() → asy::FutureOr<core::Set<core::int>>
-  return let final core::Set<core::int> #t9 = col::LinkedHashSet::•<core::int>() in #t9;
+  return let final core::Set<core::int> #t11 = col::LinkedHashSet::•<core::int>() in #t11;
 static method iterablefun2() → asy::FutureOr<core::Iterable<core::int>>
-  return let final core::Set<core::int> #t10 = col::LinkedHashSet::•<core::int>() in #t10;
+  return let final core::Set<core::int> #t12 = col::LinkedHashSet::•<core::int>() in #t12;
 static method lhsfun2() → asy::FutureOr<col::LinkedHashSet<core::int>>
-  return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:38:43: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashSet<int>>'.
+  return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:38:43: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashSet<int>>'.
  - 'Set' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashSet' is from 'dart:collection'.
 Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
 FutureOr<LinkedHashSet<int>> lhsfun2() => {};
-                                          ^" in (let final core::Set<dynamic> #t12 = col::LinkedHashSet::•<dynamic>() in #t12) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int>>;
+                                          ^" in (let final core::Set<dynamic> #t14 = col::LinkedHashSet::•<dynamic>() in #t14) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int>>;
 static method lhmfun2() → asy::FutureOr<col::LinkedHashMap<core::int, core::bool>>
-  return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:39:49: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashMap<int, bool>>'.
+  return let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:39:49: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashMap<int, bool>>'.
  - 'Map' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashMap' is from 'dart:collection'.
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 9b60cf8..072636a 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
@@ -1,9 +1,59 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:13:28: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+//  - '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.
+//   LinkedHashSet<int> lhs = {};
+//                            ^
+//
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:14:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+//  - '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.
+//   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>'.
+//  - '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>'.
+//  - '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.
+// Future<LinkedHashMap<int, bool>> lhmfun() async => {};
+//                                                    ^
+//
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:38:43: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashSet<int>>'.
+//  - 'Set' is from 'dart:core'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'LinkedHashSet' is from 'dart:collection'.
+// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
+// FutureOr<LinkedHashSet<int>> lhsfun2() => {};
+//                                           ^
+//
+// pkg/front_end/testcases/set_literals/disambiguation_rule.dart:39:49: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashMap<int, bool>>'.
+//  - 'Map' is from 'dart:core'.
+//  - 'FutureOr' is from 'dart:async'.
+//  - 'LinkedHashMap' is from 'dart:collection'.
+// Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashMap<int, bool>>'.
+// FutureOr<LinkedHashMap<int, bool>> lhmfun2() => {};
+//                                                 ^
+//
 import self as self;
 import "dart:async" as asy;
 import "dart:core" as core;
 import "dart:collection" as col;
 
+import "dart:async";
+import "dart:collection";
+
 static method main() → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
   asy::FutureOr<dynamic> :return_value;
@@ -20,32 +70,37 @@
         core::Map<core::int, core::bool> m = <core::int, core::bool>{};
         core::Set<core::int> s = let final core::Set<core::int> #t1 = col::LinkedHashSet::•<core::int>() in #t1;
         core::Iterable<core::int> i = let final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>() in #t2;
-        col::LinkedHashSet<core::int> lhs = (let final core::Set<dynamic> #t3 = col::LinkedHashSet::•<dynamic>() in #t3) as{TypeError} col::LinkedHashSet<core::int>;
-        col::LinkedHashMap<core::int, core::bool> lhm = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:14:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
+        col::LinkedHashSet<core::int> lhs = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:13:28: Error: The set literal type 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+ - '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.
+  LinkedHashSet<int> lhs = {};
+                           ^" in let final core::Set<dynamic> #t4 = col::LinkedHashSet::•<dynamic>() in #t4;
+        col::LinkedHashMap<core::int, core::bool> lhm = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:14:34: Error: The map literal type 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
  - '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.
   LinkedHashMap<int, bool> lhm = {};
                                  ^" in <dynamic, dynamic>{};
-        [yield] let dynamic #t5 = asy::_awaitHelper(self::mapfun(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t6 = asy::_awaitHelper(self::mapfun(), :async_op_then, :async_op_error, :async_op) in null;
         core::Map<core::int, core::bool> fm = :result;
-        [yield] let dynamic #t6 = asy::_awaitHelper(self::setfun(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t7 = asy::_awaitHelper(self::setfun(), :async_op_then, :async_op_error, :async_op) in null;
         core::Set<core::int> fs = :result;
-        [yield] let dynamic #t7 = asy::_awaitHelper(self::iterablefun(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t8 = asy::_awaitHelper(self::iterablefun(), :async_op_then, :async_op_error, :async_op) in null;
         core::Iterable<core::int> fi = :result;
-        [yield] let dynamic #t8 = asy::_awaitHelper(self::lhsfun(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t9 = asy::_awaitHelper(self::lhsfun(), :async_op_then, :async_op_error, :async_op) in null;
         col::LinkedHashSet<core::int> flhs = :result;
-        [yield] let dynamic #t9 = asy::_awaitHelper(self::lhmfun(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t10 = asy::_awaitHelper(self::lhmfun(), :async_op_then, :async_op_error, :async_op) in null;
         col::LinkedHashMap<core::int, core::bool> flhm = :result;
-        [yield] let dynamic #t10 = asy::_awaitHelper(self::mapfun2(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t11 = asy::_awaitHelper(self::mapfun2(), :async_op_then, :async_op_error, :async_op) in null;
         core::Map<core::int, core::bool> fm2 = :result;
-        [yield] let dynamic #t11 = asy::_awaitHelper(self::setfun2(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t12 = asy::_awaitHelper(self::setfun2(), :async_op_then, :async_op_error, :async_op) in null;
         core::Set<core::int> fs2 = :result;
-        [yield] let dynamic #t12 = asy::_awaitHelper(self::iterablefun2(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t13 = asy::_awaitHelper(self::iterablefun2(), :async_op_then, :async_op_error, :async_op) in null;
         core::Iterable<core::int> fi2 = :result;
-        [yield] let dynamic #t13 = asy::_awaitHelper(self::lhsfun2(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t14 = asy::_awaitHelper(self::lhsfun2(), :async_op_then, :async_op_error, :async_op) in null;
         col::LinkedHashSet<core::int> flhs2 = :result;
-        [yield] let dynamic #t14 = asy::_awaitHelper(self::lhmfun2(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t15 = asy::_awaitHelper(self::lhmfun2(), :async_op_then, :async_op_error, :async_op) in null;
         col::LinkedHashMap<core::int, core::bool> flhm2 = :result;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -99,7 +154,7 @@
     try {
       #L3:
       {
-        :return_value = let final core::Set<core::int> #t15 = col::LinkedHashSet::•<core::int>() in #t15;
+        :return_value = let final core::Set<core::int> #t16 = col::LinkedHashSet::•<core::int>() in #t16;
         break #L3;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -126,7 +181,7 @@
     try {
       #L4:
       {
-        :return_value = let final core::Set<core::int> #t16 = col::LinkedHashSet::•<core::int>() in #t16;
+        :return_value = let final core::Set<core::int> #t17 = col::LinkedHashSet::•<core::int>() in #t17;
         break #L4;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -153,7 +208,12 @@
     try {
       #L5:
       {
-        :return_value = (let final core::Set<dynamic> #t17 = col::LinkedHashSet::•<dynamic>() in #t17) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::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 'Set<dynamic>' isn't of expected type 'LinkedHashSet<int>'.
+ - '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> #t19 = col::LinkedHashSet::•<dynamic>() in #t19;
         break #L5;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
@@ -180,7 +240,7 @@
     try {
       #L6:
       {
-        :return_value = let final<BottomType> #t18 = 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 'Map<dynamic, dynamic>' isn't of expected type 'LinkedHashMap<int, bool>'.
  - '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.
@@ -203,19 +263,19 @@
 static method mapfun2() → asy::FutureOr<core::Map<core::int, core::bool>>
   return <core::int, core::bool>{};
 static method setfun2() → asy::FutureOr<core::Set<core::int>>
-  return let final core::Set<core::int> #t19 = col::LinkedHashSet::•<core::int>() in #t19;
+  return let final core::Set<core::int> #t21 = col::LinkedHashSet::•<core::int>() in #t21;
 static method iterablefun2() → asy::FutureOr<core::Iterable<core::int>>
-  return let final core::Set<core::int> #t20 = col::LinkedHashSet::•<core::int>() in #t20;
+  return let final core::Set<core::int> #t22 = col::LinkedHashSet::•<core::int>() in #t22;
 static method lhsfun2() → asy::FutureOr<col::LinkedHashSet<core::int>>
-  return let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:38:43: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashSet<int>>'.
+  return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:38:43: Error: A value of type 'Set<dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashSet<int>>'.
  - 'Set' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashSet' is from 'dart:collection'.
 Try changing the type of the left hand side, or casting the right hand side to 'FutureOr<LinkedHashSet<int>>'.
 FutureOr<LinkedHashSet<int>> lhsfun2() => {};
-                                          ^" in (let final core::Set<dynamic> #t22 = col::LinkedHashSet::•<dynamic>() in #t22) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int>>;
+                                          ^" in (let final core::Set<dynamic> #t24 = col::LinkedHashSet::•<dynamic>() in #t24) as{TypeError} asy::FutureOr<col::LinkedHashSet<core::int>>;
 static method lhmfun2() → asy::FutureOr<col::LinkedHashMap<core::int, core::bool>>
-  return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:39:49: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashMap<int, bool>>'.
+  return let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:39:49: Error: A value of type 'Map<dynamic, dynamic>' can't be assigned to a variable of type 'FutureOr<LinkedHashMap<int, bool>>'.
  - 'Map' is from 'dart:core'.
  - 'FutureOr' is from 'dart:async'.
  - 'LinkedHashMap' is from 'dart:collection'.
diff --git a/pkg/front_end/testcases/spread_collection.dart b/pkg/front_end/testcases/spread_collection.dart
new file mode 100644
index 0000000..333331b
--- /dev/null
+++ b/pkg/front_end/testcases/spread_collection.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.
+
+main() {
+  final aList = <int>[1, ...[2], ...?[3]];
+  final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+  final aSet = <int>{1, ...[2], ...?[3]};
+  final aSetOrMap = {...foo()};
+
+  print(aList);
+  print(aSet);
+  print(aMap);
+}
+
+foo() => null;
\ No newline at end of file
diff --git a/pkg/front_end/testcases/spread_collection.dart.legacy.expect b/pkg/front_end/testcases/spread_collection.dart.legacy.expect
new file mode 100644
index 0000000..e6445d9
--- /dev/null
+++ b/pkg/front_end/testcases/spread_collection.dart.legacy.expect
@@ -0,0 +1,46 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/spread_collection.dart:6:26: Error: Unexpected token '...'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                          ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:34: Error: Unexpected token '...?'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                                  ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:33: Error: Unexpected token '...'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                 ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:44: Error: Unexpected token '...?'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                            ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:25: Error: Unexpected token '...'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                         ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:33: Error: Unexpected token '...?'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                                 ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:9:22: Error: Unexpected token '...'.
+//   final aSetOrMap = {...foo()};
+//                      ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  final dynamic aList = <core::int>[1, <dynamic>[2], <dynamic>[3]];
+  final dynamic aMap = <core::int, core::int>{1: 1};
+  final dynamic aSet = <core::int>{1, <dynamic>[2], <dynamic>[3]};
+  final dynamic aSetOrMap = <dynamic, dynamic>{};
+  core::print(aList);
+  core::print(aSet);
+  core::print(aMap);
+}
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/spread_collection.dart.legacy.transformed.expect b/pkg/front_end/testcases/spread_collection.dart.legacy.transformed.expect
new file mode 100644
index 0000000..e6445d9
--- /dev/null
+++ b/pkg/front_end/testcases/spread_collection.dart.legacy.transformed.expect
@@ -0,0 +1,46 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/spread_collection.dart:6:26: Error: Unexpected token '...'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                          ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:34: Error: Unexpected token '...?'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                                  ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:33: Error: Unexpected token '...'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                 ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:44: Error: Unexpected token '...?'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                            ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:25: Error: Unexpected token '...'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                         ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:33: Error: Unexpected token '...?'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                                 ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:9:22: Error: Unexpected token '...'.
+//   final aSetOrMap = {...foo()};
+//                      ^^^
+//
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  final dynamic aList = <core::int>[1, <dynamic>[2], <dynamic>[3]];
+  final dynamic aMap = <core::int, core::int>{1: 1};
+  final dynamic aSet = <core::int>{1, <dynamic>[2], <dynamic>[3]};
+  final dynamic aSetOrMap = <dynamic, dynamic>{};
+  core::print(aList);
+  core::print(aSet);
+  core::print(aMap);
+}
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/spread_collection.dart.outline.expect b/pkg/front_end/testcases/spread_collection.dart.outline.expect
new file mode 100644
index 0000000..4c2eb20
--- /dev/null
+++ b/pkg/front_end/testcases/spread_collection.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method foo() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/spread_collection.dart.strong.expect b/pkg/front_end/testcases/spread_collection.dart.strong.expect
new file mode 100644
index 0000000..8721adb
--- /dev/null
+++ b/pkg/front_end/testcases/spread_collection.dart.strong.expect
@@ -0,0 +1,87 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/spread_collection.dart:6:26: Error: Unexpected token '...'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                          ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:34: Error: Unexpected token '...?'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                                  ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:33: Error: Unexpected token '...'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                 ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:44: Error: Unexpected token '...?'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                            ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:25: Error: Unexpected token '...'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                         ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:33: Error: Unexpected token '...?'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                                 ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:9:22: Error: Unexpected token '...'.
+//   final aSetOrMap = {...foo()};
+//                      ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:29: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                             ^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:38: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                                      ^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:28: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                            ^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:37: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                                     ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+static method main() → dynamic {
+  final core::List<core::int> aList = <core::int>[1, let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:6:29: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aList = <int>[1, ...[2], ...?[3]];
+                            ^" in <core::int>[2] as{TypeError} core::int, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:6:38: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aList = <int>[1, ...[2], ...?[3]];
+                                     ^" in <core::int>[3] as{TypeError} core::int];
+  final core::Map<core::int, core::int> aMap = <core::int, core::int>{1: 1};
+  final core::Set<core::int> aSet = let final core::Set<core::int> #t3 = col::LinkedHashSet::•<core::int>() in let final dynamic #t4 = #t3.{core::Set::add}(1) in let final dynamic #t5 = #t3.{core::Set::add}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:8:28: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aSet = <int>{1, ...[2], ...?[3]};
+                           ^" in <core::int>[2] as{TypeError} core::int) in let final dynamic #t7 = #t3.{core::Set::add}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:8:37: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aSet = <int>{1, ...[2], ...?[3]};
+                                    ^" in <core::int>[3] as{TypeError} core::int) in #t3;
+  final core::Map<dynamic, dynamic> aSetOrMap = <dynamic, dynamic>{};
+  core::print(aList);
+  core::print(aSet);
+  core::print(aMap);
+}
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect
new file mode 100644
index 0000000..6ee5ecf
--- /dev/null
+++ b/pkg/front_end/testcases/spread_collection.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/spread_collection.dart:6:26: Error: Unexpected token '...'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                          ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:34: Error: Unexpected token '...?'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                                  ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:33: Error: Unexpected token '...'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                 ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:7:44: Error: Unexpected token '...?'.
+//   final aMap = <int, int>{1: 1, ...{2: 2}, ...?{3: 3}};
+//                                            ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:25: Error: Unexpected token '...'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                         ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:33: Error: Unexpected token '...?'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                                 ^^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:9:22: Error: Unexpected token '...'.
+//   final aSetOrMap = {...foo()};
+//                      ^^^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:29: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                             ^
+//
+// pkg/front_end/testcases/spread_collection.dart:6:38: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aList = <int>[1, ...[2], ...?[3]];
+//                                      ^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:28: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                            ^
+//
+// pkg/front_end/testcases/spread_collection.dart:8:37: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+//  - 'List' is from 'dart:core'.
+// Try changing the type of the left hand side, or casting the right hand side to 'int'.
+//   final aSet = <int>{1, ...[2], ...?[3]};
+//                                     ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+static method main() → dynamic {
+  final core::List<core::int> aList = <core::int>[1, let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:6:29: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aList = <int>[1, ...[2], ...?[3]];
+                            ^" in <core::int>[2] as{TypeError} core::int, let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:6:38: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aList = <int>[1, ...[2], ...?[3]];
+                                     ^" in <core::int>[3] as{TypeError} core::int];
+  final core::Map<core::int, core::int> aMap = <core::int, core::int>{1: 1};
+  final core::Set<core::int> aSet = let final core::Set<core::int> #t3 = col::LinkedHashSet::•<core::int>() in let final core::bool #t4 = #t3.{core::Set::add}(1) in let final core::bool #t5 = #t3.{core::Set::add}(let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:8:28: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aSet = <int>{1, ...[2], ...?[3]};
+                           ^" in <core::int>[2] as{TypeError} core::int) in let final core::bool #t7 = #t3.{core::Set::add}(let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/spread_collection.dart:8:37: Error: A value of type 'List<int>' can't be assigned to a variable of type 'int'.
+ - 'List' is from 'dart:core'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  final aSet = <int>{1, ...[2], ...?[3]};
+                                    ^" in <core::int>[3] as{TypeError} core::int) in #t3;
+  final core::Map<dynamic, dynamic> aSetOrMap = <dynamic, dynamic>{};
+  core::print(aList);
+  core::print(aSet);
+  core::print(aMap);
+}
+static method foo() → dynamic
+  return null;
diff --git a/pkg/front_end/testcases/statements.dart.legacy.expect b/pkg/front_end/testcases/statements.dart.legacy.expect
index 533d647..412bb2d 100644
--- a/pkg/front_end/testcases/statements.dart.legacy.expect
+++ b/pkg/front_end/testcases/statements.dart.legacy.expect
@@ -1,24 +1,15 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/statements.dart:15:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
-//     yield x;
-//     ^^^^^
-//
-// pkg/front_end/testcases/statements.dart:16:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
-//     yield* x;
-//     ^^^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/statements.dart:15:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
-//     yield x;
-//     ^^^^^
-//
-// pkg/front_end/testcases/statements.dart:16:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
-//     yield* x;
-//     ^^^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/statements.dart:15:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
+//     yield x;
+//     ^^^^^
+//
+// pkg/front_end/testcases/statements.dart:16:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
+//     yield* x;
+//     ^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/statements.dart.legacy.transformed.expect b/pkg/front_end/testcases/statements.dart.legacy.transformed.expect
index 2cc8929..606cb49 100644
--- a/pkg/front_end/testcases/statements.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/statements.dart.legacy.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/statements.dart:15:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
 //     yield x;
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/statements.dart:16:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
 //     yield* x;
 //     ^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
diff --git a/pkg/front_end/testcases/statements.dart.strong.expect b/pkg/front_end/testcases/statements.dart.strong.expect
index 8a35aa2..e8366ee 100644
--- a/pkg/front_end/testcases/statements.dart.strong.expect
+++ b/pkg/front_end/testcases/statements.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/statements.dart:15:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
 //     yield x;
@@ -13,18 +15,7 @@
 //  - 'Stream' is from 'dart:async'.
 //   await for (var x in []) {
 //                       ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/statements.dart:15:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
-//     yield x;
-//     ^^^^^
-//
-// pkg/front_end/testcases/statements.dart:16:5: Error: 'yield' can only be used in 'sync*' or 'async*' methods.
-//     yield* x;
-//     ^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
diff --git a/pkg/front_end/testcases/static_setter.dart.hierarchy.expect b/pkg/front_end/testcases/static_setter.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc6110
--- /dev/null
+++ b/pkg/front_end/testcases/static_setter.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/store_load.dart.hierarchy.expect b/pkg/front_end/testcases/store_load.dart.hierarchy.expect
new file mode 100644
index 0000000..6d5caac
--- /dev/null
+++ b/pkg/front_end/testcases/store_load.dart.hierarchy.expect
@@ -0,0 +1,91 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo._field
+
+FooValue:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Bar:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Bar._field
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Bar._field
+
+BarValue:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index f42074f..1fde8dc 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -24,7 +24,6 @@
 expressions: RuntimeError
 external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
 fallthrough: ExpectationFileMismatch
-for_in_without_declaration: TypeCheckError
 incomplete_field_formal_parameter: RuntimeError
 inference/abstract_class_instantiation: InstrumentationMismatch # Issue #30040
 inference/conflicts_can_happen: TypeCheckError
@@ -148,7 +147,9 @@
 runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
 set_literals/disambiguation_rule: RuntimeError
 statements: Crash
+spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
 type_variable_as_super: RuntimeError
 type_variable_prefix: RuntimeError
+unsound_promotion: RuntimeError
 void_methods: ExpectationFileMismatch
 warn_unresolved_sends: InstrumentationMismatch # Test assumes Dart 1.0 semantics
diff --git a/pkg/front_end/testcases/super_call.dart.hierarchy.expect b/pkg/front_end/testcases/super_call.dart.hierarchy.expect
new file mode 100644
index 0000000..2bda25e
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.hierarchy.expect
@@ -0,0 +1,57 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    A.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    B.call_super
+    B.call
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/super_call.dart.legacy.expect b/pkg/front_end/testcases/super_call.dart.legacy.expect
index 0928d4f..4e4dd69 100644
--- a/pkg/front_end/testcases/super_call.dart.legacy.expect
+++ b/pkg/front_end/testcases/super_call.dart.legacy.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.
 // To delegate a constructor to a super constructor, put the super call as an initializer.
 //     return super(5);
 //            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/super_call.dart.legacy.transformed.expect b/pkg/front_end/testcases/super_call.dart.legacy.transformed.expect
index e58a60b..4e4dd69 100644
--- a/pkg/front_end/testcases/super_call.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/super_call.dart.legacy.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//     return super(5);
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/super_call.dart.strong.expect b/pkg/front_end/testcases/super_call.dart.strong.expect
index bc4395d..3342243 100644
--- a/pkg/front_end/testcases/super_call.dart.strong.expect
+++ b/pkg/front_end/testcases/super_call.dart.strong.expect
@@ -1,11 +1,12 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.
 // To delegate a constructor to a super constructor, put the super call as an initializer.
 //     return super(5);
 //            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/super_call.dart.strong.transformed.expect b/pkg/front_end/testcases/super_call.dart.strong.transformed.expect
index 0d474d7..3342243 100644
--- a/pkg/front_end/testcases/super_call.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/super_call.dart.strong.transformed.expect
@@ -1,4 +1,12 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.
+// To delegate a constructor to a super constructor, put the super call as an initializer.
+//     return super(5);
+//            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/super_nsm.dart.hierarchy.expect b/pkg/front_end/testcases/super_nsm.dart.hierarchy.expect
new file mode 100644
index 0000000..bfe9aef
--- /dev/null
+++ b/pkg/front_end/testcases/super_nsm.dart.hierarchy.expect
@@ -0,0 +1,100 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+I:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    I.interfaceMethod
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    C.noSuchMethod
+    Object._identityHashCode
+    I.interfaceMethod
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces: I
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.dMethod
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    D.noSuchMethod
+    Object._identityHashCode
+    I.interfaceMethod
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.dMethod
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/tabs.dart.legacy.expect b/pkg/front_end/testcases/tabs.dart.legacy.expect
index a304f47..7397272 100644
--- a/pkg/front_end/testcases/tabs.dart.legacy.expect
+++ b/pkg/front_end/testcases/tabs.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/tabs.dart:9:8: Warning: Getter not found: 'one'.
 // 	print(one);
@@ -19,8 +21,7 @@
 // pkg/front_end/testcases/tabs.dart:13:14: Warning: Getter not found: 'five'.
 // 	   	  print(five);
 // 	   	        ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/tabs.dart.legacy.transformed.expect b/pkg/front_end/testcases/tabs.dart.legacy.transformed.expect
index b542e17..7397272 100644
--- a/pkg/front_end/testcases/tabs.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/tabs.dart.legacy.transformed.expect
@@ -1,4 +1,27 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/tabs.dart:9:8: Warning: Getter not found: 'one'.
+// 	print(one);
+// 	      ^^^
+//
+// pkg/front_end/testcases/tabs.dart:10:9: Warning: Getter not found: 'two'.
+// 		print(two);
+// 		      ^^^
+//
+// pkg/front_end/testcases/tabs.dart:11:11: Warning: Getter not found: 'three'.
+// 		  print(three);
+// 		        ^^^^^
+//
+// pkg/front_end/testcases/tabs.dart:12:12: Warning: Getter not found: 'four'.
+// 	   	print(four);
+// 	   	      ^^^^
+//
+// pkg/front_end/testcases/tabs.dart:13:14: Warning: Getter not found: 'five'.
+// 	   	  print(five);
+// 	   	        ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/tabs.dart.strong.expect b/pkg/front_end/testcases/tabs.dart.strong.expect
index 55b8efd..d8b5c84 100644
--- a/pkg/front_end/testcases/tabs.dart.strong.expect
+++ b/pkg/front_end/testcases/tabs.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/tabs.dart:9:8: Error: Getter not found: 'one'.
 // 	print(one);
@@ -19,8 +21,7 @@
 // pkg/front_end/testcases/tabs.dart:13:14: Error: Getter not found: 'five'.
 // 	   	  print(five);
 // 	   	        ^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/tabs.dart.strong.transformed.expect b/pkg/front_end/testcases/tabs.dart.strong.transformed.expect
index 3028e07..d8b5c84 100644
--- a/pkg/front_end/testcases/tabs.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/tabs.dart.strong.transformed.expect
@@ -1,4 +1,27 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/tabs.dart:9:8: Error: Getter not found: 'one'.
+// 	print(one);
+// 	      ^^^
+//
+// pkg/front_end/testcases/tabs.dart:10:9: Error: Getter not found: 'two'.
+// 		print(two);
+// 		      ^^^
+//
+// pkg/front_end/testcases/tabs.dart:11:11: Error: Getter not found: 'three'.
+// 		  print(three);
+// 		        ^^^^^
+//
+// pkg/front_end/testcases/tabs.dart:12:12: Error: Getter not found: 'four'.
+// 	   	print(four);
+// 	   	      ^^^^
+//
+// pkg/front_end/testcases/tabs.dart:13:14: Error: Getter not found: 'five'.
+// 	   	  print(five);
+// 	   	        ^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index c4a93e2..0027189 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -8,7 +8,7 @@
 
 abstract_members: TypeCheckError
 accessors: TextSerializationFailure # Was: RuntimeError
-ambiguous_exports: TextSerializationFailure # Was: RuntimeError # Expected, this file exports two main methods.
+ambiguous_exports: RuntimeError # Expected, this file exports two main methods.
 annotation_eof: TextSerializationFailure # Was: Pass
 annotation_on_enum_values: TextSerializationFailure # Was: Pass
 annotation_top: TextSerializationFailure # Was: Pass
@@ -59,6 +59,7 @@
 clone_function_type: TextSerializationFailure # Was: Pass
 closure: TextSerializationFailure # Was: Pass
 co19_language_metadata_syntax_t04: TextSerializationFailure # Was: Pass
+complex_class_hierarchy: TextSerializationFailure
 constructor_const_inference: TextSerializationFailure # Was: Pass
 constructor_cycle: TextSerializationFailure # Was: Pass
 constructor_function_types: TextSerializationFailure # Was: Pass
@@ -91,11 +92,10 @@
 fallthrough: ExpectationFileMismatch
 fibonacci: TextSerializationFailure # Was: Pass
 for_in_scope: TextSerializationFailure # Was: Pass
-for_in_without_declaration: TypeCheckError
+for_in_without_declaration: TextSerializationFailure
 function_in_field: TextSerializationFailure # Was: Pass
 functions: TextSerializationFailure # Was: Pass
 function_type_assignments: TextSerializationFailure # Was: Pass
-function_type_default_value: TextSerializationFailure # Was: Pass
 function_type_is_check: TextSerializationFailure # Was: Pass
 function_type_recovery: TextSerializationFailure # Was: Pass
 future_or_test: TextSerializationFailure # Was: Pass
@@ -664,10 +664,13 @@
 invalid_cast: TextSerializationFailure # Was: Pass
 invalid_type: TypeCheckError
 invocations: TextSerializationFailure # Was: RuntimeError
+issue34515: TextSerializationFailure
 issue34899: TypeCheckError
+issue35875: TextSerializationFailure
 literals: TextSerializationFailure # Was: Pass
 local_generic_function: TextSerializationFailure # Was: Pass
 magic_const: TextSerializationFailure # Was: Pass
+many_errors: TextSerializationFailure
 map: TextSerializationFailure # Was: Pass
 metadata_enum: TextSerializationFailure # Was: Pass
 metadata_named_mixin_application: TextSerializationFailure # Was: Pass
@@ -675,9 +678,11 @@
 minimum_int: TextSerializationFailure # Was: Pass
 missing_constructor: TextSerializationFailure # Was: Pass
 mixin_application_override: TypeCheckError
+mixin_conflicts: TextSerializationFailure
 mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
 mixin_inherited_setter_for_mixed_in_field: TextSerializationFailure # Was: Pass
 mixin_super_repeated: TextSerializationFailure # Was: Pass
+mixin_with_static_member: TextSerializationFailure
 mixin: TextSerializationFailure # Was: Pass
 named_function_scope: TextSerializationFailure # Was: Pass
 named_parameters: TextSerializationFailure # Was: Pass
@@ -721,6 +726,10 @@
 override: TextSerializationFailure # Was: Pass
 part_as_entry_point_lib: TextSerializationFailure # Was: Pass
 part_as_entry_point: TextSerializationFailure # Was: Pass
+part_not_part_of: TextSerializationFailure
+part_not_part_of_same_named_library: TextSerializationFailure
+part_part_of_different_unnamed_library: TextSerializationFailure
+part_part_of_differently_named_library: TextSerializationFailure
 prefer_baseclass: TextSerializationFailure # Was: Pass
 private_method_tearoff_lib: TextSerializationFailure # Was: Pass
 private_method_tearoff: TextSerializationFailure # Was: Pass
@@ -777,7 +786,6 @@
 rasta/issue_000043: TextSerializationFailure # Was: RuntimeError
 rasta/issue_000044: TextSerializationFailure # Was: RuntimeError
 rasta/issue_000046: TextSerializationFailure # Was: RuntimeError
-rasta/issue_000047: TextSerializationFailure # Was: Pass
 rasta/issue_000048: TextSerializationFailure # Was: Pass
 rasta/issue_000052: TextSerializationFailure # Was: Pass
 rasta/issue_000053: TextSerializationFailure # Was: Pass
@@ -829,7 +837,6 @@
 regress/issue_29941: TextSerializationFailure # Was: Pass
 regress/issue_29942: TextSerializationFailure # Was: Pass
 regress/issue_29944: TextSerializationFailure # Was: Pass
-regress/issue_29975: TextSerializationFailure # Was: Pass
 regress/issue_29976: RuntimeError # Tests runtime behavior of error recovery.
 regress/issue_29978: TextSerializationFailure # Was: Pass
 regress/issue_29979: TextSerializationFailure # Was: Pass
@@ -847,7 +854,6 @@
 regress/issue_31183: TextSerializationFailure # Was: Pass
 regress/issue_31184: TextSerializationFailure # Was: Pass
 regress/issue_31185: TextSerializationFailure # Was: Pass
-regress/issue_31188: TextSerializationFailure # Was: Pass
 regress/issue_31190: TextSerializationFailure # Was: Pass
 regress/issue_31192: TextSerializationFailure # Was: Pass
 regress/issue_31198: TextSerializationFailure # Was: Pass
@@ -950,7 +956,9 @@
 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
+sdk_diagnostic: TextSerializationFailure
 set_literals/disambiguation_rule: TextSerializationFailure # Was: RuntimeError
+spread_collection: TextSerializationFailure # Should be fixed as part of implementing spread collection support
 statements: Crash
 static_setter: TextSerializationFailure # Was: Pass
 store_load: TextSerializationFailure # Was: Pass
@@ -962,12 +970,14 @@
 top_level_accessors: TextSerializationFailure # Was: Pass
 top_level_library_method: TextSerializationFailure # Was: Pass
 typedef: TextSerializationFailure # Was: Pass
+type_of_null: TextSerializationFailure
 type_variable_as_super: TextSerializationFailure # Was: RuntimeError
 type_variable_prefix: TextSerializationFailure # Was: RuntimeError
 type_variable_uses: TextSerializationFailure # Was: Pass
 undefined_getter_in_compound_assignment: TextSerializationFailure # Was: Pass
 undefined: TextSerializationFailure # Was: Pass
 uninitialized_fields: TextSerializationFailure # Was: Pass
+unsound_promotion: TextSerializationFailure
 unused_methods: TextSerializationFailure # Was: Pass
 var_as_type_name: TextSerializationFailure # Was: Pass
 void_methods: ExpectationFileMismatch
diff --git a/pkg/front_end/testcases/top_level_accessors.dart.legacy.expect b/pkg/front_end/testcases/top_level_accessors.dart.legacy.expect
index 35b8eac..55f39bd 100644
--- a/pkg/front_end/testcases/top_level_accessors.dart.legacy.expect
+++ b/pkg/front_end/testcases/top_level_accessors.dart.legacy.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part top_level_accessors_part.dart;
 static set /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode(core::int code) → void {
   core::print(code);
 }
diff --git a/pkg/front_end/testcases/top_level_accessors.dart.legacy.transformed.expect b/pkg/front_end/testcases/top_level_accessors.dart.legacy.transformed.expect
index 35b8eac..55f39bd 100644
--- a/pkg/front_end/testcases/top_level_accessors.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/top_level_accessors.dart.legacy.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part top_level_accessors_part.dart;
 static set /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode(core::int code) → void {
   core::print(code);
 }
diff --git a/pkg/front_end/testcases/top_level_accessors.dart.outline.expect b/pkg/front_end/testcases/top_level_accessors.dart.outline.expect
index da336ad..88e4404 100644
--- a/pkg/front_end/testcases/top_level_accessors.dart.outline.expect
+++ b/pkg/front_end/testcases/top_level_accessors.dart.outline.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part top_level_accessors_part.dart;
 static set /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode(core::int code) → void
   ;
 static get /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode() → core::int
diff --git a/pkg/front_end/testcases/top_level_accessors.dart.strong.expect b/pkg/front_end/testcases/top_level_accessors.dart.strong.expect
index 35b8eac..55f39bd 100644
--- a/pkg/front_end/testcases/top_level_accessors.dart.strong.expect
+++ b/pkg/front_end/testcases/top_level_accessors.dart.strong.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part top_level_accessors_part.dart;
 static set /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode(core::int code) → void {
   core::print(code);
 }
diff --git a/pkg/front_end/testcases/top_level_accessors.dart.strong.transformed.expect b/pkg/front_end/testcases/top_level_accessors.dart.strong.transformed.expect
index 35b8eac..55f39bd 100644
--- a/pkg/front_end/testcases/top_level_accessors.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/top_level_accessors.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
+part top_level_accessors_part.dart;
 static set /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode(core::int code) → void {
   core::print(code);
 }
diff --git a/pkg/front_end/testcases/type_of_null.dart b/pkg/front_end/testcases/type_of_null.dart
new file mode 100644
index 0000000..859c3db
--- /dev/null
+++ b/pkg/front_end/testcases/type_of_null.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.
+
+/*@testedFeatures=inference*/
+T map<T>(T Function() f1, T Function() f2) {}
+
+id<T>(T t) => t;
+
+Null foo() => null;
+
+main() {
+  /*@typeArgs=Null*/map(/*@returnType=Null*/() {}, /*@returnType=<BottomType>*/() => throw "hello");
+  /*@typeArgs=Null*/map(/*@returnType=<BottomType>*/() => throw "hello", /*@returnType=Null*/() {});
+  Null Function() f = /*@returnType=Null*/() {};
+  /*@typeArgs=Null*/map(foo, /*@returnType=<BottomType>*/() => throw "hello");
+  /*@typeArgs=Null*/map(/*@returnType=<BottomType>*/() => throw "hello", foo);
+  /*@typeArgs=Null*/map(/*@returnType=Null*/() {
+    return null;
+  }, /*@returnType=<BottomType>*/() => throw "hello");
+
+  /*@typeArgs=Null*/map(/*@returnType=<BottomType>*/() => throw "hello", /*@returnType=Null*/() {
+    return null;
+  });
+  /*@typeArgs=() -> Null*/id(/*@returnType=Null*/() {});
+}
diff --git a/pkg/front_end/testcases/type_of_null.dart.legacy.expect b/pkg/front_end/testcases/type_of_null.dart.legacy.expect
new file mode 100644
index 0000000..83e584c
--- /dev/null
+++ b/pkg/front_end/testcases/type_of_null.dart.legacy.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method map<T extends core::Object = dynamic>(() → self::map::T f1, () → self::map::T f2) → self::map::T {}
+static method id<T extends core::Object = dynamic>(self::id::T t) → dynamic
+  return t;
+static method foo() → core::Null
+  return null;
+static method main() → dynamic {
+  self::map<dynamic>(() → dynamic {}, () → dynamic => throw "hello");
+  self::map<dynamic>(() → dynamic => throw "hello", () → dynamic {});
+  () → core::Null f = () → dynamic {};
+  self::map<dynamic>(self::foo, () → dynamic => throw "hello");
+  self::map<dynamic>(() → dynamic => throw "hello", self::foo);
+  self::map<dynamic>(() → dynamic {
+    return null;
+  }, () → dynamic => throw "hello");
+  self::map<dynamic>(() → dynamic => throw "hello", () → dynamic {
+    return null;
+  });
+  self::id<dynamic>(() → dynamic {});
+}
diff --git a/pkg/front_end/testcases/type_of_null.dart.legacy.transformed.expect b/pkg/front_end/testcases/type_of_null.dart.legacy.transformed.expect
new file mode 100644
index 0000000..83e584c
--- /dev/null
+++ b/pkg/front_end/testcases/type_of_null.dart.legacy.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method map<T extends core::Object = dynamic>(() → self::map::T f1, () → self::map::T f2) → self::map::T {}
+static method id<T extends core::Object = dynamic>(self::id::T t) → dynamic
+  return t;
+static method foo() → core::Null
+  return null;
+static method main() → dynamic {
+  self::map<dynamic>(() → dynamic {}, () → dynamic => throw "hello");
+  self::map<dynamic>(() → dynamic => throw "hello", () → dynamic {});
+  () → core::Null f = () → dynamic {};
+  self::map<dynamic>(self::foo, () → dynamic => throw "hello");
+  self::map<dynamic>(() → dynamic => throw "hello", self::foo);
+  self::map<dynamic>(() → dynamic {
+    return null;
+  }, () → dynamic => throw "hello");
+  self::map<dynamic>(() → dynamic => throw "hello", () → dynamic {
+    return null;
+  });
+  self::id<dynamic>(() → dynamic {});
+}
diff --git a/pkg/front_end/testcases/type_of_null.dart.outline.expect b/pkg/front_end/testcases/type_of_null.dart.outline.expect
new file mode 100644
index 0000000..c42aee1
--- /dev/null
+++ b/pkg/front_end/testcases/type_of_null.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method map<T extends core::Object = dynamic>(() → self::map::T f1, () → self::map::T f2) → self::map::T
+  ;
+static method id<T extends core::Object = dynamic>(self::id::T t) → dynamic
+  ;
+static method foo() → core::Null
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/type_of_null.dart.strong.expect b/pkg/front_end/testcases/type_of_null.dart.strong.expect
new file mode 100644
index 0000000..5bee3f8
--- /dev/null
+++ b/pkg/front_end/testcases/type_of_null.dart.strong.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method map<T extends core::Object = dynamic>(() → self::map::T f1, () → self::map::T f2) → self::map::T {}
+static method id<T extends core::Object = dynamic>(self::id::T t) → dynamic
+  return t;
+static method foo() → core::Null
+  return null;
+static method main() → dynamic {
+  self::map<core::Null>(() → core::Null {}, () → <BottomType>=> throw "hello");
+  self::map<core::Null>(() → <BottomType>=> throw "hello", () → core::Null {});
+  () → core::Null f = () → core::Null {};
+  self::map<core::Null>(self::foo, () → <BottomType>=> throw "hello");
+  self::map<core::Null>(() → <BottomType>=> throw "hello", self::foo);
+  self::map<core::Null>(() → core::Null {
+    return null;
+  }, () → <BottomType>=> throw "hello");
+  self::map<core::Null>(() → <BottomType>=> throw "hello", () → core::Null {
+    return null;
+  });
+  self::id<() → core::Null>(() → core::Null {});
+}
diff --git a/pkg/front_end/testcases/type_of_null.dart.strong.transformed.expect b/pkg/front_end/testcases/type_of_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..5bee3f8
--- /dev/null
+++ b/pkg/front_end/testcases/type_of_null.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method map<T extends core::Object = dynamic>(() → self::map::T f1, () → self::map::T f2) → self::map::T {}
+static method id<T extends core::Object = dynamic>(self::id::T t) → dynamic
+  return t;
+static method foo() → core::Null
+  return null;
+static method main() → dynamic {
+  self::map<core::Null>(() → core::Null {}, () → <BottomType>=> throw "hello");
+  self::map<core::Null>(() → <BottomType>=> throw "hello", () → core::Null {});
+  () → core::Null f = () → core::Null {};
+  self::map<core::Null>(self::foo, () → <BottomType>=> throw "hello");
+  self::map<core::Null>(() → <BottomType>=> throw "hello", self::foo);
+  self::map<core::Null>(() → core::Null {
+    return null;
+  }, () → <BottomType>=> throw "hello");
+  self::map<core::Null>(() → <BottomType>=> throw "hello", () → core::Null {
+    return null;
+  });
+  self::id<() → core::Null>(() → core::Null {});
+}
diff --git a/pkg/front_end/testcases/type_variable_as_super.dart.hierarchy.expect b/pkg/front_end/testcases/type_variable_as_super.dart.hierarchy.expect
new file mode 100644
index 0000000..a0f0def
--- /dev/null
+++ b/pkg/front_end/testcases/type_variable_as_super.dart.hierarchy.expect
@@ -0,0 +1,70 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    T
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    T
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    T
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/type_variable_as_super.dart.outline.expect b/pkg/front_end/testcases/type_variable_as_super.dart.outline.expect
index fc52e8d..9b48c25 100644
--- a/pkg/front_end/testcases/type_variable_as_super.dart.outline.expect
+++ b/pkg/front_end/testcases/type_variable_as_super.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_as_super.dart:5:16: Error: The type variable 'T' can't be used as supertype.
 // abstract class A<T> extends T {}
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/type_variable_as_super.dart:11:7: Error: The type variable 'T' can't be used as supertype.
 // class C<T> extends T {}
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_as_super.dart.strong.expect b/pkg/front_end/testcases/type_variable_as_super.dart.strong.expect
index 965f277..37ea872 100644
--- a/pkg/front_end/testcases/type_variable_as_super.dart.strong.expect
+++ b/pkg/front_end/testcases/type_variable_as_super.dart.strong.expect
@@ -1,48 +1,27 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:5:16: Error: The type variable 'T' can't be used as supertype.
-// abstract class A<T> extends T {}
-//                ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:7:16: Error: The type variable 'T' can't be used as supertype.
-// abstract class B<T> extends T {
-//                ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:11:7: Error: The type variable 'T' can't be used as supertype.
-// class C<T> extends T {}
-//       ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:14:7: Error: The class 'A' is abstract and can't be instantiated.
-//   new A();
-//       ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:15:7: Error: The class 'B' is abstract and can't be instantiated.
-//   new B();
-//       ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:5:16: Error: The type variable 'T' can't be used as supertype.
-// abstract class A<T> extends T {}
-//                ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:7:16: Error: The type variable 'T' can't be used as supertype.
-// abstract class B<T> extends T {
-//                ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:11:7: Error: The type variable 'T' can't be used as supertype.
-// class C<T> extends T {}
-//       ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:14:7: Error: The class 'A' is abstract and can't be instantiated.
-//   new A();
-//       ^
-//
-// pkg/front_end/testcases/type_variable_as_super.dart:15:7: Error: The class 'B' is abstract and can't be instantiated.
-//   new B();
-//       ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/type_variable_as_super.dart:5:16: Error: The type variable 'T' can't be used as supertype.
+// abstract class A<T> extends T {}
+//                ^
+//
+// pkg/front_end/testcases/type_variable_as_super.dart:7:16: Error: The type variable 'T' can't be used as supertype.
+// abstract class B<T> extends T {
+//                ^
+//
+// pkg/front_end/testcases/type_variable_as_super.dart:11:7: Error: The type variable 'T' can't be used as supertype.
+// class C<T> extends T {}
+//       ^
+//
+// pkg/front_end/testcases/type_variable_as_super.dart:14:7: Error: The class 'A' is abstract and can't be instantiated.
+//   new A();
+//       ^
+//
+// pkg/front_end/testcases/type_variable_as_super.dart:15:7: Error: The class 'B' is abstract and can't be instantiated.
+//   new B();
+//       ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_as_super.dart.strong.transformed.expect b/pkg/front_end/testcases/type_variable_as_super.dart.strong.transformed.expect
index d58011a..37ea872 100644
--- a/pkg/front_end/testcases/type_variable_as_super.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_as_super.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_as_super.dart:5:16: Error: The type variable 'T' can't be used as supertype.
 // abstract class A<T> extends T {}
@@ -19,8 +21,7 @@
 // pkg/front_end/testcases/type_variable_as_super.dart:15:7: Error: The class 'B' is abstract and can't be instantiated.
 //   new B();
 //       ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.hierarchy.expect b/pkg/front_end/testcases/type_variable_prefix.dart.hierarchy.expect
new file mode 100644
index 0000000..0cfa5ec
--- /dev/null
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.legacy.expect b/pkg/front_end/testcases/type_variable_prefix.dart.legacy.expect
index 89d4f6a..e409640 100644
--- a/pkg/front_end/testcases/type_variable_prefix.dart.legacy.expect
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.legacy.expect
@@ -1,13 +1,16 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_prefix.dart:8:3: Warning: 'T.String' can't be used as a type because 'T' doesn't refer to an import prefix.
 //   T.String method() => "Hello, World!";
 //   ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:core" as T;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.legacy.transformed.expect b/pkg/front_end/testcases/type_variable_prefix.dart.legacy.transformed.expect
index 91a6346..e409640 100644
--- a/pkg/front_end/testcases/type_variable_prefix.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.legacy.transformed.expect
@@ -1,7 +1,16 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/type_variable_prefix.dart:8:3: Warning: 'T.String' can't be used as a type because 'T' doesn't refer to an import prefix.
+//   T.String method() => "Hello, World!";
+//   ^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:core" as T;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.outline.expect b/pkg/front_end/testcases/type_variable_prefix.dart.outline.expect
index 9680b15..16cecb0 100644
--- a/pkg/front_end/testcases/type_variable_prefix.dart.outline.expect
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.outline.expect
@@ -1,13 +1,16 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_prefix.dart:8:3: Warning: 'T.String' can't be used as a type because 'T' doesn't refer to an import prefix.
 //   T.String method() => "Hello, World!";
 //   ^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:core" as T;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T>
     ;
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.strong.expect b/pkg/front_end/testcases/type_variable_prefix.dart.strong.expect
index af040d1..1ca7685 100644
--- a/pkg/front_end/testcases/type_variable_prefix.dart.strong.expect
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_prefix.dart:8:3: Error: 'T.String' can't be used as a type because 'T' doesn't refer to an import prefix.
 //   T.String method() => "Hello, World!";
@@ -13,17 +15,12 @@
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   T.String s = new C().method();
 //                        ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/type_variable_prefix.dart:8:3: Error: 'T.String' can't be used as a type because 'T' doesn't refer to an import prefix.
-//   T.String method() => "Hello, World!";
-//   ^^^^^^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
+import "dart:core" as T;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect
index 01b57d3..1ca7685 100644
--- a/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect
@@ -1,13 +1,26 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_prefix.dart:8:3: Error: 'T.String' can't be used as a type because 'T' doesn't refer to an import prefix.
 //   T.String method() => "Hello, World!";
 //   ^^^^^^^^
-
-library;
+//
+// pkg/front_end/testcases/type_variable_prefix.dart:8:24: Error: A value of type 'String' can't be assigned to a variable of type 'invalid-type'.
+// Try changing the type of the left hand side, or casting the right hand side to 'invalid-type'.
+//   T.String method() => "Hello, World!";
+//                        ^
+//
+// pkg/front_end/testcases/type_variable_prefix.dart:12:24: Error: A value of type 'invalid-type' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   T.String s = new C().method();
+//                        ^
+//
 import self as self;
 import "dart:core" as core;
 
+import "dart:core" as T;
+
 class C<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.hierarchy.expect b/pkg/front_end/testcases/type_variable_uses.dart.hierarchy.expect
new file mode 100644
index 0000000..5250d3d
--- /dev/null
+++ b/pkg/front_end/testcases/type_variable_uses.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    C.staticMethod
+    Object._instanceOf
+    Object.noSuchMethod
+    C.instanceMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.legacy.expect b/pkg/front_end/testcases/type_variable_uses.dart.legacy.expect
index eeed9e1..57ef641 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.legacy.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_uses.dart:7:15: Warning: Can only use type variables in instance methods.
 //   static C<T> staticMethod() {
@@ -59,30 +61,7 @@
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
-//     const <Object>[const C<T>()];
-//                            ^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.legacy.transformed.expect b/pkg/front_end/testcases/type_variable_uses.dart.legacy.transformed.expect
index ab55341..57ef641 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.legacy.transformed.expect
@@ -1,4 +1,46 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/type_variable_uses.dart:7:15: Warning: Can only use type variables in instance methods.
+//   static C<T> staticMethod() {
+//               ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:8:11: Warning: Type variables can't be used in static members.
+//     print(T);
+//           ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:9:5: Warning: Type variables can't be used in static members.
+//     T t;
+//     ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:10:7: Warning: Type variables can't be used in static members.
+//     C<T> l;
+//       ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:11:9: Warning: Type variables can't be used in static members.
+//     C<C<T>> ll;
+//         ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:12:13: Warning: Type variables can't be used in static members.
+//     const C<T>();
+//             ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:13:12: Warning: Type variables can't be used in static members.
+//     const <T>[];
+//            ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:14:14: Warning: Type variables can't be used in static members.
+//     const <C<T>>[];
+//              ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:15:20: Warning: Type variables can't be used in static members.
+//     const <Object>[T];
+//                    ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:16:28: Warning: Type variables can't be used in static members.
+//     const <Object>[const C<T>()];
+//                            ^
 //
 // pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
 //     const C<T>();
@@ -19,8 +61,7 @@
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.outline.expect b/pkg/front_end/testcases/type_variable_uses.dart.outline.expect
index 57300d4..3843eac 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.outline.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.outline.expect
@@ -1,10 +1,11 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_uses.dart:7:15: Warning: Can only use type variables in instance methods.
 //   static C<T> staticMethod() {
 //               ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.strong.expect b/pkg/front_end/testcases/type_variable_uses.dart.strong.expect
index a8e6b38..e393464 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.strong.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.strong.expect
@@ -1,128 +1,67 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/type_variable_uses.dart:7:15: Error: Can only use type variables in instance methods.
-//   static C<T> staticMethod() {
-//               ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:8:11: Error: Type variables can't be used in static members.
-//     print(T);
-//           ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:9:5: Error: Type variables can't be used in static members.
-//     T t;
-//     ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:10:7: Error: Type variables can't be used in static members.
-//     C<T> l;
-//       ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:11:9: Error: Type variables can't be used in static members.
-//     C<C<T>> ll;
-//         ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
-//     const <Object>[const C<T>()];
-//                            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
-//     const <Object>[const C<T>()];
-//                            ^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/type_variable_uses.dart:7:15: Error: Can only use type variables in instance methods.
-//   static C<T> staticMethod() {
-//               ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:8:11: Error: Type variables can't be used in static members.
-//     print(T);
-//           ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:9:5: Error: Type variables can't be used in static members.
-//     T t;
-//     ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:10:7: Error: Type variables can't be used in static members.
-//     C<T> l;
-//       ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:11:9: Error: Type variables can't be used in static members.
-//     C<C<T>> ll;
-//         ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
-//     const <Object>[const C<T>()];
-//                            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
-//     const C<T>();
-//             ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
-//     const <T>[];
-//            ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
-//     const <C<T>>[];
-//              ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
-//     const <Object>[T];
-//                    ^
-//
-// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
-//     const <Object>[const C<T>()];
-//                            ^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/type_variable_uses.dart:7:15: Error: Can only use type variables in instance methods.
+//   static C<T> staticMethod() {
+//               ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:8:11: Error: Type variables can't be used in static members.
+//     print(T);
+//           ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:9:5: Error: Type variables can't be used in static members.
+//     T t;
+//     ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:10:7: Error: Type variables can't be used in static members.
+//     C<T> l;
+//       ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:11:9: Error: Type variables can't be used in static members.
+//     C<C<T>> ll;
+//         ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:12:13: Error: Type variables can't be used in static members.
+//     const C<T>();
+//             ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:13:12: Error: Type variables can't be used in static members.
+//     const <T>[];
+//            ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:14:14: Error: Type variables can't be used in static members.
+//     const <C<T>>[];
+//              ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:15:20: Error: Type variables can't be used in static members.
+//     const <Object>[T];
+//                    ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:16:28: Error: Type variables can't be used in static members.
+//     const <Object>[const C<T>()];
+//                            ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:24:13: Error: Type variables can't be used as constants.
+//     const C<T>();
+//             ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:25:12: Error: Type variables can't be used as constants.
+//     const <T>[];
+//            ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:26:14: Error: Type variables can't be used as constants.
+//     const <C<T>>[];
+//              ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:27:20: Error: Type variables can't be used as constants.
+//     const <Object>[T];
+//                    ^
+//
+// pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
+//     const <Object>[const C<T>()];
+//                            ^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect b/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect
index 335895d..e393464 100644
--- a/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/type_variable_uses.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/type_variable_uses.dart:7:15: Error: Can only use type variables in instance methods.
 //   static C<T> staticMethod() {
@@ -59,8 +61,7 @@
 // pkg/front_end/testcases/type_variable_uses.dart:28:28: Error: Type variables can't be used as constants.
 //     const <Object>[const C<T>()];
 //                            ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/undefined.dart.hierarchy.expect b/pkg/front_end/testcases/undefined.dart.hierarchy.expect
new file mode 100644
index 0000000..24335b5
--- /dev/null
+++ b/pkg/front_end/testcases/undefined.dart.hierarchy.expect
@@ -0,0 +1,39 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.f
+    Object.toString
+    C.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/undefined.dart.strong.expect b/pkg/front_end/testcases/undefined.dart.strong.expect
index 4dabf97..acd6f2d 100644
--- a/pkg/front_end/testcases/undefined.dart.strong.expect
+++ b/pkg/front_end/testcases/undefined.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class 'C'.
 //  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
@@ -17,8 +19,7 @@
 // Try correcting the name to the name of an existing setter, or defining a setter or field named 'y'.
 //   c. /*@error=UndefinedSetter*/ y = null;
 //                                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -31,19 +32,19 @@
 }
 static method test(self::C c) → void {
   c.{self::C::x};
-  let final dynamic #t1 = c in invalid-expression "pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'y'.
   c. /*@error=UndefinedGetter*/ y;
                                 ^";
   c.{self::C::f}();
-  let final dynamic #t2 = c in invalid-expression "pkg/front_end/testcases/undefined.dart:16:33: Error: The method 'g' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/undefined.dart:16:33: Error: The method 'g' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
 Try correcting the name to the name of an existing method, or defining a method named 'g'.
   c. /*@error=UndefinedMethod*/ g();
                                 ^";
   c.{self::C::x} = null;
-  let final dynamic #t3 = c in invalid-expression "pkg/front_end/testcases/undefined.dart:18:33: Error: The setter 'y' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/undefined.dart:18:33: Error: The setter 'y' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'y'.
   c. /*@error=UndefinedSetter*/ y = null;
diff --git a/pkg/front_end/testcases/undefined.dart.strong.transformed.expect b/pkg/front_end/testcases/undefined.dart.strong.transformed.expect
index 03483b3..acd6f2d 100644
--- a/pkg/front_end/testcases/undefined.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/undefined.dart.strong.transformed.expect
@@ -1,4 +1,25 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'y'.
+//   c. /*@error=UndefinedGetter*/ y;
+//                                 ^
+//
+// pkg/front_end/testcases/undefined.dart:16:33: Error: The method 'g' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
+// Try correcting the name to the name of an existing method, or defining a method named 'g'.
+//   c. /*@error=UndefinedMethod*/ g();
+//                                 ^
+//
+// pkg/front_end/testcases/undefined.dart:18:33: Error: The setter 'y' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
+// Try correcting the name to the name of an existing setter, or defining a setter or field named 'y'.
+//   c. /*@error=UndefinedSetter*/ y = null;
+//                                 ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -11,19 +32,19 @@
 }
 static method test(self::C c) → void {
   c.{self::C::x};
-  let final self::C #t1 = c in invalid-expression "pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'y'.
   c. /*@error=UndefinedGetter*/ y;
                                 ^";
   c.{self::C::f}();
-  let final self::C #t2 = c in invalid-expression "pkg/front_end/testcases/undefined.dart:16:33: Error: The method 'g' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/undefined.dart:16:33: Error: The method 'g' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
 Try correcting the name to the name of an existing method, or defining a method named 'g'.
   c. /*@error=UndefinedMethod*/ g();
                                 ^";
   c.{self::C::x} = null;
-  let final self::C #t3 = c in invalid-expression "pkg/front_end/testcases/undefined.dart:18:33: Error: The setter 'y' isn't defined for the class 'C'.
+  invalid-expression "pkg/front_end/testcases/undefined.dart:18:33: Error: The setter 'y' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined.dart'.
 Try correcting the name to the name of an existing setter, or defining a setter or field named 'y'.
   c. /*@error=UndefinedSetter*/ y = null;
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.hierarchy.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.hierarchy.expect
new file mode 100644
index 0000000..a7d997a
--- /dev/null
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.hierarchy.expect
@@ -0,0 +1,37 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.x
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
index de383ad..a86da13 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class 'C'.
 //  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
@@ -11,8 +13,7 @@
 // Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
 //   c. /*@error=UndefinedGetter*/ x ??= 1;
 //                                 ^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
@@ -24,15 +25,15 @@
 }
 static method test(self::C c) → void {
   c.{self::C::x} = 1;
-  let final self::C #t1 = c in #t1.{self::C::x} = (let final dynamic #t2 = #t1 in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class 'C'.
+  let final self::C #t1 = c in #t1.{self::C::x} = invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
   c. /*@error=UndefinedGetter*/ x += 1;
-                                ^").+(1);
-  let final self::C #t3 = c in (let final dynamic #t4 = #t3 in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class 'C'.
+                                ^".+(1);
+  let final self::C #t2 = c in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
   c. /*@error=UndefinedGetter*/ x ??= 1;
-                                ^").{core::Object::==}(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
+                                ^".{core::Object::==}(null) ?{dynamic} #t2.{self::C::x} = 1 : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
index db60632..a86da13 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
@@ -1,4 +1,19 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
+//   c. /*@error=UndefinedGetter*/ x += 1;
+//                                 ^
+//
+// pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class 'C'.
+//  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
+// Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
+//   c. /*@error=UndefinedGetter*/ x ??= 1;
+//                                 ^
+//
 import self as self;
 import "dart:core" as core;
 
@@ -10,15 +25,15 @@
 }
 static method test(self::C c) → void {
   c.{self::C::x} = 1;
-  let final self::C #t1 = c in #t1.{self::C::x} = (let final self::C #t2 = #t1 in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class 'C'.
+  let final self::C #t1 = c in #t1.{self::C::x} = invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
   c. /*@error=UndefinedGetter*/ x += 1;
-                                ^").+(1);
-  let final self::C #t3 = c in (let final self::C #t4 = #t3 in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class 'C'.
+                                ^".+(1);
+  let final self::C #t2 = c in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class 'C'.
  - 'C' is from 'pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart'.
 Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
   c. /*@error=UndefinedGetter*/ x ??= 1;
-                                ^").{core::Object::==}(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
+                                ^".{core::Object::==}(null) ?{dynamic} #t2.{self::C::x} = 1 : null;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/uninitialized_fields.dart.hierarchy.expect b/pkg/front_end/testcases/uninitialized_fields.dart.hierarchy.expect
new file mode 100644
index 0000000..92ba89a
--- /dev/null
+++ b/pkg/front_end/testcases/uninitialized_fields.dart.hierarchy.expect
@@ -0,0 +1,95 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Uninitialized:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Uninitialized.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Uninitialized.x
+
+PartiallyInitialized:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    PartiallyInitialized.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    PartiallyInitialized.x
+
+Initialized:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Initialized.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Initialized.x
+
+Forwarding:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Forwarding.x
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Forwarding.x
diff --git a/pkg/front_end/testcases/unsound_promotion.dart b/pkg/front_end/testcases/unsound_promotion.dart
new file mode 100644
index 0000000..f04da5f
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {}
+
+class B {}
+
+class C extends B implements A {}
+
+List<A> list;
+
+List<T> g<T extends A>(T t) {
+  list = <T>[];
+  print(list.runtimeType);
+  return list;
+}
+
+List<S> f<S>(S s) {
+  if (s is A) {
+    var list = g(s);
+    return list;
+  }
+  return null;
+}
+
+main() {
+  f<B>(new C());
+  print(list.runtimeType);
+  List<A> aList;
+  aList = list;
+  Object o = aList;
+  aList = o;
+}
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.hierarchy.expect b/pkg/front_end/testcases/unsound_promotion.dart.hierarchy.expect
new file mode 100644
index 0000000..c1e95c6
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.hierarchy.expect
@@ -0,0 +1,83 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+      -> B
+  interfaces: A
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.legacy.expect b/pkg/front_end/testcases/unsound_promotion.dart.legacy.expect
new file mode 100644
index 0000000..fc1dfe0
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.legacy.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::A {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static field core::List<self::A> list;
+static method g<T extends self::A = dynamic>(self::g::T t) → core::List<self::g::T> {
+  self::list = <self::g::T>[];
+  core::print(self::list.runtimeType);
+  return self::list;
+}
+static method f<S extends core::Object = dynamic>(self::f::S s) → core::List<self::f::S> {
+  if(s is self::A) {
+    dynamic list = self::g<dynamic>(s);
+    return list;
+  }
+  return null;
+}
+static method main() → dynamic {
+  self::f<self::B>(new self::C::•());
+  core::print(self::list.runtimeType);
+  core::List<self::A> aList;
+  aList = self::list;
+  core::Object o = aList;
+  aList = o;
+}
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.legacy.transformed.expect b/pkg/front_end/testcases/unsound_promotion.dart.legacy.transformed.expect
new file mode 100644
index 0000000..fc1dfe0
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.legacy.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::A {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static field core::List<self::A> list;
+static method g<T extends self::A = dynamic>(self::g::T t) → core::List<self::g::T> {
+  self::list = <self::g::T>[];
+  core::print(self::list.runtimeType);
+  return self::list;
+}
+static method f<S extends core::Object = dynamic>(self::f::S s) → core::List<self::f::S> {
+  if(s is self::A) {
+    dynamic list = self::g<dynamic>(s);
+    return list;
+  }
+  return null;
+}
+static method main() → dynamic {
+  self::f<self::B>(new self::C::•());
+  core::print(self::list.runtimeType);
+  core::List<self::A> aList;
+  aList = self::list;
+  core::Object o = aList;
+  aList = o;
+}
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.outline.expect b/pkg/front_end/testcases/unsound_promotion.dart.outline.expect
new file mode 100644
index 0000000..9503f5c
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.outline.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    ;
+}
+class C extends self::B implements self::A {
+  synthetic constructor •() → self::C
+    ;
+}
+static field core::List<self::A> list;
+static method g<T extends self::A = dynamic>(self::g::T t) → core::List<self::g::T>
+  ;
+static method f<S extends core::Object = dynamic>(self::f::S s) → core::List<self::f::S>
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.strong.expect b/pkg/front_end/testcases/unsound_promotion.dart.strong.expect
new file mode 100644
index 0000000..4f9cda5
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.strong.expect
@@ -0,0 +1,49 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/unsound_promotion.dart:21:16: Error: Can't infer a type for 'T', it can be either 'S' or 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/unsound_promotion.dart'.
+// Try adding a type argument selecting one of the options.
+//     var list = g(s);
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::A {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static field core::List<self::A> list;
+static method g<T extends self::A = self::A>(self::g::T t) → core::List<self::g::T> {
+  self::list = <self::g::T>[];
+  core::print(self::list.{core::Object::runtimeType});
+  return self::list as{TypeError} core::List<self::g::T>;
+}
+static method f<S extends core::Object = dynamic>(self::f::S s) → core::List<self::f::S> {
+  if(s is self::A) {
+    core::List<self::f::S extends self::A> list = self::g<self::f::S extends self::A>(s{self::f::S extends self::A});
+    return list;
+  }
+  return null;
+}
+static method main() → dynamic {
+  self::f<self::B>(new self::C::•());
+  core::print(self::list.{core::Object::runtimeType});
+  core::List<self::A> aList;
+  aList = self::list;
+  core::Object o = aList;
+  aList = o as{TypeError} core::List<self::A>;
+}
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.strong.transformed.expect b/pkg/front_end/testcases/unsound_promotion.dart.strong.transformed.expect
new file mode 100644
index 0000000..4f9cda5
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/unsound_promotion.dart:21:16: Error: Can't infer a type for 'T', it can be either 'S' or 'A'.
+//  - 'A' is from 'pkg/front_end/testcases/unsound_promotion.dart'.
+// Try adding a type argument selecting one of the options.
+//     var list = g(s);
+//                ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::A {
+  synthetic constructor •() → self::C
+    : super self::B::•()
+    ;
+}
+static field core::List<self::A> list;
+static method g<T extends self::A = self::A>(self::g::T t) → core::List<self::g::T> {
+  self::list = <self::g::T>[];
+  core::print(self::list.{core::Object::runtimeType});
+  return self::list as{TypeError} core::List<self::g::T>;
+}
+static method f<S extends core::Object = dynamic>(self::f::S s) → core::List<self::f::S> {
+  if(s is self::A) {
+    core::List<self::f::S extends self::A> list = self::g<self::f::S extends self::A>(s{self::f::S extends self::A});
+    return list;
+  }
+  return null;
+}
+static method main() → dynamic {
+  self::f<self::B>(new self::C::•());
+  core::print(self::list.{core::Object::runtimeType});
+  core::List<self::A> aList;
+  aList = self::list;
+  core::Object o = aList;
+  aList = o as{TypeError} core::List<self::A>;
+}
diff --git a/pkg/front_end/testcases/unsound_promotion.dart.type_promotion.expect b/pkg/front_end/testcases/unsound_promotion.dart.type_promotion.expect
new file mode 100644
index 0000000..c175828
--- /dev/null
+++ b/pkg/front_end/testcases/unsound_promotion.dart.type_promotion.expect
@@ -0,0 +1,9 @@
+pkg/front_end/testcases/unsound_promotion.dart:20:9: Context: Possible promotion of s@397
+  if (s is A) {
+        ^^
+pkg/front_end/testcases/unsound_promotion.dart:31:9: Context: Write to aList@541
+  aList = list;
+        ^
+pkg/front_end/testcases/unsound_promotion.dart:33:9: Context: Write to aList@541
+  aList = o;
+        ^
diff --git a/pkg/front_end/testcases/unused_methods.dart.hierarchy.expect b/pkg/front_end/testcases/unused_methods.dart.hierarchy.expect
new file mode 100644
index 0000000..bd3ac0d
--- /dev/null
+++ b/pkg/front_end/testcases/unused_methods.dart.hierarchy.expect
@@ -0,0 +1,164 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+UnusedClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+UsedAsBaseClass:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    UsedAsBaseClass.calledFromSubclass
+    Object.toString
+    UsedAsBaseClass.usedInSubclass
+    UsedAsBaseClass.calledFromB
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+UsedAsInterface:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    UsedAsInterface.usedInSubclass
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+InstantiatedButMethodsUnused:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    InstantiatedButMethodsUnused.usedInSubclass
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+ClassA:
+  superclasses:
+    Object
+      -> UsedAsBaseClass
+  interfaces: UsedAsInterface, InstantiatedButMethodsUnused
+  classMembers:
+    UsedAsBaseClass.calledFromSubclass
+    Object.toString
+    ClassA.usedInSubclass
+    UsedAsBaseClass.calledFromB
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    UsedAsBaseClass.calledFromSubclass
+    Object.toString
+    ClassA.usedInSubclass
+    UsedAsBaseClass.calledFromB
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
+
+ClassB:
+  superclasses:
+    Object
+      -> UsedAsBaseClass
+  interfaces: UsedAsInterface, InstantiatedButMethodsUnused
+  classMembers:
+    ClassB.calledFromSubclass
+    Object.toString
+    ClassB.usedInSubclass
+    UsedAsBaseClass.calledFromB
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+  interfaceMembers:
+    ClassB.calledFromSubclass
+    Object.toString
+    ClassB.usedInSubclass
+    UsedAsBaseClass.calledFromB
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  interfaceSetters:
diff --git a/pkg/front_end/testcases/var_as_type_name.dart.hierarchy.expect b/pkg/front_end/testcases/var_as_type_name.dart.hierarchy.expect
new file mode 100644
index 0000000..86fe8bf
--- /dev/null
+++ b/pkg/front_end/testcases/var_as_type_name.dart.hierarchy.expect
@@ -0,0 +1,38 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    A.m
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    A.m
diff --git a/pkg/front_end/testcases/var_as_type_name.dart.legacy.expect b/pkg/front_end/testcases/var_as_type_name.dart.legacy.expect
index a57cbf9..3807e34 100644
--- a/pkg/front_end/testcases/var_as_type_name.dart.legacy.expect
+++ b/pkg/front_end/testcases/var_as_type_name.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
 //   Map<String, var> m;
@@ -11,14 +13,7 @@
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Warning: 'var' isn't a type.
 //   Map<String, var> m;
 //               ^^^
-
-// Unhandled errors:
 //
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
-//   Map<String, var> m;
-//               ^^^
-
-library;
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/var_as_type_name.dart.legacy.transformed.expect b/pkg/front_end/testcases/var_as_type_name.dart.legacy.transformed.expect
index 0311700..3807e34 100644
--- a/pkg/front_end/testcases/var_as_type_name.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/var_as_type_name.dart.legacy.transformed.expect
@@ -1,10 +1,19 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
 //   Map<String, var> m;
 //               ^^^
-
-library;
+//
+// pkg/front_end/testcases/var_as_type_name.dart:6:15: Warning: Type 'var' not found.
+//   Map<String, var> m;
+//               ^^^
+//
+// pkg/front_end/testcases/var_as_type_name.dart:6:15: Warning: 'var' isn't a type.
+//   Map<String, var> m;
+//               ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/var_as_type_name.dart.outline.expect b/pkg/front_end/testcases/var_as_type_name.dart.outline.expect
index cb7a015..dc6939d 100644
--- a/pkg/front_end/testcases/var_as_type_name.dart.outline.expect
+++ b/pkg/front_end/testcases/var_as_type_name.dart.outline.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
 //   Map<String, var> m;
@@ -7,8 +9,7 @@
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Warning: Type 'var' not found.
 //   Map<String, var> m;
 //               ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/var_as_type_name.dart.strong.expect b/pkg/front_end/testcases/var_as_type_name.dart.strong.expect
index 0b4ad72..8c534a9 100644
--- a/pkg/front_end/testcases/var_as_type_name.dart.strong.expect
+++ b/pkg/front_end/testcases/var_as_type_name.dart.strong.expect
@@ -1,32 +1,19 @@
-// Formatted problems:
-//
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
-//   Map<String, var> m;
-//               ^^^
-//
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: Type 'var' not found.
-//   Map<String, var> m;
-//               ^^^
-//
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: 'var' isn't a type.
-//   Map<String, var> m;
-//               ^^^
-
-// Unhandled errors:
-//
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
-//   Map<String, var> m;
-//               ^^^
-//
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: Type 'var' not found.
-//   Map<String, var> m;
-//               ^^^
-//
-// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: 'var' isn't a type.
-//   Map<String, var> m;
-//               ^^^
-
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
+//   Map<String, var> m;
+//               ^^^
+//
+// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: Type 'var' not found.
+//   Map<String, var> m;
+//               ^^^
+//
+// pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: 'var' isn't a type.
+//   Map<String, var> m;
+//               ^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/var_as_type_name.dart.strong.transformed.expect b/pkg/front_end/testcases/var_as_type_name.dart.strong.transformed.expect
index ebce5d7..8c534a9 100644
--- a/pkg/front_end/testcases/var_as_type_name.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/var_as_type_name.dart.strong.transformed.expect
@@ -1,4 +1,6 @@
-// Unhandled errors:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: The keyword 'var' can't be used as a type name.
 //   Map<String, var> m;
@@ -11,8 +13,7 @@
 // pkg/front_end/testcases/var_as_type_name.dart:6:15: Error: 'var' isn't a type.
 //   Map<String, var> m;
 //               ^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/void_methods.dart.hierarchy.expect b/pkg/front_end/testcases/void_methods.dart.hierarchy.expect
new file mode 100644
index 0000000..77a190c
--- /dev/null
+++ b/pkg/front_end/testcases/void_methods.dart.hierarchy.expect
@@ -0,0 +1,41 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Foo:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Foo.list
+    Foo.[]=
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Foo.clear
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    Foo.list
+    Foo.first
diff --git a/pkg/front_end/testcases/warn_unresolved_sends.dart.hierarchy.expect b/pkg/front_end/testcases/warn_unresolved_sends.dart.hierarchy.expect
new file mode 100644
index 0000000..eb50940
--- /dev/null
+++ b/pkg/front_end/testcases/warn_unresolved_sends.dart.hierarchy.expect
@@ -0,0 +1,105 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+C:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    C.getterOnly
+    Object.toString
+    C.superField
+    C.setterOnly
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.superMethod
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+    C.getterOnly
+    C.superField
+    C.setterOnly
+
+D:
+  superclasses:
+    Object
+      -> C
+  interfaces:
+  classMembers:
+    D.getterOnly
+    Object.toString
+    C.superField
+    C.setterOnly
+    Object.runtimeType
+    Object._simpleInstanceOf
+    D.field
+    D.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    C.superMethod
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.test
+  classSetters:
+    C.getterOnly
+    C.superField
+    D.setterOnly
+    D.field
+
+E:
+  superclasses:
+    Object
+      -> C
+        -> D
+  interfaces:
+  classMembers:
+    D.getterOnly
+    Object.toString
+    C.superField
+    C.setterOnly
+    Object.runtimeType
+    Object._simpleInstanceOf
+    D.field
+    D.method
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    E.missingField
+    C.superMethod
+    Object.hashCode
+    E.missingMethod
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+    D.test
+  classSetters:
+    C.getterOnly
+    C.superField
+    D.setterOnly
+    D.field
+    E.missingField
diff --git a/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.expect b/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.expect
index 46b046b..6a98a24 100644
--- a/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.expect
+++ b/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.expect
@@ -1,4 +1,6 @@
-// Formatted problems:
+library;
+//
+// Problems in library:
 //
 // pkg/front_end/testcases/warn_unresolved_sends.dart:49:39: Warning: Getter not found: 'missingField'.
 //     this. /*@warning=GetterNotFound*/ missingField;
@@ -23,8 +25,7 @@
 // pkg/front_end/testcases/warn_unresolved_sends.dart:55:33: Warning: Method not found: 'missingMethod'.
 //     /*@warning=MethodNotFound*/ missingMethod();
 //                                 ^^^^^^^^^^^^^
-
-library;
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.transformed.expect b/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.transformed.expect
index 08aae4d..6a98a24 100644
--- a/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/warn_unresolved_sends.dart.legacy.transformed.expect
@@ -1,4 +1,31 @@
 library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/warn_unresolved_sends.dart:49:39: Warning: Getter not found: 'missingField'.
+//     this. /*@warning=GetterNotFound*/ missingField;
+//                                       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/warn_unresolved_sends.dart:50:39: Warning: Setter not found: 'missingField'.
+//     this. /*@warning=SetterNotFound*/ missingField = 0;
+//                                       ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/warn_unresolved_sends.dart:51:39: Warning: Method not found: 'missingMethod'.
+//     this. /*@warning=MethodNotFound*/ missingMethod();
+//                                       ^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/warn_unresolved_sends.dart:53:33: Warning: Getter not found: 'missingField'.
+//     /*@warning=GetterNotFound*/ missingField;
+//                                 ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/warn_unresolved_sends.dart:54:33: Warning: Setter not found: 'missingField'.
+//     /*@warning=SetterNotFound*/ missingField = 0;
+//                                 ^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/warn_unresolved_sends.dart:55:33: Warning: Method not found: 'missingMethod'.
+//     /*@warning=MethodNotFound*/ missingMethod();
+//                                 ^^^^^^^^^^^^^
+//
 import self as self;
 import "dart:core" as core;
 
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 6ad3fa1..6dd8999 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -192,9 +192,12 @@
         "/language_2/export_ambiguous_main_test\\.dart$",
         "/language_2/export_double_same_main_test\\.dart$",
         "/language_2/export_main_test\\.dart$",
+        "/language_2/import_nonexisting_dart_uri_test\\.dart$",
+        "/language_2/internal_library_test\\.dart$",
         "/language_2/issue1578_negative_test\\.dart$",
         "/language_2/missing_part_of_tag_test\\.dart$",
         "/language_2/no_main_test\\.dart$",
+        "/language_2/part_refers_to_core_library_test\\.dart$",
         "/language_2/regress_27957_test\\.dart$",
         "/language_2/script1_negative_test\\.dart$",
         "/language_2/script2_negative_test\\.dart$",
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index d4ccb3a..77987c1 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -182,10 +182,11 @@
             }
             var parsedValue;
             if (valueSpecification == int) {
-              parsedValue = int.parse(value, onError: (_) {
+              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;
@@ -332,9 +333,7 @@
   final Uri singleRootBase = options["--single-root-base"];
 
   FileSystem fileSystem = StandardFileSystem.instance;
-  List<String> extraSchemes = const [];
   if (singleRootScheme != null) {
-    extraSchemes = [singleRootScheme];
     fileSystem = new SchemeBasedFileSystem({
       'file': fileSystem,
       'data': fileSystem,
@@ -366,8 +365,7 @@
     return new ProcessedOptions(
         options: new CompilerOptions()
           ..sdkSummary = options["--platform"]
-          ..librariesSpecificationUri =
-              resolveInputUri(arguments[1], extraSchemes: extraSchemes)
+          ..librariesSpecificationUri = resolveInputUri(arguments[1])
           ..setExitCodeOnProblem = true
           ..fileSystem = fileSystem
           ..packagesFileUri = packages
@@ -381,15 +379,15 @@
           ..verbose = verbose
           ..verify = verify
           ..bytecode = bytecode
-          ..experimentalFlags = experimentalFlags,
+          ..experimentalFlags = experimentalFlags
+          ..environmentDefines = parsedArguments.defines,
         inputs: <Uri>[Uri.parse(arguments[0])],
-        output: resolveInputUri(arguments[3], extraSchemes: extraSchemes));
+        output: resolveInputUri(arguments[3]));
   } else if (arguments.isEmpty) {
     return throw new CommandLineProblem.deprecated("No Dart file specified.");
   }
 
-  final Uri defaultOutput =
-      resolveInputUri("${arguments.first}.dill", extraSchemes: extraSchemes);
+  final Uri defaultOutput = resolveInputUri("${arguments.first}.dill");
 
   final Uri output = options["-o"] ?? options["--output"] ?? defaultOutput;
 
@@ -416,14 +414,15 @@
     ..omitPlatform = omitPlatform
     ..verbose = verbose
     ..verify = verify
-    ..experimentalFlags = experimentalFlags;
+    ..experimentalFlags = experimentalFlags
+    ..environmentDefines = parsedArguments.defines;
 
   // TODO(ahe): What about chase dependencies?
 
   List<Uri> inputs = <Uri>[];
   if (areRestArgumentsInputs) {
     for (String argument in arguments) {
-      inputs.add(resolveInputUri(argument, extraSchemes: extraSchemes));
+      inputs.add(resolveInputUri(argument));
     }
   }
   return new ProcessedOptions(
diff --git a/pkg/front_end/tool/_fasta/log_collector.dart b/pkg/front_end/tool/_fasta/log_collector.dart
index 5f3e184..f95564c 100644
--- a/pkg/front_end/tool/_fasta/log_collector.dart
+++ b/pkg/front_end/tool/_fasta/log_collector.dart
@@ -38,14 +38,14 @@
   } on FormatException catch (e) {
     print(e);
     return badRequest(
-        request, HttpStatus.BAD_REQUEST, "Malformed JSON data: ${e.message}.");
+        request, HttpStatus.badRequest, "Malformed JSON data: ${e.message}.");
   }
   if (data is! Map) {
     return badRequest(
-        request, HttpStatus.BAD_REQUEST, "Malformed JSON data: not a map.");
+        request, HttpStatus.badRequest, "Malformed JSON data: not a map.");
   }
   if (data["type"] != "crash") {
-    return badRequest(request, HttpStatus.BAD_REQUEST,
+    return badRequest(request, HttpStatus.badRequest,
         "Malformed JSON data: type should be 'crash'.");
   }
   request.response.close();
@@ -92,16 +92,16 @@
     throw "Unexpected arguments: ${arguments.join(' ')}.";
   }
   int port = uri.hasPort ? uri.port : 0;
-  var host = uri.host.isEmpty ? InternetAddress.LOOPBACK_IP_V4 : uri.host;
+  var host = uri.host.isEmpty ? InternetAddress.loopbackIPv4 : uri.host;
   HttpServer server = await HttpServer.bind(host, port);
   print("Listening on http://${server.address.host}:${server.port}/");
   await for (HttpRequest request in server) {
     if (request.method != "POST") {
-      badRequest(request, HttpStatus.METHOD_NOT_ALLOWED, "Not allowed.");
+      badRequest(request, HttpStatus.methodNotAllowed, "Not allowed.");
       continue;
     }
     if (request.uri.path != "/") {
-      badRequest(request, HttpStatus.NOT_FOUND, "Not found.");
+      badRequest(request, HttpStatus.notFound, "Not found.");
       continue;
     }
     collectLog(new DateTime.now(), request);
diff --git a/pkg/front_end/tool/_fasta/resolve_input_uri.dart b/pkg/front_end/tool/_fasta/resolve_input_uri.dart
index f0b49d5..0dd3a17 100644
--- a/pkg/front_end/tool/_fasta/resolve_input_uri.dart
+++ b/pkg/front_end/tool/_fasta/resolve_input_uri.dart
@@ -2,18 +2,37 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/// Resolve [string] as a [Uri].  If the input [string] starts with a supported
-/// scheme, it is resolved as a Uri of that scheme, otherwise the [string]
-/// is treated as a file system (possibly relative) path.
-///
-/// Three schemes are always supported by default: `dart`, `package`, and
-/// `data`. Additional supported schemes can be specified via [extraSchemes].
-Uri resolveInputUri(String string, {List<String> extraSchemes: const []}) {
-  if (string.startsWith('dart:')) return Uri.parse(string);
-  if (string.startsWith('data:')) return Uri.parse(string);
-  if (string.startsWith('package:')) return Uri.parse(string);
-  for (var scheme in extraSchemes) {
-    if (string.startsWith('$scheme:')) return Uri.parse(string);
+/// Detect if we're on Windows without importing `dart:io`.
+bool isWindows = new Uri.directory("C:\\").path ==
+    new Uri.directory("C:\\", windows: true).path;
+
+Uri resolveInputUri(String path) {
+  Uri uri;
+  if (path.indexOf(":") == -1) {
+    uri = new Uri.file(path, windows: isWindows);
+  } else if (!isWindows) {
+    uri = parseUri(path);
+  } else {
+    uri = resolveAmbiguousWindowsPath(path);
   }
-  return Uri.base.resolveUri(new Uri.file(string));
+  return Uri.base.resolveUri(uri);
+}
+
+Uri parseUri(String path) {
+  if (path.startsWith("file:")) {
+    if (Uri.base.scheme == "file") {
+      // The Uri class doesn't handle relative file URIs correctly, the
+      // following works around that issue.
+      return new Uri(path: Uri.parse("x-$path").path);
+    }
+  }
+  return Uri.parse(path);
+}
+
+Uri resolveAmbiguousWindowsPath(String path) {
+  try {
+    return new Uri.file(path, windows: isWindows);
+  } on ArgumentError catch (_) {
+    return parseUri(path);
+  }
 }
diff --git a/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart b/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart
index d644f92..e520fec 100644
--- a/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart
+++ b/pkg/front_end/tool/_fasta/resolve_input_uri_test.dart
@@ -2,39 +2,38 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:io' show Platform;
-
-import 'package:test/test.dart';
+import 'package:expect/expect.dart' show Expect;
 
 import 'resolve_input_uri.dart';
 
+test() {
+  // data URI scheme is supported by default'.
+  Expect.stringEquals('data', resolveInputUri('data:,foo').scheme);
+
+  // Custom Dart schemes are recognized by default.
+  Expect.stringEquals('dart', resolveInputUri('dart:foo').scheme);
+  Expect.stringEquals('package', resolveInputUri('package:foo').scheme);
+
+  // Unknown schemes are recognized by default.
+  Expect.stringEquals(
+      isWindows ? 'file' : 'c', resolveInputUri('c:/foo').scheme);
+  Expect.stringEquals('test', resolveInputUri('test:foo').scheme);
+  Expect.stringEquals(
+      'org-dartlang-foo', resolveInputUri('org-dartlang-foo:bar').scheme);
+  Expect.stringEquals('test', resolveInputUri('test:/foo').scheme);
+  Expect.stringEquals(
+      'org-dartlang-foo', resolveInputUri('org-dartlang-foo:/bar').scheme);
+  Expect.stringEquals(
+      "${Uri.base.resolve('file.txt')}", "${resolveInputUri('file:file.txt')}");
+}
+
 main() {
-  test('data URI scheme is supported by default', () {
-    expect(resolveInputUri('data:,foo').scheme, 'data');
-  });
-
-  test('internal dart schemes are recognized by default', () {
-    expect(resolveInputUri('dart:foo').scheme, 'dart');
-    expect(resolveInputUri('package:foo').scheme, 'package');
-  });
-
-  test('unknown schemes are not recognized by default', () {
-    expect(resolveInputUri('c:/foo').scheme, 'file');
-    if (Platform.isWindows) {
-      /// : is an invalid path character in windows.
-      expect(() => resolveInputUri('test:foo').scheme, throws);
-      expect(() => resolveInputUri('org-dartlang-foo:bar').scheme, throws);
-    } else {
-      expect(resolveInputUri('test:foo').scheme, 'file');
-      expect(resolveInputUri('org-dartlang-foo:bar').scheme, 'file');
-    }
-  });
-
-  test('more schemes can be supported', () {
-    expect(resolveInputUri('test:foo', extraSchemes: ['test']).scheme, 'test');
-    expect(
-        resolveInputUri('org-dartlang-foo:bar',
-            extraSchemes: ['org-dartlang-foo']).scheme,
-        'org-dartlang-foo');
-  });
+  // Test platform default.
+  test();
+  // Test non-Windows behavior.
+  isWindows = false;
+  test();
+  // Test Windows behavior.
+  isWindows = true;
+  test();
 }
diff --git a/pkg/front_end/tool/perf.dart b/pkg/front_end/tool/perf.dart
index 582d65a..553ffc6 100644
--- a/pkg/front_end/tool/perf.dart
+++ b/pkg/front_end/tool/perf.dart
@@ -22,13 +22,13 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/physical_file_system.dart'
     show PhysicalResourceProvider;
-import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
 import 'package:analyzer/src/file_system/file_system.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:front_end/src/fasta/scanner.dart';
 import 'package:front_end/src/scanner/token.dart';
 import 'package:package_config/discovery.dart';
diff --git a/pkg/js/proposal.md b/pkg/js/proposal.md
new file mode 100644
index 0000000..abc888d
--- /dev/null
+++ b/pkg/js/proposal.md
@@ -0,0 +1,1636 @@
+# Better JavaScript and Dart interoperability
+
+Table of contents:
+
+<!-- toc -->
+
+- [Motivation](#motivation)
+- [Typed APIs](#typed-apis)
+  * [Automatic Typed API Generation](#automatic-typed-api-generation)
+  * [Static Dispatch](#static-dispatch)
+    + [Extension Fields](#extension-fields)
+  * [JS Interop Checked Mode](#js-interop-checked-mode)
+  * [Data Type Interoperability](#data-type-interoperability)
+  * [Implicit and Explicit Conversions](#implicit-and-explicit-conversions)
+- [Functions](#functions)
+  * [Optional Arguments](#optional-arguments)
+  * [Named Arguments](#named-arguments)
+  * [Overloads](#overloads)
+  * [This Argument](#this-argument)
+  * [Method Tearoffs](#method-tearoffs)
+  * [Generic Type Parameters](#generic-type-parameters)
+- [Data Types Conversions](#data-types-conversions)
+  * [Generic Types, List and JS Array](#generic-types-list-and-js-array)
+  * [Null and Undefined](#null-and-undefined)
+  * [Future and JS Promise](#future-and-js-promise)
+  * [Iterable and JS Iterable](#iterable-and-js-iterable)
+  * [Stream and JS Async Iterable](#stream-and-js-async-iterable)
+  * [Stream and Callbacks](#stream-and-callbacks)
+  * [DateTime and JS Date](#datetime-and-js-date)
+  * [Map/Set and JS Map/Set](#mapset-and-js-mapset)
+  * [Maps and JS Objects](#maps-and-js-objects)
+    + [Wrapper-based JSObjectMap](#wrapper-based-jsobjectmap)
+    + [Autoboxing JSObjectMap](#autoboxing-jsobjectmap)
+- [Less Static Interop](#less-static-interop)
+  * [Virtual Dispatch](#virtual-dispatch)
+  * [Interface and Dynamic dispatch](#interface-and-dynamic-dispatch)
+  * [JS Proxy](#js-proxy)
+  * [JS Reflection](#js-reflection)
+- [Exporting Dart to JS](#exporting-dart-to-js)
+  * [Exporting classes and libraries](#exporting-classes-and-libraries)
+  * [Inheritance between Dart and JS](#inheritance-between-dart-and-js)
+  * [Interop with JS Modules](#interop-with-js-modules)
+  * [Exposing JS Methods as Getters](#exposing-js-methods-as-getters)
+- [JS Types in the Dart Type System](#js-types-in-the-dart-type-system)
+- [Implementation Roadmap](#implementation-roadmap)
+- [Compatibility and Evolution](#compatibility-and-evolution)
+- [FAQ](#faq)
+  * [Q: How does JSON work?](#q-how-does-json-work)
+  * [Q: Would new Dart language features help?](#q-would-new-dart-language-features-help)
+  * [Q: Can dart2js and dartdevc share implementation for JS interop?](#q-can-dart2js-and-dartdevc-share-implementation-for-js-interop)
+  * [Q: If a JS API returns "Object" does this break dart2js tree shaking?](#q-if-a-js-api-returns-object-does-this-break-dart2js-tree-shaking)
+  * [Q: Could we use dynamic interop instead?](#q-could-we-use-dynamic-interop-instead)
+
+<!-- tocstop -->
+
+## Motivation
+
+Better interoperability with JavaScript is one of the most highly requested 
+features for Dart. Previous work has made JS interop possible, but gaps remain.
+This proposal outlines a series of usability improvements that, taken together,
+make it much easier to use JS from Dart and vice versa.
+
+Here's an example of JS interop is like today, from the [Firebase package](https://pub.dartlang.org/packages/firebase):
+```dart
+import 'interop/app_interop.dart';
+
+/// A Firebase App holds the initialization information for a collection
+/// of services.
+///
+/// See: <https://firebase.google.com/docs/reference/js/firebase.app>.
+class App extends JsObjectWrapper<AppJsImpl> {
+  // [ed: doc comments removed to condense code]
+  static final _expando = Expando<App>();
+
+  String get name => jsObject.name;
+  FirebaseOptions get options => jsObject.options;
+
+  static App getInstance(AppJsImpl jsObject) {
+    if (jsObject == null) {
+      return null;
+    }
+    return _expando[jsObject] ??= App._fromJsObject(jsObject);
+  }
+
+  App._fromJsObject(AppJsImpl jsObject) : super.fromJsObject(jsObject);
+
+  Auth auth() => Auth.getInstance(jsObject.auth());
+  Database database() => Database.getInstance(jsObject.database());
+  Future delete() => handleThenable(jsObject.delete());
+  Firestore firestore() => Firestore.getInstance(jsObject.firestore());
+
+  Storage storage([String url]) {
+    var jsObjectStorage =
+        (url != null) ? jsObject.storage(url) : jsObject.storage();
+    return Storage.getInstance(jsObjectStorage);
+  }
+}
+
+// [ed: in interop/app_interop.dart]
+
+@JS('App')
+abstract class AppJsImpl {
+  external String get name;
+  external FirebaseOptions get options;
+  external AuthJsImpl auth();
+  external DatabaseJsImpl database();
+  external PromiseJsImpl delete();
+  external StorageJsImpl storage([String url]);
+  external FirestoreJsImpl firestore();
+}
+```
+
+Nearly all of the Firebase classes are wrapped like that. It's a lot of work and
+boilerplate to implement wrappers like this, and it adds overhead to every
+operation.
+
+What we'd like to write is more like this:
+```dart
+@JS()
+class App {
+  external String get name;
+  external FirebaseOptions get options;
+
+  // Wrappers no longer necessary for these classes.
+  external Auth auth();
+  external Database database();
+  external Firestore firestore();
+
+  // Promise -> Future is handled automatically
+  external Future delete();
+
+  // Optional arguments are handled correctly by the compiler.
+  // (In advanced cases, there are ways to declare overloads.)
+  external Storage storage([String url]);
+}
+```
+
+The [Google Maps API](https://github.com/a14n/dart-google-maps) package is
+similar, but generated using the [js_wrapping](https://github.com/a14n/dart-js-wrapping)
+code generator:
+
+```dart
+@GeneratedFrom(_LatLngBounds)
+@JsName('google.maps.LatLngBounds')
+class LatLngBounds extends JsInterface {
+  LatLngBounds([LatLng sw, LatLng ne])
+      : this.created(JsObject(context['google']['maps']['LatLngBounds'],
+            [__codec0.encode(sw), __codec0.encode(ne)]));
+  LatLngBounds.created(JsObject o) : super.created(o);
+
+  bool contains(LatLng latLng) =>
+      asJsObject(this).callMethod('contains', [__codec0.encode(latLng)]);
+  bool equals(LatLngBounds other) =>
+      asJsObject(this).callMethod('equals', [__codec1.encode(other)]);
+  LatLngBounds extend(LatLng point) => __codec1
+      .decode(asJsObject(this).callMethod('extend', [__codec0.encode(point)]));
+  LatLng get center => _getCenter();
+  LatLng _getCenter() =>
+      __codec0.decode(asJsObject(this).callMethod('getCenter'));
+  LatLng get northEast => _getNorthEast();
+  LatLng _getNorthEast() =>
+      __codec0.decode(asJsObject(this).callMethod('getNorthEast'));
+  LatLng get southWest => _getSouthWest();
+  LatLng _getSouthWest() =>
+      __codec0.decode(asJsObject(this).callMethod('getSouthWest'));
+  bool intersects(LatLngBounds other) =>
+      asJsObject(this).callMethod('intersects', [__codec1.encode(other)]);
+  bool get isEmpty => _isEmpty();
+  bool _isEmpty() => asJsObject(this).callMethod('isEmpty');
+  LatLng toSpan() => __codec0.decode(asJsObject(this).callMethod('toSpan'));
+  String toString() => asJsObject(this).callMethod('toString');
+  String toUrlValue([num precision]) =>
+      asJsObject(this).callMethod('toUrlValue', [precision]);
+  LatLngBounds union(LatLngBounds other) => __codec1
+      .decode(asJsObject(this).callMethod('union', [__codec1.encode(other)]));
+}
+```
+
+What we'd like to write instead:
+```dart
+@JS('google.maps.LatLngBounds')
+class LatLngBounds {
+  external LatLngBounds([LatLng sw, LatLng ne]);
+
+  external bool contains(LatLng latLng);
+  external bool equals(LatLngBounds other);
+  external LatLngBounds extend(LatLng point);
+  external bool intersects(LatLngBounds other);
+  external LatLng toSpan();
+  external String toString();
+  external String toUrlValue([num precision]);
+  external LatLngBounds union(LatLngBounds other);
+
+  @sealed
+  LatLng get center => _getCenter();
+  @sealed
+  LatLng get northEast => _getNorthEast();
+  @sealed
+  LatLng get southWest => _getSouthWest();
+  @sealed
+  bool get isEmpty => _isEmpty();
+
+  @JS('getCenter')
+  external LatLng _getCenter();
+  @JS('getNorthEast')
+  external LatLng _getNorthEast();
+  @JS('getSouthWest')
+  external LatLng _getSouthWest();
+  @JS('isEmpty')
+  external bool _isEmpty();
+}
+```
+
+The rest of the proposal outlines how we get there, as well as many other
+usability and correctness improvements.
+
+
+## Typed APIs
+
+The key principle behind Dart and JS interop is declaring API signatures,
+as illustrated above. The two main pieces of this are `@JS()` annotations and
+the `external` keyword:
+
+```dart
+@JS('firebase.app')
+library firebase.app;
+
+import 'package:js/js.dart' show JS;
+
+@JS('App')
+class App {
+  external String get name;
+  // [...]
+}
+```
+
+The `external` keyword marks a class member or library member as representing a 
+JavaScript API. It allows the body of the API to be omitted, and is only valid
+on a declaration that is in a `@JS()` context (either it is marked with `@JS()`
+itself, or is within a library/class that is marked).
+
+The `@JS()` annotation marks a declaration (library, class, library member or
+class member) as representing a JavaScript API. An optional string can be
+provided, to specify the name of the declaration in JS. This allows APIs to be
+renamed. For example:
+
+```dart
+@JS()
+@anonymous
+class UserInfo {
+  // [...]
+
+  /// Returns a JSON-serializable representation of this object.
+  @JS('toJSON')
+  @JSConvert(dartify)
+  external Map<String, dynamic> toJson();
+}
+```
+
+In the example above `toJSON()` was named `toJson()` to match Dart naming
+conventions. (This also implicitly marks it as `@sealed`.)
+
+Typed APIs provide many benefits:
+- They assist discovery and use of the API, via autocompletion in the editor.
+- They provide static type checking to help use the API correctly.
+- They're the foundation of automatic data type conversions, and adding Dart
+  members to JS interop classes, to provide a more Dart-like API when desired.
+
+
+### Automatic Typed API Generation
+
+Many JavaScript APIs have types now, either from TypeScript or Closure Compiler
+comments. We'd like to have a tool to automatically generate
+Dart interop APIs from those. The resulting file can then be hand edited, if
+desired, to further customize the interop, or used immediately.
+
+
+### Static Dispatch
+
+The example above renames *instance members*, allowing the API to be made
+more Dart-friendly. This feature is crucial for interoperability, as the
+JavaScript API may have a name that is not legal in Dart, or its name may have
+different visibility, such as names starting with underscore.
+
+Renames are made possible by taking advantage of the static type of the
+reciever. This is similar to static calls and extension methods.
+
+```dart
+UserInfo user = someExpression;
+print(user.toJson());
+```
+
+The compiler only needs to generate something like:
+
+```js
+let user = someExpression;
+core.print(js.dartify(user.toJSON()));
+```
+
+Here a conversion was also inserted, based on the `@JSConvert(dartify)`
+annotation. Because it's static, the compilers are able to inline JS code if
+they choose to.
+
+Static dispatch lets us reshape APIs in very powerful ways, without the
+overhead and complexity of wrappers. It also provides a good user experience
+in the IDE.
+
+Notably, this interop is extremely similar to the language team's
+[Static Extension Types](https://github.com/dart-lang/language/issues/42) and
+[Static Extension Methods](https://github.com/dart-lang/language/issues/41)
+proposals. All members in a JS interop class that have Dart implementation code
+(i.e. function bodies, rather than `external`) are required to be nonextensible.
+If we get those language features, they'll provide an alternate syntax, and
+offer additional capabilities.
+
+
+#### Extension Fields
+
+In existing web compilers, there is some ambiguity about how fields on JS types
+are interpreted:
+
+```dart
+@JS()
+class MyJSClass {
+  external int get foo;
+  external set foo(int value);
+
+  int bar;
+
+  @JS()
+  int baz;
+}
+```
+
+Both compilers support "foo". DDC interprets "bar" as a getter/setter pair
+similar to "foo" but dart2js does not. Neither compiler recognizes the `@JS` on
+"baz".
+
+Existing JS interop code suggests we need to provide two features:
+- make it easy to declare external getter/setter pairs.
+- add Dart state to JS classes.
+
+We can accomplish this by using `@JS` to indicate a JS field. With the new
+interpretation:
+
+```dart
+@JS()
+class MyJSClass {
+  external int get foo; // external getter/setter
+  external set foo(int value);
+
+  @sealed
+  int bar; // Dart extension field
+
+  @JS() // sugar for external getter/setter, can't have an initializer
+  int baz;
+}
+```
+
+The "extension field" is essentially an expando:
+
+```dart
+@JS()
+class MyJSClass {
+  // [...]
+  @sealed
+  int get bar => _bar[this];
+  @sealed
+  void set bar(value) { _bar[this] = value; }
+}
+
+final _bar = Expando<int>();
+```
+
+(Web compilers may implement it differently, such as a JS Symbol property stored
+on the instance.)
+
+
+### JS Interop Checked Mode
+
+We may want a "JS interop checked mode" to instrument APIs and check that
+parameters and return types match their declarations. This would provide a lot
+of added safety. It could be turned on for tests, for example.
+If implemented, this would be an opt-in capability
+
+
+### Data Type Interoperability
+
+To use typed APIs, we need to be able to pass data back and forth, and write
+type annotations for the parameters and return value. One of the key questions
+then is: can JS and Dart objects be passed directly, or is some type of
+conversion or wrappers required?
+
+As the Firebase example illustrates, using wrappers everywhere has significant
+cost in code size, performance, and usability.
+
+However, it is impossible to make every single Dart and JS object "just work" in
+the other environment. Consider this example:
+
+```dart
+  external factory RecaptchaVerifier(container,
+      [@JSConvert(jsify) Map<String, Object> parameters, App app]);
+```
+
+While JavaScript has a [Map class](https://tc39.github.io/ecma262/#sec-map-objects) 
+now, many APIs still use raw JS Objects, such as `{ "size": "invisible" }`. In
+Dart `Map<String, Object>` is an interface that at runtime, could contain any
+class that implements Map (including user-defined Maps). Dart's equality
+semantics (`operator ==` and `hashCode`) are different from JS too.
+
+(Even if we're only interested in Dart's default LinkedHashMap with String
+keys, it would be difficult to make this work. The Map class would need to
+store its data as properties on itself. Some keys would not work correctly such
+as "__proto__", and some operations would have different performance 
+characteristics. The map can be modified from JS, so it's difficult to see how
+things like `length` and `keys` could be implemented efficiently.)
+
+For these reasons, we can't take an all-or-nothing approach: ideally most types
+are wrapperless, but we'll need good support for conversions too.
+
+
+### Implicit and Explicit Conversions
+
+Wrapperless types are very convenient: you pass them back and forth, and they
+just work. Explicit conversions involve a lot of boilerplate that must be
+repeated everywhere. For example, we could've written the earlier `toJson()`
+example like this:
+
+```dart
+@JS()
+@anonymous
+class UserInfo {
+  // [...]
+
+  /// Returns a JSON-serializable representation of this object.
+  @sealed
+  Map<String, dynamic> toJson() => dartify(_toJson());
+
+  @JS('toJSON')
+  external Map<String, dynamic> _toJson();
+}
+```
+
+Or worse, the original version of the Recaptcha example shown earlier:
+```dart
+factory RecaptchaVerifier(container,
+          [Map<String, dynamic> parameters, App app]) =>
+      (parameters != null)
+          ? ((app != null)
+              ? RecaptchaVerifier.fromJsObject(RecaptchaVerifierJsImpl(
+                  container, jsify(parameters), app.jsObject))
+              : RecaptchaVerifier.fromJsObject(
+                  RecaptchaVerifierJsImpl(container, jsify(parameters))))
+          : RecaptchaVerifier.fromJsObject(RecaptchaVerifierJsImpl(container));
+
+// [ed: in interop/auth_interop.dart]
+
+  external factory RecaptchaVerifierJsImpl(container,
+      [Object parameters, AppJsImpl app]);
+```
+
+Implicit conversions reduce the boilerplate and make the types feel more
+like directly passed (wrapperless) types. They require less developer input to
+get the correct conversion. The downside is that the conversion is less visible,
+and the implications of conversions may surprise the developer. Overall these
+conversion are similar to "autoboxing" in C# and Java, and are probably a net
+usability benefit.
+
+There's a language issue for [implicit conversions](https://github.com/dart-lang/language/issues/107),
+so that may provide us better support. The native FFI also has a similar
+mechanism for marshalling.
+
+
+## Functions
+
+Similar to Array, functions from JS do not have reified type information and are
+allowed to be cast to any Dart function. This is already implemented in Dart web
+compilers.
+
+Ideally Dart functions could also be directly passed to JS. However this is not
+the case in dart2js. It is not simple to change that, however.
+
+In the meantime, automatic converisons will be provided:
+- passing a Dart function type to any JS parameter performs an `allowInterop`
+  conversion.
+- passing any Dart value to a JS function type performs an `allowInterop`
+  conversion if the runtime value is a Dart function.
+- Function typed parameters/variables can be annotated with `@JS()` to indicate
+  that they should be treated as being passed to JS, implying an `allowInterop`
+  conversion.
+- Typedefs can be annoated with `@JS()` to indicated they should be treated as
+  being passed to JS, implying an `allowInterop` conversion.
+
+One particular challenge is that dartdevc (DDC) represents Dart functions as JS
+functions, so it is difficult to catch problems that may arise later in dart2js.
+It should not occur much in practice, thanks to implicit conversions, and the
+previously mentioned "checked mode" provides a means to catch it.
+
+
+### Optional Arguments
+
+To pass functions between JS and Dart, we need to define how calling conventions
+work. The general principle is "when calling JS, work like JS". Consider the
+first example again:
+
+```dart
+  Storage storage([String url]) {
+    var jsObjectStorage =
+        (url != null) ? jsObject.storage(url) : jsObject.storage();
+    return Storage.getInstance(jsObjectStorage);
+  }
+
+  // What we'd like to write:
+  external Storage storage([String url]);
+```
+
+Or for a more complex case, consider the Recaptcha example:
+```dart
+factory RecaptchaVerifier(container,
+          [Map<String, dynamic> parameters, App app]) =>
+      (parameters != null)
+          ? ((app != null)
+              ? RecaptchaVerifier.fromJsObject(RecaptchaVerifierJsImpl(
+                  container, jsify(parameters), app.jsObject))
+              : RecaptchaVerifier.fromJsObject(
+                  RecaptchaVerifierJsImpl(container, jsify(parameters))))
+          : RecaptchaVerifier.fromJsObject(RecaptchaVerifierJsImpl(container));
+
+// [ed: in interop/auth_interop.dart]
+  external factory RecaptchaVerifierJsImpl(container,
+      [Object parameters, AppJsImpl app]);
+```
+
+These methods are dispatching the call manually, to handle the difference in
+JS and Dart calling conventions: optional arguments are not passed as `null`
+in JS, but are visible via `arguments.length` and their value defaults to
+`undefined` rather than `null`.
+
+What we'd like to write for Recaptcha is: 
+```dart
+  external factory RecaptchaVerifier(container,
+      [@JSMapToObject() Map<String, Object> parameters, App app]);
+```
+
+Because it's now a JS function, the compilers must call it with the correct
+number of arguments. For example, this Dart code:
+```dart
+RecaptchaVerifier(container);
+RecaptchaVerifier(container, {'foo': 'bar'});
+RecaptchaVerifier(container, {'foo': 'bar'}, app);
+```
+
+Should compile to JS code similar to:
+```js
+new auth.RecaptchaVerifier(container);
+new auth.RecaptchaVerifier(container, {'foo': 'bar'});
+new auth.RecaptchaVerifier(container, {'foo': 'bar'}, app);
+```
+
+If someone wants to forward multiple parameters, we could provide an annotation
+to help:
+
+```dart
+@JS()
+class Example {
+  @sealed
+  Object wrapsMethodWithOptionalArgs([Object foo, Object bar]) {
+    // [...]
+    return _underlyingJSMethod(foo, bar);
+  }
+
+  @JS('underlyingJSMethod')
+  external Object _underlyingJSMethod(
+      [@JSNullToOptional() Object foo, @JSNullToOptional() Object bar]);
+}
+```
+
+With `@JSNullToOptional()` the compiler would automatically check for `null` in
+those arguments and dispatch the call to the correct JS signature.
+
+
+### Named Arguments
+
+JS functions don't have a notion of named arguments; rather by convention, JS
+Object literals are passed, and optionally destructured into parameters by the
+callee.
+
+Named arguments will be allowed as syntactic sugar for passing a JS object
+literal. For example:
+
+```dart
+class Example {
+  external takesJSObject({String a, int b})
+}
+f(Example e) {
+  e.takesJSObject(a: 'hi', b: 123);
+}
+```
+
+Is equivalent to this JS:
+
+```js
+function f(e) {
+  e.takesJSObject({a: 'hi', b: 123});
+}
+```
+
+Similarly if a Dart function that takes named arguments is passed to JS, it
+must desugar them. To make this work, we'll need to restrict JS function types
+to having only optional or named arguments, not both.
+
+
+### Overloads
+
+Method overloads do not exist in JavaScript. They can be helpful for
+expressing type signatures, and calling native APIs that are
+overloaded, such as Canvas's [createImageData](https://html.spec.whatwg.org/multipage/canvas.html#pixel-manipulation).
+ 
+Overloads can be expressed by declaring multiple Dart methods and giving them
+the same JavaScript name:
+
+```dart
+// in CanvasRenderingContext2D
+  @JS('createImageData')
+  external ImageData createImageDataFromImage(ImageData imagedata);
+  @JS()
+  external ImageData createImageData(int sw, int sh);
+```
+
+If the author wanted to expose those as the same method, they could instead do:
+
+```dart
+  @JS()
+  external ImageData createImageData(imagedata_OR_sw, [int sh]);
+```
+
+Dispatching based on types should not generally be required, but if it is, it
+can be written like this:
+
+```dart
+  @sealed
+  ImageData createImageData(imagedata_OR_sw, [int sh]) {
+    if (imagedata_OR_sw is int && sh != null) {
+      return _createImageData(imagedata_OR_sw, sh);
+    } else {
+      return _createImageDataFromImage(imagedata_OR_sw);
+    }
+  }
+  JS('createImageData')
+  external ImageData _createImageDataFromImage(ImageData imagedata);
+  @JS()
+  external ImageData _createImageData(int sw, int sh);
+```
+
+The language team is also considering the problem of declaring Dart APIs like
+this, see [issue 145](https://github.com/dart-lang/language/issues/145).
+
+
+### This Argument
+
+JS functions have a hidden `this` parameter, and it is sometimes important for
+Dart to be able to pass that to JS, or receive it from JS.
+
+That's accomplished with the `@JSThis()` annotation:
+
+```dart
+@JS('Object')
+abstract class JSObject {
+  external static _JSObjectPrototype prototype;
+}
+
+@JS()
+@anonymous
+abstract class _JSObjectPrototype {
+  external static bool hasOwnProperty(@JSThis() target, propertyKey);
+}
+
+@JS()
+@anonymous
+class PropertyDescriptor {
+  @JS() Object value;
+  @JS() bool writable;
+  @JS() bool configurable;
+  @JS() bool enumerable;
+  external Object Function(@JSThis() Object) get;
+  external void Function(@JSThis() Object, Object) set;
+}
+```
+
+This lets you declare which parameter should receive `this`/be passed as `this`.
+
+
+### Method Tearoffs
+
+Tearoffs of JS types should bind `this`, as noted in
+[issue 32370](https://github.com/dart-lang/sdk/issues/32370). We also need to
+decide what runtime type information to attach. Tearoffs could get the
+statically visible type at the call site, or they could be treated like other
+JS functions, and be assignable to any function type. Untyped is advantageous
+for performance/simplicity, so it's probably preferrable, unless we find
+compelling examples.
+
+
+### Generic Type Parameters
+
+JavaScript does not have reified generic types. Generic types can
+be used in interop signatures, but they have no effect at runtime, and no type
+argument is passed. 
+
+For JS code calling into exported Dart functions (e.g. `@JSExport`), generic
+type arguments will come through as a special, runtime-only type `JSAny` that
+represents the absence of a reified generic type. This is discussed further in
+the next section, about Generic Types, List and JS Array.
+
+
+## Data Types Conversions
+
+This section discusses specific data types, and has recommendations for how
+these should be handled in the Dart web compilers
+
+### Generic Types, List and JS Array
+
+Both Dart web compilers already use JS Array to implement Dart `List<T>` in
+a wrapperless style. The main challenge for JS interop is how to handle generic
+types.
+
+Generic types in Dart are reified, in other words, generic type arguments are
+represented and stored at run time. These are used by `is` and `as` checks, for
+example, `<int>[1, 2, 3] is List<int>` will return true, and the cast
+`<int>[1, 2, 3] as List<int>` will succeed. But `<int>[1, 2, 3] is List<String>`
+will return false.
+
+JavaScript cannot create Arrays that have an associated Dart generic type.
+Currently these are interpreted as `List<dynamic>`, which frequently results in
+a cast failure, or requires a workaround. For example:
+```dart
+List<App> get apps => firebase.apps
+    // explicitly typing the param as dynamic to work-around
+    // https://github.com/dart-lang/sdk/issues/33537
+    .map((dynamic e) => App.getInstance(e))
+    .toList();
+
+// [in another file]
+
+@JS()
+external List<AppJsImpl> get apps;
+```
+
+The problem is that `List<AppJsImpl> get apps` actually returns `List<dynamic>`,
+so calls like `.map` will fail Dart's reified generic checks (because the list
+could contain anything, the parameter `e` must be typed to accept anything).
+This leads to other strange results, such as:
+
+```dart
+@JS()
+external List<String> get stringsFromJS;
+
+main() {
+  // Either prints `true` or `false`!
+  // True if the compiler optimizes it, false if it's evaluated at runtime.
+  print(stringsFromJS is List<String>);
+
+  List list = stringsFromJS;
+  List<String> list2 = list; // type error: not a List<String>.
+}
+```
+
+The new version of this API is simply:
+```dart
+external List<App> get apps;
+```
+
+And it works mostly how you'd expect with `is` and `as` checks:
+
+```dart
+main() {
+  List apps = firebase.apps;
+  print(apps is List<App>); // true
+  apps as List<App>; // works
+
+  // prints list of names names, `(a)` is inferred as `(App a)`
+  print(apps.map((a) => a.name).toList());
+
+  apps is List<int>         // true: `int` could be from JS
+  apps is List<MyDartClass> // false: can't be a list of Dart classes
+                            // (unless the class is exported to JS)
+}
+```
+
+The last check is an example of one consequence of the looser checking. 
+Conceptually we have a `JSAny` type. This type only exists in runtime, and does
+not require a representation, since it results from the absense of type
+information. This is discussed later when we look at the type system.
+
+Besides JS Arrays, Dart generic functions and methods can also be called from
+JS. In that case, the reified generic type will usually be omitted. This is
+discussed later when we look at exporting Dart classes to JS.
+
+
+### Null and Undefined
+
+Dart web compilers generally treat these as interchangeable; while they don't
+create `undefined` themselves, it's treated as `== null`. This makes interop
+easier, so it's probably worth keeping. We should also add an `undefined`
+constant to "package:js", for cases where it's necessary to pass it explicitly
+to JS.
+
+
+### Future and JS Promise
+
+JS Promises are very common in web APIs, as many operations are asynchronous.
+These function very similarly to Dart's `Future<T>` interface.
+
+There are several possible answers:
+1. provide an implicit conversion
+2. both types implement the other's interface
+3. have _Future be a JS Promise
+
+Option 3 is not feasible. Option 2 is ideal, but may cause issues in dart2js,
+because they currently assume no JS types implement `Future` (this avoids
+"getInterceptor" overhead). So we probably need to go with Option 1. The
+dart:html library already has a conversion in one direction, and `dartdevc` may
+soon have both directions (to use JS async/await).
+
+If we did want to do the adapter design, here is a rough sketch:
+
+```dart
+@JS('Promise')
+@JSInterfaceDispatch()
+@JSDynamicDispatch() // Note: because existing SDK native types support this.
+class JSPromise<T> implements Future<T> {
+  @JS('then')
+  external JSPromise<R> _then<R>(
+    /*R | Thenable<R>*/Object Function(T) onFulfilled,
+    [/*R | Thenable<R>*/Object Function(Object) onRejected]);
+
+  external factory JSPromise.resolve(/*R | Thenable<R>*/Object value);
+
+  Future<R> then<R>(FutureOr<R> onValue(T value), {Function onError}) {
+    return _then(
+        Zone.current.bindUnaryCallback(onValue),
+        onError != null
+            // Note: real impl must also support an `onError` callback that 
+            // takes a StackTrace as the second argument.
+            ? Zone.current.bindUnaryCallback(onError as dynamic)
+            : null);
+  }
+  // [...]
+}
+
+class _Future<T> implements Future<T> {
+  // [...]
+
+  // Note: in reality this could be injected by the compiler on any class
+  // implementing Future<T> if we want them to be Promise-like.
+  @JSExport('then')
+  JSPromise<R> _jsThen<R>(
+    /*R | Thenable<R>*/Object Function(T) onFulfilled,
+    [/*R | Thenable<R>*/Object Function(Object) onRejected]) {
+
+    Future<R> f = then((value) => JSPromise.resolve(onFulfilled(value)),
+        onError: onRejected != null
+            ? (error) => JSPromise.resolve(onRejected(error))
+            : null);
+    // This conversion is not necessary if we only want to implement Thenable.
+    return JSPromise.resolve(f);
+  }
+}
+```
+
+
+### Iterable<T> and JS Iterable
+
+All Dart `Iterable<T>` classes should implement `[Symbol.iterator]`, which
+allows them to be used in JS `for-of` loops.
+
+Converting from a JS iterable to a Dart Iterable requires a conversion
+(either implicit or explicit).
+
+Avoiding a conversion is probably not ideal. We'd need `Iterable<T>` methods
+on any JS object that contains `[Symbol.iterator]`. This requires compilers to
+place `Iterable<T>` members on Object.prototype, or handle this at the
+interceptor level. The current theory is that not many JS APIs return
+iterables (Arrays are much more common). A wrapper-based conversion, either
+implicit or explcit, should be enought to handle this.
+
+
+### Stream<T> and JS Async Iterable
+
+The EcmaScript draft contains a new feature [for-await-of loops](https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements)
+and `Symbol.asyncIterator` (see also [MDN for-await-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of)).
+Once JS has that, `Stream<T>` could work similarly to `Future<T>`.
+
+
+### Stream<T> and Callbacks
+
+These will require a conversion in either direction. However we can provide
+helpers to make this easy. Consider this example from Firebase:
+
+```dart
+class Auth extends JsObjectWrapper<AuthJsImpl> {
+  // [...]
+  Func0 _onAuthUnsubscribe;
+  StreamController<User> _changeController;
+
+  Stream<User> get onAuthStateChanged {
+    if (_changeController == null) {
+      var nextWrapper = allowInterop((firebase_interop.UserJsImpl user) {
+        _changeController.add(User.getInstance(user));
+      });
+
+      var errorWrapper = allowInterop((e) => _changeController.addError(e));
+
+      void startListen() {
+        assert(_onAuthUnsubscribe == null);
+        _onAuthUnsubscribe =
+            jsObject.onAuthStateChanged(nextWrapper, errorWrapper);
+      }
+
+      void stopListen() {
+        _onAuthUnsubscribe();
+        _onAuthUnsubscribe = null;
+      }
+
+      _changeController = StreamController<User>.broadcast(
+          onListen: startListen, onCancel: stopListen, sync: true);
+    }
+    return _changeController.stream;
+  }
+}
+
+// [in interop/auth_iterop.dart]
+@JS('Auth')
+class AuthJsImpl {
+  // [...]
+  external Func0 onAuthStateChanged(nextOrObserver,
+      [Func1 opt_error, Func0 opt_completed]);
+}
+```
+
+With the right helpers and elimination of wrappers, this becomes:
+
+```dart
+@JS()
+class Auth {
+  @sealed
+  Stream<User> _changeStream;
+
+  @JS('onAuthStateChanged')
+  external Func0 _onAuthStateChanged(Func1<User, void> nextOrObserver,
+      [Func1 opt_error, Func0 opt_completed]);
+
+  @sealed
+  Stream<User> get onAuthStateChanged =>
+      _changeStream ??= CreateStream(_onAuthStateChanged);
+}
+
+// Note: package:js will defined some helpers like this.
+// More research is needed to find all of the the common patterns.
+static Stream<T> CreateStream<T>(
+    @JS() Func0 Function(Func1<T, void> nextOrObserver, [Func1 opt_error])
+        subscribeToEvent) {
+  Func0 unsubscribe;
+  StreamController<T> controller;
+  controller = StreamController.broadcast(
+      onListen: () {
+        // Because `subscribeToEvent` is annotated with `@JS()`, `allowInterop`
+        // will be automatically handled on these callbacks.
+        unsubscribe = subscribeToEvent(controller.add, controller.addError);
+      },
+      onCancel: unsubscribe,
+      sync: true);
+  return controller.stream;
+}
+```
+
+
+### DateTime and JS Date
+
+Similar to Future/Promise, we can investigate and determine which of these is
+best:
+- implement DateTime on top of JS Date
+- have them implement each other's interfaces
+- provide an implicit conversion
+
+
+### Map/Set and JS Map/Set
+
+At the very least, we'll provide `JSMap<K, V>` and `JSSet<T>` types in
+"package:js" that will implement the corresponding Dart interfaces and also be
+wrapperless JS Maps/Sets.
+
+Both web compilers already use (or have prototyped use of) ES6 Map/Set under
+some circumstances, such as identity Maps/Sets. So it may be possible to have
+the objects returned by `HashMap.identity()` and `HashSet.identity()` simply be
+JS Map/Set respectively. That would be a nice feature, but is not necessary
+to provide good interop with these types.
+
+Declaring a JS API as returning a Dart Map will be a hint, because it will
+probably not work the way the developer expects (if they are expecting a JS
+object to be interpreted as a Map). Instead they can:
+- use `JSMap<K, V>` if they intended the JS Map class.
+- use `JSObjectMap<K, V>` if the return value is a JS object. It's a normal Dart
+  class that implements Map and is backed by the JS Object. This indicates a
+  wrapping conversion.
+- use `@JSConvert()` to provide a custom conversion to Map
+- use some other JS class type, which declares the properties that the map
+  contains. Useful when a JS Object is returned, and the data is structured.
+
+Open question: are the generic type arguments to JSMap/JSSet reified if
+allocated in Dart? I think they should be, for consistency with `List<T>`.
+Similar to `List<T>` however, a `Map` allocated in JS could be cast to
+`JSMap<K, V>` for any types `K` and `V` that subtype `JSAny`.
+
+
+### Maps and JS Objects
+
+Converting arbitrary Dart maps to JS Objects is probably not feasible, for
+reasons discussed in "Data Type Interoperability". However we can provide
+a conversion: 
+
+```dart
+  external factory RecaptchaVerifier(container,
+      [@JSConvert(jsify) Map<String, Object> parameters, App app]);
+```
+
+The `jsify` function is declared by Firebase, and does a deep conversion based
+on the specific types Firebase APIs use. However most of that will no longer be
+necessary, so we might be able to get away with:
+
+```dart
+  external factory RecaptchaVerifier(container,
+      [@MapToJSObject() Map<String, Object> parameters, App app]);
+```
+
+This uses a built-in shallow conversion from a Dart Map to a JS object.
+
+
+#### Wrapper-based JSObjectMap
+
+To make it easier to work with JS objects via indexing, we could provide several
+classes in "package:js" to help:
+
+```dart
+@JS()
+@anonymous
+class JSIndexable<K extends Object, V extends Object> {
+  external V operator [](K key);
+  external void operator []=(K key, Object value);
+
+  Map<K2, V2> toMap<K2, V2>() => JSObjectMap(this);
+}
+
+/// Wraps a JS Object in a Dart Map.
+class JSObjectMap<K, V> with MapMixin<K, V> implements Map<K, V> {
+  final JSIndexable object;
+
+  JSObjectMap([Object object])
+      : object = object as JSIndexable ?? JSIndexable();
+
+  factory JSObjectMap.from(Map other) => JSObjectMap<K, V>()..addAll(other);
+  factory JSObjectMap.of(Map<K, V> other) = JSObjectMap.from;
+  factory JSObjectMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
+      JSObjectMap<K, V>()..addEntries(entries);
+
+  bool containsKey(Object key) => Reflect.has(object, key);
+  V operator [](Object key) => object[key];
+  void operator []=(Object key, value) {
+    object[key] = value;
+  }
+  List<K> get keys => Reflect.ownKeys(object) as List<K>;
+  V remove(Object key) {
+    if (Reflect.has(object, key)) {
+      var result = object[key];
+      Reflect.deleteProperty(object, key);
+      return result;
+    }
+    return null;
+  }
+  void clear() {
+    for (var key in Reflect.ownKeys(object)) {
+      Reflect.deleteProperty(object, key);
+    }
+  }
+}
+```
+
+Here `JSObjectMap` works like a normal Dart class, but it's easy to get the
+raw JS object from it. Meanwhile any JS object can be cast to `JSIndexable` to
+provide access to the index operators and the `toMap()` function.
+
+
+#### Autoboxing JSObjectMap
+
+
+*NOTE*: we probably won't want/need this, but I wanted to mention it as a
+possible optoon. It provides a means of implementing Dart interfaces from JS
+classes, that is reasonably friendly to optimizations.
+
+An alternative design for `JSObjectMap` is to work similarly to `JSIndexable`.
+This provides a Map-like view of an arbitrary JS object. Then the question
+becomes: how do we cast our type to a `Map<K, V>`? Autoboxing would allow us to
+do that.
+
+Here's a rough sketch:
+
+```dart
+@JS()
+@JSAutobox()
+class JSObjectMap<K, V> extends MapBase<K, V> {
+  factory JSObjectMap() => _create(null);
+  factory JSObjectMap.from(Map other) => _create<K, V>(null)..addAll(other);
+  factory JSObjectMap.of(Map<K, V> other) = JSObjectMap.from;
+  factory JSObjectMap.fromEntries(Iterable<MapEntry<K, V>> entries) =>
+      _create<K, V>(null)..addEntries(entries);
+
+  @JS('create')
+  external static JSObjectMap<K2, V2> _create<K2, V2>(Object proto);
+
+  external V operator [](Object key);
+  external void operator []=(Object key, Object value);
+  
+  bool containsKey(Object key) => Reflect.has(this, key);
+  List<K> get keys => Reflect.ownKeys(this) as List<K>;
+
+  V remove(Object key) {
+    if (Reflect.has(this, key)) {
+      var result = this[key];
+      Reflect.deleteProperty(this, key);
+      return result;
+    }
+    return null;
+  }
+
+  void clear() {
+    for (var key in Reflect.ownKeys(this)) {
+      Reflect.deleteProperty(this, key);
+    }
+  }
+}
+```
+
+Because this type uses `@JSAutobox()`, the JS object will be automatically
+boxed when cast to any Dart interface that it implements (except for dart:core
+Object). This reduces the boilerplate that might otherwise be required.
+
+The benefit of this approach is that any JS object can be freely cast to
+`JSObjectMap`, providing efficient access using Map-like APIs. For example,
+let's revist our `UserInfo.toJson()` example:
+
+```dart
+@JS()
+@anonymous
+class UserInfo {
+  // [...]
+  /// Returns a JSON-serializable representation of this object.
+  @JS('toJSON')
+  external JSObjectMap<String, dynamic> toJson();
+}
+
+// [code snippet from auth_test.dart]
+
+  test('toJson()', () async {
+    // [...]
+    var userMap = userCredential.user.toJson();
+    expect(userMap, isNotNull);
+    expect(userMap as Map, isNotEmpty); // [note: `as Map` was added]
+    expect(userMap["displayName"], "Other User");
+    expect(userMap["photoURL"], "http://google.com");
+    // [...]
+  });
+```
+
+Consider the line `expect(userMap as Map, isNotEmpty)` in this example.
+The `as Map` is necessary to trigger boxing, so the `isNotEmpty` matcher will
+work.
+
+Autoboxing would be a neat way to provide support for implementing Dart
+interfaces from JS. Autoboxing has proven useful in other languages for native
+interop. It may be useful for advanced JS interop scenarios, such as providing
+a dart:html-like API without JS dynamic/interface dispatch.
+
+
+## Less Static Interop
+
+### Virtual Dispatch
+
+In many cases JS interop can take advantage of virtual dispatch, even with
+`@sealed`, because the JS method it calls will dispatch with normal JS rules
+(i.e. lookup the property on the prototype chain). `@sealed` procludes overrides
+of itself with another Dart member, however.
+
+We support virtual Dart methods on JS types, with a bit more work. This doesn't
+compromise the model very much, but it does add additional dispatch cost.
+Implementing interfaces and dynamic dispatch would still be restricted.
+
+
+### Interface and Dynamic dispatch
+
+In the future, we may want to provide something like `@JSInterfaceDispatch()` or
+`@JSDynamicDispatch()`, that preserves RTTI and enables interface/dynamic
+dispatch. Our compilers already support this, as they use it themselves for core
+types in the SDK, and for the HTML libraries.
+
+There are several issues with exposing this:
+- extensions would now have to be globally unique for a given JS prototype.
+- this requires compile time checking (dart2js) or runtime checking (dartdevc).
+- it's possible to subvert compile time checking accidentally (if the same JS 
+  prototype is exposed with two different names).
+- we'd need to standardize the annotations between the compilers and ensure
+  they have the same semantics.
+
+Scoped extension method approaches for dynamic languages may help for the naming
+conflicts (e.g.
+[as discussed in this paper](https://arxiv.org/pdf/1708.01679.pdf)),
+but those have performance/complexity/usability tradeoffs.
+
+Many users have requested flags to disable dynamic dispatch, so this may not be
+the direction we need go. Implementing interfaces can be useful however.
+(The "autoboxing" approach discussed previously may be a possible compromise.)
+
+
+### JS Proxy
+
+One question that comes up occassionally is how to use JS Proxy from Dart.
+We can expose JSProxy from "package:js":
+
+```dart
+@JS('Proxy')
+class JSProxy {
+  external factory JSProxy(Object target, JSProxyHadler handler);
+}
+
+@JS()
+@anonymous
+abstract class JSProxyHandler {
+  // Note: these are defined as field to allow only a subset of them to be
+  // implemented
+  @JS()
+  Object Function(Object target) getPrototypeOf;
+
+  @JS()
+  Object Function(Object target, Object proto) setPrototypeOf;
+
+  // [...]
+
+  @JS()
+  bool Function(Object target, Object key) has;
+
+  @JS()
+  Object Function(Object target, Object key) get;
+
+  @JS()
+  Object Function(Object target, Object key, Object value) set;
+
+  @JS()
+  bool Function(Object target, Object key) deleteProperty;
+
+  external factory JSProxyHandler({
+      this.getPrototypeOf,
+      this.setPrototypeOf,
+      this.get,
+      this.set,
+      this.has,
+      this.deleteProperty /* [...] */});
+}
+```
+
+It's possible to implement a proxy handler that forwards to Dart's
+noSuchMethod, or the reverse, if someone wanted to do that.
+
+(It's also possible to have a noSuchMethod that uses JS Reflect and Object APIs
+to access the JS object. It's not necessary though, because `@JS()` classes are
+essentially a more optimized form of that.)
+
+
+### JS Reflection
+
+JS Reflection APIs are useful for low level support, and these can be provided
+by "package:js":
+
+```dart
+@JS('Reflect')
+class JSReflect {
+  external static Object apply(target, thisArgument, argumentsList);
+  external static Object construct(target, argumentsList, [newTarget]);
+  external static bool defineProperty(
+      target, propertyKey, PropertyDescriptor attributes);
+  external static bool deleteProperty(target, propertyKey, [receiver]);
+  external static Object get(target, propertyKey);
+  external static PropertyDescriptor getOwnPropertyDescriptor(
+      target, propertyKey);
+  external static Object getPrototypeOf(target);
+  external static bool has(target, propertyKey);
+  external static bool isExtensible(target);
+  external static List<Object> ownKeys(target);
+  external static void preventExtensions();
+  external static set(target, propertyKey, value, [receiver]);
+  external static setPrototypeOf(target, prototype);
+
+  static bool hasOwnProperty(target, propertyKey) {
+    // Note: could also be implemented using `getOwnPropertyDescriptor`
+    return _JSObject.prototype.hasOwnProperty(target, propertyKey);
+  }
+
+  static Object getOwnProperty(target, propertyKey) {
+    var desc = getOwnPropertyDescriptor(target, propertyKey);
+    if (desc == null) return null;
+    if (desc.get != null) return desc.get(target);
+    return desc.value;
+  }
+}
+
+@JS('Object')
+abstract class _JSObject {
+  external static _JSObjectPrototype prototype;
+}
+
+@JS()
+@anonymous
+abstract class _JSObjectPrototype {
+  external static bool hasOwnProperty(@JSThis() target, propertyKey);
+}
+
+@JS()
+@anonymous
+class PropertyDescriptor {
+  Object value;
+  bool writable;
+  bool configurable;
+  bool enumerable;
+  Object Function(@JSThis() Object) get;
+  void Function(@JSThis() Object, Object) set;
+}
+```
+
+
+## Exporting Dart to JS
+
+Dart functions and accessors can be exported to JS with `@JSExport`. A compiler
+must provide a version of the function that is callable via the JS interop
+calling conventions described earlier, and ensure that version of the function
+is used when it is passed to JavaScript. (It may have other versions of the
+function that use optimized, dart-specific calling conventions.)
+
+
+### Exporting classes and libraries
+
+This will use `@JSExport` similar to top-level functions/accessors.
+
+TODO: more details here
+
+### Inheritance between Dart and JS
+
+Conceptually extending a JS class from Dart is similar to adding methods,
+because `super` calls are statically dispatched. The tricky part is what to do
+with constructors. JS constructors are normally written as `external factory`
+which precludes extending them. Also there are some notable differences in
+field initialization+super constructor call order between Dart and JS.
+
+(JS requires super before initializing fields, Dart requires super after
+initializing final fields. Dart's approach is nice because it prevents
+virtual methods from observing uninitialized state. But for interop, the problem
+is that the two orders are incompatible.)
+
+We may be able to provide a method that creates your class:
+
+```dart
+class MyDartClass extends TheirJSClass {
+  final int x = 1;
+  int y, z;
+  factory MyDartClass(int y, int z) {
+    // super constructpr parameters passed here?
+    var self = createJS<MyDartClass>(); 
+    self.y = y;
+    self.z = z;
+    return self;
+  }
+  // ...
+}
+```
+
+It's not the most satisfying solution, but it seems like a relatively easy way
+to support this.
+
+TODO: extending a Dart class from JS
+
+
+### Interop with JS Modules
+
+We'll need a way to declare a JS interop library corresponds to a JS module.
+This could be done on the library tag:
+
+```dart
+@JSImport('goog.editor', moduleFormat: 'closure')
+library goog.editor;
+```
+
+The compiler can then generate the appropriate import, instead of a global
+reference. This will need to be coordinated with the overall build and server
+system, however, to ensure the JS module is available to the module loader
+(requirejs, ES6 imports, etc).
+
+Typically the module format will be assumed to be passed in globally to the
+compiler, as there is generally one standardized module format, so that argument
+won't be present. (Closure library is illustrated here as it can be used in
+addition to other formats, it may be useful to tell the compiler "this module
+is definitely a closure namespace, import it as such".)
+
+
+### Exposing JS Methods as Getters
+
+One common pattern that comes up is converting "getX" methods into "get X"
+getters. We could add `@JSMethod` syntactic sugar to simplify that.
+Consider this prior example of a Google Maps API:
+
+```dart
+  LatLng get center => _getCenter();
+  LatLng get northEast => _getNorthEast();
+  LatLng get southWest => _getSouthWest();
+  bool get isEmpty => _isEmpty();
+
+  @JS('getCenter')
+  external LatLng _getCenter();
+  @JS('getNorthEast')
+  external LatLng _getNorthEast();
+  @JS('getSouthWest')
+  external LatLng _getSouthWest();
+  @JS('isEmpty')
+  external bool _isEmpty();
+```
+
+It could be written as:
+
+```dart
+  @JSMethod('getCenter')
+  external LatLng get center;
+
+  @JSMethod('getNorthEast')
+  external LatLng get northEast;
+
+  @JSMethod('getSouthWest')
+  external LatLng get southWest;
+
+  @JSMethod('isEmpty')
+  external bool get isEmpty;
+```
+
+## JS Types in the Dart Type System
+
+As discussed earlier, at runtime the absence of reified type information will be
+tracked with a `JSAny` type. `JSAny` can contain types that may originate from
+JS, and it only exists at run time. Here are some examples:
+
+```dart
+import 'package:firebase/firebase.dart' show App, Database;
+import 'package:firebase/firebase.dart' as firebase;
+main() {
+  List apps = firebase.apps;
+  apps is List<Object>      // true: Object can hold JS types
+  apps is List<int>         // true: `int` could be from JS
+  apps is List<List>        // true: `List` could be from JS
+  apps is List<Database>    // true: could be a list of any JS interop types
+  apps is List<MyDartClass> // false: can't be a Dart class
+  apps is List<Stopwatch>   // false: can't be a Dart class like Stopwatch
+}
+```
+
+We'll probably want to provide access to JS `typeof` and `instanceof` as library
+functions in "package:js".
+
+The proposed typing rules for JSAny allow it assigned to/from these types:
+- primitives: Null | bool | int | num | double | String
+- JS interop classes (`@JS()`)
+- Dart classes exported to JS (`@JSExport()`)
+- `List<JSAny>`
+- other "native" SDK types
+- functions (restrict to JSAny param/return types?)
+
+This type will not exist in the static type system. The hope is that these
+restrictions keep the unsoundness restricted to objects allocated from JS, and
+to types that are likely to be used by existing JS APIs. By excluding Dart
+classes, we're able to catch things like `List<JSAny>` assigned to
+`List<MyDartClass>`, which is unlikely to work.
+
+Open question: should preserve reified JSAny if that type parameter is used to
+construct other types? For example:
+
+```dart
+@JS()
+external List foo();
+bar() {
+  var list = foo();
+  var set = list.toSet() as Set<int>; // does this work?
+  // ...
+}
+```
+
+
+## Implementation Roadmap
+
+Here's a rough breakdown of the features into different categories.
+Details subject to change. The items are not in any particular order.
+
+Required features (P0):
+- static dispatch (with rename support)
+- static type checking rules (warnings/errors for incorrect usage)
+- runtime type checking rules
+- conversions for builtin types:
+  - Functions
+  - Dart Map to/from JS Object
+  - Future/Promise
+- calling conventions for optional arguments, "this"
+- exporting top-level functions, accessors to JS
+
+Important features (P1):
+- user defined conversions
+- conversions for types (e.g. DateTime, Iterables)
+- named arguments
+- exporting classes/members to JS
+- package:js helper library
+  - common conversion functions, e.g. jsify/dartify
+  - predefined interop for core JS types like Set/Map
+- extension fields
+
+Nice to have features (P2):
+- helpers for common callback-to-stream patterns
+- other helpers like `@JSMethod`
+- autoboxing to implement Dart interfaces(?)
+
+Features for building "package:html" (P2?):
+- virtual dispatch for JS classes
+- subtyping Dart classes from JS
+- subtyping JS classes from Dart
+- interface dispatch for JS classes (useful for migrating to package:html)
+- dynamic dispatch for JS classes (useful for migrating to package:html)
+
+
+## Compatibility and Evolution
+
+Most of the features described here are backwards compatible, relative to the
+set of JS interop supported by both web compilers.
+
+One question that came up is interfaces: currently JS interop classes can be
+implemented by Dart classes (although this may lead to inconsistent behavior
+between the compilers). If `@sealed` Dart members are added to a JS interop
+class, then it won't be legal to implement that as an interface. But this is a
+new feature, so it's only "breaking" in the sense that adding `@sealed` members
+is a breaking change for the package API. (Technically: adding *any* public
+member to a Dart class is a breaking change, for this reason. In practice many
+types are not intended to be used as interfaces, so they don't treat new members
+as breaking).
+
+If we discover something that is too backwards incompatible, we can add new
+annotations and leave the current behavior for the existing ones. Or we can
+bump the major version on "package:js". There's a lot of possibilities.
+
+
+## FAQ
+
+### Q: How does JSON work?
+
+A: If the JSON is relatively typed, then it can be 
+
+
+### Q: Would new Dart language features help?
+
+A: Yes! All of these features would be helpful:
+- extension methods/members
+- extension types
+- implicit conversions
+- autoboxing
+- non-null
+- generalized typedefs
+- `external` on fields (sugar for external getter/setter)
+
+In the meantime, this proposal provides a way to improve interop, and is
+intended to be compatible with those features.
+
+
+### Q: Can dart2js and dartdevc share implementation for JS interop?
+
+A: Probably, especially for the static features.
+
+If both compilers are exclusively using Kernel, much of this can
+be implemented as a Kernel transform. The static checking can also be done in
+a shared way.
+
+Dynamic dispatch, calling conventions, and runtime type checks, and native SDK
+types are different between the two compilers, so those details would require
+separete work.
+
+
+### Q: If a JS API returns "Object" does this break dart2js tree shaking?
+
+A: It does not. Dart classes can be tree-shaken, unless they're explicitly
+exported to JS. Static dispatch members can be tree shaken. Static JS Interop
+types, by design, do not require any runtime type information (RTTI).
+Opt-in features like interface or dynamic dispatch will cause more RTTI to be
+retained.
+
+This question may be referring to "dart:html". It supports dynamic dispatch, and
+this causes RTTI to be retained, unless great care is taken on the part
+of dart:html authors (to carefully annotate return types, and avoid untyped
+results) and by developers (to carefully avoid dynamic calls that use names in
+"dart:html", and to avoid JS interop features that could return HTML elements).
+
+We may be able to find a better solution, such a providing new "package:html"
+bindings that are mostly static (and using interface/dynamic dispatch sparingly,
+in places where it's really needed).
+
+
+### Q: Could we use dynamic interop instead?
+
+A: It's certainly possible to imagine interop that works "like JS"
+(example from Closure Library's
+[goog.editor Example](https://github.com/google/closure-library/blob/master/closure/goog/demos/editor/editor.html#L84)):
+
+```dart
+// Hypothetical dynamic interop
+dynamic goog = window.goog;
+dynamic myField = goog.editor.Field.new('editMe');
+
+// Create and register all of the editing plugins you want to use.
+myField.registerPlugin(goog.editor.plugins.BasicTextFormatter.new());
+```
+
+The problem is it'll run into the same issues around data type conversions, but
+it won't be able to address them without wrapper classes. As illustrated by the
+".new" it will never be as simple as copying and pasting JS code, and there
+won't be any tooling to help.
+
+What we may want to do is provide a way to write small chunk of JS code (in a
+Dart file), similar to GWT. But that shouldn't be used much, with the
+improvements in this proposal to calling conventions and easy ways to access
+properties on JS objects.
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index 157aa9c..3fe69da 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -37,6 +37,7 @@
       negatable: false,
       help: 'Be verbose (e.g. prints transformed main library).',
       defaultsTo: false)
+  ..addMultiOption('define', abbr: 'D', splitCommas: false)
   ..addMultiOption('embedder-entry-points-manifest',
       help: 'A path to a file describing entrypoints '
           '(lines of the form `<library>,<class>,<member>`).')
@@ -69,6 +70,21 @@
   var format = options['format'];
   var verbose = options['verbose'];
 
+  Map<String, String> defines = <String, String>{};
+  for (String define in options['define']) {
+    int index = define.indexOf('=');
+    String name;
+    String expression;
+    if (index != -1) {
+      name = define.substring(0, index);
+      expression = define.substring(index + 1);
+    } else {
+      name = define;
+      expression = define;
+    }
+    defines[name] = expression;
+  }
+
   if (output == null) {
     output = '${input.substring(0, input.lastIndexOf('.'))}.transformed.dill';
   }
@@ -94,14 +110,9 @@
       component = coq.transformComponent(coreTypes, component);
       break;
     case 'constants':
-      // We use the -D defines supplied to this VM instead of explicitly using a
-      // constructed map of constants.
-      final Map<String, String> defines = null;
-      final VmConstantsBackend backend =
-          new VmConstantsBackend(defines, coreTypes);
+      final VmConstantsBackend backend = new VmConstantsBackend(coreTypes);
       component = constants.transformComponent(
-          component, backend, const constants.SimpleErrorReporter(),
-          legacyMode: true);
+          component, backend, defines, const constants.SimpleErrorReporter());
       break;
     case 'treeshake':
       component = treeshaker.transformComponent(coreTypes, hierarchy, component,
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 9408027..8ea99dc 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -1,3 +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.
+-->
+
 This file describes the binary format of Dart Kernel.
 
 Notation
@@ -131,7 +137,8 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 16;
+  UInt32 formatVersion = 18;
+  List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
   UriSource sourceMap;
   List<CanonicalName> canonicalNames;
@@ -214,11 +221,12 @@
 }
 
 type Library {
-  Byte flags (isExternal);
+  Byte flags (isExternal, isSynthetic);
   CanonicalNameReference canonicalName;
   StringReference name;
   // An absolute path URI to the .dart file from which the library was created.
   UriReference fileUri;
+  List<String> problemsAsJson; // Described in problems.md.
   List<Expression> annotations;
   List<LibraryDependency> libraryDependencies;
   List<CanonicalNameReference> additionalExports;
@@ -926,26 +934,8 @@
   DartType type;
 }
 
-type EnvironmentBoolConstant extends Constant {
-  Byte tag = 12;
-  StringReference name;
-  ConstantReference defaultValue;
-}
-
-type EnvironmentIntConstant extends Constant {
-  Byte tag = 13;
-  StringReference name;
-  ConstantReference defaultValue;
-}
-
-type EnvironmentStringConstant extends Constant {
-  Byte tag = 14;
-  StringReference name;
-  ConstantReference defaultValue;
-}
-
 type UnevaluatedConstant extends Constant {
-  Byte tag = 15;
+  Byte tag = 12;
   Expression expression;
 }
 
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 2bddaf9..d738ec5 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -155,6 +155,8 @@
 
   Component get enclosingComponent => parent?.enclosingComponent;
 
+  Library get enclosingLibrary => parent?.enclosingLibrary;
+
   /// Returns the best known source location of the given AST node, or `null` if
   /// the node is orphaned.
   ///
@@ -278,6 +280,11 @@
   /// The URI of the source file this library was loaded from.
   Uri fileUri;
 
+  static const int ExternalFlag = 1 << 0;
+  static const int SyntheticFlag = 1 << 1;
+
+  int flags = 0;
+
   /// If true, the library is part of another build unit and its contents
   /// are only partially loaded.
   ///
@@ -287,10 +294,26 @@
   ///
   /// If the library is non-external, then its classes are at [ClassLevel.Body]
   /// and all members are loaded.
-  bool isExternal;
+  bool get isExternal => (flags & ExternalFlag) != 0;
+  void set isExternal(bool value) {
+    flags = value ? (flags | ExternalFlag) : (flags & ~ExternalFlag);
+  }
+
+  /// If true, the library is synthetic, for instance library that doesn't
+  /// represents an actual file and is created as the result of error recovery.
+  bool get isSynthetic => flags & SyntheticFlag != 0;
+  void set isSynthetic(bool value) {
+    flags = value ? (flags | SyntheticFlag) : (flags & ~SyntheticFlag);
+  }
 
   String name;
 
+  /// Problems in this [Library] encoded as json objects.
+  ///
+  /// Note that this field can be null, and by convention should be null if the
+  /// list is empty.
+  List<String> problemsAsJson;
+
   @nocoq
   final List<Expression> annotations;
 
@@ -312,7 +335,7 @@
 
   Library(this.importUri,
       {this.name,
-      this.isExternal: false,
+      bool isExternal: false,
       List<Expression> annotations,
       List<LibraryDependency> dependencies,
       List<LibraryPart> parts,
@@ -330,6 +353,7 @@
         this.procedures = procedures ?? <Procedure>[],
         this.fields = fields ?? <Field>[],
         super(reference) {
+    this.isExternal = isExternal;
     setParents(this.dependencies, this);
     setParents(this.parts, this);
     setParents(this.typedefs, this);
@@ -444,6 +468,8 @@
   Location _getLocationInEnclosingFile(int offset) {
     return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
+
+  Library get enclosingLibraray => this;
 }
 
 /// An import or export declaration in a library.
@@ -5104,6 +5130,10 @@
 
   /// Gets the type of this constant.
   DartType getType(TypeEnvironment types);
+
+  Expression asExpression() {
+    return new ConstantExpression(this);
+  }
 }
 
 abstract class PrimitiveConstant<T> extends Constant {
@@ -5296,7 +5326,7 @@
 
   InstanceConstant(this.classReference, this.typeArguments, this.fieldValues);
 
-  Class get klass => classReference.asClass;
+  Class get classNode => classReference.asClass;
 
   visitChildren(Visitor v) {
     classReference.asClass.acceptReference(v);
@@ -5344,7 +5374,7 @@
   }
 
   DartType getType(TypeEnvironment types) =>
-      new InterfaceType(klass, typeArguments);
+      new InterfaceType(classNode, typeArguments);
 }
 
 class PartialInstantiationConstant extends Constant {
@@ -5440,56 +5470,12 @@
   DartType getType(TypeEnvironment types) => types.typeType;
 }
 
-abstract class EnvironmentConstant extends Constant {
-  final String name;
-  final Constant defaultValue;
-
-  EnvironmentConstant(this.name, this.defaultValue);
-  visitChildren(Visitor v) {
-    defaultValue.acceptReference(v);
-  }
-}
-
-class EnvironmentBoolConstant extends EnvironmentConstant {
-  EnvironmentBoolConstant(String name, Constant defaultValue)
-      : super(name, defaultValue);
-
-  accept(ConstantVisitor v) => v.visitEnvironmentBoolConstant(this);
-  acceptReference(Visitor v) {
-    return v.visitEnvironmentBoolConstantReference(this);
-  }
-
-  DartType getType(TypeEnvironment types) => types.boolType;
-}
-
-class EnvironmentIntConstant extends EnvironmentConstant {
-  EnvironmentIntConstant(String name, Constant defaultValue)
-      : super(name, defaultValue);
-
-  accept(ConstantVisitor v) => v.visitEnvironmentIntConstant(this);
-  acceptReference(Visitor v) {
-    return v.visitEnvironmentIntConstantReference(this);
-  }
-
-  DartType getType(TypeEnvironment types) => types.intType;
-}
-
-class EnvironmentStringConstant extends EnvironmentConstant {
-  EnvironmentStringConstant(String name, Constant defaultValue)
-      : super(name, defaultValue);
-
-  accept(ConstantVisitor v) => v.visitEnvironmentStringConstant(this);
-  acceptReference(Visitor v) {
-    return v.visitEnvironmentStringConstantReference(this);
-  }
-
-  DartType getType(TypeEnvironment types) => types.stringType;
-}
-
 class UnevaluatedConstant extends Constant {
   final Expression expression;
 
-  UnevaluatedConstant(this.expression);
+  UnevaluatedConstant(this.expression) {
+    expression?.parent = null;
+  }
 
   visitChildren(Visitor v) {
     expression.accept(v);
@@ -5499,6 +5485,9 @@
   acceptReference(Visitor v) => v.visitUnevaluatedConstantReference(this);
 
   DartType getType(TypeEnvironment types) => expression.getStaticType(types);
+
+  @override
+  Expression asExpression() => expression;
 }
 
 // ------------------------------------------------------------------------
@@ -5509,6 +5498,12 @@
 class Component extends TreeNode {
   final CanonicalName root;
 
+  /// Problems in this [Component] encoded as json objects.
+  ///
+  /// Note that this field can be null, and by convention should be null if the
+  /// list is empty.
+  List<String> problemsAsJson;
+
   final List<Library> libraries;
 
   /// Map from a source file URI to a line-starts table and source code.
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 59148f3..cc11d87 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -270,18 +270,6 @@
       case ConstantTag.TypeLiteralConstant:
         final DartType type = readDartType();
         return new TypeLiteralConstant(type);
-      case ConstantTag.EnvironmentBoolConstant:
-        final String name = readStringReference();
-        final Constant defaultValue = readConstantReference();
-        return new EnvironmentBoolConstant(name, defaultValue);
-      case ConstantTag.EnvironmentIntConstant:
-        final String name = readStringReference();
-        final Constant defaultValue = readConstantReference();
-        return new EnvironmentIntConstant(name, defaultValue);
-      case ConstantTag.EnvironmentStringConstant:
-        final String name = readStringReference();
-        final Constant defaultValue = readConstantReference();
-        return new EnvironmentStringConstant(name, defaultValue);
       case ConstantTag.UnevaluatedConstant:
         final Expression expression = readExpression();
         return new UnevaluatedConstant(expression);
@@ -624,6 +612,12 @@
       throw InvalidKernelVersionError(formatVersion);
     }
 
+    List<String> problemsAsJson = readListOfStrings();
+    if (problemsAsJson != null) {
+      component.problemsAsJson ??= <String>[];
+      component.problemsAsJson.addAll(problemsAsJson);
+    }
+
     // Read component index from the end of this ComponentFiles serialized data.
     _ComponentIndex index = _readComponentIndex(componentFileSize);
 
@@ -659,6 +653,19 @@
     _byteOffset = _componentStartOffset + componentFileSize;
   }
 
+  /// Read a list of strings. If the list is empty, [null] is returned.
+  List<String> readListOfStrings() {
+    int length = readUInt();
+    if (length == 0) return null;
+    List<String> strings =
+        new List<String>.filled(length, null, growable: true);
+    for (int i = 0; i < length; i++) {
+      String s = const Utf8Decoder().convert(readByteList());
+      strings[i] = s;
+    }
+    return strings;
+  }
+
   Map<Uri, Source> readUriToSource() {
     int length = readUint32();
 
@@ -778,7 +785,7 @@
     _byteOffset = savedByteOffset;
 
     int flags = readByte();
-    bool isExternal = (flags & 0x1) != 0;
+    bool isExternal = (flags & Library.ExternalFlag) != 0;
     _isReadingLibraryImplementation = !isExternal;
     var canonicalName = readCanonicalNameReference();
     Reference reference = canonicalName.getReference();
@@ -795,10 +802,13 @@
     // TODO(jensj): We currently save (almost the same) uri twice.
     Uri fileUri = readUriReference();
 
+    List<String> problemsAsJson = readListOfStrings();
+
     if (shouldWriteData) {
-      library.isExternal = isExternal;
+      library.flags = flags;
       library.name = name;
       library.fileUri = fileUri;
+      library.problemsAsJson = problemsAsJson;
     }
 
     assert(() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 2e5bb5d..1b945ba 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -221,7 +221,7 @@
       constant.entries.forEach(writeConstantReference);
     } else if (constant is InstanceConstant) {
       writeByte(ConstantTag.InstanceConstant);
-      writeClassReference(constant.klass);
+      writeClassReference(constant.classNode);
       writeUInt30(constant.typeArguments.length);
       constant.typeArguments.forEach(writeDartType);
       writeUInt30(constant.fieldValues.length);
@@ -243,18 +243,6 @@
     } else if (constant is TypeLiteralConstant) {
       writeByte(ConstantTag.TypeLiteralConstant);
       writeDartType(constant.type);
-    } else if (constant is EnvironmentBoolConstant) {
-      writeByte(ConstantTag.EnvironmentBoolConstant);
-      writeStringReference(constant.name);
-      writeConstantReference(constant.defaultValue);
-    } else if (constant is EnvironmentIntConstant) {
-      writeByte(ConstantTag.EnvironmentIntConstant);
-      writeStringReference(constant.name);
-      writeConstantReference(constant.defaultValue);
-    } else if (constant is EnvironmentStringConstant) {
-      writeByte(ConstantTag.EnvironmentStringConstant);
-      writeStringReference(constant.name);
-      writeConstantReference(constant.defaultValue);
     } else if (constant is UnevaluatedConstant) {
       writeByte(ConstantTag.UnevaluatedConstant);
       writeNode(constant.expression);
@@ -526,6 +514,7 @@
     final componentOffset = getBufferOffset();
     writeUInt32(Tag.ComponentFile);
     writeUInt32(Tag.BinaryFormatVersion);
+    writeListOfStrings(component.problemsAsJson);
     indexLinkTable(component);
     _collectMetadata(component);
     if (_metadataSubsections != null) {
@@ -547,6 +536,18 @@
     _flush();
   }
 
+  void writeListOfStrings(List<String> strings) {
+    writeUInt30(strings?.length ?? 0);
+    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));
+      }
+    }
+  }
+
   /// Collect non-empty metadata repositories associated with the component.
   void _collectMetadata(Component component) {
     component.metadata.forEach((tag, repository) {
@@ -882,10 +883,11 @@
   void visitLibrary(Library node) {
     insideExternalLibrary = node.isExternal;
     libraryOffsets.add(getBufferOffset());
-    writeByte(insideExternalLibrary ? 1 : 0);
+    writeByte(node.flags);
     writeNonNullCanonicalNameReference(getCanonicalNameOfLibrary(node));
     writeStringReference(node.name ?? '');
     writeUriReference(node.fileUri);
+    writeListOfStrings(node.problemsAsJson);
     enterScope(memberScope: true);
     writeAnnotationList(node.annotations);
     writeLibraryDependencies(node);
@@ -2063,39 +2065,6 @@
   }
 
   @override
-  void visitEnvironmentBoolConstant(EnvironmentBoolConstant node) {
-    throw new UnsupportedError('serialization of EnvironmentBoolConstants');
-  }
-
-  @override
-  void visitEnvironmentBoolConstantReference(EnvironmentBoolConstant node) {
-    throw new UnsupportedError(
-        'serialization of EnvironmentBoolConstant references');
-  }
-
-  @override
-  void visitEnvironmentIntConstant(EnvironmentIntConstant node) {
-    throw new UnsupportedError('serialization of EnvironmentIntConstants');
-  }
-
-  @override
-  void visitEnvironmentIntConstantReference(EnvironmentIntConstant node) {
-    throw new UnsupportedError(
-        'serialization of EnvironmentIntConstant references');
-  }
-
-  @override
-  void visitEnvironmentStringConstant(EnvironmentStringConstant node) {
-    throw new UnsupportedError('serialization of EnvironmentStringConstants');
-  }
-
-  @override
-  void visitEnvironmentStringConstantReference(EnvironmentStringConstant node) {
-    throw new UnsupportedError(
-        'serialization of EnvironmentStringConstant references');
-  }
-
-  @override
   void visitFieldReference(Field node) {
     throw new UnsupportedError('serialization of Field references');
   }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 6a34a73..280454f 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -137,7 +137,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 = 16;
+  static const int BinaryFormatVersion = 18;
 }
 
 abstract class ConstantTag {
@@ -153,8 +153,5 @@
   static const int PartialInstantiationConstant = 9;
   static const int TearOffConstant = 10;
   static const int TypeLiteralConstant = 11;
-  static const int EnvironmentBoolConstant = 12;
-  static const int EnvironmentIntConstant = 13;
-  static const int EnvironmentStringConstant = 14;
-  static const int UnevaluatedConstant = 15;
+  static const int UnevaluatedConstant = 12;
 }
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 9fa31ec..51f0730 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -34,6 +34,8 @@
   void set onAmbiguousSupertypes(
       HandleAmbiguousSupertypes onAmbiguousSupertypes);
 
+  void set mixinInferrer(MixinInferrer mixinInferrer);
+
   /// Given the [unordered] classes, return them in such order that classes
   /// occur after their superclasses.  If some superclasses are not in
   /// [unordered], they are not included.
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 9df95ca..ddc4aac 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -33,6 +33,11 @@
     'dart:async': [
       'Future',
       'Stream',
+    ],
+    'dart:ffi': [
+      'DynamicLibrary',
+      'Pointer',
+      'Struct',
     ]
   };
 
@@ -93,10 +98,97 @@
   Class _pragmaClass;
   Field _pragmaName;
   Field _pragmaOptions;
+  Constructor _pragmaConstructor;
+
+  Library _ffiLibrary;
+  Class _ffiPointerClass;
+  Procedure _ffiPointerLoadProcedure;
+  Procedure _ffiPointerStoreProcedure;
+  Procedure _ffiPointerCastProcedure;
+  Procedure _ffiPointerOffsetByProcedure;
+  Procedure _ffiPointerAsFunctionProcedure;
+  Field _ffiStructField;
+  Class _ffiDynamicLibraryClass;
+  Procedure _ffiDynamicLibraryLookupFunctionProcedure;
+  Procedure _ffiAllocateProcedure;
+  Procedure _ffiSizeOfProcedure;
+  Procedure _ffiFromFunctionProcedure;
+  Class _ffiNativeFunctionClass;
 
   CoreTypes(Component component)
       : index = new LibraryIndex.coreLibraries(component);
 
+  Library get ffiLibrary {
+    return _ffiLibrary ??= index.getLibrary('dart:ffi');
+  }
+
+  Class get ffiPointerClass {
+    return _ffiPointerClass ??= index.getClass('dart:ffi', 'Pointer');
+  }
+
+  Procedure get ffiPointerLoadProcedure {
+    return _ffiPointerLoadProcedure ??=
+        index.getMember('dart:ffi', 'Pointer', 'load');
+  }
+
+  Procedure get ffiPointerStoreProcedure {
+    return _ffiPointerStoreProcedure ??=
+        index.getMember('dart:ffi', 'Pointer', 'store');
+  }
+
+  Procedure get ffiPointerCastProcedure {
+    return _ffiPointerCastProcedure ??=
+        index.getMember('dart:ffi', 'Pointer', 'cast');
+  }
+
+  Procedure get ffiPointerOffsetByProcedure {
+    return _ffiPointerOffsetByProcedure ??=
+        index.getMember('dart:ffi', 'Pointer', 'offsetBy');
+  }
+
+  Procedure get ffiPointerAsFunctionProcedure {
+    return _ffiPointerAsFunctionProcedure ??=
+        index.getMember('dart:ffi', 'Pointer', 'asFunction');
+  }
+
+  Field get ffiStructField {
+    return _ffiStructField ??= index.getTopLevelMember('dart:ffi', 'struct');
+  }
+
+  Class get ffiDynamicLibraryClass {
+    return _ffiDynamicLibraryClass ??=
+        index.getClass('dart:ffi', 'DynamicLibrary');
+  }
+
+  Procedure get ffiDynamicLibraryLookupFunctionProcedure {
+    return _ffiDynamicLibraryLookupFunctionProcedure ??=
+        index.getMember('dart:ffi', 'DynamicLibrary', 'lookupFunction');
+  }
+
+  Procedure get ffiAllocateProcedure {
+    return _ffiAllocateProcedure ??=
+        index.getTopLevelMember('dart:ffi', 'allocate');
+  }
+
+  Procedure get ffiSizeOfProcedure {
+    return _ffiSizeOfProcedure ??=
+        index.getTopLevelMember('dart:ffi', 'sizeOf');
+  }
+
+  Procedure get ffiFromFunctionProcedure {
+    return _ffiFromFunctionProcedure ??=
+        index.getTopLevelMember('dart:ffi', 'fromFunction');
+  }
+
+  Class get ffiNativeFunctionClass {
+    return _ffiNativeFunctionClass ??=
+        index.getClass('dart:ffi', 'NativeFunction');
+  }
+
+  Class ffiNativeTypeClass(String name) {
+    return index.getClass('dart:ffi', name);
+  }
+
   Procedure get asyncErrorWrapperHelperProcedure {
     return _asyncErrorWrapperHelperProcedure ??=
         index.getTopLevelMember('dart:async', '_asyncErrorWrapperHelper');
@@ -204,11 +296,12 @@
   }
 
   Class get futureClass {
-    return _futureClass ??= index.getClass('dart:async', 'Future');
+    return _futureClass ??= index.getClass('dart:core', 'Future');
   }
 
   Class get futureOrClass {
-    return _futureOrClass ??= index.getClass('dart:async', 'FutureOr');
+    return _futureOrClass ??= (index.tryGetClass('dart:core', 'FutureOr') ??
+        index.getClass('dart:async', 'FutureOr'));
   }
 
   Procedure get identicalProcedure {
@@ -311,12 +404,16 @@
     return _pragmaOptions ??= index.getMember('dart:core', 'pragma', 'options');
   }
 
+  Constructor get pragmaConstructor {
+    return _pragmaConstructor ??= index.getMember('dart:core', 'pragma', '_');
+  }
+
   Class get stackTraceClass {
     return _stackTraceClass ??= index.getClass('dart:core', 'StackTrace');
   }
 
   Class get streamClass {
-    return _streamClass ??= index.getClass('dart:async', 'Stream');
+    return _streamClass ??= index.getClass('dart:core', 'Stream');
   }
 
   Member get streamIteratorSubscription {
diff --git a/pkg/kernel/lib/external_name.dart b/pkg/kernel/lib/external_name.dart
index 4da52a8..2646fc4 100644
--- a/pkg/kernel/lib/external_name.dart
+++ b/pkg/kernel/lib/external_name.dart
@@ -27,7 +27,7 @@
     } else if (annotation is ConstantExpression) {
       final constant = annotation.constant;
       if (constant is InstanceConstant) {
-        if (_isExternalName(constant.klass)) {
+        if (_isExternalName(constant.classNode)) {
           return (constant.fieldValues.values.single as StringConstant).value;
         }
       }
diff --git a/pkg/kernel/lib/library_index.dart b/pkg/kernel/lib/library_index.dart
index 0f5ab16..abebaa4 100644
--- a/pkg/kernel/lib/library_index.dart
+++ b/pkg/kernel/lib/library_index.dart
@@ -141,6 +141,12 @@
       for (var class_ in library.classes) {
         _classes[class_.name] = new _MemberTable(this, class_);
       }
+      for (Reference reference in library.additionalExports) {
+        NamedNode node = reference.node;
+        if (node is Class) {
+          _classes[node.name] = new _MemberTable(this, node);
+        }
+      }
     }
     return _classes;
   }
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 5dc341f..a165582 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -351,7 +351,10 @@
   }
   for (int i = 0; i < arguments.length; ++i) {
     DartType argument = arguments[i];
-    if (argument is FunctionType && argument.typeParameters.length > 0) {
+    if (argument is TypeParameterType && argument.promotedBound != null) {
+      result ??= <TypeArgumentIssue>[];
+      result.add(new TypeArgumentIssue(argument, parameters[i], null));
+    } else if (argument is FunctionType && argument.typeParameters.length > 0) {
       // Generic function types aren't allowed as type arguments either.
       result ??= <TypeArgumentIssue>[];
       result.add(new TypeArgumentIssue(argument, parameters[i], null));
@@ -451,3 +454,59 @@
   return type is InterfaceType &&
       type.classNode == typeEnvironment.nullType.classNode;
 }
+
+// Value set for variance of a type parameter X in a type term T.
+class Variance {
+  // Used when X does not occur free in T.
+  static const int unrelated = 0;
+
+  // Used when X occurs free in T, and U <: V implies [U/X]T <: [V/X]T.
+  static const int covariant = 1;
+
+  // Used when X occurs free in T, and U <: V implies [V/X]T <: [U/X]T.
+  static const int contravariant = 2;
+
+  // Used when there exists a pair U and V such that U <: V, but [U/X]T and
+  // [V/X]T are incomparable.
+  static const int invariant = 3;
+
+  // Variance values form a lattice where [unrelated] is the top, [invariant]
+  // is the bottom, and [covariant] and [contravariant] are incomparable.
+  // [meet] calculates the meet of two elements of such lattice.  It can be
+  // used, for example, to calculate the variance of a typedef type parameter
+  // if it's encountered on the r.h.s. of the typedef multiple times.
+  static int meet(int a, int b) => a | b;
+
+  // Combines variances of X in T and Y in S into variance of X in [Y/T]S.
+  //
+  // Consider the following examples:
+  //
+  // * variance of X in Function(X) is [contravariant], variance of Y in List<Y>
+  // is [covariant], so variance of X in List<Function(X)> is [contravariant];
+  //
+  // * variance of X in List<X> is [covariant], variance of Y in Function(Y) is
+  // [contravariant], so variance of X in Function(List<X>) is [contravariant];
+  //
+  // * variance of X in Function(X) is [contravariant], variance of Y in
+  // Function(Y) is [contravariant], so variance of X in Function(Function(X))
+  // is [covariant];
+  //
+  // * let the following be declared:
+  //
+  //     typedef F<Z> = Function();
+  //
+  // then variance of X in F<X> is [unrelated], variance of Y in List<Y> is
+  // [covariant], so variance of X in List<F<X>> is [unrelated];
+  //
+  // * let the following be declared:
+  //
+  //     typedef G<Z> = Z Function(Z);
+  //
+  // then variance of X in List<X> is [covariant], variance of Y in G<Y> is
+  // [invariant], so variance of `X` in `G<List<X>>` is [invariant].
+  static int combine(int a, int b) {
+    if (a == unrelated || b == unrelated) return unrelated;
+    if (a == invariant || b == invariant) return invariant;
+    return a == b ? covariant : contravariant;
+  }
+}
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 007fc9e..a0e9a5b 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -6,6 +6,7 @@
 import '../ast.dart';
 import '../class_hierarchy.dart';
 import '../core_types.dart';
+import '../transformations/constants.dart' show ConstantsBackend;
 import '../transformations/treeshaker.dart' show ProgramRoot;
 
 final List<String> targetNames = targets.keys.toList();
@@ -36,6 +37,11 @@
   return builder(flags);
 }
 
+abstract class DiagnosticReporter<M, C> {
+  void report(M message, int charOffset, int length, Uri fileUri,
+      {List<C> context});
+}
+
 /// A target provides backend-specific options for generating kernel IR.
 abstract class Target {
   String get name;
@@ -94,8 +100,12 @@
   void performOutlineTransformations(Component component) {}
 
   /// Perform target-specific modular transformations on the given libraries.
-  void performModularTransformationsOnLibraries(Component component,
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+  void performModularTransformationsOnLibraries(
+      Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
       {void logger(String msg)});
 
   /// Perform target-specific modular transformations on the given program.
@@ -186,6 +196,8 @@
 
   Class concreteIntLiteralClass(CoreTypes coreTypes, int value) => null;
   Class concreteStringLiteralClass(CoreTypes coreTypes, String value) => null;
+
+  ConstantsBackend constantsBackend(CoreTypes coreTypes);
 }
 
 class NoneTarget extends Target {
@@ -196,8 +208,12 @@
   bool get legacyMode => flags.legacyMode;
   String get name => 'none';
   List<String> get extraRequiredLibraries => <String>[];
-  void performModularTransformationsOnLibraries(Component component,
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+  void performModularTransformationsOnLibraries(
+      Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
       {void logger(String msg)}) {}
 
   @override
@@ -221,4 +237,8 @@
       bool isTopLevel: false}) {
     return new InvalidExpression(null);
   }
+
+  @override
+  ConstantsBackend constantsBackend(CoreTypes coreTypes) =>
+      new ConstantsBackend();
 }
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 2f74c96..dc0a65e 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -5,6 +5,8 @@
 
 import 'dart:core' hide MapEntry;
 
+import 'dart:convert' show json;
+
 import '../ast.dart';
 import '../import_table.dart';
 
@@ -344,6 +346,32 @@
     }
   }
 
+  void writeComponentProblems(Component component) {
+    writeProblemsAsJson("Problems in component", component.problemsAsJson);
+  }
+
+  void writeProblemsAsJson(String header, List<String> problemsAsJson) {
+    if (problemsAsJson?.isEmpty == false) {
+      endLine("//");
+      write("// ");
+      write(header);
+      endLine(":");
+      endLine("//");
+      for (String s in problemsAsJson) {
+        Map<String, Object> decoded = json.decode(s);
+        List<Object> plainTextFormatted = decoded["plainTextFormatted"];
+        List<String> lines = plainTextFormatted.join("\n").split("\n");
+        for (int i = 0; i < lines.length; i++) {
+          write("//");
+          String trimmed = lines[i].trimRight();
+          if (trimmed.isNotEmpty) write(" ");
+          endLine(trimmed);
+        }
+        if (lines.isNotEmpty) endLine("//");
+      }
+    }
+  }
+
   void writeLibraryFile(Library library) {
     writeAnnotationList(library.annotations);
     writeWord('library');
@@ -351,7 +379,14 @@
       writeWord(library.name);
     }
     endLine(';');
-    var imports = new LibraryImportTable(library);
+
+    LibraryImportTable imports = new LibraryImportTable(library);
+    Printer inner = createInner(imports, library.enclosingComponent?.metadata);
+    inner.writeStandardLibraryContent(library,
+        outerPrinter: this, importsToPrint: imports);
+  }
+
+  void printLibraryImportTable(LibraryImportTable imports) {
     for (var library in imports.importedLibraries) {
       var importPath = imports.getImportPath(library);
       if (importPath == "") {
@@ -363,47 +398,63 @@
         endLine('import "$importPath" as $prefix;');
       }
     }
+  }
 
-    // TODO(scheglov): Do we want to print dependencies? dartbug.com/30224
-    if (library.additionalExports.isNotEmpty) {
-      write('additionalExports = (');
-      bool isFirst = true;
-      for (var reference in library.additionalExports) {
-        if (isFirst) {
-          isFirst = false;
-        } else {
-          write(', ');
-        }
-        var node = reference.node;
-        if (node is Class) {
-          Library nodeLibrary = node.enclosingLibrary;
-          String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
-          write(prefix + '::' + node.name);
-        } else if (node is Field) {
-          Library nodeLibrary = node.enclosingLibrary;
-          String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
-          write(prefix + '::' + node.name.name);
-        } else if (node is Procedure) {
-          Library nodeLibrary = node.enclosingLibrary;
-          String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
-          write(prefix + '::' + node.name.name);
-        } else if (node is Typedef) {
-          Library nodeLibrary = node.enclosingLibrary;
-          String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
-          write(prefix + '::' + node.name);
-        } else {
-          throw new UnimplementedError('${node.runtimeType}');
-        }
+  void writeStandardLibraryContent(Library library,
+      {Printer outerPrinter, LibraryImportTable importsToPrint}) {
+    outerPrinter ??= this;
+    outerPrinter.writeProblemsAsJson(
+        "Problems in library", library.problemsAsJson);
+
+    if (importsToPrint != null) {
+      outerPrinter.printLibraryImportTable(importsToPrint);
+    }
+
+    writeAdditionalExports(library.additionalExports);
+    endLine();
+    library.dependencies.forEach(writeNode);
+    if (library.dependencies.isNotEmpty) endLine();
+    library.parts.forEach(writeNode);
+    library.typedefs.forEach(writeNode);
+    library.classes.forEach(writeNode);
+    library.fields.forEach(writeNode);
+    library.procedures.forEach(writeNode);
+  }
+
+  void writeAdditionalExports(List<Reference> additionalExports) {
+    if (additionalExports.isEmpty) return;
+    write('additionalExports = (');
+    bool isFirst = true;
+    for (Reference reference in additionalExports) {
+      if (isFirst) {
+        isFirst = false;
+      } else {
+        write(', ');
+      }
+      var node = reference.node;
+      if (node is Class) {
+        Library nodeLibrary = node.enclosingLibrary;
+        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
+        write(prefix + '::' + node.name);
+      } else if (node is Field) {
+        Library nodeLibrary = node.enclosingLibrary;
+        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
+        write(prefix + '::' + node.name.name);
+      } else if (node is Procedure) {
+        Library nodeLibrary = node.enclosingLibrary;
+        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
+        write(prefix + '::' + node.name.name);
+      } else if (node is Typedef) {
+        Library nodeLibrary = node.enclosingLibrary;
+        String prefix = syntheticNames.nameLibraryPrefix(nodeLibrary);
+        write(prefix + '::' + node.name);
+      } else {
+        throw new UnimplementedError('${node.runtimeType}');
       }
       endLine(')');
     }
 
     endLine();
-    var inner = createInner(imports, library.enclosingComponent?.metadata);
-    library.typedefs.forEach(inner.writeNode);
-    library.classes.forEach(inner.writeNode);
-    library.fields.forEach(inner.writeNode);
-    library.procedures.forEach(inner.writeNode);
   }
 
   void writeComponentFile(Component component) {
@@ -416,6 +467,7 @@
     if (showMetadata) {
       inner.writeMetadata(component);
     }
+    writeComponentProblems(component);
     for (var library in component.libraries) {
       if (library.isExternal) {
         if (!showExternal) {
@@ -437,14 +489,18 @@
       writeWord(prefix);
       endLine(' {');
       ++inner.indentation;
-      library.dependencies.forEach(inner.writeNode);
-      library.typedefs.forEach(inner.writeNode);
-      library.classes.forEach(inner.writeNode);
-      library.fields.forEach(inner.writeNode);
-      library.procedures.forEach(inner.writeNode);
+
+      inner.writeStandardLibraryContent(library);
       --inner.indentation;
       endLine('}');
     }
+    writeConstantTable(component);
+  }
+
+  void writeConstantTable(Component component) {
+    if (syntheticNames.constants.map.isEmpty) return;
+    ImportTable imports = new ComponentImportTable(component);
+    var inner = createInner(imports, component.metadata);
     writeWord('constants ');
     endLine(' {');
     ++inner.indentation;
@@ -1359,6 +1415,14 @@
     state = WORD;
   }
 
+  visitLibraryPart(LibraryPart node) {
+    writeAnnotationList(node.annotations);
+    writeIndentation();
+    writeWord('part');
+    writeWord(node.partUri);
+    endLine(";");
+  }
+
   visitLibraryDependency(LibraryDependency node) {
     writeIndentation();
     writeWord(node.isImport ? 'import' : 'export');
@@ -1896,37 +1960,31 @@
     final String name = syntheticNames.nameConstant(node);
     write('  $name = ');
     final sb = new StringBuffer();
-    sb.write('${node.klass}');
-    if (!node.klass.typeParameters.isEmpty) {
+    sb.write('${node.classNode}');
+    if (!node.classNode.typeParameters.isEmpty) {
       sb.write('<');
       sb.write(node.typeArguments.map((type) => type.toString()).join(', '));
       sb.write('>');
     }
     sb.write(' {');
+    bool first = true;
     node.fieldValues.forEach((Reference fieldRef, Constant constant) {
       final String name = syntheticNames.nameConstant(constant);
-      sb.write('${fieldRef.asField.name}: $name, ');
+      if (!first) {
+        first = false;
+        sb.write(', ');
+      }
+      sb.write('${fieldRef.asField.name}: $name');
     });
     sb.write('}');
     endLine(sb.toString());
   }
 
-  visitEnvironmentBoolConstant(EnvironmentBoolConstant node) {
+  visitUnevaluatedConstant(UnevaluatedConstant node) {
     final String name = syntheticNames.nameConstant(node);
-    final String defaultValue = syntheticNames.nameConstant(node.defaultValue);
-    endLine('  $name = bool.fromEnvironment(${node.name}, ${defaultValue})');
-  }
-
-  visitEnvironmentIntConstant(EnvironmentIntConstant node) {
-    final String name = syntheticNames.nameConstant(node);
-    final String defaultValue = syntheticNames.nameConstant(node.defaultValue);
-    endLine('  $name = int.fromEnvironment(${node.name}, ${defaultValue})');
-  }
-
-  visitEnvironmentStringConstant(EnvironmentStringConstant node) {
-    final String name = syntheticNames.nameConstant(node);
-    final String defaultValue = syntheticNames.nameConstant(node.defaultValue);
-    endLine('  $name = String.fromEnvironment(${node.name}, ${defaultValue})');
+    write('  $name = ');
+    writeExpression(node.expression);
+    endLine();
   }
 
   defaultNode(Node node) {
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
index 4b34e70..c06937d 100644
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ b/pkg/kernel/lib/text/serializer_combinators.dart
@@ -7,6 +7,7 @@
 import 'dart:convert' show json;
 
 import '../ast.dart' show Node;
+import '../canonical_name.dart' show CanonicalName;
 import 'text_serializer.dart' show Tagger;
 
 class DeserializationEnvironment<T extends Node> {
@@ -68,12 +69,24 @@
   }
 }
 
+class DeserializationState {
+  final DeserializationEnvironment environment;
+  final CanonicalName nameRoot;
+
+  DeserializationState(this.environment, this.nameRoot);
+}
+
+class SerializationState {
+  final SerializationEnvironment environment;
+
+  SerializationState(this.environment);
+}
+
 abstract class TextSerializer<T> {
   const TextSerializer();
 
-  T readFrom(Iterator<Object> stream, DeserializationEnvironment environment);
-  void writeTo(
-      StringBuffer buffer, T object, SerializationEnvironment environment);
+  T readFrom(Iterator<Object> stream, DeserializationState state);
+  void writeTo(StringBuffer buffer, T object, SerializationState state);
 
   /// True if this serializer/deserializer writes/reads nothing.  This is true
   /// for the serializer [Nothing] and also some serializers derived from it.
@@ -83,9 +96,9 @@
 class Nothing extends TextSerializer<void> {
   const Nothing();
 
-  void readFrom(Iterator<Object> stream, DeserializationEnvironment _) {}
+  void readFrom(Iterator<Object> stream, DeserializationState _) {}
 
-  void writeTo(StringBuffer buffer, void ignored, SerializationEnvironment _) {}
+  void writeTo(StringBuffer buffer, void ignored, SerializationState _) {}
 
   bool get isEmpty => true;
 }
@@ -93,7 +106,7 @@
 class DartString extends TextSerializer<String> {
   const DartString();
 
-  String readFrom(Iterator<Object> stream, DeserializationEnvironment _) {
+  String readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
       throw StateError("expected an atom, found a list");
     }
@@ -102,7 +115,7 @@
     return result;
   }
 
-  void writeTo(StringBuffer buffer, String object, SerializationEnvironment _) {
+  void writeTo(StringBuffer buffer, String object, SerializationState _) {
     buffer.write(json.encode(object));
   }
 }
@@ -110,7 +123,7 @@
 class DartInt extends TextSerializer<int> {
   const DartInt();
 
-  int readFrom(Iterator<Object> stream, DeserializationEnvironment _) {
+  int readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
       throw StateError("expected an atom, found a list");
     }
@@ -119,7 +132,7 @@
     return result;
   }
 
-  void writeTo(StringBuffer buffer, int object, SerializationEnvironment _) {
+  void writeTo(StringBuffer buffer, int object, SerializationState _) {
     buffer.write(object);
   }
 }
@@ -127,7 +140,7 @@
 class DartDouble extends TextSerializer<double> {
   const DartDouble();
 
-  double readFrom(Iterator<Object> stream, DeserializationEnvironment _) {
+  double readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
       throw StateError("expected an atom, found a list");
     }
@@ -136,7 +149,7 @@
     return result;
   }
 
-  void writeTo(StringBuffer buffer, double object, SerializationEnvironment _) {
+  void writeTo(StringBuffer buffer, double object, SerializationState _) {
     buffer.write(object);
   }
 }
@@ -144,7 +157,7 @@
 class DartBool extends TextSerializer<bool> {
   const DartBool();
 
-  bool readFrom(Iterator<Object> stream, DeserializationEnvironment _) {
+  bool readFrom(Iterator<Object> stream, DeserializationState _) {
     if (stream.current is! String) {
       throw StateError("expected an atom, found a list");
     }
@@ -160,7 +173,7 @@
     return result;
   }
 
-  void writeTo(StringBuffer buffer, bool object, SerializationEnvironment _) {
+  void writeTo(StringBuffer buffer, bool object, SerializationState _) {
     buffer.write(object ? 'true' : 'false');
   }
 }
@@ -181,7 +194,7 @@
       : tags = [],
         serializers = [];
 
-  T readFrom(Iterator<Object> stream, DeserializationEnvironment environment) {
+  T readFrom(Iterator<Object> stream, DeserializationState state) {
     if (stream.current is! Iterator) {
       throw StateError("expected list, found atom");
     }
@@ -194,7 +207,7 @@
     for (int i = 0; i < tags.length; ++i) {
       if (tags[i] == tag) {
         nested.moveNext();
-        T result = serializers[i].readFrom(nested, environment);
+        T result = serializers[i].readFrom(nested, state);
         if (nested.moveNext()) {
           throw StateError("extra cruft in tagged '${tag}'");
         }
@@ -205,8 +218,7 @@
     throw StateError("unrecognized tag '${tag}'");
   }
 
-  void writeTo(
-      StringBuffer buffer, T object, SerializationEnvironment environment) {
+  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) {
@@ -214,7 +226,7 @@
         if (!serializers[i].isEmpty) {
           buffer.write(" ");
         }
-        serializers[i].writeTo(buffer, object, environment);
+        serializers[i].writeTo(buffer, object, state);
         buffer.write(")");
         return;
       }
@@ -232,30 +244,28 @@
 
   Wrapped(this.unwrap, this.wrap, this.contents);
 
-  K readFrom(Iterator<Object> stream, DeserializationEnvironment environment) {
-    return wrap(contents.readFrom(stream, environment));
+  K readFrom(Iterator<Object> stream, DeserializationState state) {
+    return wrap(contents.readFrom(stream, state));
   }
 
-  void writeTo(
-      StringBuffer buffer, K object, SerializationEnvironment environment) {
-    contents.writeTo(buffer, unwrap(object), environment);
+  void writeTo(StringBuffer buffer, K object, SerializationState state) {
+    contents.writeTo(buffer, unwrap(object), state);
   }
 
   bool get isEmpty => contents.isEmpty;
 }
 
-class ScopedReference<T extends Node> extends TextSerializer<T> {
+class ScopedUse<T extends Node> extends TextSerializer<T> {
   final DartString stringSerializer = const DartString();
 
-  const ScopedReference();
+  const ScopedUse();
 
-  T readFrom(Iterator<Object> stream, DeserializationEnvironment environment) {
-    return environment.lookup(stringSerializer.readFrom(stream, null));
+  T readFrom(Iterator<Object> stream, DeserializationState state) {
+    return state.environment.lookup(stringSerializer.readFrom(stream, null));
   }
 
-  void writeTo(
-      StringBuffer buffer, T object, SerializationEnvironment environment) {
-    stringSerializer.writeTo(buffer, environment.lookup(object), null);
+  void writeTo(StringBuffer buffer, T object, SerializationState state) {
+    stringSerializer.writeTo(buffer, state.environment.lookup(object), null);
   }
 }
 
@@ -266,17 +276,16 @@
 
   const Tuple2Serializer(this.first, this.second);
 
-  Tuple2<T1, T2> readFrom(
-      Iterator<Object> stream, DeserializationEnvironment environment) {
-    return new Tuple2(first.readFrom(stream, environment),
-        second.readFrom(stream, environment));
+  Tuple2<T1, T2> readFrom(Iterator<Object> stream, DeserializationState state) {
+    return new Tuple2(
+        first.readFrom(stream, state), second.readFrom(stream, state));
   }
 
-  void writeTo(StringBuffer buffer, Tuple2<T1, T2> object,
-      SerializationEnvironment environment) {
-    first.writeTo(buffer, object.first, environment);
+  void writeTo(
+      StringBuffer buffer, Tuple2<T1, T2> object, SerializationState state) {
+    first.writeTo(buffer, object.first, state);
     buffer.write(' ');
-    second.writeTo(buffer, object.second, environment);
+    second.writeTo(buffer, object.second, state);
   }
 }
 
@@ -295,20 +304,18 @@
   const Tuple3Serializer(this.first, this.second, this.third);
 
   Tuple3<T1, T2, T3> readFrom(
-      Iterator<Object> stream, DeserializationEnvironment environment) {
-    return new Tuple3(
-        first.readFrom(stream, environment),
-        second.readFrom(stream, environment),
-        third.readFrom(stream, environment));
+      Iterator<Object> stream, DeserializationState state) {
+    return new Tuple3(first.readFrom(stream, state),
+        second.readFrom(stream, state), third.readFrom(stream, state));
   }
 
   void writeTo(StringBuffer buffer, Tuple3<T1, T2, T3> object,
-      SerializationEnvironment environment) {
-    first.writeTo(buffer, object.first, environment);
+      SerializationState state) {
+    first.writeTo(buffer, object.first, state);
     buffer.write(' ');
-    second.writeTo(buffer, object.second, environment);
+    second.writeTo(buffer, object.second, state);
     buffer.write(' ');
-    third.writeTo(buffer, object.third, environment);
+    third.writeTo(buffer, object.third, state);
   }
 }
 
@@ -330,23 +337,23 @@
   const Tuple4Serializer(this.first, this.second, this.third, this.fourth);
 
   Tuple4<T1, T2, T3, T4> readFrom(
-      Iterator<Object> stream, DeserializationEnvironment environment) {
+      Iterator<Object> stream, DeserializationState state) {
     return new Tuple4(
-        first.readFrom(stream, environment),
-        second.readFrom(stream, environment),
-        third.readFrom(stream, environment),
-        fourth.readFrom(stream, environment));
+        first.readFrom(stream, state),
+        second.readFrom(stream, state),
+        third.readFrom(stream, state),
+        fourth.readFrom(stream, state));
   }
 
   void writeTo(StringBuffer buffer, Tuple4<T1, T2, T3, T4> object,
-      SerializationEnvironment environment) {
-    first.writeTo(buffer, object.first, environment);
+      SerializationState state) {
+    first.writeTo(buffer, object.first, state);
     buffer.write(' ');
-    second.writeTo(buffer, object.second, environment);
+    second.writeTo(buffer, object.second, state);
     buffer.write(' ');
-    third.writeTo(buffer, object.third, environment);
+    third.writeTo(buffer, object.third, state);
     buffer.write(' ');
-    fourth.writeTo(buffer, object.fourth, environment);
+    fourth.writeTo(buffer, object.fourth, state);
   }
 }
 
@@ -365,8 +372,7 @@
 
   const ListSerializer(this.elements);
 
-  List<T> readFrom(
-      Iterator<Object> stream, DeserializationEnvironment environment) {
+  List<T> readFrom(Iterator<Object> stream, DeserializationState state) {
     if (stream.current is! Iterator) {
       throw StateError("expected a list, found an atom");
     }
@@ -374,18 +380,17 @@
     list.moveNext();
     List<T> result = [];
     while (list.current != null) {
-      result.add(elements.readFrom(list, environment));
+      result.add(elements.readFrom(list, state));
     }
     stream.moveNext();
     return result;
   }
 
-  void writeTo(StringBuffer buffer, List<T> object,
-      SerializationEnvironment environment) {
+  void writeTo(StringBuffer buffer, List<T> object, SerializationState state) {
     buffer.write('(');
     for (int i = 0; i < object.length; ++i) {
       if (i != 0) buffer.write(' ');
-      elements.writeTo(buffer, object[i], environment);
+      elements.writeTo(buffer, object[i], state);
     }
     buffer.write(')');
   }
@@ -396,20 +401,19 @@
 
   const Optional(this.contents);
 
-  T readFrom(Iterator<Object> stream, DeserializationEnvironment environment) {
+  T readFrom(Iterator<Object> stream, DeserializationState state) {
     if (stream.current == '_') {
       stream.moveNext();
       return null;
     }
-    return contents.readFrom(stream, environment);
+    return contents.readFrom(stream, state);
   }
 
-  void writeTo(
-      StringBuffer buffer, T object, SerializationEnvironment environment) {
+  void writeTo(StringBuffer buffer, T object, SerializationState state) {
     if (object == null) {
       buffer.write('_');
     } else {
-      contents.writeTo(buffer, object, environment);
+      contents.writeTo(buffer, object, state);
     }
   }
 }
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index 644f15a..78659ef 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -4,7 +4,8 @@
 
 import '../ast.dart';
 
-import '../text/serializer_combinators.dart' show TextSerializer;
+import '../text/serializer_combinators.dart'
+    show DeserializationState, SerializationState, TextSerializer;
 
 import '../text/text_reader.dart' show TextIterator;
 
@@ -80,7 +81,8 @@
     stream.moveNext();
     T result;
     try {
-      result = serializer.readFrom(stream, null);
+      result = serializer.readFrom(
+          stream, new DeserializationState(null, new CanonicalName.root()));
     } catch (exception) {
       failures.add(
           new TextDeserializationFailure(exception.toString(), uri, offset));
@@ -96,7 +98,7 @@
       T node, TextSerializer<T> serializer, Uri uri, int offset) {
     StringBuffer buffer = new StringBuffer();
     try {
-      serializer.writeTo(buffer, node, null);
+      serializer.writeTo(buffer, node, new SerializationState(null));
     } catch (exception) {
       failures
           .add(new TextSerializationFailure(exception.toString(), uri, offset));
@@ -302,24 +304,6 @@
   }
 
   @override
-  void visitEnvironmentBoolConstantReference(EnvironmentBoolConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitEnvironmentIntConstantReference(EnvironmentIntConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitEnvironmentStringConstantReference(EnvironmentStringConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitUnevaluatedConstantReference(UnevaluatedConstant node) {
     storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
@@ -404,24 +388,6 @@
   }
 
   @override
-  void visitEnvironmentBoolConstant(EnvironmentBoolConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitEnvironmentIntConstant(EnvironmentIntConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitEnvironmentStringConstant(EnvironmentStringConstant node) {
-    storeLastSeenUriAndOffset(node);
-    node.visitChildren(this);
-  }
-
-  @override
   void visitUnevaluatedConstant(UnevaluatedConstant node) {
     storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 06799f1..b3a3595 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -98,6 +98,23 @@
 
   String visitVariableGet(VariableGet _) => "get-var";
   String visitVariableSet(VariableSet _) => "set-var";
+  String visitStaticGet(StaticGet _) => "get-static";
+  String visitStaticSet(StaticSet _) => "set-static";
+  String visitDirectPropertyGet(DirectPropertyGet _) => "get-direct-prop";
+  String visitDirectPropertySet(DirectPropertySet _) => "set-direct-prop";
+  String visitStaticInvocation(StaticInvocation expression) {
+    return expression.isConst ? "invoke-const-static" : "invoke-static";
+  }
+
+  String visitDirectMethodInvocation(DirectMethodInvocation _) {
+    return "invoke-direct-method";
+  }
+
+  String visitConstructorInvocation(ConstructorInvocation expression) {
+    return expression.isConst
+        ? "invoke-const-constructor"
+        : "invoke-constructor";
+  }
 }
 
 TextSerializer<InvalidExpression> invalidExpressionSerializer = new Wrapped(
@@ -374,29 +391,30 @@
 class LetSerializer extends TextSerializer<Let> {
   const LetSerializer();
 
-  Let readFrom(
-      Iterator<Object> stream, DeserializationEnvironment environment) {
+  Let readFrom(Iterator<Object> stream, DeserializationState state) {
     VariableDeclaration variable =
-        variableDeclarationSerializer.readFrom(stream, environment);
+        variableDeclarationSerializer.readFrom(stream, state);
     Expression body = expressionSerializer.readFrom(
         stream,
-        new DeserializationEnvironment(environment)
-          ..add(variable.name, variable));
+        new DeserializationState(
+            new DeserializationEnvironment(state.environment)
+              ..add(variable.name, variable),
+            state.nameRoot));
     return new Let(variable, body);
   }
 
-  void writeTo(
-      StringBuffer buffer, Let object, SerializationEnvironment environment) {
-    SerializationEnvironment bodyScope =
-        new SerializationEnvironment(environment);
+  void writeTo(StringBuffer buffer, Let object, SerializationState state) {
+    SerializationState bodyState =
+        new SerializationState(new SerializationEnvironment(state.environment));
     VariableDeclaration variable = object.variable;
     String oldVariableName = variable.name;
-    String newVariableName = bodyScope.add(variable, oldVariableName);
+    String newVariableName =
+        bodyState.environment.add(variable, oldVariableName);
     variableDeclarationSerializer.writeTo(
-        buffer, variable..name = newVariableName, environment);
+        buffer, variable..name = newVariableName, state);
     variable.name = oldVariableName;
     buffer.write(' ');
-    expressionSerializer.writeTo(buffer, object.body, bodyScope);
+    expressionSerializer.writeTo(buffer, object.body, bodyState);
   }
 }
 
@@ -485,7 +503,7 @@
 TextSerializer<VariableGet> variableGetSerializer = new Wrapped(
     unwrapVariableGet,
     wrapVariableGet,
-    new Tuple2Serializer(const ScopedReference<VariableDeclaration>(),
+    new Tuple2Serializer(const ScopedUse<VariableDeclaration>(),
         new Optional(dartTypeSerializer)));
 
 Tuple2<VariableDeclaration, DartType> unwrapVariableGet(VariableGet node) {
@@ -501,7 +519,7 @@
     unwrapVariableSet,
     wrapVariableSet,
     new Tuple2Serializer(
-        const ScopedReference<VariableDeclaration>(), expressionSerializer));
+        const ScopedUse<VariableDeclaration>(), expressionSerializer));
 
 Tuple2<VariableDeclaration, Expression> unwrapVariableSet(VariableSet node) {
   return new Tuple2<VariableDeclaration, Expression>(node.variable, node.value);
@@ -511,6 +529,178 @@
   return new VariableSet(tuple.first, tuple.second);
 }
 
+class CanonicalNameSerializer extends TextSerializer<CanonicalName> {
+  static const String delimiter = "::";
+
+  const CanonicalNameSerializer();
+
+  static void writeName(CanonicalName name, StringBuffer buffer) {
+    if (!name.isRoot) {
+      if (!name.parent.isRoot) {
+        writeName(name.parent, buffer);
+        buffer.write(delimiter);
+      }
+      buffer.write(name.name);
+    }
+  }
+
+  CanonicalName readFrom(Iterator<Object> stream, DeserializationState state) {
+    String string = const DartString().readFrom(stream, state);
+    CanonicalName name = state.nameRoot;
+    for (String s in string.split(delimiter)) {
+      name = name.getChild(s);
+    }
+    return name;
+  }
+
+  void writeTo(
+      StringBuffer buffer, CanonicalName name, SerializationState state) {
+    StringBuffer sb = new StringBuffer();
+    writeName(name, sb);
+    const DartString().writeTo(buffer, sb.toString(), state);
+  }
+}
+
+TextSerializer<StaticGet> staticGetSerializer =
+    new Wrapped(unwrapStaticGet, wrapStaticGet, new CanonicalNameSerializer());
+
+CanonicalName unwrapStaticGet(StaticGet expression) {
+  return expression.targetReference.canonicalName;
+}
+
+StaticGet wrapStaticGet(CanonicalName name) {
+  return new StaticGet.byReference(name.getReference());
+}
+
+TextSerializer<StaticSet> staticSetSerializer = new Wrapped(
+    unwrapStaticSet,
+    wrapStaticSet,
+    new Tuple2Serializer(
+        const CanonicalNameSerializer(), expressionSerializer));
+
+Tuple2<CanonicalName, Expression> unwrapStaticSet(StaticSet expression) {
+  return new Tuple2(expression.targetReference.canonicalName, expression.value);
+}
+
+StaticSet wrapStaticSet(Tuple2<CanonicalName, Expression> tuple) {
+  return new StaticSet.byReference(tuple.first.getReference(), tuple.second);
+}
+
+TextSerializer<DirectPropertyGet> directPropertyGetSerializer = new Wrapped(
+    unwrapDirectPropertyGet,
+    wrapDirectPropertyGet,
+    new Tuple2Serializer(
+        expressionSerializer, const CanonicalNameSerializer()));
+
+Tuple2<Expression, CanonicalName> unwrapDirectPropertyGet(
+    DirectPropertyGet expression) {
+  return new Tuple2(
+      expression.receiver, expression.targetReference.canonicalName);
+}
+
+DirectPropertyGet wrapDirectPropertyGet(
+    Tuple2<Expression, CanonicalName> tuple) {
+  return new DirectPropertyGet.byReference(
+      tuple.first, tuple.second.getReference());
+}
+
+TextSerializer<DirectPropertySet> directPropertySetSerializer = new Wrapped(
+    unwrapDirectPropertySet,
+    wrapDirectPropertySet,
+    new Tuple3Serializer(expressionSerializer, const CanonicalNameSerializer(),
+        expressionSerializer));
+
+Tuple3<Expression, CanonicalName, Expression> unwrapDirectPropertySet(
+    DirectPropertySet expression) {
+  return new Tuple3(expression.receiver,
+      expression.targetReference.canonicalName, expression.value);
+}
+
+DirectPropertySet wrapDirectPropertySet(
+    Tuple3<Expression, CanonicalName, Expression> tuple) {
+  return new DirectPropertySet.byReference(
+      tuple.first, tuple.second.getReference(), tuple.third);
+}
+
+TextSerializer<StaticInvocation> staticInvocationSerializer = new Wrapped(
+    unwrapStaticInvocation,
+    wrapStaticInvocation,
+    new Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+
+Tuple2<CanonicalName, Arguments> unwrapStaticInvocation(
+    StaticInvocation expression) {
+  return new Tuple2(
+      expression.targetReference.canonicalName, expression.arguments);
+}
+
+StaticInvocation wrapStaticInvocation(Tuple2<CanonicalName, Arguments> tuple) {
+  return new StaticInvocation.byReference(
+      tuple.first.getReference(), tuple.second,
+      isConst: false);
+}
+
+TextSerializer<StaticInvocation> constStaticInvocationSerializer = new Wrapped(
+    unwrapStaticInvocation,
+    wrapConstStaticInvocation,
+    new Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+
+StaticInvocation wrapConstStaticInvocation(
+    Tuple2<CanonicalName, Arguments> tuple) {
+  return new StaticInvocation.byReference(
+      tuple.first.getReference(), tuple.second,
+      isConst: true);
+}
+
+TextSerializer<DirectMethodInvocation> directMethodInvocationSerializer =
+    new Wrapped(
+        unwrapDirectMethodInvocation,
+        wrapDirectMethodInvocation,
+        new Tuple3Serializer(expressionSerializer,
+            const CanonicalNameSerializer(), argumentsSerializer));
+
+Tuple3<Expression, CanonicalName, Arguments> unwrapDirectMethodInvocation(
+    DirectMethodInvocation expression) {
+  return new Tuple3(expression.receiver,
+      expression.targetReference.canonicalName, expression.arguments);
+}
+
+DirectMethodInvocation wrapDirectMethodInvocation(
+    Tuple3<Expression, CanonicalName, Arguments> tuple) {
+  return new DirectMethodInvocation.byReference(
+      tuple.first, tuple.second.getReference(), tuple.third);
+}
+
+TextSerializer<ConstructorInvocation> constructorInvocationSerializer =
+    new Wrapped(
+        unwrapConstructorInvocation,
+        wrapConstructorInvocation,
+        new Tuple2Serializer(
+            const CanonicalNameSerializer(), argumentsSerializer));
+
+Tuple2<CanonicalName, Arguments> unwrapConstructorInvocation(
+    ConstructorInvocation expression) {
+  return new Tuple2(
+      expression.targetReference.canonicalName, expression.arguments);
+}
+
+ConstructorInvocation wrapConstructorInvocation(
+    Tuple2<CanonicalName, Arguments> tuple) {
+  return new ConstructorInvocation.byReference(
+      tuple.first.getReference(), tuple.second,
+      isConst: false);
+}
+
+TextSerializer<ConstructorInvocation> constConstructorInvocationSerializer =
+    new Wrapped(unwrapConstructorInvocation, wrapConstConstructorInvocation,
+        Tuple2Serializer(const CanonicalNameSerializer(), argumentsSerializer));
+
+ConstructorInvocation wrapConstConstructorInvocation(
+    Tuple2<CanonicalName, Arguments> tuple) {
+  return new ConstructorInvocation.byReference(
+      tuple.first.getReference(), tuple.second,
+      isConst: true);
+}
+
 Case<Expression> expressionSerializer =
     new Case.uninitialized(const ExpressionTagger());
 
@@ -648,6 +838,7 @@
   String visitDynamicType(DynamicType _) => "dynamic";
   String visitVoidType(VoidType _) => "void";
   String visitBottomType(BottomType _) => "bottom";
+  String visitFunctionType(FunctionType _) => "->";
 }
 
 TextSerializer<InvalidType> invalidTypeSerializer =
@@ -678,6 +869,23 @@
 
 BottomType wrapBottomType(void ignored) => const BottomType();
 
+// TODO(dmitryas):  Also handle typeParameters, nameParameters, and typedefType.
+TextSerializer<FunctionType> functionTypeSerializer = new Wrapped(
+    unwrapFunctionType,
+    wrapFunctionType,
+    Tuple3Serializer(new ListSerializer(dartTypeSerializer), const DartInt(),
+        dartTypeSerializer));
+
+Tuple3<List<DartType>, int, DartType> unwrapFunctionType(FunctionType type) {
+  return new Tuple3(
+      type.positionalParameters, type.requiredParameterCount, type.returnType);
+}
+
+FunctionType wrapFunctionType(Tuple3<List<DartType>, int, DartType> tuple) {
+  return new FunctionType(tuple.first, tuple.third,
+      requiredParameterCount: tuple.second);
+}
+
 Case<DartType> dartTypeSerializer =
     new Case.uninitialized(const DartTypeTagger());
 
@@ -717,6 +925,15 @@
     "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",
   ]);
   expressionSerializer.serializers.addAll([
     stringLiteralSerializer,
@@ -753,17 +970,28 @@
     superMethodInvocationSerializer,
     variableGetSerializer,
     variableSetSerializer,
+    staticGetSerializer,
+    staticSetSerializer,
+    directPropertyGetSerializer,
+    directPropertySetSerializer,
+    staticInvocationSerializer,
+    constStaticInvocationSerializer,
+    directMethodInvocationSerializer,
+    constructorInvocationSerializer,
+    constConstructorInvocationSerializer,
   ]);
   dartTypeSerializer.tags.addAll([
     "invalid",
     "dynamic",
     "void",
     "bottom",
+    "->",
   ]);
   dartTypeSerializer.serializers.addAll([
     invalidTypeSerializer,
     dynamicTypeSerializer,
     voidTypeSerializer,
     bottomTypeSerializer,
+    functionTypeSerializer,
   ]);
 }
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 17bd047..eceaa13 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -23,13 +23,12 @@
 import '../ast.dart';
 import '../class_hierarchy.dart';
 import '../core_types.dart';
-import '../external_name.dart' show getExternalName;
 import '../kernel.dart';
 import '../type_algebra.dart';
 import '../type_environment.dart';
 
-Component transformComponent(
-    Component component, ConstantsBackend backend, ErrorReporter errorReporter,
+Component transformComponent(Component component, ConstantsBackend backend,
+    Map<String, String> environmentDefines, ErrorReporter errorReporter,
     {bool keepFields: false,
     bool legacyMode: false,
     bool enableAsserts: false,
@@ -42,10 +41,9 @@
   final typeEnvironment =
       new TypeEnvironment(coreTypes, hierarchy, legacyMode: legacyMode);
 
-  transformLibraries(
-      component.libraries, backend, coreTypes, typeEnvironment, errorReporter,
+  transformLibraries(component.libraries, backend, environmentDefines,
+      typeEnvironment, errorReporter,
       keepFields: keepFields,
-      legacyMode: legacyMode,
       enableAsserts: enableAsserts,
       evaluateAnnotations: evaluateAnnotations);
   return component;
@@ -54,24 +52,22 @@
 void transformLibraries(
     List<Library> libraries,
     ConstantsBackend backend,
-    CoreTypes coreTypes,
+    Map<String, String> environmentDefines,
     TypeEnvironment typeEnvironment,
     ErrorReporter errorReporter,
     {bool keepFields: false,
-    bool legacyMode: false,
     bool keepVariables: false,
     bool evaluateAnnotations: true,
     bool enableAsserts: false}) {
   final ConstantsTransformer constantsTransformer = new ConstantsTransformer(
       backend,
+      environmentDefines,
       keepFields,
       keepVariables,
       evaluateAnnotations,
-      coreTypes,
       typeEnvironment,
       enableAsserts,
-      errorReporter,
-      legacyMode: legacyMode);
+      errorReporter);
   for (final Library library in libraries) {
     constantsTransformer.convertLibrary(library);
   }
@@ -79,7 +75,6 @@
 
 class ConstantsTransformer extends Transformer {
   final ConstantEvaluator constantEvaluator;
-  final CoreTypes coreTypes;
   final TypeEnvironment typeEnvironment;
 
   /// Whether to preserve constant [Field]s.  All use-sites will be rewritten.
@@ -89,17 +84,15 @@
 
   ConstantsTransformer(
       ConstantsBackend backend,
+      Map<String, String> environmentDefines,
       this.keepFields,
       this.keepVariables,
       this.evaluateAnnotations,
-      this.coreTypes,
       this.typeEnvironment,
       bool enableAsserts,
-      ErrorReporter errorReporter,
-      {bool legacyMode: false})
-      : constantEvaluator = new ConstantEvaluator(
-            backend, typeEnvironment, coreTypes, enableAsserts, errorReporter,
-            legacyMode: legacyMode);
+      ErrorReporter errorReporter)
+      : constantEvaluator = new ConstantEvaluator(backend, environmentDefines,
+            typeEnvironment, enableAsserts, errorReporter);
 
   // Transform the library/class members:
 
@@ -353,6 +346,17 @@
     return super.visitStaticInvocation(node);
   }
 
+  visitConstantExpression(ConstantExpression node) {
+    Constant constant = node.constant;
+    if (constant is UnevaluatedConstant) {
+      Expression expression = constant.expression;
+      return tryEvaluateAndTransformWithContext(expression, expression);
+    } else {
+      node.constant = constantEvaluator.canonicalize(constant);
+      return node;
+    }
+  }
+
   tryEvaluateAndTransformWithContext(TreeNode treeContext, Expression node) {
     final Constant constant = tryEvaluateWithContext(treeContext, node);
     return constant != null ? new ConstantExpression(constant) : node;
@@ -371,9 +375,9 @@
 
 class ConstantEvaluator extends RecursiveVisitor {
   final ConstantsBackend backend;
+  Map<String, String> environmentDefines;
   final CoreTypes coreTypes;
   final TypeEnvironment typeEnvironment;
-  final bool legacyMode;
   final bool enableAsserts;
   final ErrorReporter errorReporter;
 
@@ -391,19 +395,19 @@
   InstanceBuilder instanceBuilder;
   EvaluationEnvironment env;
 
-  ConstantEvaluator(this.backend, this.typeEnvironment, this.coreTypes,
-      this.enableAsserts, this.errorReporter,
-      {this.legacyMode: false})
-      : canonicalizationCache = <Constant, Constant>{},
-        nodeCache = <Node, Constant>{};
+  ConstantEvaluator(this.backend, this.environmentDefines, this.typeEnvironment,
+      this.enableAsserts, this.errorReporter)
+      : coreTypes = typeEnvironment.coreTypes,
+        canonicalizationCache = <Constant, Constant>{},
+        nodeCache = <Node, Constant>{},
+        env = new EvaluationEnvironment();
 
   /// Evaluates [node] and possibly cache the evaluation result.
-  /// Returns `null` if expression can't be evaluated.
   Constant evaluate(Expression node) {
     try {
       return _evaluateSubexpression(node);
-    } on _AbortCurrentEvaluation catch (_) {
-      return null;
+    } on _AbortCurrentEvaluation catch (e) {
+      return new UnevaluatedConstant(new InvalidExpression(e.message));
     }
   }
 
@@ -416,7 +420,9 @@
       // environment.
       if (nodeCache.containsKey(node)) {
         final Constant constant = nodeCache[node];
-        if (constant == null) throw const _AbortCurrentEvaluation();
+        if (constant == null)
+          throw new _AbortCurrentEvaluation(
+              errorReporter.circularity(contextChain, node));
         return constant;
       }
 
@@ -493,22 +499,21 @@
 
   visitListLiteral(ListLiteral node) {
     if (!node.isConst) {
-      errorReporter.nonConstLiteral(contextChain, node, 'List');
-      throw const _AbortCurrentEvaluation();
+      throw new _AbortCurrentEvaluation(
+          errorReporter.nonConstLiteral(contextChain, node, 'List'));
     }
     final List<Constant> entries = new List<Constant>(node.expressions.length);
     for (int i = 0; i < node.expressions.length; ++i) {
       entries[i] = node.expressions[i].accept(this);
     }
     final DartType typeArgument = evaluateDartType(node, node.typeArgument);
-    final ListConstant listConstant = new ListConstant(typeArgument, entries);
-    return canonicalize(backend.lowerListConstant(listConstant));
+    return canonicalize(new ListConstant(typeArgument, entries));
   }
 
   visitMapLiteral(MapLiteral node) {
     if (!node.isConst) {
-      errorReporter.nonConstLiteral(contextChain, node, 'Map');
-      throw const _AbortCurrentEvaluation();
+      throw new _AbortCurrentEvaluation(
+          errorReporter.nonConstLiteral(contextChain, node, 'Map'));
     }
     final Set<Constant> usedKeys = new Set<Constant>();
     final List<ConstantMapEntry> entries =
@@ -520,21 +525,19 @@
         // TODO(kustermann): We should change the context handling from just
         // capturing the `TreeNode`s to a `(TreeNode, String message)` tuple and
         // report where the first key with the same value was.
-        errorReporter.duplicateKey(contextChain, node.entries[i], key);
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(
+            errorReporter.duplicateKey(contextChain, node.entries[i], key));
       }
       entries[i] = new ConstantMapEntry(key, value);
     }
     final DartType keyType = evaluateDartType(node, node.keyType);
     final DartType valueType = evaluateDartType(node, node.valueType);
-    final MapConstant mapConstant =
-        new MapConstant(keyType, valueType, entries);
-    return canonicalize(backend.lowerMapConstant(mapConstant));
+    return canonicalize(new MapConstant(keyType, valueType, entries));
   }
 
   visitFunctionExpression(FunctionExpression node) {
-    errorReporter.nonConstLiteral(contextChain, node, 'Function');
-    throw const _AbortCurrentEvaluation();
+    throw new _AbortCurrentEvaluation(
+        errorReporter.nonConstLiteral(contextChain, node, 'Function'));
   }
 
   visitConstructorInvocation(ConstructorInvocation node) {
@@ -548,6 +551,14 @@
         constructor.function.body is! EmptyStatement) {
       throw 'Constructor "$node" has non-trivial body "${constructor.function.body.runtimeType}".';
     }
+    if (constructor.isInExternalLibrary &&
+        constructor.initializers.isEmpty &&
+        constructor.enclosingClass.supertype != null) {
+      // The constructor is unavailable due to separate compilation.
+      return new UnevaluatedConstant(new ConstructorInvocation(
+          constructor, unevaluatedArguments(node.arguments),
+          isConst: true));
+    }
     if (klass.isAbstract) {
       throw 'Constructor "$node" belongs to abstract class "${klass}".';
     }
@@ -572,7 +583,7 @@
 
         // Special case the dart:core's Symbol class here and convert it to a
         // [SymbolConstant].  For invalid values we report a compile-time error.
-        if (result.klass == coreTypes.internalSymbolClass) {
+        if (result.classNode == coreTypes.internalSymbolClass) {
           // The dart:_internal's Symbol class has only the name field.
           assert(coreTypes.internalSymbolClass.fields
                   .where((f) => !f.isStatic)
@@ -584,9 +595,8 @@
               isValidSymbolName(nameValue.value)) {
             return canonicalize(new SymbolConstant(nameValue.value, null));
           }
-          errorReporter.invalidSymbolName(
-              contextChain, node.arguments.positional.first, nameValue);
-          throw const _AbortCurrentEvaluation();
+          throw new _AbortCurrentEvaluation(errorReporter.invalidSymbolName(
+              contextChain, node.arguments.positional.first, nameValue));
         }
 
         return canonicalize(result);
@@ -786,28 +796,27 @@
                 if (!condition.value) {
                   final Constant message = init.statement.message?.accept(this);
                   if (message == null) {
-                    errorReporter.failedAssertion(
-                        contextChain, init.statement.condition, null);
-                    throw const _AbortCurrentEvaluation();
+                    throw new _AbortCurrentEvaluation(
+                        errorReporter.failedAssertion(
+                            contextChain, init.statement.condition, null));
                   } else if (message is StringConstant) {
-                    errorReporter.failedAssertion(
-                        contextChain, init.statement.condition, message.value);
-                    throw const _AbortCurrentEvaluation();
+                    throw new _AbortCurrentEvaluation(
+                        errorReporter.failedAssertion(contextChain,
+                            init.statement.condition, message.value));
                   }
-                  errorReporter.invalidDartType(
-                      contextChain,
-                      init.statement.message,
-                      message,
-                      typeEnvironment.stringType);
-                  throw const _AbortCurrentEvaluation();
+                  throw new _AbortCurrentEvaluation(
+                      errorReporter.invalidDartType(
+                          contextChain,
+                          init.statement.message,
+                          message,
+                          typeEnvironment.stringType));
                 }
               } else {
-                errorReporter.invalidDartType(
+                throw new _AbortCurrentEvaluation(errorReporter.invalidDartType(
                     contextChain,
                     init.statement.condition,
                     condition,
-                    typeEnvironment.boolType);
-                throw const _AbortCurrentEvaluation();
+                    typeEnvironment.boolType));
               }
             }
           } else {
@@ -820,8 +829,7 @@
   }
 
   visitInvalidExpression(InvalidExpression node) {
-    // Invalid expressions are always distinct, we do not canonicalize them.
-    return new UnevaluatedConstant(node);
+    throw new _AbortCurrentEvaluation(node.message);
   }
 
   visitMethodInvocation(MethodInvocation node) {
@@ -855,14 +863,14 @@
               return canonicalize(
                   new StringConstant(receiver.value + other.value));
             }
-            errorReporter.invalidBinaryOperandType(
-                contextChain,
-                node,
-                receiver,
-                '+',
-                typeEnvironment.stringType,
-                other.getType(typeEnvironment));
-            throw const _AbortCurrentEvaluation();
+            throw new _AbortCurrentEvaluation(
+                errorReporter.invalidBinaryOperandType(
+                    contextChain,
+                    node,
+                    receiver,
+                    '+',
+                    typeEnvironment.stringType,
+                    other.getType(typeEnvironment)));
         }
       }
     } else if (receiver is BoolConstant) {
@@ -885,14 +893,14 @@
                   : falseConstant;
           }
         }
-        errorReporter.invalidBinaryOperandType(
-            contextChain,
-            node,
-            receiver,
-            '${node.name.name}',
-            typeEnvironment.boolType,
-            right.getType(typeEnvironment));
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(
+            errorReporter.invalidBinaryOperandType(
+                contextChain,
+                node,
+                receiver,
+                '${node.name.name}',
+                typeEnvironment.boolType,
+                right.getType(typeEnvironment)));
       }
     } else if (receiver is IntConstant) {
       if (arguments.length == 0) {
@@ -907,9 +915,12 @@
         final op = node.name.name;
         if (other is IntConstant) {
           if ((op == '<<' || op == '>>') && other.value < 0) {
-            errorReporter.negativeShift(contextChain,
-                node.arguments.positional.first, receiver, op, other);
-            throw const _AbortCurrentEvaluation();
+            throw new _AbortCurrentEvaluation(errorReporter.negativeShift(
+                contextChain,
+                node.arguments.positional.first,
+                receiver,
+                op,
+                other));
           }
           switch (op) {
             case '|':
@@ -932,9 +943,8 @@
 
         if (other is IntConstant) {
           if (other.value == 0 && (op == '%' || op == '~/')) {
-            errorReporter.zeroDivisor(
-                contextChain, node.arguments.positional.first, receiver, op);
-            throw const _AbortCurrentEvaluation();
+            throw new _AbortCurrentEvaluation(errorReporter.zeroDivisor(
+                contextChain, node.arguments.positional.first, receiver, op));
           }
 
           return evaluateBinaryNumericOperation(
@@ -943,15 +953,14 @@
           return evaluateBinaryNumericOperation(
               node.name.name, receiver.value, other.value, node);
         }
-
-        errorReporter.invalidBinaryOperandType(
-            contextChain,
-            node,
-            receiver,
-            '${node.name.name}',
-            typeEnvironment.numType,
-            other.getType(typeEnvironment));
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(
+            errorReporter.invalidBinaryOperandType(
+                contextChain,
+                node,
+                receiver,
+                '${node.name.name}',
+                typeEnvironment.numType,
+                other.getType(typeEnvironment)));
       }
     } else if (receiver is DoubleConstant) {
       if (arguments.length == 0) {
@@ -969,19 +978,18 @@
           return evaluateBinaryNumericOperation(
               node.name.name, receiver.value, value, node);
         }
-        errorReporter.invalidBinaryOperandType(
-            contextChain,
-            node,
-            receiver,
-            '${node.name.name}',
-            typeEnvironment.numType,
-            other.getType(typeEnvironment));
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(
+            errorReporter.invalidBinaryOperandType(
+                contextChain,
+                node,
+                receiver,
+                '${node.name.name}',
+                typeEnvironment.numType,
+                other.getType(typeEnvironment)));
       }
     }
-    errorReporter.invalidMethodInvocation(
-        contextChain, node, receiver, node.name.name);
-    throw const _AbortCurrentEvaluation();
+    throw new _AbortCurrentEvaluation(errorReporter.invalidMethodInvocation(
+        contextChain, node, receiver, node.name.name));
   }
 
   visitLogicalExpression(LogicalExpression node) {
@@ -995,18 +1003,18 @@
           if (right is BoolConstant) {
             return right;
           }
-          errorReporter.invalidBinaryOperandType(
-              contextChain,
-              node,
-              left,
-              '${node.operator}',
-              typeEnvironment.boolType,
-              right.getType(typeEnvironment));
-          throw const _AbortCurrentEvaluation();
+
+          throw new _AbortCurrentEvaluation(
+              errorReporter.invalidBinaryOperandType(
+                  contextChain,
+                  node,
+                  left,
+                  '${node.operator}',
+                  typeEnvironment.boolType,
+                  right.getType(typeEnvironment)));
         }
-        errorReporter.invalidMethodInvocation(
-            contextChain, node, left, '${node.operator}');
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(errorReporter.invalidMethodInvocation(
+            contextChain, node, left, '${node.operator}'));
       case '&&':
         if (left is BoolConstant) {
           if (!left.value) return falseConstant;
@@ -1015,26 +1023,24 @@
           if (right is BoolConstant) {
             return right;
           }
-          errorReporter.invalidBinaryOperandType(
-              contextChain,
-              node,
-              left,
-              '${node.operator}',
-              typeEnvironment.boolType,
-              right.getType(typeEnvironment));
-          throw const _AbortCurrentEvaluation();
+          throw new _AbortCurrentEvaluation(
+              errorReporter.invalidBinaryOperandType(
+                  contextChain,
+                  node,
+                  left,
+                  '${node.operator}',
+                  typeEnvironment.boolType,
+                  right.getType(typeEnvironment)));
         }
-        errorReporter.invalidMethodInvocation(
-            contextChain, node, left, '${node.operator}');
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(errorReporter.invalidMethodInvocation(
+            contextChain, node, left, '${node.operator}'));
       case '??':
         return (left is! NullConstant)
             ? left
             : _evaluateSubexpression(node.right);
       default:
-        errorReporter.invalidMethodInvocation(
-            contextChain, node, left, '${node.operator}');
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(errorReporter.invalidMethodInvocation(
+            contextChain, node, left, '${node.operator}'));
     }
   }
 
@@ -1045,9 +1051,8 @@
     } else if (constant == falseConstant) {
       return _evaluateSubexpression(node.otherwise);
     } else {
-      errorReporter.invalidDartType(
-          contextChain, node, constant, typeEnvironment.boolType);
-      throw const _AbortCurrentEvaluation();
+      throw new _AbortCurrentEvaluation(errorReporter.invalidDartType(
+          contextChain, node, constant, typeEnvironment.boolType));
     }
   }
 
@@ -1092,8 +1097,8 @@
     if (variable.parent is Let || _isFormalParameter(variable)) {
       final Constant constant = env.lookupVariable(node.variable);
       if (constant == null) {
-        errorReporter.nonConstantVariableGet(contextChain, node, variable.name);
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(errorReporter.nonConstantVariableGet(
+            contextChain, node, variable.name));
       }
       return constant;
     }
@@ -1107,16 +1112,24 @@
   visitStaticGet(StaticGet node) {
     return withNewEnvironment(() {
       final Member target = node.target;
-      if (target is Field && target.isConst) {
-        return runInsideContext(target, () {
-          return _evaluateSubexpression(target.initializer);
-        });
+      if (target is Field) {
+        if (target.isConst) {
+          if (target.isInExternalLibrary && target.initializer == null) {
+            // The variable is unavailable due to separate compilation.
+            return new UnevaluatedConstant(node);
+          }
+          return runInsideContext(target, () {
+            return _evaluateSubexpression(target.initializer);
+          });
+        }
+        throw new _AbortCurrentEvaluation(
+            errorReporter.invalidStaticInvocation(contextChain, node, target));
       } else if (target is Procedure) {
         if (target.kind == ProcedureKind.Method) {
           return canonicalize(new TearOffConstant(target));
         }
-        errorReporter.invalidStaticInvocation(contextChain, node, target);
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(
+            errorReporter.invalidStaticInvocation(contextChain, node, target));
       } else {
         throw new Exception(
             'No support for ${target.runtimeType} in a static-get.');
@@ -1139,9 +1152,8 @@
       } else if (constant is StringConstant) {
         return constant.value;
       } else {
-        errorReporter.invalidStringInterpolationOperand(
-            contextChain, node, constant);
-        throw const _AbortCurrentEvaluation();
+        throw new _AbortCurrentEvaluation(errorReporter
+            .invalidStringInterpolationOperand(contextChain, node, constant));
       }
     }).join('');
     return canonicalize(new StringConstant(value));
@@ -1149,36 +1161,72 @@
 
   visitStaticInvocation(StaticInvocation node) {
     final Procedure target = node.target;
+    final Arguments arguments = node.arguments;
     if (target.kind == ProcedureKind.Factory) {
-      final String nativeName = getExternalName(target);
-      if (nativeName != null) {
-        final Constant constant = backend.buildConstantForNative(
-            nativeName,
-            evaluateTypeArguments(node, node.arguments),
-            evaluatePositionalArguments(node.arguments),
-            evaluateNamedArguments(node.arguments),
-            contextChain,
-            node,
-            errorReporter,
-            () => throw const _AbortCurrentEvaluation());
-        assert(constant != null);
-        return canonicalize(constant);
+      if (target.isConst &&
+          target.name.name == "fromEnvironment" &&
+          target.enclosingLibrary == coreTypes.coreLibrary &&
+          arguments.positional.length == 1) {
+        if (environmentDefines != null) {
+          // Evaluate environment constant.
+          Constant name = arguments.positional[0].accept(this);
+          if (name is StringConstant) {
+            String value = environmentDefines[name.value];
+            Constant defaultValue = null;
+            for (int i = 0; i < arguments.named.length; i++) {
+              NamedExpression named = arguments.named[i];
+              if (named.name == "defaultValue") {
+                defaultValue = named.value.accept(this);
+                break;
+              }
+            }
+
+            if (target.enclosingClass == coreTypes.boolClass) {
+              Constant boolConstant = value == "true"
+                  ? trueConstant
+                  : value == "false"
+                      ? falseConstant
+                      : defaultValue is BoolConstant
+                          ? defaultValue.value ? trueConstant : falseConstant
+                          : defaultValue is NullConstant
+                              ? nullConstant
+                              : falseConstant;
+              return boolConstant;
+            } else if (target.enclosingClass == coreTypes.intClass) {
+              int intValue = value != null ? int.tryParse(value) : null;
+              intValue ??=
+                  defaultValue is IntConstant ? defaultValue.value : null;
+              if (intValue == null) return nullConstant;
+              return canonicalize(new IntConstant(intValue));
+            } else if (target.enclosingClass == coreTypes.stringClass) {
+              value ??=
+                  defaultValue is StringConstant ? defaultValue.value : null;
+              if (value == null) return nullConstant;
+              return canonicalize(new StringConstant(value));
+            }
+          }
+          // TODO(askesc): Give more meaningful error message if name is null.
+        } else {
+          // Leave environment constant unevaluated.
+          return new UnevaluatedConstant(new StaticInvocation(
+              target, unevaluatedArguments(arguments),
+              isConst: true));
+        }
       }
     } else if (target.name.name == 'identical') {
       // Ensure the "identical()" function comes from dart:core.
       final parent = target.parent;
       if (parent is Library && parent == coreTypes.coreLibrary) {
-        final positionalArguments = evaluatePositionalArguments(node.arguments);
+        final positionalArguments = evaluatePositionalArguments(arguments);
         final Constant left = positionalArguments[0];
         final Constant right = positionalArguments[1];
         // Since we canonicalize constants during the evaluation, we can use
         // identical here.
-        assert(left == right);
         return identical(left, right) ? trueConstant : falseConstant;
       }
     }
-    errorReporter.invalidStaticInvocation(contextChain, node, target);
-    throw const _AbortCurrentEvaluation();
+    throw new _AbortCurrentEvaluation(
+        errorReporter.invalidStaticInvocation(contextChain, node, target));
   }
 
   visitAsExpression(AsExpression node) {
@@ -1192,9 +1240,8 @@
     if (constant is BoolConstant) {
       return constant == trueConstant ? falseConstant : trueConstant;
     }
-    errorReporter.invalidDartType(
-        contextChain, node, constant, typeEnvironment.boolType);
-    throw const _AbortCurrentEvaluation();
+    throw new _AbortCurrentEvaluation(errorReporter.invalidDartType(
+        contextChain, node, constant, typeEnvironment.boolType));
   }
 
   visitSymbolLiteral(SymbolLiteral node) {
@@ -1222,43 +1269,18 @@
 
   @override
   visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
-    errorReporter.deferredLibrary(contextChain, node, node.import.name);
-    throw const _AbortCurrentEvaluation();
+    throw new _AbortCurrentEvaluation(
+        errorReporter.deferredLibrary(contextChain, node, node.import.name));
   }
 
   // Helper methods:
 
   void ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
-    DartType constantType;
-    if (constant is NullConstant) {
-      constantType = new InterfaceType(coreTypes.nullClass);
-    } else if (constant is BoolConstant) {
-      constantType = new InterfaceType(coreTypes.boolClass);
-    } else if (constant is IntConstant) {
-      constantType = new InterfaceType(coreTypes.intClass);
-    } else if (constant is DoubleConstant) {
-      constantType = new InterfaceType(coreTypes.doubleClass);
-    } else if (constant is StringConstant) {
-      constantType = new InterfaceType(coreTypes.stringClass);
-    } else if (constant is MapConstant) {
-      constantType = new InterfaceType(
-          coreTypes.mapClass, <DartType>[constant.keyType, constant.valueType]);
-    } else if (constant is ListConstant) {
-      constantType = new InterfaceType(
-          coreTypes.stringClass, <DartType>[constant.typeArgument]);
-    } else if (constant is InstanceConstant) {
-      constantType = new InterfaceType(constant.klass, constant.typeArguments);
-    } else if (constant is TearOffConstant) {
-      constantType = constant.procedure.function.functionType;
-    } else if (constant is TypeLiteralConstant) {
-      constantType = new InterfaceType(coreTypes.typeClass);
-    } else {
-      throw new Exception('No support for ${constant.runtimeType}.runtimeType');
-    }
+    DartType constantType = constant.getType(typeEnvironment);
 
     if (!typeEnvironment.isSubtypeOf(constantType, type)) {
-      errorReporter.invalidDartType(contextChain, node, constant, type);
-      throw const _AbortCurrentEvaluation();
+      throw new _AbortCurrentEvaluation(
+          errorReporter.invalidDartType(contextChain, node, constant, type));
     }
   }
 
@@ -1281,8 +1303,8 @@
     final result = env.subsituteType(type);
 
     if (!isInstantiated(result)) {
-      errorReporter.freeTypeParameter(contextChain, node, type);
-      throw const _AbortCurrentEvaluation();
+      throw new _AbortCurrentEvaluation(
+          errorReporter.freeTypeParameter(contextChain, node, type));
     }
 
     return result;
@@ -1304,7 +1326,23 @@
     return named;
   }
 
-  canonicalize(Constant constant) {
+  Arguments unevaluatedArguments(Arguments arguments) {
+    final positional = new List<Expression>(arguments.positional.length);
+    final named = new List<NamedExpression>(arguments.named.length);
+    for (int i = 0; i < arguments.positional.length; ++i) {
+      Constant constant = arguments.positional[i].accept(this);
+      positional[i] = constant.asExpression();
+    }
+    for (int i = 0; i < arguments.named.length; ++i) {
+      NamedExpression arg = arguments.named[i];
+      Constant constant = arg.value.accept(this);
+      named[i] = new NamedExpression(arg.name, constant.asExpression());
+    }
+    return new Arguments(positional, named: named, types: arguments.types);
+  }
+
+  Constant canonicalize(Constant constant) {
+    constant = backend.lowerConstant(constant);
     return canonicalizationCache.putIfAbsent(constant, () => constant);
   }
 
@@ -1328,7 +1366,10 @@
     }
   }
 
-  evaluateBinaryNumericOperation(String op, num a, num b, TreeNode node) {
+  Constant evaluateBinaryNumericOperation(
+      String op, num a, num b, TreeNode node) {
+    a = backend.prepareNumericOperand(a);
+    b = backend.prepareNumericOperand(b);
     num result;
     switch (op) {
       case '+':
@@ -1353,7 +1394,7 @@
 
     if (result != null) {
       return canonicalize(result is int
-          ? new IntConstant(_wrapAroundInteger(result))
+          ? new IntConstant(result.toSigned(64))
           : new DoubleConstant(result as double));
     }
 
@@ -1371,13 +1412,6 @@
     throw new Exception("Unexpected binary numeric operation '$op'.");
   }
 
-  int _wrapAroundInteger(int value) {
-    if (!legacyMode) {
-      return value.toSigned(64);
-    }
-    return value;
-  }
-
   Library libraryOf(TreeNode node) {
     // The tree structure of the kernel AST ensures we always have an enclosing
     // library.
@@ -1457,23 +1491,22 @@
   }
 }
 
-abstract class ConstantsBackend {
-  Constant buildConstantForNative(
-      String nativeName,
-      List<DartType> typeArguments,
-      List<Constant> positionalArguments,
-      Map<String, Constant> namedArguments,
-      List<TreeNode> context,
-      StaticInvocation node,
-      ErrorReporter errorReporter,
-      void abortEvaluation());
-  Constant lowerListConstant(ListConstant constant);
-  Constant lowerMapConstant(MapConstant constant);
+// Backend specific constant evaluation behavior
+class ConstantsBackend {
+  /// Transformation of constants prior to canonicalization, e.g. to change the
+  /// representation of certain kinds of constants, or to implement specific
+  /// number semantics.
+  Constant lowerConstant(Constant constant) => constant;
+
+  /// Transformation of numeric operands prior to a binary operation,
+  /// e.g. to implement specific number semantics.
+  num prepareNumericOperand(num operand) => operand;
 }
 
 // Used as control-flow to abort the current evaluation.
 class _AbortCurrentEvaluation {
-  const _AbortCurrentEvaluation();
+  final String message;
+  _AbortCurrentEvaluation(this.message);
 }
 
 abstract class ErrorReporter {
@@ -1493,66 +1526,71 @@
     return node == null ? TreeNode.noOffset : node.fileOffset;
   }
 
-  void freeTypeParameter(List<TreeNode> context, TreeNode node, DartType type);
-  void invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
-      DartType expectedType);
-  void invalidBinaryOperandType(List<TreeNode> context, TreeNode node,
+  String freeTypeParameter(
+      List<TreeNode> context, TreeNode node, DartType type);
+  String invalidDartType(List<TreeNode> context, TreeNode node,
+      Constant receiver, DartType expectedType);
+  String invalidBinaryOperandType(List<TreeNode> context, TreeNode node,
       Constant receiver, String op, DartType expectedType, DartType actualType);
-  void invalidMethodInvocation(
+  String invalidMethodInvocation(
       List<TreeNode> context, TreeNode node, Constant receiver, String op);
-  void invalidStaticInvocation(
-      List<TreeNode> context, TreeNode node, Procedure target);
-  void invalidStringInterpolationOperand(
+  String invalidStaticInvocation(
+      List<TreeNode> context, TreeNode node, Member target);
+  String invalidStringInterpolationOperand(
       List<TreeNode> context, TreeNode node, Constant constant);
-  void invalidSymbolName(
+  String invalidSymbolName(
       List<TreeNode> context, TreeNode node, Constant constant);
-  void zeroDivisor(
+  String zeroDivisor(
       List<TreeNode> context, TreeNode node, IntConstant receiver, String op);
-  void negativeShift(List<TreeNode> context, TreeNode node,
+  String negativeShift(List<TreeNode> context, TreeNode node,
       IntConstant receiver, String op, IntConstant argument);
-  void nonConstLiteral(List<TreeNode> context, TreeNode node, String klass);
-  void duplicateKey(List<TreeNode> context, TreeNode node, Constant key);
-  void failedAssertion(List<TreeNode> context, TreeNode node, String message);
-  void nonConstantVariableGet(
+  String nonConstLiteral(List<TreeNode> context, TreeNode node, String klass);
+  String duplicateKey(List<TreeNode> context, TreeNode node, Constant key);
+  String failedAssertion(List<TreeNode> context, TreeNode node, String message);
+  String nonConstantVariableGet(
       List<TreeNode> context, TreeNode node, String variableName);
-  void deferredLibrary(
+  String deferredLibrary(
       List<TreeNode> context, TreeNode node, String importName);
+  String circularity(List<TreeNode> context, TreeNode node);
 }
 
 class SimpleErrorReporter extends ErrorReporter {
   const SimpleErrorReporter();
 
-  void report(List<TreeNode> context, String message, TreeNode node) {
+  String report(List<TreeNode> context, String what, TreeNode node) {
     io.exitCode = 42;
     final Uri uri = getFileUri(node);
     final int fileOffset = getFileOffset(node);
-
-    io.stderr.writeln('$uri:$fileOffset Constant evaluation error: $message');
+    final String message = '$uri:$fileOffset Constant evaluation error: $what';
+    io.stderr.writeln(message);
+    return message;
   }
 
   @override
-  void freeTypeParameter(List<TreeNode> context, TreeNode node, DartType type) {
-    report(context, 'Expected type to be instantiated but was ${type}', node);
+  String freeTypeParameter(
+      List<TreeNode> context, TreeNode node, DartType type) {
+    return report(
+        context, 'Expected type to be instantiated but was ${type}', node);
   }
 
   @override
-  void invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
-      DartType expectedType) {
-    report(
+  String invalidDartType(List<TreeNode> context, TreeNode node,
+      Constant receiver, DartType expectedType) {
+    return report(
         context,
         'Expected expression to evaluate to "$expectedType" but got "$receiver.',
         node);
   }
 
   @override
-  void invalidBinaryOperandType(
+  String invalidBinaryOperandType(
       List<TreeNode> context,
       TreeNode node,
       Constant receiver,
       String op,
       DartType expectedType,
       DartType actualType) {
-    report(
+    return report(
         context,
         'Calling "$op" on "$receiver" needs operand of type '
         '"$expectedType" (but got "$actualType")',
@@ -1560,23 +1598,23 @@
   }
 
   @override
-  void invalidMethodInvocation(
+  String invalidMethodInvocation(
       List<TreeNode> context, TreeNode node, Constant receiver, String op) {
-    report(context, 'Cannot call "$op" on "$receiver" in constant expression',
-        node);
+    return report(context,
+        'Cannot call "$op" on "$receiver" in constant expression', node);
   }
 
   @override
-  void invalidStaticInvocation(
-      List<TreeNode> context, TreeNode node, Procedure target) {
-    report(
+  String invalidStaticInvocation(
+      List<TreeNode> context, TreeNode node, Member target) {
+    return report(
         context, 'Cannot invoke "$target" inside a constant expression', node);
   }
 
   @override
-  void invalidStringInterpolationOperand(
+  String invalidStringInterpolationOperand(
       List<TreeNode> context, TreeNode node, Constant constant) {
-    report(
+    return report(
         context,
         'Only null/bool/int/double/String values are allowed as string '
         'interpolation expressions during constant evaluation (was: "$constant").',
@@ -1584,9 +1622,9 @@
   }
 
   @override
-  void invalidSymbolName(
+  String invalidSymbolName(
       List<TreeNode> context, TreeNode node, Constant constant) {
-    report(
+    return report(
         context,
         'The symbol name must be a valid public Dart member name, public '
         'constructor name, or library name, optionally qualified.',
@@ -1594,9 +1632,9 @@
   }
 
   @override
-  void zeroDivisor(
+  String zeroDivisor(
       List<TreeNode> context, TreeNode node, IntConstant receiver, String op) {
-    report(
+    return report(
         context,
         "Binary operator '$op' on '${receiver.value}' requires non-zero "
         "divisor, but divisor was '0'.",
@@ -1604,9 +1642,9 @@
   }
 
   @override
-  void negativeShift(List<TreeNode> context, TreeNode node,
+  String negativeShift(List<TreeNode> context, TreeNode node,
       IntConstant receiver, String op, IntConstant argument) {
-    report(
+    return report(
         context,
         "Binary operator '$op' on '${receiver.value}' requires non-negative "
         "operand, but was '${argument.value}'.",
@@ -1614,33 +1652,34 @@
   }
 
   @override
-  void nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
-    report(
+  String nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+    return report(
         context,
         'Cannot have a non-constant $klass literal within a const context.',
         node);
   }
 
   @override
-  void duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
-    report(
+  String duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
+    return report(
         context,
         'Duplicate keys are not allowed in constant maps (found duplicate key "$key")',
         node);
   }
 
   @override
-  void failedAssertion(List<TreeNode> context, TreeNode node, String message) {
-    report(
+  String failedAssertion(
+      List<TreeNode> context, TreeNode node, String message) {
+    return report(
         context,
         'The assertion condition evaluated to "false" with message "$message"',
         node);
   }
 
   @override
-  void nonConstantVariableGet(
+  String nonConstantVariableGet(
       List<TreeNode> context, TreeNode node, String variableName) {
-    report(
+    return report(
         context,
         'The variable "$variableName" cannot be used inside a constant '
         'expression.',
@@ -1648,14 +1687,19 @@
   }
 
   @override
-  void deferredLibrary(
+  String deferredLibrary(
       List<TreeNode> context, TreeNode node, String importName) {
-    report(
+    return report(
         context,
         'Deferred "$importName" cannot be used inside a constant '
         'expression',
         node);
   }
+
+  @override
+  String circularity(List<TreeNode> context, TreeNode node) {
+    return report(context, 'Constant expression depends on itself.', node);
+  }
 }
 
 class IsInstantiatedVisitor extends DartTypeVisitor<bool> {
diff --git a/pkg/kernel/lib/transformations/treeshaker.dart b/pkg/kernel/lib/transformations/treeshaker.dart
index 07218c9..b340326 100644
--- a/pkg/kernel/lib/transformations/treeshaker.dart
+++ b/pkg/kernel/lib/transformations/treeshaker.dart
@@ -977,7 +977,7 @@
 
   @override
   visitInstanceConstant(InstanceConstant node) {
-    shaker._addInstantiatedClass(node.klass);
+    shaker._addInstantiatedClass(node.classNode);
     super.visitInstanceConstant(node);
   }
 
diff --git a/pkg/kernel/lib/type_environment.dart b/pkg/kernel/lib/type_environment.dart
index b532e87..20cceb6 100644
--- a/pkg/kernel/lib/type_environment.dart
+++ b/pkg/kernel/lib/type_environment.dart
@@ -165,11 +165,6 @@
 
   InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass);
 
-  /// Determines if the given type is at the bottom of the type hierarchy.  May
-  /// be overridden in subclasses.
-  bool isBottom(DartType type) =>
-      type is BottomType || (!legacyMode && type == nullType);
-
   /// Determines if the given type is at the top of the type hierarchy.  May be
   /// overridden in subclasses.
   bool isTop(DartType type) =>
@@ -180,7 +175,11 @@
     subtype = subtype.unalias;
     supertype = supertype.unalias;
     if (identical(subtype, supertype)) return true;
-    if (isBottom(subtype)) return true;
+    if (subtype is BottomType) return true;
+    if (subtype == nullType) {
+      // See rule 4 of the subtype rules from the Dart Language Specification.
+      return supertype is! BottomType;
+    }
     if (isTop(supertype)) return true;
 
     // Handle FutureOr<T> union type.
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 79a3be8..a83374b 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -295,12 +295,6 @@
       defaultConstant(node);
   R visitTearOffConstant(TearOffConstant node) => defaultConstant(node);
   R visitTypeLiteralConstant(TypeLiteralConstant node) => defaultConstant(node);
-  R visitEnvironmentBoolConstant(EnvironmentBoolConstant node) =>
-      defaultConstant(node);
-  R visitEnvironmentIntConstant(EnvironmentIntConstant node) =>
-      defaultConstant(node);
-  R visitEnvironmentStringConstant(EnvironmentStringConstant node) =>
-      defaultConstant(node);
   R visitUnevaluatedConstant(UnevaluatedConstant node) => defaultConstant(node);
 }
 
@@ -355,12 +349,6 @@
       defaultConstant(node);
   R visitTearOffConstant(TearOffConstant node) => defaultConstant(node);
   R visitTypeLiteralConstant(TypeLiteralConstant node) => defaultConstant(node);
-  R visitEnvironmentBoolConstant(EnvironmentBoolConstant node) =>
-      defaultConstant(node);
-  R visitEnvironmentIntConstant(EnvironmentIntConstant node) =>
-      defaultConstant(node);
-  R visitEnvironmentStringConstant(EnvironmentStringConstant node) =>
-      defaultConstant(node);
   R visitUnevaluatedConstant(UnevaluatedConstant node) => defaultConstant(node);
 
   // Class references
@@ -394,12 +382,6 @@
       defaultConstantReference(node);
   R visitTypeLiteralConstantReference(TypeLiteralConstant node) =>
       defaultConstantReference(node);
-  R visitEnvironmentBoolConstantReference(EnvironmentBoolConstant node) =>
-      defaultConstantReference(node);
-  R visitEnvironmentIntConstantReference(EnvironmentIntConstant node) =>
-      defaultConstantReference(node);
-  R visitEnvironmentStringConstantReference(EnvironmentStringConstant node) =>
-      defaultConstantReference(node);
   R visitUnevaluatedConstantReference(UnevaluatedConstant node) =>
       defaultConstantReference(node);
 
diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart
index e3611d2..58c8eca 100644
--- a/pkg/kernel/lib/vm/constants_native_effects.dart
+++ b/pkg/kernel/lib/vm/constants_native_effects.dart
@@ -8,150 +8,48 @@
 import '../transformations/constants.dart';
 import '../core_types.dart';
 
-class VmConstantsBackend implements ConstantsBackend {
-  final Map<String, String> defines;
-
+class VmConstantsBackend extends ConstantsBackend {
   final Class immutableMapClass;
-  final Class internalSymbolClass;
-  final Class stringClass;
-  final Field symbolNameField;
 
-  VmConstantsBackend._(this.defines, this.immutableMapClass,
-      this.internalSymbolClass, this.stringClass, this.symbolNameField);
+  VmConstantsBackend._(this.immutableMapClass);
 
   /// If [defines] is not `null` it will be used for handling
   /// `const {bool,...}.fromEnvironment()` otherwise the current VM's values
   /// will be used.
-  factory VmConstantsBackend(Map<String, String> defines, CoreTypes coreTypes) {
+  factory VmConstantsBackend(CoreTypes coreTypes) {
     final Library coreLibrary = coreTypes.coreLibrary;
     final Class immutableMapClass = coreLibrary.classes
         .firstWhere((Class klass) => klass.name == '_ImmutableMap');
     assert(immutableMapClass != null);
 
-    final Class internalSymbolClass = coreTypes.internalSymbolClass;
-    assert(internalSymbolClass != null);
-
-    final Class stringClass = coreTypes.stringClass;
-    assert(stringClass != null);
-
-    final Field symbolNameField =
-        internalSymbolClass.fields.where((Field field) {
-      return field.isInstanceMember && field.name.name == '_name';
-    }).single;
-
-    return new VmConstantsBackend._(defines, immutableMapClass,
-        internalSymbolClass, stringClass, symbolNameField);
+    return new VmConstantsBackend._(immutableMapClass);
   }
 
-  Constant buildConstantForNative(
-      String nativeName,
-      List<DartType> typeArguments,
-      List<Constant> positionalArguments,
-      Map<String, Constant> namedArguments,
-      List<TreeNode> context,
-      StaticInvocation node,
-      ErrorReporter errorReporter,
-      void abortEvaluation()) {
-    if ([
-      'Bool_fromEnvironment',
-      'Integer_fromEnvironment',
-      'String_fromEnvironment'
-    ].contains(nativeName)) {
-      final argument = positionalArguments[0];
-      if (argument is StringConstant) {
-        final name = argument.value;
-
-        Constant handleFromEnvironment<ValueT, ConstantT>(
-            {ValueT defaultValue,
-            ValueT parse(String v, {ValueT defaultValue}),
-            ValueT fromEnvironment(String name, {ValueT defaultValue}),
-            ConstantT makeConstant(ValueT val)}) {
-          final Constant constant = namedArguments['defaultValue'];
-          if (constant is ConstantT) {
-            defaultValue = (constant as dynamic).value;
-          } else if (constant is NullConstant) {
-            defaultValue = null;
-          }
-          ValueT value;
-          if (defines != null) {
-            value = parse(defines[name], defaultValue: defaultValue);
-          } else {
-            value = fromEnvironment(name, defaultValue: defaultValue);
-          }
-          return value != null ? makeConstant(value) : new NullConstant();
-        }
-
-        switch (nativeName) {
-          case 'Bool_fromEnvironment':
-            return handleFromEnvironment<bool, BoolConstant>(
-                defaultValue: false,
-                parse: (String v, {bool defaultValue}) {
-                  final String defineValue = defines[name];
-                  return defineValue == 'true'
-                      ? true
-                      : (defineValue == 'false' ? false : defaultValue);
-                },
-                fromEnvironment: (v, {defaultValue}) =>
-                    bool.fromEnvironment(v, defaultValue: defaultValue),
-                makeConstant: (v) => BoolConstant(v));
-          case 'Integer_fromEnvironment':
-            return handleFromEnvironment<int, IntConstant>(
-                defaultValue: null,
-                parse: (String v, {int defaultValue}) {
-                  final String defineValue = defines[name];
-                  return defineValue != null
-                      ? (int.tryParse(defineValue) ?? defaultValue)
-                      : defaultValue;
-                },
-                fromEnvironment: (v, {defaultValue}) =>
-                    int.fromEnvironment(v, defaultValue: defaultValue),
-                makeConstant: (v) => new IntConstant(v));
-          case 'String_fromEnvironment':
-            return handleFromEnvironment<String, StringConstant>(
-                defaultValue: null,
-                parse: (String v, {String defaultValue}) {
-                  final String defineValue = defines[name];
-                  return defineValue ?? defaultValue;
-                },
-                fromEnvironment: (v, {defaultValue}) =>
-                    String.fromEnvironment(v, defaultValue: defaultValue),
-                makeConstant: (v) => new StringConstant(v));
-        }
-      } else {
-        errorReporter.invalidDartType(context, node.arguments.positional.first,
-            argument, new InterfaceType(stringClass));
-        abortEvaluation();
+  @override
+  Constant lowerConstant(Constant constant) {
+    if (constant is MapConstant) {
+      // The _ImmutableMap class is implemented via one field pointing to a list
+      // of key/value pairs -- see runtime/lib/immutable_map.dart!
+      final List<Constant> kvListPairs =
+          new List<Constant>(2 * constant.entries.length);
+      for (int i = 0; i < constant.entries.length; i++) {
+        final ConstantMapEntry entry = constant.entries[i];
+        kvListPairs[2 * i] = entry.key;
+        kvListPairs[2 * i + 1] = entry.value;
       }
+      // This is a bit fishy, since we merge the key and the value type by
+      // putting both into the same list.
+      final kvListConstant = new ListConstant(const DynamicType(), kvListPairs);
+      assert(immutableMapClass.fields.length == 1);
+      final Field kvPairListField = immutableMapClass.fields[0];
+      return new InstanceConstant(immutableMapClass.reference, <DartType>[
+        constant.keyType,
+        constant.valueType,
+      ], <Reference, Constant>{
+        kvPairListField.reference: kvListConstant,
+      });
     }
 
-    throw 'No native effect registered for constant evaluation: $nativeName';
-  }
-
-  Constant lowerMapConstant(MapConstant constant) {
-    // The _ImmutableMap class is implemented via one field pointing to a list
-    // of key/value pairs -- see runtime/lib/immutable_map.dart!
-    final List<Constant> kvListPairs =
-        new List<Constant>(2 * constant.entries.length);
-    for (int i = 0; i < constant.entries.length; i++) {
-      final ConstantMapEntry entry = constant.entries[i];
-      kvListPairs[2 * i] = entry.key;
-      kvListPairs[2 * i + 1] = entry.value;
-    }
-    // This is a bit fishy, since we merge the key and the value type by
-    // putting both into the same list.
-    final kvListConstant = new ListConstant(const DynamicType(), kvListPairs);
-    assert(immutableMapClass.fields.length == 1);
-    final Field kvPairListField = immutableMapClass.fields[0];
-    return new InstanceConstant(immutableMapClass.reference, <DartType>[
-      constant.keyType,
-      constant.valueType,
-    ], <Reference, Constant>{
-      kvPairListField.reference: kvListConstant,
-    });
-  }
-
-  Constant lowerListConstant(ListConstant constant) {
-    // Currently we let vipunen deal with the [ListConstant]s.
     return constant;
   }
 }
diff --git a/pkg/kernel/problems.md b/pkg/kernel/problems.md
new file mode 100644
index 0000000..3c1fb5e
--- /dev/null
+++ b/pkg/kernel/problems.md
@@ -0,0 +1,24 @@
+<!--
+Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+for details. All rights reserved. Use of this source code is governed by a
+BSD-style license that can be found in the LICENSE file.
+-->
+
+This file describes the format of the `problemsAsJson` strings in Dart Kernel.
+
+Each string in the list is a json object consisting of these keys and values:
+
+`ansiFormatted`: A list of strings the contain ansi formatted (for instance with
+colors) problem-texts as reported by the compiler.
+
+`plainTextFormatted`: A list of strings that contain formatted plaintext
+problem-texts as reported by the compiler.
+
+`severity`: An integer representing severity. This should match the index in
+`package:front_end/src/fasta/severity.dart`.
+
+`uri: A uri that this problems relates to.
+
+These values are subject to change, but this file will be updated along with any
+such changes. On the code-side these are defined in
+`package:front_end/src/fasta/fasta_codes.dart`.
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index f9ee3da..21e199c 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
 name: kernel
 # Currently, kernel API is not stable and users should
 # not depend on semver semantics when depending on this package.
-version: 0.3.8
+version: 0.3.11
 author: Dart Team <misc@dartlang.org>
 description: Dart IR (Intermediate Representation)
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -13,9 +13,9 @@
 dev_dependencies:
   expect:
     path: ../expect
-  front_end: 0.1.8
-  test: ^1.3.4
-  stack_trace: ^1.6.6
-  test_reflective_loader: ^0.1.0
+  front_end:
+    path: ../front_end
+  test:
+    path: ../third_party/pkg/test
   testing:
     path: ../testing
diff --git a/pkg/kernel/test/binary/library_flags_test.dart b/pkg/kernel/test/binary/library_flags_test.dart
new file mode 100644
index 0000000..9389b21
--- /dev/null
+++ b/pkg/kernel/test/binary/library_flags_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'utils.dart';
+
+/// Test that library flags (external, synthetic)
+/// are serialized and read correctly.
+main() {
+  Library lib = new Library(Uri.parse("foo://bar.dart"));
+  lib.isExternal = false;
+  lib.isSynthetic = false;
+  Library lib2 = libRoundTrip(lib);
+  if (lib2.isExternal != false)
+    throw "Serialized and re-read library had change in external flag.";
+  if (lib2.isSynthetic != false)
+    throw "Serialized and re-read library had change in synthetic flag.";
+
+  lib = new Library(Uri.parse("foo://bar.dart"));
+  lib.isExternal = true;
+  lib.isSynthetic = false;
+  lib2 = libRoundTrip(lib);
+  if (lib2.isExternal != true)
+    throw "Serialized and re-read library had change in external flag.";
+  if (lib2.isSynthetic != false)
+    throw "Serialized and re-read library had change in synthetic flag.";
+
+  lib = new Library(Uri.parse("foo://bar.dart"));
+  lib.isExternal = false;
+  lib.isSynthetic = true;
+  lib2 = libRoundTrip(lib);
+  if (lib2.isExternal != false)
+    throw "Serialized and re-read library had change in external flag.";
+  if (lib2.isSynthetic != true)
+    throw "Serialized and re-read library had change in synthetic flag.";
+
+  lib = new Library(Uri.parse("foo://bar.dart"));
+  lib.isExternal = true;
+  lib.isSynthetic = true;
+  lib2 = libRoundTrip(lib);
+  if (lib2.isExternal != true)
+    throw "Serialized and re-read library had change in external flag.";
+  if (lib2.isSynthetic != true)
+    throw "Serialized and re-read library had change in synthetic flag.";
+}
diff --git a/pkg/kernel/test/binary/utils.dart b/pkg/kernel/test/binary/utils.dart
new file mode 100644
index 0000000..28bf4be
--- /dev/null
+++ b/pkg/kernel/test/binary/utils.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' show BytesBuilder;
+
+import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
+import 'package:kernel/kernel.dart';
+export 'package:kernel/kernel.dart';
+
+Library libRoundTrip(Library lib) {
+  return serializationRoundTrip([lib])[0];
+}
+
+List<Library> serializationRoundTrip(List<Library> libraries) {
+  Component c = new Component(libraries: libraries);
+  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;
+}
+
+/// A [Sink] that directly writes data into a byte builder.
+class ByteSink implements Sink<List<int>> {
+  final BytesBuilder builder = new BytesBuilder();
+
+  void add(List<int> data) {
+    builder.add(data);
+  }
+
+  void close() {}
+}
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index 956c0cf..c195192 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -2,23 +2,96 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/core_types.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
-import 'package:kernel/text/ast_to_text.dart';
-import 'package:kernel/type_algebra.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
+import "package:expect/matchers_lite.dart";
+
+import "package:kernel/ast.dart";
+import "package:kernel/class_hierarchy.dart";
+import "package:kernel/core_types.dart";
+import "package:kernel/testing/mock_sdk_component.dart";
+import "package:kernel/text/ast_to_text.dart";
 
 main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ClosedWorldClassHierarchyTest);
-  });
+  new ClosedWorldClassHierarchyTest().test_applyTreeChanges();
+
+  new ClosedWorldClassHierarchyTest().test_applyMemberChanges();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getSingleTargetForInterfaceInvocation();
+
+  new ClosedWorldClassHierarchyTest().test_getSubtypesOf();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_forEachOverridePair_supertypeOverridesInterface();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_forEachOverridePair_supertypeOverridesThis();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_forEachOverridePair_supertypeOverridesThisAbstract();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_forEachOverridePair_thisOverridesSupertype();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_forEachOverridePair_thisOverridesSupertype_setter();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getClassAsInstanceOf_generic_extends();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getClassAsInstanceOf_generic_implements();
+
+  new ClosedWorldClassHierarchyTest().test_getClassAsInstanceOf_generic_with();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getClassAsInstanceOf_notGeneric_extends();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getClassAsInstanceOf_notGeneric_implements();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getClassAsInstanceOf_notGeneric_with();
+
+  new ClosedWorldClassHierarchyTest().test_getDeclaredMembers();
+
+  new ClosedWorldClassHierarchyTest().test_getDispatchTarget();
+
+  new ClosedWorldClassHierarchyTest().test_getDispatchTarget_abstract();
+
+  new ClosedWorldClassHierarchyTest().test_getInterfaceMember_extends();
+
+  new ClosedWorldClassHierarchyTest().test_getInterfaceMember_implements();
+
+  new ClosedWorldClassHierarchyTest().test_getInterfaceMembers_in_class();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getInterfaceMembers_inherited_or_mixed_in();
+
+  new ClosedWorldClassHierarchyTest().test_getInterfaceMembers_multiple();
+
+  new ClosedWorldClassHierarchyTest().test_getInterfaceMembers_shadowed();
+
+  new ClosedWorldClassHierarchyTest().test_getOrderedClasses();
+
+  new ClosedWorldClassHierarchyTest()
+      .test_getTypeAsInstanceOf_generic_extends();
 }
 
-@reflectiveTest
-class ClosedWorldClassHierarchyTest extends _ClassHierarchyTest {
+class ClosedWorldClassHierarchyTest {
+  final Component component = createMockSdkComponent();
+  CoreTypes coreTypes;
+
+  final Library library =
+      new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');
+
+  ClassHierarchy _hierarchy;
+
+  ClosedWorldClassHierarchyTest() {
+    coreTypes = new CoreTypes(component);
+    library.parent = component;
+    component.libraries.add(library);
+  }
+
   ClassHierarchy createClassHierarchy(Component component) {
     return new ClassHierarchy(component);
   }
@@ -208,16 +281,6 @@
     expect(cwchst.getSubtypesOf(g), unorderedEquals([g, h]));
     expect(cwchst.getSubtypesOf(h), unorderedEquals([h]));
   }
-}
-
-abstract class _ClassHierarchyTest {
-  Component component;
-  CoreTypes coreTypes;
-
-  /// The test library.
-  Library library;
-
-  ClassHierarchy _hierarchy;
 
   /// Return the new or existing instance of [ClassHierarchy].
   ClassHierarchy get hierarchy {
@@ -259,17 +322,6 @@
         implementedTypes: implementedTypes));
   }
 
-  /// Add a new class with the given [name] that extends `Object` and
-  /// [implements_] the given classes.
-  Class addImplementsClass(String name, List<Class> implements_) {
-    return addClass(new Class(
-        name: name,
-        supertype: objectSuper,
-        implementedTypes: implements_.map((c) => c.asThisSupertype).toList()));
-  }
-
-  ClassHierarchy createClassHierarchy(Component component);
-
   Procedure newEmptyGetter(String name,
       {DartType returnType: const DynamicType(), bool isAbstract: false}) {
     var body =
@@ -296,17 +348,6 @@
             positionalParameters: [new VariableDeclaration('_', type: type)]));
   }
 
-  void setUp() {
-    // Start with mock SDK libraries.
-    component = createMockSdkComponent();
-    coreTypes = new CoreTypes(component);
-
-    // Add the test library.
-    library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');
-    library.parent = component;
-    component.libraries.add(library);
-  }
-
   /// 2. A non-abstract member is inherited from a superclass, and in the
   /// context of this class, it overrides an abstract member inheritable through
   /// one of its superinterfaces.
@@ -646,175 +687,6 @@
     expect(hierarchy.getClassAsInstanceOf(z, a), null);
   }
 
-  /// Copy of the tests/language/least_upper_bound_expansive_test.dart test.
-  void test_getLegacyLeastUpperBound_expansive() {
-    var int = coreTypes.intClass.rawType;
-    var string = coreTypes.stringClass.rawType;
-
-    // class N<T> {}
-    var NT = new TypeParameter('T', objectClass.rawType);
-    var N = addClass(
-        new Class(name: 'N', typeParameters: [NT], supertype: objectSuper));
-
-    // class C1<T> extends N<N<C1<T>>> {}
-    Class C1;
-    {
-      var T = new TypeParameter('T', objectClass.rawType);
-      C1 = addClass(
-          new Class(name: 'C1', typeParameters: [T], supertype: objectSuper));
-      DartType C1_T = Substitution.fromMap({T: new TypeParameterType(T)})
-          .substituteType(C1.thisType);
-      DartType N_C1_T =
-          Substitution.fromMap({NT: C1_T}).substituteType(N.thisType);
-      Supertype N_N_C1_T = Substitution.fromMap({NT: N_C1_T})
-          .substituteSupertype(N.asThisSupertype);
-      C1.supertype = N_N_C1_T;
-    }
-
-    // class C2<T> extends N<N<C2<N<C2<T>>>>> {}
-    Class C2;
-    {
-      var T = new TypeParameter('T', objectClass.rawType);
-      C2 = addClass(
-          new Class(name: 'C2', typeParameters: [T], supertype: objectSuper));
-      DartType C2_T = Substitution.fromMap({T: new TypeParameterType(T)})
-          .substituteType(C2.thisType);
-      DartType N_C2_T =
-          Substitution.fromMap({NT: C2_T}).substituteType(N.thisType);
-      DartType C2_N_C2_T =
-          Substitution.fromMap({T: N_C2_T}).substituteType(C2.thisType);
-      DartType N_C2_N_C2_T =
-          Substitution.fromMap({NT: C2_N_C2_T}).substituteType(N.thisType);
-      Supertype N_N_C2_N_C2_T = Substitution.fromMap({NT: N_C2_N_C2_T})
-          .substituteSupertype(N.asThisSupertype);
-      C2.supertype = N_N_C2_N_C2_T;
-    }
-
-    _assertTestLibraryText('''
-class N<T> {}
-class C1<T> extends self::N<self::N<self::C1<self::C1::T>>> {}
-class C2<T> extends self::N<self::N<self::C2<self::N<self::C2<self::C2::T>>>>> {}
-''');
-
-    // The least upper bound of C1<int> and N<C1<String>> is Object since the
-    // supertypes are
-    //     {C1<int>, N<N<C1<int>>>, Object} for C1<int> and
-    //     {N<C1<String>>, Object} for N<C1<String>> and
-    // Object is the most specific type in the intersection of the supertypes.
-    expect(
-        hierarchy.getLegacyLeastUpperBound(
-            new InterfaceType(C1, [int]),
-            new InterfaceType(N, [
-              new InterfaceType(C1, [string])
-            ])),
-        objectClass.thisType);
-
-    // The least upper bound of C2<int> and N<C2<String>> is Object since the
-    // supertypes are
-    //     {C2<int>, N<N<C2<N<C2<int>>>>>, Object} for C2<int> and
-    //     {N<C2<String>>, Object} for N<C2<String>> and
-    // Object is the most specific type in the intersection of the supertypes.
-    expect(
-        hierarchy.getLegacyLeastUpperBound(
-            new InterfaceType(C2, [int]),
-            new InterfaceType(N, [
-              new InterfaceType(C2, [string])
-            ])),
-        objectClass.thisType);
-  }
-
-  void test_getLegacyLeastUpperBound_generic() {
-    var int = coreTypes.intClass.rawType;
-    var double = coreTypes.doubleClass.rawType;
-    var bool = coreTypes.boolClass.rawType;
-
-    var a = addGenericClass('A', []);
-    var b =
-        addGenericClass('B', ['T'], implements_: (_) => [a.asThisSupertype]);
-    var c =
-        addGenericClass('C', ['U'], implements_: (_) => [a.asThisSupertype]);
-    var d = addGenericClass('D', ['T', 'U'], implements_: (typeParameterTypes) {
-      var t = typeParameterTypes[0];
-      var u = typeParameterTypes[1];
-      return [
-        new Supertype(b, [t]),
-        new Supertype(c, [u])
-      ];
-    });
-    var e = addGenericClass('E', [],
-        implements_: (_) => [
-              new Supertype(d, [int, double])
-            ]);
-    var f = addGenericClass('F', [],
-        implements_: (_) => [
-              new Supertype(d, [int, bool])
-            ]);
-
-    _assertTestLibraryText('''
-class A {}
-class B<T> implements self::A {}
-class C<U> implements self::A {}
-class D<T, U> implements self::B<self::D::T>, self::C<self::D::U> {}
-class E implements self::D<core::int, core::double> {}
-class F implements self::D<core::int, core::bool> {}
-''');
-
-    expect(
-        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
-            new InterfaceType(d, [int, double])),
-        new InterfaceType(d, [int, double]));
-    expect(
-        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
-            new InterfaceType(d, [int, bool])),
-        new InterfaceType(b, [int]));
-    expect(
-        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
-            new InterfaceType(d, [bool, double])),
-        new InterfaceType(c, [double]));
-    expect(
-        hierarchy.getLegacyLeastUpperBound(new InterfaceType(d, [int, double]),
-            new InterfaceType(d, [bool, int])),
-        a.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(e.rawType, f.rawType),
-        new InterfaceType(b, [int]));
-  }
-
-  void test_getLegacyLeastUpperBound_nonGeneric() {
-    var a = addImplementsClass('A', []);
-    var b = addImplementsClass('B', []);
-    var c = addImplementsClass('C', [a]);
-    var d = addImplementsClass('D', [a]);
-    var e = addImplementsClass('E', [a]);
-    var f = addImplementsClass('F', [c, d]);
-    var g = addImplementsClass('G', [c, d]);
-    var h = addImplementsClass('H', [c, d, e]);
-    var i = addImplementsClass('I', [c, d, e]);
-
-    _assertTestLibraryText('''
-class A {}
-class B {}
-class C implements self::A {}
-class D implements self::A {}
-class E implements self::A {}
-class F implements self::C, self::D {}
-class G implements self::C, self::D {}
-class H implements self::C, self::D, self::E {}
-class I implements self::C, self::D, self::E {}
-''');
-
-    expect(hierarchy.getLegacyLeastUpperBound(a.rawType, b.rawType),
-        objectClass.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(a.rawType, objectClass.rawType),
-        objectClass.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(objectClass.rawType, b.rawType),
-        objectClass.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(c.rawType, d.rawType), a.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(c.rawType, a.rawType), a.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(a.rawType, d.rawType), a.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(f.rawType, g.rawType), a.rawType);
-    expect(hierarchy.getLegacyLeastUpperBound(h.rawType, i.rawType), a.rawType);
-  }
-
   void test_getDeclaredMembers() {
     var method = newEmptyMethod('method');
     var getter = newEmptyGetter('getter');
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 f934baa..34f572b 100644
--- a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
+++ b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
@@ -14,37 +14,39 @@
 }
 
 // Wrappers for testing.
-Expression readExpression(
-    String input, DeserializationEnvironment environment) {
+Expression readExpression(String input, DeserializationState state) {
   TextIterator stream = new TextIterator(input, 0);
   stream.moveNext();
-  Expression result = expressionSerializer.readFrom(stream, environment);
+  Expression result = expressionSerializer.readFrom(stream, state);
   if (stream.moveNext()) {
     throw StateError("extra cruft in basic literal");
   }
   return result;
 }
 
-String writeExpression(
-    Expression expression, SerializationEnvironment environment) {
+String writeExpression(Expression expression, SerializationState state) {
   StringBuffer buffer = new StringBuffer();
-  expressionSerializer.writeTo(buffer, expression, environment);
+  expressionSerializer.writeTo(buffer, expression, state);
   return buffer.toString();
 }
 
 class TestCase {
   final String name;
   final Node node;
-  final SerializationEnvironment serializationEnvironment;
-  final DeserializationEnvironment deserializationEnvironment;
+  final SerializationState serializationState;
+  final DeserializationState deserializationState;
   final String expectation;
 
   TestCase(
       {this.name,
       this.node,
       this.expectation,
-      this.serializationEnvironment,
-      this.deserializationEnvironment});
+      SerializationState serializationState,
+      DeserializationState deserializationState})
+      : this.serializationState =
+            serializationState ?? new SerializationState(null),
+        this.deserializationState = deserializationState ??
+            new DeserializationState(null, new CanonicalName.root());
 }
 
 void test() {
@@ -92,19 +94,215 @@
           new VariableDeclaration("x", type: const DynamicType());
       return new TestCase(
           name: "/* suppose: dynamic x; */ x = 42",
-          node: () {
-            return new VariableSet(x, new IntLiteral(42));
-          }(),
+          node: new VariableSet(x, new IntLiteral(42)),
           expectation: "(set-var \"x^0\" (int 42))",
-          serializationEnvironment: new SerializationEnvironment(null)
-            ..add(x, "x^0"),
-          deserializationEnvironment: new DeserializationEnvironment(null)
-            ..add("x^0", x));
+          serializationState: new SerializationState(
+            new SerializationEnvironment(null)..add(x, "x^0"),
+          ),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null)..add("x^0", x),
+              new CanonicalName.root()));
+    }(),
+    () {
+      Field field = new Field(new Name("field"), type: const DynamicType());
+      Library library = new Library(
+          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",
+          node: new StaticGet(field),
+          expectation: "(get-static \"package:foo/bar.dart::@fields::field\")",
+          serializationState: new SerializationState(null),
+          deserializationState: new DeserializationState(null, component.root));
+    }(),
+    () {
+      Field field = new Field(new Name("field"), type: const DynamicType());
+      Library library = new Library(
+          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",
+          node: new StaticSet(field, new IntLiteral(1)),
+          expectation:
+              "(set-static \"package:foo/bar.dart::@fields::field\" (int 1))",
+          serializationState: new SerializationState(null),
+          deserializationState: new DeserializationState(null, component.root));
+    }(),
+    () {
+      Procedure topLevelProcedure = new Procedure(
+          new Name("foo"),
+          ProcedureKind.Method,
+          new FunctionNode(null, positionalParameters: <VariableDeclaration>[
+            new VariableDeclaration("x", type: const DynamicType())
+          ]),
+          isStatic: true);
+      Library library = new Library(
+          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)",
+          node: new StaticInvocation.byReference(topLevelProcedure.reference,
+              new Arguments(<Expression>[new IntLiteral(42)]),
+              isConst: false),
+          expectation: ""
+              "(invoke-static \"package:foo/bar.dart::@methods::foo\""
+              " () ((int 42)) ())",
+          serializationState: new SerializationState(null),
+          deserializationState: new DeserializationState(null, component.root));
+    }(),
+    () {
+      Procedure factoryConstructor = new Procedure(
+          new Name("foo"), ProcedureKind.Factory, new FunctionNode(null),
+          isStatic: true, isConst: true);
+      Class klass =
+          new Class(name: "A", procedures: <Procedure>[factoryConstructor]);
+      Library library = new Library(
+          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()",
+          node: new StaticInvocation.byReference(
+              factoryConstructor.reference, new Arguments([]),
+              isConst: true),
+          expectation: ""
+              "(invoke-const-static"
+              " \"package:foo/bar.dart::A::@factories::foo\""
+              " () () ())",
+          serializationState: new SerializationState(null),
+          deserializationState: new DeserializationState(null, component.root));
+    }(),
+    () {
+      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"),
+          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}",
+          node: new DirectPropertyGet.byReference(
+              new VariableGet(x), field.reference),
+          expectation: ""
+              "(get-direct-prop (get-var \"x^0\" _)"
+              " \"package:foo/bar.dart::A::@fields::field\")",
+          serializationState: new SerializationState(
+              new SerializationEnvironment(null)..add(x, "x^0")),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null)..add("x^0", x),
+              component.root));
+    }(),
+    () {
+      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"),
+          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",
+          node: new DirectPropertySet.byReference(
+              new VariableGet(x), field.reference, new IntLiteral(42)),
+          expectation: ""
+              "(set-direct-prop (get-var \"x^0\" _)"
+              " \"package:foo/bar.dart::A::@fields::field\" (int 42))",
+          serializationState: new SerializationState(
+              new SerializationEnvironment(null)..add(x, "x^0")),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null)..add("x^0", x),
+              component.root));
+    }(),
+    () {
+      Procedure method = new Procedure(
+          new Name("foo"), ProcedureKind.Method, new FunctionNode(null),
+          isStatic: true, isConst: true);
+      Class klass = new Class(name: "A", procedures: <Procedure>[method]);
+      Library library = new Library(
+          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}()",
+          node: new DirectMethodInvocation.byReference(
+              new VariableGet(x), method.reference, new Arguments([])),
+          expectation: ""
+              "(invoke-direct-method (get-var \"x^0\" _)"
+              " \"package:foo/bar.dart::A::@methods::foo\""
+              " () () ())",
+          serializationState: new SerializationState(
+              new SerializationEnvironment(null)..add(x, "x^0")),
+          deserializationState: new DeserializationState(
+              new DeserializationEnvironment(null)..add("x^0", x),
+              component.root));
+    }(),
+    () {
+      Constructor constructor =
+          new Constructor(new FunctionNode(null), name: new Name("foo"));
+      Class klass =
+          new Class(name: "A", constructors: <Constructor>[constructor]);
+      Library library = new Library(
+          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()",
+          node: new ConstructorInvocation.byReference(
+              constructor.reference, new Arguments([])),
+          expectation: ""
+              "(invoke-constructor"
+              " \"package:foo/bar.dart::A::@constructors::foo\""
+              " () () ())",
+          serializationState: new SerializationState(null),
+          deserializationState: new DeserializationState(null, component.root));
+    }(),
+    () {
+      Constructor constructor = new Constructor(new FunctionNode(null),
+          name: new Name("foo"), isConst: true);
+      Class klass =
+          new Class(name: "A", constructors: <Constructor>[constructor]);
+      Library library = new Library(
+          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()",
+          node: new ConstructorInvocation.byReference(
+              constructor.reference, new Arguments([]),
+              isConst: true),
+          expectation: ""
+              "(invoke-const-constructor"
+              " \"package:foo/bar.dart::A::@constructors::foo\""
+              " () () ())",
+          serializationState: new SerializationState(null),
+          deserializationState: new DeserializationState(null, component.root));
     }(),
   ];
   for (TestCase testCase in tests) {
     String roundTripInput =
-        writeExpression(testCase.node, testCase.serializationEnvironment);
+        writeExpression(testCase.node, testCase.serializationState);
     if (roundTripInput != testCase.expectation) {
       failures.add(''
           '* initial serialization for test "${testCase.name}"'
@@ -112,9 +310,9 @@
     }
 
     TreeNode deserialized =
-        readExpression(roundTripInput, testCase.deserializationEnvironment);
+        readExpression(roundTripInput, testCase.deserializationState);
     String roundTripOutput =
-        writeExpression(deserialized, testCase.serializationEnvironment);
+        writeExpression(deserialized, testCase.serializationState);
     if (roundTripOutput != roundTripInput) {
       failures.add(''
           '* input "${testCase.name}" gave output "${roundTripOutput}"');
diff --git a/pkg/kernel/test/text_serializer_test.dart b/pkg/kernel/test/text_serializer_test.dart
index 029b91b..1cd569c 100644
--- a/pkg/kernel/test/text_serializer_test.dart
+++ b/pkg/kernel/test/text_serializer_test.dart
@@ -4,6 +4,7 @@
 library kernel.text_serializer_test;
 
 import 'package:kernel/ast.dart';
+import 'package:kernel/text/serializer_combinators.dart';
 import 'package:kernel/text/text_reader.dart';
 import 'package:kernel/text/text_serializer.dart';
 
@@ -16,7 +17,8 @@
 Expression readExpression(String input) {
   TextIterator stream = new TextIterator(input, 0);
   stream.moveNext();
-  Expression result = expressionSerializer.readFrom(stream, null);
+  Expression result = expressionSerializer.readFrom(
+      stream, new DeserializationState(null, new CanonicalName.root()));
   if (stream.moveNext()) {
     throw StateError("extra cruft in basic literal");
   }
@@ -25,7 +27,8 @@
 
 String writeExpression(Expression expression) {
   StringBuffer buffer = new StringBuffer();
-  expressionSerializer.writeTo(buffer, expression, null);
+  expressionSerializer.writeTo(
+      buffer, expression, new SerializationState(null));
   return buffer.toString();
 }
 
@@ -76,6 +79,11 @@
     "(map (dynamic) (void) ((int 0) (null) (int 1) (null) (int 2) (null)))",
     "(const-map (dynamic) (void) ((int 0) (null) (int 1) (null) "
         "(int 2) (null)))",
+    "(type (-> ((dynamic)) 1 (dynamic)))",
+    "(type (-> ((dynamic)) 0 (dynamic)))",
+    "(type (-> ((dynamic) (dynamic)) 2 (dynamic)))",
+    "(type (-> () 0 (dynamic)))",
+    "(type (-> ((-> ((dynamic)) 1 (dynamic))) 1 (dynamic)))",
   ];
   for (var test in tests) {
     var literal = readExpression(test);
diff --git a/pkg/kernel/test/type_subtype_test.dart b/pkg/kernel/test/type_subtype_test.dart
deleted file mode 100644
index 753e525..0000000
--- a/pkg/kernel/test/type_subtype_test.dart
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:test/test.dart';
-import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/type_environment.dart';
-import 'type_parser.dart';
-
-/// Description of a small class hierarchy for use in subtype tests.
-var classEnvironment = <String, List<String>>{
-  'Comparable<T>': ['Object'],
-  'num': ['Object', 'Comparable<num>'],
-  'int': ['num'],
-  'double': ['num'],
-  'Iterable<T>': ['Object'],
-  'List<T>': ['Iterable<T>'],
-  'Future<T>': ['Object'],
-  'FutureOr<T>': ['Object'],
-  'Null': ['Object'],
-};
-
-List<TestCase> testCases = <TestCase>[
-  subtype('int', 'num', legacyMode: true),
-  subtype('int', 'Comparable<num>', legacyMode: true),
-  subtype('int', 'Comparable<Object>', legacyMode: true),
-  subtype('int', 'Object', legacyMode: true),
-  subtype('double', 'num', legacyMode: true),
-
-  notSubtype('int', 'double', legacyMode: true),
-  notSubtype('int', 'Comparable<int>', legacyMode: true),
-  notSubtype('int', 'Iterable<int>', legacyMode: true),
-  notSubtype('Comparable<int>', 'Iterable<int>', legacyMode: true),
-
-  subtype('List<int>', 'List<int>', legacyMode: true),
-  subtype('List<int>', 'Iterable<int>', legacyMode: true),
-  subtype('List<int>', 'List<num>', legacyMode: true),
-  subtype('List<int>', 'Iterable<num>', legacyMode: true),
-  subtype('List<int>', 'List<Object>', legacyMode: true),
-  subtype('List<int>', 'Iterable<Object>', legacyMode: true),
-  subtype('List<int>', 'Object', legacyMode: true),
-  subtype('List<int>', 'List<Comparable<Object>>', legacyMode: true),
-  subtype('List<int>', 'List<Comparable<num>>', legacyMode: true),
-  subtype('List<int>', 'List<Comparable<Comparable<num>>>', legacyMode: true),
-
-  notSubtype('List<int>', 'List<double>', legacyMode: true),
-  notSubtype('List<int>', 'Iterable<double>', legacyMode: true),
-  notSubtype('List<int>', 'Comparable<int>', legacyMode: true),
-  notSubtype('List<int>', 'List<Comparable<int>>', legacyMode: true),
-  notSubtype('List<int>', 'List<Comparable<Comparable<int>>>',
-      legacyMode: true),
-
-  subtype('(num) => num', '(int) => num', legacyMode: true),
-  subtype('(num) => int', '(num) => num', legacyMode: true),
-  subtype('(num) => int', '(int) => num', legacyMode: true),
-  notSubtype('(int) => int', '(num) => num', legacyMode: true),
-
-  subtype('(num) => (num) => num', '(num) => (int) => num', legacyMode: true),
-  notSubtype('(num) => (int) => int', '(num) => (num) => num',
-      legacyMode: true),
-
-  subtype('(x:num) => num', '(x:int) => num',
-      legacyMode: true), // named parameters
-  subtype('(num,x:num) => num', '(int,x:int) => num', legacyMode: true),
-  subtype('(x:num) => int', '(x:num) => num', legacyMode: true),
-  notSubtype('(x:int) => int', '(x:num) => num', legacyMode: true),
-
-  subtype('<E>(E) => int', '<E>(E) => num',
-      legacyMode: true), // type parameters
-  subtype('<E>(num) => E', '<E>(int) => E', legacyMode: true),
-  subtype('<E>(E,num) => E', '<E>(E,int) => E', legacyMode: true),
-  notSubtype('<E>(E,num) => E', '<E>(E,E) => E', legacyMode: true),
-
-  subtype('<E>(E) => (E) => E', '<F>(F) => (F) => F', legacyMode: true),
-  subtype('<E>(E, (int,E) => E) => E', '<E>(E, (int,E) => E) => E',
-      legacyMode: true),
-  subtype('<E>(E, (int,E) => E) => E', '<E>(E, (num,E) => E) => E',
-      legacyMode: true),
-  notSubtype('<E,F>(E) => (F) => E', '<E>(E) => <F>(F) => E', legacyMode: true),
-  notSubtype('<E,F>(E) => (F) => E', '<F,E>(E) => (F) => E', legacyMode: true),
-
-  notSubtype('<E>(E,num) => E', '<E:num>(E,E) => E', legacyMode: true),
-  notSubtype('<E:num>(E) => int', '<E:int>(E) => int', legacyMode: true),
-  notSubtype('<E:num>(E) => E', '<E:int>(E) => E', legacyMode: true),
-  notSubtype('<E:num>(int) => E', '<E:int>(int) => E', legacyMode: true),
-  subtype('<E:num>(E) => E', '<F:num>(F) => num', legacyMode: true),
-  subtype('<E:int>(E) => E', '<F:int>(F) => num', legacyMode: true),
-  subtype('<E:int>(E) => E', '<F:int>(F) => int', legacyMode: true),
-  notSubtype('<E>(int) => int', '(int) => int', legacyMode: true),
-  notSubtype('<E,F>(int) => int', '<E>(int) => int', legacyMode: true),
-
-  subtype('<E:List<E>>(E) => E', '<F:List<F>>(F) => F', legacyMode: true),
-  notSubtype('<E:Iterable<E>>(E) => E', '<F:List<F>>(F) => F',
-      legacyMode: true),
-  notSubtype('<E>(E,List<Object>) => E', '<F:List<F>>(F,F) => F',
-      legacyMode: true),
-  notSubtype('<E>(E,List<Object>) => List<E>', '<F:List<F>>(F,F) => F',
-      legacyMode: true),
-  notSubtype('<E>(E,List<Object>) => int', '<F:List<F>>(F,F) => F',
-      legacyMode: true),
-  notSubtype('<E>(E,List<Object>) => E', '<F:List<F>>(F,F) => void',
-      legacyMode: true),
-
-  subtype('int', 'FutureOr<int>'),
-  subtype('int', 'FutureOr<num>'),
-  subtype('Future<int>', 'FutureOr<int>'),
-  subtype('Future<int>', 'FutureOr<num>'),
-  subtype('Future<int>', 'FutureOr<Object>'),
-  subtype('FutureOr<int>', 'FutureOr<int>'),
-  subtype('FutureOr<int>', 'FutureOr<num>'),
-  subtype('FutureOr<int>', 'Object'),
-  notSubtype('int', 'FutureOr<double>'),
-  notSubtype('FutureOr<double>', 'int'),
-  notSubtype('FutureOr<int>', 'Future<num>'),
-  notSubtype('FutureOr<int>', 'num'),
-
-  // T & B <: T & A if B <: A
-  subtype('T & int', 'T & int', legacyMode: true),
-  subtype('T & int', 'T & num', legacyMode: true),
-  subtype('T & num', 'T & num', legacyMode: true),
-  notSubtype('T & num', 'T & int', legacyMode: true),
-
-  // T & B <: T extends A if B <: A
-  // (Trivially satisfied since promoted bounds are always a subtype of the
-  // original bound)
-  subtype('T & int', 'T', legacyMode: true, typeParameters: 'T: int'),
-  subtype('T & int', 'T', legacyMode: true, typeParameters: 'T: num'),
-  subtype('T & num', 'T', legacyMode: true, typeParameters: 'T: num'),
-
-  // T extends B <: T & A if B <: A
-  subtype('T', 'T & int', legacyMode: true, typeParameters: 'T: int'),
-  subtype('T', 'T & num', legacyMode: true, typeParameters: 'T: int'),
-  subtype('T', 'T & num', legacyMode: true, typeParameters: 'T: num'),
-  notSubtype('T', 'T & int', legacyMode: true, typeParameters: 'T: num'),
-
-  // T extends A <: T extends A
-  subtype('T', 'T', legacyMode: true, typeParameters: 'T: num'),
-
-  // S & B <: A if B <: A, A is not S (or a promotion thereof)
-  subtype('S & int', 'int', legacyMode: true),
-  subtype('S & int', 'num', legacyMode: true),
-  subtype('S & num', 'num', legacyMode: true),
-  notSubtype('S & num', 'int', legacyMode: true),
-  notSubtype('S & num', 'T', legacyMode: true),
-  notSubtype('S & num', 'T & num', legacyMode: true),
-
-  // S extends B <: A if B <: A, A is not S (or a promotion thereof)
-  subtype('S', 'int', legacyMode: true, typeParameters: 'S: int'),
-  subtype('S', 'num', legacyMode: true, typeParameters: 'S: int'),
-  subtype('S', 'num', legacyMode: true, typeParameters: 'S: num'),
-  notSubtype('S', 'int', legacyMode: true, typeParameters: 'S: num'),
-  notSubtype('S', 'T', legacyMode: true, typeParameters: 'S: num'),
-  notSubtype('S', 'T & num', legacyMode: true, typeParameters: 'S: num'),
-];
-
-/// Assert that [subtype] is a subtype of [supertype], and that [supertype]
-/// is not a subtype of [subtype] (unless the two strings are equal).
-TestCase subtype(String subtype_, String supertype,
-    {bool legacyMode: false, String typeParameters}) {
-  return new TestCase(subtype_, supertype,
-      isSubtype: true, legacyMode: legacyMode, typeParameters: typeParameters);
-}
-
-/// Assert that neither type is a subtype of the other.
-TestCase notSubtype(String subtype_, String supertype,
-    {bool legacyMode: false, String typeParameters}) {
-  return new TestCase(subtype_, supertype,
-      isSubtype: false, legacyMode: legacyMode, typeParameters: typeParameters);
-}
-
-class TestCase {
-  String subtype;
-  String supertype;
-  String typeParameters;
-  bool isSubtype;
-  bool legacyMode;
-
-  TestCase(this.subtype, this.supertype,
-      {this.isSubtype, this.legacyMode: false, this.typeParameters});
-
-  String toString() {
-    var description =
-        isSubtype ? '$subtype <: $supertype' : '$subtype </: $supertype';
-    if (typeParameters != null) {
-      description += ' (type parameters: $typeParameters)';
-    }
-    if (legacyMode) {
-      description += ' (legacy mode)';
-    }
-    return description;
-  }
-}
-
-class MockSubtypeTester extends SubtypeTester {
-  ClassHierarchy hierarchy;
-  InterfaceType objectType;
-  InterfaceType nullType;
-  InterfaceType rawFunctionType;
-  Class futureClass;
-  Class futureOrClass;
-  LazyTypeEnvironment environment;
-  bool legacyMode = false;
-
-  InterfaceType futureType(DartType type) =>
-      new InterfaceType(futureClass, [type]);
-
-  @override
-  InterfaceType getTypeAsInstanceOf(InterfaceType type, Class superclass) {
-    return hierarchy.getTypeAsInstanceOf(type, superclass);
-  }
-
-  MockSubtypeTester(
-      this.hierarchy,
-      this.objectType,
-      this.nullType,
-      this.rawFunctionType,
-      this.futureClass,
-      this.futureOrClass,
-      this.environment);
-}
-
-MockSubtypeTester makeSubtypeTester(Map<String, List<String>> testcase) {
-  LazyTypeEnvironment environment = new LazyTypeEnvironment();
-  Class objectClass = environment.lookup('Object');
-  Class nullClass = environment.lookup('Null');
-  Class functionClass = environment.lookup('Function');
-  Class futureClass = environment.lookup('Future');
-  Class futureOrClass = environment.lookup('FutureOr');
-  functionClass.supertype = objectClass.asRawSupertype;
-  for (var typeString in testcase.keys) {
-    InterfaceType type = environment.parseFresh(typeString);
-    Class class_ = type.classNode;
-    for (TypeParameterType typeArg in type.typeArguments) {
-      class_.typeParameters.add(typeArg.parameter);
-    }
-    for (var supertypeString in testcase[typeString]) {
-      if (class_.supertype == null) {
-        class_.supertype = environment.parseSuper(supertypeString);
-      } else {
-        class_.implementedTypes.add(environment.parseSuper(supertypeString));
-      }
-    }
-  }
-  var component = new Component(libraries: [environment.dummyLibrary]);
-  var hierarchy = new ClassHierarchy(component);
-  return new MockSubtypeTester(
-      hierarchy,
-      objectClass.rawType,
-      nullClass.rawType,
-      functionClass.rawType,
-      futureClass,
-      futureOrClass,
-      environment);
-}
-
-main() {
-  var tester = makeSubtypeTester(classEnvironment);
-  for (var testCase in testCases) {
-    test('$testCase', () {
-      tester.legacyMode = testCase.legacyMode;
-      var environment = tester.environment;
-      environment.clearTypeParameters();
-      if (testCase.typeParameters != null) {
-        environment.setupTypeParameters(testCase.typeParameters);
-      }
-      var subtype = environment.parse(testCase.subtype);
-      var supertype = environment.parse(testCase.supertype);
-      if (tester.isSubtypeOf(subtype, supertype) != testCase.isSubtype) {
-        fail('isSubtypeOf(${testCase.subtype}, ${testCase.supertype}) returned '
-            '${!testCase.isSubtype} but should return ${testCase.isSubtype}');
-      }
-      if (subtype != supertype && tester.isSubtypeOf(supertype, subtype)) {
-        fail('isSubtypeOf(${testCase.supertype}, ${testCase.subtype}) returned '
-            'true but should return false');
-      }
-    });
-  }
-}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 47cc165..edb50ff 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -31,6 +31,8 @@
 front_end/test/fasta/analyze_test: Pass, Slow
 front_end/test/fasta/ast_builder_test: Pass, Slow
 front_end/test/fasta/bootstrap_test: Pass, Slow
+front_end/test/fasta/fast_legacy_test: Pass, Slow
+front_end/test/fasta/fast_strong_test: Pass, Slow
 front_end/test/fasta/legacy_test: Pass, ExtraSlow
 front_end/test/fasta/outline_test: Pass, Slow
 front_end/test/fasta/rasta/*: SkipByDesign # Anything in rasta is input to fasta unit tests and shouldn't be run as tests.
@@ -87,9 +89,6 @@
 [ $runtime == dart_precompiled ]
 *: SkipByDesign # The pkg test framework imports dart:mirrors.
 
-[ $runtime == flutter ]
-status_file/*: SkipByDesign # Only meant to run on the standalone VM.
-
 [ $runtime == jsshell ]
 async/test/stream_zip_test: RuntimeError, OK # Issue 26103. Timers are not supported.
 front_end/test/*: RuntimeError, OK, Pass # Issue 26103. Timers are not supported.
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index ea0b8d1..803ac2b 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -261,7 +261,6 @@
         useBlobs: boolOption("use-blobs"),
         useDart2JSWithKernel: boolOption("dart2js-with-kernel"),
         useDart2JSOldFrontEnd: boolOption("dart2js-old-frontend"),
-        useFastStartup: boolOption("fast-startup"),
         useHotReload: boolOption("hot-reload"),
         useHotReloadRollback: boolOption("hot-reload-rollback"),
         useSdk: boolOption("use-sdk"));
@@ -318,8 +317,6 @@
   final bool useDart2JSWithKernel;
   final bool useDart2JSOldFrontEnd;
 
-  final bool useFastStartup;
-
   final bool useHotReload;
   final bool useHotReloadRollback;
 
@@ -341,7 +338,6 @@
       bool useBlobs,
       bool useDart2JSWithKernel,
       bool useDart2JSOldFrontEnd,
-      bool useFastStartup,
       bool useHotReload,
       bool useHotReloadRollback,
       bool useSdk})
@@ -359,7 +355,6 @@
         useBlobs = useBlobs ?? false,
         useDart2JSWithKernel = useDart2JSWithKernel ?? false,
         useDart2JSOldFrontEnd = useDart2JSOldFrontEnd ?? false,
-        useFastStartup = useFastStartup ?? false,
         useHotReload = useHotReload ?? false,
         useHotReloadRollback = useHotReloadRollback ?? false,
         useSdk = useSdk ?? false;
@@ -386,7 +381,6 @@
       useBlobs == other.useBlobs &&
       useDart2JSWithKernel == other.useDart2JSWithKernel &&
       useDart2JSOldFrontEnd == other.useDart2JSOldFrontEnd &&
-      useFastStartup == other.useFastStartup &&
       useHotReload == other.useHotReload &&
       useHotReloadRollback == other.useHotReloadRollback &&
       useSdk == other.useSdk;
@@ -394,6 +388,9 @@
   bool operator ==(Object other) =>
       other is Configuration && name == other.name && optionsEqual(other);
 
+  int _toBinary(List<bool> bits) =>
+      bits.fold(0, (sum, bit) => (sum << 1) ^ (bit ? 1 : 0));
+
   int get hashCode =>
       name.hashCode ^
       architecture.hashCode ^
@@ -404,21 +401,22 @@
       builderTag.hashCode ^
       vmOptions.join(" & ").hashCode ^
       timeout.hashCode ^
-      (enableAsserts ? 1 : 0) ^
-      (isChecked ? 2 : 0) ^
-      (isCsp ? 4 : 0) ^
-      (isHostChecked ? 8 : 0) ^
-      (isMinified ? 16 : 0) ^
-      (previewDart2 ? 32 : 0) ^
-      (useAnalyzerCfe ? 64 : 0) ^
-      (useAnalyzerFastaParser ? 128 : 0) ^
-      (useBlobs ? 256 : 0) ^
-      (useDart2JSWithKernel ? 512 : 0) ^
-      (useDart2JSOldFrontEnd ? 1024 : 0) ^
-      (useFastStartup ? 2048 : 0) ^
-      (useHotReload ? 4096 : 0) ^
-      (useHotReloadRollback ? 8192 : 0) ^
-      (useSdk ? 16384 : 0);
+      _toBinary([
+        enableAsserts,
+        isChecked,
+        isCsp,
+        isHostChecked,
+        isMinified,
+        previewDart2,
+        useAnalyzerCfe,
+        useAnalyzerFastaParser,
+        useBlobs,
+        useDart2JSWithKernel,
+        useDart2JSOldFrontEnd,
+        useHotReload,
+        useHotReloadRollback,
+        useSdk
+      ]);
 
   String toString() {
     var buffer = new StringBuffer();
@@ -446,7 +444,6 @@
     if (useBlobs) fields.add("use-blobs");
     if (useDart2JSWithKernel) fields.add("dart2js-with-kernel");
     if (useDart2JSOldFrontEnd) fields.add("dart2js-old-frontend");
-    if (useFastStartup) fields.add("fast-startup");
     if (useHotReload) fields.add("hot-reload");
     if (useHotReloadRollback) fields.add("hot-reload-rollback");
     if (useSdk) fields.add("use-sdk");
@@ -515,9 +512,6 @@
       fields.add("useDart2JSOldFrontEnd "
           "$useDart2JSOldFrontEnd ${other.useDart2JSOldFrontEnd}");
     }
-    if (useFastStartup || other.useFastStartup) {
-      fields.add("useFastStartup $useFastStartup ${other.useFastStartup}");
-    }
     if (useHotReload || other.useHotReload) {
       fields.add("useHotReload $useHotReload ${other.useHotReload}");
     }
diff --git a/pkg/smith/test/configuration_test.dart b/pkg/smith/test/configuration_test.dart
index c7e64fe..0952c72 100644
--- a/pkg/smith/test/configuration_test.dart
+++ b/pkg/smith/test/configuration_test.dart
@@ -208,7 +208,6 @@
               "preview-dart-2": true,
               "dart2js-with-kernel": true,
               "dart2js-old-frontend": true,
-              "fast-startup": true,
               "hot-reload": true,
               "hot-reload-rollback": true,
               "use-sdk": true,
@@ -230,7 +229,6 @@
               previewDart2: true,
               useDart2JSWithKernel: true,
               useDart2JSOldFrontEnd: true,
-              useFastStartup: true,
               useHotReload: true,
               useHotReloadRollback: true,
               useSdk: true,
diff --git a/pkg/sourcemap_testing/pubspec.yaml b/pkg/sourcemap_testing/pubspec.yaml
index c12dcf1..a7ee40e 100644
--- a/pkg/sourcemap_testing/pubspec.yaml
+++ b/pkg/sourcemap_testing/pubspec.yaml
@@ -1,6 +1,10 @@
 # Helper package for testing sourcemaps. Used by ddc and dart2js.
 name: sourcemap_testing
-#version: do-not-upload
+publish_to: none
+
+environment:
+  sdk: '>=2.1.0 <3.0.0'
+
 dependencies:
   package_config: '>=0.1.1 <2.0.0'
   pub_semver: ^1.2.1
diff --git a/pkg/status_file/test/data/co19-dart2js.status b/pkg/status_file/test/data/co19-dart2js.status
index 498112d..c863c9f 100644
--- a/pkg/status_file/test/data/co19-dart2js.status
+++ b/pkg/status_file/test/data/co19-dart2js.status
@@ -402,7 +402,7 @@
 WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: RuntimeError # Please triage this failure
 
-[ $compiler == dart2js && $fast_startup ]
+[ $compiler == dart2js ]
 Language/Classes/Instance_Methods/Operators/unary_minus: Fail # mirrors not supported
 Language/Expressions/Null/instance_of_class_null_t01: Fail # mirrors not supported
 Language/Metadata/before_class_t01: Fail # mirrors not supported
@@ -448,13 +448,13 @@
 [ $compiler == dart2js && $runtime == jsshell ]
 LibTest/isolate/Isolate/spawn_A04_t04: Fail # Issue 27558
 
-[ $compiler == dart2js && $fast_startup && $runtime == d8]
+[ $compiler == dart2js && $runtime == d8]
 LibTest/isolate/Isolate/spawn_A04_t04: Fail # Issue 27558
 
-[ $compiler == dart2js && $fast_startup && $runtime == jsshell ]
+[ $compiler == dart2js && $runtime == jsshell ]
 LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Fail # please triage
 
-[ $compiler == dart2js && $fast_startup && $browser ]
+[ $compiler == dart2js && $browser ]
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: Fail # custom elements not supported
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: Fail # please triage
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: Fail # please triage
@@ -486,7 +486,7 @@
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: Fail # please triage
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: Fail # please triage
 
-[ $compiler == dart2js && $fast_startup && $browser && $runtime != chrome ]
+[ $compiler == dart2js && $browser && $runtime != chrome ]
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005_t01: Fail # please triage
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-001_t01: Fail # please triage
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-002_t01: Fail # please triage
@@ -538,10 +538,10 @@
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/shadow-root-001_t01: Fail # please triage
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-011_t01: Fail # please triage
 
-[ $compiler == dart2js && $fast_startup && $browser && $runtime != chrome ]
+[ $compiler == dart2js && $browser && $runtime != chrome ]
 WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: Fail # please triage
 
-[ $compiler == dart2js && $fast_startup && $browser ]
+[ $compiler == dart2js && $browser ]
 WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: Fail # custom elements not supported
 WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-001_t01: Fail # please triage
 WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-002_t01: Fail # please triage
diff --git a/pkg/testing/lib/src/chain.dart b/pkg/testing/lib/src/chain.dart
index 53256ae..1c0c748 100644
--- a/pkg/testing/lib/src/chain.dart
+++ b/pkg/testing/lib/src/chain.dart
@@ -138,8 +138,8 @@
           !partialSelectors.any((s) => selector.startsWith(s))) {
         continue;
       }
-      final Set<Expectation> expectedOutcomes =
-          expectations.expectations(description.shortName);
+      final Set<Expectation> expectedOutcomes = processExpectedOutcomes(
+          expectations.expectations(description.shortName));
       final StringBuffer sb = new StringBuffer();
       final Step lastStep = steps.isNotEmpty ? steps.last : null;
       final Iterator<Step> iterator = steps.iterator;
@@ -255,6 +255,10 @@
     }
   }
 
+  Set<Expectation> processExpectedOutcomes(Set<Expectation> outcomes) {
+    return outcomes;
+  }
+
   Result processTestResult(
       TestDescription description, Result result, bool last) {
     if (description is FileBasedTestDescription &&
diff --git a/pkg/testing/lib/src/run.dart b/pkg/testing/lib/src/run.dart
index c93303a..1d83c9b 100644
--- a/pkg/testing/lib/src/run.dart
+++ b/pkg/testing/lib/src/run.dart
@@ -53,16 +53,16 @@
 ///
 /// The optional argument [configurationPath] should be used when
 /// `testing.json` isn't located in the current working directory and is a path
-/// relative to `Platform.script`.
+/// relative to [me] which defaults to `Platform.script`.
 Future<Null> runMe(List<String> arguments, CreateContext f,
-    [String configurationPath]) {
+    [String configurationPath, Uri me]) {
+  me ??= Platform.script;
   return withErrorHandling(() async {
-    TestRoot testRoot =
-        await computeTestRoot(configurationPath, Platform.script);
+    TestRoot testRoot = await computeTestRoot(configurationPath, me);
     CommandLine cl = CommandLine.parse(arguments);
     if (cl.verbose) enableVerboseOutput();
     for (Chain suite in testRoot.toolChains) {
-      if (Platform.script == suite.source) {
+      if (me == suite.source) {
         print("Running suite ${suite.name}...");
         ChainContext context = await f(suite, cl.environment);
         await context.run(suite, new Set<String>.from(cl.selectors));
diff --git a/pkg/vm/bin/compare_sizes.dart b/pkg/vm/bin/compare_sizes.dart
new file mode 100644
index 0000000..691566e
--- /dev/null
+++ b/pkg/vm/bin/compare_sizes.dart
@@ -0,0 +1,262 @@
+// 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 tool compares two JSON size reports produced by
+// --print-instructions-sizes-to and reports which symbols increased in size
+// and which symbols decreased in size.
+
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math' as math;
+
+bool limitWidth = false;
+
+void main(List<String> args) {
+  if (args.length == 3 && args[2] == 'narrow') {
+    limitWidth = true;
+  } else if (args.length != 2) {
+    print("""
+Usage: dart ${Platform.script} <old.json> <new.json> [narrow]
+
+This tool compares two JSON size reports produced by
+--print-instructions-sizes-to and reports which symbols increased in size
+and which symbols decreased in size. The optional 'narrow' parameter limits
+the colunm widths.
+""");
+    exit(-1);
+  }
+
+  final oldSizes = loadSymbolSizes(args[0]);
+  final newSizes = loadSymbolSizes(args[1]);
+
+  var totalOld = 0;
+  var totalNew = 0;
+  var totalDiff = 0;
+  final diffBySymbol = <String, int>{};
+
+  // Process all symbols (from both old and new results) and compute the change
+  // in size. If symbol is not present in the compilation assume its size to be
+  // zero.
+  for (var key in Set<String>()..addAll(newSizes.keys)..addAll(oldSizes.keys)) {
+    final oldSize = oldSizes[key] ?? 0;
+    final newSize = newSizes[key] ?? 0;
+    final diff = newSize - oldSize;
+    if (diff != 0) diffBySymbol[key] = diff;
+    totalOld += oldSize;
+    totalNew += newSize;
+    totalDiff += diff;
+  }
+
+  // Compute the list of changed symbols sorted by difference (descending).
+  final changedSymbolsBySize = diffBySymbol.keys.toList();
+  changedSymbolsBySize.sort((a, b) => diffBySymbol[b] - diffBySymbol[a]);
+
+  // Now produce the report table.
+  const numLargerSymbolsToReport = 30;
+  const numSmallerSymbolsToReport = 10;
+  final table = AsciiTable(header: [
+    Text.left('Library'),
+    Text.left('Method'),
+    Text.right('Diff (Bytes)')
+  ]);
+
+  // Report [numLargerSymbolsToReport] symbols that increased in size most.
+  for (var key in changedSymbolsBySize
+      .where((k) => diffBySymbol[k] > 0)
+      .take(numLargerSymbolsToReport)) {
+    final name = key.split(librarySeparator);
+    table.addRow([name[0], name[1], '+${diffBySymbol[key]}']);
+  }
+  table.addSeparator(Separator.Wave);
+
+  // Report [numSmallerSymbolsToReport] symbols that decreased in size most.
+  for (var key in changedSymbolsBySize.reversed
+      .where((k) => diffBySymbol[k] < 0)
+      .take(numSmallerSymbolsToReport)
+      .toList()
+      .reversed) {
+    final name = key.split(librarySeparator);
+    table.addRow([name[0], name[1], '${diffBySymbol[key]}']);
+  }
+  table.addSeparator();
+
+  table.render();
+  print('Comparing ${args[0]} (old) to ${args[1]} (new)');
+  print('Old   : ${totalOld} bytes.');
+  print('New   : ${totalNew} bytes.');
+  print('Change: ${totalDiff > 0 ? '+' : ''}${totalDiff} bytes.');
+}
+
+/// A combination of characters that is unlikely to occur in the symbol name.
+const String librarySeparator = ',';
+
+/// Load --print-instructions-sizes-to output as a mapping from symbol names
+/// to their sizes.
+///
+/// Note: we produce a single symbol name from function name and library name
+/// by concatenating them with [librarySeparator].
+Map<String, int> loadSymbolSizes(String name) {
+  final symbols = jsonDecode(File(name).readAsStringSync());
+  final result = new Map<String, int>();
+  final regexp = new RegExp(r"0x[a-fA-F0-9]+");
+  for (int i = 0, n = symbols.length; i < n; i++) {
+    final e = symbols[i];
+    // Obtain a key by combining library and method name. Strip anything
+    // after the library separator to make sure we can easily decode later.
+    // For method names, also remove non-deterministic parts to avoid
+    // reporting non-existing differences against the same layout.
+    String lib = ((e['l'] ?? '').split(librarySeparator))[0];
+    String name = (e['n'].split(librarySeparator))[0]
+        .replaceAll('[Optimized] ', '')
+        .replaceAll(regexp, '');
+    String key = lib + librarySeparator + name;
+    int val = e['s'];
+    result[key] =
+        (result[key] ?? 0) + val; // add (key,val), accumulate if exists
+  }
+  return result;
+}
+
+/// A row in the [AsciiTable].
+abstract class Row {
+  String render(List<int> widths, List<AlignmentDirection> alignments);
+}
+
+enum Separator {
+  /// Line separator looks like this: `+-------+------+`
+  Line,
+
+  /// Wave separator looks like this: `~~~~~~~~~~~~~~~~` repeated twice.
+  Wave
+}
+
+/// A separator row in the [AsciiTable].
+class SeparatorRow extends Row {
+  final Separator filler;
+  SeparatorRow(this.filler);
+
+  @override
+  String render(List<int> widths, List<AlignmentDirection> alignments) {
+    switch (filler) {
+      case Separator.Line:
+        final sb = StringBuffer();
+        sb.write('+');
+        for (var i = 0; i < widths.length; i++) {
+          sb.write('-' * (widths[i] + 2));
+          sb.write('+');
+        }
+        return sb.toString();
+
+      case Separator.Wave:
+        final sb = StringBuffer();
+        sb.write('~');
+        for (var i = 0; i < widths.length; i++) {
+          sb.write('~' * (widths[i] + 2));
+          sb.write('~');
+        }
+        return sb.toString() + '\n' + sb.toString();
+    }
+  }
+}
+
+class NormalRow extends Row {
+  final List<dynamic> columns;
+  NormalRow(this.columns);
+
+  @override
+  String render(List<int> widths, List<AlignmentDirection> alignments) {
+    final sb = StringBuffer();
+    sb.write('|');
+    for (var i = 0; i < widths.length; i++) {
+      sb.write(' ');
+      final text = columns[i] is Text
+          ? columns[i]
+          : Text(value: columns[i], direction: alignments[i]);
+      sb.write(text.render(widths[i]));
+      sb.write(' |');
+    }
+    return sb.toString();
+  }
+}
+
+enum AlignmentDirection { Left, Right, Center }
+
+/// A chunk of text aligned in the given direction within a cell.
+class Text {
+  final String value;
+  final AlignmentDirection direction;
+
+  Text({this.value, this.direction});
+  Text.left(String value)
+      : this(value: value, direction: AlignmentDirection.Left);
+  Text.right(String value)
+      : this(value: value, direction: AlignmentDirection.Right);
+  Text.center(String value)
+      : this(value: value, direction: AlignmentDirection.Center);
+
+  String render(int width) {
+    if (value.length > width) {
+      // Narrowed column.
+      return value.substring(0, width - 2) + '..';
+    }
+    switch (direction) {
+      case AlignmentDirection.Left:
+        return value.padRight(width);
+      case AlignmentDirection.Right:
+        return value.padLeft(width);
+      case AlignmentDirection.Center:
+        final diff = width - value.length;
+        return ' ' * (diff ~/ 2) + value + (' ' * (diff - diff ~/ 2));
+    }
+  }
+
+  int get length => value.length;
+}
+
+class AsciiTable {
+  final List<Row> rows = <Row>[];
+  AsciiTable({List<dynamic> header}) {
+    if (header != null) {
+      addSeparator();
+      addRow(header);
+      addSeparator();
+    }
+  }
+
+  void addRow(List<dynamic> columns) => rows.add(NormalRow(columns));
+
+  void addSeparator([Separator filler = Separator.Line]) =>
+      rows.add(SeparatorRow(filler));
+
+  void render() {
+    // We assume that the first row gives us alignment directions that
+    // subsequent rows would follow.
+    List<AlignmentDirection> alignments = rows
+        .whereType<NormalRow>()
+        .first
+        .columns
+        .map((v) => v is Text ? v.direction : AlignmentDirection.Left)
+        .toList();
+    List<int> widths =
+        List<int>.filled(rows.whereType<NormalRow>().first.columns.length, 0);
+
+    // Compute max width for each column in the table.
+    for (var row in rows.whereType<NormalRow>()) {
+      assert(row.columns.length == widths.length);
+      for (var i = 0; i < widths.length; i++) {
+        widths[i] = math.max(row.columns[i].length, widths[i]);
+      }
+    }
+
+    if (limitWidth) {
+      for (var i = 0; i < widths.length; i++) {
+        widths[i] = math.min(widths[i], 25);
+      }
+    }
+
+    for (var row in rows) {
+      print(row.render(widths, alignments));
+    }
+  }
+}
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index e1e6bc8..141fb61 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -21,6 +21,7 @@
 library runtime.tools.kernel_service;
 
 import 'dart:async' show Future, ZoneSpecification, runZoned;
+import 'dart:collection' show UnmodifiableMapBase;
 import 'dart:convert' show utf8;
 import 'dart:io' show Platform, stderr hide FileSystemEntity;
 import 'dart:isolate';
@@ -112,6 +113,7 @@
       ..bytecode = bytecode
       ..experimentalFlags =
           parseExperimentalFlags(expFlags, (msg) => errors.add(msg))
+      ..environmentDefines = new EnvironmentMap()
       ..onDiagnostic = (DiagnosticMessage message) {
         bool printMessage;
         switch (message.severity) {
@@ -154,6 +156,25 @@
   Future<Component> compileInternal(Uri script);
 }
 
+// Environment map which looks up environment defines in the VM environment
+// at runtime.
+// TODO(askesc): This is a temporary hack to get hold of the environment during
+// JIT compilation. We use a lazy map accessing the VM runtime environment using
+// new String.fromEnvironment, since the VM currently does not support providing
+// the full (isolate specific) environment as a finite, static map.
+class EnvironmentMap extends UnmodifiableMapBase<String, String> {
+  @override
+  String operator [](Object key) {
+    // The fromEnvironment constructor is specified to throw when called using
+    // new. However, the VM implementation actually looks up the given name in
+    // the environment.
+    return new String.fromEnvironment(key);
+  }
+
+  @override
+  get keys => throw "Environment map iteration not supported";
+}
+
 class FileSink implements Sink<List<int>> {
   MemoryFileSystemEntity entityForUri;
   List<int> bytes = <int>[];
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index eaab503..a8d8cb0 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -271,6 +271,11 @@
     emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd));
   }
 
+  void emitDirectCall(int ra, int rd) {
+    emitSourcePosition();
+    emitWord(_encodeAD(Opcode.kDirectCall, ra, rd));
+  }
+
   void emitInterfaceCall(int ra, int rd) {
     emitSourcePosition();
     emitWord(_encodeAD(Opcode.kInterfaceCall, ra, rd));
diff --git a/pkg/vm/lib/bytecode/ast_remover.dart b/pkg/vm/lib/bytecode/ast_remover.dart
new file mode 100644
index 0000000..17adabc
--- /dev/null
+++ b/pkg/vm/lib/bytecode/ast_remover.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.
+
+library vm.bytecode.ast_remover;
+
+import 'package:kernel/ast.dart' hide MapEntry;
+import '../metadata/bytecode.dart';
+
+/// Drops kernel AST for members with bytecode.
+/// Can preserve removed AST and restore it if needed.
+class ASTRemover extends Transformer {
+  final BytecodeMetadataRepository metadata;
+  final droppedAST = <Member, dynamic>{};
+
+  ASTRemover(Component component)
+      : metadata = component.metadata[new BytecodeMetadataRepository().tag];
+
+  @override
+  TreeNode defaultMember(Member node) {
+    if (_hasBytecode(node)) {
+      if (node is Field) {
+        droppedAST[node] = node.initializer;
+        node.initializer = null;
+      } else if (node is Constructor) {
+        droppedAST[node] =
+            new _DroppedConstructor(node.initializers, node.function.body);
+        node.initializers = <Initializer>[];
+        node.function.body = null;
+      } else if (node.function != null) {
+        droppedAST[node] = node.function.body;
+        node.function.body = null;
+      }
+    }
+
+    // Instance field initializers do not form separate functions, and bytecode
+    // is not attached to instance fields (it is included into constructors).
+    // When VM reads a constructor from kernel, it also reads and translates
+    // instance field initializers. So, their ASTs can be dropped only if
+    // bytecode was generated for all generative constructors.
+    if (node is Field && !node.isStatic && node.initializer != null) {
+      if (node.enclosingClass.constructors.every(_hasBytecode)) {
+        droppedAST[node] = node.initializer;
+        node.initializer = null;
+      }
+    }
+
+    return node;
+  }
+
+  bool _hasBytecode(Member node) =>
+      metadata != null && metadata.mapping.containsKey(node);
+
+  void restoreAST() {
+    droppedAST.forEach((Member node, dynamic dropped) {
+      if (node is Field) {
+        node.initializer = dropped;
+      } else if (node is Constructor) {
+        _DroppedConstructor droppedConstructor = dropped;
+        node.initializers = droppedConstructor.initializers;
+        node.function.body = droppedConstructor.body;
+      } else {
+        node.function.body = dropped;
+      }
+    });
+  }
+}
+
+class _DroppedConstructor {
+  final List<Initializer> initializers;
+  final Statement body;
+
+  _DroppedConstructor(this.initializers, this.body);
+}
diff --git a/pkg/vm/lib/bytecode/bytecode_serialization.dart b/pkg/vm/lib/bytecode/bytecode_serialization.dart
index a592981..fd577df 100644
--- a/pkg/vm/lib/bytecode/bytecode_serialization.dart
+++ b/pkg/vm/lib/bytecode/bytecode_serialization.dart
@@ -5,7 +5,7 @@
 library vm.bytecode.bytecode_serialization;
 
 import 'dart:io' show BytesBuilder;
-import 'dart:typed_data' show Uint8List, Uint16List;
+import 'dart:typed_data' show ByteData, Endian, Uint8List, Uint16List;
 
 abstract class StringWriter {
   int put(String string);
@@ -277,6 +277,7 @@
   }
 
   void write(BufferedWriter writer) {
+    final start = writer.offset;
     writer.writeUInt32(_oneByteStrings.length);
     writer.writeUInt32(_twoByteStrings.length);
     int endOffset = 0;
@@ -301,6 +302,7 @@
       }
     }
     _written = true;
+    BytecodeSizeStatistics.stringTableSize += (writer.offset - start);
   }
 
   StringTable.read(BufferedReader reader) {
@@ -358,3 +360,68 @@
     return sb.toString();
   }
 }
+
+int doubleToIntBits(double value) {
+  final buf = new ByteData(8);
+  buf.setFloat64(0, value, Endian.little);
+  return buf.getInt64(0, Endian.little);
+}
+
+double intBitsToDouble(int bits) {
+  final buf = new ByteData(8);
+  buf.setInt64(0, bits, Endian.little);
+  return buf.getFloat64(0, Endian.little);
+}
+
+class NamedEntryStatistics {
+  final String name;
+  int size = 0;
+  int count = 0;
+
+  NamedEntryStatistics(this.name);
+
+  String toString() => "${name.padRight(40)}:    ${size.toString().padLeft(10)}"
+      "  (count: ${count.toString().padLeft(8)})";
+}
+
+class BytecodeSizeStatistics {
+  static int componentSize = 0;
+  static int objectTableSize = 0;
+  static int objectTableEntriesCount = 0;
+  static int stringTableSize = 0;
+  static int membersSize = 0;
+  static int constantPoolSize = 0;
+  static int instructionsSize = 0;
+  static List<NamedEntryStatistics> constantPoolStats =
+      <NamedEntryStatistics>[];
+  static List<NamedEntryStatistics> objectTableStats = <NamedEntryStatistics>[];
+
+  static void reset() {
+    componentSize = 0;
+    objectTableSize = 0;
+    objectTableEntriesCount = 0;
+    stringTableSize = 0;
+    membersSize = 0;
+    constantPoolSize = 0;
+    instructionsSize = 0;
+    constantPoolStats = <NamedEntryStatistics>[];
+    objectTableStats = <NamedEntryStatistics>[];
+  }
+
+  static void dump() {
+    print("Bytecode size statistics:");
+    print("  Bytecode component:  $componentSize");
+    print(
+        "   - object table:     $objectTableSize   (count: $objectTableEntriesCount)");
+    for (var entry in objectTableStats) {
+      print("       - $entry");
+    }
+    print("   - string table:     $stringTableSize");
+    print("  Bytecode members:    $membersSize");
+    print("   - constant pool:    $constantPoolSize");
+    for (var entry in constantPoolStats) {
+      print("       - $entry");
+    }
+    print("   - instructions:     $instructionsSize");
+  }
+}
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index e4c77c1..18b1ac1 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -10,7 +10,12 @@
 
 import 'dbc.dart' show constantPoolIndexLimit, BytecodeLimitExceededException;
 import 'bytecode_serialization.dart'
-    show BufferedWriter, BufferedReader, StringTable;
+    show
+        BufferedWriter,
+        BufferedReader,
+        BytecodeSizeStatistics,
+        NamedEntryStatistics,
+        StringTable;
 import 'object_table.dart' show ObjectHandle, ObjectTable;
 
 /*
@@ -170,7 +175,7 @@
 }
 
 // Occupies 2 entries in the constant pool.
-type ConstantInterfaceCall extends ConstantPoolEntry {
+type ConstantInterfaceCallV1 extends ConstantPoolEntry {
   Byte tag = 26;
   Byte flags(invocationKindBit0, invocationKindBit1);
              // Where invocationKind is index into InvocationKind.
@@ -178,38 +183,63 @@
   ConstantIndex argDesc;
 }
 
+type ConstantObjectRef extends ConstantPoolEntry {
+  Byte tag = 27;
+  PackedObject object;
+}
+
+// Occupies 2 entries in the constant pool.
+type ConstantDirectCall extends ConstantPoolEntry {
+  Byte tag = 28;
+  PackedObject target;
+  PackedObject argDesc;
+}
+
+// Occupies 2 entries in the constant pool.
+type ConstantInterfaceCall extends ConstantPoolEntry {
+  Byte tag = 29;
+  PackedObject target;
+  PackedObject argDesc;
+}
+
 */
 
 enum ConstantTag {
   kInvalid,
-  kNull,
-  kString,
-  kInt,
-  kDouble,
-  kBool,
-  kArgDesc,
+  kNull, // TODO(alexmarkov): obsolete, remove
+  kString, // TODO(alexmarkov): obsolete, remove
+  kInt, // TODO(alexmarkov): obsolete, remove
+  kDouble, // TODO(alexmarkov): obsolete, remove
+  kBool, // TODO(alexmarkov): obsolete, remove
+  kArgDesc, // TODO(alexmarkov): obsolete, remove
   kICData,
-  kStaticICData,
+  kStaticICData, // TODO(alexmarkov): obsolete, remove
   kStaticField,
   kInstanceField,
   kClass,
   kTypeArgumentsField,
-  kTearOff,
+  kTearOff, // TODO(alexmarkov): obsolete, remove
   kType,
-  kTypeArguments,
-  kList,
-  kInstance,
-  kTypeArgumentsForInstanceAllocation,
+  kTypeArguments, // TODO(alexmarkov): obsolete, remove
+  kList, // TODO(alexmarkov): obsolete, remove
+  kInstance, // TODO(alexmarkov): obsolete, remove
+  kTypeArgumentsForInstanceAllocation, // TODO(alexmarkov): obsolete, remove
   kClosureFunction,
   kEndClosureFunctionScope,
   kNativeEntry,
   kSubtypeTestCache,
-  kPartialTearOffInstantiation,
+  kPartialTearOffInstantiation, // TODO(alexmarkov): obsolete, remove
   kEmptyTypeArguments,
-  kSymbol,
+  kSymbol, // TODO(alexmarkov): obsolete, remove
+  kInterfaceCallV1, // TODO(alexmarkov): obsolete, remove
+  kObjectRef,
+  kDirectCall,
   kInterfaceCall,
 }
 
+String constantTagToString(ConstantTag tag) =>
+    tag.toString().substring('ConstantTag.k'.length);
+
 abstract class ConstantPoolEntry {
   const ConstantPoolEntry();
 
@@ -281,6 +311,12 @@
         return new ConstantEmptyTypeArguments.read(reader);
       case ConstantTag.kSymbol:
         return new ConstantSymbol.read(reader);
+      case ConstantTag.kInterfaceCallV1:
+        return new ConstantInterfaceCallV1.read(reader);
+      case ConstantTag.kObjectRef:
+        return new ConstantObjectRef.read(reader);
+      case ConstantTag.kDirectCall:
+        return new ConstantDirectCall.read(reader);
       case ConstantTag.kInterfaceCall:
         return new ConstantInterfaceCall.read(reader);
     }
@@ -539,7 +575,7 @@
   String toString() => 'ICData '
       '${isDynamic ? 'dynamic ' : ''}'
       '${_invocationKindToString(invocationKind)}'
-      'target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
+      'target-name $targetName, arg-desc CP#$argDescConstantIndex';
 
   // ConstantICData entries are created per call site and should not be merged,
   // so ConstantICData class uses identity [hashCode] and [operator ==].
@@ -1083,19 +1119,19 @@
   bool operator ==(other) => other is ConstantSymbol && this.name == other.name;
 }
 
-class ConstantInterfaceCall extends ConstantPoolEntry {
+class ConstantInterfaceCallV1 extends ConstantPoolEntry {
   final InvocationKind invocationKind;
   final ObjectHandle targetName;
   final int argDescConstantIndex;
 
-  ConstantInterfaceCall(
+  ConstantInterfaceCallV1(
       this.invocationKind, this.targetName, this.argDescConstantIndex);
 
   // Reserve 1 extra slot for arguments descriptor, following target name slot.
   int get numReservedEntries => 1;
 
   @override
-  ConstantTag get tag => ConstantTag.kInterfaceCall;
+  ConstantTag get tag => ConstantTag.kInterfaceCallV1;
 
   @override
   void writeValue(BufferedWriter writer) {
@@ -1104,15 +1140,15 @@
     writer.writePackedUInt30(argDescConstantIndex);
   }
 
-  ConstantInterfaceCall.read(BufferedReader reader)
+  ConstantInterfaceCallV1.read(BufferedReader reader)
       : invocationKind = InvocationKind.values[reader.readByte()],
         targetName = reader.readPackedObject(),
         argDescConstantIndex = reader.readPackedUInt30();
 
   @override
-  String toString() => 'InterfaceCall '
+  String toString() => 'InterfaceCallV1 '
       '${_invocationKindToString(invocationKind)}'
-      'target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
+      'target-name $targetName, arg-desc CP#$argDescConstantIndex';
 
   @override
   int get hashCode => _combineHashes(
@@ -1121,12 +1157,109 @@
 
   @override
   bool operator ==(other) =>
-      other is ConstantInterfaceCall &&
+      other is ConstantInterfaceCallV1 &&
       this.invocationKind == other.invocationKind &&
       this.targetName == other.targetName &&
       this.argDescConstantIndex == other.argDescConstantIndex;
 }
 
+class ConstantObjectRef extends ConstantPoolEntry {
+  final ObjectHandle object;
+
+  ConstantObjectRef(this.object);
+
+  @override
+  ConstantTag get tag => ConstantTag.kObjectRef;
+
+  @override
+  void writeValue(BufferedWriter writer) {
+    writer.writePackedObject(object);
+  }
+
+  ConstantObjectRef.read(BufferedReader reader)
+      : object = reader.readPackedObject();
+
+  @override
+  String toString() => 'ObjectRef $object';
+
+  @override
+  int get hashCode => object.hashCode;
+
+  @override
+  bool operator ==(other) =>
+      other is ConstantObjectRef && this.object == other.object;
+}
+
+class ConstantDirectCall extends ConstantPoolEntry {
+  final ObjectHandle target;
+  final ObjectHandle argDesc;
+
+  ConstantDirectCall(this.target, this.argDesc);
+
+  // Reserve 1 extra slot for arguments descriptor, following target slot.
+  int get numReservedEntries => 1;
+
+  @override
+  ConstantTag get tag => ConstantTag.kDirectCall;
+
+  @override
+  void writeValue(BufferedWriter writer) {
+    writer.writePackedObject(target);
+    writer.writePackedObject(argDesc);
+  }
+
+  ConstantDirectCall.read(BufferedReader reader)
+      : target = reader.readPackedObject(),
+        argDesc = reader.readPackedObject();
+
+  @override
+  String toString() => "DirectCall '$target', $argDesc";
+
+  @override
+  int get hashCode => _combineHashes(target.hashCode, argDesc.hashCode);
+
+  @override
+  bool operator ==(other) =>
+      other is ConstantDirectCall &&
+      this.target == other.target &&
+      this.argDesc == other.argDesc;
+}
+
+class ConstantInterfaceCall extends ConstantPoolEntry {
+  final ObjectHandle target;
+  final ObjectHandle argDesc;
+
+  ConstantInterfaceCall(this.target, this.argDesc);
+
+  // Reserve 1 extra slot for arguments descriptor, following target slot.
+  int get numReservedEntries => 1;
+
+  @override
+  ConstantTag get tag => ConstantTag.kInterfaceCall;
+
+  @override
+  void writeValue(BufferedWriter writer) {
+    writer.writePackedObject(target);
+    writer.writePackedObject(argDesc);
+  }
+
+  ConstantInterfaceCall.read(BufferedReader reader)
+      : target = reader.readPackedObject(),
+        argDesc = reader.readPackedObject();
+
+  @override
+  String toString() => "InterfaceCall '$target', $argDesc";
+
+  @override
+  int get hashCode => _combineHashes(target.hashCode, argDesc.hashCode);
+
+  @override
+  bool operator ==(other) =>
+      other is ConstantInterfaceCall &&
+      this.target == other.target &&
+      this.argDesc == other.argDesc;
+}
+
 /// Reserved constant pool entry.
 class _ReservedConstantPoolEntry extends ConstantPoolEntry {
   const _ReservedConstantPoolEntry();
@@ -1148,25 +1281,17 @@
 
   ConstantPool(this.stringTable, this.objectTable);
 
-  int addNull() => _add(const ConstantNull());
-
-  int addString(String value) => _add(new ConstantString(_indexString(value)));
-
-  int addInt(int value) => _add(new ConstantInt(value));
-
-  int addDouble(double value) => _add(new ConstantDouble(value));
-
-  int addBool(bool value) => _add(new ConstantBool(value));
+  int addString(String value) => addObjectRef(new StringConstant(value));
 
   int addArgDesc(int numArguments,
           {int numTypeArgs = 0, List<String> argNames = const <String>[]}) =>
-      _add(new ConstantArgDesc(
-          numArguments, numTypeArgs, _indexStrings(argNames)));
+      _add(new ConstantObjectRef(
+          objectTable.getArgDescHandle(numArguments, numTypeArgs, argNames)));
 
   int addArgDescByArguments(Arguments args,
           {bool hasReceiver: false, bool isFactory: false}) =>
-      _add(new ConstantArgDesc.fromArguments(
-          _indexArgNames(args), hasReceiver, isFactory));
+      _add(new ConstantObjectRef(objectTable.getArgDescHandleByArguments(args,
+          hasReceiver: hasReceiver, isFactory: isFactory)));
 
   int addICData(
           InvocationKind invocationKind, Name targetName, int argDescCpIndex,
@@ -1179,30 +1304,29 @@
           argDescCpIndex,
           isDynamic));
 
-  int addStaticICData(
-          InvocationKind invocationKind, Member target, int argDescCpIndex) =>
-      _add(new ConstantStaticICData(
+  int addDirectCall(
+          InvocationKind invocationKind, Member target, ObjectHandle argDesc) =>
+      _add(new ConstantDirectCall(
           objectTable.getMemberHandle(target,
               isGetter: invocationKind == InvocationKind.getter,
               isSetter: invocationKind == InvocationKind.setter),
-          argDescCpIndex));
+          argDesc));
 
   int addInterfaceCall(
-          InvocationKind invocationKind, Name targetName, int argDescCpIndex) =>
+          InvocationKind invocationKind, Member target, ObjectHandle argDesc) =>
       _add(new ConstantInterfaceCall(
-          invocationKind,
-          objectTable.getSelectorNameHandle(targetName,
+          objectTable.getMemberHandle(target,
               isGetter: invocationKind == InvocationKind.getter,
               isSetter: invocationKind == InvocationKind.setter),
-          argDescCpIndex));
+          argDesc));
 
-  int addInstanceCall(
-          InvocationKind invocationKind, Name targetName, int argDescCpIndex,
-          {bool isDynamic: false}) =>
-      isDynamic
-          ? addICData(invocationKind, targetName, argDescCpIndex,
+  int addInstanceCall(InvocationKind invocationKind, Member target,
+          Name targetName, ObjectHandle argDesc) =>
+      (target == null)
+          ? addICData(
+              invocationKind, targetName, _add(new ConstantObjectRef(argDesc)),
               isDynamic: true)
-          : addInterfaceCall(invocationKind, targetName, argDescCpIndex);
+          : addInterfaceCall(invocationKind, target, argDesc);
 
   int addStaticField(Field field) =>
       _add(new ConstantStaticField(objectTable.getHandle(field)));
@@ -1216,30 +1340,11 @@
   int addTypeArgumentsField(Class node) =>
       _add(new ConstantTypeArgumentsField(objectTable.getHandle(node)));
 
-  int addTearOff(Procedure node) =>
-      _add(new ConstantTearOff(objectTable.getHandle(node)));
-
   int addType(DartType type) =>
       _add(new ConstantType(objectTable.getHandle(type)));
 
   int addTypeArguments(List<DartType> typeArgs) =>
-      _add(new ConstantTypeArguments(objectTable.getHandles(typeArgs)));
-
-  int addList(DartType typeArgument, List<int> entries) =>
-      _add(new ConstantList(objectTable.getHandle(typeArgument), entries));
-
-  int addInstance(
-          Class klass, int typeArgumentsCpIndex, Map<Field, int> fieldValues) =>
-      _add(new ConstantInstance(
-          objectTable.getHandle(klass),
-          typeArgumentsCpIndex,
-          fieldValues.map<ObjectHandle, int>((Field field, int valueCpIndex) =>
-              new MapEntry(objectTable.getHandle(field), valueCpIndex))));
-
-  int addTypeArgumentsForInstanceAllocation(
-          Class classNode, List<DartType> typeArgs) =>
-      _add(new ConstantTypeArgumentsForInstanceAllocation(
-          objectTable.getHandle(classNode), objectTable.getHandles(typeArgs)));
+      _add(new ConstantObjectRef(objectTable.getTypeArgumentsHandle(typeArgs)));
 
   int addClosureFunction(int closureIndex) =>
       _add(new ConstantClosureFunction(closureIndex));
@@ -1252,15 +1357,10 @@
 
   int addSubtypeTestCache() => _add(new ConstantSubtypeTestCache());
 
-  int addPartialTearOffInstantiation(
-          int tearOffCpIndex, int typeArgumentsCpIndex) =>
-      _add(new ConstantPartialTearOffInstantiation(
-          tearOffCpIndex, typeArgumentsCpIndex));
-
   int addEmptyTypeArguments() => _add(const ConstantEmptyTypeArguments());
 
-  int addSymbol(Library library, String name) =>
-      _add(new ConstantSymbol(objectTable.getNameHandle(library, name)));
+  int addObjectRef(Node node) =>
+      _add(new ConstantObjectRef(objectTable.getHandle(node)));
 
   int _add(ConstantPoolEntry entry) {
     return _canonicalizationCache.putIfAbsent(entry, () {
@@ -1288,28 +1388,29 @@
     return str;
   }
 
-  List<String> _indexStrings(List<String> strings) {
-    for (var str in strings) {
-      stringTable.put(str);
-    }
-    return strings;
-  }
-
-  Arguments _indexArgNames(Arguments args) {
-    for (var arg in args.named) {
-      stringTable.put(arg.name);
-    }
-    return args;
-  }
-
   void write(BufferedWriter writer) {
+    final start = writer.offset;
+    if (BytecodeSizeStatistics.constantPoolStats.isEmpty) {
+      for (var tag in ConstantTag.values) {
+        BytecodeSizeStatistics.constantPoolStats
+            .add(new NamedEntryStatistics(constantTagToString(tag)));
+      }
+    }
     writer.writePackedUInt30(entries.length);
     entries.forEach((e) {
       if (e is _ReservedConstantPoolEntry) {
         return;
       }
+
+      final entryStart = writer.offset;
+
       e.write(writer);
+
+      final entryStat = BytecodeSizeStatistics.constantPoolStats[e.tag.index];
+      entryStat.size += (writer.offset - entryStart);
+      ++entryStat.count;
     });
+    BytecodeSizeStatistics.constantPoolSize += (writer.offset - start);
   }
 
   ConstantPool.read(BufferedReader reader)
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 6f7923a..c4b55c6 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -6,11 +6,11 @@
 
 library vm.bytecode.dbc;
 
-/// Version of stable bytecode format, produced by default.
-/// Before bumping stable bytecode version format, make sure that
+/// Version of bytecode format, produced by default.
+/// Before bumping current bytecode version format, make sure that
 /// all users have switched to a VM which is able to consume next
 /// version of bytecode.
-const int stableBytecodeFormatVersion = 1;
+const int stableBytecodeFormatVersion = 2;
 
 /// Version of bleeding edge bytecode format.
 /// Produced by bytecode generator when --use-future-bytecode-format
@@ -123,6 +123,8 @@
   kCompareIntLt,
   kCompareIntGe,
   kCompareIntLe,
+
+  kDirectCall,
 }
 
 enum Encoding {
@@ -298,6 +300,8 @@
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kCompareIntLe: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+  Opcode.kDirectCall: const Format(
+      Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
 };
 
 // Should match constant in runtime/vm/stack_frame_dbc.h.
@@ -318,6 +322,7 @@
     case Opcode.kInterfaceCall:
     case Opcode.kDynamicCall:
     case Opcode.kNativeCall:
+    case Opcode.kDirectCall:
       return true;
     default:
       return false;
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 04a58fb..cecadf5 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -4,8 +4,6 @@
 
 library vm.bytecode.gen_bytecode;
 
-import 'dart:math' show min;
-
 import 'package:kernel/ast.dart' hide MapEntry;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/core_types.dart' show CoreTypes;
@@ -27,6 +25,12 @@
 import 'constant_pool.dart';
 import 'dbc.dart';
 import 'exceptions.dart';
+import 'generics.dart'
+    show
+        flattenInstantiatorTypeArguments,
+        getInstantiatorTypeArguments,
+        hasFreeTypeParameters,
+        hasInstantiatorTypeArguments;
 import 'local_vars.dart' show LocalVariables;
 import 'nullability_detector.dart' show NullabilityDetector;
 import 'object_table.dart' show ObjectHandle, ObjectTable, NameAndType;
@@ -41,11 +45,10 @@
 
 void generateBytecode(
   Component component, {
-  bool dropAST: false,
   bool emitSourcePositions: false,
   bool omitAssertSourcePositions: false,
   bool useFutureBytecodeFormat: false,
-  Map<String, String> environmentDefines,
+  Map<String, String> environmentDefines: const <String, String>{},
   ErrorReporter errorReporter,
   List<Library> libraries,
 }) {
@@ -54,8 +57,7 @@
   final hierarchy = new ClassHierarchy(component,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
   final typeEnvironment = new TypeEnvironment(coreTypes, hierarchy);
-  final constantsBackend =
-      new VmConstantsBackend(environmentDefines, coreTypes);
+  final constantsBackend = new VmConstantsBackend(coreTypes);
   final errorReporter = new ForwardConstantEvaluationErrors(typeEnvironment);
   libraries ??= component.libraries;
   final bytecodeGenerator = new BytecodeGenerator(
@@ -64,6 +66,7 @@
       hierarchy,
       typeEnvironment,
       constantsBackend,
+      environmentDefines,
       emitSourcePositions,
       omitAssertSourcePositions,
       useFutureBytecodeFormat,
@@ -71,12 +74,6 @@
   for (var library in libraries) {
     bytecodeGenerator.visitLibrary(library);
   }
-  if (dropAST) {
-    final astRemover = new DropAST(component);
-    for (var library in libraries) {
-      astRemover.visitLibrary(library);
-    }
-  }
 }
 
 class BytecodeGenerator extends RecursiveVisitor<Null> {
@@ -85,6 +82,7 @@
   final ClassHierarchy hierarchy;
   final TypeEnvironment typeEnvironment;
   final ConstantsBackend constantsBackend;
+  final Map<String, String> environmentDefines;
   final bool emitSourcePositions;
   final bool omitAssertSourcePositions;
   final bool useFutureBytecodeFormat;
@@ -117,7 +115,6 @@
   Set<Field> initializedFields;
   List<ObjectHandle> nullableFields;
   ConstantPool cp;
-  ConstantEmitter constantEmitter;
   BytecodeAssembler asm;
   List<BytecodeAssembler> savedAssemblers;
   bool hasErrors;
@@ -129,6 +126,7 @@
       this.hierarchy,
       this.typeEnvironment,
       this.constantsBackend,
+      this.environmentDefines,
       this.emitSourcePositions,
       this.omitAssertSourcePositions,
       this.useFutureBytecodeFormat,
@@ -314,6 +312,18 @@
   Procedure get unsafeCast => _unsafeCast ??=
       libraryIndex.getTopLevelMember('dart:_internal', 'unsafeCast');
 
+  Procedure _iterableIterator;
+  Procedure get iterableIterator => _iterableIterator ??=
+      libraryIndex.getMember('dart:core', 'Iterable', 'get:iterator');
+
+  Procedure _iteratorMoveNext;
+  Procedure get iteratorMoveNext => _iteratorMoveNext ??=
+      libraryIndex.getMember('dart:core', 'Iterator', 'moveNext');
+
+  Procedure _iteratorCurrent;
+  Procedure get iteratorCurrent => _iteratorCurrent ??=
+      libraryIndex.getMember('dart:core', 'Iterator', 'get:current');
+
   void _recordSourcePosition(TreeNode node) {
     if (emitSourcePositions) {
       asm.currentSourcePosition = node.fileOffset;
@@ -397,7 +407,7 @@
     if (value.bitLength + 1 <= 16) {
       asm.emitPushInt(value);
     } else {
-      asm.emitPushConstant(cp.addInt(value));
+      asm.emitPushConstant(cp.addObjectRef(new IntConstant(value)));
     }
   }
 
@@ -406,9 +416,10 @@
       return expr.constant;
     }
     final constant = constantEvaluator.evaluate(expr);
-    if (constant == null) {
+    if (constant is UnevaluatedConstant &&
+        constant.expression is InvalidExpression) {
       // Compile-time error is already reported. Proceed with compilation
-      // in order to report as many errors as possible.
+      // in order to report errors in other constant expressions.
       hasErrors = true;
       return new NullConstant();
     }
@@ -424,7 +435,7 @@
     } else if (constant is IntConstant) {
       _genPushInt(constant.value);
     } else {
-      asm.emitPushConstant(constant.accept(constantEmitter));
+      asm.emitPushConstant(cp.addObjectRef(constant));
     }
   }
 
@@ -432,21 +443,20 @@
     asm.emitReturnTOS();
   }
 
-  void _genStaticCall(Member target, int argDescIndex, int totalArgCount,
+  void _genDirectCall(Member target, ObjectHandle argDesc, int totalArgCount,
       {bool isGet: false, bool isSet: false}) {
     assert(!isGet || !isSet);
     final kind = isGet
         ? InvocationKind.getter
         : (isSet ? InvocationKind.setter : InvocationKind.method);
-    final icdataIndex = cp.addStaticICData(kind, target, argDescIndex);
+    final cpIndex = cp.addDirectCall(kind, target, argDesc);
 
-    asm.emitPushConstant(icdataIndex);
-    asm.emitIndirectStaticCall(totalArgCount, argDescIndex);
+    asm.emitDirectCall(totalArgCount, cpIndex);
   }
 
-  void _genStaticCallWithArgs(Member target, Arguments args,
+  void _genDirectCallWithArgs(Member target, Arguments args,
       {bool hasReceiver: false, bool isFactory: false}) {
-    final int argDescIndex = cp.addArgDescByArguments(args,
+    final argDesc = objectTable.getArgDescHandleByArguments(args,
         hasReceiver: hasReceiver, isFactory: isFactory);
 
     int totalArgCount = args.positional.length + args.named.length;
@@ -459,22 +469,15 @@
       totalArgCount++;
     }
 
-    _genStaticCall(target, argDescIndex, totalArgCount);
-  }
-
-  bool hasFreeTypeParameters(List<DartType> typeArgs) {
-    final findTypeParams = new FindFreeTypeParametersVisitor();
-    return typeArgs.any((t) => t.accept(findTypeParams));
+    _genDirectCall(target, argDesc, totalArgCount);
   }
 
   void _genTypeArguments(List<DartType> typeArgs, {Class instantiatingClass}) {
     int typeArgsCPIndex() {
       if (instantiatingClass != null) {
-        return cp.addTypeArgumentsForInstanceAllocation(
-            instantiatingClass, typeArgs);
-      } else {
-        return cp.addTypeArguments(typeArgs);
+        typeArgs = getInstantiatorTypeArguments(instantiatingClass, typeArgs);
       }
+      return cp.addTypeArguments(typeArgs);
     }
 
     if (typeArgs.isEmpty || !hasFreeTypeParameters(typeArgs)) {
@@ -483,7 +486,7 @@
       final flattenedTypeArgs = (instantiatingClass != null &&
               (instantiatorTypeArguments != null ||
                   functionTypeParameters != null))
-          ? _flattenInstantiatorTypeArguments(instantiatingClass, typeArgs)
+          ? flattenInstantiatorTypeArguments(instantiatingClass, typeArgs)
           : typeArgs;
       if (_canReuseInstantiatorTypeArguments(flattenedTypeArgs)) {
         _genPushInstantiatorTypeArguments();
@@ -535,52 +538,6 @@
     }
   }
 
-  bool _canReuseSuperclassTypeArguments(List<DartType> superTypeArgs,
-      List<TypeParameter> typeParameters, int overlap) {
-    for (int i = 0; i < overlap; ++i) {
-      final superTypeArg = superTypeArgs[superTypeArgs.length - overlap + i];
-      if (!(superTypeArg is TypeParameterType &&
-          superTypeArg.parameter == typeParameters[i])) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  List<DartType> _flattenInstantiatorTypeArguments(
-      Class instantiatedClass, List<DartType> typeArgs) {
-    final typeParameters = instantiatedClass.typeParameters;
-    assert(typeArgs.length == typeParameters.length);
-
-    final supertype = instantiatedClass.supertype;
-    if (supertype == null) {
-      return typeArgs;
-    }
-
-    final superTypeArgs = _flattenInstantiatorTypeArguments(
-        supertype.classNode, supertype.typeArguments);
-
-    // Shrink type arguments by reusing portion of superclass type arguments
-    // if there is an overlapping. This optimization should be consistent with
-    // VM in order to correctly reuse instantiator type arguments.
-    int overlap = min(superTypeArgs.length, typeArgs.length);
-    for (; overlap > 0; --overlap) {
-      if (_canReuseSuperclassTypeArguments(
-          superTypeArgs, typeParameters, overlap)) {
-        break;
-      }
-    }
-
-    final substitution = Substitution.fromPairs(typeParameters, typeArgs);
-
-    List<DartType> flatTypeArgs = <DartType>[];
-    flatTypeArgs
-        .addAll(superTypeArgs.map((t) => substitution.substituteType(t)));
-    flatTypeArgs.addAll(typeArgs.getRange(overlap, typeArgs.length));
-
-    return flatTypeArgs;
-  }
-
   bool _canReuseInstantiatorTypeArguments(List<DartType> typeArgs) {
     if (instantiatorTypeArguments == null) {
       return false;
@@ -744,10 +701,10 @@
 
   int _getDefaultParamConstIndex(VariableDeclaration param) {
     if (param.initializer == null) {
-      return cp.addNull();
+      return cp.addObjectRef(null);
     }
     final constant = _evaluateConstantExpression(param.initializer);
-    return constant.accept(constantEmitter);
+    return cp.addObjectRef(constant);
   }
 
   // Duplicates value on top of the stack using temporary variable with
@@ -770,10 +727,10 @@
     if (type is InterfaceType && type.typeArguments.isEmpty) {
       assert(type.classNode.typeParameters.isEmpty);
       asm.emitPushConstant(cp.addType(type));
-      final argDescIndex = cp.addArgDesc(2);
-      final icdataIndex = cp.addInterfaceCall(
-          InvocationKind.method, objectSimpleInstanceOf.name, argDescIndex);
-      asm.emitInterfaceCall(2, icdataIndex);
+      final argDesc = objectTable.getArgDescHandle(2);
+      final cpIndex = cp.addInterfaceCall(
+          InvocationKind.method, objectSimpleInstanceOf, argDesc);
+      asm.emitInterfaceCall(2, cpIndex);
       return;
     }
 
@@ -784,10 +741,10 @@
       asm.emitPushNull(); // Function type arguments.
     }
     asm.emitPushConstant(cp.addType(type));
-    final argDescIndex = cp.addArgDesc(4);
-    final icdataIndex = cp.addInterfaceCall(
-        InvocationKind.method, objectInstanceOf.name, argDescIndex);
-    asm.emitInterfaceCall(4, icdataIndex);
+    final argDesc = objectTable.getArgDescHandle(4);
+    final cpIndex =
+        cp.addInterfaceCall(InvocationKind.method, objectInstanceOf, argDesc);
+    asm.emitInterfaceCall(4, cpIndex);
   }
 
   void start(Member node) {
@@ -818,7 +775,7 @@
             .map((p) => new TypeParameterType(p))
             .toList();
         instantiatorTypeArguments =
-            _flattenInstantiatorTypeArguments(enclosingClass, typeParameters);
+            flattenInstantiatorTypeArguments(enclosingClass, typeParameters);
       }
     }
     if (enclosingFunction != null &&
@@ -829,8 +786,12 @@
     }
     locals = new LocalVariables(node);
     // TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
-    constantEvaluator = new ConstantEvaluator(constantsBackend, typeEnvironment,
-        coreTypes, /* enableAsserts = */ true, errorReporter)
+    constantEvaluator = new ConstantEvaluator(
+        constantsBackend,
+        environmentDefines,
+        typeEnvironment,
+        /* enableAsserts = */ true,
+        errorReporter)
       ..env = new EvaluationEnvironment();
     labeledStatements = <LabeledStatement, Label>{};
     switchCases = <SwitchCase, Label>{};
@@ -842,7 +803,6 @@
     initializedFields = null; // Tracked for constructors only.
     nullableFields = const <ObjectHandle>[];
     cp = new ConstantPool(stringTable, objectTable);
-    constantEmitter = new ConstantEmitter(cp);
     asm = new BytecodeAssembler();
     savedAssemblers = <BytecodeAssembler>[];
     currentLoopDepth = 0;
@@ -906,7 +866,6 @@
     initializedFields = null;
     nullableFields = null;
     cp = null;
-    constantEmitter = null;
     asm = null;
     savedAssemblers = null;
     hasErrors = false;
@@ -979,7 +938,8 @@
               cp.addInstanceField(closureFunctionTypeArguments));
           _genPushInt(numParentTypeArgs);
           _genPushInt(numParentTypeArgs + function.typeParameters.length);
-          _genStaticCall(prependTypeArguments, cp.addArgDesc(4), 4);
+          _genDirectCall(
+              prependTypeArguments, objectTable.getArgDescHandle(4), 4);
           asm.emitPopLocal(locals.functionTypeArgsVarIndexInFrame);
         } else {
           asm.emitPush(locals.closureVarIndexInFrame);
@@ -1606,12 +1566,13 @@
     // Argument 3 for _allocateInvocationMirror(): isSuperInvocation flag.
     asm.emitPushTrue();
 
-    _genStaticCall(allocateInvocationMirror, cp.addArgDesc(4), 4);
+    _genDirectCall(
+        allocateInvocationMirror, objectTable.getArgDescHandle(4), 4);
 
     final Member target = hierarchy.getDispatchTarget(
         enclosingClass.superclass, new Name('noSuchMethod'));
     assert(target != null);
-    _genStaticCall(target, cp.addArgDesc(2), 2);
+    _genDirectCall(target, objectTable.getArgDescHandle(2), 2);
   }
 
   @override
@@ -1642,7 +1603,7 @@
 
   @override
   visitDoubleLiteral(DoubleLiteral node) {
-    final cpIndex = cp.addDouble(node.value);
+    final cpIndex = cp.addObjectRef(new DoubleConstant(node.value));
     asm.emitPushConstant(cpIndex);
   }
 
@@ -1694,7 +1655,7 @@
         new Arguments(node.arguments.positional, named: node.arguments.named)
           ..parent = node;
     _genArguments(null, args);
-    _genStaticCallWithArgs(node.target, args, hasReceiver: true);
+    _genDirectCallWithArgs(node.target, args, hasReceiver: true);
     asm.emitDrop1();
   }
 
@@ -1704,7 +1665,7 @@
     _genArguments(node.receiver, args);
     final target = node.target;
     if (target is Procedure && !target.isGetter && !target.isSetter) {
-      _genStaticCallWithArgs(target, args, hasReceiver: true);
+      _genDirectCallWithArgs(target, args, hasReceiver: true);
     } else {
       throw new UnsupportedOperationError(
           'Unsupported DirectMethodInvocation with target ${target.runtimeType} $target');
@@ -1716,7 +1677,7 @@
     _generateNode(node.receiver);
     final target = node.target;
     if (target is Field || (target is Procedure && target.isGetter)) {
-      _genStaticCall(target, cp.addArgDesc(1), 1, isGet: true);
+      _genDirectCall(target, objectTable.getArgDescHandle(1), 1, isGet: true);
     } else {
       throw new UnsupportedOperationError(
           'Unsupported DirectPropertyGet with ${target.runtimeType} $target');
@@ -1737,7 +1698,7 @@
 
     final target = node.target;
     assert(target is Field || (target is Procedure && target.isSetter));
-    _genStaticCall(target, cp.addArgDesc(2), 2, isSet: true);
+    _genDirectCall(target, objectTable.getArgDescHandle(2), 2, isSet: true);
     asm.emitDrop1();
 
     if (hasResult) {
@@ -1762,7 +1723,8 @@
     _genTypeArguments(node.typeArguments);
     asm.emitStoreLocal(typeArguments);
 
-    _genStaticCall(boundsCheckForPartialInstantiation, cp.addArgDesc(2), 2);
+    _genDirectCall(
+        boundsCheckForPartialInstantiation, objectTable.getArgDescHandle(2), 2);
     asm.emitDrop1();
 
     assert(closureClass.typeParameters.isEmpty);
@@ -1833,7 +1795,7 @@
     // Type arguments passed to a factory constructor are counted as a normal
     // argument and not counted in number of type arguments.
     assert(listFromLiteral.isFactory);
-    _genStaticCall(listFromLiteral, cp.addArgDesc(2, numTypeArgs: 0), 2);
+    _genDirectCall(listFromLiteral, objectTable.getArgDescHandle(2), 2);
   }
 
   @override
@@ -1872,7 +1834,8 @@
     _genTypeArguments([node.keyType, node.valueType]);
 
     if (node.entries.isEmpty) {
-      asm.emitPushConstant(cp.addList(const DynamicType(), const []));
+      asm.emitPushConstant(
+          cp.addObjectRef(new ListConstant(const DynamicType(), const [])));
     } else {
       _genTypeArguments([const DynamicType()]);
       _genPushInt(node.entries.length * 2);
@@ -1899,7 +1862,7 @@
     // Type arguments passed to a factory constructor are counted as a normal
     // argument and not counted in number of type arguments.
     assert(mapFromLiteral.isFactory);
-    _genStaticCall(mapFromLiteral, cp.addArgDesc(2, numTypeArgs: 0), 2);
+    _genDirectCall(mapFromLiteral, objectTable.getArgDescHandle(2), 2);
   }
 
   void _genMethodInvocationUsingSpecializedBytecode(
@@ -1943,11 +1906,11 @@
     asm.emitBytecode0(opcode);
   }
 
-  void _genInstanceCall(int totalArgCount, int icdataCpIndex, bool isDynamic) {
+  void _genInstanceCall(int totalArgCount, int callCpIndex, bool isDynamic) {
     if (isDynamic) {
-      asm.emitDynamicCall(totalArgCount, icdataCpIndex);
+      asm.emitDynamicCall(totalArgCount, callCpIndex);
     } else {
-      asm.emitInterfaceCall(totalArgCount, icdataCpIndex);
+      asm.emitInterfaceCall(totalArgCount, callCpIndex);
     }
   }
 
@@ -1959,28 +1922,34 @@
       return;
     }
     final args = node.arguments;
-    final isDynamic = node.interfaceTarget == null;
+    Member interfaceTarget = node.interfaceTarget;
+    if (interfaceTarget is Field ||
+        interfaceTarget is Procedure && interfaceTarget.isGetter) {
+      // Call via field or getter. Treat it as a dynamic call because
+      // interface target doesn't fully represent what is being called.
+      interfaceTarget = null;
+    }
+    final isDynamic = interfaceTarget == null;
     _genArguments(node.receiver, args);
-    final argDescIndex = cp.addArgDescByArguments(args, hasReceiver: true);
-    final icdataIndex = cp.addInstanceCall(
-        InvocationKind.method, node.name, argDescIndex,
-        isDynamic: isDynamic);
+    final argDesc =
+        objectTable.getArgDescHandleByArguments(args, hasReceiver: true);
+    final callCpIndex = cp.addInstanceCall(
+        InvocationKind.method, interfaceTarget, node.name, argDesc);
     final totalArgCount = args.positional.length +
         args.named.length +
         1 /* receiver */ +
         (args.types.isNotEmpty ? 1 : 0) /* type arguments */;
-    _genInstanceCall(totalArgCount, icdataIndex, isDynamic);
+    _genInstanceCall(totalArgCount, callCpIndex, isDynamic);
   }
 
   @override
   visitPropertyGet(PropertyGet node) {
     _generateNode(node.receiver);
     final isDynamic = node.interfaceTarget == null;
-    final argDescIndex = cp.addArgDesc(1);
-    final icdataIndex = cp.addInstanceCall(
-        InvocationKind.getter, node.name, argDescIndex,
-        isDynamic: isDynamic);
-    _genInstanceCall(1, icdataIndex, isDynamic);
+    final argDesc = objectTable.getArgDescHandle(1);
+    final callCpIndex = cp.addInstanceCall(
+        InvocationKind.getter, node.interfaceTarget, node.name, argDesc);
+    _genInstanceCall(1, callCpIndex, isDynamic);
   }
 
   @override
@@ -1996,11 +1965,10 @@
     }
 
     final isDynamic = node.interfaceTarget == null;
-    final argDescIndex = cp.addArgDesc(2);
-    final icdataIndex = cp.addInstanceCall(
-        InvocationKind.setter, node.name, argDescIndex,
-        isDynamic: isDynamic);
-    _genInstanceCall(2, icdataIndex, isDynamic);
+    final argDesc = objectTable.getArgDescHandle(2);
+    final callCpIndex = cp.addInstanceCall(
+        InvocationKind.setter, node.interfaceTarget, node.name, argDesc);
+    _genInstanceCall(2, callCpIndex, isDynamic);
     asm.emitDrop1();
 
     if (hasResult) {
@@ -2026,7 +1994,7 @@
       return;
     }
     _genArguments(new ThisExpression(), args);
-    _genStaticCallWithArgs(target, args, hasReceiver: true);
+    _genDirectCallWithArgs(target, args, hasReceiver: true);
   }
 
   @override
@@ -2040,7 +2008,7 @@
       return;
     }
     _genPushReceiver();
-    _genStaticCall(target, cp.addArgDesc(1), 1, isGet: true);
+    _genDirectCall(target, objectTable.getArgDescHandle(1), 1, isGet: true);
   }
 
   @override
@@ -2063,7 +2031,7 @@
       }
 
       assert(target is Field || (target is Procedure && target.isSetter));
-      _genStaticCall(target, cp.addArgDesc(2), 2, isSet: true);
+      _genDirectCall(target, objectTable.getArgDescHandle(2), 2, isSet: true);
     }
 
     asm.emitDrop1();
@@ -2122,14 +2090,13 @@
             fieldIndex); // TODO(alexmarkov): do we really need this?
         asm.emitPushStatic(fieldIndex);
       } else {
-        _genStaticCall(target, cp.addArgDesc(0), 0, isGet: true);
+        _genDirectCall(target, objectTable.getArgDescHandle(0), 0, isGet: true);
       }
     } else if (target is Procedure) {
       if (target.isGetter) {
-        _genStaticCall(target, cp.addArgDesc(0), 0, isGet: true);
+        _genDirectCall(target, objectTable.getArgDescHandle(0), 0, isGet: true);
       } else {
-        final tearOffIndex = cp.addTearOff(target);
-        asm.emitPushConstant(tearOffIndex);
+        asm.emitPushConstant(cp.addObjectRef(new TearOffConstant(target)));
       }
     } else {
       throw 'Unexpected target for StaticGet: ${target.runtimeType} $target';
@@ -2166,7 +2133,7 @@
             ..parent = node;
     }
     _genArguments(null, args);
-    _genStaticCallWithArgs(target, args, isFactory: target.isFactory);
+    _genDirectCallWithArgs(target, args, isFactory: target.isFactory);
   }
 
   @override
@@ -2184,7 +2151,7 @@
       int cpIndex = cp.addStaticField(target);
       asm.emitStoreStaticTOS(cpIndex);
     } else {
-      _genStaticCall(target, cp.addArgDesc(1), 1, isSet: true);
+      _genDirectCall(target, objectTable.getArgDescHandle(1), 1, isSet: true);
       asm.emitDrop1();
     }
   }
@@ -2193,7 +2160,7 @@
   visitStringConcatenation(StringConcatenation node) {
     if (node.expressions.length == 1) {
       _generateNode(node.expressions.single);
-      _genStaticCall(interpolateSingle, cp.addArgDesc(1), 1);
+      _genDirectCall(interpolateSingle, objectTable.getArgDescHandle(1), 1);
     } else {
       asm.emitPushNull();
       _genPushInt(node.expressions.length);
@@ -2209,7 +2176,7 @@
         asm.emitStoreIndexedTOS();
       }
 
-      _genStaticCall(interpolate, cp.addArgDesc(1), 1);
+      _genDirectCall(interpolate, objectTable.getArgDescHandle(1), 1);
     }
   }
 
@@ -2291,7 +2258,7 @@
 
   void _genFutureNull() {
     asm.emitPushNull();
-    _genStaticCall(futureValue, cp.addArgDesc(1), 1);
+    _genDirectCall(futureValue, objectTable.getArgDescHandle(1), 1);
   }
 
   @override
@@ -2320,7 +2287,7 @@
       asm.emitPushNull();
     }
 
-    _genStaticCall(throwNewAssertionError, cp.addArgDesc(3), 3);
+    _genDirectCall(throwNewAssertionError, objectTable.getArgDescHandle(3), 3);
     asm.emitDrop1();
 
     asm.bind(done);
@@ -2407,16 +2374,12 @@
   visitForInStatement(ForInStatement node) {
     _generateNode(node.iterable);
 
-    const kIterator = 'iterator'; // Iterable.iterator
-    const kMoveNext = 'moveNext'; // Iterator.moveNext
-    const kCurrent = 'current'; // Iterator.current
-
     // Front-end inserts implicit cast (type check) which ensures that
     // result of iterable expression is Iterable<dynamic>.
     asm.emitInterfaceCall(
         1,
-        cp.addInterfaceCall(
-            InvocationKind.getter, new Name(kIterator), cp.addArgDesc(1)));
+        cp.addInterfaceCall(InvocationKind.getter, iterableIterator,
+            objectTable.getArgDescHandle(1)));
 
     final iteratorTemp = locals.tempIndexInFrame(node);
     asm.emitPopLocal(iteratorTemp);
@@ -2449,8 +2412,8 @@
 
     asm.emitInterfaceCall(
         1,
-        cp.addInterfaceCall(
-            InvocationKind.method, new Name(kMoveNext), cp.addArgDesc(1)));
+        cp.addInterfaceCall(InvocationKind.method, iteratorMoveNext,
+            objectTable.getArgDescHandle(1)));
     _genJumpIfFalse(/* negated = */ false, done);
 
     _enterScope(node);
@@ -2460,8 +2423,8 @@
     asm.emitPush(iteratorTemp);
     asm.emitInterfaceCall(
         1,
-        cp.addInterfaceCall(
-            InvocationKind.getter, new Name(kCurrent), cp.addArgDesc(1)));
+        cp.addInterfaceCall(InvocationKind.getter, iteratorCurrent,
+            objectTable.getArgDescHandle(1)));
 
     _genStoreVar(node.variable);
 
@@ -2603,7 +2566,7 @@
     final Label done = new Label();
     final List<Label> caseLabels = new List<Label>.generate(
         node.cases.length, (_) => new Label(allowsBackwardJumps: true));
-    final equalsArgDesc = cp.addArgDesc(2);
+    final equalsArgDesc = objectTable.getArgDescHandle(2);
 
     Label defaultLabel = done;
     for (int i = 0; i < node.cases.length; i++) {
@@ -2619,8 +2582,8 @@
           _genPushConstExpr(expr);
           asm.emitInterfaceCall(
               2,
-              cp.addInterfaceCall(
-                  InvocationKind.method, new Name('=='), equalsArgDesc));
+              cp.addInterfaceCall(InvocationKind.method, coreTypes.objectEquals,
+                  equalsArgDesc));
           _genJumpIfTrue(/* negated = */ false, caseLabel);
         }
       }
@@ -2974,7 +2937,7 @@
     final args = node.arguments;
     assert(args.types.isEmpty);
     _genArguments(new ThisExpression(), args);
-    _genStaticCallWithArgs(node.target, args, hasReceiver: true);
+    _genDirectCallWithArgs(node.target, args, hasReceiver: true);
     asm.emitDrop1();
   }
 
@@ -2992,7 +2955,7 @@
       }
     }
     assert(target != null);
-    _genStaticCallWithArgs(target, args, hasReceiver: true);
+    _genDirectCallWithArgs(target, args, hasReceiver: true);
     asm.emitDrop1();
   }
 
@@ -3012,62 +2975,6 @@
   }
 }
 
-class ConstantEmitter extends ConstantVisitor<int> {
-  final ConstantPool cp;
-
-  ConstantEmitter(this.cp);
-
-  @override
-  int defaultConstant(Constant node) => throw new UnsupportedOperationError(
-      'Unsupported constant node ${node.runtimeType}');
-
-  @override
-  int visitNullConstant(NullConstant node) => cp.addNull();
-
-  @override
-  int visitBoolConstant(BoolConstant node) => cp.addBool(node.value);
-
-  @override
-  int visitIntConstant(IntConstant node) => cp.addInt(node.value);
-
-  @override
-  int visitDoubleConstant(DoubleConstant node) => cp.addDouble(node.value);
-
-  @override
-  int visitStringConstant(StringConstant node) => cp.addString(node.value);
-
-  @override
-  int visitSymbolConstant(SymbolConstant node) =>
-      cp.addSymbol(node.libraryReference?.asLibrary, node.name);
-
-  @override
-  int visitListConstant(ListConstant node) => cp.addList(node.typeArgument,
-      new List<int>.from(node.entries.map((Constant c) => c.accept(this))));
-
-  @override
-  int visitInstanceConstant(InstanceConstant node) => cp.addInstance(
-      node.klass,
-      hasInstantiatorTypeArguments(node.klass)
-          ? cp.addTypeArgumentsForInstanceAllocation(
-              node.klass, node.typeArguments)
-          : cp.addNull(),
-      node.fieldValues.map<Field, int>((Reference fieldRef, Constant value) =>
-          new MapEntry(fieldRef.asField, value.accept(this))));
-
-  @override
-  int visitTearOffConstant(TearOffConstant node) =>
-      cp.addTearOff(node.procedure);
-
-  @override
-  int visitTypeLiteralConstant(TypeLiteralConstant node) =>
-      cp.addType(node.type);
-
-  @override
-  int visitPartialInstantiationConstant(PartialInstantiationConstant node) =>
-      cp.addPartialTearOffInstantiation(
-          node.tearOffConstant.accept(this), cp.addTypeArguments(node.types));
-}
-
 class UnsupportedOperationError {
   final String message;
   UnsupportedOperationError(this.message);
@@ -3076,97 +2983,6 @@
   String toString() => message;
 }
 
-class FindFreeTypeParametersVisitor extends DartTypeVisitor<bool> {
-  Set<TypeParameter> _declaredTypeParameters;
-
-  bool visit(DartType type) => type.accept(this);
-
-  @override
-  bool defaultDartType(DartType node) =>
-      throw 'Unexpected type ${node.runtimeType} $node';
-
-  @override
-  bool visitInvalidType(InvalidType node) => false;
-
-  @override
-  bool visitDynamicType(DynamicType node) => false;
-
-  @override
-  bool visitVoidType(VoidType node) => false;
-
-  @override
-  bool visitBottomType(BottomType node) => false;
-
-  @override
-  bool visitTypeParameterType(TypeParameterType node) =>
-      _declaredTypeParameters == null ||
-      !_declaredTypeParameters.contains(node.parameter);
-
-  @override
-  bool visitInterfaceType(InterfaceType node) =>
-      node.typeArguments.any((t) => t.accept(this));
-
-  @override
-  bool visitTypedefType(TypedefType node) =>
-      node.typeArguments.any((t) => t.accept(this));
-
-  @override
-  bool visitFunctionType(FunctionType node) {
-    if (node.typeParameters.isNotEmpty) {
-      _declaredTypeParameters ??= new Set<TypeParameter>();
-      _declaredTypeParameters.addAll(node.typeParameters);
-    }
-
-    final bool result = node.positionalParameters.any((t) => t.accept(this)) ||
-        node.namedParameters.any((p) => p.type.accept(this)) ||
-        node.returnType.accept(this);
-
-    if (node.typeParameters.isNotEmpty) {
-      _declaredTypeParameters.removeAll(node.typeParameters);
-    }
-
-    return result;
-  }
-}
-
-// Drop kernel AST for members with bytecode.
-class DropAST extends Transformer {
-  BytecodeMetadataRepository metadata;
-
-  DropAST(Component component)
-      : metadata = component.metadata[new BytecodeMetadataRepository().tag];
-
-  @override
-  TreeNode defaultMember(Member node) {
-    if (_hasBytecode(node)) {
-      if (node is Field) {
-        node.initializer = null;
-      } else if (node is Constructor) {
-        node.initializers = <Initializer>[];
-        node.function.body = null;
-      } else if (node.function != null) {
-        node.function.body = null;
-      }
-    }
-
-    // Instance field initializers do not form separate functions, and bytecode
-    // is not attached to instance fields (it is included into constructors).
-    // When VM reads a constructor from kernel, it also reads and translates
-    // instance field initializers. So, their ASTs can be dropped only if
-    // bytecode was generated for all generative constructors.
-    if (node is Field && !node.isStatic && node.initializer != null) {
-      if (node.enclosingClass.constructors.every(_hasBytecode)) {
-        node.initializer = null;
-      }
-    }
-
-    return node;
-  }
-
-  bool _hasBytecode(Member node) =>
-      metadata != null && metadata.mapping.containsKey(node);
-}
-
 typedef void GenerateContinuation();
 
 class FinallyBlock {
@@ -3175,8 +2991,3 @@
 
   FinallyBlock(this.generateContinuation);
 }
-
-bool hasInstantiatorTypeArguments(Class c) {
-  return c.typeParameters.isNotEmpty ||
-      (c.superclass != null && hasInstantiatorTypeArguments(c.superclass));
-}
diff --git a/pkg/vm/lib/bytecode/generics.dart b/pkg/vm/lib/bytecode/generics.dart
new file mode 100644
index 0000000..70b6327
--- /dev/null
+++ b/pkg/vm/lib/bytecode/generics.dart
@@ -0,0 +1,228 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 vm.bytecode.generics;
+
+import 'dart:math' show min;
+
+import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/type_algebra.dart' show Substitution;
+
+bool hasInstantiatorTypeArguments(Class c) {
+  for (; c != null; c = c.superclass) {
+    if (c.typeParameters.isNotEmpty) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool _canReuseSuperclassTypeArguments(List<DartType> superTypeArgs,
+    List<TypeParameter> typeParameters, int overlap) {
+  for (int i = 0; i < overlap; ++i) {
+    final superTypeArg = superTypeArgs[superTypeArgs.length - overlap + i];
+    if (!(superTypeArg is TypeParameterType &&
+        superTypeArg.parameter == typeParameters[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+List<DartType> flattenInstantiatorTypeArguments(
+    Class instantiatedClass, List<DartType> typeArgs) {
+  final typeParameters = instantiatedClass.typeParameters;
+  assert(typeArgs.length == typeParameters.length);
+
+  final supertype = instantiatedClass.supertype;
+  if (supertype == null) {
+    return typeArgs;
+  }
+
+  final superTypeArgs = flattenInstantiatorTypeArguments(
+      supertype.classNode, supertype.typeArguments);
+
+  // Shrink type arguments by reusing portion of superclass type arguments
+  // if there is an overlapping. This optimization should be consistent with
+  // VM in order to correctly reuse instantiator type arguments.
+  int overlap = min(superTypeArgs.length, typeArgs.length);
+  for (; overlap > 0; --overlap) {
+    if (_canReuseSuperclassTypeArguments(
+        superTypeArgs, typeParameters, overlap)) {
+      break;
+    }
+  }
+
+  final substitution = Substitution.fromPairs(typeParameters, typeArgs);
+
+  List<DartType> flatTypeArgs = <DartType>[];
+  flatTypeArgs.addAll(superTypeArgs.map((t) => substitution.substituteType(t)));
+  flatTypeArgs.addAll(typeArgs.getRange(overlap, typeArgs.length));
+
+  return flatTypeArgs;
+}
+
+List<DartType> getInstantiatorTypeArguments(
+    Class instantiatedClass, List<DartType> typeArgs) {
+  final flatTypeArgs =
+      flattenInstantiatorTypeArguments(instantiatedClass, typeArgs);
+  if (_isAllDynamic(flatTypeArgs)) {
+    return null;
+  }
+  return flatTypeArgs;
+}
+
+bool _isAllDynamic(List<DartType> typeArgs) {
+  for (var t in typeArgs) {
+    if (t != const DynamicType()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool hasFreeTypeParameters(List<DartType> typeArgs) {
+  final findTypeParams = new FindFreeTypeParametersVisitor();
+  return typeArgs.any((t) => t.accept(findTypeParams));
+}
+
+class FindFreeTypeParametersVisitor extends DartTypeVisitor<bool> {
+  Set<TypeParameter> _declaredTypeParameters;
+
+  bool visit(DartType type) => type.accept(this);
+
+  @override
+  bool defaultDartType(DartType node) =>
+      throw 'Unexpected type ${node.runtimeType} $node';
+
+  @override
+  bool visitInvalidType(InvalidType node) => false;
+
+  @override
+  bool visitDynamicType(DynamicType node) => false;
+
+  @override
+  bool visitVoidType(VoidType node) => false;
+
+  @override
+  bool visitBottomType(BottomType node) => false;
+
+  @override
+  bool visitTypeParameterType(TypeParameterType node) =>
+      _declaredTypeParameters == null ||
+      !_declaredTypeParameters.contains(node.parameter);
+
+  @override
+  bool visitInterfaceType(InterfaceType node) =>
+      node.typeArguments.any((t) => t.accept(this));
+
+  @override
+  bool visitTypedefType(TypedefType node) =>
+      node.typeArguments.any((t) => t.accept(this));
+
+  @override
+  bool visitFunctionType(FunctionType node) {
+    if (node.typeParameters.isNotEmpty) {
+      _declaredTypeParameters ??= new Set<TypeParameter>();
+      _declaredTypeParameters.addAll(node.typeParameters);
+    }
+
+    final bool result = node.positionalParameters.any((t) => t.accept(this)) ||
+        node.namedParameters.any((p) => p.type.accept(this)) ||
+        node.returnType.accept(this);
+
+    if (node.typeParameters.isNotEmpty) {
+      _declaredTypeParameters.removeAll(node.typeParameters);
+    }
+
+    return result;
+  }
+}
+
+/// Returns true if the given type is recursive after its type arguments
+/// are flattened.
+bool isRecursiveAfterFlattening(InterfaceType type) {
+  final visitor = new IsRecursiveAfterFlatteningVisitor();
+  visitor.visit(type);
+  return visitor.isRecursive(type);
+}
+
+class IsRecursiveAfterFlatteningVisitor extends DartTypeVisitor<void> {
+  Set<DartType> _visited = new Set<DartType>();
+  List<DartType> _stack = <DartType>[];
+  Set<DartType> _recursive;
+
+  bool isRecursive(DartType type) =>
+      _recursive != null && _recursive.contains(type);
+
+  void visit(DartType type) {
+    if (!_visited.add(type)) {
+      _recordRecursiveType(type);
+      return;
+    }
+    _stack.add(type);
+
+    type.accept(this);
+
+    _stack.removeLast();
+    _visited.remove(type);
+  }
+
+  void _recordRecursiveType(DartType type) {
+    final int start = _stack.lastIndexOf(type);
+    final recursive = (_recursive ??= new Set<DartType>());
+    for (int i = start; i < _stack.length; ++i) {
+      recursive.add(_stack[i]);
+    }
+  }
+
+  @override
+  void defaultDartType(DartType node) =>
+      throw 'Unexpected type ${node.runtimeType} $node';
+
+  @override
+  void visitInvalidType(InvalidType node) {}
+
+  @override
+  void visitDynamicType(DynamicType node) {}
+
+  @override
+  void visitVoidType(VoidType node) {}
+
+  @override
+  void visitBottomType(BottomType node) {}
+
+  @override
+  void visitTypeParameterType(TypeParameterType node) {}
+
+  @override
+  void visitInterfaceType(InterfaceType node) {
+    for (var typeArg in node.typeArguments) {
+      visit(typeArg);
+    }
+    if (isRecursive(node)) {
+      return;
+    }
+    final flatTypeArgs =
+        flattenInstantiatorTypeArguments(node.classNode, node.typeArguments);
+    for (var typeArg in flatTypeArgs.getRange(
+        0, flatTypeArgs.length - node.typeArguments.length)) {
+      visit(typeArg);
+    }
+  }
+
+  @override
+  void visitTypedefType(TypedefType node) => visit(node.unalias);
+
+  @override
+  void visitFunctionType(FunctionType node) {
+    for (var p in node.positionalParameters) {
+      visit(p);
+    }
+    for (var p in node.namedParameters) {
+      visit(p.type);
+    }
+    visit(node.returnType);
+  }
+}
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index b3fac13..0baa233 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -512,6 +512,10 @@
   @override
   visitFunctionDeclaration(FunctionDeclaration node) {
     _currentFrame.hasClosures = true;
+    if (_currentFrame.receiverVar != null) {
+      // Closure creation may load receiver to get instantiator type arguments.
+      _useThis();
+    }
     node.variable.accept(this);
     _visitFunction(node);
   }
@@ -519,6 +523,10 @@
   @override
   visitFunctionExpression(FunctionExpression node) {
     _currentFrame.hasClosures = true;
+    if (_currentFrame.receiverVar != null) {
+      // Closure creation may load receiver to get instantiator type arguments.
+      _useThis();
+    }
     _visitFunction(node);
   }
 
diff --git a/pkg/vm/lib/bytecode/object_table.dart b/pkg/vm/lib/bytecode/object_table.dart
index 4b17c60..fd54b70 100644
--- a/pkg/vm/lib/bytecode/object_table.dart
+++ b/pkg/vm/lib/bytecode/object_table.dart
@@ -12,9 +12,15 @@
         BufferedWriter,
         BufferedReader,
         BytecodeObject,
+        BytecodeSizeStatistics,
+        NamedEntryStatistics,
+        doubleToIntBits,
+        intBitsToDouble,
         ObjectReader,
         ObjectWriter,
         StringWriter;
+import 'generics.dart'
+    show getInstantiatorTypeArguments, isRecursiveAfterFlattening;
 
 /*
 
@@ -141,6 +147,88 @@
   PackedString string;
 }
 
+// Type arguments vector.
+type TypeArguments extends ObjectContents {
+  kind = 10;
+  List<PackedObject> args;
+}
+
+type FinalizedGenericType extends ObjectContents {
+  kind = 11;
+  PackedObject class;
+  PackedObject typeArgs;
+}
+
+abstract type ConstObject extends ObjectContents {
+  kind = 12;
+  flags = constantTag (4 bits)
+}
+
+type ConstInstance extends ConstObject {
+  kind = 12
+  constantTag (flags) = 1
+  PackedObject type;
+  List<Pair<PackedObject, PackedObject>> fieldValues;
+}
+
+type ConstInt extends ConstValue {
+  kind = 12
+  constantTag (flags) = 2
+  SLEB128 value;
+}
+
+type ConstDouble extends ConstValue {
+  kind = 12
+  constantTag (flags) = 3
+  // double bits are converted to int
+  SLEB128 value;
+}
+
+type ConstList extends ConstObject {
+  kind = 12
+  constantTag (flags) = 4
+  PackedObject elemType;
+  List<PackedObject> entries;
+}
+
+type ConstTearOff extends ConstObject {
+  kind = 12
+  constantTag (flags) = 5
+  PackedObject target;
+}
+
+type ConstBool extends ConstValue {
+  kind = 12
+  constantTag = 6
+  Byte isTrue;
+}
+
+type ConstSymbol extends ConstObject {
+  kind = 12
+  constantTag (flags) = 7
+  PackedObject name;
+}
+
+type ConstTearOffInstantiation extends ConstObject {
+  kind = 12
+  constantTag (flags) = 8
+  PackedObject tearOff;
+  PackedObject typeArguments;
+}
+
+type ArgDesc extends ObjectContents {
+  kind = 13;
+  flags = (hasNamedArgs, hasTypeArgs)
+
+  UInt numArguments
+
+  if hasTypeArgs
+    UInt numTypeArguments
+
+  if hasNamedArgs
+    List<PackedObject> argNames;
+}
+
 */
 
 enum ObjectKind {
@@ -154,6 +242,22 @@
   kGenericType,
   kFunctionType,
   kName,
+  kTypeArguments,
+  kFinalizedGenericType,
+  kConstObject,
+  kArgDesc,
+}
+
+enum ConstTag {
+  kInvalid,
+  kInstance,
+  kInt,
+  kDouble,
+  kList,
+  kTearOff,
+  kBool,
+  kSymbol,
+  kTearOffInstantiation,
 }
 
 String objectKindToString(ObjectKind kind) =>
@@ -172,7 +276,8 @@
   static const int flagBit0 = 1 << 5;
   static const int flagBit1 = 1 << 6;
   static const int flagBit2 = 1 << 7;
-  static const int flagsMask = flagBit0 | flagBit1 | flagBit2;
+  static const int flagBit3 = 1 << 8;
+  static const int flagsMask = flagBit0 | flagBit1 | flagBit2 | flagBit3;
 
   static int _makeReference(int index) => (index << indexShift) | referenceBit;
 
@@ -231,6 +336,14 @@
         return new _FunctionTypeHandle._empty();
       case ObjectKind.kName:
         return new _NameHandle._empty();
+      case ObjectKind.kTypeArguments:
+        return new _TypeArgumentsHandle._empty();
+      case ObjectKind.kFinalizedGenericType:
+        return new _FinalizedGenericTypeHandle._empty();
+      case ObjectKind.kConstObject:
+        return new _ConstObjectHandle._empty();
+      case ObjectKind.kArgDesc:
+        return new _ArgDescHandle._empty();
     }
     throw 'Unexpected object kind $kind';
   }
@@ -354,7 +467,7 @@
 
   @override
   String toString() =>
-      name.name == topLevelClassName ? '$library' : '$library::$name';
+      name.name == topLevelClassName ? '$library' : '$library::${name.name}';
 }
 
 class _MemberHandle extends ObjectHandle {
@@ -416,7 +529,7 @@
 
   @override
   String toString() =>
-      '$parent::$name' +
+      '$parent::${name.name}' +
       (flags & flagIsField != 0 ? ' (field)' : '') +
       (flags & flagIsConstructor != 0 ? ' (constructor)' : '');
 }
@@ -638,7 +751,7 @@
       this.type == other.type;
 
   @override
-  String toString() => '$type $name';
+  String toString() => '$type ${name.name}';
 }
 
 class _FunctionTypeHandle extends _TypeHandle {
@@ -845,7 +958,408 @@
       this.library == other.library;
 
   @override
-  String toString() => name.isEmpty ? "''" : name;
+  String toString() => "'$name'";
+}
+
+class _TypeArgumentsHandle extends ObjectHandle {
+  List<_TypeHandle> args;
+
+  _TypeArgumentsHandle._empty();
+
+  _TypeArgumentsHandle(this.args);
+
+  @override
+  ObjectKind get kind => ObjectKind.kTypeArguments;
+
+  @override
+  void writeContents(BufferedWriter writer) {
+    writer.writePackedList(args);
+  }
+
+  @override
+  void readContents(BufferedReader reader) {
+    args = reader.readPackedList<_TypeHandle>();
+  }
+
+  @override
+  void accountUsesForObjectCopies(int numCopies) {
+    args.forEach((t) {
+      t._useCount += numCopies;
+    });
+  }
+
+  @override
+  int get hashCode => listHashCode(args);
+
+  @override
+  bool operator ==(other) =>
+      other is _TypeArgumentsHandle && listEquals(this.args, other.args);
+
+  @override
+  String toString() => '< ${args.join(', ')} >';
+}
+
+class _FinalizedGenericTypeHandle extends _TypeHandle {
+  _ClassHandle class_;
+  _TypeArgumentsHandle typeArgs;
+
+  _FinalizedGenericTypeHandle._empty();
+
+  _FinalizedGenericTypeHandle(this.class_, this.typeArgs);
+
+  @override
+  ObjectKind get kind => ObjectKind.kFinalizedGenericType;
+
+  @override
+  void writeContents(BufferedWriter writer) {
+    writer.writePackedObject(class_);
+    writer.writePackedObject(typeArgs);
+  }
+
+  @override
+  void readContents(BufferedReader reader) {
+    class_ = reader.readPackedObject();
+    typeArgs = reader.readPackedObject();
+  }
+
+  @override
+  void accountUsesForObjectCopies(int numCopies) {
+    class_._useCount += numCopies;
+    if (typeArgs != null) {
+      typeArgs._useCount += numCopies;
+    }
+  }
+
+  @override
+  int get hashCode => _combineHashes(class_.hashCode, typeArgs.hashCode);
+
+  @override
+  bool operator ==(other) =>
+      other is _FinalizedGenericTypeHandle &&
+      this.class_ == other.class_ &&
+      this.typeArgs == other.typeArgs;
+
+  @override
+  String toString() => '$class_ $typeArgs';
+}
+
+class _ConstObjectHandle extends ObjectHandle {
+  ConstTag tag;
+  dynamic value;
+  ObjectHandle type;
+
+  _ConstObjectHandle._empty();
+
+  _ConstObjectHandle(this.tag, this.value, [this.type]);
+
+  @override
+  ObjectKind get kind => ObjectKind.kConstObject;
+
+  @override
+  int get flags => tag.index * ObjectHandle.flagBit0;
+
+  @override
+  set flags(int value) {
+    tag = ConstTag.values[value ~/ ObjectHandle.flagBit0];
+    assert(tag != ConstTag.kInvalid);
+  }
+
+  bool get isCacheable => (tag != ConstTag.kInt) && (tag != ConstTag.kBool);
+
+  @override
+  void writeContents(BufferedWriter writer) {
+    switch (tag) {
+      case ConstTag.kInt:
+        writer.writeSLEB128(value as int);
+        break;
+      case ConstTag.kDouble:
+        writer.writeSLEB128(doubleToIntBits(value as double));
+        break;
+      case ConstTag.kBool:
+        writer.writeByte((value as bool) ? 1 : 0);
+        break;
+      case ConstTag.kInstance:
+        {
+          final fieldValues = value as Map<ObjectHandle, ObjectHandle>;
+          writer.writePackedObject(type);
+          writer.writePackedUInt30(fieldValues.length);
+          fieldValues.forEach((ObjectHandle field, ObjectHandle value) {
+            writer.writePackedObject(field);
+            writer.writePackedObject(value);
+          });
+        }
+        break;
+      case ConstTag.kList:
+        {
+          final elems = value as List<ObjectHandle>;
+          writer.writePackedObject(type);
+          writer.writePackedList(elems);
+        }
+        break;
+      case ConstTag.kTearOff:
+        {
+          final target = value as ObjectHandle;
+          writer.writePackedObject(target);
+        }
+        break;
+      case ConstTag.kSymbol:
+        {
+          final name = value as ObjectHandle;
+          writer.writePackedObject(name);
+        }
+        break;
+      case ConstTag.kTearOffInstantiation:
+        {
+          final tearOff = value as ObjectHandle;
+          writer.writePackedObject(tearOff);
+          writer.writePackedObject(type as _TypeArgumentsHandle);
+        }
+        break;
+      default:
+        throw 'Unexpected constant tag: $tag';
+    }
+  }
+
+  @override
+  void readContents(BufferedReader reader) {
+    switch (tag) {
+      case ConstTag.kInt:
+        value = reader.readSLEB128();
+        break;
+      case ConstTag.kDouble:
+        value = intBitsToDouble(reader.readSLEB128());
+        break;
+      case ConstTag.kBool:
+        value = reader.readByte() != 0;
+        break;
+      case ConstTag.kInstance:
+        type = reader.readPackedObject();
+        value = Map<ObjectHandle, ObjectHandle>.fromEntries(
+            new List<MapEntry<ObjectHandle, ObjectHandle>>.generate(
+                reader.readPackedUInt30(),
+                (_) => new MapEntry<ObjectHandle, ObjectHandle>(
+                    reader.readPackedObject(), reader.readPackedObject())));
+        break;
+      case ConstTag.kList:
+        type = reader.readPackedObject();
+        value = reader.readPackedList<ObjectHandle>();
+        break;
+      case ConstTag.kTearOff:
+        value = reader.readPackedObject();
+        break;
+      case ConstTag.kSymbol:
+        value = reader.readPackedObject();
+        break;
+      case ConstTag.kTearOffInstantiation:
+        value = reader.readPackedObject();
+        type = reader.readPackedObject();
+        break;
+      default:
+        throw 'Unexpected constant tag: $tag';
+    }
+  }
+
+  @override
+  void accountUsesForObjectCopies(int numCopies) {
+    switch (tag) {
+      case ConstTag.kInt:
+      case ConstTag.kDouble:
+      case ConstTag.kBool:
+        break;
+      case ConstTag.kInstance:
+        {
+          type._useCount += numCopies;
+          final fieldValues = value as Map<ObjectHandle, ObjectHandle>;
+          fieldValues.forEach((ObjectHandle field, ObjectHandle value) {
+            field._useCount += numCopies;
+            value?._useCount += numCopies;
+          });
+        }
+        break;
+      case ConstTag.kList:
+        {
+          final elems = value as List<ObjectHandle>;
+          for (var elem in elems) {
+            elem?._useCount += numCopies;
+          }
+          type._useCount += numCopies;
+        }
+        break;
+      case ConstTag.kTearOff:
+        {
+          final target = value as ObjectHandle;
+          target._useCount += numCopies;
+        }
+        break;
+      case ConstTag.kSymbol:
+        {
+          final name = value as ObjectHandle;
+          name._useCount += numCopies;
+        }
+        break;
+      case ConstTag.kTearOffInstantiation:
+        {
+          final tearOff = value as ObjectHandle;
+          tearOff._useCount += numCopies;
+          if (type != null) {
+            type._useCount += numCopies;
+          }
+        }
+        break;
+      default:
+        throw 'Unexpected constant tag: $tag';
+    }
+  }
+
+  @override
+  int get hashCode {
+    switch (tag) {
+      case ConstTag.kInt:
+      case ConstTag.kDouble:
+      case ConstTag.kBool:
+      case ConstTag.kTearOff:
+      case ConstTag.kSymbol:
+        return value.hashCode;
+      case ConstTag.kInstance:
+        {
+          final fieldValues = value as Map<ObjectHandle, ObjectHandle>;
+          return _combineHashes(type.hashCode, mapHashCode(fieldValues));
+        }
+        break;
+      case ConstTag.kList:
+        {
+          final elems = value as List<ObjectHandle>;
+          return _combineHashes(type.hashCode, listHashCode(elems));
+        }
+        break;
+      case ConstTag.kTearOffInstantiation:
+        return _combineHashes(value.hashCode, type.hashCode);
+      default:
+        throw 'Unexpected constant tag: $tag';
+    }
+  }
+
+  @override
+  bool operator ==(other) {
+    if (other is _ConstObjectHandle && this.tag == other.tag) {
+      switch (tag) {
+        case ConstTag.kInt:
+        case ConstTag.kBool:
+        case ConstTag.kTearOff:
+        case ConstTag.kSymbol:
+          return this.value == other.value;
+        case ConstTag.kDouble:
+          return this.value.compareTo(other.value) == 0;
+        case ConstTag.kInstance:
+          return this.type == other.type && mapEquals(this.value, other.value);
+        case ConstTag.kList:
+          return this.type == other.type && listEquals(this.value, other.value);
+        case ConstTag.kTearOffInstantiation:
+          return this.type == other.type && this.value == other.value;
+        default:
+          throw 'Unexpected constant tag: $tag';
+      }
+    }
+    return false;
+  }
+
+  @override
+  String toString() {
+    switch (tag) {
+      case ConstTag.kInt:
+      case ConstTag.kDouble:
+      case ConstTag.kBool:
+      case ConstTag.kSymbol:
+        return 'const $value';
+      case ConstTag.kInstance:
+        return 'const $type $value';
+      case ConstTag.kList:
+        return 'const <$type> $value';
+      case ConstTag.kTearOff:
+        return 'const tear-off $value';
+      case ConstTag.kTearOffInstantiation:
+        return 'const $type $value';
+      default:
+        throw 'Unexpected constant tag: $tag';
+    }
+  }
+}
+
+class _ArgDescHandle extends _TypeHandle {
+  static const int flagHasNamedArgs = ObjectHandle.flagBit0;
+  static const int flagHasTypeArgs = ObjectHandle.flagBit1;
+
+  int _flags = 0;
+  int numArguments;
+  int numTypeArguments;
+  List<_NameHandle> argNames;
+
+  _ArgDescHandle._empty();
+
+  _ArgDescHandle(this.numArguments, this.numTypeArguments, this.argNames) {
+    if (argNames.isNotEmpty) {
+      _flags |= flagHasNamedArgs;
+    }
+    if (numTypeArguments > 0) {
+      _flags |= flagHasTypeArgs;
+    }
+  }
+
+  @override
+  ObjectKind get kind => ObjectKind.kArgDesc;
+
+  @override
+  int get flags => _flags;
+
+  @override
+  set flags(int value) {
+    _flags = value;
+  }
+
+  @override
+  void writeContents(BufferedWriter writer) {
+    writer.writePackedUInt30(numArguments);
+    if ((_flags & flagHasTypeArgs) != 0) {
+      writer.writePackedUInt30(numTypeArguments);
+    }
+    if ((_flags & flagHasNamedArgs) != 0) {
+      writer.writePackedList(argNames);
+    }
+  }
+
+  @override
+  void readContents(BufferedReader reader) {
+    numArguments = reader.readPackedUInt30();
+    numTypeArguments =
+        ((_flags & flagHasTypeArgs) != 0) ? reader.readPackedUInt30() : 0;
+    argNames = ((_flags & flagHasNamedArgs) != 0)
+        ? reader.readPackedList<_NameHandle>()
+        : null;
+  }
+
+  @override
+  void accountUsesForObjectCopies(int numCopies) {
+    if (argNames != null) {
+      for (var name in argNames) {
+        name._useCount += numCopies;
+      }
+    }
+  }
+
+  @override
+  int get hashCode => _combineHashes(
+      numArguments, _combineHashes(numTypeArguments, listHashCode(argNames)));
+
+  @override
+  bool operator ==(other) =>
+      other is _ArgDescHandle &&
+      this.numArguments == other.numArguments &&
+      this.numTypeArguments == other.numTypeArguments &&
+      listEquals(this.argNames, other.argNames);
+
+  @override
+  String toString() =>
+      'ArgDesc num-args $numArguments, num-type-args $numTypeArguments, names $argNames';
 }
 
 class ObjectTable implements ObjectWriter, ObjectReader {
@@ -945,6 +1459,40 @@
         new _MemberHandle(classHandle, nameHandle, isField, isConstructor));
   }
 
+  ObjectHandle getTypeArgumentsHandle(List<DartType> typeArgs) {
+    if (typeArgs == null) {
+      return null;
+    }
+    final List<_TypeHandle> handles =
+        typeArgs.map((t) => getHandle(t) as _TypeHandle).toList();
+    return getOrAddObject(new _TypeArgumentsHandle(handles));
+  }
+
+  ObjectHandle getArgDescHandle(int numArguments,
+      [int numTypeArguments = 0, List<String> argNames = const <String>[]]) {
+    return getOrAddObject(new _ArgDescHandle(
+        numArguments,
+        numTypeArguments,
+        argNames
+            .map<_NameHandle>((name) => getNameHandle(null, name))
+            .toList()));
+  }
+
+  ObjectHandle getArgDescHandleByArguments(Arguments args,
+      {bool hasReceiver: false, bool isFactory: false}) {
+    return getArgDescHandle(
+        args.positional.length +
+            args.named.length +
+            (hasReceiver ? 1 : 0) +
+            // VM expects that type arguments vector passed to a factory
+            // constructor is counted in numArguments, and not counted in
+            // numTypeArgs.
+            // TODO(alexmarkov): Clean this up.
+            (isFactory ? 1 : 0),
+        isFactory ? 0 : args.types.length,
+        new List<String>.from(args.named.map((ne) => ne.name)));
+  }
+
   void declareClosure(
       FunctionNode function, Member enclosingMember, int closureIndex) {
     final handle = getOrAddObject(
@@ -1022,6 +1570,13 @@
   void write(BufferedWriter writer) {
     assert(writer.objectWriter == this);
     assert(_indexTable != null);
+    final start = writer.offset;
+    if (BytecodeSizeStatistics.objectTableStats.isEmpty) {
+      for (var kind in ObjectKind.values) {
+        BytecodeSizeStatistics.objectTableStats
+            .add(new NamedEntryStatistics(objectKindToString(kind)));
+      }
+    }
 
     BufferedWriter contentsWriter = new BufferedWriter.fromWriter(writer);
     List<int> offsets = new List<int>(_indexTable.length);
@@ -1029,6 +1584,11 @@
     for (int i = 0; i < _indexTable.length; ++i) {
       offsets[i] = contentsWriter.offset;
       _indexTable[i]._write(contentsWriter);
+
+      final entryStat =
+          BytecodeSizeStatistics.objectTableStats[_indexTable[i].kind.index];
+      entryStat.size += (contentsWriter.offset - offsets[i]);
+      ++entryStat.count;
     }
 
     writer.writePackedUInt30(_indexTable.length);
@@ -1045,6 +1605,9 @@
         obj.indexStrings(writer.stringWriter);
       }
     }
+
+    BytecodeSizeStatistics.objectTableSize += (writer.offset - start);
+    BytecodeSizeStatistics.objectTableEntriesCount += _indexTable.length;
   }
 
   ObjectTable.read(BufferedReader reader) {
@@ -1119,11 +1682,41 @@
     if (node.typeArguments.isEmpty) {
       return objectTable.getOrAddObject(new _SimpleTypeHandle(classHandle));
     }
-    final List<_TypeHandle> typeArgs = node.typeArguments
-        .map((t) => objectTable.getHandle(t) as _TypeHandle)
-        .toList();
-    return objectTable
-        .getOrAddObject(new _GenericTypeHandle(classHandle, typeArgs));
+    // In order to save loading time, generic types are written out in
+    // finalized form, if possible.
+    //
+    // Object table serialization/deserialization cannot handle cycles between
+    // objects. Non-finalized types are not recursive, but finalization of
+    // generic types includes flattening of type arguments and types could
+    // become recursive. Consider the following example:
+    //
+    //  class Base<T> {}
+    //  class Foo<T> extends Base<Foo<T>> {}
+    //
+    //  Foo<int> is not recursive, but finalized type is recursive:
+    //  Foo<int>* = Foo [ Base [ Foo<int>* ], int ]
+    //
+    // Recursive types are very rare, so object table includes such types in
+    // non-finalized form.
+    //
+    // VM handles recursive types by introducing placeholder
+    // TypeRef objects. Also, VM ensures that recursive types are contractive
+    // (e.g. their fully finalized representation should be finite).
+    //
+    if (!isRecursiveAfterFlattening(node)) {
+      List<DartType> instantiatorArgs =
+          getInstantiatorTypeArguments(node.classNode, node.typeArguments);
+      ObjectHandle typeArgsHandle =
+          objectTable.getTypeArgumentsHandle(instantiatorArgs);
+      return objectTable.getOrAddObject(
+          new _FinalizedGenericTypeHandle(classHandle, typeArgsHandle));
+    } else {
+      final List<_TypeHandle> typeArgs = node.typeArguments
+          .map((t) => objectTable.getHandle(t) as _TypeHandle)
+          .toList();
+      return objectTable
+          .getOrAddObject(new _GenericTypeHandle(classHandle, typeArgs));
+    }
   }
 
   @override
@@ -1208,6 +1801,68 @@
   @override
   ObjectHandle visitTypedefType(TypedefType node) =>
       objectTable.getHandle(node.unalias);
+
+  @override
+  ObjectHandle visitNullConstant(NullConstant node) => null;
+
+  @override
+  ObjectHandle visitBoolConstant(BoolConstant node) => objectTable
+      .getOrAddObject(new _ConstObjectHandle(ConstTag.kBool, node.value));
+
+  @override
+  ObjectHandle visitIntConstant(IntConstant node) => objectTable
+      .getOrAddObject(new _ConstObjectHandle(ConstTag.kInt, node.value));
+
+  @override
+  ObjectHandle visitDoubleConstant(DoubleConstant node) => objectTable
+      .getOrAddObject(new _ConstObjectHandle(ConstTag.kDouble, node.value));
+
+  @override
+  ObjectHandle visitStringConstant(StringConstant node) =>
+      objectTable.getNameHandle(null, node.value);
+
+  @override
+  ObjectHandle visitSymbolConstant(SymbolConstant node) =>
+      objectTable.getOrAddObject(new _ConstObjectHandle(
+          ConstTag.kSymbol,
+          objectTable.getNameHandle(
+              node.libraryReference?.asLibrary, node.name)));
+
+  @override
+  ObjectHandle visitListConstant(ListConstant node) =>
+      objectTable.getOrAddObject(new _ConstObjectHandle(
+          ConstTag.kList,
+          new List<ObjectHandle>.from(
+              node.entries.map((Constant c) => objectTable.getHandle(c))),
+          objectTable.getHandle(node.typeArgument)));
+
+  @override
+  ObjectHandle visitInstanceConstant(InstanceConstant node) =>
+      objectTable.getOrAddObject(new _ConstObjectHandle(
+          ConstTag.kInstance,
+          node.fieldValues.map<ObjectHandle, ObjectHandle>(
+              (Reference fieldRef, Constant value) => new MapEntry(
+                  objectTable.getHandle(fieldRef.asField),
+                  objectTable.getHandle(value))),
+          objectTable.getHandle(
+              new InterfaceType(node.classNode, node.typeArguments))));
+
+  @override
+  ObjectHandle visitTearOffConstant(TearOffConstant node) =>
+      objectTable.getOrAddObject(new _ConstObjectHandle(
+          ConstTag.kTearOff, objectTable.getHandle(node.procedure)));
+
+  @override
+  ObjectHandle visitTypeLiteralConstant(TypeLiteralConstant node) =>
+      objectTable.getHandle(node.type);
+
+  @override
+  ObjectHandle visitPartialInstantiationConstant(
+          PartialInstantiationConstant node) =>
+      objectTable.getOrAddObject(new _ConstObjectHandle(
+          ConstTag.kTearOffInstantiation,
+          objectTable.getHandle(node.tearOffConstant),
+          objectTable.getTypeArgumentsHandle(node.types)));
 }
 
 int _combineHashes(int hash1, int hash2) =>
diff --git a/pkg/vm/lib/constants_error_reporter.dart b/pkg/vm/lib/constants_error_reporter.dart
index cadbc0e..d2fdc95 100644
--- a/pkg/vm/lib/constants_error_reporter.dart
+++ b/pkg/vm/lib/constants_error_reporter.dart
@@ -12,7 +12,7 @@
 import 'package:front_end/src/api_unstable/vm.dart' as codes;
 
 import 'package:kernel/ast.dart'
-    show Constant, DartType, IntConstant, Procedure, TreeNode;
+    show Constant, DartType, IntConstant, Member, TreeNode;
 import 'package:kernel/transformations/constants.dart' as constants;
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
 
@@ -26,28 +26,29 @@
   ForwardConstantEvaluationErrors(this.typeEnvironment);
 
   @override
-  void freeTypeParameter(List<TreeNode> context, TreeNode node, DartType type) {
+  String freeTypeParameter(
+      List<TreeNode> context, TreeNode node, DartType type) {
     final message =
         codes.templateConstEvalFreeTypeParameter.withArguments(type);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
+  String duplicateKey(List<TreeNode> context, TreeNode node, Constant key) {
     final message = codes.templateConstEvalDuplicateKey.withArguments(key);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void invalidDartType(List<TreeNode> context, TreeNode node, Constant receiver,
-      DartType expectedType) {
+  String invalidDartType(List<TreeNode> context, TreeNode node,
+      Constant receiver, DartType expectedType) {
     final message = codes.templateConstEvalInvalidType.withArguments(
         receiver, expectedType, receiver.getType(typeEnvironment));
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void invalidBinaryOperandType(
+  String invalidBinaryOperandType(
       List<TreeNode> context,
       TreeNode node,
       Constant receiver,
@@ -56,90 +57,97 @@
       DartType actualType) {
     final message = codes.templateConstEvalInvalidBinaryOperandType
         .withArguments(op, receiver, expectedType, actualType);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void invalidMethodInvocation(
+  String invalidMethodInvocation(
       List<TreeNode> context, TreeNode node, Constant receiver, String op) {
     final message = codes.templateConstEvalInvalidMethodInvocation
         .withArguments(op, receiver);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void invalidStaticInvocation(
-      List<TreeNode> context, TreeNode node, Procedure target) {
+  String invalidStaticInvocation(
+      List<TreeNode> context, TreeNode node, Member target) {
     final message = codes.templateConstEvalInvalidStaticInvocation
         .withArguments(target.name.toString());
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void invalidStringInterpolationOperand(
+  String invalidStringInterpolationOperand(
       List<TreeNode> context, TreeNode node, Constant constant) {
     final message = codes.templateConstEvalInvalidStringInterpolationOperand
         .withArguments(constant);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void invalidSymbolName(
+  String invalidSymbolName(
       List<TreeNode> context, TreeNode node, Constant constant) {
     final message =
         codes.templateConstEvalInvalidSymbolName.withArguments(constant);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void zeroDivisor(
+  String zeroDivisor(
       List<TreeNode> context, TreeNode node, IntConstant receiver, String op) {
     final message = codes.templateConstEvalZeroDivisor
         .withArguments(op, '${receiver.value}');
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void negativeShift(List<TreeNode> context, TreeNode node,
+  String negativeShift(List<TreeNode> context, TreeNode node,
       IntConstant receiver, String op, IntConstant argument) {
     final message = codes.templateConstEvalNegativeShift
         .withArguments(op, '${receiver.value}', '${argument.value}');
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
+  String nonConstLiteral(List<TreeNode> context, TreeNode node, String klass) {
     final message =
         codes.templateConstEvalNonConstantLiteral.withArguments(klass);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void failedAssertion(List<TreeNode> context, TreeNode node, String string) {
+  String failedAssertion(List<TreeNode> context, TreeNode node, String string) {
     final message = string == null
         ? codes.messageConstEvalFailedAssertion
         : codes.templateConstEvalFailedAssertionWithMessage
             .withArguments(string);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void nonConstantVariableGet(
+  String nonConstantVariableGet(
       List<TreeNode> context, TreeNode node, String variableName) {
     final message = codes.templateConstEvalNonConstantVariableGet
         .withArguments(variableName);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
   @override
-  void deferredLibrary(
+  String deferredLibrary(
       List<TreeNode> context, TreeNode node, String importName) {
     final message =
         codes.templateConstEvalDeferredLibrary.withArguments(importName);
-    reportIt(context, message, node);
+    return reportIt(context, message, node);
   }
 
-  void reportIt(List<TreeNode> context, codes.Message message, TreeNode node) {
+  @override
+  String circularity(List<TreeNode> context, TreeNode node) {
+    final message = codes.messageConstEvalCircularity;
+    return reportIt(context, message, node);
+  }
+
+  String reportIt(
+      List<TreeNode> context, codes.Message message, TreeNode node) {
     final Uri uri = getFileUri(node);
     final int fileOffset = getFileOffset(node);
 
@@ -156,5 +164,6 @@
 
     compilerContext.options
         .report(locatedMessage, Severity.error, context: contextMessages);
+    return locatedMessage.message;
   }
 }
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 2d4b546..8b15aa5 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -14,6 +14,8 @@
 // that would replace api used below. This api was made private in
 // an effort to discourage further use.
 // ignore_for_file: implementation_imports
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, parseExperimentalFlags;
 import 'package:front_end/src/api_unstable/vm.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
@@ -105,6 +107,9 @@
           'used, and where dill filesize does not matter, and the gain is '
           'improved speed.',
       defaultsTo: false,
+      hide: true)
+  ..addMultiOption('enable-experiment',
+      help: 'Comma separated list of experimental features, eg set-literals.',
       hide: true);
 
 String usage = '''
@@ -274,6 +279,8 @@
       ..sdkSummary = sdkRoot.resolve(platformKernelDill)
       ..verbose = options['verbose']
       ..embedSourceText = options['embed-source-text']
+      ..experimentalFlags = parseExperimentalFlags(
+          options['enable-experiment'], (msg) => errors.add(msg))
       ..onDiagnostic = (DiagnosticMessage message) {
         bool printMessage;
         switch (message.severity) {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 2105181..088a723 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -27,6 +27,7 @@
         StandardFileSystem,
         getMessageUri,
         kernelForProgram,
+        parseExperimentalFlags,
         printDiagnosticMessage;
 
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
@@ -41,6 +42,8 @@
 import 'package:kernel/transformations/constants.dart' as constants;
 import 'package:kernel/vm/constants_native_effects.dart' as vm_constants;
 
+import 'bytecode/ast_remover.dart' show ASTRemover;
+import 'bytecode/bytecode_serialization.dart' show BytecodeSizeStatistics;
 import 'bytecode/gen_bytecode.dart' show generateBytecode;
 
 import 'constants_error_reporter.dart' show ForwardConstantEvaluationErrors;
@@ -104,8 +107,12 @@
       help: 'Emit source positions in bytecode', defaultsTo: false);
   args.addFlag('drop-ast',
       help: 'Drop AST for members with bytecode', defaultsTo: false);
+  args.addFlag('show-bytecode-size-stat',
+      help: 'Show bytecode size breakdown.', defaultsTo: false);
   args.addFlag('use-future-bytecode-format',
       help: 'Generate bytecode in the bleeding edge format', defaultsTo: false);
+  args.addMultiOption('enable-experiment',
+      help: 'Comma separated list of experimental features to enable.');
 }
 
 /// Create ArgParser and populate it with options consumed by [runCompiler].
@@ -147,6 +154,8 @@
   final bool enableAsserts = options['enable-asserts'];
   final bool enableConstantEvaluation = options['enable-constant-evaluation'];
   final bool splitOutputByPackages = options['split-output-by-packages'];
+  final bool showBytecodeSizeStat = options['show-bytecode-size-stat'];
+  final List<String> experimentalFlags = options['enable-experiment'];
   final Map<String, String> environmentDefines = {};
 
   if (!parseCommandLineDefines(options['define'], environmentDefines, usage)) {
@@ -186,6 +195,7 @@
     ..fileSystem = fileSystem
     ..linkedDependencies = linkedDependencies
     ..packagesFileUri = packagesUri
+    ..experimentalFlags = parseExperimentalFlags(experimentalFlags, print)
     ..onDiagnostic = (DiagnosticMessage m) {
       errorDetector(m);
     }
@@ -208,11 +218,19 @@
     return compileTimeErrorExitCode;
   }
 
+  if (showBytecodeSizeStat && !splitOutputByPackages) {
+    BytecodeSizeStatistics.reset();
+  }
+
   final IOSink sink = new File(outputFileName).openWrite();
   final BinaryPrinter printer = new BinaryPrinter(sink);
   printer.writeComponentFile(component);
   await sink.close();
 
+  if (showBytecodeSizeStat && !splitOutputByPackages) {
+    BytecodeSizeStatistics.dump();
+  }
+
   if (depfile != null) {
     await writeDepfile(fileSystem, component, outputFileName, depfile);
   }
@@ -227,6 +245,8 @@
       genBytecode: genBytecode,
       emitBytecodeSourcePositions: emitBytecodeSourcePositions,
       dropAST: dropAST,
+      showBytecodeSizeStat: showBytecodeSizeStat,
+      useFutureBytecodeFormat: useFutureBytecodeFormat,
     );
   }
 
@@ -288,11 +308,14 @@
   if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
     await runWithFrontEndCompilerContext(source, options, component, () {
       generateBytecode(component,
-          dropAST: dropAST,
           emitSourcePositions: emitBytecodeSourcePositions,
           useFutureBytecodeFormat: useFutureBytecodeFormat,
           environmentDefines: environmentDefines);
     });
+
+    if (dropAST) {
+      new ASTRemover(component).visitComponent(component);
+    }
   }
 
   // Restore error handler (in case 'options' are reused).
@@ -375,8 +398,7 @@
     CoreTypes coreTypes,
     Map<String, String> environmentDefines,
     bool enableAsserts) async {
-  final vmConstants =
-      new vm_constants.VmConstantsBackend(environmentDefines, coreTypes);
+  final vmConstants = new vm_constants.VmConstantsBackend(coreTypes);
 
   await runWithFrontEndCompilerContext(source, compilerOptions, component, () {
     final hierarchy = new ClassHierarchy(component);
@@ -384,7 +406,7 @@
 
     // TFA will remove constants fields which are unused (and respects the
     // vm/embedder entrypoints).
-    constants.transformComponent(component, vmConstants,
+    constants.transformComponent(component, vmConstants, environmentDefines,
         new ForwardConstantEvaluationErrors(typeEnvironment),
         keepFields: true,
         evaluateAnnotations: true,
@@ -578,6 +600,7 @@
   bool genBytecode: false,
   bool emitBytecodeSourcePositions: false,
   bool dropAST: false,
+  bool showBytecodeSizeStat: false,
   bool useFutureBytecodeFormat: false,
 }) async {
   // Package sharing: make the encoding not depend on the order in which parts
@@ -602,6 +625,10 @@
   final List<String> packages = packagesSet.toList();
   packages.add('main'); // Make sure main package is last.
 
+  if (showBytecodeSizeStat) {
+    BytecodeSizeStatistics.reset();
+  }
+
   await runWithFrontEndCompilerContext(source, compilerOptions, component,
       () async {
     for (String package in packages) {
@@ -613,27 +640,41 @@
         component.mainMethod = null;
       }
 
+      ASTRemover astRemover;
       if (genBytecode) {
         final List<Library> libraries = component.libraries
             .where((lib) => packageFor(lib) == package)
             .toList();
         generateBytecode(component,
             libraries: libraries,
-            dropAST: dropAST,
             emitSourcePositions: emitBytecodeSourcePositions,
             useFutureBytecodeFormat: useFutureBytecodeFormat,
             environmentDefines: environmentDefines);
+
+        if (dropAST) {
+          astRemover = new ASTRemover(component);
+          for (var library in libraries) {
+            astRemover.visitLibrary(library);
+          }
+        }
       }
 
       final BinaryPrinter printer = new LimitedBinaryPrinter(sink,
           (lib) => packageFor(lib) == package, false /* excludeUriToSource */);
       printer.writeComponentFile(component);
       component.mainMethod = main;
+      if (genBytecode && dropAST) {
+        astRemover.restoreAST();
+      }
 
       await sink.close();
     }
   });
 
+  if (showBytecodeSizeStat) {
+    BytecodeSizeStatistics.dump();
+  }
+
   final IOSink packagesList = new File('$outputFileName-packages').openWrite();
   for (String package in packages) {
     packagesList.writeln(package);
diff --git a/pkg/vm/lib/metadata/bytecode.dart b/pkg/vm/lib/metadata/bytecode.dart
index 7a86c70..cd9f65e 100644
--- a/pkg/vm/lib/metadata/bytecode.dart
+++ b/pkg/vm/lib/metadata/bytecode.dart
@@ -6,7 +6,7 @@
 
 import 'package:kernel/ast.dart';
 import '../bytecode/bytecode_serialization.dart'
-    show BufferedWriter, BufferedReader, StringTable;
+    show BufferedWriter, BufferedReader, BytecodeSizeStatistics, StringTable;
 import '../bytecode/constant_pool.dart' show ConstantPool;
 import '../bytecode/dbc.dart'
     show
@@ -121,6 +121,7 @@
 
   @override
   void write(BufferedWriter writer) {
+    final start = writer.offset;
     writer.writePackedUInt30(flags);
     if (hasClosures) {
       writer.writePackedUInt30(closures.length);
@@ -140,6 +141,7 @@
     if (hasClosures) {
       closures.forEach((c) => c.bytecode.write(writer));
     }
+    BytecodeSizeStatistics.membersSize += (writer.offset - start);
   }
 
   factory MemberBytecode.read(BufferedReader reader) {
@@ -368,6 +370,7 @@
 
   @override
   void write(BufferedWriter writer) {
+    final start = writer.offset;
     objectTable.allocateIndexTable();
 
     // Writing object table may add new strings to strings table,
@@ -384,6 +387,7 @@
 
     writer.writeBytes(stringsWriter.takeBytes());
     writer.writeBytes(objectsWriter.takeBytes());
+    BytecodeSizeStatistics.componentSize += (writer.offset - start);
   }
 
   BytecodeComponent.read(BufferedReader reader) {
@@ -461,6 +465,7 @@
   writer.writePackedUInt30(bytecodes.length);
   writer.align(bytecodeInstructionsAlignment);
   writer.writeBytes(bytecodes);
+  BytecodeSizeStatistics.instructionsSize += bytecodes.length;
 }
 
 List<int> _readBytecodeInstructions(BufferedReader reader) {
diff --git a/pkg/vm/lib/target/dart_runner.dart b/pkg/vm/lib/target/dart_runner.dart
index ba877f2..923898e 100644
--- a/pkg/vm/lib/target/dart_runner.dart
+++ b/pkg/vm/lib/target/dart_runner.dart
@@ -23,6 +23,7 @@
         'dart:collection',
         'dart:convert',
         'dart:developer',
+        'dart:ffi',
         'dart:_internal',
         'dart:isolate',
         'dart:math',
diff --git a/pkg/vm/lib/target/flutter.dart b/pkg/vm/lib/target/flutter.dart
index 3be0d7c..1faa9a2 100644
--- a/pkg/vm/lib/target/flutter.dart
+++ b/pkg/vm/lib/target/flutter.dart
@@ -23,6 +23,7 @@
         'dart:collection',
         'dart:convert',
         'dart:developer',
+        'dart:ffi',
         'dart:_internal',
         'dart:isolate',
         'dart:math',
diff --git a/pkg/vm/lib/target/flutter_runner.dart b/pkg/vm/lib/target/flutter_runner.dart
index acb04e8..3ffde3c 100644
--- a/pkg/vm/lib/target/flutter_runner.dart
+++ b/pkg/vm/lib/target/flutter_runner.dart
@@ -23,6 +23,7 @@
         'dart:collection',
         'dart:convert',
         'dart:developer',
+        'dart:ffi',
         'dart:_internal',
         'dart:isolate',
         'dart:math',
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index a43e07c..1682f35 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -11,12 +11,20 @@
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/transformations/mixin_full_resolution.dart'
     as transformMixins show transformLibraries;
+import 'package:kernel/transformations/constants.dart' show ConstantsBackend;
 import 'package:kernel/transformations/continuation.dart' as transformAsync
     show transformLibraries, transformProcedure;
+import 'package:kernel/vm/constants_native_effects.dart'
+    show VmConstantsBackend;
 
 import '../transformations/call_site_annotator.dart' as callSiteAnnotator;
 import '../transformations/list_factory_specializer.dart'
     as listFactorySpecializer;
+import '../transformations/ffi.dart' as transformFfi show ReplacedMembers;
+import '../transformations/ffi_definitions.dart' as transformFfiDefinitions
+    show transformLibraries;
+import '../transformations/ffi_use_sites.dart' as transformFfiUseSites
+    show transformLibraries;
 
 /// Specializes the kernel IR to the Dart VM.
 class VmTarget extends Target {
@@ -49,6 +57,7 @@
         'dart:collection',
         'dart:convert',
         'dart:developer',
+        'dart:ffi',
         'dart:_internal',
         'dart:isolate',
         'dart:math',
@@ -68,13 +77,24 @@
       ];
 
   @override
-  void performModularTransformationsOnLibraries(Component component,
-      CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+  void performModularTransformationsOnLibraries(
+      Component component,
+      CoreTypes coreTypes,
+      ClassHierarchy hierarchy,
+      List<Library> libraries,
+      DiagnosticReporter diagnosticReporter,
       {void logger(String msg)}) {
     transformMixins.transformLibraries(this, coreTypes, hierarchy, libraries,
         doSuperResolution: false /* resolution is done in Dart VM */);
     logger?.call("Transformed mixin applications");
 
+    transformFfi.ReplacedMembers replacedFields =
+        transformFfiDefinitions.transformLibraries(
+            coreTypes, hierarchy, libraries, diagnosticReporter);
+    transformFfiUseSites.transformLibraries(
+        coreTypes, hierarchy, libraries, diagnosticReporter, replacedFields);
+    logger?.call("Transformed ffi annotations");
+
     // TODO(kmillikin): Make this run on a per-method basis.
     transformAsync.transformLibraries(coreTypes, libraries);
     logger?.call("Transformed async methods");
@@ -345,4 +365,8 @@
     return _oneByteString ??=
         coreTypes.index.getClass('dart:core', '_OneByteString');
   }
+
+  @override
+  ConstantsBackend constantsBackend(CoreTypes coreTypes) =>
+      new VmConstantsBackend(coreTypes);
 }
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
new file mode 100644
index 0000000..f79ce37
--- /dev/null
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file contains logic which is shared between the ffi_definition and
+// ffi_use_site transformers.
+
+library vm.transformations.ffi;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart';
+import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+
+/// Represents the (instantiated) ffi.NativeType.
+enum NativeType {
+  kPointer,
+  kNativeFunction,
+  kInt8,
+  kInt16,
+  kInt32,
+  kInt64,
+  kUint8,
+  kUint16,
+  kUint32,
+  kUnit64,
+  kIntptr,
+  kFloat,
+  kDouble,
+  kVoid
+}
+
+const NativeType kNativeTypeIntStart = NativeType.kInt8;
+const NativeType kNativeTypeIntEnd = NativeType.kIntptr;
+
+/// The [NativeType] class names, indexed by [NativeType].
+const List<String> nativeTypeClassNames = [
+  'Pointer',
+  'NativeFunction',
+  'Int8',
+  'Int16',
+  'Int32',
+  'Int64',
+  'Uint8',
+  'Uint16',
+  'Uint32',
+  'Uint64',
+  'IntPtr',
+  'Float',
+  'Double',
+  'Void'
+];
+
+const int UNKNOWN = 0;
+const int WORD_SIZE = -1;
+
+/// The [NativeType] sizes in bytes, indexed by [NativeType].
+const List<int> nativeTypeSizes = [
+  WORD_SIZE, // Pointer
+  UNKNOWN, // NativeFunction
+  1, // Int8
+  2, // Int16
+  4, // Int32
+  8, // Int64
+  1, // Uint8
+  2, // Uint16
+  4, // Uint32
+  8, // Uint64
+  WORD_SIZE, // IntPtr
+  4, // Float
+  8, // Double
+  UNKNOWN, // Void
+];
+
+/// [FfiTransformer] contains logic which is shared between
+/// _FfiUseSiteTransformer and _FfiDefinitionTransformer.
+class FfiTransformer extends Transformer {
+  final TypeEnvironment env;
+  final ClassHierarchy hierarchy;
+  final DiagnosticReporter diagnosticReporter;
+
+  final Class intClass;
+  final Class doubleClass;
+  final Constructor pragmaConstructor;
+
+  final Library ffiLibrary;
+  final Class nativeFunctionClass;
+  final Class pointerClass;
+  final Procedure castMethod;
+  final Procedure loadMethod;
+  final Procedure storeMethod;
+  final Procedure offsetByMethod;
+  final Procedure asFunctionMethod;
+  final Procedure lookupFunctionMethod;
+  final Procedure fromFunctionMethod;
+  final Field structField;
+
+  /// Classes corresponding to [NativeType], indexed by [NativeType].
+  final List<Class> nativeTypesClasses;
+
+  FfiTransformer(this.hierarchy, CoreTypes coreTypes, this.diagnosticReporter)
+      : env = new TypeEnvironment(coreTypes, hierarchy),
+        intClass = coreTypes.intClass,
+        doubleClass = coreTypes.doubleClass,
+        ffiLibrary = coreTypes.ffiLibrary,
+        nativeFunctionClass = coreTypes.ffiNativeFunctionClass,
+        pointerClass = coreTypes.ffiPointerClass,
+        castMethod = coreTypes.ffiPointerCastProcedure,
+        loadMethod = coreTypes.ffiPointerLoadProcedure,
+        storeMethod = coreTypes.ffiPointerStoreProcedure,
+        offsetByMethod = coreTypes.ffiPointerOffsetByProcedure,
+        asFunctionMethod = coreTypes.ffiPointerAsFunctionProcedure,
+        lookupFunctionMethod =
+            coreTypes.ffiDynamicLibraryLookupFunctionProcedure,
+        fromFunctionMethod = coreTypes.ffiFromFunctionProcedure,
+        structField = coreTypes.ffiStructField,
+        pragmaConstructor = coreTypes.pragmaConstructor,
+        nativeTypesClasses =
+            nativeTypeClassNames.map(coreTypes.ffiNativeTypeClass).toList() {}
+
+  /// Computes the Dart type corresponding to a ffi.[NativeType], returns null
+  /// if it is not a valid NativeType.
+  ///
+  /// [Int8]                               -> [int]
+  /// [Int16]                              -> [int]
+  /// [Int32]                              -> [int]
+  /// [Int64]                              -> [int]
+  /// [Uint8]                              -> [int]
+  /// [Uint16]                             -> [int]
+  /// [Uint32]                             -> [int]
+  /// [Uint64]                             -> [int]
+  /// [IntPtr]                             -> [int]
+  /// [Double]                             -> [double]
+  /// [Float]                              -> [double]
+  /// [Pointer]<T>                         -> [Pointer]<T>
+  /// T extends [Pointer]                  -> T
+  /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
+  ///    where DartRepresentationOf(Tn) -> Sn
+  DartType convertNativeTypeToDartType(DartType nativeType) {
+    if (nativeType is! InterfaceType) {
+      return null;
+    }
+    Class nativeClass = (nativeType as InterfaceType).classNode;
+    if (env.isSubtypeOf(
+        InterfaceType(nativeClass), InterfaceType(pointerClass))) {
+      return nativeType;
+    }
+    NativeType nativeType_ = getType(nativeClass);
+    if (nativeType_ == null) {
+      return null;
+    }
+    if (kNativeTypeIntStart.index <= nativeType_.index &&
+        nativeType_.index <= kNativeTypeIntEnd.index) {
+      return InterfaceType(intClass);
+    }
+    if (nativeType_ == NativeType.kFloat || nativeType_ == NativeType.kDouble) {
+      return InterfaceType(doubleClass);
+    }
+    if (nativeType_ == NativeType.kNativeFunction) {
+      DartType fun = (nativeType as InterfaceType).typeArguments[0];
+      if (fun is FunctionType) {
+        if (fun.namedParameters.isNotEmpty) return null;
+        if (fun.positionalParameters.length != fun.requiredParameterCount)
+          return null;
+        if (fun.typeParameters.length != 0) return null;
+        DartType returnType = convertNativeTypeToDartType(fun.returnType);
+        if (returnType == null) return null;
+        List<DartType> argumentTypes = fun.positionalParameters
+            .map(this.convertNativeTypeToDartType)
+            .toList();
+        if (argumentTypes.contains(null)) return null;
+        return FunctionType(argumentTypes, returnType);
+      }
+    }
+    return null;
+  }
+
+  NativeType getType(Class c) {
+    int index = nativeTypesClasses.indexOf(c);
+    if (index == -1) {
+      return null;
+    }
+    return NativeType.values[index];
+  }
+}
+
+/// Contains replaced members, of which all the call sites need to be replaced.
+///
+/// [ReplacedMembers] is populated by _FfiDefinitionTransformer and consumed by
+/// _FfiUseSiteTransformer.
+class ReplacedMembers {
+  final Map<Field, Procedure> replacedGetters;
+  final Map<Field, Procedure> replacedSetters;
+  ReplacedMembers(this.replacedGetters, this.replacedSetters);
+}
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
new file mode 100644
index 0000000..e738406
--- /dev/null
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -0,0 +1,372 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.ffi_definitions;
+
+import 'dart:math' as math;
+
+import 'package:front_end/src/api_unstable/vm.dart'
+    show
+        templateFfiFieldAnnotation,
+        templateFfiStructAnnotation,
+        templateFfiTypeMismatch,
+        templateFfiFieldInitializer;
+
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+
+import 'ffi.dart'
+    show
+        ReplacedMembers,
+        NativeType,
+        FfiTransformer,
+        nativeTypeSizes,
+        WORD_SIZE;
+
+/// Checks and expands the dart:ffi @struct and field annotations.
+///
+/// Sample input:
+/// @ffi.struct
+/// class Coord extends ffi.Pointer<Void> {
+///   @ffi.Double()
+///   double x;
+///
+///   @ffi.Double()
+///   double y;
+///
+///   @ffi.Pointer()
+///   Coord next;
+///
+///   external static int sizeOf();
+/// }
+///
+/// Sample output:
+/// class Coordinate extends ffi.Pointer<ffi.Void> {
+///   ffi.Pointer<ffi.Double> get _xPtr => cast();
+///   set x(double v) => _xPtr.store(v);
+///   double get x => _xPtr.load();
+///
+///   ffi.Pointer<ffi.Double> get _yPtr =>
+///       offsetBy(ffi.sizeOf<ffi.Double>() * 1).cast();
+///   set y(double v) => _yPtr.store(v);
+///   double get y => _yPtr.load();
+///
+///   ffi.Pointer<Coordinate> get _nextPtr =>
+///       offsetBy(ffi.sizeOf<ffi.Double>() * 2).cast();
+///   set next(Coordinate v) => _nextPtr.store(v);
+///   Coordinate get next => _nextPtr.load();
+///
+///   static int sizeOf() => 24;
+/// }
+ReplacedMembers transformLibraries(
+    CoreTypes coreTypes,
+    ClassHierarchy hierarchy,
+    List<Library> libraries,
+    DiagnosticReporter diagnosticReporter) {
+  final transformer =
+      new _FfiDefinitionTransformer(hierarchy, coreTypes, diagnosticReporter);
+  libraries.forEach(transformer.visitLibrary);
+  return ReplacedMembers(
+      transformer.replacedGetters, transformer.replacedSetters);
+}
+
+/// Checks and expands the dart:ffi @struct and field annotations.
+class _FfiDefinitionTransformer extends FfiTransformer {
+  Map<Field, Procedure> replacedGetters = {};
+  Map<Field, Procedure> replacedSetters = {};
+
+  _FfiDefinitionTransformer(ClassHierarchy hierarchy, CoreTypes coreTypes,
+      DiagnosticReporter diagnosticReporter)
+      : super(hierarchy, coreTypes, diagnosticReporter) {}
+
+  @override
+  visitClass(Class node) {
+    if (node == pointerClass || !hierarchy.isSubtypeOf(node, pointerClass)) {
+      return node;
+    }
+
+    // Because subtypes of Pointer are only allocated by allocate<Pointer<..>>()
+    // and fromAddress<Pointer<..>>() which are not recognized as constructor
+    // calls, we need to prevent these classes from being tree shaken out.
+    _preventTreeShaking(node);
+
+    _checkFieldAnnotations(node);
+    _checkConstructors(node);
+
+    bool isStruct = _checkStructAnnotation(node);
+    if (isStruct) {
+      int size = _replaceFields(node);
+      _replaceSizeOfMethod(node, size);
+    }
+
+    return node;
+  }
+
+  bool _checkStructAnnotation(Class node) {
+    bool isStruct = _hasAnnotation(node);
+    if (!isStruct && node.fields.isNotEmpty) {
+      diagnosticReporter.report(
+          templateFfiStructAnnotation.withArguments(node.name),
+          node.fileOffset,
+          1,
+          node.fileUri);
+    }
+    return isStruct;
+  }
+
+  void _checkFieldAnnotations(Class node) {
+    for (Field f in node.fields) {
+      if (f.initializer is! NullLiteral) {
+        diagnosticReporter.report(
+            templateFfiFieldInitializer.withArguments(f.name.name),
+            f.fileOffset,
+            f.name.name.length,
+            f.fileUri);
+      }
+      List<NativeType> annos = _getAnnotations(f).toList();
+      if (annos.length != 1) {
+        diagnosticReporter.report(
+            templateFfiFieldAnnotation.withArguments(f.name.name),
+            f.fileOffset,
+            f.name.name.length,
+            f.fileUri);
+      } else {
+        DartType dartType = f.type;
+        DartType nativeType =
+            InterfaceType(nativeTypesClasses[annos.first.index]);
+        DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
+        if (!env.isSubtypeOf(dartType, shouldBeDartType)) {
+          diagnosticReporter.report(
+              templateFfiTypeMismatch.withArguments(
+                  dartType, shouldBeDartType, nativeType),
+              f.fileOffset,
+              1,
+              f.location.file);
+        }
+      }
+    }
+  }
+
+  void _checkConstructors(Class node) {
+    List<Initializer> toRemove = [];
+    for (Constructor c in node.constructors) {
+      for (Initializer i in c.initializers) {
+        if (i is FieldInitializer) {
+          toRemove.add(i);
+          diagnosticReporter.report(
+              templateFfiFieldInitializer.withArguments(i.field.name.name),
+              i.fileOffset,
+              1,
+              i.location.file);
+        }
+      }
+    }
+    // Remove initializers referring to fields to prevent cascading errors.
+    for (Initializer i in toRemove) {
+      i.remove();
+    }
+  }
+
+  /// Computes the field offsets in the struct and replaces the fields with
+  /// getters and setters using these offsets.
+  ///
+  /// Returns the total size of the struct.
+  int _replaceFields(Class node) {
+    List<Field> fields = [];
+    List<NativeType> types = [];
+
+    for (Field f in node.fields) {
+      List<NativeType> annos = _getAnnotations(f).toList();
+      if (annos.length == 1) {
+        NativeType t = annos.first;
+        fields.add(f);
+        types.add(t);
+      }
+    }
+
+    List<int> offsets = _calculateOffsets(types);
+    int size = _calculateSize(offsets, types);
+
+    for (int i = 0; i < fields.length; i++) {
+      List<Procedure> methods =
+          _generateMethodsForField(fields[i], types[i], offsets[i]);
+      for (Procedure p in methods) {
+        node.addMember(p);
+      }
+    }
+
+    for (Field f in fields) {
+      f.remove();
+    }
+
+    return size;
+  }
+
+  /// Sample output:
+  /// ffi.Pointer<ffi.Double> get _xPtr => cast();
+  /// double get x => _xPtr.load();
+  /// set x(double v) => _xPtr.store(v);
+  List<Procedure> _generateMethodsForField(
+      Field field, NativeType type, int offset) {
+    DartType nativeType = type == NativeType.kPointer
+        ? field.type
+        : InterfaceType(nativeTypesClasses[type.index]);
+    DartType pointerType = InterfaceType(pointerClass, [nativeType]);
+    Name pointerName = Name('#_ptr_${field.name.name}');
+
+    // Sample output for primitives:
+    // ffi.Pointer<ffi.Double> get _xPtr => cast<ffi.Pointer<ffi.Double>>();
+    // Sample output for structs:
+    // ffi.Pointer<Coordinate> get _xPtr => offsetBy(16).cast<...>();
+    Expression offsetExpression = ThisExpression();
+    if (offset != 0) {
+      offsetExpression = MethodInvocation(offsetExpression, offsetByMethod.name,
+          Arguments([IntLiteral(offset)]), offsetByMethod);
+    }
+    Procedure pointerGetter = Procedure(
+        pointerName,
+        ProcedureKind.Getter,
+        FunctionNode(
+            ReturnStatement(MethodInvocation(offsetExpression, castMethod.name,
+                Arguments([], types: [pointerType]), castMethod)),
+            returnType: pointerType));
+
+    // Sample output:
+    // double get x => _xPtr.load<double>();
+    Procedure getter = Procedure(
+        field.name,
+        ProcedureKind.Getter,
+        FunctionNode(
+            ReturnStatement(MethodInvocation(
+                PropertyGet(ThisExpression(), pointerName, pointerGetter),
+                loadMethod.name,
+                Arguments([], types: [field.type]),
+                loadMethod)),
+            returnType: field.type));
+
+    // Sample output:
+    // set x(double v) => _xPtr.store(v);
+    VariableDeclaration argument = VariableDeclaration('#v', type: field.type);
+    Procedure setter = Procedure(
+        field.name,
+        ProcedureKind.Setter,
+        FunctionNode(
+            ReturnStatement(MethodInvocation(
+                PropertyGet(ThisExpression(), pointerName, pointerGetter),
+                storeMethod.name,
+                Arguments([VariableGet(argument)]),
+                storeMethod)),
+            returnType: VoidType(),
+            positionalParameters: [argument]));
+
+    replacedGetters[field] = getter;
+    replacedSetters[field] = setter;
+
+    return [pointerGetter, getter, setter];
+  }
+
+  /// Sample input:
+  /// external static int sizeOf();
+  ///
+  /// Sample output:
+  /// static int sizeOf() => 24;
+  void _replaceSizeOfMethod(Class struct, int size) {
+    Procedure sizeOf = _findProcedure(struct, 'sizeOf');
+    if (sizeOf == null || !sizeOf.isExternal || !sizeOf.isStatic) {
+      return;
+    }
+
+    // replace in place to avoid going over use sites
+    sizeOf.function = FunctionNode(ReturnStatement(IntLiteral(size)),
+        returnType: InterfaceType(intClass));
+    sizeOf.isExternal = false;
+  }
+
+  // TODO(dacoharkes): move to VM, take into account architecture
+  // https://github.com/dart-lang/sdk/issues/35768
+  int _sizeInBytes(NativeType t) {
+    int size = nativeTypeSizes[t.index];
+    if (size == WORD_SIZE) {
+      size = 8;
+    }
+    return size;
+  }
+
+  int _align(int offset, int size) {
+    int remainder = offset % size;
+    if (remainder != 0) {
+      offset -= remainder;
+      offset += size;
+    }
+    return offset;
+  }
+
+  // TODO(dacoharkes): move to VM, take into account architecture
+  // https://github.com/dart-lang/sdk/issues/35768
+  List<int> _calculateOffsets(List<NativeType> types) {
+    int offset = 0;
+    List<int> offsets = [];
+    for (NativeType t in types) {
+      int size = _sizeInBytes(t);
+      offset = _align(offset, size);
+      offsets.add(offset);
+      offset += size;
+    }
+    return offsets;
+  }
+
+  // TODO(dacoharkes): move to VM, take into account architecture
+  // https://github.com/dart-lang/sdk/issues/35768
+  int _calculateSize(List<int> offsets, List<NativeType> types) {
+    if (offsets.isEmpty) {
+      return 0;
+    }
+    int largestElement = types.map((e) => _sizeInBytes(e)).reduce(math.max);
+    int highestOffsetIndex = types.length - 1;
+    int highestOffset = offsets[highestOffsetIndex];
+    int highestOffsetSize = _sizeInBytes(types[highestOffsetIndex]);
+    return _align(highestOffset + highestOffsetSize, largestElement);
+  }
+
+  bool _hasAnnotation(Class node) {
+    for (Expression e in node.annotations) {
+      if (e is StaticGet) {
+        if (e.target == structField) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  void _preventTreeShaking(Class node) {
+    node.addAnnotation(ConstructorInvocation(
+        pragmaConstructor, Arguments([StringLiteral("vm:entry-point")])));
+  }
+
+  NativeType _getFieldType(Class c) {
+    NativeType fieldType = getType(c);
+
+    if (fieldType == NativeType.kVoid) {
+      // Fields cannot have Void types.
+      return null;
+    }
+    return fieldType;
+  }
+
+  Iterable<NativeType> _getAnnotations(Field node) {
+    return node.annotations
+        .whereType<ConstructorInvocation>()
+        .map((expr) => expr.target.parent)
+        .map((klass) => _getFieldType(klass))
+        .where((type) => type != null);
+  }
+}
+
+/// Finds procedure with name, otherwise returns null.
+Procedure _findProcedure(Class c, String name) =>
+    c.procedures.firstWhere((p) => p.name.name == name, orElse: () => null);
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
new file mode 100644
index 0000000..8e9227c
--- /dev/null
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -0,0 +1,270 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 kernel.transformations.ffi_use_sites;
+
+import 'package:front_end/src/api_unstable/vm.dart'
+    show
+        templateFfiTypeInvalid,
+        templateFfiTypeMismatch,
+        templateFfiTypeUnsized,
+        templateFfiNotStatic;
+
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+
+import 'ffi.dart'
+    show
+        ReplacedMembers,
+        NativeType,
+        kNativeTypeIntStart,
+        kNativeTypeIntEnd,
+        FfiTransformer;
+
+/// Checks and replaces calls to dart:ffi struct fields and methods.
+void transformLibraries(
+    CoreTypes coreTypes,
+    ClassHierarchy hierarchy,
+    List<Library> libraries,
+    DiagnosticReporter diagnosticReporter,
+    ReplacedMembers replacedFields) {
+  final transformer = new _FfiUseSiteTransformer(
+      hierarchy,
+      coreTypes,
+      diagnosticReporter,
+      replacedFields.replacedGetters,
+      replacedFields.replacedSetters);
+  libraries.forEach(transformer.visitLibrary);
+}
+
+/// Checks and replaces calls to dart:ffi struct fields and methods.
+class _FfiUseSiteTransformer extends FfiTransformer {
+  final Map<Field, Procedure> replacedGetters;
+  final Map<Field, Procedure> replacedSetters;
+
+  _FfiUseSiteTransformer(
+      ClassHierarchy hierarchy,
+      CoreTypes coreTypes,
+      DiagnosticReporter diagnosticReporter,
+      this.replacedGetters,
+      this.replacedSetters)
+      : super(hierarchy, coreTypes, diagnosticReporter) {}
+
+  @override
+  visitClass(Class node) {
+    env.thisType = InterfaceType(node);
+    try {
+      return super.visitClass(node);
+    } finally {
+      env.thisType = null;
+    }
+  }
+
+  @override
+  visitPropertyGet(PropertyGet node) {
+    super.visitPropertyGet(node);
+
+    Procedure replacedWith = replacedGetters[node.interfaceTarget];
+    if (replacedWith != null) {
+      node = PropertyGet(node.receiver, replacedWith.name, replacedWith);
+    }
+
+    return node;
+  }
+
+  @override
+  visitPropertySet(PropertySet node) {
+    super.visitPropertySet(node);
+
+    Procedure replacedWith = replacedSetters[node.interfaceTarget];
+    if (replacedWith != null) {
+      node = PropertySet(
+          node.receiver, replacedWith.name, node.value, replacedWith);
+    }
+
+    return node;
+  }
+
+  @override
+  visitStaticInvocation(StaticInvocation node) {
+    super.visitStaticInvocation(node);
+
+    Member target = node.target;
+    try {
+      if (target == fromFunctionMethod) {
+        DartType nativeType =
+            InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
+        Expression func = node.arguments.positional[0];
+        DartType dartType = func.getStaticType(env);
+
+        _ensureIsStatic(func);
+        _ensureNativeTypeValid(nativeType, node);
+        _ensureNativeTypeToDartType(nativeType, dartType, node);
+      }
+    } catch (_FfiStaticTypeError) {}
+
+    return node;
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    super.visitMethodInvocation(node);
+
+    Member target = node.interfaceTarget;
+    try {
+      if (target == lookupFunctionMethod) {
+        DartType nativeType =
+            InterfaceType(nativeFunctionClass, [node.arguments.types[0]]);
+        DartType dartType = node.arguments.types[1];
+
+        _ensureNativeTypeValid(nativeType, node);
+        _ensureNativeTypeToDartType(nativeType, dartType, node);
+      } else if (target == asFunctionMethod) {
+        if (node.enclosingLibrary == ffiLibrary) {
+          // Library code of dart:ffi uses asFunction to implement
+          // lookupFunction. Since we treat lookupFunction as well, this call
+          // can be generic and still support AOT.
+          return node;
+        }
+
+        DartType dartType = node.arguments.types[0];
+        DartType pointerType = node.receiver.getStaticType(env);
+        DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+
+        _ensureNativeTypeValid(pointerType, node);
+        _ensureNativeTypeValid(nativeType, node);
+        _ensureNativeTypeToDartType(nativeType, dartType, node);
+      } else if (target == loadMethod) {
+        // TODO(dacoharkes): should load and store permitted to be generic?
+        // https://github.com/dart-lang/sdk/issues/35902
+        DartType dartType = node.arguments.types[0];
+        DartType pointerType = node.receiver.getStaticType(env);
+        DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+
+        _ensureNativeTypeValid(pointerType, node);
+        _ensureNativeTypeValid(nativeType, node);
+        _ensureNativeTypeSized(nativeType, node, target.name);
+        _ensureNativeTypeToDartType(nativeType, dartType, node);
+      } else if (target == storeMethod) {
+        // TODO(dacoharkes): should load and store permitted to be generic?
+        // https://github.com/dart-lang/sdk/issues/35902
+        DartType dartType = node.arguments.positional[0].getStaticType(env);
+        DartType pointerType = node.receiver.getStaticType(env);
+        DartType nativeType = _pointerTypeGetTypeArg(pointerType);
+
+        _ensureNativeTypeValid(pointerType, node);
+        _ensureNativeTypeValid(nativeType, node);
+        _ensureNativeTypeSized(nativeType, node, target.name);
+        _ensureNativeTypeToDartType(nativeType, dartType, node);
+      }
+    } catch (_FfiStaticTypeError) {}
+
+    return node;
+  }
+
+  DartType _pointerTypeGetTypeArg(DartType pointerType) {
+    if (pointerType is InterfaceType) {
+      InterfaceType superType =
+          hierarchy.getTypeAsInstanceOf(pointerType, pointerClass);
+      return superType?.typeArguments[0];
+    }
+    return null;
+  }
+
+  void _ensureNativeTypeToDartType(
+      DartType nativeType, DartType dartType, Expression node) {
+    DartType shouldBeDartType = convertNativeTypeToDartType(nativeType);
+    if (dartType != shouldBeDartType) {
+      diagnosticReporter.report(
+          templateFfiTypeMismatch.withArguments(
+              dartType, shouldBeDartType, nativeType),
+          node.fileOffset,
+          1,
+          node.location.file);
+      throw _FfiStaticTypeError();
+    }
+  }
+
+  void _ensureNativeTypeValid(DartType nativeType, Expression node) {
+    if (!_nativeTypeValid(nativeType)) {
+      diagnosticReporter.report(
+          templateFfiTypeInvalid.withArguments(nativeType),
+          node.fileOffset,
+          1,
+          node.location.file);
+      throw _FfiStaticTypeError();
+    }
+  }
+
+  /// The Dart type system does not enforce that NativeFunction return and
+  /// parameter types are only NativeTypes, so we need to check this.
+  bool _nativeTypeValid(DartType nativeType) {
+    return convertNativeTypeToDartType(nativeType) != null;
+  }
+
+  void _ensureNativeTypeSized(
+      DartType nativeType, Expression node, Name targetName) {
+    if (!_nativeTypeSized(nativeType)) {
+      diagnosticReporter.report(
+          templateFfiTypeUnsized.withArguments(targetName.name, nativeType),
+          node.fileOffset,
+          1,
+          node.location.file);
+      throw _FfiStaticTypeError();
+    }
+  }
+
+  /// Unsized NativeTypes do not support [sizeOf] because their size is unknown.
+  /// Consequently, [allocate], [Pointer.load], [Pointer.store], and
+  /// [Pointer.elementAt] are not available.
+  bool _nativeTypeSized(DartType nativeType) {
+    if (!(nativeType is InterfaceType)) {
+      return false;
+    }
+    Class nativeClass = (nativeType as InterfaceType).classNode;
+    if (env.isSubtypeOf(
+        InterfaceType(nativeClass), InterfaceType(pointerClass))) {
+      return true;
+    }
+    NativeType nativeType_ = getType(nativeClass);
+    if (nativeType_ == null) {
+      return false;
+    }
+    if (kNativeTypeIntStart.index <= nativeType_.index &&
+        nativeType_.index <= kNativeTypeIntEnd.index) {
+      return true;
+    }
+    if (nativeType_ == NativeType.kFloat || nativeType_ == NativeType.kDouble) {
+      return true;
+    }
+    if (nativeType_ == NativeType.kPointer) {
+      return true;
+    }
+    return false;
+  }
+
+  void _ensureIsStatic(Expression node) {
+    if (!_isStatic(node)) {
+      diagnosticReporter.report(
+          templateFfiNotStatic.withArguments(fromFunctionMethod.name.name),
+          node.fileOffset,
+          1,
+          node.location.file);
+      throw _FfiStaticTypeError();
+    }
+  }
+
+  bool _isStatic(Expression node) {
+    if (node is! StaticGet) return false;
+
+    return (node as StaticGet).target is Procedure;
+  }
+}
+
+/// Used internally for abnormal control flow to prevent cascading error
+/// messages.
+class _FfiStaticTypeError implements Exception {}
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index e9d777b..f4e50e7 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -1629,8 +1629,8 @@
 
   @override
   Type visitInstanceConstant(InstanceConstant constant) {
-    final resultType =
-        summaryCollector._entryPointsListener.addAllocatedClass(constant.klass);
+    final resultType = summaryCollector._entryPointsListener
+        .addAllocatedClass(constant.classNode);
     constant.fieldValues.forEach((Reference fieldReference, Constant value) {
       summaryCollector._entryPointsListener
           .addDirectFieldAccess(fieldReference.asField, typeFor(value));
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 4e3103d..c0b92a0 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1050,7 +1050,7 @@
   @override
   visitInstanceConstant(InstanceConstant constant) {
     instanceConstants.add(constant);
-    shaker.addClassUsedInType(constant.klass);
+    shaker.addClassUsedInType(constant.classNode);
     visitList(constant.typeArguments, typeVisitor);
     constant.fieldValues.forEach((Reference fieldRef, Constant value) {
       shaker.addUsedMember(fieldRef.asField);
diff --git a/pkg/vm/test/bytecode/generics_test.dart b/pkg/vm/test/bytecode/generics_test.dart
new file mode 100644
index 0000000..6b0a75f
--- /dev/null
+++ b/pkg/vm/test/bytecode/generics_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:test/test.dart';
+import 'package:vm/bytecode/generics.dart';
+
+main() {
+  Library lib;
+  Supertype objectSuper;
+  DartType intType;
+  Class base;
+
+  Class addClass(String name, List<TypeParameter> typeParameters) {
+    Class cls = new Class(
+        name: name, supertype: objectSuper, typeParameters: typeParameters);
+    lib.addClass(cls);
+    return cls;
+  }
+
+  setUp(() {
+    // Start with mock SDK libraries.
+    Component component = createMockSdkComponent();
+    CoreTypes coreTypes = new CoreTypes(component);
+    objectSuper = coreTypes.objectClass.asThisSupertype;
+    intType = new InterfaceType(coreTypes.intClass);
+
+    // Add the test library.
+    lib = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
+    lib.parent = component;
+    component.libraries.add(lib);
+
+    // class Base<T>
+    base = addClass('Base', [new TypeParameter('T')]);
+  });
+
+  tearDown(() {});
+
+  test('isRecursiveAfterFlattening-00', () async {
+    // class Derived<T> extends Base<Derived<T>>
+    TypeParameter t = new TypeParameter('T');
+    Class derived = addClass('Derived', [t]);
+    DartType derivedOfT =
+        new InterfaceType(derived, [new TypeParameterType(t)]);
+    DartType derivedOfInt = new InterfaceType(derived, [intType]);
+    derived.supertype = new Supertype(base, [derivedOfT]);
+
+    expect(isRecursiveAfterFlattening(derivedOfT), isTrue);
+    expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
+  });
+
+  test('isRecursiveAfterFlattening-01', () async {
+    // class Derived<T> extends Base<Derived<Derived<int>>>
+    TypeParameter t = new TypeParameter('T');
+    Class derived = addClass('Derived', [t]);
+    DartType derivedOfT =
+        new InterfaceType(derived, [new TypeParameterType(t)]);
+    DartType derivedOfInt = new InterfaceType(derived, [intType]);
+    DartType derivedOfDerivedOfInt = new InterfaceType(derived, [derivedOfInt]);
+    derived.supertype = new Supertype(base, [derivedOfDerivedOfInt]);
+
+    expect(isRecursiveAfterFlattening(derivedOfT), isFalse);
+    expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
+  });
+
+  test('isRecursiveAfterFlattening-02', () async {
+    // class Derived<T> extends Base<Derived<Derived<T>>>
+    TypeParameter t = new TypeParameter('T');
+    Class derived = addClass('Derived', [t]);
+    DartType derivedOfT =
+        new InterfaceType(derived, [new TypeParameterType(t)]);
+    DartType derivedOfInt = new InterfaceType(derived, [intType]);
+    DartType derivedOfDerivedOfT = new InterfaceType(derived, [derivedOfT]);
+    derived.supertype = new Supertype(base, [derivedOfDerivedOfT]);
+
+    expect(isRecursiveAfterFlattening(derivedOfT), isTrue);
+    expect(isRecursiveAfterFlattening(derivedOfInt), isTrue);
+  });
+
+  test('isRecursiveAfterFlattening-03', () async {
+    // class Derived1<U> extends Base<Derived2<U>>
+    // class Derived2<V> extends Base<Derived1<V>>
+    TypeParameter u = new TypeParameter('U');
+    Class derived1 = addClass('Derived1', [u]);
+
+    TypeParameter v = new TypeParameter('V');
+    Class derived2 = addClass('Derived2', [v]);
+
+    DartType derived2OfU =
+        new InterfaceType(derived2, [new TypeParameterType(u)]);
+    derived1.supertype = new Supertype(base, [derived2OfU]);
+
+    DartType derived1OfV =
+        new InterfaceType(derived1, [new TypeParameterType(v)]);
+    derived2.supertype = new Supertype(base, [derived1OfV]);
+
+    DartType derived1OfU =
+        new InterfaceType(derived1, [new TypeParameterType(u)]);
+    DartType derived1OfInt = new InterfaceType(derived1, [intType]);
+
+    DartType derived2OfV =
+        new InterfaceType(derived2, [new TypeParameterType(v)]);
+    DartType derived2OfInt = new InterfaceType(derived2, [intType]);
+
+    expect(isRecursiveAfterFlattening(derived1OfU), isTrue);
+    expect(isRecursiveAfterFlattening(derived1OfInt), isTrue);
+    expect(isRecursiveAfterFlattening(derived2OfV), isTrue);
+    expect(isRecursiveAfterFlattening(derived2OfInt), isTrue);
+  });
+}
diff --git a/pkg/vm/testcases/bytecode/asserts.dart.expect b/pkg/vm/testcases/bytecode/asserts.dart.expect
index 575ae5f..0c5afe3 100644
--- a/pkg/vm/testcases/bytecode/asserts.dart.expect
+++ b/pkg/vm/testcases/bytecode/asserts.dart.expect
@@ -13,16 +13,15 @@
   PushInt              0
   PushInt              0
   PushNull
-  PushConstant         CP#1
-  IndirectStaticCall   3, CP#0
+  DirectCall           3, CP#0
   Drop1
 L1:
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 3, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::_AssertionError::_throwNew', arg-desc CP#0
+  [0] = DirectCall 'dart:core::_AssertionError::_throwNew', ArgDesc num-args 3, num-type-args 0, names []
+  [1] = Reserved
 }
 ]static method test1(core::bool condition) → void {
   assert(condition);
@@ -40,19 +39,18 @@
   PushInt              0
   Push                 FP[-5]
   DynamicCall          1, CP#2
-  PushConstant         CP#4
-  IndirectStaticCall   3, CP#3
+  DirectCall           3, CP#3
   Drop1
 L1:
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
+  [0] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
   [1] = ICData dynamic target-name 'call', arg-desc CP#0
   [2] = ICData dynamic target-name 'call', arg-desc CP#0
-  [3] = ArgDesc num-args 3, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::_AssertionError::_throwNew', arg-desc CP#3
+  [3] = DirectCall 'dart:core::_AssertionError::_throwNew', ArgDesc num-args 3, num-type-args 0, names []
+  [4] = Reserved
 }
 ]static method test2(() → core::bool condition, () → core::String message) → void {
   assert([@vm.call-site-attributes.metadata=receiverType:() → dart.core::bool] condition.call(), [@vm.call-site-attributes.metadata=receiverType:() → dart.core::String] message.call());
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 115e062..a9c151f 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -3,24 +3,26 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
+import "dart:async";
+
 [@vm.bytecode=
 Bytecode {
   Entry                3
   CheckStack           0
-  Allocate             CP#21
+  Allocate             CP#20
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#22
+  StoreFieldTOS        CP#21
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#24
+  StoreFieldTOS        CP#23
   Push                 r2
-  PushConstant         CP#26
-  StoreFieldTOS        CP#27
+  PushConstant         CP#25
+  StoreFieldTOS        CP#26
   Push                 r2
   PushConstant         CP#0
-  StoreFieldTOS        CP#29
+  StoreFieldTOS        CP#28
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
@@ -31,42 +33,45 @@
   [1] = InstanceField dart:core::_Closure::_context (field)
   [2] = Reserved
   [3] = Type dart:async::Future < dart:core::int >
-  [4] = String 'x'
+  [4] = ObjectRef 'x'
   [5] = SubtypeTestCache
   [6] = Class dart:async::_AsyncAwaitCompleter
-  [7] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::Null]
-  [8] = ArgDesc num-args 1, num-type-args 0, names []
-  [9] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#8
+  [7] = ObjectRef < dart:core::Null >
+  [8] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [9] = Reserved
   [10] = ClosureFunction 1
-  [11] = Null
-  [12] = ArgDesc num-args 4, num-type-args 0, names []
-  [13] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#12
-  [14] = ArgDesc num-args 2, num-type-args 0, names []
-  [15] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#14
+  [11] = ObjectRef null
+  [12] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
+  [13] = Reserved
+  [14] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
+  [15] = Reserved
   [16] = Type dynamic
-  [17] = ArgDesc num-args 3, num-type-args 0, names []
-  [18] = InterfaceCall target-name 'completeError', arg-desc CP#17
-  [19] = Reserved
-  [20] = EndClosureFunctionScope
-  [21] = Class dart:core::_Closure
-  [22] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [23] = Reserved
-  [24] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [25] = Reserved
-  [26] = EmptyTypeArguments
-  [27] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [28] = Reserved
-  [29] = InstanceField dart:core::_Closure::_function (field)
-  [30] = Reserved
-  [31] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#8
-  [32] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#8
-  [33] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#8
-  [34] = ICData dynamic target-name 'start', arg-desc CP#14
-  [35] = InterfaceCall get target-name 'get:future', arg-desc CP#8
-  [36] = Reserved
-  [37] = EndClosureFunctionScope
+  [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
+  [18] = Reserved
+  [19] = EndClosureFunctionScope
+  [20] = Class dart:core::_Closure
+  [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [22] = Reserved
+  [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [24] = Reserved
+  [25] = EmptyTypeArguments
+  [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [27] = Reserved
+  [28] = InstanceField dart:core::_Closure::_function (field)
+  [29] = Reserved
+  [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [31] = Reserved
+  [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [33] = Reserved
+  [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [35] = Reserved
+  [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [37] = ICData dynamic target-name 'start', arg-desc CP#36
+  [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [39] = Reserved
+  [40] = EndClosureFunctionScope
 }
-Closure #lib::asyncInFieldInitializer (field)::<anonymous closure> (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
+Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
 ClosureBytecode {
   EntryFixed           2, 4
   CheckStack           0
@@ -91,8 +96,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#8
+  DirectCall           1, CP#8
   Drop1
   StoreContextVar      0, 1
   Push                 r0
@@ -116,55 +120,52 @@
   PushNull
   StoreContextVar      0, 7
   Push                 r0
-  Allocate             CP#21
+  Allocate             CP#20
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#22
+  StoreFieldTOS        CP#21
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#24
+  StoreFieldTOS        CP#23
   Push                 r2
-  PushConstant         CP#26
-  StoreFieldTOS        CP#27
+  PushConstant         CP#25
+  StoreFieldTOS        CP#26
   Push                 r2
   PushConstant         CP#10
-  StoreFieldTOS        CP#29
+  StoreFieldTOS        CP#28
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
   StoreContextVar      0, 8
   Push                 r0
   LoadContextVar       0, 8
-  PushConstant         CP#31
-  IndirectStaticCall   1, CP#8
+  DirectCall           1, CP#30
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#8
+  DirectCall           1, CP#32
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#8
+  DirectCall           1, CP#34
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          2, CP#34
+  DynamicCall          2, CP#37
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#35
+  InterfaceCall        1, CP#38
   ReturnTOS
 
 }
 
-Closure #lib::asyncInFieldInitializer (field)::Closure/0:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::asyncInFieldInitializer (field)::Closure/0::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#11
@@ -198,8 +199,7 @@
   LoadContextVar       0, 4
   Push                 r4
   LoadContextVar       0, 8
-  PushConstant         CP#13
-  IndirectStaticCall   4, CP#12
+  DirectCall           4, CP#12
   PopLocal             r8
   PushNull
   ReturnTOS
@@ -216,8 +216,7 @@
   LoadContextVar       0, 1
   Push                 r4
   LoadContextVar       0, 2
-  PushConstant         CP#15
-  IndirectStaticCall   2, CP#14
+  DirectCall           2, CP#14
   Drop1
   PushNull
   ReturnTOS
@@ -240,7 +239,7 @@
   LoadContextVar       0, 1
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#18
+  InterfaceCall        3, CP#17
   Drop1
   Jump                 L3
 L3:
@@ -293,8 +292,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   StoreContextVar      0, 0
   Push                 r0
@@ -312,80 +310,80 @@
   Push                 r0
   PushNull
   StoreContextVar      0, 3
-  Allocate             CP#15
+  Allocate             CP#14
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#16
+  StoreFieldTOS        CP#15
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#18
+  StoreFieldTOS        CP#17
   Push                 r2
-  PushConstant         CP#20
-  StoreFieldTOS        CP#21
+  PushConstant         CP#19
+  StoreFieldTOS        CP#20
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#23
+  StoreFieldTOS        CP#22
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   PopLocal             r6
   Push                 r6
-  PushConstant         CP#25
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#24
   PopLocal             r3
   Push                 r6
-  PushConstant         CP#26
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#26
   PopLocal             r4
   Push                 r6
-  PushConstant         CP#27
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#28
   PopLocal             r5
   Push                 r0
   LoadContextVar       0, 0
   Push                 r6
-  DynamicCall          2, CP#28
+  DynamicCall          2, CP#31
   Drop1
   Push                 r0
   LoadContextVar       0, 0
-  InterfaceCall        1, CP#29
+  InterfaceCall        1, CP#32
   ReturnTOS
 }
 ConstantPool {
   [0] = Class dart:async::_AsyncAwaitCompleter
-  [1] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::int]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < dart:core::int >
+  [2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
   [4] = ClosureFunction 0
-  [5] = Null
+  [5] = ObjectRef null
   [6] = InstanceField dart:core::_Closure::_context (field)
   [7] = Reserved
-  [8] = ArgDesc num-args 2, num-type-args 0, names []
-  [9] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#8
+  [8] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
+  [9] = Reserved
   [10] = Type dynamic
-  [11] = ArgDesc num-args 3, num-type-args 0, names []
-  [12] = InterfaceCall target-name 'completeError', arg-desc CP#11
-  [13] = Reserved
-  [14] = EndClosureFunctionScope
-  [15] = Class dart:core::_Closure
-  [16] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [17] = Reserved
-  [18] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [19] = Reserved
-  [20] = EmptyTypeArguments
-  [21] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [22] = Reserved
-  [23] = InstanceField dart:core::_Closure::_function (field)
-  [24] = Reserved
-  [25] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#2
-  [26] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#2
-  [27] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#2
-  [28] = ICData dynamic target-name 'start', arg-desc CP#8
-  [29] = InterfaceCall get target-name 'get:future', arg-desc CP#2
-  [30] = Reserved
+  [11] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
+  [12] = Reserved
+  [13] = EndClosureFunctionScope
+  [14] = Class dart:core::_Closure
+  [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [16] = Reserved
+  [17] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [18] = Reserved
+  [19] = EmptyTypeArguments
+  [20] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [21] = Reserved
+  [22] = InstanceField dart:core::_Closure::_function (field)
+  [23] = Reserved
+  [24] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [25] = Reserved
+  [26] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [27] = Reserved
+  [28] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [29] = Reserved
+  [30] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [31] = ICData dynamic target-name 'start', arg-desc CP#30
+  [32] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [33] = Reserved
 }
-Closure #lib::foo:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::foo::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#5
@@ -413,8 +411,7 @@
   LoadContextVar       0, 0
   Push                 r4
   LoadContextVar       0, 1
-  PushConstant         CP#9
-  IndirectStaticCall   2, CP#8
+  DirectCall           2, CP#8
   Drop1
   PushNull
   ReturnTOS
@@ -433,7 +430,7 @@
   LoadContextVar       0, 0
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#12
+  InterfaceCall        3, CP#11
   Drop1
   Jump                 L3
 L3:
@@ -488,8 +485,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   StoreContextVar      0, 2
   Push                 r0
@@ -516,91 +512,90 @@
   PushNull
   StoreContextVar      0, 9
   Push                 r0
-  Allocate             CP#20
+  Allocate             CP#18
   StoreLocal           r2
   Push                 r2
   PushNull
+  StoreFieldTOS        CP#19
+  Push                 r2
+  PushNull
   StoreFieldTOS        CP#21
   Push                 r2
-  PushNull
-  StoreFieldTOS        CP#23
-  Push                 r2
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
+  PushConstant         CP#23
+  StoreFieldTOS        CP#24
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#26
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   StoreContextVar      0, 10
   Push                 r0
   LoadContextVar       0, 10
-  PushConstant         CP#30
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#28
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  PushConstant         CP#31
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#30
   StoreContextVar      0, 4
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#32
   StoreContextVar      0, 5
   Push                 r0
   LoadContextVar       0, 2
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          2, CP#33
+  DynamicCall          2, CP#35
   Drop1
   Push                 r0
   LoadContextVar       0, 2
-  InterfaceCall        1, CP#34
+  InterfaceCall        1, CP#36
   ReturnTOS
 }
 ConstantPool {
   [0] = Class dart:async::_AsyncAwaitCompleter
-  [1] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::int]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < dart:core::int >
+  [2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
   [4] = ClosureFunction 0
-  [5] = Null
+  [5] = ObjectRef null
   [6] = InstanceField dart:core::_Closure::_context (field)
   [7] = Reserved
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [10] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [11] = ArgDesc num-args 2, num-type-args 0, names []
-  [12] = InterfaceCall target-name '+', arg-desc CP#11
+  [8] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
+  [9] = Reserved
+  [10] = InterfaceCall 'dart:core::num::+', ArgDesc num-args 2, num-type-args 0, names []
+  [11] = Reserved
+  [12] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
   [13] = Reserved
-  [14] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#11
-  [15] = Type dynamic
-  [16] = ArgDesc num-args 3, num-type-args 0, names []
-  [17] = InterfaceCall target-name 'completeError', arg-desc CP#16
-  [18] = Reserved
-  [19] = EndClosureFunctionScope
-  [20] = Class dart:core::_Closure
-  [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [14] = Type dynamic
+  [15] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
+  [16] = Reserved
+  [17] = EndClosureFunctionScope
+  [18] = Class dart:core::_Closure
+  [19] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [20] = Reserved
+  [21] = InstanceField dart:core::_Closure::_function_type_arguments (field)
   [22] = Reserved
-  [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [24] = Reserved
-  [25] = EmptyTypeArguments
-  [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [23] = EmptyTypeArguments
+  [24] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [25] = Reserved
+  [26] = InstanceField dart:core::_Closure::_function (field)
   [27] = Reserved
-  [28] = InstanceField dart:core::_Closure::_function (field)
+  [28] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
   [29] = Reserved
-  [30] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#2
-  [31] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#2
-  [32] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#2
-  [33] = ICData dynamic target-name 'start', arg-desc CP#11
-  [34] = InterfaceCall get target-name 'get:future', arg-desc CP#2
-  [35] = Reserved
+  [30] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [31] = Reserved
+  [32] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [33] = Reserved
+  [34] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [35] = ICData dynamic target-name 'start', arg-desc CP#34
+  [36] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [37] = Reserved
 }
-Closure #lib::simpleAsyncAwait:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::simpleAsyncAwait::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#5
@@ -634,8 +629,7 @@
   LoadContextVar       0, 5
   Push                 r4
   LoadContextVar       0, 10
-  PushConstant         CP#9
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r8
   PushNull
   ReturnTOS
@@ -663,8 +657,7 @@
   LoadContextVar       0, 5
   Push                 r4
   LoadContextVar       0, 10
-  PushConstant         CP#10
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r9
   PushNull
   ReturnTOS
@@ -679,7 +672,7 @@
   Push                 r4
   LoadContextVar       0, 9
   Push                 r1
-  InterfaceCall        2, CP#12
+  InterfaceCall        2, CP#10
   StoreContextVar      0, 3
   Jump                 L4
 L4:
@@ -687,8 +680,7 @@
   LoadContextVar       0, 2
   Push                 r4
   LoadContextVar       0, 3
-  PushConstant         CP#14
-  IndirectStaticCall   2, CP#11
+  DirectCall           2, CP#12
   Drop1
   PushNull
   ReturnTOS
@@ -711,7 +703,7 @@
   LoadContextVar       0, 2
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#17
+  InterfaceCall        3, CP#15
   Drop1
   Jump                 L5
 L5:
@@ -774,8 +766,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   StoreContextVar      0, 1
   Push                 r0
@@ -805,98 +796,98 @@
   PushNull
   StoreContextVar      0, 9
   Push                 r0
-  Allocate             CP#27
+  Allocate             CP#26
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#27
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#30
+  StoreFieldTOS        CP#29
   Push                 r2
-  PushConstant         CP#32
-  StoreFieldTOS        CP#33
+  PushConstant         CP#31
+  StoreFieldTOS        CP#32
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#35
+  StoreFieldTOS        CP#34
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   StoreContextVar      0, 10
   Push                 r0
   LoadContextVar       0, 10
-  PushConstant         CP#37
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#36
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  PushConstant         CP#38
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#38
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  PushConstant         CP#39
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#40
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          2, CP#40
+  DynamicCall          2, CP#43
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#41
+  InterfaceCall        1, CP#44
   ReturnTOS
 }
 ConstantPool {
   [0] = Class dart:async::_AsyncAwaitCompleter
-  [1] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::int]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < dart:core::int >
+  [2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
   [4] = ClosureFunction 0
-  [5] = Null
+  [5] = ObjectRef null
   [6] = InstanceField dart:core::_Closure::_context (field)
   [7] = Reserved
-  [8] = InterfaceCall get target-name 'get:iterator', arg-desc CP#2
+  [8] = InterfaceCall 'dart:core::Iterable::get:iterator', ArgDesc num-args 1, num-type-args 0, names []
   [9] = Reserved
-  [10] = InterfaceCall target-name 'moveNext', arg-desc CP#2
+  [10] = InterfaceCall 'dart:core::Iterator::moveNext', ArgDesc num-args 1, num-type-args 0, names []
   [11] = Reserved
-  [12] = InterfaceCall get target-name 'get:current', arg-desc CP#2
+  [12] = InterfaceCall 'dart:core::Iterator::get:current', ArgDesc num-args 1, num-type-args 0, names []
   [13] = Reserved
-  [14] = ArgDesc num-args 0, num-type-args 0, names []
-  [15] = StaticICData target '#lib::foo', arg-desc CP#14
-  [16] = ArgDesc num-args 4, num-type-args 0, names []
-  [17] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#16
-  [18] = ArgDesc num-args 2, num-type-args 0, names []
-  [19] = InterfaceCall target-name '+', arg-desc CP#18
-  [20] = Reserved
-  [21] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#18
+  [14] = DirectCall '#lib::foo', ArgDesc num-args 0, num-type-args 0, names []
+  [15] = Reserved
+  [16] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
+  [17] = Reserved
+  [18] = InterfaceCall 'dart:core::num::+', ArgDesc num-args 2, num-type-args 0, names []
+  [19] = Reserved
+  [20] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
+  [21] = Reserved
   [22] = Type dynamic
-  [23] = ArgDesc num-args 3, num-type-args 0, names []
-  [24] = InterfaceCall target-name 'completeError', arg-desc CP#23
-  [25] = Reserved
-  [26] = EndClosureFunctionScope
-  [27] = Class dart:core::_Closure
-  [28] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [29] = Reserved
-  [30] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [31] = Reserved
-  [32] = EmptyTypeArguments
-  [33] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [34] = Reserved
-  [35] = InstanceField dart:core::_Closure::_function (field)
-  [36] = Reserved
-  [37] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#2
-  [38] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#2
-  [39] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#2
-  [40] = ICData dynamic target-name 'start', arg-desc CP#18
-  [41] = InterfaceCall get target-name 'get:future', arg-desc CP#2
-  [42] = Reserved
+  [23] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
+  [24] = Reserved
+  [25] = EndClosureFunctionScope
+  [26] = Class dart:core::_Closure
+  [27] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [28] = Reserved
+  [29] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [30] = Reserved
+  [31] = EmptyTypeArguments
+  [32] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [33] = Reserved
+  [34] = InstanceField dart:core::_Closure::_function (field)
+  [35] = Reserved
+  [36] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [37] = Reserved
+  [38] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [39] = Reserved
+  [40] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [41] = Reserved
+  [42] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [43] = ICData dynamic target-name 'start', arg-desc CP#42
+  [44] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [45] = Reserved
 }
-Closure #lib::loops:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::loops::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#5
@@ -999,8 +990,7 @@
   LoadContextParent
   Push                 r4
   StoreContextVar      0, 6
-  PushConstant         CP#15
-  IndirectStaticCall   0, CP#14
+  DirectCall           0, CP#14
   Push                 r4
   LoadContextParent
   LoadContextParent
@@ -1016,8 +1006,7 @@
   LoadContextParent
   LoadContextParent
   LoadContextVar       0, 10
-  PushConstant         CP#17
-  IndirectStaticCall   4, CP#16
+  DirectCall           4, CP#16
   PopLocal             r10
   PushNull
   ReturnTOS
@@ -1042,8 +1031,8 @@
   LoadContextParent
   LoadContextVar       0, 8
   Push                 r1
-  InterfaceCall        2, CP#19
-  InterfaceCall        2, CP#19
+  InterfaceCall        2, CP#18
+  InterfaceCall        2, CP#18
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1102,8 +1091,7 @@
   LoadContextVar       0, 1
   Push                 r4
   LoadContextVar       0, 2
-  PushConstant         CP#21
-  IndirectStaticCall   2, CP#18
+  DirectCall           2, CP#20
   Drop1
   PushNull
   ReturnTOS
@@ -1126,7 +1114,7 @@
   LoadContextVar       0, 1
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#24
+  InterfaceCall        3, CP#23
   Drop1
   Jump                 L10
 L10:
@@ -1202,8 +1190,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   StoreContextVar      0, 3
   Push                 r0
@@ -1242,101 +1229,96 @@
   PushNull
   StoreContextVar      0, 14
   Push                 r0
-  Allocate             CP#30
+  Allocate             CP#24
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#31
+  StoreFieldTOS        CP#25
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#33
+  StoreFieldTOS        CP#27
   Push                 r2
-  PushConstant         CP#35
-  StoreFieldTOS        CP#36
+  PushConstant         CP#29
+  StoreFieldTOS        CP#30
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#38
+  StoreFieldTOS        CP#32
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   StoreContextVar      0, 15
   Push                 r0
   LoadContextVar       0, 15
-  PushConstant         CP#40
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#34
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 15
-  PushConstant         CP#41
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#36
   StoreContextVar      0, 5
   Push                 r0
   Push                 r0
   LoadContextVar       0, 15
-  PushConstant         CP#42
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#38
   StoreContextVar      0, 6
   Push                 r0
   LoadContextVar       0, 3
   Push                 r0
   LoadContextVar       0, 15
-  DynamicCall          2, CP#43
+  DynamicCall          2, CP#41
   Drop1
   Push                 r0
   LoadContextVar       0, 3
-  InterfaceCall        1, CP#44
+  InterfaceCall        1, CP#42
   ReturnTOS
 }
 ConstantPool {
   [0] = Class dart:async::_AsyncAwaitCompleter
-  [1] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::int]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < dart:core::int >
+  [2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
   [4] = ClosureFunction 0
-  [5] = Null
+  [5] = ObjectRef null
   [6] = InstanceField dart:core::_Closure::_context (field)
   [7] = Reserved
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [10] = ArgDesc num-args 2, num-type-args 0, names []
-  [11] = InterfaceCall target-name '+', arg-desc CP#10
-  [12] = Reserved
-  [13] = Type dynamic
-  [14] = Type dart:core::Error
-  [15] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#10
-  [16] = Reserved
-  [17] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [18] = String 'fin'
-  [19] = StaticICData target 'dart:core::print', arg-desc CP#2
-  [20] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [21] = StaticICData target 'dart:core::print', arg-desc CP#2
-  [22] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [23] = StaticICData target 'dart:core::print', arg-desc CP#2
-  [24] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [25] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#10
-  [26] = ArgDesc num-args 3, num-type-args 0, names []
-  [27] = InterfaceCall target-name 'completeError', arg-desc CP#26
+  [8] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
+  [9] = Reserved
+  [10] = InterfaceCall 'dart:core::num::+', ArgDesc num-args 2, num-type-args 0, names []
+  [11] = Reserved
+  [12] = Type dynamic
+  [13] = Type dart:core::Error
+  [14] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
+  [15] = Reserved
+  [16] = ObjectRef 'fin'
+  [17] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [18] = Reserved
+  [19] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
+  [20] = Reserved
+  [21] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
+  [22] = Reserved
+  [23] = EndClosureFunctionScope
+  [24] = Class dart:core::_Closure
+  [25] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [26] = Reserved
+  [27] = InstanceField dart:core::_Closure::_function_type_arguments (field)
   [28] = Reserved
-  [29] = EndClosureFunctionScope
-  [30] = Class dart:core::_Closure
-  [31] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [32] = Reserved
-  [33] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [34] = Reserved
-  [35] = EmptyTypeArguments
-  [36] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [29] = EmptyTypeArguments
+  [30] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [31] = Reserved
+  [32] = InstanceField dart:core::_Closure::_function (field)
+  [33] = Reserved
+  [34] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [35] = Reserved
+  [36] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [37] = Reserved
-  [38] = InstanceField dart:core::_Closure::_function (field)
+  [38] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [39] = Reserved
-  [40] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#2
-  [41] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#2
-  [42] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#2
-  [43] = ICData dynamic target-name 'start', arg-desc CP#10
-  [44] = InterfaceCall get target-name 'get:future', arg-desc CP#2
-  [45] = Reserved
+  [40] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [41] = ICData dynamic target-name 'start', arg-desc CP#40
+  [42] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [43] = Reserved
 }
-Closure #lib::tryCatchRethrow:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::tryCatchRethrow::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#5
@@ -1400,8 +1382,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 15
-  PushConstant         CP#9
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r13
   PushNull
   ReturnTOS
@@ -1417,7 +1398,7 @@
   LoadContextParent
   LoadContextVar       0, 14
   Push                 r1
-  InterfaceCall        2, CP#11
+  InterfaceCall        2, CP#10
   StoreContextVar      1, 0
   Jump                 L3
 Try #2 end:
@@ -1444,8 +1425,8 @@
   StoreContextVar      1, 1
   Push                 r4
   LoadContextVar       1, 1
-  PushConstant         CP#14
-  InterfaceCall        2, CP#15
+  PushConstant         CP#13
+  InterfaceCall        2, CP#14
   JumpIfFalse          L4
   Push                 r4
   LoadContextParent
@@ -1478,8 +1459,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 15
-  PushConstant         CP#17
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r13
   PushNull
   ReturnTOS
@@ -1495,7 +1475,7 @@
   LoadContextParent
   LoadContextVar       0, 14
   Push                 r1
-  InterfaceCall        2, CP#11
+  InterfaceCall        2, CP#10
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1525,9 +1505,8 @@
   LoadContextParent
   Push                 r9
   StoreContextVar      0, 13
-  PushConstant         CP#18
-  PushConstant         CP#19
-  IndirectStaticCall   1, CP#2
+  PushConstant         CP#16
+  DirectCall           1, CP#17
   Drop1
   Push                 r4
   LoadContextParent
@@ -1554,8 +1533,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 15
-  PushConstant         CP#20
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r12
   PushNull
   ReturnTOS
@@ -1571,7 +1549,7 @@
   LoadContextParent
   LoadContextVar       0, 14
   Push                 r1
-  InterfaceCall        2, CP#11
+  InterfaceCall        2, CP#10
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1589,9 +1567,8 @@
   Push                 r4
   LoadContextVar       0, 10
   PopLocal             r4
-  PushConstant         CP#18
-  PushConstant         CP#21
-  IndirectStaticCall   1, CP#2
+  PushConstant         CP#16
+  DirectCall           1, CP#17
   Drop1
   Push                 r4
   LoadContextParent
@@ -1618,8 +1595,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 15
-  PushConstant         CP#22
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r12
   PushNull
   ReturnTOS
@@ -1635,7 +1611,7 @@
   LoadContextParent
   LoadContextVar       0, 14
   Push                 r1
-  InterfaceCall        2, CP#11
+  InterfaceCall        2, CP#10
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1653,9 +1629,8 @@
   Push                 r4
   LoadContextVar       0, 10
   PopLocal             r4
-  PushConstant         CP#18
-  PushConstant         CP#23
-  IndirectStaticCall   1, CP#2
+  PushConstant         CP#16
+  DirectCall           1, CP#17
   Drop1
   Push                 r4
   LoadContextParent
@@ -1682,8 +1657,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       0, 15
-  PushConstant         CP#24
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r12
   PushNull
   ReturnTOS
@@ -1699,7 +1673,7 @@
   LoadContextParent
   LoadContextVar       0, 14
   Push                 r1
-  InterfaceCall        2, CP#11
+  InterfaceCall        2, CP#10
   StoreContextVar      1, 0
   Push                 r4
   LoadContextParent
@@ -1715,8 +1689,7 @@
   LoadContextVar       0, 3
   Push                 r4
   LoadContextVar       0, 4
-  PushConstant         CP#25
-  IndirectStaticCall   2, CP#10
+  DirectCall           2, CP#19
   Drop1
   PushNull
   ReturnTOS
@@ -1739,7 +1712,7 @@
   LoadContextVar       0, 3
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#27
+  InterfaceCall        3, CP#21
   Drop1
   Jump                 L12
 L12:
@@ -1832,20 +1805,20 @@
   Push                 r0
   PushInt              3
   StoreContextVar      0, 1
-  Allocate             CP#21
+  Allocate             CP#20
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#22
+  StoreFieldTOS        CP#21
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#24
+  StoreFieldTOS        CP#23
   Push                 r3
-  PushConstant         CP#26
-  StoreFieldTOS        CP#27
+  PushConstant         CP#25
+  StoreFieldTOS        CP#26
   Push                 r3
   PushConstant         CP#0
-  StoreFieldTOS        CP#29
+  StoreFieldTOS        CP#28
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
@@ -1858,42 +1831,45 @@
   [1] = InstanceField dart:core::_Closure::_context (field)
   [2] = Reserved
   [3] = Class dart:async::_AsyncAwaitCompleter
-  [4] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::int]
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#5
+  [4] = ObjectRef < dart:core::int >
+  [5] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
   [7] = ClosureFunction 1
-  [8] = Null
-  [9] = ArgDesc num-args 4, num-type-args 0, names []
-  [10] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#9
+  [8] = ObjectRef null
+  [9] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
+  [10] = Reserved
   [11] = Type dynamic
-  [12] = String 'fin'
-  [13] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [14] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [15] = ArgDesc num-args 2, num-type-args 0, names []
-  [16] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#15
-  [17] = ArgDesc num-args 3, num-type-args 0, names []
-  [18] = InterfaceCall target-name 'completeError', arg-desc CP#17
-  [19] = Reserved
-  [20] = EndClosureFunctionScope
-  [21] = Class dart:core::_Closure
-  [22] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [23] = Reserved
-  [24] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [25] = Reserved
-  [26] = EmptyTypeArguments
-  [27] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [28] = Reserved
-  [29] = InstanceField dart:core::_Closure::_function (field)
-  [30] = Reserved
-  [31] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#5
-  [32] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#5
-  [33] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#5
-  [34] = ICData dynamic target-name 'start', arg-desc CP#15
-  [35] = InterfaceCall get target-name 'get:future', arg-desc CP#5
-  [36] = Reserved
-  [37] = EndClosureFunctionScope
+  [12] = ObjectRef 'fin'
+  [13] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [14] = Reserved
+  [15] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
+  [16] = Reserved
+  [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
+  [18] = Reserved
+  [19] = EndClosureFunctionScope
+  [20] = Class dart:core::_Closure
+  [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [22] = Reserved
+  [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [24] = Reserved
+  [25] = EmptyTypeArguments
+  [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [27] = Reserved
+  [28] = InstanceField dart:core::_Closure::_function (field)
+  [29] = Reserved
+  [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [31] = Reserved
+  [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [33] = Reserved
+  [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [35] = Reserved
+  [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [37] = ICData dynamic target-name 'start', arg-desc CP#36
+  [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [39] = Reserved
+  [40] = EndClosureFunctionScope
 }
-Closure #lib::closure::nested () -> dart:async::Future < dart:core::int >
+Closure #lib::closure::'nested' () -> dart:async::Future < dart:core::int >
 ClosureBytecode {
   EntryFixed           1, 4
   CheckStack           0
@@ -1912,8 +1888,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#5
   Drop1
   StoreContextVar      1, 0
   Push                 r0
@@ -1940,55 +1915,52 @@
   PushNull
   StoreContextVar      1, 7
   Push                 r0
-  Allocate             CP#21
+  Allocate             CP#20
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#22
+  StoreFieldTOS        CP#21
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#24
+  StoreFieldTOS        CP#23
   Push                 r2
-  PushConstant         CP#26
-  StoreFieldTOS        CP#27
+  PushConstant         CP#25
+  StoreFieldTOS        CP#26
   Push                 r2
   PushConstant         CP#7
-  StoreFieldTOS        CP#29
+  StoreFieldTOS        CP#28
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
   StoreContextVar      1, 8
   Push                 r0
   LoadContextVar       1, 8
-  PushConstant         CP#31
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#30
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       1, 8
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#32
   StoreContextVar      1, 2
   Push                 r0
   Push                 r0
   LoadContextVar       1, 8
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#34
   StoreContextVar      1, 3
   Push                 r0
   LoadContextVar       1, 0
   Push                 r0
   LoadContextVar       1, 8
-  DynamicCall          2, CP#34
+  DynamicCall          2, CP#37
   Drop1
   Push                 r0
   LoadContextVar       1, 0
-  InterfaceCall        1, CP#35
+  InterfaceCall        1, CP#38
   ReturnTOS
 
 }
 
-Closure #lib::closure::Closure/0:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::closure::Closure/0::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#8
@@ -2048,8 +2020,7 @@
   Push                 r4
   LoadContextParent
   LoadContextVar       1, 8
-  PushConstant         CP#10
-  IndirectStaticCall   4, CP#9
+  DirectCall           4, CP#9
   PopLocal             r11
   PushNull
   ReturnTOS
@@ -2086,8 +2057,7 @@
   MoveSpecial          exception, r8
   MoveSpecial          stackTrace, r9
   PushConstant         CP#12
-  PushConstant         CP#13
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#13
   Drop1
   Push                 r8
   Push                 r9
@@ -2100,8 +2070,7 @@
   LoadContextVar       1, 7
   PopLocal             r4
   PushConstant         CP#12
-  PushConstant         CP#14
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#13
   Drop1
   Push                 r4
   LoadContextParent
@@ -2112,8 +2081,7 @@
   LoadContextVar       1, 0
   Push                 r4
   LoadContextVar       1, 1
-  PushConstant         CP#16
-  IndirectStaticCall   2, CP#15
+  DirectCall           2, CP#15
   Drop1
   PushNull
   ReturnTOS
@@ -2136,7 +2104,7 @@
   LoadContextVar       1, 0
   Push                 r8
   Push                 r9
-  InterfaceCall        3, CP#18
+  InterfaceCall        3, CP#17
   Drop1
   Jump                 L5
 L5:
@@ -2206,8 +2174,7 @@
   AllocateT
   StoreLocal           r2
   Push                 r2
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   StoreContextVar      0, 1
   Push                 r0
@@ -2251,51 +2218,48 @@
   StoreContextVar      0, 8
   Push                 r0
   LoadContextVar       0, 8
-  PushConstant         CP#30
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#30
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  PushConstant         CP#31
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#32
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#34
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          2, CP#33
+  DynamicCall          2, CP#37
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#34
+  InterfaceCall        1, CP#38
   ReturnTOS
 }
 ConstantPool {
   [0] = Class dart:async::_AsyncAwaitCompleter
-  [1] = TypeArgumentsForInstanceAllocation dart:async::_AsyncAwaitCompleter [dart:core::int]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target 'dart:async::_AsyncAwaitCompleter::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < dart:core::int >
+  [2] = DirectCall 'dart:async::_AsyncAwaitCompleter:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
   [4] = ClosureFunction 0
-  [5] = Null
+  [5] = ObjectRef null
   [6] = InstanceField dart:core::_Closure::_context (field)
   [7] = Reserved
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = StaticICData target 'dart:async::_awaitHelper', arg-desc CP#8
-  [10] = ArgDesc num-args 2, num-type-args 0, names []
-  [11] = InterfaceCall target-name '==', arg-desc CP#10
-  [12] = Reserved
-  [13] = ArgDesc num-args 3, num-type-args 0, names []
-  [14] = StaticICData target 'dart:core::_AssertionError::_throwNew', arg-desc CP#13
-  [15] = StaticICData target 'dart:async::_completeOnAsyncReturn', arg-desc CP#10
+  [8] = DirectCall 'dart:async::_awaitHelper', ArgDesc num-args 4, num-type-args 0, names []
+  [9] = Reserved
+  [10] = InterfaceCall 'dart:core::num::==', ArgDesc num-args 2, num-type-args 0, names []
+  [11] = Reserved
+  [12] = DirectCall 'dart:core::_AssertionError::_throwNew', ArgDesc num-args 3, num-type-args 0, names []
+  [13] = Reserved
+  [14] = DirectCall 'dart:async::_completeOnAsyncReturn', ArgDesc num-args 2, num-type-args 0, names []
+  [15] = Reserved
   [16] = Type dynamic
-  [17] = InterfaceCall target-name 'completeError', arg-desc CP#13
+  [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [18] = Reserved
   [19] = EndClosureFunctionScope
   [20] = Class dart:core::_Closure
@@ -2308,14 +2272,18 @@
   [27] = Reserved
   [28] = InstanceField dart:core::_Closure::_function (field)
   [29] = Reserved
-  [30] = StaticICData target 'dart:async::_asyncStackTraceHelper', arg-desc CP#2
-  [31] = StaticICData target 'dart:async::_asyncThenWrapperHelper', arg-desc CP#2
-  [32] = StaticICData target 'dart:async::_asyncErrorWrapperHelper', arg-desc CP#2
-  [33] = ICData dynamic target-name 'start', arg-desc CP#10
-  [34] = InterfaceCall get target-name 'get:future', arg-desc CP#2
+  [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [31] = Reserved
+  [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [33] = Reserved
+  [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
   [35] = Reserved
+  [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [37] = ICData dynamic target-name 'start', arg-desc CP#36
+  [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [39] = Reserved
 }
-Closure #lib::testAssert:::async_op ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
+Closure #lib::testAssert::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureBytecode {
   EntryOptional        1, 3, 0
   LoadConstant         r1, CP#5
@@ -2350,8 +2318,7 @@
   LoadContextVar       0, 4
   Push                 r4
   LoadContextVar       0, 8
-  PushConstant         CP#9
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r8
   PushNull
   ReturnTOS
@@ -2365,14 +2332,13 @@
   JumpIfNoAsserts      L2
   Push                 r1
   PushInt              42
-  InterfaceCall        2, CP#11
+  InterfaceCall        2, CP#10
   AssertBoolean        0
   JumpIfTrue           L2
   PushInt              0
   PushInt              0
   PushNull
-  PushConstant         CP#14
-  IndirectStaticCall   3, CP#13
+  DirectCall           3, CP#12
   Drop1
 L2:
   Push                 r4
@@ -2384,8 +2350,7 @@
   LoadContextVar       0, 1
   Push                 r4
   LoadContextVar       0, 2
-  PushConstant         CP#15
-  IndirectStaticCall   2, CP#10
+  DirectCall           2, CP#14
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index ed981f0..31b1d4a 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -11,15 +11,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::_ScheduleImmediate
     : super core::Object::•()
@@ -32,15 +31,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  constructor _() → self::_NamespaceImpl
     : super core::Object::•()
@@ -91,22 +89,20 @@
   Allocate             CP#0
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Push                 FP[-5]
-  PushConstant         CP#4
-  IndirectStaticCall   2, CP#3
+  DirectCall           2, CP#3
   StoreStaticTOS       CP#5
   PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::_NamespaceImpl
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target '#lib::_NamespaceImpl::_ (constructor)', arg-desc CP#1
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#3
+  [1] = DirectCall '#lib::_NamespaceImpl::_ (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
+  [3] = DirectCall '#lib::_NamespaceImpl::_create', ArgDesc num-args 2, num-type-args 0, names []
+  [4] = Reserved
   [5] = StaticField #lib::_NamespaceImpl::_cachedNamespace (field)
 }
 ]  static method _setupNamespace(dynamic namespace) → void {
@@ -123,13 +119,10 @@
   Allocate             CP#1
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
-  PushConstant         CP#5
-  IndirectStaticCall   0, CP#4
-  PushConstant         CP#7
-  IndirectStaticCall   2, CP#6
+  DirectCall           0, CP#4
+  DirectCall           2, CP#6
   StoreStaticTOS       CP#0
 L1:
   PushConstant         CP#0
@@ -139,12 +132,12 @@
 ConstantPool {
   [0] = StaticField #lib::_NamespaceImpl::_cachedNamespace (field)
   [1] = Class #lib::_NamespaceImpl
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target '#lib::_NamespaceImpl::_ (constructor)', arg-desc CP#2
-  [4] = ArgDesc num-args 0, num-type-args 0, names []
-  [5] = StaticICData target '#lib::_NamespaceImpl::_getDefault', arg-desc CP#4
-  [6] = ArgDesc num-args 2, num-type-args 0, names []
-  [7] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#6
+  [2] = DirectCall '#lib::_NamespaceImpl::_ (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
+  [4] = DirectCall '#lib::_NamespaceImpl::_getDefault', ArgDesc num-args 0, num-type-args 0, names []
+  [5] = Reserved
+  [6] = DirectCall '#lib::_NamespaceImpl::_create', ArgDesc num-args 2, num-type-args 0, names []
+  [7] = Reserved
 }
 ]  static get _namespace() → self::_NamespaceImpl {
     if(self::_NamespaceImpl::_cachedNamespace.{core::Object::==}(null)) {
@@ -156,17 +149,15 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#1
-  IndirectStaticCall   0, CP#0
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           0, CP#0
+  DirectCall           1, CP#2
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 0, num-type-args 0, names []
-  [1] = StaticICData target '#lib::_NamespaceImpl::get:_namespace', arg-desc CP#0
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target '#lib::_NamespaceImpl::_getPointer', arg-desc CP#2
+  [0] = DirectCall '#lib::_NamespaceImpl::get:_namespace', ArgDesc num-args 0, num-type-args 0, names []
+  [1] = Reserved
+  [2] = DirectCall '#lib::_NamespaceImpl::_getPointer', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]  static get _namespacePointer() → core::int
     return self::_NamespaceImpl::_getPointer(self::_NamespaceImpl::_namespace);
@@ -177,15 +168,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::_Namespace
     : super core::Object::•()
@@ -195,15 +185,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::_NamespaceImpl::_setupNamespace', arg-desc CP#0
+  [0] = DirectCall '#lib::_NamespaceImpl::_setupNamespace', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  static method _setupNamespace(dynamic namespace) → void {
     self::_NamespaceImpl::_setupNamespace(namespace);
@@ -212,13 +201,12 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#1
-  IndirectStaticCall   0, CP#0
+  DirectCall           0, CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 0, num-type-args 0, names []
-  [1] = StaticICData target '#lib::_NamespaceImpl::get:_namespace', arg-desc CP#0
+  [0] = DirectCall '#lib::_NamespaceImpl::get:_namespace', ArgDesc num-args 0, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  static get _namespace() → self::_Namespace
     return self::_NamespaceImpl::_namespace;
@@ -226,13 +214,12 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#1
-  IndirectStaticCall   0, CP#0
+  DirectCall           0, CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 0, num-type-args 0, names []
-  [1] = StaticICData target '#lib::_NamespaceImpl::get:_namespacePointer', arg-desc CP#0
+  [0] = DirectCall '#lib::_NamespaceImpl::get:_namespacePointer', ArgDesc num-args 0, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  static get _namespacePointer() → core::int
     return self::_NamespaceImpl::_namespacePointer;
@@ -254,15 +241,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::VMLibraryHooks
     : super core::Object::•()
@@ -318,7 +304,7 @@
 ConstantPool {
   [0] = StaticField #lib::VMLibraryHooks::_cachedScript (field)
   [1] = StaticField #lib::VMLibraryHooks::_computeScriptUri (field)
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
+  [2] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
   [3] = ICData dynamic target-name 'call', arg-desc CP#2
 }
 ]  static get platformScript() → dynamic {
@@ -334,15 +320,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::Stdin
     : super core::Object::•()
@@ -354,15 +339,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::_StdIOUtils
     : super core::Object::•()
@@ -402,18 +386,17 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#0
+  InterfaceCall        1, CP#0
+  DirectCall           1, CP#2
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall target-name 'toString', arg-desc CP#0
-  [2] = Reserved
-  [3] = StaticICData target '#lib::_printString', arg-desc CP#0
+  [0] = InterfaceCall 'dart:core::Object::toString', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = DirectCall '#lib::_printString', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method _print(dynamic arg) → void {
   self::_printString(arg.{core::Object::toString}());
@@ -426,7 +409,7 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = TearOff #lib::_print
+  [0] = ObjectRef const tear-off #lib::_print
 }
 ]static method _getPrintClosure() → dynamic
   return self::_print;
@@ -475,13 +458,13 @@
   PushConstant         CP#0
   PushStatic           CP#0
   PushConstant         CP#1
-  InterfaceCall        2, CP#3
+  InterfaceCall        2, CP#2
   AssertBoolean        0
   JumpIfTrue           L1
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#5
-  InterfaceCall        2, CP#3
+  PushConstant         CP#4
+  InterfaceCall        2, CP#2
   AssertBoolean        0
   PopLocal             r1
   Jump                 L2
@@ -493,8 +476,8 @@
   JumpIfTrue           L3
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#6
-  InterfaceCall        2, CP#3
+  PushConstant         CP#5
+  InterfaceCall        2, CP#2
   AssertBoolean        0
   PopLocal             r0
   Jump                 L4
@@ -506,34 +489,31 @@
   JumpIfFalse          L5
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
+  DirectCall           1, CP#6
   ReturnTOS
 L5:
-  PushConstant         CP#10
-  IndirectStaticCall   0, CP#9
+  DirectCall           0, CP#8
   PushNull
   PushConstant         CP#0
   PushStatic           CP#0
-  PushConstant         CP#11
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#10
   InterfaceCall        2, CP#12
   ReturnTOS
 }
 ConstantPool {
   [0] = StaticField #lib::_rawScript (field)
-  [1] = String 'http:'
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = InterfaceCall target-name 'startsWith', arg-desc CP#2
-  [4] = Reserved
-  [5] = String 'https:'
-  [6] = String 'file:'
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target 'dart:core::Uri::parse', arg-desc CP#7
-  [9] = ArgDesc num-args 0, num-type-args 0, names []
-  [10] = StaticICData target 'dart:core::Uri::get:base', arg-desc CP#9
-  [11] = StaticICData target 'dart:core::_Uri::file (constructor)', arg-desc CP#2
-  [12] = InterfaceCall target-name 'resolveUri', arg-desc CP#2
+  [1] = ObjectRef 'http:'
+  [2] = InterfaceCall 'dart:core::String::startsWith', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
+  [4] = ObjectRef 'https:'
+  [5] = ObjectRef 'file:'
+  [6] = DirectCall 'dart:core::Uri::parse', ArgDesc num-args 1, num-type-args 0, names []
+  [7] = Reserved
+  [8] = DirectCall 'dart:core::Uri::get:base', ArgDesc num-args 0, num-type-args 0, names []
+  [9] = Reserved
+  [10] = DirectCall 'dart:core::_Uri::file (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [11] = Reserved
+  [12] = InterfaceCall 'dart:core::Uri::resolveUri', ArgDesc num-args 2, num-type-args 0, names []
   [13] = Reserved
 }
 ]static method _scriptUri() → core::Uri {
@@ -549,16 +529,15 @@
   Entry                1
   CheckStack           0
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = TearOff #lib::_scriptUri
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target '#lib::VMLibraryHooks::set:platformScript', arg-desc CP#1
+  [0] = ObjectRef const tear-off #lib::_scriptUri
+  [1] = DirectCall '#lib::VMLibraryHooks::set:platformScript', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]static method _setupHooks() → dynamic {
   self::VMLibraryHooks::platformScript = self::_scriptUri;
@@ -573,8 +552,7 @@
   JumpIfFalse          L1
   PushConstant         CP#1
   PushStatic           CP#1
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   StoreLocal           r1
   Push                 r1
   StoreStaticTOS       CP#0
@@ -593,8 +571,8 @@
 ConstantPool {
   [0] = StaticField #lib::_stdin (field)
   [1] = StaticField #lib::_stdinFD (field)
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target '#lib::_StdIOUtils::_getStdioInputStream', arg-desc CP#2
+  [2] = DirectCall '#lib::_StdIOUtils::_getStdioInputStream', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static get stdin() → self::Stdin {
   self::_stdin.{core::Object::==}(null) ?{self::Stdin} self::_stdin = self::_StdIOUtils::_getStdioInputStream(self::_stdinFD) : null;
diff --git a/pkg/vm/testcases/bytecode/closures.dart b/pkg/vm/testcases/bytecode/closures.dart
index 5e6359f..e96872c 100644
--- a/pkg/vm/testcases/bytecode/closures.dart
+++ b/pkg/vm/testcases/bytecode/closures.dart
@@ -143,6 +143,14 @@
   foo(T t) {
     return () => t;
   }
+
+  bar() {
+    return () {
+      inner() {}
+
+      inner();
+    };
+  }
 }
 
 main() {}
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index f801084..6eaeaf0 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -9,15 +9,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C1
     : super core::Object::•()
@@ -29,15 +28,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C2
     : super core::Object::•()
@@ -49,15 +47,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C3
     : super core::Object::•()
@@ -69,15 +66,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C4
     : super core::Object::•()
@@ -89,15 +85,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C5
     : super core::Object::•()
@@ -109,15 +104,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C6
     : super core::Object::•()
@@ -129,15 +123,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C7
     : super core::Object::•()
@@ -149,15 +142,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C8
     : super core::Object::•()
@@ -169,15 +161,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::A<self::A::T1, self::A::T2>
     : super core::Object::•()
@@ -192,12 +183,12 @@
   Push                 r1
   Push                 FP[-5]
   StoreContextVar      0, 0
-  Allocate             CP#31
+  Allocate             CP#30
   StoreLocal           r4
   Push                 r4
   Push                 FP[-5]
-  LoadTypeArgumentsField CP#15
-  StoreFieldTOS        CP#32
+  LoadTypeArgumentsField CP#14
+  StoreFieldTOS        CP#31
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -206,7 +197,7 @@
   StoreFieldTOS        CP#3
   Push                 r4
   PushConstant         CP#0
-  StoreFieldTOS        CP#34
+  StoreFieldTOS        CP#33
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
@@ -231,48 +222,48 @@
   [5] = EmptyTypeArguments
   [6] = InstanceField dart:core::_Closure::_function_type_arguments (field)
   [7] = Reserved
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = StaticICData target 'dart:_internal::_prependTypeArguments', arg-desc CP#8
+  [8] = DirectCall 'dart:_internal::_prependTypeArguments', ArgDesc num-args 4, num-type-args 0, names []
+  [9] = Reserved
   [10] = ClosureFunction 1
-  [11] = StaticICData target 'dart:_internal::_prependTypeArguments', arg-desc CP#8
-  [12] = ClosureFunction 2
-  [13] = TypeArgs [dart:core::Type]
-  [14] = Type #lib::A::TypeParam/0
-  [15] = TypeArgumentsField #lib::A
-  [16] = Type #lib::A::TypeParam/1
-  [17] = Type #lib::A::foo::TypeParam/0
-  [18] = Type #lib::A::foo::TypeParam/1
-  [19] = Type #lib::A::foo::Closure/0::TypeParam/0
-  [20] = Type #lib::A::foo::Closure/0::TypeParam/1
-  [21] = Type #lib::A::foo::Closure/1::TypeParam/0
-  [22] = Type #lib::A::foo::Closure/1::TypeParam/1
-  [23] = ArgDesc num-args 2, num-type-args 0, names []
-  [24] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#23
-  [25] = ArgDesc num-args 1, num-type-args 0, names []
-  [26] = StaticICData target 'dart:core::print', arg-desc CP#25
-  [27] = TypeArgs [#lib::A::TypeParam/0, #lib::A::TypeParam/1, #lib::A::foo::TypeParam/0, #lib::A::foo::TypeParam/1, #lib::A::foo::Closure/0::TypeParam/0, #lib::A::foo::Closure/0::TypeParam/1, #lib::A::foo::Closure/1::TypeParam/0, #lib::A::foo::Closure/1::TypeParam/1]
-  [28] = ArgDesc num-args 0, num-type-args 8, names []
-  [29] = StaticICData target '#lib::callWithArgs', arg-desc CP#28
-  [30] = EndClosureFunctionScope
-  [31] = Class dart:core::_Closure
-  [32] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [33] = Reserved
-  [34] = InstanceField dart:core::_Closure::_function (field)
-  [35] = Reserved
-  [36] = ICData dynamic target-name 'call', arg-desc CP#25
+  [11] = ClosureFunction 2
+  [12] = ObjectRef < dart:core::Type >
+  [13] = Type #lib::A::TypeParam/0
+  [14] = TypeArgumentsField #lib::A
+  [15] = Type #lib::A::TypeParam/1
+  [16] = Type #lib::A::foo::TypeParam/0
+  [17] = Type #lib::A::foo::TypeParam/1
+  [18] = Type #lib::A::foo::Closure/0::TypeParam/0
+  [19] = Type #lib::A::foo::Closure/0::TypeParam/1
+  [20] = Type #lib::A::foo::Closure/1::TypeParam/0
+  [21] = Type #lib::A::foo::Closure/1::TypeParam/1
+  [22] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [23] = Reserved
+  [24] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [25] = Reserved
+  [26] = ObjectRef < #lib::A::TypeParam/0, #lib::A::TypeParam/1, #lib::A::foo::TypeParam/0, #lib::A::foo::TypeParam/1, #lib::A::foo::Closure/0::TypeParam/0, #lib::A::foo::Closure/0::TypeParam/1, #lib::A::foo::Closure/1::TypeParam/0, #lib::A::foo::Closure/1::TypeParam/1 >
+  [27] = DirectCall '#lib::callWithArgs', ArgDesc num-args 0, num-type-args 8, names []
+  [28] = Reserved
+  [29] = EndClosureFunctionScope
+  [30] = Class dart:core::_Closure
+  [31] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [32] = Reserved
+  [33] = InstanceField dart:core::_Closure::_function (field)
+  [34] = Reserved
+  [35] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [36] = ICData dynamic target-name 'call', arg-desc CP#35
   [37] = EndClosureFunctionScope
-  [38] = TypeArgs [#lib::C7, #lib::C8]
-  [39] = ArgDesc num-args 1, num-type-args 2, names []
+  [38] = ObjectRef < #lib::C7, #lib::C8 >
+  [39] = ObjectRef ArgDesc num-args 1, num-type-args 2, names []
   [40] = ICData dynamic target-name 'call', arg-desc CP#39
-  [41] = TypeArgs [dart:core::List < #lib::C7 >, dart:core::List < #lib::C8 >]
+  [41] = ObjectRef < dart:core::List < #lib::C7 >, dart:core::List < #lib::C8 > >
   [42] = ICData dynamic target-name 'call', arg-desc CP#39
   [43] = EndClosureFunctionScope
-  [44] = TypeArgs [#lib::C5, #lib::C6]
+  [44] = ObjectRef < #lib::C5, #lib::C6 >
   [45] = ICData dynamic target-name 'call', arg-desc CP#39
-  [46] = TypeArgs [dart:core::List < #lib::C5 >, dart:core::List < #lib::C6 >]
+  [46] = ObjectRef < dart:core::List < #lib::C5 >, dart:core::List < #lib::C6 > >
   [47] = ICData dynamic target-name 'call', arg-desc CP#39
 }
-Closure #lib::A::foo::nested1 <dart:core::Object T5, dart:core::Object T6> () -> void
+Closure #lib::A::foo::'nested1' <dart:core::Object T5, dart:core::Object T6> () -> void
 ClosureBytecode {
   EntryFixed           1, 5
   CheckStack           0
@@ -294,16 +285,15 @@
   LoadFieldTOS         CP#6
   PushInt              2
   PushInt              4
-  PushConstant         CP#9
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r0
-  Allocate             CP#31
+  Allocate             CP#30
   StoreLocal           r4
   Push                 r4
   Push                 r1
   LoadContextVar       0, 0
-  LoadTypeArgumentsField CP#15
-  StoreFieldTOS        CP#32
+  LoadTypeArgumentsField CP#14
+  StoreFieldTOS        CP#31
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -312,7 +302,7 @@
   StoreFieldTOS        CP#3
   Push                 r4
   PushConstant         CP#10
-  StoreFieldTOS        CP#34
+  StoreFieldTOS        CP#33
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
@@ -330,7 +320,7 @@
 
 }
 
-Closure #lib::A::foo::Closure/0::nested2 <dart:core::Object T7, dart:core::Object T8> () -> void
+Closure #lib::A::foo::Closure/0::'nested2' <dart:core::Object T7, dart:core::Object T8> () -> void
 ClosureBytecode {
   EntryFixed           1, 5
   CheckStack           0
@@ -352,16 +342,15 @@
   LoadFieldTOS         CP#6
   PushInt              4
   PushInt              6
-  PushConstant         CP#11
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r0
-  Allocate             CP#31
+  Allocate             CP#30
   StoreLocal           r4
   Push                 r4
   Push                 r1
   LoadContextVar       0, 0
-  LoadTypeArgumentsField CP#15
-  StoreFieldTOS        CP#32
+  LoadTypeArgumentsField CP#14
+  StoreFieldTOS        CP#31
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -369,8 +358,8 @@
   PushConstant         CP#5
   StoreFieldTOS        CP#3
   Push                 r4
-  PushConstant         CP#12
-  StoreFieldTOS        CP#34
+  PushConstant         CP#11
+  StoreFieldTOS        CP#33
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
@@ -383,7 +372,7 @@
 
 }
 
-Closure #lib::A::foo::Closure/1::<anonymous closure> () -> dart:core::Null
+Closure #lib::A::foo::Closure/1::'<anonymous closure>' () -> dart:core::Null
 ClosureBytecode {
   EntryFixed           1, 4
   CheckStack           0
@@ -393,7 +382,7 @@
   Push                 FP[-5]
   LoadFieldTOS         CP#6
   PopLocal             r0
-  PushConstant         CP#13
+  PushConstant         CP#12
   StoreLocal           r3
   Push                 r3
   PushInt              8
@@ -403,66 +392,63 @@
   PushInt              0
   Push                 r1
   LoadContextVar       0, 0
-  LoadTypeArgumentsField CP#15
+  LoadTypeArgumentsField CP#14
   PushNull
-  InstantiateType      CP#14
+  InstantiateType      CP#13
   StoreIndexedTOS
   Push                 r3
   PushInt              1
   Push                 r1
   LoadContextVar       0, 0
-  LoadTypeArgumentsField CP#15
+  LoadTypeArgumentsField CP#14
   PushNull
-  InstantiateType      CP#16
+  InstantiateType      CP#15
   StoreIndexedTOS
   Push                 r3
   PushInt              2
   PushNull
   Push                 r0
-  InstantiateType      CP#17
+  InstantiateType      CP#16
   StoreIndexedTOS
   Push                 r3
   PushInt              3
   PushNull
   Push                 r0
-  InstantiateType      CP#18
+  InstantiateType      CP#17
   StoreIndexedTOS
   Push                 r3
   PushInt              4
   PushNull
   Push                 r0
-  InstantiateType      CP#19
+  InstantiateType      CP#18
   StoreIndexedTOS
   Push                 r3
   PushInt              5
   PushNull
   Push                 r0
-  InstantiateType      CP#20
+  InstantiateType      CP#19
   StoreIndexedTOS
   Push                 r3
   PushInt              6
   PushNull
   Push                 r0
-  InstantiateType      CP#21
+  InstantiateType      CP#20
   StoreIndexedTOS
   Push                 r3
   PushInt              7
   PushNull
   Push                 r0
-  InstantiateType      CP#22
+  InstantiateType      CP#21
   StoreIndexedTOS
-  PushConstant         CP#24
-  IndirectStaticCall   2, CP#23
-  PushConstant         CP#26
-  IndirectStaticCall   1, CP#25
+  DirectCall           2, CP#22
+  DirectCall           1, CP#24
   Drop1
   Push                 r1
   LoadContextVar       0, 0
-  LoadTypeArgumentsField CP#15
+  LoadTypeArgumentsField CP#14
   Push                 r0
-  InstantiateTypeArgumentsTOS 0, CP#27
-  PushConstant         CP#29
-  IndirectStaticCall   1, CP#28
+  InstantiateTypeArgumentsTOS 0, CP#26
+  DirectCall           1, CP#27
   Drop1
   PushNull
   ReturnTOS
@@ -491,16 +477,15 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 Nullable fields: [#lib::B::foo (field)]}
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::B
     : super core::Object::•()
@@ -522,69 +507,66 @@
   Push                 r0
   PushInt              3
   StoreContextVar      0, 2
-  Allocate             CP#11
+  Allocate             CP#10
   StoreLocal           r4
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#14
+  StoreFieldTOS        CP#13
   Push                 r4
-  PushConstant         CP#16
-  StoreFieldTOS        CP#17
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r4
   PushConstant         CP#0
-  StoreFieldTOS        CP#19
+  StoreFieldTOS        CP#18
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
   PushInt              10
-  DynamicCall          2, CP#25
+  DynamicCall          2, CP#26
   Drop1
   Push                 r3
   PushInt              11
-  DynamicCall          2, CP#26
+  DynamicCall          2, CP#27
   Drop1
   Push                 r2
-  PushConstant         CP#27
-  IndirectStaticCall   1, CP#7
+  DirectCall           1, CP#22
   Drop1
   Push                 r0
   LoadContextVar       0, 2
-  PushConstant         CP#28
-  IndirectStaticCall   1, CP#7
+  DirectCall           1, CP#22
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  PushConstant         CP#29
-  IndirectStaticCall   1, CP#7
+  DirectCall           1, CP#22
   Drop1
   Push                 r0
   PushInt              42
   StoreContextVar      0, 3
-  Allocate             CP#11
+  Allocate             CP#10
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#14
+  StoreFieldTOS        CP#13
   Push                 r3
-  PushConstant         CP#16
-  StoreFieldTOS        CP#17
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r3
-  PushConstant         CP#30
-  StoreFieldTOS        CP#19
+  PushConstant         CP#28
+  StoreFieldTOS        CP#18
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  DynamicCall          1, CP#34
+  DynamicCall          1, CP#32
   Drop1
   PushNull
   ReturnTOS
@@ -594,39 +576,37 @@
   [1] = InstanceField dart:core::_Closure::_context (field)
   [2] = Reserved
   [3] = Type dart:core::int
-  [4] = String 'y'
+  [4] = ObjectRef 'y'
   [5] = SubtypeTestCache
   [6] = ClosureFunction 1
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = InterfaceCall get target-name 'get:foo', arg-desc CP#7
-  [9] = Reserved
-  [10] = EndClosureFunctionScope
-  [11] = Class dart:core::_Closure
-  [12] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [13] = Reserved
-  [14] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [15] = Reserved
-  [16] = EmptyTypeArguments
-  [17] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [18] = Reserved
-  [19] = InstanceField dart:core::_Closure::_function (field)
-  [20] = Reserved
-  [21] = ICData dynamic target-name 'call', arg-desc CP#7
-  [22] = StaticICData target 'dart:core::print', arg-desc CP#7
-  [23] = EndClosureFunctionScope
-  [24] = ArgDesc num-args 2, num-type-args 0, names []
-  [25] = ICData dynamic target-name 'call', arg-desc CP#24
-  [26] = ICData dynamic target-name 'call', arg-desc CP#24
-  [27] = StaticICData target 'dart:core::print', arg-desc CP#7
-  [28] = StaticICData target 'dart:core::print', arg-desc CP#7
-  [29] = StaticICData target 'dart:core::print', arg-desc CP#7
-  [30] = ClosureFunction 2
-  [31] = InterfaceCall set target-name 'set:foo', arg-desc CP#24
-  [32] = Reserved
-  [33] = EndClosureFunctionScope
-  [34] = ICData dynamic target-name 'call', arg-desc CP#7
+  [7] = InterfaceCall '#lib::B::get:foo', ArgDesc num-args 1, num-type-args 0, names []
+  [8] = Reserved
+  [9] = EndClosureFunctionScope
+  [10] = Class dart:core::_Closure
+  [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [12] = Reserved
+  [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [14] = Reserved
+  [15] = EmptyTypeArguments
+  [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [17] = Reserved
+  [18] = InstanceField dart:core::_Closure::_function (field)
+  [19] = Reserved
+  [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [21] = ICData dynamic target-name 'call', arg-desc CP#20
+  [22] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [23] = Reserved
+  [24] = EndClosureFunctionScope
+  [25] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [26] = ICData dynamic target-name 'call', arg-desc CP#25
+  [27] = ICData dynamic target-name 'call', arg-desc CP#25
+  [28] = ClosureFunction 2
+  [29] = InterfaceCall '#lib::B::set:foo', ArgDesc num-args 2, num-type-args 0, names []
+  [30] = Reserved
+  [31] = EndClosureFunctionScope
+  [32] = ICData dynamic target-name 'call', arg-desc CP#20
 }
-Closure #lib::B::topLevel::<anonymous closure> (dart:core::int y) -> dart:core::Null
+Closure #lib::B::topLevel::'<anonymous closure>' (dart:core::int y) -> dart:core::Null
 ClosureBytecode {
   EntryFixed           2, 4
   CheckStack           0
@@ -665,20 +645,20 @@
   Push                 r0
   PushInt              4
   StoreContextVar      1, 1
-  Allocate             CP#11
+  Allocate             CP#10
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#14
+  StoreFieldTOS        CP#13
   Push                 r2
-  PushConstant         CP#16
-  StoreFieldTOS        CP#17
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r2
   PushConstant         CP#6
-  StoreFieldTOS        CP#19
+  StoreFieldTOS        CP#18
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
@@ -688,8 +668,7 @@
   Drop1
   Push                 r0
   LoadContextVar       1, 1
-  PushConstant         CP#22
-  IndirectStaticCall   1, CP#7
+  DirectCall           1, CP#22
   Drop1
 L1:
   PushNull
@@ -697,7 +676,7 @@
 
 }
 
-Closure #lib::B::topLevel::Closure/0::closure2 () -> void
+Closure #lib::B::topLevel::Closure/0::'closure2' () -> void
 ClosureBytecode {
   EntryFixed           1, 3
   CheckStack           0
@@ -716,7 +695,7 @@
   Push                 r0
   LoadContextParent
   LoadContextVar       0, 0
-  InterfaceCall        1, CP#8
+  InterfaceCall        1, CP#7
   Push                 r0
   LoadContextVar       1, 0
   AddInt
@@ -726,7 +705,7 @@
 
 }
 
-Closure #lib::B::topLevel::<anonymous closure> () -> dart:core::Null
+Closure #lib::B::topLevel::'<anonymous closure>' () -> dart:core::Null
 ClosureBytecode {
   EntryFixed           1, 3
   CheckStack           0
@@ -737,7 +716,7 @@
   LoadContextVar       0, 0
   Push                 r0
   LoadContextVar       0, 3
-  InterfaceCall        2, CP#31
+  InterfaceCall        2, CP#29
   Drop1
   PushNull
   ReturnTOS
@@ -783,15 +762,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C
     : super core::Object::•()
@@ -811,8 +789,7 @@
   PushInt              0
   CreateArrayTOS
   StoreLocal           r3
-  PushConstant         CP#2
-  IndirectStaticCall   2, CP#1
+  DirectCall           2, CP#1
   PopLocal             r2
   PushConstant         CP#0
   StoreLocal           r3
@@ -820,8 +797,7 @@
   PushInt              0
   CreateArrayTOS
   StoreLocal           r3
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#1
+  DirectCall           2, CP#1
   PopLocal             r4
   AllocateContext      1, 1
   StoreLocal           r1
@@ -840,44 +816,44 @@
   CompareIntLt
   JumpIfFalse          L1
   Push                 r2
-  Allocate             CP#8
+  Allocate             CP#7
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r3
-  PushConstant         CP#13
-  StoreFieldTOS        CP#14
+  PushConstant         CP#12
+  StoreFieldTOS        CP#13
   Push                 r3
-  PushConstant         CP#4
-  StoreFieldTOS        CP#16
+  PushConstant         CP#3
+  StoreFieldTOS        CP#15
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#5
-  InterfaceCall        2, CP#18
+  StoreFieldTOS        CP#4
+  InterfaceCall        2, CP#17
   Drop1
   Push                 r4
-  Allocate             CP#8
+  Allocate             CP#7
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r3
-  PushConstant         CP#13
-  StoreFieldTOS        CP#14
+  PushConstant         CP#12
+  StoreFieldTOS        CP#13
   Push                 r3
-  PushConstant         CP#20
-  StoreFieldTOS        CP#16
+  PushConstant         CP#19
+  StoreFieldTOS        CP#15
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#5
-  InterfaceCall        2, CP#18
+  StoreFieldTOS        CP#4
+  InterfaceCall        2, CP#17
   Drop1
   Push                 r0
   CloneContext         1, 1
@@ -903,38 +879,37 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::Function]
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#1
-  [3] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#1
-  [4] = ClosureFunction 0
-  [5] = InstanceField dart:core::_Closure::_context (field)
-  [6] = Reserved
-  [7] = EndClosureFunctionScope
-  [8] = Class dart:core::_Closure
-  [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [10] = Reserved
-  [11] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [12] = Reserved
-  [13] = EmptyTypeArguments
-  [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [15] = Reserved
-  [16] = InstanceField dart:core::_Closure::_function (field)
-  [17] = Reserved
-  [18] = InterfaceCall target-name 'add', arg-desc CP#1
-  [19] = Reserved
-  [20] = ClosureFunction 1
-  [21] = Type dart:core::int
-  [22] = String 'ii'
-  [23] = SubtypeTestCache
-  [24] = EndClosureFunctionScope
+  [0] = ObjectRef < dart:core::Function >
+  [1] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [2] = Reserved
+  [3] = ClosureFunction 0
+  [4] = InstanceField dart:core::_Closure::_context (field)
+  [5] = Reserved
+  [6] = EndClosureFunctionScope
+  [7] = Class dart:core::_Closure
+  [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [9] = Reserved
+  [10] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [11] = Reserved
+  [12] = EmptyTypeArguments
+  [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [14] = Reserved
+  [15] = InstanceField dart:core::_Closure::_function (field)
+  [16] = Reserved
+  [17] = InterfaceCall 'dart:core::List::add', ArgDesc num-args 2, num-type-args 0, names []
+  [18] = Reserved
+  [19] = ClosureFunction 1
+  [20] = Type dart:core::int
+  [21] = ObjectRef 'ii'
+  [22] = SubtypeTestCache
+  [23] = EndClosureFunctionScope
 }
-Closure #lib::C::testForLoop::<anonymous closure> () -> dart:core::int
+Closure #lib::C::testForLoop::'<anonymous closure>' () -> dart:core::int
 ClosureBytecode {
   EntryFixed           1, 2
   CheckStack           0
   Push                 FP[-5]
-  LoadFieldTOS         CP#5
+  LoadFieldTOS         CP#4
   PopLocal             r0
   Push                 r0
   LoadContextVar       1, 0
@@ -946,19 +921,19 @@
 
 }
 
-Closure #lib::C::testForLoop::<anonymous closure> (dart:core::int ii) -> dart:core::Null
+Closure #lib::C::testForLoop::'<anonymous closure>' (dart:core::int ii) -> dart:core::Null
 ClosureBytecode {
   EntryFixed           2, 3
   CheckStack           0
   Push                 FP[-6]
-  LoadFieldTOS         CP#5
+  LoadFieldTOS         CP#4
   PopLocal             r0
   Push                 FP[-5]
+  PushConstant         CP#20
+  PushNull
+  PushNull
   PushConstant         CP#21
-  PushNull
-  PushNull
-  PushConstant         CP#22
-  AssertAssignable     1, CP#23
+  AssertAssignable     1, CP#22
   Drop1
   Push                 r0
   Push                 FP[-5]
@@ -987,44 +962,43 @@
   Entry                5
   CheckStack           0
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   PopLocal             r2
 L2:
   CheckStack           1
   Push                 r2
-  InterfaceCall        1, CP#3
+  InterfaceCall        1, CP#2
   JumpIfFalse          L1
   AllocateContext      0, 1
   PopLocal             r0
   Push                 r0
   Push                 r2
-  InterfaceCall        1, CP#5
+  InterfaceCall        1, CP#4
   StoreContextVar      0, 0
-  Allocate             CP#11
+  Allocate             CP#10
   StoreLocal           r4
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#14
+  StoreFieldTOS        CP#13
   Push                 r4
-  PushConstant         CP#16
-  StoreFieldTOS        CP#17
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r4
-  PushConstant         CP#7
-  StoreFieldTOS        CP#19
+  PushConstant         CP#6
+  StoreFieldTOS        CP#18
   Push                 r4
   Push                 r0
-  StoreFieldTOS        CP#8
+  StoreFieldTOS        CP#7
   PopLocal             r3
   Push                 r3
   DynamicCall          1, CP#21
   Drop1
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#22
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#22
   Drop1
   Push                 r0
   LoadContextParent
@@ -1035,36 +1009,37 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:iterator', arg-desc CP#0
-  [2] = Reserved
-  [3] = InterfaceCall target-name 'moveNext', arg-desc CP#0
-  [4] = Reserved
-  [5] = InterfaceCall get target-name 'get:current', arg-desc CP#0
-  [6] = Reserved
-  [7] = ClosureFunction 0
-  [8] = InstanceField dart:core::_Closure::_context (field)
-  [9] = Reserved
-  [10] = EndClosureFunctionScope
-  [11] = Class dart:core::_Closure
-  [12] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [13] = Reserved
-  [14] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [15] = Reserved
-  [16] = EmptyTypeArguments
-  [17] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [18] = Reserved
-  [19] = InstanceField dart:core::_Closure::_function (field)
-  [20] = Reserved
-  [21] = ICData dynamic target-name 'call', arg-desc CP#0
-  [22] = StaticICData target 'dart:core::print', arg-desc CP#0
+  [0] = InterfaceCall 'dart:core::Iterable::get:iterator', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::Iterator::moveNext', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
+  [4] = InterfaceCall 'dart:core::Iterator::get:current', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
+  [6] = ClosureFunction 0
+  [7] = InstanceField dart:core::_Closure::_context (field)
+  [8] = Reserved
+  [9] = EndClosureFunctionScope
+  [10] = Class dart:core::_Closure
+  [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [12] = Reserved
+  [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [14] = Reserved
+  [15] = EmptyTypeArguments
+  [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [17] = Reserved
+  [18] = InstanceField dart:core::_Closure::_function (field)
+  [19] = Reserved
+  [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [21] = ICData dynamic target-name 'call', arg-desc CP#20
+  [22] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [23] = Reserved
 }
-Closure #lib::C::testForInLoop::<anonymous closure> () -> dart:core::Null
+Closure #lib::C::testForInLoop::'<anonymous closure>' () -> dart:core::Null
 ClosureBytecode {
   EntryFixed           1, 3
   CheckStack           0
   Push                 FP[-5]
-  LoadFieldTOS         CP#8
+  LoadFieldTOS         CP#7
   PopLocal             r0
   Push                 r0
   Push                 r0
@@ -1092,15 +1067,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::D<self::D::T>
     : super core::Object::•()
@@ -1145,7 +1119,7 @@
 ConstantPool {
   [0] = Type #lib::D::TypeParam/0
   [1] = TypeArgumentsField #lib::D
-  [2] = String 't'
+  [2] = ObjectRef 't'
   [3] = SubtypeTestCache
   [4] = ClosureFunction 0
   [5] = InstanceField dart:core::_Closure::_context (field)
@@ -1162,7 +1136,7 @@
   [16] = InstanceField dart:core::_Closure::_function (field)
   [17] = Reserved
 }
-Closure #lib::D::foo::<anonymous closure> () -> #lib::D::TypeParam/0
+Closure #lib::D::foo::'<anonymous closure>' () -> #lib::D::TypeParam/0
 ClosureBytecode {
   EntryFixed           1, 2
   CheckStack           0
@@ -1177,6 +1151,108 @@
 ]  method foo(generic-covariant-impl self::D::T t) → dynamic {
     return () → self::D::T => t;
   }
+[@vm.bytecode=
+Bytecode {
+  Entry                3
+  CheckStack           0
+  AllocateContext      0, 1
+  PopLocal             r0
+  Push                 r0
+  Push                 FP[-5]
+  StoreContextVar      0, 0
+  Allocate             CP#5
+  StoreLocal           r2
+  Push                 r2
+  Push                 FP[-5]
+  LoadTypeArgumentsField CP#6
+  StoreFieldTOS        CP#7
+  Push                 r2
+  PushNull
+  StoreFieldTOS        CP#9
+  Push                 r2
+  PushConstant         CP#11
+  StoreFieldTOS        CP#12
+  Push                 r2
+  PushConstant         CP#0
+  StoreFieldTOS        CP#14
+  Push                 r2
+  Push                 r0
+  StoreFieldTOS        CP#1
+  ReturnTOS
+}
+ConstantPool {
+  [0] = ClosureFunction 0
+  [1] = InstanceField dart:core::_Closure::_context (field)
+  [2] = Reserved
+  [3] = ClosureFunction 1
+  [4] = EndClosureFunctionScope
+  [5] = Class dart:core::_Closure
+  [6] = TypeArgumentsField #lib::D
+  [7] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [8] = Reserved
+  [9] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [10] = Reserved
+  [11] = EmptyTypeArguments
+  [12] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [13] = Reserved
+  [14] = InstanceField dart:core::_Closure::_function (field)
+  [15] = Reserved
+  [16] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [17] = ICData dynamic target-name 'call', arg-desc CP#16
+  [18] = EndClosureFunctionScope
+}
+Closure #lib::D::bar::'<anonymous closure>' () -> dart:core::Null
+ClosureBytecode {
+  EntryFixed           1, 4
+  CheckStack           0
+  Push                 FP[-5]
+  LoadFieldTOS         CP#1
+  PopLocal             r0
+  Allocate             CP#5
+  StoreLocal           r3
+  Push                 r3
+  Push                 r0
+  LoadContextVar       0, 0
+  LoadTypeArgumentsField CP#6
+  StoreFieldTOS        CP#7
+  Push                 r3
+  PushNull
+  StoreFieldTOS        CP#9
+  Push                 r3
+  PushConstant         CP#11
+  StoreFieldTOS        CP#12
+  Push                 r3
+  PushConstant         CP#3
+  StoreFieldTOS        CP#14
+  Push                 r3
+  Push                 r0
+  StoreFieldTOS        CP#1
+  PopLocal             r2
+  Push                 r2
+  DynamicCall          1, CP#17
+  Drop1
+  PushNull
+  ReturnTOS
+
+}
+
+Closure #lib::D::bar::Closure/0::'inner' () -> dart:core::Null
+ClosureBytecode {
+  EntryFixed           1, 2
+  CheckStack           0
+  Push                 FP[-5]
+  LoadFieldTOS         CP#1
+  PopLocal             r0
+  PushNull
+  ReturnTOS
+
+}
+]  method bar() → dynamic {
+    return () → core::Null {
+      function inner() → core::Null {}
+      [@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] inner.call();
+    };
+  }
 }
 [@vm.bytecode=
 Bytecode {
@@ -1218,7 +1294,7 @@
   [1] = InstanceField dart:core::_Closure::_context (field)
   [2] = Reserved
   [3] = Type dart:core::int
-  [4] = String 'y'
+  [4] = ObjectRef 'y'
   [5] = SubtypeTestCache
   [6] = EndClosureFunctionScope
   [7] = Class dart:core::_Closure
@@ -1231,10 +1307,10 @@
   [14] = Reserved
   [15] = InstanceField dart:core::_Closure::_function (field)
   [16] = Reserved
-  [17] = ArgDesc num-args 2, num-type-args 0, names []
+  [17] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
   [18] = ICData dynamic target-name 'call', arg-desc CP#17
 }
-Closure #lib::simpleClosure::<anonymous closure> (dart:core::int y) -> dart:core::Null
+Closure #lib::simpleClosure::'<anonymous closure>' (dart:core::int y) -> dart:core::Null
 ClosureBytecode {
   EntryFixed           2, 3
   CheckStack           0
@@ -1325,16 +1401,14 @@
   Push                 r0
   InstantiateType      CP#8
   StoreIndexedTOS
-  PushConstant         CP#10
-  IndirectStaticCall   2, CP#9
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#11
+  DirectCall           2, CP#9
+  DirectCall           1, CP#11
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::Type]
+  [0] = ObjectRef < dart:core::Type >
   [1] = Type #lib::callWithArgs::TypeParam/0
   [2] = Type #lib::callWithArgs::TypeParam/1
   [3] = Type #lib::callWithArgs::TypeParam/2
@@ -1343,10 +1417,10 @@
   [6] = Type #lib::callWithArgs::TypeParam/5
   [7] = Type #lib::callWithArgs::TypeParam/6
   [8] = Type #lib::callWithArgs::TypeParam/7
-  [9] = ArgDesc num-args 2, num-type-args 0, names []
-  [10] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#9
-  [11] = ArgDesc num-args 1, num-type-args 0, names []
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#11
+  [9] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [10] = Reserved
+  [11] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [12] = Reserved
 }
 ]static method callWithArgs<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic, T3 extends core::Object = dynamic, T4 extends core::Object = dynamic, T5 extends core::Object = dynamic, T6 extends core::Object = dynamic, T7 extends core::Object = dynamic, T8 extends core::Object = dynamic>() → void {
   core::print(<core::Type>[self::callWithArgs::T1, self::callWithArgs::T2, self::callWithArgs::T3, self::callWithArgs::T4, self::callWithArgs::T5, self::callWithArgs::T6, self::callWithArgs::T7, self::callWithArgs::T8]);
@@ -1361,49 +1435,43 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
-  InterfaceCall        2, CP#6
+  InterfaceCall        2, CP#5
   Drop1
-  PushConstant         CP#8
+  PushConstant         CP#7
   PushConstant         CP#2
   PushConstant         CP#1
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
-  InterfaceCall        2, CP#6
+  InterfaceCall        2, CP#5
   Drop1
+  PushConstant         CP#7
   PushConstant         CP#8
-  PushConstant         CP#10
   PushConstant         CP#1
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
-  InterfaceCall        2, CP#6
+  InterfaceCall        2, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [#lib::C3, #lib::C4]
+  [0] = ObjectRef < #lib::C3, #lib::C4 >
   [1] = Class #lib::A
-  [2] = TypeArgumentsForInstanceAllocation #lib::A [#lib::C1, #lib::C2]
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
-  [5] = ArgDesc num-args 1, num-type-args 2, names []
-  [6] = InterfaceCall target-name 'foo', arg-desc CP#5
-  [7] = Reserved
-  [8] = TypeArgs [dart:core::List < #lib::C3 >, dart:core::List < #lib::C4 >]
-  [9] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
-  [10] = TypeArgumentsForInstanceAllocation #lib::A [dart:core::List < #lib::C1 >, dart:core::List < #lib::C2 >]
-  [11] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
+  [2] = ObjectRef < #lib::C1, #lib::C2 >
+  [3] = DirectCall '#lib::A:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [4] = Reserved
+  [5] = InterfaceCall '#lib::A::foo', ArgDesc num-args 1, num-type-args 2, names []
+  [6] = Reserved
+  [7] = ObjectRef < dart:core::List < #lib::C3 >, dart:core::List < #lib::C4 > >
+  [8] = ObjectRef < dart:core::List < #lib::C1 >, dart:core::List < #lib::C2 > >
 }
 ]static method callA() → void {
   new self::A::•<self::C1, self::C2>().{self::A::foo}<self::C3, self::C4>();
@@ -1436,8 +1504,7 @@
   StoreLocal           r3
   PushConstant         CP#19
   StoreLocal           r6
-  PushConstant         CP#21
-  IndirectStaticCall   2, CP#20
+  DirectCall           2, CP#20
   Drop1
   Allocate             CP#14
   StoreLocal           r5
@@ -1473,10 +1540,10 @@
   [5] = EmptyTypeArguments
   [6] = InstanceField dart:core::_Closure::_function_type_arguments (field)
   [7] = Reserved
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = StaticICData target 'dart:_internal::_prependTypeArguments', arg-desc CP#8
+  [8] = DirectCall 'dart:_internal::_prependTypeArguments', ArgDesc num-args 4, num-type-args 0, names []
+  [9] = Reserved
   [10] = Type #lib::testPartialInstantiation::Closure/0::TypeParam/0
-  [11] = String 't'
+  [11] = ObjectRef 't'
   [12] = SubtypeTestCache
   [13] = EndClosureFunctionScope
   [14] = Class dart:core::_Closure
@@ -1484,11 +1551,11 @@
   [16] = Reserved
   [17] = InstanceField dart:core::_Closure::_function (field)
   [18] = Reserved
-  [19] = TypeArgs [dart:core::int]
-  [20] = ArgDesc num-args 2, num-type-args 0, names []
-  [21] = StaticICData target 'dart:_internal::_boundsCheckForPartialInstantiation', arg-desc CP#20
+  [19] = ObjectRef < dart:core::int >
+  [20] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names []
+  [21] = Reserved
 }
-Closure #lib::testPartialInstantiation::foo <dart:core::Object T> (#lib::testPartialInstantiation::Closure/0::TypeParam/0 t) -> void
+Closure #lib::testPartialInstantiation::'foo' <dart:core::Object T> (#lib::testPartialInstantiation::Closure/0::TypeParam/0 t) -> void
 ClosureBytecode {
   EntryFixed           2, 3
   CheckStack           0
@@ -1510,8 +1577,7 @@
   LoadFieldTOS         CP#6
   PushInt              0
   PushInt              1
-  PushConstant         CP#9
-  IndirectStaticCall   4, CP#8
+  DirectCall           4, CP#8
   PopLocal             r0
   Push                 FP[-5]
   PushConstant         CP#10
diff --git a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
index ec106c3..131cb14 100644
--- a/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
+++ b/pkg/vm/testcases/bytecode/deferred_lib.dart.expect
@@ -2,23 +2,23 @@
 import self as self;
 import "./hello.dart" as hel;
 
+import "#pkg/vm/testcases/bytecode/hello.dart" deferred as lib;
+
 [@vm.bytecode=
 Bytecode {
   Entry                1
   CheckStack           0
   PushNull
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   PopLocal             r0
-  PushConstant         CP#3
-  IndirectStaticCall   0, CP#2
+  DirectCall           0, CP#2
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:async::Future::value (constructor)', arg-desc CP#0
-  [2] = ArgDesc num-args 0, num-type-args 0, names []
-  [3] = StaticICData target '#pkg/vm/testcases/bytecode/hello.dart::main', arg-desc CP#2
+  [0] = DirectCall 'dart:async::Future::value (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = DirectCall '#pkg/vm/testcases/bytecode/hello.dart::main', ArgDesc num-args 0, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method callDeferred() → dynamic
   return let final dynamic #t1 = CheckLibraryIsLoaded(lib) in hel::main();
@@ -27,13 +27,12 @@
   Entry                0
   CheckStack           0
   PushNull
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:async::Future::value (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:async::Future::value (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]static method testLoadLibrary() → dynamic
   return LoadLibrary(lib);
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart.expect b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
index 695f1a9..f5f3808 100644
--- a/pkg/vm/testcases/bytecode/field_initializers.dart.expect
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
@@ -25,8 +25,7 @@
   PushInt              44
   StoreFieldTOS        CP#2
   Push                 FP[-6]
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  DirectCall           1, CP#6
   Drop1
   PushNull
   ReturnTOS
@@ -39,8 +38,8 @@
   [3] = Reserved
   [4] = InstanceField #lib::A::foo4 (field)
   [5] = Reserved
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#6
+  [6] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [7] = Reserved
 }
 ]  constructor •(core::int foo4) → self::A
     : self::A::foo1 = null, self::A::foo4 = foo4, self::A::foo5 = 44, super core::Object::•()
@@ -64,8 +63,7 @@
   AddInt
   StoreFieldTOS        CP#2
   Push                 FP[-7]
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  DirectCall           1, CP#6
   Drop1
   PushNull
   ReturnTOS
@@ -78,8 +76,8 @@
   [3] = Reserved
   [4] = InstanceField #lib::A::foo1 (field)
   [5] = Reserved
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#6
+  [6] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [7] = Reserved
 }
 ]  constructor constr2(core::int x, core::int y) → self::A
     : self::A::foo4 = null, self::A::foo1 = x, self::A::foo5 = y.{core::num::+}(1), super core::Object::•()
@@ -90,15 +88,14 @@
   CheckStack           0
   Push                 FP[-5]
   PushInt              45
-  PushConstant         CP#1
-  IndirectStaticCall   2, CP#0
+  DirectCall           2, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::A:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  constructor redirecting1() → self::A
     : this self::A::•(45)
@@ -112,15 +109,14 @@
   Push                 FP[-6]
   Push                 FP[-5]
   MulInt
-  PushConstant         CP#1
-  IndirectStaticCall   3, CP#0
+  DirectCall           3, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 3, num-type-args 0, names []
-  [1] = StaticICData target '#lib::A::constr2 (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::A::constr2 (constructor)', ArgDesc num-args 3, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  constructor redirecting2(core::int a, core::int b, core::int c) → self::A
     : this self::A::constr2(a, b.{core::num::*}(c))
@@ -139,8 +135,7 @@
   StoreFieldTOS        CP#0
   Push                 FP[-5]
   PushInt              49
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#2
   Drop1
   PushNull
   ReturnTOS
@@ -148,8 +143,8 @@
 ConstantPool {
   [0] = InstanceField #lib::B::foo6 (field)
   [1] = Reserved
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#2
+  [2] = DirectCall '#lib::A:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]  constructor •() → self::B
     : super self::A::•(49)
@@ -168,8 +163,7 @@
   Push                 FP[-6]
   Push                 FP[-5]
   PushInt              51
-  PushConstant         CP#3
-  IndirectStaticCall   4, CP#2
+  DirectCall           4, CP#2
   Drop1
   PushNull
   ReturnTOS
@@ -177,8 +171,8 @@
 ConstantPool {
   [0] = InstanceField #lib::B::foo6 (field)
   [1] = Reserved
-  [2] = ArgDesc num-args 4, num-type-args 0, names []
-  [3] = StaticICData target '#lib::A::redirecting2 (constructor)', arg-desc CP#2
+  [2] = DirectCall '#lib::A::redirecting2 (constructor)', ArgDesc num-args 4, num-type-args 0, names []
+  [3] = Reserved
 }
 ]  constructor c2(core::int i, core::int j) → self::B
     : self::B::foo6 = 50, super self::A::redirecting2(i, j, 51)
diff --git a/pkg/vm/testcases/bytecode/hello.dart.expect b/pkg/vm/testcases/bytecode/hello.dart.expect
index 0c5c9de..bcddfbb 100644
--- a/pkg/vm/testcases/bytecode/hello.dart.expect
+++ b/pkg/vm/testcases/bytecode/hello.dart.expect
@@ -7,16 +7,15 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = String 'Hello, Dart Bytecode!'
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [0] = ObjectRef 'Hello, Dart Bytecode!'
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]static method main() → dynamic {
   core::print("Hello, Dart Bytecode!");
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
index 1407a9e..7c6bf14 100644
--- a/pkg/vm/testcases/bytecode/instance_creation.dart.expect
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -11,8 +11,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   PushInt              4
@@ -40,25 +39,25 @@
   PushNull
   InstantiateType      CP#6
   StoreIndexedTOS
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#0
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#7
+  DirectCall           1, CP#9
   Drop1
   PushNull
   ReturnTOS
 }
 Nullable fields: [#lib::Base::t1 (field), #lib::Base::t2 (field)]}
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
-  [2] = String 'Base: '
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = ObjectRef 'Base: '
   [3] = Type #lib::Base::TypeParam/0
   [4] = TypeArgumentsField #lib::Base
-  [5] = String ', '
+  [5] = ObjectRef ', '
   [6] = Type #lib::Base::TypeParam/1
-  [7] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#0
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#0
+  [7] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [8] = Reserved
+  [9] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [10] = Reserved
 }
 ]  constructor •() → self::Base<self::Base::T1, self::Base::T2>
     : super core::Object::•() {
@@ -71,15 +70,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-6]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::Base:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  constructor •(core::String s) → self::A
     : super self::Base::•()
@@ -91,8 +89,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   PushInt              2
@@ -109,22 +106,22 @@
   PushNull
   InstantiateType      CP#3
   StoreIndexedTOS
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#0
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#5
+  DirectCall           1, CP#7
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base::'' (constructor)', arg-desc CP#0
-  [2] = String 'B: '
+  [0] = DirectCall '#lib::Base:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = ObjectRef 'B: '
   [3] = Type #lib::B::TypeParam/0
   [4] = TypeArgumentsField #lib::B
-  [5] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#0
-  [6] = StaticICData target 'dart:core::print', arg-desc CP#0
+  [5] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
+  [7] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [8] = Reserved
 }
 ]  constructor •() → self::B<self::B::T>
     : super self::Base::•() {
@@ -137,8 +134,7 @@
   Entry                1
   CheckStack           0
   Push                 FP[-6]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   PushInt              2
@@ -152,20 +148,20 @@
   PushInt              1
   Push                 FP[-5]
   StoreIndexedTOS
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#0
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#3
+  DirectCall           1, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
-  [2] = String 'C: '
-  [3] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#0
-  [4] = StaticICData target 'dart:core::print', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = ObjectRef 'C: '
+  [3] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [4] = Reserved
+  [5] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
 }
 ]  constructor •(core::String s) → self::C
     : super core::Object::•() {
@@ -178,15 +174,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::E<self::E::K, self::E::V>
     : super core::Object::•()
@@ -197,14 +192,13 @@
   CheckStack           0
   Push                 FP[-5]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::E
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::Map::'' (constructor)', arg-desc CP#1
+  [1] = DirectCall 'dart:core::Map:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]  method test_reuse1() → dynamic
     return core::Map::•<self::E::K, self::E::V>();
@@ -215,15 +209,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::E::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::E:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::F<self::F::K, self::F::V>
     : super self::E::•()
@@ -234,14 +227,13 @@
   CheckStack           0
   Push                 FP[-5]
   LoadTypeArgumentsField CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::F
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::Map::'' (constructor)', arg-desc CP#1
+  [1] = DirectCall 'dart:core::Map:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]  method test_reuse2() → dynamic
     return core::Map::•<core::String, core::List<self::F::V>>();
@@ -252,15 +244,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  constructor •() → self::G<self::G::K, self::G::V>
     : super core::Object::•()
@@ -276,16 +267,15 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::H
-  [1] = TypeArgumentsForInstanceAllocation #lib::H [dart:core::String, #lib::G::test_factory (constructor)::TypeParam/0, #lib::G::test_factory (constructor)::TypeParam/1]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target '#lib::H::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < #lib::G::test_factory (constructor)::TypeParam/0, #lib::G::test_factory (constructor)::TypeParam/1, dart:core::String, #lib::G::test_factory (constructor)::TypeParam/0, #lib::G::test_factory (constructor)::TypeParam/1 >
+  [2] = DirectCall '#lib::H:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]  static factory test_factory<K extends core::Object = dynamic, V extends core::Object = dynamic>() → self::G<self::G::test_factory::K, self::G::test_factory::V>
     return new self::H::•<core::String, self::G::test_factory::K, self::G::test_factory::V>();
@@ -296,15 +286,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::G::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::G:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::H<self::H::P1, self::H::P2, self::H::P3>
     : super self::G::•()
@@ -316,15 +305,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-6]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  constructor •(dynamic param) → self::I
     : super core::Object::•()
@@ -340,17 +328,16 @@
   StoreLocal           r2
   Push                 r2
   Push                 r1
-  PushConstant         CP#4
-  IndirectStaticCall   2, CP#3
+  DirectCall           2, CP#3
   Drop1
   ReturnTOS
 }
 ConstantPool {
-  [0] = String 'param'
-  [1] = Null
+  [0] = ObjectRef 'param'
+  [1] = ObjectRef null
   [2] = Class #lib::I
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = StaticICData target '#lib::I::'' (constructor)', arg-desc CP#3
+  [3] = DirectCall '#lib::I:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [4] = Reserved
 }
 ]  static factory test_factory2({dynamic param = null}) → self::I
     return new self::I::•(param);
@@ -380,15 +367,14 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::TestTypeArgReuse
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target '#lib::TestTypeArgReuse::'' (constructor)', arg-desc CP#1
+  [1] = DirectCall '#lib::TestTypeArgReuse:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]  static factory •<A extends core::Object = dynamic, B extends core::Object = dynamic>() → self::K<self::K::•::A, self::K::•::B>
     return new self::TestTypeArgReuse::•<self::K::•::A, self::K::•::B>();
@@ -399,15 +385,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::Base:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::TestTypeArgReuse<self::TestTypeArgReuse::P, self::TestTypeArgReuse::Q>
     : super self::Base::•()
@@ -421,16 +406,15 @@
   StoreLocal           r0
   Push                 r0
   PushConstant         CP#1
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#2
   Drop1
   ReturnTOS
 }
 ConstantPool {
   [0] = Class #lib::C
-  [1] = String 'hello'
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = StaticICData target '#lib::C::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef 'hello'
+  [2] = DirectCall '#lib::C:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method foo1() → dynamic
   return new self::C::•("hello");
@@ -444,8 +428,7 @@
   StoreLocal           r0
   Push                 r0
   PushConstant         CP#2
-  PushConstant         CP#4
-  IndirectStaticCall   2, CP#3
+  DirectCall           2, CP#3
   Drop1
   Drop1
   PushConstant         CP#6
@@ -453,8 +436,7 @@
   AllocateT
   StoreLocal           r0
   Push                 r0
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#7
+  DirectCall           1, CP#7
   Drop1
   Drop1
   PushNull
@@ -462,14 +444,14 @@
 }
 ConstantPool {
   [0] = Class #lib::A
-  [1] = TypeArgumentsForInstanceAllocation #lib::A []
-  [2] = String 'hi'
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#3
+  [1] = ObjectRef < dart:core::int, dart:core::String >
+  [2] = ObjectRef 'hi'
+  [3] = DirectCall '#lib::A:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [4] = Reserved
   [5] = Class #lib::B
-  [6] = TypeArgumentsForInstanceAllocation #lib::B [dart:core::int]
-  [7] = ArgDesc num-args 1, num-type-args 0, names []
-  [8] = StaticICData target '#lib::B::'' (constructor)', arg-desc CP#7
+  [6] = ObjectRef < dart:core::List < dart:core::int >, dart:core::String, dart:core::int >
+  [7] = DirectCall '#lib::B:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [8] = Reserved
 }
 ]static method foo2() → void {
   new self::A::•("hi");
@@ -487,8 +469,7 @@
   AllocateT
   StoreLocal           r1
   Push                 r1
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   Drop1
   PushNull
@@ -496,9 +477,9 @@
 }
 ConstantPool {
   [0] = Class #lib::B
-  [1] = TypeArgumentsForInstanceAllocation #lib::B [dart:core::List < #lib::foo3::TypeParam/0 >]
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target '#lib::B::'' (constructor)', arg-desc CP#2
+  [1] = ObjectRef < dart:core::List < dart:core::List < #lib::foo3::TypeParam/0 > >, dart:core::String, dart:core::List < #lib::foo3::TypeParam/0 > >
+  [2] = DirectCall '#lib::B:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method foo3<T extends core::Object = dynamic>() → void {
   new self::B::•<core::List<self::foo3::T>>();
@@ -508,16 +489,15 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgumentsForInstanceAllocation #lib::G [dart:core::int, dart:core::List < dart:core::String >]
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target '#lib::G::test_factory (constructor)', arg-desc CP#1
+  [0] = ObjectRef < dart:core::int, dart:core::List < dart:core::String > >
+  [1] = DirectCall '#lib::G::test_factory (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]static method foo4() → void {
   self::G::test_factory<core::int, core::List<core::String>>();
@@ -527,22 +507,20 @@
   Entry                0
   CheckStack           0
   PushNull
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   PushInt              42
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#2
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::I::test_factory2 (constructor)', arg-desc CP#0
-  [2] = ArgDesc num-args 2, num-type-args 0, names [param]
-  [3] = StaticICData target '#lib::I::test_factory2 (constructor)', arg-desc CP#2
+  [0] = DirectCall '#lib::I::test_factory2 (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = DirectCall '#lib::I::test_factory2 (constructor)', ArgDesc num-args 2, num-type-args 0, names ['param']
+  [3] = Reserved
 }
 ]static method foo5() → void {
   self::I::test_factory2();
@@ -554,14 +532,13 @@
   CheckStack           0
   PushConstant         CP#0
   PushInt              0
-  PushConstant         CP#2
-  IndirectStaticCall   2, CP#1
+  DirectCall           2, CP#1
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgumentsForInstanceAllocation dart:core::_GrowableList [dart:core::String]
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::_GrowableList::'' (constructor)', arg-desc CP#1
+  [0] = ObjectRef < dart:core::String >
+  [1] = DirectCall 'dart:core::_GrowableList:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [2] = Reserved
 }
 ]static method foo6() → dynamic
   return core::_GrowableList::•<core::String>(0);
@@ -571,14 +548,13 @@
   CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
-  PushConstant         CP#2
-  IndirectStaticCall   2, CP#1
+  DirectCall           2, CP#1
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgumentsForInstanceAllocation dart:core::_List [dart:core::int]
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::_List::'' (constructor)', arg-desc CP#1
+  [0] = ObjectRef < dart:core::int >
+  [1] = DirectCall 'dart:core::_List:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [2] = Reserved
 }
 ]static method foo7(core::int n) → dynamic
   return core::_List::•<core::int>(n);
@@ -586,26 +562,24 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#1
-  IndirectStaticCall   0, CP#0
+  DirectCall           0, CP#0
   Drop1
-  PushConstant         CP#2
-  IndirectStaticCall   0, CP#0
+  DirectCall           0, CP#2
   Drop1
-  PushConstant         CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#4
+  DirectCall           1, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 0, num-type-args 0, names []
-  [1] = StaticICData target '#lib::foo1', arg-desc CP#0
-  [2] = StaticICData target '#lib::foo2', arg-desc CP#0
-  [3] = TypeArgs [dart:core::String]
-  [4] = ArgDesc num-args 0, num-type-args 1, names []
-  [5] = StaticICData target '#lib::foo3', arg-desc CP#4
+  [0] = DirectCall '#lib::foo1', ArgDesc num-args 0, num-type-args 0, names []
+  [1] = Reserved
+  [2] = DirectCall '#lib::foo2', ArgDesc num-args 0, num-type-args 0, names []
+  [3] = Reserved
+  [4] = ObjectRef < dart:core::String >
+  [5] = DirectCall '#lib::foo3', ArgDesc num-args 0, num-type-args 1, names []
+  [6] = Reserved
 }
 ]static method main() → dynamic {
   self::foo1();
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
index 4649642..bef20c6 100644
--- a/pkg/vm/testcases/bytecode/literals.dart.expect
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -10,80 +10,55 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#13
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 0
-  [2] = String 'A.elem1'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
-  [4] = Int 1
-  [5] = String 'A.elem2'
-  [6] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#4, #lib::A::_name (field): CP#5}
-  [7] = Int 2
-  [8] = String 'A.elem3'
-  [9] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#7, #lib::A::_name (field): CP#8}
-  [10] = Int 3
-  [11] = String 'A.elem4'
-  [12] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#10, #lib::A::_name (field): CP#11}
-  [13] = List type-arg #lib::A, entries CP# [3, 6, 9, 12]
+  [0] = ObjectRef const <#lib::A> [const #lib::A {#lib::A::index (field): const 0, #lib::A::_name (field): 'A.elem1'}, const #lib::A {#lib::A::index (field): const 1, #lib::A::_name (field): 'A.elem2'}, const #lib::A {#lib::A::index (field): const 2, #lib::A::_name (field): 'A.elem3'}, const #lib::A {#lib::A::index (field): const 3, #lib::A::_name (field): 'A.elem4'}]
 }
 ]  static const field core::List<self::A> values = const <self::A>[self::A::elem1, self::A::elem2, self::A::elem3, self::A::elem4];
 [@vm.bytecode=
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 0
-  [2] = String 'A.elem1'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
+  [0] = ObjectRef const #lib::A {#lib::A::index (field): const 0, #lib::A::_name (field): 'A.elem1'}
 }
 ]  static const field self::A elem1 = const self::A::•(0, "A.elem1");
 [@vm.bytecode=
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 1
-  [2] = String 'A.elem2'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
+  [0] = ObjectRef const #lib::A {#lib::A::index (field): const 1, #lib::A::_name (field): 'A.elem2'}
 }
 ]  static const field self::A elem2 = const self::A::•(1, "A.elem2");
 [@vm.bytecode=
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 2
-  [2] = String 'A.elem3'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
+  [0] = ObjectRef const #lib::A {#lib::A::index (field): const 2, #lib::A::_name (field): 'A.elem3'}
 }
 ]  static const field self::A elem3 = const self::A::•(2, "A.elem3");
 [@vm.bytecode=
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 3
-  [2] = String 'A.elem4'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
+  [0] = ObjectRef const #lib::A {#lib::A::index (field): const 3, #lib::A::_name (field): 'A.elem4'}
 }
 ]  static const field self::A elem4 = const self::A::•(3, "A.elem4");
 [@vm.bytecode=
@@ -97,8 +72,7 @@
   Push                 FP[-5]
   StoreFieldTOS        CP#2
   Push                 FP[-7]
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#4
   Drop1
   PushNull
   ReturnTOS
@@ -108,8 +82,8 @@
   [1] = Reserved
   [2] = InstanceField #lib::A::_name (field)
   [3] = Reserved
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#4
+  [4] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
 }
 ]  const constructor •(core::int index, core::String _name) → self::A
     : self::A::index = index, self::A::_name = _name, super core::Object::•()
@@ -119,13 +93,12 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::A::get:_name', arg-desc CP#0
+  [0] = DirectCall '#lib::A::get:_name', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  method toString() → core::String
     return this.{=self::A::_name};
@@ -140,8 +113,7 @@
   Push                 FP[-5]
   StoreFieldTOS        CP#0
   Push                 FP[-6]
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#2
+  DirectCall           1, CP#2
   Drop1
   PushNull
   ReturnTOS
@@ -149,8 +121,8 @@
 ConstantPool {
   [0] = InstanceField #lib::B::i (field)
   [1] = Reserved
-  [2] = ArgDesc num-args 1, num-type-args 0, names []
-  [3] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#2
+  [2] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]  const constructor •(core::int i) → self::B
     : self::B::i = i, super core::Object::•()
@@ -171,8 +143,7 @@
   Push                 FP[-5]
   PushInt              5
   MulInt
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#2
   Drop1
   PushNull
   ReturnTOS
@@ -180,8 +151,8 @@
 ConstantPool {
   [0] = InstanceField #lib::C::j (field)
   [1] = Reserved
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = StaticICData target '#lib::B::'' (constructor)', arg-desc CP#2
+  [2] = DirectCall '#lib::B:: (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]  const constructor •(core::int a, core::int b, core::int c) → self::C
     : self::C::j = a.{core::num::+}(b), super self::B::•(c.{core::num::*}(5))
@@ -203,20 +174,19 @@
   Push                 r2
   StoreFieldTOS        CP#3
   Push                 r0
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
+  [0] = ObjectRef null
   [1] = InstanceField #lib::D::x (field)
   [2] = Reserved
   [3] = InstanceField #lib::D::y (field)
   [4] = Reserved
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#5
+  [5] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
 }
 ]  const constructor •(dynamic x, [dynamic y = null]) → self::D
     : self::D::x = x, self::D::y = y, super core::Object::•()
@@ -228,15 +198,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  const constructor •() → self::E<self::E::T>
     : super core::Object::•()
@@ -248,15 +217,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::E::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::E:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  const constructor •() → self::F<self::F::P, self::F::Q>
     : super self::E::•()
@@ -266,14 +234,11 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 2
-  [2] = String 'A.elem3'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
+  [0] = ObjectRef const #lib::A {#lib::A::index (field): const 2, #lib::A::_name (field): 'A.elem3'}
 }
 ]static const field self::A c1 = self::A::elem3;
 static const field core::String c2 = "hello!";
@@ -291,28 +256,22 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 3
-  [2] = Int 15
-  [3] = Instance #lib::C type-args CP#0 {#lib::C::j (field): CP#1, #lib::B::i (field): CP#2}
+  [0] = ObjectRef const #lib::C {#lib::C::j (field): const 3, #lib::B::i (field): const 15}
 }
 ]static const field self::C c4 = const self::C::•(1, 2, 3);
 [@vm.bytecode=
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 4
-  [2] = Instance #lib::B type-args CP#0 {#lib::B::i (field): CP#1}
-  [3] = Instance #lib::D type-args CP#0 {#lib::D::x (field): CP#2, #lib::D::y (field): CP#0}
+  [0] = ObjectRef const #lib::D {#lib::D::x (field): const #lib::B {#lib::B::i (field): const 4}, #lib::D::y (field): null}
 }
 ]static const field self::D c5 = const self::D::•(const self::B::•(4));
 static field core::double fieldWithDoubleLiteralInitializer = 1.0;
@@ -320,47 +279,31 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#0
+  DirectCall           1, CP#1
   Drop1
-  PushConstant         CP#6
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#3
+  DirectCall           1, CP#1
   Drop1
   PushInt              6
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#1
   Drop1
-  PushConstant         CP#11
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#4
+  DirectCall           1, CP#1
   Drop1
-  PushConstant         CP#15
-  PushConstant         CP#16
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#5
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Null
-  [1] = Int 2
-  [2] = String 'A.elem3'
-  [3] = Instance #lib::A type-args CP#0 {#lib::A::index (field): CP#1, #lib::A::_name (field): CP#2}
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [6] = String 'hello!'
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [9] = Int 3
-  [10] = Int 15
-  [11] = Instance #lib::C type-args CP#0 {#lib::C::j (field): CP#9, #lib::B::i (field): CP#10}
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [13] = Int 4
-  [14] = Instance #lib::B type-args CP#0 {#lib::B::i (field): CP#13}
-  [15] = Instance #lib::D type-args CP#0 {#lib::D::x (field): CP#14, #lib::D::y (field): CP#0}
-  [16] = StaticICData target 'dart:core::print', arg-desc CP#4
+  [0] = ObjectRef const #lib::A {#lib::A::index (field): const 2, #lib::A::_name (field): 'A.elem3'}
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
+  [3] = ObjectRef 'hello!'
+  [4] = ObjectRef const #lib::C {#lib::C::j (field): const 3, #lib::B::i (field): const 15}
+  [5] = ObjectRef const #lib::D {#lib::D::x (field): const #lib::B {#lib::B::i (field): const 4}, #lib::D::y (field): null}
 }
 ]static method test_constants1() → void {
   core::print(self::c1);
@@ -374,66 +317,34 @@
   Entry                0
   CheckStack           0
   PushInt              42
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushConstant         CP#2
+  DirectCall           1, CP#0
+  Drop1
   PushConstant         CP#3
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
-  PushConstant         CP#7
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#0
+  PushConstant         CP#4
+  DirectCall           1, CP#0
   Drop1
-  PushConstant         CP#11
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#0
+  PushConstant         CP#5
+  DirectCall           1, CP#0
   Drop1
-  PushConstant         CP#20
-  PushConstant         CP#21
-  IndirectStaticCall   1, CP#0
-  Drop1
-  PushConstant         CP#31
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#0
+  PushConstant         CP#6
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::print', arg-desc CP#0
-  [2] = String 'foo'
-  [3] = StaticICData target 'dart:core::print', arg-desc CP#0
-  [4] = Null
-  [5] = Int 1
-  [6] = String 'A.elem2'
-  [7] = Instance #lib::A type-args CP#4 {#lib::A::index (field): CP#5, #lib::A::_name (field): CP#6}
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#0
-  [9] = Int 42
-  [10] = Type dart:core::int
-  [11] = List type-arg dart:core::Object, entries CP# [9, 2, 10]
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#0
-  [13] = TypeArgumentsForInstanceAllocation dart:core::_ImmutableMap [dart:core::String, #lib::A]
-  [14] = String 'E2'
-  [15] = String 'E4'
-  [16] = Int 3
-  [17] = String 'A.elem4'
-  [18] = Instance #lib::A type-args CP#4 {#lib::A::index (field): CP#16, #lib::A::_name (field): CP#17}
-  [19] = List type-arg dynamic, entries CP# [14, 7, 15, 18]
-  [20] = Instance dart:core::_ImmutableMap type-args CP#13 {dart:core::_ImmutableMap::_kvPairs (field): CP#19}
-  [21] = StaticICData target 'dart:core::print', arg-desc CP#0
-  [22] = Int 9
-  [23] = Int 30
-  [24] = Instance #lib::C type-args CP#4 {#lib::C::j (field): CP#22, #lib::B::i (field): CP#23}
-  [25] = TypeArgumentsForInstanceAllocation dart:core::_ImmutableMap [dart:core::String, dart:core::Object]
-  [26] = String 'bar'
-  [27] = Int 6
-  [28] = Instance #lib::B type-args CP#4 {#lib::B::i (field): CP#27}
-  [29] = List type-arg dynamic, entries CP# [2, 9, 26, 28]
-  [30] = Instance dart:core::_ImmutableMap type-args CP#25 {dart:core::_ImmutableMap::_kvPairs (field): CP#29}
-  [31] = Instance #lib::D type-args CP#4 {#lib::D::x (field): CP#24, #lib::D::y (field): CP#30}
-  [32] = StaticICData target 'dart:core::print', arg-desc CP#0
+  [0] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = ObjectRef 'foo'
+  [3] = ObjectRef const #lib::A {#lib::A::index (field): const 1, #lib::A::_name (field): 'A.elem2'}
+  [4] = ObjectRef const <dart:core::Object> [const 42, 'foo', dart:core::int]
+  [5] = ObjectRef const dart:core::_ImmutableMap < dart:core::String, #lib::A > {dart:core::_ImmutableMap::_kvPairs (field): const <dynamic> ['E2', const #lib::A {#lib::A::index (field): const 1, #lib::A::_name (field): 'A.elem2'}, 'E4', const #lib::A {#lib::A::index (field): const 3, #lib::A::_name (field): 'A.elem4'}]}
+  [6] = ObjectRef const #lib::D {#lib::D::x (field): const #lib::C {#lib::C::j (field): const 9, #lib::B::i (field): const 30}, #lib::D::y (field): const dart:core::_ImmutableMap < dart:core::String, dart:core::Object > {dart:core::_ImmutableMap::_kvPairs (field): const <dynamic> ['foo', const 42, 'bar', const #lib::B {#lib::B::i (field): const 6}]}}
 }
 ]static method test_constants2() → void {
   core::print(42);
@@ -465,10 +376,8 @@
   PushInt              2
   PushInt              3
   StoreIndexedTOS
-  PushConstant         CP#2
-  IndirectStaticCall   2, CP#1
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
+  DirectCall           2, CP#1
+  DirectCall           1, CP#3
   Drop1
   PushConstant         CP#5
   StoreLocal           r0
@@ -489,27 +398,23 @@
   PushInt              2
   PushConstant         CP#9
   StoreIndexedTOS
-  PushConstant         CP#10
-  IndirectStaticCall   2, CP#1
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#3
+  DirectCall           2, CP#1
+  DirectCall           1, CP#3
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::int]
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#1
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [5] = TypeArgs [dart:core::String]
-  [6] = String 'a'
-  [7] = InterfaceCall target-name 'toString', arg-desc CP#3
+  [0] = ObjectRef < dart:core::int >
+  [1] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [2] = Reserved
+  [3] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [4] = Reserved
+  [5] = ObjectRef < dart:core::String >
+  [6] = ObjectRef 'a'
+  [7] = InterfaceCall 'dart:core::int::toString', ArgDesc num-args 1, num-type-args 0, names []
   [8] = Reserved
-  [9] = String 'b'
-  [10] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#1
-  [11] = StaticICData target 'dart:core::print', arg-desc CP#3
+  [9] = ObjectRef 'b'
 }
 ]static method test_list_literal(core::int a) → void {
   core::print(<core::int>[1, a, 3]);
@@ -541,10 +446,8 @@
   PushInt              3
   PushInt              2
   StoreIndexedTOS
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#4
+  DirectCall           2, CP#2
+  DirectCall           1, CP#4
   Drop1
   PushConstant         CP#6
   PushConstant         CP#1
@@ -568,23 +471,19 @@
   PushInt              3
   PushInt              3
   StoreIndexedTOS
-  PushConstant         CP#10
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#2
+  DirectCall           1, CP#4
+  Drop1
+  PushNull
+  Push                 r0
+  InstantiateTypeArgumentsTOS 0, CP#10
   PushConstant         CP#11
-  IndirectStaticCall   1, CP#4
+  DirectCall           2, CP#2
+  DirectCall           1, CP#4
   Drop1
   PushNull
   Push                 r0
   InstantiateTypeArgumentsTOS 0, CP#12
-  PushConstant         CP#13
-  PushConstant         CP#14
-  IndirectStaticCall   2, CP#2
-  PushConstant         CP#15
-  IndirectStaticCall   1, CP#4
-  Drop1
-  PushNull
-  Push                 r0
-  InstantiateTypeArgumentsTOS 0, CP#16
   PushConstant         CP#1
   PushInt              2
   CreateArrayTOS
@@ -597,34 +496,26 @@
   PushInt              1
   PushInt              4
   StoreIndexedTOS
-  PushConstant         CP#17
-  IndirectStaticCall   2, CP#2
-  PushConstant         CP#18
-  IndirectStaticCall   1, CP#4
+  DirectCall           2, CP#2
+  DirectCall           1, CP#4
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::int, dart:core::int]
-  [1] = TypeArgs [dynamic]
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [6] = TypeArgs [dart:core::String, dart:core::int]
-  [7] = String 'foo'
-  [8] = InterfaceCall target-name 'toString', arg-desc CP#4
+  [0] = ObjectRef < dart:core::int, dart:core::int >
+  [1] = ObjectRef < dynamic >
+  [2] = DirectCall 'dart:core::Map::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
+  [4] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
+  [6] = ObjectRef < dart:core::String, dart:core::int >
+  [7] = ObjectRef 'foo'
+  [8] = InterfaceCall 'dart:core::int::toString', ArgDesc num-args 1, num-type-args 0, names []
   [9] = Reserved
-  [10] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
-  [11] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [12] = TypeArgs [dart:core::String, #lib::test_map_literal::TypeParam/0]
-  [13] = List type-arg dynamic, entries CP# []
-  [14] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
-  [15] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [16] = TypeArgs [#lib::test_map_literal::TypeParam/0, dart:core::int]
-  [17] = StaticICData target 'dart:core::Map::_fromLiteral (constructor)', arg-desc CP#2
-  [18] = StaticICData target 'dart:core::print', arg-desc CP#4
+  [10] = ObjectRef < dart:core::String, #lib::test_map_literal::TypeParam/0 >
+  [11] = ObjectRef const <dynamic> []
+  [12] = ObjectRef < #lib::test_map_literal::TypeParam/0, dart:core::int >
 }
 ]static method test_map_literal<T extends core::Object = dynamic>(core::int a, core::int b, self::test_map_literal::T c) → void {
   core::print(<core::int, core::int>{1: a, b: 2});
@@ -637,22 +528,19 @@
   Entry                0
   CheckStack           0
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushConstant         CP#3
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = Symbol test_symbol
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [3] = Symbol _private_symbol
-  [4] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [0] = ObjectRef const 'test_symbol'
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
+  [3] = ObjectRef const '_private_symbol'
 }
 ]static method test_symbol() → void {
   core::print(#test_symbol);
@@ -664,24 +552,21 @@
   CheckStack           0
   CheckFunctionTypeArgs 1, r0
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushNull
   Push                 r0
   InstantiateType      CP#3
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
   [0] = Type dart:core::String
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
   [3] = Type #lib::test_type_literal::TypeParam/0
-  [4] = StaticICData target 'dart:core::print', arg-desc CP#1
 }
 ]static method test_type_literal<T extends core::Object = dynamic>() → void {
   core::print(core::String);
@@ -691,12 +576,11 @@
 Bytecode {
   Entry                0
   CheckStack           0
-  PushConstant         CP#1
+  PushConstant         CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgumentsForInstanceAllocation #lib::F [dart:core::int, dart:core::String]
-  [1] = Instance #lib::F type-args CP#0 {}
+  [0] = ObjectRef const #lib::F < dart:core::Map < dart:core::int, dart:core::String >, dart:core::int, dart:core::String > {}
 }
 ]static method testGenericConstInstance() → dynamic
   return const self::F::•<core::int, core::String>();
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
index 4fbdb3b..0c91ab3 100644
--- a/pkg/vm/testcases/bytecode/loops.dart.expect
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -14,13 +14,13 @@
   CheckStack           1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   CompareIntLt
   JumpIfFalse          L1
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#4
+  InterfaceCall        2, CP#2
   AddInt
   PopLocal             r0
   Push                 r1
@@ -34,12 +34,10 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
-  [2] = Reserved
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = InterfaceCall target-name '[]', arg-desc CP#3
-  [5] = Reserved
+  [0] = InterfaceCall 'dart:core::List::get:length', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::List::[]', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method test_for(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -64,7 +62,7 @@
   JumpIfFalse          L1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   CompareIntGe
   JumpIfFalse          L2
   Jump                 L1
@@ -72,7 +70,7 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#4
+  InterfaceCall        2, CP#2
   AddInt
   PopLocal             r0
   Push                 r1
@@ -86,12 +84,10 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
-  [2] = Reserved
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = InterfaceCall target-name '[]', arg-desc CP#3
-  [5] = Reserved
+  [0] = InterfaceCall 'dart:core::List::get:length', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::List::[]', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method test_for_break(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -117,7 +113,7 @@
   CheckStack           1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   CompareIntLt
   JumpIfFalse          L1
   Push                 r1
@@ -129,7 +125,7 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#4
+  InterfaceCall        2, CP#2
   AddInt
   PopLocal             r0
 L3:
@@ -144,12 +140,10 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
-  [2] = Reserved
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = InterfaceCall target-name '[]', arg-desc CP#3
-  [5] = Reserved
+  [0] = InterfaceCall 'dart:core::List::get:length', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::List::[]', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method test_for_continue(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -175,7 +169,7 @@
   CheckStack           1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   CompareIntLt
   JumpIfFalse          L1
   Push                 r0
@@ -188,7 +182,7 @@
   StoreLocal           r1
   PopLocal             r3
   Push                 r2
-  InterfaceCall        2, CP#4
+  InterfaceCall        2, CP#2
   AddInt
   PopLocal             r0
   Jump                 L2
@@ -197,12 +191,10 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:length', arg-desc CP#0
-  [2] = Reserved
-  [3] = ArgDesc num-args 2, num-type-args 0, names []
-  [4] = InterfaceCall target-name '[]', arg-desc CP#3
-  [5] = Reserved
+  [0] = InterfaceCall 'dart:core::List::get:length', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::List::[]', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method test_while(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -225,7 +217,7 @@
   Push                 r0
   Push                 FP[-5]
   Push                 r1
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   AddInt
   PopLocal             r0
   Push                 r1
@@ -234,19 +226,17 @@
   PopLocal             r1
   Push                 r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#4
+  InterfaceCall        1, CP#2
   CompareIntLt
   JumpIfTrue           L1
   Push                 r0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = InterfaceCall target-name '[]', arg-desc CP#0
-  [2] = Reserved
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = InterfaceCall get target-name 'get:length', arg-desc CP#3
-  [5] = Reserved
+  [0] = InterfaceCall 'dart:core::List::[]', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::List::get:length', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
 }
 ]static method test_do_while(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -265,15 +255,15 @@
   PushInt              0
   PopLocal             r0
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   PopLocal             r1
 L2:
   CheckStack           1
   Push                 r1
-  InterfaceCall        1, CP#3
+  InterfaceCall        1, CP#2
   JumpIfFalse          L1
   Push                 r1
-  InterfaceCall        1, CP#5
+  InterfaceCall        1, CP#4
   PopLocal             r2
   Push                 r0
   Push                 r2
@@ -285,13 +275,12 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:iterator', arg-desc CP#0
-  [2] = Reserved
-  [3] = InterfaceCall target-name 'moveNext', arg-desc CP#0
-  [4] = Reserved
-  [5] = InterfaceCall get target-name 'get:current', arg-desc CP#0
-  [6] = Reserved
+  [0] = InterfaceCall 'dart:core::Iterable::get:iterator', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::Iterator::moveNext', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
+  [4] = InterfaceCall 'dart:core::Iterator::get:current', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
 }
 ]static method test_for_in(core::List<core::int> list) → core::int {
   core::int sum = 0;
@@ -309,15 +298,15 @@
   PushInt              42
   PopLocal             r1
   Push                 FP[-5]
-  InterfaceCall        1, CP#1
+  InterfaceCall        1, CP#0
   PopLocal             r2
 L2:
   CheckStack           1
   Push                 r2
-  InterfaceCall        1, CP#3
+  InterfaceCall        1, CP#2
   JumpIfFalse          L1
   Push                 r2
-  InterfaceCall        1, CP#5
+  InterfaceCall        1, CP#4
   PopLocal             r3
   Push                 r3
   PopLocal             r1
@@ -331,13 +320,12 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = InterfaceCall get target-name 'get:iterator', arg-desc CP#0
-  [2] = Reserved
-  [3] = InterfaceCall target-name 'moveNext', arg-desc CP#0
-  [4] = Reserved
-  [5] = InterfaceCall get target-name 'get:current', arg-desc CP#0
-  [6] = Reserved
+  [0] = InterfaceCall 'dart:core::Iterable::get:iterator', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
+  [2] = InterfaceCall 'dart:core::Iterator::moveNext', ArgDesc num-args 1, num-type-args 0, names []
+  [3] = Reserved
+  [4] = InterfaceCall 'dart:core::Iterator::get:current', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
 }
 ]static method test_for_in_with_outer_var(core::List<core::int> list) → core::int {
   core::int sum = 0;
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
index d715039..0920f3c 100644
--- a/pkg/vm/testcases/bytecode/optional_params.dart.expect
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -21,10 +21,8 @@
   PushInt              1
   Push                 r0
   StoreIndexedTOS
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
+  DirectCall           1, CP#5
   Drop1
   PushNull
   PushInt              2
@@ -32,16 +30,14 @@
   StoreLocal           r3
   Push                 r3
   PushInt              0
-  PushConstant         CP#6
+  PushConstant         CP#7
   StoreIndexedTOS
   Push                 r3
   PushInt              1
   Push                 r1
   StoreIndexedTOS
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#3
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
+  DirectCall           1, CP#5
   Drop1
   PushNull
   PushInt              2
@@ -49,33 +45,28 @@
   StoreLocal           r3
   Push                 r3
   PushInt              0
-  PushConstant         CP#9
+  PushConstant         CP#8
   StoreIndexedTOS
   Push                 r3
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#3
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
+  DirectCall           1, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = String 'default_a'
-  [1] = String 'default_b'
-  [2] = String 'x = '
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#3
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [6] = String 'a = '
-  [7] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#3
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [9] = String 'b = '
-  [10] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#3
-  [11] = StaticICData target 'dart:core::print', arg-desc CP#3
+  [0] = ObjectRef 'default_a'
+  [1] = ObjectRef 'default_b'
+  [2] = ObjectRef 'x = '
+  [3] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [4] = Reserved
+  [5] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
+  [7] = ObjectRef 'a = '
+  [8] = ObjectRef 'b = '
 }
 ]static method foo1(dynamic x, [dynamic a = "default_a", dynamic b = "default_b"]) → void {
   core::print("x = ${x}");
@@ -88,9 +79,9 @@
   LoadConstant         r2, CP#0
   LoadConstant         r2, CP#1
   LoadConstant         r3, CP#2
-  LoadConstant         r3, CP#4
+  LoadConstant         r3, CP#3
+  LoadConstant         r4, CP#4
   LoadConstant         r4, CP#5
-  LoadConstant         r4, CP#6
   Frame                1
   CheckStack           0
   PushNull
@@ -99,16 +90,14 @@
   StoreLocal           r5
   Push                 r5
   PushInt              0
-  PushConstant         CP#7
+  PushConstant         CP#6
   StoreIndexedTOS
   Push                 r5
   PushInt              1
   Push                 r0
   StoreIndexedTOS
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#8
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#8
+  DirectCall           1, CP#7
+  DirectCall           1, CP#9
   Drop1
   PushNull
   PushInt              2
@@ -122,10 +111,38 @@
   PushInt              1
   Push                 r1
   StoreIndexedTOS
+  DirectCall           1, CP#7
+  DirectCall           1, CP#9
+  Drop1
+  PushNull
+  PushInt              2
+  CreateArrayTOS
+  StoreLocal           r5
+  Push                 r5
+  PushInt              0
   PushConstant         CP#12
-  IndirectStaticCall   1, CP#8
+  StoreIndexedTOS
+  Push                 r5
+  PushInt              1
+  Push                 r2
+  StoreIndexedTOS
+  DirectCall           1, CP#7
+  DirectCall           1, CP#9
+  Drop1
+  PushNull
+  PushInt              2
+  CreateArrayTOS
+  StoreLocal           r5
+  Push                 r5
+  PushInt              0
   PushConstant         CP#13
-  IndirectStaticCall   1, CP#8
+  StoreIndexedTOS
+  Push                 r5
+  PushInt              1
+  Push                 r3
+  StoreIndexedTOS
+  DirectCall           1, CP#7
+  DirectCall           1, CP#9
   Drop1
   PushNull
   PushInt              2
@@ -137,74 +154,30 @@
   StoreIndexedTOS
   Push                 r5
   PushInt              1
-  Push                 r2
-  StoreIndexedTOS
-  PushConstant         CP#15
-  IndirectStaticCall   1, CP#8
-  PushConstant         CP#16
-  IndirectStaticCall   1, CP#8
-  Drop1
-  PushNull
-  PushInt              2
-  CreateArrayTOS
-  StoreLocal           r5
-  Push                 r5
-  PushInt              0
-  PushConstant         CP#17
-  StoreIndexedTOS
-  Push                 r5
-  PushInt              1
-  Push                 r3
-  StoreIndexedTOS
-  PushConstant         CP#18
-  IndirectStaticCall   1, CP#8
-  PushConstant         CP#19
-  IndirectStaticCall   1, CP#8
-  Drop1
-  PushNull
-  PushInt              2
-  CreateArrayTOS
-  StoreLocal           r5
-  Push                 r5
-  PushInt              0
-  PushConstant         CP#20
-  StoreIndexedTOS
-  Push                 r5
-  PushInt              1
   Push                 r4
   StoreIndexedTOS
-  PushConstant         CP#21
-  IndirectStaticCall   1, CP#8
-  PushConstant         CP#22
-  IndirectStaticCall   1, CP#8
+  DirectCall           1, CP#7
+  DirectCall           1, CP#9
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = String 'a'
-  [1] = Int 42
-  [2] = String 'b'
-  [3] = String 'default_b'
-  [4] = List type-arg dart:core::String, entries CP# [3]
-  [5] = String 'c'
-  [6] = String 'default_c'
-  [7] = String 'y = '
-  [8] = ArgDesc num-args 1, num-type-args 0, names []
-  [9] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#8
-  [10] = StaticICData target 'dart:core::print', arg-desc CP#8
-  [11] = String 'z = '
-  [12] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#8
-  [13] = StaticICData target 'dart:core::print', arg-desc CP#8
-  [14] = String 'a = '
-  [15] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#8
-  [16] = StaticICData target 'dart:core::print', arg-desc CP#8
-  [17] = String 'b = '
-  [18] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#8
-  [19] = StaticICData target 'dart:core::print', arg-desc CP#8
-  [20] = String 'c = '
-  [21] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#8
-  [22] = StaticICData target 'dart:core::print', arg-desc CP#8
+  [0] = ObjectRef 'a'
+  [1] = ObjectRef const 42
+  [2] = ObjectRef 'b'
+  [3] = ObjectRef const <dart:core::String> ['default_b']
+  [4] = ObjectRef 'c'
+  [5] = ObjectRef 'default_c'
+  [6] = ObjectRef 'y = '
+  [7] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [8] = Reserved
+  [9] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [10] = Reserved
+  [11] = ObjectRef 'z = '
+  [12] = ObjectRef 'a = '
+  [13] = ObjectRef 'b = '
+  [14] = ObjectRef 'c = '
 }
 ]static method foo2(dynamic y, dynamic z, {dynamic c = "default_c", dynamic a = 42, dynamic b = const <core::String>["default_b"]}) → void {
   core::print("y = ${y}");
@@ -226,30 +199,25 @@
   PushNull
   Push                 r4
   InstantiateType      CP#4
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#5
   Drop1
   Push                 r1
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#5
   Drop1
   Push                 r3
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#5
+  DirectCall           1, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = String 'a'
-  [1] = Bool false
-  [2] = String 'b'
-  [3] = Null
+  [0] = ObjectRef 'a'
+  [1] = ObjectRef const false
+  [2] = ObjectRef 'b'
+  [3] = ObjectRef null
   [4] = Type #lib::foo3::TypeParam/0
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#5
+  [5] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
 }
 ]static method foo3<P extends core::Object = dynamic, Q extends core::Object = dynamic>(dynamic z, dynamic y, {core::bool a = false, core::Map<self::foo3::P, self::foo3::Q> b = null}) → void {
   core::print(self::foo3::P);
@@ -262,27 +230,25 @@
   CheckStack           0
   PushConstant         CP#0
   PushConstant         CP#1
-  PushConstant         CP#3
-  IndirectStaticCall   2, CP#2
+  DirectCall           2, CP#2
   Drop1
   PushConstant         CP#4
   PushConstant         CP#5
   PushConstant         CP#1
-  PushConstant         CP#7
-  IndirectStaticCall   3, CP#6
+  DirectCall           3, CP#6
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = String 'fixed_x'
-  [1] = String 'concrete_a'
-  [2] = ArgDesc num-args 2, num-type-args 0, names []
-  [3] = StaticICData target '#lib::foo1', arg-desc CP#2
-  [4] = String 'fixed_y'
-  [5] = String 'fixed_z'
-  [6] = ArgDesc num-args 3, num-type-args 0, names [a]
-  [7] = StaticICData target '#lib::foo2', arg-desc CP#6
+  [0] = ObjectRef 'fixed_x'
+  [1] = ObjectRef 'concrete_a'
+  [2] = DirectCall '#lib::foo1', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
+  [4] = ObjectRef 'fixed_y'
+  [5] = ObjectRef 'fixed_z'
+  [6] = DirectCall '#lib::foo2', ArgDesc num-args 3, num-type-args 0, names ['a']
+  [7] = Reserved
 }
 ]static method main() → dynamic {
   self::foo1("fixed_x", "concrete_a");
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index 346cd8a..4fa0a47 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -8,15 +8,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::Base1
     : super core::Object::•()
@@ -60,15 +59,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base1::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::Base1:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::A
     : super self::Base1::•()
@@ -81,15 +79,14 @@
   Push                 FP[-6]
   PushConstant         CP#1
   PushInt              2
-  PushConstant         CP#3
-  IndirectStaticCall   4, CP#2
+  DirectCall           4, CP#2
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::String]
-  [1] = String 'a1'
-  [2] = ArgDesc num-args 3, num-type-args 1, names []
-  [3] = StaticICData target '#lib::Base1::foo', arg-desc CP#2
+  [0] = ObjectRef < dart:core::String >
+  [1] = ObjectRef 'a1'
+  [2] = DirectCall '#lib::Base1::foo', ArgDesc num-args 3, num-type-args 1, names []
+  [3] = Reserved
 }
 ]  method testSuperCall(core::int x) → dynamic
     return super.{self::Base1::foo}<core::String>("a1", 2);
@@ -98,13 +95,12 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base1::get:foo', arg-desc CP#0
+  [0] = DirectCall '#lib::Base1::get:foo', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  method testSuperTearOff() → dynamic
     return super.{self::Base1::foo};
@@ -113,13 +109,12 @@
   Entry                1
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base1::get:bar', arg-desc CP#0
+  [0] = DirectCall '#lib::Base1::get:bar', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  method testSuperGet() → dynamic
     return super.{self::Base1::bar};
@@ -129,18 +124,17 @@
   CheckStack           0
   PushConstant         CP#0
   Push                 FP[-5]
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   PushConstant         CP#3
   DynamicCall          3, CP#5
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::int]
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target '#lib::Base1::get:bar', arg-desc CP#1
-  [3] = String 'param'
-  [4] = ArgDesc num-args 2, num-type-args 1, names []
+  [0] = ObjectRef < dart:core::int >
+  [1] = DirectCall '#lib::Base1::get:bar', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
+  [3] = ObjectRef 'param'
+  [4] = ObjectRef ArgDesc num-args 2, num-type-args 1, names []
   [5] = ICData dynamic target-name 'call', arg-desc CP#4
 }
 ]  method testSuperCallViaGetter() → dynamic
@@ -151,15 +145,14 @@
   CheckStack           0
   Push                 FP[-5]
   PushInt              3
-  PushConstant         CP#1
-  IndirectStaticCall   2, CP#0
+  DirectCall           2, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base1::set:bazz', arg-desc CP#0
+  [0] = DirectCall '#lib::Base1::set:bazz', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  method testSuperSet() → dynamic {
     super.{self::Base1::bazz} = 3;
@@ -171,15 +164,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::Base2
     : super core::Object::•()
@@ -194,15 +186,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::Base2::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::Base2:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::B
     : super self::Base2::•()
@@ -239,23 +230,21 @@
   PushInt              5
   StoreIndexedTOS
   PushTrue
-  PushConstant         CP#7
-  IndirectStaticCall   4, CP#6
-  PushConstant         CP#9
-  IndirectStaticCall   2, CP#8
+  DirectCall           4, CP#6
+  DirectCall           2, CP#8
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 4, num-type-args 1, names []
-  [1] = String 'foo'
-  [2] = TypeArgs [dynamic]
-  [3] = TypeArgs [dart:core::double]
-  [4] = String 'a1'
-  [5] = Double 3.14
-  [6] = ArgDesc num-args 4, num-type-args 0, names []
-  [7] = StaticICData target 'dart:core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#6
-  [8] = ArgDesc num-args 2, num-type-args 0, names []
-  [9] = StaticICData target 'dart:core::Object::noSuchMethod', arg-desc CP#8
+  [0] = ObjectRef ArgDesc num-args 4, num-type-args 1, names []
+  [1] = ObjectRef 'foo'
+  [2] = ObjectRef < dynamic >
+  [3] = ObjectRef < dart:core::double >
+  [4] = ObjectRef 'a1'
+  [5] = ObjectRef const 3.14
+  [6] = DirectCall 'dart:core::_InvocationMirror::_allocateInvocationMirror', ArgDesc num-args 4, num-type-args 0, names []
+  [7] = Reserved
+  [8] = DirectCall 'dart:core::Object::noSuchMethod', ArgDesc num-args 2, num-type-args 0, names []
+  [9] = Reserved
 }
 ]  method testSuperCall(core::int x) → dynamic
     return super.{self::Base2::foo}<core::double>("a1", 3.14, 5);
@@ -275,20 +264,18 @@
   Push                 FP[-5]
   StoreIndexedTOS
   PushTrue
-  PushConstant         CP#4
-  IndirectStaticCall   4, CP#3
-  PushConstant         CP#6
-  IndirectStaticCall   2, CP#5
+  DirectCall           4, CP#3
+  DirectCall           2, CP#5
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = String 'foo'
-  [2] = TypeArgs [dynamic]
-  [3] = ArgDesc num-args 4, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#3
-  [5] = ArgDesc num-args 2, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::Object::noSuchMethod', arg-desc CP#5
+  [0] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ObjectRef 'foo'
+  [2] = ObjectRef < dynamic >
+  [3] = DirectCall 'dart:core::_InvocationMirror::_allocateInvocationMirror', ArgDesc num-args 4, num-type-args 0, names []
+  [4] = Reserved
+  [5] = DirectCall 'dart:core::Object::noSuchMethod', ArgDesc num-args 2, num-type-args 0, names []
+  [6] = Reserved
 }
 ]  method testSuperTearOff() → dynamic
     return super.{self::Base2::foo};
@@ -308,20 +295,18 @@
   Push                 FP[-5]
   StoreIndexedTOS
   PushTrue
-  PushConstant         CP#4
-  IndirectStaticCall   4, CP#3
-  PushConstant         CP#6
-  IndirectStaticCall   2, CP#5
+  DirectCall           4, CP#3
+  DirectCall           2, CP#5
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = String 'bar'
-  [2] = TypeArgs [dynamic]
-  [3] = ArgDesc num-args 4, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#3
-  [5] = ArgDesc num-args 2, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::Object::noSuchMethod', arg-desc CP#5
+  [0] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [1] = ObjectRef 'bar'
+  [2] = ObjectRef < dynamic >
+  [3] = DirectCall 'dart:core::_InvocationMirror::_allocateInvocationMirror', ArgDesc num-args 4, num-type-args 0, names []
+  [4] = Reserved
+  [5] = DirectCall 'dart:core::Object::noSuchMethod', ArgDesc num-args 2, num-type-args 0, names []
+  [6] = Reserved
 }
 ]  method testSuperGet() → dynamic
     return super.{self::Base2::bar};
@@ -342,25 +327,23 @@
   Push                 FP[-5]
   StoreIndexedTOS
   PushTrue
-  PushConstant         CP#5
-  IndirectStaticCall   4, CP#4
-  PushConstant         CP#7
-  IndirectStaticCall   2, CP#6
+  DirectCall           4, CP#4
+  DirectCall           2, CP#6
   PushConstant         CP#8
   DynamicCall          3, CP#10
   ReturnTOS
 }
 ConstantPool {
-  [0] = TypeArgs [dart:core::int]
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = String 'bar'
-  [3] = TypeArgs [dynamic]
-  [4] = ArgDesc num-args 4, num-type-args 0, names []
-  [5] = StaticICData target 'dart:core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#4
-  [6] = ArgDesc num-args 2, num-type-args 0, names []
-  [7] = StaticICData target 'dart:core::Object::noSuchMethod', arg-desc CP#6
-  [8] = String 'param'
-  [9] = ArgDesc num-args 2, num-type-args 1, names []
+  [0] = ObjectRef < dart:core::int >
+  [1] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [2] = ObjectRef 'bar'
+  [3] = ObjectRef < dynamic >
+  [4] = DirectCall 'dart:core::_InvocationMirror::_allocateInvocationMirror', ArgDesc num-args 4, num-type-args 0, names []
+  [5] = Reserved
+  [6] = DirectCall 'dart:core::Object::noSuchMethod', ArgDesc num-args 2, num-type-args 0, names []
+  [7] = Reserved
+  [8] = ObjectRef 'param'
+  [9] = ObjectRef ArgDesc num-args 2, num-type-args 1, names []
   [10] = ICData dynamic target-name 'call', arg-desc CP#9
 }
 ]  method testSuperCallViaGetter() → dynamic
@@ -385,21 +368,20 @@
   PushInt              3
   StoreIndexedTOS
   PushTrue
-  PushConstant         CP#4
-  IndirectStaticCall   4, CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   2, CP#0
+  DirectCall           4, CP#3
+  DirectCall           2, CP#5
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = String 'bazz'
-  [2] = TypeArgs [dynamic]
-  [3] = ArgDesc num-args 4, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::_InvocationMirror::_allocateInvocationMirror', arg-desc CP#3
-  [5] = StaticICData target 'dart:core::Object::noSuchMethod', arg-desc CP#0
+  [0] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [1] = ObjectRef 'bazz'
+  [2] = ObjectRef < dynamic >
+  [3] = DirectCall 'dart:core::_InvocationMirror::_allocateInvocationMirror', ArgDesc num-args 4, num-type-args 0, names []
+  [4] = Reserved
+  [5] = DirectCall 'dart:core::Object::noSuchMethod', ArgDesc num-args 2, num-type-args 0, names []
+  [6] = Reserved
 }
 ]  method testSuperSet() → dynamic {
     super.{self::Base2::bazz} = 3;
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
index 93301c3..d66c358 100644
--- a/pkg/vm/testcases/bytecode/switch.dart.expect
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -12,15 +12,15 @@
   PopLocal             r1
   Push                 r1
   PushInt              1
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              2
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Push                 r1
   PushInt              3
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L3
   Jump                 L4
 L1:
@@ -40,9 +40,8 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = InterfaceCall target-name '==', arg-desc CP#0
-  [2] = Reserved
+  [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
 }
 ]static method foo1(core::int x) → core::int {
   core::int y;
@@ -79,27 +78,27 @@
   PopLocal             r1
   Push                 r1
   PushInt              1
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              2
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              3
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              4
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Push                 r1
   PushInt              5
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Push                 r1
   PushInt              6
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Jump                 L3
 L1:
@@ -118,9 +117,8 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = InterfaceCall target-name '==', arg-desc CP#0
-  [2] = Reserved
+  [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
 }
 ]static method foo2(core::int x) → core::int {
   core::int y;
@@ -160,27 +158,27 @@
   PopLocal             r1
   Push                 r1
   PushInt              1
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              2
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              3
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r1
   PushInt              4
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Push                 r1
   PushInt              5
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Push                 r1
   PushInt              6
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Jump                 L3
 L1:
@@ -199,9 +197,8 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = InterfaceCall target-name '==', arg-desc CP#0
-  [2] = Reserved
+  [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
 }
 ]static method foo3(core::int x) → core::int {
   core::int y;
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index e946fb1..384bd81 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -8,8 +8,7 @@
   CheckStack           0
 Try #0 start:
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -31,10 +30,8 @@
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#1
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#5
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L1:
@@ -42,16 +39,16 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 7, handler 7, types [CP#3]
+  try-index 0, outer -1, start 2, end 6, handler 6, types [CP#3]
 }
 ConstantPool {
-  [0] = String 'danger!'
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [0] = ObjectRef 'danger!'
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
   [3] = Type dynamic
-  [4] = String 'caught '
-  [5] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
-  [6] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [4] = ObjectRef 'caught '
+  [5] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
 }
 ]static method testTryCatch1() → dynamic {
   try {
@@ -67,8 +64,7 @@
   CheckStack           0
 Try #0 start:
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 Try #0 end:
@@ -78,17 +74,16 @@
   MoveSpecial          stackTrace, r1
   Push                 r0
   PushConstant         CP#3
-  InterfaceCall        2, CP#5
+  InterfaceCall        2, CP#4
   JumpIfFalse          L2
-  PushConstant         CP#7
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#1
+  PushConstant         CP#6
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L2:
   Push                 r0
-  PushConstant         CP#9
-  InterfaceCall        2, CP#5
+  PushConstant         CP#7
+  InterfaceCall        2, CP#4
   JumpIfFalse          L3
   Push                 r0
   PopLocal             r2
@@ -98,22 +93,20 @@
   StoreLocal           r3
   Push                 r3
   PushInt              0
-  PushConstant         CP#10
+  PushConstant         CP#8
   StoreIndexedTOS
   Push                 r3
   PushInt              1
   Push                 r2
   StoreIndexedTOS
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#1
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#9
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L3:
   Push                 r0
-  PushConstant         CP#13
-  InterfaceCall        2, CP#5
+  PushConstant         CP#11
+  InterfaceCall        2, CP#4
   JumpIfFalse          L4
   Push                 r0
   PopLocal             r2
@@ -125,7 +118,7 @@
   StoreLocal           r4
   Push                 r4
   PushInt              0
-  PushConstant         CP#14
+  PushConstant         CP#12
   StoreIndexedTOS
   Push                 r4
   PushInt              1
@@ -133,16 +126,14 @@
   StoreIndexedTOS
   Push                 r4
   PushInt              2
-  PushConstant         CP#15
+  PushConstant         CP#13
   StoreIndexedTOS
   Push                 r4
   PushInt              3
   Push                 r3
   StoreIndexedTOS
-  PushConstant         CP#16
-  IndirectStaticCall   1, CP#1
-  PushConstant         CP#17
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#9
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L4:
@@ -156,7 +147,7 @@
   StoreLocal           r4
   Push                 r4
   PushInt              0
-  PushConstant         CP#19
+  PushConstant         CP#15
   StoreIndexedTOS
   Push                 r4
   PushInt              1
@@ -164,16 +155,14 @@
   StoreIndexedTOS
   Push                 r4
   PushInt              2
-  PushConstant         CP#15
+  PushConstant         CP#13
   StoreIndexedTOS
   Push                 r4
   PushInt              3
   Push                 r3
   StoreIndexedTOS
-  PushConstant         CP#20
-  IndirectStaticCall   1, CP#1
-  PushConstant         CP#21
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#9
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L1:
@@ -181,31 +170,25 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 7, handler 7, needs-stack-trace, types [CP#3, CP#9, CP#13, CP#18]
+  try-index 0, outer -1, start 2, end 6, handler 6, needs-stack-trace, types [CP#3, CP#7, CP#11, CP#14]
 }
 ConstantPool {
-  [0] = String 'danger!'
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [0] = ObjectRef 'danger!'
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
   [3] = Type dart:core::TypeError
-  [4] = ArgDesc num-args 2, num-type-args 0, names []
-  [5] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#4
-  [6] = Reserved
-  [7] = String 'caught type error'
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [9] = Type dart:core::AssertionError
-  [10] = String 'caught assertion error '
-  [11] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [13] = Type dart:core::Error
-  [14] = String 'caught error '
-  [15] = String ' '
-  [16] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
-  [17] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [18] = Type dynamic
-  [19] = String 'caught something '
-  [20] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#1
-  [21] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [4] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
+  [5] = Reserved
+  [6] = ObjectRef 'caught type error'
+  [7] = Type dart:core::AssertionError
+  [8] = ObjectRef 'caught assertion error '
+  [9] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [10] = Reserved
+  [11] = Type dart:core::Error
+  [12] = ObjectRef 'caught error '
+  [13] = ObjectRef ' '
+  [14] = Type dynamic
+  [15] = ObjectRef 'caught something '
 }
 ]static method testTryCatch2() → dynamic {
   try {
@@ -239,20 +222,20 @@
   Push                 r0
   PushInt              2
   StoreContextVar      0, 1
-  Allocate             CP#9
+  Allocate             CP#8
   StoreLocal           r5
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#10
+  StoreFieldTOS        CP#9
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r5
-  PushConstant         CP#14
-  StoreFieldTOS        CP#15
+  PushConstant         CP#13
+  StoreFieldTOS        CP#14
   Push                 r5
   PushConstant         CP#0
-  StoreFieldTOS        CP#17
+  StoreFieldTOS        CP#16
   Push                 r5
   Push                 r0
   StoreFieldTOS        CP#1
@@ -262,8 +245,7 @@
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  PushConstant         CP#20
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#4
   Drop1
   Jump                 L1
 Try #0 end:
@@ -284,7 +266,7 @@
   StoreLocal           r5
   Push                 r5
   PushInt              0
-  PushConstant         CP#21
+  PushConstant         CP#20
   StoreIndexedTOS
   Push                 r5
   PushInt              1
@@ -292,32 +274,30 @@
   StoreIndexedTOS
   Push                 r5
   PushInt              2
-  PushConstant         CP#22
+  PushConstant         CP#21
   StoreIndexedTOS
   Push                 r5
   PushInt              3
   Push                 r0
   LoadContextVar       0, 2
   StoreIndexedTOS
-  PushConstant         CP#23
-  IndirectStaticCall   1, CP#4
-  PushConstant         CP#24
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#22
+  DirectCall           1, CP#4
   Drop1
-  Allocate             CP#9
+  Allocate             CP#8
   StoreLocal           r5
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#10
+  StoreFieldTOS        CP#9
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r5
-  PushConstant         CP#14
-  StoreFieldTOS        CP#15
+  PushConstant         CP#13
+  StoreFieldTOS        CP#14
   Push                 r5
-  PushConstant         CP#25
-  StoreFieldTOS        CP#17
+  PushConstant         CP#24
+  StoreFieldTOS        CP#16
   Push                 r5
   Push                 r0
   StoreFieldTOS        CP#1
@@ -332,48 +312,43 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 9, end 39, handler 39, needs-stack-trace, types [CP#6]
+  try-index 0, outer -1, start 9, end 38, handler 38, needs-stack-trace, types [CP#6]
 }
 ConstantPool {
   [0] = ClosureFunction 0
   [1] = InstanceField dart:core::_Closure::_context (field)
   [2] = Reserved
-  [3] = String 'danger foo'
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#4
+  [3] = ObjectRef 'danger foo'
+  [4] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
   [6] = Type dynamic
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [8] = EndClosureFunctionScope
-  [9] = Class dart:core::_Closure
-  [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [11] = Reserved
-  [12] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [13] = Reserved
-  [14] = EmptyTypeArguments
-  [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [16] = Reserved
-  [17] = InstanceField dart:core::_Closure::_function (field)
-  [18] = Reserved
-  [19] = ICData dynamic target-name 'call', arg-desc CP#4
-  [20] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [21] = String 'caught '
-  [22] = String ' '
-  [23] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#4
-  [24] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [25] = ClosureFunction 1
-  [26] = String 'danger bar'
-  [27] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [28] = Type dart:core::Error
-  [29] = ArgDesc num-args 2, num-type-args 0, names []
-  [30] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#29
-  [31] = Reserved
-  [32] = String 'error '
-  [33] = String ', captured stack trace: '
-  [34] = StaticICData target 'dart:core::_StringBase::_interpolate', arg-desc CP#4
-  [35] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [36] = EndClosureFunctionScope
+  [7] = EndClosureFunctionScope
+  [8] = Class dart:core::_Closure
+  [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [10] = Reserved
+  [11] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [12] = Reserved
+  [13] = EmptyTypeArguments
+  [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [15] = Reserved
+  [16] = InstanceField dart:core::_Closure::_function (field)
+  [17] = Reserved
+  [18] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [19] = ICData dynamic target-name 'call', arg-desc CP#18
+  [20] = ObjectRef 'caught '
+  [21] = ObjectRef ' '
+  [22] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [23] = Reserved
+  [24] = ClosureFunction 1
+  [25] = ObjectRef 'danger bar'
+  [26] = Type dart:core::Error
+  [27] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
+  [28] = Reserved
+  [29] = ObjectRef 'error '
+  [30] = ObjectRef ', captured stack trace: '
+  [31] = EndClosureFunctionScope
 }
-Closure #lib::testTryCatch3::foo () -> void
+Closure #lib::testTryCatch3::'foo' () -> void
 ClosureBytecode {
   EntryFixed           1, 6
   CheckStack           0
@@ -384,8 +359,7 @@
   PopLocal             r2
 Try #0 start:
   PushConstant         CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#4
   Drop1
   Jump                 L1
 Try #0 end:
@@ -399,8 +373,7 @@
   PopLocal             r4
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#4
   Drop1
   Push                 r0
   PushInt              3
@@ -412,7 +385,7 @@
 
 }
 
-Closure #lib::testTryCatch3::bar () -> void
+Closure #lib::testTryCatch3::'bar' () -> void
 ClosureBytecode {
   EntryFixed           1, 6
   CheckStack           0
@@ -422,9 +395,8 @@
   Push                 r0
   PopLocal             r2
 Try #0 start:
-  PushConstant         CP#26
-  PushConstant         CP#27
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#25
+  DirectCall           1, CP#4
   Drop1
   Jump                 L1
 Try #0 end:
@@ -435,8 +407,8 @@
   MoveSpecial          exception, r2
   MoveSpecial          stackTrace, r3
   Push                 r2
-  PushConstant         CP#28
-  InterfaceCall        2, CP#30
+  PushConstant         CP#26
+  InterfaceCall        2, CP#27
   JumpIfFalse          L2
   Push                 r2
   PopLocal             r4
@@ -446,7 +418,7 @@
   StoreLocal           r5
   Push                 r5
   PushInt              0
-  PushConstant         CP#32
+  PushConstant         CP#29
   StoreIndexedTOS
   Push                 r5
   PushInt              1
@@ -454,17 +426,15 @@
   StoreIndexedTOS
   Push                 r5
   PushInt              2
-  PushConstant         CP#33
+  PushConstant         CP#30
   StoreIndexedTOS
   Push                 r5
   PushInt              3
   Push                 r0
   LoadContextVar       0, 2
   StoreIndexedTOS
-  PushConstant         CP#34
-  IndirectStaticCall   1, CP#4
-  PushConstant         CP#35
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#22
+  DirectCall           1, CP#4
   Drop1
   Jump                 L1
 L2:
@@ -512,8 +482,7 @@
 Try #0 start:
 Try #1 start:
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 Try #1 end:
@@ -525,8 +494,7 @@
   PopLocal             r4
 Try #2 start:
   PushConstant         CP#4
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Push                 FP[-5]
   AssertBoolean        0
@@ -543,9 +511,8 @@
   MoveSpecial          stackTrace, r6
   Push                 r5
   PopLocal             r7
-  PushConstant         CP#6
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#1
+  PushConstant         CP#5
+  DirectCall           1, CP#1
   Drop1
   Jump                 L3
 L3:
@@ -561,13 +528,11 @@
   PopLocal             r2
   Push                 r1
   PopLocal             r3
-  PushConstant         CP#8
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#1
+  PushConstant         CP#6
+  DirectCall           1, CP#1
   Drop1
   Push                 r3
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L4
 L4:
@@ -575,22 +540,18 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 35, handler 35, needs-stack-trace, types [CP#3]
-  try-index 1, outer 0, start 2, end 7, handler 7, needs-stack-trace, types [CP#3]
-  try-index 2, outer 0, start 12, end 23, handler 23, types [CP#3]
+  try-index 0, outer -1, start 2, end 32, handler 32, needs-stack-trace, types [CP#3]
+  try-index 1, outer 0, start 2, end 6, handler 6, needs-stack-trace, types [CP#3]
+  try-index 2, outer 0, start 11, end 21, handler 21, types [CP#3]
 }
 ConstantPool {
-  [0] = String 'try 1 > try 2'
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [0] = ObjectRef 'try 1 > try 2'
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
   [3] = Type dynamic
-  [4] = String 'try 1 > catch 2 > try 3'
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [6] = String 'try 1 > catch 2 > catch 3'
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [8] = String 'catch 1'
-  [9] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [10] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [4] = ObjectRef 'try 1 > catch 2 > try 3'
+  [5] = ObjectRef 'try 1 > catch 2 > catch 3'
+  [6] = ObjectRef 'catch 1'
 }
 ]static method testRethrow(core::bool cond) → dynamic {
   try {
@@ -640,22 +601,19 @@
   MoveSpecial          exception, r1
   MoveSpecial          stackTrace, r2
   Push                 r0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Push                 r1
   Push                 r2
   Throw                1
 L3:
   Push                 r0
-  PushConstant         CP#3
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L4:
   Push                 r0
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Push                 r0
   PushInt              1
@@ -672,10 +630,8 @@
 }
 ConstantPool {
   [0] = Type dynamic
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [3] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [4] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
 }
 ]static method testTryFinally1() → dynamic {
   #L1:
@@ -704,20 +660,19 @@
   PopLocal             r2
   Push                 r2
   PushInt              1
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L1
   Push                 r2
   PushInt              2
-  InterfaceCall        2, CP#1
+  InterfaceCall        2, CP#0
   JumpIfTrue           L2
   Jump                 L3
 L1:
   Push                 r0
   PopLocal             r3
 Try #0 start:
-  PushConstant         CP#3
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#2
+  DirectCall           1, CP#3
   Drop1
   Push                 r0
   PushInt              3
@@ -725,30 +680,29 @@
   Push                 r0
   PopLocal             r5
 Try #1 start:
-  PushConstant         CP#6
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#5
+  DirectCall           1, CP#3
   Drop1
-  Allocate             CP#14
+  Allocate             CP#10
   StoreLocal           r8
   Push                 r8
   PushNull
-  StoreFieldTOS        CP#15
+  StoreFieldTOS        CP#11
   Push                 r8
   PushNull
-  StoreFieldTOS        CP#17
+  StoreFieldTOS        CP#13
   Push                 r8
-  PushConstant         CP#19
-  StoreFieldTOS        CP#20
+  PushConstant         CP#15
+  StoreFieldTOS        CP#16
   Push                 r8
-  PushConstant         CP#8
-  StoreFieldTOS        CP#22
+  PushConstant         CP#6
+  StoreFieldTOS        CP#18
   Push                 r8
   Push                 r0
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#7
   PopLocal             r7
   Push                 r7
-  DynamicCall          1, CP#24
+  DynamicCall          1, CP#21
   Drop1
   Jump                 L4
 Try #1 end:
@@ -758,9 +712,8 @@
   PopLocal             r0
   MoveSpecial          exception, r5
   MoveSpecial          stackTrace, r6
-  PushConstant         CP#26
-  PushConstant         CP#27
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#23
+  DirectCall           1, CP#3
   Drop1
   Push                 r5
   Push                 r6
@@ -768,9 +721,8 @@
 L4:
   Push                 r5
   PopLocal             r0
-  PushConstant         CP#26
-  PushConstant         CP#28
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#23
+  DirectCall           1, CP#3
   Drop1
   Jump                 L5
 Try #0 end:
@@ -780,9 +732,8 @@
   PopLocal             r0
   MoveSpecial          exception, r3
   MoveSpecial          stackTrace, r4
-  PushConstant         CP#31
-  PushConstant         CP#32
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#25
+  DirectCall           1, CP#3
   Drop1
   Push                 r3
   Push                 r4
@@ -790,15 +741,13 @@
 L5:
   Push                 r3
   PopLocal             r0
-  PushConstant         CP#31
-  PushConstant         CP#33
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#25
+  DirectCall           1, CP#3
   Drop1
   Jump                 L2
 L2:
-  PushConstant         CP#34
-  PushConstant         CP#35
-  IndirectStaticCall   1, CP#4
+  PushConstant         CP#26
+  DirectCall           1, CP#3
   Drop1
   Jump                 L3
 L3:
@@ -806,63 +755,52 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 21, end 75, handler 75, needs-stack-trace, types [CP#25]
-  try-index 1, outer 0, start 30, end 56, handler 56, needs-stack-trace, types [CP#25]
+  try-index 0, outer -1, start 21, end 71, handler 71, needs-stack-trace, types [CP#22]
+  try-index 1, outer 0, start 29, end 54, handler 54, needs-stack-trace, types [CP#22]
 }
 ConstantPool {
-  [0] = ArgDesc num-args 2, num-type-args 0, names []
-  [1] = InterfaceCall target-name '==', arg-desc CP#0
-  [2] = Reserved
-  [3] = String 'before try 1'
-  [4] = ArgDesc num-args 1, num-type-args 0, names []
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [6] = String 'try'
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [8] = ClosureFunction 0
-  [9] = InstanceField dart:core::_Closure::_context (field)
-  [10] = Reserved
-  [11] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [13] = EndClosureFunctionScope
-  [14] = Class dart:core::_Closure
-  [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [16] = Reserved
-  [17] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [18] = Reserved
-  [19] = EmptyTypeArguments
-  [20] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [21] = Reserved
-  [22] = InstanceField dart:core::_Closure::_function (field)
-  [23] = Reserved
-  [24] = ICData dynamic target-name 'call', arg-desc CP#4
-  [25] = Type dynamic
-  [26] = String 'finally 1'
-  [27] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [28] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [29] = String 'after try 1'
-  [30] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [31] = String 'finally 2'
-  [32] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [33] = StaticICData target 'dart:core::print', arg-desc CP#4
-  [34] = String 'case 2'
-  [35] = StaticICData target 'dart:core::print', arg-desc CP#4
+  [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
+  [1] = Reserved
+  [2] = ObjectRef 'before try 1'
+  [3] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [4] = Reserved
+  [5] = ObjectRef 'try'
+  [6] = ClosureFunction 0
+  [7] = InstanceField dart:core::_Closure::_context (field)
+  [8] = Reserved
+  [9] = EndClosureFunctionScope
+  [10] = Class dart:core::_Closure
+  [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [12] = Reserved
+  [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [14] = Reserved
+  [15] = EmptyTypeArguments
+  [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [17] = Reserved
+  [18] = InstanceField dart:core::_Closure::_function (field)
+  [19] = Reserved
+  [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [21] = ICData dynamic target-name 'call', arg-desc CP#20
+  [22] = Type dynamic
+  [23] = ObjectRef 'finally 1'
+  [24] = ObjectRef 'after try 1'
+  [25] = ObjectRef 'finally 2'
+  [26] = ObjectRef 'case 2'
 }
-Closure #lib::testTryFinally2::foo () -> void
+Closure #lib::testTryFinally2::'foo' () -> void
 ClosureBytecode {
   EntryFixed           1, 2
   CheckStack           0
   Push                 FP[-5]
-  LoadFieldTOS         CP#9
+  LoadFieldTOS         CP#7
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#3
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#4
+  DirectCall           1, CP#3
   Drop1
   PushNull
   ReturnTOS
@@ -918,20 +856,20 @@
   Push                 r0
   PopLocal             r3
 Try #0 start:
-  Allocate             CP#16
+  Allocate             CP#9
   StoreLocal           r5
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#17
+  StoreFieldTOS        CP#10
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#19
+  StoreFieldTOS        CP#12
   Push                 r5
-  PushConstant         CP#21
-  StoreFieldTOS        CP#22
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r5
   PushConstant         CP#0
-  StoreFieldTOS        CP#24
+  StoreFieldTOS        CP#17
   Push                 r5
   Push                 r0
   StoreFieldTOS        CP#1
@@ -946,11 +884,10 @@
   MoveSpecial          stackTrace, r4
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#26
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   Push                 r2
-  DynamicCall          1, CP#27
+  DynamicCall          1, CP#20
   Drop1
   Push                 r3
   Push                 r4
@@ -960,11 +897,10 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#28
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   Push                 r2
-  DynamicCall          1, CP#29
+  DynamicCall          1, CP#21
   Drop1
   Push                 r0
   LoadContextParent
@@ -973,41 +909,33 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 11, end 30, handler 30, needs-stack-trace, types [CP#7]
+  try-index 0, outer -1, start 11, end 30, handler 30, needs-stack-trace, types [CP#6]
 }
 ConstantPool {
   [0] = ClosureFunction 0
   [1] = InstanceField dart:core::_Closure::_context (field)
   [2] = Reserved
-  [3] = ArgDesc num-args 1, num-type-args 0, names []
-  [4] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [5] = String 'try 1'
-  [6] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [7] = Type dynamic
-  [8] = String 'try 2'
-  [9] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [10] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [11] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [13] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [14] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [15] = EndClosureFunctionScope
-  [16] = Class dart:core::_Closure
-  [17] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [3] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [4] = Reserved
+  [5] = ObjectRef 'try 1'
+  [6] = Type dynamic
+  [7] = ObjectRef 'try 2'
+  [8] = EndClosureFunctionScope
+  [9] = Class dart:core::_Closure
+  [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [11] = Reserved
+  [12] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [13] = Reserved
+  [14] = EmptyTypeArguments
+  [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [16] = Reserved
+  [17] = InstanceField dart:core::_Closure::_function (field)
   [18] = Reserved
-  [19] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [20] = Reserved
-  [21] = EmptyTypeArguments
-  [22] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [23] = Reserved
-  [24] = InstanceField dart:core::_Closure::_function (field)
-  [25] = Reserved
-  [26] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [27] = ICData dynamic target-name 'call', arg-desc CP#3
-  [28] = StaticICData target 'dart:core::print', arg-desc CP#3
-  [29] = ICData dynamic target-name 'call', arg-desc CP#3
+  [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [20] = ICData dynamic target-name 'call', arg-desc CP#19
+  [21] = ICData dynamic target-name 'call', arg-desc CP#19
 }
-Closure #lib::testTryFinally3::<anonymous closure> () -> dart:core::int
+Closure #lib::testTryFinally3::'<anonymous closure>' () -> dart:core::int
 ClosureBytecode {
   EntryFixed           1, 6
   CheckStack           0
@@ -1016,15 +944,13 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#4
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   Push                 r0
   PopLocal             r2
 Try #0 start:
   PushConstant         CP#5
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   Jump                 L1
 Try #0 end:
@@ -1037,9 +963,8 @@
   Push                 r0
   PopLocal             r4
 Try #1 start:
-  PushConstant         CP#8
-  PushConstant         CP#9
-  IndirectStaticCall   1, CP#3
+  PushConstant         CP#7
+  DirectCall           1, CP#3
   Drop1
   Jump                 L2
 Try #1 end:
@@ -1051,8 +976,7 @@
   MoveSpecial          stackTrace, r5
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   Push                 r4
   Push                 r5
@@ -1062,8 +986,7 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#11
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   PushInt              43
   ReturnTOS
@@ -1073,9 +996,8 @@
   Push                 r0
   PopLocal             r4
 Try #2 start:
-  PushConstant         CP#8
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#3
+  PushConstant         CP#7
+  DirectCall           1, CP#3
   Drop1
   Jump                 L3
 Try #2 end:
@@ -1087,8 +1009,7 @@
   MoveSpecial          stackTrace, r5
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#13
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   Push                 r4
   Push                 r5
@@ -1098,8 +1019,7 @@
   PopLocal             r0
   Push                 r0
   LoadContextVar       0, 0
-  PushConstant         CP#14
-  IndirectStaticCall   1, CP#3
+  DirectCall           1, CP#3
   Drop1
   PushInt              43
   ReturnTOS
@@ -1138,8 +1058,7 @@
 Try #0 start:
 Try #1 start:
   PushConstant         CP#0
-  PushConstant         CP#2
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 Try #1 end:
@@ -1150,8 +1069,7 @@
   Push                 r2
   PopLocal             r4
   PushConstant         CP#4
-  PushConstant         CP#5
-  IndirectStaticCall   1, CP#1
+  DirectCall           1, CP#1
   Drop1
   Jump                 L1
 L1:
@@ -1161,35 +1079,30 @@
   SetFrame             5
   MoveSpecial          exception, r0
   MoveSpecial          stackTrace, r1
-  PushConstant         CP#6
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#1
+  PushConstant         CP#5
+  DirectCall           1, CP#1
   Drop1
   Push                 r0
   Push                 r1
   Throw                1
 L2:
-  PushConstant         CP#6
-  PushConstant         CP#8
-  IndirectStaticCall   1, CP#1
+  PushConstant         CP#5
+  DirectCall           1, CP#1
   Drop1
   PushNull
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 2, end 18, handler 18, needs-stack-trace, types [CP#3]
-  try-index 1, outer 0, start 2, end 7, handler 7, types [CP#3]
+  try-index 0, outer -1, start 2, end 16, handler 16, needs-stack-trace, types [CP#3]
+  try-index 1, outer 0, start 2, end 6, handler 6, types [CP#3]
 }
 ConstantPool {
-  [0] = String 'try'
-  [1] = ArgDesc num-args 1, num-type-args 0, names []
-  [2] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [0] = ObjectRef 'try'
+  [1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [2] = Reserved
   [3] = Type dynamic
-  [4] = String 'catch'
-  [5] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [6] = String 'finally'
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#1
-  [8] = StaticICData target 'dart:core::print', arg-desc CP#1
+  [4] = ObjectRef 'catch'
+  [5] = ObjectRef 'finally'
 }
 ]static method testTryCatchFinally() → dynamic {
   try
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index 04a4e32..6da40f3 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -8,15 +8,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target 'dart:core::Object::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::A<self::A::T>
     : super core::Object::•()
@@ -28,15 +27,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::A::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::A:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::B
     : super self::A::•()
@@ -48,15 +46,14 @@
   Entry                0
   CheckStack           0
   Push                 FP[-5]
-  PushConstant         CP#1
-  IndirectStaticCall   1, CP#0
+  DirectCall           1, CP#0
   Drop1
   PushNull
   ReturnTOS
 }
 ConstantPool {
-  [0] = ArgDesc num-args 1, num-type-args 0, names []
-  [1] = StaticICData target '#lib::B::'' (constructor)', arg-desc CP#0
+  [0] = DirectCall '#lib::B:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [1] = Reserved
 }
 ]  synthetic constructor •() → self::C<self::C::T1, self::C::T2, self::C::T3>
     : super self::B::•()
@@ -78,8 +75,7 @@
   AssertAssignable     0, CP#3
   StoreFieldTOS        CP#4
   Push                 FP[-6]
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  DirectCall           1, CP#6
   Drop1
   PushNull
   ReturnTOS
@@ -87,12 +83,12 @@
 ConstantPool {
   [0] = Type dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
   [1] = TypeArgumentsField #lib::D
-  [2] = String ''
+  [2] = ObjectRef ''
   [3] = SubtypeTestCache
   [4] = InstanceField #lib::D::foo (field)
   [5] = Reserved
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target '#lib::C::'' (constructor)', arg-desc CP#6
+  [6] = DirectCall '#lib::C:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
+  [7] = Reserved
 }
 ]  constructor •(dynamic tt) → self::D<self::D::P, self::D::Q>
     : self::D::foo = tt as{TypeError} core::Map<self::D::P, self::D::Q>, super self::C::•()
@@ -106,34 +102,32 @@
   LoadTypeArgumentsField CP#0
   PushNull
   PushConstant         CP#1
-  InterfaceCall        4, CP#3
+  InterfaceCall        4, CP#2
   JumpIfFalse          L1
-  PushConstant         CP#5
-  PushConstant         CP#7
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#4
+  DirectCall           1, CP#5
   Drop1
 L1:
   Push                 FP[-5]
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
   PushNull
-  PushConstant         CP#8
-  InterfaceCall        4, CP#3
+  PushConstant         CP#7
+  InterfaceCall        4, CP#2
   JumpIfFalse          L2
-  PushConstant         CP#9
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#6
+  PushConstant         CP#8
+  DirectCall           1, CP#5
   Drop1
 L2:
   Push                 FP[-6]
   Push                 FP[-5]
-  PushConstant         CP#11
+  PushConstant         CP#9
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
   PushNull
-  PushConstant         CP#12
-  AssertAssignable     0, CP#13
-  InterfaceCall        2, CP#15
+  PushConstant         CP#10
+  AssertAssignable     0, CP#11
+  InterfaceCall        2, CP#12
   Drop1
   PushNull
   ReturnTOS
@@ -141,21 +135,18 @@
 ConstantPool {
   [0] = TypeArgumentsField #lib::D
   [1] = Type #lib::A < #lib::D::TypeParam/0 >
-  [2] = ArgDesc num-args 4, num-type-args 0, names []
-  [3] = InterfaceCall target-name '_instanceOf', arg-desc CP#2
-  [4] = Reserved
-  [5] = String '21'
-  [6] = ArgDesc num-args 1, num-type-args 0, names []
-  [7] = StaticICData target 'dart:core::print', arg-desc CP#6
-  [8] = Type #lib::C < dynamic, #lib::D::TypeParam/1, dart:core::List < #lib::D::TypeParam/0 > >
-  [9] = String '22'
-  [10] = StaticICData target 'dart:core::print', arg-desc CP#6
-  [11] = Type dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
-  [12] = String ''
-  [13] = SubtypeTestCache
-  [14] = ArgDesc num-args 2, num-type-args 0, names []
-  [15] = InterfaceCall set target-name 'set:foo', arg-desc CP#14
-  [16] = Reserved
+  [2] = InterfaceCall 'dart:core::Object::_instanceOf', ArgDesc num-args 4, num-type-args 0, names []
+  [3] = Reserved
+  [4] = ObjectRef '21'
+  [5] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [6] = Reserved
+  [7] = Type #lib::C < dart:core::String, dynamic, #lib::D::TypeParam/1, dart:core::List < #lib::D::TypeParam/0 > >
+  [8] = ObjectRef '22'
+  [9] = Type dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
+  [10] = ObjectRef ''
+  [11] = SubtypeTestCache
+  [12] = InterfaceCall '#lib::D::set:foo', ArgDesc num-args 2, num-type-args 0, names []
+  [13] = Reserved
 }
 ]  method foo2(dynamic y) → dynamic {
     if(y is self::A<self::D::P>) {
@@ -175,52 +166,48 @@
   PushNull
   Push                 r0
   PushConstant         CP#0
-  InterfaceCall        4, CP#2
+  InterfaceCall        4, CP#1
   JumpIfFalse          L1
-  PushConstant         CP#4
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#3
+  DirectCall           1, CP#4
   Drop1
 L1:
   Push                 FP[-5]
   Push                 FP[-6]
-  LoadTypeArgumentsField CP#7
+  LoadTypeArgumentsField CP#6
   Push                 r0
-  PushConstant         CP#8
-  InterfaceCall        4, CP#2
+  PushConstant         CP#7
+  InterfaceCall        4, CP#1
   JumpIfFalse          L2
-  PushConstant         CP#9
-  PushConstant         CP#10
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#8
+  DirectCall           1, CP#4
   Drop1
 L2:
   Push                 FP[-5]
-  PushConstant         CP#11
+  PushConstant         CP#9
   Push                 FP[-6]
-  LoadTypeArgumentsField CP#7
+  LoadTypeArgumentsField CP#6
   Push                 r0
-  PushConstant         CP#12
-  AssertAssignable     0, CP#13
-  InterfaceCall        1, CP#14
+  PushConstant         CP#10
+  AssertAssignable     0, CP#11
+  InterfaceCall        1, CP#12
   ReturnTOS
 }
 ConstantPool {
   [0] = Type #lib::A < #lib::D::foo3::TypeParam/0 >
-  [1] = ArgDesc num-args 4, num-type-args 0, names []
-  [2] = InterfaceCall target-name '_instanceOf', arg-desc CP#1
-  [3] = Reserved
-  [4] = String '31'
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [7] = TypeArgumentsField #lib::D
-  [8] = Type #lib::C < dart:core::Map < #lib::D::foo3::TypeParam/0, #lib::D::TypeParam/0 >, dart:core::List < #lib::D::foo3::TypeParam/1 >, #lib::D::TypeParam/1 >
-  [9] = String '32'
-  [10] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [11] = Type dart:core::Map < #lib::D::foo3::TypeParam/1, #lib::D::TypeParam/1 >
-  [12] = String ' in type cast'
-  [13] = SubtypeTestCache
-  [14] = InterfaceCall get target-name 'get:values', arg-desc CP#5
-  [15] = Reserved
+  [1] = InterfaceCall 'dart:core::Object::_instanceOf', ArgDesc num-args 4, num-type-args 0, names []
+  [2] = Reserved
+  [3] = ObjectRef '31'
+  [4] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
+  [6] = TypeArgumentsField #lib::D
+  [7] = Type #lib::C < dart:core::String, dart:core::Map < #lib::D::foo3::TypeParam/0, #lib::D::TypeParam/0 >, dart:core::List < #lib::D::foo3::TypeParam/1 >, #lib::D::TypeParam/1 >
+  [8] = ObjectRef '32'
+  [9] = Type dart:core::Map < #lib::D::foo3::TypeParam/1, #lib::D::TypeParam/1 >
+  [10] = ObjectRef ' in type cast'
+  [11] = SubtypeTestCache
+  [12] = InterfaceCall 'dart:core::Map::get:values', ArgDesc num-args 1, num-type-args 0, names []
+  [13] = Reserved
 }
 ]  method foo3<T1 extends core::Object = dynamic, T2 extends core::Object = dynamic>(dynamic z) → dynamic {
     if(z is self::A<self::D::foo3::T1>) {
@@ -254,8 +241,7 @@
   PushConstant         CP#3
   AssertAssignable     0, CP#4
   StoreIndexedTOS
-  PushConstant         CP#6
-  IndirectStaticCall   2, CP#5
+  DirectCall           2, CP#5
   PopLocal             r0
   Push                 FP[-5]
   PushConstant         CP#2
@@ -268,12 +254,12 @@
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::D
-  [1] = TypeArgs [dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >]
+  [1] = ObjectRef < dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 > >
   [2] = Type dart:core::Map < #lib::D::TypeParam/0, #lib::D::TypeParam/1 >
-  [3] = String ''
+  [3] = ObjectRef ''
   [4] = SubtypeTestCache
-  [5] = ArgDesc num-args 2, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::List::_fromLiteral (constructor)', arg-desc CP#5
+  [5] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [6] = Reserved
   [7] = SubtypeTestCache
 }
 ]  method foo4(dynamic w) → core::Map<self::D::P, self::D::Q> {
@@ -317,10 +303,10 @@
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::E
-  [1] = TypeArgs [#lib::E::TypeParam/0, dart:core::List < #lib::E::TypeParam/0 >]
+  [1] = ObjectRef < #lib::E::TypeParam/0, dart:core::List < #lib::E::TypeParam/0 > >
   [2] = Type #lib::E::foo6::TypeParam/0
   [3] = Type #lib::E::TypeParam/0
-  [4] = String 'T'
+  [4] = ObjectRef 'T'
 }
 ]  method foo6<generic-covariant-impl T extends self::E::P = self::E::P, U extends core::List<self::E::foo6::T> = core::List<self::E::P>>(core::Map<self::E::foo6::T, self::E::foo6::U> map) → void {}
 }
@@ -331,49 +317,44 @@
   CheckStack           0
   Push                 FP[-5]
   PushConstant         CP#0
-  InterfaceCall        2, CP#2
+  InterfaceCall        2, CP#1
   JumpIfFalse          L1
-  PushConstant         CP#4
-  PushConstant         CP#6
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#3
+  DirectCall           1, CP#4
   Drop1
 L1:
   Push                 FP[-5]
   PushNull
   PushNull
-  PushConstant         CP#7
-  InterfaceCall        4, CP#9
+  PushConstant         CP#6
+  InterfaceCall        4, CP#7
   JumpIfFalse          L2
-  PushConstant         CP#11
-  PushConstant         CP#12
-  IndirectStaticCall   1, CP#5
+  PushConstant         CP#9
+  DirectCall           1, CP#4
   Drop1
 L2:
   Push                 FP[-5]
-  PushConstant         CP#13
+  PushConstant         CP#10
   PushNull
   PushNull
-  PushConstant         CP#14
-  AssertAssignable     0, CP#15
+  PushConstant         CP#11
+  AssertAssignable     0, CP#12
   ReturnTOS
 }
 ConstantPool {
   [0] = Type #lib::B
-  [1] = ArgDesc num-args 2, num-type-args 0, names []
-  [2] = InterfaceCall target-name '_simpleInstanceOf', arg-desc CP#1
-  [3] = Reserved
-  [4] = String '11'
-  [5] = ArgDesc num-args 1, num-type-args 0, names []
-  [6] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [7] = Type #lib::C < dart:core::int, dart:core::Object, dynamic >
-  [8] = ArgDesc num-args 4, num-type-args 0, names []
-  [9] = InterfaceCall target-name '_instanceOf', arg-desc CP#8
-  [10] = Reserved
-  [11] = String '12'
-  [12] = StaticICData target 'dart:core::print', arg-desc CP#5
-  [13] = Type #lib::A < dart:core::int >
-  [14] = String ' in type cast'
-  [15] = SubtypeTestCache
+  [1] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
+  [2] = Reserved
+  [3] = ObjectRef '11'
+  [4] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [5] = Reserved
+  [6] = Type #lib::C < dart:core::String, dart:core::int, dart:core::Object, dynamic >
+  [7] = InterfaceCall 'dart:core::Object::_instanceOf', ArgDesc num-args 4, num-type-args 0, names []
+  [8] = Reserved
+  [9] = ObjectRef '12'
+  [10] = Type #lib::A < dart:core::int >
+  [11] = ObjectRef ' in type cast'
+  [12] = SubtypeTestCache
 }
 ]static method foo1(dynamic x) → dynamic {
   if(x is self::B) {
@@ -399,8 +380,8 @@
   ReturnTOS
 }
 ConstantPool {
-  [0] = Type dart:core::List < dart:core::Iterable < dynamic > >
-  [1] = String ''
+  [0] = Type dart:core::List < dart:core::Iterable null >
+  [1] = ObjectRef ''
   [2] = SubtypeTestCache
   [3] = StaticField #lib::globalVar (field)
 }
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 b2c1ba2..fb2975e 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
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:typed_data" as typ;
 
+import "dart:typed_data";
+
 class _Vector extends core::Object {
 [@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::int _offset;
 [@vm.inferred-type.metadata=dart.core::_Smi] [@vm.procedure-attributes.metadata=hasDynamicUses:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false]  final field core::int _length;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
index a84a25f..122b604 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/class_generics_case1.dart.expect
@@ -2,6 +2,8 @@
 import self as self;
 import "dart:core" as core;
 
+import "dart:collection";
+
 class Element extends core::Object {
   synthetic constructor •() → self::Element
     : super core::Object::•()
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
index 3998132..0af71e5 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future.dart.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 class C<T extends core::Object = dynamic> extends core::Object {
   synthetic constructor •() → self::C<self::C::T>
     : super core::Object::•()
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index 4a94677..5b867b7 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -3,6 +3,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+import "dart:async";
+
 abstract class A extends core::Object {
   synthetic constructor •() → self::A
     : super core::Object::•()
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 feb28eb..0630a2a 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
@@ -4,6 +4,8 @@
 import "dart:_internal" as _in;
 import "package:expect/expect.dart" as exp;
 
+import "package:expect/expect.dart";
+
 class T1 extends core::Object {
   synthetic constructor •() → self::T1
     : super core::Object::•()
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index f220caa..41a4b0a 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -4,15 +4,15 @@
 
 import("../../build/dart/dart_action.gni")
 import("../runtime_args.gni")
-import("../vm/heap/heap_sources.gni")
 import("../vm/compiler/compiler_sources.gni")
+import("../vm/heap/heap_sources.gni")
 import("../vm/vm_sources.gni")
 import("builtin_impl_sources.gni")
 import("builtin_sources.gni")
-import("io_impl_sources.gni")
-import("io_sources.gni")
 import("cli_impl_sources.gni")
 import("cli_sources.gni")
+import("io_impl_sources.gni")
+import("io_sources.gni")
 
 config("libdart_builtin_config") {
   if (!is_win) {
@@ -981,6 +981,73 @@
   }
 }
 
+shared_library("entrypoints_verification_test_extension") {
+  deps = [
+    ":dart",
+  ]
+  sources = [
+    "entrypoints_verification_test_extension.cc",
+    "entrypoints_verification_test_extension_dllmain_win.cc",
+  ]
+  include_dirs = [ ".." ]
+  defines = [
+    # The only effect of DART_SHARED_LIB is to export the Dart API.
+    "DART_SHARED_LIB",
+  ]
+  if (is_linux || is_android) {
+    cflags = [ "-fPIC" ]
+  }
+  if (is_win) {
+    libs = [ "dart.lib" ]
+    abs_root_out_dir = rebase_path(root_out_dir)
+    ldflags = [ "/LIBPATH:$abs_root_out_dir" ]
+  }
+}
+
+shared_library("ffi_test_dynamic_library") {
+  deps = [
+    ":dart",
+  ]
+  sources = [
+    "ffi_test_dynamic_library.cc",
+  ]
+  include_dirs = [ ".." ]
+  defines = [
+    # The only effect of DART_SHARED_LIB is to export the Dart API.
+    "DART_SHARED_LIB",
+  ]
+  if (is_linux || is_android) {
+    cflags = [ "-fPIC" ]
+  }
+  if (is_win) {
+    libs = [ "dart.lib" ]
+    abs_root_out_dir = rebase_path(root_out_dir)
+    ldflags = [ "/LIBPATH:$abs_root_out_dir" ]
+  }
+}
+
+shared_library("ffi_test_functions") {
+  deps = [
+    ":dart",
+  ]
+  sources = [
+    "ffi_test_functions.cc",
+  ]
+  include_dirs = [ ".." ]
+  defines = [
+    # The only effect of DART_SHARED_LIB is to export the Dart API.
+    "DART_SHARED_LIB",
+  ]
+  if (is_linux || is_android) {
+    cflags = [ "-fPIC" ]
+  }
+  if (is_win) {
+    libs = [ "dart.lib" ]
+    abs_root_out_dir = rebase_path(root_out_dir)
+    ldflags = [ "/LIBPATH:$abs_root_out_dir" ]
+  }
+}
+
 shared_library("sample_extension") {
   deps = [
     ":dart",
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 2d663e0..363469b 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -81,6 +81,7 @@
 // Special handling for Windows paths so that they are compatible with URI
 // handling.
 // Embedder sets this to true if we are running on Windows.
+@pragma("vm:entry-point")
 bool _isWindows = false;
 
 // Logging from builtin.dart is prefixed with a '*'.
diff --git a/runtime/bin/entrypoints_verification_test_extension.cc b/runtime/bin/entrypoints_verification_test_extension.cc
new file mode 100644
index 0000000..e070996
--- /dev/null
+++ b/runtime/bin/entrypoints_verification_test_extension.cc
@@ -0,0 +1,160 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "./include/dart_api.h"
+#include "./include/dart_native_api.h"
+
+#define CHECK(H) DART_CHECK_VALID(H)
+
+#define ASSERT(E)                                                              \
+  if (!(E)) {                                                                  \
+    fprintf(stderr, "Assertion \"" #E "\" failed!");                           \
+    abort();                                                                   \
+  }
+
+Dart_Handle GetCurrentLibrary() {
+  Dart_Handle libraries = Dart_GetLoadedLibraries();
+  CHECK(libraries);
+  intptr_t length = 0;
+  CHECK(Dart_ListLength(libraries, &length));
+  for (intptr_t i = 0; i < length; ++i) {
+    Dart_Handle library = Dart_ListGetAt(libraries, i);
+    CHECK(library);
+    Dart_Handle url = Dart_LibraryUrl(library);
+    CHECK(url);
+    const char* url_str;
+    CHECK(Dart_StringToCString(url, &url_str));
+    if (strstr(url_str, "entrypoints_verification_test")) {
+      return library;
+    }
+  }
+  fprintf(stderr, "Could not find current library!");
+  abort();
+}
+
+void Fail(const char* name, Dart_Handle result) {
+  ASSERT(Dart_IsApiError(result));
+  const char* error = Dart_GetError(result);
+  ASSERT(strstr(error, name));
+  ASSERT(strstr(error, "It is illegal to access"));
+}
+
+void FailClosurize(const char* name, Dart_Handle result) {
+  ASSERT(Dart_IsApiError(result));
+  const char* error = Dart_GetError(result);
+  ASSERT(strstr(error, name));
+  ASSERT(strstr(error, "Entry-points do not allow closurizing methods"));
+}
+
+void TestFields(Dart_Handle target) {
+  Fail("fld0", Dart_GetField(target, Dart_NewStringFromCString("fld0")));
+  Fail("fld0",
+       Dart_SetField(target, Dart_NewStringFromCString("fld0"), Dart_Null()));
+
+  Dart_Handle result =
+      Dart_Invoke(target, Dart_NewStringFromCString("fld0"), 0, nullptr);
+  FailClosurize("fld0", result);
+
+  CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld1")));
+  CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld1"), Dart_Null()));
+  FailClosurize("fld1", Dart_Invoke(target, Dart_NewStringFromCString("fld1"),
+                                    0, nullptr));
+
+  CHECK(Dart_GetField(target, Dart_NewStringFromCString("fld2")));
+  Fail("fld2",
+       Dart_SetField(target, Dart_NewStringFromCString("fld2"), Dart_Null()));
+  FailClosurize("fld2", Dart_Invoke(target, Dart_NewStringFromCString("fld2"),
+                                    0, nullptr));
+
+  Fail("fld3", Dart_GetField(target, Dart_NewStringFromCString("fld3")));
+  CHECK(Dart_SetField(target, Dart_NewStringFromCString("fld3"), Dart_Null()));
+  FailClosurize("fld3", Dart_Invoke(target, Dart_NewStringFromCString("fld3"),
+                                    0, nullptr));
+}
+
+void RunTests(Dart_NativeArguments arguments) {
+  Dart_Handle lib = GetCurrentLibrary();
+
+  //////// Test allocation and constructor invocation.
+
+  Fail("C", Dart_GetClass(lib, Dart_NewStringFromCString("C")));
+
+  Dart_Handle D_class = Dart_GetClass(lib, Dart_NewStringFromCString("D"));
+  CHECK(D_class);
+
+  CHECK(Dart_Allocate(D_class));
+
+  Fail("D.", Dart_New(D_class, Dart_Null(), 0, nullptr));
+
+  CHECK(Dart_New(D_class, Dart_NewStringFromCString("defined"), 0, nullptr));
+  Dart_Handle D =
+      Dart_New(D_class, Dart_NewStringFromCString("fact"), 0, nullptr);
+  CHECK(D);
+
+  //////// Test actions against methods
+
+  Fail("fn0", Dart_Invoke(D, Dart_NewStringFromCString("fn0"), 0, nullptr));
+
+  CHECK(Dart_Invoke(D, Dart_NewStringFromCString("fn1"), 0, nullptr));
+
+  Fail("get_fn0", Dart_GetField(D, Dart_NewStringFromCString("fn0")));
+
+  Fail("get_fn1", Dart_GetField(D, Dart_NewStringFromCString("fn1")));
+
+  Fail("fn2",
+       Dart_Invoke(D_class, Dart_NewStringFromCString("fn2"), 0, nullptr));
+
+  CHECK(Dart_Invoke(D_class, Dart_NewStringFromCString("fn3"), 0, nullptr));
+
+  FailClosurize("fn2",
+                Dart_GetField(D_class, Dart_NewStringFromCString("fn2")));
+
+  FailClosurize("fn3",
+                Dart_GetField(D_class, Dart_NewStringFromCString("fn3")));
+
+  Fail("fn0", Dart_Invoke(lib, Dart_NewStringFromCString("fn0"), 0, nullptr));
+
+  CHECK(Dart_Invoke(lib, Dart_NewStringFromCString("fn1"), 0, nullptr));
+
+  FailClosurize("fn0", Dart_GetField(lib, Dart_NewStringFromCString("fn0")));
+
+  FailClosurize("fn1", Dart_GetField(lib, Dart_NewStringFromCString("fn1")));
+
+  //////// Test actions against fields
+
+  TestFields(D);
+
+  Dart_Handle F_class = Dart_GetClass(lib, Dart_NewStringFromCString("F"));
+  TestFields(F_class);
+
+  TestFields(lib);
+}
+
+Dart_NativeFunction ResolveName(Dart_Handle name,
+                                int argc,
+                                bool* auto_setup_scope) {
+  if (auto_setup_scope == NULL) {
+    return NULL;
+  }
+  *auto_setup_scope = true;
+  return RunTests;
+}
+
+DART_EXPORT Dart_Handle
+entrypoints_verification_test_extension_Init(Dart_Handle parent_library) {
+  if (Dart_IsError(parent_library)) {
+    return parent_library;
+  }
+
+  Dart_Handle result_code =
+      Dart_SetNativeResolver(parent_library, ResolveName, NULL);
+  if (Dart_IsError(result_code)) {
+    return result_code;
+  }
+
+  return Dart_Null();
+}
diff --git a/runtime/bin/entrypoints_verification_test_extension_dllmain_win.cc b/runtime/bin/entrypoints_verification_test_extension_dllmain_win.cc
new file mode 100644
index 0000000..cbf42d5
--- /dev/null
+++ b/runtime/bin/entrypoints_verification_test_extension_dllmain_win.cc
@@ -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.
+
+#include "platform/globals.h"
+#if defined(HOST_OS_WINDOWS)
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>  // NOLINT
+
+BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
+  return true;
+}
+
+#endif  // defined(HOST_OS_WINDOWS)
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 7dc6561..7b73b7e 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -166,13 +166,11 @@
 }
 
 bool Handle::HasPendingRead() {
-  MonitorLocker ml(monitor_);
-  return pending_read_ != NULL;
+  return pending_read_ != nullptr;
 }
 
 bool Handle::HasPendingWrite() {
-  MonitorLocker ml(monitor_);
-  return pending_write_ != NULL;
+  return pending_write_ != nullptr;
 }
 
 void Handle::WaitForReadThreadStarted() {
@@ -258,7 +256,7 @@
 
 void Handle::ReadSyncCompleteAsync() {
   NotifyReadThreadStarted();
-  ASSERT(pending_read_ != NULL);
+  ASSERT(HasPendingRead());
   ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize);
 
   DWORD buffer_size = pending_read_->GetBufferSize();
@@ -283,7 +281,7 @@
 
 bool Handle::IssueRead() {
   ASSERT(type_ != kListenSocket);
-  ASSERT(pending_read_ == NULL);
+  ASSERT(!HasPendingRead());
   OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
   if (SupportsOverlappedIO()) {
     ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
@@ -319,7 +317,7 @@
   MonitorLocker ml(monitor_);
   ASSERT(type_ != kListenSocket);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
-  ASSERT(pending_write_ != NULL);
+  ASSERT(HasPendingWrite());
   ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite);
 
   OverlappedBuffer* buffer = pending_write_;
@@ -395,13 +393,13 @@
 }
 
 bool DirectoryWatchHandle::IsClosed() {
-  return IsClosing() && (pending_read_ == NULL);
+  return IsClosing() && !HasPendingRead();
 }
 
 bool DirectoryWatchHandle::IssueRead() {
   // It may have been started before, as we start the directory-handler when
   // we create it.
-  if ((pending_read_ != NULL) || (data_ready_ != NULL)) {
+  if (HasPendingRead() || (data_ready_ != NULL)) {
     return true;
   }
   OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
@@ -422,7 +420,7 @@
   MonitorLocker ml(monitor_);
   // Stop the outstanding read, so we can close the handle.
 
-  if (pending_read_ != NULL) {
+  if (HasPendingRead()) {
     CancelIoEx(handle(), pending_read_->GetCleanOverlapped());
     // Don't dispose of the buffer, as it will still complete (with length 0).
   }
@@ -660,7 +658,7 @@
 
 intptr_t Handle::Write(const void* buffer, intptr_t num_bytes) {
   MonitorLocker ml(monitor_);
-  if (pending_write_ != NULL) {
+  if (HasPendingWrite()) {
     return 0;
   }
   if (num_bytes > kBufferSize) {
@@ -684,7 +682,7 @@
                         struct sockaddr* sa,
                         socklen_t sa_len) {
   MonitorLocker ml(monitor_);
-  if (pending_write_ != NULL) {
+  if (HasPendingWrite()) {
     return 0;
   }
   if (num_bytes > kBufferSize) {
@@ -728,7 +726,7 @@
 
   while (write_thread_running_) {
     ml.Wait(Monitor::kNoTimeout);
-    if (pending_write_ != NULL) {
+    if (HasPendingWrite()) {
       // We woke up and had a pending write. Execute it.
       WriteSyncCompleteAsync();
     }
@@ -739,7 +737,7 @@
 }
 
 void StdHandle::WriteSyncCompleteAsync() {
-  ASSERT(pending_write_ != NULL);
+  ASSERT(HasPendingWrite());
 
   DWORD bytes_written = -1;
   BOOL ok = WriteFile(handle_, pending_write_->GetBufferStart(),
@@ -759,7 +757,7 @@
 
 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) {
   MonitorLocker ml(monitor_);
-  if (pending_write_ != NULL) {
+  if (HasPendingWrite()) {
     return 0;
   }
   if (num_bytes > kBufferSize) {
@@ -861,7 +859,7 @@
 bool ClientSocket::IssueRead() {
   MonitorLocker ml(monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
-  ASSERT(pending_read_ == NULL);
+  ASSERT(!HasPendingRead());
 
   // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can
   // handle 64k datagrams.
@@ -884,7 +882,7 @@
 bool ClientSocket::IssueWrite() {
   MonitorLocker ml(monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
-  ASSERT(pending_write_ != NULL);
+  ASSERT(HasPendingWrite());
   ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite);
 
   int rc = WSASend(socket(), pending_write_->GetWASBUF(), 1, NULL, 0,
@@ -959,13 +957,13 @@
 }
 
 bool ClientSocket::IsClosed() {
-  return connected_ && closed_;
+  return connected_ && closed_ && !HasPendingRead() && !HasPendingWrite();
 }
 
 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) {
   MonitorLocker ml(monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
-  ASSERT(pending_write_ != NULL);
+  ASSERT(HasPendingWrite());
   ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo);
 
   int rc = WSASendTo(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, sa,
@@ -982,7 +980,7 @@
 bool DatagramSocket::IssueRecvFrom() {
   MonitorLocker ml(monitor_);
   ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
-  ASSERT(pending_read_ == NULL);
+  ASSERT(!HasPendingRead());
 
   OverlappedBuffer* buffer =
       OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength);
diff --git a/runtime/bin/ffi_test_dynamic_library.cc b/runtime/bin/ffi_test_dynamic_library.cc
new file mode 100644
index 0000000..c925300
--- /dev/null
+++ b/runtime/bin/ffi_test_dynamic_library.cc
@@ -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.
+
+#include "include/dart_api.h"
+
+DART_EXPORT int return42() {
+  return 42;
+}
+
+DART_EXPORT double timesFour(double d) {
+  return d * 4.0;
+}
diff --git a/runtime/bin/ffi_test_functions.cc b/runtime/bin/ffi_test_functions.cc
new file mode 100644
index 0000000..0248829
--- /dev/null
+++ b/runtime/bin/ffi_test_functions.cc
@@ -0,0 +1,368 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 contains test functions for the dart:ffi test cases.
+
+#include <stddef.h>
+#include <iostream>
+
+#include "include/dart_api.h"
+
+namespace dart {
+
+// Sums two ints and adds 42.
+// Simple function to test trampolines.
+// Also used for testing argument exception on passing null instead of a Dart
+// int.
+DART_EXPORT int32_t SumPlus42(int32_t a, int32_t b) {
+  std::cout << "SumPlus42(" << a << ", " << b << ")\n";
+  int32_t retval = 42 + a + b;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Performs some computation on various sized signed ints.
+// Used for testing value ranges for signed ints.
+DART_EXPORT int64_t IntComputation(int8_t a, int16_t b, int32_t c, int64_t d) {
+  std::cout << "IntComputation(" << static_cast<int>(a) << ", " << b << ", "
+            << c << ", " << d << ")\n";
+  int64_t retval = d - c + b - a;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Performs some computation on various sized unsigned ints.
+// Used for testing value ranges for unsigned ints.
+DART_EXPORT int64_t UintComputation(uint8_t a,
+                                    uint16_t b,
+                                    uint32_t c,
+                                    uint64_t d) {
+  std::cout << "UintComputation(" << static_cast<int>(a) << ", " << b << ", "
+            << c << ", " << d << ")\n";
+  uint64_t retval = d - c + b - a;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Multiplies pointer sized int by three.
+// Used for testing pointer sized parameter and return value.
+DART_EXPORT intptr_t Times3(intptr_t a) {
+  std::cout << "Times3(" << a << ")\n";
+  intptr_t retval = a * 3;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Multiples a double by 1.337.
+// Used for testing double parameter and return value.
+// Also used for testing argument exception on passing null instead of a Dart
+// double.
+DART_EXPORT double Times1_337Double(double a) {
+  std::cout << "Times1_337Double(" << a << ")\n";
+  double retval = a * 1.337;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Multiples a float by 1.337.
+// Used for testing float parameter and return value.
+DART_EXPORT float Times1_337Float(float a) {
+  std::cout << "Times1_337Float(" << a << ")\n";
+  float retval = a * 1.337f;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Sums many ints.
+// Used for testing calling conventions. With so many doubles we are using all
+// normal parameter registers and some stack slots.
+DART_EXPORT intptr_t SumManyInts(intptr_t a,
+                                 intptr_t b,
+                                 intptr_t c,
+                                 intptr_t d,
+                                 intptr_t e,
+                                 intptr_t f,
+                                 intptr_t g,
+                                 intptr_t h,
+                                 intptr_t i,
+                                 intptr_t j) {
+  std::cout << "SumManyInts(" << a << ", " << b << ", " << c << ", " << d
+            << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
+            << ", " << j << ")\n";
+  intptr_t retval = a + b + c + d + e + f + g + h + i + j;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Sums many doubles.
+// Used for testing calling conventions. With so many doubles we are using all
+// xmm parameter registers and some stack slots.
+DART_EXPORT double SumManyDoubles(double a,
+                                  double b,
+                                  double c,
+                                  double d,
+                                  double e,
+                                  double f,
+                                  double g,
+                                  double h,
+                                  double i,
+                                  double j) {
+  std::cout << "SumManyDoubles(" << a << ", " << b << ", " << c << ", " << d
+            << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
+            << ", " << j << ")\n";
+  double retval = a + b + c + d + e + f + g + h + i + j;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Sums many numbers.
+// Used for testing calling conventions. With so many parameters we are using
+// both registers and stack slots.
+DART_EXPORT double SumManyNumbers(int a,
+                                  float b,
+                                  int c,
+                                  double d,
+                                  int e,
+                                  float f,
+                                  int g,
+                                  double h,
+                                  int i,
+                                  float j,
+                                  int k,
+                                  double l,
+                                  int m,
+                                  float n,
+                                  int o,
+                                  double p,
+                                  int q,
+                                  float r,
+                                  int s,
+                                  double t) {
+  std::cout << "SumManyNumbers(" << a << ", " << b << ", " << c << ", " << d
+            << ", " << e << ", " << f << ", " << g << ", " << h << ", " << i
+            << ", " << j << ", " << k << ", " << l << ", " << m << ", " << n
+            << ", " << o << ", " << p << ", " << q << ", " << r << ", " << s
+            << ", " << t << ")\n";
+  double retval = a + b + c + d + e + f + g + h + i + j + k + l + m + n + o +
+                  p + q + r + s + t;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Assigns 1337 to the second element and returns the address of that element.
+// Used for testing Pointer parameters and return values.
+DART_EXPORT int64_t* Assign1337Index1(int64_t* a) {
+  std::cout << "Assign1337Index1(" << a << ")\n";
+  std::cout << "val[0] = " << a[0] << "\n";
+  std::cout << "val[1] = " << a[1] << "\n";
+  a[1] = 1337;
+  std::cout << "val[1] = " << a[1] << "\n";
+  int64_t* retval = a + 1;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+struct Coord {
+  double x;
+  double y;
+  Coord* next;
+};
+
+// Transposes Coordinate by (10, 10) and returns next Coordinate.
+// Used for testing struct pointer parameter, struct pointer return value,
+// struct field access, and struct pointer field dereference.
+DART_EXPORT Coord* TransposeCoordinate(Coord* coord) {
+  std::cout << "TransposeCoordinate(" << coord << " {" << coord->x << ", "
+            << coord->y << ", " << coord->next << "})\n";
+  coord->x = coord->x + 10.0;
+  coord->y = coord->y + 10.0;
+  std::cout << "returning " << coord->next << "\n";
+  return coord->next;
+}
+
+// Takes a Coordinate array and returns a Coordinate pointer to the next
+// element.
+// Used for testing struct arrays.
+DART_EXPORT Coord* CoordinateElemAt1(Coord* coord) {
+  std::cout << "CoordinateElemAt1(" << coord << ")\n";
+  std::cout << "sizeof(Coord): " << sizeof(Coord) << "\n";
+  std::cout << "coord[0] = {" << coord[0].x << ", " << coord[0].y << ", "
+            << coord[0].next << "}\n";
+  std::cout << "coord[1] = {" << coord[1].x << ", " << coord[1].y << ", "
+            << coord[1].next << "}\n";
+  Coord* retval = coord + 1;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+typedef Coord* (*CoordUnOp)(Coord* coord);
+
+// Takes a Coordinate Function(Coordinate) and applies it three times to a
+// Coordinate.
+// Used for testing function pointers with structs.
+DART_EXPORT Coord* CoordinateUnOpTrice(CoordUnOp unop, Coord* coord) {
+  std::cout << "CoordinateUnOpTrice(" << unop << ", " << coord << ")\n";
+  Coord* retval = unop(unop(unop(coord)));
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+typedef intptr_t (*IntptrBinOp)(intptr_t a, intptr_t b);
+
+// Returns a closure.
+// Note this closure is not properly marked as DART_EXPORT or extern "C".
+// Used for testing passing a pointer to a closure to Dart.
+// TODO(dacoharkes): is this a supported use case?
+DART_EXPORT IntptrBinOp IntptrAdditionClosure() {
+  std::cout << "IntptrAdditionClosure()\n";
+  IntptrBinOp retval = [](intptr_t a, intptr_t b) { return a + b; };
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Applies an intptr binop function to 42 and 74.
+// Used for testing passing a function pointer to C.
+DART_EXPORT intptr_t ApplyTo42And74(IntptrBinOp binop) {
+  std::cout << "ApplyTo42And74()\n";
+  intptr_t retval = binop(42, 74);
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Returns next element in the array, unless a null pointer is passed.
+// When a null pointer is passed, a null pointer is returned.
+// Used for testing null pointers.
+DART_EXPORT int64_t* NullableInt64ElemAt1(int64_t* a) {
+  std::cout << "NullableInt64ElemAt1(" << a << ")\n";
+  int64_t* retval;
+  if (a) {
+    std::cout << "not null pointer, address: " << a << "\n";
+    retval = a + 1;
+  } else {
+    std::cout << "null pointer, address: " << a << "\n";
+    retval = nullptr;
+  }
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+struct VeryLargeStruct {
+  int8_t a;
+  int16_t b;
+  int32_t c;
+  int64_t d;
+  uint8_t e;
+  uint16_t f;
+  uint32_t g;
+  uint64_t h;
+  intptr_t i;
+  float j;
+  double k;
+  VeryLargeStruct* parent;
+  intptr_t numChildren;
+  VeryLargeStruct* children;
+  int8_t smallLastField;
+};
+
+// Sums the fields of a very large struct, including the first field (a) from
+// the parent and children.
+// Used for testing alignment and padding in structs.
+DART_EXPORT int64_t SumVeryLargeStruct(VeryLargeStruct* vls) {
+  std::cout << "SumVeryLargeStruct(" << vls << ")\n";
+  std::cout << "offsetof(a): " << offsetof(VeryLargeStruct, a) << "\n";
+  std::cout << "offsetof(b): " << offsetof(VeryLargeStruct, b) << "\n";
+  std::cout << "offsetof(c): " << offsetof(VeryLargeStruct, c) << "\n";
+  std::cout << "offsetof(d): " << offsetof(VeryLargeStruct, d) << "\n";
+  std::cout << "offsetof(e): " << offsetof(VeryLargeStruct, e) << "\n";
+  std::cout << "offsetof(f): " << offsetof(VeryLargeStruct, f) << "\n";
+  std::cout << "offsetof(g): " << offsetof(VeryLargeStruct, g) << "\n";
+  std::cout << "offsetof(h): " << offsetof(VeryLargeStruct, h) << "\n";
+  std::cout << "offsetof(i): " << offsetof(VeryLargeStruct, i) << "\n";
+  std::cout << "offsetof(j): " << offsetof(VeryLargeStruct, j) << "\n";
+  std::cout << "offsetof(k): " << offsetof(VeryLargeStruct, k) << "\n";
+  std::cout << "offsetof(parent): " << offsetof(VeryLargeStruct, parent)
+            << "\n";
+  std::cout << "offsetof(numChildren): "
+            << offsetof(VeryLargeStruct, numChildren) << "\n";
+  std::cout << "offsetof(children): " << offsetof(VeryLargeStruct, children)
+            << "\n";
+  std::cout << "offsetof(smallLastField): "
+            << offsetof(VeryLargeStruct, smallLastField) << "\n";
+  std::cout << "sizeof(VeryLargeStruct): " << sizeof(VeryLargeStruct) << "\n";
+
+  std::cout << "vls->a: " << static_cast<int>(vls->a) << "\n";
+  std::cout << "vls->b: " << vls->b << "\n";
+  std::cout << "vls->c: " << vls->c << "\n";
+  std::cout << "vls->d: " << vls->d << "\n";
+  std::cout << "vls->e: " << static_cast<int>(vls->e) << "\n";
+  std::cout << "vls->f: " << vls->f << "\n";
+  std::cout << "vls->g: " << vls->g << "\n";
+  std::cout << "vls->h: " << vls->h << "\n";
+  std::cout << "vls->i: " << vls->i << "\n";
+  std::cout << "vls->j: " << vls->j << "\n";
+  std::cout << "vls->k: " << vls->k << "\n";
+  std::cout << "vls->parent: " << vls->parent << "\n";
+  std::cout << "vls->numChildren: " << vls->numChildren << "\n";
+  std::cout << "vls->children: " << vls->children << "\n";
+  std::cout << "vls->smallLastField: " << static_cast<int>(vls->smallLastField)
+            << "\n";
+
+  int64_t retval = 0;
+  retval += 0x0L + vls->a;
+  retval += vls->b;
+  retval += vls->c;
+  retval += vls->d;
+  retval += vls->e;
+  retval += vls->f;
+  retval += vls->g;
+  retval += vls->h;
+  retval += vls->i;
+  retval += vls->j;
+  retval += vls->k;
+  retval += vls->smallLastField;
+  std::cout << retval << "\n";
+  if (vls->parent) {
+    std::cout << "has parent\n";
+    retval += vls->parent->a;
+  }
+  std::cout << "has " << vls->numChildren << " children\n";
+  for (int i = 0; i < vls->numChildren; i++) {
+    retval += vls->children[i].a;
+  }
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Sums numbers of various sizes.
+// Used for testing truncation and sign extension of non 64 bit parameters.
+DART_EXPORT int64_t SumSmallNumbers(int8_t a,
+                                    int16_t b,
+                                    int32_t c,
+                                    uint8_t d,
+                                    uint16_t e,
+                                    uint32_t f) {
+  std::cout << "SumSmallNumbers(" << static_cast<int>(a) << ", " << b << ", "
+            << c << ", " << static_cast<int>(d) << ", " << e << ", " << f
+            << ")\n";
+  int64_t retval = 0;
+  retval += a;
+  retval += b;
+  retval += c;
+  retval += d;
+  retval += e;
+  retval += f;
+  std::cout << "returning " << retval << "\n";
+  return retval;
+}
+
+// Checks whether the float is between 1336.0f and 1338.0f.
+// Used for testing rounding of Dart Doubles to floats in Pointer.store().
+DART_EXPORT uint8_t IsRoughly1337(float* a) {
+  std::cout << "IsRoughly1337(" << a[0] << ")\n";
+  uint8_t retval = (1336.0f < a[0] && a[0] < 1338.0f) ? 1 : 0;
+  std::cout << "returning " << static_cast<int>(retval) << "\n";
+  return retval;
+}
+
+}  // namespace dart
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 0bc02c0..cdbbc95 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -113,12 +113,15 @@
 }
 
 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) {
-  Namespace* namespc = Namespace::GetNamespace(args, 0);
-  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
-  TypedDataScope data(path_handle);
-  ASSERT(data.type() == Dart_TypedData_kUint8);
-  const char* filename = data.GetCString();
-  bool exists = File::Exists(namespc, filename);
+  bool exists;
+  {
+    Namespace* namespc = Namespace::GetNamespace(args, 0);
+    Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* filename = data.GetCString();
+    exists = File::Exists(namespc, filename);
+  }
   Dart_SetBooleanReturnValue(args, exists);
 }
 
@@ -710,13 +713,16 @@
 }
 
 void FUNCTION_NAME(File_GetType)(Dart_NativeArguments args) {
-  Namespace* namespc = Namespace::GetNamespace(args, 0);
-  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
-  TypedDataScope data(path_handle);
-  ASSERT(data.type() == Dart_TypedData_kUint8);
-  const char* path = data.GetCString();
-  bool follow_links = DartUtils::GetNativeBooleanArgument(args, 2);
-  File::Type type = File::GetType(namespc, path, follow_links);
+  File::Type type;
+  {
+    Namespace* namespc = Namespace::GetNamespace(args, 0);
+    Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* path = data.GetCString();
+    bool follow_links = DartUtils::GetNativeBooleanArgument(args, 2);
+    type = File::GetType(namespc, path, follow_links);
+  }
   Dart_SetIntegerReturnValue(args, static_cast<int>(type));
 }
 
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index d7d5b3f..0b59b20 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -375,63 +375,32 @@
 static const int kReparseDataHeaderSize = sizeof ULONG + 2 * sizeof USHORT;
 static const int kMountPointHeaderSize = 4 * sizeof USHORT;
 
+// Note: CreateLink used to create junctions on Windows instead of true
+// symbolic links. All File::*Link methods now support handling links created
+// as junctions and symbolic links.
 bool File::CreateLink(Namespace* namespc,
                       const char* utf8_name,
                       const char* utf8_target) {
   Utf8ToWideScope name(utf8_name);
-  int create_status = CreateDirectoryW(name.wide(), NULL);
-  // If the directory already existed, treat it as a success.
-  if ((create_status == 0) &&
-      ((GetLastError() != ERROR_ALREADY_EXISTS) ||
-       ((GetFileAttributesW(name.wide()) & FILE_ATTRIBUTE_DIRECTORY) != 0))) {
-    return false;
-  }
-
-  HANDLE dir_handle = CreateFileW(
-      name.wide(), GENERIC_READ | GENERIC_WRITE,
-      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
-      OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
-      NULL);
-  if (dir_handle == INVALID_HANDLE_VALUE) {
-    return false;
-  }
-
   Utf8ToWideScope target(utf8_target);
-  int target_len = wcslen(target.wide());
-  if (target_len > MAX_PATH - 1) {
-    CloseHandle(dir_handle);
-    return false;
+  DWORD flags = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
+
+  File::Type type = File::GetType(namespc, utf8_target, true);
+  if (type == kIsDirectory) {
+    flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
   }
 
-  int reparse_data_buffer_size =
-      sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR;
-  REPARSE_DATA_BUFFER* reparse_data_buffer =
-      reinterpret_cast<REPARSE_DATA_BUFFER*>(malloc(reparse_data_buffer_size));
-  reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
-  wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer,
-         target.wide());
-  wcscpy(
-      reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1,
-      target.wide());
-  reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
-  reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength =
-      target_len * sizeof WCHAR;
-  reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset =
-      (target_len + 1) * sizeof WCHAR;
-  reparse_data_buffer->MountPointReparseBuffer.PrintNameLength =
-      target_len * sizeof WCHAR;
-  reparse_data_buffer->ReparseDataLength =
-      (target_len + 1) * 2 * sizeof WCHAR + kMountPointHeaderSize;
-  DWORD dummy_received_bytes;
-  int result = DeviceIoControl(
-      dir_handle, FSCTL_SET_REPARSE_POINT, reparse_data_buffer,
-      reparse_data_buffer->ReparseDataLength + kReparseDataHeaderSize, NULL, 0,
-      &dummy_received_bytes, NULL);
-  free(reparse_data_buffer);
-  if (CloseHandle(dir_handle) == 0) {
-    return false;
+  int create_status = CreateSymbolicLinkW(name.wide(), target.wide(), flags);
+
+  // If running on a Windows 10 build older than 14972, an invalid parameter
+  // error will be returned when trying to use the
+  // SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE flag. Retry without the flag.
+  if ((create_status == 0) && (GetLastError() == ERROR_INVALID_PARAMETER)) {
+    flags &= ~SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
+    create_status = CreateSymbolicLinkW(name.wide(), target.wide(), flags);
   }
-  return (result != 0);
+
+  return (create_status != 0);
 }
 
 bool File::Delete(Namespace* namespc, const char* name) {
@@ -444,12 +413,18 @@
   Utf8ToWideScope system_name(name);
   bool result = false;
   DWORD attributes = GetFileAttributesW(system_name.wide());
-  if ((attributes != INVALID_FILE_ATTRIBUTES) &&
-      (attributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
-    // It's a junction(link), delete it.
+  if ((attributes == INVALID_FILE_ATTRIBUTES) ||
+      ((attributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0)) {
+    SetLastError(ERROR_NOT_A_REPARSE_POINT);
+    return false;
+  }
+  if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+    // It's a junction, which is a special type of directory, or a symbolic
+    // link to a directory. Remove the directory.
     result = (RemoveDirectoryW(system_name.wide()) != 0);
   } else {
-    SetLastError(ERROR_NOT_A_REPARSE_POINT);
+    // Symbolic link to a file. Remove the file.
+    result = (DeleteFileW(system_name.wide()) != 0);
   }
   return result;
 }
@@ -458,65 +433,59 @@
                   const char* old_path,
                   const char* new_path) {
   File::Type type = GetType(namespc, old_path, false);
-  if (type == kIsFile) {
-    Utf8ToWideScope system_old_path(old_path);
-    Utf8ToWideScope system_new_path(new_path);
-    DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
-    int move_status =
-        MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
-    return (move_status != 0);
-  } else {
+  if (type != kIsFile) {
     SetLastError(ERROR_FILE_NOT_FOUND);
+    return false;
   }
-  return false;
+  Utf8ToWideScope system_old_path(old_path);
+  Utf8ToWideScope system_new_path(new_path);
+  DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
+  int move_status =
+      MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
+  return (move_status != 0);
 }
 
 bool File::RenameLink(Namespace* namespc,
                       const char* old_path,
                       const char* new_path) {
   File::Type type = GetType(namespc, old_path, false);
-  if (type == kIsLink) {
-    Utf8ToWideScope system_old_path(old_path);
-    Utf8ToWideScope system_new_path(new_path);
-    DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
-    // Links on Windows appear as special directories. MoveFileExW's
-    // MOVEFILE_REPLACE_EXISTING does not allow for replacement of directories,
-    // so we need to remove it before renaming a link.
-    if (Directory::Exists(namespc, new_path) == Directory::EXISTS) {
-      bool result = true;
-      if (GetType(namespc, new_path, false) == kIsLink) {
-        result = DeleteLink(namespc, new_path);
-      } else {
-        result = Delete(namespc, new_path);
-      }
-      // Bail out if the Delete calls fail.
-      if (!result) {
-        return false;
-      }
-    }
-    int move_status =
-        MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
-    return (move_status != 0);
-  } else {
+  if (type != kIsLink) {
     SetLastError(ERROR_FILE_NOT_FOUND);
+    return false;
   }
-  return false;
+  Utf8ToWideScope system_old_path(old_path);
+  Utf8ToWideScope system_new_path(new_path);
+  DWORD flags = MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING;
+
+  // Junction links on Windows appear as special directories. MoveFileExW's
+  // MOVEFILE_REPLACE_EXISTING does not allow for replacement of directories,
+  // so we need to remove it before renaming a link. This step is only
+  // necessary for junctions created by the old Link.create implementation.
+  if ((Directory::Exists(namespc, new_path) == Directory::EXISTS) &&
+      (GetType(namespc, new_path, false) == kIsLink)) {
+    // Bail out if the DeleteLink call fails.
+    if (!DeleteLink(namespc, new_path)) {
+      return false;
+    }
+  }
+  int move_status =
+      MoveFileExW(system_old_path.wide(), system_new_path.wide(), flags);
+  return (move_status != 0);
 }
 
 bool File::Copy(Namespace* namespc,
                 const char* old_path,
                 const char* new_path) {
   File::Type type = GetType(namespc, old_path, false);
-  if (type == kIsFile) {
-    Utf8ToWideScope system_old_path(old_path);
-    Utf8ToWideScope system_new_path(new_path);
-    bool success = CopyFileExW(system_old_path.wide(), system_new_path.wide(),
-                               NULL, NULL, NULL, 0) != 0;
-    return success;
-  } else {
+  if (type != kIsFile) {
     SetLastError(ERROR_FILE_NOT_FOUND);
+    return false;
   }
-  return false;
+  Utf8ToWideScope system_old_path(old_path);
+  Utf8ToWideScope system_new_path(new_path);
+  bool success = CopyFileExW(system_old_path.wide(), system_new_path.wide(),
+                             NULL, NULL, NULL, 0) != 0;
+  return success;
 }
 
 int64_t File::LengthFromPath(Namespace* namespc, const char* name) {
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 3cb0462..c0656b7 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -71,7 +71,6 @@
 enum SnapshotKind {
   kCore,
   kCoreJIT,
-  kCoreJITAll,
   kApp,
   kAppJIT,
   kAppAOTBlobs,
@@ -99,7 +98,6 @@
     // clang-format off
     "core",
     "core-jit",
-    "core-jit-all",
     "app",
     "app-jit",
     "app-aot-blobs",
@@ -132,6 +130,8 @@
   V(save_obfuscation_map, obfuscation_map_filename)
 
 #define BOOL_OPTIONS_LIST(V)                                                   \
+  V(read_all_bytecode, read_all_bytecode)                                      \
+  V(compile_all, compile_all)                                                  \
   V(obfuscate, obfuscate)                                                      \
   V(verbose, verbose)                                                          \
   V(version, version)                                                          \
@@ -286,7 +286,6 @@
       }
       break;
     }
-    case kCoreJITAll:
     case kCoreJIT: {
       if ((vm_snapshot_data_filename == NULL) ||
           (vm_snapshot_instructions_filename == NULL) ||
@@ -461,7 +460,6 @@
         WriteDependenciesWithTarget(isolate_snapshot_data_filename);
         // WriteDependenciesWithTarget(isolate_snapshot_instructions_filename);
         break;
-      case kCoreJITAll:
       case kCoreJIT:
         WriteDependenciesWithTarget(vm_snapshot_data_filename);
         // WriteDependenciesWithTarget(vm_snapshot_instructions_filename);
@@ -550,16 +548,20 @@
   dependencies->Clear();
 }
 
-static void LoadBytecode() {
-  if ((Dart_IsVMFlagSet("enable_interpreter") ||
-       Dart_IsVMFlagSet("use_bytecode_compiler")) &&
-      ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
+static void MaybeLoadCode() {
+  if (read_all_bytecode &&
+      ((snapshot_kind == kCore) || (snapshot_kind == kCoreJIT) ||
+       (snapshot_kind == kApp) || (snapshot_kind == kAppJIT))) {
     Dart_Handle result = Dart_ReadAllBytecode();
     CHECK_RESULT(result);
   }
-}
 
-static void LoadCompilationTrace() {
+  if (compile_all &&
+      ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
+    Dart_Handle result = Dart_CompileAll();
+    CHECK_RESULT(result);
+  }
+
   if ((load_compilation_trace_filename != NULL) &&
       ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
     uint8_t* buffer = NULL;
@@ -568,6 +570,7 @@
     Dart_Handle result = Dart_LoadCompilationTrace(buffer, size);
     CHECK_RESULT(result);
   }
+
   if ((load_type_feedback_filename != NULL) &&
       ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) {
     uint8_t* buffer = NULL;
@@ -578,13 +581,6 @@
   }
 }
 
-static void CompileAll() {
-  if (snapshot_kind == kCoreJITAll) {
-    Dart_Handle result = Dart_CompileAll();
-    CHECK_RESULT(result);
-  }
-}
-
 static void CreateAndWriteCoreSnapshot() {
   ASSERT(snapshot_kind == kCore);
   ASSERT(vm_snapshot_data_filename != NULL);
@@ -645,7 +641,7 @@
 }
 
 static void CreateAndWriteCoreJITSnapshot() {
-  ASSERT((snapshot_kind == kCoreJIT) || (snapshot_kind == kCoreJITAll));
+  ASSERT(snapshot_kind == kCoreJIT);
   ASSERT(vm_snapshot_data_filename != NULL);
   ASSERT(vm_snapshot_instructions_filename != NULL);
   ASSERT(isolate_snapshot_data_filename != NULL);
@@ -909,6 +905,8 @@
       Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size));
   CHECK_RESULT(result);
 
+  MaybeLoadCode();
+
   switch (snapshot_kind) {
     case kAppAOTBlobs:
     case kAppAOTAssembly: {
@@ -927,21 +925,13 @@
     case kCore:
       CreateAndWriteCoreSnapshot();
       break;
-    case kCoreJITAll:
-      CompileAll();
-      CreateAndWriteCoreJITSnapshot();
-      break;
     case kCoreJIT:
-      LoadBytecode();
-      LoadCompilationTrace();
       CreateAndWriteCoreJITSnapshot();
       break;
     case kApp:
       CreateAndWriteAppSnapshot();
       break;
     case kAppJIT:
-      LoadBytecode();
-      LoadCompilationTrace();
       CreateAndWriteAppJITSnapshot();
       break;
     case kVMAOTAssembly: {
@@ -1019,8 +1009,7 @@
 
   if (IsSnapshottingForPrecompilation()) {
     vm_options.AddArgument("--precompilation");
-  } else if ((snapshot_kind == kCoreJITAll) || (snapshot_kind == kCoreJIT) ||
-             (snapshot_kind == kAppJIT)) {
+  } else if ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT)) {
     vm_options.AddArgument("--fields_may_be_reset");
 #if !defined(TARGET_ARCH_IA32)
     vm_options.AddArgument("--link_natives_lazily");
diff --git a/runtime/bin/io_impl_sources.gni b/runtime/bin/io_impl_sources.gni
index 94477a7..a476664 100644
--- a/runtime/bin/io_impl_sources.gni
+++ b/runtime/bin/io_impl_sources.gni
@@ -37,6 +37,7 @@
   "namespace.h",
   "namespace_android.cc",
   "namespace_fuchsia.cc",
+  "namespace_fuchsia.h",
   "namespace_linux.cc",
   "namespace_macos.cc",
   "namespace_win.cc",
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index e5b885e..94a0c35258 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -9,6 +9,7 @@
 
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
+#include "bin/socket_base.h"
 #include "include/dart_api.h"
 #include "platform/assert.h"
 
@@ -109,6 +110,7 @@
   V(Process_ClearSignalHandler, 1)                                             \
   V(ProcessInfo_CurrentRSS, 0)                                                 \
   V(ProcessInfo_MaxRSS, 0)                                                     \
+  V(RawSocketOption_GetOptionValue, 1)                                         \
   V(SecureSocket_Connect, 7)                                                   \
   V(SecureSocket_Destroy, 1)                                                   \
   V(SecureSocket_FilterPointer, 1)                                             \
@@ -137,6 +139,7 @@
   V(Socket_GetRemotePeer, 1)                                                   \
   V(Socket_GetError, 1)                                                        \
   V(Socket_GetOption, 3)                                                       \
+  V(Socket_GetRawOption, 4)                                                    \
   V(Socket_GetSocketId, 1)                                                     \
   V(Socket_GetStdioHandle, 2)                                                  \
   V(Socket_GetType, 1)                                                         \
@@ -146,6 +149,7 @@
   V(Socket_RecvFrom, 1)                                                        \
   V(Socket_SendTo, 6)                                                          \
   V(Socket_SetOption, 4)                                                       \
+  V(Socket_SetRawOption, 4)                                                    \
   V(Socket_SetSocketId, 3)                                                     \
   V(Socket_WriteList, 4)                                                       \
   V(Stdin_ReadByte, 1)                                                         \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index cb1dd8d..301b3ee 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -38,8 +38,6 @@
 #include "platform/hashmap.h"
 #include "platform/text_buffer.h"
 
-#include "vm/flags.h"
-
 extern "C" {
 extern const uint8_t kDartVmSnapshotData[];
 extern const uint8_t kDartVmSnapshotInstructions[];
@@ -228,7 +226,7 @@
   result = DartUtils::PrepareForScriptLoading(false, Options::trace_loading());
   CHECK_RESULT(result);
 
-  if (FLAG_support_service || !kDartPrecompiledRuntime) {
+  if (Dart_IsVMFlagSet("support_service") || !Dart_IsPrecompiledRuntime()) {
     // Set up the load port provided by the service isolate so that we can
     // load scripts.
     result = DartUtils::SetupServiceLoadPort();
@@ -307,7 +305,7 @@
     result = DartUtils::SetupIOLibrary(namespc, script_uri,
                                        Options::exit_disabled());
     CHECK_RESULT(result);
-    if (FLAG_support_service || !kDartPrecompiledRuntime) {
+    if (Dart_IsVMFlagSet("support_service") || !Dart_IsPrecompiledRuntime()) {
       Loader::InitForSnapshot(script_uri);
     }
 #if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/bin/namespace_fuchsia.cc b/runtime/bin/namespace_fuchsia.cc
index 030ba76..843e8b2 100644
--- a/runtime/bin/namespace_fuchsia.cc
+++ b/runtime/bin/namespace_fuchsia.cc
@@ -6,6 +6,7 @@
 #if defined(HOST_OS_FUCHSIA)
 
 #include "bin/namespace.h"
+#include "bin/namespace_fuchsia.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -19,82 +20,67 @@
 namespace dart {
 namespace bin {
 
-class NamespaceImpl {
- public:
-  explicit NamespaceImpl(fdio_ns_t* fdio_ns)
+NamespaceImpl::NamespaceImpl(fdio_ns_t* fdio_ns)
       : fdio_ns_(fdio_ns),
         rootfd_(fdio_ns_opendir(fdio_ns)),
         cwd_(strdup("/")) {
-    ASSERT(rootfd_ > 0);
-    cwdfd_ = dup(rootfd_);
-    ASSERT(cwdfd_ > 0);
-  }
+  ASSERT(rootfd_ > 0);
+  cwdfd_ = dup(rootfd_);
+  ASSERT(cwdfd_ > 0);
+}
 
-  explicit NamespaceImpl(const char* path)
+NamespaceImpl::NamespaceImpl(const char* path)
       : fdio_ns_(NULL),
         rootfd_(TEMP_FAILURE_RETRY(open(path, O_DIRECTORY))),
         cwd_(strdup("/")) {
-    ASSERT(rootfd_ > 0);
-    cwdfd_ = dup(rootfd_);
-    ASSERT(cwdfd_ > 0);
-  }
+  ASSERT(rootfd_ > 0);
+  cwdfd_ = dup(rootfd_);
+  ASSERT(cwdfd_ > 0);
+}
 
-  ~NamespaceImpl() {
-    NO_RETRY_EXPECTED(close(rootfd_));
-    free(cwd_);
-    NO_RETRY_EXPECTED(close(cwdfd_));
-    if (fdio_ns_ != NULL) {
-      zx_status_t status = fdio_ns_destroy(fdio_ns_);
-      if (status != ZX_OK) {
-        Log::PrintErr("fdio_ns_destroy: %s\n", zx_status_get_string(status));
-      }
+NamespaceImpl::~NamespaceImpl() {
+  NO_RETRY_EXPECTED(close(rootfd_));
+  free(cwd_);
+  NO_RETRY_EXPECTED(close(cwdfd_));
+  if (fdio_ns_ != NULL) {
+    zx_status_t status = fdio_ns_destroy(fdio_ns_);
+    if (status != ZX_OK) {
+      Log::PrintErr("fdio_ns_destroy: %s\n", zx_status_get_string(status));
     }
   }
+}
 
-  intptr_t rootfd() const { return rootfd_; }
-  char* cwd() const { return cwd_; }
-  intptr_t cwdfd() const { return cwdfd_; }
-
-  bool SetCwd(Namespace* namespc, const char* new_path) {
-    NamespaceScope ns(namespc, new_path);
-    const intptr_t new_cwdfd =
-        TEMP_FAILURE_RETRY(openat(ns.fd(), ns.path(), O_DIRECTORY));
-    if (new_cwdfd != 0) {
-      return false;
-    }
-
-    // Build the new cwd.
-    TextBuffer tbuf(PATH_MAX);
-    if (!File::IsAbsolutePath(new_path)) {
-      tbuf.AddString(cwd_);
-    }
-    tbuf.AddString(File::PathSeparator());
-    tbuf.AddString(ns.path());
-
-    // Normalize it.
-    char result[PATH_MAX];
-    const intptr_t result_len =
-        File::CleanUnixPath(tbuf.buf(), result, PATH_MAX);
-    if (result_len < 0) {
-      errno = ENAMETOOLONG;
-      return false;
-    }
-
-    free(cwd_);
-    cwd_ = strdup(result);
-    close(cwdfd_);
-    cwdfd_ = new_cwdfd;
-    return true;
+bool NamespaceImpl::SetCwd(Namespace* namespc, const char* new_path) {
+  NamespaceScope ns(namespc, new_path);
+  const intptr_t new_cwdfd =
+      TEMP_FAILURE_RETRY(openat(ns.fd(), ns.path(), O_DIRECTORY));
+  if (new_cwdfd != 0) {
+    return false;
   }
 
- private:
-  fdio_ns_t* fdio_ns_;  // native namespace object, if any.
-  intptr_t rootfd_;     // dirfd for the namespace root.
-  char* cwd_;           // cwd relative to the namespace.
-  intptr_t cwdfd_;      // dirfd for the cwd.
+  // Build the new cwd.
+  TextBuffer tbuf(PATH_MAX);
+  if (!File::IsAbsolutePath(new_path)) {
+    tbuf.AddString(cwd_);
+  }
+  tbuf.AddString(File::PathSeparator());
+  tbuf.AddString(ns.path());
 
-  DISALLOW_COPY_AND_ASSIGN(NamespaceImpl);
-};
+  // Normalize it.
+  char result[PATH_MAX];
+  const intptr_t result_len =
+      File::CleanUnixPath(tbuf.buf(), result, PATH_MAX);
+  if (result_len < 0) {
+    errno = ENAMETOOLONG;
+    return false;
+  }
+
+  free(cwd_);
+  cwd_ = strdup(result);
+  close(cwdfd_);
+  cwdfd_ = new_cwdfd;
+  return true;
+}
 
 Namespace* Namespace::Create(intptr_t namespc) {
   NamespaceImpl* namespc_impl = NULL;
diff --git a/runtime/bin/namespace_fuchsia.h b/runtime/bin/namespace_fuchsia.h
new file mode 100644
index 0000000..ef1fff2
--- /dev/null
+++ b/runtime/bin/namespace_fuchsia.h
@@ -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.
+
+#ifndef RUNTIME_BIN_NAMESPACE_FUCHSIA_H_
+#define RUNTIME_BIN_NAMESPACE_FUCHSIA_H_
+
+#include "platform/globals.h"
+#if !defined(HOST_OS_FUCHSIA)
+#error "This header file should only be included when targeting Fuchsia."
+#endif
+
+#include <lib/fdio/namespace.h>
+
+namespace dart {
+namespace bin {
+
+class NamespaceImpl {
+ public:
+  explicit NamespaceImpl(fdio_ns_t* fdio_ns);
+  explicit NamespaceImpl(const char* path);
+  ~NamespaceImpl();
+
+  intptr_t rootfd() const { return rootfd_; }
+  char* cwd() const { return cwd_; }
+  intptr_t cwdfd() const { return cwdfd_; }
+  fdio_ns_t* fdio_ns() const { return fdio_ns_; }
+
+  bool SetCwd(Namespace* namespc, const char* new_path);
+
+ private:
+  fdio_ns_t* fdio_ns_;  // native namespace object, if any.
+  intptr_t rootfd_;     // dirfd for the namespace root.
+  char* cwd_;           // cwd relative to the namespace.
+  intptr_t cwdfd_;      // dirfd for the cwd.
+
+  DISALLOW_COPY_AND_ASSIGN(NamespaceImpl);
+};
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // RUNTIME_BIN_NAMESPACE_FUCHSIA_H_
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 1608bc9..6fd29a0 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -34,6 +34,7 @@
 #include "bin/lockers.h"
 #include "bin/log.h"
 #include "bin/namespace.h"
+#include "bin/namespace_fuchsia.h"
 #include "platform/signal_blocker.h"
 #include "platform/utils.h"
 
@@ -346,18 +347,9 @@
                    intptr_t err,
                    intptr_t exit_event,
                    ProcessResult* result) {
-  // input not needed.
-  IOHandle* in_iohandle = reinterpret_cast<IOHandle*>(in);
-  in_iohandle->Close();
-  in_iohandle->Release();
-  in_iohandle = NULL;
-
   IOHandle* out_iohandle = reinterpret_cast<IOHandle*>(out);
   IOHandle* err_iohandle = reinterpret_cast<IOHandle*>(err);
   IOHandle* exit_iohandle = reinterpret_cast<IOHandle*>(exit_event);
-  IOHandleScope out_ioscope(out_iohandle);
-  IOHandleScope err_ioscope(err_iohandle);
-  IOHandleScope exit_ioscope(exit_iohandle);
 
   // There is no return from this function using Dart_PropagateError
   // as memory used by the buffer lists is freed through their
@@ -597,15 +589,14 @@
       return status;
     }
 
-    fdio_spawn_action_t actions[4];
-    memset(actions, 0, sizeof(actions));
-    AddPipe(0, &write_out_, &actions[0]);
-    AddPipe(1, &read_in_, &actions[1]);
-    AddPipe(2, &read_err_, &actions[2]);
-    actions[3] = {
-      .action = FDIO_SPAWN_ACTION_SET_NAME,
-      .name.data = program_arguments_[0],
-    };
+    fdio_spawn_action_t* actions;
+    const intptr_t actions_count = BuildSpawnActions(
+        namespc_->namespc()->fdio_ns(), &actions);
+    if (actions_count < 0) {
+      *os_error_message_ = DartUtils::ScopedCopyCString(
+          "Failed to build spawn actions array.");
+      return ZX_ERR_IO;
+    }
 
     // TODO(zra): Use the supplied working directory when fdio_spawn_vmo adds an
     // API to set it.
@@ -613,12 +604,13 @@
     LOG_INFO("ProcessStarter: Start() Calling fdio_spawn_vmo\n");
     zx_handle_t process = ZX_HANDLE_INVALID;
     char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
-    uint32_t flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC |
-        FDIO_SPAWN_CLONE_NAMESPACE;
+    uint32_t flags = FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC;
     status =
         fdio_spawn_vmo(ZX_HANDLE_INVALID, flags, vmo, program_arguments_,
-                       program_environment_, 4, actions, &process, err_msg);
-
+                       program_environment_, actions_count, actions, &process,
+                       err_msg);
+    // Handles are consumed by fdio_spawn_vmo even if it fails.
+    delete[] actions;
     if (status != ZX_OK) {
       LOG_ERR("ProcessStarter: Start() fdio_spawn_vmo failed\n");
       close(exit_pipe_fds[0]);
@@ -681,6 +673,54 @@
     return ZX_OK;
   }
 
+  // Fills in 'actions_out' and returns action count.
+  intptr_t BuildSpawnActions(fdio_ns_t* ns, fdio_spawn_action_t** actions_out) {
+    const intptr_t fixed_actions_cnt = 4;
+    intptr_t ns_cnt = 0;
+
+    // First, figure out how many namespace actions are needed.
+    fdio_flat_namespace_t* flat_ns = nullptr;
+    if (ns != nullptr) {
+      zx_status_t status = fdio_ns_export(ns, &flat_ns);
+      if (status != ZX_OK) {
+        LOG_ERR("ProcessStarter: BuildSpawnActions: fdio_ns_export: %s\n",
+                zx_status_get_string(status));
+        return -1;
+      }
+      ns_cnt = flat_ns->count;
+    }
+
+    // Allocate the actions array.
+    const intptr_t actions_cnt = ns_cnt + fixed_actions_cnt;
+    fdio_spawn_action_t* actions = new fdio_spawn_action_t[actions_cnt];
+
+    // Fill in the entries for passing stdin/out/err handles, and the program
+    // name.
+    AddPipe(0, &write_out_, &actions[0]);
+    AddPipe(1, &read_in_, &actions[1]);
+    AddPipe(2, &read_err_, &actions[2]);
+    actions[3] = {
+      .action = FDIO_SPAWN_ACTION_SET_NAME,
+      .name.data = program_arguments_[0],
+    };
+
+    // Then fill in the namespace actions.
+    if (ns != nullptr) {
+      for (size_t i = 0; i < flat_ns->count; i++) {
+        actions[fixed_actions_cnt + i] = {
+          .action = FDIO_SPAWN_ACTION_ADD_NS_ENTRY,
+          .ns.prefix = flat_ns->path[i],
+          .ns.handle = flat_ns->handle[i],
+        };
+      }
+      free(flat_ns);
+      flat_ns = nullptr;
+    }
+
+    *actions_out = actions;
+    return actions_cnt;
+  }
+
   int read_in_;    // Pipe for stdout to child process.
   int read_err_;   // Pipe for stderr to child process.
   int write_out_;  // Pipe for stdin to child process.
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 85cb8e0..113ea22 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -315,11 +315,11 @@
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
   intptr_t available = SocketBase::Available(socket->fd());
   if (available >= 0) {
-    Dart_SetReturnValue(args, Dart_NewInteger(available));
+    Dart_SetIntegerReturnValue(args, available);
   } else {
     // Available failed. Mark socket as having data, to trigger a future read
     // event where the actual error can be reported.
-    Dart_SetReturnValue(args, Dart_NewInteger(1));
+    Dart_SetIntegerReturnValue(args, 1);
   }
 }
 
@@ -482,9 +482,9 @@
     if (short_write) {
       // If the write was forced 'short', indicate by returning the negative
       // number of bytes. A forced short write may not trigger a write event.
-      Dart_SetReturnValue(args, Dart_NewInteger(-bytes_written));
+      Dart_SetIntegerReturnValue(args, -bytes_written);
     } else {
-      Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
+      Dart_SetIntegerReturnValue(args, bytes_written);
     }
   } else {
     // Extract OSError before we release data, as it may override the error.
@@ -521,7 +521,7 @@
                                               addr, SocketBase::kAsync);
   if (bytes_written >= 0) {
     Dart_TypedDataReleaseData(buffer_obj);
-    Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
+    Dart_SetIntegerReturnValue(args, bytes_written);
   } else {
     // Extract OSError before we release data, as it may override the error.
     OSError os_error;
@@ -536,7 +536,7 @@
   OSError os_error;
   intptr_t port = SocketBase::GetPort(socket->fd());
   if (port > 0) {
-    Dart_SetReturnValue(args, Dart_NewInteger(port));
+    Dart_SetIntegerReturnValue(args, port);
   } else {
     Dart_SetReturnValue(args, DartUtils::NewDartOSError());
   }
@@ -581,7 +581,7 @@
   OSError os_error;
   intptr_t type = SocketBase::GetType(socket->fd());
   if (type >= 0) {
-    Dart_SetReturnValue(args, Dart_NewInteger(type));
+    Dart_SetIntegerReturnValue(args, type);
   } else {
     Dart_SetReturnValue(args, DartUtils::NewDartOSError());
   }
@@ -600,7 +600,7 @@
   Socket* socket =
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
   intptr_t id = reinterpret_cast<intptr_t>(socket);
-  Dart_SetReturnValue(args, Dart_NewInteger(id));
+  Dart_SetIntegerReturnValue(args, id);
 }
 
 void FUNCTION_NAME(Socket_SetSocketId)(Dart_NativeArguments args) {
@@ -783,7 +783,7 @@
       bool enabled;
       ok = SocketBase::GetNoDelay(socket->fd(), &enabled);
       if (ok) {
-        Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
+        Dart_SetBooleanReturnValue(args, enabled);
       }
       break;
     }
@@ -791,7 +791,7 @@
       bool enabled;
       ok = SocketBase::GetMulticastLoop(socket->fd(), protocol, &enabled);
       if (ok) {
-        Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
+        Dart_SetBooleanReturnValue(args, enabled);
       }
       break;
     }
@@ -799,7 +799,7 @@
       int value;
       ok = SocketBase::GetMulticastHops(socket->fd(), protocol, &value);
       if (ok) {
-        Dart_SetReturnValue(args, Dart_NewInteger(value));
+        Dart_SetIntegerReturnValue(args, value);
       }
       break;
     }
@@ -811,7 +811,7 @@
       bool enabled;
       ok = SocketBase::GetBroadcast(socket->fd(), &enabled);
       if (ok) {
-        Dart_SetReturnValue(args, enabled ? Dart_True() : Dart_False());
+        Dart_SetBooleanReturnValue(args, enabled);
       }
       break;
     }
@@ -869,6 +869,106 @@
   }
 }
 
+void FUNCTION_NAME(Socket_SetRawOption)(Dart_NativeArguments args) {
+  Socket* socket =
+      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
+  int64_t level = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
+  int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
+  Dart_Handle data_obj = Dart_GetNativeArgument(args, 3);
+  ASSERT(Dart_IsList(data_obj));
+  char* data = NULL;
+  intptr_t length;
+  Dart_TypedData_Type type;
+  Dart_Handle data_result = Dart_TypedDataAcquireData(
+      data_obj, &type, reinterpret_cast<void**>(&data), &length);
+  if (Dart_IsError(data_result)) {
+    Dart_PropagateError(data_result);
+  }
+
+  bool result = SocketBase::SetOption(socket->fd(), static_cast<int>(level),
+                                      static_cast<int>(option), data,
+                                      static_cast<int>(length));
+
+  Dart_TypedDataReleaseData(data_obj);
+
+  if (result) {
+    Dart_SetReturnValue(args, Dart_Null());
+  } else {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+  }
+}
+
+void FUNCTION_NAME(Socket_GetRawOption)(Dart_NativeArguments args) {
+  Socket* socket =
+      Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
+  int64_t level = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
+  int64_t option = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
+  Dart_Handle data_obj = Dart_GetNativeArgument(args, 3);
+  ASSERT(Dart_IsList(data_obj));
+  char* data = NULL;
+  intptr_t length;
+  Dart_TypedData_Type type;
+  Dart_Handle data_result = Dart_TypedDataAcquireData(
+      data_obj, &type, reinterpret_cast<void**>(&data), &length);
+  if (Dart_IsError(data_result)) {
+    Dart_PropagateError(data_result);
+  }
+  unsigned int int_length = static_cast<unsigned int>(length);
+  bool result =
+      SocketBase::GetOption(socket->fd(), static_cast<int>(level),
+                            static_cast<int>(option), data, &int_length);
+
+  Dart_TypedDataReleaseData(data_obj);
+
+  if (result) {
+    Dart_SetReturnValue(args, Dart_Null());
+  } else {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+  }
+}
+
+// Keep in sync with _RawSocketOptions in socket.dart
+enum _RawSocketOptions : int64_t {
+  DART_SOL_SOCKET = 0,
+  DART_IPPROTO_IP = 1,
+  DART_IP_MULTICAST_IF = 2,
+  DART_IPPROTO_IPV6 = 3,
+  DART_IPV6_MULTICAST_IF = 4,
+  DART_IPPROTO_TCP = 5,
+  DART_IPPROTO_UDP = 6
+};
+
+void FUNCTION_NAME(RawSocketOption_GetOptionValue)(Dart_NativeArguments args) {
+  _RawSocketOptions key = static_cast<_RawSocketOptions>(
+      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0)));
+  switch (key) {
+    case DART_SOL_SOCKET:
+      Dart_SetIntegerReturnValue(args, SOL_SOCKET);
+      break;
+    case DART_IPPROTO_IP:
+      Dart_SetIntegerReturnValue(args, IPPROTO_IP);
+      break;
+    case DART_IP_MULTICAST_IF:
+      Dart_SetIntegerReturnValue(args, IP_MULTICAST_IF);
+      break;
+    case DART_IPPROTO_IPV6:
+      Dart_SetIntegerReturnValue(args, DART_IPPROTO_IPV6);
+      break;
+    case DART_IPV6_MULTICAST_IF:
+      Dart_SetIntegerReturnValue(args, IPV6_MULTICAST_IF);
+      break;
+    case DART_IPPROTO_TCP:
+      Dart_SetIntegerReturnValue(args, IPPROTO_TCP);
+      break;
+    case DART_IPPROTO_UDP:
+      Dart_SetIntegerReturnValue(args, IPPROTO_UDP);
+      break;
+    default:
+      Dart_PropagateError(Dart_NewApiError("Value outside of expected range"));
+      break;
+  }
+}
+
 void FUNCTION_NAME(Socket_JoinMulticast)(Dart_NativeArguments args) {
   Socket* socket =
       Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
diff --git a/runtime/bin/socket_base.h b/runtime/bin/socket_base.h
index f8c2f01..8cab1aa 100644
--- a/runtime/bin/socket_base.h
+++ b/runtime/bin/socket_base.h
@@ -182,6 +182,16 @@
   static bool SetMulticastHops(intptr_t fd, intptr_t protocol, int value);
   static bool GetBroadcast(intptr_t fd, bool* value);
   static bool SetBroadcast(intptr_t fd, bool value);
+  static bool GetOption(intptr_t fd,
+                        int level,
+                        int option,
+                        char* data,
+                        unsigned int* length);
+  static bool SetOption(intptr_t fd,
+                        int level,
+                        int option,
+                        const char* data,
+                        int length);
   static bool JoinMulticast(intptr_t fd,
                             const RawAddr& addr,
                             const RawAddr& interface,
diff --git a/runtime/bin/socket_base_android.cc b/runtime/bin/socket_base_android.cc
index d54a24c..83f400b 100644
--- a/runtime/bin/socket_base_android.cc
+++ b/runtime/bin/socket_base_android.cc
@@ -350,6 +350,25 @@
                                       sizeof(on))) == 0;
 }
 
+bool SocketBase::SetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           const char* data,
+                           int length) {
+  return NO_RETRY_EXPECTED(setsockopt(fd, level, option, data, length)) == 0;
+}
+
+bool SocketBase::GetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           char* data,
+                           unsigned int* length) {
+  socklen_t optlen = static_cast<socklen_t>(*length);
+  auto result = NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, &optlen));
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
+}
+
 bool SocketBase::JoinMulticast(intptr_t fd,
                                const RawAddr& addr,
                                const RawAddr&,
diff --git a/runtime/bin/socket_base_fuchsia.cc b/runtime/bin/socket_base_fuchsia.cc
index d6c9495a..7191a64 100644
--- a/runtime/bin/socket_base_fuchsia.cc
+++ b/runtime/bin/socket_base_fuchsia.cc
@@ -9,10 +9,10 @@
 
 // TODO(ZX-766): If/when Fuchsia adds getifaddrs(), use that instead of the
 // ioctl in netconfig.h.
-#include <errno.h>  // NOLINT
-#include <fcntl.h>  // NOLINT
+#include <errno.h>    // NOLINT
+#include <fcntl.h>    // NOLINT
+#include <ifaddrs.h>  // NOLINT
 #include <lib/netstack/c/netconfig.h>
-#include <ifaddrs.h>      // NOLINT
 #include <net/if.h>       // NOLINT
 #include <netinet/tcp.h>  // NOLINT
 #include <stdio.h>        // NOLINT
@@ -375,6 +375,29 @@
   return false;
 }
 
+bool SocketBase::SetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           const char* data,
+                           int length) {
+  IOHandle* handle = reinterpret_cast<IOHandle*>(fd);
+  return NO_RETRY_EXPECTED(
+             setsockopt(handle->fd(), level, option, data, length)) == 0;
+}
+
+bool SocketBase::GetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           char* data,
+                           unsigned int* length) {
+  IOHandle* handle = reinterpret_cast<IOHandle*>(fd);
+  socklen_t optlen = static_cast<socklen_t>(*length);
+  auto result =
+      NO_RETRY_EXPECTED(getsockopt(handle->fd(), level, option, data, &optlen));
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
+}
+
 bool SocketBase::JoinMulticast(intptr_t fd,
                                const RawAddr& addr,
                                const RawAddr&,
diff --git a/runtime/bin/socket_base_linux.cc b/runtime/bin/socket_base_linux.cc
index 9fcc2ab..2e6b461 100644
--- a/runtime/bin/socket_base_linux.cc
+++ b/runtime/bin/socket_base_linux.cc
@@ -391,6 +391,25 @@
                                       sizeof(on))) == 0;
 }
 
+bool SocketBase::SetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           const char* data,
+                           int length) {
+  return NO_RETRY_EXPECTED(setsockopt(fd, level, option, data, length)) == 0;
+}
+
+bool SocketBase::GetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           char* data,
+                           unsigned int* length) {
+  socklen_t optlen = static_cast<socklen_t>(*length);
+  auto result = NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, &optlen));
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
+}
+
 bool SocketBase::JoinMulticast(intptr_t fd,
                                const RawAddr& addr,
                                const RawAddr&,
diff --git a/runtime/bin/socket_base_macos.cc b/runtime/bin/socket_base_macos.cc
index ee8bd8d..4a53bac 100644
--- a/runtime/bin/socket_base_macos.cc
+++ b/runtime/bin/socket_base_macos.cc
@@ -381,6 +381,22 @@
                                       sizeof(on))) == 0;
 }
 
+bool SocketBase::SetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           const char* data,
+                           int length) {
+  return NO_RETRY_EXPECTED(setsockopt(fd, level, option, data, length)) == 0;
+}
+
+bool SocketBase::GetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           char* data,
+                           unsigned int* length) {
+  return NO_RETRY_EXPECTED(getsockopt(fd, level, option, data, length)) == 0;
+}
+
 static bool JoinOrLeaveMulticast(intptr_t fd,
                                  const RawAddr& addr,
                                  const RawAddr& interface,
diff --git a/runtime/bin/socket_base_win.cc b/runtime/bin/socket_base_win.cc
index 0cd36f9..69d566b 100644
--- a/runtime/bin/socket_base_win.cc
+++ b/runtime/bin/socket_base_win.cc
@@ -396,6 +396,27 @@
                     reinterpret_cast<char*>(&on), sizeof(on)) == 0;
 }
 
+bool SocketBase::SetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           const char* data,
+                           int length) {
+  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
+  return setsockopt(handle->socket(), level, option, data, length) == 0;
+}
+
+bool SocketBase::GetOption(intptr_t fd,
+                           int level,
+                           int option,
+                           char* data,
+                           unsigned int* length) {
+  SocketHandle* handle = reinterpret_cast<SocketHandle*>(fd);
+  int optlen = static_cast<int>(*length);
+  auto result = getsockopt(handle->socket(), level, option, data, &optlen);
+  *length = static_cast<unsigned int>(optlen);
+  return result == 0;
+}
+
 bool SocketBase::JoinMulticast(intptr_t fd,
                                const RawAddr& addr,
                                const RawAddr&,
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 81ede2e..fc81838 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -95,6 +95,7 @@
     return -1;
   }
 
+
   if (reuseAddress) {
     int optval = 1;
     VOID_NO_RETRY_EXPECTED(
@@ -116,6 +117,12 @@
     return -1;
   }
 
+  // Don't raise SIGPIPE when attempting to write to a connection which has
+  // already closed.
+  int optval = 1;
+  VOID_NO_RETRY_EXPECTED(
+      setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)));
+
   if (NO_RETRY_EXPECTED(
           bind(fd, &addr.addr, SocketAddress::GetAddrLength(addr))) < 0) {
     FDUtils::SaveErrorAndClose(fd);
@@ -148,6 +155,12 @@
   VOID_NO_RETRY_EXPECTED(
       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
 
+  // Don't raise SIGPIPE when attempting to write to a connection which has
+  // already closed.
+  optval = 1;
+  VOID_NO_RETRY_EXPECTED(
+      setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)));
+
   if (addr.ss.ss_family == AF_INET6) {
     optval = v6_only ? 1 : 0;
     VOID_NO_RETRY_EXPECTED(
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 6b3e495..fb7b69d 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -29,6 +29,24 @@
 }
 
 @patch
+class RawSocketOption {
+  static final List<int> _optionsCache =
+      List<int>(_RawSocketOptions.values.length);
+
+  @patch
+  static int _getOptionValue(int key) {
+    if (key > _RawSocketOptions.values.length) {
+      throw ArgumentError.value(key, 'key');
+    }
+    _optionsCache[key] ??= _getNativeOptionValue(key);
+    return _optionsCache[key];
+  }
+
+  static int _getNativeOptionValue(int key)
+      native "RawSocketOption_GetOptionValue";
+}
+
+@patch
 class InternetAddress {
   @patch
   static InternetAddress get LOOPBACK_IP_V4 {
@@ -1084,6 +1102,23 @@
     return true;
   }
 
+  Uint8List getRawOption(RawSocketOption option) {
+    if (option == null) throw new ArgumentError.notNull("option");
+    if (option.value == null) throw new ArgumentError.notNull("option.value");
+
+    var result = nativeGetRawOption(option.level, option.option, option.value);
+    if (result != null) throw result;
+    return option.value;
+  }
+
+  void setRawOption(RawSocketOption option) {
+    if (option == null) throw new ArgumentError.notNull("option");
+    if (option.value == null) throw new ArgumentError.notNull("option.value");
+
+    var result = nativeSetRawOption(option.level, option.option, option.value);
+    if (result != null) throw result;
+  }
+
   InternetAddress multicastAddress(
       InternetAddress addr, NetworkInterface interface) {
     // On Mac OS using the interface index for joining IPv4 multicast groups
@@ -1146,8 +1181,12 @@
   int nativeGetSocketId() native "Socket_GetSocketId";
   OSError nativeGetError() native "Socket_GetError";
   nativeGetOption(int option, int protocol) native "Socket_GetOption";
+  OSError nativeGetRawOption(int level, int option, Uint8List data)
+      native "Socket_GetRawOption";
   OSError nativeSetOption(int option, int protocol, value)
       native "Socket_SetOption";
+  OSError nativeSetRawOption(int level, int option, Uint8List data)
+      native "Socket_SetRawOption";
   OSError nativeJoinMulticast(List<int> addr, List<int> interfaceAddr,
       int interfaceIndex) native "Socket_JoinMulticast";
   bool nativeLeaveMulticast(List<int> addr, List<int> interfaceAddr,
@@ -1377,6 +1416,10 @@
   bool setOption(SocketOption option, bool enabled) =>
       _socket.setOption(option, enabled);
 
+  Uint8List getRawOption(RawSocketOption option) =>
+      _socket.getRawOption(option);
+  void setRawOption(RawSocketOption option) => _socket.setRawOption(option);
+
   _pause() {
     _socket.setListening(read: false, write: false);
   }
@@ -1642,6 +1685,15 @@
     return _raw.setOption(option, enabled);
   }
 
+  Uint8List getRawOption(RawSocketOption option) {
+    if (_raw == null) return null;
+    return _raw.getRawOption(option);
+  }
+
+  void setRawOption(RawSocketOption option) {
+    _raw?.setRawOption(option);
+  }
+
   int get port {
     if (_raw == null) throw const SocketException.closed();
     ;
@@ -1913,6 +1965,10 @@
       _socket.close();
     }
   }
+
+  Uint8List getRawOption(RawSocketOption option) =>
+      _socket.getRawOption(option);
+  void setRawOption(RawSocketOption option) => _socket.setRawOption(option);
 }
 
 @pragma("vm:entry-point")
diff --git a/runtime/bin/sync_socket.cc b/runtime/bin/sync_socket.cc
index 12b1fee..4589d4a 100644
--- a/runtime/bin/sync_socket.cc
+++ b/runtime/bin/sync_socket.cc
@@ -141,13 +141,13 @@
   buffer += offset;
   intptr_t bytes_written =
       SynchronousSocket::Write(socket->fd(), buffer, length);
+  Dart_TypedDataReleaseData(buffer_obj);
   if (bytes_written >= 0) {
     Dart_SetIntegerReturnValue(args, bytes_written);
   } else {
     OSError os_error;
     Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
-  Dart_TypedDataReleaseData(buffer_obj);
 }
 
 void FUNCTION_NAME(SynchronousSocket_ReadList)(Dart_NativeArguments args) {
diff --git a/runtime/docs/compiler/aot/entry_point_pragma.md b/runtime/docs/compiler/aot/entry_point_pragma.md
index 69cf760..c560070 100644
--- a/runtime/docs/compiler/aot/entry_point_pragma.md
+++ b/runtime/docs/compiler/aot/entry_point_pragma.md
@@ -60,8 +60,11 @@
 
 If the second parameter is missing, `null` or `true`, the procedure will
 available for lookup and invocation directly from native or VM code. If the
-procedure is a *generative* constructor, the enclosing class will also be marked
-for allocation from native or VM code.
+procedure is a *generative* constructor, the enclosing class must also be
+annotated for allocation from native or VM code.
+
+Note that annotating a procedure does not allow closurizing it, e.g. access a
+non-getter via `Dart_GetField`.
 
 ### Fields
 
diff --git a/runtime/docs/compiler/optimization_levels.md b/runtime/docs/compiler/optimization_levels.md
new file mode 100644
index 0000000..c86976b
--- /dev/null
+++ b/runtime/docs/compiler/optimization_levels.md
@@ -0,0 +1,63 @@
+# Dart MiniDesign Doc
+
+## Optimization Levels for AOT Dart Compiler
+
+# Introduction
+
+In order to strike the right balance between compile-time, code speed, and code size, most optimizing compilers support several levels of optimizations, typically controlled by an -Ox switch. The usual ones relevant to this design code are:
+
+*   O0: short compilation-time, unoptimized code, small code size; highly debuggable
+*   O2: medium compilation-time, optimized code, reasonable code size
+*   O3: potentially long compilation-time, highly optimized code, possibly larger code size
+*   Os: medium compilation-time, optimized while favoring code size
+
+The O0 level is typically used during development and early testing, when a very fast compilation-time is more desirable than code speed. Also, this code is best for debugging, since unoptimized code has a very straightforward mapping between native instructions and memory locations and source program instructions and variables.
+
+The O2 level is used to generate code for shipping. It strikes a right balance between compile-time and generated code speed and size. Since shipping occurs less frequently than debugging and testing, slightly longer compilation-times are acceptable.
+
+When either code speed or size is favored, respectively, levels O3 or Os are used. For the former, longer compilation-times are acceptable as well.
+
+The Dart compiler conceptually only supports level O0 (the un-optimized code that is used as our deopt "fallback") and level O2 (optimized code). Although the quality of optimization can heavily depend on profile feedback (JIT) and the possibility for speculative execution, both JIT and AOT strike more or less the same balance between generated code speed and size.
+
+# Proposal
+
+Some optimizations are known to benefit mostly code speed (with an unfavorable or unknown impact on code size) or mostly code size (with an unfavorable or unknown impact on code speed). For example, more aggressively inlining (to a certain extent) usually yields faster but more sizable code. Conversely, not aligning code (where allowed) usually yields more compact, but potentially slower running code.
+
+Sometimes performing more expensive analysis, which negatively impacts compile-time, may discover more optimization opportunities in some cases, but remain completely empty handed in other cases. For example, doing an expensive data dependence analysis of loops only pays of if the loop is eventually vectorized or parallelized. Otherwise, all analysis time is wasted.
+
+Note that almost every optimization decision_ is heuristic in nature_; optimizations generally improve a certain aspect of the code, but there are no hard guarantees.
+
+Since Dart conceptually only supports O2, _all_ optimizations must always be chosen to strike a balance between compile-time and generated code speed and size. In order to give users more control over the optimization decision when using the Dart compiler, we propose adding the concept of Os and O3 as additional compilation modes. This could be implemented as an optimization level, for example as:
+
+```
+--optimization_level=
+       0: unoptimized (O0)
+       1: size optimized (Os)
+       2: default optimized (O2)
+       3: speed optimized (O3)
+```
+
+Level 0 corresponds to our current unoptimized path, whereas level 2 corresponds to the default path through our optimization passes. The other two levels alter the default path using the following guidelines.
+
+*   optimization_level=1 (Os)
+    *   Skip O2 optimizations that tend to increase code size, even if doing so may negatively impacts code speed
+    *   Introduce new optimizations that "heuristically" decrease code size, but at high risk of negatively impacting code speed
+*   optimization_level=3 (O3)
+    *   Introduce more detailed analysis or optimizations that "heuristically" increase code speed, but at high risk of negatively impacting compile-time or code size
+
+The guidelines are intentionally worded this way to avoid reckless use of the flag as a substitute for proper heuristics. For example, an optimization aimed at reducing code size with a neutral impact on code speed belongs in O2, not Os. As another example, always inlining without proper heuristics just in the hope to improve speed by blindly giving up size is not something we want in O3. Also, inlining heuristics that overall increase code speed with only minimal code size increase belongs in O2.
+
+The proposal would apply to both the JIT and AOT compiler (to avoid adding yet another dimension through the optimization passes), although initially we may only want to expose the switch externally for the AOT compiler.
+
+Advantages of approach:
+
+*   Allows new optimizations for size or speed that don't fit the current O2 philosophy
+*   Enables removal of existing optimization from O2 that had a disproportionate negative impact on only size
+*   Allows introduction of more expensive analysis that can (but is not guaranteed to) find more opportunities for optimization
+*   Gives more control to users that favor size or speed differently than others
+*   Potentially gives more insights on optimizations that were initially deemed to risky but helped "in the field"; perhaps better heuristics can be found to move these to O2
+
+Disadvantages of the approach:
+
+*   Two additional code paths through compiler, increases the size of all testing matrices (Dart, Flutter, performance, correctness)
+*   Risk of misusing the flag to avoid spending time finding better heuristics
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index a560eb2..a017584 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -562,7 +562,6 @@
   bool use_osr;
   bool obfuscate;
   Dart_QualifiedFunctionName* entry_points;
-  bool use_bare_instructions;
   bool load_vmservice_library;
   bool unsafe_trust_strong_mode_types;
   bool copy_parent_code;
diff --git a/runtime/include/dart_tools_api.h b/runtime/include/dart_tools_api.h
index 49b1f19..402e01d 100644
--- a/runtime/include/dart_tools_api.h
+++ b/runtime/include/dart_tools_api.h
@@ -344,58 +344,6 @@
 DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask);
 
 typedef enum {
-  /** Indicates a new stream is being output */
-  Dart_StreamConsumer_kStart = 0,
-  /** Data for the current stream */
-  Dart_StreamConsumer_kData = 1,
-  /** Indicates stream is finished */
-  Dart_StreamConsumer_kFinish = 2,
-} Dart_StreamConsumer_State;
-
-/**
- * A stream consumer callback function.
- *
- * This function will be called repeatedly until there is no more data in a
- * stream and there are no more streams.
- *
- * \param state Indicates a new stream, data, or a finished stream.
- * \param stream_name A name for this stream. Not guaranteed to be meaningful.
- * \param buffer A pointer to the stream data.
- * \param buffer_length The number of bytes at buffer that should be consumed.
- * \param stream_callback_data The pointer passed in when requesting the stream.
- *
- * At the start of each stream state will be DART_STREAM_CONSUMER_STATE_START
- * and buffer will be NULL.
- *
- * For each chunk of data the state will be DART_STREAM_CONSUMER_STATE_DATA
- * and buffer will not be NULL.
- *
- * At the end of each stream state will be DART_STREAM_CONSUMER_STATE_FINISH
- * and buffer will be NULL.
- */
-typedef void (*Dart_StreamConsumer)(Dart_StreamConsumer_State state,
-                                    const char* stream_name,
-                                    const uint8_t* buffer,
-                                    intptr_t buffer_length,
-                                    void* stream_callback_data);
-
-/**
- * Get the timeline for entire VM (including all isolates).
- *
- * NOTE: The timeline retrieved from this API call may not include the most
- * recent events.
- *
- * \param consumer A Dart_StreamConsumer.
- * \param user_data User data passed into consumer.
- *
- * NOTE: The trace-event format is documented here: https://goo.gl/hDZw5M
- *
- * \return True if a stream was output.
- */
-DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
-                                             void* user_data);
-
-typedef enum {
   Dart_Timeline_Event_Begin,          // Phase = 'B'.
   Dart_Timeline_Event_End,            // Phase = 'E'.
   Dart_Timeline_Event_Instant,        // Phase = 'i'.
@@ -436,31 +384,6 @@
  */
 DART_EXPORT void Dart_SetThreadName(const char* name);
 
-/**
- * Called by the VM to let the embedder know when to start recording into the
- * timeline. Can be called from any thread.
- */
-typedef void (*Dart_EmbedderTimelineStartRecording)();
-
-/**
- * Called by the VM to let the embedder know when to stop recording into the
- * timeline. Can be called from any thread.
- */
-typedef void (*Dart_EmbedderTimelineStopRecording)();
-
-/**
- * Sets the embedder timeline callbacks. These callbacks are used by the VM
- * to notify the embedder of timeline recording state changes.
- *
- * \param start_recording See Dart_EmbedderTimelineStartRecording.
- * \param stop_recording See Dart_EmbedderTimelineStopRecording.
- *
- * NOTE: To avoid races, this should be called before Dart_Initialize.
- */
-DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
-    Dart_EmbedderTimelineStartRecording start_recording,
-    Dart_EmbedderTimelineStopRecording stop_recording);
-
 /*
  * =======
  * Metrics
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
index 3d99c0d..7342f87 100644
--- a/runtime/lib/convert_patch.dart
+++ b/runtime/lib/convert_patch.dart
@@ -261,7 +261,7 @@
   // TODO(lrn): See if parsing of numbers can be abstracted to something
   // not only working on strings, but also on char-code lists, without lossing
   // performance.
-  int parseInt() => int.parse(getString());
+  num parseNum() => num.parse(getString());
   double parseDouble() => double.parse(getString());
 }
 
@@ -598,13 +598,17 @@
   String getString(int start, int end, int bits);
 
   /**
-   * Parse a slice of the current chunk as an integer.
+   * Parse a slice of the current chunk as a number.
+   *
+   * Since integers have a maximal value, and we don't track the value
+   * in the buffer, a sequence of digits can be either an int or a double.
+   * The `num.parse` function does the right thing.
    *
    * The format is expected to be correct.
    */
-  int parseInt(int start, int end) {
-    const int asciiBits = 0x7f; // Integer literals are ASCII only.
-    return int.parse(getString(start, end, asciiBits));
+  num parseNum(int start, int end) {
+    const int asciiBits = 0x7f; // Number literals are ASCII only.
+    return num.parse(getString(start, end, asciiBits));
   }
 
   /**
@@ -917,7 +921,6 @@
         default:
           if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
           state |= VALUE_READ_BITS;
-          if (char == null) print("$chunk - $position");
           position = parseNumber(char, position);
           break;
       }
@@ -1214,7 +1217,8 @@
       addNumberChunk(buffer, start, end, 0);
     }
     if (state == NUM_DIGIT) {
-      listener.handleNumber(buffer.parseInt());
+      num value = buffer.parseNum();
+      listener.handleNumber(value);
     } else if (state == NUM_DOT_DIGIT || state == NUM_E_DIGIT) {
       listener.handleNumber(buffer.parseDouble());
     } else {
@@ -1230,9 +1234,11 @@
     int start = position;
     int length = chunkEnd;
     // Collects an int value while parsing. Used for both an integer literal,
-    // an the exponent part of a double literal.
+    // and the exponent part of a double literal.
+    // Stored as negative to ensure we can represent -2^63.
     int intValue = 0;
     double doubleValue = 0.0; // Collect double value while parsing.
+    // 1 if there is no leading -, -1 if there is.
     int sign = 1;
     bool isDouble = false;
     // Break this block when the end of the number literal is reached.
@@ -1261,8 +1267,22 @@
       // If starting with zero, next character must not be digit.
       if (digit <= 9) fail(position);
     } else {
+      int digitCount = 0;
       do {
-        intValue = 10 * intValue + digit;
+        if (digitCount >= 18) {
+          // Check for overflow.
+          // Is 1 if digit is 8 or 9 and sign == 0, or digit is 9 and sign < 0;
+          int highDigit = digit >> 3;
+          if (sign < 0) highDigit &= digit;
+          if (digitCount == 19 || intValue - highDigit < -922337203685477580) {
+            isDouble = true;
+            // Big value that we know is not trusted to be exact later,
+            // forcing reparsing using `double.parse`.
+            doubleValue = 9223372036854775808.0;
+          }
+        }
+        intValue = 10 * intValue - digit;
+        digitCount++;
         position++;
         if (position == length) return beginChunkNumber(NUM_DIGIT, start);
         char = getChar(position);
@@ -1270,8 +1290,10 @@
       } while (digit <= 9);
     }
     if (char == DECIMALPOINT) {
-      isDouble = true;
-      doubleValue = intValue.toDouble();
+      if (!isDouble) {
+        isDouble = true;
+        doubleValue = (intValue == 0) ? 0.0 : -intValue.toDouble();
+      }
       intValue = 0;
       position++;
       if (position == length) return beginChunkNumber(NUM_DOT, start);
@@ -1289,16 +1311,16 @@
     }
     if ((char | 0x20) == CHAR_e) {
       if (!isDouble) {
-        doubleValue = intValue.toDouble();
-        intValue = 0;
         isDouble = true;
+        doubleValue = (intValue == 0) ? 0.0 : -intValue.toDouble();
+        intValue = 0;
       }
       position++;
       if (position == length) return beginChunkNumber(NUM_E, start);
       char = getChar(position);
       int expSign = 1;
       int exponent = 0;
-      if (char == PLUS || char == MINUS) {
+      if (((char + 1) | 2) == 0x2e /*+ or -*/) {
         expSign = 0x2C - char; // -1 for MINUS, +1 for PLUS
         position++;
         if (position == length) return beginChunkNumber(NUM_E_SIGN, start);
@@ -1308,20 +1330,33 @@
       if (digit > 9) {
         fail(position, "Missing expected digit");
       }
+      bool exponentOverflow = false;
       do {
         exponent = 10 * exponent + digit;
+        if (exponent > 400) exponentOverflow = true;
         position++;
         if (position == length) return beginChunkNumber(NUM_E_DIGIT, start);
         char = getChar(position);
         digit = char ^ CHAR_0;
       } while (digit <= 9);
+      if (exponentOverflow) {
+        if (doubleValue == 0.0 || expSign < 0) {
+          listener.handleNumber(sign < 0 ? -0.0 : 0.0);
+        } else {
+          listener.handleNumber(
+              sign < 0 ? double.negativeInfinity : double.infinity);
+        }
+        return position;
+      }
       intValue += expSign * exponent;
     }
     if (!isDouble) {
-      listener.handleNumber(sign * intValue);
+      int bitFlag = -(sign + 1) >> 1; // 0 if sign == -1, -1 if sign == 1
+      // Negate if bitFlag is -1 by doing ~intValue + 1
+      listener.handleNumber((intValue ^ bitFlag) - bitFlag);
       return position;
     }
-    // Double values at or above this value (2 ** 53) may have lost precission.
+    // Double values at or above this value (2 ** 53) may have lost precision.
     // Only trust results that are below this value.
     const double maxExactDouble = 9007199254740992.0;
     if (doubleValue < maxExactDouble) {
diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc
new file mode 100644
index 0000000..0621990
--- /dev/null
+++ b/runtime/lib/ffi.cc
@@ -0,0 +1,680 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "include/dart_api.h"
+#include "vm/bootstrap_natives.h"
+#include "vm/class_finalizer.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/exceptions.h"
+#include "vm/log.h"
+#include "vm/native_arguments.h"
+#include "vm/native_entry.h"
+#include "vm/object.h"
+#include "vm/object_store.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+// The following functions are runtime checks on type arguments.
+// Some checks are also performed in kernel transformation, these are asserts.
+// Some checks are only performed at runtime to allow for generic code, these
+// throw ArgumentExceptions.
+
+static void ThrowTypeArgumentError(const AbstractType& type_arg,
+                                   const char* expected) {
+  const String& error = String::Handle(String::NewFormatted(
+      "Type argument (%s) should be a %s",
+      String::Handle(type_arg.UserVisibleName()).ToCString(), expected));
+  Exceptions::ThrowArgumentError(error);
+}
+
+static bool IsPointerType(const AbstractType& type) {
+  // Do a fast check for predefined types.
+  classid_t type_cid = type.type_class_id();
+  if (RawObject::IsFfiPointerClassId(type_cid)) {
+    return true;
+  }
+
+  // Do a slow check for subtyping.
+  const Class& pointer_class =
+      Class::Handle(Isolate::Current()->object_store()->ffi_pointer_class());
+  AbstractType& pointer_type =
+      AbstractType::Handle(pointer_class.DeclarationType());
+  pointer_type ^= pointer_type.InstantiateFrom(Object::null_type_arguments(),
+                                               Object::null_type_arguments(),
+                                               kNoneFree, NULL, Heap::kNew);
+  ASSERT(pointer_type.IsInstantiated());
+  ASSERT(type.IsInstantiated());
+  return type.IsSubtypeOf(pointer_type, Heap::kNew);
+}
+
+static bool IsConcreteNativeType(const AbstractType& type) {
+  // Do a fast check for predefined types.
+  classid_t type_cid = type.type_class_id();
+  if (RawObject::IsFfiNativeTypeTypeClassId(type_cid)) {
+    return false;
+  }
+  if (RawObject::IsFfiTypeClassId(type_cid)) {
+    return true;
+  }
+
+  // Do a slow check for subtyping.
+  const Class& native_type_class = Class::Handle(
+      Isolate::Current()->object_store()->ffi_native_type_class());
+  AbstractType& native_type_type =
+      AbstractType::Handle(native_type_class.DeclarationType());
+  return type.IsSubtypeOf(native_type_type, Heap::kNew);
+}
+
+static void CheckIsConcreteNativeType(const AbstractType& type) {
+  if (!IsConcreteNativeType(type)) {
+    ThrowTypeArgumentError(type, "concrete sub type of NativeType");
+  }
+}
+
+static bool IsNativeFunction(const AbstractType& type_arg) {
+  classid_t type_cid = type_arg.type_class_id();
+  return RawObject::IsFfiTypeNativeFunctionClassId(type_cid);
+}
+
+static void CheckSized(const AbstractType& type_arg) {
+  classid_t type_cid = type_arg.type_class_id();
+  if (RawObject::IsFfiTypeVoidClassId(type_cid) ||
+      RawObject::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 "
+        "is unknown. "
+        "Consequently, [allocate], [Pointer.load], [Pointer.store], and "
+        "[Pointer.elementAt] are not available.",
+        String::Handle(type_arg.UserVisibleName()).ToCString()));
+    Exceptions::ThrowArgumentError(error);
+  }
+}
+
+// Checks that a dart type correspond to a [NativeType].
+// Because this is checked already in a kernel transformation, it does not throw
+// an ArgumentException but a boolean which should be asserted.
+//
+// [Int8]                               -> [int]
+// [Int16]                              -> [int]
+// [Int32]                              -> [int]
+// [Int64]                              -> [int]
+// [Uint8]                              -> [int]
+// [Uint16]                             -> [int]
+// [Uint32]                             -> [int]
+// [Uint64]                             -> [int]
+// [IntPtr]                             -> [int]
+// [Double]                             -> [double]
+// [Float]                              -> [double]
+// [Pointer]<T>                         -> [Pointer]<T>
+// T extends [Pointer]                  -> T
+// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
+//    where DartRepresentationOf(Tn) -> Sn
+static bool DartAndCTypeCorrespond(const AbstractType& native_type,
+                                   const AbstractType& dart_type) {
+  classid_t native_type_cid = native_type.type_class_id();
+  if (RawObject::IsFfiTypeIntClassId(native_type_cid)) {
+    return dart_type.IsSubtypeOf(AbstractType::Handle(Type::IntType()),
+                                 Heap::kNew);
+  }
+  if (RawObject::IsFfiTypeDoubleClassId(native_type_cid)) {
+    return dart_type.IsSubtypeOf(AbstractType::Handle(Type::Double()),
+                                 Heap::kNew);
+  }
+  if (RawObject::IsFfiPointerClassId(native_type_cid)) {
+    return native_type.Equals(dart_type) || dart_type.IsNullType();
+  }
+  if (RawObject::IsFfiTypeNativeFunctionClassId(native_type_cid)) {
+    if (!dart_type.IsFunctionType()) {
+      return false;
+    }
+    TypeArguments& nativefunction_type_args =
+        TypeArguments::Handle(native_type.arguments());
+    AbstractType& nativefunction_type_arg =
+        AbstractType::Handle(nativefunction_type_args.TypeAt(0));
+    if (!nativefunction_type_arg.IsFunctionType()) {
+      return false;
+    }
+    Function& dart_function = Function::Handle(((Type&)dart_type).signature());
+    if (dart_function.NumTypeParameters() != 0 ||
+        dart_function.HasOptionalPositionalParameters() ||
+        dart_function.HasOptionalNamedParameters()) {
+      return false;
+    }
+    Function& nativefunction_function =
+        Function::Handle(((Type&)nativefunction_type_arg).signature());
+    if (nativefunction_function.NumTypeParameters() != 0 ||
+        nativefunction_function.HasOptionalPositionalParameters() ||
+        nativefunction_function.HasOptionalNamedParameters()) {
+      return false;
+    }
+    if (!(dart_function.NumParameters() ==
+          nativefunction_function.NumParameters())) {
+      return false;
+    }
+    if (!DartAndCTypeCorrespond(
+            AbstractType::Handle(nativefunction_function.result_type()),
+            AbstractType::Handle(dart_function.result_type()))) {
+      return false;
+    }
+    for (intptr_t i = 0; i < dart_function.NumParameters(); i++) {
+      if (!DartAndCTypeCorrespond(
+              AbstractType::Handle(nativefunction_function.ParameterTypeAt(i)),
+              AbstractType::Handle(dart_function.ParameterTypeAt(i)))) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+// The following functions are runtime checks on arguments.
+
+// Note that expected_from and expected_to are inclusive.
+static void CheckRange(const Integer& argument_value,
+                       intptr_t expected_from,
+                       intptr_t expected_to,
+                       const char* argument_name) {
+  int64_t value = argument_value.AsInt64Value();
+  if (value < expected_from || expected_to < value) {
+    Exceptions::ThrowRangeError(argument_name, argument_value, expected_from,
+                                expected_to);
+  }
+}
+
+static const Pointer& AsPointer(const Instance& instance) {
+  if (!instance.IsPointer()) {
+    const String& error = String::Handle(String::NewFormatted(
+        "Expected a Pointer object but found %s", instance.ToCString()));
+    Exceptions::ThrowArgumentError(error);
+  }
+  return Pointer::Cast(instance);
+}
+
+static const Integer& AsInteger(const Instance& instance) {
+  if (!instance.IsInteger()) {
+    const String& error = String::Handle(String::NewFormatted(
+        "Expected an int but found %s", instance.ToCString()));
+    Exceptions::ThrowArgumentError(error);
+  }
+  return Integer::Cast(instance);
+}
+
+static const Double& AsDouble(const Instance& instance) {
+  if (!instance.IsDouble()) {
+    const String& error = String::Handle(String::NewFormatted(
+        "Expected a double but found %s", instance.ToCString()));
+    Exceptions::ThrowArgumentError(error);
+  }
+  return Double::Cast(instance);
+}
+
+// Native data types sizes in bytes
+
+static const size_t kSizeUnknown = 0;
+
+static const intptr_t kNumElementSizes = kFfiVoidCid - kFfiPointerCid + 1;
+
+static const size_t element_size_table[kNumElementSizes] = {
+    sizeof(intptr_t),  // kFfiPointerCid
+    kSizeUnknown,      // kFfiNativeFunctionCid
+    1,                 // kFfiInt8Cid
+    2,                 // kFfiInt16Cid
+    4,                 // kFfiInt32Cid
+    8,                 // kFfiInt64Cid
+    1,                 // kFfiUint8Cid
+    2,                 // kFfiUint16Cid
+    4,                 // kFfiUint32Cid
+    8,                 // kFfiUint64Cid
+    sizeof(intptr_t),  // kFfiIntPtrCid
+    4,                 // kFfiFloatCid
+    8,                 // kFfiDoubleCid
+    kSizeUnknown,      // kFfiVoidCid
+};
+
+static size_t ElementSizeInBytes(intptr_t class_id) {
+  ASSERT(RawObject::IsFfiTypeClassId(class_id));
+  ASSERT(class_id != kFfiNativeFunctionCid);
+  ASSERT(class_id != kFfiVoidCid);
+  intptr_t index = class_id - kFfiPointerCid;
+  return element_size_table[index];
+}
+
+// The remainder of this file implements the dart:ffi native methods.
+
+DEFINE_NATIVE_ENTRY(Ffi_allocate, 1, 1) {
+  // TODO(dacoharkes): When we have a way of determining the size of structs in
+  // the VM, change the signature so we can allocate structs, subtype of
+  // Pointer. https://github.com/dart-lang/sdk/issues/35782
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+
+  CheckIsConcreteNativeType(type_arg);
+  CheckSized(type_arg);
+
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, argCount, arguments->NativeArgAt(0));
+  int64_t count = argCount.AsInt64Value();
+  classid_t type_cid = type_arg.type_class_id();
+  int64_t max_count = INTPTR_MAX / ElementSizeInBytes(type_cid);
+  CheckRange(argCount, 1, max_count, "count");
+
+  size_t size = ElementSizeInBytes(type_cid) * count;
+  uint8_t* memory = reinterpret_cast<uint8_t*>(malloc(size));
+  if (memory == NULL) {
+    const String& error = String::Handle(String::NewFormatted(
+        "allocating (%" Pd ") bytes of memory failed", size));
+    Exceptions::ThrowArgumentError(error);
+  }
+
+  RawPointer* result = Pointer::New(type_arg, memory);
+  return result;
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_fromAddress, 1, 1) {
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+  TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
+  AbstractType& native_type = AbstractType::Handle(
+      type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
+  CheckIsConcreteNativeType(native_type);
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, arg_ptr, arguments->NativeArgAt(0));
+
+  uint8_t* address = reinterpret_cast<uint8_t*>(arg_ptr.AsInt64Value());
+  // TODO(dacoharkes): should this return NULL if addres is 0?
+  // https://github.com/dart-lang/sdk/issues/35756
+
+  RawPointer* result =
+      Pointer::New(native_type, address, type_arg.type_class_id());
+  return result;
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_elementAt, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, index, arguments->NativeArgAt(1));
+  AbstractType& pointer_type_arg =
+      AbstractType::Handle(pointer.type_argument());
+  CheckSized(pointer_type_arg);
+
+  classid_t class_id = pointer_type_arg.type_class_id();
+  uint8_t* address = pointer.GetCMemoryAddress();
+  uint8_t* address_new =
+      address + index.AsInt64Value() * ElementSizeInBytes(class_id);
+  RawPointer* result = Pointer::New(pointer_type_arg, address_new);
+  return result;
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_offsetBy, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, offset, arguments->NativeArgAt(1));
+  AbstractType& pointer_type_arg =
+      AbstractType::Handle(pointer.type_argument());
+
+  uint8_t* address = pointer.GetCMemoryAddress();
+  uint8_t* address_new = address + offset.AsInt64Value();
+  RawPointer* result = Pointer::New(pointer_type_arg, address_new);
+  return result;
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_cast, 1, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+  TypeArguments& type_args = TypeArguments::Handle(type_arg.arguments());
+  AbstractType& native_type = AbstractType::Handle(
+      type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos));
+  CheckIsConcreteNativeType(native_type);
+
+  uint8_t* address = pointer.GetCMemoryAddress();
+  RawPointer* result =
+      Pointer::New(native_type, address, type_arg.type_class_id());
+  return result;
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_free, 0, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+
+  uint8_t* address = pointer.GetCMemoryAddress();
+  free(address);
+  pointer.SetCMemoryAddress(0);
+  return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_address, 0, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+
+  uint8_t* address = pointer.GetCMemoryAddress();
+  intptr_t int_ptr = reinterpret_cast<intptr_t>(address);
+  return Integer::NewFromUint64(int_ptr);
+}
+
+static RawInstance* BoxLoadPointer(uint8_t* address,
+                                   const AbstractType& instance_type_arg,
+                                   intptr_t type_cid) {
+  // TODO(dacoharkes): should this return NULL if addres is 0?
+  // https://github.com/dart-lang/sdk/issues/35756
+  if (address == 0) {  // 0 is the c++ null pointer
+    return Instance::null();
+  }
+  AbstractType& type_arg =
+      AbstractType::Handle(TypeArguments::Handle(instance_type_arg.arguments())
+                               .TypeAt(Pointer::kNativeTypeArgPos));
+  return Pointer::New(type_arg, address, type_cid);
+}
+
+static RawInstance* LoadValue(uint8_t* address,
+                              const AbstractType& instance_type_arg) {
+  classid_t type_cid = instance_type_arg.type_class_id();
+  switch (type_cid) {
+    case kFfiInt8Cid:
+      return Integer::New(*reinterpret_cast<int8_t*>(address));
+    case kFfiInt16Cid:
+      return Integer::New(*reinterpret_cast<int16_t*>(address));
+    case kFfiInt32Cid:
+      return Integer::New(*reinterpret_cast<int32_t*>(address));
+    case kFfiInt64Cid:
+      return Integer::New(*reinterpret_cast<int64_t*>(address));
+    case kFfiUint8Cid:
+      return Integer::NewFromUint64(*reinterpret_cast<uint8_t*>(address));
+    case kFfiUint16Cid:
+      return Integer::NewFromUint64(*reinterpret_cast<uint16_t*>(address));
+    case kFfiUint32Cid:
+      return Integer::NewFromUint64(*reinterpret_cast<uint32_t*>(address));
+    case kFfiUint64Cid:
+      return Integer::NewFromUint64(*reinterpret_cast<uint64_t*>(address));
+    case kFfiIntPtrCid:
+      return Integer::New(*reinterpret_cast<intptr_t*>(address));
+    case kFfiFloatCid:
+      return Double::New(*reinterpret_cast<float_t*>(address));
+    case kFfiDoubleCid:
+      return Double::New(*reinterpret_cast<double_t*>(address));
+    case kFfiPointerCid:
+    default:
+      ASSERT(IsPointerType(instance_type_arg));
+      return BoxLoadPointer(*reinterpret_cast<uint8_t**>(address),
+                            instance_type_arg, type_cid);
+  }
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_load, 1, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+  AbstractType& pointer_type_arg =
+      AbstractType::Handle(pointer.type_argument());
+  CheckSized(pointer_type_arg);
+  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
+
+  uint8_t* address = pointer.GetCMemoryAddress();
+  return LoadValue(address, pointer_type_arg);
+}
+
+static void StoreValue(const Pointer& pointer,
+                       classid_t type_cid,
+                       const Instance& new_value) {
+  uint8_t* address = pointer.GetCMemoryAddress();
+  AbstractType& pointer_type_arg =
+      AbstractType::Handle(pointer.type_argument());
+  switch (type_cid) {
+    case kFfiInt8Cid:
+      *reinterpret_cast<int8_t*>(address) = AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiInt16Cid:
+      *reinterpret_cast<int16_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiInt32Cid:
+      *reinterpret_cast<int32_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiInt64Cid:
+      *reinterpret_cast<int64_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiUint8Cid:
+      *reinterpret_cast<uint8_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiUint16Cid:
+      *reinterpret_cast<uint16_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiUint32Cid:
+      *reinterpret_cast<uint32_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiUint64Cid:
+      *reinterpret_cast<uint64_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiIntPtrCid:
+      *reinterpret_cast<intptr_t*>(address) =
+          AsInteger(new_value).AsInt64Value();
+      break;
+    case kFfiFloatCid:
+      *reinterpret_cast<float*>(address) = AsDouble(new_value).value();
+      break;
+    case kFfiDoubleCid:
+      *reinterpret_cast<double*>(address) = AsDouble(new_value).value();
+      break;
+    case kFfiPointerCid:
+    default: {
+      ASSERT(IsPointerType(pointer_type_arg));
+      uint8_t* new_value_unwrapped = nullptr;
+      if (!new_value.IsNull()) {
+        ASSERT(new_value.IsPointer());
+        new_value_unwrapped = AsPointer(new_value).GetCMemoryAddress();
+        // TODO(dacoharkes): should this return NULL if addres is 0?
+        // https://github.com/dart-lang/sdk/issues/35756
+      }
+      *reinterpret_cast<uint8_t**>(address) = new_value_unwrapped;
+    } break;
+  }
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_store, 0, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  GET_NATIVE_ARGUMENT(Instance, new_value, arguments->NativeArgAt(1));
+  AbstractType& arg_type = AbstractType::Handle(new_value.GetType(Heap::kNew));
+  AbstractType& pointer_type_arg =
+      AbstractType::Handle(pointer.type_argument());
+  CheckSized(pointer_type_arg);
+  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, arg_type));
+
+  classid_t type_cid = pointer_type_arg.type_class_id();
+  StoreValue(pointer, type_cid, new_value);
+  return Object::null();
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_sizeOf, 1, 0) {
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+  CheckIsConcreteNativeType(type_arg);
+  CheckSized(type_arg);
+
+  classid_t type_cid = type_arg.type_class_id();
+  return Smi::New(ElementSizeInBytes(type_cid));
+}
+
+// Generates assembly to trampoline from Dart into C++.
+//
+// Attaches assembly code to the function with the folling features:
+// - unboxes arguments
+// - puts the arguments on the c stack
+// - invokes the c function
+// - reads the the result
+// - boxes the result and returns it.
+//
+// It inspects the signature to know what to box/unbox
+// Parameter `function` has the Dart types in its signature
+// Parameter `c_signature` has the C++ types in its signature
+static RawCode* TrampolineCode(const Function& function,
+                               const Function& c_signature) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
+  // Currently we generate the trampoline when calling asFunction(), this means
+  // the ffi cannot be used in AOT.
+  // In order make it work in AOT we need to:
+  // - collect all asFunction signatures ahead of time
+  // - generate trampolines for those
+  // - store these in the object store
+  // - and read these from the object store when calling asFunction()
+  // https://github.com/dart-lang/sdk/issues/35765
+  UNREACHABLE();
+#elif !defined(TARGET_ARCH_X64)
+  // https://github.com/dart-lang/sdk/issues/35774
+  UNREACHABLE();
+#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
+  // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
+  // https://github.com/dart-lang/sdk/issues/35771 Windows
+  // https://github.com/dart-lang/sdk/issues/35772 Arm64
+  // https://github.com/dart-lang/sdk/issues/35773 DBC
+  UNREACHABLE();
+#else
+  extern void GenerateFfiTrampoline(Assembler * assembler,
+                                    const Function& signature);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
+  GenerateFfiTrampoline(&assembler, c_signature);
+  const Code& code = Code::Handle(Code::FinalizeCode(
+      function, nullptr, &assembler, Code::PoolAttachment::kAttachPool));
+  code.set_exception_handlers(
+      ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
+  return code.raw();
+#endif
+}
+
+// TODO(dacoharkes): Cache the trampolines.
+// We can possibly address simultaniously with 'precaching' in AOT.
+static RawFunction* TrampolineFunction(const Function& dart_signature,
+                                       const Function& c_signature) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  const String& name =
+      String::ZoneHandle(Symbols::New(Thread::Current(), "FfiTrampoline"));
+  const Library& lib = Library::Handle(Library::FfiLibrary());
+  const Class& owner_class = Class::Handle(lib.toplevel_class());
+  Function& function = Function::ZoneHandle(
+      zone, Function::New(name, RawFunction::kFfiTrampoline,
+                          true,   // is_static
+                          false,  // is_const
+                          false,  // is_abstract
+                          false,  // is_external
+                          true,   // is_native
+                          owner_class, TokenPosition::kMinSource));
+
+  function.set_num_fixed_parameters(dart_signature.num_fixed_parameters());
+  function.set_result_type(AbstractType::Handle(dart_signature.result_type()));
+  function.set_parameter_types(Array::Handle(dart_signature.parameter_types()));
+
+  const Code& code = Code::Handle(TrampolineCode(function, c_signature));
+  function.AttachCode(code);
+
+  return function.raw();
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_asFunction, 1, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0));
+  AbstractType& pointer_type_arg =
+      AbstractType::Handle(pointer.type_argument());
+  ASSERT(IsNativeFunction(pointer_type_arg));
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+  ASSERT(DartAndCTypeCorrespond(pointer_type_arg, type_arg));
+
+  Function& dart_signature = Function::Handle(Type::Cast(type_arg).signature());
+  TypeArguments& nativefunction_type_args =
+      TypeArguments::Handle(pointer_type_arg.arguments());
+  AbstractType& nativefunction_type_arg =
+      AbstractType::Handle(nativefunction_type_args.TypeAt(0));
+  Function& c_signature =
+      Function::Handle(Type::Cast(nativefunction_type_arg).signature());
+  Function& function =
+      Function::Handle(TrampolineFunction(dart_signature, c_signature));
+
+  // Set the c function pointer in the context of the closure rather than in
+  // the function so that we can reuse the function for each c function with
+  // the same signature.
+  Context& context = Context::Handle(Context::New(1));
+  context.SetAt(0,
+                Object::Handle(Integer::NewFromUint64(
+                    reinterpret_cast<intptr_t>(pointer.GetCMemoryAddress()))));
+
+  RawClosure* raw_closure =
+      Closure::New(Object::null_type_arguments(), Object::null_type_arguments(),
+                   function, context, Heap::kOld);
+
+  return raw_closure;
+}
+
+// Generates assembly to trampoline from C++ back into Dart.
+static void* GenerateFfiInverseTrampoline(const Function& signature,
+                                          void* dart_entry_point) {
+#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
+  UNREACHABLE();
+#elif !defined(TARGET_ARCH_X64)
+  // https://github.com/dart-lang/sdk/issues/35774
+  UNREACHABLE();
+#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
+  // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
+  // https://github.com/dart-lang/sdk/issues/35771 Windows
+  // https://github.com/dart-lang/sdk/issues/35772 Arm64
+  // https://github.com/dart-lang/sdk/issues/35773 DBC
+  UNREACHABLE();
+#else
+  extern void GenerateFfiInverseTrampoline(
+      Assembler * assembler, const Function& signature, void* dart_entry_point);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
+  GenerateFfiInverseTrampoline(&assembler, signature, dart_entry_point);
+  const Code& code = Code::Handle(
+      Code::FinalizeCode("inverse trampoline", nullptr, &assembler,
+                         Code::PoolAttachment::kAttachPool, false));
+
+  uword entryPoint = code.EntryPoint();
+
+  return reinterpret_cast<void*>(entryPoint);
+#endif
+}
+
+// TODO(dacoharkes): Implement this feature.
+// https://github.com/dart-lang/sdk/issues/35761
+// For now, it always returns Pointer with address 0.
+DEFINE_NATIVE_ENTRY(Ffi_fromFunction, 1, 1) {
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0));
+
+  Function& c_signature = Function::Handle(((Type&)type_arg).signature());
+
+  Function& func = Function::Handle(closure.function());
+  Code& code = Code::Handle(func.EnsureHasCode());
+  void* entryPoint = reinterpret_cast<void*>(code.EntryPoint());
+
+  THR_Print("Ffi_fromFunction: %s\n", type_arg.ToCString());
+  THR_Print("Ffi_fromFunction: %s\n", c_signature.ToCString());
+  THR_Print("Ffi_fromFunction: %s\n", closure.ToCString());
+  THR_Print("Ffi_fromFunction: %s\n", func.ToCString());
+  THR_Print("Ffi_fromFunction: %s\n", code.ToCString());
+  THR_Print("Ffi_fromFunction: %p\n", entryPoint);
+  THR_Print("Ffi_fromFunction: %" Pd "\n", code.Size());
+
+  void* address = GenerateFfiInverseTrampoline(c_signature, entryPoint);
+
+  TypeArguments& type_args = TypeArguments::Handle(zone);
+  type_args = TypeArguments::New(1);
+  type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
+  type_args ^= type_args.Canonicalize();
+
+  Class& native_function_class = Class::Handle(
+      Isolate::Current()->class_table()->At(kFfiNativeFunctionCid));
+  native_function_class.EnsureIsFinalized(Thread::Current());
+
+  Type& native_function_type = Type::Handle(
+      Type::New(native_function_class, type_args, TokenPosition::kNoSource));
+  native_function_type ^=
+      ClassFinalizer::FinalizeType(Class::Handle(), native_function_type);
+  native_function_type ^= native_function_type.Canonicalize();
+
+  address = 0;  // https://github.com/dart-lang/sdk/issues/35761
+
+  Pointer& result = Pointer::Handle(
+      Pointer::New(native_function_type, reinterpret_cast<uint8_t*>(address)));
+
+  return result.raw();
+}
+
+}  // namespace dart
diff --git a/runtime/lib/ffi_dynamic_library.cc b/runtime/lib/ffi_dynamic_library.cc
new file mode 100644
index 0000000..b083e04
--- /dev/null
+++ b/runtime/lib/ffi_dynamic_library.cc
@@ -0,0 +1,114 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
+// TODO(dacoharkes): implement dynamic libraries for other targets.
+// see
+// - runtime/vm/native_symbol.h
+// - runtime/vm/native_symbol_linux.cc
+// - runtime/bin/extensions.h (but we cannot import from bin)
+// - runtime/bin/extensions_linux.cc
+#else
+#include <dlfcn.h>
+#endif
+#include "include/dart_api.h"
+#include "vm/bootstrap_natives.h"
+#include "vm/exceptions.h"
+#include "vm/native_entry.h"
+
+namespace dart {
+
+// Concatenates a NULL terminated array of strings.
+// The returned string is scope allocated.
+// TODO(dacoharkes): Can we share this with runtime/bin/extensions.cc?
+const char* Concatenate(const char** strings) {
+  int size = 1;  // null termination.
+  for (int i = 0; strings[i] != NULL; i++) {
+    size += strlen(strings[i]);
+  }
+  char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(size));
+  int index = 0;
+  for (int i = 0; strings[i] != NULL; i++) {
+    index += snprintf(result + index, size - index, "%s", strings[i]);
+  }
+  ASSERT(index == size - 1);
+  ASSERT(result[size - 1] == '\0');
+  return result;
+}
+
+// TODO(dacoharkes): Can we share this with runtime/bin/extensions.cc?
+const char* LibraryPath(const char* library_name) {
+  const char* library_prefix = "lib";
+#if defined(TARGET_OS_LINUX)
+  const char* library_extension = "so";
+#elif defined(TARGET_OS_MACOS)
+  const char* library_extension = "dylib";
+#else
+  const char* library_extension = "";
+  UNREACHABLE();
+#endif
+
+  const char* path_components[] = {
+      library_prefix, library_name, ".", library_extension, NULL,
+  };
+
+  return Concatenate(path_components);
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
+#if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
+  UNREACHABLE();
+#else
+  GET_NON_NULL_NATIVE_ARGUMENT(String, argName, arguments->NativeArgAt(0));
+
+  dlerror();  // Clear any errors.
+  void* handle = dlopen(LibraryPath(argName.ToCString()), RTLD_LAZY);
+  if (handle == nullptr) {
+    char* error = dlerror();
+    const String& msg = String::Handle(
+        String::NewFormatted("Failed to load dynamic library(%s)", error));
+    Exceptions::ThrowArgumentError(msg);
+  }
+
+  return DynamicLibrary::New(handle);
+#endif
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
+#if !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
+  UNREACHABLE();
+#else
+  GET_NATIVE_TYPE_ARGUMENT(type_arg, arguments->NativeTypeArgAt(0));
+
+  GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, argSymbolName,
+                               arguments->NativeArgAt(1));
+
+  void* handle = dlib.GetHandle();
+
+  dlerror();  // Clear any errors.
+  uint8_t* pointer =
+      reinterpret_cast<uint8_t*>(dlsym(handle, argSymbolName.ToCString()));
+  char* error;
+  if ((error = dlerror()) != NULL) {
+    const String& msg = String::Handle(
+        String::NewFormatted("Failed to lookup symbol (%s)", error));
+    Exceptions::ThrowArgumentError(msg);
+  }
+
+  // TODO(dacoharkes): should this return NULL if addres is 0?
+  // https://github.com/dart-lang/sdk/issues/35756
+  RawPointer* result = Pointer::New(type_arg, pointer);
+  return result;
+#endif
+}
+
+DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
+  GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
+
+  intptr_t handle = reinterpret_cast<intptr_t>(dlib.GetHandle());
+  return Integer::NewFromUint64(handle);
+}
+
+}  // namespace dart
diff --git a/runtime/lib/ffi_dynamic_library_patch.dart b/runtime/lib/ffi_dynamic_library_patch.dart
new file mode 100644
index 0000000..db45805
--- /dev/null
+++ b/runtime/lib/ffi_dynamic_library_patch.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:_internal" show patch;
+
+DynamicLibrary _open(String name) native "Ffi_dl_open";
+
+@patch
+class DynamicLibrary {
+  @patch
+  @pragma("vm:entry-point")
+  factory DynamicLibrary.open(String name) {
+    return _open(name);
+  }
+
+  @patch
+  Pointer<T> lookup<T extends NativeType>(String symbolName)
+      native "Ffi_dl_lookup";
+
+  // TODO(dacoharkes): Expose this to users, or extend Pointer?
+  // https://github.com/dart-lang/sdk/issues/35881
+  int getHandle() native "Ffi_dl_getHandle";
+
+  @patch
+  bool operator ==(other) {
+    if (other == null) return false;
+    return getHandle() == other.getHandle();
+  }
+
+  @patch
+  int get hashCode {
+    return getHandle().hashCode;
+  }
+}
diff --git a/runtime/lib/ffi_native_type_patch.dart b/runtime/lib/ffi_native_type_patch.dart
new file mode 100644
index 0000000..b12f0b8
--- /dev/null
+++ b/runtime/lib/ffi_native_type_patch.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:_internal" show patch;
+
+@patch
+@pragma("vm:entry-point")
+class NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class _NativeInteger extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class _NativeDouble extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class Int8 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Int16 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Int32 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Int64 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint8 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint16 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint32 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Uint64 extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class IntPtr extends _NativeInteger {}
+
+@patch
+@pragma("vm:entry-point")
+class Float extends _NativeDouble {}
+
+@patch
+@pragma("vm:entry-point")
+class Double extends _NativeDouble {}
+
+@patch
+@pragma("vm:entry-point")
+class Void extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
+class NativeFunction<T extends Function> extends NativeType {}
diff --git a/runtime/lib/ffi_patch.dart b/runtime/lib/ffi_patch.dart
new file mode 100644
index 0000000..c8fde6c
--- /dev/null
+++ b/runtime/lib/ffi_patch.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.
+
+import "dart:_internal" show patch;
+
+@patch
+Pointer<T> allocate<T extends NativeType>({int count: 1}) native "Ffi_allocate";
+
+@patch
+T fromAddress<T extends Pointer>(int ptr) native "Ffi_fromAddress";
+
+@patch
+int sizeOf<T extends NativeType>() native "Ffi_sizeOf";
+
+@patch
+Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+    @DartRepresentationOf("T") Function f) native "Ffi_fromFunction";
+
+@patch
+@pragma("vm:entry-point")
+class Pointer<T extends NativeType> {
+  @patch
+  void store(Object value) native "Ffi_store";
+
+  @patch
+  R load<R>() native "Ffi_load";
+
+  @patch
+  int get address native "Ffi_address";
+
+  // Note this could also be implmented without an extra native as offsetBy
+  // (elementSize()*index). This would be 2 native calls rather than one. What
+  // would be better?
+  @patch
+  Pointer<T> elementAt(int index) native "Ffi_elementAt";
+
+  // Note this could also be implmented without an extra  native as
+  // fromAddress(address). This would be 2 native calls rather than one.
+  // What would be better?
+  @patch
+  Pointer<T> offsetBy(int offsetInBytes) native "Ffi_offsetBy";
+
+  // Note this could also be implemented without an extra native as
+  // fromAddress(address). This would be 2 native calls rather than one.
+  // What would be better?
+  @patch
+  U cast<U extends Pointer>() native "Ffi_cast";
+
+  @patch
+  R asFunction<R extends Function>() native "Ffi_asFunction";
+
+  @patch
+  void free() native "Ffi_free";
+}
diff --git a/runtime/lib/ffi_sources.gni b/runtime/lib/ffi_sources.gni
new file mode 100644
index 0000000..fd625f4
--- /dev/null
+++ b/runtime/lib/ffi_sources.gni
@@ -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.
+
+# Sources visible via dart:ffi library.
+ffi_runtime_cc_files = [
+  "ffi.cc",
+  "ffi_dynamic_library.cc",
+]
+
+ffi_runtime_dart_files = [
+  "ffi_patch.dart",
+  "ffi_dynamic_library_patch.dart",
+  "ffi_native_type_patch.dart",
+]
+
+ffi_runtime_sources = ffi_runtime_cc_files + ffi_runtime_dart_files
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 0dbe008..e22e8bf 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -150,6 +150,7 @@
 
   void _setIndexed(int index, T value) native "GrowableList_setIndexed";
 
+  @pragma("vm:entry-point")
   void add(T value) {
     var len = length;
     if (len == _capacity) {
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 972d9af..a9a6a41 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -240,6 +240,17 @@
 }
 
 /**
+ * Returns the _startMainIsolate function. This closurization allows embedders
+ * to setup trampolines to the main function. This workaround can be removed
+ * once support for @pragma("vm:entry_point", "get") as documented in
+ * https://github.com/dart-lang/sdk/issues/35720 lands.
+ */
+@pragma("vm:entry-point")
+Function _getStartMainIsolateFunction() {
+  return _startMainIsolate;
+}
+
+/**
  * Takes the real entry point as argument and invokes it with the initial
  * message.
  */
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index d4916d0..81ce5c3 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1032,6 +1032,8 @@
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
   const Library& library = Library::Handle(ref.GetLibraryReferent());
 
+  library.EnsureTopLevelClassIsFinalized();
+
   Instance& member_mirror = Instance::Handle();
   const GrowableObjectArray& member_mirrors =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 3e68d99..8255b23 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -16,26 +16,24 @@
 // Native implementations for the dart:developer library.
 
 DEFINE_NATIVE_ENTRY(Timeline_isDartStreamEnabled, 0, 0) {
-#ifndef PRODUCT
-  if (!FLAG_support_timeline) {
-    return Bool::False().raw();
-  }
+#if defined(SUPPORT_TIMELINE)
   if (Timeline::GetDartStream()->enabled()) {
     return Bool::True().raw();
   }
-#endif  // !PRODUCT
+#endif
   return Bool::False().raw();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_getNextAsyncId, 0, 0) {
-  if (!FLAG_support_timeline) {
-    return Integer::New(0);
-  }
+#if !defined(SUPPORT_TIMELINE)
+  return Integer::New(0);
+#else
   TimelineEventRecorder* recorder = Timeline::recorder();
   if (recorder == NULL) {
     return Integer::New(0);
   }
   return Integer::New(recorder->GetNextAsyncId());
+#endif
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0, 0) {
@@ -47,10 +45,7 @@
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 0, 6) {
-#ifndef PRODUCT
-  if (!FLAG_support_timeline) {
-    return Object::null();
-  }
+#if defined(SUPPORT_TIMELINE)
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, id, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, phase, arguments->NativeArgAt(2));
@@ -72,15 +67,12 @@
   DartTimelineEventHelpers::ReportTaskEvent(
       thread, event, start.AsInt64Value(), id.AsInt64Value(), phase.ToCString(),
       category.ToCString(), name.ToMallocCString(), args.ToMallocCString());
-#endif
+#endif  // SUPPORT_TIMELINE
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportCompleteEvent, 0, 5) {
-#ifndef PRODUCT
-  if (!FLAG_support_timeline) {
-    return Object::null();
-  }
+#if defined(SUPPORT_TIMELINE)
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
@@ -101,15 +93,12 @@
   DartTimelineEventHelpers::ReportCompleteEvent(
       thread, event, start.AsInt64Value(), start_cpu.AsInt64Value(),
       category.ToCString(), name.ToMallocCString(), args.ToMallocCString());
-#endif  // !defined(PRODUCT)
+#endif  // SUPPORT_TIMELINE
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportFlowEvent, 0, 7) {
-#ifndef PRODUCT
-  if (!FLAG_support_timeline) {
-    return Object::null();
-  }
+#if defined(SUPPORT_TIMELINE)
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
@@ -133,15 +122,12 @@
       thread, event, start.AsInt64Value(), start_cpu.AsInt64Value(),
       category.ToCString(), name.ToMallocCString(), type.AsInt64Value(),
       flow_id.AsInt64Value(), args.ToMallocCString());
-#endif  // !defined(PRODUCT)
+#endif  // SUPPORT_TIMELINE
   return Object::null();
 }
 
 DEFINE_NATIVE_ENTRY(Timeline_reportInstantEvent, 0, 4) {
-#ifndef PRODUCT
-  if (!FLAG_support_timeline) {
-    return Object::null();
-  }
+#if defined(SUPPORT_TIMELINE)
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(2));
@@ -161,7 +147,7 @@
   DartTimelineEventHelpers::ReportInstantEvent(
       thread, event, start.AsInt64Value(), category.ToCString(),
       name.ToMallocCString(), args.ToMallocCString());
-#endif
+#endif  // SUPPORT_TIMELINE
   return Object::null();
 }
 
diff --git a/runtime/lib/timer_patch.dart b/runtime/lib/timer_patch.dart
index 88940ff..c243a86 100644
--- a/runtime/lib/timer_patch.dart
+++ b/runtime/lib/timer_patch.dart
@@ -39,8 +39,6 @@
 typedef Timer _TimerFactoryClosure(
     int milliseconds, void callback(Timer timer), bool repeating);
 
-// Warning: Dartium sets _TimerFactory._factory instead of setting things up
-// through VMLibraryHooks.timerFactory.
 class _TimerFactory {
   static _TimerFactoryClosure _factory;
 }
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index 91d7efd..56d4fe3 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -4366,8 +4366,13 @@
     _typedData._setFloat32x4(_offset + byteOffset, value);
   }
 
+  @pragma("vm:non-nullable-result-type")
   final _TypedList _typedData;
+
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   final int _offset;
+
+  @pragma("vm:exact-result-type", "dart:core#_Smi")
   final int length;
 }
 
diff --git a/runtime/observatory/HACKING.md b/runtime/observatory/HACKING.md
index c13377f..afcab5c 100644
--- a/runtime/observatory/HACKING.md
+++ b/runtime/observatory/HACKING.md
@@ -9,16 +9,6 @@
 Before you start to hack on Observatory, follow the [instructions][build_sdk] to
 have a working environment in which you are able to build and test the Dart SDK.
 
-### Develop with Dartium ~ Suggested
-If you want to avoid triggering a new compilation to JavaScript for each edit
-you do, you can use a modified version of Chromium named Dartium that will
-interpret your dart code directly.
-
-You can obtain Dartium in two different ways:
-1. [Download][download_dartium] the binaries
-2. [Build][build_dartium] Dartium from the source code
-
-
 ## Run existing tests
 Before hacking Observatory let's run the existing Observatory tests.
 We suggest to run all the test in __debug__ mode.
@@ -34,21 +24,14 @@
 ```
 
 ## Serve Observatory
-Observatory is built as part of building the sdk, but when working on
-Observatory we recommend that you use __pub serve__ so you can avoid the
-overhead of building the sdk for each change.
+Observatory is built as part of building the sdk. Previously, it was recommended
+to run the Observatory using `pub serve` to avoid having to rebuild the sdk for
+each change to Observatory. However, `pub serve` was deprecated as part of the
+transition to Dart 2.0.
 
-Use __pub__ to __serve__ Observatory:
-```
-[...]/runtime/observatory$ pub serve
-```
-
-## Open Observatory
-You can open the development version of Observatory from
-Chrome/Chromium/__Dartium__ by navigating to [localhost:8080][open_observatory]
-
-Every change you make to the Observatory source code will be visible by simply
-__refreshing__ the page in the browser.
+[Issue #35678](https://github.com/dart-lang/sdk/issues/35678)
+tracks changes required to allow for `package:build_runner` to run Observatory
+without having to rebuild the sdk after each change.
 
 ## Connect to a VM
 Start a Dart VM with the ``--observe`` flag (as explained in the
@@ -185,8 +168,6 @@
 See: __Run existing tests__
 
 [build_sdk]: https://github.com/dart-lang/sdk/wiki/Building "Building the Dart SDK"
-[download_dartium]: https://webdev.dartlang.org/tools/dartium/ "Download Dartium"
-[build_dartium]: https://github.com/dart-lang/sdk/wiki/Building-Dartium "Build Dartium"
 [open_observatory]: http://localhost:8080/ "Open Observatory"
 [observatory_get_started]: https://dart-lang.github.io/observatory/get-started.html "Observatory get started"
 [code_review]: https://github.com/dart-lang/sdk/wiki/Code-review-workflow-with-GitHub-and-reitveld "Code Review"
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
index 3e5a2b3..10260fd 100644
--- a/runtime/observatory/tests/observatory_ui/observatory_ui.status
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -2,11 +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.
 
+[ !$browser ]
+*: SkipByDesign
+
 # custom elements are not supported on old browsers, we don't
 # intend for observatory to work on old browser versions, so
 # skipping.
 [ $runtime == ff || $runtime == ie10 || $runtime == ie11 || $runtime == safari ]
 *: SkipByDesign
-
-[ !$browser || $fast_startup ]
-*: SkipByDesign
diff --git a/runtime/observatory/tests/service/get_flag_list_rpc_test.dart b/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
index 2240e01..472bfbb 100644
--- a/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
@@ -7,6 +7,17 @@
 
 import 'test_helper.dart';
 
+Future getFlagValue(VM vm, String flagName) async {
+  var result = await vm.invokeRpcNoUpgrade('getFlagList', {});
+  expect(result['type'], equals('FlagList'));
+  final flags = result['flags'];
+  for (final flag in flags) {
+    if (flag['name'] == flagName) {
+      return flag['valueAsString'];
+    }
+  }
+}
+
 var tests = <VMTest>[
   (VM vm) async {
     var result = await vm.invokeRpcNoUpgrade('getFlagList', {});
@@ -45,6 +56,32 @@
     var result = await vm.invokeRpcNoUpgrade('setFlag', params);
     expect(result['type'], equals('Success'));
   },
+
+  // Modify a flag which cannot be set at runtime.
+  (VM vm) async {
+    var params = {
+      'name': 'random_seed',
+      'value': '42',
+    };
+    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    expect(result['type'], equals('Error'));
+    expect(
+        result['message'], equals('Cannot set flag: cannot change at runtime'));
+  },
+
+  // Modify the profile_period at runtime.
+  (VM vm) async {
+    final kProfilePeriod = 'profile_period';
+    final kValue = 100;
+    expect(await getFlagValue(vm, kProfilePeriod), '1000');
+    var params = {
+      'name': '$kProfilePeriod',
+      'value': '$kValue',
+    };
+    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    expect(result['type'], equals('Success'));
+    expect(await getFlagValue(vm, kProfilePeriod), kValue.toString());
+  }
 ];
 
 main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index ce2fa5b3..6b70552 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -34,6 +34,19 @@
   MyClass.myFunction(10000);
 }
 
+class MyConstClass {
+  const MyConstClass();
+  static const MyConstClass instance = null ?? const MyConstClass();
+
+  void foo() {
+    debugger();
+  }
+}
+
+void testFunction2() {
+  MyConstClass.instance.foo();
+}
+
 bool allRangesCompiled(coverage) {
   for (int i = 0; i < coverage['ranges'].length; i++) {
     if (!coverage['ranges'][i]['compiled']) {
@@ -78,9 +91,9 @@
     final numRanges = coverage['ranges'].length;
     expect(coverage['type'], equals('SourceReport'));
 
-    // Running in app_jitk mode will result in the number of ranges being 6
-    // during the training run and 7 when running from the snapshot.
-    expect(((numRanges == 6) || (numRanges == 7)), isTrue);
+    // Running in app_jitk mode will result in the number of ranges being 10
+    // during the training run and 11 when running from the snapshot.
+    expect(((numRanges == 10) || (numRanges == 11)), isTrue);
     expect(coverage['ranges'][0], equals(expectedRange));
     expect(coverage['scripts'].length, 1);
     expect(
@@ -95,7 +108,7 @@
     };
     coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
     expect(coverage['type'], equals('SourceReport'));
-    expect(coverage['ranges'].length, numRanges);
+    expect(coverage['ranges'].length, numRanges + 3);
     expect(allRangesCompiled(coverage), isTrue);
 
     // One function
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 9b1fb1a..ca2028a 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(13));
+    expect(result['minor'], equals(14));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/regress_34841_lib.dart b/runtime/observatory/tests/service/regress_34841_lib.dart
new file mode 100644
index 0000000..304f6f5
--- /dev/null
+++ b/runtime/observatory/tests/service/regress_34841_lib.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class Foo {
+  final String foo = () {
+    return StackTrace.current.toString();
+  }();
+}
diff --git a/runtime/observatory/tests/service/regress_34841_test.dart b/runtime/observatory/tests/service/regress_34841_test.dart
new file mode 100644
index 0000000..69acbad
--- /dev/null
+++ b/runtime/observatory/tests/service/regress_34841_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// While it's not (currently) necessary, add some noise here to push down token
+// positions in this file compared to the file regress_34841_lib.dart.
+// This is to ensure that any possible tokens in that file are just comments
+// (i.e. not actual) positions in this file.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'service_test_common.dart';
+import 'dart:developer';
+import 'regress_34841_lib.dart';
+
+class Bar extends Object with Foo {}
+
+void testFunction() {
+  Bar bar = new Bar();
+  print(bar.foo);
+  debugger();
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    var stack = await isolate.getStack();
+
+    // Make sure we are in the right place.
+    expect(stack.type, equals('Stack'));
+    expect(stack['frames'].length, greaterThanOrEqualTo(1));
+    expect(stack['frames'][0].function.name, equals('testFunction'));
+
+    var root = isolate.rootLibrary;
+    await root.load();
+    Script script = root.scripts.first;
+    await script.load();
+
+    var params = {
+      'reports': ['Coverage'],
+      'scriptId': script.id,
+      'forceCompile': true
+    };
+    var report = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+    List<dynamic> ranges = report['ranges'];
+    List<int> coveragePlaces = <int>[];
+    for (var range in ranges) {
+      for (int i in range["coverage"]["hits"]) {
+        coveragePlaces.add(i);
+      }
+      for (int i in range["coverage"]["misses"]) {
+        coveragePlaces.add(i);
+      }
+    }
+
+    // Make sure we can translate it all.
+    for (int place in coveragePlaces) {
+      int line = script.tokenToLine(place);
+      int column = script.tokenToCol(place);
+      if (line == null || column == null) {
+        throw "Token $place translated to $line:$column";
+      }
+    }
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 3b35e4f..b72cf4c 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -31,6 +31,7 @@
 get_user_level_retaining_path_rpc_test: SkipByDesign # No incremental compiler available.
 instance_field_order_rpc_test: SkipByDesign # No incremental compiler available.
 pause_on_exceptions_test: SkipByDesign # No incremental compiler available.
+regress_34841_test: RuntimeError # http://dartbug.com/34841
 rewind_optimized_out_test: SkipByDesign # No incremental compiler available.
 rewind_test: SkipByDesign # No incremental compiler available.
 simple_reload_test: RuntimeError, Timeout # Issue 35506
@@ -46,6 +47,7 @@
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
 pause_on_unhandled_async_exceptions2_test: Pass, Slow
+regress_34841_test: RuntimeError # http://dartbug.com/34841
 unused_changes_in_last_reload_test: RuntimeError
 
 [ $compiler == dartkp ]
diff --git a/runtime/observatory/tests/service/step_through_switch_with_continue_test.dart b/runtime/observatory/tests/service/step_through_switch_with_continue_test.dart
index cfcce49..d9afbb4 100644
--- a/runtime/observatory/tests/service/step_through_switch_with_continue_test.dart
+++ b/runtime/observatory/tests/service/step_through_switch_with_continue_test.dart
@@ -31,6 +31,7 @@
   "$file:${LINE+0}:5", // after 'code'
 
   "$file:${LINE+1}:11", // on switchOnMe
+  "$file:${LINE+17}:27", // on switchOnMe initializer starting '['
   "$file:${LINE+1}:22", // on length
 
   "$file:${LINE+2}:10", // on 0
diff --git a/runtime/observatory/web/favicon.ico b/runtime/observatory/web/favicon.ico
index 7ba349b..c861395 100644
--- a/runtime/observatory/web/favicon.ico
+++ b/runtime/observatory/web/favicon.ico
Binary files differ
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 56c49bb..2951d43 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -6,6 +6,7 @@
 #define RUNTIME_PLATFORM_UTILS_H_
 
 #include <limits>
+#include <type_traits>
 
 #include "platform/assert.h"
 #include "platform/globals.h"
@@ -338,21 +339,24 @@
   }
 
   // Decode integer in SLEB128 format from |data| and update |byte_index|.
-  static intptr_t DecodeSLEB128(const uint8_t* data,
-                                const intptr_t data_length,
-                                intptr_t* byte_index) {
+  template <typename ValueType>
+  static ValueType DecodeSLEB128(const uint8_t* data,
+                                 const intptr_t data_length,
+                                 intptr_t* byte_index) {
     ASSERT(*byte_index < data_length);
     uword shift = 0;
-    intptr_t value = 0;
+    ValueType value = 0;
     uint8_t part = 0;
     do {
       part = data[(*byte_index)++];
-      value |= static_cast<intptr_t>(part & 0x7f) << shift;
+      value |= static_cast<ValueType>(part & 0x7f) << shift;
       shift += 7;
     } while ((part & 0x80) != 0);
 
-    if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) {
-      value |= static_cast<intptr_t>(kUwordMax << shift);
+    if ((shift < (sizeof(ValueType) * CHAR_BIT)) && ((part & 0x40) != 0)) {
+      using Unsigned = typename std::make_unsigned<ValueType>::type;
+      const Unsigned kMax = std::numeric_limits<Unsigned>::max();
+      value |= static_cast<ValueType>(kMax << shift);
     }
     return value;
   }
diff --git a/runtime/tests/vm/dart/bare_instructions_trampolines_test.dart b/runtime/tests/vm/dart/bare_instructions_trampolines_test.dart
new file mode 100644
index 0000000..b7d734d
--- /dev/null
+++ b/runtime/tests/vm/dart/bare_instructions_trampolines_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.
+
+// VMOptions=--always-generate-trampolines-for-testing --use-bare-instructions
+
+// We use a reasonable sized test and run it with the above options.
+import 'hello_fuchsia_test.dart' as test;
+
+main(args) {
+  test.main(args);
+}
diff --git a/runtime/tests/vm/dart/fuzz3608420507_regression_test.dart b/runtime/tests/vm/dart/fuzz3608420507_regression_test.dart
new file mode 100644
index 0000000..198ba7c
--- /dev/null
+++ b/runtime/tests/vm/dart/fuzz3608420507_regression_test.dart
@@ -0,0 +1,236 @@
+// The Dart Project Fuzz Tester (1.2).
+// Program generated as:
+//   dart dartfuzz.dart --seed 3608420507
+
+bool var0 = false;
+bool var1 = false;
+int var2 = -49;
+double var3 = double.maxFinite;
+String var4 = '5Cw)';
+List<int> var5 = [ 8589934591 ];
+Map<int, String> var6 = { 0 : '\u2665', 1 : '7\u{1f600}\u{1f600}t\u2665s', 2 : '\u2665&)I', 3 : 'G\u2665\u{1f600}e' };
+
+List<int> foo0(List<int> par1, int par2, int par3) {
+  var6 ??= var6;
+  var4 ??= '';
+  par1 = var5;
+  return [ -94 ];
+}
+
+int foo1(Map<int, String> par1, bool par2) {
+  print((-((((var4 == (var4).toLowerCase()) ? false : par2) ? (-(double.nan)) : (var1 ? (((false ? true : var1) ? (par2 ? ((-((double.maxFinite + var3)))).roundToDouble() : (-(var3))) : var3)).abs() : var3)))));
+  { List<int> loc0 = [ 95 ];
+    return var2;
+  }
+}
+
+String foo2() {
+  var3 += (true ? ((var3).remainder((var1 ? (-(0.20648281590433248)) : double.maxFinite)) + double.maxFinite) : (var3 * var3));
+  var2 %= (var2--);
+  var6 = var6;
+  return (var1 ? (false ? (((!(true)) || false) ? var4 : ((var6).isEmpty ? var4 : 'I#')) : var4) : 'XLH+c\u2665\u2665');
+}
+
+class X0  {
+
+  String fld0_0 = '\u2665';
+
+  String foo0_0() {
+    if (((({ 0 : 'e\u{1f600}mw', 1 : 'XZPq', 2 : '2l', 3 : 'EI' } ?? { 0 : '1fG', 1 : 'LV\u2665s\u{1f600}s\u2665', 2 : '\u{1f600}#', 3 : 'V' }) ?? { 0 : 'Z6' })).isNotEmpty) {
+      var4 ??= var4;
+    } else {
+      if ((var5 == ((var1 ? ((!((false ? var1 : (!((true && (var0 ? (false ? (false ? false : var1) : true) : var1))))))) ? var0 : var1) : false) ? ((([ -9223372030412324863, 21, -97 ] + var5) ?? ([ -9223372034707292160, -16, 6 ] + var5)) + ([ 83, -52, 18 ]).sublist((++var2))) : ((var1 ? var5 : var5)).sublist(foo1(var6, true))))) {
+        { int loc0 = (var2--);
+          if (false) {
+            fld0_0 ??= '\u26655JnN';
+            { Map<int, String> loc1 = var6;
+              return var4;
+            }
+          }
+        }
+      }
+    }
+    return '1f';
+  }
+
+  void run() {
+    if ((foo0([ -23, -74, 8589934591 ], (true ? (-(-9223372030412324863)) : var2), (var0 ? var2 : foo1({ 0 : 'kU0', 1 : '\u{1f600}', 2 : '\u2665M' }, (var1 && (var2).isEven)))) == [ 81, -9223372030412324865, 56, 62 ])) {
+      var6 ??= { 0 : '\u{1f600}\u{1f600}D\u26652', 1 : 'yJb\u26657+' };
+      return;
+    } else {
+      return;
+    }
+  }
+}
+
+class X1 extends X0 {
+
+  double fld1_0 = 0.6358731486904787;
+
+  bool foo1_0() {
+    { List<int> loc0 = (foo0(var5, (var1 ? foo1({ 0 : '\u26657@MJF', 1 : 'J' }, true) : (~((--var2)))), ([ 6442450945 ]).removeLast()) + foo0([ 58 ], (-(var2)), (var2++)));
+      print(foo0([ 69 ], 97, 63));
+      var5 = (((var5).sublist(var2)).sublist(var2)).sublist(((-(var3))).toInt());
+    }
+    var1 = (!(var0));
+    print((!(((-(double.infinity)) != double.minPositive))));
+    return var0;
+  }
+
+  List<int> foo1_1(bool par1, double par2, int par3) {
+    print(foo2());
+    fld1_0 = (-(double.infinity));
+    var0 = (([ -9223372036854775808, -19 ]).remove(foo1(var6, ((-((par3++))) < var2))) ? (var4 == 'Z72') : var1);
+    return foo0(foo0((foo0(([ 14, -79 ] ?? var5), (-(par3)), ((true ? true : (!(var1))) ? (var0 ? (-73 * par3) : 53) : 66)) + (var1 ? var5 : [ 17 ])), ((true ? var1 : (par1 ? (!(false)) : par1)) ? par3 : var2), foo1(var6, true)), foo1({ 0 : '1okmvo', 1 : 'Cyn', 2 : 'Iq\u{1f600}' }, (!((!(foo1_0()))))), (par1 ? (~((foo1_0() ? (--var2) : -1))) : (par1 ? var2 : 74)));
+  }
+
+  void run() {
+    super.run();
+    if ((false ? var0 : ({ 0 : 'SVw', 1 : '\u266576Q', 2 : '\u2665b&E' }).containsValue(var4))) {
+      return;
+    }
+  }
+}
+
+class X2 extends X1 {
+
+  String fld2_0 = '';
+  Map<int, String> fld2_1 = { 0 : '\u{1f600}\u2665F8', 1 : '\u{1f600}Kd', 2 : 'CW6e@d' };
+  Map<int, String> fld2_2 = { 0 : 'MM3Ogd\u{1f600}', 1 : 'D', 2 : 'I\u{1f600}2kH4\u{1f600}' };
+
+  List<int> foo2_0(String par1, double par2, int par3) {
+    var6 ??= ({ 0 : 'hVMi', 1 : '', 2 : 'S' } ?? { 0 : '9c\u{1f600}\u{1f600}\u{1f600}dW', 1 : 'g(Fu\u{1f600}bX', 2 : 'Pi2Z\u{1f600}', 3 : 'O\u2665' });
+    for (int loc0 = 0; loc0 < 84; loc0++) {
+      return (((!((!(var1)))) ? false : false) ? var5 : (false ? var5 : [ -9223372030412324864 ]));
+    }
+  }
+
+  bool foo2_1(int par1, String par2) {
+    { double loc0 = var3;
+      fld2_2 = { 0 : 'mWycw' };
+      var0 = true;
+    }
+    return (var1 ? ((par1++) != foo1(fld2_1, (!(false)))) : true);
+  }
+
+  Map<int, String> foo2_2() {
+    { String loc0 = 'Am 3x';
+      return fld2_1;
+    }
+  }
+
+  double foo2_3(List<int> par1) {
+    var6 = foo2_2();
+    if (var1) {
+      print({ 0 : 'K\u{1f600}\u{1f600}\u2665\u{1f600}', 1 : 'lh34LP' });
+      print('im\u2665');
+      { String loc0 = (var1 ? ('y\u2665E4UQQ' + ('Q0J2  y').substring(-78)) : foo2());
+        { bool loc1 = (((-(-92))).isOdd && (!((!(false)))));
+          print(var3);
+          if ((var2).isEven) {
+            var3 /= 0.536905815119827;
+            var2 |= (++var2);
+            { double loc2 = var3;
+              { int loc3 = foo1({ 0 : 'G(', 1 : '\u{1f600}&a9t', 2 : '\u{1f600}TF', 3 : '\u2665m-' }, true);
+                var4 ??= (loc0).substring(((((par1 ?? [ -9223372034707292159, 44, -1, 2147483648 ])).remove((false ? -9223372032559808511 : (((++loc3) ~/ (2147483649 | 54))).ceil())) || false) ? (~((loc3++))) : (foo1(fld2_1, (var6 == { 0 : '', 1 : 'KP8' })) >> 50)));
+                if ((true != ((!(loc1)) ? ((-(40)) >= -32) : foo2_1(9223372034707292159, (foo2_2()).remove((((-((loc3).abs())) ~/ 42)).toSigned(-27)))))) {
+                  if (loc1) {
+                    return loc2;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  void run() {
+    super.run();
+    fld2_2 ??= (var1 ? fld2_2 : { 0 : 'M ', 1 : 'zG', 2 : 'c' });
+    if (((foo2_1(var2, var4) ? ((false ? ((var1 || (true && foo2_1(9223372032559808512, var4))) ? var5 : var5) : ([ -52 ]).sublist((true ? 24 : var2)))).remove(9223372036854775807) : false) && var0)) {
+      for (int loc0 = 0; loc0 < 57; loc0++) {
+        var5 ??= (([ 26, 82, -9223372032559808512 ]).sublist((-22 >> 27)) + var5);
+        var6 ??= fld2_2;
+        fld2_0 ??= foo2();
+        for (int loc1 = 0; loc1 < 67; loc1++) {
+          for (int loc2 = 0; loc2 < 31; loc2++) {
+            var4 = foo2();
+            { bool loc3 = foo2_1((-(((!(var0)) ? foo1(fld2_2, true) : foo1((foo2_1((false ? ([ -74, -49, -79, 2 ]).length : 9223372034707292161), 'y') ? ({ 0 : '\u{1f600}Jf', 1 : 'NF' } ?? { 0 : '1 y\u{1f600}\u26659' }) : { 0 : '6MO\u2665A\u{1f600})', 1 : 'p\u{1f600}\u{1f600}6J', 2 : 'sg)' }), var0)))), fld2_0);
+              var5 ??= var5;
+              for (int loc4 = 0; loc4 < 78; loc4++) {
+                return;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+class X3 extends X2 {
+
+  List<int> fld3_0 = [ -4, -4, -79, 34 ];
+
+  bool foo3_0(int par1, List<int> par2) {
+    return (((var1 ? 60 : var2)).isOdd ? ((var1 ? fld3_0 : par2)).remove(foo1(var6, (var1 != var0))) : (false ? false : (('GB').substring((++var2))).endsWith(('p\u{1f600}f1u\u2665' ?? 'L\u2665OY!ui'))));
+  }
+
+  int foo3_1(List<int> par1, int par2, bool par3) {
+    if (true) {
+      return par2;
+    }
+  }
+
+  List<int> foo3_2(List<int> par1, List<int> par2) {
+    for (int loc0 = 0; loc0 < 68; loc0++) {
+      { String loc1 = foo2();
+        var2 -= (~((false ? (~((false ? loc0 : -9223372034707292161))) : (var2--))));
+        for (int loc2 = 0; loc2 < 95; loc2++) {
+          var3 ??= ((false ? var3 : (-(var3))) * (var3 ?? ((-(double.negativeInfinity))).remainder((var3 * double.nan))));
+          if ((loc1).endsWith('')) {
+            print((((!(foo3_0(-47, par2))) ? par1 : ([ 2, -52, -9223372032559808512, 2147483649 ] + par2))).removeLast());
+            var2 -= foo3_1((foo0((foo0(((var0 ? [ -4294967295, -95, -22, 27 ] : [ 38 ]) + [ 2147483647 ]), (var3).truncate(), var2) ?? par1), (~(loc0)), 53)).sublist((--loc0)), ((loc2++) ?? ((!((false || var0))) ? (69 + (47 & (foo0([ 24, -98, 2147483647, -48 ], loc0, 47)).indexOf(37))) : (var4).compareTo((var1 ? loc1 : loc1)))), (foo3_0((var2 + (~(loc2))), foo0(([ 20, 13 ] + par2), loc0, var2)) && (loc1).isNotEmpty));
+            for (int loc3 = 0; loc3 < 62; loc3++) {
+              for (int loc4 = 0; loc4 < 61; loc4++) {
+                return fld3_0;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  bool foo3_3(List<int> par1, Map<int, String> par2, Map<int, String> par3) {
+    for (int loc0 = 0; loc0 < 16; loc0++) {
+      if (foo3_0((-((var0 ? 8589934591 : 65))), foo3_2(fld3_0, (fld3_0).sublist((true ? (0.23821360229648214).toInt() : var2))))) {
+        par1 ??= (((var4 == '&Tze') ? ([ -27, 23, -40 ] != par1) : true) ? [ 23, 21, 4294967295 ] : fld3_0);
+        print((par2 ?? { 0 : '\u{1f600}\u2665\u{1f600}Jpj&', 1 : '', 2 : '', 3 : '' }));
+        var4 = var4;
+        var1 = (((~(((++loc0) ?? loc0)))).isEven == false);
+      }
+      for (int loc1 = 0; loc1 < 93; loc1++) {
+        var4 = 'gngT';
+        return (foo3_0(((((var3 * (loc1).ceilToDouble()) - ((0.6230577340230226 > var3) ? (var3 - var3) : double.maxFinite)) - double.nan)).ceil(), [ 0 ]) ? ((!(var0)) && foo3_0((-(-59)), [ 8, 1, 12, -9223372030412324863 ])) : foo3_0(foo3_1(foo3_2([ 2, -33, -72 ], [ 30, 58, 0 ]), loc1, (!(var1))), var5));
+      }
+    }
+  }
+
+  void run() {
+    super.run();
+    var1 = (var6).containsKey((var0 ? (30).floor() : (~((++var2)))));
+  }
+}
+
+main() {
+  try {
+    new X3().run();
+  } catch (e) {
+    print('throws');
+  } finally {
+    print('$var0\n$var1\n$var2\n$var3\n$var4\n$var5\n$var6\n');
+  }
+}
diff --git a/runtime/tests/vm/dart/regress_35887_test.dart b/runtime/tests/vm/dart/regress_35887_test.dart
new file mode 100644
index 0000000..b0018fb
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_35887_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.
+//
+// Regression test for dartbug.com/35887.
+//
+// The call specializer inserts a "CheckNull" into main() here, but CheckNull
+// was broken in JIT because it didn't create a deopt-info to hold the
+// environment in case the it was inside a try/catch block.
+//
+// VMOptions=--optimization_counter_threshold=10 --no-background-compilation
+
+import 'package:expect/expect.dart';
+
+class Value {
+  const Value(this.val);
+
+  final int val;
+}
+
+const int limit = 50;
+
+Value maybeWrap(int i) => i < limit ? new Value(i) : null;
+
+Future<void> test() async {
+  for (int i = 0; i < 60; ++i) {
+    if (maybeWrap(i).val == -1) {
+      // never mind we just do something with it
+      print(i);
+    }
+  }
+}
+
+void main() {
+  test().catchError((e) {});
+}
diff --git a/runtime/tests/vm/dart/regress_range_analysis_shift_test.dart b/runtime/tests/vm/dart/regress_range_analysis_shift_test.dart
new file mode 100644
index 0000000..f30a370
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_range_analysis_shift_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+//
+// Test that SpeculativeInt64ShiftOp's range is correctly inferred when the RHS
+// is a nullable smi.
+
+import 'package:expect/expect.dart';
+
+int getShift(List<String> args) {
+  return args.length == -1 ? null : 40;
+}
+
+void test(List<String> args) {
+  int x = 1;
+  if (args.length <= 0) {
+    int s = getShift(args);
+    x = x << s;
+  }
+  x += 1;
+  Expect.equals(x, 1099511627777);
+}
+
+void main(List<String> args) {
+  for (int i = 0; i < 100; ++i) {
+    test(args);
+  }
+}
diff --git a/runtime/tests/vm/dart/slow_path_shared_stub_test.dart b/runtime/tests/vm/dart/slow_path_shared_stub_test.dart
index 87ce2ed..7c50e88 100644
--- a/runtime/tests/vm/dart/slow_path_shared_stub_test.dart
+++ b/runtime/tests/vm/dart/slow_path_shared_stub_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // VMOptions=--optimization_counter_threshold=10 --no-background-compilation --shared-slow-path-triggers-gc
+// VMOptions=--optimization_counter_threshold=10 --no-background-compilation --shared-slow-path-triggers-gc --no-use-vfp
 
 // This tests the stackmaps and environments for safepoints corresponding to
 // slow-path code which uses shared runtime stubs.
diff --git a/runtime/tests/vm/dart/use_bare_instructions_flag_test.dart b/runtime/tests/vm/dart/use_bare_instructions_flag_test.dart
new file mode 100644
index 0000000..bb8cc83
--- /dev/null
+++ b/runtime/tests/vm/dart/use_bare_instructions_flag_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 is ensuring that the flag for --use-bare-instructions given at
+// AOT compile-time will be used at runtime (irrespective if other values were
+// passed to the runtime).
+
+import "dart:async";
+import "dart:io";
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+main(List<String> args) async {
+  if (!Platform.executable.endsWith("dart_precompiled_runtime")) {
+    return; // Running in JIT: AOT binaries not available.
+  }
+
+  if (Platform.isAndroid) {
+    return; // SDK tree and dart_bootstrap not available on the test device.
+  }
+
+  final buildDir = path.dirname(Platform.executable);
+  final sdkDir = path.dirname(path.dirname(buildDir));
+  final platformDill = path.join(buildDir, 'vm_platform_strong.dill');
+  final genSnapshot = path.join(buildDir, 'gen_snapshot');
+  final aotRuntime = path.join(buildDir, 'dart_precompiled_runtime');
+
+  await withTempDir((String tempDir) async {
+    final script = path.join(sdkDir, 'pkg/kernel/bin/dump.dart');
+    final scriptDill = path.join(tempDir, 'kernel_dump.dill');
+
+    // Compile script to Kernel IR.
+    await run('pkg/vm/tool/gen_kernel', <String>[
+      '--aot',
+      '--platform=$platformDill',
+      '-o',
+      scriptDill,
+      script,
+    ]);
+
+    // Run the AOT compiler with/without bare instructions.
+    final scriptBareSnapshot = path.join(tempDir, 'bare.snapshot');
+    final scriptNonBareSnapshot = path.join(tempDir, 'non_bare.snapshot');
+    await Future.wait(<Future>[
+      run(genSnapshot, <String>[
+        '--use-bare-instructions',
+        '--snapshot-kind=app-aot-blobs',
+        '--blobs_container_filename=$scriptBareSnapshot',
+        scriptDill,
+      ]),
+      run(genSnapshot, <String>[
+        '--no-use-bare-instructions',
+        '--snapshot-kind=app-aot-blobs',
+        '--blobs_container_filename=$scriptNonBareSnapshot',
+        scriptDill,
+      ]),
+    ]);
+
+    // Run the resulting bare-AOT compiled script.
+    final bareOut1 = path.join(tempDir, 'bare-out1.txt');
+    final bareOut2 = path.join(tempDir, 'bare-out2.txt');
+    await Future.wait(<Future>[
+      run(aotRuntime, <String>[
+        '--use-bare-instructions',
+        scriptBareSnapshot,
+        scriptDill,
+        bareOut1,
+      ]),
+      run(aotRuntime, <String>[
+        '--no-use-bare-instructions',
+        scriptBareSnapshot,
+        scriptDill,
+        bareOut2,
+      ]),
+    ]);
+
+    // Run the resulting non-bare-AOT compiled script.
+    final nonBareOut1 = path.join(tempDir, 'non-bare-out1.txt');
+    final nonBareOut2 = path.join(tempDir, 'non-bare-out2.txt');
+    await Future.wait(<Future>[
+      run(aotRuntime, <String>[
+        '--use-bare-instructions',
+        scriptNonBareSnapshot,
+        scriptDill,
+        nonBareOut1,
+      ]),
+      run(aotRuntime, <String>[
+        '--no-use-bare-instructions',
+        scriptNonBareSnapshot,
+        scriptDill,
+        nonBareOut2,
+      ]),
+    ]);
+
+    // Ensure we got 4 times the same result.
+    final output = await readFile(bareOut1);
+    Expect.equals(output, await readFile(bareOut2));
+    Expect.equals(output, await readFile(nonBareOut1));
+    Expect.equals(output, await readFile(nonBareOut2));
+  });
+}
+
+Future<String> readFile(String file) {
+  return new File(file).readAsString();
+}
+
+Future run(String executable, List<String> args) async {
+  print('Running $executable ${args.join(' ')}');
+
+  final result = await Process.run(executable, args);
+  final String stdout = result.stdout;
+  final String stderr = result.stderr;
+  if (stdout.isNotEmpty) {
+    print('stdout:');
+    print(stdout);
+  }
+  if (stderr.isNotEmpty) {
+    print('stderr:');
+    print(stderr);
+  }
+
+  if (result.exitCode != 0) {
+    throw 'Command failed with non-zero exit code (was ${result.exitCode})';
+  }
+}
+
+withTempDir(Future fun(String dir)) async {
+  final tempDir = Directory.systemTemp.createTempSync('bare-flag-test');
+  try {
+    await fun(tempDir.path);
+  } finally {
+    tempDir.deleteSync(recursive: true);
+  }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index dda2b1d..4e33a68 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -22,6 +22,7 @@
 dart/snapshot_version_test: Skip # This test is a Dart1 test (script snapshot)
 dart/slow_path_shared_stub_test: Pass, Slow # Uses --shared-slow-path-triggers-gc flag.
 dart/stack_overflow_shared_test: Pass, Slow # Uses --shared-slow-path-triggers-gc flag.
+dart/use_bare_instructions_flag_test: Pass, Slow # Spawns several subprocesses
 
 [ $mode == debug ]
 dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
@@ -51,6 +52,8 @@
 dart/simd128float32_test: Skip # compilers not aware of Simd128
 dart/truncating_ints_test: SkipByDesign # The test requires int64.
 dart/wrap_around_in_range_analysis_test: SkipByDesign # The test requires int64.
+dart/regress_range_analysis_shift_test: SkipByDesign # The test requires int64.
+dart/fuzz3608420507_regression_test: SkipByDesign # Not relevant to dart2js.
 
 [ $compiler != dartk || ($arch != x64 && $arch != simarm && $arch != arm) || $hot_reload || $hot_reload_rollback ]
 dart/entrypoints/jit/*: SkipByDesign  # Only supported in the Dart 2 JIT and AOT, and test optimizations - hence disabled on hotreload bots.
@@ -106,6 +109,12 @@
 dart/spawn_infinite_loop_test: SkipByDesign # VM shutdown test
 dart/spawn_shutdown_test: SkipByDesign # VM Shutdown test
 
+[ $runtime != dart_precompiled  || $system == android ]
+dart/bare_instructions_trampolines_test: SkipByDesign # This test is for VM AOT only (android fails due to listing interfaces).
+
+[ $mode == debug || $runtime != dart_precompiled  || $system == android ]
+dart/use_bare_instructions_flag_test: SkipByDesign # This test is for VM AOT only and is quite slow (so we don't run it in debug mode).
+
 [ $system == fuchsia ]
 cc/CorelibIsolateStartup: Skip # OOM crash can bring down the OS.
 cc/Read: Fail # TODO(zra): Investigate, ../../dart/runtime/bin/file_test.cc: 34: error: expected: !file->WriteByte(1)
@@ -141,9 +150,6 @@
 cc/PrintJSON: Crash
 cc/Service_TokenStream: Crash
 
-[ ($compiler == dartk || $compiler == dartkb) && $runtime == vm ]
-dart/appjit_cha_deopt_test: Pass, RuntimeError # Issue 34627
-
 # Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
diff --git a/runtime/tools/dartfuzz/README.md b/runtime/tools/dartfuzz/README.md
index ba3dfcc..14398d7 100644
--- a/runtime/tools/dartfuzz/README.md
+++ b/runtime/tools/dartfuzz/README.md
@@ -29,15 +29,13 @@
 =============================
 To start a fuzz testing session, run
 
-    dart dartfuzz_test.dart
-
-    run_dartfuzz_test.py  [--help]
-                          [--isolates ISOLATES ]
-                          [--repeat REPEAT]
-                          [--time TIME]
-                          [--true_divergence]
-                          [--mode1 MODE]
-                          [--mode2 MODE]
+    dart dartfuzz_test.dart [--help]
+                            [--isolates ISOLATES ]
+                            [--repeat REPEAT]
+                            [--time TIME]
+                            [--true_divergence]
+                            [--mode1 MODE]
+                            [--mode2 MODE]
 
 where
 
@@ -50,19 +48,19 @@
     --dart-top        : sets DART_TOP explicitly through command line
     --mode1           : m1
     --mode2           : m2, and values one of
-        jit-[stress-][debug-]ia32  = Dart JIT (ia32)
-        jit-[stress-][debug-]x64   = Dart JIT (x64)
-        jit-[stress-][debug-]arm32 = Dart JIT (simarm)
-        jit-[stress-][debug-]arm64 = Dart JIT (simarm64)
-        jit-[stress-][debug-]dbc   = Dart JIT (simdbc)
-        jit-[stress-][debug-]dbc64 = Dart JIT (simdbc64)
-        aot-[debug-]x64            = Dart AOT (x64)
-        aot-[debug-]arm32          = Dart AOT (simarm)
-        aot-[debug-]arm64          = Dart AOT (simarm64)
-        kbc-int-[debug-]x64        = Dart KBC (interpreted bytecode)
-        kbc-mix-[debug-]x64        = Dart KBC (mixed-mode bytecode)
-        kbc-cmp-[debug-]x64        = Dart KBC (compiled bytecode)
-        js-x64                     = dart2js + Node.JS
+        jit-[debug-]ia32    = Dart JIT (ia32)
+        jit-[debug-]x64     = Dart JIT (x64)
+        jit-[debug-]arm32   = Dart JIT (simarm)
+        jit-[debug-]arm64   = Dart JIT (simarm64)
+        jit-[debug-]dbc     = Dart JIT (simdbc)
+        jit-[debug-]dbc64   = Dart JIT (simdbc64)
+        aot-[debug-]x64     = Dart AOT (x64)
+        aot-[debug-]arm32   = Dart AOT (simarm)
+        aot-[debug-]arm64   = Dart AOT (simarm64)
+        kbc-int-[debug-]x64 = Dart KBC (interpreted bytecode)
+        kbc-mix-[debug-]x64 = Dart KBC (mixed-mode bytecode)
+        kbc-cmp-[debug-]x64 = Dart KBC (compiled bytecode)
+        djs-x64             = dart2js + Node.JS
 
 If no modes are given, a random JIT and/or AOT combination is used.
 
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 0ad5858..9843383 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -12,7 +12,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.2';
+const String version = '1.3';
 
 // Restriction on statement and expression depths.
 const int stmtDepth = 5;
@@ -160,6 +160,33 @@
   }
 
   //
+  // Comments (for FE and analysis tools).
+  //
+
+  void emitComment() {
+    switch (rand.nextInt(4)) {
+      case 0:
+        emitLn('// Single-line comment.');
+        break;
+      case 1:
+        emitLn('/// Single-line documentation comment.');
+        break;
+      case 2:
+        emitLn('/*');
+        emitLn(' * Multi-line');
+        emitLn(' * comment.');
+        emitLn(' */');
+        break;
+      default:
+        emitLn('/**');
+        emitLn(' ** Multi-line');
+        emitLn(' ** documentation comment.');
+        emitLn(' */');
+        break;
+    }
+  }
+
+  //
   // Statements.
   //
 
@@ -167,7 +194,7 @@
   bool emitAssign() {
     DartType tp = getType();
     emitLn('', newline: false);
-    emitVar(tp);
+    emitVar(0, tp);
     emitAssignOp(tp);
     emitExpr(0, tp);
     emit(';', newline: true);
@@ -202,10 +229,10 @@
     emitExpr(0, DartType.BOOL);
     emit(') {', newline: true);
     indent += 2;
-    bool b = emitStatements(depth + 1);
+    emitStatements(depth + 1);
     indent -= 2;
     emitLn('}');
-    return b;
+    return true;
   }
 
   // Emit a two-way if statement.
@@ -257,13 +284,17 @@
   // Emit a statement. Returns true if code may fall-through.
   // TODO: add many more constructs
   bool emitStatement(int depth) {
+    // Throw in a comment every once in a while.
+    if (rand.nextInt(10) == 0) {
+      emitComment();
+    }
     // Continuing nested statements becomes less likely as the depth grows.
     if (rand.nextInt(depth + 1) > stmtDepth) {
       return emitAssign();
     }
     // Possibly nested statement.
     switch (rand.nextInt(8)) {
-      // favors assignment
+      // Favors assignment.
       case 0:
         return emitIf1(depth);
       case 1:
@@ -310,10 +341,9 @@
 
   void emitInt() {
     switch (rand.nextInt(4)) {
-      // favors small positive int
+      // Favors small positive int.
       case 0:
-        emit(
-            '${DartFuzzValues.interestingIntegers[rand.nextInt(DartFuzzValues.interestingIntegers.length)]}');
+        emit('${oneOf(DartFuzzValues.interestingIntegers)}');
         break;
       case 1:
         emitSmallNegativeInt();
@@ -325,22 +355,10 @@
   }
 
   void emitDouble() {
-    switch (rand.nextInt(7)) {
-      // favors small double
+    switch (rand.nextInt(10)) {
+      // Favors regular double.
       case 0:
-        emit('double.infinity');
-        break;
-      case 1:
-        emit('double.maxFinite');
-        break;
-      case 2:
-        emit('double.minPositive');
-        break;
-      case 3:
-        emit('double.nan');
-        break;
-      case 4:
-        emit('double.negativeInfinity');
+        emit(oneOf(DartFuzzValues.interestingDoubles));
         break;
       default:
         emit('${rand.nextDouble()}');
@@ -350,15 +368,12 @@
 
   void emitChar() {
     switch (rand.nextInt(10)) {
-      // favors regular char
+      // Favors regular char.
       case 0:
-        emit('\\u2665');
-        break;
-      case 1:
-        emit('\\u{1f600}'); // rune
+        emit(oneOf(DartFuzzValues.interestingChars));
         break;
       default:
-        emit(DartFuzzValues.interestingChars[
+        emit(DartFuzzValues.regularChars[
             rand.nextInt(DartFuzzValues.interestingChars.length)]);
         break;
     }
@@ -442,18 +457,40 @@
     emit('${choices[rand.nextInt(choices.length)]}');
   }
 
-  void emitVar(DartType tp) {
-    // TODO: add subscripted var
-    emitScalarVar(tp);
+  void emitSubscriptedVar(int depth, DartType tp) {
+    if (tp == DartType.INT) {
+      emitScalarVar(DartType.INT_LIST);
+      emit('[');
+      emitExpr(depth + 1, DartType.INT);
+      emit(']');
+    } else if (tp == DartType.STRING) {
+      emitScalarVar(DartType.INT_STRING_MAP);
+      emit('[');
+      emitExpr(depth + 1, DartType.INT);
+      emit(']');
+    } else {
+      emitScalarVar(tp); // resort to scalar
+    }
   }
 
-  void emitTerminal(DartType tp) {
+  void emitVar(int depth, DartType tp) {
+    switch (rand.nextInt(2)) {
+      case 0:
+        emitScalarVar(tp);
+        break;
+      default:
+        emitSubscriptedVar(depth, tp);
+        break;
+    }
+  }
+
+  void emitTerminal(int depth, DartType tp) {
     switch (rand.nextInt(2)) {
       case 0:
         emitLiteral(tp);
         break;
       default:
-        emitVar(tp);
+        emitVar(depth, tp);
         break;
     }
   }
@@ -478,7 +515,7 @@
       emitExpr(depth + 1, tp);
       emit('))');
     } else {
-      emitTerminal(tp); // resort to terminal
+      emitTerminal(depth, tp); // resort to terminal
     }
   }
 
@@ -495,6 +532,16 @@
         emit(')');
         return;
       }
+    } else if (tp == DartType.STRING || tp == DartType.INT_LIST) {
+      // For strings and lists, a construct like x = x + x; inside a loop
+      // yields an exponentially growing data structure. We avoid this
+      // situation by forcing a literal on the rhs of each +.
+      emit('(');
+      emitExpr(depth + 1, tp);
+      emitBinaryOp(tp);
+      emitLiteral(tp);
+      emit(')');
+      return;
     }
     emit('(');
     emitExpr(depth + 1, tp);
@@ -524,32 +571,34 @@
       if (r == 1) emitPreOrPostOp(tp);
       emit(')');
     } else {
-      emitTerminal(tp); // resort to terminal
+      emitTerminal(depth, tp); // resort to terminal
     }
   }
 
   // Emit library call.
   void emitLibraryCall(int depth, DartType tp) {
-    if (tp == DartType.INT_STRING_MAP) {
-      emitTerminal(tp); // resort to terminal
-      return;
-    }
     DartLib lib = getLibraryMethod(tp);
-    List<DartType> proto = lib.proto;
+    String proto = lib.proto;
     // Receiver.
-    if (proto[0] != null) {
-      DartType deeper_tp = proto[0];
+    if (proto[0] != 'V') {
       emit('(');
-      emitExpr(depth + 1, deeper_tp);
+      emitArg(depth + 1, proto[0]);
       emit(').');
     }
     // Call.
     emit('${lib.name}');
     // Parameters.
-    if (proto.length == 1) {
-      emit('()');
-    } else if (proto[1] != null) {
-      emitExprList(depth + 1, proto);
+    if (proto[1] != 'v') {
+      emit('(');
+      if (proto[1] != 'V') {
+        for (int i = 1; i < proto.length; i++) {
+          emitArg(depth + 1, proto[i]);
+          if (i != (proto.length - 1)) {
+            emit(', ');
+          }
+        }
+      }
+      emit(')');
     }
   }
 
@@ -586,14 +635,14 @@
         return;
       }
     }
-    emitTerminal(tp); // resort to terminal.
+    emitTerminal(depth, tp); // resort to terminal.
   }
 
   // Emit expression.
   void emitExpr(int depth, DartType tp) {
     // Continuing nested expressions becomes less likely as the depth grows.
     if (rand.nextInt(depth + 1) > exprDepth) {
-      emitTerminal(tp);
+      emitTerminal(depth, tp);
       return;
     }
     // Possibly nested expression.
@@ -617,7 +666,7 @@
         emitMethodCall(depth, tp);
         break;
       default:
-        emitTerminal(tp);
+        emitTerminal(depth, tp);
         break;
     }
   }
@@ -725,11 +774,42 @@
       return oneOf(DartLib.stringLibs);
     } else if (tp == DartType.INT_LIST) {
       return oneOf(DartLib.intListLibs);
+    } else if (tp == DartType.INT_STRING_MAP) {
+      return oneOf(DartLib.intStringMapLibs);
     } else {
       assert(false);
     }
   }
 
+  // Emit a library argument, possibly subject to restrictions.
+  void emitArg(int depth, String p) {
+    switch (p) {
+      case 'B':
+        emitExpr(depth, DartType.BOOL);
+        break;
+      case 'i':
+        emitSmallPositiveInt();
+        break;
+      case 'I':
+        emitExpr(depth, DartType.INT);
+        break;
+      case 'D':
+        emitExpr(depth, DartType.DOUBLE);
+        break;
+      case 'S':
+        emitExpr(depth, DartType.STRING);
+        break;
+      case 'L':
+        emitExpr(depth, DartType.INT_LIST);
+        break;
+      case 'M':
+        emitExpr(depth, DartType.INT_STRING_MAP);
+        break;
+      default:
+        assert(false);
+    }
+  }
+
   //
   // Types.
   //
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index 06545ca..148f19e 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -51,38 +51,70 @@
   // Factory.
   static TestRunner getTestRunner(String mode, String top, String tmp,
       Map<String, String> env, Random rand) {
+    String prefix = mode.substring(0, 3).toUpperCase();
     String tag = getTag(mode);
-    if (mode.startsWith('jit-stress'))
-      switch (rand.nextInt(6)) {
-        case 0:
-          return new TestRunnerJIT('JIT-NOFIELDGUARDS', tag, top, tmp, env,
-              ['--use_field_guards=false']);
-        case 1:
-          return new TestRunnerJIT(
-              'JIT-NOINTRINSIFY', tag, top, tmp, env, ['--intrinsify=false']);
-        case 2:
-          return new TestRunnerJIT('JIT-COMPACTEVERY', tag, top, tmp, env,
-              ['--gc_every=1000', '--use_compactor=true']);
-        case 3:
-          return new TestRunnerJIT('JIT-MARKSWEEPEVERY', tag, top, tmp, env,
-              ['--gc_every=1000', '--use_compactor=false']);
-        case 4:
-          return new TestRunnerJIT('JIT-DEPOPTEVERY', tag, top, tmp, env,
-              ['--deoptimize_every=100']);
-        case 5:
-          return new TestRunnerJIT('JIT-STACKTRACEEVERY', tag, top, tmp, env,
-              ['--stacktrace_every=100']);
-        case 6:
-          // Crashes (https://github.com/dart-lang/sdk/issues/35196):
-          return new TestRunnerJIT('JIT-OPTCOUNTER', tag, top, tmp, env,
-              ['--optimization_counter_threshold=1']);
+    // Prepare extra flags.
+    List<String> extraFlags = [];
+    if (mode.startsWith('kbc-int')) {
+      prefix += '-INT';
+      extraFlags += [
+        '--enable-interpreter',
+        '--compilation-counter-threshold=-1'
+      ];
+    } else if (mode.startsWith('kbc-mix')) {
+      prefix += '-MIX';
+      extraFlags += ['--enable-interpreter'];
+    } else if (mode.startsWith('kbc-cmp')) {
+      prefix += '-CMP';
+      extraFlags += ['--use-bytecode-compiler'];
+    }
+    // Every once in a while, stress test JIT.
+    if (mode.startsWith('jit') && rand.nextInt(4) == 0) {
+      final r = rand.nextInt(6);
+      if (r == 0) {
+        prefix += '-NOFIELDGUARDS';
+        extraFlags += ['--use_field_guards=false'];
+      } else if (r == 1) {
+        prefix += '-NOINTRINSIFY';
+        extraFlags += ['--intrinsify=false'];
+      } else if (r == 2) {
+        prefix += '-COMPACTEVERY';
+        extraFlags += ['--gc_every=1000', '--use_compactor=true'];
+      } else if (r == 3) {
+        prefix += '-MARKSWEEPEVERY';
+        extraFlags += ['--gc_every=1000', '--use_compactor=false'];
+      } else if (r == 4) {
+        prefix += '-DEPOPTEVERY';
+        extraFlags += ['--deoptimize_every=100'];
+      } else if (r == 5) {
+        prefix += '-STACKTRACEEVERY';
+        extraFlags += ['--stacktrace_every=100'];
+      } else if (r == 6) {
+        // Crashes (https://github.com/dart-lang/sdk/issues/35196):
+        prefix += '-OPTCOUNTER';
+        extraFlags += ['--optimization_counter_threshold=1'];
       }
-    if (mode.startsWith('jit'))
-      return new TestRunnerJIT('JIT', tag, top, tmp, env, []);
-    if (mode.startsWith('aot')) return new TestRunnerAOT(tag, top, tmp, env);
-    if (mode.startsWith('kbc'))
-      return new TestRunnerKBC(mode, tag, top, tmp, env);
-    if (mode.startsWith('js')) return new TestRunnerJS(tag, top, tmp, env);
+    }
+    // Every once in a while, disable VFP on arm32.
+    if (mode.contains('arm32') && rand.nextInt(4) == 0) {
+      prefix += '-noVFP';
+      extraFlags += ['--no-use-vfp'];
+    }
+    // Every once in a while, use -O3 compiler.
+    if (!mode.startsWith('djs') && rand.nextInt(4) == 0) {
+      prefix += '-O3';
+      extraFlags += ['--optimization_level=3'];
+    }
+    // Construct runner.
+    if (mode.startsWith('jit')) {
+      return new TestRunnerJIT(prefix, tag, top, tmp, env, extraFlags);
+    } else if (mode.startsWith('aot')) {
+      return new TestRunnerAOT(prefix, tag, top, tmp, env, extraFlags);
+    } else if (mode.startsWith('kbc')) {
+      return new TestRunnerKBC(prefix, tag, top, tmp, env, extraFlags);
+    } else if (mode.startsWith('djs')) {
+      return new TestRunnerDJS(prefix, tag, top, tmp, env);
+    }
     throw ('unknown runner in mode: $mode');
   }
 
@@ -106,13 +138,12 @@
 
 /// Concrete test runner of Dart JIT.
 class TestRunnerJIT implements TestRunner {
-  TestRunnerJIT(String prefix, String tag, String top, String tmp,
-      Map<String, String> e, List<String> extra_flags) {
+  TestRunnerJIT(String prefix, String tag, String top, String tmp, this.env,
+      List<String> extraFlags) {
     description = '$prefix-$tag';
     dart = '$top/out/$tag/dart';
     fileName = '$tmp/fuzz.dart';
-    env = e;
-    cmd = [dart, "--deterministic"] + extra_flags + [fileName];
+    cmd = [dart, "--deterministic"] + extraFlags + [fileName];
   }
 
   TestResult run() {
@@ -128,14 +159,16 @@
 
 /// Concrete test runner of Dart AOT.
 class TestRunnerAOT implements TestRunner {
-  TestRunnerAOT(String tag, String top, String tmp, Map<String, String> e) {
-    description = 'AOT-${tag}';
+  TestRunnerAOT(String prefix, String tag, String top, String tmp,
+      Map<String, String> e, List<String> extraFlags) {
+    description = '$prefix-$tag';
     precompiler = '$top/pkg/vm/tool/precompiler2';
     dart = '$top/pkg/vm/tool/dart_precompiled_runtime2';
     fileName = '$tmp/fuzz.dart';
     snapshot = '$tmp/snapshot';
     env = Map<String, String>.from(e);
     env['DART_CONFIGURATION'] = tag;
+    env['OPTIONS'] = extraFlags.join(' ');
   }
 
   TestResult run() {
@@ -156,28 +189,15 @@
 
 /// Concrete test runner of bytecode.
 class TestRunnerKBC implements TestRunner {
-  TestRunnerKBC(
-      String mode, String tag, String top, String tmp, Map<String, String> e) {
+  TestRunnerKBC(String prefix, String tag, String top, String tmp, this.env,
+      List<String> extraFlags) {
+    description = '$prefix-$tag';
     generate = '$top/pkg/vm/tool/gen_kernel';
     platform = '--platform=$top/out/$tag/vm_platform_strong.dill';
     dill = '$tmp/out.dill';
     dart = '$top/out/$tag/dart';
     fileName = '$tmp/fuzz.dart';
-    env = e;
-    cmd = [dart];
-    if (mode.startsWith('kbc-int')) {
-      description = 'KBC-INT-${tag}';
-      cmd += ['--enable-interpreter', '--compilation-counter-threshold=-1'];
-    } else if (mode.startsWith('kbc-mix')) {
-      description = 'KBC-MIX-${tag}';
-      cmd += ['--enable-interpreter'];
-    } else if (mode.startsWith('kbc-cmp')) {
-      description = 'KBC-CMP-${tag}';
-      cmd += ['--use-bytecode-compiler'];
-    } else {
-      throw ('unknown KBC mode: $mode');
-    }
-    cmd += [dill];
+    cmd = [dart] + extraFlags + [dill];
   }
 
   TestResult run() {
@@ -200,13 +220,12 @@
 }
 
 /// Concrete test runner of Dart2JS.
-class TestRunnerJS implements TestRunner {
-  TestRunnerJS(String tag, String top, String tmp, Map<String, String> e) {
-    description = 'Dart2JS-$tag';
+class TestRunnerDJS implements TestRunner {
+  TestRunnerDJS(String prefix, String tag, String top, String tmp, this.env) {
+    description = '$prefix-$tag';
     dart2js = '$top/sdk/bin/dart2js';
     fileName = '$tmp/fuzz.dart';
     js = '$tmp/out.js';
-    env = e;
   }
 
   TestResult run() {
@@ -525,18 +544,6 @@
     'jit-arm64',
     'jit-dbc',
     'jit-dbc64',
-    'jit-stress-debug-ia32',
-    'jit-stress-debug-x64',
-    'jit-stress-debug-arm32',
-    'jit-stress-debug-arm64',
-    'jit-stress-debug-dbc',
-    'jit-stress-debug-dbc64',
-    'jit-stress-ia32',
-    'jit-stress-x64',
-    'jit-stress-arm32',
-    'jit-stress-arm64',
-    'jit-stress-dbc',
-    'jit-stress-dbc64',
     'aot-debug-x64',
     'aot-x64',
     'kbc-int-debug-x64',
diff --git a/runtime/tools/dartfuzz/dartfuzz_values.dart b/runtime/tools/dartfuzz/dartfuzz_values.dart
index e19e301..c97249d 100644
--- a/runtime/tools/dartfuzz/dartfuzz_values.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_values.dart
@@ -26,9 +26,24 @@
 /// Class with interesting values for fuzzing.
 class DartFuzzValues {
   // Interesting characters.
-  static const interestingChars =
+  static const List<String> interestingChars = [
+    '\\u2665',
+    '\\u{1f600}', // rune
+  ];
+
+  // Regular characters.
+  static const regularChars =
       'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#&()+- ';
 
+  // Interesting doubles.
+  static const interestingDoubles = [
+    'double.infinity',
+    'double.maxFinite',
+    'double.minPositive',
+    'double.nan',
+    'double.negativeInfinity',
+  ];
+
   // Interesting integer values.
   static const List<int> interestingIntegers = [
     0x0000000000000000,
@@ -71,97 +86,111 @@
 }
 
 /// Class that represents Dart library methods.
+//
 /// The invididual lists are organized by return type.
-/// Proto list:
-///   [ receiver-type (null denotes none),
-///     param1 type (null denotes getter),
-///     param2 type,
-///     ...
-///   ]
+/// The proto string has the following format:
+///    +-------> receiver type (V denotes none)
+///    |+------> param1 type  (V denotes none, v denotes getter)
+///    ||+-----> param2 type
+///    |||+----> ....
+///    ||||
+///   "TTTT...."
+/// where:
+///   V void
+///   v void (special)
+///   B bool
+///   I int
+///   i int (small)
+///   D double
+///   S String
+///   L List<int>
+///   M Map<int, String>
 ///
 /// TODO(ajcbik): generate these lists automatically
 ///
 class DartLib {
   final String name;
-  final List<DartType> proto;
+  final String proto;
   const DartLib(this.name, this.proto);
 
   static const boolLibs = [
-    DartLib('isEven', [DartType.INT, null]),
-    DartLib('isOdd', [DartType.INT, null]),
-    DartLib('isEmpty', [DartType.STRING, null]),
-    DartLib('isEmpty', [DartType.INT_STRING_MAP, null]),
-    DartLib('isNotEmpty', [DartType.STRING, null]),
-    DartLib('isNotEmpty', [DartType.INT_STRING_MAP, null]),
-    DartLib('endsWith', [DartType.STRING, DartType.STRING]),
-    DartLib('remove', [DartType.INT_LIST, DartType.INT]),
-    DartLib('containsValue', [DartType.INT_STRING_MAP, DartType.STRING]),
-    DartLib('containsKey', [DartType.INT_STRING_MAP, DartType.INT]),
+    DartLib('isEven', "Iv"),
+    DartLib('isOdd', "Iv"),
+    DartLib('isEmpty', "Sv"),
+    DartLib('isEmpty', "Mv"),
+    DartLib('isNotEmpty', "Sv"),
+    DartLib('isNotEmpty', "Mv"),
+    DartLib('endsWith', "SS"),
+    DartLib('remove', "LI"),
+    DartLib('containsValue', "MS"),
+    DartLib('containsKey', "MI"),
   ];
 
   static const intLibs = [
-    DartLib('bitLength', [DartType.INT, null]),
-    DartLib('sign', [DartType.INT, null]),
-    DartLib('abs', [DartType.INT]),
-    DartLib('round', [DartType.INT]),
-    DartLib('round', [DartType.DOUBLE]),
-    DartLib('floor', [DartType.INT]),
-    DartLib('floor', [DartType.DOUBLE]),
-    DartLib('ceil', [DartType.INT]),
-    DartLib('ceil', [DartType.DOUBLE]),
-    DartLib('truncate', [DartType.INT]),
-    DartLib('truncate', [DartType.DOUBLE]),
-    DartLib('toInt', [DartType.DOUBLE]),
-    DartLib('toUnsigned', [DartType.INT, DartType.INT]),
-    DartLib('toSigned', [DartType.INT, DartType.INT]),
-    DartLib('modInverse', [DartType.INT, DartType.INT]),
-    DartLib('modPow', [DartType.INT, DartType.INT, DartType.INT]),
-    DartLib('length', [DartType.STRING, null]),
-    DartLib('length', [DartType.INT_LIST, null]),
-    DartLib('length', [DartType.INT_STRING_MAP, null]),
-    DartLib('codeUnitAt', [DartType.STRING, DartType.INT]),
-    DartLib('compareTo', [DartType.STRING, DartType.STRING]),
-    DartLib('removeLast', [DartType.INT_LIST]),
-    DartLib('removeAt', [DartType.INT_LIST, DartType.INT]),
-    DartLib('indexOf', [DartType.INT_LIST, DartType.INT]),
-    DartLib('lastIndexOf', [DartType.INT_LIST, DartType.INT]),
+    DartLib('bitLength', "Iv"),
+    DartLib('sign', "Iv"),
+    DartLib('abs', "IV"),
+    DartLib('round', "IV"),
+    DartLib('round', "DV"),
+    DartLib('floor', "IV"),
+    DartLib('floor', "DV"),
+    DartLib('ceil', "IV"),
+    DartLib('ceil', "DV"),
+    DartLib('truncate', "IV"),
+    DartLib('truncate', "DV"),
+    DartLib('toInt', "DV"),
+    DartLib('toUnsigned', "II"),
+    DartLib('toSigned', "II"),
+    DartLib('modInverse', "II"),
+    DartLib('modPow', "III"),
+    DartLib('length', "Sv"),
+    DartLib('length', "Lv"),
+    DartLib('length', "Mv"),
+    DartLib('codeUnitAt', "SI"),
+    DartLib('compareTo', "SS"),
+    DartLib('removeLast', "LV"),
+    DartLib('removeAt', "LI"),
+    DartLib('indexOf', "LI"),
+    DartLib('lastIndexOf', "LI"),
   ];
 
   static const doubleLibs = [
-    DartLib('sign', [DartType.DOUBLE, null]),
-    DartLib('abs', [DartType.DOUBLE]),
-    DartLib('toDouble', [DartType.INT]),
-    DartLib('roundToDouble', [DartType.INT]),
-    DartLib('roundToDouble', [DartType.DOUBLE]),
-    DartLib('floorToDouble', [DartType.INT]),
-    DartLib('floorToDouble', [DartType.DOUBLE]),
-    DartLib('ceilToDouble', [DartType.INT]),
-    DartLib('ceilToDouble', [DartType.DOUBLE]),
-    DartLib('truncateToDouble', [DartType.INT]),
-    DartLib('truncateToDouble', [DartType.DOUBLE]),
-    DartLib('remainder', [DartType.DOUBLE, DartType.DOUBLE]),
+    DartLib('sign', "Dv"),
+    DartLib('abs', "DV"),
+    DartLib('toDouble', "IV"),
+    DartLib('roundToDouble', "IV"),
+    DartLib('roundToDouble', "DV"),
+    DartLib('floorToDouble', "IV"),
+    DartLib('floorToDouble', "DV"),
+    DartLib('ceilToDouble', "IV"),
+    DartLib('ceilToDouble', "DV"),
+    DartLib('truncateToDouble', "IV"),
+    DartLib('truncateToDouble', "DV"),
+    DartLib('remainder', "DD"),
   ];
 
   static const stringLibs = [
-    DartLib('toString', [DartType.BOOL]),
-    DartLib('toString', [DartType.INT]),
-    DartLib('toString', [DartType.DOUBLE]),
-    DartLib('toRadixString', [DartType.INT, DartType.INT]),
-    DartLib('trim', [DartType.STRING]),
-    DartLib('trimLeft', [DartType.STRING]),
-    DartLib('trimRight', [DartType.STRING]),
-    DartLib('toLowerCase', [DartType.STRING]),
-    DartLib('toUpperCase', [DartType.STRING]),
-    DartLib('substring', [DartType.STRING, DartType.INT]),
-    DartLib('replaceRange',
-        [DartType.STRING, DartType.INT, DartType.INT, DartType.STRING]),
-    DartLib('remove', [DartType.INT_STRING_MAP, DartType.INT]),
-    // Avoid (OOM divergences, TODO(ajcbik): restrict parameters)
-    // DartLib('padLeft', [DartType.STRING, DartType.INT]),
-    // DartLib('padRight', [DartType.STRING, DartType.INT]),
+    DartLib('toString', "BV"),
+    DartLib('toString', "IV"),
+    DartLib('toString', "DV"),
+    DartLib('toRadixString', "II"),
+    DartLib('trim', "SV"),
+    DartLib('trimLeft', "SV"),
+    DartLib('trimRight', "SV"),
+    DartLib('toLowerCase', "SV"),
+    DartLib('toUpperCase', "SV"),
+    DartLib('substring', "SI"),
+    DartLib('replaceRange', "SIIS"),
+    DartLib('remove', "MI"),
+    DartLib('padLeft', "Si"), // restrict!
+    DartLib('padRight', "Si"), // restrict!
   ];
 
   static const intListLibs = [
-    DartLib('sublist', [DartType.INT_LIST, DartType.INT])
+    DartLib('sublist', "LI"),
+  ];
+
+  static const intStringMapLibs = [
+    DartLib('Map.from', "VM"),
   ];
 }
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index cd8eaf1..d018eb1 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -8,6 +8,7 @@
 import("../../sdk/lib/convert/convert_sources.gni")
 import("../../sdk/lib/core/core_sources.gni")
 import("../../sdk/lib/developer/developer_sources.gni")
+import("../../sdk/lib/ffi/ffi_sources.gni")
 import("../../sdk/lib/internal/internal_sources.gni")
 import("../../sdk/lib/isolate/isolate_sources.gni")
 import("../../sdk/lib/math/math_sources.gni")
@@ -16,13 +17,15 @@
 import("../../sdk/lib/typed_data/typed_data_sources.gni")
 import("../../sdk/lib/vmservice/vmservice_sources.gni")
 import("../../utils/compile_platform.gni")
-import("../bin/io_sources.gni")
 import("../bin/cli_sources.gni")
+import("../bin/io_sources.gni")
+import("../configs.gni")
 import("../lib/async_sources.gni")
 import("../lib/collection_sources.gni")
 import("../lib/convert_sources.gni")
 import("../lib/core_sources.gni")
 import("../lib/developer_sources.gni")
+import("../lib/ffi_sources.gni")
 import("../lib/internal_sources.gni")
 import("../lib/isolate_sources.gni")
 import("../lib/math_sources.gni")
@@ -30,7 +33,6 @@
 import("../lib/profiler_sources.gni")
 import("../lib/typed_data_sources.gni")
 import("../lib/vmservice_sources.gni")
-import("../configs.gni")
 import("../runtime_args.gni")
 import("compiler/compiler_sources.gni")
 import("heap/heap_sources.gni")
@@ -63,7 +65,7 @@
       # TODO(US-399): Remove time_service specific code when it is no longer
       # necessary.
       "//garnet/public/lib/component/cpp",
-      "//garnet/public/fidl/fuchsia.timezone",
+      "//sdk/fidl/fuchsia.timezone",
 
       # TODO(zra): When the platform-specific timeline code is moved out to
       # the embedder, this can go away.
@@ -84,12 +86,13 @@
 library_for_all_configs("libdart_lib") {
   target_type = "source_set"
   include_dirs = [ ".." ]
-  allsources = async_runtime_sources + collection_runtime_sources +
-               convert_runtime_sources + core_runtime_sources +
-               developer_runtime_sources + internal_runtime_sources +
-               isolate_runtime_sources + math_runtime_sources +
-               mirrors_runtime_sources + profiler_runtime_sources +
-               typed_data_runtime_sources + vmservice_runtime_sources
+  allsources =
+      async_runtime_sources + collection_runtime_sources +
+      convert_runtime_sources + core_runtime_sources +
+      developer_runtime_sources + internal_runtime_sources +
+      isolate_runtime_sources + math_runtime_sources + mirrors_runtime_sources +
+      profiler_runtime_sources + typed_data_runtime_sources +
+      vmservice_runtime_sources + ffi_runtime_sources
   sources = [ "bootstrap.cc" ] + rebase_path(allsources, ".", "../lib")
   snapshot_sources = []
   nosnapshot_sources = []
diff --git a/runtime/vm/allocation.h b/runtime/vm/allocation.h
index 420b85e..834b28b 100644
--- a/runtime/vm/allocation.h
+++ b/runtime/vm/allocation.h
@@ -7,13 +7,13 @@
 
 #include "platform/allocation.h"
 #include "platform/assert.h"
-#include "vm/base_isolate.h"
 #include "vm/globals.h"
 
 namespace dart {
 
 // Forward declarations.
 class ThreadState;
+class Zone;
 
 // Stack resources subclass from this base class. The VM will ensure that the
 // destructors of these objects are called before the stack is unwound past the
diff --git a/runtime/vm/bitfield.h b/runtime/vm/bitfield.h
index af2ca2a..7d15b0a 100644
--- a/runtime/vm/bitfield.h
+++ b/runtime/vm/bitfield.h
@@ -5,6 +5,7 @@
 #ifndef RUNTIME_VM_BITFIELD_H_
 #define RUNTIME_VM_BITFIELD_H_
 
+#include "platform/assert.h"
 #include "platform/globals.h"
 
 namespace dart {
@@ -16,6 +17,9 @@
 template <typename S, typename T, int position, int size>
 class BitField {
  public:
+  static_assert((sizeof(S) * kBitsPerByte) >= (position + size),
+                "BitField does not fit into the type.");
+
   static const intptr_t kNextBit = position + size;
 
   // Tells whether the provided value fits into the bit field.
@@ -39,7 +43,6 @@
 
   // Returns an S with the bit field value encoded.
   static S encode(T value) {
-    COMPILE_ASSERT((sizeof(S) * kBitsPerByte) >= (position + size));
     ASSERT(is_valid(value));
     return static_cast<S>(value) << position;
   }
diff --git a/runtime/vm/bitmap.h b/runtime/vm/bitmap.h
index 40a589c..469153b 100644
--- a/runtime/vm/bitmap.h
+++ b/runtime/vm/bitmap.h
@@ -6,15 +6,11 @@
 #define RUNTIME_VM_BITMAP_H_
 
 #include "vm/allocation.h"
-#include "vm/isolate.h"
+#include "vm/thread_state.h"
 #include "vm/zone.h"
 
 namespace dart {
 
-// Forward declarations.
-class RawStackMap;
-class StackMap;
-
 // BitmapBuilder is used to build a bitmap. The implementation is optimized
 // for a dense set of small bit maps without a fixed upper bound (e.g: a
 // pointer map description of a stack).
@@ -23,7 +19,8 @@
   BitmapBuilder()
       : length_(0),
         data_size_in_bytes_(kInitialSizeInBytes),
-        data_(Thread::Current()->zone()->Alloc<uint8_t>(kInitialSizeInBytes)) {
+        data_(ThreadState::Current()->zone()->Alloc<uint8_t>(
+            kInitialSizeInBytes)) {
     memset(data_, 0, kInitialSizeInBytes);
   }
 
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index e02c6fa..a0e99e3 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -100,6 +100,11 @@
   library.set_native_entry_resolver(resolver);
   library.set_native_entry_symbol_resolver(symbol_resolver);
 
+  library = Library::FfiLibrary();
+  ASSERT(!library.IsNull());
+  library.set_native_entry_resolver(resolver);
+  library.set_native_entry_symbol_resolver(symbol_resolver);
+
   library = Library::InternalLibrary();
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 551784d..194a86c 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -350,7 +350,22 @@
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
   V(VMService_DecodeAssets, 1)                                                 \
-  V(VMService_spawnUriNotify, 2)
+  V(VMService_spawnUriNotify, 2)                                               \
+  V(Ffi_allocate, 1)                                                           \
+  V(Ffi_free, 1)                                                               \
+  V(Ffi_load, 1)                                                               \
+  V(Ffi_store, 2)                                                              \
+  V(Ffi_address, 1)                                                            \
+  V(Ffi_fromAddress, 1)                                                        \
+  V(Ffi_elementAt, 2)                                                          \
+  V(Ffi_offsetBy, 2)                                                           \
+  V(Ffi_cast, 1)                                                               \
+  V(Ffi_sizeOf, 0)                                                             \
+  V(Ffi_asFunction, 1)                                                         \
+  V(Ffi_fromFunction, 1)                                                       \
+  V(Ffi_dl_open, 1)                                                            \
+  V(Ffi_dl_lookup, 2)                                                          \
+  V(Ffi_dl_getHandle, 1)
 
 // List of bootstrap native entry points used in the dart:mirror library.
 #define MIRRORS_BOOTSTRAP_NATIVE_LIST(V)                                       \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 572175d..a60217b 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -172,8 +172,7 @@
 // b) after the user classes are loaded (dart_api).
 bool ClassFinalizer::ProcessPendingClasses() {
   Thread* thread = Thread::Current();
-  NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
-                                           "ProcessPendingClasses"));
+  TIMELINE_DURATION(thread, Isolate, "ProcessPendingClasses");
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   HANDLESCOPE(thread);
@@ -192,11 +191,13 @@
     class_array = object_store->pending_classes();
     ASSERT(!class_array.IsNull());
     Class& cls = Class::Handle();
-    // First check all superclasses.
+    // Mark all classes as cycle-free (should be checked by front-end).
+    // TODO(alexmarkov): Cleanup is_cycle_free bit on classes.
     for (intptr_t i = 0; i < class_array.Length(); i++) {
       cls ^= class_array.At(i);
-      GrowableArray<intptr_t> visited_interfaces;
-      CheckSuperTypeAndInterfaces(cls, &visited_interfaces);
+      if (!cls.is_cycle_free()) {
+        cls.set_is_cycle_free();
+      }
     }
     // Finalize all classes.
     for (intptr_t i = 0; i < class_array.Length(); i++) {
@@ -977,6 +978,30 @@
   }
 }
 
+// For a class used as an interface marks this class and all its superclasses
+// implemented.
+//
+// Does not mark its interfaces implemented because those would already be
+// marked as such.
+static void MarkImplemented(Zone* zone, const Class& iface) {
+  if (iface.is_implemented()) {
+    return;
+  }
+
+  Class& cls = Class::Handle(zone, iface.raw());
+  AbstractType& type = AbstractType::Handle(zone);
+
+  while (!cls.is_implemented()) {
+    cls.set_is_implemented();
+
+    type = cls.super_type();
+    if (type.IsNull() || type.IsObjectType()) {
+      break;
+    }
+    cls = type.type_class();
+  }
+}
+
 void ClassFinalizer::FinalizeTypesInClass(const Class& cls) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
@@ -986,12 +1011,6 @@
   if (FLAG_trace_class_finalization) {
     THR_Print("Finalize types in %s\n", cls.ToCString());
   }
-  if (!IsSuperCycleFree(cls)) {
-    const String& name = String::Handle(cls.Name());
-    ReportError(cls, cls.token_pos(),
-                "class '%s' has a cycle in its superclass relationship",
-                name.ToCString());
-  }
   // Finalize super class.
   Class& super_class = Class::Handle(cls.SuperClass());
   if (!super_class.IsNull()) {
@@ -1014,13 +1033,6 @@
     ASSERT(type.signature() == signature.raw());
     ASSERT(type.type_class() == cls.raw());
 
-    // Check for illegal self references.
-    GrowableArray<intptr_t> visited_aliases;
-    if (!IsTypedefCycleFree(cls, type, &visited_aliases)) {
-      const String& name = String::Handle(cls.Name());
-      ReportError(cls, cls.token_pos(),
-                  "typedef '%s' illegally refers to itself", name.ToCString());
-    }
     cls.set_is_type_finalized();
 
     // Finalize the result and parameter types of the signature
@@ -1048,35 +1060,10 @@
   // Finalize interface types (but not necessarily interface classes).
   Array& interface_types = Array::Handle(cls.interfaces());
   AbstractType& interface_type = AbstractType::Handle();
-  AbstractType& seen_interf = AbstractType::Handle();
   for (intptr_t i = 0; i < interface_types.Length(); i++) {
     interface_type ^= interface_types.At(i);
     interface_type = FinalizeType(cls, interface_type);
     interface_types.SetAt(i, interface_type);
-
-    // Check whether the interface is duplicated. We need to wait with
-    // this check until the super type and interface types are finalized,
-    // so that we can use Type::Equals() for the test.
-    // TODO(regis): This restriction about duplicated interfaces may get lifted.
-    ASSERT(interface_type.IsFinalized());
-    ASSERT(super_type.IsNull() || super_type.IsFinalized());
-    if (!super_type.IsNull() && interface_type.Equals(super_type)) {
-      ReportError(cls, cls.token_pos(),
-                  "super type '%s' may not be listed in "
-                  "implements clause of class '%s'",
-                  String::Handle(super_type.Name()).ToCString(),
-                  String::Handle(cls.Name()).ToCString());
-    }
-    for (intptr_t j = 0; j < i; j++) {
-      seen_interf ^= interface_types.At(j);
-      if (interface_type.Equals(seen_interf)) {
-        ReportError(cls, cls.token_pos(),
-                    "interface '%s' appears twice in "
-                    "implements clause of class '%s'",
-                    String::Handle(interface_type.Name()).ToCString(),
-                    String::Handle(cls.Name()).ToCString());
-      }
-    }
   }
   cls.set_is_type_finalized();
 
@@ -1091,10 +1078,15 @@
   // classes.
   Zone* zone = thread->zone();
   auto& interface_class = Class::Handle(zone);
+  const intptr_t mixin_index = cls.is_transformed_mixin_application()
+                                   ? interface_types.Length() - 1
+                                   : -1;
   for (intptr_t i = 0; i < interface_types.Length(); ++i) {
     interface_type ^= interface_types.At(i);
     interface_class = interface_type.type_class();
-    interface_class.AddDirectImplementor(cls);
+    MarkImplemented(thread->zone(), interface_class);
+    interface_class.AddDirectImplementor(cls,
+                                         /* is_mixin = */ i == mixin_index);
   }
 
   if (FLAG_use_cha_deopt) {
@@ -1109,33 +1101,34 @@
       interface_class.DisableCHAImplementorUsers();
     }
   }
-
-  // A top level class is loaded eagerly so just finalize it.
-  if (cls.IsTopLevel()) {
-    FinalizeClass(cls);
-  }
 }
 
 void ClassFinalizer::FinalizeClass(const Class& cls) {
-  Thread* thread = Thread::Current();
-  HANDLESCOPE(thread);
   ASSERT(cls.is_type_finalized());
   if (cls.is_finalized()) {
     return;
   }
+
+  Thread* thread = Thread::Current();
+  HANDLESCOPE(thread);
+
   if (FLAG_trace_class_finalization) {
     THR_Print("Finalize %s\n", cls.ToCString());
   }
 
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
   TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
-                            "ClassFinalizer::FinalizeClass");
-#endif  // !defined(PRODUCT)
+                            "FinalizeClass");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(0, "class", cls.ToCString());
+  }
+#endif  // defined(SUPPORT_TIMELINE)
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // If loading from a kernel, make sure that the class is fully loaded.
-  // Top level classes are always fully loaded.
-  if (!cls.IsTopLevel() && cls.kernel_offset() > 0) {
+  ASSERT(cls.IsTopLevel() || (cls.kernel_offset() > 0));
+  if (!cls.is_loaded()) {
     kernel::KernelLoader::FinishLoading(cls);
     if (cls.is_finalized()) {
       return;
@@ -1169,9 +1162,6 @@
          cls.is_abstract() || (Array::Handle(cls.functions()).Length() > 0));
   FinalizeMemberTypes(cls);
   // Run additional checks after all types are finalized.
-  if (cls.is_const()) {
-    CheckForLegalConstClass(cls);
-  }
   if (FLAG_use_cha_deopt) {
     GrowableArray<intptr_t> cids;
     CollectFinalizedSuperClasses(cls, &cids);
@@ -1186,10 +1176,6 @@
 
 RawError* ClassFinalizer::LoadClassMembers(const Class& cls) {
   ASSERT(Thread::Current()->IsMutatorThread());
-  // If class is a top level class it is already loaded.
-  if (cls.IsTopLevel()) {
-    return Error::null();
-  }
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     ClassFinalizer::FinalizeClass(cls);
@@ -1304,306 +1290,6 @@
   }
 }
 
-bool ClassFinalizer::IsSuperCycleFree(const Class& cls) {
-  Class& test1 = Class::Handle(cls.raw());
-  Class& test2 = Class::Handle(cls.SuperClass());
-  // A finalized class has been checked for cycles.
-  // Using the hare and tortoise algorithm for locating cycles.
-  while (!test1.is_type_finalized() && !test2.IsNull() &&
-         !test2.is_type_finalized()) {
-    if (test1.raw() == test2.raw()) {
-      // Found a cycle.
-      return false;
-    }
-    test1 = test1.SuperClass();
-    test2 = test2.SuperClass();
-    if (!test2.IsNull()) {
-      test2 = test2.SuperClass();
-    }
-  }
-  // No cycles.
-  return true;
-}
-
-// Returns false if a function type alias illegally refers to itself.
-bool ClassFinalizer::IsTypedefCycleFree(const Class& cls,
-                                        const AbstractType& type,
-                                        GrowableArray<intptr_t>* visited) {
-  ASSERT(visited != NULL);
-  bool checking_typedef = false;
-  if (type.IsType()) {
-    AbstractType& other_type = AbstractType::Handle();
-    if (type.IsFunctionType()) {
-      const Class& scope_class = Class::Handle(type.type_class());
-      const Function& signature_function =
-          Function::Handle(Type::Cast(type).signature());
-      // The signature function of this function type may be a local signature
-      // function used in a formal parameter type of the typedef signature, but
-      // not the typedef signature function itself, thus not qualifying as an
-      // illegal self reference.
-      if (!scope_class.is_type_finalized() && scope_class.IsTypedefClass() &&
-          (scope_class.signature_function() == signature_function.raw())) {
-        checking_typedef = true;
-        const intptr_t scope_class_id = scope_class.id();
-        ASSERT(visited != NULL);
-        for (intptr_t i = 0; i < visited->length(); i++) {
-          if ((*visited)[i] == scope_class_id) {
-            // We have already visited alias 'scope_class'. We found a cycle.
-            return false;
-          }
-        }
-        visited->Add(scope_class_id);
-      }
-      // Check the bounds of this function type.
-      const intptr_t num_type_params = scope_class.NumTypeParameters();
-      TypeParameter& type_param = TypeParameter::Handle();
-      const TypeArguments& type_params =
-          TypeArguments::Handle(scope_class.type_parameters());
-      ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
-             (type_params.Length() == num_type_params));
-      for (intptr_t i = 0; i < num_type_params; i++) {
-        type_param ^= type_params.TypeAt(i);
-        other_type = type_param.bound();
-        if (!IsTypedefCycleFree(cls, other_type, visited)) {
-          return false;
-        }
-      }
-      // Check the result type of the signature of this function type.
-      other_type = signature_function.result_type();
-      if (!IsTypedefCycleFree(cls, other_type, visited)) {
-        return false;
-      }
-      // Check the parameter types of the signature of this function type.
-      const intptr_t num_parameters = signature_function.NumParameters();
-      for (intptr_t i = 0; i < num_parameters; i++) {
-        other_type = signature_function.ParameterTypeAt(i);
-        if (!IsTypedefCycleFree(cls, other_type, visited)) {
-          return false;
-        }
-      }
-    }
-    const TypeArguments& type_args = TypeArguments::Handle(type.arguments());
-    if (!type_args.IsNull()) {
-      for (intptr_t i = 0; i < type_args.Length(); i++) {
-        other_type = type_args.TypeAt(i);
-        if (!IsTypedefCycleFree(cls, other_type, visited)) {
-          return false;
-        }
-      }
-    }
-    if (checking_typedef) {
-      visited->RemoveLast();
-    }
-  }
-  return true;
-}
-
-// For a class used as an interface marks this class and all its superclasses
-// implemented.
-//
-// Does not mark its interfaces implemented because those would already be
-// marked as such.
-static void MarkImplemented(Zone* zone, const Class& iface) {
-  if (iface.is_implemented()) {
-    return;
-  }
-
-  Class& cls = Class::Handle(zone, iface.raw());
-  AbstractType& type = AbstractType::Handle(zone);
-
-  while (!cls.is_implemented()) {
-    cls.set_is_implemented();
-
-    type = cls.super_type();
-    if (type.IsNull() || type.IsObjectType()) {
-      break;
-    }
-    cls = type.type_class();
-  }
-}
-
-// Recursively walks the graph of explicitly declared super type and
-// interfaces.
-// Reports an error if there is a cycle in the graph. We detect cycles by
-// remembering interfaces we've visited in each path through the
-// graph. If we visit an interface a second time on a given path,
-// we found a loop.
-void ClassFinalizer::CheckSuperTypeAndInterfaces(
-    const Class& cls,
-    GrowableArray<intptr_t>* visited) {
-  if (cls.is_cycle_free()) {
-    return;
-  }
-  ASSERT(visited != NULL);
-  if (FLAG_trace_class_finalization) {
-    THR_Print("Checking super and interfaces: %s\n", cls.ToCString());
-  }
-  Zone* zone = Thread::Current()->zone();
-  const intptr_t cls_index = cls.id();
-  for (intptr_t i = 0; i < visited->length(); i++) {
-    if ((*visited)[i] == cls_index) {
-      // We have already visited class 'cls'. We found a cycle.
-      const String& class_name = String::Handle(zone, cls.Name());
-      ReportError(cls, cls.token_pos(), "cyclic reference found for class '%s'",
-                  class_name.ToCString());
-    }
-  }
-
-  // If the class/interface has no explicit super class/interfaces, we are done.
-  AbstractType& super_type = AbstractType::Handle(zone, cls.super_type());
-  Array& super_interfaces = Array::Handle(zone, cls.interfaces());
-  if ((super_type.IsNull() || super_type.IsObjectType()) &&
-      (super_interfaces.Length() == 0)) {
-    cls.set_is_cycle_free();
-    return;
-  }
-
-  // If cls belongs to core lib or is a synthetic class which could belong to
-  // the core library, the restrictions about allowed interfaces are lifted.
-  const bool exempt_from_hierarchy_restrictions =
-      cls.library() == Library::CoreLibrary() ||
-      String::Handle(cls.Name()).Equals(Symbols::DebugClassName());
-
-  // Check the super type and interfaces of cls.
-  visited->Add(cls_index);
-  AbstractType& interface = AbstractType::Handle(zone);
-  Class& interface_class = Class::Handle(zone);
-
-  // Check super type. Failures lead to a longjmp.
-  if (super_type.IsDynamicType()) {
-    ReportError(cls, cls.token_pos(), "class '%s' may not extend 'dynamic'",
-                String::Handle(zone, cls.Name()).ToCString());
-  }
-  interface_class = super_type.type_class();
-  if (interface_class.IsTypedefClass()) {
-    ReportError(cls, cls.token_pos(),
-                "class '%s' may not extend function type alias '%s'",
-                String::Handle(zone, cls.Name()).ToCString(),
-                String::Handle(zone, super_type.UserVisibleName()).ToCString());
-  }
-  if (interface_class.is_enum_class()) {
-    ReportError(cls, cls.token_pos(), "class '%s' may not extend enum '%s'",
-                String::Handle(zone, cls.Name()).ToCString(),
-                String::Handle(zone, interface_class.Name()).ToCString());
-  }
-
-  // If cls belongs to core lib or to core lib's implementation, restrictions
-  // about allowed interfaces are lifted.
-  if (!exempt_from_hierarchy_restrictions) {
-    // Prevent extending core implementation classes.
-    bool is_error = false;
-    switch (interface_class.id()) {
-      case kNumberCid:
-      case kIntegerCid:  // Class Integer, not int.
-      case kSmiCid:
-      case kMintCid:
-      case kDoubleCid:  // Class Double, not double.
-      case kOneByteStringCid:
-      case kTwoByteStringCid:
-      case kExternalOneByteStringCid:
-      case kExternalTwoByteStringCid:
-      case kBoolCid:
-      case kNullCid:
-      case kArrayCid:
-      case kImmutableArrayCid:
-      case kGrowableObjectArrayCid:
-#define DO_NOT_EXTEND_TYPED_DATA_CLASSES(clazz)                                \
-  case kTypedData##clazz##Cid:                                                 \
-  case kTypedData##clazz##ViewCid:                                             \
-  case kExternalTypedData##clazz##Cid:
-        CLASS_LIST_TYPED_DATA(DO_NOT_EXTEND_TYPED_DATA_CLASSES)
-#undef DO_NOT_EXTEND_TYPED_DATA_CLASSES
-      case kByteDataViewCid:
-      case kWeakPropertyCid:
-        is_error = true;
-        break;
-      default: {
-        // Special case: classes for which we don't have a known class id.
-        if (super_type.IsDoubleType() || super_type.IsIntType() ||
-            super_type.IsStringType()) {
-          is_error = true;
-        }
-        break;
-      }
-    }
-    if (is_error) {
-      const String& interface_name =
-          String::Handle(zone, interface_class.Name());
-      ReportError(cls, cls.token_pos(), "'%s' is not allowed to extend '%s'",
-                  String::Handle(zone, cls.Name()).ToCString(),
-                  interface_name.ToCString());
-    }
-  }
-  // Now check the super interfaces of the super type.
-  CheckSuperTypeAndInterfaces(interface_class, visited);
-
-  // Check interfaces. Failures lead to a longjmp.
-  for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
-    interface ^= super_interfaces.At(i);
-    ASSERT(!interface.IsTypeParameter());  // Should be detected by parser.
-    if (interface.IsDynamicType()) {
-      ReportError(cls, cls.token_pos(),
-                  "'dynamic' may not be used as interface");
-    }
-    interface_class = interface.type_class();
-    if (interface_class.IsTypedefClass()) {
-      const String& interface_name =
-          String::Handle(zone, interface_class.Name());
-      ReportError(cls, cls.token_pos(),
-                  "function type alias '%s' may not be used as interface",
-                  interface_name.ToCString());
-    }
-    if (interface_class.is_enum_class()) {
-      const String& interface_name =
-          String::Handle(zone, interface_class.Name());
-      ReportError(cls, cls.token_pos(),
-                  "enum '%s' may not be used as interface",
-                  interface_name.ToCString());
-    }
-    // Verify that unless cls belongs to core lib, it cannot extend, implement,
-    // or mixin any of Null, bool, num, int, double, String, dynamic.
-    if (!exempt_from_hierarchy_restrictions) {
-      if (interface.IsBoolType() || interface.IsNullType() ||
-          interface.IsNumberType() || interface.IsIntType() ||
-          interface.IsDoubleType() || interface.IsStringType() ||
-          interface.IsDynamicType()) {
-        const String& interface_name =
-            String::Handle(zone, interface_class.Name());
-        ReportError(cls, cls.token_pos(),
-                    "'%s' is not allowed to extend or implement '%s'",
-                    String::Handle(zone, cls.Name()).ToCString(),
-                    interface_name.ToCString());
-      }
-    }
-
-    // Now check the super interfaces.
-    CheckSuperTypeAndInterfaces(interface_class, visited);
-    MarkImplemented(zone, interface_class);
-  }
-  visited->RemoveLast();
-  cls.set_is_cycle_free();
-}
-
-// A class is marked as constant if it has one constant constructor.
-// A constant class can only have final instance fields.
-// Note: we must check for cycles before checking for const properties.
-void ClassFinalizer::CheckForLegalConstClass(const Class& cls) {
-  ASSERT(cls.is_const());
-  const Array& fields_array = Array::Handle(cls.fields());
-  intptr_t len = fields_array.Length();
-  Field& field = Field::Handle();
-  for (intptr_t i = 0; i < len; i++) {
-    field ^= fields_array.At(i);
-    if (!field.is_static() && !field.is_final()) {
-      const String& class_name = String::Handle(cls.Name());
-      const String& field_name = String::Handle(field.name());
-      ReportError(cls, field.token_pos(),
-                  "const class '%s' has non-final field '%s'",
-                  class_name.ToCString(), field_name.ToCString());
-    }
-  }
-}
-
 void ClassFinalizer::PrintClassInformation(const Class& cls) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
@@ -1699,6 +1385,7 @@
   String& name = String::Handle(zone);
   String& expected_name = String::Handle(zone);
   Error& error = Error::Handle(zone);
+  TypeParameter& type_param = TypeParameter::Handle(zone);
 
   // First verify field offsets of all the TypedDataView classes.
   for (intptr_t cid = kTypedDataInt8ArrayViewCid;
@@ -1757,6 +1444,15 @@
   name ^= field.name();
   expected_name ^= String::New("_data");
   ASSERT(String::EqualsIgnoringPrivateKey(name, expected_name));
+
+  // Now verify field offsets of 'Pointer' class.
+  cls = class_table.At(kFfiPointerCid);
+  error = cls.EnsureIsFinalized(thread);
+  ASSERT(error.IsNull());
+  ASSERT(cls.NumOwnTypeArguments() == 1);
+  type_param ^= TypeParameter::RawCast(
+      TypeArguments::Handle(cls.type_parameters()).TypeAt(0));
+  ASSERT(Pointer::kNativeTypeArgPos == type_param.index());
 #endif
 }
 
@@ -1764,6 +1460,11 @@
   Thread* T = Thread::Current();
   Zone* Z = T->zone();
   Isolate* I = T->isolate();
+
+  // Prevent background compiler from adding deferred classes or canonicalizing
+  // new types while classes are being sorted and type hashes are modified.
+  BackgroundCompiler::Stop(I);
+
   ClassTable* table = I->class_table();
   intptr_t num_cids = table->NumCids();
   intptr_t* old_to_new_cid = new intptr_t[num_cids];
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index a720aa0..91292e9 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -74,13 +74,6 @@
 
  private:
   static void AllocateEnumValues(const Class& enum_cls);
-  static bool IsSuperCycleFree(const Class& cls);
-  static bool IsTypedefCycleFree(const Class& cls,
-                                 const AbstractType& type,
-                                 GrowableArray<intptr_t>* visited);
-  static void CheckForLegalConstClass(const Class& cls);
-  static void CheckSuperTypeAndInterfaces(const Class& cls,
-                                          GrowableArray<intptr_t>* visited);
   static void FinalizeTypeParameters(const Class& cls,
                                      PendingTypes* pending_types = NULL);
   static intptr_t ExpandAndFinalizeTypeArguments(const Class& cls,
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 42fee86..a1440d2 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -51,23 +51,4 @@
   EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
 
-ISOLATE_UNIT_TEST_CASE(ClassFinalize_Cycles) {
-  Zone* zone = thread->zone();
-  Isolate* isolate = thread->isolate();
-  ObjectStore* object_store = isolate->object_store();
-  const GrowableObjectArray& pending_classes =
-      GrowableObjectArray::Handle(zone, object_store->pending_classes());
-  GrowableArray<const Class*> classes;
-  classes.Add(&Class::Handle(CreateTestClass("Jungfrau")));
-  pending_classes.Add(*classes[0]);
-  classes.Add(&Class::Handle(CreateTestClass("Eiger")));
-  pending_classes.Add(*classes[1]);
-  // Create a cycle.
-  classes[0]->set_super_type(
-      Type::Handle(Type::NewNonParameterizedType(*classes[1])));
-  classes[1]->set_super_type(
-      Type::Handle(Type::NewNonParameterizedType(*classes[0])));
-  EXPECT(!ClassFinalizer::ProcessPendingClasses());
-}
-
 }  // namespace dart
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
new file mode 100644
index 0000000..ddbd7a0
--- /dev/null
+++ b/runtime/vm/class_id.h
@@ -0,0 +1,212 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_CLASS_ID_H_
+#define RUNTIME_VM_CLASS_ID_H_
+
+// This header defines the list of VM implementation classes and their ids.
+//
+// Note: we assume that all builds of Dart VM use exactly the same class ids
+// for these classes.
+
+namespace dart {
+
+#define CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                           \
+  V(Class)                                                                     \
+  V(PatchClass)                                                                \
+  V(Function)                                                                  \
+  V(ClosureData)                                                               \
+  V(SignatureData)                                                             \
+  V(RedirectionData)                                                           \
+  V(FfiTrampolineData)                                                         \
+  V(Field)                                                                     \
+  V(Script)                                                                    \
+  V(Library)                                                                   \
+  V(Namespace)                                                                 \
+  V(KernelProgramInfo)                                                         \
+  V(Code)                                                                      \
+  V(Bytecode)                                                                  \
+  V(Instructions)                                                              \
+  V(ObjectPool)                                                                \
+  V(PcDescriptors)                                                             \
+  V(CodeSourceMap)                                                             \
+  V(StackMap)                                                                  \
+  V(LocalVarDescriptors)                                                       \
+  V(ExceptionHandlers)                                                         \
+  V(Context)                                                                   \
+  V(ContextScope)                                                              \
+  V(SingleTargetCache)                                                         \
+  V(UnlinkedCall)                                                              \
+  V(ICData)                                                                    \
+  V(MegamorphicCache)                                                          \
+  V(SubtypeTestCache)                                                          \
+  V(Error)                                                                     \
+  V(ApiError)                                                                  \
+  V(LanguageError)                                                             \
+  V(UnhandledException)                                                        \
+  V(UnwindError)                                                               \
+  V(Instance)                                                                  \
+  V(LibraryPrefix)                                                             \
+  V(TypeArguments)                                                             \
+  V(AbstractType)                                                              \
+  V(Type)                                                                      \
+  V(TypeRef)                                                                   \
+  V(TypeParameter)                                                             \
+  V(Closure)                                                                   \
+  V(Number)                                                                    \
+  V(Integer)                                                                   \
+  V(Smi)                                                                       \
+  V(Mint)                                                                      \
+  V(Double)                                                                    \
+  V(Bool)                                                                      \
+  V(GrowableObjectArray)                                                       \
+  V(Float32x4)                                                                 \
+  V(Int32x4)                                                                   \
+  V(Float64x2)                                                                 \
+  V(TypedData)                                                                 \
+  V(ExternalTypedData)                                                         \
+  V(Pointer)                                                                   \
+  V(DynamicLibrary)                                                            \
+  V(Capability)                                                                \
+  V(ReceivePort)                                                               \
+  V(SendPort)                                                                  \
+  V(StackTrace)                                                                \
+  V(RegExp)                                                                    \
+  V(WeakProperty)                                                              \
+  V(MirrorReference)                                                           \
+  V(LinkedHashMap)                                                             \
+  V(UserTag)
+
+#define CLASS_LIST_ARRAYS(V)                                                   \
+  V(Array)                                                                     \
+  V(ImmutableArray)
+
+#define CLASS_LIST_STRINGS(V)                                                  \
+  V(String)                                                                    \
+  V(OneByteString)                                                             \
+  V(TwoByteString)                                                             \
+  V(ExternalOneByteString)                                                     \
+  V(ExternalTwoByteString)
+
+#define CLASS_LIST_TYPED_DATA(V)                                               \
+  V(Int8Array)                                                                 \
+  V(Uint8Array)                                                                \
+  V(Uint8ClampedArray)                                                         \
+  V(Int16Array)                                                                \
+  V(Uint16Array)                                                               \
+  V(Int32Array)                                                                \
+  V(Uint32Array)                                                               \
+  V(Int64Array)                                                                \
+  V(Uint64Array)                                                               \
+  V(Float32Array)                                                              \
+  V(Float64Array)                                                              \
+  V(Float32x4Array)                                                            \
+  V(Int32x4Array)                                                              \
+  V(Float64x2Array)
+
+#define CLASS_LIST_FFI_TYPE_MARKER(V)                                          \
+  V(Int8)                                                                      \
+  V(Int16)                                                                     \
+  V(Int32)                                                                     \
+  V(Int64)                                                                     \
+  V(Uint8)                                                                     \
+  V(Uint16)                                                                    \
+  V(Uint32)                                                                    \
+  V(Uint64)                                                                    \
+  V(IntPtr)                                                                    \
+  V(Float)                                                                     \
+  V(Double)                                                                    \
+  V(Void)
+
+#define CLASS_LIST_FFI(V)                                                      \
+  V(Pointer)                                                                   \
+  V(NativeFunction)                                                            \
+  CLASS_LIST_FFI_TYPE_MARKER(V)                                                \
+  V(NativeType)                                                                \
+  V(DynamicLibrary)
+
+#define DART_CLASS_LIST_TYPED_DATA(V)                                          \
+  V(Int8)                                                                      \
+  V(Uint8)                                                                     \
+  V(Uint8Clamped)                                                              \
+  V(Int16)                                                                     \
+  V(Uint16)                                                                    \
+  V(Int32)                                                                     \
+  V(Uint32)                                                                    \
+  V(Int64)                                                                     \
+  V(Uint64)                                                                    \
+  V(Float32)                                                                   \
+  V(Float64)                                                                   \
+  V(Float32x4)                                                                 \
+  V(Int32x4)                                                                   \
+  V(Float64x2)
+
+#define CLASS_LIST_FOR_HANDLES(V)                                              \
+  CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                                 \
+  V(Array)                                                                     \
+  V(String)
+
+#define CLASS_LIST_NO_OBJECT(V)                                                \
+  CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                                 \
+  CLASS_LIST_ARRAYS(V)                                                         \
+  CLASS_LIST_STRINGS(V)
+
+#define CLASS_LIST(V)                                                          \
+  V(Object)                                                                    \
+  CLASS_LIST_NO_OBJECT(V)
+
+enum ClassId {
+  // Illegal class id.
+  kIllegalCid = 0,
+
+  // A sentinel used by the vm service's heap snapshots to represent references
+  // from the stack.
+  kStackCid = 1,
+
+  // The following entries describes classes for pseudo-objects in the heap
+  // that should never be reachable from live objects. Free list elements
+  // maintain the free list for old space, and forwarding corpses are used to
+  // implement one-way become.
+  kFreeListElement,
+  kForwardingCorpse,
+
+// List of Ids for predefined classes.
+#define DEFINE_OBJECT_KIND(clazz) k##clazz##Cid,
+  CLASS_LIST(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
+#define DEFINE_OBJECT_KIND(clazz) kFfi##clazz##Cid,
+      CLASS_LIST_FFI(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
+// clang-format off
+#define DEFINE_OBJECT_KIND(clazz) kTypedData##clazz##Cid,
+  CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
+#define DEFINE_OBJECT_KIND(clazz) kTypedData##clazz##ViewCid,
+  CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
+  kByteDataViewCid,
+
+#define DEFINE_OBJECT_KIND(clazz) kExternalTypedData##clazz##Cid,
+  CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
+#undef DEFINE_OBJECT_KIND
+
+  kByteBufferCid,
+  // clang-format on
+
+  // The following entries do not describe a predefined class, but instead
+  // are class indexes for pre-allocated instances (Null, dynamic and Void).
+  kNullCid,
+  kDynamicCid,
+  kVoidCid,
+
+  kNumPredefinedCids,
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_CLASS_ID_H_
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 21ea84d..6da5677 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -205,11 +205,9 @@
   }
 }
 
-#if defined(DEBUG)
 void ClassTable::Unregister(intptr_t index) {
   table_[index] = ClassAndSize(NULL);
 }
-#endif
 
 void ClassTable::Remap(intptr_t* old_to_new_cid) {
   ASSERT(Thread::Current()->IsAtSafepoint());
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index b87d242..bbf55b9 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -226,9 +226,7 @@
 
   void AllocateIndex(intptr_t index);
 
-#if defined(DEBUG)
   void Unregister(intptr_t index);
-#endif
 
   void Remap(intptr_t* old_to_new_cids);
 
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 779e9fe..2f07321 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -69,10 +69,6 @@
   return RawObject::FromAddr(address);
 }
 
-static bool SnapshotContainsTypeTestingStubs(Snapshot::Kind kind) {
-  return kind == Snapshot::kFullAOT || kind == Snapshot::kFullJIT;
-}
-
 void Deserializer::InitializeHeader(RawObject* raw,
                                     intptr_t class_id,
                                     intptr_t size,
@@ -597,9 +593,6 @@
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadFunction"));
-
     if (kind == Snapshot::kFullAOT) {
       Function& func = Function::Handle(zone);
       for (intptr_t i = start_index_; i < stop_index_; i++) {
@@ -883,16 +876,16 @@
         s->Push(field->ptr()->value_.static_value_);
       } else {
         // Otherwise, for static fields we write out the initial static value.
-        s->Push(field->ptr()->initializer_.saved_value_);
+        s->Push(field->ptr()->saved_initial_value_);
       }
     } else {
       s->Push(field->ptr()->value_.offset_);
     }
-    // Write out the initializer function or saved initial value.
-    if (kind == Snapshot::kFullAOT) {
-      s->Push(field->ptr()->initializer_.precompiled_);
-    } else {
-      s->Push(field->ptr()->initializer_.saved_value_);
+    // Write out the initializer function
+    s->Push(field->ptr()->initializer_);
+    if (kind != Snapshot::kFullAOT) {
+      // Write out the saved initial value
+      s->Push(field->ptr()->saved_initial_value_);
     }
     if (kind != Snapshot::kFullAOT) {
       // Write out the guarded list length.
@@ -934,16 +927,15 @@
           WriteField(field, value_.static_value_);
         } else {
           // Otherwise, for static fields we write out the initial static value.
-          WriteField(field, initializer_.saved_value_);
+          WriteField(field, saved_initial_value_);
         }
       } else {
         WriteField(field, value_.offset_);
       }
       // Write out the initializer function or saved initial value.
-      if (kind == Snapshot::kFullAOT) {
-        WriteField(field, initializer_.precompiled_);
-      } else {
-        WriteField(field, initializer_.saved_value_);
+      WriteField(field, initializer_);
+      if (kind != Snapshot::kFullAOT) {
+        WriteField(field, saved_initial_value_);
       }
       if (kind != Snapshot::kFullAOT) {
         // Write out the guarded list length.
@@ -1011,9 +1003,6 @@
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadField"));
-
     Field& field = Field::Handle(zone);
     if (!Isolate::Current()->use_field_guards()) {
       for (intptr_t i = start_index_; i < stop_index_; i++) {
@@ -1061,7 +1050,7 @@
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawScript* script = objects_[i];
-      AutoTraceObject(script);
+      AutoTraceObjectName(script, script->ptr()->url_);
       WriteFromTo(script);
       s->Write<int32_t>(script->ptr()->line_offset_);
       s->Write<int32_t>(script->ptr()->col_offset_);
@@ -1138,7 +1127,6 @@
       s->Write<int32_t>(lib->ptr()->index_);
       s->Write<uint16_t>(lib->ptr()->num_imports_);
       s->Write<int8_t>(lib->ptr()->load_state_);
-      s->Write<bool>(lib->ptr()->corelib_imported_);
       s->Write<bool>(lib->ptr()->is_dart_scheme_);
       s->Write<bool>(lib->ptr()->debuggable_);
       if (s->kind() != Snapshot::kFullAOT) {
@@ -1180,7 +1168,6 @@
       lib->ptr()->index_ = d->Read<int32_t>();
       lib->ptr()->num_imports_ = d->Read<uint16_t>();
       lib->ptr()->load_state_ = d->Read<int8_t>();
-      lib->ptr()->corelib_imported_ = d->Read<bool>();
       lib->ptr()->is_dart_scheme_ = d->Read<bool>();
       lib->ptr()->debuggable_ = d->Read<bool>();
       lib->ptr()->is_in_fullsnapshot_ = true;
@@ -1325,14 +1312,14 @@
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    Array& array_ = Array::Handle(zone);
-    KernelProgramInfo& info_ = KernelProgramInfo::Handle(zone);
+    Array& array = Array::Handle(zone);
+    KernelProgramInfo& info = KernelProgramInfo::Handle(zone);
     for (intptr_t id = start_index_; id < stop_index_; id++) {
-      info_ ^= refs.At(id);
-      array_ = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
-      info_.set_libraries_cache(array_);
-      array_ = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
-      info_.set_classes_cache(array_);
+      info ^= refs.At(id);
+      array = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
+      info.set_libraries_cache(array);
+      array = HashTables::New<UnorderedHashMap<SmiTraits>>(16, Heap::kOld);
+      info.set_classes_cache(array);
     }
   }
 };
@@ -1586,7 +1573,9 @@
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawBytecode* bytecode = objects_[i];
+      s->Write<int32_t>(bytecode->ptr()->instructions_size_);
       WriteFromTo(bytecode);
+      s->Write<int32_t>(bytecode->ptr()->instructions_binary_offset_);
       s->Write<int32_t>(bytecode->ptr()->source_positions_binary_offset_);
     }
   }
@@ -1618,10 +1607,25 @@
       RawBytecode* bytecode = reinterpret_cast<RawBytecode*>(d->Ref(id));
       Deserializer::InitializeHeader(bytecode, kBytecodeCid,
                                      Bytecode::InstanceSize(), is_vm_object);
+      bytecode->ptr()->instructions_ = 0;
+      bytecode->ptr()->instructions_size_ = d->Read<int32_t>();
       ReadFromTo(bytecode);
+      bytecode->ptr()->instructions_binary_offset_ = d->Read<int32_t>();
       bytecode->ptr()->source_positions_binary_offset_ = d->Read<int32_t>();
     }
   }
+
+  void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
+    Bytecode& bytecode = Bytecode::Handle(zone);
+    ExternalTypedData& binary = ExternalTypedData::Handle(zone);
+
+    for (intptr_t i = start_index_; i < stop_index_; i++) {
+      bytecode ^= refs.At(i);
+      binary = bytecode.GetBinary(zone);
+      bytecode.set_instructions(reinterpret_cast<uword>(
+          binary.DataAddr(bytecode.instructions_binary_offset())));
+    }
+  }
 };
 
 class ObjectPoolSerializationCluster : public SerializationCluster {
@@ -1637,8 +1641,8 @@
     uint8_t* entry_bits = pool->ptr()->entry_bits();
     for (intptr_t i = 0; i < length; i++) {
       auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
-      if ((entry_type == ObjectPool::kTaggedObject) ||
-          (entry_type == ObjectPool::kNativeEntryData)) {
+      if ((entry_type == ObjectPool::EntryType::kTaggedObject) ||
+          (entry_type == ObjectPool::EntryType::kNativeEntryData)) {
         s->Push(pool->ptr()->data()[i].raw_obj_);
       }
     }
@@ -1669,7 +1673,7 @@
         s->Write<uint8_t>(entry_bits[j]);
         RawObjectPool::Entry& entry = pool->ptr()->data()[j];
         switch (ObjectPool::TypeBits::decode(entry_bits[j])) {
-          case ObjectPool::kTaggedObject: {
+          case ObjectPool::EntryType::kTaggedObject: {
 #if !defined(TARGET_ARCH_DBC)
             if ((entry.raw_obj_ == StubCode::CallNoScopeNative().raw()) ||
                 (entry.raw_obj_ == StubCode::CallAutoScopeNative().raw())) {
@@ -1683,11 +1687,11 @@
             s->WriteElementRef(entry.raw_obj_, j);
             break;
           }
-          case ObjectPool::kImmediate: {
+          case ObjectPool::EntryType::kImmediate: {
             s->Write<intptr_t>(entry.raw_value_);
             break;
           }
-          case ObjectPool::kNativeEntryData: {
+          case ObjectPool::EntryType::kNativeEntryData: {
             RawObject* raw = entry.raw_obj_;
             RawTypedData* raw_data = reinterpret_cast<RawTypedData*>(raw);
             // kNativeEntryData object pool entries are for linking natives for
@@ -1703,8 +1707,8 @@
             s->WriteElementRef(raw, j);
             break;
           }
-          case ObjectPool::kNativeFunction:
-          case ObjectPool::kNativeFunctionWrapper: {
+          case ObjectPool::EntryType::kNativeFunction:
+          case ObjectPool::EntryType::kNativeFunctionWrapper: {
             // Write nothing. Will initialize with the lazy link entry.
             break;
           }
@@ -1750,21 +1754,21 @@
         pool->ptr()->entry_bits()[j] = entry_bits;
         RawObjectPool::Entry& entry = pool->ptr()->data()[j];
         switch (ObjectPool::TypeBits::decode(entry_bits)) {
-          case ObjectPool::kNativeEntryData:
-          case ObjectPool::kTaggedObject:
+          case ObjectPool::EntryType::kNativeEntryData:
+          case ObjectPool::EntryType::kTaggedObject:
             entry.raw_obj_ = d->ReadRef();
             break;
-          case ObjectPool::kImmediate:
+          case ObjectPool::EntryType::kImmediate:
             entry.raw_value_ = d->Read<intptr_t>();
             break;
-          case ObjectPool::kNativeFunction: {
+          case ObjectPool::EntryType::kNativeFunction: {
             // Read nothing. Initialize with the lazy link entry.
             uword new_entry = NativeEntry::LinkNativeCallEntry();
             entry.raw_value_ = static_cast<intptr_t>(new_entry);
             break;
           }
 #if defined(TARGET_ARCH_DBC)
-          case ObjectPool::kNativeFunctionWrapper: {
+          case ObjectPool::EntryType::kNativeFunctionWrapper: {
             // Read nothing. Initialize with the lazy link entry.
             uword new_entry = NativeEntry::BootstrapNativeCallWrapperEntry();
             entry.raw_value_ = static_cast<intptr_t>(new_entry);
@@ -2157,7 +2161,7 @@
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawUnlinkedCall* unlinked = objects_[i];
-      AutoTraceObject(unlinked);
+      AutoTraceObjectName(unlinked, unlinked->ptr()->target_name_);
       WriteFromTo(unlinked);
     }
   }
@@ -2224,15 +2228,12 @@
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawICData* ic = objects_[i];
-      AutoTraceObject(ic);
+      AutoTraceObjectName(ic, ic->ptr()->target_name_);
       WriteFromTo(ic);
       if (kind != Snapshot::kFullAOT) {
         NOT_IN_PRECOMPILED(s->Write<int32_t>(ic->ptr()->deopt_id_));
       }
       s->Write<uint32_t>(ic->ptr()->state_bits_);
-#if defined(TAG_IC_DATA)
-      s->Write<int32_t>(static_cast<int32_t>(ic->ptr()->tag_));
-#endif
     }
   }
 
@@ -2266,9 +2267,6 @@
       ReadFromTo(ic);
       NOT_IN_PRECOMPILED(ic->ptr()->deopt_id_ = d->Read<int32_t>());
       ic->ptr()->state_bits_ = d->Read<int32_t>();
-#if defined(TAG_IC_DATA)
-      ic->ptr()->tag_ = static_cast<ICData::Tag>(d->Read<int32_t>());
-#endif
     }
   }
 };
@@ -2300,7 +2298,7 @@
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawMegamorphicCache* cache = objects_[i];
-      AutoTraceObject(cache);
+      AutoTraceObjectName(cache, cache->ptr()->target_name_);
       WriteFromTo(cache);
       s->Write<int32_t>(cache->ptr()->filled_entry_count_);
     }
@@ -2766,8 +2764,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeSerializationCluster : public SerializationCluster {
  public:
-  explicit TypeSerializationCluster(const TypeTestingStubFinder& ttsf)
-      : SerializationCluster("Type"), type_testing_stubs_(ttsf) {}
+  TypeSerializationCluster() : SerializationCluster("Type") {}
   ~TypeSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -2808,10 +2805,6 @@
   }
 
   void WriteFill(Serializer* s) {
-    const bool is_vm_isolate = s->isolate() == Dart::vm_isolate();
-    const bool should_write_type_testing_stub =
-        SnapshotContainsTypeTestingStubs(s->kind());
-
     intptr_t count = canonical_objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawType* type = canonical_objects_[i];
@@ -2819,11 +2812,6 @@
       WriteFromTo(type);
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int8_t>(type->ptr()->type_state_);
-      if (should_write_type_testing_stub) {
-        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
-            type->ptr()->type_test_stub_entry_point_);
-        s->WriteInstructions(instr, Code::null());
-      }
     }
     count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
@@ -2832,37 +2820,18 @@
       WriteFromTo(type);
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int8_t>(type->ptr()->type_state_);
-      if (should_write_type_testing_stub) {
-        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
-            type->ptr()->type_test_stub_entry_point_);
-        s->WriteInstructions(instr, Code::null());
-      }
-    }
-
-    // The dynamic/void objects are not serialized, so we manually send
-    // the type testing stub for it.
-    if (should_write_type_testing_stub && is_vm_isolate) {
-      RawInstructions* dynamic_instr = type_testing_stubs_.LookupByAddresss(
-          Type::dynamic_type().type_test_stub_entry_point());
-      s->WriteInstructions(dynamic_instr, Code::null());
-
-      RawInstructions* void_instr = type_testing_stubs_.LookupByAddresss(
-          Type::void_type().type_test_stub_entry_point());
-      s->WriteInstructions(void_instr, Code::null());
     }
   }
 
  private:
   GrowableArray<RawType*> canonical_objects_;
   GrowableArray<RawType*> objects_;
-  const TypeTestingStubFinder& type_testing_stubs_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 class TypeDeserializationCluster : public DeserializationCluster {
  public:
-  TypeDeserializationCluster()
-      : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
+  TypeDeserializationCluster() {}
   ~TypeDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
@@ -2884,8 +2853,6 @@
 
   void ReadFill(Deserializer* d) {
     const bool is_vm_isolate = d->isolate() == Dart::vm_isolate();
-    const bool should_read_type_testing_stub =
-        SnapshotContainsTypeTestingStubs(d->kind());
 
     for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
          id++) {
@@ -2895,11 +2862,6 @@
       ReadFromTo(type);
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->type_state_ = d->Read<int8_t>();
-      if (should_read_type_testing_stub) {
-        instr_ = d->ReadInstructions();
-        type_ = type;
-        type_.SetTypeTestingStub(instr_);
-      }
     }
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
@@ -2909,35 +2871,36 @@
       ReadFromTo(type);
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->type_state_ = d->Read<int8_t>();
-      if (should_read_type_testing_stub) {
-        instr_ = d->ReadInstructions();
-        type_ = type;
-        type_.SetTypeTestingStub(instr_);
-      }
-    }
-
-    // The dynamic/void objects are not serialized, so we manually send
-    // the type testing stub for it.
-    if (should_read_type_testing_stub && is_vm_isolate) {
-      instr_ = d->ReadInstructions();
-      Type::dynamic_type().SetTypeTestingStub(instr_);
-      instr_ = d->ReadInstructions();
-      Type::void_type().SetTypeTestingStub(instr_);
     }
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    if (!SnapshotContainsTypeTestingStubs(kind)) {
+    Type& type = Type::Handle(zone);
+    Code& stub = Code::Handle(zone);
+
+    if (Snapshot::IncludesCode(kind)) {
       for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
            id++) {
-        type_ ^= refs.At(id);
-        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
-        type_.SetTypeTestingStub(instr_);
+        type ^= refs.At(id);
+        stub = type.type_test_stub();
+        type.SetTypeTestingStub(stub);  // Update type_test_stub_entry_point_
       }
       for (intptr_t id = start_index_; id < stop_index_; id++) {
-        type_ ^= refs.At(id);
-        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
-        type_.SetTypeTestingStub(instr_);
+        type ^= refs.At(id);
+        stub = type.type_test_stub();
+        type.SetTypeTestingStub(stub);  // Update type_test_stub_entry_point_
+      }
+    } else {
+      for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
+           id++) {
+        type ^= refs.At(id);
+        stub = TypeTestingStubGenerator::DefaultCodeForType(type);
+        type.SetTypeTestingStub(stub);
+      }
+      for (intptr_t id = start_index_; id < stop_index_; id++) {
+        type ^= refs.At(id);
+        stub = TypeTestingStubGenerator::DefaultCodeForType(type);
+        type.SetTypeTestingStub(stub);
       }
     }
   }
@@ -2945,15 +2908,12 @@
  private:
   intptr_t canonical_start_index_;
   intptr_t canonical_stop_index_;
-  AbstractType& type_;
-  Instructions& instr_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeRefSerializationCluster : public SerializationCluster {
  public:
-  explicit TypeRefSerializationCluster(const TypeTestingStubFinder& ttsf)
-      : SerializationCluster("TypeRef"), type_testing_stubs_(ttsf) {}
+  TypeRefSerializationCluster() : SerializationCluster("TypeRef") {}
   ~TypeRefSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -2973,32 +2933,22 @@
   }
 
   void WriteFill(Serializer* s) {
-    const bool should_write_type_testing_stub =
-        SnapshotContainsTypeTestingStubs(s->kind());
-
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawTypeRef* type = objects_[i];
       AutoTraceObject(type);
       WriteFromTo(type);
-      if (should_write_type_testing_stub) {
-        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
-            type->ptr()->type_test_stub_entry_point_);
-        s->WriteInstructions(instr, Code::null());
-      }
     }
   }
 
  private:
   GrowableArray<RawTypeRef*> objects_;
-  const TypeTestingStubFinder& type_testing_stubs_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 class TypeRefDeserializationCluster : public DeserializationCluster {
  public:
-  TypeRefDeserializationCluster()
-      : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
+  TypeRefDeserializationCluster() {}
   ~TypeRefDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
@@ -3013,42 +2963,40 @@
 
   void ReadFill(Deserializer* d) {
     const bool is_vm_object = d->isolate() == Dart::vm_isolate();
-    const bool should_read_type_testing_stub =
-        SnapshotContainsTypeTestingStubs(d->kind());
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTypeRef* type = reinterpret_cast<RawTypeRef*>(d->Ref(id));
       Deserializer::InitializeHeader(type, kTypeRefCid, TypeRef::InstanceSize(),
                                      is_vm_object);
       ReadFromTo(type);
-      if (should_read_type_testing_stub) {
-        instr_ = d->ReadInstructions();
-        type_ = type;
-        type_.SetTypeTestingStub(instr_);
-      }
     }
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    if (!SnapshotContainsTypeTestingStubs(kind)) {
+    TypeRef& type_ref = TypeRef::Handle(zone);
+    Code& stub = Code::Handle(zone);
+
+    if (Snapshot::IncludesCode(kind)) {
       for (intptr_t id = start_index_; id < stop_index_; id++) {
-        type_ ^= refs.At(id);
-        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
-        type_.SetTypeTestingStub(instr_);
+        type_ref ^= refs.At(id);
+        stub = type_ref.type_test_stub();
+        type_ref.SetTypeTestingStub(
+            stub);  // Update type_test_stub_entry_point_
+      }
+    } else {
+      for (intptr_t id = start_index_; id < stop_index_; id++) {
+        type_ref ^= refs.At(id);
+        stub = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
+        type_ref.SetTypeTestingStub(stub);
       }
     }
   }
-
- private:
-  AbstractType& type_;
-  Instructions& instr_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class TypeParameterSerializationCluster : public SerializationCluster {
  public:
-  explicit TypeParameterSerializationCluster(const TypeTestingStubFinder& ttsf)
-      : SerializationCluster("TypeParameter"), type_testing_stubs_(ttsf) {}
+  TypeParameterSerializationCluster() : SerializationCluster("TypeParameter") {}
 
   ~TypeParameterSerializationCluster() {}
 
@@ -3070,9 +3018,6 @@
   }
 
   void WriteFill(Serializer* s) {
-    const bool should_write_type_testing_stub =
-        SnapshotContainsTypeTestingStubs(s->kind());
-
     intptr_t count = objects_.length();
     for (intptr_t i = 0; i < count; i++) {
       RawTypeParameter* type = objects_[i];
@@ -3082,24 +3027,17 @@
       s->WriteTokenPosition(type->ptr()->token_pos_);
       s->Write<int16_t>(type->ptr()->index_);
       s->Write<int8_t>(type->ptr()->type_state_);
-      if (should_write_type_testing_stub) {
-        RawInstructions* instr = type_testing_stubs_.LookupByAddresss(
-            type->ptr()->type_test_stub_entry_point_);
-        s->WriteInstructions(instr, Code::null());
-      }
     }
   }
 
  private:
   GrowableArray<RawTypeParameter*> objects_;
-  const TypeTestingStubFinder& type_testing_stubs_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
 
 class TypeParameterDeserializationCluster : public DeserializationCluster {
  public:
-  TypeParameterDeserializationCluster()
-      : type_(AbstractType::Handle()), instr_(Instructions::Handle()) {}
+  TypeParameterDeserializationCluster() {}
   ~TypeParameterDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
@@ -3115,8 +3053,6 @@
 
   void ReadFill(Deserializer* d) {
     bool is_vm_object = d->isolate() == Dart::vm_isolate();
-    const bool should_read_type_testing_stub =
-        SnapshotContainsTypeTestingStubs(d->kind());
 
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       RawTypeParameter* type = reinterpret_cast<RawTypeParameter*>(d->Ref(id));
@@ -3127,27 +3063,28 @@
       type->ptr()->token_pos_ = d->ReadTokenPosition();
       type->ptr()->index_ = d->Read<int16_t>();
       type->ptr()->type_state_ = d->Read<int8_t>();
-      if (should_read_type_testing_stub) {
-        instr_ = d->ReadInstructions();
-        type_ = type;
-        type_.SetTypeTestingStub(instr_);
-      }
     }
   }
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    if (!SnapshotContainsTypeTestingStubs(kind)) {
+    TypeParameter& type_param = TypeParameter::Handle(zone);
+    Code& stub = Code::Handle(zone);
+
+    if (Snapshot::IncludesCode(kind)) {
       for (intptr_t id = start_index_; id < stop_index_; id++) {
-        type_ ^= refs.At(id);
-        instr_ = TypeTestingStubGenerator::DefaultCodeForType(type_);
-        type_.SetTypeTestingStub(instr_);
+        type_param ^= refs.At(id);
+        stub = type_param.type_test_stub();
+        type_param.SetTypeTestingStub(
+            stub);  // Update type_test_stub_entry_point_
+      }
+    } else {
+      for (intptr_t id = start_index_; id < stop_index_; id++) {
+        type_param ^= refs.At(id);
+        stub = TypeTestingStubGenerator::DefaultCodeForType(type_param);
+        type_param.SetTypeTestingStub(stub);
       }
     }
   }
-
- private:
-  AbstractType& type_;
-  Instructions& instr_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -3219,7 +3156,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class MintSerializationCluster : public SerializationCluster {
  public:
-  MintSerializationCluster() : SerializationCluster("Mint") {}
+  MintSerializationCluster() : SerializationCluster("int") {}
   ~MintSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -3291,9 +3228,6 @@
   void ReadFill(Deserializer* d) {}
 
   void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        Thread::Current(), Timeline::GetIsolateStream(), "PostLoadMint"));
-
     const Class& mint_cls =
         Class::Handle(zone, Isolate::Current()->object_store()->mint_class());
     mint_cls.set_constants(Object::empty_array());
@@ -3310,7 +3244,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
 class DoubleSerializationCluster : public SerializationCluster {
  public:
-  DoubleSerializationCluster() : SerializationCluster("Double") {}
+  DoubleSerializationCluster() : SerializationCluster("double") {}
   ~DoubleSerializationCluster() {}
 
   void Trace(Serializer* s, RawObject* object) {
@@ -4357,11 +4291,11 @@
     case kLibraryPrefixCid:
       return new (Z) LibraryPrefixSerializationCluster();
     case kTypeCid:
-      return new (Z) TypeSerializationCluster(type_testing_stubs_);
+      return new (Z) TypeSerializationCluster();
     case kTypeRefCid:
-      return new (Z) TypeRefSerializationCluster(type_testing_stubs_);
+      return new (Z) TypeRefSerializationCluster();
     case kTypeParameterCid:
-      return new (Z) TypeParameterSerializationCluster(type_testing_stubs_);
+      return new (Z) TypeParameterSerializationCluster();
     case kClosureCid:
       return new (Z) ClosureSerializationCluster();
     case kMintCid:
@@ -4402,13 +4336,15 @@
       break;
   }
 
-  FATAL2("No cluster defined for cid %" Pd ", kind %s", cid,
-         Snapshot::KindToCString(kind_));
+  // The caller will check for NULL and provide an error with more context than
+  // is available here.
   return NULL;
 #endif  // !DART_PRECOMPILED_RUNTIME
 }
 
 void Serializer::WriteInstructions(RawInstructions* instr, RawCode* code) {
+  ASSERT(code != Code::null());
+
   const intptr_t offset = image_writer_->GetTextOffsetFor(instr, code);
   ASSERT(offset != 0);
   Write<int32_t>(offset);
@@ -4506,7 +4442,10 @@
     // roots we do not trace references, e.g. inside [RawCode], to
     // [RawInstructions], since [RawInstructions] doesn't contain any references
     // and the serialization code uses an [ImageWriter] for those.
-    ASSERT(object->GetClassId() != kInstructionsCid);
+    if (object->IsInstructions()) {
+      UnexpectedObject(object,
+                       "Instructions should only be reachable from Code");
+    }
 
     heap_->SetObjectId(object, 1);
     ASSERT(heap_->GetObjectId(object) != 0);
@@ -4532,6 +4471,9 @@
   SerializationCluster* cluster = clusters_by_cid_[cid];
   if (cluster == NULL) {
     cluster = NewClusterForClass(cid);
+    if (cluster == NULL) {
+      UnexpectedObject(object, "No serialization cluster defined");
+    }
     clusters_by_cid_[cid] = cluster;
   }
   ASSERT(cluster != NULL);
@@ -4553,7 +4495,8 @@
     thread()->DecrementNoSafepointScopeDepth();
   }
   Object& object = Object::Handle(raw_object);
-  OS::PrintErr("Unexpected object (%s): 0x%" Px " %s\n", message,
+  OS::PrintErr("Unexpected object (%s, %s): 0x%" Px " %s\n", message,
+               Snapshot::KindToCString(kind_),
                reinterpret_cast<uword>(object.raw()), object.ToCString());
 #if defined(SNAPSHOT_BACKTRACE)
   while (!object.IsNull()) {
@@ -4730,9 +4673,10 @@
   // These objects are always allocated by Object::InitOnce, so they are not
   // written into the snapshot.
 
-  AddBaseObject(Object::null(), "Null", "<null>");
-  AddBaseObject(Object::sentinel().raw(), "Sentinel");
-  AddBaseObject(Object::transition_sentinel().raw(), "Sentinel");
+  AddBaseObject(Object::null(), "Null", "null");
+  AddBaseObject(Object::sentinel().raw(), "Null", "sentinel");
+  AddBaseObject(Object::transition_sentinel().raw(), "Null",
+                "transition_sentinel");
   AddBaseObject(Object::empty_array().raw(), "Array", "<empty_array>");
   AddBaseObject(Object::zero_array().raw(), "Array", "<zero_array>");
   AddBaseObject(Object::dynamic_type().raw(), "Type", "<dynamic type>");
@@ -4758,8 +4702,8 @@
                   "ArgumentsDescriptor", "<cached arguments descriptor>");
   }
   for (intptr_t i = 0; i < ICData::kCachedICDataArrayCount; i++) {
-    AddBaseObject(ICData::cached_icdata_arrays_[i], "ICData",
-                  "<cached icdata>");
+    AddBaseObject(ICData::cached_icdata_arrays_[i], "Array",
+                  "<empty icdata entries>");
   }
 
   ClassTable* table = isolate()->class_table();
@@ -4865,7 +4809,8 @@
                            const uint8_t* data_buffer,
                            const uint8_t* instructions_buffer,
                            const uint8_t* shared_data_buffer,
-                           const uint8_t* shared_instructions_buffer)
+                           const uint8_t* shared_instructions_buffer,
+                           intptr_t offset)
     : ThreadStackResource(thread),
       heap_(thread->isolate()->heap()),
       zone_(thread->zone()),
@@ -4882,6 +4827,7 @@
         new (zone_) ImageReader(data_buffer, instructions_buffer,
                                 shared_data_buffer, shared_instructions_buffer);
   }
+  stream_.SetPosition(offset);
 }
 
 Deserializer::~Deserializer() {
@@ -5008,33 +4954,43 @@
   return NULL;
 }
 
-RawApiError* Deserializer::VerifyVersionAndFeatures(Isolate* isolate) {
-  if (image_reader_ != NULL) {
-    RawApiError* error = image_reader_->VerifyAlignment();
-    if (error != ApiError::null()) {
-      return error;
-    }
+RawApiError* Deserializer::VerifyImageAlignment() {
+  if (image_reader_ != nullptr) {
+    return image_reader_->VerifyAlignment();
   }
+  return ApiError::null();
+}
 
+char* SnapshotHeaderReader::VerifyVersionAndFeatures(Isolate* isolate,
+                                                     intptr_t* offset) {
+  char* error = VerifyVersion();
+  if (error == nullptr) {
+    error = VerifyFeatures(isolate);
+  }
+  if (error == nullptr) {
+    *offset = stream_.Position();
+  }
+  return error;
+}
+
+char* SnapshotHeaderReader::VerifyVersion() {
   // If the version string doesn't match, return an error.
   // Note: New things are allocated only if we're going to return an error.
 
   const char* expected_version = Version::SnapshotString();
   ASSERT(expected_version != NULL);
   const intptr_t version_len = strlen(expected_version);
-  if (PendingBytes() < version_len) {
+  if (stream_.PendingBytes() < version_len) {
     const intptr_t kMessageBufferSize = 128;
     char message_buffer[kMessageBufferSize];
     Utils::SNPrint(message_buffer, kMessageBufferSize,
                    "No full snapshot version found, expected '%s'",
                    expected_version);
-    // 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_buffer, Heap::kOld));
-    return ApiError::New(msg, Heap::kOld);
+    return BuildError(message_buffer);
   }
 
-  const char* version = reinterpret_cast<const char*>(CurrentBufferAddress());
+  const char* version =
+      reinterpret_cast<const char*>(stream_.AddressOfCurrentPosition());
   ASSERT(version != NULL);
   if (strncmp(version, expected_version, version_len)) {
     const intptr_t kMessageBufferSize = 256;
@@ -5045,41 +5001,73 @@
                    (Snapshot::IsFull(kind_)) ? "full" : "script",
                    expected_version, actual_version);
     free(actual_version);
-    // 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_buffer, Heap::kOld));
-    return ApiError::New(msg, Heap::kOld);
+    return BuildError(message_buffer);
   }
-  Advance(version_len);
+  stream_.Advance(version_len);
 
+  return nullptr;
+}
+
+char* SnapshotHeaderReader::VerifyFeatures(Isolate* isolate) {
   const char* expected_features =
       Dart::FeaturesString(isolate, (isolate == NULL), kind_);
   ASSERT(expected_features != NULL);
   const intptr_t expected_len = strlen(expected_features);
 
-  const char* features = reinterpret_cast<const char*>(CurrentBufferAddress());
-  ASSERT(features != NULL);
-  intptr_t buffer_len = Utils::StrNLen(features, PendingBytes());
-  if ((buffer_len != expected_len) ||
+  const char* features = nullptr;
+  intptr_t features_length = 0;
+
+  auto error = ReadFeatures(&features, &features_length);
+  if (error != nullptr) {
+    return error;
+  }
+
+  if (features_length != expected_len ||
       strncmp(features, expected_features, expected_len)) {
     const intptr_t kMessageBufferSize = 1024;
     char message_buffer[kMessageBufferSize];
-    char* actual_features =
-        Utils::StrNDup(features, buffer_len < 1024 ? buffer_len : 1024);
+    char* actual_features = Utils::StrNDup(
+        features, features_length < 1024 ? features_length : 1024);
     Utils::SNPrint(message_buffer, kMessageBufferSize,
                    "Snapshot not compatible with the current VM configuration: "
                    "the snapshot requires '%s' but the VM has '%s'",
                    actual_features, expected_features);
     free(const_cast<char*>(expected_features));
     free(actual_features);
-    // 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_buffer, Heap::kOld));
-    return ApiError::New(msg, Heap::kOld);
+    return BuildError(message_buffer);
   }
   free(const_cast<char*>(expected_features));
-  Advance(expected_len + 1);
-  return ApiError::null();
+  return nullptr;
+}
+
+char* SnapshotHeaderReader::ReadFeatures(const char** features,
+                                         intptr_t* features_length) {
+  const char* cursor =
+      reinterpret_cast<const char*>(stream_.AddressOfCurrentPosition());
+  const intptr_t length = Utils::StrNLen(cursor, stream_.PendingBytes());
+  if (length == stream_.PendingBytes()) {
+    return BuildError(
+        "The features string in the snapshot was not '\\0'-terminated.");
+  }
+  *features = cursor;
+  *features_length = length;
+  stream_.Advance(length + 1);
+  return nullptr;
+}
+
+char* SnapshotHeaderReader::BuildError(const char* message) {
+  return strdup(message);
+}
+
+RawApiError* 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));
+
+  // The [message] was constructed with [BuildError] and needs to be freed.
+  free(message);
+
+  return ApiError::New(msg, Heap::kOld);
 }
 
 RawInstructions* Deserializer::ReadInstructions() {
@@ -5112,32 +5100,24 @@
            num_base_objects_, next_ref_index_ - 1);
   }
 
-  {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        thread(), Timeline::GetIsolateStream(), "ReadAlloc"));
-    for (intptr_t i = 0; i < num_clusters_; i++) {
-      clusters_[i] = ReadCluster();
-      clusters_[i]->ReadAlloc(this);
+  for (intptr_t i = 0; i < num_clusters_; i++) {
+    clusters_[i] = ReadCluster();
+    clusters_[i]->ReadAlloc(this);
 #if defined(DEBUG)
-      intptr_t serializers_next_ref_index_ = Read<int32_t>();
-      ASSERT(serializers_next_ref_index_ == next_ref_index_);
+    intptr_t serializers_next_ref_index_ = Read<int32_t>();
+    ASSERT(serializers_next_ref_index_ == next_ref_index_);
 #endif
-    }
   }
 
   // We should have completely filled the ref array.
   ASSERT((next_ref_index_ - 1) == num_objects_);
 
-  {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        thread(), Timeline::GetIsolateStream(), "ReadFill"));
-    for (intptr_t i = 0; i < num_clusters_; i++) {
-      clusters_[i]->ReadFill(this);
+  for (intptr_t i = 0; i < num_clusters_; i++) {
+    clusters_[i]->ReadFill(this);
 #if defined(DEBUG)
-      int32_t section_marker = Read<int32_t>();
-      ASSERT(section_marker == kSectionMarker);
+    int32_t section_marker = Read<int32_t>();
+    ASSERT(section_marker == kSectionMarker);
 #endif
-    }
   }
 }
 
@@ -5245,6 +5225,10 @@
 #if defined(DEBUG)
   isolate()->ValidateClassTable();
 #endif
+
+  for (intptr_t i = 0; i < num_clusters_; i++) {
+    clusters_[i]->PostLoad(refs, kind_, zone_);
+  }
 }
 
 void Deserializer::ReadIsolateSnapshot(ObjectStore* object_store) {
@@ -5280,7 +5264,7 @@
   }
 
   thread()->isolate()->class_table()->CopySizesFromClassObjects();
-  heap_->old_space()->EvaluateSnapshotLoad();
+  heap_->old_space()->EvaluateAfterLoading();
 
 #if defined(DEBUG)
   Isolate* isolate = thread()->isolate();
@@ -5428,8 +5412,7 @@
   // generated from a VM that has loaded this snapshots, much like app-jit
   // snapshots.
   if ((vm_snapshot_data_buffer != NULL) && (kind != Snapshot::kFullAOT)) {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(
-        thread(), Timeline::GetIsolateStream(), "PrepareNewVMIsolate"));
+    TIMELINE_DURATION(thread(), Isolate, "PrepareNewVMIsolate");
 
     SeedVMIsolateVisitor visitor(thread()->zone(),
                                  Snapshot::IncludesCode(kind));
@@ -5470,8 +5453,7 @@
 }
 
 intptr_t FullSnapshotWriter::WriteVMSnapshot() {
-  NOT_IN_PRODUCT(TimelineDurationScope tds(
-      thread(), Timeline::GetIsolateStream(), "WriteVMSnapshot"));
+  TIMELINE_DURATION(thread(), Isolate, "WriteVMSnapshot");
 
   ASSERT(vm_snapshot_data_buffer_ != NULL);
   Serializer serializer(thread(), kind_, vm_snapshot_data_buffer_, alloc_,
@@ -5504,8 +5486,7 @@
 }
 
 void FullSnapshotWriter::WriteIsolateSnapshot(intptr_t num_base_objects) {
-  NOT_IN_PRODUCT(TimelineDurationScope tds(
-      thread(), Timeline::GetIsolateStream(), "WriteIsolateSnapshot"));
+  TIMELINE_DURATION(thread(), Isolate, "WriteIsolateSnapshot");
 
   Serializer serializer(thread(), kind_, isolate_snapshot_data_buffer_, alloc_,
                         kInitialSize, isolate_image_writer_, /*vm=*/false,
@@ -5589,17 +5570,70 @@
   shared_instructions_image_ = shared_instructions;
 }
 
-RawApiError* FullSnapshotReader::ReadVMSnapshot() {
-  Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
-                            instructions_image_, NULL, NULL);
+char* SnapshotHeaderReader::InitializeGlobalVMFlagsFromSnapshot(
+    const Snapshot* snapshot) {
+  SnapshotHeaderReader header_reader(snapshot);
 
-  deserializer.SkipHeader();
-
-  RawApiError* error = deserializer.VerifyVersionAndFeatures(/*isolate=*/NULL);
-  if (error != ApiError::null()) {
+  char* error = header_reader.VerifyVersion();
+  if (error != nullptr) {
     return error;
   }
 
+  const char* features = nullptr;
+  intptr_t features_length = 0;
+  error = header_reader.ReadFeatures(&features, &features_length);
+  if (error != nullptr) {
+    return error;
+  }
+
+  ASSERT(features[features_length] == '\0');
+  const char* cursor = features;
+  while (*cursor != '\0') {
+    while (*cursor == ' ') {
+      cursor++;
+    }
+
+    const char* end = strstr(cursor, " ");
+    if (end == nullptr) {
+      end = features + features_length;
+    }
+#define CHECK_FLAG(name, flag)                                                 \
+  if (strncmp(cursor, #name, end - cursor) == 0) {                             \
+    flag = true;                                                               \
+    cursor = end;                                                              \
+    continue;                                                                  \
+  }                                                                            \
+  if (strncmp(cursor, "no-" #name, end - cursor) == 0) {                       \
+    flag = false;                                                              \
+    cursor = end;                                                              \
+    continue;                                                                  \
+  }
+    VM_GLOBAL_FLAG_LIST(CHECK_FLAG)
+#undef CHECK_FLAG
+
+    cursor = end;
+  }
+
+  return nullptr;
+}
+
+RawApiError* FullSnapshotReader::ReadVMSnapshot() {
+  SnapshotHeaderReader header_reader(kind_, buffer_, size_);
+
+  intptr_t offset = 0;
+  char* error =
+      header_reader.VerifyVersionAndFeatures(/*isolate=*/NULL, &offset);
+  if (error != nullptr) {
+    return ConvertToApiError(error);
+  }
+
+  Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
+                            instructions_image_, NULL, NULL, offset);
+  RawApiError* api_error = deserializer.VerifyImageAlignment();
+  if (api_error != ApiError::null()) {
+    return api_error;
+  }
+
   if (Snapshot::IncludesCode(kind_)) {
     ASSERT(data_image_ != NULL);
     thread_->isolate()->SetupImagePage(data_image_,
@@ -5615,16 +5649,20 @@
 }
 
 RawApiError* FullSnapshotReader::ReadIsolateSnapshot() {
+  SnapshotHeaderReader header_reader(kind_, buffer_, size_);
+  intptr_t offset = 0;
+  char* error =
+      header_reader.VerifyVersionAndFeatures(thread_->isolate(), &offset);
+  if (error != nullptr) {
+    return ConvertToApiError(error);
+  }
+
   Deserializer deserializer(thread_, kind_, buffer_, size_, data_image_,
                             instructions_image_, shared_data_image_,
-                            shared_instructions_image_);
-
-  deserializer.SkipHeader();
-
-  RawApiError* error =
-      deserializer.VerifyVersionAndFeatures(thread_->isolate());
-  if (error != ApiError::null()) {
-    return error;
+                            shared_instructions_image_, offset);
+  RawApiError* api_error = deserializer.VerifyImageAlignment();
+  if (api_error != ApiError::null()) {
+    return api_error;
   }
 
   if (Snapshot::IncludesCode(kind_)) {
@@ -5664,12 +5702,13 @@
     auto& entry = Object::Handle(zone);
     auto& smi = Smi::Handle(zone);
     for (intptr_t i = 0; i < pool.Length(); i++) {
-      if (pool.TypeAt(i) == ObjectPool::kTaggedObject) {
+      if (pool.TypeAt(i) == ObjectPool::EntryType::kTaggedObject) {
         entry = pool.ObjectAt(i);
         if (entry.raw() == StubCode::UnlinkedCall().raw()) {
           smi = Smi::FromAlignedAddress(
               StubCode::UnlinkedCall().MonomorphicEntryPoint());
-          pool.SetTypeAt(i, ObjectPool::kImmediate, ObjectPool::kPatchable);
+          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 420742d..3b863bd 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -17,7 +17,6 @@
 #include "vm/object.h"
 #include "vm/raw_object_fields.h"
 #include "vm/snapshot.h"
-#include "vm/type_testing_stubs.h"
 #include "vm/v8_snapshot_writer.h"
 #include "vm/version.h"
 
@@ -368,7 +367,6 @@
   void DumpCombinedCodeStatistics();
 
  private:
-  TypeTestingStubFinder type_testing_stubs_;
   Heap* heap_;
   Zone* zone_;
   Snapshot::Kind kind_;
@@ -431,6 +429,42 @@
   Serializer* serializer_;
 };
 
+// This class can be used to read version and features from a snapshot before
+// the VM has been initialized.
+class SnapshotHeaderReader {
+ public:
+  static char* InitializeGlobalVMFlagsFromSnapshot(const Snapshot* snapshot);
+
+  explicit SnapshotHeaderReader(const Snapshot* snapshot)
+      : SnapshotHeaderReader(snapshot->kind(),
+                             snapshot->Addr(),
+                             snapshot->length()) {}
+
+  SnapshotHeaderReader(Snapshot::Kind kind,
+                       const uint8_t* buffer,
+                       intptr_t size)
+      : kind_(kind), stream_(buffer, size) {
+    stream_.SetPosition(Snapshot::kHeaderSize);
+  }
+
+  // Verifies the version and features in the snapshot are compatible with the
+  // current VM.  If isolate is non-null it validates isolate-specific features.
+  //
+  // Returns null on success and a malloc()ed error on failure.
+  // The [offset] will be the next position in the snapshot stream after the
+  // features.
+  char* VerifyVersionAndFeatures(Isolate* isolate, intptr_t* offset);
+
+ private:
+  char* VerifyVersion();
+  char* ReadFeatures(const char** features, intptr_t* features_length);
+  char* VerifyFeatures(Isolate* isolate);
+  char* BuildError(const char* message);
+
+  Snapshot::Kind kind_;
+  ReadStream stream_;
+};
+
 class Deserializer : public ThreadStackResource {
  public:
   Deserializer(Thread* thread,
@@ -440,9 +474,16 @@
                const uint8_t* data_buffer,
                const uint8_t* instructions_buffer,
                const uint8_t* shared_data_buffer,
-               const uint8_t* shared_instructions_buffer);
+               const uint8_t* shared_instructions_buffer,
+               intptr_t offset = 0);
   ~Deserializer();
 
+  // Verifies the image alignment.
+  //
+  // Returns ApiError::null() on success and an ApiError with an an appropriate
+  // message otherwise.
+  RawApiError* VerifyImageAlignment();
+
   void ReadIsolateSnapshot(ObjectStore* object_store);
   void ReadVMSnapshot();
 
@@ -470,8 +511,6 @@
   void Advance(intptr_t value) { stream_.Advance(value); }
   void Align(intptr_t alignment) { stream_.Align(alignment); }
 
-  intptr_t PendingBytes() const { return stream_.PendingBytes(); }
-
   void AddBaseObject(RawObject* base_object) { AssignRef(base_object); }
 
   void AssignRef(RawObject* object) {
@@ -517,8 +556,6 @@
 
   void SkipHeader() { stream_.SetPosition(Snapshot::kHeaderSize); }
 
-  RawApiError* VerifyVersionAndFeatures(Isolate* isolate);
-
   void Prepare();
   void Deserialize();
 
@@ -633,6 +670,8 @@
   RawApiError* ReadIsolateSnapshot();
 
  private:
+  RawApiError* ConvertToApiError(char* message);
+
   Snapshot::Kind kind_;
   Thread* thread_;
   const uint8_t* buffer_;
diff --git a/runtime/vm/code_entry_kind.h b/runtime/vm/code_entry_kind.h
new file mode 100644
index 0000000..52b6e9e
--- /dev/null
+++ b/runtime/vm/code_entry_kind.h
@@ -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.
+
+#ifndef RUNTIME_VM_CODE_ENTRY_KIND_H_
+#define RUNTIME_VM_CODE_ENTRY_KIND_H_
+
+namespace dart {
+
+// Compiled functions might have several different entry points, which either
+// perform additional checking on entry into the function or skip some of the
+// checks normally performed on the entry.
+//
+// Which checks are performed and skipped depend on the function and VM mode.
+enum class CodeEntryKind {
+  // Normal entry into the function.
+  //
+  // Usually such entries perform type checks for all parameters which are not
+  // guaranteed to be type checked on the callee side. This can happen if
+  // parameter type depends on the type parameter of an enclosing class.
+  kNormal,
+
+  // Unchecked entry into the function.
+  //
+  // These entries usually skip most of the type checks that normal entries
+  // perform and are used when optimizing compiler can prove that those
+  // checks are not needed at a specific call site.
+  kUnchecked,
+
+  // Monomorphic entry into the function.
+  //
+  // In AOT mode we might patch call-site to directly invoke target function,
+  // which would then validate that it is invoked with the expected type of
+  // the receiver. This validation is handled by monomorphic entry, which then
+  // falls through to the normal entry.
+  kMonomorphic,
+
+  // Similar to monomorphic entry but with a fallthrough into unchecked entry.
+  kMonomorphicUnchecked,
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_CODE_ENTRY_KIND_H_
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index 9b31dcd..6aa62af 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -12,17 +12,12 @@
 namespace dart {
 
 // Forward declaration.
-class Array;
 class Code;
-class ExternalLabel;
-class Function;
 class ICData;
 class RawArray;
 class RawCode;
 class RawFunction;
-class RawICData;
 class RawObject;
-class String;
 
 // Stack-allocated class to create a scope where the specified region
 // [address, address + size] has write access enabled. This is used
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 1794125..f53cf2a 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -378,11 +378,13 @@
     } else {
       FATAL1("Failed to decode at %" Px, pc);
     }
-    ASSERT(object_pool_.TypeAt(target_index_) == ObjectPool::kImmediate);
+    ASSERT(object_pool_.TypeAt(target_index_) ==
+           ObjectPool::EntryType::kImmediate);
   }
 
   void SetTarget(const Code& target) const {
-    ASSERT(object_pool_.TypeAt(target_index()) == ObjectPool::kImmediate);
+    ASSERT(object_pool_.TypeAt(target_index()) ==
+           ObjectPool::EntryType::kImmediate);
     object_pool_.SetRawValueAt(target_index(), target.MonomorphicEntryPoint());
   }
 
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index 2a9f62d..29cdfa2 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -316,12 +316,37 @@
       call_sites_(Array::Handle()),
       call_site_(ICData::Handle()) {}
 
+// These flags affect deopt ids.
+static char* CompilerFlags() {
+  TextBuffer buffer(64);
+
+#define ADD_FLAG(flag) buffer.AddString(FLAG_##flag ? " " #flag : " no-" #flag)
+  ADD_FLAG(enable_asserts);
+  ADD_FLAG(use_field_guards);
+  ADD_FLAG(use_osr);
+  ADD_FLAG(causal_async_stacks);
+  ADD_FLAG(fields_may_be_reset);
+#undef ADD_FLAG
+  buffer.AddString(FLAG_use_bytecode_compiler || FLAG_enable_interpreter
+                       ? " bytecode"
+                       : " no-bytecode");
+
+  return buffer.Steal();
+}
+
 void TypeFeedbackSaver::WriteHeader() {
   const char* expected_version = Version::SnapshotString();
   ASSERT(expected_version != NULL);
   const intptr_t version_len = strlen(expected_version);
   stream_->WriteBytes(reinterpret_cast<const uint8_t*>(expected_version),
                       version_len);
+
+  char* expected_features = CompilerFlags();
+  ASSERT(expected_features != NULL);
+  const intptr_t features_len = strlen(expected_features);
+  stream_->WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
+                      features_len + 1);
+  free(expected_features);
 }
 
 void TypeFeedbackSaver::SaveClasses() {
@@ -534,6 +559,27 @@
   }
   stream_->Advance(version_len);
 
+  char* expected_features = CompilerFlags();
+  ASSERT(expected_features != NULL);
+  const intptr_t expected_len = strlen(expected_features);
+
+  const char* features =
+      reinterpret_cast<const char*>(stream_->AddressOfCurrentPosition());
+  ASSERT(features != NULL);
+  intptr_t buffer_len = Utils::StrNLen(features, stream_->PendingBytes());
+  if ((buffer_len != expected_len) ||
+      strncmp(features, expected_features, expected_len)) {
+    const String& msg = String::Handle(String::NewFormatted(
+        Heap::kOld,
+        "Feedback not compatible with the current VM configuration: "
+        "the feedback requires '%.*s' but the VM has '%s'",
+        static_cast<int>(buffer_len > 1024 ? 1024 : buffer_len), features,
+        expected_features));
+    free(expected_features);
+    return ApiError::New(msg, Heap::kOld);
+  }
+  free(expected_features);
+  stream_->Advance(expected_len + 1);
   return Error::null();
 }
 
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 9c0544a..23e66c0 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -416,7 +416,7 @@
 }
 
 // Modulo against a constant power-of-two can be optimized into a mask.
-// x % y -> x & (y - 1)
+// x % y -> x & (|y| - 1)  for smi masks only
 Definition* AotCallSpecializer::TryOptimizeMod(TemplateDartCall<0>* instr,
                                                Token::Kind op_kind,
                                                Value* left_value,
@@ -426,8 +426,11 @@
   }
 
   const Object& rhs = right_value->BoundConstant();
-  int64_t modulus = Utils::Abs(rhs.IsSmi() ? Smi::Cast(rhs).Value()
-                                           : Mint::Cast(rhs).value());
+  const int64_t value = Integer::Cast(rhs).AsInt64Value();  // smi and mint
+  if (value == kMinInt64) {
+    return nullptr;  // non-smi mask
+  }
+  const int64_t modulus = Utils::Abs(value);
   if (!Utils::IsPowerOfTwo(modulus) || !Smi::IsValid(modulus - 1)) {
     return nullptr;
   }
@@ -622,13 +625,13 @@
     return false;
   }
 
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
+    return false;
+  }
+
   Definition* replacement = NULL;
 
   if (instr->ArgumentCount() == 2) {
-    if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
-      return false;
-    }
-
     Value* left_value = instr->PushArgumentAt(0)->value();
     Value* right_value = instr->PushArgumentAt(1)->value();
     CompileType* left_type = left_value->Type();
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 1fc69d6..2187130 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -198,7 +198,7 @@
       // Since we keep the object pool until the end of AOT compilation, it
       // will hang on to its entries until the very end. Therefore we have
       // to use handles which survive that long, so we use [zone_] here.
-      global_object_pool_wrapper_.InitializeWithZone(zone_);
+      global_object_pool_builder_.InitializeWithZone(zone_);
     }
 
     {
@@ -238,18 +238,51 @@
         const Code& code = StubCode::InterpretCall();
         const ObjectPool& stub_pool = ObjectPool::Handle(code.object_pool());
 
-        global_object_pool_wrapper()->Reset();
-        global_object_pool_wrapper()->InitializeFrom(stub_pool);
+        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_wrapper());
-        I->object_store()->set_build_method_extractor_code(
-            Code::Handle(StubCode::GetBuildMethodExtractorStub(
-                global_object_pool_wrapper())));
+            isolate_, global_object_pool_builder());
+
+        auto& stub_code = Code::Handle();
+
+        stub_code =
+            StubCode::GetBuildMethodExtractorStub(global_object_pool_builder());
+        I->object_store()->set_build_method_extractor_code(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::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);
       }
 
       CollectDynamicFunctionNames();
@@ -270,10 +303,10 @@
         // Now we generate the actual object pool instance and attach it to the
         // object store. The AOT runtime will use it from there in the enter
         // dart code stub.
-        const auto& pool =
-            ObjectPool::Handle(global_object_pool_wrapper()->MakeObjectPool());
+        const auto& pool = ObjectPool::Handle(
+            ObjectPool::NewFromBuilder(*global_object_pool_builder()));
         I->object_store()->set_global_object_pool(pool);
-        global_object_pool_wrapper()->Reset();
+        global_object_pool_builder()->Reset();
 
         if (FLAG_print_gop) {
           THR_Print("Global object pool:\n");
@@ -292,12 +325,14 @@
 
       // Clear these before dropping classes as they may hold onto otherwise
       // dead instances of classes we will remove or otherwise unused symbols.
-      DropScriptData();
       I->object_store()->set_unique_dynamic_targets(Array::null_array());
       Class& null_class = Class::Handle(Z);
       Function& null_function = Function::Handle(Z);
+      Field& null_field = Field::Handle(Z);
       I->object_store()->set_future_class(null_class);
       I->object_store()->set_pragma_class(null_class);
+      I->object_store()->set_pragma_name(null_field);
+      I->object_store()->set_pragma_options(null_field);
       I->object_store()->set_completer_class(null_class);
       I->object_store()->set_symbol_class(null_class);
       I->object_store()->set_compiletime_error_class(null_class);
@@ -331,7 +366,7 @@
     Symbols::GetStats(I, &symbols_before, &capacity);
   }
 
-  Symbols::Compact(I);
+  Symbols::Compact();
 
   if (FLAG_trace_precompiler) {
     Symbols::GetStats(I, &symbols_after, &capacity);
@@ -494,7 +529,7 @@
 
 void Precompiler::ProcessFunction(const Function& function) {
   const intptr_t gop_offset =
-      FLAG_use_bare_instructions ? global_object_pool_wrapper()->CurrentLength()
+      FLAG_use_bare_instructions ? global_object_pool_builder()->CurrentLength()
                                  : 0;
 
   if (!function.HasCode()) {
@@ -561,9 +596,10 @@
   String& selector = String::Handle(Z);
   if (FLAG_use_bare_instructions) {
     for (intptr_t i = gop_offset;
-         i < global_object_pool_wrapper()->CurrentLength(); i++) {
-      const auto& wrapper_entry = global_object_pool_wrapper()->EntryAt(i);
-      if (wrapper_entry.type() == ObjectPool::kTaggedObject) {
+         i < global_object_pool_builder()->CurrentLength(); i++) {
+      const auto& wrapper_entry = global_object_pool_builder()->EntryAt(i);
+      if (wrapper_entry.type() ==
+          compiler::ObjectPoolBuilderEntry::kTaggedObject) {
         const auto& entry = *wrapper_entry.obj_;
         AddCalleesOfHelper(entry, &selector, &cls);
       }
@@ -572,7 +608,7 @@
     const auto& pool = ObjectPool::Handle(Z, code.object_pool());
     auto& entry = Object::Handle(Z);
     for (intptr_t i = 0; i < pool.Length(); i++) {
-      if (pool.TypeAt(i) == ObjectPool::kTaggedObject) {
+      if (pool.TypeAt(i) == ObjectPool::EntryType::kTaggedObject) {
         entry = pool.ObjectAt(i);
         AddCalleesOfHelper(entry, &selector, &cls);
       }
@@ -841,20 +877,20 @@
       // Should not be in the middle of initialization while precompiling.
       ASSERT(value.raw() != Object::transition_sentinel().raw());
 
-      if (!field.HasPrecompiledInitializer() ||
-          !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) {
+      if (!field.HasInitializer() ||
+          !Function::Handle(Z, field.Initializer()).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_wrapper()->CurrentLength()
+                ? 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.SetPrecompiledInitializer(initializer);
+        field.SetInitializer(initializer);
         AddCalleesOf(initializer, gop_offset);
       }
     }
@@ -945,21 +981,16 @@
   }
 }
 
-enum class EntryPointPragma { kAlways, kNever, kGetterOnly, kSetterOnly };
-
 // Adds all values annotated with @pragma('vm:entry-point') as roots.
 void Precompiler::AddAnnotatedRoots() {
   auto& lib = Library::Handle(Z);
-  auto& cls = Class::Handle(isolate()->object_store()->pragma_class());
+  auto& cls = Class::Handle(Z);
   auto& members = Array::Handle(Z);
   auto& function = Function::Handle(Z);
   auto& field = Field::Handle(Z);
   auto& metadata = Array::Handle(Z);
-  auto& pragma = Object::Handle(Z);
-  auto& pragma_options = Object::Handle(Z);
-  auto& pragma_name_field = Field::Handle(Z, cls.LookupField(Symbols::name()));
-  auto& pragma_options_field =
-      Field::Handle(Z, cls.LookupField(Symbols::options()));
+  auto& reusable_object_handle = Object::Handle(Z);
+  auto& reusable_field_handle = Field::Handle(Z);
 
   // Lists of fields which need implicit getter/setter/static final getter
   // added.
@@ -967,33 +998,6 @@
   auto& implicit_setters = GrowableObjectArray::Handle(Z);
   auto& implicit_static_getters = GrowableObjectArray::Handle(Z);
 
-  // Local function allows easy reuse of handles above.
-  auto metadata_defines_entrypoint = [&]() {
-    for (intptr_t i = 0; i < metadata.Length(); i++) {
-      pragma = metadata.At(i);
-      if (pragma.clazz() != isolate()->object_store()->pragma_class()) {
-        continue;
-      }
-      if (Instance::Cast(pragma).GetField(pragma_name_field) !=
-          Symbols::vm_entry_point().raw()) {
-        continue;
-      }
-      pragma_options = Instance::Cast(pragma).GetField(pragma_options_field);
-      if (pragma_options.raw() == Bool::null() ||
-          pragma_options.raw() == Bool::True().raw()) {
-        return EntryPointPragma::kAlways;
-        break;
-      }
-      if (pragma_options.raw() == Symbols::Get().raw()) {
-        return EntryPointPragma::kGetterOnly;
-      }
-      if (pragma_options.raw() == Symbols::Set().raw()) {
-        return EntryPointPragma::kSetterOnly;
-      }
-    }
-    return EntryPointPragma::kNever;
-  };
-
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
     lib ^= libraries_.At(i);
     ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
@@ -1003,7 +1007,9 @@
       // Check for @pragma on the class itself.
       if (cls.has_pragma()) {
         metadata ^= lib.GetMetadata(cls);
-        if (metadata_defines_entrypoint() == EntryPointPragma::kAlways) {
+        if (FindEntryPointPragma(isolate(), metadata, &reusable_field_handle,
+                                 &reusable_object_handle) ==
+            EntryPointPragma::kAlways) {
           AddInstantiatedClass(cls);
         }
       }
@@ -1018,7 +1024,9 @@
         if (field.has_pragma()) {
           metadata ^= lib.GetMetadata(field);
           if (metadata.IsNull()) continue;
-          EntryPointPragma pragma = metadata_defines_entrypoint();
+          EntryPointPragma pragma =
+              FindEntryPointPragma(isolate(), metadata, &reusable_field_handle,
+                                   &reusable_object_handle);
           if (pragma == EntryPointPragma::kNever) continue;
 
           AddField(field);
@@ -1043,7 +1051,9 @@
         if (function.has_pragma()) {
           metadata ^= lib.GetMetadata(function);
           if (metadata.IsNull()) continue;
-          if (metadata_defines_entrypoint() != EntryPointPragma::kAlways) {
+          if (FindEntryPointPragma(isolate(), metadata, &reusable_field_handle,
+                                   &reusable_object_handle) !=
+              EntryPointPragma::kAlways) {
             continue;
           }
 
@@ -1494,7 +1504,7 @@
   type_usage_info->BuildTypeUsageInformation();
 
   TypeTestingStubGenerator type_testing_stubs;
-  Instructions& instr = Instructions::Handle();
+  Code& code = Code::Handle();
   for (intptr_t i = 0; i < types.length(); i++) {
     const AbstractType& type = types.At(i);
 
@@ -1505,8 +1515,8 @@
     }
 
     if (type_usage_info->IsUsedInTypeTest(type)) {
-      instr = type_testing_stubs.OptimizedCodeForType(type);
-      type.SetTypeTestingStub(instr);
+      code = type_testing_stubs.OptimizedCodeForType(type);
+      type.SetTypeTestingStub(code);
 
       // Ensure we retain the type.
       AddType(type);
@@ -1527,12 +1537,13 @@
   {
     CanonicalTypeSet types_table(Z, object_store->canonical_types());
     types_array = HashTables::ToArray(types_table, false);
-    for (intptr_t i = 0; i < (types_array.Length() - 1); i++) {
+    for (intptr_t i = 0; i < types_array.Length(); i++) {
       type ^= types_array.At(i);
       bool retain = types_to_retain_.HasKey(&type);
       if (retain) {
         retained_types.Add(type);
       } else {
+        type.ClearCanonical();
         dropped_type_count_++;
       }
     }
@@ -1564,12 +1575,13 @@
     CanonicalTypeArgumentsSet typeargs_table(
         Z, object_store->canonical_type_arguments());
     typeargs_array = HashTables::ToArray(typeargs_table, false);
-    for (intptr_t i = 0; i < (typeargs_array.Length() - 1); i++) {
+    for (intptr_t i = 0; i < typeargs_array.Length(); i++) {
       typeargs ^= typeargs_array.At(i);
       bool retain = typeargs_to_retain_.HasKey(&typeargs);
       if (retain) {
         retained_typeargs.Add(typeargs);
       } else {
+        typeargs.ClearCanonical();
         dropped_typearg_count_++;
       }
     }
@@ -1591,21 +1603,6 @@
   object_store->set_canonical_type_arguments(typeargs_table.Release());
 }
 
-void Precompiler::DropScriptData() {
-  Library& lib = Library::Handle(Z);
-  Array& scripts = Array::Handle(Z);
-  Script& script = Script::Handle(Z);
-  for (intptr_t i = 0; i < libraries_.Length(); i++) {
-    lib ^= libraries_.At(i);
-    scripts = lib.LoadedScripts();
-    for (intptr_t j = 0; j < scripts.Length(); j++) {
-      script ^= scripts.At(j);
-      script.set_compile_time_constants(Array::null_array());
-      script.set_source(String::null_string());
-    }
-  }
-}
-
 void Precompiler::TraceTypesFromRetainedClasses() {
   auto& lib = Library::Handle(Z);
   auto& cls = Class::Handle(Z);
@@ -1728,6 +1725,8 @@
   Array& scripts = Array::Handle(Z);
   Script& script = Script::Handle(Z);
   KernelProgramInfo& program_info = KernelProgramInfo::Handle(Z);
+  const TypedData& null_typed_data = TypedData::Handle(Z);
+  const KernelProgramInfo& null_info = KernelProgramInfo::Handle(Z);
 
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
     lib ^= libraries_.At(i);
@@ -1761,11 +1760,6 @@
       }
       dict.SetAt(j, Object::null_object());
     }
-    lib.RehashDictionary(dict, used * 4 / 3 + 1);
-    if (!(retain_root_library_caches_ &&
-          (lib.raw() == I->object_store()->root_library()))) {
-      lib.DropDependenciesAndCaches();
-    }
 
     scripts = lib.LoadedScripts();
     if (!scripts.IsNull()) {
@@ -1774,17 +1768,34 @@
         program_info = script.kernel_program_info();
         if (!program_info.IsNull()) {
           program_info.set_constants(Array::null_array());
+          program_info.set_scripts(Array::null_array());
+          program_info.set_libraries_cache(Array::null_array());
+          program_info.set_classes_cache(Array::null_array());
+          program_info.set_bytecode_component(Array::null_array());
         }
+        script.set_resolved_url(String::null_string());
+        script.set_compile_time_constants(Array::null_array());
+        script.set_line_starts(null_typed_data);
+        script.set_debug_positions(Array::null_array());
+        script.set_yield_positions(Array::null_array());
+        script.set_kernel_program_info(null_info);
+        script.set_source(String::null_string());
       }
     }
+
+    lib.RehashDictionary(dict, used * 4 / 3 + 1);
+    if (!(retain_root_library_caches_ &&
+          (lib.raw() == I->object_store()->root_library()))) {
+      lib.DropDependenciesAndCaches();
+    }
   }
 }
 
 void Precompiler::DropClasses() {
   Class& cls = Class::Handle(Z);
   Array& constants = Array::Handle(Z);
+  const Script& null_script = Script::Handle(Z);
 
-#if defined(DEBUG)
   // 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
   // corpses because the class table entry may be used to find the size of
@@ -1792,7 +1803,6 @@
   // we continue.
   I->heap()->CollectAllGarbage();
   I->heap()->WaitForSweeperTasks(T);
-#endif
 
   ClassTable* class_table = I->class_table();
   intptr_t num_cids = class_table->NumCids();
@@ -1820,7 +1830,7 @@
     constants = cls.constants();
     ASSERT(constants.Length() == 0);
 
-#if defined(DEBUG)
+#if !defined(PRODUCT)
     intptr_t instances =
         class_table->StatsWithUpdatedSize(cid)->post_gc.new_count +
         class_table->StatsWithUpdatedSize(cid)->post_gc.old_count;
@@ -1835,10 +1845,9 @@
       THR_Print("Dropping class %" Pd " %s\n", cid, cls.ToCString());
     }
 
-#if defined(DEBUG)
     class_table->Unregister(cid);
-#endif
     cls.set_id(kIllegalCid);  // We check this when serializing.
+    cls.set_script(null_script);
   }
 }
 
@@ -1849,6 +1858,7 @@
       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);
@@ -1883,10 +1893,10 @@
       retained_libraries.Add(lib);
     } else {
       toplevel_class = lib.toplevel_class();
-#if defined(DEBUG)
+
       I->class_table()->Unregister(toplevel_class.id());
-#endif
       toplevel_class.set_id(kIllegalCid);  // We check this when serializing.
+      toplevel_class.set_script(null_script);
 
       dropped_library_count_++;
       lib.set_index(-1);
@@ -1914,6 +1924,7 @@
       if (!function.HasCode()) {
         return;
       }
+
       code_ = function.CurrentCode();
       table_ = code_.static_calls_target_table();
       StaticCallsTable static_calls(table_);
@@ -1999,7 +2010,9 @@
 
     void SwitchPool(const ObjectPool& pool) {
       for (intptr_t i = 0; i < pool.Length(); i++) {
-        if (pool.TypeAt(i) != ObjectPool::kTaggedObject) continue;
+        if (pool.TypeAt(i) != ObjectPool::EntryType::kTaggedObject) {
+          continue;
+        }
         entry_ = pool.ObjectAt(i);
         if (entry_.IsICData()) {
           // The only IC calls generated by precompilation are for switchable
@@ -2133,11 +2146,6 @@
       str = Symbols::New(T, str);
       str = obfuscator.Rename(str, /*atomic=*/true);
       script.set_url(str);
-
-      str = script.resolved_url();
-      str = Symbols::New(T, str);
-      str = obfuscator.Rename(str, /*atomic=*/true);
-      script.set_resolved_url(str);
     }
 
     Library& lib = Library::Handle();
@@ -2259,9 +2267,6 @@
   }
   bool is_compiled = false;
   Zone* const zone = thread()->zone();
-#ifndef PRODUCT
-  TimelineStream* compiler_timeline = Timeline::GetCompilerStream();
-#endif  // !PRODUCT
   HANDLESCOPE(thread());
 
   // We may reattempt compilation if the function needs to be assembled using
@@ -2286,10 +2291,8 @@
 
       {
         ic_data_array = new (zone) ZoneGrowableArray<const ICData*>();
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(), compiler_timeline,
-                                  "BuildFlowGraph");
-#endif  // !PRODUCT
+
+        TIMELINE_DURATION(thread(), CompilerVerbose, "BuildFlowGraph");
         flow_graph =
             pipeline->BuildFlowGraph(zone, parsed_function(), ic_data_array,
                                      Compiler::kNoOSRDeoptId, optimized());
@@ -2314,13 +2317,9 @@
       pass_state.block_scheduler = &block_scheduler;
       pass_state.reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized());
-      NOT_IN_PRODUCT(pass_state.compiler_timeline = compiler_timeline);
 
       if (optimized()) {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(), compiler_timeline,
-                                  "OptimizationPasses");
-#endif  // !PRODUCT
+        TIMELINE_DURATION(thread(), CompilerVerbose, "OptimizationPasses");
 
         pass_state.inline_id_to_function.Add(&function);
         // We do not add the token position now because we don't know the
@@ -2344,12 +2343,12 @@
 
       ASSERT(!FLAG_use_bare_instructions || precompiler_ != nullptr);
 
-      ObjectPoolWrapper object_pool;
-      ObjectPoolWrapper* active_object_pool_wrapper =
+      ObjectPoolBuilder object_pool;
+      ObjectPoolBuilder* active_object_pool_builder =
           FLAG_use_bare_instructions
-              ? precompiler_->global_object_pool_wrapper()
+              ? precompiler_->global_object_pool_builder()
               : &object_pool;
-      Assembler assembler(active_object_pool_wrapper, use_far_branches);
+      Assembler assembler(active_object_pool_builder, use_far_branches);
 
       CodeStatistics* function_stats = NULL;
       if (FLAG_print_instruction_stats) {
@@ -2364,17 +2363,12 @@
           pass_state.inline_id_to_token_pos, pass_state.caller_inline_id,
           ic_data_array, function_stats);
       {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(), compiler_timeline, "CompileGraph");
-#endif  // !PRODUCT
+        TIMELINE_DURATION(thread(), CompilerVerbose, "CompileGraph");
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation(flow_graph);
       }
       {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(), compiler_timeline,
-                                  "FinalizeCompilation");
-#endif  // !PRODUCT
+        TIMELINE_DURATION(thread(), CompilerVerbose, "FinalizeCompilation");
         ASSERT(thread()->IsMutatorThread());
         FinalizeCompilation(&assembler, &graph_compiler, flow_graph,
                             function_stats);
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 9454afc..28c0a67 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -247,9 +247,9 @@
     return get_runtime_type_is_unique_;
   }
 
-  ObjectPoolWrapper* global_object_pool_wrapper() {
+  compiler::ObjectPoolBuilder* global_object_pool_builder() {
     ASSERT(FLAG_use_bare_instructions);
-    return &global_object_pool_wrapper_;
+    return &global_object_pool_builder_;
   }
 
   static Precompiler* Instance() { return singleton_; }
@@ -293,7 +293,6 @@
   void TraceTypesFromRetainedClasses();
   void DropTypes();
   void DropTypeArguments();
-  void DropScriptData();
   void DropMetadata();
   void DropLibraryEntries();
   void DropClasses();
@@ -331,7 +330,7 @@
   intptr_t dropped_type_count_;
   intptr_t dropped_library_count_;
 
-  ObjectPoolWrapper global_object_pool_wrapper_;
+  compiler::ObjectPoolBuilder global_object_pool_builder_;
   GrowableObjectArray& libraries_;
   const GrowableObjectArray& pending_functions_;
   SymbolSet sent_selectors_;
diff --git a/runtime/vm/compiler/asm_intrinsifier.cc b/runtime/vm/compiler/asm_intrinsifier.cc
new file mode 100644
index 0000000..6cc847a
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier.cc
@@ -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.
+// Class for intrinsifying functions.
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/compiler/asm_intrinsifier.h"
+
+namespace dart {
+namespace compiler {
+
+#if !defined(TARGET_ARCH_DBC)
+
+void AsmIntrinsifier::String_identityHash(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  String_getHashCode(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_identityHash(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Double_hashCode(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::RegExp_ExecuteMatch(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body,
+                                                /*sticky=*/false);
+}
+
+void AsmIntrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body,
+                                                /*sticky=*/true);
+}
+
+#endif  // !defined(TARGET_ARCH_DBC)
+
+}  // 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
new file mode 100644
index 0000000..9f7e5d7
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Class for intrinsifying functions.
+
+#ifndef RUNTIME_VM_COMPILER_ASM_INTRINSIFIER_H_
+#define RUNTIME_VM_COMPILER_ASM_INTRINSIFIER_H_
+
+#include "vm/allocation.h"
+#include "vm/compiler/recognized_methods_list.h"
+
+namespace dart {
+
+// Forward declarations.
+class FlowGraphCompiler;
+class Function;
+class TargetEntryInstr;
+class ParsedFunction;
+class FlowGraph;
+
+namespace compiler {
+class Assembler;
+class Label;
+
+class AsmIntrinsifier : public AllStatic {
+ public:
+  static intptr_t ParameterSlotFromSp();
+
+  static void IntrinsicCallPrologue(Assembler* assembler);
+  static void IntrinsicCallEpilogue(Assembler* assembler);
+
+ private:
+  friend class Intrinsifier;
+
+  // The "_A" value used in the intrinsification of
+  // `runtime/lib/math_patch.dart:_Random._nextState()`
+  static const int64_t kRandomAValue = 0xffffda61;
+
+  static bool CanIntrinsify(const Function& function);
+
+#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp)             \
+  static void enum_name(Assembler* assembler, Label* normal_ir_body);
+  ALL_INTRINSICS_LIST(DECLARE_FUNCTION)
+
+  // On DBC all intrinsics are handled the same way.
+#if defined(TARGET_ARCH_DBC)
+  GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
+#endif  // defined(TARGET_ARCH_DBC)
+
+#undef DECLARE_FUNCTION
+
+  static void IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                           Label* normal_ir_body,
+                                           bool sticky);
+};
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_ASM_INTRINSIFIER_H_
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
new file mode 100644
index 0000000..c00607e
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -0,0 +1,2280 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"  // Needed here to get TARGET_ARCH_ARM.
+#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
+#include "vm/compiler/asm_intrinsifier.h"
+#include "vm/compiler/assembler/assembler.h"
+
+namespace dart {
+namespace compiler {
+
+// When entering intrinsics code:
+// R4: Arguments descriptor
+// LR: Return address
+// The R4 register can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The FP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_arm.h) must be preserved.
+
+#define __ assembler->
+
+intptr_t AsmIntrinsifier::ParameterSlotFromSp() {
+  return -1;
+}
+
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
+void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+
+  // Save LR by moving it to a callee saved temporary register.
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->mov(CALLEE_SAVED_TEMP, Operand(LR));
+}
+
+void AsmIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  // Restore LR.
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->mov(LR, Operand(CALLEE_SAVED_TEMP));
+}
+
+// Allocate a GrowableObjectArray:: using the backing array specified.
+// On stack: type argument (+1), data (+0).
+void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  // The newly allocated object is returned in R0.
+  const intptr_t kTypeArgumentsOffset = 1 * target::kWordSize;
+  const intptr_t kArrayOffset = 0 * target::kWordSize;
+
+  // Try allocating in new space.
+  const Class& cls = GrowableObjectArrayClass();
+  __ TryAllocate(cls, normal_ir_body, R0, R1);
+
+  // Store backing array object in growable array object.
+  __ ldr(R1, Address(SP, kArrayOffset));  // Data argument.
+  // R0 is new, no barrier needed.
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::GrowableObjectArray::data_offset()), R1);
+
+  // R0: new growable array object start as a tagged pointer.
+  // Store the type argument field in the growable array object.
+  __ ldr(R1, Address(SP, kTypeArgumentsOffset));  // Type argument.
+  __ StoreIntoObjectNoBarrier(
+      R0,
+      FieldAddress(R0, target::GrowableObjectArray::type_arguments_offset()),
+      R1);
+
+  // Set the length field in the growable array object to 0.
+  __ LoadImmediate(R1, 0);
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::GrowableObjectArray::length_offset()), R1);
+  __ Ret();  // Returns the newly allocated object in R0.
+
+  __ Bind(normal_ir_body);
+}
+
+#define TYPED_ARRAY_ALLOCATION(cid, max_len, scale_shift)                      \
+  Label fall_through;                                                          \
+  const intptr_t kArrayLengthStackOffset = 0 * target::kWordSize;              \
+  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R2, cid));                      \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, normal_ir_body));                 \
+  __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
+  /* Check that length is a positive Smi. */                                   \
+  /* R2: requested array length argument. */                                   \
+  __ tst(R2, Operand(kSmiTagMask));                                            \
+  __ b(normal_ir_body, NE);                                                    \
+  __ CompareImmediate(R2, 0);                                                  \
+  __ b(normal_ir_body, LT);                                                    \
+  __ SmiUntag(R2);                                                             \
+  /* Check for maximum allowed length. */                                      \
+  /* R2: untagged array length. */                                             \
+  __ CompareImmediate(R2, max_len);                                            \
+  __ b(normal_ir_body, GT);                                                    \
+  __ mov(R2, Operand(R2, LSL, scale_shift));                                   \
+  const intptr_t fixed_size_plus_alignment_padding =                           \
+      target::TypedData::InstanceSize() +                                      \
+      target::ObjectAlignment::kObjectAlignment - 1;                           \
+  __ AddImmediate(R2, fixed_size_plus_alignment_padding);                      \
+  __ bic(R2, R2, Operand(target::ObjectAlignment::kObjectAlignment - 1));      \
+  __ ldr(R0, Address(THR, target::Thread::top_offset()));                      \
+                                                                               \
+  /* R2: allocation size. */                                                   \
+  __ adds(R1, R0, Operand(R2));                                                \
+  __ b(normal_ir_body, CS); /* Fail on unsigned overflow. */                   \
+                                                                               \
+  /* Check if the allocation fits into the remaining space. */                 \
+  /* R0: potential new object start. */                                        \
+  /* R1: potential next object start. */                                       \
+  /* R2: allocation size. */                                                   \
+  __ ldr(IP, Address(THR, target::Thread::end_offset()));                      \
+  __ cmp(R1, Operand(IP));                                                     \
+  __ b(normal_ir_body, CS);                                                    \
+                                                                               \
+  /* Successfully allocated the object(s), now update top to point to */       \
+  /* next object start and initialize the object. */                           \
+  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));                      \
+  __ str(R1, Address(THR, target::Thread::top_offset()));                      \
+  __ AddImmediate(R0, kHeapObjectTag);                                         \
+  /* Initialize the tags. */                                                   \
+  /* R0: new object start as a tagged pointer. */                              \
+  /* R1: new object end address. */                                            \
+  /* R2: allocation size. */                                                   \
+  /* R4: allocation stats address */                                           \
+  {                                                                            \
+    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);            \
+    __ mov(R3,                                                                 \
+           Operand(R2, LSL,                                                    \
+                   target::RawObject::kTagBitsSizeTagPos -                     \
+                       target::ObjectAlignment::kObjectAlignmentLog2),         \
+           LS);                                                                \
+    __ mov(R3, Operand(0), HI);                                                \
+                                                                               \
+    /* Get the class index and insert it into the tags. */                     \
+    uint32_t tags =                                                            \
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);        \
+    __ LoadImmediate(TMP, tags);                                               \
+    __ orr(R3, R3, Operand(TMP));                                              \
+    __ str(R3, FieldAddress(R0, target::Object::tags_offset())); /* Tags. */   \
+  }                                                                            \
+  /* Set the length field. */                                                  \
+  /* R0: new object start as a tagged pointer. */                              \
+  /* R1: new object end address. */                                            \
+  /* R2: allocation size. */                                                   \
+  /* R4: allocation stats address. */                                          \
+  __ ldr(R3, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
+  __ StoreIntoObjectNoBarrier(                                                 \
+      R0, FieldAddress(R0, target::TypedData::length_offset()), R3);           \
+  /* Initialize all array elements to 0. */                                    \
+  /* R0: new object start as a tagged pointer. */                              \
+  /* R1: new object end address. */                                            \
+  /* R2: allocation size. */                                                   \
+  /* R3: iterator which initially points to the start of the variable */       \
+  /* R4: allocation stats address */                                           \
+  /* R8, R9: zero. */                                                          \
+  /* data area to be initialized. */                                           \
+  __ LoadImmediate(R8, 0);                                                     \
+  __ mov(R9, Operand(R8));                                                     \
+  __ AddImmediate(R3, R0, target::TypedData::InstanceSize() - 1);              \
+  Label init_loop;                                                             \
+  __ Bind(&init_loop);                                                         \
+  __ AddImmediate(R3, 2 * target::kWordSize);                                  \
+  __ cmp(R3, Operand(R1));                                                     \
+  __ strd(R8, R9, R3, -2 * target::kWordSize, LS);                             \
+  __ b(&init_loop, CC);                                                        \
+  __ str(R8, Address(R3, -2 * target::kWordSize), HI);                         \
+                                                                               \
+  NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2));                 \
+  __ Ret();                                                                    \
+  __ Bind(normal_ir_body);
+
+static int GetScaleFactor(intptr_t size) {
+  switch (size) {
+    case 1:
+      return 0;
+    case 2:
+      return 1;
+    case 4:
+      return 2;
+    case 8:
+      return 3;
+    case 16:
+      return 4;
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+#define TYPED_DATA_ALLOCATOR(clazz)                                            \
+  void AsmIntrinsifier::TypedData_##clazz##_factory(Assembler* assembler,      \
+                                                    Label* normal_ir_body) {   \
+    intptr_t size = TypedDataElementSizeInBytes(kTypedData##clazz##Cid);       \
+    intptr_t max_len = TypedDataMaxNewSpaceElements(kTypedData##clazz##Cid);   \
+    int shift = GetScaleFactor(size);                                          \
+    TYPED_ARRAY_ALLOCATION(kTypedData##clazz##Cid, max_len, shift);            \
+  }
+CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
+#undef TYPED_DATA_ALLOCATOR
+
+// Loads args from stack into R0 and R1
+// Tests if they are smis, jumps to label not_smi if not.
+static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
+  __ ldr(R0, Address(SP, +0 * target::kWordSize));
+  __ ldr(R1, Address(SP, +1 * target::kWordSize));
+  __ orr(TMP, R0, Operand(R1));
+  __ tst(TMP, Operand(kSmiTagMask));
+  __ b(not_smi, NE);
+}
+
+void AsmIntrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
+  __ adds(R0, R0, Operand(R1));                      // Adds.
+  __ bx(LR, VC);                                     // Return if no overflow.
+  // Otherwise fall through.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ subs(R0, R0, Operand(R1));  // Subtract.
+  __ bx(LR, VC);                 // Return if no overflow.
+  // Otherwise fall through.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ subs(R0, R1, Operand(R0));  // Subtract.
+  __ bx(LR, VC);                 // Return if no overflow.
+  // Otherwise fall through.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
+  __ SmiUntag(R0);           // Untags R0. We only want result shifted by one.
+  __ smull(R0, IP, R0, R1);  // IP:R0 <- R0 * R1.
+  __ cmp(IP, Operand(R0, ASR, 31));
+  __ bx(LR, EQ);
+  __ Bind(normal_ir_body);  // Fall through on overflow.
+}
+
+void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
+}
+
+// Optimizations:
+// - result is 0 if:
+//   - left is 0
+//   - left equals right
+// - result is left if
+//   - left > 0 && left < right
+// R1: Tagged left (dividend).
+// R0: Tagged right (divisor).
+// Returns:
+//   R1: Untagged fallthrough result (remainder to be adjusted), or
+//   R0: Tagged return result (remainder).
+static void EmitRemainderOperation(Assembler* assembler) {
+  Label modulo;
+  const Register left = R1;
+  const Register right = R0;
+  const Register result = R1;
+  const Register tmp = R2;
+  ASSERT(left == result);
+
+  // Check for quick zero results.
+  __ cmp(left, Operand(0));
+  __ mov(R0, Operand(0), EQ);
+  __ bx(LR, EQ);  // left is 0? Return 0.
+  __ cmp(left, Operand(right));
+  __ mov(R0, Operand(0), EQ);
+  __ bx(LR, EQ);  // left == right? Return 0.
+
+  // Check if result should be left.
+  __ cmp(left, Operand(0));
+  __ b(&modulo, LT);
+  // left is positive.
+  __ cmp(left, Operand(right));
+  // left is less than right, result is left.
+  __ mov(R0, Operand(left), LT);
+  __ bx(LR, LT);
+
+  __ Bind(&modulo);
+  // result <- left - right * (left / right)
+  __ SmiUntag(left);
+  __ SmiUntag(right);
+
+  __ IntegerDivide(tmp, left, right, D1, D0);
+
+  __ mls(result, right, tmp, left);  // result <- left - right * TMP
+}
+
+// Implementation:
+//  res = left % right;
+//  if (res < 0) {
+//    if (right < 0) {
+//      res = res - right;
+//    } else {
+//      res = res + right;
+//    }
+//  }
+void AsmIntrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  if (!TargetCPUFeatures::can_divide()) {
+    return;
+  }
+  // Check to see if we have integer division
+  __ ldr(R1, Address(SP, +0 * target::kWordSize));
+  __ ldr(R0, Address(SP, +1 * target::kWordSize));
+  __ orr(TMP, R0, Operand(R1));
+  __ tst(TMP, Operand(kSmiTagMask));
+  __ b(normal_ir_body, NE);
+  // R1: Tagged left (dividend).
+  // R0: Tagged right (divisor).
+  // Check if modulo by zero -> exception thrown in main function.
+  __ cmp(R0, Operand(0));
+  __ b(normal_ir_body, EQ);
+  EmitRemainderOperation(assembler);
+  // Untagged right in R0. Untagged remainder result in R1.
+
+  __ cmp(R1, Operand(0));
+  __ mov(R0, Operand(R1, LSL, 1), GE);  // Tag and move result to R0.
+  __ bx(LR, GE);
+
+  // Result is negative, adjust it.
+  __ cmp(R0, Operand(0));
+  __ sub(R0, R1, Operand(R0), LT);
+  __ add(R0, R1, Operand(R0), GE);
+  __ SmiTag(R0);
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  if (!TargetCPUFeatures::can_divide()) {
+    return;
+  }
+  // Check to see if we have integer division
+
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ cmp(R0, Operand(0));
+  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
+
+  __ SmiUntag(R0);
+  __ SmiUntag(R1);
+
+  __ IntegerDivide(R0, R1, R0, D1, D0);
+
+  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
+  // cannot tag the result.
+  __ CompareImmediate(R0, 0x40000000);
+  __ SmiTag(R0, NE);  // Not equal. Okay to tag and return.
+  __ bx(LR, NE);      // Return.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_negate(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, +0 * target::kWordSize));  // Grab first argument.
+  __ tst(R0, Operand(kSmiTagMask));                 // Test for Smi.
+  __ b(normal_ir_body, NE);
+  __ rsbs(R0, R0, Operand(0));  // R0 is a Smi. R0 <- 0 - R0.
+  __ bx(LR, VC);  // Return if there wasn't overflow, fall through otherwise.
+  // R0 is not a Smi. Fall through.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
+  __ and_(R0, R0, Operand(R1));
+
+  __ Ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
+  __ orr(R0, R0, Operand(R1));
+
+  __ Ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
+  __ eor(R0, R0, Operand(R1));
+
+  __ Ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
+  ASSERT(kSmiTagShift == 1);
+  ASSERT(kSmiTag == 0);
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ CompareImmediate(R0, target::ToRawSmi(target::Smi::kBits));
+  __ b(normal_ir_body, HI);
+
+  __ SmiUntag(R0);
+
+  // Check for overflow by shifting left and shifting back arithmetically.
+  // If the result is different from the original, there was overflow.
+  __ mov(IP, Operand(R1, LSL, R0));
+  __ cmp(R1, Operand(IP, ASR, R0));
+
+  // No overflow, result in R0.
+  __ mov(R0, Operand(R1, LSL, R0), EQ);
+  __ bx(LR, EQ);
+
+  // Arguments are Smi but the shift produced an overflow to Mint.
+  __ CompareImmediate(R1, 0);
+  __ b(normal_ir_body, LT);
+  __ SmiUntag(R1);
+
+  // Pull off high bits that will be shifted off of R1 by making a mask
+  // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back.
+  // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0)
+  // lo bits = R1 << R0
+  __ LoadImmediate(NOTFP, 1);
+  __ mov(NOTFP, Operand(NOTFP, LSL, R0));  // NOTFP <- 1 << R0
+  __ sub(NOTFP, NOTFP, Operand(1));        // NOTFP <- NOTFP - 1
+  __ rsb(R3, R0, Operand(32));             // R3 <- 32 - R0
+  __ mov(NOTFP, Operand(NOTFP, LSL, R3));  // NOTFP <- NOTFP << R3
+  __ and_(NOTFP, R1, Operand(NOTFP));      // NOTFP <- NOTFP & R1
+  __ mov(NOTFP, Operand(NOTFP, LSR, R3));  // NOTFP <- NOTFP >> R3
+  // Now NOTFP has the bits that fall off of R1 on a left shift.
+  __ mov(R1, Operand(R1, LSL, R0));  // R1 gets the low bits.
+
+  const Class& mint_class = MintClass();
+  __ TryAllocate(mint_class, normal_ir_body, R0, R2);
+
+  __ str(R1, FieldAddress(R0, target::Mint::value_offset()));
+  __ str(NOTFP,
+         FieldAddress(R0, target::Mint::value_offset() + target::kWordSize));
+  __ Ret();
+  __ Bind(normal_ir_body);
+}
+
+static void Get64SmiOrMint(Assembler* assembler,
+                           Register res_hi,
+                           Register res_lo,
+                           Register reg,
+                           Label* not_smi_or_mint) {
+  Label not_smi, done;
+  __ tst(reg, Operand(kSmiTagMask));
+  __ b(&not_smi, NE);
+  __ SmiUntag(reg);
+
+  // Sign extend to 64 bit
+  __ mov(res_lo, Operand(reg));
+  __ mov(res_hi, Operand(res_lo, ASR, 31));
+  __ b(&done);
+
+  __ Bind(&not_smi);
+  __ CompareClassId(reg, kMintCid, res_lo);
+  __ b(not_smi_or_mint, NE);
+
+  // Mint.
+  __ ldr(res_lo, FieldAddress(reg, target::Mint::value_offset()));
+  __ ldr(res_hi,
+         FieldAddress(reg, target::Mint::value_offset() + target::kWordSize));
+  __ Bind(&done);
+}
+
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
+  Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
+  TestBothArgumentsSmis(assembler, &try_mint_smi);
+  // R0 contains the right argument. R1 contains left argument
+
+  __ cmp(R1, Operand(R0));
+  __ b(&is_true, true_condition);
+  __ Bind(&is_false);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ Ret();
+  __ Bind(&is_true);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ Ret();
+
+  // 64-bit comparison
+  Condition hi_true_cond, hi_false_cond, lo_false_cond;
+  switch (true_condition) {
+    case LT:
+    case LE:
+      hi_true_cond = LT;
+      hi_false_cond = GT;
+      lo_false_cond = (true_condition == LT) ? CS : HI;
+      break;
+    case GT:
+    case GE:
+      hi_true_cond = GT;
+      hi_false_cond = LT;
+      lo_false_cond = (true_condition == GT) ? LS : CC;
+      break;
+    default:
+      UNREACHABLE();
+      hi_true_cond = hi_false_cond = lo_false_cond = VS;
+  }
+
+  __ Bind(&try_mint_smi);
+  // Get left as 64 bit integer.
+  Get64SmiOrMint(assembler, R3, R2, R1, normal_ir_body);
+  // Get right as 64 bit integer.
+  Get64SmiOrMint(assembler, NOTFP, R8, R0, normal_ir_body);
+  // R3: left high.
+  // R2: left low.
+  // NOTFP: right high.
+  // R8: right low.
+
+  __ cmp(R3, Operand(NOTFP));  // Compare left hi, right high.
+  __ b(&is_false, hi_false_cond);
+  __ b(&is_true, hi_true_cond);
+  __ cmp(R2, Operand(R8));  // Compare left lo, right lo.
+  __ b(&is_false, lo_false_cond);
+  // Else is true.
+  __ b(&is_true);
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LT);
+}
+
+void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Integer_greaterThanFromInt(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GT);
+}
+
+void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LE);
+}
+
+void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GE);
+}
+
+// This is called for Smi and Mint receivers. The right argument
+// can be Smi, Mint or double.
+void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label true_label, check_for_mint;
+  // For integer receiver '===' check first.
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));
+  __ cmp(R0, Operand(R1));
+  __ b(&true_label, EQ);
+
+  __ orr(R2, R0, Operand(R1));
+  __ tst(R2, Operand(kSmiTagMask));
+  __ b(&check_for_mint, NE);  // If R0 or R1 is not a smi do Mint checks.
+
+  // Both arguments are smi, '===' is good enough.
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ Ret();
+  __ Bind(&true_label);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ Ret();
+
+  // At least one of the arguments was not Smi.
+  Label receiver_not_smi;
+  __ Bind(&check_for_mint);
+
+  __ tst(R1, Operand(kSmiTagMask));  // Check receiver.
+  __ b(&receiver_not_smi, NE);
+
+  // Left (receiver) is Smi, return false if right is not Double.
+  // Note that an instance of Mint never contains a value that can be
+  // represented by Smi.
+
+  __ CompareClassId(R0, kDoubleCid, R2);
+  __ b(normal_ir_body, EQ);
+  __ LoadObject(R0,
+                CastHandle<Object>(FalseObject()));  // Smi == Mint -> false.
+  __ Ret();
+
+  __ Bind(&receiver_not_smi);
+  // R1:: receiver.
+
+  __ CompareClassId(R1, kMintCid, R2);
+  __ b(normal_ir_body, NE);
+  // Receiver is Mint, return false if right is Smi.
+  __ tst(R0, Operand(kSmiTagMask));
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()), EQ);
+  __ bx(LR, EQ);
+  // TODO(srdjan): Implement Mint == Mint comparison.
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_equal(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // Shift amount in R0. Value to shift in R1.
+
+  // Fall through if shift amount is negative.
+  __ SmiUntag(R0);
+  __ CompareImmediate(R0, 0);
+  __ b(normal_ir_body, LT);
+
+  // If shift amount is bigger than 31, set to 31.
+  __ CompareImmediate(R0, 0x1F);
+  __ LoadImmediate(R0, 0x1F, GT);
+  __ SmiUntag(R1);
+  __ mov(R0, Operand(R1, ASR, R0));
+  __ SmiTag(R0);
+  __ Ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ mvn(R0, Operand(R0));
+  __ bic(R0, R0, Operand(kSmiTagMask));  // Remove inverted smi-tag.
+  __ Ret();
+}
+
+void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ SmiUntag(R0);
+  // XOR with sign bit to complement bits if value is negative.
+  __ eor(R0, R0, Operand(R0, ASR, 31));
+  __ clz(R0, R0);
+  __ rsb(R0, R0, Operand(32));
+  __ SmiTag(R0);
+  __ Ret();
+}
+
+void AsmIntrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
+  __ ldrd(R0, R1, SP, 2 * target::kWordSize);
+  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldrd(R2, R3, SP, 0 * target::kWordSize);
+  __ SmiUntag(R3);
+  // R4 = n ~/ _DIGIT_BITS
+  __ Asr(R4, R3, Operand(5));
+  // R8 = &x_digits[0]
+  __ add(R8, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &x_digits[x_used]
+  __ add(NOTFP, R8, Operand(R0, LSL, 1));
+  // R6 = &r_digits[1]
+  __ add(R6, R2,
+         Operand(target::TypedData::data_offset() - kHeapObjectTag +
+                 kBytesPerBigIntDigit));
+  // R6 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
+  __ add(R4, R4, Operand(R0, ASR, 1));
+  __ add(R6, R6, Operand(R4, LSL, 2));
+  // R1 = n % _DIGIT_BITS
+  __ and_(R1, R3, Operand(31));
+  // R0 = 32 - R1
+  __ rsb(R0, R1, Operand(32));
+  __ mov(R9, Operand(0));
+  Label loop;
+  __ Bind(&loop);
+  __ ldr(R4, Address(NOTFP, -kBytesPerBigIntDigit, Address::PreIndex));
+  __ orr(R9, R9, Operand(R4, LSR, R0));
+  __ str(R9, Address(R6, -kBytesPerBigIntDigit, Address::PreIndex));
+  __ mov(R9, Operand(R4, LSL, R1));
+  __ teq(NOTFP, Operand(R8));
+  __ b(&loop, NE);
+  __ str(R9, Address(R6, -kBytesPerBigIntDigit, Address::PreIndex));
+  __ LoadObject(R0, NullObject());
+  __ Ret();
+}
+
+void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
+  __ ldrd(R0, R1, SP, 2 * target::kWordSize);
+  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldrd(R2, R3, SP, 0 * target::kWordSize);
+  __ SmiUntag(R3);
+  // R4 = n ~/ _DIGIT_BITS
+  __ Asr(R4, R3, Operand(5));
+  // R6 = &r_digits[0]
+  __ add(R6, R2, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+  // NOTFP = &x_digits[n ~/ _DIGIT_BITS]
+  __ add(NOTFP, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+  __ add(NOTFP, NOTFP, Operand(R4, LSL, 2));
+  // R8 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
+  __ add(R4, R4, Operand(1));
+  __ rsb(R4, R4, Operand(R0, ASR, 1));
+  __ add(R8, R6, Operand(R4, LSL, 2));
+  // R1 = n % _DIGIT_BITS
+  __ and_(R1, R3, Operand(31));
+  // R0 = 32 - R1
+  __ rsb(R0, R1, Operand(32));
+  // R9 = x_digits[n ~/ _DIGIT_BITS] >> (n % _DIGIT_BITS)
+  __ ldr(R9, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
+  __ mov(R9, Operand(R9, LSR, R1));
+  Label loop_entry;
+  __ b(&loop_entry);
+  Label loop;
+  __ Bind(&loop);
+  __ ldr(R4, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
+  __ orr(R9, R9, Operand(R4, LSL, R0));
+  __ str(R9, Address(R6, kBytesPerBigIntDigit, Address::PostIndex));
+  __ mov(R9, Operand(R4, LSR, R1));
+  __ Bind(&loop_entry);
+  __ teq(R6, Operand(R8));
+  __ b(&loop, NE);
+  __ str(R9, Address(R6, 0));
+  __ LoadObject(R0, NullObject());
+  __ Ret();
+}
+
+void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absAdd(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  // R0 = used, R1 = digits
+  __ ldrd(R0, R1, SP, 3 * target::kWordSize);
+  // R1 = &digits[0]
+  __ add(R1, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R2 = a_used, R3 = a_digits
+  __ ldrd(R2, R3, SP, 1 * target::kWordSize);
+  // R3 = &a_digits[0]
+  __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R8 = r_digits
+  __ ldr(R8, Address(SP, 0 * target::kWordSize));
+  // R8 = &r_digits[0]
+  __ add(R8, R8, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // NOTFP = &digits[a_used >> 1], a_used is Smi.
+  __ add(NOTFP, R1, Operand(R2, LSL, 1));
+
+  // R6 = &digits[used >> 1], used is Smi.
+  __ add(R6, R1, Operand(R0, LSL, 1));
+
+  __ adds(R4, R4, Operand(0));  // carry flag = 0
+  Label add_loop;
+  __ Bind(&add_loop);
+  // Loop a_used times, a_used > 0.
+  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
+  __ ldr(R9, Address(R3, kBytesPerBigIntDigit, Address::PostIndex));
+  __ adcs(R4, R4, Operand(R9));
+  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
+  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&add_loop, NE);
+
+  Label last_carry;
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ b(&last_carry, EQ);    // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop used - a_used times, used - a_used > 0.
+  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
+  __ adcs(R4, R4, Operand(0));
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&carry_loop, NE);
+
+  __ Bind(&last_carry);
+  __ mov(R4, Operand(0));
+  __ adc(R4, R4, Operand(0));
+  __ str(R4, Address(R8, 0));
+
+  __ LoadObject(R0, NullObject());
+  __ Ret();
+}
+
+void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absSub(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  // R0 = used, R1 = digits
+  __ ldrd(R0, R1, SP, 3 * target::kWordSize);
+  // R1 = &digits[0]
+  __ add(R1, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R2 = a_used, R3 = a_digits
+  __ ldrd(R2, R3, SP, 1 * target::kWordSize);
+  // R3 = &a_digits[0]
+  __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R8 = r_digits
+  __ ldr(R8, Address(SP, 0 * target::kWordSize));
+  // R8 = &r_digits[0]
+  __ add(R8, R8, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // NOTFP = &digits[a_used >> 1], a_used is Smi.
+  __ add(NOTFP, R1, Operand(R2, LSL, 1));
+
+  // R6 = &digits[used >> 1], used is Smi.
+  __ add(R6, R1, Operand(R0, LSL, 1));
+
+  __ subs(R4, R4, Operand(0));  // carry flag = 1
+  Label sub_loop;
+  __ Bind(&sub_loop);
+  // Loop a_used times, a_used > 0.
+  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
+  __ ldr(R9, Address(R3, kBytesPerBigIntDigit, Address::PostIndex));
+  __ sbcs(R4, R4, Operand(R9));
+  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
+  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&sub_loop, NE);
+
+  Label done;
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ b(&done, EQ);          // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop used - a_used times, used - a_used > 0.
+  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
+  __ sbcs(R4, R4, Operand(0));
+  __ teq(R1, Operand(R6));  // Does not affect carry flag.
+  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&carry_loop, NE);
+
+  __ Bind(&done);
+  __ LoadObject(R0, NullObject());
+  __ Ret();
+}
+
+void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulAdd(Uint32List x_digits, int xi,
+  //                    Uint32List m_digits, int i,
+  //                    Uint32List a_digits, int j, int n) {
+  //   uint32_t x = x_digits[xi >> 1];  // xi is Smi.
+  //   if (x == 0 || n == 0) {
+  //     return 1;
+  //   }
+  //   uint32_t* mip = &m_digits[i >> 1];  // i is Smi.
+  //   uint32_t* ajp = &a_digits[j >> 1];  // j is Smi.
+  //   uint32_t c = 0;
+  //   SmiUntag(n);
+  //   do {
+  //     uint32_t mi = *mip++;
+  //     uint32_t aj = *ajp;
+  //     uint64_t t = x*mi + aj + c;  // 32-bit * 32-bit -> 64-bit.
+  //     *ajp++ = low32(t);
+  //     c = high32(t);
+  //   } while (--n > 0);
+  //   while (c != 0) {
+  //     uint64_t t = *ajp + c;
+  //     *ajp++ = low32(t);
+  //     c = high32(t);  // c == 0 or 1.
+  //   }
+  //   return 1;
+  // }
+
+  Label done;
+  // R3 = x, no_op if x == 0
+  __ ldrd(R0, R1, SP, 5 * target::kWordSize);  // R0 = xi as Smi, R1 = x_digits.
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ ldr(R3, FieldAddress(R1, target::TypedData::data_offset()));
+  __ tst(R3, Operand(R3));
+  __ b(&done, EQ);
+
+  // R8 = SmiUntag(n), no_op if n == 0
+  __ ldr(R8, Address(SP, 0 * target::kWordSize));
+  __ Asrs(R8, R8, Operand(kSmiTagSize));
+  __ b(&done, EQ);
+
+  // R4 = mip = &m_digits[i >> 1]
+  __ ldrd(R0, R1, SP, 3 * target::kWordSize);  // R0 = i as Smi, R1 = m_digits.
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ add(R4, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R9 = ajp = &a_digits[j >> 1]
+  __ ldrd(R0, R1, SP, 1 * target::kWordSize);  // R0 = j as Smi, R1 = a_digits.
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ add(R9, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R1 = c = 0
+  __ mov(R1, Operand(0));
+
+  Label muladd_loop;
+  __ Bind(&muladd_loop);
+  // x:   R3
+  // mip: R4
+  // ajp: R9
+  // c:   R1
+  // n:   R8
+
+  // uint32_t mi = *mip++
+  __ ldr(R2, Address(R4, kBytesPerBigIntDigit, Address::PostIndex));
+
+  // uint32_t aj = *ajp
+  __ ldr(R0, Address(R9, 0));
+
+  // uint64_t t = x*mi + aj + c
+  __ umaal(R0, R1, R2, R3);  // R1:R0 = R2*R3 + R1 + R0.
+
+  // *ajp++ = low32(t) = R0
+  __ str(R0, Address(R9, kBytesPerBigIntDigit, Address::PostIndex));
+
+  // c = high32(t) = R1
+
+  // while (--n > 0)
+  __ subs(R8, R8, Operand(1));  // --n
+  __ b(&muladd_loop, NE);
+
+  __ tst(R1, Operand(R1));
+  __ b(&done, EQ);
+
+  // *ajp++ += c
+  __ ldr(R0, Address(R9, 0));
+  __ adds(R0, R0, Operand(R1));
+  __ str(R0, Address(R9, kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&done, CC);
+
+  Label propagate_carry_loop;
+  __ Bind(&propagate_carry_loop);
+  __ ldr(R0, Address(R9, 0));
+  __ adds(R0, R0, Operand(1));
+  __ str(R0, Address(R9, kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&propagate_carry_loop, CS);
+
+  __ Bind(&done);
+  __ mov(R0, Operand(target::ToRawSmi(1)));  // One digit processed.
+  __ Ret();
+}
+
+void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _sqrAdd(Uint32List x_digits, int i,
+  //                    Uint32List a_digits, int used) {
+  //   uint32_t* xip = &x_digits[i >> 1];  // i is Smi.
+  //   uint32_t x = *xip++;
+  //   if (x == 0) return 1;
+  //   uint32_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
+  //   uint32_t aj = *ajp;
+  //   uint64_t t = x*x + aj;
+  //   *ajp++ = low32(t);
+  //   uint64_t c = high32(t);
+  //   int n = ((used - i) >> 1) - 1;  // used and i are Smi.
+  //   while (--n >= 0) {
+  //     uint32_t xi = *xip++;
+  //     uint32_t aj = *ajp;
+  //     uint96_t t = 2*x*xi + aj + c;  // 2-bit * 32-bit * 32-bit -> 65-bit.
+  //     *ajp++ = low32(t);
+  //     c = high64(t);  // 33-bit.
+  //   }
+  //   uint32_t aj = *ajp;
+  //   uint64_t t = aj + c;  // 32-bit + 33-bit -> 34-bit.
+  //   *ajp++ = low32(t);
+  //   *ajp = high32(t);
+  //   return 1;
+  // }
+
+  // R4 = xip = &x_digits[i >> 1]
+  __ ldrd(R2, R3, SP, 2 * target::kWordSize);  // R2 = i as Smi, R3 = x_digits
+  __ add(R3, R3, Operand(R2, LSL, 1));
+  __ add(R4, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R3 = x = *xip++, return if x == 0
+  Label x_zero;
+  __ ldr(R3, Address(R4, kBytesPerBigIntDigit, Address::PostIndex));
+  __ tst(R3, Operand(R3));
+  __ b(&x_zero, EQ);
+
+  // NOTFP = ajp = &a_digits[i]
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));  // a_digits
+  __ add(R1, R1, Operand(R2, LSL, 2));             // j == 2*i, i is Smi.
+  __ add(NOTFP, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R8:R0 = t = x*x + *ajp
+  __ ldr(R0, Address(NOTFP, 0));
+  __ mov(R8, Operand(0));
+  __ umaal(R0, R8, R3, R3);  // R8:R0 = R3*R3 + R8 + R0.
+
+  // *ajp++ = low32(t) = R0
+  __ str(R0, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
+
+  // R8 = low32(c) = high32(t)
+  // R9 = high32(c) = 0
+  __ mov(R9, Operand(0));
+
+  // int n = used - i - 1; while (--n >= 0) ...
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));  // used is Smi
+  __ sub(R6, R0, Operand(R2));
+  __ mov(R0, Operand(2));  // n = used - i - 2; if (n >= 0) ... while (--n >= 0)
+  __ rsbs(R6, R0, Operand(R6, ASR, kSmiTagSize));
+
+  Label loop, done;
+  __ b(&done, MI);
+
+  __ Bind(&loop);
+  // x:   R3
+  // xip: R4
+  // ajp: NOTFP
+  // c:   R9:R8
+  // t:   R2:R1:R0 (not live at loop entry)
+  // n:   R6
+
+  // uint32_t xi = *xip++
+  __ ldr(R2, Address(R4, kBytesPerBigIntDigit, Address::PostIndex));
+
+  // uint96_t t = R9:R8:R0 = 2*x*xi + aj + c
+  __ umull(R0, R1, R2, R3);  // R1:R0 = R2*R3.
+  __ adds(R0, R0, Operand(R0));
+  __ adcs(R1, R1, Operand(R1));
+  __ mov(R2, Operand(0));
+  __ adc(R2, R2, Operand(0));  // R2:R1:R0 = 2*x*xi.
+  __ adds(R0, R0, Operand(R8));
+  __ adcs(R1, R1, Operand(R9));
+  __ adc(R2, R2, Operand(0));     // R2:R1:R0 = 2*x*xi + c.
+  __ ldr(R8, Address(NOTFP, 0));  // R8 = aj = *ajp.
+  __ adds(R0, R0, Operand(R8));
+  __ adcs(R8, R1, Operand(0));
+  __ adc(R9, R2, Operand(0));  // R9:R8:R0 = 2*x*xi + c + aj.
+
+  // *ajp++ = low32(t) = R0
+  __ str(R0, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
+
+  // while (--n >= 0)
+  __ subs(R6, R6, Operand(1));  // --n
+  __ b(&loop, PL);
+
+  __ Bind(&done);
+  // uint32_t aj = *ajp
+  __ ldr(R0, Address(NOTFP, 0));
+
+  // uint64_t t = aj + c
+  __ adds(R8, R8, Operand(R0));
+  __ adc(R9, R9, Operand(0));
+
+  // *ajp = low32(t) = R8
+  // *(ajp + 1) = high32(t) = R9
+  __ strd(R8, R9, NOTFP, 0);
+
+  __ Bind(&x_zero);
+  __ mov(R0, Operand(target::ToRawSmi(1)));  // One digit processed.
+  __ Ret();
+}
+
+void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+  // No unsigned 64-bit / 32-bit divide instruction.
+}
+
+void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
+  //   uint32_t rho = args[_RHO];  // _RHO == 2.
+  //   uint32_t d = digits[i >> 1];  // i is Smi.
+  //   uint64_t t = rho*d;
+  //   args[_MU] = t mod DIGIT_BASE;  // _MU == 4.
+  //   return 1;
+  // }
+
+  // R4 = args
+  __ ldr(R4, Address(SP, 2 * target::kWordSize));  // args
+
+  // R3 = rho = args[2]
+  __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset() +
+                                  2 * kBytesPerBigIntDigit));
+
+  // R2 = digits[i >> 1]
+  __ ldrd(R0, R1, SP, 0 * target::kWordSize);  // R0 = i as Smi, R1 = digits
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ ldr(R2, FieldAddress(R1, target::TypedData::data_offset()));
+
+  // R1:R0 = t = rho*d
+  __ umull(R0, R1, R2, R3);
+
+  // args[4] = t mod DIGIT_BASE = low32(t)
+  __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
+                                  4 * kBytesPerBigIntDigit));
+
+  __ mov(R0, Operand(target::ToRawSmi(1)));  // One digit processed.
+  __ Ret();
+}
+
+// Check if the last argument is a double, jump to label 'is_smi' if smi
+// (easy to convert to double), otherwise jump to label 'not_double_smi',
+// Returns the last argument in R0.
+static void TestLastArgumentIsDouble(Assembler* assembler,
+                                     Label* is_smi,
+                                     Label* not_double_smi) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ tst(R0, Operand(kSmiTagMask));
+  __ b(is_smi, EQ);
+  __ CompareClassId(R0, kDoubleCid, R1);
+  __ b(not_double_smi, NE);
+  // Fall through with Double in R0.
+}
+
+// Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
+// type. Return true or false object in the register R0. Any NaN argument
+// returns false. Any non-double arg1 causes control flow to fall through to the
+// slow case (compiled method body).
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label is_smi, double_op;
+
+    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+    // Both arguments are double, right operand is in R0.
+
+    __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Bind(&double_op);
+    __ ldr(R0, Address(SP, 1 * target::kWordSize));  // Left argument.
+    __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+
+    __ vcmpd(D0, D1);
+    __ vmstat();
+    __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+    // Return false if D0 or D1 was NaN before checking true condition.
+    __ bx(LR, VS);
+    __ LoadObject(R0, CastHandle<Object>(TrueObject()), true_condition);
+    __ Ret();
+
+    __ Bind(&is_smi);  // Convert R0 to a double.
+    __ SmiUntag(R0);
+    __ vmovsr(S0, R0);
+    __ vcvtdi(D1, S0);
+    __ b(&double_op);  // Then do the comparison.
+    __ Bind(normal_ir_body);
+  }
+}
+
+void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, HI);
+}
+
+void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CS);
+}
+
+void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CC);
+}
+
+void AsmIntrinsifier::Double_equal(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQ);
+}
+
+void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, LS);
+}
+
+// Expects left argument to be double (receiver). Right argument is unknown.
+// Both arguments are on stack.
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label is_smi, double_op;
+
+    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+    // Both arguments are double, right operand is in R0.
+    __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Bind(&double_op);
+    __ ldr(R0, Address(SP, 1 * target::kWordSize));  // Left argument.
+    __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    switch (kind) {
+      case Token::kADD:
+        __ vaddd(D0, D0, D1);
+        break;
+      case Token::kSUB:
+        __ vsubd(D0, D0, D1);
+        break;
+      case Token::kMUL:
+        __ vmuld(D0, D0, D1);
+        break;
+      case Token::kDIV:
+        __ vdivd(D0, D0, D1);
+        break;
+      default:
+        UNREACHABLE();
+    }
+    const Class& double_class = DoubleClass();
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
+    __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Ret();
+    __ Bind(&is_smi);  // Convert R0 to a double.
+    __ SmiUntag(R0);
+    __ vmovsr(S0, R0);
+    __ vcvtdi(D1, S0);
+    __ b(&double_op);
+    __ Bind(normal_ir_body);
+  }
+}
+
+void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
+}
+
+void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
+}
+
+void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
+}
+
+void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
+}
+
+// Left is double, right is integer (Mint or Smi)
+void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label fall_through;
+    // Only smis allowed.
+    __ ldr(R0, Address(SP, 0 * target::kWordSize));
+    __ tst(R0, Operand(kSmiTagMask));
+    __ b(normal_ir_body, NE);
+    // Is Smi.
+    __ SmiUntag(R0);
+    __ vmovsr(S0, R0);
+    __ vcvtdi(D1, S0);
+    __ ldr(R0, Address(SP, 1 * target::kWordSize));
+    __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ vmuld(D0, D0, D1);
+    const Class& double_class = DoubleClass();
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
+    __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Ret();
+    __ Bind(normal_ir_body);
+  }
+}
+
+void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label fall_through;
+
+    __ ldr(R0, Address(SP, 0 * target::kWordSize));
+    __ tst(R0, Operand(kSmiTagMask));
+    __ b(normal_ir_body, NE);
+    // Is Smi.
+    __ SmiUntag(R0);
+    __ vmovsr(S0, R0);
+    __ vcvtdi(D0, S0);
+    const Class& double_class = DoubleClass();
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
+    __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Ret();
+    __ Bind(normal_ir_body);
+  }
+}
+
+void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    __ ldr(R0, Address(SP, 0 * target::kWordSize));
+    __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ vcmpd(D0, D0);
+    __ vmstat();
+    __ LoadObject(R0, CastHandle<Object>(FalseObject()), VC);
+    __ LoadObject(R0, CastHandle<Object>(TrueObject()), VS);
+    __ Ret();
+  }
+}
+
+void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    __ ldr(R0, Address(SP, 0 * target::kWordSize));
+    // R1 <- value[0:31], R2 <- value[32:63]
+    __ LoadFieldFromOffset(kWord, R1, R0, target::Double::value_offset());
+    __ LoadFieldFromOffset(kWord, R2, R0,
+                           target::Double::value_offset() + target::kWordSize);
+
+    // If the low word isn't 0, then it isn't infinity.
+    __ cmp(R1, Operand(0));
+    __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+    __ bx(LR, NE);  // Return if NE.
+
+    // Mask off the sign bit.
+    __ AndImmediate(R2, R2, 0x7FFFFFFF);
+    // Compare with +infinity.
+    __ CompareImmediate(R2, 0x7FF00000);
+    __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+    __ bx(LR, NE);
+
+    __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+    __ Ret();
+  }
+}
+
+void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label is_false, is_true, is_zero;
+    __ ldr(R0, Address(SP, 0 * target::kWordSize));
+    __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ vcmpdz(D0);
+    __ vmstat();
+    __ b(&is_false, VS);  // NaN -> false.
+    __ b(&is_zero, EQ);   // Check for negative zero.
+    __ b(&is_false, CS);  // >= 0 -> false.
+
+    __ Bind(&is_true);
+    __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+    __ Ret();
+
+    __ Bind(&is_false);
+    __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+    __ Ret();
+
+    __ Bind(&is_zero);
+    // Check for negative zero by looking at the sign bit.
+    __ vmovrrd(R0, R1, D0);  // R1:R0 <- D0, so sign bit is in bit 31 of R1.
+    __ mov(R1, Operand(R1, LSR, 31));
+    __ tst(R1, Operand(1));
+    __ b(&is_true, NE);  // Sign bit set.
+    __ b(&is_false);
+  }
+}
+
+void AsmIntrinsifier::DoubleToInteger(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label fall_through;
+
+    __ ldr(R0, Address(SP, 0 * target::kWordSize));
+    __ LoadDFromOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+
+    // Explicit NaN check, since ARM gives an FPU exception if you try to
+    // convert NaN to an int.
+    __ vcmpd(D0, D0);
+    __ vmstat();
+    __ b(normal_ir_body, VS);
+
+    __ vcvtid(S0, D0);
+    __ vmovrs(R0, S0);
+    // Overflow is signaled with minint.
+    // Check for overflow and that it fits into Smi.
+    __ CompareImmediate(R0, 0xC0000000);
+    __ SmiTag(R0, PL);
+    __ bx(LR, PL);
+    __ Bind(normal_ir_body);
+  }
+}
+
+void AsmIntrinsifier::Double_hashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
+
+  if (!TargetCPUFeatures::vfp_supported()) return;
+
+  // Load double value and check that it isn't NaN, since ARM gives an
+  // FPU exception if you try to convert NaN to an int.
+  Label double_hash;
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));
+  __ LoadDFromOffset(D0, R1, target::Double::value_offset() - kHeapObjectTag);
+  __ vcmpd(D0, D0);
+  __ vmstat();
+  __ b(&double_hash, VS);
+
+  // Convert double value to signed 32-bit int in R0.
+  __ vcvtid(S2, D0);
+  __ vmovrs(R0, S2);
+
+  // Tag the int as a Smi, making sure that it fits; this checks for
+  // overflow in the conversion from double to int. Conversion
+  // overflow is signalled by vcvt through clamping R0 to either
+  // INT32_MAX or INT32_MIN (saturation).
+  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
+  __ adds(R0, R0, Operand(R0));
+  __ b(normal_ir_body, VS);
+
+  // Compare the two double values. If they are equal, we return the
+  // Smi tagged result immediately as the hash code.
+  __ vcvtdi(D1, S2);
+  __ vcmpd(D0, D1);
+  __ vmstat();
+  __ bx(LR, EQ);
+
+  // Convert the double bits to a hash code that fits in a Smi.
+  __ Bind(&double_hash);
+  __ ldr(R0, FieldAddress(R1, target::Double::value_offset()));
+  __ ldr(R1, FieldAddress(R1, target::Double::value_offset() + 4));
+  __ eor(R0, R0, Operand(R1));
+  __ AndImmediate(R0, R0, kSmiMax);
+  __ SmiTag(R0);
+  __ Ret();
+
+  // Fall into the native C++ implementation.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  if (TargetCPUFeatures::vfp_supported()) {
+    Label is_smi, double_op;
+    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+    // Argument is double and is in R0.
+    __ LoadDFromOffset(D1, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Bind(&double_op);
+    __ vsqrtd(D0, D1);
+    const Class& double_class = DoubleClass();
+    __ TryAllocate(double_class, normal_ir_body, R0,
+                   R1);  // Result register.
+    __ StoreDToOffset(D0, R0, target::Double::value_offset() - kHeapObjectTag);
+    __ Ret();
+    __ Bind(&is_smi);
+    __ SmiUntag(R0);
+    __ vmovsr(S0, R0);
+    __ vcvtdi(D1, S0);
+    __ b(&double_op);
+    __ Bind(normal_ir_body);
+  }
+}
+
+//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
+//    _state[kSTATE_LO] = state & _MASK_32;
+//    _state[kSTATE_HI] = state >> 32;
+void AsmIntrinsifier::Random_nextState(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  const Field& state_field = LookupMathRandomStateFieldOffset();
+  const int64_t a_int_value = AsmIntrinsifier::kRandomAValue;
+
+  // 'a_int_value' is a mask.
+  ASSERT(Utils::IsUint(32, a_int_value));
+  int32_t a_int32_value = static_cast<int32_t>(a_int_value);
+
+  // Receiver.
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  // Field '_state'.
+  __ ldr(R1, FieldAddress(R0, LookupFieldOffsetInBytes(state_field)));
+  // Addresses of _state[0] and _state[1].
+
+  const int64_t disp_0 =
+      target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
+  const int64_t disp_1 =
+      disp_0 + target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
+
+  __ LoadImmediate(R0, a_int32_value);
+  __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
+  __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
+  __ mov(R8, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
+  // Unsigned 32-bit multiply and 64-bit accumulate into R8:R3.
+  __ umlal(R3, R8, R0, R2);  // R8:R3 <- R8:R3 + R0 * R2.
+  __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
+  __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
+  ASSERT(target::ToRawSmi(0) == 0);
+  __ eor(R0, R0, Operand(R0));
+  __ Ret();
+}
+
+void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));
+  __ cmp(R0, Operand(R1));
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()), EQ);
+  __ Ret();
+}
+
+static void RangeCheck(Assembler* assembler,
+                       Register val,
+                       Register tmp,
+                       intptr_t low,
+                       intptr_t high,
+                       Condition cc,
+                       Label* target) {
+  __ AddImmediate(tmp, val, -low);
+  __ CompareImmediate(tmp, high - low);
+  __ b(target, cc);
+}
+
+const Condition kIfNotInRange = HI;
+const Condition kIfInRange = LS;
+
+static void JumpIfInteger(Assembler* assembler,
+                          Register cid,
+                          Register tmp,
+                          Label* target) {
+  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfInRange, target);
+}
+
+static void JumpIfNotInteger(Assembler* assembler,
+                             Register cid,
+                             Register tmp,
+                             Label* target) {
+  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfNotInRange, target);
+}
+
+static void JumpIfString(Assembler* assembler,
+                         Register cid,
+                         Register tmp,
+                         Label* target) {
+  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfInRange, target);
+}
+
+static void JumpIfNotString(Assembler* assembler,
+                            Register cid,
+                            Register tmp,
+                            Label* target) {
+  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfNotInRange, target);
+}
+
+// Return type quickly for simple types (not parameterized and not signature).
+void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Label use_declaration_type, not_double, not_integer;
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(R1, R0);
+
+  __ CompareImmediate(R1, kClosureCid);
+  __ b(normal_ir_body, EQ);  // Instance is a closure.
+
+  __ CompareImmediate(R1, kNumPredefinedCids);
+  __ b(&use_declaration_type, HI);
+
+  __ CompareImmediate(R1, kDoubleCid);
+  __ b(&not_double, NE);
+
+  __ LoadIsolate(R0);
+  __ LoadFromOffset(kWord, R0, R0, target::Isolate::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::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::ObjectStore::string_type_offset());
+  __ Ret();
+
+  __ Bind(&use_declaration_type);
+  __ LoadClassById(R2, R1);  // Overwrites R1.
+  __ ldrh(R3, FieldAddress(
+                  R2, target::Class::num_type_arguments_offset_in_bytes()));
+  __ CompareImmediate(R3, 0);
+  __ b(normal_ir_body, NE);
+
+  __ ldr(R0, FieldAddress(R2, target::Class::declaration_type_offset()));
+  __ CompareObject(R0, NullObject());
+  __ b(normal_ir_body, EQ);
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(R1, R0);
+
+  // Check if left hand size is a closure. Closures are handled in the runtime.
+  __ CompareImmediate(R1, kClosureCid);
+  __ b(normal_ir_body, EQ);
+
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(R2, R0);
+
+  // Check whether class ids match. If class ids don't match objects can still
+  // have the same runtime type (e.g. multiple string implementation classes
+  // map to a single String type).
+  __ cmp(R1, Operand(R2));
+  __ b(&different_cids, NE);
+
+  // Objects have the same class and neither is a closure.
+  // Check if there are no type arguments. In this case we can return true.
+  // Otherwise fall through into the runtime to handle comparison.
+  __ LoadClassById(R3, R1);
+  __ ldrh(R3, FieldAddress(
+                  R3, target::Class::num_type_arguments_offset_in_bytes()));
+  __ CompareImmediate(R3, 0);
+  __ b(normal_ir_body, NE);
+
+  __ Bind(&equal);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ Ret();
+
+  // Class ids are different. Check if we are comparing runtime types of
+  // two strings (with different representations) or two integers.
+  __ Bind(&different_cids);
+  __ CompareImmediate(R1, kNumPredefinedCids);
+  __ b(&not_equal, HI);
+
+  // Check if both are integers.
+  JumpIfNotInteger(assembler, R1, R0, &not_integer);
+  JumpIfInteger(assembler, R2, R0, &equal);
+  __ b(&not_equal);
+
+  __ Bind(&not_integer);
+  // Check if both are strings.
+  JumpIfNotString(assembler, R1, R0, &not_equal);
+  JumpIfString(assembler, R2, R0, &equal);
+
+  // Neither strings nor integers and have different class ids.
+  __ Bind(&not_equal);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::String::hash_offset()));
+  __ cmp(R0, Operand(0));
+  __ bx(LR, NE);
+  // Hash not yet computed.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::Type::hash_offset()));
+  __ cmp(R0, Operand(0));
+  __ bx(LR, NE);
+  // Hash not yet computed.
+  __ Bind(normal_ir_body);
+}
+
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(R1);
+  __ ldr(R8, FieldAddress(R0, target::String::length_offset()));  // this.length
+  __ SmiUntag(R8);
+  __ ldr(R9,
+         FieldAddress(R2, target::String::length_offset()));  // other.length
+  __ SmiUntag(R9);
+
+  // if (other.length == 0) return true;
+  __ cmp(R9, Operand(0));
+  __ b(return_true, EQ);
+
+  // if (start < 0) return false;
+  __ cmp(R1, Operand(0));
+  __ b(return_false, LT);
+
+  // if (start + other.length > this.length) return false;
+  __ add(R3, R1, Operand(R9));
+  __ cmp(R3, Operand(R8));
+  __ b(return_false, GT);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(R0, target::OneByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(R0, target::TwoByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+    __ add(R0, R0, Operand(R1));
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(R2, target::OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(R2, target::TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(R3, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ ldrb(R4, Address(R0, 0));  // this.codeUnitAt(i + start)
+  } else {
+    __ ldrh(R4, Address(R0, 0));  // this.codeUnitAt(i + start)
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ ldrb(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
+  } else {
+    __ ldrh(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
+  }
+  __ cmp(R4, Operand(NOTFP));
+  __ b(return_false, NE);
+
+  // i++, while (i < len)
+  __ AddImmediate(R3, 1);
+  __ AddImmediate(R0, receiver_cid == kOneByteStringCid ? 1 : 2);
+  __ AddImmediate(R2, other_cid == kOneByteStringCid ? 1 : 2);
+  __ cmp(R3, Operand(R9));
+  __ b(&loop, LT);
+
+  __ b(return_true);
+}
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  Label return_true, return_false, try_two_byte;
+  __ ldr(R0, Address(SP, 2 * target::kWordSize));  // this
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));  // start
+  __ ldr(R2, Address(SP, 0 * target::kWordSize));  // other
+  __ Push(R4);  // Make ARGS_DESC_REG available.
+
+  __ tst(R1, Operand(kSmiTagMask));
+  __ b(normal_ir_body, NE);  // 'start' is not a Smi.
+
+  __ CompareClassId(R2, kOneByteStringCid, R3);
+  __ b(normal_ir_body, NE);
+
+  __ CompareClassId(R0, kOneByteStringCid, R3);
+  __ b(&try_two_byte, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
+                                         kOneByteStringCid, &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(R0, kTwoByteStringCid, R3);
+  __ b(normal_ir_body, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
+                                         kOneByteStringCid, &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ Pop(R4);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ Ret();
+
+  __ Bind(&return_false);
+  __ Pop(R4);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+  __ Pop(R4);
+}
+
+void AsmIntrinsifier::Object_getHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  UNREACHABLE();
+}
+
+void AsmIntrinsifier::Object_setHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  UNREACHABLE();
+}
+
+void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Label try_two_byte_string;
+
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Index.
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // String.
+  __ tst(R1, Operand(kSmiTagMask));
+  __ b(normal_ir_body, NE);  // Index is not a Smi.
+  // Range check.
+  __ ldr(R2, FieldAddress(R0, target::String::length_offset()));
+  __ cmp(R1, Operand(R2));
+  __ b(normal_ir_body, CS);  // Runtime throws exception.
+
+  __ CompareClassId(R0, kOneByteStringCid, R3);
+  __ b(&try_two_byte_string, NE);
+  __ SmiUntag(R1);
+  __ AddImmediate(R0, target::OneByteString::data_offset() - kHeapObjectTag);
+  __ ldrb(R1, Address(R0, R1));
+  __ CompareImmediate(R1, target::Symbols::kNumberOfOneCharCodeSymbols);
+  __ b(normal_ir_body, GE);
+  __ ldr(R0, Address(THR, target::Thread::predefined_symbols_address_offset()));
+  __ AddImmediate(
+      R0, target::Symbols::kNullCharCodeSymbolOffset * target::kWordSize);
+  __ ldr(R0, Address(R0, R1, LSL, 2));
+  __ Ret();
+
+  __ Bind(&try_two_byte_string);
+  __ CompareClassId(R0, kTwoByteStringCid, R3);
+  __ b(normal_ir_body, NE);
+  ASSERT(kSmiTagShift == 1);
+  __ AddImmediate(R0, target::TwoByteString::data_offset() - kHeapObjectTag);
+  __ ldrh(R1, Address(R0, R1));
+  __ CompareImmediate(R1, target::Symbols::kNumberOfOneCharCodeSymbols);
+  __ b(normal_ir_body, GE);
+  __ ldr(R0, Address(THR, target::Thread::predefined_symbols_address_offset()));
+  __ AddImmediate(
+      R0, target::Symbols::kNullCharCodeSymbolOffset * target::kWordSize);
+  __ ldr(R0, Address(R0, R1, LSL, 2));
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::String::length_offset()));
+  __ cmp(R0, Operand(target::ToRawSmi(0)));
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()), EQ);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+  __ Ret();
+}
+
+void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R1, target::String::hash_offset()));
+  __ cmp(R0, Operand(0));
+  __ bx(LR, NE);  // Return if already computed.
+
+  __ ldr(R2, FieldAddress(R1, target::String::length_offset()));
+
+  Label done;
+  // If the string is empty, set the hash to 1, and return.
+  __ cmp(R2, Operand(target::ToRawSmi(0)));
+  __ b(&done, EQ);
+
+  __ SmiUntag(R2);
+  __ mov(R3, Operand(0));
+  __ AddImmediate(R8, R1,
+                  target::OneByteString::data_offset() - kHeapObjectTag);
+  // R1: Instance of OneByteString.
+  // R2: String length, untagged integer.
+  // R3: Loop counter, untagged integer.
+  // R8: String data.
+  // R0: Hash code, untagged integer.
+
+  Label loop;
+  // Add to hash code: (hash_ is uint32)
+  // hash_ += ch;
+  // hash_ += hash_ << 10;
+  // hash_ ^= hash_ >> 6;
+  // Get one characters (ch).
+  __ Bind(&loop);
+  __ ldrb(NOTFP, Address(R8, 0));
+  // NOTFP: ch.
+  __ add(R3, R3, Operand(1));
+  __ add(R8, R8, Operand(1));
+  __ add(R0, R0, Operand(NOTFP));
+  __ add(R0, R0, Operand(R0, LSL, 10));
+  __ eor(R0, R0, Operand(R0, LSR, 6));
+  __ cmp(R3, Operand(R2));
+  __ b(&loop, NE);
+
+  // Finalize.
+  // hash_ += hash_ << 3;
+  // hash_ ^= hash_ >> 11;
+  // hash_ += hash_ << 15;
+  __ add(R0, R0, Operand(R0, LSL, 3));
+  __ eor(R0, R0, Operand(R0, LSR, 11));
+  __ add(R0, R0, Operand(R0, LSL, 15));
+  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
+  __ LoadImmediate(R2,
+                   (static_cast<intptr_t>(1) << target::String::kHashBits) - 1);
+  __ and_(R0, R0, Operand(R2));
+  __ cmp(R0, Operand(0));
+  // return hash_ == 0 ? 1 : hash_;
+  __ Bind(&done);
+  __ mov(R0, Operand(1), EQ);
+  __ SmiTag(R0);
+  __ StoreIntoSmiField(FieldAddress(R1, target::String::hash_offset()), R0);
+  __ Ret();
+}
+
+// Allocates one-byte string of length 'end - start'. The content is not
+// initialized.
+// 'length-reg' (R2) contains tagged length.
+// Returns new string as tagged pointer in R0.
+static void TryAllocateOnebyteString(Assembler* assembler,
+                                     Label* ok,
+                                     Label* failure) {
+  const Register length_reg = R2;
+  Label fail;
+  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R0, kOneByteStringCid));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R0, failure));
+  __ mov(R8, Operand(length_reg));  // Save the length register.
+  // TODO(koda): Protect against negative length and overflow here.
+  __ SmiUntag(length_reg);
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::String::InstanceSize() +
+      target::ObjectAlignment::kObjectAlignment - 1;
+  __ AddImmediate(length_reg, fixed_size_plus_alignment_padding);
+  __ bic(length_reg, length_reg,
+         Operand(target::ObjectAlignment::kObjectAlignment - 1));
+
+  const intptr_t cid = kOneByteStringCid;
+  __ ldr(R0, Address(THR, target::Thread::top_offset()));
+
+  // length_reg: allocation size.
+  __ adds(R1, R0, Operand(length_reg));
+  __ b(&fail, CS);  // Fail on unsigned overflow.
+
+  // Check if the allocation fits into the remaining space.
+  // R0: potential new object start.
+  // R1: potential next object start.
+  // R2: allocation size.
+  __ ldr(NOTFP, Address(THR, target::Thread::end_offset()));
+  __ cmp(R1, Operand(NOTFP));
+  __ b(&fail, CS);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
+  __ str(R1, Address(THR, target::Thread::top_offset()));
+  __ AddImmediate(R0, kHeapObjectTag);
+
+  // Initialize the tags.
+  // R0: new object start as a tagged pointer.
+  // R1: new object end address.
+  // R2: allocation size.
+  // R4: allocation stats address.
+  {
+    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2;
+
+    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+    __ mov(R3, Operand(R2, LSL, shift), LS);
+    __ mov(R3, Operand(0), HI);
+
+    // Get the class index and insert it into the tags.
+    // R3: size and bit tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    __ LoadImmediate(TMP, tags);
+    __ orr(R3, R3, Operand(TMP));
+    __ str(R3, FieldAddress(R0, target::Object::tags_offset()));  // Store tags.
+  }
+
+  // Set the length field using the saved length (R8).
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::String::length_offset()), R8);
+  // Clear hash.
+  __ LoadImmediate(TMP, 0);
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::String::hash_offset()), TMP);
+
+  NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2));
+  __ b(ok);
+
+  __ Bind(&fail);
+  __ b(failure);
+}
+
+// Arg0: OneByteString (receiver).
+// Arg1: Start index as Smi.
+// Arg2: End index as Smi.
+// The indexes must be valid.
+void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                       Label* normal_ir_body) {
+  const intptr_t kStringOffset = 2 * target::kWordSize;
+  const intptr_t kStartIndexOffset = 1 * target::kWordSize;
+  const intptr_t kEndIndexOffset = 0 * target::kWordSize;
+  Label ok;
+
+  __ ldr(R2, Address(SP, kEndIndexOffset));
+  __ ldr(TMP, Address(SP, kStartIndexOffset));
+  __ orr(R3, R2, Operand(TMP));
+  __ tst(R3, Operand(kSmiTagMask));
+  __ b(normal_ir_body, NE);  // 'start', 'end' not Smi.
+
+  __ sub(R2, R2, Operand(TMP));
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+  __ Bind(&ok);
+  // R0: new string as tagged pointer.
+  // Copy string.
+  __ ldr(R3, Address(SP, kStringOffset));
+  __ ldr(R1, Address(SP, kStartIndexOffset));
+  __ SmiUntag(R1);
+  __ add(R3, R3, Operand(R1));
+  // Calculate start address and untag (- 1).
+  __ AddImmediate(R3, target::OneByteString::data_offset() - 1);
+
+  // R3: Start address to copy from (untagged).
+  // R1: Untagged start index.
+  __ ldr(R2, Address(SP, kEndIndexOffset));
+  __ SmiUntag(R2);
+  __ sub(R2, R2, Operand(R1));
+
+  // R3: Start address to copy from (untagged).
+  // R2: Untagged number of bytes to copy.
+  // R0: Tagged result string.
+  // R8: Pointer into R3.
+  // NOTFP: Pointer into R0.
+  // R1: Scratch register.
+  Label loop, done;
+  __ cmp(R2, Operand(0));
+  __ b(&done, LE);
+  __ mov(R8, Operand(R3));
+  __ mov(NOTFP, Operand(R0));
+  __ Bind(&loop);
+  __ ldrb(R1, Address(R8, 0));
+  __ AddImmediate(R8, 1);
+  __ sub(R2, R2, Operand(1));
+  __ cmp(R2, Operand(0));
+  __ strb(R1, FieldAddress(NOTFP, target::OneByteString::data_offset()));
+  __ AddImmediate(NOTFP, 1);
+  __ b(&loop, GT);
+
+  __ Bind(&done);
+  __ Ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ ldr(R2, Address(SP, 0 * target::kWordSize));  // Value.
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));  // Index.
+  __ ldr(R0, Address(SP, 2 * target::kWordSize));  // OneByteString.
+  __ SmiUntag(R1);
+  __ SmiUntag(R2);
+  __ AddImmediate(R3, R0,
+                  target::OneByteString::data_offset() - kHeapObjectTag);
+  __ strb(R2, Address(R3, R1));
+  __ Ret();
+}
+
+void AsmIntrinsifier::OneByteString_allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ ldr(R2, Address(SP, 0 * target::kWordSize));  // Length.
+  Label ok;
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+
+  __ Bind(&ok);
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+}
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // This.
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Other.
+
+  // Are identical?
+  __ cmp(R0, Operand(R1));
+  __ b(&is_true, EQ);
+
+  // Is other OneByteString?
+  __ tst(R1, Operand(kSmiTagMask));
+  __ b(normal_ir_body, EQ);
+  __ CompareClassId(R1, string_cid, R2);
+  __ b(normal_ir_body, NE);
+
+  // Have same length?
+  __ ldr(R2, FieldAddress(R0, target::String::length_offset()));
+  __ ldr(R3, FieldAddress(R1, target::String::length_offset()));
+  __ cmp(R2, Operand(R3));
+  __ b(&is_false, NE);
+
+  // Check contents, no fall-through possible.
+  // TODO(zra): try out other sequences.
+  ASSERT((string_cid == kOneByteStringCid) ||
+         (string_cid == kTwoByteStringCid));
+  const intptr_t offset = (string_cid == kOneByteStringCid)
+                              ? target::OneByteString::data_offset()
+                              : target::TwoByteString::data_offset();
+  __ AddImmediate(R0, offset - kHeapObjectTag);
+  __ AddImmediate(R1, offset - kHeapObjectTag);
+  __ SmiUntag(R2);
+  __ Bind(&loop);
+  __ AddImmediate(R2, -1);
+  __ cmp(R2, Operand(0));
+  __ b(&is_true, LT);
+  if (string_cid == kOneByteStringCid) {
+    __ ldrb(R3, Address(R0));
+    __ ldrb(R4, Address(R1));
+    __ AddImmediate(R0, 1);
+    __ AddImmediate(R1, 1);
+  } else if (string_cid == kTwoByteStringCid) {
+    __ ldrh(R3, Address(R0));
+    __ ldrh(R4, Address(R1));
+    __ AddImmediate(R0, 2);
+    __ AddImmediate(R1, 2);
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmp(R3, Operand(R4));
+  __ b(&is_false, NE);
+  __ b(&loop);
+
+  __ Bind(&is_true);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ Ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ Ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
+}
+
+void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
+}
+
+void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                   Label* normal_ir_body,
+                                                   bool sticky) {
+  if (FLAG_interpret_irregexp) return;
+
+  static const intptr_t kRegExpParamOffset = 2 * target::kWordSize;
+  static const intptr_t kStringParamOffset = 1 * target::kWordSize;
+  // start_index smi is located at offset 0.
+
+  // Incoming registers:
+  // R0: Function. (Will be reloaded with the specialized matcher function.)
+  // R4: Arguments descriptor. (Will be preserved.)
+  // R9: Unknown. (Must be GC safe on tail call.)
+
+  // Load the specialized function pointer into R0. Leverage the fact the
+  // string CIDs as well as stored function pointers are in sequence.
+  __ ldr(R2, Address(SP, kRegExpParamOffset));
+  __ ldr(R1, Address(SP, kStringParamOffset));
+  __ LoadClassId(R1, R1);
+  __ AddImmediate(R1, -kOneByteStringCid);
+  __ add(R1, R2, Operand(R1, LSL, target::kWordSizeLog2));
+  __ ldr(R0, FieldAddress(R1, target::RegExp::function_offset(kOneByteStringCid,
+                                                              sticky)));
+
+  // Registers are now set up for the lazy compile stub. It expects the function
+  // in R0, the argument descriptor in R4, and IC-Data in R9.
+  __ eor(R9, R9, Operand(R9));
+
+  // Tail-call the function.
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+}
+
+// On stack: user tag (+0).
+void AsmIntrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  // R1: Isolate.
+  __ LoadIsolate(R1);
+  // R0: Current user tag.
+  __ ldr(R0, Address(R1, target::Isolate::current_tag_offset()));
+  // R2: UserTag.
+  __ ldr(R2, Address(SP, +0 * target::kWordSize));
+  // Set target::Isolate::current_tag_.
+  __ str(R2, Address(R1, target::Isolate::current_tag_offset()));
+  // R2: UserTag's tag.
+  __ ldr(R2, FieldAddress(R2, target::UserTag::tag_offset()));
+  // Set target::Isolate::user_tag_.
+  __ str(R2, Address(R1, target::Isolate::user_tag_offset()));
+  __ Ret();
+}
+
+void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ LoadIsolate(R0);
+  __ ldr(R0, Address(R0, target::Isolate::default_tag_offset()));
+  __ Ret();
+}
+
+void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ LoadIsolate(R0);
+  __ ldr(R0, Address(R0, target::Isolate::current_tag_offset()));
+  __ Ret();
+}
+
+void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+#if !defined(SUPPORT_TIMELINE)
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ Ret();
+#else
+  // Load TimelineStream*.
+  __ ldr(R0, Address(THR, target::Thread::dart_stream_offset()));
+  // Load uintptr_t from TimelineStream*.
+  __ ldr(R0, Address(R0, target::TimelineStream::enabled_offset()));
+  __ cmp(R0, Operand(0));
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()), NE);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()), EQ);
+  __ Ret();
+#endif
+}
+
+void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  __ LoadObject(R0, NullObject());
+  __ str(R0, Address(THR, target::Thread::async_stack_trace_offset()));
+  __ Ret();
+}
+
+void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  __ ldr(R0, Address(THR, target::Thread::async_stack_trace_offset()));
+  __ LoadObject(R0, NullObject());
+  __ Ret();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
new file mode 100644
index 0000000..6ba42cd
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -0,0 +1,2344 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"  // Needed here to get TARGET_ARCH_ARM64.
+#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
+#include "vm/compiler/asm_intrinsifier.h"
+#include "vm/compiler/assembler/assembler.h"
+
+namespace dart {
+namespace compiler {
+
+// When entering intrinsics code:
+// R4: Arguments descriptor
+// LR: Return address
+// The R4 register can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The FP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_arm64.h) must be preserved.
+
+#define __ assembler->
+
+intptr_t AsmIntrinsifier::ParameterSlotFromSp() {
+  return -1;
+}
+
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
+void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
+
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->mov(CALLEE_SAVED_TEMP, LR);
+  assembler->mov(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
+}
+
+void AsmIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->mov(LR, CALLEE_SAVED_TEMP);
+  assembler->mov(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
+}
+
+// Allocate a GrowableObjectArray:: using the backing array specified.
+// On stack: type argument (+1), data (+0).
+void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  // The newly allocated object is returned in R0.
+  const intptr_t kTypeArgumentsOffset = 1 * target::kWordSize;
+  const intptr_t kArrayOffset = 0 * target::kWordSize;
+
+  // Try allocating in new space.
+  const Class& cls = GrowableObjectArrayClass();
+  __ TryAllocate(cls, normal_ir_body, R0, R1);
+
+  // Store backing array object in growable array object.
+  __ ldr(R1, Address(SP, kArrayOffset));  // Data argument.
+  // R0 is new, no barrier needed.
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::GrowableObjectArray::data_offset()), R1);
+
+  // R0: new growable array object start as a tagged pointer.
+  // Store the type argument field in the growable array object.
+  __ ldr(R1, Address(SP, kTypeArgumentsOffset));  // Type argument.
+  __ StoreIntoObjectNoBarrier(
+      R0,
+      FieldAddress(R0, target::GrowableObjectArray::type_arguments_offset()),
+      R1);
+
+  // Set the length field in the growable array object to 0.
+  __ LoadImmediate(R1, 0);
+  __ str(R1, FieldAddress(R0, target::GrowableObjectArray::length_offset()));
+  __ ret();  // Returns the newly allocated object in R0.
+
+  __ Bind(normal_ir_body);
+}
+
+static int GetScaleFactor(intptr_t size) {
+  switch (size) {
+    case 1:
+      return 0;
+    case 2:
+      return 1;
+    case 4:
+      return 2;
+    case 8:
+      return 3;
+    case 16:
+      return 4;
+  }
+  UNREACHABLE();
+  return -1;
+}
+
+#define TYPED_ARRAY_ALLOCATION(cid, max_len, scale_shift)                      \
+  Label fall_through;                                                          \
+  const intptr_t kArrayLengthStackOffset = 0 * target::kWordSize;              \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, normal_ir_body));            \
+  __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
+  /* Check that length is a positive Smi. */                                   \
+  /* R2: requested array length argument. */                                   \
+  __ BranchIfNotSmi(R2, normal_ir_body);                                       \
+  __ CompareRegisters(R2, ZR);                                                 \
+  __ b(normal_ir_body, LT);                                                    \
+  __ SmiUntag(R2);                                                             \
+  /* Check for maximum allowed length. */                                      \
+  /* R2: untagged array length. */                                             \
+  __ CompareImmediate(R2, max_len);                                            \
+  __ b(normal_ir_body, GT);                                                    \
+  __ LslImmediate(R2, R2, scale_shift);                                        \
+  const intptr_t fixed_size_plus_alignment_padding =                           \
+      target::TypedData::InstanceSize() +                                      \
+      target::ObjectAlignment::kObjectAlignment - 1;                           \
+  __ AddImmediate(R2, fixed_size_plus_alignment_padding);                      \
+  __ andi(R2, R2,                                                              \
+          Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));        \
+  __ ldr(R0, Address(THR, target::Thread::top_offset()));                      \
+                                                                               \
+  /* R2: allocation size. */                                                   \
+  __ adds(R1, R0, Operand(R2));                                                \
+  __ b(normal_ir_body, CS); /* Fail on unsigned overflow. */                   \
+                                                                               \
+  /* Check if the allocation fits into the remaining space. */                 \
+  /* R0: potential new object start. */                                        \
+  /* R1: potential next object start. */                                       \
+  /* R2: allocation size. */                                                   \
+  __ ldr(R6, Address(THR, target::Thread::end_offset()));                      \
+  __ cmp(R1, Operand(R6));                                                     \
+  __ b(normal_ir_body, CS);                                                    \
+                                                                               \
+  /* Successfully allocated the object(s), now update top to point to */       \
+  /* next object start and initialize the object. */                           \
+  __ str(R1, Address(THR, target::Thread::top_offset()));                      \
+  __ AddImmediate(R0, kHeapObjectTag);                                         \
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2));                   \
+  /* Initialize the tags. */                                                   \
+  /* R0: new object start as a tagged pointer. */                              \
+  /* R1: new object end address. */                                            \
+  /* R2: allocation size. */                                                   \
+  {                                                                            \
+    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);            \
+    __ LslImmediate(R2, R2,                                                    \
+                    target::RawObject::kTagBitsSizeTagPos -                    \
+                        target::ObjectAlignment::kObjectAlignmentLog2);        \
+    __ csel(R2, ZR, R2, HI);                                                   \
+                                                                               \
+    /* Get the class index and insert it into the tags. */                     \
+    uint32_t tags =                                                            \
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);        \
+    __ LoadImmediate(TMP, tags);                                               \
+    __ orr(R2, R2, Operand(TMP));                                              \
+    __ str(R2, FieldAddress(R0, target::Object::tags_offset())); /* Tags. */   \
+  }                                                                            \
+  /* Set the length field. */                                                  \
+  /* R0: new object start as a tagged pointer. */                              \
+  /* R1: new object end address. */                                            \
+  __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
+  __ StoreIntoObjectNoBarrier(                                                 \
+      R0, FieldAddress(R0, target::TypedData::length_offset()), R2);           \
+  /* Initialize all array elements to 0. */                                    \
+  /* R0: new object start as a tagged pointer. */                              \
+  /* R1: new object end address. */                                            \
+  /* R2: iterator which initially points to the start of the variable */       \
+  /* R3: scratch register. */                                                  \
+  /* data area to be initialized. */                                           \
+  __ mov(R3, ZR);                                                              \
+  __ AddImmediate(R2, R0, target::TypedData::InstanceSize() - 1);              \
+  Label init_loop, done;                                                       \
+  __ Bind(&init_loop);                                                         \
+  __ cmp(R2, Operand(R1));                                                     \
+  __ b(&done, CS);                                                             \
+  __ str(R3, Address(R2, 0));                                                  \
+  __ add(R2, R2, Operand(target::kWordSize));                                  \
+  __ b(&init_loop);                                                            \
+  __ Bind(&done);                                                              \
+                                                                               \
+  __ ret();                                                                    \
+  __ Bind(normal_ir_body);
+
+#define TYPED_DATA_ALLOCATOR(clazz)                                            \
+  void AsmIntrinsifier::TypedData_##clazz##_factory(Assembler* assembler,      \
+                                                    Label* normal_ir_body) {   \
+    intptr_t size = TypedDataElementSizeInBytes(kTypedData##clazz##Cid);       \
+    intptr_t max_len = TypedDataMaxNewSpaceElements(kTypedData##clazz##Cid);   \
+    int shift = GetScaleFactor(size);                                          \
+    TYPED_ARRAY_ALLOCATION(kTypedData##clazz##Cid, max_len, shift);            \
+  }
+CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
+#undef TYPED_DATA_ALLOCATOR
+
+// Loads args from stack into R0 and R1
+// Tests if they are smis, jumps to label not_smi if not.
+static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
+  __ ldr(R0, Address(SP, +0 * target::kWordSize));
+  __ ldr(R1, Address(SP, +1 * target::kWordSize));
+  __ orr(TMP, R0, Operand(R1));
+  __ BranchIfNotSmi(TMP, not_smi);
+}
+
+void AsmIntrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
+  __ adds(R0, R0, Operand(R1));                      // Adds.
+  __ b(normal_ir_body, VS);  // Fall-through on overflow.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ subs(R0, R0, Operand(R1));  // Subtract.
+  __ b(normal_ir_body, VS);      // Fall-through on overflow.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ subs(R0, R1, Operand(R0));  // Subtract.
+  __ b(normal_ir_body, VS);      // Fall-through on overflow.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
+  __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
+
+  __ mul(TMP, R0, R1);
+  __ smulh(TMP2, R0, R1);
+  // TMP: result bits 64..127.
+  __ cmp(TMP2, Operand(TMP, ASR, 63));
+  __ b(normal_ir_body, NE);
+  __ mov(R0, TMP);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
+}
+
+// Optimizations:
+// - result is 0 if:
+//   - left is 0
+//   - left equals right
+// - result is left if
+//   - left > 0 && left < right
+// R1: Tagged left (dividend).
+// R0: Tagged right (divisor).
+// Returns:
+//   R1: Untagged fallthrough result (remainder to be adjusted), or
+//   R0: Tagged return result (remainder).
+static void EmitRemainderOperation(Assembler* assembler) {
+  Label return_zero, modulo;
+  const Register left = R1;
+  const Register right = R0;
+  const Register result = R1;
+  const Register tmp = R2;
+  ASSERT(left == result);
+
+  // Check for quick zero results.
+  __ CompareRegisters(left, ZR);
+  __ b(&return_zero, EQ);
+  __ CompareRegisters(left, right);
+  __ b(&return_zero, EQ);
+
+  // Check if result should be left.
+  __ CompareRegisters(left, ZR);
+  __ b(&modulo, LT);
+  // left is positive.
+  __ CompareRegisters(left, right);
+  // left is less than right, result is left.
+  __ b(&modulo, GT);
+  __ mov(R0, left);
+  __ ret();
+
+  __ Bind(&return_zero);
+  __ mov(R0, ZR);
+  __ ret();
+
+  __ Bind(&modulo);
+  // result <- left - right * (left / right)
+  __ SmiUntag(left);
+  __ SmiUntag(right);
+
+  __ sdiv(tmp, left, right);
+  __ msub(result, right, tmp, left);  // result <- left - right * tmp
+}
+
+// Implementation:
+//  res = left % right;
+//  if (res < 0) {
+//    if (right < 0) {
+//      res = res - right;
+//    } else {
+//      res = res + right;
+//    }
+//  }
+void AsmIntrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  // Check to see if we have integer division
+  Label neg_remainder, fall_through;
+  __ ldr(R1, Address(SP, +0 * target::kWordSize));
+  __ ldr(R0, Address(SP, +1 * target::kWordSize));
+  __ orr(TMP, R0, Operand(R1));
+  __ BranchIfNotSmi(TMP, normal_ir_body);
+  // R1: Tagged left (dividend).
+  // R0: Tagged right (divisor).
+  // Check if modulo by zero -> exception thrown in main function.
+  __ CompareRegisters(R0, ZR);
+  __ b(normal_ir_body, EQ);
+  EmitRemainderOperation(assembler);
+  // Untagged right in R0. Untagged remainder result in R1.
+
+  __ CompareRegisters(R1, ZR);
+  __ b(&neg_remainder, LT);
+  __ SmiTag(R0, R1);  // Tag and move result to R0.
+  __ ret();
+
+  __ Bind(&neg_remainder);
+  // Result is negative, adjust it.
+  __ CompareRegisters(R0, ZR);
+  __ sub(TMP, R1, Operand(R0));
+  __ add(TMP2, R1, Operand(R0));
+  __ csel(R0, TMP2, TMP, GE);
+  __ SmiTag(R0);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  // Check to see if we have integer division
+
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ CompareRegisters(R0, ZR);
+  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
+
+  __ SmiUntag(R0);
+  __ SmiUntag(R1);
+
+  __ sdiv(R0, R1, R0);
+
+  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
+  // cannot tag the result.
+  __ CompareImmediate(R0, 0x4000000000000000);
+  __ b(normal_ir_body, EQ);
+  __ SmiTag(R0);  // Not equal. Okay to tag and return.
+  __ ret();       // Return.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_negate(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, +0 * target::kWordSize));  // Grab first argument.
+  __ BranchIfNotSmi(R0, normal_ir_body);
+  __ negs(R0, R0);
+  __ b(normal_ir_body, VS);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
+  __ and_(R0, R0, Operand(R1));
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
+  __ orr(R0, R0, Operand(R1));
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
+  __ eor(R0, R0, Operand(R1));
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
+  ASSERT(kSmiTagShift == 1);
+  ASSERT(kSmiTag == 0);
+  const Register right = R0;
+  const Register left = R1;
+  const Register temp = R2;
+  const Register result = R0;
+
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ CompareImmediate(right, target::ToRawSmi(target::Smi::kBits));
+  __ b(normal_ir_body, CS);
+
+  // Left is not a constant.
+  // Check if count too large for handling it inlined.
+  __ SmiUntag(TMP, right);  // SmiUntag right into TMP.
+  // Overflow test (preserve left, right, and TMP);
+  __ lslv(temp, left, TMP);
+  __ asrv(TMP2, temp, TMP);
+  __ CompareRegisters(left, TMP2);
+  __ b(normal_ir_body, NE);  // Overflow.
+  // Shift for result now we know there is no overflow.
+  __ lslv(result, left, TMP);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
+  Label true_label;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // R0 contains the right argument, R1 the left.
+  __ CompareRegisters(R1, R0);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
+  __ csel(R0, TMP, R0, true_condition);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LT);
+}
+
+void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Integer_greaterThanFromInt(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GT);
+}
+
+void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LE);
+}
+
+void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GE);
+}
+
+// This is called for Smi and Mint receivers. The right argument
+// can be Smi, Mint or double.
+void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label true_label, check_for_mint;
+  // For integer receiver '===' check first.
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));
+  __ cmp(R0, Operand(R1));
+  __ b(&true_label, EQ);
+
+  __ orr(R2, R0, Operand(R1));
+  __ BranchIfNotSmi(R2, &check_for_mint);
+  // If R0 or R1 is not a smi do Mint checks.
+
+  // Both arguments are smi, '===' is good enough.
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&true_label);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // At least one of the arguments was not Smi.
+  Label receiver_not_smi;
+  __ Bind(&check_for_mint);
+
+  __ BranchIfNotSmi(R1, &receiver_not_smi);  // Check receiver.
+
+  // Left (receiver) is Smi, return false if right is not Double.
+  // Note that an instance of Mint never contains a value that can be
+  // represented by Smi.
+
+  __ CompareClassId(R0, kDoubleCid);
+  __ b(normal_ir_body, EQ);
+  __ LoadObject(R0,
+                CastHandle<Object>(FalseObject()));  // Smi == Mint -> false.
+  __ ret();
+
+  __ Bind(&receiver_not_smi);
+  // R1: receiver.
+
+  __ CompareClassId(R1, kMintCid);
+  __ b(normal_ir_body, NE);
+  // Receiver is Mint, return false if right is Smi.
+  __ BranchIfNotSmi(R0, normal_ir_body);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ ret();
+  // TODO(srdjan): Implement Mint == Mint comparison.
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_equal(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // Shift amount in R0. Value to shift in R1.
+
+  // Fall through if shift amount is negative.
+  __ SmiUntag(R0);
+  __ CompareRegisters(R0, ZR);
+  __ b(normal_ir_body, LT);
+
+  // If shift amount is bigger than 63, set to 63.
+  __ LoadImmediate(TMP, 0x3F);
+  __ CompareRegisters(R0, TMP);
+  __ csel(R0, TMP, R0, GT);
+  __ SmiUntag(R1);
+  __ asrv(R0, R1, R0);
+  __ SmiTag(R0);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ mvn(R0, R0);
+  __ andi(R0, R0, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
+  __ ret();
+}
+
+void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ SmiUntag(R0);
+  // XOR with sign bit to complement bits if value is negative.
+  __ eor(R0, R0, Operand(R0, ASR, 63));
+  __ clz(R0, R0);
+  __ LoadImmediate(R1, 64);
+  __ sub(R0, R1, Operand(R0));
+  __ SmiTag(R0);
+  __ ret();
+}
+
+void AsmIntrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
+  __ ldp(R2, R3, Address(SP, 2 * target::kWordSize, Address::PairOffset));
+  __ add(R2, R2, Operand(2));  // x_used > 0, Smi. R2 = x_used + 1, round up.
+  __ AsrImmediate(R2, R2, 2);  // R2 = num of digit pairs to read.
+  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldp(R4, R5, Address(SP, 0 * target::kWordSize, Address::PairOffset));
+  __ SmiUntag(R5);
+  // R0 = n ~/ (2*_DIGIT_BITS)
+  __ AsrImmediate(R0, R5, 6);
+  // R6 = &x_digits[0]
+  __ add(R6, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+  // R7 = &x_digits[2*R2]
+  __ add(R7, R6, Operand(R2, LSL, 3));
+  // R8 = &r_digits[2*1]
+  __ add(R8, R4,
+         Operand(target::TypedData::data_offset() - kHeapObjectTag +
+                 2 * kBytesPerBigIntDigit));
+  // R8 = &r_digits[2*(R2 + n ~/ (2*_DIGIT_BITS) + 1)]
+  __ add(R0, R0, Operand(R2));
+  __ add(R8, R8, Operand(R0, LSL, 3));
+  // R3 = n % (2 * _DIGIT_BITS)
+  __ AndImmediate(R3, R5, 63);
+  // R2 = 64 - R3
+  __ LoadImmediate(R2, 64);
+  __ sub(R2, R2, Operand(R3));
+  __ mov(R1, ZR);
+  Label loop;
+  __ Bind(&loop);
+  __ ldr(R0, Address(R7, -2 * kBytesPerBigIntDigit, Address::PreIndex));
+  __ lsrv(R4, R0, R2);
+  __ orr(R1, R1, Operand(R4));
+  __ str(R1, Address(R8, -2 * kBytesPerBigIntDigit, Address::PreIndex));
+  __ lslv(R1, R0, R3);
+  __ cmp(R7, Operand(R6));
+  __ b(&loop, NE);
+  __ str(R1, Address(R8, -2 * kBytesPerBigIntDigit, Address::PreIndex));
+  __ LoadObject(R0, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
+  __ ldp(R2, R3, Address(SP, 2 * target::kWordSize, Address::PairOffset));
+  __ add(R2, R2, Operand(2));  // x_used > 0, Smi. R2 = x_used + 1, round up.
+  __ AsrImmediate(R2, R2, 2);  // R2 = num of digit pairs to read.
+  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
+  __ ldp(R4, R5, Address(SP, 0 * target::kWordSize, Address::PairOffset));
+  __ SmiUntag(R5);
+  // R0 = n ~/ (2*_DIGIT_BITS)
+  __ AsrImmediate(R0, R5, 6);
+  // R8 = &r_digits[0]
+  __ add(R8, R4, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+  // R7 = &x_digits[2*(n ~/ (2*_DIGIT_BITS))]
+  __ add(R7, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+  __ add(R7, R7, Operand(R0, LSL, 3));
+  // R6 = &r_digits[2*(R2 - n ~/ (2*_DIGIT_BITS) - 1)]
+  __ add(R0, R0, Operand(1));
+  __ sub(R0, R2, Operand(R0));
+  __ add(R6, R8, Operand(R0, LSL, 3));
+  // R3 = n % (2*_DIGIT_BITS)
+  __ AndImmediate(R3, R5, 63);
+  // R2 = 64 - R3
+  __ LoadImmediate(R2, 64);
+  __ sub(R2, R2, Operand(R3));
+  // R1 = x_digits[n ~/ (2*_DIGIT_BITS)] >> (n % (2*_DIGIT_BITS))
+  __ ldr(R1, Address(R7, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ lsrv(R1, R1, R3);
+  Label loop_entry;
+  __ b(&loop_entry);
+  Label loop;
+  __ Bind(&loop);
+  __ ldr(R0, Address(R7, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ lslv(R4, R0, R2);
+  __ orr(R1, R1, Operand(R4));
+  __ str(R1, Address(R8, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ lsrv(R1, R0, R3);
+  __ Bind(&loop_entry);
+  __ cmp(R8, Operand(R6));
+  __ b(&loop, NE);
+  __ str(R1, Address(R8, 0));
+  __ LoadObject(R0, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absAdd(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  // R2 = used, R3 = digits
+  __ ldp(R2, R3, Address(SP, 3 * target::kWordSize, Address::PairOffset));
+  __ add(R2, R2, Operand(2));  // used > 0, Smi. R2 = used + 1, round up.
+  __ add(R2, ZR, Operand(R2, ASR, 2));  // R2 = num of digit pairs to process.
+  // R3 = &digits[0]
+  __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R4 = a_used, R5 = a_digits
+  __ ldp(R4, R5, Address(SP, 1 * target::kWordSize, Address::PairOffset));
+  __ add(R4, R4, Operand(2));  // a_used > 0, Smi. R4 = a_used + 1, round up.
+  __ add(R4, ZR, Operand(R4, ASR, 2));  // R4 = num of digit pairs to process.
+  // R5 = &a_digits[0]
+  __ add(R5, R5, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R6 = r_digits
+  __ ldr(R6, Address(SP, 0 * target::kWordSize));
+  // R6 = &r_digits[0]
+  __ add(R6, R6, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R7 = &digits[a_used rounded up to even number].
+  __ add(R7, R3, Operand(R4, LSL, 3));
+
+  // R8 = &digits[a_used rounded up to even number].
+  __ add(R8, R3, Operand(R2, LSL, 3));
+
+  __ adds(R0, R0, Operand(0));  // carry flag = 0
+  Label add_loop;
+  __ Bind(&add_loop);
+  // Loop (a_used+1)/2 times, a_used > 0.
+  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ ldr(R1, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ adcs(R0, R0, R1);
+  __ sub(R9, R3, Operand(R7));  // Does not affect carry flag.
+  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ cbnz(&add_loop, R9);  // Does not affect carry flag.
+
+  Label last_carry;
+  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
+  __ cbz(&last_carry, R9);      // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop (used+1)/2 - (a_used+1)/2 times, used - a_used > 0.
+  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ adcs(R0, R0, ZR);
+  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
+  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ cbnz(&carry_loop, R9);
+
+  __ Bind(&last_carry);
+  Label done;
+  __ b(&done, CC);
+  __ LoadImmediate(R0, 1);
+  __ str(R0, Address(R6, 0));
+
+  __ Bind(&done);
+  __ LoadObject(R0, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absSub(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  // R2 = used, R3 = digits
+  __ ldp(R2, R3, Address(SP, 3 * target::kWordSize, Address::PairOffset));
+  __ add(R2, R2, Operand(2));  // used > 0, Smi. R2 = used + 1, round up.
+  __ add(R2, ZR, Operand(R2, ASR, 2));  // R2 = num of digit pairs to process.
+  // R3 = &digits[0]
+  __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R4 = a_used, R5 = a_digits
+  __ ldp(R4, R5, Address(SP, 1 * target::kWordSize, Address::PairOffset));
+  __ add(R4, R4, Operand(2));  // a_used > 0, Smi. R4 = a_used + 1, round up.
+  __ add(R4, ZR, Operand(R4, ASR, 2));  // R4 = num of digit pairs to process.
+  // R5 = &a_digits[0]
+  __ add(R5, R5, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R6 = r_digits
+  __ ldr(R6, Address(SP, 0 * target::kWordSize));
+  // R6 = &r_digits[0]
+  __ add(R6, R6, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R7 = &digits[a_used rounded up to even number].
+  __ add(R7, R3, Operand(R4, LSL, 3));
+
+  // R8 = &digits[a_used rounded up to even number].
+  __ add(R8, R3, Operand(R2, LSL, 3));
+
+  __ subs(R0, R0, Operand(0));  // carry flag = 1
+  Label sub_loop;
+  __ Bind(&sub_loop);
+  // Loop (a_used+1)/2 times, a_used > 0.
+  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ ldr(R1, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ sbcs(R0, R0, R1);
+  __ sub(R9, R3, Operand(R7));  // Does not affect carry flag.
+  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ cbnz(&sub_loop, R9);  // Does not affect carry flag.
+
+  Label done;
+  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
+  __ cbz(&done, R9);            // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop (used+1)/2 - (a_used+1)/2 times, used - a_used > 0.
+  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ sbcs(R0, R0, ZR);
+  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
+  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ cbnz(&carry_loop, R9);
+
+  __ Bind(&done);
+  __ LoadObject(R0, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulAdd(Uint32List x_digits, int xi,
+  //                    Uint32List m_digits, int i,
+  //                    Uint32List a_digits, int j, int n) {
+  //   uint64_t x = x_digits[xi >> 1 .. (xi >> 1) + 1];  // xi is Smi and even.
+  //   if (x == 0 || n == 0) {
+  //     return 2;
+  //   }
+  //   uint64_t* mip = &m_digits[i >> 1];  // i is Smi and even.
+  //   uint64_t* ajp = &a_digits[j >> 1];  // j is Smi and even.
+  //   uint64_t c = 0;
+  //   SmiUntag(n);  // n is Smi and even.
+  //   n = (n + 1)/2;  // Number of pairs to process.
+  //   do {
+  //     uint64_t mi = *mip++;
+  //     uint64_t aj = *ajp;
+  //     uint128_t t = x*mi + aj + c;  // 64-bit * 64-bit -> 128-bit.
+  //     *ajp++ = low64(t);
+  //     c = high64(t);
+  //   } while (--n > 0);
+  //   while (c != 0) {
+  //     uint128_t t = *ajp + c;
+  //     *ajp++ = low64(t);
+  //     c = high64(t);  // c == 0 or 1.
+  //   }
+  //   return 2;
+  // }
+
+  Label done;
+  // R3 = x, no_op if x == 0
+  // R0 = xi as Smi, R1 = x_digits.
+  __ ldp(R0, R1, Address(SP, 5 * target::kWordSize, Address::PairOffset));
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ ldr(R3, FieldAddress(R1, target::TypedData::data_offset()));
+  __ tst(R3, Operand(R3));
+  __ b(&done, EQ);
+
+  // R6 = (SmiUntag(n) + 1)/2, no_op if n == 0
+  __ ldr(R6, Address(SP, 0 * target::kWordSize));
+  __ add(R6, R6, Operand(2));
+  __ adds(R6, ZR, Operand(R6, ASR, 2));  // SmiUntag(R6) and set cc.
+  __ b(&done, EQ);
+
+  // R4 = mip = &m_digits[i >> 1]
+  // R0 = i as Smi, R1 = m_digits.
+  __ ldp(R0, R1, Address(SP, 3 * target::kWordSize, Address::PairOffset));
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ add(R4, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R5 = ajp = &a_digits[j >> 1]
+  // R0 = j as Smi, R1 = a_digits.
+  __ ldp(R0, R1, Address(SP, 1 * target::kWordSize, Address::PairOffset));
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ add(R5, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R1 = c = 0
+  __ mov(R1, ZR);
+
+  Label muladd_loop;
+  __ Bind(&muladd_loop);
+  // x:   R3
+  // mip: R4
+  // ajp: R5
+  // c:   R1
+  // n:   R6
+  // t:   R7:R8 (not live at loop entry)
+
+  // uint64_t mi = *mip++
+  __ ldr(R2, Address(R4, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+
+  // uint64_t aj = *ajp
+  __ ldr(R0, Address(R5, 0));
+
+  // uint128_t t = x*mi + aj + c
+  __ mul(R7, R2, R3);    // R7 = low64(R2*R3).
+  __ umulh(R8, R2, R3);  // R8 = high64(R2*R3), t = R8:R7 = x*mi.
+  __ adds(R7, R7, Operand(R0));
+  __ adc(R8, R8, ZR);            // t += aj.
+  __ adds(R0, R7, Operand(R1));  // t += c, R0 = low64(t).
+  __ adc(R1, R8, ZR);            // c = R1 = high64(t).
+
+  // *ajp++ = low64(t) = R0
+  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+
+  // while (--n > 0)
+  __ subs(R6, R6, Operand(1));  // --n
+  __ b(&muladd_loop, NE);
+
+  __ tst(R1, Operand(R1));
+  __ b(&done, EQ);
+
+  // *ajp++ += c
+  __ ldr(R0, Address(R5, 0));
+  __ adds(R0, R0, Operand(R1));
+  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&done, CC);
+
+  Label propagate_carry_loop;
+  __ Bind(&propagate_carry_loop);
+  __ ldr(R0, Address(R5, 0));
+  __ adds(R0, R0, Operand(1));
+  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ b(&propagate_carry_loop, CS);
+
+  __ Bind(&done);
+  __ LoadImmediate(R0, target::ToRawSmi(2));  // Two digits processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _sqrAdd(Uint32List x_digits, int i,
+  //                    Uint32List a_digits, int used) {
+  //   uint64_t* xip = &x_digits[i >> 1];  // i is Smi and even.
+  //   uint64_t x = *xip++;
+  //   if (x == 0) return 2;
+  //   uint64_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
+  //   uint64_t aj = *ajp;
+  //   uint128_t t = x*x + aj;
+  //   *ajp++ = low64(t);
+  //   uint128_t c = high64(t);
+  //   int n = ((used - i + 2) >> 2) - 1;  // used and i are Smi. n: num pairs.
+  //   while (--n >= 0) {
+  //     uint64_t xi = *xip++;
+  //     uint64_t aj = *ajp;
+  //     uint192_t t = 2*x*xi + aj + c;  // 2-bit * 64-bit * 64-bit -> 129-bit.
+  //     *ajp++ = low64(t);
+  //     c = high128(t);  // 65-bit.
+  //   }
+  //   uint64_t aj = *ajp;
+  //   uint128_t t = aj + c;  // 64-bit + 65-bit -> 66-bit.
+  //   *ajp++ = low64(t);
+  //   *ajp = high64(t);
+  //   return 2;
+  // }
+
+  // R4 = xip = &x_digits[i >> 1]
+  // R2 = i as Smi, R3 = x_digits
+  __ ldp(R2, R3, Address(SP, 2 * target::kWordSize, Address::PairOffset));
+  __ add(R3, R3, Operand(R2, LSL, 1));
+  __ add(R4, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R3 = x = *xip++, return if x == 0
+  Label x_zero;
+  __ ldr(R3, Address(R4, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+  __ tst(R3, Operand(R3));
+  __ b(&x_zero, EQ);
+
+  // R5 = ajp = &a_digits[i]
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));  // a_digits
+  __ add(R1, R1, Operand(R2, LSL, 2));             // j == 2*i, i is Smi.
+  __ add(R5, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+
+  // R6:R1 = t = x*x + *ajp
+  __ ldr(R0, Address(R5, 0));
+  __ mul(R1, R3, R3);            // R1 = low64(R3*R3).
+  __ umulh(R6, R3, R3);          // R6 = high64(R3*R3).
+  __ adds(R1, R1, Operand(R0));  // R6:R1 += *ajp.
+  __ adc(R6, R6, ZR);            // R6 = low64(c) = high64(t).
+  __ mov(R7, ZR);                // R7 = high64(c) = 0.
+
+  // *ajp++ = low64(t) = R1
+  __ str(R1, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+
+  // int n = (used - i + 1)/2 - 1
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));  // used is Smi
+  __ sub(R8, R0, Operand(R2));
+  __ add(R8, R8, Operand(2));
+  __ movn(R0, Immediate(1), 0);          // R0 = ~1 = -2.
+  __ adds(R8, R0, Operand(R8, ASR, 2));  // while (--n >= 0)
+
+  Label loop, done;
+  __ b(&done, MI);
+
+  __ Bind(&loop);
+  // x:   R3
+  // xip: R4
+  // ajp: R5
+  // c:   R7:R6
+  // t:   R2:R1:R0 (not live at loop entry)
+  // n:   R8
+
+  // uint64_t xi = *xip++
+  __ ldr(R2, Address(R4, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+
+  // uint192_t t = R2:R1:R0 = 2*x*xi + aj + c
+  __ mul(R0, R2, R3);    // R0 = low64(R2*R3) = low64(x*xi).
+  __ umulh(R1, R2, R3);  // R1 = high64(R2*R3) = high64(x*xi).
+  __ adds(R0, R0, Operand(R0));
+  __ adcs(R1, R1, R1);
+  __ adc(R2, ZR, ZR);  // R2:R1:R0 = R1:R0 + R1:R0 = 2*x*xi.
+  __ adds(R0, R0, Operand(R6));
+  __ adcs(R1, R1, R7);
+  __ adc(R2, R2, ZR);          // R2:R1:R0 += c.
+  __ ldr(R7, Address(R5, 0));  // R7 = aj = *ajp.
+  __ adds(R0, R0, Operand(R7));
+  __ adcs(R6, R1, ZR);
+  __ adc(R7, R2, ZR);  // R7:R6:R0 = 2*x*xi + aj + c.
+
+  // *ajp++ = low64(t) = R0
+  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
+
+  // while (--n >= 0)
+  __ subs(R8, R8, Operand(1));  // --n
+  __ b(&loop, PL);
+
+  __ Bind(&done);
+  // uint64_t aj = *ajp
+  __ ldr(R0, Address(R5, 0));
+
+  // uint128_t t = aj + c
+  __ adds(R6, R6, Operand(R0));
+  __ adc(R7, R7, ZR);
+
+  // *ajp = low64(t) = R6
+  // *(ajp + 1) = high64(t) = R7
+  __ stp(R6, R7, Address(R5, 0, Address::PairOffset));
+
+  __ Bind(&x_zero);
+  __ LoadImmediate(R0, target::ToRawSmi(2));  // Two digits processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+  // There is no 128-bit by 64-bit division instruction on arm64, so we use two
+  // 64-bit by 32-bit divisions and two 64-bit by 64-bit multiplications to
+  // adjust the two 32-bit digits of the estimated quotient.
+  //
+  // Pseudo code:
+  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
+  //   uint64_t yt = args[_YT_LO .. _YT];  // _YT_LO == 0, _YT == 1.
+  //   uint64_t* dp = &digits[(i >> 1) - 1];  // i is Smi.
+  //   uint64_t dh = dp[0];  // dh == digits[(i >> 1) - 1 .. i >> 1].
+  //   uint64_t qd;
+  //   if (dh == yt) {
+  //     qd = (DIGIT_MASK << 32) | DIGIT_MASK;
+  //   } else {
+  //     dl = dp[-1];  // dl == digits[(i >> 1) - 3 .. (i >> 1) - 2].
+  //     // We cannot calculate qd = dh:dl / yt, so ...
+  //     uint64_t yth = yt >> 32;
+  //     uint64_t qh = dh / yth;
+  //     uint128_t ph:pl = yt*qh;
+  //     uint64_t tl = (dh << 32)|(dl >> 32);
+  //     uint64_t th = dh >> 32;
+  //     while ((ph > th) || ((ph == th) && (pl > tl))) {
+  //       if (pl < yt) --ph;
+  //       pl -= yt;
+  //       --qh;
+  //     }
+  //     qd = qh << 32;
+  //     tl = (pl << 32);
+  //     th = (ph << 32)|(pl >> 32);
+  //     if (tl > dl) ++th;
+  //     dl -= tl;
+  //     dh -= th;
+  //     uint64_t ql = ((dh << 32)|(dl >> 32)) / yth;
+  //     ph:pl = yt*ql;
+  //     while ((ph > dh) || ((ph == dh) && (pl > dl))) {
+  //       if (pl < yt) --ph;
+  //       pl -= yt;
+  //       --ql;
+  //     }
+  //     qd |= ql;
+  //   }
+  //   args[_QD .. _QD_HI] = qd;  // _QD == 2, _QD_HI == 3.
+  //   return 2;
+  // }
+
+  // R4 = args
+  __ ldr(R4, Address(SP, 2 * target::kWordSize));  // args
+
+  // R3 = yt = args[0..1]
+  __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset()));
+
+  // R2 = dh = digits[(i >> 1) - 1 .. i >> 1]
+  // R0 = i as Smi, R1 = digits
+  __ ldp(R0, R1, Address(SP, 0 * target::kWordSize, Address::PairOffset));
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ ldr(R2, FieldAddress(
+                 R1, target::TypedData::data_offset() - kBytesPerBigIntDigit));
+
+  // R0 = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
+  __ movn(R0, Immediate(0), 0);
+
+  // Return qd if dh == yt
+  Label return_qd;
+  __ cmp(R2, Operand(R3));
+  __ b(&return_qd, EQ);
+
+  // R1 = dl = digits[(i >> 1) - 3 .. (i >> 1) - 2]
+  __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset() -
+                                  3 * kBytesPerBigIntDigit));
+
+  // R5 = yth = yt >> 32
+  __ orr(R5, ZR, Operand(R3, LSR, 32));
+
+  // R6 = qh = dh / yth
+  __ udiv(R6, R2, R5);
+
+  // R8:R7 = ph:pl = yt*qh
+  __ mul(R7, R3, R6);
+  __ umulh(R8, R3, R6);
+
+  // R9 = tl = (dh << 32)|(dl >> 32)
+  __ orr(R9, ZR, Operand(R2, LSL, 32));
+  __ orr(R9, R9, Operand(R1, LSR, 32));
+
+  // R10 = th = dh >> 32
+  __ orr(R10, ZR, Operand(R2, LSR, 32));
+
+  // while ((ph > th) || ((ph == th) && (pl > tl)))
+  Label qh_adj_loop, qh_adj, qh_ok;
+  __ Bind(&qh_adj_loop);
+  __ cmp(R8, Operand(R10));
+  __ b(&qh_adj, HI);
+  __ b(&qh_ok, NE);
+  __ cmp(R7, Operand(R9));
+  __ b(&qh_ok, LS);
+
+  __ Bind(&qh_adj);
+  // if (pl < yt) --ph
+  __ sub(TMP, R8, Operand(1));  // TMP = ph - 1
+  __ cmp(R7, Operand(R3));
+  __ csel(R8, TMP, R8, CC);  // R8 = R7 < R3 ? TMP : R8
+
+  // pl -= yt
+  __ sub(R7, R7, Operand(R3));
+
+  // --qh
+  __ sub(R6, R6, Operand(1));
+
+  // Continue while loop.
+  __ b(&qh_adj_loop);
+
+  __ Bind(&qh_ok);
+  // R0 = qd = qh << 32
+  __ orr(R0, ZR, Operand(R6, LSL, 32));
+
+  // tl = (pl << 32)
+  __ orr(R9, ZR, Operand(R7, LSL, 32));
+
+  // th = (ph << 32)|(pl >> 32);
+  __ orr(R10, ZR, Operand(R8, LSL, 32));
+  __ orr(R10, R10, Operand(R7, LSR, 32));
+
+  // if (tl > dl) ++th
+  __ add(TMP, R10, Operand(1));  // TMP = th + 1
+  __ cmp(R9, Operand(R1));
+  __ csel(R10, TMP, R10, HI);  // R10 = R9 > R1 ? TMP : R10
+
+  // dl -= tl
+  __ sub(R1, R1, Operand(R9));
+
+  // dh -= th
+  __ sub(R2, R2, Operand(R10));
+
+  // R6 = ql = ((dh << 32)|(dl >> 32)) / yth
+  __ orr(R6, ZR, Operand(R2, LSL, 32));
+  __ orr(R6, R6, Operand(R1, LSR, 32));
+  __ udiv(R6, R6, R5);
+
+  // R8:R7 = ph:pl = yt*ql
+  __ mul(R7, R3, R6);
+  __ umulh(R8, R3, R6);
+
+  // while ((ph > dh) || ((ph == dh) && (pl > dl))) {
+  Label ql_adj_loop, ql_adj, ql_ok;
+  __ Bind(&ql_adj_loop);
+  __ cmp(R8, Operand(R2));
+  __ b(&ql_adj, HI);
+  __ b(&ql_ok, NE);
+  __ cmp(R7, Operand(R1));
+  __ b(&ql_ok, LS);
+
+  __ Bind(&ql_adj);
+  // if (pl < yt) --ph
+  __ sub(TMP, R8, Operand(1));  // TMP = ph - 1
+  __ cmp(R7, Operand(R3));
+  __ csel(R8, TMP, R8, CC);  // R8 = R7 < R3 ? TMP : R8
+
+  // pl -= yt
+  __ sub(R7, R7, Operand(R3));
+
+  // --ql
+  __ sub(R6, R6, Operand(1));
+
+  // Continue while loop.
+  __ b(&ql_adj_loop);
+
+  __ Bind(&ql_ok);
+  // qd |= ql;
+  __ orr(R0, R0, Operand(R6));
+
+  __ Bind(&return_qd);
+  // args[2..3] = qd
+  __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
+                                  2 * kBytesPerBigIntDigit));
+
+  __ LoadImmediate(R0, target::ToRawSmi(2));  // Two digits processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
+  //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
+  //   uint64_t d = digits[i >> 1 .. (i >> 1) + 1];  // i is Smi and even.
+  //   uint128_t t = rho*d;
+  //   args[_MU .. _MU_HI] = t mod DIGIT_BASE^2;  // _MU == 4, _MU_HI == 5.
+  //   return 2;
+  // }
+
+  // R4 = args
+  __ ldr(R4, Address(SP, 2 * target::kWordSize));  // args
+
+  // R3 = rho = args[2..3]
+  __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset() +
+                                  2 * kBytesPerBigIntDigit));
+
+  // R2 = digits[i >> 1 .. (i >> 1) + 1]
+  // R0 = i as Smi, R1 = digits
+  __ ldp(R0, R1, Address(SP, 0 * target::kWordSize, Address::PairOffset));
+  __ add(R1, R1, Operand(R0, LSL, 1));
+  __ ldr(R2, FieldAddress(R1, target::TypedData::data_offset()));
+
+  // R0 = rho*d mod DIGIT_BASE
+  __ mul(R0, R2, R3);  // R0 = low64(R2*R3).
+
+  // args[4 .. 5] = R0
+  __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
+                                  4 * kBytesPerBigIntDigit));
+
+  __ LoadImmediate(R0, target::ToRawSmi(2));  // Two digits processed.
+  __ ret();
+}
+
+// Check if the last argument is a double, jump to label 'is_smi' if smi
+// (easy to convert to double), otherwise jump to label 'not_double_smi',
+// Returns the last argument in R0.
+static void TestLastArgumentIsDouble(Assembler* assembler,
+                                     Label* is_smi,
+                                     Label* not_double_smi) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ BranchIfSmi(R0, is_smi);
+  __ CompareClassId(R0, kDoubleCid);
+  __ b(not_double_smi, NE);
+  // Fall through with Double in R0.
+}
+
+// Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
+// type. Return true or false object in the register R0. Any NaN argument
+// returns false. Any non-double arg1 causes control flow to fall through to the
+// slow case (compiled method body).
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  Label is_smi, double_op, not_nan;
+
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Both arguments are double, right operand is in R0.
+
+  __ LoadDFieldFromOffset(V1, R0, target::Double::value_offset());
+  __ Bind(&double_op);
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // Left argument.
+  __ LoadDFieldFromOffset(V0, R0, target::Double::value_offset());
+
+  __ fcmpd(V0, V1);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  // Return false if D0 or D1 was NaN before checking true condition.
+  __ b(&not_nan, VC);
+  __ ret();
+  __ Bind(&not_nan);
+  __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
+  __ csel(R0, TMP, R0, true_condition);
+  __ ret();
+
+  __ Bind(&is_smi);  // Convert R0 to a double.
+  __ SmiUntag(R0);
+  __ scvtfdx(V1, R0);
+  __ b(&double_op);  // Then do the comparison.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, HI);
+}
+
+void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CS);
+}
+
+void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, CC);
+}
+
+void AsmIntrinsifier::Double_equal(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQ);
+}
+
+void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, LS);
+}
+
+// Expects left argument to be double (receiver). Right argument is unknown.
+// Both arguments are on stack.
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  Label is_smi, double_op;
+
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Both arguments are double, right operand is in R0.
+  __ LoadDFieldFromOffset(V1, R0, target::Double::value_offset());
+  __ Bind(&double_op);
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // Left argument.
+  __ LoadDFieldFromOffset(V0, R0, target::Double::value_offset());
+  switch (kind) {
+    case Token::kADD:
+      __ faddd(V0, V0, V1);
+      break;
+    case Token::kSUB:
+      __ fsubd(V0, V0, V1);
+      break;
+    case Token::kMUL:
+      __ fmuld(V0, V0, V1);
+      break;
+    case Token::kDIV:
+      __ fdivd(V0, V0, V1);
+      break;
+    default:
+      UNREACHABLE();
+  }
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
+  __ StoreDFieldToOffset(V0, R0, target::Double::value_offset());
+  __ ret();
+
+  __ Bind(&is_smi);  // Convert R0 to a double.
+  __ SmiUntag(R0);
+  __ scvtfdx(V1, R0);
+  __ b(&double_op);
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
+}
+
+void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
+}
+
+void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
+}
+
+void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
+}
+
+// Left is double, right is integer (Mint or Smi)
+void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  // Only smis allowed.
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ BranchIfNotSmi(R0, normal_ir_body);
+  // Is Smi.
+  __ SmiUntag(R0);
+  __ scvtfdx(V1, R0);
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));
+  __ LoadDFieldFromOffset(V0, R0, target::Double::value_offset());
+  __ fmuld(V0, V0, V1);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
+  __ StoreDFieldToOffset(V0, R0, target::Double::value_offset());
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ BranchIfNotSmi(R0, normal_ir_body);
+  // Is Smi.
+  __ SmiUntag(R0);
+  __ scvtfdx(V0, R0);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
+  __ StoreDFieldToOffset(V0, R0, target::Double::value_offset());
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadDFieldFromOffset(V0, R0, target::Double::value_offset());
+  __ fcmpd(V0, V0);
+  __ LoadObject(TMP, CastHandle<Object>(FalseObject()));
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ csel(R0, TMP, R0, VC);
+  __ ret();
+}
+
+void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadFieldFromOffset(R0, R0, target::Double::value_offset());
+  // Mask off the sign.
+  __ AndImmediate(R0, R0, 0x7FFFFFFFFFFFFFFFLL);
+  // Compare with +infinity.
+  __ CompareImmediate(R0, 0x7FF0000000000000LL);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
+  __ csel(R0, TMP, R0, EQ);
+  __ ret();
+}
+
+void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  const Register false_reg = R0;
+  const Register true_reg = R2;
+  Label is_false, is_true, is_zero;
+
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadDFieldFromOffset(V0, R0, target::Double::value_offset());
+  __ fcmpdz(V0);
+  __ LoadObject(true_reg, CastHandle<Object>(TrueObject()));
+  __ LoadObject(false_reg, CastHandle<Object>(FalseObject()));
+  __ b(&is_false, VS);  // NaN -> false.
+  __ b(&is_zero, EQ);   // Check for negative zero.
+  __ b(&is_false, CS);  // >= 0 -> false.
+
+  __ Bind(&is_true);
+  __ mov(R0, true_reg);
+
+  __ Bind(&is_false);
+  __ ret();
+
+  __ Bind(&is_zero);
+  // Check for negative zero by looking at the sign bit.
+  __ fmovrd(R1, V0);
+  __ LsrImmediate(R1, R1, 63);
+  __ tsti(R1, Immediate(1));
+  __ csel(R0, true_reg, false_reg, NE);  // Sign bit set.
+  __ ret();
+}
+
+void AsmIntrinsifier::DoubleToInteger(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadDFieldFromOffset(V0, R0, target::Double::value_offset());
+
+  // Explicit NaN check, since ARM gives an FPU exception if you try to
+  // convert NaN to an int.
+  __ fcmpd(V0, V0);
+  __ b(normal_ir_body, VS);
+
+  __ fcvtzds(R0, V0);
+  // Overflow is signaled with minint.
+  // Check for overflow and that it fits into Smi.
+  __ CompareImmediate(R0, 0xC000000000000000);
+  __ b(normal_ir_body, MI);
+  __ SmiTag(R0);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_hashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
+
+  // Load double value and check that it isn't NaN, since ARM gives an
+  // FPU exception if you try to convert NaN to an int.
+  Label double_hash;
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));
+  __ LoadDFieldFromOffset(V0, R1, target::Double::value_offset());
+  __ fcmpd(V0, V0);
+  __ b(&double_hash, VS);
+
+  // Convert double value to signed 64-bit int in R0 and back to a
+  // double value in V1.
+  __ fcvtzds(R0, V0);
+  __ scvtfdx(V1, R0);
+
+  // Tag the int as a Smi, making sure that it fits; this checks for
+  // overflow in the conversion from double to int. Conversion
+  // overflow is signalled by fcvt through clamping R0 to either
+  // INT64_MAX or INT64_MIN (saturation).
+  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
+  __ adds(R0, R0, Operand(R0));
+  __ b(normal_ir_body, VS);
+
+  // Compare the two double values. If they are equal, we return the
+  // Smi tagged result immediately as the hash code.
+  __ fcmpd(V0, V1);
+  __ b(&double_hash, NE);
+  __ ret();
+
+  // Convert the double bits to a hash code that fits in a Smi.
+  __ Bind(&double_hash);
+  __ fmovrd(R0, V0);
+  __ eor(R0, R0, Operand(R0, LSR, 32));
+  __ AndImmediate(R0, R0, kSmiMax);
+  __ SmiTag(R0);
+  __ ret();
+
+  // Fall into the native C++ implementation.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Argument is double and is in R0.
+  __ LoadDFieldFromOffset(V1, R0, target::Double::value_offset());
+  __ Bind(&double_op);
+  __ fsqrtd(V0, V1);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, R0, R1);
+  __ StoreDFieldToOffset(V0, R0, target::Double::value_offset());
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(R0);
+  __ scvtfdx(V1, R0);
+  __ b(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
+//    _state[kSTATE_LO] = state & _MASK_32;
+//    _state[kSTATE_HI] = state >> 32;
+void AsmIntrinsifier::Random_nextState(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  const Field& state_field = LookupMathRandomStateFieldOffset();
+  const int64_t a_int_value = AsmIntrinsifier::kRandomAValue;
+
+  // Receiver.
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  // Field '_state'.
+  __ ldr(R1, FieldAddress(R0, LookupFieldOffsetInBytes(state_field)));
+
+  // Addresses of _state[0].
+  const int64_t disp =
+      target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid) -
+      kHeapObjectTag;
+
+  __ LoadImmediate(R0, a_int_value);
+  __ LoadFromOffset(R2, R1, disp);
+  __ LsrImmediate(R3, R2, 32);
+  __ andi(R2, R2, Immediate(0xffffffff));
+  __ mul(R2, R0, R2);
+  __ add(R2, R2, Operand(R3));
+  __ StoreToOffset(R2, R1, disp);
+  ASSERT(target::ToRawSmi(0) == 0);
+  __ eor(R0, R0, Operand(R0));
+  __ ret();
+}
+
+void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));
+  __ cmp(R0, Operand(R1));
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
+  __ csel(R0, TMP, R0, EQ);
+  __ ret();
+}
+
+static void RangeCheck(Assembler* assembler,
+                       Register val,
+                       Register tmp,
+                       intptr_t low,
+                       intptr_t high,
+                       Condition cc,
+                       Label* target) {
+  __ AddImmediate(tmp, val, -low);
+  __ CompareImmediate(tmp, high - low);
+  __ b(target, cc);
+}
+
+const Condition kIfNotInRange = HI;
+const Condition kIfInRange = LS;
+
+static void JumpIfInteger(Assembler* assembler,
+                          Register cid,
+                          Register tmp,
+                          Label* target) {
+  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfInRange, target);
+}
+
+static void JumpIfNotInteger(Assembler* assembler,
+                             Register cid,
+                             Register tmp,
+                             Label* target) {
+  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfNotInRange, target);
+}
+
+static void JumpIfString(Assembler* assembler,
+                         Register cid,
+                         Register tmp,
+                         Label* target) {
+  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfInRange, target);
+}
+
+static void JumpIfNotString(Assembler* assembler,
+                            Register cid,
+                            Register tmp,
+                            Label* target) {
+  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfNotInRange, target);
+}
+
+// Return type quickly for simple types (not parameterized and not signature).
+void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Label use_declaration_type, not_double, not_integer;
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(R1, R0);
+
+  __ CompareImmediate(R1, kClosureCid);
+  __ b(normal_ir_body, EQ);  // Instance is a closure.
+
+  __ CompareImmediate(R1, kNumPredefinedCids);
+  __ b(&use_declaration_type, HI);
+
+  __ CompareImmediate(R1, kDoubleCid);
+  __ b(&not_double, NE);
+
+  __ LoadIsolate(R0);
+  __ LoadFromOffset(R0, R0, target::Isolate::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::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::ObjectStore::string_type_offset());
+  __ ret();
+
+  __ Bind(&use_declaration_type);
+  __ LoadClassById(R2, R1);  // Overwrites R1.
+  __ ldr(R3,
+         FieldAddress(R2, target::Class::num_type_arguments_offset_in_bytes()),
+         kHalfword);
+  __ CompareImmediate(R3, 0);
+  __ b(normal_ir_body, NE);
+
+  __ ldr(R0, FieldAddress(R2, target::Class::declaration_type_offset()));
+  __ CompareObject(R0, NullObject());
+  __ b(normal_ir_body, EQ);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(R1, R0);
+
+  // Check if left hand size is a closure. Closures are handled in the runtime.
+  __ CompareImmediate(R1, kClosureCid);
+  __ b(normal_ir_body, EQ);
+
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(R2, R0);
+
+  // Check whether class ids match. If class ids don't match objects can still
+  // have the same runtime type (e.g. multiple string implementation classes
+  // map to a single String type).
+  __ cmp(R1, Operand(R2));
+  __ b(&different_cids, NE);
+
+  // Objects have the same class and neither is a closure.
+  // Check if there are no type arguments. In this case we can return true.
+  // Otherwise fall through into the runtime to handle comparison.
+  __ LoadClassById(R3, R1);  // Overwrites R1.
+  __ ldr(R3,
+         FieldAddress(R3, target::Class::num_type_arguments_offset_in_bytes()),
+         kHalfword);
+  __ CompareImmediate(R3, 0);
+  __ b(normal_ir_body, NE);
+
+  __ Bind(&equal);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // Class ids are different. Check if we are comparing runtime types of
+  // two strings (with different representations) or two integers.
+  __ Bind(&different_cids);
+  __ CompareImmediate(R1, kNumPredefinedCids);
+  __ b(&not_equal, HI);
+
+  // Check if both are integers.
+  JumpIfNotInteger(assembler, R1, R0, &not_integer);
+  JumpIfInteger(assembler, R2, R0, &equal);
+  __ b(&not_equal);
+
+  __ Bind(&not_integer);
+  // Check if both are strings.
+  JumpIfNotString(assembler, R1, R0, &not_equal);
+  JumpIfString(assembler, R2, R0, &equal);
+
+  // Neither strings nor integers and have different class ids.
+  __ Bind(&not_equal);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::String::hash_offset()), kUnsignedWord);
+  __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
+  __ b(normal_ir_body, EQ);
+  __ ret();
+  // Hash not yet computed.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::Type::hash_offset()));
+  __ cbz(normal_ir_body, R0);
+  __ ret();
+  // Hash not yet computed.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Object_getHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::String::hash_offset()), kUnsignedWord);
+  __ SmiTag(R0);
+  __ ret();
+}
+
+void AsmIntrinsifier::Object_setHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // Object.
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Value.
+  __ SmiUntag(R1);
+  __ str(R1, FieldAddress(R0, target::String::hash_offset()), kUnsignedWord);
+  __ ret();
+}
+
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ SmiUntag(R1);
+  __ ldr(R8, FieldAddress(R0, target::String::length_offset()));  // this.length
+  __ SmiUntag(R8);
+  __ ldr(R9,
+         FieldAddress(R2, target::String::length_offset()));  // other.length
+  __ SmiUntag(R9);
+
+  // if (other.length == 0) return true;
+  __ cmp(R9, Operand(0));
+  __ b(return_true, EQ);
+
+  // if (start < 0) return false;
+  __ cmp(R1, Operand(0));
+  __ b(return_false, LT);
+
+  // if (start + other.length > this.length) return false;
+  __ add(R3, R1, Operand(R9));
+  __ cmp(R3, Operand(R8));
+  __ b(return_false, GT);
+
+  if (receiver_cid == kOneByteStringCid) {
+    __ AddImmediate(R0, target::OneByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ AddImmediate(R0, target::TwoByteString::data_offset() - kHeapObjectTag);
+    __ add(R0, R0, Operand(R1));
+    __ add(R0, R0, Operand(R1));
+  }
+  if (other_cid == kOneByteStringCid) {
+    __ AddImmediate(R2, target::OneByteString::data_offset() - kHeapObjectTag);
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ AddImmediate(R2, target::TwoByteString::data_offset() - kHeapObjectTag);
+  }
+
+  // i = 0
+  __ LoadImmediate(R3, 0);
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  // this.codeUnitAt(i + start)
+  __ ldr(R10, Address(R0, 0),
+         receiver_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+  // other.codeUnitAt(i)
+  __ ldr(R11, Address(R2, 0),
+         other_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
+  __ cmp(R10, Operand(R11));
+  __ b(return_false, NE);
+
+  // i++, while (i < len)
+  __ add(R3, R3, Operand(1));
+  __ add(R0, R0, Operand(receiver_cid == kOneByteStringCid ? 1 : 2));
+  __ add(R2, R2, Operand(other_cid == kOneByteStringCid ? 1 : 2));
+  __ cmp(R3, Operand(R9));
+  __ b(&loop, LT);
+
+  __ b(return_true);
+}
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  Label return_true, return_false, try_two_byte;
+  __ ldr(R0, Address(SP, 2 * target::kWordSize));  // this
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));  // start
+  __ ldr(R2, Address(SP, 0 * target::kWordSize));  // other
+
+  __ BranchIfNotSmi(R1, normal_ir_body);
+
+  __ CompareClassId(R2, kOneByteStringCid);
+  __ b(normal_ir_body, NE);
+
+  __ CompareClassId(R0, kOneByteStringCid);
+  __ b(normal_ir_body, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
+                                         kOneByteStringCid, &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(R0, kTwoByteStringCid);
+  __ b(normal_ir_body, NE);
+
+  GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
+                                         kOneByteStringCid, &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Label try_two_byte_string;
+
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Index.
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // String.
+  __ BranchIfNotSmi(R1, normal_ir_body);           // Index is not a Smi.
+  // Range check.
+  __ ldr(R2, FieldAddress(R0, target::String::length_offset()));
+  __ cmp(R1, Operand(R2));
+  __ b(normal_ir_body, CS);  // Runtime throws exception.
+
+  __ CompareClassId(R0, kOneByteStringCid);
+  __ b(&try_two_byte_string, NE);
+  __ SmiUntag(R1);
+  __ AddImmediate(R0, target::OneByteString::data_offset() - kHeapObjectTag);
+  __ ldr(R1, Address(R0, R1), kUnsignedByte);
+  __ CompareImmediate(R1, target::Symbols::kNumberOfOneCharCodeSymbols);
+  __ b(normal_ir_body, GE);
+  __ ldr(R0, Address(THR, target::Thread::predefined_symbols_address_offset()));
+  __ AddImmediate(
+      R0, target::Symbols::kNullCharCodeSymbolOffset * target::kWordSize);
+  __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
+  __ ret();
+
+  __ Bind(&try_two_byte_string);
+  __ CompareClassId(R0, kTwoByteStringCid);
+  __ b(normal_ir_body, NE);
+  ASSERT(kSmiTagShift == 1);
+  __ AddImmediate(R0, target::TwoByteString::data_offset() - kHeapObjectTag);
+  __ ldr(R1, Address(R0, R1), kUnsignedHalfword);
+  __ CompareImmediate(R1, target::Symbols::kNumberOfOneCharCodeSymbols);
+  __ b(normal_ir_body, GE);
+  __ ldr(R0, Address(THR, target::Thread::predefined_symbols_address_offset()));
+  __ AddImmediate(
+      R0, target::Symbols::kNullCharCodeSymbolOffset * target::kWordSize);
+  __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R0, FieldAddress(R0, target::String::length_offset()));
+  __ cmp(R0, Operand(target::ToRawSmi(0)));
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ LoadObject(TMP, CastHandle<Object>(FalseObject()));
+  __ csel(R0, TMP, R0, NE);
+  __ ret();
+}
+
+void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label compute_hash;
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));  // OneByteString object.
+  __ ldr(R0, FieldAddress(R1, target::String::hash_offset()), kUnsignedWord);
+  __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
+  __ b(&compute_hash, EQ);
+  __ ret();  // Return if already computed.
+
+  __ Bind(&compute_hash);
+  __ ldr(R2, FieldAddress(R1, target::String::length_offset()));
+  __ SmiUntag(R2);
+
+  Label done;
+  // If the string is empty, set the hash to 1, and return.
+  __ CompareRegisters(R2, ZR);
+  __ b(&done, EQ);
+
+  __ mov(R3, ZR);
+  __ AddImmediate(R6, R1,
+                  target::OneByteString::data_offset() - kHeapObjectTag);
+  // R1: Instance of OneByteString.
+  // R2: String length, untagged integer.
+  // R3: Loop counter, untagged integer.
+  // R6: String data.
+  // R0: Hash code, untagged integer.
+
+  Label loop;
+  // Add to hash code: (hash_ is uint32)
+  // hash_ += ch;
+  // hash_ += hash_ << 10;
+  // hash_ ^= hash_ >> 6;
+  // Get one characters (ch).
+  __ Bind(&loop);
+  __ ldr(R7, Address(R6, R3), kUnsignedByte);
+  // R7: ch.
+  __ add(R3, R3, Operand(1));
+  __ addw(R0, R0, Operand(R7));
+  __ addw(R0, R0, Operand(R0, LSL, 10));
+  __ eorw(R0, R0, Operand(R0, LSR, 6));
+  __ cmp(R3, Operand(R2));
+  __ b(&loop, NE);
+
+  // Finalize.
+  // hash_ += hash_ << 3;
+  // hash_ ^= hash_ >> 11;
+  // hash_ += hash_ << 15;
+  __ addw(R0, R0, Operand(R0, LSL, 3));
+  __ eorw(R0, R0, Operand(R0, LSR, 11));
+  __ addw(R0, R0, Operand(R0, LSL, 15));
+  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
+  __ AndImmediate(R0, R0,
+                  (static_cast<intptr_t>(1) << target::String::kHashBits) - 1);
+  __ CompareRegisters(R0, ZR);
+  // return hash_ == 0 ? 1 : hash_;
+  __ Bind(&done);
+  __ csinc(R0, R0, ZR, NE);  // R0 <- (R0 != 0) ? R0 : (ZR + 1).
+  __ str(R0, FieldAddress(R1, target::String::hash_offset()), kUnsignedWord);
+  __ SmiTag(R0);
+  __ ret();
+}
+
+// Allocates one-byte string of length 'end - start'. The content is not
+// initialized.
+// 'length-reg' (R2) contains tagged length.
+// Returns new string as tagged pointer in R0.
+static void TryAllocateOnebyteString(Assembler* assembler,
+                                     Label* ok,
+                                     Label* failure) {
+  const Register length_reg = R2;
+  Label fail;
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, R0, failure));
+  __ mov(R6, length_reg);  // Save the length register.
+  // TODO(koda): Protect against negative length and overflow here.
+  __ adds(length_reg, ZR, Operand(length_reg, ASR, kSmiTagSize));  // Smi untag.
+  // If the length is 0 then we have to make the allocated size a bit bigger,
+  // otherwise the string takes up less space than an ExternalOneByteString,
+  // and cannot be externalized.  TODO(erikcorry): We should probably just
+  // return a static zero length string here instead.
+  // length <- (length != 0) ? length : (ZR + 1).
+  __ csinc(length_reg, length_reg, ZR, NE);
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::String::InstanceSize() +
+      target::ObjectAlignment::kObjectAlignment - 1;
+  __ AddImmediate(length_reg, fixed_size_plus_alignment_padding);
+  __ andi(length_reg, length_reg,
+          Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
+
+  const intptr_t cid = kOneByteStringCid;
+  __ ldr(R0, Address(THR, target::Thread::top_offset()));
+
+  // length_reg: allocation size.
+  __ adds(R1, R0, Operand(length_reg));
+  __ b(&fail, CS);  // Fail on unsigned overflow.
+
+  // Check if the allocation fits into the remaining space.
+  // R0: potential new object start.
+  // R1: potential next object start.
+  // R2: allocation size.
+  __ ldr(R7, Address(THR, target::Thread::end_offset()));
+  __ cmp(R1, Operand(R7));
+  __ b(&fail, CS);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  __ str(R1, Address(THR, target::Thread::top_offset()));
+  __ AddImmediate(R0, kHeapObjectTag);
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2));
+
+  // Initialize the tags.
+  // R0: new object start as a tagged pointer.
+  // R1: new object end address.
+  // R2: allocation size.
+  {
+    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2;
+
+    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+    __ LslImmediate(R2, R2, shift);
+    __ csel(R2, R2, ZR, LS);
+
+    // Get the class index and insert it into the tags.
+    // R2: size and bit tags.
+    // This also clears the hash, which is in the high word of the tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    __ LoadImmediate(TMP, tags);
+    __ orr(R2, R2, Operand(TMP));
+    __ str(R2, FieldAddress(R0, target::Object::tags_offset()));  // Store tags.
+  }
+
+  // Set the length field using the saved length (R6).
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::String::length_offset()), R6);
+  __ b(ok);
+
+  __ Bind(&fail);
+  __ b(failure);
+}
+
+// Arg0: OneByteString (receiver).
+// Arg1: Start index as Smi.
+// Arg2: End index as Smi.
+// The indexes must be valid.
+void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                       Label* normal_ir_body) {
+  const intptr_t kStringOffset = 2 * target::kWordSize;
+  const intptr_t kStartIndexOffset = 1 * target::kWordSize;
+  const intptr_t kEndIndexOffset = 0 * target::kWordSize;
+  Label ok;
+
+  __ ldr(R2, Address(SP, kEndIndexOffset));
+  __ ldr(TMP, Address(SP, kStartIndexOffset));
+  __ orr(R3, R2, Operand(TMP));
+  __ BranchIfNotSmi(R3, normal_ir_body);  // 'start', 'end' not Smi.
+
+  __ sub(R2, R2, Operand(TMP));
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+  __ Bind(&ok);
+  // R0: new string as tagged pointer.
+  // Copy string.
+  __ ldr(R3, Address(SP, kStringOffset));
+  __ ldr(R1, Address(SP, kStartIndexOffset));
+  __ SmiUntag(R1);
+  __ add(R3, R3, Operand(R1));
+  // Calculate start address and untag (- 1).
+  __ AddImmediate(R3, target::OneByteString::data_offset() - 1);
+
+  // R3: Start address to copy from (untagged).
+  // R1: Untagged start index.
+  __ ldr(R2, Address(SP, kEndIndexOffset));
+  __ SmiUntag(R2);
+  __ sub(R2, R2, Operand(R1));
+
+  // R3: Start address to copy from (untagged).
+  // R2: Untagged number of bytes to copy.
+  // R0: Tagged result string.
+  // R6: Pointer into R3.
+  // R7: Pointer into R0.
+  // R1: Scratch register.
+  Label loop, done;
+  __ cmp(R2, Operand(0));
+  __ b(&done, LE);
+  __ mov(R6, R3);
+  __ mov(R7, R0);
+  __ Bind(&loop);
+  __ ldr(R1, Address(R6), kUnsignedByte);
+  __ AddImmediate(R6, 1);
+  __ sub(R2, R2, Operand(1));
+  __ cmp(R2, Operand(0));
+  __ str(R1, FieldAddress(R7, target::OneByteString::data_offset()),
+         kUnsignedByte);
+  __ AddImmediate(R7, 1);
+  __ b(&loop, GT);
+
+  __ Bind(&done);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ ldr(R2, Address(SP, 0 * target::kWordSize));  // Value.
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));  // Index.
+  __ ldr(R0, Address(SP, 2 * target::kWordSize));  // OneByteString.
+  __ SmiUntag(R1);
+  __ SmiUntag(R2);
+  __ AddImmediate(R3, R0,
+                  target::OneByteString::data_offset() - kHeapObjectTag);
+  __ str(R2, Address(R3, R1), kUnsignedByte);
+  __ ret();
+}
+
+void AsmIntrinsifier::OneByteString_allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label ok;
+
+  __ ldr(R2, Address(SP, 0 * target::kWordSize));  // Length.
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
+
+  __ Bind(&ok);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
+  __ ldr(R0, Address(SP, 1 * target::kWordSize));  // This.
+  __ ldr(R1, Address(SP, 0 * target::kWordSize));  // Other.
+
+  // Are identical?
+  __ cmp(R0, Operand(R1));
+  __ b(&is_true, EQ);
+
+  // Is other OneByteString?
+  __ BranchIfSmi(R1, normal_ir_body);
+  __ CompareClassId(R1, string_cid);
+  __ b(normal_ir_body, NE);
+
+  // Have same length?
+  __ ldr(R2, FieldAddress(R0, target::String::length_offset()));
+  __ ldr(R3, FieldAddress(R1, target::String::length_offset()));
+  __ cmp(R2, Operand(R3));
+  __ b(&is_false, NE);
+
+  // Check contents, no fall-through possible.
+  // TODO(zra): try out other sequences.
+  ASSERT((string_cid == kOneByteStringCid) ||
+         (string_cid == kTwoByteStringCid));
+  const intptr_t offset = (string_cid == kOneByteStringCid)
+                              ? target::OneByteString::data_offset()
+                              : target::TwoByteString::data_offset();
+  __ AddImmediate(R0, offset - kHeapObjectTag);
+  __ AddImmediate(R1, offset - kHeapObjectTag);
+  __ SmiUntag(R2);
+  __ Bind(&loop);
+  __ AddImmediate(R2, -1);
+  __ CompareRegisters(R2, ZR);
+  __ b(&is_true, LT);
+  if (string_cid == kOneByteStringCid) {
+    __ ldr(R3, Address(R0), kUnsignedByte);
+    __ ldr(R4, Address(R1), kUnsignedByte);
+    __ AddImmediate(R0, 1);
+    __ AddImmediate(R1, 1);
+  } else if (string_cid == kTwoByteStringCid) {
+    __ ldr(R3, Address(R0), kUnsignedHalfword);
+    __ ldr(R4, Address(R1), kUnsignedHalfword);
+    __ AddImmediate(R0, 2);
+    __ AddImmediate(R1, 2);
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmp(R3, Operand(R4));
+  __ b(&is_false, NE);
+  __ b(&loop);
+
+  __ Bind(&is_true);
+  __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
+}
+
+void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
+}
+
+void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                   Label* normal_ir_body,
+                                                   bool sticky) {
+  if (FLAG_interpret_irregexp) return;
+
+  static const intptr_t kRegExpParamOffset = 2 * target::kWordSize;
+  static const intptr_t kStringParamOffset = 1 * target::kWordSize;
+  // start_index smi is located at offset 0.
+
+  // Incoming registers:
+  // R0: Function. (Will be reloaded with the specialized matcher function.)
+  // R4: Arguments descriptor. (Will be preserved.)
+  // R5: Unknown. (Must be GC safe on tail call.)
+
+  // Load the specialized function pointer into R0. Leverage the fact the
+  // string CIDs as well as stored function pointers are in sequence.
+  __ ldr(R2, Address(SP, kRegExpParamOffset));
+  __ ldr(R1, Address(SP, kStringParamOffset));
+  __ LoadClassId(R1, R1);
+  __ AddImmediate(R1, -kOneByteStringCid);
+  __ add(R1, R2, Operand(R1, LSL, target::kWordSizeLog2));
+  __ ldr(R0, FieldAddress(R1, target::RegExp::function_offset(kOneByteStringCid,
+                                                              sticky)));
+
+  // Registers are now set up for the lazy compile stub. It expects the function
+  // in R0, the argument descriptor in R4, and IC-Data in R5.
+  __ eor(R5, R5, Operand(R5));
+
+  // Tail-call the function.
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ ldr(R1, FieldAddress(R0, target::Function::entry_point_offset()));
+  __ br(R1);
+}
+
+// On stack: user tag (+0).
+void AsmIntrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  // R1: Isolate.
+  __ LoadIsolate(R1);
+  // R0: Current user tag.
+  __ ldr(R0, Address(R1, target::Isolate::current_tag_offset()));
+  // R2: UserTag.
+  __ ldr(R2, Address(SP, +0 * target::kWordSize));
+  // Set target::Isolate::current_tag_.
+  __ str(R2, Address(R1, target::Isolate::current_tag_offset()));
+  // R2: UserTag's tag.
+  __ ldr(R2, FieldAddress(R2, target::UserTag::tag_offset()));
+  // Set target::Isolate::user_tag_.
+  __ str(R2, Address(R1, target::Isolate::user_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ LoadIsolate(R0);
+  __ ldr(R0, Address(R0, target::Isolate::default_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ LoadIsolate(R0);
+  __ ldr(R0, Address(R0, target::Isolate::current_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+#if !defined(SUPPORT_TIMELINE)
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ ret();
+#else
+  // Load TimelineStream*.
+  __ ldr(R0, Address(THR, target::Thread::dart_stream_offset()));
+  // Load uintptr_t from TimelineStream*.
+  __ ldr(R0, Address(R0, target::TimelineStream::enabled_offset()));
+  __ cmp(R0, Operand(0));
+  __ LoadObject(R0, CastHandle<Object>(FalseObject()));
+  __ LoadObject(TMP, CastHandle<Object>(TrueObject()));
+  __ csel(R0, TMP, R0, NE);
+  __ ret();
+#endif
+}
+
+void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  __ LoadObject(R0, NullObject());
+  __ str(R0, Address(THR, target::Thread::async_stack_trace_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  __ ldr(R0, Address(THR, target::Thread::async_stack_trace_offset()));
+  __ LoadObject(R0, NullObject());
+  __ ret();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/asm_intrinsifier_dbc.cc b/runtime/vm/compiler/asm_intrinsifier_dbc.cc
new file mode 100644
index 0000000..cfb1130
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier_dbc.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for 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"  // Needed here to get TARGET_ARCH_DBC.
+#if defined(TARGET_ARCH_DBC)
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
+#include "vm/compiler/asm_intrinsifier.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/intrinsifier.h"
+
+namespace dart {
+namespace compiler {
+
+DECLARE_FLAG(bool, interpret_irregexp);
+
+#define DEFINE_FUNCTION(class_name, test_function_name, enum_name, fp)         \
+  void AsmIntrinsifier::enum_name(Assembler* assembler,                        \
+                                  Label* normal_ir_body) {                     \
+    if (Simulator::IsSupportedIntrinsic(Simulator::k##enum_name##Intrinsic)) { \
+      assembler->Intrinsic(Simulator::k##enum_name##Intrinsic);                \
+    }                                                                          \
+    assembler->Bind(normal_ir_body);                                           \
+  }
+
+ALL_INTRINSICS_LIST(DEFINE_FUNCTION)
+GRAPH_INTRINSICS_LIST(DEFINE_FUNCTION)
+#undef DEFINE_FUNCTION
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
new file mode 100644
index 0000000..392d129
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -0,0 +1,2284 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 intrinsic code below is executed before a method has built its frame.
+// The return address is on the stack and the arguments below it.
+// Registers EDX (arguments descriptor) and ECX (function) must be preserved.
+// Each intrinsification method returns true if the corresponding
+// Dart method was intrinsified.
+
+#include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
+#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
+#include "vm/compiler/asm_intrinsifier.h"
+#include "vm/compiler/assembler/assembler.h"
+
+namespace dart {
+namespace compiler {
+
+// When entering intrinsics code:
+// ECX: IC Data
+// EDX: Arguments descriptor
+// TOS: Return address
+// The ECX, EDX registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The EBP register should not be modified, because it is used by the profiler.
+// The THR register (see constants_ia32.h) must be preserved.
+
+#define __ assembler->
+
+intptr_t AsmIntrinsifier::ParameterSlotFromSp() {
+  return 0;
+}
+
+void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->movl(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
+}
+
+void AsmIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
+}
+
+// Allocate a GrowableObjectArray:: using the backing array specified.
+// On stack: type argument (+2), data (+1), return-address (+0).
+void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  // This snippet of inlined code uses the following registers:
+  // EAX, EBX
+  // and the newly allocated object is returned in EAX.
+  const intptr_t kTypeArgumentsOffset = 2 * target::kWordSize;
+
+  const intptr_t kArrayOffset = 1 * target::kWordSize;
+
+  // Try allocating in new space.
+  const Class& cls = GrowableObjectArrayClass();
+  __ TryAllocate(cls, normal_ir_body, Assembler::kNearJump, EAX, EBX);
+
+  // Store backing array object in growable array object.
+  __ movl(EBX, Address(ESP, kArrayOffset));  // data argument.
+  // EAX is new, no barrier needed.
+  __ StoreIntoObjectNoBarrier(
+      EAX, FieldAddress(EAX, target::GrowableObjectArray::data_offset()), EBX);
+
+  // EAX: new growable array object start as a tagged pointer.
+  // Store the type argument field in the growable array object.
+  __ movl(EBX, Address(ESP, kTypeArgumentsOffset));  // type argument.
+  __ StoreIntoObjectNoBarrier(
+      EAX,
+      FieldAddress(EAX, target::GrowableObjectArray::type_arguments_offset()),
+      EBX);
+
+  __ ZeroInitSmiField(
+      FieldAddress(EAX, target::GrowableObjectArray::length_offset()));
+  __ ret();  // returns the newly allocated object in EAX.
+
+  __ Bind(normal_ir_body);
+}
+
+#define TYPED_ARRAY_ALLOCATION(cid, max_len, scale_factor)                     \
+  const intptr_t kArrayLengthStackOffset = 1 * target::kWordSize;              \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, EDI, normal_ir_body, false));    \
+  __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */     \
+  /* Check that length is a positive Smi. */                                   \
+  /* EDI: requested array length argument. */                                  \
+  __ testl(EDI, Immediate(kSmiTagMask));                                       \
+  __ j(NOT_ZERO, normal_ir_body);                                              \
+  __ cmpl(EDI, Immediate(0));                                                  \
+  __ j(LESS, normal_ir_body);                                                  \
+  __ SmiUntag(EDI);                                                            \
+  /* Check for maximum allowed length. */                                      \
+  /* EDI: untagged array length. */                                            \
+  __ cmpl(EDI, Immediate(max_len));                                            \
+  __ j(GREATER, normal_ir_body);                                               \
+  /* Special case for scaling by 16. */                                        \
+  if (scale_factor == TIMES_16) {                                              \
+    /* double length of array. */                                              \
+    __ addl(EDI, EDI);                                                         \
+    /* only scale by 8. */                                                     \
+    scale_factor = TIMES_8;                                                    \
+  }                                                                            \
+  const intptr_t fixed_size_plus_alignment_padding =                           \
+      target::TypedData::InstanceSize() +                                      \
+      target::ObjectAlignment::kObjectAlignment - 1;                           \
+  __ leal(EDI, Address(EDI, scale_factor, fixed_size_plus_alignment_padding)); \
+  __ andl(EDI, Immediate(-target::ObjectAlignment::kObjectAlignment));         \
+  __ movl(EAX, Address(THR, target::Thread::top_offset()));                    \
+  __ movl(EBX, EAX);                                                           \
+                                                                               \
+  /* EDI: allocation size. */                                                  \
+  __ addl(EBX, EDI);                                                           \
+  __ j(CARRY, normal_ir_body);                                                 \
+                                                                               \
+  /* Check if the allocation fits into the remaining space. */                 \
+  /* EAX: potential new object start. */                                       \
+  /* EBX: potential next object start. */                                      \
+  /* EDI: allocation size. */                                                  \
+  __ cmpl(EBX, Address(THR, target::Thread::end_offset()));                    \
+  __ j(ABOVE_EQUAL, normal_ir_body);                                           \
+                                                                               \
+  /* Successfully allocated the object(s), now update top to point to */       \
+  /* next object start and initialize the object. */                           \
+  __ movl(Address(THR, target::Thread::top_offset()), EBX);                    \
+  __ addl(EAX, Immediate(kHeapObjectTag));                                     \
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EDI, ECX));             \
+                                                                               \
+  /* Initialize the tags. */                                                   \
+  /* EAX: new object start as a tagged pointer. */                             \
+  /* EBX: new object end address. */                                           \
+  /* EDI: allocation size. */                                                  \
+  {                                                                            \
+    Label size_tag_overflow, done;                                             \
+    __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));            \
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);                     \
+    __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -             \
+                           target::ObjectAlignment::kObjectAlignmentLog2));    \
+    __ jmp(&done, Assembler::kNearJump);                                       \
+                                                                               \
+    __ Bind(&size_tag_overflow);                                               \
+    __ movl(EDI, Immediate(0));                                                \
+    __ Bind(&done);                                                            \
+                                                                               \
+    /* Get the class index and insert it into the tags. */                     \
+    uint32_t tags =                                                            \
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);        \
+    __ orl(EDI, Immediate(tags));                                              \
+    __ movl(FieldAddress(EAX, target::Object::tags_offset()),                  \
+            EDI); /* Tags. */                                                  \
+  }                                                                            \
+  /* Set the length field. */                                                  \
+  /* EAX: new object start as a tagged pointer. */                             \
+  /* EBX: new object end address. */                                           \
+  __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */     \
+  __ StoreIntoObjectNoBarrier(                                                 \
+      EAX, FieldAddress(EAX, target::TypedData::length_offset()), EDI);        \
+  /* Initialize all array elements to 0. */                                    \
+  /* EAX: new object start as a tagged pointer. */                             \
+  /* EBX: new object end address. */                                           \
+  /* EDI: iterator which initially points to the start of the variable */      \
+  /* ECX: scratch register. */                                                 \
+  /* data area to be initialized. */                                           \
+  __ xorl(ECX, ECX); /* Zero. */                                               \
+  __ leal(EDI, FieldAddress(EAX, target::TypedData::InstanceSize()));          \
+  Label done, init_loop;                                                       \
+  __ Bind(&init_loop);                                                         \
+  __ cmpl(EDI, EBX);                                                           \
+  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);                              \
+  __ movl(Address(EDI, 0), ECX);                                               \
+  __ addl(EDI, Immediate(target::kWordSize));                                  \
+  __ jmp(&init_loop, Assembler::kNearJump);                                    \
+  __ Bind(&done);                                                              \
+                                                                               \
+  __ ret();                                                                    \
+  __ Bind(normal_ir_body);
+
+static ScaleFactor GetScaleFactor(intptr_t size) {
+  switch (size) {
+    case 1:
+      return TIMES_1;
+    case 2:
+      return TIMES_2;
+    case 4:
+      return TIMES_4;
+    case 8:
+      return TIMES_8;
+    case 16:
+      return TIMES_16;
+  }
+  UNREACHABLE();
+  return static_cast<ScaleFactor>(0);
+}
+
+#define TYPED_DATA_ALLOCATOR(clazz)                                            \
+  void AsmIntrinsifier::TypedData_##clazz##_factory(Assembler* assembler,      \
+                                                    Label* normal_ir_body) {   \
+    intptr_t size = TypedDataElementSizeInBytes(kTypedData##clazz##Cid);       \
+    intptr_t max_len = TypedDataMaxNewSpaceElements(kTypedData##clazz##Cid);   \
+    ScaleFactor scale = GetScaleFactor(size);                                  \
+    TYPED_ARRAY_ALLOCATION(kTypedData##clazz##Cid, max_len, scale);            \
+  }
+CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
+#undef TYPED_DATA_ALLOCATOR
+
+// Tests if two top most arguments are smis, jumps to label not_smi if not.
+// Topmost argument is in EAX.
+static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
+  __ orl(EBX, EAX);
+  __ testl(EBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, not_smi, Assembler::kNearJump);
+}
+
+void AsmIntrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ addl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ subl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ movl(EBX, EAX);
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ subl(EAX, EBX);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
+  __ SmiUntag(EAX);
+  __ imull(EAX, Address(ESP, +2 * target::kWordSize));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
+}
+
+// Optimizations:
+// - result is 0 if:
+//   - left is 0
+//   - left equals right
+// - result is left if
+//   - left > 0 && left < right
+// EAX: Tagged left (dividend).
+// EBX: Tagged right (divisor).
+// Returns:
+//   EDX: Untagged fallthrough result (remainder to be adjusted), or
+//   EAX: Tagged return result (remainder).
+static void EmitRemainderOperation(Assembler* assembler) {
+  Label return_zero, modulo;
+  // Check for quick zero results.
+  __ cmpl(EAX, Immediate(0));
+  __ j(EQUAL, &return_zero, Assembler::kNearJump);
+  __ cmpl(EAX, EBX);
+  __ j(EQUAL, &return_zero, Assembler::kNearJump);
+
+  // Check if result equals left.
+  __ cmpl(EAX, Immediate(0));
+  __ j(LESS, &modulo, Assembler::kNearJump);
+  // left is positive.
+  __ cmpl(EAX, EBX);
+  __ j(GREATER, &modulo, Assembler::kNearJump);
+  // left is less than right, result is left (EAX).
+  __ ret();
+
+  __ Bind(&return_zero);
+  __ xorl(EAX, EAX);
+  __ ret();
+
+  __ Bind(&modulo);
+  __ SmiUntag(EBX);
+  __ SmiUntag(EAX);
+  __ cdq();
+  __ idivl(EBX);
+}
+
+// Implementation:
+//  res = left % right;
+//  if (res < 0) {
+//    if (right < 0) {
+//      res = res - right;
+//    } else {
+//      res = res + right;
+//    }
+//  }
+void AsmIntrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label subtract;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
+  // EAX: Tagged left (dividend).
+  // EBX: Tagged right (divisor).
+  // Check if modulo by zero -> exception thrown in main function.
+  __ cmpl(EBX, Immediate(0));
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
+  EmitRemainderOperation(assembler);
+  // Untagged remainder result in EDX.
+  Label done;
+  __ movl(EAX, EDX);
+  __ cmpl(EAX, Immediate(0));
+  __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
+  // Result is negative, adjust it.
+  __ cmpl(EBX, Immediate(0));
+  __ j(LESS, &subtract, Assembler::kNearJump);
+  __ addl(EAX, EBX);
+  __ SmiTag(EAX);
+  __ ret();
+
+  __ Bind(&subtract);
+  __ subl(EAX, EBX);
+
+  __ Bind(&done);
+  // The remainder of two smis is always a smi, no overflow check needed.
+  __ SmiTag(EAX);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // EAX: right argument (divisor)
+  __ cmpl(EAX, Immediate(0));
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ movl(EBX, EAX);
+  __ SmiUntag(EBX);
+  __ movl(EAX,
+          Address(ESP, +2 * target::kWordSize));  // Left argument (dividend).
+  __ SmiUntag(EAX);
+  __ pushl(EDX);  // Preserve EDX in case of 'fall_through'.
+  __ cdq();
+  __ idivl(EBX);
+  __ popl(EDX);
+  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
+  // cannot tag the result.
+  __ cmpl(EAX, Immediate(0x40000000));
+  __ j(EQUAL, normal_ir_body);
+  __ SmiTag(EAX);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_negate(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
+  __ negl(EAX);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
+  __ andl(EAX, EBX);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
+  __ orl(EAX, EBX);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
+  __ xorl(EAX, EBX);
+  // Result is in EAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
+  ASSERT(kSmiTagShift == 1);
+  ASSERT(kSmiTag == 0);
+  Label overflow;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // Shift value is in EAX. Compare with tagged Smi.
+  __ cmpl(EAX, Immediate(target::ToRawSmi(target::Smi::kBits)));
+  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
+
+  __ SmiUntag(EAX);
+  __ movl(ECX, EAX);  // Shift amount must be in ECX.
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Value.
+
+  // Overflow test - all the shifted-out bits must be same as the sign bit.
+  __ movl(EBX, EAX);
+  __ shll(EAX, ECX);
+  __ sarl(EAX, ECX);
+  __ cmpl(EAX, EBX);
+  __ j(NOT_EQUAL, &overflow, Assembler::kNearJump);
+
+  __ shll(EAX, ECX);  // Shift for result now we know there is no overflow.
+
+  // EAX is a correctly tagged Smi.
+  __ ret();
+
+  __ Bind(&overflow);
+  // Arguments are Smi but the shift produced an overflow to Mint.
+  __ cmpl(EBX, Immediate(0));
+  // TODO(srdjan): Implement negative values, for now fall through.
+  __ j(LESS, normal_ir_body, Assembler::kNearJump);
+  __ SmiUntag(EBX);
+  __ movl(EAX, EBX);
+  __ shll(EBX, ECX);
+  __ xorl(EDI, EDI);
+  __ shldl(EDI, EAX, ECX);
+  // Result in EDI (high) and EBX (low).
+  const Class& mint_class = MintClass();
+  __ TryAllocate(mint_class, normal_ir_body, Assembler::kNearJump,
+                 EAX,   // Result register.
+                 ECX);  // temp
+  // EBX and EDI are not objects but integer values.
+  __ movl(FieldAddress(EAX, target::Mint::value_offset()), EBX);
+  __ movl(FieldAddress(EAX, target::Mint::value_offset() + target::kWordSize),
+          EDI);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+static void Push64SmiOrMint(Assembler* assembler,
+                            Register reg,
+                            Register tmp,
+                            Label* not_smi_or_mint) {
+  Label not_smi, done;
+  __ testl(reg, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
+  __ SmiUntag(reg);
+  // Sign extend to 64 bit
+  __ movl(tmp, reg);
+  __ sarl(tmp, Immediate(31));
+  __ pushl(tmp);
+  __ pushl(reg);
+  __ jmp(&done);
+  __ Bind(&not_smi);
+  __ CompareClassId(reg, kMintCid, tmp);
+  __ j(NOT_EQUAL, not_smi_or_mint);
+  // Mint.
+  __ pushl(FieldAddress(reg, target::Mint::value_offset() + target::kWordSize));
+  __ pushl(FieldAddress(reg, target::Mint::value_offset()));
+  __ Bind(&done);
+}
+
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
+  Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
+  TestBothArgumentsSmis(assembler, &try_mint_smi);
+  // EAX contains the right argument.
+  __ cmpl(Address(ESP, +2 * target::kWordSize), EAX);
+  __ j(true_condition, &is_true, Assembler::kNearJump);
+  __ Bind(&is_false);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // 64-bit comparison
+  Condition hi_true_cond, hi_false_cond, lo_false_cond;
+  switch (true_condition) {
+    case LESS:
+    case LESS_EQUAL:
+      hi_true_cond = LESS;
+      hi_false_cond = GREATER;
+      lo_false_cond = (true_condition == LESS) ? ABOVE_EQUAL : ABOVE;
+      break;
+    case GREATER:
+    case GREATER_EQUAL:
+      hi_true_cond = GREATER;
+      hi_false_cond = LESS;
+      lo_false_cond = (true_condition == GREATER) ? BELOW_EQUAL : BELOW;
+      break;
+    default:
+      UNREACHABLE();
+      hi_true_cond = hi_false_cond = lo_false_cond = OVERFLOW;
+  }
+  __ Bind(&try_mint_smi);
+  // Note that EDX and ECX must be preserved in case we fall through to main
+  // method.
+  // EAX contains the right argument.
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));  // Left argument.
+  // Push left as 64 bit integer.
+  Push64SmiOrMint(assembler, EBX, EDI, normal_ir_body);
+  // Push right as 64 bit integer.
+  Push64SmiOrMint(assembler, EAX, EDI, &drop_two_fall_through);
+  __ popl(EBX);       // Right.LO.
+  __ popl(ECX);       // Right.HI.
+  __ popl(EAX);       // Left.LO.
+  __ popl(EDX);       // Left.HI.
+  __ cmpl(EDX, ECX);  // cmpl left.HI, right.HI.
+  __ j(hi_false_cond, &is_false, Assembler::kNearJump);
+  __ j(hi_true_cond, &is_true, Assembler::kNearJump);
+  __ cmpl(EAX, EBX);  // cmpl left.LO, right.LO.
+  __ j(lo_false_cond, &is_false, Assembler::kNearJump);
+  // Else is true.
+  __ jmp(&is_true);
+
+  __ Bind(&drop_two_fall_through);
+  __ Drop(2);
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS);
+}
+
+void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Integer_greaterThanFromInt(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER);
+}
+
+void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS_EQUAL);
+}
+
+void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER_EQUAL);
+}
+
+// This is called for Smi and Mint receivers. The right argument
+// can be Smi, Mint or double.
+void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label true_label, check_for_mint;
+  // For integer receiver '===' check first.
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ cmpl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ j(EQUAL, &true_label, Assembler::kNearJump);
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));
+  __ orl(EAX, EBX);
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
+  // Both arguments are smi, '===' is good enough.
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&true_label);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // At least one of the arguments was not Smi.
+  Label receiver_not_smi;
+  __ Bind(&check_for_mint);
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Receiver.
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &receiver_not_smi);
+
+  // Left (receiver) is Smi, return false if right is not Double.
+  // Note that an instance of Mint never contains a value that can be
+  // represented by Smi.
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // Right argument.
+  __ CompareClassId(EAX, kDoubleCid, EDI);
+  __ j(EQUAL, normal_ir_body);
+  __ LoadObject(EAX,
+                CastHandle<Object>(FalseObject()));  // Smi == Mint -> false.
+  __ ret();
+
+  __ Bind(&receiver_not_smi);
+  // EAX:: receiver.
+  __ CompareClassId(EAX, kMintCid, EDI);
+  __ j(NOT_EQUAL, normal_ir_body);
+  // Receiver is Mint, return false if right is Smi.
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // Right argument.
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  // TODO(srdjan): Implement Mint == Mint comparison.
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_equal(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  Label shift_count_ok;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // Can destroy ECX since we are not falling through.
+  const Immediate& count_limit = Immediate(0x1F);
+  // Check that the count is not larger than what the hardware can handle.
+  // For shifting right a Smi the result is the same for all numbers
+  // >= count_limit.
+  __ SmiUntag(EAX);
+  // Negative counts throw exception.
+  __ cmpl(EAX, Immediate(0));
+  __ j(LESS, normal_ir_body, Assembler::kNearJump);
+  __ cmpl(EAX, count_limit);
+  __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
+  __ movl(EAX, count_limit);
+  __ Bind(&shift_count_ok);
+  __ movl(ECX, EAX);  // Shift amount must be in ECX.
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Value.
+  __ SmiUntag(EAX);                                    // Value.
+  __ sarl(EAX, ECX);
+  __ SmiTag(EAX);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+// Argument is Smi (receiver).
+void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // Receiver.
+  __ notl(EAX);
+  __ andl(EAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
+  __ ret();
+}
+
+void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  ASSERT(kSmiTagShift == 1);
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // Receiver.
+  // XOR with sign bit to complement bits if value is negative.
+  __ movl(ECX, EAX);
+  __ sarl(ECX, Immediate(31));  // All 0 or all 1.
+  __ xorl(EAX, ECX);
+  // BSR does not write the destination register if source is zero.  Put a 1 in
+  // the Smi tag bit to ensure BSR writes to destination register.
+  __ orl(EAX, Immediate(kSmiTagMask));
+  __ bsrl(EAX, EAX);
+  __ SmiTag(EAX);
+  __ ret();
+}
+
+void AsmIntrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 5 * target::kWordSize));  // x_digits
+  __ movl(ECX, Address(ESP, 3 * target::kWordSize));  // n is Smi
+  __ SmiUntag(ECX);
+  __ movl(EBX, Address(ESP, 2 * target::kWordSize));  // r_digits
+  __ movl(ESI, ECX);
+  __ sarl(ESI, Immediate(5));  // ESI = n ~/ _DIGIT_BITS.
+  __ leal(EBX,
+          FieldAddress(EBX, ESI, TIMES_4, target::TypedData::data_offset()));
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // x_used > 0, Smi.
+  __ SmiUntag(ESI);
+  __ decl(ESI);
+  __ xorl(EAX, EAX);  // EAX = 0.
+  __ movl(EDX,
+          FieldAddress(EDI, ESI, TIMES_4, target::TypedData::data_offset()));
+  __ shldl(EAX, EDX, ECX);
+  __ movl(Address(EBX, ESI, TIMES_4, kBytesPerBigIntDigit), EAX);
+  Label last;
+  __ cmpl(ESI, Immediate(0));
+  __ j(EQUAL, &last, Assembler::kNearJump);
+  Label loop;
+  __ Bind(&loop);
+  __ movl(EAX, EDX);
+  __ movl(EDX, FieldAddress(
+                   EDI, ESI, TIMES_4,
+                   target::TypedData::data_offset() - kBytesPerBigIntDigit));
+  __ shldl(EAX, EDX, ECX);
+  __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
+  __ decl(ESI);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+  __ Bind(&last);
+  __ shldl(EDX, ESI, ECX);  // ESI == 0.
+  __ movl(Address(EBX, 0), EDX);
+
+  // Restore THR and return.
+  __ popl(THR);
+  __ LoadObject(EAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _rsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 5 * target::kWordSize));  // x_digits
+  __ movl(ECX, Address(ESP, 3 * target::kWordSize));  // n is Smi
+  __ SmiUntag(ECX);
+  __ movl(EBX, Address(ESP, 2 * target::kWordSize));  // r_digits
+  __ movl(EDX, ECX);
+  __ sarl(EDX, Immediate(5));                         // EDX = n ~/ _DIGIT_BITS.
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // x_used > 0, Smi.
+  __ SmiUntag(ESI);
+  __ decl(ESI);
+  // EDI = &x_digits[x_used - 1].
+  __ leal(EDI,
+          FieldAddress(EDI, ESI, TIMES_4, target::TypedData::data_offset()));
+  __ subl(ESI, EDX);
+  // EBX = &r_digits[x_used - 1 - (n ~/ 32)].
+  __ leal(EBX,
+          FieldAddress(EBX, ESI, TIMES_4, target::TypedData::data_offset()));
+  __ negl(ESI);
+  __ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
+  Label last;
+  __ cmpl(ESI, Immediate(0));
+  __ j(EQUAL, &last, Assembler::kNearJump);
+  Label loop;
+  __ Bind(&loop);
+  __ movl(EAX, EDX);
+  __ movl(EDX, Address(EDI, ESI, TIMES_4, kBytesPerBigIntDigit));
+  __ shrdl(EAX, EDX, ECX);
+  __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
+  __ incl(ESI);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+  __ Bind(&last);
+  __ shrdl(EDX, ESI, ECX);  // ESI == 0.
+  __ movl(Address(EBX, 0), EDX);
+
+  // Restore THR and return.
+  __ popl(THR);
+  __ LoadObject(EAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absAdd(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 6 * target::kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 5 * target::kWordSize));  // used is Smi
+  __ SmiUntag(EAX);                                   // used > 0.
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // a_digits
+  __ movl(ECX, Address(ESP, 3 * target::kWordSize));  // a_used is Smi
+  __ SmiUntag(ECX);                                   // a_used > 0.
+  __ movl(EBX, Address(ESP, 2 * target::kWordSize));  // r_digits
+
+  // Precompute 'used - a_used' now so that carry flag is not lost later.
+  __ subl(EAX, ECX);
+  __ incl(EAX);  // To account for the extra test between loops.
+  __ pushl(EAX);
+
+  __ xorl(EDX, EDX);  // EDX = 0, carry flag = 0.
+  Label add_loop;
+  __ Bind(&add_loop);
+  // Loop a_used times, ECX = a_used, ECX > 0.
+  __ movl(EAX,
+          FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+  __ adcl(EAX,
+          FieldAddress(ESI, EDX, TIMES_4, target::TypedData::data_offset()));
+  __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+          EAX);
+  __ incl(EDX);  // Does not affect carry flag.
+  __ decl(ECX);  // Does not affect carry flag.
+  __ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
+
+  Label last_carry;
+  __ popl(ECX);
+  __ decl(ECX);                                   // Does not affect carry flag.
+  __ j(ZERO, &last_carry, Assembler::kNearJump);  // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop used - a_used times, ECX = used - a_used, ECX > 0.
+  __ movl(EAX,
+          FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+  __ adcl(EAX, Immediate(0));
+  __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+          EAX);
+  __ incl(EDX);  // Does not affect carry flag.
+  __ decl(ECX);  // Does not affect carry flag.
+  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
+
+  __ Bind(&last_carry);
+  __ movl(EAX, Immediate(0));
+  __ adcl(EAX, Immediate(0));
+  __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+          EAX);
+
+  // Restore THR and return.
+  __ popl(THR);
+  __ LoadObject(EAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absSub(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  __ movl(EDI, Address(ESP, 6 * target::kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 5 * target::kWordSize));  // used is Smi
+  __ SmiUntag(EAX);                                   // used > 0.
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // a_digits
+  __ movl(ECX, Address(ESP, 3 * target::kWordSize));  // a_used is Smi
+  __ SmiUntag(ECX);                                   // a_used > 0.
+  __ movl(EBX, Address(ESP, 2 * target::kWordSize));  // r_digits
+
+  // Precompute 'used - a_used' now so that carry flag is not lost later.
+  __ subl(EAX, ECX);
+  __ incl(EAX);  // To account for the extra test between loops.
+  __ pushl(EAX);
+
+  __ xorl(EDX, EDX);  // EDX = 0, carry flag = 0.
+  Label sub_loop;
+  __ Bind(&sub_loop);
+  // Loop a_used times, ECX = a_used, ECX > 0.
+  __ movl(EAX,
+          FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+  __ sbbl(EAX,
+          FieldAddress(ESI, EDX, TIMES_4, target::TypedData::data_offset()));
+  __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+          EAX);
+  __ incl(EDX);  // Does not affect carry flag.
+  __ decl(ECX);  // Does not affect carry flag.
+  __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
+
+  Label done;
+  __ popl(ECX);
+  __ decl(ECX);                             // Does not affect carry flag.
+  __ j(ZERO, &done, Assembler::kNearJump);  // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop used - a_used times, ECX = used - a_used, ECX > 0.
+  __ movl(EAX,
+          FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+  __ sbbl(EAX, Immediate(0));
+  __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+          EAX);
+  __ incl(EDX);  // Does not affect carry flag.
+  __ decl(ECX);  // Does not affect carry flag.
+  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  // Restore THR and return.
+  __ popl(THR);
+  __ LoadObject(EAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulAdd(Uint32List x_digits, int xi,
+  //                    Uint32List m_digits, int i,
+  //                    Uint32List a_digits, int j, int n) {
+  //   uint32_t x = x_digits[xi >> 1];  // xi is Smi.
+  //   if (x == 0 || n == 0) {
+  //     return 1;
+  //   }
+  //   uint32_t* mip = &m_digits[i >> 1];  // i is Smi.
+  //   uint32_t* ajp = &a_digits[j >> 1];  // j is Smi.
+  //   uint32_t c = 0;
+  //   SmiUntag(n);
+  //   do {
+  //     uint32_t mi = *mip++;
+  //     uint32_t aj = *ajp;
+  //     uint64_t t = x*mi + aj + c;  // 32-bit * 32-bit -> 64-bit.
+  //     *ajp++ = low32(t);
+  //     c = high32(t);
+  //   } while (--n > 0);
+  //   while (c != 0) {
+  //     uint64_t t = *ajp + c;
+  //     *ajp++ = low32(t);
+  //     c = high32(t);  // c == 0 or 1.
+  //   }
+  //   return 1;
+  // }
+
+  Label no_op;
+  // EBX = x, no_op if x == 0
+  __ movl(ECX, Address(ESP, 7 * target::kWordSize));  // x_digits
+  __ movl(EAX, Address(ESP, 6 * target::kWordSize));  // xi is Smi
+  __ movl(EBX,
+          FieldAddress(ECX, EAX, TIMES_2, target::TypedData::data_offset()));
+  __ testl(EBX, EBX);
+  __ j(ZERO, &no_op, Assembler::kNearJump);
+
+  // EDX = SmiUntag(n), no_op if n == 0
+  __ movl(EDX, Address(ESP, 1 * target::kWordSize));
+  __ SmiUntag(EDX);
+  __ j(ZERO, &no_op, Assembler::kNearJump);
+
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  // EDI = mip = &m_digits[i >> 1]
+  __ movl(EDI, Address(ESP, 6 * target::kWordSize));  // m_digits
+  __ movl(EAX, Address(ESP, 5 * target::kWordSize));  // i is Smi
+  __ leal(EDI,
+          FieldAddress(EDI, EAX, TIMES_2, target::TypedData::data_offset()));
+
+  // ESI = ajp = &a_digits[j >> 1]
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // a_digits
+  __ movl(EAX, Address(ESP, 3 * target::kWordSize));  // j is Smi
+  __ leal(ESI,
+          FieldAddress(ESI, EAX, TIMES_2, target::TypedData::data_offset()));
+
+  // Save n
+  __ pushl(EDX);
+  Address n_addr = Address(ESP, 0 * target::kWordSize);
+
+  // ECX = c = 0
+  __ xorl(ECX, ECX);
+
+  Label muladd_loop;
+  __ Bind(&muladd_loop);
+  // x:   EBX
+  // mip: EDI
+  // ajp: ESI
+  // c:   ECX
+  // t:   EDX:EAX (not live at loop entry)
+  // n:   ESP[0]
+
+  // uint32_t mi = *mip++
+  __ movl(EAX, Address(EDI, 0));
+  __ addl(EDI, Immediate(kBytesPerBigIntDigit));
+
+  // uint64_t t = x*mi
+  __ mull(EBX);       // t = EDX:EAX = EAX * EBX
+  __ addl(EAX, ECX);  // t += c
+  __ adcl(EDX, Immediate(0));
+
+  // uint32_t aj = *ajp; t += aj
+  __ addl(EAX, Address(ESI, 0));
+  __ adcl(EDX, Immediate(0));
+
+  // *ajp++ = low32(t)
+  __ movl(Address(ESI, 0), EAX);
+  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
+
+  // c = high32(t)
+  __ movl(ECX, EDX);
+
+  // while (--n > 0)
+  __ decl(n_addr);  // --n
+  __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump);
+
+  Label done;
+  __ testl(ECX, ECX);
+  __ j(ZERO, &done, Assembler::kNearJump);
+
+  // *ajp += c
+  __ addl(Address(ESI, 0), ECX);
+  __ j(NOT_CARRY, &done, Assembler::kNearJump);
+
+  Label propagate_carry_loop;
+  __ Bind(&propagate_carry_loop);
+  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
+  __ incl(Address(ESI, 0));  // c == 0 or 1
+  __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  __ Drop(1);  // n
+  // Restore THR and return.
+  __ popl(THR);
+
+  __ Bind(&no_op);
+  __ movl(EAX, Immediate(target::ToRawSmi(1)));  // One digit processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _sqrAdd(Uint32List x_digits, int i,
+  //                    Uint32List a_digits, int used) {
+  //   uint32_t* xip = &x_digits[i >> 1];  // i is Smi.
+  //   uint32_t x = *xip++;
+  //   if (x == 0) return 1;
+  //   uint32_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
+  //   uint32_t aj = *ajp;
+  //   uint64_t t = x*x + aj;
+  //   *ajp++ = low32(t);
+  //   uint64_t c = high32(t);
+  //   int n = ((used - i) >> 1) - 1;  // used and i are Smi.
+  //   while (--n >= 0) {
+  //     uint32_t xi = *xip++;
+  //     uint32_t aj = *ajp;
+  //     uint96_t t = 2*x*xi + aj + c;  // 2-bit * 32-bit * 32-bit -> 65-bit.
+  //     *ajp++ = low32(t);
+  //     c = high64(t);  // 33-bit.
+  //   }
+  //   uint32_t aj = *ajp;
+  //   uint64_t t = aj + c;  // 32-bit + 33-bit -> 34-bit.
+  //   *ajp++ = low32(t);
+  //   *ajp = high32(t);
+  //   return 1;
+  // }
+
+  // EDI = xip = &x_digits[i >> 1]
+  __ movl(EDI, Address(ESP, 4 * target::kWordSize));  // x_digits
+  __ movl(EAX, Address(ESP, 3 * target::kWordSize));  // i is Smi
+  __ leal(EDI,
+          FieldAddress(EDI, EAX, TIMES_2, target::TypedData::data_offset()));
+
+  // EBX = x = *xip++, return if x == 0
+  Label x_zero;
+  __ movl(EBX, Address(EDI, 0));
+  __ cmpl(EBX, Immediate(0));
+  __ j(EQUAL, &x_zero, Assembler::kNearJump);
+  __ addl(EDI, Immediate(kBytesPerBigIntDigit));
+
+  // Preserve THR to free ESI.
+  __ pushl(THR);
+  ASSERT(THR == ESI);
+
+  // ESI = ajp = &a_digits[i]
+  __ movl(ESI, Address(ESP, 3 * target::kWordSize));  // a_digits
+  __ leal(ESI,
+          FieldAddress(ESI, EAX, TIMES_4, target::TypedData::data_offset()));
+
+  // EDX:EAX = t = x*x + *ajp
+  __ movl(EAX, EBX);
+  __ mull(EBX);
+  __ addl(EAX, Address(ESI, 0));
+  __ adcl(EDX, Immediate(0));
+
+  // *ajp++ = low32(t)
+  __ movl(Address(ESI, 0), EAX);
+  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
+
+  // int n = used - i - 1
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));  // used is Smi
+  __ subl(EAX, Address(ESP, 4 * target::kWordSize));  // i is Smi
+  __ SmiUntag(EAX);
+  __ decl(EAX);
+  __ pushl(EAX);  // Save n on stack.
+
+  // uint64_t c = high32(t)
+  __ pushl(Immediate(0));  // push high32(c) == 0
+  __ pushl(EDX);           // push low32(c) == high32(t)
+
+  Address n_addr = Address(ESP, 2 * target::kWordSize);
+  Address ch_addr = Address(ESP, 1 * target::kWordSize);
+  Address cl_addr = Address(ESP, 0 * target::kWordSize);
+
+  Label loop, done;
+  __ Bind(&loop);
+  // x:   EBX
+  // xip: EDI
+  // ajp: ESI
+  // c:   ESP[1]:ESP[0]
+  // t:   ECX:EDX:EAX (not live at loop entry)
+  // n:   ESP[2]
+
+  // while (--n >= 0)
+  __ decl(Address(ESP, 2 * target::kWordSize));  // --n
+  __ j(NEGATIVE, &done, Assembler::kNearJump);
+
+  // uint32_t xi = *xip++
+  __ movl(EAX, Address(EDI, 0));
+  __ addl(EDI, Immediate(kBytesPerBigIntDigit));
+
+  // uint96_t t = ECX:EDX:EAX = 2*x*xi + aj + c
+  __ mull(EBX);       // EDX:EAX = EAX * EBX
+  __ xorl(ECX, ECX);  // ECX = 0
+  __ shldl(ECX, EDX, Immediate(1));
+  __ shldl(EDX, EAX, Immediate(1));
+  __ shll(EAX, Immediate(1));     // ECX:EDX:EAX <<= 1
+  __ addl(EAX, Address(ESI, 0));  // t += aj
+  __ adcl(EDX, Immediate(0));
+  __ adcl(ECX, Immediate(0));
+  __ addl(EAX, cl_addr);  // t += low32(c)
+  __ adcl(EDX, ch_addr);  // t += high32(c) << 32
+  __ adcl(ECX, Immediate(0));
+
+  // *ajp++ = low32(t)
+  __ movl(Address(ESI, 0), EAX);
+  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
+
+  // c = high64(t)
+  __ movl(cl_addr, EDX);
+  __ movl(ch_addr, ECX);
+
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  // uint64_t t = aj + c
+  __ movl(EAX, cl_addr);  // t = c
+  __ movl(EDX, ch_addr);
+  __ addl(EAX, Address(ESI, 0));  // t += *ajp
+  __ adcl(EDX, Immediate(0));
+
+  // *ajp++ = low32(t)
+  // *ajp = high32(t)
+  __ movl(Address(ESI, 0), EAX);
+  __ movl(Address(ESI, kBytesPerBigIntDigit), EDX);
+
+  // Restore THR and return.
+  __ Drop(3);
+  __ popl(THR);
+  __ Bind(&x_zero);
+  __ movl(EAX, Immediate(target::ToRawSmi(1)));  // One digit processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
+  //   uint32_t yt = args[_YT];  // _YT == 1.
+  //   uint32_t* dp = &digits[i >> 1];  // i is Smi.
+  //   uint32_t dh = dp[0];  // dh == digits[i >> 1].
+  //   uint32_t qd;
+  //   if (dh == yt) {
+  //     qd = DIGIT_MASK;
+  //   } else {
+  //     dl = dp[-1];  // dl == digits[(i - 1) >> 1].
+  //     qd = dh:dl / yt;  // No overflow possible, because dh < yt.
+  //   }
+  //   args[_QD] = qd;  // _QD == 2.
+  //   return 1;
+  // }
+
+  // EDI = args
+  __ movl(EDI, Address(ESP, 3 * target::kWordSize));  // args
+
+  // ECX = yt = args[1]
+  __ movl(ECX, FieldAddress(EDI, target::TypedData::data_offset() +
+                                     kBytesPerBigIntDigit));
+
+  // EBX = dp = &digits[i >> 1]
+  __ movl(EBX, Address(ESP, 2 * target::kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 1 * target::kWordSize));  // i is Smi
+  __ leal(EBX,
+          FieldAddress(EBX, EAX, TIMES_2, target::TypedData::data_offset()));
+
+  // EDX = dh = dp[0]
+  __ movl(EDX, Address(EBX, 0));
+
+  // EAX = qd = DIGIT_MASK = -1
+  __ movl(EAX, Immediate(-1));
+
+  // Return qd if dh == yt
+  Label return_qd;
+  __ cmpl(EDX, ECX);
+  __ j(EQUAL, &return_qd, Assembler::kNearJump);
+
+  // EAX = dl = dp[-1]
+  __ movl(EAX, Address(EBX, -kBytesPerBigIntDigit));
+
+  // EAX = qd = dh:dl / yt = EDX:EAX / ECX
+  __ divl(ECX);
+
+  __ Bind(&return_qd);
+  // args[2] = qd
+  __ movl(FieldAddress(
+              EDI, target::TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
+          EAX);
+
+  __ movl(EAX, Immediate(target::ToRawSmi(1)));  // One digit processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
+  //   uint32_t rho = args[_RHO];  // _RHO == 2.
+  //   uint32_t d = digits[i >> 1];  // i is Smi.
+  //   uint64_t t = rho*d;
+  //   args[_MU] = t mod DIGIT_BASE;  // _MU == 4.
+  //   return 1;
+  // }
+
+  // EDI = args
+  __ movl(EDI, Address(ESP, 3 * target::kWordSize));  // args
+
+  // ECX = rho = args[2]
+  __ movl(ECX, FieldAddress(EDI, target::TypedData::data_offset() +
+                                     2 * kBytesPerBigIntDigit));
+
+  // EAX = digits[i >> 1]
+  __ movl(EBX, Address(ESP, 2 * target::kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 1 * target::kWordSize));  // i is Smi
+  __ movl(EAX,
+          FieldAddress(EBX, EAX, TIMES_2, target::TypedData::data_offset()));
+
+  // EDX:EAX = t = rho*d
+  __ mull(ECX);
+
+  // args[4] = t mod DIGIT_BASE = low32(t)
+  __ movl(FieldAddress(
+              EDI, target::TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
+          EAX);
+
+  __ movl(EAX, Immediate(target::ToRawSmi(1)));  // One digit processed.
+  __ ret();
+}
+
+// Check if the last argument is a double, jump to label 'is_smi' if smi
+// (easy to convert to double), otherwise jump to label 'not_double_smi',
+// Returns the last argument in EAX.
+static void TestLastArgumentIsDouble(Assembler* assembler,
+                                     Label* is_smi,
+                                     Label* not_double_smi) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(ZERO, is_smi, Assembler::kNearJump);  // Jump if Smi.
+  __ CompareClassId(EAX, kDoubleCid, EBX);
+  __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump);
+  // Fall through if double.
+}
+
+// Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
+// type. Return true or false object in the register EAX. Any NaN argument
+// returns false. Any non-double arg1 causes control flow to fall through to the
+// slow case (compiled method body).
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  Label is_false, is_true, is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Both arguments are double, right operand is in EAX.
+  __ movsd(XMM1, FieldAddress(EAX, target::Double::value_offset()));
+  __ Bind(&double_op);
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Left argument.
+  __ movsd(XMM0, FieldAddress(EAX, target::Double::value_offset()));
+  __ comisd(XMM0, XMM1);
+  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false;
+  __ j(true_condition, &is_true, Assembler::kNearJump);
+  // Fall through false.
+  __ Bind(&is_false);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(EAX);
+  __ cvtsi2sd(XMM1, EAX);
+  __ jmp(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+// arg0 is Double, arg1 is unknown.
+void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE);
+}
+
+// arg0 is Double, arg1 is unknown.
+void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE_EQUAL);
+}
+
+// arg0 is Double, arg1 is unknown.
+void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW);
+}
+
+// arg0 is Double, arg1 is unknown.
+void AsmIntrinsifier::Double_equal(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQUAL);
+}
+
+// arg0 is Double, arg1 is unknown.
+void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW_EQUAL);
+}
+
+// Expects left argument to be double (receiver). Right argument is unknown.
+// Both arguments are on stack.
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Both arguments are double, right operand is in EAX.
+  __ movsd(XMM1, FieldAddress(EAX, target::Double::value_offset()));
+  __ Bind(&double_op);
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Left argument.
+  __ movsd(XMM0, FieldAddress(EAX, target::Double::value_offset()));
+  switch (kind) {
+    case Token::kADD:
+      __ addsd(XMM0, XMM1);
+      break;
+    case Token::kSUB:
+      __ subsd(XMM0, XMM1);
+      break;
+    case Token::kMUL:
+      __ mulsd(XMM0, XMM1);
+      break;
+    case Token::kDIV:
+      __ divsd(XMM0, XMM1);
+      break;
+    default:
+      UNREACHABLE();
+  }
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
+                 EAX,  // Result register.
+                 EBX);
+  __ movsd(FieldAddress(EAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(EAX);
+  __ cvtsi2sd(XMM1, EAX);
+  __ jmp(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
+}
+
+void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
+}
+
+void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
+}
+
+void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
+}
+
+// Left is double, right is integer (Mint or Smi)
+void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  // Only smis allowed.
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);
+  // Is Smi.
+  __ SmiUntag(EAX);
+  __ cvtsi2sd(XMM1, EAX);
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(EAX, target::Double::value_offset()));
+  __ mulsd(XMM0, XMM1);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
+                 EAX,  // Result register.
+                 EBX);
+  __ movsd(FieldAddress(EAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);
+  // Is Smi.
+  __ SmiUntag(EAX);
+  __ cvtsi2sd(XMM0, EAX);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
+                 EAX,  // Result register.
+                 EBX);
+  __ movsd(FieldAddress(EAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  Label is_true;
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(EAX, target::Double::value_offset()));
+  __ comisd(XMM0, XMM0);
+  __ j(PARITY_EVEN, &is_true, Assembler::kNearJump);  // NaN -> true;
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  Label not_inf;
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ movl(EBX, FieldAddress(EAX, target::Double::value_offset()));
+
+  // If the low word isn't zero, then it isn't infinity.
+  __ cmpl(EBX, Immediate(0));
+  __ j(NOT_EQUAL, &not_inf, Assembler::kNearJump);
+  // Check the high word.
+  __ movl(EBX, FieldAddress(
+                   EAX, target::Double::value_offset() + target::kWordSize));
+  // Mask off sign bit.
+  __ andl(EBX, Immediate(0x7FFFFFFF));
+  // Compare with +infinity.
+  __ cmpl(EBX, Immediate(0x7FF00000));
+  __ j(NOT_EQUAL, &not_inf, Assembler::kNearJump);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  __ Bind(&not_inf);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  Label is_false, is_true, is_zero;
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(EAX, target::Double::value_offset()));
+  __ xorpd(XMM1, XMM1);  // 0.0 -> XMM1.
+  __ comisd(XMM0, XMM1);
+  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false.
+  __ j(EQUAL, &is_zero, Assembler::kNearJump);  // Check for negative zero.
+  __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump);  // >= 0 -> false.
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+  __ Bind(&is_false);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_zero);
+  // Check for negative zero (get the sign bit).
+  __ movmskpd(EAX, XMM0);
+  __ testl(EAX, Immediate(1));
+  __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
+  __ jmp(&is_false, Assembler::kNearJump);
+}
+
+void AsmIntrinsifier::DoubleToInteger(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(EAX, target::Double::value_offset()));
+  __ cvttsd2si(EAX, XMM0);
+  // Overflow is signalled with minint.
+  // Check for overflow and that it fits into Smi.
+  __ cmpl(EAX, Immediate(0xC0000000));
+  __ j(NEGATIVE, normal_ir_body, Assembler::kNearJump);
+  __ SmiTag(EAX);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_hashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
+
+  // Convert double value to signed 32-bit int in EAX and
+  // back to a double in XMM1.
+  __ movl(ECX, Address(ESP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(ECX, target::Double::value_offset()));
+  __ cvttsd2si(EAX, XMM0);
+  __ cvtsi2sd(XMM1, EAX);
+
+  // Tag the int as a Smi, making sure that it fits; this checks for
+  // overflow and NaN in the conversion from double to int. Conversion
+  // overflow from cvttsd2si is signalled with an INT32_MIN value.
+  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
+  __ addl(EAX, EAX);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+
+  // Compare the two double values. If they are equal, we return the
+  // Smi tagged result immediately as the hash code.
+  Label double_hash;
+  __ comisd(XMM0, XMM1);
+  __ j(NOT_EQUAL, &double_hash, Assembler::kNearJump);
+  __ ret();
+
+  // Convert the double bits to a hash code that fits in a Smi.
+  __ Bind(&double_hash);
+  __ movl(EAX, FieldAddress(ECX, target::Double::value_offset()));
+  __ movl(ECX, FieldAddress(ECX, target::Double::value_offset() + 4));
+  __ xorl(EAX, ECX);
+  __ andl(EAX, Immediate(kSmiMax));
+  __ SmiTag(EAX);
+  __ ret();
+
+  // Fall into the native C++ implementation.
+  __ Bind(normal_ir_body);
+}
+
+// Argument type is not known
+void AsmIntrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Argument is double and is in EAX.
+  __ movsd(XMM1, FieldAddress(EAX, target::Double::value_offset()));
+  __ Bind(&double_op);
+  __ sqrtsd(XMM0, XMM1);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
+                 EAX,  // Result register.
+                 EBX);
+  __ movsd(FieldAddress(EAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(EAX);
+  __ cvtsi2sd(XMM1, EAX);
+  __ jmp(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
+//    _state[kSTATE_LO] = state & _MASK_32;
+//    _state[kSTATE_HI] = state >> 32;
+void AsmIntrinsifier::Random_nextState(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  const Field& state_field = LookupMathRandomStateFieldOffset();
+  const int64_t a_int_value = AsmIntrinsifier::kRandomAValue;
+
+  // 'a_int_value' is a mask.
+  ASSERT(Utils::IsUint(32, a_int_value));
+  int32_t a_int32_value = static_cast<int32_t>(a_int_value);
+
+  // Receiver.
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  // Field '_state'.
+  __ movl(EBX, FieldAddress(EAX, LookupFieldOffsetInBytes(state_field)));
+  // Addresses of _state[0] and _state[1].
+  const intptr_t scale =
+      target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
+  const intptr_t offset =
+      target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
+  Address addr_0 = FieldAddress(EBX, 0 * scale + offset);
+  Address addr_1 = FieldAddress(EBX, 1 * scale + offset);
+  __ movl(EAX, Immediate(a_int32_value));
+  // 64-bit multiply EAX * value -> EDX:EAX.
+  __ mull(addr_0);
+  __ addl(EAX, addr_1);
+  __ adcl(EDX, Immediate(0));
+  __ movl(addr_1, EDX);
+  __ movl(addr_0, EAX);
+  ASSERT(target::ToRawSmi(0) == 0);
+  __ xorl(EAX, EAX);
+  __ ret();
+}
+
+// Identity comparison.
+void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  Label is_true;
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ cmpl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+}
+
+static void RangeCheck(Assembler* assembler,
+                       Register reg,
+                       intptr_t low,
+                       intptr_t high,
+                       Condition cc,
+                       Label* target) {
+  __ subl(reg, Immediate(low));
+  __ cmpl(reg, Immediate(high - low));
+  __ j(cc, target);
+}
+
+const Condition kIfNotInRange = ABOVE;
+const Condition kIfInRange = BELOW_EQUAL;
+
+static void JumpIfInteger(Assembler* assembler, Register cid, Label* target) {
+  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfInRange, target);
+}
+
+static void JumpIfNotInteger(Assembler* assembler,
+                             Register cid,
+                             Label* target) {
+  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfNotInRange, target);
+}
+
+static void JumpIfString(Assembler* assembler, Register cid, Label* target) {
+  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfInRange, target);
+}
+
+static void JumpIfNotString(Assembler* assembler, Register cid, Label* target) {
+  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfNotInRange, target);
+}
+
+// Return type quickly for simple types (not parameterized and not signature).
+void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Label use_declaration_type, not_double, not_integer;
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(EDI, EAX);
+
+  __ cmpl(EDI, Immediate(kClosureCid));
+  __ j(EQUAL, normal_ir_body);  // Instance is a closure.
+
+  __ cmpl(EDI, Immediate(kNumPredefinedCids));
+  __ j(ABOVE, &use_declaration_type);
+
+  // If object is a instance of _Double return double type.
+  __ cmpl(EDI, Immediate(kDoubleCid));
+  __ j(NOT_EQUAL, &not_double);
+
+  __ LoadIsolate(EAX);
+  __ movl(EAX, Address(EAX, target::Isolate::object_store_offset()));
+  __ movl(EAX, Address(EAX, target::ObjectStore::double_type_offset()));
+  __ ret();
+
+  __ Bind(&not_double);
+  // If object is an integer (smi, mint or bigint) return int type.
+  __ movl(EAX, EDI);
+  JumpIfNotInteger(assembler, EAX, &not_integer);
+
+  __ LoadIsolate(EAX);
+  __ movl(EAX, Address(EAX, target::Isolate::object_store_offset()));
+  __ movl(EAX, Address(EAX, target::ObjectStore::int_type_offset()));
+  __ ret();
+
+  __ Bind(&not_integer);
+  // If object is a string (one byte, two byte or external variants) return
+  // string type.
+  __ movl(EAX, EDI);
+  JumpIfNotString(assembler, EAX, &use_declaration_type);
+
+  __ LoadIsolate(EAX);
+  __ movl(EAX, Address(EAX, target::Isolate::object_store_offset()));
+  __ movl(EAX, Address(EAX, target::ObjectStore::string_type_offset()));
+  __ ret();
+
+  // Object is neither double, nor integer, nor string.
+  __ Bind(&use_declaration_type);
+  __ LoadClassById(EBX, EDI);
+  __ movzxw(EDI, FieldAddress(
+                     EBX, target::Class::num_type_arguments_offset_in_bytes()));
+  __ cmpl(EDI, Immediate(0));
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ movl(EAX, FieldAddress(EBX, target::Class::declaration_type_offset()));
+  __ CompareObject(EAX, NullObject());
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
+
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(EDI, EAX);
+
+  // Check if left hand size is a closure. Closures are handled in the runtime.
+  __ cmpl(EDI, Immediate(kClosureCid));
+  __ j(EQUAL, normal_ir_body);
+
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(EBX, EAX);
+
+  // Check whether class ids match. If class ids don't match objects can still
+  // have the same runtime type (e.g. multiple string implementation classes
+  // map to a single String type).
+  __ cmpl(EDI, EBX);
+  __ j(NOT_EQUAL, &different_cids);
+
+  // Objects have the same class and neither is a closure.
+  // Check if there are no type arguments. In this case we can return true.
+  // Otherwise fall through into the runtime to handle comparison.
+  __ LoadClassById(EBX, EDI);
+  __ movzxw(EBX, FieldAddress(
+                     EBX, target::Class::num_type_arguments_offset_in_bytes()));
+  __ cmpl(EBX, Immediate(0));
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+
+  __ Bind(&equal);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // Class ids are different. Check if we are comparing runtime types of
+  // two strings (with different representations) or two integers.
+  __ Bind(&different_cids);
+  __ cmpl(EDI, Immediate(kNumPredefinedCids));
+  __ j(ABOVE_EQUAL, &not_equal);
+
+  __ movl(EAX, EDI);
+  JumpIfNotInteger(assembler, EAX, &not_integer);
+
+  // First object is an integer. Check if the second is an integer too.
+  // Otherwise types are unequal because only integers have the same runtime
+  // type as other integers.
+  JumpIfInteger(assembler, EBX, &equal);
+  __ jmp(&not_equal);
+
+  __ Bind(&not_integer);
+  // Check if the first object is a string. If it is not then
+  // objects don't have the same runtime type because they have
+  // different class ids and they are not strings or integers.
+  JumpIfNotString(assembler, EDI, &not_equal);
+  // First object is a string. Check if the second is a string too.
+  JumpIfString(assembler, EBX, &equal);
+  // Strings only have the same runtime type as other strings.
+  // Fall-through to the not equal case.
+
+  __ Bind(&not_equal);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // String object.
+  __ movl(EAX, FieldAddress(EAX, target::String::hash_offset()));
+  __ cmpl(EAX, Immediate(0));
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ ret();
+  __ Bind(normal_ir_body);
+  // Hash not yet computed.
+}
+
+void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // Type object.
+  __ movl(EAX, FieldAddress(EAX, target::Type::hash_offset()));
+  __ testl(EAX, EAX);
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ ret();
+  __ Bind(normal_ir_body);
+  // Hash not yet computed.
+}
+
+// bool _substringMatches(int start, String other)
+void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  // For precompilation, not implemented on IA32.
+}
+
+void AsmIntrinsifier::Object_getHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  UNREACHABLE();
+}
+
+void AsmIntrinsifier::Object_setHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  UNREACHABLE();
+}
+
+void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Label try_two_byte_string;
+  __ movl(EBX, Address(ESP, +1 * target::kWordSize));  // Index.
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // String.
+  __ testl(EBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi index.
+  // Range check.
+  __ cmpl(EBX, FieldAddress(EAX, target::String::length_offset()));
+  // Runtime throws exception.
+  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ CompareClassId(EAX, kOneByteStringCid, EDI);
+  __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
+  __ SmiUntag(EBX);
+  __ movzxb(EBX, FieldAddress(EAX, EBX, TIMES_1,
+                              target::OneByteString::data_offset()));
+  __ cmpl(EBX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
+  __ j(GREATER_EQUAL, normal_ir_body);
+  __ movl(EAX, Immediate(SymbolsPredefinedAddress()));
+  __ movl(EAX, Address(EAX, EBX, TIMES_4,
+                       target::Symbols::kNullCharCodeSymbolOffset *
+                           target::kWordSize));
+  __ ret();
+
+  __ Bind(&try_two_byte_string);
+  __ CompareClassId(EAX, kTwoByteStringCid, EDI);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+  ASSERT(kSmiTagShift == 1);
+  __ movzxw(EBX, FieldAddress(EAX, EBX, TIMES_1,
+                              target::TwoByteString::data_offset()));
+  __ cmpl(EBX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
+  __ j(GREATER_EQUAL, normal_ir_body);
+  __ movl(EAX, Immediate(SymbolsPredefinedAddress()));
+  __ movl(EAX, Address(EAX, EBX, TIMES_4,
+                       target::Symbols::kNullCharCodeSymbolOffset *
+                           target::kWordSize));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Label is_true;
+  // Get length.
+  __ movl(EAX, Address(ESP, +1 * target::kWordSize));  // String object.
+  __ movl(EAX, FieldAddress(EAX, target::String::length_offset()));
+  __ cmpl(EAX, Immediate(target::ToRawSmi(0)));
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+}
+
+void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label compute_hash;
+  __ movl(EBX, Address(ESP, +1 * target::kWordSize));  // OneByteString object.
+  __ movl(EAX, FieldAddress(EBX, target::String::hash_offset()));
+  __ cmpl(EAX, Immediate(0));
+  __ j(EQUAL, &compute_hash, Assembler::kNearJump);
+  __ ret();
+
+  __ Bind(&compute_hash);
+  // Hash not yet computed, use algorithm of class StringHasher.
+  __ movl(ECX, FieldAddress(EBX, target::String::length_offset()));
+  __ SmiUntag(ECX);
+  __ xorl(EAX, EAX);
+  __ xorl(EDI, EDI);
+  // EBX: Instance of OneByteString.
+  // ECX: String length, untagged integer.
+  // EDI: Loop counter, untagged integer.
+  // EAX: Hash code, untagged integer.
+  Label loop, done, set_hash_code;
+  __ Bind(&loop);
+  __ cmpl(EDI, ECX);
+  __ j(EQUAL, &done, Assembler::kNearJump);
+  // Add to hash code: (hash_ is uint32)
+  // hash_ += ch;
+  // hash_ += hash_ << 10;
+  // hash_ ^= hash_ >> 6;
+  // Get one characters (ch).
+  __ movzxb(EDX, FieldAddress(EBX, EDI, TIMES_1,
+                              target::OneByteString::data_offset()));
+  // EDX: ch and temporary.
+  __ addl(EAX, EDX);
+  __ movl(EDX, EAX);
+  __ shll(EDX, Immediate(10));
+  __ addl(EAX, EDX);
+  __ movl(EDX, EAX);
+  __ shrl(EDX, Immediate(6));
+  __ xorl(EAX, EDX);
+
+  __ incl(EDI);
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  // Finalize:
+  // hash_ += hash_ << 3;
+  // hash_ ^= hash_ >> 11;
+  // hash_ += hash_ << 15;
+  __ movl(EDX, EAX);
+  __ shll(EDX, Immediate(3));
+  __ addl(EAX, EDX);
+  __ movl(EDX, EAX);
+  __ shrl(EDX, Immediate(11));
+  __ xorl(EAX, EDX);
+  __ movl(EDX, EAX);
+  __ shll(EDX, Immediate(15));
+  __ addl(EAX, EDX);
+  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
+  __ andl(
+      EAX,
+      Immediate(((static_cast<intptr_t>(1) << target::String::kHashBits) - 1)));
+
+  // return hash_ == 0 ? 1 : hash_;
+  __ cmpl(EAX, Immediate(0));
+  __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
+  __ incl(EAX);
+  __ Bind(&set_hash_code);
+  __ SmiTag(EAX);
+  __ StoreIntoSmiField(FieldAddress(EBX, target::String::hash_offset()), EAX);
+  __ ret();
+}
+
+// Allocates one-byte string of length 'end - start'. The content is not
+// initialized. 'length-reg' contains tagged length.
+// Returns new string as tagged pointer in EAX.
+static void TryAllocateOnebyteString(Assembler* assembler,
+                                     Label* ok,
+                                     Label* failure,
+                                     Register length_reg) {
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(kOneByteStringCid, EAX, failure, false));
+  if (length_reg != EDI) {
+    __ movl(EDI, length_reg);
+  }
+  Label pop_and_fail;
+  __ pushl(EDI);  // Preserve length.
+  __ SmiUntag(EDI);
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::String::InstanceSize() +
+      target::ObjectAlignment::kObjectAlignment - 1;
+  __ leal(EDI, Address(EDI, TIMES_1,
+                       fixed_size_plus_alignment_padding));  // EDI is untagged.
+  __ andl(EDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
+
+  const intptr_t cid = kOneByteStringCid;
+  __ movl(EAX, Address(THR, target::Thread::top_offset()));
+  __ movl(EBX, EAX);
+
+  // EDI: allocation size.
+  __ addl(EBX, EDI);
+  __ j(CARRY, &pop_and_fail);
+
+  // Check if the allocation fits into the remaining space.
+  // EAX: potential new object start.
+  // EBX: potential next object start.
+  // EDI: allocation size.
+  __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
+  __ j(ABOVE_EQUAL, &pop_and_fail);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  __ movl(Address(THR, target::Thread::top_offset()), EBX);
+  __ addl(EAX, Immediate(kHeapObjectTag));
+
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EDI, ECX));
+
+  // Initialize the tags.
+  // EAX: new object start as a tagged pointer.
+  // EBX: new object end address.
+  // EDI: allocation size.
+  {
+    Label size_tag_overflow, done;
+    __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+    __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2));
+    __ jmp(&done, Assembler::kNearJump);
+
+    __ Bind(&size_tag_overflow);
+    __ xorl(EDI, EDI);
+    __ Bind(&done);
+
+    // Get the class index and insert it into the tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    __ orl(EDI, Immediate(tags));
+    __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI);  // Tags.
+  }
+
+  // Set the length field.
+  __ popl(EDI);
+  __ StoreIntoObjectNoBarrier(
+      EAX, FieldAddress(EAX, target::String::length_offset()), EDI);
+  // Clear hash.
+  __ ZeroInitSmiField(FieldAddress(EAX, target::String::hash_offset()));
+  __ jmp(ok, Assembler::kNearJump);
+
+  __ Bind(&pop_and_fail);
+  __ popl(EDI);
+  __ jmp(failure);
+}
+
+// Arg0: OneByteString (receiver)
+// Arg1: Start index as Smi.
+// Arg2: End index as Smi.
+// The indexes must be valid.
+void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                       Label* normal_ir_body) {
+  const intptr_t kStringOffset = 3 * target::kWordSize;
+  const intptr_t kStartIndexOffset = 2 * target::kWordSize;
+  const intptr_t kEndIndexOffset = 1 * target::kWordSize;
+  Label ok;
+  __ movl(EAX, Address(ESP, +kStartIndexOffset));
+  __ movl(EDI, Address(ESP, +kEndIndexOffset));
+  __ orl(EAX, EDI);
+  __ testl(EAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
+
+  __ subl(EDI, Address(ESP, +kStartIndexOffset));
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
+  __ Bind(&ok);
+  // EAX: new string as tagged pointer.
+  // Copy string.
+  __ movl(EDI, Address(ESP, +kStringOffset));
+  __ movl(EBX, Address(ESP, +kStartIndexOffset));
+  __ SmiUntag(EBX);
+  __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1,
+                            target::OneByteString::data_offset()));
+  // EDI: Start address to copy from (untagged).
+  // EBX: Untagged start index.
+  __ movl(ECX, Address(ESP, +kEndIndexOffset));
+  __ SmiUntag(ECX);
+  __ subl(ECX, EBX);
+  __ xorl(EDX, EDX);
+  // EDI: Start address to copy from (untagged).
+  // ECX: Untagged number of bytes to copy.
+  // EAX: Tagged result string.
+  // EDX: Loop counter.
+  // EBX: Scratch register.
+  Label loop, check;
+  __ jmp(&check, Assembler::kNearJump);
+  __ Bind(&loop);
+  __ movzxb(EBX, Address(EDI, EDX, TIMES_1, 0));
+  __ movb(FieldAddress(EAX, EDX, TIMES_1, target::OneByteString::data_offset()),
+          BL);
+  __ incl(EDX);
+  __ Bind(&check);
+  __ cmpl(EDX, ECX);
+  __ j(LESS, &loop, Assembler::kNearJump);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ movl(ECX, Address(ESP, +1 * target::kWordSize));  // Value.
+  __ movl(EBX, Address(ESP, +2 * target::kWordSize));  // Index.
+  __ movl(EAX, Address(ESP, +3 * target::kWordSize));  // OneByteString.
+  __ SmiUntag(EBX);
+  __ SmiUntag(ECX);
+  __ movb(FieldAddress(EAX, EBX, TIMES_1, target::OneByteString::data_offset()),
+          CL);
+  __ ret();
+}
+
+void AsmIntrinsifier::OneByteString_allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ movl(EDI, Address(ESP, +1 * target::kWordSize));  // Length.
+  Label ok;
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
+  // EDI: Start address to copy from (untagged).
+
+  __ Bind(&ok);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // This.
+  __ movl(EBX, Address(ESP, +1 * target::kWordSize));  // Other.
+
+  // Are identical?
+  __ cmpl(EAX, EBX);
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+
+  // Is other OneByteString?
+  __ testl(EBX, Immediate(kSmiTagMask));
+  __ j(ZERO, &is_false);  // Smi
+  __ CompareClassId(EBX, string_cid, EDI);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+
+  // Have same length?
+  __ movl(EDI, FieldAddress(EAX, target::String::length_offset()));
+  __ cmpl(EDI, FieldAddress(EBX, target::String::length_offset()));
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+
+  // Check contents, no fall-through possible.
+  // TODO(srdjan): write a faster check.
+  __ SmiUntag(EDI);
+  __ Bind(&loop);
+  __ decl(EDI);
+  __ cmpl(EDI, Immediate(0));
+  __ j(LESS, &is_true, Assembler::kNearJump);
+  if (string_cid == kOneByteStringCid) {
+    __ movzxb(ECX, FieldAddress(EAX, EDI, TIMES_1,
+                                target::OneByteString::data_offset()));
+    __ movzxb(EDX, FieldAddress(EBX, EDI, TIMES_1,
+                                target::OneByteString::data_offset()));
+  } else if (string_cid == kTwoByteStringCid) {
+    __ movzxw(ECX, FieldAddress(EAX, EDI, TIMES_2,
+                                target::TwoByteString::data_offset()));
+    __ movzxw(EDX, FieldAddress(EBX, EDI, TIMES_2,
+                                target::TwoByteString::data_offset()));
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmpl(ECX, EDX);
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&is_true);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
+}
+
+void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
+}
+
+void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                   Label* normal_ir_body,
+                                                   bool sticky) {
+  if (FLAG_interpret_irregexp) return;
+
+  static const intptr_t kRegExpParamOffset = 3 * target::kWordSize;
+  static const intptr_t kStringParamOffset = 2 * target::kWordSize;
+  // start_index smi is located at offset 1.
+
+  // Incoming registers:
+  // EAX: Function. (Will be loaded with the specialized matcher function.)
+  // ECX: Unknown. (Must be GC safe on tail call.)
+  // EDX: Arguments descriptor. (Will be preserved.)
+
+  // Load the specialized function pointer into EAX. Leverage the fact the
+  // string CIDs as well as stored function pointers are in sequence.
+  __ movl(EBX, Address(ESP, kRegExpParamOffset));
+  __ movl(EDI, Address(ESP, kStringParamOffset));
+  __ LoadClassId(EDI, EDI);
+  __ SubImmediate(EDI, Immediate(kOneByteStringCid));
+  __ movl(EAX, FieldAddress(
+                   EBX, EDI, TIMES_4,
+                   target::RegExp::function_offset(kOneByteStringCid, sticky)));
+
+  // Registers are now set up for the lazy compile stub. It expects the function
+  // in EAX, the argument descriptor in EDX, and IC-Data in ECX.
+  __ xorl(ECX, ECX);
+
+  // Tail-call the function.
+  __ movl(EDI, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ jmp(EDI);
+}
+
+// On stack: user tag (+1), return-address (+0).
+void AsmIntrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  // RDI: Isolate.
+  __ LoadIsolate(EDI);
+  // EAX: Current user tag.
+  __ movl(EAX, Address(EDI, target::Isolate::current_tag_offset()));
+  // EAX: UserTag.
+  __ movl(EBX, Address(ESP, +1 * target::kWordSize));
+  // Set target::Isolate::current_tag_.
+  __ movl(Address(EDI, target::Isolate::current_tag_offset()), EBX);
+  // EAX: UserTag's tag.
+  __ movl(EBX, FieldAddress(EBX, target::UserTag::tag_offset()));
+  // Set target::Isolate::user_tag_.
+  __ movl(Address(EDI, target::Isolate::user_tag_offset()), EBX);
+  __ ret();
+}
+
+void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ LoadIsolate(EAX);
+  __ movl(EAX, Address(EAX, target::Isolate::default_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ LoadIsolate(EAX);
+  __ movl(EAX, Address(EAX, target::Isolate::current_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+#if !defined(SUPPORT_TIMELINE)
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+#else
+  Label true_label;
+  // Load TimelineStream*.
+  __ movl(EAX, Address(THR, target::Thread::dart_stream_offset()));
+  // Load uintptr_t from TimelineStream*.
+  __ movl(EAX, Address(EAX, target::TimelineStream::enabled_offset()));
+  __ cmpl(EAX, Immediate(0));
+  __ j(NOT_ZERO, &true_label, Assembler::kNearJump);
+  // Not enabled.
+  __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  // Enabled.
+  __ Bind(&true_label);
+  __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+#endif
+}
+
+void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  __ LoadObject(EAX, NullObject());
+  __ movl(Address(THR, target::Thread::async_stack_trace_offset()), EAX);
+  __ ret();
+}
+
+void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  __ movl(Address(THR, target::Thread::async_stack_trace_offset()), EAX);
+  __ LoadObject(EAX, NullObject());
+  __ ret();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
new file mode 100644
index 0000000..1c34df5
--- /dev/null
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -0,0 +1,2313 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"  // Needed here to get TARGET_ARCH_X64.
+#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
+#include "vm/compiler/asm_intrinsifier.h"
+#include "vm/compiler/assembler/assembler.h"
+
+namespace dart {
+namespace compiler {
+
+// When entering intrinsics code:
+// R10: Arguments descriptor
+// TOS: Return address
+// The R10 registers can be destroyed only if there is no slow-path, i.e.
+// if the intrinsified method always executes a return.
+// The RBP register should not be modified, because it is used by the profiler.
+// The PP and THR registers (see constants_x64.h) must be preserved.
+
+#define __ assembler->
+
+intptr_t AsmIntrinsifier::ParameterSlotFromSp() {
+  return 0;
+}
+
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
+}
+
+void AsmIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
+}
+
+void AsmIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
+}
+
+// Allocate a GrowableObjectArray using the backing array specified.
+// On stack: type argument (+2), data (+1), return-address (+0).
+void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  // This snippet of inlined code uses the following registers:
+  // RAX, RCX, R13
+  // and the newly allocated object is returned in RAX.
+  const intptr_t kTypeArgumentsOffset = 2 * target::kWordSize;
+  const intptr_t kArrayOffset = 1 * target::kWordSize;
+
+  // Try allocating in new space.
+  const Class& cls = GrowableObjectArrayClass();
+  __ TryAllocate(cls, normal_ir_body, Assembler::kFarJump, RAX, R13);
+
+  // Store backing array object in growable array object.
+  __ movq(RCX, Address(RSP, kArrayOffset));  // data argument.
+  // RAX is new, no barrier needed.
+  __ StoreIntoObjectNoBarrier(
+      RAX, FieldAddress(RAX, target::GrowableObjectArray::data_offset()), RCX);
+
+  // RAX: new growable array object start as a tagged pointer.
+  // Store the type argument field in the growable array object.
+  __ movq(RCX, Address(RSP, kTypeArgumentsOffset));  // type argument.
+  __ StoreIntoObjectNoBarrier(
+      RAX,
+      FieldAddress(RAX, target::GrowableObjectArray::type_arguments_offset()),
+      RCX);
+
+  // Set the length field in the growable array object to 0.
+  __ ZeroInitSmiField(
+      FieldAddress(RAX, target::GrowableObjectArray::length_offset()));
+  __ ret();  // returns the newly allocated object in RAX.
+
+  __ Bind(normal_ir_body);
+}
+
+#define TYPED_ARRAY_ALLOCATION(cid, max_len, scale_factor)                     \
+  Label fall_through;                                                          \
+  const intptr_t kArrayLengthStackOffset = 1 * target::kWordSize;              \
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, normal_ir_body, false));         \
+  __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */     \
+  /* Check that length is a positive Smi. */                                   \
+  /* RDI: requested array length argument. */                                  \
+  __ testq(RDI, Immediate(kSmiTagMask));                                       \
+  __ j(NOT_ZERO, normal_ir_body);                                              \
+  __ cmpq(RDI, Immediate(0));                                                  \
+  __ j(LESS, normal_ir_body);                                                  \
+  __ SmiUntag(RDI);                                                            \
+  /* Check for maximum allowed length. */                                      \
+  /* RDI: untagged array length. */                                            \
+  __ cmpq(RDI, Immediate(max_len));                                            \
+  __ j(GREATER, normal_ir_body);                                               \
+  /* Special case for scaling by 16. */                                        \
+  if (scale_factor == TIMES_16) {                                              \
+    /* double length of array. */                                              \
+    __ addq(RDI, RDI);                                                         \
+    /* only scale by 8. */                                                     \
+    scale_factor = TIMES_8;                                                    \
+  }                                                                            \
+  const intptr_t fixed_size_plus_alignment_padding =                           \
+      target::TypedData::InstanceSize() +                                      \
+      target::ObjectAlignment::kObjectAlignment - 1;                           \
+  __ leaq(RDI, Address(RDI, scale_factor, fixed_size_plus_alignment_padding)); \
+  __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));         \
+  __ movq(RAX, Address(THR, target::Thread::top_offset()));                    \
+  __ movq(RCX, RAX);                                                           \
+                                                                               \
+  /* RDI: allocation size. */                                                  \
+  __ addq(RCX, RDI);                                                           \
+  __ j(CARRY, normal_ir_body);                                                 \
+                                                                               \
+  /* Check if the allocation fits into the remaining space. */                 \
+  /* RAX: potential new object start. */                                       \
+  /* RCX: potential next object start. */                                      \
+  /* RDI: allocation size. */                                                  \
+  __ cmpq(RCX, Address(THR, target::Thread::end_offset()));                    \
+  __ j(ABOVE_EQUAL, normal_ir_body);                                           \
+                                                                               \
+  /* Successfully allocated the object(s), now update top to point to */       \
+  /* next object start and initialize the object. */                           \
+  __ movq(Address(THR, target::Thread::top_offset()), RCX);                    \
+  __ addq(RAX, Immediate(kHeapObjectTag));                                     \
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, RDI));                  \
+  /* Initialize the tags. */                                                   \
+  /* RAX: new object start as a tagged pointer. */                             \
+  /* RCX: new object end address. */                                           \
+  /* RDI: allocation size. */                                                  \
+  /* R13: scratch register. */                                                 \
+  {                                                                            \
+    Label size_tag_overflow, done;                                             \
+    __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));            \
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);                     \
+    __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -             \
+                           target::ObjectAlignment::kObjectAlignmentLog2));    \
+    __ jmp(&done, Assembler::kNearJump);                                       \
+                                                                               \
+    __ Bind(&size_tag_overflow);                                               \
+    __ LoadImmediate(RDI, Immediate(0));                                       \
+    __ Bind(&done);                                                            \
+                                                                               \
+    /* Get the class index and insert it into the tags. */                     \
+    uint32_t tags =                                                            \
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);        \
+    __ orq(RDI, Immediate(tags));                                              \
+    __ movq(FieldAddress(RAX, target::Object::tags_offset()),                  \
+            RDI); /* Tags. */                                                  \
+  }                                                                            \
+  /* Set the length field. */                                                  \
+  /* RAX: new object start as a tagged pointer. */                             \
+  /* RCX: new object end address. */                                           \
+  __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */     \
+  __ StoreIntoObjectNoBarrier(                                                 \
+      RAX, FieldAddress(RAX, target::TypedData::length_offset()), RDI);        \
+  /* Initialize all array elements to 0. */                                    \
+  /* RAX: new object start as a tagged pointer. */                             \
+  /* RCX: new object end address. */                                           \
+  /* RDI: iterator which initially points to the start of the variable */      \
+  /* RBX: scratch register. */                                                 \
+  /* data area to be initialized. */                                           \
+  __ xorq(RBX, RBX); /* Zero. */                                               \
+  __ leaq(RDI, FieldAddress(RAX, target::TypedData::InstanceSize()));          \
+  Label done, init_loop;                                                       \
+  __ Bind(&init_loop);                                                         \
+  __ cmpq(RDI, RCX);                                                           \
+  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);                              \
+  __ movq(Address(RDI, 0), RBX);                                               \
+  __ addq(RDI, Immediate(target::kWordSize));                                  \
+  __ jmp(&init_loop, Assembler::kNearJump);                                    \
+  __ Bind(&done);                                                              \
+                                                                               \
+  __ ret();                                                                    \
+  __ Bind(normal_ir_body);
+
+static ScaleFactor GetScaleFactor(intptr_t size) {
+  switch (size) {
+    case 1:
+      return TIMES_1;
+    case 2:
+      return TIMES_2;
+    case 4:
+      return TIMES_4;
+    case 8:
+      return TIMES_8;
+    case 16:
+      return TIMES_16;
+  }
+  UNREACHABLE();
+  return static_cast<ScaleFactor>(0);
+}
+
+#define TYPED_DATA_ALLOCATOR(clazz)                                            \
+  void AsmIntrinsifier::TypedData_##clazz##_factory(Assembler* assembler,      \
+                                                    Label* normal_ir_body) {   \
+    intptr_t size = TypedDataElementSizeInBytes(kTypedData##clazz##Cid);       \
+    intptr_t max_len = TypedDataMaxNewSpaceElements(kTypedData##clazz##Cid);   \
+    ScaleFactor scale = GetScaleFactor(size);                                  \
+    TYPED_ARRAY_ALLOCATION(kTypedData##clazz##Cid, max_len, scale);            \
+  }
+CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
+#undef TYPED_DATA_ALLOCATOR
+
+// Tests if two top most arguments are smis, jumps to label not_smi if not.
+// Topmost argument is in RAX.
+static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ movq(RCX, Address(RSP, +2 * target::kWordSize));
+  __ orq(RCX, RAX);
+  __ testq(RCX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, not_smi);
+}
+
+void AsmIntrinsifier::Integer_addFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX contains right argument.
+  __ addq(RAX, Address(RSP, +2 * target::kWordSize));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
+  Integer_addFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_subFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX contains right argument, which is the actual minuend of subtraction.
+  __ subq(RAX, Address(RSP, +2 * target::kWordSize));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX contains right argument, which is the actual subtrahend of subtraction.
+  __ movq(RCX, RAX);
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));
+  __ subq(RAX, RCX);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mulFromInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX is the right argument.
+  ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
+  __ SmiUntag(RAX);
+  __ imulq(RAX, Address(RSP, +2 * target::kWordSize));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
+  Integer_mulFromInteger(assembler, normal_ir_body);
+}
+
+// Optimizations:
+// - result is 0 if:
+//   - left is 0
+//   - left equals right
+// - result is left if
+//   - left > 0 && left < right
+// RAX: Tagged left (dividend).
+// RCX: Tagged right (divisor).
+// Returns:
+//   RAX: Untagged fallthrough result (remainder to be adjusted), or
+//   RAX: Tagged return result (remainder).
+static void EmitRemainderOperation(Assembler* assembler) {
+  Label return_zero, try_modulo, not_32bit, done;
+  // Check for quick zero results.
+  __ cmpq(RAX, Immediate(0));
+  __ j(EQUAL, &return_zero, Assembler::kNearJump);
+  __ cmpq(RAX, RCX);
+  __ j(EQUAL, &return_zero, Assembler::kNearJump);
+
+  // Check if result equals left.
+  __ cmpq(RAX, Immediate(0));
+  __ j(LESS, &try_modulo, Assembler::kNearJump);
+  // left is positive.
+  __ cmpq(RAX, RCX);
+  __ j(GREATER, &try_modulo, Assembler::kNearJump);
+  // left is less than right, result is left (RAX).
+  __ ret();
+
+  __ Bind(&return_zero);
+  __ xorq(RAX, RAX);
+  __ ret();
+
+  __ Bind(&try_modulo);
+
+  // Check if both operands fit into 32bits as idiv with 64bit operands
+  // requires twice as many cycles and has much higher latency. We are checking
+  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
+  // raises exception because quotient is too large for 32bit register.
+  __ movsxd(RBX, RAX);
+  __ cmpq(RBX, RAX);
+  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
+  __ movsxd(RBX, RCX);
+  __ cmpq(RBX, RCX);
+  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
+
+  // Both operands are 31bit smis. Divide using 32bit idiv.
+  __ SmiUntag(RAX);
+  __ SmiUntag(RCX);
+  __ cdq();
+  __ idivl(RCX);
+  __ movsxd(RAX, RDX);
+  __ jmp(&done, Assembler::kNearJump);
+
+  // Divide using 64bit idiv.
+  __ Bind(&not_32bit);
+  __ SmiUntag(RAX);
+  __ SmiUntag(RCX);
+  __ cqo();
+  __ idivq(RCX);
+  __ movq(RAX, RDX);
+  __ Bind(&done);
+}
+
+// Implementation:
+//  res = left % right;
+//  if (res < 0) {
+//    if (right < 0) {
+//      res = res - right;
+//    } else {
+//      res = res + right;
+//    }
+//  }
+void AsmIntrinsifier::Integer_moduloFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label negative_result;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  __ movq(RCX, Address(RSP, +2 * target::kWordSize));
+  // RAX: Tagged left (dividend).
+  // RCX: Tagged right (divisor).
+  __ cmpq(RCX, Immediate(0));
+  __ j(EQUAL, normal_ir_body);
+  EmitRemainderOperation(assembler);
+  // Untagged remainder result in RAX.
+  __ cmpq(RAX, Immediate(0));
+  __ j(LESS, &negative_result, Assembler::kNearJump);
+  __ SmiTag(RAX);
+  __ ret();
+
+  __ Bind(&negative_result);
+  Label subtract;
+  // RAX: Untagged result.
+  // RCX: Untagged right.
+  __ cmpq(RCX, Immediate(0));
+  __ j(LESS, &subtract, Assembler::kNearJump);
+  __ addq(RAX, RCX);
+  __ SmiTag(RAX);
+  __ ret();
+
+  __ Bind(&subtract);
+  __ subq(RAX, RCX);
+  __ SmiTag(RAX);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_truncDivide(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  Label not_32bit;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX: right argument (divisor)
+  __ cmpq(RAX, Immediate(0));
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ movq(RCX, RAX);
+  __ movq(RAX,
+          Address(RSP, +2 * target::kWordSize));  // Left argument (dividend).
+
+  // Check if both operands fit into 32bits as idiv with 64bit operands
+  // requires twice as many cycles and has much higher latency. We are checking
+  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
+  // raises exception because quotient is too large for 32bit register.
+  __ movsxd(RBX, RAX);
+  __ cmpq(RBX, RAX);
+  __ j(NOT_EQUAL, &not_32bit);
+  __ movsxd(RBX, RCX);
+  __ cmpq(RBX, RCX);
+  __ j(NOT_EQUAL, &not_32bit);
+
+  // Both operands are 31bit smis. Divide using 32bit idiv.
+  __ SmiUntag(RAX);
+  __ SmiUntag(RCX);
+  __ cdq();
+  __ idivl(RCX);
+  __ movsxd(RAX, RAX);
+  __ SmiTag(RAX);  // Result is guaranteed to fit into a smi.
+  __ ret();
+
+  // Divide using 64bit idiv.
+  __ Bind(&not_32bit);
+  __ SmiUntag(RAX);
+  __ SmiUntag(RCX);
+  __ pushq(RDX);  // Preserve RDX in case of 'fall_through'.
+  __ cqo();
+  __ idivq(RCX);
+  __ popq(RDX);
+  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
+  // cannot tag the result.
+  __ cmpq(RAX, Immediate(0x4000000000000000));
+  __ j(EQUAL, normal_ir_body);
+  __ SmiTag(RAX);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_negate(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
+  __ negq(RAX);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX is the right argument.
+  __ andq(RAX, Address(RSP, +2 * target::kWordSize));
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitAnd(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX is the right argument.
+  __ orq(RAX, Address(RSP, +2 * target::kWordSize));
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitOr(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_bitOrFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX is the right argument.
+  __ xorq(RAX, Address(RSP, +2 * target::kWordSize));
+  // Result is in RAX.
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_bitXor(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  Integer_bitXorFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
+  ASSERT(kSmiTagShift == 1);
+  ASSERT(kSmiTag == 0);
+  Label overflow;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // Shift value is in RAX. Compare with tagged Smi.
+  __ cmpq(RAX, Immediate(target::ToRawSmi(target::Smi::kBits)));
+  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
+
+  __ SmiUntag(RAX);
+  __ movq(RCX, RAX);  // Shift amount must be in RCX.
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Value.
+
+  // Overflow test - all the shifted-out bits must be same as the sign bit.
+  __ movq(RDI, RAX);
+  __ shlq(RAX, RCX);
+  __ sarq(RAX, RCX);
+  __ cmpq(RAX, RDI);
+  __ j(NOT_EQUAL, &overflow, Assembler::kNearJump);
+
+  __ shlq(RAX, RCX);  // Shift for result now we know there is no overflow.
+
+  // RAX is a correctly tagged Smi.
+  __ ret();
+
+  __ Bind(&overflow);
+  // Mint is rarely used on x64 (only for integers requiring 64 bit instead of
+  // 63 bits as represented by Smi).
+  __ Bind(normal_ir_body);
+}
+
+static void CompareIntegers(Assembler* assembler,
+                            Label* normal_ir_body,
+                            Condition true_condition) {
+  Label true_label;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  // RAX contains the right argument.
+  __ cmpq(Address(RSP, +2 * target::kWordSize), RAX);
+  __ j(true_condition, &true_label, Assembler::kNearJump);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&true_label);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS);
+}
+
+void AsmIntrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS);
+}
+
+void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER);
+}
+
+void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, LESS_EQUAL);
+}
+
+void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  CompareIntegers(assembler, normal_ir_body, GREATER_EQUAL);
+}
+
+// This is called for Smi and Mint receivers. The right argument
+// can be Smi, Mint or double.
+void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  Label true_label, check_for_mint;
+  const intptr_t kReceiverOffset = 2;
+  const intptr_t kArgumentOffset = 1;
+
+  // For integer receiver '===' check first.
+  __ movq(RAX, Address(RSP, +kArgumentOffset * target::kWordSize));
+  __ movq(RCX, Address(RSP, +kReceiverOffset * target::kWordSize));
+  __ cmpq(RAX, RCX);
+  __ j(EQUAL, &true_label, Assembler::kNearJump);
+  __ orq(RAX, RCX);
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
+  // Both arguments are smi, '===' is good enough.
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&true_label);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // At least one of the arguments was not Smi.
+  Label receiver_not_smi;
+  __ Bind(&check_for_mint);
+  __ movq(RAX, Address(RSP, +kReceiverOffset * target::kWordSize));
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &receiver_not_smi);
+
+  // Left (receiver) is Smi, return false if right is not Double.
+  // Note that an instance of Mint never contains a value that can be
+  // represented by Smi.
+  __ movq(RAX, Address(RSP, +kArgumentOffset * target::kWordSize));
+  __ CompareClassId(RAX, kDoubleCid);
+  __ j(EQUAL, normal_ir_body);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(&receiver_not_smi);
+  // RAX:: receiver.
+  __ CompareClassId(RAX, kMintCid);
+  __ j(NOT_EQUAL, normal_ir_body);
+  // Receiver is Mint, return false if right is Smi.
+  __ movq(RAX, Address(RSP, +kArgumentOffset * target::kWordSize));
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);
+  // Smi == Mint -> false.
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  // TODO(srdjan): Implement Mint == Mint comparison.
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_equal(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  Integer_equalToInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
+  Label shift_count_ok;
+  TestBothArgumentsSmis(assembler, normal_ir_body);
+  const Immediate& count_limit = Immediate(0x3F);
+  // Check that the count is not larger than what the hardware can handle.
+  // For shifting right a Smi the result is the same for all numbers
+  // >= count_limit.
+  __ SmiUntag(RAX);
+  // Negative counts throw exception.
+  __ cmpq(RAX, Immediate(0));
+  __ j(LESS, normal_ir_body, Assembler::kNearJump);
+  __ cmpq(RAX, count_limit);
+  __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
+  __ movq(RAX, count_limit);
+  __ Bind(&shift_count_ok);
+  __ movq(RCX, RAX);  // Shift amount must be in RCX.
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Value.
+  __ SmiUntag(RAX);                                    // Value.
+  __ sarq(RAX, RCX);
+  __ SmiTag(RAX);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+// Argument is Smi (receiver).
+void AsmIntrinsifier::Smi_bitNegate(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Index.
+  __ notq(RAX);
+  __ andq(RAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
+  __ ret();
+}
+
+void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  ASSERT(kSmiTagShift == 1);
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Index.
+  // XOR with sign bit to complement bits if value is negative.
+  __ movq(RCX, RAX);
+  __ sarq(RCX, Immediate(63));  // All 0 or all 1.
+  __ xorq(RAX, RCX);
+  // BSR does not write the destination register if source is zero.  Put a 1 in
+  // the Smi tag bit to ensure BSR writes to destination register.
+  __ orq(RAX, Immediate(kSmiTagMask));
+  __ bsrq(RAX, RAX);
+  __ SmiTag(RAX);
+  __ ret();
+}
+
+void AsmIntrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Integer_bitAndFromInteger(assembler, normal_ir_body);
+}
+
+void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _lsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  __ movq(RDI, Address(RSP, 4 * target::kWordSize));  // x_digits
+  __ movq(R8, Address(RSP, 3 * target::kWordSize));   // x_used is Smi
+  __ subq(R8, Immediate(2));  // x_used > 0, Smi. R8 = x_used - 1, round up.
+  __ sarq(R8, Immediate(2));  // R8 + 1 = number of digit pairs to read.
+  __ movq(RCX, Address(RSP, 2 * target::kWordSize));  // n is Smi
+  __ SmiUntag(RCX);
+  __ movq(RBX, Address(RSP, 1 * target::kWordSize));  // r_digits
+  __ movq(RSI, RCX);
+  __ sarq(RSI, Immediate(6));  // RSI = n ~/ (2*_DIGIT_BITS).
+  __ leaq(RBX,
+          FieldAddress(RBX, RSI, TIMES_8, target::TypedData::data_offset()));
+  __ xorq(RAX, RAX);  // RAX = 0.
+  __ movq(RDX,
+          FieldAddress(RDI, R8, TIMES_8, target::TypedData::data_offset()));
+  __ shldq(RAX, RDX, RCX);
+  __ movq(Address(RBX, R8, TIMES_8, 2 * kBytesPerBigIntDigit), RAX);
+  Label last;
+  __ cmpq(R8, Immediate(0));
+  __ j(EQUAL, &last, Assembler::kNearJump);
+  Label loop;
+  __ Bind(&loop);
+  __ movq(RAX, RDX);
+  __ movq(RDX, FieldAddress(RDI, R8, TIMES_8,
+                            target::TypedData::data_offset() -
+                                2 * kBytesPerBigIntDigit));
+  __ shldq(RAX, RDX, RCX);
+  __ movq(Address(RBX, R8, TIMES_8, 0), RAX);
+  __ decq(R8);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+  __ Bind(&last);
+  __ shldq(RDX, R8, RCX);  // R8 == 0.
+  __ movq(Address(RBX, 0), RDX);
+  __ LoadObject(RAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
+  // static void _rsh(Uint32List x_digits, int x_used, int n,
+  //                  Uint32List r_digits)
+
+  __ movq(RDI, Address(RSP, 4 * target::kWordSize));  // x_digits
+  __ movq(RCX, Address(RSP, 2 * target::kWordSize));  // n is Smi
+  __ SmiUntag(RCX);
+  __ movq(RBX, Address(RSP, 1 * target::kWordSize));  // r_digits
+  __ movq(RDX, RCX);
+  __ sarq(RDX, Immediate(6));  // RDX = n ~/ (2*_DIGIT_BITS).
+  __ movq(RSI, Address(RSP, 3 * target::kWordSize));  // x_used is Smi
+  __ subq(RSI, Immediate(2));  // x_used > 0, Smi. RSI = x_used - 1, round up.
+  __ sarq(RSI, Immediate(2));
+  __ leaq(RDI,
+          FieldAddress(RDI, RSI, TIMES_8, target::TypedData::data_offset()));
+  __ subq(RSI, RDX);  // RSI + 1 = number of digit pairs to read.
+  __ leaq(RBX,
+          FieldAddress(RBX, RSI, TIMES_8, target::TypedData::data_offset()));
+  __ negq(RSI);
+  __ movq(RDX, Address(RDI, RSI, TIMES_8, 0));
+  Label last;
+  __ cmpq(RSI, Immediate(0));
+  __ j(EQUAL, &last, Assembler::kNearJump);
+  Label loop;
+  __ Bind(&loop);
+  __ movq(RAX, RDX);
+  __ movq(RDX, Address(RDI, RSI, TIMES_8, 2 * kBytesPerBigIntDigit));
+  __ shrdq(RAX, RDX, RCX);
+  __ movq(Address(RBX, RSI, TIMES_8, 0), RAX);
+  __ incq(RSI);
+  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
+  __ Bind(&last);
+  __ shrdq(RDX, RSI, RCX);  // RSI == 0.
+  __ movq(Address(RBX, 0), RDX);
+  __ LoadObject(RAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absAdd(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  __ movq(RDI, Address(RSP, 5 * target::kWordSize));  // digits
+  __ movq(R8, Address(RSP, 4 * target::kWordSize));   // used is Smi
+  __ addq(R8, Immediate(2));  // used > 0, Smi. R8 = used + 1, round up.
+  __ sarq(R8, Immediate(2));  // R8 = number of digit pairs to process.
+  __ movq(RSI, Address(RSP, 3 * target::kWordSize));  // a_digits
+  __ movq(RCX, Address(RSP, 2 * target::kWordSize));  // a_used is Smi
+  __ addq(RCX, Immediate(2));  // a_used > 0, Smi. R8 = a_used + 1, round up.
+  __ sarq(RCX, Immediate(2));  // R8 = number of digit pairs to process.
+  __ movq(RBX, Address(RSP, 1 * target::kWordSize));  // r_digits
+
+  // Precompute 'used - a_used' now so that carry flag is not lost later.
+  __ subq(R8, RCX);
+  __ incq(R8);  // To account for the extra test between loops.
+
+  __ xorq(RDX, RDX);  // RDX = 0, carry flag = 0.
+  Label add_loop;
+  __ Bind(&add_loop);
+  // Loop (a_used+1)/2 times, RCX > 0.
+  __ movq(RAX,
+          FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+  __ adcq(RAX,
+          FieldAddress(RSI, RDX, TIMES_8, target::TypedData::data_offset()));
+  __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+          RAX);
+  __ incq(RDX);  // Does not affect carry flag.
+  __ decq(RCX);  // Does not affect carry flag.
+  __ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
+
+  Label last_carry;
+  __ decq(R8);                                    // Does not affect carry flag.
+  __ j(ZERO, &last_carry, Assembler::kNearJump);  // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
+  __ movq(RAX,
+          FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+  __ adcq(RAX, Immediate(0));
+  __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+          RAX);
+  __ incq(RDX);  // Does not affect carry flag.
+  __ decq(R8);   // Does not affect carry flag.
+  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
+
+  __ Bind(&last_carry);
+  Label done;
+  __ j(NOT_CARRY, &done);
+  __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+          Immediate(1));
+
+  __ Bind(&done);
+  __ LoadObject(RAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // static void _absSub(Uint32List digits, int used,
+  //                     Uint32List a_digits, int a_used,
+  //                     Uint32List r_digits)
+
+  __ movq(RDI, Address(RSP, 5 * target::kWordSize));  // digits
+  __ movq(R8, Address(RSP, 4 * target::kWordSize));   // used is Smi
+  __ addq(R8, Immediate(2));  // used > 0, Smi. R8 = used + 1, round up.
+  __ sarq(R8, Immediate(2));  // R8 = number of digit pairs to process.
+  __ movq(RSI, Address(RSP, 3 * target::kWordSize));  // a_digits
+  __ movq(RCX, Address(RSP, 2 * target::kWordSize));  // a_used is Smi
+  __ addq(RCX, Immediate(2));  // a_used > 0, Smi. R8 = a_used + 1, round up.
+  __ sarq(RCX, Immediate(2));  // R8 = number of digit pairs to process.
+  __ movq(RBX, Address(RSP, 1 * target::kWordSize));  // r_digits
+
+  // Precompute 'used - a_used' now so that carry flag is not lost later.
+  __ subq(R8, RCX);
+  __ incq(R8);  // To account for the extra test between loops.
+
+  __ xorq(RDX, RDX);  // RDX = 0, carry flag = 0.
+  Label sub_loop;
+  __ Bind(&sub_loop);
+  // Loop (a_used+1)/2 times, RCX > 0.
+  __ movq(RAX,
+          FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+  __ sbbq(RAX,
+          FieldAddress(RSI, RDX, TIMES_8, target::TypedData::data_offset()));
+  __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+          RAX);
+  __ incq(RDX);  // Does not affect carry flag.
+  __ decq(RCX);  // Does not affect carry flag.
+  __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
+
+  Label done;
+  __ decq(R8);                              // Does not affect carry flag.
+  __ j(ZERO, &done, Assembler::kNearJump);  // If used - a_used == 0.
+
+  Label carry_loop;
+  __ Bind(&carry_loop);
+  // Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
+  __ movq(RAX,
+          FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+  __ sbbq(RAX, Immediate(0));
+  __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+          RAX);
+  __ incq(RDX);  // Does not affect carry flag.
+  __ decq(R8);   // Does not affect carry flag.
+  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  __ LoadObject(RAX, NullObject());
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulAdd(Uint32List x_digits, int xi,
+  //                    Uint32List m_digits, int i,
+  //                    Uint32List a_digits, int j, int n) {
+  //   uint64_t x = x_digits[xi >> 1 .. (xi >> 1) + 1];  // xi is Smi and even.
+  //   if (x == 0 || n == 0) {
+  //     return 2;
+  //   }
+  //   uint64_t* mip = &m_digits[i >> 1];  // i is Smi and even.
+  //   uint64_t* ajp = &a_digits[j >> 1];  // j is Smi and even.
+  //   uint64_t c = 0;
+  //   SmiUntag(n);  // n is Smi and even.
+  //   n = (n + 1)/2;  // Number of pairs to process.
+  //   do {
+  //     uint64_t mi = *mip++;
+  //     uint64_t aj = *ajp;
+  //     uint128_t t = x*mi + aj + c;  // 64-bit * 64-bit -> 128-bit.
+  //     *ajp++ = low64(t);
+  //     c = high64(t);
+  //   } while (--n > 0);
+  //   while (c != 0) {
+  //     uint128_t t = *ajp + c;
+  //     *ajp++ = low64(t);
+  //     c = high64(t);  // c == 0 or 1.
+  //   }
+  //   return 2;
+  // }
+
+  Label done;
+  // RBX = x, done if x == 0
+  __ movq(RCX, Address(RSP, 7 * target::kWordSize));  // x_digits
+  __ movq(RAX, Address(RSP, 6 * target::kWordSize));  // xi is Smi
+  __ movq(RBX,
+          FieldAddress(RCX, RAX, TIMES_2, target::TypedData::data_offset()));
+  __ testq(RBX, RBX);
+  __ j(ZERO, &done, Assembler::kNearJump);
+
+  // R8 = (SmiUntag(n) + 1)/2, no_op if n == 0
+  __ movq(R8, Address(RSP, 1 * target::kWordSize));
+  __ addq(R8, Immediate(2));
+  __ sarq(R8, Immediate(2));  // R8 = number of digit pairs to process.
+  __ j(ZERO, &done, Assembler::kNearJump);
+
+  // RDI = mip = &m_digits[i >> 1]
+  __ movq(RDI, Address(RSP, 5 * target::kWordSize));  // m_digits
+  __ movq(RAX, Address(RSP, 4 * target::kWordSize));  // i is Smi
+  __ leaq(RDI,
+          FieldAddress(RDI, RAX, TIMES_2, target::TypedData::data_offset()));
+
+  // RSI = ajp = &a_digits[j >> 1]
+  __ movq(RSI, Address(RSP, 3 * target::kWordSize));  // a_digits
+  __ movq(RAX, Address(RSP, 2 * target::kWordSize));  // j is Smi
+  __ leaq(RSI,
+          FieldAddress(RSI, RAX, TIMES_2, target::TypedData::data_offset()));
+
+  // RCX = c = 0
+  __ xorq(RCX, RCX);
+
+  Label muladd_loop;
+  __ Bind(&muladd_loop);
+  // x:   RBX
+  // mip: RDI
+  // ajp: RSI
+  // c:   RCX
+  // t:   RDX:RAX (not live at loop entry)
+  // n:   R8
+
+  // uint64_t mi = *mip++
+  __ movq(RAX, Address(RDI, 0));
+  __ addq(RDI, Immediate(2 * kBytesPerBigIntDigit));
+
+  // uint128_t t = x*mi
+  __ mulq(RBX);       // t = RDX:RAX = RAX * RBX, 64-bit * 64-bit -> 64-bit
+  __ addq(RAX, RCX);  // t += c
+  __ adcq(RDX, Immediate(0));
+
+  // uint64_t aj = *ajp; t += aj
+  __ addq(RAX, Address(RSI, 0));
+  __ adcq(RDX, Immediate(0));
+
+  // *ajp++ = low64(t)
+  __ movq(Address(RSI, 0), RAX);
+  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
+
+  // c = high64(t)
+  __ movq(RCX, RDX);
+
+  // while (--n > 0)
+  __ decq(R8);  // --n
+  __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump);
+
+  __ testq(RCX, RCX);
+  __ j(ZERO, &done, Assembler::kNearJump);
+
+  // *ajp += c
+  __ addq(Address(RSI, 0), RCX);
+  __ j(NOT_CARRY, &done, Assembler::kNearJump);
+
+  Label propagate_carry_loop;
+  __ Bind(&propagate_carry_loop);
+  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
+  __ incq(Address(RSI, 0));  // c == 0 or 1
+  __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  __ movq(RAX, Immediate(target::ToRawSmi(2)));  // Two digits processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
+                                    Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _sqrAdd(Uint32List x_digits, int i,
+  //                    Uint32List a_digits, int used) {
+  //   uint64_t* xip = &x_digits[i >> 1];  // i is Smi and even.
+  //   uint64_t x = *xip++;
+  //   if (x == 0) return 2;
+  //   uint64_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
+  //   uint64_t aj = *ajp;
+  //   uint128_t t = x*x + aj;
+  //   *ajp++ = low64(t);
+  //   uint128_t c = high64(t);
+  //   int n = ((used - i + 2) >> 2) - 1;  // used and i are Smi. n: num pairs.
+  //   while (--n >= 0) {
+  //     uint64_t xi = *xip++;
+  //     uint64_t aj = *ajp;
+  //     uint192_t t = 2*x*xi + aj + c;  // 2-bit * 64-bit * 64-bit -> 129-bit.
+  //     *ajp++ = low64(t);
+  //     c = high128(t);  // 65-bit.
+  //   }
+  //   uint64_t aj = *ajp;
+  //   uint128_t t = aj + c;  // 64-bit + 65-bit -> 66-bit.
+  //   *ajp++ = low64(t);
+  //   *ajp = high64(t);
+  //   return 2;
+  // }
+
+  // RDI = xip = &x_digits[i >> 1]
+  __ movq(RDI, Address(RSP, 4 * target::kWordSize));  // x_digits
+  __ movq(RAX, Address(RSP, 3 * target::kWordSize));  // i is Smi
+  __ leaq(RDI,
+          FieldAddress(RDI, RAX, TIMES_2, target::TypedData::data_offset()));
+
+  // RBX = x = *xip++, return if x == 0
+  Label x_zero;
+  __ movq(RBX, Address(RDI, 0));
+  __ cmpq(RBX, Immediate(0));
+  __ j(EQUAL, &x_zero);
+  __ addq(RDI, Immediate(2 * kBytesPerBigIntDigit));
+
+  // RSI = ajp = &a_digits[i]
+  __ movq(RSI, Address(RSP, 2 * target::kWordSize));  // a_digits
+  __ leaq(RSI,
+          FieldAddress(RSI, RAX, TIMES_4, target::TypedData::data_offset()));
+
+  // RDX:RAX = t = x*x + *ajp
+  __ movq(RAX, RBX);
+  __ mulq(RBX);
+  __ addq(RAX, Address(RSI, 0));
+  __ adcq(RDX, Immediate(0));
+
+  // *ajp++ = low64(t)
+  __ movq(Address(RSI, 0), RAX);
+  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
+
+  // int n = (used - i + 1)/2 - 1
+  __ movq(R8, Address(RSP, 1 * target::kWordSize));  // used is Smi
+  __ subq(R8, Address(RSP, 3 * target::kWordSize));  // i is Smi
+  __ addq(R8, Immediate(2));
+  __ sarq(R8, Immediate(2));
+  __ decq(R8);  // R8 = number of digit pairs to process.
+
+  // uint128_t c = high64(t)
+  __ xorq(R13, R13);  // R13 = high64(c) == 0
+  __ movq(R12, RDX);  // R12 = low64(c) == high64(t)
+
+  Label loop, done;
+  __ Bind(&loop);
+  // x:   RBX
+  // xip: RDI
+  // ajp: RSI
+  // c:   R13:R12
+  // t:   RCX:RDX:RAX (not live at loop entry)
+  // n:   R8
+
+  // while (--n >= 0)
+  __ decq(R8);  // --n
+  __ j(NEGATIVE, &done, Assembler::kNearJump);
+
+  // uint64_t xi = *xip++
+  __ movq(RAX, Address(RDI, 0));
+  __ addq(RDI, Immediate(2 * kBytesPerBigIntDigit));
+
+  // uint192_t t = RCX:RDX:RAX = 2*x*xi + aj + c
+  __ mulq(RBX);       // RDX:RAX = RAX * RBX
+  __ xorq(RCX, RCX);  // RCX = 0
+  __ shldq(RCX, RDX, Immediate(1));
+  __ shldq(RDX, RAX, Immediate(1));
+  __ shlq(RAX, Immediate(1));     // RCX:RDX:RAX <<= 1
+  __ addq(RAX, Address(RSI, 0));  // t += aj
+  __ adcq(RDX, Immediate(0));
+  __ adcq(RCX, Immediate(0));
+  __ addq(RAX, R12);  // t += low64(c)
+  __ adcq(RDX, R13);  // t += high64(c) << 64
+  __ adcq(RCX, Immediate(0));
+
+  // *ajp++ = low64(t)
+  __ movq(Address(RSI, 0), RAX);
+  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
+
+  // c = high128(t)
+  __ movq(R12, RDX);
+  __ movq(R13, RCX);
+
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  // uint128_t t = aj + c
+  __ addq(R12, Address(RSI, 0));  // t = c, t += *ajp
+  __ adcq(R13, Immediate(0));
+
+  // *ajp++ = low64(t)
+  // *ajp = high64(t)
+  __ movq(Address(RSI, 0), R12);
+  __ movq(Address(RSI, 2 * kBytesPerBigIntDigit), R13);
+
+  __ Bind(&x_zero);
+  __ movq(RAX, Immediate(target::ToRawSmi(2)));  // Two digits processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
+  //   uint64_t yt = args[_YT_LO .. _YT];  // _YT_LO == 0, _YT == 1.
+  //   uint64_t* dp = &digits[(i >> 1) - 1];  // i is Smi.
+  //   uint64_t dh = dp[0];  // dh == digits[(i >> 1) - 1 .. i >> 1].
+  //   uint64_t qd;
+  //   if (dh == yt) {
+  //     qd = (DIGIT_MASK << 32) | DIGIT_MASK;
+  //   } else {
+  //     dl = dp[-1];  // dl == digits[(i >> 1) - 3 .. (i >> 1) - 2].
+  //     qd = dh:dl / yt;  // No overflow possible, because dh < yt.
+  //   }
+  //   args[_QD .. _QD_HI] = qd;  // _QD == 2, _QD_HI == 3.
+  //   return 2;
+  // }
+
+  // RDI = args
+  __ movq(RDI, Address(RSP, 3 * target::kWordSize));  // args
+
+  // RCX = yt = args[0..1]
+  __ movq(RCX, FieldAddress(RDI, target::TypedData::data_offset()));
+
+  // RBX = dp = &digits[(i >> 1) - 1]
+  __ movq(RBX, Address(RSP, 2 * target::kWordSize));  // digits
+  __ movq(RAX, Address(RSP, 1 * target::kWordSize));  // i is Smi and odd.
+  __ leaq(RBX, FieldAddress(
+                   RBX, RAX, TIMES_2,
+                   target::TypedData::data_offset() - kBytesPerBigIntDigit));
+
+  // RDX = dh = dp[0]
+  __ movq(RDX, Address(RBX, 0));
+
+  // RAX = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
+  __ movq(RAX, Immediate(-1));
+
+  // Return qd if dh == yt
+  Label return_qd;
+  __ cmpq(RDX, RCX);
+  __ j(EQUAL, &return_qd, Assembler::kNearJump);
+
+  // RAX = dl = dp[-1]
+  __ movq(RAX, Address(RBX, -2 * kBytesPerBigIntDigit));
+
+  // RAX = qd = dh:dl / yt = RDX:RAX / RCX
+  __ divq(RCX);
+
+  __ Bind(&return_qd);
+  // args[2..3] = qd
+  __ movq(FieldAddress(
+              RDI, target::TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
+          RAX);
+
+  __ movq(RAX, Immediate(target::ToRawSmi(2)));  // Two digits processed.
+  __ ret();
+}
+
+void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  // Pseudo code:
+  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
+  //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
+  //   uint64_t d = digits[i >> 1 .. (i >> 1) + 1];  // i is Smi and even.
+  //   uint128_t t = rho*d;
+  //   args[_MU .. _MU_HI] = t mod DIGIT_BASE^2;  // _MU == 4, _MU_HI == 5.
+  //   return 2;
+  // }
+
+  // RDI = args
+  __ movq(RDI, Address(RSP, 3 * target::kWordSize));  // args
+
+  // RCX = rho = args[2 .. 3]
+  __ movq(RCX, FieldAddress(RDI, target::TypedData::data_offset() +
+                                     2 * kBytesPerBigIntDigit));
+
+  // RAX = digits[i >> 1 .. (i >> 1) + 1]
+  __ movq(RBX, Address(RSP, 2 * target::kWordSize));  // digits
+  __ movq(RAX, Address(RSP, 1 * target::kWordSize));  // i is Smi
+  __ movq(RAX,
+          FieldAddress(RBX, RAX, TIMES_2, target::TypedData::data_offset()));
+
+  // RDX:RAX = t = rho*d
+  __ mulq(RCX);
+
+  // args[4 .. 5] = t mod DIGIT_BASE^2 = low64(t)
+  __ movq(FieldAddress(
+              RDI, target::TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
+          RAX);
+
+  __ movq(RAX, Immediate(target::ToRawSmi(2)));  // Two digits processed.
+  __ ret();
+}
+
+// Check if the last argument is a double, jump to label 'is_smi' if smi
+// (easy to convert to double), otherwise jump to label 'not_double_smi',
+// Returns the last argument in RAX.
+static void TestLastArgumentIsDouble(Assembler* assembler,
+                                     Label* is_smi,
+                                     Label* not_double_smi) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(ZERO, is_smi);  // Jump if Smi.
+  __ CompareClassId(RAX, kDoubleCid);
+  __ j(NOT_EQUAL, not_double_smi);
+  // Fall through if double.
+}
+
+// Both arguments on stack, left argument is a double, right argument is of
+// unknown type. Return true or false object in RAX. Any NaN argument
+// returns false. Any non-double argument causes control flow to fall through
+// to the slow case (compiled method body).
+static void CompareDoubles(Assembler* assembler,
+                           Label* normal_ir_body,
+                           Condition true_condition) {
+  Label is_false, is_true, is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Both arguments are double, right operand is in RAX.
+  __ movsd(XMM1, FieldAddress(RAX, target::Double::value_offset()));
+  __ Bind(&double_op);
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Left argument.
+  __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
+  __ comisd(XMM0, XMM1);
+  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false;
+  __ j(true_condition, &is_true, Assembler::kNearJump);
+  // Fall through false.
+  __ Bind(&is_false);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(RAX);
+  __ cvtsi2sdq(XMM1, RAX);
+  __ jmp(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE);
+}
+
+void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
+                                              Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, ABOVE_EQUAL);
+}
+
+void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW);
+}
+
+void AsmIntrinsifier::Double_equal(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, EQUAL);
+}
+
+void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  CompareDoubles(assembler, normal_ir_body, BELOW_EQUAL);
+}
+
+// Expects left argument to be double (receiver). Right argument is unknown.
+// Both arguments are on stack.
+static void DoubleArithmeticOperations(Assembler* assembler,
+                                       Label* normal_ir_body,
+                                       Token::Kind kind) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Both arguments are double, right operand is in RAX.
+  __ movsd(XMM1, FieldAddress(RAX, target::Double::value_offset()));
+  __ Bind(&double_op);
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Left argument.
+  __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
+  switch (kind) {
+    case Token::kADD:
+      __ addsd(XMM0, XMM1);
+      break;
+    case Token::kSUB:
+      __ subsd(XMM0, XMM1);
+      break;
+    case Token::kMUL:
+      __ mulsd(XMM0, XMM1);
+      break;
+    case Token::kDIV:
+      __ divsd(XMM0, XMM1);
+      break;
+    default:
+      UNREACHABLE();
+  }
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
+                 RAX,  // Result register.
+                 R13);
+  __ movsd(FieldAddress(RAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(RAX);
+  __ cvtsi2sdq(XMM1, RAX);
+  __ jmp(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
+}
+
+void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
+}
+
+void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
+}
+
+void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
+  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
+}
+
+void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
+                                            Label* normal_ir_body) {
+  // Only smis allowed.
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);
+  // Is Smi.
+  __ SmiUntag(RAX);
+  __ cvtsi2sdq(XMM1, RAX);
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
+  __ mulsd(XMM0, XMM1);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
+                 RAX,  // Result register.
+                 R13);
+  __ movsd(FieldAddress(RAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+// Left is double, right is integer (Mint or Smi)
+void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ testq(RAX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);
+  // Is Smi.
+  __ SmiUntag(RAX);
+  __ cvtsi2sdq(XMM0, RAX);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
+                 RAX,  // Result register.
+                 R13);
+  __ movsd(FieldAddress(RAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  Label is_true;
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
+  __ comisd(XMM0, XMM0);
+  __ j(PARITY_EVEN, &is_true, Assembler::kNearJump);  // NaN -> true;
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  Label is_inf, done;
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ movq(RAX, FieldAddress(RAX, target::Double::value_offset()));
+  // Mask off the sign.
+  __ AndImmediate(RAX, Immediate(0x7FFFFFFFFFFFFFFFLL));
+  // Compare with +infinity.
+  __ CompareImmediate(RAX, Immediate(0x7FF0000000000000LL));
+  __ j(EQUAL, &is_inf, Assembler::kNearJump);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ jmp(&done);
+
+  __ Bind(&is_inf);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+
+  __ Bind(&done);
+  __ ret();
+}
+
+void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
+                                           Label* normal_ir_body) {
+  Label is_false, is_true, is_zero;
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
+  __ xorpd(XMM1, XMM1);  // 0.0 -> XMM1.
+  __ comisd(XMM0, XMM1);
+  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false.
+  __ j(EQUAL, &is_zero, Assembler::kNearJump);  // Check for negative zero.
+  __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump);  // >= 0 -> false.
+  __ Bind(&is_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+  __ Bind(&is_false);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_zero);
+  // Check for negative zero (get the sign bit).
+  __ movmskpd(RAX, XMM0);
+  __ testq(RAX, Immediate(1));
+  __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
+  __ jmp(&is_false, Assembler::kNearJump);
+}
+
+void AsmIntrinsifier::DoubleToInteger(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(RAX, target::Double::value_offset()));
+  __ cvttsd2siq(RAX, XMM0);
+  // Overflow is signalled with minint.
+  // Check for overflow and that it fits into Smi.
+  __ movq(RCX, RAX);
+  __ shlq(RCX, Immediate(1));
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+  __ SmiTag(RAX);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::Double_hashCode(Assembler* assembler,
+                                      Label* normal_ir_body) {
+  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
+
+  // Convert double value to signed 64-bit int in RAX and
+  // back to a double in XMM1.
+  __ movq(RCX, Address(RSP, +1 * target::kWordSize));
+  __ movsd(XMM0, FieldAddress(RCX, target::Double::value_offset()));
+  __ cvttsd2siq(RAX, XMM0);
+  __ cvtsi2sdq(XMM1, RAX);
+
+  // Tag the int as a Smi, making sure that it fits; this checks for
+  // overflow and NaN in the conversion from double to int. Conversion
+  // overflow from cvttsd2si is signalled with an INT64_MIN value.
+  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
+  __ addq(RAX, RAX);
+  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
+
+  // Compare the two double values. If they are equal, we return the
+  // Smi tagged result immediately as the hash code.
+  Label double_hash;
+  __ comisd(XMM0, XMM1);
+  __ j(NOT_EQUAL, &double_hash, Assembler::kNearJump);
+  __ ret();
+
+  // Convert the double bits to a hash code that fits in a Smi.
+  __ Bind(&double_hash);
+  __ movq(RAX, FieldAddress(RCX, target::Double::value_offset()));
+  __ movq(RCX, RAX);
+  __ shrq(RCX, Immediate(32));
+  __ xorq(RAX, RCX);
+  __ andq(RAX, Immediate(kSmiMax));
+  __ SmiTag(RAX);
+  __ ret();
+
+  // Fall into the native C++ implementation.
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
+  Label is_smi, double_op;
+  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
+  // Argument is double and is in RAX.
+  __ movsd(XMM1, FieldAddress(RAX, target::Double::value_offset()));
+  __ Bind(&double_op);
+  __ sqrtsd(XMM0, XMM1);
+  const Class& double_class = DoubleClass();
+  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
+                 RAX,  // Result register.
+                 R13);
+  __ movsd(FieldAddress(RAX, target::Double::value_offset()), XMM0);
+  __ ret();
+  __ Bind(&is_smi);
+  __ SmiUntag(RAX);
+  __ cvtsi2sdq(XMM1, RAX);
+  __ jmp(&double_op);
+  __ Bind(normal_ir_body);
+}
+
+//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
+//    _state[kSTATE_LO] = state & _MASK_32;
+//    _state[kSTATE_HI] = state >> 32;
+void AsmIntrinsifier::Random_nextState(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  const Field& state_field = LookupMathRandomStateFieldOffset();
+  const int64_t a_int_value = AsmIntrinsifier::kRandomAValue;
+
+  // Receiver.
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  // Field '_state'.
+  __ movq(RBX, FieldAddress(RAX, LookupFieldOffsetInBytes(state_field)));
+  // Addresses of _state[0] and _state[1].
+  const intptr_t scale =
+      target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
+  const intptr_t offset =
+      target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
+  Address addr_0 = FieldAddress(RBX, 0 * scale + offset);
+  Address addr_1 = FieldAddress(RBX, 1 * scale + offset);
+  __ movq(RAX, Immediate(a_int_value));
+  __ movl(RCX, addr_0);
+  __ imulq(RCX, RAX);
+  __ movl(RDX, addr_1);
+  __ addq(RDX, RCX);
+  __ movl(addr_0, RDX);
+  __ shrq(RDX, Immediate(32));
+  __ movl(addr_1, RDX);
+  ASSERT(target::ToRawSmi(0) == 0);
+  __ xorq(RAX, RAX);
+  __ ret();
+}
+
+// Identity comparison.
+void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
+                                   Label* normal_ir_body) {
+  Label is_true;
+  const intptr_t kReceiverOffset = 2;
+  const intptr_t kArgumentOffset = 1;
+
+  __ movq(RAX, Address(RSP, +kArgumentOffset * target::kWordSize));
+  __ cmpq(RAX, Address(RSP, +kReceiverOffset * target::kWordSize));
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+}
+
+static void RangeCheck(Assembler* assembler,
+                       Register reg,
+                       intptr_t low,
+                       intptr_t high,
+                       Condition cc,
+                       Label* target) {
+  __ subq(reg, Immediate(low));
+  __ cmpq(reg, Immediate(high - low));
+  __ j(cc, target);
+}
+
+const Condition kIfNotInRange = ABOVE;
+const Condition kIfInRange = BELOW_EQUAL;
+
+static void JumpIfInteger(Assembler* assembler, Register cid, Label* target) {
+  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfInRange, target);
+}
+
+static void JumpIfNotInteger(Assembler* assembler,
+                             Register cid,
+                             Label* target) {
+  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfNotInRange, target);
+}
+
+static void JumpIfString(Assembler* assembler, Register cid, Label* target) {
+  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfInRange, target);
+}
+
+static void JumpIfNotString(Assembler* assembler, Register cid, Label* target) {
+  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
+             kIfNotInRange, target);
+}
+
+// Return type quickly for simple types (not parameterized and not signature).
+void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Label use_declaration_type, not_integer, not_double;
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(RCX, RAX);
+
+  // RCX: untagged cid of instance (RAX).
+  __ cmpq(RCX, Immediate(kClosureCid));
+  __ j(EQUAL, normal_ir_body);  // Instance is a closure.
+
+  __ cmpl(RCX, Immediate(kNumPredefinedCids));
+  __ j(ABOVE, &use_declaration_type);
+
+  // If object is a instance of _Double return double type.
+  __ cmpl(RCX, Immediate(kDoubleCid));
+  __ j(NOT_EQUAL, &not_double);
+
+  __ LoadIsolate(RAX);
+  __ movq(RAX, Address(RAX, target::Isolate::object_store_offset()));
+  __ movq(RAX, Address(RAX, target::ObjectStore::double_type_offset()));
+  __ ret();
+
+  __ Bind(&not_double);
+  // If object is an integer (smi, mint or bigint) return int type.
+  __ movl(RAX, RCX);
+  JumpIfNotInteger(assembler, RAX, &not_integer);
+
+  __ LoadIsolate(RAX);
+  __ movq(RAX, Address(RAX, target::Isolate::object_store_offset()));
+  __ movq(RAX, Address(RAX, target::ObjectStore::int_type_offset()));
+  __ ret();
+
+  __ Bind(&not_integer);
+  // If object is a string (one byte, two byte or external variants) return
+  // string type.
+  __ movq(RAX, RCX);
+  JumpIfNotString(assembler, RAX, &use_declaration_type);
+
+  __ LoadIsolate(RAX);
+  __ movq(RAX, Address(RAX, target::Isolate::object_store_offset()));
+  __ movq(RAX, Address(RAX, target::ObjectStore::string_type_offset()));
+  __ ret();
+
+  // Object is neither double, nor integer, nor string.
+  __ Bind(&use_declaration_type);
+  __ LoadClassById(RDI, RCX);
+  __ movzxw(RCX, FieldAddress(
+                     RDI, target::Class::num_type_arguments_offset_in_bytes()));
+  __ cmpq(RCX, Immediate(0));
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+  __ movq(RAX, FieldAddress(RDI, target::Class::declaration_type_offset()));
+  __ CompareObject(RAX, NullObject());
+  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label different_cids, equal, not_equal, not_integer;
+
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(RCX, RAX);
+
+  // Check if left hand size is a closure. Closures are handled in the runtime.
+  __ cmpq(RCX, Immediate(kClosureCid));
+  __ j(EQUAL, normal_ir_body);
+
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));
+  __ LoadClassIdMayBeSmi(RDX, RAX);
+
+  // Check whether class ids match. If class ids don't match objects can still
+  // have the same runtime type (e.g. multiple string implementation classes
+  // map to a single String type).
+  __ cmpq(RCX, RDX);
+  __ j(NOT_EQUAL, &different_cids);
+
+  // Objects have the same class and neither is a closure.
+  // Check if there are no type arguments. In this case we can return true.
+  // Otherwise fall through into the runtime to handle comparison.
+  __ LoadClassById(RDI, RCX);
+  __ movzxw(RCX, FieldAddress(
+                     RDI, target::Class::num_type_arguments_offset_in_bytes()));
+  __ cmpq(RCX, Immediate(0));
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+
+  __ Bind(&equal);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  // Class ids are different. Check if we are comparing runtime types of
+  // two strings (with different representations) or two integers.
+  __ Bind(&different_cids);
+  __ cmpq(RCX, Immediate(kNumPredefinedCids));
+  __ j(ABOVE_EQUAL, &not_equal);
+
+  __ movq(RAX, RCX);
+  JumpIfNotInteger(assembler, RAX, &not_integer);
+
+  // First object is an integer. Check if the second is an integer too.
+  // Otherwise types are unequal because only integers have the same runtime
+  // type as other integers.
+  JumpIfInteger(assembler, RDX, &equal);
+  __ jmp(&not_equal);
+
+  __ Bind(&not_integer);
+  // Check if the first object is a string. If it is not then
+  // objects don't have the same runtime type because they have
+  // different class ids and they are not strings or integers.
+  JumpIfNotString(assembler, RCX, &not_equal);
+  // First object is a string. Check if the second is a string too.
+  JumpIfString(assembler, RDX, &equal);
+  // Strings only have the same runtime type as other strings.
+  // Fall-through to the not equal case.
+
+  __ Bind(&not_equal);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // String object.
+  __ movl(RAX, FieldAddress(RAX, target::String::hash_offset()));
+  ASSERT(kSmiTag == 0);
+  ASSERT(kSmiTagShift == 1);
+  __ addq(RAX, RAX);  // Smi tag RAX, setting Z flag.
+  __ j(ZERO, normal_ir_body, Assembler::kNearJump);
+  __ ret();
+  __ Bind(normal_ir_body);
+  // Hash not yet computed.
+}
+
+void AsmIntrinsifier::Type_getHashCode(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Type object.
+  __ movq(RAX, FieldAddress(RAX, target::Type::hash_offset()));
+  ASSERT(kSmiTag == 0);
+  ASSERT(kSmiTagShift == 1);
+  __ testq(RAX, RAX);
+  __ j(ZERO, normal_ir_body, Assembler::kNearJump);
+  __ ret();
+  __ Bind(normal_ir_body);
+  // Hash not yet computed.
+}
+
+void AsmIntrinsifier::Object_getHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // Object.
+  __ movl(RAX, FieldAddress(RAX, target::String::hash_offset()));
+  __ SmiTag(RAX);
+  __ ret();
+}
+
+void AsmIntrinsifier::Object_setHash(Assembler* assembler,
+                                     Label* normal_ir_body) {
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Object.
+  __ movq(RDX, Address(RSP, +1 * target::kWordSize));  // Value.
+  __ SmiUntag(RDX);
+  __ movl(FieldAddress(RAX, target::String::hash_offset()), RDX);
+  __ ret();
+}
+
+void GenerateSubstringMatchesSpecialization(Assembler* assembler,
+                                            intptr_t receiver_cid,
+                                            intptr_t other_cid,
+                                            Label* return_true,
+                                            Label* return_false) {
+  __ movq(R8, FieldAddress(RAX, target::String::length_offset()));
+  __ movq(R9, FieldAddress(RCX, target::String::length_offset()));
+
+  // if (other.length == 0) return true;
+  __ testq(R9, R9);
+  __ j(ZERO, return_true);
+
+  // if (start < 0) return false;
+  __ testq(RBX, RBX);
+  __ j(SIGN, return_false);
+
+  // if (start + other.length > this.length) return false;
+  __ movq(R11, RBX);
+  __ addq(R11, R9);
+  __ cmpq(R11, R8);
+  __ j(GREATER, return_false);
+
+  __ SmiUntag(RBX);                     // start
+  __ SmiUntag(R9);                      // other.length
+  __ LoadImmediate(R11, Immediate(0));  // i = 0
+
+  // do
+  Label loop;
+  __ Bind(&loop);
+
+  // this.codeUnitAt(i + start)
+  // clobbering this.length
+  __ movq(R8, R11);
+  __ addq(R8, RBX);
+  if (receiver_cid == kOneByteStringCid) {
+    __ movzxb(R12, FieldAddress(RAX, R8, TIMES_1,
+                                target::OneByteString::data_offset()));
+  } else {
+    ASSERT(receiver_cid == kTwoByteStringCid);
+    __ movzxw(R12, FieldAddress(RAX, R8, TIMES_2,
+                                target::TwoByteString::data_offset()));
+  }
+  // other.codeUnitAt(i)
+  if (other_cid == kOneByteStringCid) {
+    __ movzxb(R13, FieldAddress(RCX, R11, TIMES_1,
+                                target::OneByteString::data_offset()));
+  } else {
+    ASSERT(other_cid == kTwoByteStringCid);
+    __ movzxw(R13, FieldAddress(RCX, R11, TIMES_2,
+                                target::TwoByteString::data_offset()));
+  }
+  __ cmpq(R12, R13);
+  __ j(NOT_EQUAL, return_false);
+
+  // i++, while (i < len)
+  __ addq(R11, Immediate(1));
+  __ cmpq(R11, R9);
+  __ j(LESS, &loop, Assembler::kNearJump);
+
+  __ jmp(return_true);
+}
+
+// bool _substringMatches(int start, String other)
+// This intrinsic handles a OneByteString or TwoByteString receiver with a
+// OneByteString other.
+void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  Label return_true, return_false, try_two_byte;
+  __ movq(RAX, Address(RSP, +3 * target::kWordSize));  // receiver
+  __ movq(RBX, Address(RSP, +2 * target::kWordSize));  // start
+  __ movq(RCX, Address(RSP, +1 * target::kWordSize));  // other
+
+  __ testq(RBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);  // 'start' is not Smi.
+
+  __ CompareClassId(RCX, kOneByteStringCid);
+  __ j(NOT_EQUAL, normal_ir_body);
+
+  __ CompareClassId(RAX, kOneByteStringCid);
+  __ j(NOT_EQUAL, &try_two_byte);
+
+  GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
+                                         kOneByteStringCid, &return_true,
+                                         &return_false);
+
+  __ Bind(&try_two_byte);
+  __ CompareClassId(RAX, kTwoByteStringCid);
+  __ j(NOT_EQUAL, normal_ir_body);
+
+  GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
+                                         kOneByteStringCid, &return_true,
+                                         &return_false);
+
+  __ Bind(&return_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  __ Bind(&return_false);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
+                                       Label* normal_ir_body) {
+  Label try_two_byte_string;
+  __ movq(RCX, Address(RSP, +1 * target::kWordSize));  // Index.
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // String.
+  __ testq(RCX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);  // Non-smi index.
+  // Range check.
+  __ cmpq(RCX, FieldAddress(RAX, target::String::length_offset()));
+  // Runtime throws exception.
+  __ j(ABOVE_EQUAL, normal_ir_body);
+  __ CompareClassId(RAX, kOneByteStringCid);
+  __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
+  __ SmiUntag(RCX);
+  __ movzxb(RCX, FieldAddress(RAX, RCX, TIMES_1,
+                              target::OneByteString::data_offset()));
+  __ cmpq(RCX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
+  __ j(GREATER_EQUAL, normal_ir_body);
+  __ movq(RAX,
+          Address(THR, target::Thread::predefined_symbols_address_offset()));
+  __ movq(RAX, Address(RAX, RCX, TIMES_8,
+                       target::Symbols::kNullCharCodeSymbolOffset *
+                           target::kWordSize));
+  __ ret();
+
+  __ Bind(&try_two_byte_string);
+  __ CompareClassId(RAX, kTwoByteStringCid);
+  __ j(NOT_EQUAL, normal_ir_body);
+  ASSERT(kSmiTagShift == 1);
+  __ movzxw(RCX, FieldAddress(RAX, RCX, TIMES_1,
+                              target::OneByteString::data_offset()));
+  __ cmpq(RCX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
+  __ j(GREATER_EQUAL, normal_ir_body);
+  __ movq(RAX,
+          Address(THR, target::Thread::predefined_symbols_address_offset()));
+  __ movq(RAX, Address(RAX, RCX, TIMES_8,
+                       target::Symbols::kNullCharCodeSymbolOffset *
+                           target::kWordSize));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
+                                        Label* normal_ir_body) {
+  Label is_true;
+  // Get length.
+  __ movq(RAX, Address(RSP, +1 * target::kWordSize));  // String object.
+  __ movq(RAX, FieldAddress(RAX, target::String::length_offset()));
+  __ cmpq(RAX, Immediate(target::ToRawSmi(0)));
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  __ Bind(&is_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+}
+
+void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
+                                                Label* normal_ir_body) {
+  Label compute_hash;
+  __ movq(
+      RBX,
+      Address(RSP, +1 * target::kWordSize));  // target::OneByteString object.
+  __ movl(RAX, FieldAddress(RBX, target::String::hash_offset()));
+  __ cmpq(RAX, Immediate(0));
+  __ j(EQUAL, &compute_hash, Assembler::kNearJump);
+  __ SmiTag(RAX);
+  __ ret();
+
+  __ Bind(&compute_hash);
+  // Hash not yet computed, use algorithm of class StringHasher.
+  __ movq(RCX, FieldAddress(RBX, target::String::length_offset()));
+  __ SmiUntag(RCX);
+  __ xorq(RAX, RAX);
+  __ xorq(RDI, RDI);
+  // RBX: Instance of target::OneByteString.
+  // RCX: String length, untagged integer.
+  // RDI: Loop counter, untagged integer.
+  // RAX: Hash code, untagged integer.
+  Label loop, done, set_hash_code;
+  __ Bind(&loop);
+  __ cmpq(RDI, RCX);
+  __ j(EQUAL, &done, Assembler::kNearJump);
+  // Add to hash code: (hash_ is uint32)
+  // hash_ += ch;
+  // hash_ += hash_ << 10;
+  // hash_ ^= hash_ >> 6;
+  // Get one characters (ch).
+  __ movzxb(RDX, FieldAddress(RBX, RDI, TIMES_1,
+                              target::OneByteString::data_offset()));
+  // RDX: ch and temporary.
+  __ addl(RAX, RDX);
+  __ movq(RDX, RAX);
+  __ shll(RDX, Immediate(10));
+  __ addl(RAX, RDX);
+  __ movq(RDX, RAX);
+  __ shrl(RDX, Immediate(6));
+  __ xorl(RAX, RDX);
+
+  __ incq(RDI);
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&done);
+  // Finalize:
+  // hash_ += hash_ << 3;
+  // hash_ ^= hash_ >> 11;
+  // hash_ += hash_ << 15;
+  __ movq(RDX, RAX);
+  __ shll(RDX, Immediate(3));
+  __ addl(RAX, RDX);
+  __ movq(RDX, RAX);
+  __ shrl(RDX, Immediate(11));
+  __ xorl(RAX, RDX);
+  __ movq(RDX, RAX);
+  __ shll(RDX, Immediate(15));
+  __ addl(RAX, RDX);
+  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
+  __ andl(
+      RAX,
+      Immediate(((static_cast<intptr_t>(1) << target::String::kHashBits) - 1)));
+
+  // return hash_ == 0 ? 1 : hash_;
+  __ cmpq(RAX, Immediate(0));
+  __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
+  __ incq(RAX);
+  __ Bind(&set_hash_code);
+  __ movl(FieldAddress(RBX, target::String::hash_offset()), RAX);
+  __ SmiTag(RAX);
+  __ ret();
+}
+
+// Allocates one-byte string of length 'end - start'. The content is not
+// initialized. 'length-reg' contains tagged length.
+// Returns new string as tagged pointer in RAX.
+static void TryAllocateOnebyteString(Assembler* assembler,
+                                     Label* ok,
+                                     Label* failure,
+                                     Register length_reg) {
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, failure, false));
+  if (length_reg != RDI) {
+    __ movq(RDI, length_reg);
+  }
+  Label pop_and_fail, not_zero_length;
+  __ pushq(RDI);                          // Preserve length.
+  __ sarq(RDI, Immediate(kSmiTagShift));  // Untag length.
+  // If the length is 0 then we have to make the allocated size a bit bigger,
+  // otherwise the string takes up less space than an ExternalOneByteString,
+  // and cannot be externalized.  TODO(erikcorry): We should probably just
+  // return a static zero length string here instead.
+  __ j(NOT_ZERO, &not_zero_length);
+  __ addq(RDI, Immediate(1));
+  __ Bind(&not_zero_length);
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::String::InstanceSize() +
+      target::ObjectAlignment::kObjectAlignment - 1;
+  __ addq(RDI, Immediate(fixed_size_plus_alignment_padding));
+  __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
+
+  const intptr_t cid = kOneByteStringCid;
+  __ movq(RAX, Address(THR, target::Thread::top_offset()));
+
+  // RDI: allocation size.
+  __ movq(RCX, RAX);
+  __ addq(RCX, RDI);
+  __ j(CARRY, &pop_and_fail);
+
+  // Check if the allocation fits into the remaining space.
+  // RAX: potential new object start.
+  // RCX: potential next object start.
+  // RDI: allocation size.
+  __ cmpq(RCX, Address(THR, target::Thread::end_offset()));
+  __ j(ABOVE_EQUAL, &pop_and_fail);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  __ movq(Address(THR, target::Thread::top_offset()), RCX);
+  __ addq(RAX, Immediate(kHeapObjectTag));
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, RDI));
+
+  // Initialize the tags.
+  // RAX: new object start as a tagged pointer.
+  // RDI: allocation size.
+  {
+    Label size_tag_overflow, done;
+    __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+    __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2));
+    __ jmp(&done, Assembler::kNearJump);
+
+    __ Bind(&size_tag_overflow);
+    __ xorq(RDI, RDI);
+    __ Bind(&done);
+
+    // Get the class index and insert it into the tags.
+    // This also clears the hash, which is in the high bits of the tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    __ orq(RDI, Immediate(tags));
+    __ movq(FieldAddress(RAX, target::Object::tags_offset()), RDI);  // Tags.
+  }
+
+  // Set the length field.
+  __ popq(RDI);
+  __ StoreIntoObjectNoBarrier(
+      RAX, FieldAddress(RAX, target::String::length_offset()), RDI);
+  __ jmp(ok, Assembler::kNearJump);
+
+  __ Bind(&pop_and_fail);
+  __ popq(RDI);
+  __ jmp(failure);
+}
+
+// Arg0: target::OneByteString (receiver).
+// Arg1: Start index as Smi.
+// Arg2: End index as Smi.
+// The indexes must be valid.
+void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
+                                                       Label* normal_ir_body) {
+  const intptr_t kStringOffset = 3 * target::kWordSize;
+  const intptr_t kStartIndexOffset = 2 * target::kWordSize;
+  const intptr_t kEndIndexOffset = 1 * target::kWordSize;
+  Label ok;
+  __ movq(RSI, Address(RSP, +kStartIndexOffset));
+  __ movq(RDI, Address(RSP, +kEndIndexOffset));
+  __ orq(RSI, RDI);
+  __ testq(RSI, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
+
+  __ subq(RDI, Address(RSP, +kStartIndexOffset));
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
+  __ Bind(&ok);
+  // RAX: new string as tagged pointer.
+  // Copy string.
+  __ movq(RSI, Address(RSP, +kStringOffset));
+  __ movq(RBX, Address(RSP, +kStartIndexOffset));
+  __ SmiUntag(RBX);
+  __ leaq(RSI, FieldAddress(RSI, RBX, TIMES_1,
+                            target::OneByteString::data_offset()));
+  // RSI: Start address to copy from (untagged).
+  // RBX: Untagged start index.
+  __ movq(RCX, Address(RSP, +kEndIndexOffset));
+  __ SmiUntag(RCX);
+  __ subq(RCX, RBX);
+  __ xorq(RDX, RDX);
+  // RSI: Start address to copy from (untagged).
+  // RCX: Untagged number of bytes to copy.
+  // RAX: Tagged result string
+  // RDX: Loop counter.
+  // RBX: Scratch register.
+  Label loop, check;
+  __ jmp(&check, Assembler::kNearJump);
+  __ Bind(&loop);
+  __ movzxb(RBX, Address(RSI, RDX, TIMES_1, 0));
+  __ movb(FieldAddress(RAX, RDX, TIMES_1, target::OneByteString::data_offset()),
+          RBX);
+  __ incq(RDX);
+  __ Bind(&check);
+  __ cmpq(RDX, RCX);
+  __ j(LESS, &loop, Assembler::kNearJump);
+  __ ret();
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteStringSetAt(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ movq(RCX, Address(RSP, +1 * target::kWordSize));  // Value.
+  __ movq(RBX, Address(RSP, +2 * target::kWordSize));  // Index.
+  __ movq(RAX, Address(RSP, +3 * target::kWordSize));  // target::OneByteString.
+  __ SmiUntag(RBX);
+  __ SmiUntag(RCX);
+  __ movb(FieldAddress(RAX, RBX, TIMES_1, target::OneByteString::data_offset()),
+          RCX);
+  __ ret();
+}
+
+void AsmIntrinsifier::OneByteString_allocate(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ movq(RDI, Address(RSP, +1 * target::kWordSize));  // Length.v=
+  Label ok;
+  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
+  // RDI: Start address to copy from (untagged).
+
+  __ Bind(&ok);
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+static void StringEquality(Assembler* assembler,
+                           Label* normal_ir_body,
+                           intptr_t string_cid) {
+  Label is_true, is_false, loop;
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // This.
+  __ movq(RCX, Address(RSP, +1 * target::kWordSize));  // Other.
+
+  // Are identical?
+  __ cmpq(RAX, RCX);
+  __ j(EQUAL, &is_true, Assembler::kNearJump);
+
+  // Is other target::OneByteString?
+  __ testq(RCX, Immediate(kSmiTagMask));
+  __ j(ZERO, &is_false);  // Smi
+  __ CompareClassId(RCX, string_cid);
+  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
+
+  // Have same length?
+  __ movq(RDI, FieldAddress(RAX, target::String::length_offset()));
+  __ cmpq(RDI, FieldAddress(RCX, target::String::length_offset()));
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+
+  // Check contents, no fall-through possible.
+  // TODO(srdjan): write a faster check.
+  __ SmiUntag(RDI);
+  __ Bind(&loop);
+  __ decq(RDI);
+  __ cmpq(RDI, Immediate(0));
+  __ j(LESS, &is_true, Assembler::kNearJump);
+  if (string_cid == kOneByteStringCid) {
+    __ movzxb(RBX, FieldAddress(RAX, RDI, TIMES_1,
+                                target::OneByteString::data_offset()));
+    __ movzxb(RDX, FieldAddress(RCX, RDI, TIMES_1,
+                                target::OneByteString::data_offset()));
+  } else if (string_cid == kTwoByteStringCid) {
+    __ movzxw(RBX, FieldAddress(RAX, RDI, TIMES_2,
+                                target::TwoByteString::data_offset()));
+    __ movzxw(RDX, FieldAddress(RCX, RDI, TIMES_2,
+                                target::TwoByteString::data_offset()));
+  } else {
+    UNIMPLEMENTED();
+  }
+  __ cmpq(RBX, RDX);
+  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&is_true);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+
+  __ Bind(&is_false);
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+
+  __ Bind(normal_ir_body);
+}
+
+void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
+}
+
+void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
+}
+
+void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
+                                                   Label* normal_ir_body,
+                                                   bool sticky) {
+  if (FLAG_interpret_irregexp) return;
+
+  static const intptr_t kRegExpParamOffset = 3 * target::kWordSize;
+  static const intptr_t kStringParamOffset = 2 * target::kWordSize;
+  // start_index smi is located at offset 1.
+
+  // Incoming registers:
+  // RAX: Function. (Will be loaded with the specialized matcher function.)
+  // RCX: Unknown. (Must be GC safe on tail call.)
+  // R10: Arguments descriptor. (Will be preserved.)
+
+  // Load the specialized function pointer into RAX. Leverage the fact the
+  // string CIDs as well as stored function pointers are in sequence.
+  __ movq(RBX, Address(RSP, kRegExpParamOffset));
+  __ movq(RDI, Address(RSP, kStringParamOffset));
+  __ LoadClassId(RDI, RDI);
+  __ SubImmediate(RDI, Immediate(kOneByteStringCid));
+  __ movq(RAX, FieldAddress(
+                   RBX, RDI, TIMES_8,
+                   target::RegExp::function_offset(kOneByteStringCid, sticky)));
+
+  // Registers are now set up for the lazy compile stub. It expects the function
+  // in RAX, the argument descriptor in R10, and IC-Data in RCX.
+  __ xorq(RCX, RCX);
+
+  // Tail-call the function.
+  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ movq(RDI, FieldAddress(RAX, target::Function::entry_point_offset()));
+  __ jmp(RDI);
+}
+
+// On stack: user tag (+1), return-address (+0).
+void AsmIntrinsifier::UserTag_makeCurrent(Assembler* assembler,
+                                          Label* normal_ir_body) {
+  // RBX: Isolate.
+  __ LoadIsolate(RBX);
+  // RAX: Current user tag.
+  __ movq(RAX, Address(RBX, target::Isolate::current_tag_offset()));
+  // R10: UserTag.
+  __ movq(R10, Address(RSP, +1 * target::kWordSize));
+  // Set Isolate::current_tag_.
+  __ movq(Address(RBX, target::Isolate::current_tag_offset()), R10);
+  // R10: UserTag's tag.
+  __ movq(R10, FieldAddress(R10, target::UserTag::tag_offset()));
+  // Set Isolate::user_tag_.
+  __ movq(Address(RBX, target::Isolate::user_tag_offset()), R10);
+  __ ret();
+}
+
+void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
+                                         Label* normal_ir_body) {
+  __ LoadIsolate(RAX);
+  __ movq(RAX, Address(RAX, target::Isolate::default_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
+                                             Label* normal_ir_body) {
+  __ LoadIsolate(RAX);
+  __ movq(RAX, Address(RAX, target::Isolate::current_tag_offset()));
+  __ ret();
+}
+
+void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
+                                                   Label* normal_ir_body) {
+#if !defined(SUPPORT_TIMELINE)
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+#else
+  Label true_label;
+  // Load TimelineStream*.
+  __ movq(RAX, Address(THR, target::Thread::dart_stream_offset()));
+  // Load uintptr_t from TimelineStream*.
+  __ movq(RAX, Address(RAX, target::TimelineStream::enabled_offset()));
+  __ cmpq(RAX, Immediate(0));
+  __ j(NOT_ZERO, &true_label, Assembler::kNearJump);
+  // Not enabled.
+  __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+  __ ret();
+  // Enabled.
+  __ Bind(&true_label);
+  __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+  __ ret();
+#endif
+}
+
+void AsmIntrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
+                                                 Label* normal_ir_body) {
+  __ LoadObject(RAX, NullObject());
+  __ movq(Address(THR, target::Thread::async_stack_trace_offset()), RAX);
+  __ ret();
+}
+
+void AsmIntrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
+                                               Label* normal_ir_body) {
+  __ movq(Address(THR, target::Thread::async_stack_trace_offset()), RAX);
+  __ LoadObject(RAX, NullObject());
+  __ ret();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/assembler/assembler.cc b/runtime/vm/compiler/assembler/assembler.cc
index f945e3f..f6c6175 100644
--- a/runtime/vm/compiler/assembler/assembler.cc
+++ b/runtime/vm/compiler/assembler/assembler.cc
@@ -28,6 +28,8 @@
 DEFINE_FLAG(bool, use_far_branches, false, "Enable far branches for ARM.");
 #endif
 
+namespace compiler {
+
 static uword NewContents(intptr_t capacity) {
   Zone* zone = Thread::Current()->zone();
   uword result = zone->AllocUnsafe(capacity);
@@ -163,14 +165,16 @@
   return count;
 }
 
+#if defined(TARGET_ARCH_IA32)
 void AssemblerBuffer::EmitObject(const Object& object) {
   // Since we are going to store the handle as part of the fixup information
   // the handle needs to be a zone handle.
-  ASSERT(object.IsNotTemporaryScopedHandle());
-  ASSERT(object.IsOld());
+  ASSERT(IsNotTemporaryScopedHandle(object));
+  ASSERT(IsInOldSpace(object));
   EmitFixup(new PatchCodeWithHandle(pointer_offsets_, object));
-  cursor_ += kWordSize;  // Reserve space for pointer.
+  cursor_ += target::kWordSize;  // Reserve space for pointer.
 }
+#endif
 
 // Shared macros are implemented here.
 void AssemblerBase::Unimplemented(const char* message) {
@@ -207,8 +211,7 @@
     va_end(args);
 
     comments_.Add(
-        new CodeComment(buffer_.GetPosition(),
-                        String::ZoneHandle(String::New(buffer, Heap::kOld))));
+        new CodeComment(buffer_.GetPosition(), AllocateString(buffer)));
   }
 }
 
@@ -216,46 +219,27 @@
   return FLAG_code_comments || FLAG_disassemble || FLAG_disassemble_optimized;
 }
 
-const Code::Comments& AssemblerBase::GetCodeComments() const {
-  Code::Comments& comments = Code::Comments::New(comments_.length());
-
-  for (intptr_t i = 0; i < comments_.length(); i++) {
-    comments.SetPCOffsetAt(i, comments_[i]->pc_offset());
-    comments.SetCommentAt(i, comments_[i]->comment());
-  }
-
-  return comments;
+#if !defined(TARGET_ARCH_DBC)
+void Assembler::Stop(const char* message) {
+  Comment("Stop: %s", message);
+  Breakpoint();
 }
+#endif
 
 intptr_t ObjIndexPair::Hashcode(Key key) {
-  if (key.type() != ObjectPool::kTaggedObject) {
+  if (key.type() != ObjectPoolBuilderEntry::kTaggedObject) {
     return key.raw_value_;
   }
-  if (key.obj_->IsNull()) {
-    return 2011;
-  }
-  if (key.obj_->IsString() || key.obj_->IsNumber()) {
-    return Instance::Cast(*key.obj_).CanonicalizeHash();
-  }
-  if (key.obj_->IsCode()) {
-    // Instructions don't move during compaction.
-    return Code::Cast(*key.obj_).PayloadStart();
-  }
-  if (key.obj_->IsFunction()) {
-    return Function::Cast(*key.obj_).Hash();
-  }
-  if (key.obj_->IsField()) {
-    return String::HashRawSymbol(Field::Cast(*key.obj_).name());
-  }
-  // Unlikely.
-  return key.obj_->GetClassId();
+
+  return ObjectHash(*key.obj_);
 }
-void ObjectPoolWrapper::Reset() {
+
+void ObjectPoolBuilder::Reset() {
   // Null out the handles we've accumulated.
   for (intptr_t i = 0; i < object_pool_.length(); ++i) {
-    if (object_pool_[i].type() == ObjectPool::kTaggedObject) {
-      *const_cast<Object*>(object_pool_[i].obj_) = Object::null();
-      *const_cast<Object*>(object_pool_[i].equivalence_) = Object::null();
+    if (object_pool_[i].type() == ObjectPoolBuilderEntry::kTaggedObject) {
+      SetToNull(const_cast<Object*>(object_pool_[i].obj_));
+      SetToNull(const_cast<Object*>(object_pool_[i].equivalence_));
     }
   }
 
@@ -263,65 +247,38 @@
   object_pool_index_table_.Clear();
 }
 
-void ObjectPoolWrapper::InitializeFrom(const ObjectPool& other) {
-  ASSERT(object_pool_.length() == 0);
-
-  for (intptr_t i = 0; i < other.Length(); i++) {
-    auto type = other.TypeAt(i);
-    auto patchable = other.PatchableAt(i);
-    switch (type) {
-      case ObjectPool::kTaggedObject: {
-        ObjectPoolWrapperEntry entry(&Object::ZoneHandle(other.ObjectAt(i)),
-                                     patchable);
-        AddObject(entry);
-        break;
-      }
-      case ObjectPool::kImmediate:
-      case ObjectPool::kNativeFunction:
-      case ObjectPool::kNativeFunctionWrapper: {
-        ObjectPoolWrapperEntry entry(other.RawValueAt(i), type, patchable);
-        AddObject(entry);
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
-  }
-
-  ASSERT(CurrentLength() == other.Length());
+intptr_t ObjectPoolBuilder::AddObject(
+    const Object& obj,
+    ObjectPoolBuilderEntry::Patchability patchable) {
+  ASSERT(IsNotTemporaryScopedHandle(obj));
+  return AddObject(ObjectPoolBuilderEntry(&obj, patchable));
 }
 
-intptr_t ObjectPoolWrapper::AddObject(const Object& obj,
-                                      ObjectPool::Patchability patchable) {
-  ASSERT(obj.IsNotTemporaryScopedHandle());
-  return AddObject(ObjectPoolWrapperEntry(&obj, patchable));
+intptr_t ObjectPoolBuilder::AddImmediate(uword imm) {
+  return AddObject(
+      ObjectPoolBuilderEntry(imm, ObjectPoolBuilderEntry::kImmediate,
+                             ObjectPoolBuilderEntry::kNotPatchable));
 }
 
-intptr_t ObjectPoolWrapper::AddImmediate(uword imm) {
-  return AddObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate,
-                                          ObjectPool::kNotPatchable));
-}
-
-intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry) {
-  ASSERT((entry.type() != ObjectPool::kTaggedObject) ||
-         (entry.obj_->IsNotTemporaryScopedHandle() &&
+intptr_t ObjectPoolBuilder::AddObject(ObjectPoolBuilderEntry entry) {
+  ASSERT((entry.type() != ObjectPoolBuilderEntry::kTaggedObject) ||
+         (IsNotTemporaryScopedHandle(*entry.obj_) &&
           (entry.equivalence_ == NULL ||
-           entry.equivalence_->IsNotTemporaryScopedHandle())));
+           IsNotTemporaryScopedHandle(*entry.equivalence_))));
 
-  if (entry.type() == ObjectPool::kTaggedObject) {
+  if (entry.type() == ObjectPoolBuilderEntry::kTaggedObject) {
     // If the owner of the object pool wrapper specified a specific zone we
     // shoulld use we'll do so.
     if (zone_ != NULL) {
-      entry.obj_ = &Object::ZoneHandle(zone_, entry.obj_->raw());
+      entry.obj_ = &NewZoneHandle(zone_, *entry.obj_);
       if (entry.equivalence_ != NULL) {
-        entry.equivalence_ =
-            &Object::ZoneHandle(zone_, entry.equivalence_->raw());
+        entry.equivalence_ = &NewZoneHandle(zone_, *entry.equivalence_);
       }
     }
   }
 
   object_pool_.Add(entry);
-  if (entry.patchable() == ObjectPool::kNotPatchable) {
+  if (entry.patchable() == ObjectPoolBuilderEntry::kNotPatchable) {
     // The object isn't patchable. Record the index for fast lookup.
     object_pool_index_table_.Insert(
         ObjIndexPair(entry, object_pool_.length() - 1));
@@ -329,10 +286,10 @@
   return object_pool_.length() - 1;
 }
 
-intptr_t ObjectPoolWrapper::FindObject(ObjectPoolWrapperEntry entry) {
+intptr_t ObjectPoolBuilder::FindObject(ObjectPoolBuilderEntry entry) {
   // If the object is not patchable, check if we've already got it in the
   // object pool.
-  if (entry.patchable() == ObjectPool::kNotPatchable) {
+  if (entry.patchable() == ObjectPoolBuilderEntry::kNotPatchable) {
     intptr_t idx = object_pool_index_table_.LookupValue(entry);
     if (idx != ObjIndexPair::kNoIndex) {
       return idx;
@@ -341,54 +298,40 @@
   return AddObject(entry);
 }
 
-intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
-                                       ObjectPool::Patchability patchable) {
-  return FindObject(ObjectPoolWrapperEntry(&obj, patchable));
+intptr_t ObjectPoolBuilder::FindObject(
+    const Object& obj,
+    ObjectPoolBuilderEntry::Patchability patchable) {
+  return FindObject(ObjectPoolBuilderEntry(&obj, patchable));
 }
 
-intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
+intptr_t ObjectPoolBuilder::FindObject(const Object& obj,
                                        const Object& equivalence) {
+  return FindObject(ObjectPoolBuilderEntry(
+      &obj, &equivalence, ObjectPoolBuilderEntry::kNotPatchable));
+}
+
+intptr_t ObjectPoolBuilder::FindImmediate(uword imm) {
   return FindObject(
-      ObjectPoolWrapperEntry(&obj, &equivalence, ObjectPool::kNotPatchable));
+      ObjectPoolBuilderEntry(imm, ObjectPoolBuilderEntry::kImmediate,
+                             ObjectPoolBuilderEntry::kNotPatchable));
 }
 
-intptr_t ObjectPoolWrapper::FindImmediate(uword imm) {
-  return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate,
-                                           ObjectPool::kNotPatchable));
-}
-
-intptr_t ObjectPoolWrapper::FindNativeFunction(
+intptr_t ObjectPoolBuilder::FindNativeFunction(
     const ExternalLabel* label,
-    ObjectPool::Patchability patchable) {
-  return FindObject(ObjectPoolWrapperEntry(
-      label->address(), ObjectPool::kNativeFunction, patchable));
+    ObjectPoolBuilderEntry::Patchability patchable) {
+  return FindObject(ObjectPoolBuilderEntry(
+      label->address(), ObjectPoolBuilderEntry::kNativeFunction, patchable));
 }
 
-intptr_t ObjectPoolWrapper::FindNativeFunctionWrapper(
+intptr_t ObjectPoolBuilder::FindNativeFunctionWrapper(
     const ExternalLabel* label,
-    ObjectPool::Patchability patchable) {
-  return FindObject(ObjectPoolWrapperEntry(
-      label->address(), ObjectPool::kNativeFunctionWrapper, patchable));
+    ObjectPoolBuilderEntry::Patchability patchable) {
+  return FindObject(ObjectPoolBuilderEntry(
+      label->address(), ObjectPoolBuilderEntry::kNativeFunctionWrapper,
+      patchable));
 }
 
-RawObjectPool* ObjectPoolWrapper::MakeObjectPool() {
-  intptr_t len = object_pool_.length();
-  if (len == 0) {
-    return Object::empty_object_pool().raw();
-  }
-  const ObjectPool& result = ObjectPool::Handle(ObjectPool::New(len));
-  for (intptr_t i = 0; i < len; ++i) {
-    auto type = object_pool_[i].type();
-    auto patchable = object_pool_[i].patchable();
-    result.SetTypeAt(i, type, patchable);
-    if (type == ObjectPool::kTaggedObject) {
-      result.SetObjectAt(i, *object_pool_[i].obj_);
-    } else {
-      result.SetRawValueAt(i, object_pool_[i].raw_value_);
-    }
-  }
-  return result.raw();
-}
+}  // namespace compiler
 
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/assembler/assembler.h b/runtime/vm/compiler/assembler/assembler.h
index 2ecb376..2a5feb5 100644
--- a/runtime/vm/compiler/assembler/assembler.h
+++ b/runtime/vm/compiler/assembler/assembler.h
@@ -7,11 +7,11 @@
 
 #include "platform/assert.h"
 #include "vm/allocation.h"
+#include "vm/compiler/assembler/object_pool_builder.h"
+#include "vm/compiler/runtime_api.h"
 #include "vm/globals.h"
 #include "vm/growable_array.h"
 #include "vm/hash_map.h"
-#include "vm/object.h"
-#include "vm/thread.h"
 
 namespace dart {
 
@@ -19,11 +19,14 @@
 DECLARE_FLAG(bool, use_far_branches);
 #endif
 
+class MemoryRegion;
+
+namespace compiler {
+
 // Forward declarations.
 class Assembler;
 class AssemblerFixup;
 class AssemblerBuffer;
-class MemoryRegion;
 
 class Label : public ZoneAllocated {
  public:
@@ -45,12 +48,12 @@
   // for unused labels.
   intptr_t Position() const {
     ASSERT(!IsUnused());
-    return IsBound() ? -position_ - kWordSize : position_ - kWordSize;
+    return IsBound() ? -position_ - kBias : position_ - kBias;
   }
 
   intptr_t LinkPosition() const {
     ASSERT(IsLinked());
-    return position_ - kWordSize;
+    return position_ - kBias;
   }
 
   intptr_t NearPosition() {
@@ -69,6 +72,12 @@
 #else
   static const int kMaxUnresolvedBranches = 1;  // Unused on non-Intel.
 #endif
+  // Zero position_ means unused (neither bound nor linked to).
+  // Thus we offset actual positions by the given bias to prevent zero
+  // positions from occurring.
+  // Note: we use target::kWordSize as a bias because on ARM
+  // there are assertions that check that distance is aligned.
+  static constexpr int kBias = 4;
 
   intptr_t position_;
   intptr_t unresolved_;
@@ -79,13 +88,13 @@
   void BindTo(intptr_t position) {
     ASSERT(!IsBound());
     ASSERT(!HasNear());
-    position_ = -position - kWordSize;
+    position_ = -position - kBias;
     ASSERT(IsBound());
   }
 
   void LinkTo(intptr_t position) {
     ASSERT(!IsBound());
-    position_ = position + kWordSize;
+    position_ = position + kBias;
     ASSERT(IsLinked());
   }
 
@@ -185,8 +194,10 @@
     return *pointer_offsets_;
   }
 
+#if defined(TARGET_ARCH_IA32)
   // Emit an object pointer directly in the code.
   void EmitObject(const Object& object);
+#endif
 
   // Emit a fixup at the current location.
   void EmitFixup(AssemblerFixup* fixup) {
@@ -285,172 +296,23 @@
   friend class AssemblerFixup;
 };
 
-struct ObjectPoolWrapperEntry {
-  ObjectPoolWrapperEntry() : raw_value_(), entry_bits_(0), equivalence_() {}
-  ObjectPoolWrapperEntry(const Object* obj, ObjectPool::Patchability patchable)
-      : obj_(obj),
-        entry_bits_(ObjectPool::TypeBits::encode(ObjectPool::kTaggedObject) |
-                    ObjectPool::PatchableBit::encode(patchable)),
-        equivalence_(obj) {}
-  ObjectPoolWrapperEntry(const Object* obj,
-                         const Object* eqv,
-                         ObjectPool::Patchability patchable)
-      : obj_(obj),
-        entry_bits_(ObjectPool::TypeBits::encode(ObjectPool::kTaggedObject) |
-                    ObjectPool::PatchableBit::encode(patchable)),
-        equivalence_(eqv) {}
-  ObjectPoolWrapperEntry(uword value,
-                         ObjectPool::EntryType info,
-                         ObjectPool::Patchability patchable)
-      : raw_value_(value),
-        entry_bits_(ObjectPool::TypeBits::encode(info) |
-                    ObjectPool::PatchableBit::encode(patchable)),
-        equivalence_() {}
-
-  ObjectPool::EntryType type() const {
-    return ObjectPool::TypeBits::decode(entry_bits_);
-  }
-
-  ObjectPool::Patchability patchable() const {
-    return ObjectPool::PatchableBit::decode(entry_bits_);
-  }
-
-  union {
-    const Object* obj_;
-    uword raw_value_;
-  };
-  uint8_t entry_bits_;
-  const Object* equivalence_;
-};
-
-// Pair type parameter for DirectChainedHashMap used for the constant pool.
-class ObjIndexPair {
- public:
-  // Typedefs needed for the DirectChainedHashMap template.
-  typedef ObjectPoolWrapperEntry Key;
-  typedef intptr_t Value;
-  typedef ObjIndexPair Pair;
-
-  static const intptr_t kNoIndex = -1;
-
-  ObjIndexPair()
-      : key_(static_cast<uword>(NULL),
-             ObjectPool::kTaggedObject,
-             ObjectPool::kPatchable),
-        value_(kNoIndex) {}
-
-  ObjIndexPair(Key key, Value value) : value_(value) {
-    key_.entry_bits_ = key.entry_bits_;
-    if (key.type() == ObjectPool::kTaggedObject) {
-      key_.obj_ = key.obj_;
-      key_.equivalence_ = key.equivalence_;
-    } else {
-      key_.raw_value_ = key.raw_value_;
-    }
-  }
-
-  static Key KeyOf(Pair kv) { return kv.key_; }
-
-  static Value ValueOf(Pair kv) { return kv.value_; }
-
-  static intptr_t Hashcode(Key key);
-
-  static inline bool IsKeyEqual(Pair kv, Key key) {
-    if (kv.key_.entry_bits_ != key.entry_bits_) return false;
-    if (kv.key_.type() == ObjectPool::kTaggedObject) {
-      return (kv.key_.obj_->raw() == key.obj_->raw()) &&
-             (kv.key_.equivalence_->raw() == key.equivalence_->raw());
-    }
-    return kv.key_.raw_value_ == key.raw_value_;
-  }
-
- private:
-  Key key_;
-  Value value_;
-};
-
-class ObjectPoolWrapper : public ValueObject {
- public:
-  ObjectPoolWrapper() : zone_(nullptr) {}
-  ~ObjectPoolWrapper() {
-    if (zone_ != nullptr) {
-      Reset();
-      zone_ = nullptr;
-    }
-  }
-
-  // Clears all existing entries in this object pool builder.
-  //
-  // Note: Any code which has been compiled via this builder might use offsets
-  // into the pool which are not correct anymore.
-  void Reset();
-
-  // Initializes this object pool builder from [other].
-  //
-  // All entries from [other] will be populated, including their
-  // kind/patchability bits.
-  void InitializeFrom(const ObjectPool& other);
-
-  // Initialize this object pool builder with a [zone].
-  //
-  // Any objects added later on will be referenced using handles from [zone].
-  void InitializeWithZone(Zone* zone) {
-    ASSERT(object_pool_.length() == 0);
-    ASSERT(zone_ == nullptr && zone != nullptr);
-    zone_ = zone;
-  }
-
-  intptr_t AddObject(
-      const Object& obj,
-      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
-  intptr_t AddImmediate(uword imm);
-
-  intptr_t FindObject(
-      const Object& obj,
-      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
-  intptr_t FindObject(const Object& obj, const Object& equivalence);
-  intptr_t FindImmediate(uword imm);
-  intptr_t FindNativeFunction(const ExternalLabel* label,
-                              ObjectPool::Patchability patchable);
-  intptr_t FindNativeFunctionWrapper(const ExternalLabel* label,
-                                     ObjectPool::Patchability patchable);
-
-  RawObjectPool* MakeObjectPool();
-
-  intptr_t CurrentLength() { return object_pool_.length(); }
-  ObjectPoolWrapperEntry& EntryAt(intptr_t i) { return object_pool_[i]; }
-
- private:
-  intptr_t AddObject(ObjectPoolWrapperEntry entry);
-  intptr_t FindObject(ObjectPoolWrapperEntry entry);
-
-  // Objects and jump targets.
-  GrowableArray<ObjectPoolWrapperEntry> object_pool_;
-
-  // Hashmap for fast lookup in object pool.
-  DirectChainedHashMap<ObjIndexPair> object_pool_index_table_;
-
-  // The zone used for allocating the handles we keep in the map and array (or
-  // NULL, in which case allocations happen using the zone active at the point
-  // of insertion).
-  Zone* zone_;
-};
-
 enum RestorePP { kRestoreCallerPP, kKeepCalleePP };
 
-class AssemblerBase : public ValueObject {
+class AssemblerBase : public StackResource {
  public:
-  explicit AssemblerBase(ObjectPoolWrapper* object_pool_wrapper)
-      : prologue_offset_(-1),
+  explicit AssemblerBase(ObjectPoolBuilder* object_pool_builder)
+      : StackResource(ThreadState::Current()),
+        prologue_offset_(-1),
         has_single_entry_point_(true),
-        object_pool_wrapper_(object_pool_wrapper) {}
+        object_pool_builder_(object_pool_builder) {}
   virtual ~AssemblerBase() {}
 
   intptr_t CodeSize() const { return buffer_.Size(); }
 
   uword CodeAddress(intptr_t offset) { return buffer_.Address(offset); }
 
-  ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
+  bool HasObjectPoolBuilder() const { return object_pool_builder_ != nullptr; }
+  ObjectPoolBuilder& object_pool_builder() { return *object_pool_builder_; }
 
   intptr_t prologue_offset() const { return prologue_offset_; }
   bool has_single_entry_point() const { return has_single_entry_point_; }
@@ -458,8 +320,6 @@
   void Comment(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   static bool EmittingComments();
 
-  const Code::Comments& GetCodeComments() const;
-
   void Unimplemented(const char* message);
   void Untested(const char* message);
   void Unreachable(const char* message);
@@ -477,19 +337,6 @@
     return buffer_.pointer_offsets();
   }
 
-  RawObjectPool* MakeObjectPool() {
-    if (object_pool_wrapper_ != nullptr) {
-      return object_pool_wrapper_->MakeObjectPool();
-    }
-    return ObjectPool::null();
-  }
-
- protected:
-  AssemblerBuffer buffer_;  // Contains position independent code.
-  int32_t prologue_offset_;
-  bool has_single_entry_point_;
-
- private:
   class CodeComment : public ZoneAllocated {
    public:
     CodeComment(intptr_t pc_offset, const String& comment)
@@ -505,10 +352,20 @@
     DISALLOW_COPY_AND_ASSIGN(CodeComment);
   };
 
+  const GrowableArray<CodeComment*>& comments() const { return comments_; }
+
+ protected:
+  AssemblerBuffer buffer_;  // Contains position independent code.
+  int32_t prologue_offset_;
+  bool has_single_entry_point_;
+
+ private:
   GrowableArray<CodeComment*> comments_;
-  ObjectPoolWrapper* object_pool_wrapper_;
+  ObjectPoolBuilder* object_pool_builder_;
 };
 
+}  // namespace compiler
+
 }  // namespace dart
 
 #if defined(TARGET_ARCH_IA32)
@@ -525,4 +382,11 @@
 #error Unknown architecture.
 #endif
 
+namespace dart {
+using compiler::Assembler;
+using compiler::ExternalLabel;
+using compiler::Label;
+using compiler::ObjectPoolBuilder;
+}  // namespace dart
+
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_H_
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 53de88b..d441d61 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -5,14 +5,13 @@
 #include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
 
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/cpu.h"
-#include "vm/longjump.h"
-#include "vm/runtime_entry.h"
-#include "vm/simulator.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
+#include "vm/instructions.h"
 
 // An extra check since we are assuming the existence of /proc/cpuinfo below.
 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) &&   \
@@ -26,6 +25,40 @@
 DECLARE_FLAG(bool, inline_alloc);
 DECLARE_FLAG(bool, precompiled_mode);
 
+namespace compiler {
+
+#ifndef PRODUCT
+using target::ClassHeapStats;
+#endif
+using target::ClassTable;
+using target::Double;
+using target::Float32x4;
+using target::Float64x2;
+using target::Heap;
+using target::Instance;
+using target::Instructions;
+using target::Isolate;
+using target::ObjectPool;
+using target::RawObject;
+using target::Thread;
+
+Assembler::Assembler(ObjectPoolBuilder* object_pool_builder,
+                     bool use_far_branches)
+    : AssemblerBase(object_pool_builder),
+      use_far_branches_(use_far_branches),
+      constant_pool_allowed_(false) {
+  generate_invoke_write_barrier_wrapper_ = [&](Condition cond, Register reg) {
+    ldr(LR, Address(THR, Thread::write_barrier_wrappers_thread_offset(reg)),
+        cond);
+    blx(LR, cond);
+  };
+  generate_invoke_array_write_barrier_ = [&](Condition cond) {
+    ldr(LR, Address(THR, Thread::array_write_barrier_entry_point_offset()),
+        cond);
+    blx(LR, cond);
+  };
+}
+
 uint32_t Address::encoding3() const {
   if (kind_ == Immediate) {
     uint32_t offset = encoding_ & kOffset12Mask;
@@ -451,7 +484,7 @@
   ASSERT(rd2 == rd + 1);
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
     ldr(rd, Address(rn, offset), cond);
-    ldr(rd2, Address(rn, offset + kWordSize), cond);
+    ldr(rd2, Address(rn, offset + target::kWordSize), cond);
   } else {
     EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, Address(rn, offset));
   }
@@ -466,7 +499,7 @@
   ASSERT(rd2 == rd + 1);
   if (TargetCPUFeatures::arm_version() == ARMv5TE) {
     str(rd, Address(rn, offset), cond);
-    str(rd2, Address(rn, offset + kWordSize), cond);
+    str(rd2, Address(rn, offset + target::kWordSize), cond);
   } else {
     EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, Address(rn, offset));
   }
@@ -1373,12 +1406,12 @@
 void Assembler::Drop(intptr_t stack_elements) {
   ASSERT(stack_elements >= 0);
   if (stack_elements > 0) {
-    AddImmediate(SP, stack_elements * kWordSize);
+    AddImmediate(SP, stack_elements * target::kWordSize);
   }
 }
 
 intptr_t Assembler::FindImmediate(int32_t imm) {
-  return object_pool_wrapper().FindImmediate(imm);
+  return object_pool_builder().FindImmediate(imm);
 }
 
 // Uses a code sequence that can easily be decoded.
@@ -1424,7 +1457,7 @@
                           Instructions::HeaderSize() - kHeapObjectTag;
   mov(R0, Operand(PC));
   AddImmediate(R0, -offset);
-  ldr(IP, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
+  ldr(IP, FieldAddress(CODE_REG, target::Code::saved_instructions_offset()));
   cmp(R0, Operand(IP));
   b(&instructions_ok, EQ);
   bkpt(1);
@@ -1435,14 +1468,15 @@
 }
 
 void Assembler::RestoreCodePointer() {
-  ldr(CODE_REG, Address(FP, compiler_frame_layout.code_from_fp * kWordSize));
+  ldr(CODE_REG,
+      Address(FP, target::frame_layout.code_from_fp * target::kWordSize));
   CheckCodePointer();
 }
 
 void Assembler::LoadPoolPointer(Register reg) {
   // Load new pool pointer.
   CheckCodePointer();
-  ldr(reg, FieldAddress(CODE_REG, Code::object_pool_offset()));
+  ldr(reg, FieldAddress(CODE_REG, target::Code::object_pool_offset()));
   set_constant_pool_allowed(reg == PP);
 }
 
@@ -1451,15 +1485,14 @@
 }
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  ASSERT(!Thread::CanLoadFromThread(object));
+  ASSERT(IsOriginalObject(object));
+  ASSERT(!target::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
   }
 
-  ASSERT(object.IsNotTemporaryScopedHandle());
-  ASSERT(object.IsOld());
+  ASSERT(IsNotTemporaryScopedHandle(object));
+  ASSERT(IsInOldSpace(object));
   return true;
 }
 
@@ -1468,21 +1501,21 @@
                                  Condition cond,
                                  bool is_unique,
                                  Register pp) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
+  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, Thread::OffsetFromThread(object)), cond);
-  } else if (object.IsSmi()) {
+    ldr(rd, Address(THR, offset), cond);
+  } else if (target::IsSmi(object)) {
     // Relocation doesn't apply to Smis.
-    LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond);
+    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 int32_t offset = ObjectPool::element_offset(
-        is_unique ? object_pool_wrapper().AddObject(object)
-                  : object_pool_wrapper().FindObject(object));
+        is_unique ? object_pool_builder().AddObject(object)
+                  : object_pool_builder().FindObject(object));
     LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond);
   } else {
     UNREACHABLE();
@@ -1502,33 +1535,31 @@
 void Assembler::LoadFunctionFromCalleePool(Register dst,
                                            const Function& function,
                                            Register new_pp) {
-  const int32_t offset =
-      ObjectPool::element_offset(object_pool_wrapper().FindObject(function));
+  const int32_t offset = ObjectPool::element_offset(
+      object_pool_builder().FindObject(ToObject(function)));
   LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp, AL);
 }
 
 void Assembler::LoadNativeEntry(Register rd,
                                 const ExternalLabel* label,
-                                ObjectPool::Patchability patchable,
+                                ObjectPoolBuilderEntry::Patchability patchable,
                                 Condition cond) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindNativeFunction(label, patchable));
+      object_pool_builder().FindNativeFunction(label, patchable));
   LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
 }
 
 void Assembler::PushObject(const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
+  ASSERT(IsOriginalObject(object));
   LoadObject(IP, object);
   Push(IP);
 }
 
 void Assembler::CompareObject(Register rn, const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
+  ASSERT(IsOriginalObject(object));
   ASSERT(rn != IP);
-  if (object.IsSmi()) {
-    CompareImmediate(rn, reinterpret_cast<int32_t>(object.raw()));
+  if (target::IsSmi(object)) {
+    CompareImmediate(rn, target::ToRawSmi(object));
   } else {
     LoadObject(IP, object);
     cmp(rn, Operand(IP));
@@ -1541,12 +1572,15 @@
                                       Label* label,
                                       CanBeSmi value_can_be_smi,
                                       BarrierFilterMode how_to_jump) {
-  COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
-                 (kOldObjectAlignmentOffset == 0));
+  COMPILE_ASSERT((target::ObjectAlignment::kNewObjectAlignmentOffset ==
+                  target::kWordSize) &&
+                 (target::ObjectAlignment::kOldObjectAlignmentOffset == 0));
   // For the value we are only interested in the new/old bit and the tag bit.
   // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
   if (value_can_be_smi == kValueCanBeSmi) {
-    and_(IP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1));
+    and_(
+        IP, value,
+        Operand(value, LSL, target::ObjectAlignment::kObjectAlignmentLog2 - 1));
     // And the result with the negated space bit of the object.
     bic(IP, IP, Operand(object));
   } else {
@@ -1558,7 +1592,7 @@
 #endif
     bic(IP, value, Operand(object));
   }
-  tst(IP, Operand(kNewObjectAlignmentOffset));
+  tst(IP, Operand(target::ObjectAlignment::kNewObjectAlignmentOffset));
   if (how_to_jump != kNoJump) {
     b(label, how_to_jump == kJumpToNoUpdate ? EQ : NE);
   }
@@ -1609,8 +1643,8 @@
     BranchIfSmi(value, &done);
   }
   if (!lr_reserved) Push(LR);
-  ldrb(TMP, FieldAddress(object, Object::tags_offset()));
-  ldrb(LR, FieldAddress(value, Object::tags_offset()));
+  ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
+  ldrb(LR, FieldAddress(value, target::Object::tags_offset()));
   and_(TMP, LR, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
   ldr(LR, Address(THR, Thread::write_barrier_mask_offset()));
   tst(TMP, Operand(LR));
@@ -1630,8 +1664,8 @@
       mov(objectForCall, Operand(object));
     }
     mov(kWriteBarrierValueReg, Operand(value));
-    ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(objectForCall)));
-    blx(LR);
+    generate_invoke_write_barrier_wrapper_(AL, objectForCall);
+
     if (object != kWriteBarrierValueReg) {
       Pop(kWriteBarrierValueReg);
     } else {
@@ -1639,8 +1673,7 @@
     }
     Bind(&restore_and_done);
   } else {
-    ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(object)), NE);
-    blx(LR, NE);
+    generate_invoke_write_barrier_wrapper_(NE, object);
   }
   if (!lr_reserved) Pop(LR);
   Bind(&done);
@@ -1674,8 +1707,8 @@
     BranchIfSmi(value, &done);
   }
   if (!lr_reserved) Push(LR);
-  ldrb(TMP, FieldAddress(object, Object::tags_offset()));
-  ldrb(LR, FieldAddress(value, Object::tags_offset()));
+  ldrb(TMP, FieldAddress(object, target::Object::tags_offset()));
+  ldrb(LR, FieldAddress(value, target::Object::tags_offset()));
   and_(TMP, LR, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
   ldr(LR, Address(THR, Thread::write_barrier_mask_offset()));
   tst(TMP, Operand(LR));
@@ -1687,10 +1720,7 @@
     // allocator.
     UNIMPLEMENTED();
   }
-
-  ldr(LR, Address(THR, Thread::array_write_barrier_entry_point_offset()), NE);
-  blx(LR, NE);
-
+  generate_invoke_array_write_barrier_(NE);
   if (!lr_reserved) Pop(LR);
   Bind(&done);
 }
@@ -1726,10 +1756,8 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
-  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
-  ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
-  ASSERT(value.IsSmi() || value.InVMHeap() ||
-         (value.IsOld() && value.IsNotTemporaryScopedHandle()));
+  ASSERT(IsOriginalObject(value));
+  ASSERT(IsNotTemporaryScopedHandle(value));
   // No store buffer update.
   LoadObject(IP, value);
   str(IP, dest);
@@ -1753,8 +1781,7 @@
 void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
                                                int32_t offset,
                                                const Object& value) {
-  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
-  ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
+  ASSERT(IsOriginalObject(value));
   int32_t ignored = 0;
   if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
     StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
@@ -1775,11 +1802,11 @@
   ASSERT(value_odd == value_even + 1);
   Label init_loop;
   Bind(&init_loop);
-  AddImmediate(begin, 2 * kWordSize);
+  AddImmediate(begin, 2 * target::kWordSize);
   cmp(begin, Operand(end));
-  strd(value_even, value_odd, begin, -2 * kWordSize, LS);
+  strd(value_even, value_odd, begin, -2 * target::kWordSize, LS);
   b(&init_loop, CC);
-  str(value_even, Address(begin, -2 * kWordSize), HI);
+  str(value_even, Address(begin, -2 * target::kWordSize), HI);
 #if defined(DEBUG)
   Label done;
   StoreIntoObjectFilter(object, value_even, &done, kValueCanBeSmi,
@@ -1800,13 +1827,13 @@
                                                   Register value_odd) {
   ASSERT(value_odd == value_even + 1);
   intptr_t current_offset = begin_offset;
-  while (current_offset + kWordSize < end_offset) {
+  while (current_offset + target::kWordSize < end_offset) {
     strd(value_even, value_odd, base, current_offset);
-    current_offset += 2 * kWordSize;
+    current_offset += 2 * target::kWordSize;
   }
   while (current_offset < end_offset) {
     str(value_even, Address(base, current_offset));
-    current_offset += kWordSize;
+    current_offset += target::kWordSize;
   }
 #if defined(DEBUG)
   Label done;
@@ -1835,7 +1862,7 @@
   ASSERT(RawObject::kClassIdTagPos == 16);
   ASSERT(RawObject::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
-      Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
+      target::Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
   ldrh(result, FieldAddress(object, class_id_offset), cond);
 }
 
@@ -1845,7 +1872,7 @@
   const intptr_t offset =
       Isolate::class_table_offset() + ClassTable::table_offset();
   LoadFromOffset(kWord, result, result, offset);
-  ldr(result, Address(result, class_id, LSL, kSizeOfClassPairLog2));
+  ldr(result, Address(result, class_id, LSL, ClassTable::kSizeOfClassPairLog2));
 }
 
 void Assembler::CompareClassId(Register object,
@@ -1869,7 +1896,7 @@
 void Assembler::BailoutIfInvalidBranchOffset(int32_t offset) {
   if (!CanEncodeBranchDistance(offset)) {
     ASSERT(!use_far_branches());
-    Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
+    BailoutWithBranchOffsetError();
   }
 }
 
@@ -2303,11 +2330,11 @@
 }
 
 void Assembler::Push(Register rd, Condition cond) {
-  str(rd, Address(SP, -kWordSize, Address::PreIndex), cond);
+  str(rd, Address(SP, -target::kWordSize, Address::PreIndex), cond);
 }
 
 void Assembler::Pop(Register rd, Condition cond) {
-  ldr(rd, Address(SP, kWordSize, Address::PostIndex), cond);
+  ldr(rd, Address(SP, target::kWordSize, Address::PostIndex), cond);
 }
 
 void Assembler::PushList(RegList regs, Condition cond) {
@@ -2524,13 +2551,13 @@
 }
 
 void Assembler::Branch(const Code& target,
-                       ObjectPool::Patchability patchable,
+                       ObjectPoolBuilderEntry::Patchability patchable,
                        Register pp,
                        Condition cond) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindObject(target, patchable));
+      object_pool_builder().FindObject(ToObject(target), patchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond);
-  Branch(FieldAddress(CODE_REG, Code::entry_point_offset()), cond);
+  Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()), cond);
 }
 
 void Assembler::Branch(const Address& address, Condition cond) {
@@ -2538,22 +2565,22 @@
 }
 
 void Assembler::BranchLink(const Code& target,
-                           ObjectPool::Patchability patchable,
-                           Code::EntryKind entry_kind) {
+                           ObjectPoolBuilderEntry::Patchability patchable,
+                           CodeEntryKind entry_kind) {
   // Make sure that class CallPattern is able to patch the label referred
   // to by this code sequence.
   // For added code robustness, use 'blx lr' in a patchable sequence and
   // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindObject(target, patchable));
+      object_pool_builder().FindObject(ToObject(target), patchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL);
-  ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
+  ldr(LR, FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
   blx(LR);  // Use blx instruction so that the return branch prediction works.
 }
 
 void Assembler::BranchLinkPatchable(const Code& target,
-                                    Code::EntryKind entry_kind) {
-  BranchLink(target, ObjectPool::kPatchable, entry_kind);
+                                    CodeEntryKind entry_kind) {
+  BranchLink(target, ObjectPoolBuilderEntry::kPatchable, entry_kind);
 }
 
 void Assembler::BranchLinkToRuntime() {
@@ -2572,15 +2599,15 @@
 
 void Assembler::BranchLinkWithEquivalence(const Code& target,
                                           const Object& equivalence,
-                                          Code::EntryKind entry_kind) {
+                                          CodeEntryKind entry_kind) {
   // Make sure that class CallPattern is able to patch the label referred
   // to by this code sequence.
   // For added code robustness, use 'blx lr' in a patchable sequence and
   // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindObject(target, equivalence));
+      object_pool_builder().FindObject(ToObject(target), equivalence));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL);
-  ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
+  ldr(LR, FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
   blx(LR);  // Use blx instruction so that the return branch prediction works.
 }
 
@@ -2824,10 +2851,10 @@
   } else {
     LoadFromOffset(kWord, tmp1, src, Double::value_offset() - kHeapObjectTag);
     LoadFromOffset(kWord, tmp2, src,
-                   Double::value_offset() + kWordSize - kHeapObjectTag);
+                   Double::value_offset() + target::kWordSize - kHeapObjectTag);
     StoreToOffset(kWord, tmp1, dst, Double::value_offset() - kHeapObjectTag);
     StoreToOffset(kWord, tmp2, dst,
-                  Double::value_offset() + kWordSize - kHeapObjectTag);
+                  Double::value_offset() + target::kWordSize - kHeapObjectTag);
   }
 }
 
@@ -2844,25 +2871,29 @@
   } else {
     LoadFromOffset(
         kWord, tmp1, src,
-        (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag);
+        (Float32x4::value_offset() + 0 * target::kWordSize) - kHeapObjectTag);
     LoadFromOffset(
         kWord, tmp2, src,
-        (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (Float32x4::value_offset() + 0 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (Float32x4::value_offset() + 1 * kWordSize) - kHeapObjectTag);
+        (Float32x4::value_offset() + 1 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp1, dst,
+        (Float32x4::value_offset() + 0 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp2, dst,
+        (Float32x4::value_offset() + 1 * target::kWordSize) - kHeapObjectTag);
 
     LoadFromOffset(
         kWord, tmp1, src,
-        (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag);
+        (Float32x4::value_offset() + 2 * target::kWordSize) - kHeapObjectTag);
     LoadFromOffset(
         kWord, tmp2, src,
-        (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (Float32x4::value_offset() + 2 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (Float32x4::value_offset() + 3 * kWordSize) - kHeapObjectTag);
+        (Float32x4::value_offset() + 3 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp1, dst,
+        (Float32x4::value_offset() + 2 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp2, dst,
+        (Float32x4::value_offset() + 3 * target::kWordSize) - kHeapObjectTag);
   }
 }
 
@@ -2879,25 +2910,29 @@
   } else {
     LoadFromOffset(
         kWord, tmp1, src,
-        (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag);
+        (Float64x2::value_offset() + 0 * target::kWordSize) - kHeapObjectTag);
     LoadFromOffset(
         kWord, tmp2, src,
-        (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (Float64x2::value_offset() + 0 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (Float64x2::value_offset() + 1 * kWordSize) - kHeapObjectTag);
+        (Float64x2::value_offset() + 1 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp1, dst,
+        (Float64x2::value_offset() + 0 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp2, dst,
+        (Float64x2::value_offset() + 1 * target::kWordSize) - kHeapObjectTag);
 
     LoadFromOffset(
         kWord, tmp1, src,
-        (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag);
+        (Float64x2::value_offset() + 2 * target::kWordSize) - kHeapObjectTag);
     LoadFromOffset(
         kWord, tmp2, src,
-        (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp1, dst,
-                  (Float64x2::value_offset() + 2 * kWordSize) - kHeapObjectTag);
-    StoreToOffset(kWord, tmp2, dst,
-                  (Float64x2::value_offset() + 3 * kWordSize) - kHeapObjectTag);
+        (Float64x2::value_offset() + 3 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp1, dst,
+        (Float64x2::value_offset() + 2 * target::kWordSize) - kHeapObjectTag);
+    StoreToOffset(
+        kWord, tmp2, dst,
+        (Float64x2::value_offset() + 3 * target::kWordSize) - kHeapObjectTag);
   }
 }
 
@@ -3131,7 +3166,7 @@
   // kVolatileCpuRegCount +1 for PP, -1 because even though LR is volatile,
   // it is pushed ahead of FP.
   const intptr_t kPushedRegistersSize =
-      kDartVolatileCpuRegCount * kWordSize + kPushedFpuRegisterSize;
+      kDartVolatileCpuRegCount * target::kWordSize + kPushedFpuRegisterSize;
   AddImmediate(SP, FP, -kPushedRegistersSize);
 
   // Restore all volatile FPU registers.
@@ -3194,8 +3229,8 @@
 
 void Assembler::LeaveDartFrame() {
   if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    ldr(PP,
-        Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
+    ldr(PP, Address(FP, target::frame_layout.saved_caller_pp_from_fp *
+                            target::kWordSize));
   }
   set_constant_pool_allowed(false);
 
@@ -3206,8 +3241,8 @@
 
 void Assembler::LeaveDartFrameAndReturn() {
   if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    ldr(PP,
-        Address(FP, compiler_frame_layout.saved_caller_pp_from_fp * kWordSize));
+    ldr(PP, Address(FP, target::frame_layout.saved_caller_pp_from_fp *
+                            target::kWordSize));
   }
   set_constant_pool_allowed(false);
 
@@ -3271,15 +3306,12 @@
 }
 
 void Assembler::IncrementAllocationStats(Register stats_addr_reg,
-                                         intptr_t cid,
-                                         Heap::Space space) {
+                                         intptr_t cid) {
   ASSERT(stats_addr_reg != kNoRegister);
   ASSERT(stats_addr_reg != TMP);
   ASSERT(cid > 0);
   const uword count_field_offset =
-      (space == Heap::kNew)
-          ? ClassHeapStats::allocated_since_gc_new_space_offset()
-          : ClassHeapStats::allocated_since_gc_old_space_offset();
+      ClassHeapStats::allocated_since_gc_new_space_offset();
   const Address& count_address = Address(stats_addr_reg, count_field_offset);
   ldr(TMP, count_address);
   AddImmediate(TMP, 1);
@@ -3287,18 +3319,13 @@
 }
 
 void Assembler::IncrementAllocationStatsWithSize(Register stats_addr_reg,
-                                                 Register size_reg,
-                                                 Heap::Space space) {
+                                                 Register size_reg) {
   ASSERT(stats_addr_reg != kNoRegister);
   ASSERT(stats_addr_reg != TMP);
   const uword count_field_offset =
-      (space == Heap::kNew)
-          ? ClassHeapStats::allocated_since_gc_new_space_offset()
-          : ClassHeapStats::allocated_since_gc_old_space_offset();
+      ClassHeapStats::allocated_since_gc_new_space_offset();
   const uword size_field_offset =
-      (space == Heap::kNew)
-          ? ClassHeapStats::allocated_size_since_gc_new_space_offset()
-          : ClassHeapStats::allocated_size_since_gc_old_space_offset();
+      ClassHeapStats::allocated_size_since_gc_new_space_offset();
   const Address& count_address = Address(stats_addr_reg, count_field_offset);
   const Address& size_address = Address(stats_addr_reg, size_field_offset);
   ldr(TMP, count_address);
@@ -3315,13 +3342,13 @@
                             Register instance_reg,
                             Register temp_reg) {
   ASSERT(failure != NULL);
-  const intptr_t instance_size = cls.instance_size();
+  const intptr_t instance_size = target::Class::GetInstanceSize(cls);
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+    const classid_t cid = target::Class::GetId(cls);
     ASSERT(instance_reg != temp_reg);
     ASSERT(temp_reg != IP);
     ASSERT(instance_size != 0);
-    NOT_IN_PRODUCT(LoadAllocationStatsAddress(temp_reg, cls.id()));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
+    NOT_IN_PRODUCT(LoadAllocationStatsAddress(temp_reg, cid));
     ldr(instance_reg, Address(THR, Thread::top_offset()));
     // TODO(koda): Protect against unsigned overflow here.
     AddImmediateSetFlags(instance_reg, instance_reg, instance_size);
@@ -3344,15 +3371,12 @@
     ASSERT(instance_size >= kHeapObjectTag);
     AddImmediate(instance_reg, -instance_size + kHeapObjectTag);
 
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
     LoadImmediate(IP, tags);
-    str(IP, FieldAddress(instance_reg, Object::tags_offset()));
+    str(IP, FieldAddress(instance_reg, target::Object::tags_offset()));
 
-    NOT_IN_PRODUCT(IncrementAllocationStats(temp_reg, cls.id(), space));
+    NOT_IN_PRODUCT(IncrementAllocationStats(temp_reg, cid));
   } else {
     b(failure);
   }
@@ -3367,7 +3391,6 @@
                                  Register temp2) {
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
     NOT_IN_PRODUCT(LoadAllocationStatsAddress(temp1, cid));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
     // Potential new object start.
     ldr(instance, Address(THR, Thread::top_offset()));
     AddImmediateSetFlags(end_address, instance, instance_size);
@@ -3392,35 +3415,27 @@
 
     // Initialize the tags.
     // instance: new object start as a tagged pointer.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
     LoadImmediate(temp2, tags);
-    str(temp2, FieldAddress(instance, Array::tags_offset()));  // Store tags.
+    str(temp2,
+        FieldAddress(instance, target::Object::tags_offset()));  // Store tags.
 
     LoadImmediate(temp2, instance_size);
-    NOT_IN_PRODUCT(IncrementAllocationStatsWithSize(temp1, temp2, space));
+    NOT_IN_PRODUCT(IncrementAllocationStatsWithSize(temp1, temp2));
   } else {
     b(failure);
   }
 }
 
-void Assembler::GenerateUnRelocatedPcRelativeCall() {
-  // Emit "blr <offset>".
-  EmitType5(AL, 0x686868, /*link=*/true);
-}
+void Assembler::GenerateUnRelocatedPcRelativeCall(Condition cond,
+                                                  intptr_t offset_into_target) {
+  // Emit "blr.cond <offset>".
+  EmitType5(cond, 0x686868, /*link=*/true);
 
-void Assembler::Stop(const char* message) {
-  if (FLAG_print_stop_message) {
-    PushList((1 << R0) | (1 << IP) | (1 << LR));  // Preserve R0, IP, LR.
-    LoadImmediate(R0, reinterpret_cast<int32_t>(message));
-    // PrintStopMessage() preserves all registers.
-    ExternalLabel label(StubCode::PrintStopMessage().EntryPoint());
-    BranchLink(&label);
-    PopList((1 << R0) | (1 << IP) | (1 << LR));  // Restore R0, IP, LR.
-  }
-  bkpt(Instr::kStopMessageCode);
+  PcRelativeCallPattern pattern(buffer_.contents() + buffer_.Size() -
+                                PcRelativeCallPattern::kLengthInBytes);
+  pattern.set_distance(offset_into_target);
 }
 
 Address Assembler::ElementAddressForIntIndex(bool is_load,
@@ -3591,6 +3606,7 @@
   return fpu_reg_names[reg];
 }
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index b4c35c9..6b79492 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -9,19 +9,53 @@
 #error Do not include assembler_arm.h directly; use assembler.h instead.
 #endif
 
+#include <functional>
+
 #include "platform/assert.h"
 #include "platform/utils.h"
+#include "vm/code_entry_kind.h"
+#include "vm/compiler/runtime_api.h"
 #include "vm/constants_arm.h"
 #include "vm/cpu.h"
 #include "vm/hash_map.h"
-#include "vm/object.h"
 #include "vm/simulator.h"
 
 namespace dart {
 
 // Forward declarations.
-class RuntimeEntry;
+class FlowGraphCompiler;
 class RegisterSet;
+class RuntimeEntry;
+
+// TODO(vegorov) these enumerations are temporarily moved out of compiler
+// namespace to make refactoring easier.
+enum OperandSize {
+  kByte,
+  kUnsignedByte,
+  kHalfword,
+  kUnsignedHalfword,
+  kWord,
+  kUnsignedWord,
+  kWordPair,
+  kSWord,
+  kDWord,
+  kRegList,
+};
+
+// Load/store multiple addressing mode.
+enum BlockAddressMode {
+  // bit encoding P U W
+  DA = (0 | 0 | 0) << 21,    // decrement after
+  IA = (0 | 4 | 0) << 21,    // increment after
+  DB = (8 | 0 | 0) << 21,    // decrement before
+  IB = (8 | 4 | 0) << 21,    // increment before
+  DA_W = (0 | 0 | 1) << 21,  // decrement after with writeback to base
+  IA_W = (0 | 4 | 1) << 21,  // increment after with writeback to base
+  DB_W = (8 | 0 | 1) << 21,  // decrement before with writeback to base
+  IB_W = (8 | 4 | 1) << 21   // increment before with writeback to base
+};
+
+namespace compiler {
 
 // Instruction encoding bits.
 enum {
@@ -180,32 +214,6 @@
   friend class Address;
 };
 
-enum OperandSize {
-  kByte,
-  kUnsignedByte,
-  kHalfword,
-  kUnsignedHalfword,
-  kWord,
-  kUnsignedWord,
-  kWordPair,
-  kSWord,
-  kDWord,
-  kRegList,
-};
-
-// Load/store multiple addressing mode.
-enum BlockAddressMode {
-  // bit encoding P U W
-  DA = (0 | 0 | 0) << 21,    // decrement after
-  IA = (0 | 4 | 0) << 21,    // increment after
-  DB = (8 | 0 | 0) << 21,    // decrement before
-  IB = (8 | 4 | 0) << 21,    // increment before
-  DA_W = (0 | 0 | 1) << 21,  // decrement after with writeback to base
-  IA_W = (0 | 4 | 1) << 21,  // increment after with writeback to base
-  DB_W = (8 | 0 | 1) << 21,  // decrement before with writeback to base
-  IB_W = (8 | 4 | 1) << 21   // increment before with writeback to base
-};
-
 class Address : public ValueObject {
  public:
   enum OffsetKind {
@@ -337,12 +345,8 @@
 
 class Assembler : public AssemblerBase {
  public:
-  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
-                     bool use_far_branches = false)
-      : AssemblerBase(object_pool_wrapper),
-        use_far_branches_(use_far_branches),
-        constant_pool_allowed_(false) {}
-
+  explicit Assembler(ObjectPoolBuilder* object_pool_builder,
+                     bool use_far_branches = false);
   ~Assembler() {}
 
   void PushRegister(Register r) { Push(r); }
@@ -656,31 +660,31 @@
   void blx(Register rm, Condition cond = AL);
 
   void Branch(const Code& code,
-              ObjectPool::Patchability patchable = ObjectPool::kNotPatchable,
+              ObjectPoolBuilderEntry::Patchability patchable =
+                  ObjectPoolBuilderEntry::kNotPatchable,
               Register pp = PP,
               Condition cond = AL);
 
   void Branch(const Address& address, Condition cond = AL);
 
-  void BranchLink(
-      const Code& code,
-      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable,
-      Code::EntryKind entry_kind = Code::EntryKind::kNormal);
+  void BranchLink(const Code& code,
+                  ObjectPoolBuilderEntry::Patchability patchable =
+                      ObjectPoolBuilderEntry::kNotPatchable,
+                  CodeEntryKind entry_kind = CodeEntryKind::kNormal);
   void BranchLinkToRuntime();
 
   void CallNullErrorShared(bool save_fpu_registers);
 
   // Branch and link to an entry address. Call sequence can be patched.
-  void BranchLinkPatchable(
-      const Code& code,
-      Code::EntryKind entry_kind = Code::EntryKind::kNormal);
+  void BranchLinkPatchable(const Code& code,
+                           CodeEntryKind entry_kind = CodeEntryKind::kNormal);
 
   // Emit a call that shares its object pool entries with other calls
   // that have the same equivalence marker.
   void BranchLinkWithEquivalence(
       const Code& code,
       const Object& equivalence,
-      Code::EntryKind entry_kind = Code::EntryKind::kNormal);
+      CodeEntryKind entry_kind = CodeEntryKind::kNormal);
 
   // Branch and link to [base + offset]. Call sequence is never patched.
   void BranchLinkOffset(Register base, int32_t offset);
@@ -756,9 +760,13 @@
                                   Register new_pp);
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
-                       ObjectPool::Patchability patchable,
+                       ObjectPoolBuilderEntry::Patchability patchable,
                        Condition cond = AL);
   void PushObject(const Object& object);
+  void PushImmediate(int32_t immediate) {
+    LoadImmediate(TMP, immediate);
+    Push(TMP);
+  }
   void CompareObject(Register rn, const Object& object);
 
   enum CanBeSmi {
@@ -1030,12 +1038,9 @@
   // allocation stats. These are separate assembler macros so we can
   // avoid a dependent load too nearby the load of the table address.
   void LoadAllocationStatsAddress(Register dest, intptr_t cid);
-  void IncrementAllocationStats(Register stats_addr,
-                                intptr_t cid,
-                                Heap::Space space);
+  void IncrementAllocationStats(Register stats_addr, intptr_t cid);
   void IncrementAllocationStatsWithSize(Register stats_addr_reg,
-                                        Register size_reg,
-                                        Heap::Space space);
+                                        Register size_reg);
 
   Address ElementAddressForIntIndex(bool is_load,
                                     bool is_external,
@@ -1106,7 +1111,12 @@
   //   (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
   //
   // will be used during relocation to fix the offset.
-  void GenerateUnRelocatedPcRelativeCall();
+  //
+  // The provided [offset_into_target] will be added to calculate the final
+  // destination.  It can be used e.g. for calling into the middle of a
+  // function.
+  void GenerateUnRelocatedPcRelativeCall(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);
@@ -1114,7 +1124,7 @@
   // On some other platforms, we draw a distinction between safe and unsafe
   // smis.
   static bool IsSafe(const Object& object) { return true; }
-  static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
+  static bool IsSafeSmi(const Object& object) { return target::IsSmi(object); }
 
   bool constant_pool_allowed() const { return constant_pool_allowed_; }
   void set_constant_pool_allowed(bool b) { constant_pool_allowed_ = b; }
@@ -1273,10 +1283,23 @@
                              CanBeSmi can_be_smi,
                              BarrierFilterMode barrier_filter_mode);
 
+  friend class dart::FlowGraphCompiler;
+  std::function<void(Condition, Register)>
+      generate_invoke_write_barrier_wrapper_;
+  std::function<void(Condition)> generate_invoke_array_write_barrier_;
+
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
 
+}  // namespace compiler
+
+// TODO(vegorov) temporary export commonly used classes into dart namespace
+// to ease migration.
+using compiler::Address;
+using compiler::FieldAddress;
+using compiler::Operand;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_ARM_H_
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 4fb6ef4..b41c7a4 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -5,14 +5,13 @@
 #include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
 
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
 #include "vm/cpu.h"
-#include "vm/longjump.h"
-#include "vm/runtime_entry.h"
+#include "vm/instructions.h"
 #include "vm/simulator.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
 
 namespace dart {
 
@@ -22,11 +21,37 @@
 
 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");
 
-Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
+namespace compiler {
+
+#ifndef PRODUCT
+using target::ClassHeapStats;
+#endif
+using target::ClassTable;
+using target::Double;
+using target::Float32x4;
+using target::Float64x2;
+using target::Heap;
+using target::Instance;
+using target::Instructions;
+using target::Isolate;
+using target::ObjectPool;
+using target::RawObject;
+using target::Thread;
+
+Assembler::Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches)
-    : AssemblerBase(object_pool_wrapper),
+    : AssemblerBase(object_pool_builder),
       use_far_branches_(use_far_branches),
-      constant_pool_allowed_(false) {}
+      constant_pool_allowed_(false) {
+  generate_invoke_write_barrier_wrapper_ = [&](Register reg) {
+    ldr(LR, Address(THR, Thread::write_barrier_wrappers_thread_offset(reg)));
+    blr(LR);
+  };
+  generate_invoke_array_write_barrier_ = [&]() {
+    ldr(LR, Address(THR, Thread::array_write_barrier_entry_point_offset()));
+    blr(LR);
+  };
+}
 
 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
   ASSERT(Utils::IsAligned(data, 4));
@@ -217,13 +242,6 @@
   label->BindTo(bound_pc);
 }
 
-void Assembler::Stop(const char* message) {
-  if (FLAG_print_stop_message) {
-    UNIMPLEMENTED();
-  }
-  brk(Instr::kStopMessageCode);
-}
-
 static int CountLeadingZeros(uint64_t value, int width) {
   ASSERT((width == 32) || (width == 64));
   if (value == 0) {
@@ -353,7 +371,7 @@
 
 void Assembler::LoadPoolPointer(Register pp) {
   CheckCodePointer();
-  ldr(pp, FieldAddress(CODE_REG, Code::object_pool_offset()));
+  ldr(pp, FieldAddress(CODE_REG, target::Code::object_pool_offset()));
 
   // When in the PP register, the pool pointer is untagged. When we
   // push it on the stack with TagAndPushPP it is tagged again. PopAndUntagPP
@@ -446,35 +464,34 @@
 }
 
 intptr_t Assembler::FindImmediate(int64_t imm) {
-  return object_pool_wrapper().FindImmediate(imm);
+  return object_pool_builder().FindImmediate(imm);
 }
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  ASSERT(!Thread::CanLoadFromThread(object));
+  ASSERT(IsOriginalObject(object));
+  ASSERT(!target::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
   }
 
   // TODO(zra, kmillikin): Also load other large immediates from the object
   // pool
-  if (object.IsSmi()) {
-    ASSERT(Smi::IsValid(Smi::Value(reinterpret_cast<RawSmi*>(object.raw()))));
+  if (target::IsSmi(object)) {
     // If the raw smi does not fit into a 32-bit signed int, then we'll keep
     // the raw value in the object pool.
-    return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw()));
+    return !Utils::IsInt(32, target::ToRawSmi(object));
   }
-  ASSERT(object.IsNotTemporaryScopedHandle());
-  ASSERT(object.IsOld());
+  ASSERT(IsNotTemporaryScopedHandle(object));
+  ASSERT(IsInOldSpace(object));
   return true;
 }
 
-void Assembler::LoadNativeEntry(Register dst,
-                                const ExternalLabel* label,
-                                ObjectPool::Patchability patchable) {
+void Assembler::LoadNativeEntry(
+    Register dst,
+    const ExternalLabel* label,
+    ObjectPoolBuilderEntry::Patchability patchable) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindNativeFunction(label, patchable));
+      object_pool_builder().FindNativeFunction(label, patchable));
   LoadWordFromPoolOffset(dst, offset);
 }
 
@@ -485,18 +502,18 @@
 void Assembler::LoadObjectHelper(Register dst,
                                  const Object& object,
                                  bool is_unique) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
-    ldr(dst, Address(THR, Thread::OffsetFromThread(object)));
+  ASSERT(IsOriginalObject(object));
+  word offset = 0;
+  if (target::CanLoadFromThread(object, &offset)) {
+    ldr(dst, Address(THR, offset));
   } else if (CanLoadFromObjectPool(object)) {
     const int32_t offset = ObjectPool::element_offset(
-        is_unique ? object_pool_wrapper().AddObject(object)
-                  : object_pool_wrapper().FindObject(object));
+        is_unique ? object_pool_builder().AddObject(object)
+                  : object_pool_builder().FindObject(object));
     LoadWordFromPoolOffset(dst, offset);
   } else {
-    ASSERT(object.IsSmi());
-    LoadImmediate(dst, reinterpret_cast<int64_t>(object.raw()));
+    ASSERT(target::IsSmi(object));
+    LoadImmediate(dst, target::ToRawSmi(object));
   }
 }
 
@@ -505,8 +522,8 @@
                                            Register new_pp) {
   ASSERT(!constant_pool_allowed());
   ASSERT(new_pp != PP);
-  const int32_t offset =
-      ObjectPool::element_offset(object_pool_wrapper().FindObject(function));
+  const int32_t offset = ObjectPool::element_offset(
+      object_pool_builder().FindObject(ToObject(function)));
   ASSERT(Address::CanHoldOffset(offset));
   ldr(dst, Address(new_pp, offset));
 }
@@ -520,17 +537,17 @@
 }
 
 void Assembler::CompareObject(Register reg, const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
-    ldr(TMP, Address(THR, Thread::OffsetFromThread(object)));
+  ASSERT(IsOriginalObject(object));
+  word offset = 0;
+  if (target::CanLoadFromThread(object, &offset)) {
+    ldr(TMP, Address(THR, offset));
     CompareRegisters(reg, TMP);
   } else if (CanLoadFromObjectPool(object)) {
     LoadObject(TMP, object);
     CompareRegisters(reg, TMP);
   } else {
-    ASSERT(object.IsSmi());
-    CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw()));
+    ASSERT(target::IsSmi(object));
+    CompareImmediate(reg, target::ToRawSmi(object));
   }
 }
 
@@ -629,24 +646,24 @@
 
 void Assembler::Branch(const Code& target,
                        Register pp,
-                       ObjectPool::Patchability patchable) {
+                       ObjectPoolBuilderEntry::Patchability patchable) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindObject(target, patchable));
+      object_pool_builder().FindObject(ToObject(target), patchable));
   LoadWordFromPoolOffset(CODE_REG, offset, pp);
-  ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  ldr(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   br(TMP);
 }
 
 void Assembler::BranchPatchable(const Code& code) {
-  Branch(code, PP, ObjectPool::kPatchable);
+  Branch(code, PP, ObjectPoolBuilderEntry::kPatchable);
 }
 
 void Assembler::BranchLink(const Code& target,
-                           ObjectPool::Patchability patchable) {
+                           ObjectPoolBuilderEntry::Patchability patchable) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindObject(target, patchable));
+      object_pool_builder().FindObject(ToObject(target), patchable));
   LoadWordFromPoolOffset(CODE_REG, offset);
-  ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  ldr(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   blr(TMP);
 }
 
@@ -658,9 +675,9 @@
 void Assembler::BranchLinkWithEquivalence(const Code& target,
                                           const Object& equivalence) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindObject(target, equivalence));
+      object_pool_builder().FindObject(ToObject(target), equivalence));
   LoadWordFromPoolOffset(CODE_REG, offset);
-  ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  ldr(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   blr(TMP);
 }
 
@@ -917,8 +934,9 @@
                                       Label* label,
                                       CanBeSmi value_can_be_smi,
                                       BarrierFilterMode how_to_jump) {
-  COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
-                 (kOldObjectAlignmentOffset == 0));
+  COMPILE_ASSERT((target::ObjectAlignment::kNewObjectAlignmentOffset ==
+                  target::kWordSize) &&
+                 (target::ObjectAlignment::kOldObjectAlignmentOffset == 0));
 
   // Write-barrier triggers if the value is in the new space (has bit set) and
   // the object is in the old space (has bit cleared).
@@ -935,14 +953,15 @@
   } else {
     // For the value we are only interested in the new/old bit and the tag bit.
     // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
-    and_(TMP, value, Operand(value, LSL, kNewObjectBitPosition));
+    and_(TMP, value,
+         Operand(value, LSL, target::ObjectAlignment::kNewObjectBitPosition));
     // And the result with the negated space bit of the object.
     bic(TMP, TMP, Operand(object));
   }
   if (how_to_jump == kJumpToNoUpdate) {
-    tbz(label, TMP, kNewObjectBitPosition);
+    tbz(label, TMP, target::ObjectAlignment::kNewObjectBitPosition);
   } else {
-    tbnz(label, TMP, kNewObjectBitPosition);
+    tbnz(label, TMP, target::ObjectAlignment::kNewObjectBitPosition);
   }
 }
 
@@ -987,8 +1006,8 @@
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
   }
-  ldr(TMP, FieldAddress(object, Object::tags_offset()), kUnsignedByte);
-  ldr(TMP2, FieldAddress(value, Object::tags_offset()), kUnsignedByte);
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
+  ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
   and_(TMP, TMP2, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
   tst(TMP, Operand(BARRIER_MASK));
   b(&done, ZERO);
@@ -1009,8 +1028,9 @@
     }
     mov(kWriteBarrierValueReg, value);
   }
-  ldr(LR, Address(THR, Thread::write_barrier_wrappers_offset(objectForCall)));
-  blr(LR);
+
+  generate_invoke_write_barrier_wrapper_(objectForCall);
+
   if (value != kWriteBarrierValueReg) {
     if (object != kWriteBarrierValueReg) {
       Pop(kWriteBarrierValueReg);
@@ -1047,8 +1067,8 @@
   if (can_be_smi == kValueCanBeSmi) {
     BranchIfSmi(value, &done);
   }
-  ldr(TMP, FieldAddress(object, Object::tags_offset()), kUnsignedByte);
-  ldr(TMP2, FieldAddress(value, Object::tags_offset()), kUnsignedByte);
+  ldr(TMP, FieldAddress(object, target::Object::tags_offset()), kUnsignedByte);
+  ldr(TMP2, FieldAddress(value, target::Object::tags_offset()), kUnsignedByte);
   and_(TMP, TMP2, Operand(TMP, LSR, RawObject::kBarrierOverlapShift));
   tst(TMP, Operand(BARRIER_MASK));
   b(&done, ZERO);
@@ -1061,10 +1081,7 @@
     // allocator.
     UNIMPLEMENTED();
   }
-
-  ldr(LR, Address(THR, Thread::array_write_barrier_entry_point_offset()));
-  blr(LR);
-
+  generate_invoke_array_write_barrier_();
   if (!lr_reserved) Pop(LR);
   Bind(&done);
 }
@@ -1096,10 +1113,8 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
-  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
-  ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
-  ASSERT(value.IsSmi() || value.InVMHeap() ||
-         (value.IsOld() && value.IsNotTemporaryScopedHandle()));
+  ASSERT(IsOriginalObject(value));
+  ASSERT(IsNotTemporaryScopedHandle(value));
   // No store buffer update.
   LoadObject(TMP2, value);
   str(TMP2, dest);
@@ -1120,7 +1135,7 @@
   ASSERT(RawObject::kClassIdTagPos == 16);
   ASSERT(RawObject::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
-      Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
+      target::Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
   LoadFromOffset(result, object, class_id_offset - kHeapObjectTag,
                  kUnsignedHalfword);
 }
@@ -1131,7 +1146,7 @@
   const intptr_t offset =
       Isolate::class_table_offset() + ClassTable::table_offset();
   LoadFromOffset(result, result, offset);
-  ASSERT(kSizeOfClassPairLog2 == 4);
+  ASSERT(ClassTable::kSizeOfClassPairLog2 == 4);
   add(class_id, class_id, Operand(class_id));
   ldr(result, Address(result, class_id, UXTX, Address::Scaled));
 }
@@ -1172,7 +1187,8 @@
 }
 
 void Assembler::RestoreCodePointer() {
-  ldr(CODE_REG, Address(FP, compiler_frame_layout.code_from_fp * kWordSize));
+  ldr(CODE_REG, Address(FP, compiler::target::frame_layout.code_from_fp *
+                                target::kWordSize));
   CheckCodePointer();
 }
 
@@ -1192,7 +1208,7 @@
   const intptr_t entry_offset =
       CodeSize() + Instructions::HeaderSize() - kHeapObjectTag;
   adr(R0, Immediate(-entry_offset));
-  ldr(TMP, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
+  ldr(TMP, FieldAddress(CODE_REG, target::Code::saved_instructions_offset()));
   cmp(R0, Operand(TMP));
   b(&instructions_ok, EQ);
   brk(1);
@@ -1291,7 +1307,8 @@
     if (restore_pp == kRestoreCallerPP) {
       // Restore and untag PP.
       LoadFromOffset(PP, FP,
-                     compiler_frame_layout.saved_caller_pp_from_fp * kWordSize);
+                     compiler::target::frame_layout.saved_caller_pp_from_fp *
+                         target::kWordSize);
       sub(PP, PP, Operand(kHeapObjectTag));
     }
   }
@@ -1329,10 +1346,10 @@
   // and ensure proper alignment of the stack frame.
   // We need to restore it before restoring registers.
   const intptr_t kPushedRegistersSize =
-      kDartVolatileCpuRegCount * kWordSize +
-      kDartVolatileFpuRegCount * kWordSize +
-      (compiler_frame_layout.dart_fixed_frame_size - 2) *
-          kWordSize;  // From EnterStubFrame (excluding PC / FP)
+      kDartVolatileCpuRegCount * target::kWordSize +
+      kDartVolatileFpuRegCount * target::kWordSize +
+      (compiler::target::frame_layout.dart_fixed_frame_size - 2) *
+          target::kWordSize;  // From EnterStubFrame (excluding PC / FP)
   AddImmediate(SP, FP, -kPushedRegistersSize);
   for (int i = kDartLastVolatileCpuReg; i >= kDartFirstVolatileCpuReg; i--) {
     const Register reg = static_cast<Register>(i);
@@ -1407,10 +1424,9 @@
   b(trace, NE);
 }
 
-void Assembler::UpdateAllocationStats(intptr_t cid, Heap::Space space) {
+void Assembler::UpdateAllocationStats(intptr_t cid) {
   ASSERT(cid > 0);
-  intptr_t counter_offset =
-      ClassTable::CounterOffsetFor(cid, space == Heap::kNew);
+  intptr_t counter_offset = ClassTable::CounterOffsetFor(cid, /*is_new=*/true);
   LoadIsolate(TMP2);
   intptr_t table_offset =
       Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
@@ -1421,19 +1437,13 @@
   str(TMP, Address(TMP2, 0));
 }
 
-void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
-                                              Register size_reg,
-                                              Heap::Space space) {
+void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, Register size_reg) {
   ASSERT(cid > 0);
   const uword class_offset = ClassTable::ClassOffsetFor(cid);
   const uword count_field_offset =
-      (space == Heap::kNew)
-          ? ClassHeapStats::allocated_since_gc_new_space_offset()
-          : ClassHeapStats::allocated_since_gc_old_space_offset();
+      ClassHeapStats::allocated_since_gc_new_space_offset();
   const uword size_field_offset =
-      (space == Heap::kNew)
-          ? ClassHeapStats::allocated_size_since_gc_new_space_offset()
-          : ClassHeapStats::allocated_size_since_gc_old_space_offset();
+      ClassHeapStats::allocated_size_since_gc_new_space_offset();
   LoadIsolate(TMP2);
   intptr_t table_offset =
       Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
@@ -1454,18 +1464,19 @@
                             Register top_reg,
                             bool tag_result) {
   ASSERT(failure != NULL);
-  const intptr_t instance_size = cls.instance_size();
+  const intptr_t instance_size = target::Class::GetInstanceSize(cls);
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(
-        MaybeTraceAllocation(cls.id(), /*temp_reg=*/top_reg, failure));
+    const classid_t cid = target::Class::GetId(cls);
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, /*temp_reg=*/top_reg, failure));
 
     const Register kEndReg = TMP;
 
     // instance_reg: potential next object start.
-    RELEASE_ASSERT((Thread::top_offset() + kWordSize) == Thread::end_offset());
+    RELEASE_ASSERT((Thread::top_offset() + target::kWordSize) ==
+                   Thread::end_offset());
     ldp(instance_reg, kEndReg,
         Address(THR, Thread::top_offset(), Address::PairOffset));
 
@@ -1478,18 +1489,14 @@
     // next object start and store the class in the class field of object.
     str(top_reg, Address(THR, Thread::top_offset()));
 
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    NOT_IN_PRODUCT(UpdateAllocationStats(cls.id(), space));
+    NOT_IN_PRODUCT(UpdateAllocationStats(cid));
 
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
     // Extends the 32 bit tags with zeros, which is the uninitialized
     // hash code.
     LoadImmediate(TMP, tags);
-    StoreToOffset(TMP, instance_reg, Object::tags_offset());
+    StoreToOffset(TMP, instance_reg, target::Object::tags_offset());
 
     if (tag_result) {
       AddImmediate(instance_reg, kHeapObjectTag);
@@ -1511,7 +1518,6 @@
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
     NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp1, failure));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
     // Potential new object start.
     ldr(instance, Address(THR, Thread::top_offset()));
     AddImmediateSetFlags(end_address, instance, instance_size);
@@ -1529,26 +1535,28 @@
     str(end_address, Address(THR, Thread::top_offset()));
     add(instance, instance, Operand(kHeapObjectTag));
     LoadImmediate(temp2, instance_size);
-    NOT_IN_PRODUCT(UpdateAllocationStatsWithSize(cid, temp2, space));
+    NOT_IN_PRODUCT(UpdateAllocationStatsWithSize(cid, temp2));
 
     // Initialize the tags.
     // instance: new object start as a tagged pointer.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
     // Extends the 32 bit tags with zeros, which is the uninitialized
     // hash code.
     LoadImmediate(temp2, tags);
-    str(temp2, FieldAddress(instance, Array::tags_offset()));  // Store tags.
+    str(temp2, FieldAddress(instance, target::Object::tags_offset()));
   } else {
     b(failure);
   }
 }
 
-void Assembler::GenerateUnRelocatedPcRelativeCall() {
+void Assembler::GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target) {
   // Emit "bl <offset>".
-  EmitUnconditionalBranchOp(BL, 0x686868);
+  EmitUnconditionalBranchOp(BL, 0);
+
+  PcRelativeCallPattern pattern(buffer_.contents() + buffer_.Size() -
+                                PcRelativeCallPattern::kLengthInBytes);
+  pattern.set_distance(offset_into_target);
 }
 
 Address Assembler::ElementAddressForIntIndex(bool is_external,
@@ -1765,6 +1773,8 @@
   }
 }
 
+}  // namespace compiler
+
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 4d3d69a..da5466b 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -9,20 +9,24 @@
 #error Do not include assembler_arm64.h directly; use assembler.h instead.
 #endif
 
+#include <functional>
+
 #include "platform/assert.h"
 #include "platform/utils.h"
+#include "vm/class_id.h"
 #include "vm/constants_arm64.h"
 #include "vm/hash_map.h"
-#include "vm/longjump.h"
-#include "vm/object.h"
 #include "vm/simulator.h"
 
 namespace dart {
 
 // Forward declarations.
+class FlowGraphCompiler;
 class RuntimeEntry;
 class RegisterSet;
 
+namespace compiler {
+
 class Immediate : public ValueObject {
  public:
   explicit Immediate(int64_t value) : value_(value) {}
@@ -424,7 +428,7 @@
 
 class Assembler : public AssemblerBase {
  public:
-  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+  explicit Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches = false);
   ~Assembler() {}
 
@@ -443,7 +447,7 @@
   void Drop(intptr_t stack_elements) {
     ASSERT(stack_elements >= 0);
     if (stack_elements > 0) {
-      add(SP, SP, Operand(stack_elements * kWordSize));
+      add(SP, SP, Operand(stack_elements * target::kWordSize));
     }
   }
 
@@ -495,7 +499,7 @@
   // On some other platforms, we draw a distinction between safe and unsafe
   // smis.
   static bool IsSafe(const Object& object) { return true; }
-  static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
+  static bool IsSafeSmi(const Object& object) { return target::IsSmi(object); }
 
   // Addition and subtraction.
   // For add and sub, to use CSP for rn, o must be of type Operand::Extend.
@@ -1254,19 +1258,19 @@
   }
   void Push(Register reg) {
     ASSERT(reg != PP);  // Only push PP with TagAndPushPP().
-    str(reg, Address(SP, -1 * kWordSize, Address::PreIndex));
+    str(reg, Address(SP, -1 * target::kWordSize, Address::PreIndex));
   }
   void Pop(Register reg) {
     ASSERT(reg != PP);  // Only pop PP with PopAndUntagPP().
-    ldr(reg, Address(SP, 1 * kWordSize, Address::PostIndex));
+    ldr(reg, Address(SP, 1 * target::kWordSize, Address::PostIndex));
   }
   void PushPair(Register low, Register high) {
     ASSERT((low != PP) && (high != PP));
-    stp(low, high, Address(SP, -2 * kWordSize, Address::PairPreIndex));
+    stp(low, high, Address(SP, -2 * target::kWordSize, Address::PairPreIndex));
   }
   void PopPair(Register low, Register high) {
     ASSERT((low != PP) && (high != PP));
-    ldp(low, high, Address(SP, 2 * kWordSize, Address::PairPostIndex));
+    ldp(low, high, Address(SP, 2 * target::kWordSize, Address::PairPostIndex));
   }
   void PushFloat(VRegister reg) {
     fstrs(reg, Address(SP, -1 * kFloatSize, Address::PreIndex));
@@ -1289,16 +1293,17 @@
   void TagAndPushPP() {
     // Add the heap object tag back to PP before putting it on the stack.
     add(TMP, PP, Operand(kHeapObjectTag));
-    str(TMP, Address(SP, -1 * kWordSize, Address::PreIndex));
+    str(TMP, Address(SP, -1 * target::kWordSize, Address::PreIndex));
   }
   void TagAndPushPPAndPcMarker() {
     COMPILE_ASSERT(CODE_REG != TMP2);
     // Add the heap object tag back to PP before putting it on the stack.
     add(TMP2, PP, Operand(kHeapObjectTag));
-    stp(TMP2, CODE_REG, Address(SP, -2 * kWordSize, Address::PairPreIndex));
+    stp(TMP2, CODE_REG,
+        Address(SP, -2 * target::kWordSize, Address::PairPreIndex));
   }
   void PopAndUntagPP() {
-    ldr(PP, Address(SP, 1 * kWordSize, Address::PostIndex));
+    ldr(PP, Address(SP, 1 * target::kWordSize, Address::PostIndex));
     sub(PP, PP, Operand(kHeapObjectTag));
     // The caller of PopAndUntagPP() must explicitly allow use of popped PP.
     set_constant_pool_allowed(false);
@@ -1351,15 +1356,16 @@
 
   void Branch(const Code& code,
               Register pp,
-              ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
+              ObjectPoolBuilderEntry::Patchability patchable =
+                  ObjectPoolBuilderEntry::kNotPatchable);
   void BranchPatchable(const Code& code);
 
-  void BranchLink(
-      const Code& code,
-      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
+  void BranchLink(const Code& code,
+                  ObjectPoolBuilderEntry::Patchability patchable =
+                      ObjectPoolBuilderEntry::kNotPatchable);
 
   void BranchLinkPatchable(const Code& code) {
-    BranchLink(code, ObjectPool::kPatchable);
+    BranchLink(code, ObjectPoolBuilderEntry::kPatchable);
   }
   void BranchLinkToRuntime();
 
@@ -1479,7 +1485,7 @@
   bool CanLoadFromObjectPool(const Object& object) const;
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
-                       ObjectPool::Patchability patchable);
+                       ObjectPoolBuilderEntry::Patchability patchable);
   void LoadFunctionFromCalleePool(Register dst,
                                   const Function& function,
                                   Register new_pp);
@@ -1500,6 +1506,10 @@
     LoadObject(TMP, object);
     Push(TMP);
   }
+  void PushImmediate(int64_t immediate) {
+    LoadImmediate(TMP, immediate);
+    Push(TMP);
+  }
   void CompareObject(Register reg, const Object& object);
 
   void LoadClassId(Register result, Register object);
@@ -1536,11 +1546,9 @@
 
   void MonomorphicCheckedEntry();
 
-  void UpdateAllocationStats(intptr_t cid, Heap::Space space);
+  void UpdateAllocationStats(intptr_t cid);
 
-  void UpdateAllocationStatsWithSize(intptr_t cid,
-                                     Register size_reg,
-                                     Heap::Space space);
+  void UpdateAllocationStatsWithSize(intptr_t cid, Register size_reg);
 
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
@@ -1578,7 +1586,11 @@
   //   (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
   //
   // will be used during relocation to fix the offset.
-  void GenerateUnRelocatedPcRelativeCall();
+  //
+  // The provided [offset_into_target] will be added to calculate the final
+  // destination.  It can be used e.g. for calling into the middle of a
+  // function.
+  void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target = 0);
 
   Address ElementAddressForIntIndex(bool is_external,
                                     intptr_t cid,
@@ -1755,8 +1767,7 @@
   int32_t EncodeImm19BranchOffset(int64_t imm, int32_t instr) {
     if (!CanEncodeImm19BranchOffset(imm)) {
       ASSERT(!use_far_branches());
-      Thread::Current()->long_jump_base()->Jump(1,
-                                                Object::branch_offset_error());
+      BailoutWithBranchOffsetError();
     }
     const int32_t imm32 = static_cast<int32_t>(imm);
     const int32_t off = (((imm32 >> 2) << kImm19Shift) & kImm19Mask);
@@ -1771,8 +1782,7 @@
   int32_t EncodeImm14BranchOffset(int64_t imm, int32_t instr) {
     if (!CanEncodeImm14BranchOffset(imm)) {
       ASSERT(!use_far_branches());
-      Thread::Current()->long_jump_base()->Jump(1,
-                                                Object::branch_offset_error());
+      BailoutWithBranchOffsetError();
     }
     const int32_t imm32 = static_cast<int32_t>(imm);
     const int32_t off = (((imm32 >> 2) << kImm14Shift) & kImm14Mask);
@@ -2233,10 +2243,21 @@
                              CanBeSmi can_be_smi,
                              BarrierFilterMode barrier_filter_mode);
 
+  friend class dart::FlowGraphCompiler;
+  std::function<void(Register reg)> generate_invoke_write_barrier_wrapper_;
+  std::function<void()> generate_invoke_array_write_barrier_;
+
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
 
+}  // namespace compiler
+
+using compiler::Address;
+using compiler::FieldAddress;
+using compiler::Immediate;
+using compiler::Operand;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_ARM64_H_
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index e3625d0..2817361 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -12,7 +12,7 @@
 #include "vm/virtual_memory.h"
 
 namespace dart {
-
+namespace compiler {
 #define __ assembler->
 
 ASSEMBLER_TEST_GENERATE(Simple, assembler) {
@@ -339,12 +339,13 @@
 ASSEMBLER_TEST_GENERATE(SimpleLoadStore, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(2 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ movz(R0, Immediate(43), 0);
   __ movz(R1, Immediate(42), 0);
-  __ str(R1, Address(SP, -1 * kWordSize, Address::PreIndex));
-  __ ldr(R0, Address(SP, 1 * kWordSize, Address::PostIndex));
+  __ str(R1, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+  __ ldr(R0, Address(SP, 1 * target::kWordSize, Address::PostIndex));
   __ RestoreCSP();
   __ ret();
 }
@@ -373,16 +374,17 @@
 ASSEMBLER_TEST_GENERATE(LoadStoreLargeIndex, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(32 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(32 * target::kWordSize));  // Must not access beyond CSP.
 
   __ movz(R0, Immediate(43), 0);
   __ movz(R1, Immediate(42), 0);
   // Largest negative offset that can fit in the signed 9-bit immediate field.
-  __ str(R1, Address(SP, -32 * kWordSize, Address::PreIndex));
+  __ str(R1, Address(SP, -32 * target::kWordSize, Address::PreIndex));
   // Largest positive kWordSize aligned offset that we can fit.
-  __ ldr(R0, Address(SP, 31 * kWordSize, Address::PostIndex));
+  __ ldr(R0, Address(SP, 31 * target::kWordSize, Address::PostIndex));
   // Correction.
-  __ add(SP, SP, Operand(kWordSize));  // Restore SP.
+  __ add(SP, SP, Operand(target::kWordSize));  // Restore SP.
   __ RestoreCSP();
   __ ret();
 }
@@ -396,10 +398,10 @@
   __ SetupDartSP();
   __ movz(R0, Immediate(43), 0);
   __ movz(R1, Immediate(42), 0);
-  __ sub(SP, SP, Operand(512 * kWordSize));
+  __ sub(SP, SP, Operand(512 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
-  __ str(R1, Address(SP, 512 * kWordSize, Address::Offset));
-  __ add(SP, SP, Operand(512 * kWordSize));
+  __ str(R1, Address(SP, 512 * target::kWordSize, Address::Offset));
+  __ add(SP, SP, Operand(512 * target::kWordSize));
   __ ldr(R0, Address(SP));
   __ RestoreCSP();
   __ ret();
@@ -419,10 +421,10 @@
   // This should sign extend R2, and add to SP to get address,
   // i.e. SP - kWordSize.
   __ str(R1, Address(SP, R2, SXTW));
-  __ sub(SP, SP, Operand(kWordSize));
+  __ sub(SP, SP, Operand(target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
   __ ldr(R0, Address(SP));
-  __ add(SP, SP, Operand(kWordSize));
+  __ add(SP, SP, Operand(target::kWordSize));
   __ RestoreCSP();
   __ ret();
 }
@@ -437,12 +439,12 @@
   __ movz(R0, Immediate(43), 0);
   __ movz(R1, Immediate(42), 0);
   __ movz(R2, Immediate(10), 0);
-  __ sub(SP, SP, Operand(10 * kWordSize));
+  __ sub(SP, SP, Operand(10 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
   // Store R1 into SP + R2 * kWordSize.
   __ str(R1, Address(SP, R2, UXTX, Address::Scaled));
   __ ldr(R0, Address(SP, R2, UXTX, Address::Scaled));
-  __ add(SP, SP, Operand(10 * kWordSize));
+  __ add(SP, SP, Operand(10 * target::kWordSize));
   __ RestoreCSP();
   __ ret();
 }
@@ -455,7 +457,8 @@
 ASSEMBLER_TEST_GENERATE(LoadSigned32Bit, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(2 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadImmediate(R1, 0xffffffff);
   __ str(R1, Address(SP, -4, Address::PreIndex, kWord), kWord);
@@ -473,12 +476,13 @@
 ASSEMBLER_TEST_GENERATE(SimpleLoadStorePair, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(2 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadImmediate(R2, 43);
   __ LoadImmediate(R3, 42);
-  __ stp(R2, R3, Address(SP, -2 * kWordSize, Address::PairPreIndex));
-  __ ldp(R0, R1, Address(SP, 2 * kWordSize, Address::PairPostIndex));
+  __ stp(R2, R3, Address(SP, -2 * target::kWordSize, Address::PairPreIndex));
+  __ ldp(R0, R1, Address(SP, 2 * target::kWordSize, Address::PairPostIndex));
   __ sub(R0, R0, Operand(R1));
   __ RestoreCSP();
   __ ret();
@@ -493,11 +497,11 @@
   __ SetupDartSP();
   __ LoadImmediate(R2, 43);
   __ LoadImmediate(R3, 42);
-  __ sub(SP, SP, Operand(4 * kWordSize));
+  __ sub(SP, SP, Operand(4 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
-  __ stp(R2, R3, Address::Pair(SP, 2 * kWordSize));
-  __ ldp(R0, R1, Address::Pair(SP, 2 * kWordSize));
-  __ add(SP, SP, Operand(4 * kWordSize));
+  __ stp(R2, R3, Address::Pair(SP, 2 * target::kWordSize));
+  __ ldp(R0, R1, Address::Pair(SP, 2 * target::kWordSize));
+  __ add(SP, SP, Operand(4 * target::kWordSize));
   __ sub(R0, R0, Operand(R1));
   __ RestoreCSP();
   __ ret();
@@ -2520,11 +2524,12 @@
 ASSEMBLER_TEST_GENERATE(FldrdFstrdPrePostIndex, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(2 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadDImmediate(V1, 42.0);
-  __ fstrd(V1, Address(SP, -1 * kWordSize, Address::PreIndex));
-  __ fldrd(V0, Address(SP, 1 * kWordSize, Address::PostIndex));
+  __ fstrd(V1, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+  __ fldrd(V0, Address(SP, 1 * target::kWordSize, Address::PostIndex));
   __ RestoreCSP();
   __ ret();
 }
@@ -2537,12 +2542,13 @@
 ASSEMBLER_TEST_GENERATE(FldrsFstrsPrePostIndex, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(2 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadDImmediate(V1, 42.0);
   __ fcvtsd(V2, V1);
-  __ fstrs(V2, Address(SP, -1 * kWordSize, Address::PreIndex));
-  __ fldrs(V3, Address(SP, 1 * kWordSize, Address::PostIndex));
+  __ fstrs(V2, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+  __ fldrs(V3, Address(SP, 1 * target::kWordSize, Address::PostIndex));
   __ fcvtds(V0, V3);
   __ RestoreCSP();
   __ ret();
@@ -2556,7 +2562,8 @@
 ASSEMBLER_TEST_GENERATE(FldrqFstrqPrePostIndex, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(2 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(2 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadDImmediate(V1, 21.0);
   __ LoadDImmediate(V2, 21.0);
@@ -2564,9 +2571,9 @@
   __ Push(R1);
   __ PushDouble(V1);
   __ PushDouble(V2);
-  __ fldrq(V3, Address(SP, 2 * kWordSize, Address::PostIndex));
+  __ fldrq(V3, Address(SP, 2 * target::kWordSize, Address::PostIndex));
   __ Pop(R0);
-  __ fstrq(V3, Address(SP, -2 * kWordSize, Address::PreIndex));
+  __ fstrq(V3, Address(SP, -2 * target::kWordSize, Address::PreIndex));
   __ PopDouble(V0);
   __ PopDouble(V1);
   __ faddd(V0, V0, V1);
@@ -2720,11 +2727,11 @@
   __ SetupDartSP();
   __ LoadDImmediate(V0, 43.0);
   __ LoadDImmediate(V1, 42.0);
-  __ AddImmediate(SP, SP, -1 * kWordSize);
+  __ AddImmediate(SP, SP, -1 * target::kWordSize);
   __ add(R2, SP, Operand(1));
   __ fstrd(V1, Address(R2, -1));
   __ fldrd(V0, Address(R2, -1));
-  __ AddImmediate(SP, 1 * kWordSize);
+  __ AddImmediate(SP, 1 * target::kWordSize);
   __ RestoreCSP();
   __ ret();
 }
@@ -2737,16 +2744,17 @@
 ASSEMBLER_TEST_GENERATE(FldrdFstrdLargeIndex, assembler) {
   __ SetupDartSP();
 
-  __ sub(CSP, CSP, Operand(32 * kWordSize));  // Must not access beyond CSP.
+  __ sub(CSP, CSP,
+         Operand(32 * target::kWordSize));  // Must not access beyond CSP.
 
   __ LoadDImmediate(V0, 43.0);
   __ LoadDImmediate(V1, 42.0);
   // Largest negative offset that can fit in the signed 9-bit immediate field.
-  __ fstrd(V1, Address(SP, -32 * kWordSize, Address::PreIndex));
+  __ fstrd(V1, Address(SP, -32 * target::kWordSize, Address::PreIndex));
   // Largest positive kWordSize aligned offset that we can fit.
-  __ fldrd(V0, Address(SP, 31 * kWordSize, Address::PostIndex));
+  __ fldrd(V0, Address(SP, 31 * target::kWordSize, Address::PostIndex));
   // Correction.
-  __ add(SP, SP, Operand(kWordSize));  // Restore SP.
+  __ add(SP, SP, Operand(target::kWordSize));  // Restore SP.
   __ RestoreCSP();
   __ ret();
 }
@@ -2760,10 +2768,10 @@
   __ SetupDartSP();
   __ LoadDImmediate(V0, 43.0);
   __ LoadDImmediate(V1, 42.0);
-  __ sub(SP, SP, Operand(512 * kWordSize));
+  __ sub(SP, SP, Operand(512 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
-  __ fstrd(V1, Address(SP, 512 * kWordSize, Address::Offset));
-  __ add(SP, SP, Operand(512 * kWordSize));
+  __ fstrd(V1, Address(SP, 512 * target::kWordSize, Address::Offset));
+  __ add(SP, SP, Operand(512 * target::kWordSize));
   __ fldrd(V0, Address(SP));
   __ RestoreCSP();
   __ ret();
@@ -2783,10 +2791,10 @@
   // This should sign extend R2, and add to SP to get address,
   // i.e. SP - kWordSize.
   __ fstrd(V1, Address(SP, R2, SXTW));
-  __ sub(SP, SP, Operand(kWordSize));
+  __ sub(SP, SP, Operand(target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
   __ fldrd(V0, Address(SP));
-  __ add(SP, SP, Operand(kWordSize));
+  __ add(SP, SP, Operand(target::kWordSize));
   __ RestoreCSP();
   __ ret();
 }
@@ -2801,12 +2809,12 @@
   __ LoadDImmediate(V0, 43.0);
   __ LoadDImmediate(V1, 42.0);
   __ movz(R2, Immediate(10), 0);
-  __ sub(SP, SP, Operand(10 * kWordSize));
+  __ sub(SP, SP, Operand(10 * target::kWordSize));
   __ andi(CSP, SP, Immediate(~15));  // Must not access beyond CSP.
   // Store V1 into SP + R2 * kWordSize.
   __ fstrd(V1, Address(SP, R2, UXTX, Address::Scaled));
   __ fldrd(V0, Address(SP, R2, UXTX, Address::Scaled));
-  __ add(SP, SP, Operand(10 * kWordSize));
+  __ add(SP, SP, Operand(10 * target::kWordSize));
   __ RestoreCSP();
   __ ret();
 }
@@ -4107,6 +4115,7 @@
   __ ret();
 }
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/compiler/assembler/assembler_arm_test.cc b/runtime/vm/compiler/assembler/assembler_arm_test.cc
index 2809d58..4e69f74 100644
--- a/runtime/vm/compiler/assembler/assembler_arm_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm_test.cc
@@ -12,6 +12,7 @@
 #include "vm/virtual_memory.h"
 
 namespace dart {
+namespace compiler {
 
 #define __ assembler->
 
@@ -262,11 +263,11 @@
   if (TargetCPUFeatures::vfp_supported()) {
     __ LoadImmediate(R0, bit_cast<int32_t, float>(12.3f));
     __ mov(R2, Operand(SP));
-    __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex));
-    __ vldrs(S0, Address(R2, (-kWordSize * 30)));
+    __ str(R0, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+    __ vldrs(S0, Address(R2, (-target::kWordSize * 30)));
     __ vadds(S0, S0, S0);
-    __ vstrs(S0, Address(R2, (-kWordSize * 30)));
-    __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex));
+    __ vstrs(S0, Address(R2, (-target::kWordSize * 30)));
+    __ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   }
   __ bx(LR);
 }
@@ -286,11 +287,11 @@
     __ mov(R2, Operand(SP));
     // Expressing __str(R0, Address(SP, (-kWordSize * 32), Address::PreIndex));
     // as:
-    __ mov(R1, Operand(kWordSize));
+    __ mov(R1, Operand(target::kWordSize));
     __ str(R0, Address(SP, R1, LSL, 5, Address::NegPreIndex));
-    __ vldrs(S0, Address(R2, (-kWordSize * 32)));
+    __ vldrs(S0, Address(R2, (-target::kWordSize * 32)));
     __ vadds(S0, S0, S0);
-    __ vstrs(S0, Address(R2, (-kWordSize * 32)));
+    __ vstrs(S0, Address(R2, (-target::kWordSize * 32)));
     // Expressing __ldr(R0, Address(SP, (kWordSize * 32), Address::PostIndex));
     // as:
     __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex));
@@ -313,13 +314,13 @@
     __ LoadImmediate(R0, Utils::Low32Bits(value));
     __ LoadImmediate(R1, Utils::High32Bits(value));
     __ mov(R2, Operand(SP));
-    __ str(R0, Address(SP, (-kWordSize * 30), Address::PreIndex));
-    __ str(R1, Address(R2, (-kWordSize * 29)));
-    __ vldrd(D0, Address(R2, (-kWordSize * 30)));
+    __ str(R0, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+    __ str(R1, Address(R2, (-target::kWordSize * 29)));
+    __ vldrd(D0, Address(R2, (-target::kWordSize * 30)));
     __ vaddd(D0, D0, D0);
-    __ vstrd(D0, Address(R2, (-kWordSize * 30)));
-    __ ldr(R1, Address(R2, (-kWordSize * 29)));
-    __ ldr(R0, Address(SP, (kWordSize * 30), Address::PostIndex));
+    __ vstrd(D0, Address(R2, (-target::kWordSize * 30)));
+    __ ldr(R1, Address(R2, (-target::kWordSize * 29)));
+    __ ldr(R0, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   }
   __ bx(LR);
 }
@@ -1082,8 +1083,8 @@
 
   __ mov(R1, Operand(0x11));
   __ mov(R2, Operand(SP));
-  __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
-  __ ldrh(R0, Address(R2, (-kWordSize * 30)));
+  __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+  __ ldrh(R0, Address(R2, (-target::kWordSize * 30)));
   __ cmp(R0, Operand(0x11));
   __ b(&Test1, EQ);
   __ mov(R0, Operand(1));
@@ -1091,8 +1092,8 @@
   __ Bind(&Test1);
 
   __ mov(R0, Operand(0x22));
-  __ strh(R0, Address(R2, (-kWordSize * 30)));
-  __ ldrh(R1, Address(R2, (-kWordSize * 30)));
+  __ strh(R0, Address(R2, (-target::kWordSize * 30)));
+  __ ldrh(R1, Address(R2, (-target::kWordSize * 30)));
   __ cmp(R1, Operand(0x22));
   __ b(&Test2, EQ);
   __ mov(R0, Operand(1));
@@ -1100,7 +1101,7 @@
   __ Bind(&Test2);
 
   __ mov(R0, Operand(0));
-  __ AddImmediate(R2, (-kWordSize * 30));
+  __ AddImmediate(R2, (-target::kWordSize * 30));
   __ strh(R0, Address(R2));
   __ ldrh(R1, Address(R2));
   __ cmp(R1, Operand(0));
@@ -1111,7 +1112,7 @@
 
   __ mov(R0, Operand(0));
   __ Bind(&Done);
-  __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
+  __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   __ bx(LR);
 }
 
@@ -1124,9 +1125,9 @@
 ASSEMBLER_TEST_GENERATE(Ldrsb, assembler) {
   __ mov(R1, Operand(0xFF));
   __ mov(R2, Operand(SP));
-  __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
-  __ ldrsb(R0, Address(R2, (-kWordSize * 30)));
-  __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
+  __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+  __ ldrsb(R0, Address(R2, (-target::kWordSize * 30)));
+  __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   __ bx(LR);
 }
 
@@ -1139,9 +1140,9 @@
 ASSEMBLER_TEST_GENERATE(Ldrb, assembler) {
   __ mov(R1, Operand(0xFF));
   __ mov(R2, Operand(SP));
-  __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
-  __ ldrb(R0, Address(R2, (-kWordSize * 30)));
-  __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
+  __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+  __ ldrb(R0, Address(R2, (-target::kWordSize * 30)));
+  __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   __ bx(LR);
 }
 
@@ -1154,9 +1155,9 @@
 ASSEMBLER_TEST_GENERATE(Ldrsh, assembler) {
   __ mov(R1, Operand(0xFF));
   __ mov(R2, Operand(SP));
-  __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
-  __ ldrsh(R0, Address(R2, (-kWordSize * 30)));
-  __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
+  __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+  __ ldrsh(R0, Address(R2, (-target::kWordSize * 30)));
+  __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   __ bx(LR);
 }
 
@@ -1169,9 +1170,9 @@
 ASSEMBLER_TEST_GENERATE(Ldrh1, assembler) {
   __ mov(R1, Operand(0xFF));
   __ mov(R2, Operand(SP));
-  __ str(R1, Address(SP, (-kWordSize * 30), Address::PreIndex));
-  __ ldrh(R0, Address(R2, (-kWordSize * 30)));
-  __ ldr(R1, Address(SP, (kWordSize * 30), Address::PostIndex));
+  __ str(R1, Address(SP, (-target::kWordSize * 30), Address::PreIndex));
+  __ ldrh(R0, Address(R2, (-target::kWordSize * 30)));
+  __ ldr(R1, Address(SP, (target::kWordSize * 30), Address::PostIndex));
   __ bx(LR);
 }
 
@@ -1183,12 +1184,12 @@
 
 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) {
   __ mov(IP, Operand(SP));
-  __ sub(SP, SP, Operand(kWordSize * 30));
+  __ sub(SP, SP, Operand(target::kWordSize * 30));
   __ strd(R2, R3, SP, 0);
-  __ strd(R0, R1, IP, (-kWordSize * 28));
-  __ ldrd(R2, R3, IP, (-kWordSize * 28));
+  __ strd(R0, R1, IP, (-target::kWordSize * 28));
+  __ ldrd(R2, R3, IP, (-target::kWordSize * 28));
   __ ldrd(R0, R1, SP, 0);
-  __ add(SP, SP, Operand(kWordSize * 30));
+  __ add(SP, SP, Operand(target::kWordSize * 30));
   __ sub(R0, R0, Operand(R2));
   __ add(R1, R1, Operand(R3));
   __ bx(LR);
@@ -1215,12 +1216,12 @@
   __ Push(R0);  // Make room, so we can decrement after.
   __ stm(DA_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
   __ str(R2, Address(SP));                 // Should be a free slot.
-  __ ldr(R9, Address(SP, 1 * kWordSize));  // R0.  R9 = +1.
-  __ ldr(IP, Address(SP, 2 * kWordSize));  // R1.
+  __ ldr(R9, Address(SP, 1 * target::kWordSize));  // R0.  R9 = +1.
+  __ ldr(IP, Address(SP, 2 * target::kWordSize));  // R1.
   __ sub(R9, R9, Operand(IP));             // -R1. R9 = -6.
-  __ ldr(IP, Address(SP, 3 * kWordSize));  // R2.
+  __ ldr(IP, Address(SP, 3 * target::kWordSize));  // R2.
   __ add(R9, R9, Operand(IP));             // +R2. R9 = +5.
-  __ ldr(IP, Address(SP, 4 * kWordSize));  // R3.
+  __ ldr(IP, Address(SP, 4 * target::kWordSize));  // R3.
   __ sub(R9, R9, Operand(IP));             // -R3. R9 = -26.
   __ ldm(IB_W, SP, (1 << R0 | 1 << R1 | 1 << R2 | 1 << R3));
   // Same operations again. But this time from the restore registers.
@@ -1245,9 +1246,9 @@
 
 ASSEMBLER_TEST_GENERATE(AddressShiftStrLSL1NegOffset, assembler) {
   __ mov(R2, Operand(42));
-  __ mov(R1, Operand(kWordSize));
+  __ mov(R1, Operand(target::kWordSize));
   __ str(R2, Address(SP, R1, LSL, 1, Address::NegOffset));
-  __ ldr(R0, Address(SP, (-kWordSize * 2), Address::Offset));
+  __ ldr(R0, Address(SP, (-target::kWordSize * 2), Address::Offset));
   __ bx(LR);
 }
 
@@ -1259,8 +1260,8 @@
 
 ASSEMBLER_TEST_GENERATE(AddressShiftLdrLSL5NegOffset, assembler) {
   __ mov(R2, Operand(42));
-  __ mov(R1, Operand(kWordSize));
-  __ str(R2, Address(SP, (-kWordSize * 32), Address::Offset));
+  __ mov(R1, Operand(target::kWordSize));
+  __ str(R2, Address(SP, (-target::kWordSize * 32), Address::Offset));
   __ ldr(R0, Address(SP, R1, LSL, 5, Address::NegOffset));
   __ bx(LR);
 }
@@ -1273,9 +1274,9 @@
 
 ASSEMBLER_TEST_GENERATE(AddressShiftStrLRS1NegOffset, assembler) {
   __ mov(R2, Operand(42));
-  __ mov(R1, Operand(kWordSize * 2));
+  __ mov(R1, Operand(target::kWordSize * 2));
   __ str(R2, Address(SP, R1, LSR, 1, Address::NegOffset));
-  __ ldr(R0, Address(SP, -kWordSize, Address::Offset));
+  __ ldr(R0, Address(SP, -target::kWordSize, Address::Offset));
   __ bx(LR);
 }
 
@@ -1287,8 +1288,8 @@
 
 ASSEMBLER_TEST_GENERATE(AddressShiftLdrLRS1NegOffset, assembler) {
   __ mov(R2, Operand(42));
-  __ mov(R1, Operand(kWordSize * 2));
-  __ str(R2, Address(SP, -kWordSize, Address::Offset));
+  __ mov(R1, Operand(target::kWordSize * 2));
+  __ str(R2, Address(SP, -target::kWordSize, Address::Offset));
   __ ldr(R0, Address(SP, R1, LSR, 1, Address::NegOffset));
   __ bx(LR);
 }
@@ -1301,10 +1302,10 @@
 
 ASSEMBLER_TEST_GENERATE(AddressShiftStrLSLNegPreIndex, assembler) {
   __ mov(R2, Operand(42));
-  __ mov(R1, Operand(kWordSize));
+  __ mov(R1, Operand(target::kWordSize));
   __ mov(R3, Operand(SP));
   __ str(R2, Address(SP, R1, LSL, 5, Address::NegPreIndex));
-  __ ldr(R0, Address(R3, (-kWordSize * 32), Address::Offset));
+  __ ldr(R0, Address(R3, (-target::kWordSize * 32), Address::Offset));
   __ mov(SP, Operand(R3));
   __ bx(LR);
 }
@@ -1317,8 +1318,8 @@
 
 ASSEMBLER_TEST_GENERATE(AddressShiftLdrLSLNegPreIndex, assembler) {
   __ mov(R2, Operand(42));
-  __ mov(R1, Operand(kWordSize));
-  __ str(R2, Address(SP, (-kWordSize * 32), Address::PreIndex));
+  __ mov(R1, Operand(target::kWordSize));
+  __ str(R2, Address(SP, (-target::kWordSize * 32), Address::PreIndex));
   __ ldr(R0, Address(SP, R1, LSL, 5, Address::PostIndex));
   __ bx(LR);
 }
@@ -3845,6 +3846,7 @@
   __ Ret();
 }
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/compiler/assembler/assembler_dbc.cc b/runtime/vm/compiler/assembler/assembler_dbc.cc
index a7643b6..141c36a 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc.cc
+++ b/runtime/vm/compiler/assembler/assembler_dbc.cc
@@ -5,19 +5,19 @@
 #include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_DBC)
 
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/cpu.h"
 #include "vm/longjump.h"
-#include "vm/runtime_entry.h"
 #include "vm/simulator.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
 
 namespace dart {
-
 DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 
+namespace compiler {
+
 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
   const uword end = data + length;
   while (data < end) {
@@ -72,11 +72,11 @@
 }
 
 const char* Assembler::RegisterName(Register reg) {
-  return Thread::Current()->zone()->PrintToString("R%d", reg);
+  return ThreadState::Current()->zone()->PrintToString("R%d", reg);
 }
 
 const char* Assembler::FpuRegisterName(FpuRegister reg) {
-  return Thread::Current()->zone()->PrintToString("F%d", reg);
+  return ThreadState::Current()->zone()->PrintToString("F%d", reg);
 }
 
 static int32_t EncodeJump(int32_t relative_pc) {
@@ -125,9 +125,11 @@
 }
 
 intptr_t Assembler::AddConstant(const Object& obj) {
-  return object_pool_wrapper().FindObject(Object::ZoneHandle(obj.raw()));
+  return object_pool_builder().FindObject(
+      NewZoneHandle(ThreadState::Current()->zone(), obj));
 }
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/compiler/assembler/assembler_dbc.h b/runtime/vm/compiler/assembler/assembler_dbc.h
index 9787191..3c57878 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc.h
+++ b/runtime/vm/compiler/assembler/assembler_dbc.h
@@ -14,11 +14,12 @@
 #include "vm/constants_dbc.h"
 #include "vm/cpu.h"
 #include "vm/hash_map.h"
-#include "vm/object.h"
 #include "vm/simulator.h"
 
 namespace dart {
 
+namespace compiler {
+
 // Dummy declaration to make things compile.
 class Address : public ValueObject {
  private:
@@ -27,9 +28,9 @@
 
 class Assembler : public AssemblerBase {
  public:
-  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+  explicit Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches = false)
-      : AssemblerBase(object_pool_wrapper) {}
+      : AssemblerBase(object_pool_builder) {}
   ~Assembler() {}
 
   void Bind(Label* label);
@@ -99,6 +100,10 @@
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
 
+}  // namespace compiler
+
+using compiler::Address;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_DBC_H_
diff --git a/runtime/vm/compiler/assembler/assembler_dbc_test.cc b/runtime/vm/compiler/assembler/assembler_dbc_test.cc
index 7652b45..c87d7aa 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_dbc_test.cc
@@ -12,6 +12,7 @@
 #include "vm/unit_test.h"
 
 namespace dart {
+namespace compiler {
 
 static RawObject* ExecuteTest(const Code& code) {
   const intptr_t kTypeArgsLen = 0;
@@ -68,8 +69,8 @@
 
 static void MakeDummyInstanceCall(Assembler* assembler, const Object& result) {
   // Make a dummy function.
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateDummyCode(&_assembler_, result);
   const char* dummy_function_name = "dummy_instance_function";
   const Function& dummy_instance_function =
@@ -134,7 +135,7 @@
   __ Frame(2);
   __ Move(0, -kParamEndSlotFromFp - 1);
   __ Move(1, -kParamEndSlotFromFp - 2);
-  __ StoreField(0, GrowableObjectArray::data_offset() / kWordSize, 1);
+  __ StoreField(0, GrowableObjectArray::data_offset() / target::kWordSize, 1);
   __ Return(0);
 }
 
@@ -2513,6 +2514,7 @@
 
 #endif  // defined(ARCH_IS_64_BIT)
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_DBC)
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 97823b4..f1ef6b1 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -5,20 +5,30 @@
 #include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_IA32)
 
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/cpu.h"
-#include "vm/heap/heap.h"
 #include "vm/instructions.h"
-#include "vm/memory_region.h"
-#include "vm/runtime_entry.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
 
 namespace dart {
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-
 DECLARE_FLAG(bool, inline_alloc);
+#endif
+
+namespace compiler {
+
+using target::ClassTable;
+using target::Heap;
+using target::Instance;
+using target::Instructions;
+using target::Isolate;
+using target::RawObject;
+using target::Thread;
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
 
 class DirectCallRelocation : public AssemblerFixup {
  public:
@@ -34,8 +44,7 @@
 
 int32_t Assembler::jit_cookie() {
   if (jit_cookie_ == 0) {
-    jit_cookie_ =
-        static_cast<int32_t>(Isolate::Current()->random()->NextUInt32());
+    jit_cookie_ = CreateJitCookie();
   }
   return jit_cookie_;
 }
@@ -1759,7 +1768,7 @@
 void Assembler::Drop(intptr_t stack_elements) {
   ASSERT(stack_elements >= 0);
   if (stack_elements > 0) {
-    addl(ESP, Immediate(stack_elements * kWordSize));
+    addl(ESP, Immediate(stack_elements * target::kWordSize));
   }
 }
 
@@ -1770,17 +1779,18 @@
 void Assembler::LoadObject(Register dst,
                            const Object& object,
                            bool movable_referent) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
+  ASSERT(IsOriginalObject(object));
+
   // movable_referent: some references to VM heap objects may be patched with
   // references to isolate-local objects (e.g., optimized static calls).
   // We need to track such references since the latter may move during
   // compaction.
-  if (object.IsSmi() || (object.InVMHeap() && !movable_referent)) {
-    movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw())));
+  if (target::CanEmbedAsRawPointerInGeneratedCode(object) &&
+      !movable_referent) {
+    movl(dst, Immediate(target::ToRawPointer(object)));
   } else {
-    ASSERT(object.IsNotTemporaryScopedHandle());
-    ASSERT(object.IsOld());
+    ASSERT(IsNotTemporaryScopedHandle(object));
+    ASSERT(IsInOldSpace(object));
     AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     EmitUint8(0xB8 + dst);
     buffer_.EmitObject(object);
@@ -1788,25 +1798,23 @@
 }
 
 void Assembler::LoadObjectSafely(Register dst, const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Assembler::IsSafe(object)) {
-    LoadObject(dst, object);
-  } else {
-    int32_t cookie = jit_cookie();
-    movl(dst, Immediate(reinterpret_cast<int32_t>(object.raw()) ^ cookie));
+  ASSERT(IsOriginalObject(object));
+  if (target::IsSmi(object) && !IsSafeSmi(object)) {
+    const int32_t cookie = jit_cookie();
+    movl(dst, Immediate(target::ToRawSmi(object) ^ cookie));
     xorl(dst, Immediate(cookie));
+  } else {
+    LoadObject(dst, object);
   }
 }
 
 void Assembler::PushObject(const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (object.IsSmi() || object.InVMHeap()) {
-    pushl(Immediate(reinterpret_cast<int32_t>(object.raw())));
+  ASSERT(IsOriginalObject(object));
+  if (target::CanEmbedAsRawPointerInGeneratedCode(object)) {
+    pushl(Immediate(target::ToRawPointer(object)));
   } else {
-    ASSERT(object.IsNotTemporaryScopedHandle());
-    ASSERT(object.IsOld());
+    ASSERT(IsNotTemporaryScopedHandle(object));
+    ASSERT(IsInOldSpace(object));
     AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     EmitUint8(0x68);
     buffer_.EmitObject(object);
@@ -1814,13 +1822,12 @@
 }
 
 void Assembler::CompareObject(Register reg, const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (object.IsSmi() || object.InVMHeap()) {
-    cmpl(reg, Immediate(reinterpret_cast<int32_t>(object.raw())));
+  ASSERT(IsOriginalObject(object));
+  if (target::CanEmbedAsRawPointerInGeneratedCode(object)) {
+    cmpl(reg, Immediate(target::ToRawPointer(object)));
   } else {
-    ASSERT(object.IsNotTemporaryScopedHandle());
-    ASSERT(object.IsOld());
+    ASSERT(IsNotTemporaryScopedHandle(object));
+    ASSERT(IsInOldSpace(object));
     AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     if (reg == EAX) {
       EmitUint8(0x05 + (7 << 3));
@@ -1846,8 +1853,9 @@
     Stop("Unexpected Smi!");
     Bind(&okay);
 #endif
-    COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
-                   (kOldObjectAlignmentOffset == 0));
+    COMPILE_ASSERT((target::ObjectAlignment::kNewObjectAlignmentOffset ==
+                    target::kWordSize) &&
+                   (target::ObjectAlignment::kOldObjectAlignmentOffset == 0));
     // Write-barrier triggers if the value is in the new space (has bit set) and
     // the object is in the old space (has bit cleared).
     // To check that we could compute value & ~object and skip the write barrier
@@ -1856,9 +1864,9 @@
     // ~value | object instead and skip the write barrier if the bit is set.
     notl(value);
     orl(value, object);
-    testl(value, Immediate(kNewObjectAlignmentOffset));
+    testl(value, Immediate(target::ObjectAlignment::kNewObjectAlignmentOffset));
   } else {
-    ASSERT(kNewObjectAlignmentOffset == 4);
+    ASSERT(target::ObjectAlignment::kNewObjectAlignmentOffset == 4);
     ASSERT(kHeapObjectTag == 1);
     // Detect value being ...101 and object being ...001.
     andl(value, Immediate(7));
@@ -1951,28 +1959,18 @@
   Bind(&done);
 }
 
-void Assembler::UnverifiedStoreOldObject(const Address& dest,
-                                         const Object& value) {
-  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
-  ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
-  ASSERT(value.IsOld());
-  ASSERT(!value.InVMHeap());
-  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
-  EmitUint8(0xC7);
-  EmitOperand(0, dest);
-  buffer_.EmitObject(value);
-}
-
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
-  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
-  ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
-  if (value.IsSmi() || value.InVMHeap()) {
-    Immediate imm_value(reinterpret_cast<int32_t>(value.raw()));
+  ASSERT(IsOriginalObject(value));
+  if (target::CanEmbedAsRawPointerInGeneratedCode(value)) {
+    Immediate imm_value(target::ToRawPointer(value));
     movl(dest, imm_value);
   } else {
-    UnverifiedStoreOldObject(dest, value);
+    AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+    EmitUint8(0xC7);
+    EmitOperand(0, dest);
+    buffer_.EmitObject(value);
   }
   // No store buffer update.
 }
@@ -1989,14 +1987,14 @@
 }
 
 void Assembler::ZeroInitSmiField(const Address& dest) {
-  Immediate zero(Smi::RawValue(0));
+  Immediate zero(target::ToRawSmi(0));
   movl(dest, zero);
 }
 
 void Assembler::IncrementSmiField(const Address& dest, int32_t increment) {
   // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
   // the length of this instruction sequence.
-  Immediate inc_imm(Smi::RawValue(increment));
+  Immediate inc_imm(target::ToRawSmi(increment));
   addl(dest, inc_imm);
 }
 
@@ -2006,7 +2004,7 @@
   pushl(Immediate(Utils::High32Bits(constant)));
   pushl(Immediate(Utils::Low32Bits(constant)));
   movsd(dst, Address(ESP, 0));
-  addl(ESP, Immediate(2 * kWordSize));
+  addl(ESP, Immediate(2 * target::kWordSize));
 }
 
 void Assembler::FloatNegate(XmmRegister f) {
@@ -2105,7 +2103,7 @@
   // and ensure proper alignment of the stack frame.
   // We need to restore it before restoring registers.
   const intptr_t kPushedRegistersSize =
-      kNumberOfVolatileCpuRegisters * kWordSize +
+      kNumberOfVolatileCpuRegisters * target::kWordSize +
       kNumberOfVolatileXmmRegisters * kFpuRegisterSize;
   leal(ESP, Address(EBP, -kPushedRegistersSize));
 
@@ -2133,8 +2131,8 @@
 }
 
 void Assembler::Call(const Code& target, bool movable_target) {
-  LoadObject(CODE_REG, target, movable_target);
-  call(FieldAddress(CODE_REG, Code::entry_point_offset()));
+  LoadObject(CODE_REG, ToObject(target), movable_target);
+  call(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
 }
 
 void Assembler::CallToRuntime() {
@@ -2142,12 +2140,12 @@
 }
 
 void Assembler::Jmp(const Code& target) {
-  const ExternalLabel label(target.EntryPoint());
+  const ExternalLabel label(target::Code::EntryPointOf(target));
   jmp(&label);
 }
 
 void Assembler::J(Condition condition, const Code& target) {
-  const ExternalLabel label(target.EntryPoint());
+  const ExternalLabel label(target::Code::EntryPointOf(target));
   j(condition, &label);
 }
 
@@ -2201,18 +2199,17 @@
       Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
   movl(temp_reg, Address(temp_reg, table_offset));
   state_address = Address(temp_reg, state_offset);
-  testb(state_address, Immediate(ClassHeapStats::TraceAllocationMask()));
+  testb(state_address,
+        Immediate(target::ClassHeapStats::TraceAllocationMask()));
   // We are tracing for this class, jump to the trace label which will use
   // the allocation stub.
   j(NOT_ZERO, trace, near_jump);
 }
 
-void Assembler::UpdateAllocationStats(intptr_t cid,
-                                      Register temp_reg,
-                                      Heap::Space space) {
+void Assembler::UpdateAllocationStats(intptr_t cid, Register temp_reg) {
   ASSERT(cid > 0);
   intptr_t counter_offset =
-      ClassTable::CounterOffsetFor(cid, space == Heap::kNew);
+      ClassTable::CounterOffsetFor(cid, /*is_new_space=*/true);
   ASSERT(temp_reg != kNoRegister);
   LoadIsolate(temp_reg);
   intptr_t table_offset =
@@ -2223,23 +2220,21 @@
 
 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
                                               Register size_reg,
-                                              Register temp_reg,
-                                              Heap::Space space) {
+                                              Register temp_reg) {
   ASSERT(cid > 0);
   ASSERT(cid < kNumPredefinedCids);
-  UpdateAllocationStats(cid, temp_reg, space);
-  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
+  UpdateAllocationStats(cid, temp_reg);
+  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, /*is_new_space=*/true);
   addl(Address(temp_reg, size_offset), size_reg);
 }
 
 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
                                               intptr_t size_in_bytes,
-                                              Register temp_reg,
-                                              Heap::Space space) {
+                                              Register temp_reg) {
   ASSERT(cid > 0);
   ASSERT(cid < kNumPredefinedCids);
-  UpdateAllocationStats(cid, temp_reg, space);
-  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
+  UpdateAllocationStats(cid, temp_reg);
+  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, /*is_new_space=*/true);
   addl(Address(temp_reg, size_offset), Immediate(size_in_bytes));
 }
 #endif  // !PRODUCT
@@ -2251,14 +2246,13 @@
                             Register temp_reg) {
   ASSERT(failure != NULL);
   ASSERT(temp_reg != kNoRegister);
-  const intptr_t instance_size = cls.instance_size();
+  const intptr_t instance_size = target::Class::GetInstanceSize(cls);
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(
-        MaybeTraceAllocation(cls.id(), temp_reg, failure, near_jump));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
+    const classid_t cid = target::Class::GetId(cls);
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, near_jump));
     movl(instance_reg, Address(THR, Thread::top_offset()));
     addl(instance_reg, Immediate(instance_size));
     // instance_reg: potential next object start.
@@ -2267,15 +2261,13 @@
     // Successfully allocated the object, now update top to point to
     // next object start and store the class in the class field of object.
     movl(Address(THR, Thread::top_offset()), instance_reg);
-    NOT_IN_PRODUCT(UpdateAllocationStats(cls.id(), temp_reg, space));
+    NOT_IN_PRODUCT(UpdateAllocationStats(cid, temp_reg));
     ASSERT(instance_size >= kHeapObjectTag);
     subl(instance_reg, Immediate(instance_size - kHeapObjectTag));
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
-    movl(FieldAddress(instance_reg, Object::tags_offset()), Immediate(tags));
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
+    movl(FieldAddress(instance_reg, target::Object::tags_offset()),
+         Immediate(tags));
   } else {
     jmp(failure);
   }
@@ -2295,7 +2287,6 @@
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
     NOT_IN_PRODUCT(MaybeTraceAllocation(cid, temp_reg, failure, near_jump));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
     movl(instance, Address(THR, Thread::top_offset()));
     movl(end_address, instance);
 
@@ -2312,22 +2303,20 @@
     // next object start and initialize the object.
     movl(Address(THR, Thread::top_offset()), end_address);
     addl(instance, Immediate(kHeapObjectTag));
-    NOT_IN_PRODUCT(
-        UpdateAllocationStatsWithSize(cid, instance_size, temp_reg, space));
+    NOT_IN_PRODUCT(UpdateAllocationStatsWithSize(cid, instance_size, temp_reg));
 
     // Initialize the tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    movl(FieldAddress(instance, Object::tags_offset()), Immediate(tags));
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
+    movl(FieldAddress(instance, target::Object::tags_offset()),
+         Immediate(tags));
   } else {
     jmp(failure);
   }
 }
 
 void Assembler::PushCodeObject() {
-  ASSERT(code_.IsNotTemporaryScopedHandle());
+  ASSERT(IsNotTemporaryScopedHandle(code_));
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x68);
   buffer_.EmitObject(code_);
@@ -2363,17 +2352,6 @@
   EnterDartFrame(0);
 }
 
-void Assembler::Stop(const char* message) {
-  if (FLAG_print_stop_message) {
-    pushl(EAX);  // Preserve EAX.
-    movl(EAX, Immediate(reinterpret_cast<int32_t>(message)));
-    Call(StubCode::PrintStopMessage());  // Passing message in EAX.
-    popl(EAX);                           // Restore EAX.
-  }
-  // Emit the int3 instruction.
-  int3();  // Execution can be resumed with the 'cont' command in gdb.
-}
-
 void Assembler::EmitOperand(int rm, const Operand& operand) {
   ASSERT(rm >= 0 && rm < 8);
   const intptr_t length = operand.length_;
@@ -2461,7 +2439,7 @@
   ASSERT(RawObject::kClassIdTagPos == 16);
   ASSERT(RawObject::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
-      Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
+      target::Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
   movzxw(result, FieldAddress(object, class_id_offset));
 }
 
@@ -2471,7 +2449,7 @@
   const intptr_t offset =
       Isolate::class_table_offset() + ClassTable::table_offset();
   movl(result, Address(result, offset));
-  ASSERT(kSizeOfClassPairLog2 == 3);
+  ASSERT(ClassTable::kSizeOfClassPairLog2 == 3);
   movl(result, Address(result, class_id, TIMES_8, 0));
 }
 
@@ -2490,7 +2468,7 @@
   ASSERT(RawObject::kClassIdTagPos == 16);
   ASSERT(RawObject::kClassIdTagSize == 16);
   const intptr_t class_id_offset =
-      Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
+      target::Object::tags_offset() + RawObject::kClassIdTagPos / kBitsPerByte;
 
   // Untag optimistically. Tag bit is shifted into the CARRY.
   SmiUntag(object);
@@ -2542,7 +2520,7 @@
     jmp(&join, Assembler::kNearJump);
 
     Bind(&smi);
-    movl(result, Immediate(Smi::RawValue(kSmiCid)));
+    movl(result, Immediate(target::ToRawSmi(kSmiCid)));
 
     Bind(&join);
   } else {
@@ -2623,6 +2601,7 @@
   return xmm_reg_names[reg];
 }
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_IA32)
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 9fcc3eb..1b110d7 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -13,11 +13,10 @@
 #include "platform/utils.h"
 #include "vm/constants_ia32.h"
 #include "vm/constants_x86.h"
+#include "vm/pointer_tagging.h"
 
 namespace dart {
-
-// Forward declarations.
-class RuntimeEntry;
+namespace compiler {
 
 class Immediate : public ValueObject {
  public:
@@ -222,11 +221,11 @@
 
 class Assembler : public AssemblerBase {
  public:
-  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+  explicit Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches = false)
-      : AssemblerBase(object_pool_wrapper),
+      : AssemblerBase(object_pool_builder),
         jit_cookie_(0),
-        code_(Code::ZoneHandle()) {
+        code_(NewZoneHandle(ThreadState::Current()->zone())) {
     // This mode is only needed and implemented for ARM.
     ASSERT(!use_far_branches);
   }
@@ -689,7 +688,7 @@
                                            intptr_t extra_disp = 0);
 
   static Address VMTagAddress() {
-    return Address(THR, Thread::vm_tag_offset());
+    return Address(THR, target::Thread::vm_tag_offset());
   }
 
   /*
@@ -774,18 +773,14 @@
                             Label* trace,
                             bool near_jump);
 
-  void UpdateAllocationStats(intptr_t cid,
-                             Register temp_reg,
-                             Heap::Space space);
+  void UpdateAllocationStats(intptr_t cid, Register temp_reg);
 
   void UpdateAllocationStatsWithSize(intptr_t cid,
                                      Register size_reg,
-                                     Register temp_reg,
-                                     Heap::Space space);
+                                     Register temp_reg);
   void UpdateAllocationStatsWithSize(intptr_t cid,
                                      intptr_t instance_size,
-                                     Register temp_reg,
-                                     Heap::Space space);
+                                     Register temp_reg);
 
   // Inlined allocation of an instance of class 'cls', code has no runtime
   // calls. Jump to 'failure' if the instance cannot be allocated here.
@@ -814,29 +809,23 @@
   static const char* RegisterName(Register reg);
   static const char* FpuRegisterName(FpuRegister reg);
 
-  // Smis that do not fit into 17 bits (16 bits of payload) are unsafe.
+  // Check if the given value is an integer value that can be directly
+  // emdedded into the code without additional XORing with jit_cookie.
+  // We consider 16-bit integers, powers of two and corresponding masks
+  // as safe values that can be emdedded into the code object.
   static bool IsSafeSmi(const Object& object) {
-    if (!object.IsSmi()) {
-      return false;
+    int64_t value;
+    if (HasIntegerValue(object, &value)) {
+      return Utils::IsInt(16, value) || Utils::IsPowerOfTwo(value) ||
+             Utils::IsPowerOfTwo(value + 1);
     }
-
-    if (Utils::IsInt(17, reinterpret_cast<intptr_t>(object.raw()))) {
-      return true;
-    }
-
-    // Single bit smis (powers of two) and corresponding masks are safe.
-    const intptr_t value = Smi::Cast(object).Value();
-    if (Utils::IsPowerOfTwo(value) || Utils::IsPowerOfTwo(value + 1)) {
-      return true;
-    }
-
     return false;
   }
   static bool IsSafe(const Object& object) {
-    return !object.IsSmi() || IsSafeSmi(object);
+    return !target::IsSmi(object) || IsSafeSmi(object);
   }
 
-  void set_code_object(const Code& code) { code_ ^= code.raw(); }
+  Object& GetSelfHandle() const { return code_; }
 
   void PushCodeObject();
 
@@ -880,12 +869,10 @@
                              CanBeSmi can_be_smi,
                              BarrierFilterMode barrier_filter_mode);
 
-  void UnverifiedStoreOldObject(const Address& dest, const Object& value);
-
   int32_t jit_cookie();
 
   int32_t jit_cookie_;
-  Code& code_;
+  Object& code_;
 
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
@@ -916,6 +903,12 @@
   EmitUint8(0x66);
 }
 
+}  // namespace compiler
+
+using compiler::Address;
+using compiler::FieldAddress;
+using compiler::Immediate;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_IA32_H_
diff --git a/runtime/vm/compiler/assembler/assembler_ia32_test.cc b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
index 154cd89..26d3784 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
@@ -19,6 +19,7 @@
 #endif
 
 namespace dart {
+namespace compiler {
 
 #define __ assembler->
 
@@ -36,7 +37,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) {
-  __ movl(EAX, Address(ESP, kWordSize));
+  __ movl(EAX, Address(ESP, target::kWordSize));
   __ ret();
 }
 
@@ -54,21 +55,21 @@
   __ movl(EAX, Address(EBP, 0));
   __ movl(EAX, Address(EAX, 0));
 
-  __ movl(EAX, Address(ESP, kWordSize));
-  __ movl(EAX, Address(EBP, kWordSize));
-  __ movl(EAX, Address(EAX, kWordSize));
+  __ movl(EAX, Address(ESP, target::kWordSize));
+  __ movl(EAX, Address(EBP, target::kWordSize));
+  __ movl(EAX, Address(EAX, target::kWordSize));
 
-  __ movl(EAX, Address(ESP, -kWordSize));
-  __ movl(EAX, Address(EBP, -kWordSize));
-  __ movl(EAX, Address(EAX, -kWordSize));
+  __ movl(EAX, Address(ESP, -target::kWordSize));
+  __ movl(EAX, Address(EBP, -target::kWordSize));
+  __ movl(EAX, Address(EAX, -target::kWordSize));
 
-  __ movl(EAX, Address(ESP, 256 * kWordSize));
-  __ movl(EAX, Address(EBP, 256 * kWordSize));
-  __ movl(EAX, Address(EAX, 256 * kWordSize));
+  __ movl(EAX, Address(ESP, 256 * target::kWordSize));
+  __ movl(EAX, Address(EBP, 256 * target::kWordSize));
+  __ movl(EAX, Address(EAX, 256 * target::kWordSize));
 
-  __ movl(EAX, Address(ESP, -256 * kWordSize));
-  __ movl(EAX, Address(EBP, -256 * kWordSize));
-  __ movl(EAX, Address(EAX, -256 * kWordSize));
+  __ movl(EAX, Address(ESP, -256 * target::kWordSize));
+  __ movl(EAX, Address(EBP, -256 * target::kWordSize));
+  __ movl(EAX, Address(EAX, -256 * target::kWordSize));
 
   __ movl(EAX, Address(EAX, TIMES_1));
   __ movl(EAX, Address(EAX, TIMES_2));
@@ -78,11 +79,11 @@
   __ movl(EAX, Address(EBP, TIMES_2));
   __ movl(EAX, Address(EAX, TIMES_2));
 
-  __ movl(EAX, Address(EBP, TIMES_2, kWordSize));
-  __ movl(EAX, Address(EAX, TIMES_2, kWordSize));
+  __ movl(EAX, Address(EBP, TIMES_2, target::kWordSize));
+  __ movl(EAX, Address(EAX, TIMES_2, target::kWordSize));
 
-  __ movl(EAX, Address(EBP, TIMES_2, 256 * kWordSize));
-  __ movl(EAX, Address(EAX, TIMES_2, 256 * kWordSize));
+  __ movl(EAX, Address(EBP, TIMES_2, 256 * target::kWordSize));
+  __ movl(EAX, Address(EAX, TIMES_2, 256 * target::kWordSize));
 
   __ movl(EAX, Address(EAX, EBP, TIMES_2, 0));
   __ movl(EAX, Address(EAX, EAX, TIMES_2, 0));
@@ -91,19 +92,19 @@
   __ movl(EAX, Address(ESP, EBP, TIMES_2, 0));
   __ movl(EAX, Address(ESP, EAX, TIMES_2, 0));
 
-  __ movl(EAX, Address(EAX, EBP, TIMES_2, kWordSize));
-  __ movl(EAX, Address(EAX, EAX, TIMES_2, kWordSize));
-  __ movl(EAX, Address(EBP, EBP, TIMES_2, kWordSize));
-  __ movl(EAX, Address(EBP, EAX, TIMES_2, kWordSize));
-  __ movl(EAX, Address(ESP, EBP, TIMES_2, kWordSize));
-  __ movl(EAX, Address(ESP, EAX, TIMES_2, kWordSize));
+  __ movl(EAX, Address(EAX, EBP, TIMES_2, target::kWordSize));
+  __ movl(EAX, Address(EAX, EAX, TIMES_2, target::kWordSize));
+  __ movl(EAX, Address(EBP, EBP, TIMES_2, target::kWordSize));
+  __ movl(EAX, Address(EBP, EAX, TIMES_2, target::kWordSize));
+  __ movl(EAX, Address(ESP, EBP, TIMES_2, target::kWordSize));
+  __ movl(EAX, Address(ESP, EAX, TIMES_2, target::kWordSize));
 
-  __ movl(EAX, Address(EAX, EBP, TIMES_2, 256 * kWordSize));
-  __ movl(EAX, Address(EAX, EAX, TIMES_2, 256 * kWordSize));
-  __ movl(EAX, Address(EBP, EBP, TIMES_2, 256 * kWordSize));
-  __ movl(EAX, Address(EBP, EAX, TIMES_2, 256 * kWordSize));
-  __ movl(EAX, Address(ESP, EBP, TIMES_2, 256 * kWordSize));
-  __ movl(EAX, Address(ESP, EAX, TIMES_2, 256 * kWordSize));
+  __ movl(EAX, Address(EAX, EBP, TIMES_2, 256 * target::kWordSize));
+  __ movl(EAX, Address(EAX, EAX, TIMES_2, 256 * target::kWordSize));
+  __ movl(EAX, Address(EBP, EBP, TIMES_2, 256 * target::kWordSize));
+  __ movl(EAX, Address(EBP, EAX, TIMES_2, 256 * target::kWordSize));
+  __ movl(EAX, Address(ESP, EBP, TIMES_2, 256 * target::kWordSize));
+  __ movl(EAX, Address(ESP, EAX, TIMES_2, 256 * target::kWordSize));
 }
 
 ASSEMBLER_TEST_RUN(AddressingModes, test) {
@@ -376,11 +377,11 @@
 }
 
 ASSEMBLER_TEST_GENERATE(AddressBinOp, assembler) {
-  __ movl(EAX, Address(ESP, kWordSize));
-  __ addl(EAX, Address(ESP, kWordSize));
+  __ movl(EAX, Address(ESP, target::kWordSize));
+  __ addl(EAX, Address(ESP, target::kWordSize));
   __ incl(EAX);
-  __ subl(EAX, Address(ESP, kWordSize));
-  __ imull(EAX, Address(ESP, kWordSize));
+  __ subl(EAX, Address(ESP, target::kWordSize));
+  __ imull(EAX, Address(ESP, target::kWordSize));
   __ ret();
 }
 
@@ -480,7 +481,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(BitScanReverse, assembler) {
-  __ movl(ECX, Address(ESP, kWordSize));
+  __ movl(ECX, Address(ESP, target::kWordSize));
   __ movl(EAX, Immediate(666));  // Marker for conditional write.
   __ bsrl(EAX, ECX);
   __ ret();
@@ -538,7 +539,7 @@
   __ movzxb(EAX, Address(ESP, 0));  // EAX = 0xff
   __ movsxw(EBX, Address(ESP, 0));  // EBX = -1
   __ movzxw(ECX, Address(ESP, 0));  // ECX = 0xffff
-  __ addl(ESP, Immediate(kWordSize));
+  __ addl(ESP, Immediate(target::kWordSize));
 
   __ addl(EBX, ECX);
   __ addl(EAX, EBX);
@@ -584,7 +585,7 @@
   __ pushl(Immediate(0x1C));
   __ xorl(ECX, Address(ESP, 0));  // 0x65B.
   __ popl(EAX);                   // Discard.
-  __ movl(EAX, Address(ESP, kWordSize));
+  __ movl(EAX, Address(ESP, target::kWordSize));
   __ movl(EDX, Immediate(0xB0));
   __ orl(Address(EAX, 0), EDX);
   __ movl(EAX, ECX);
@@ -762,7 +763,7 @@
   __ Bind(&donetest13);
 
   Label donetest14;
-  __ subl(ESP, Immediate(kWordSize));
+  __ subl(ESP, Immediate(target::kWordSize));
   __ movl(Address(ESP, 0), Immediate(0x80000000));
   __ movl(EAX, Immediate(0));
   __ movl(ECX, Immediate(3));
@@ -772,10 +773,10 @@
   __ j(EQUAL, &donetest14);
   __ int3();
   __ Bind(&donetest14);
-  __ addl(ESP, Immediate(kWordSize));
+  __ addl(ESP, Immediate(target::kWordSize));
 
   Label donetest15;
-  __ subl(ESP, Immediate(kWordSize));
+  __ subl(ESP, Immediate(target::kWordSize));
   __ movl(Address(ESP, 0), Immediate(0xFF000000));
   __ movl(EAX, Immediate(-1));
   __ movl(ECX, Immediate(2));
@@ -785,7 +786,7 @@
   __ j(EQUAL, &donetest15);
   __ int3();
   __ Bind(&donetest15);
-  __ addl(ESP, Immediate(kWordSize));
+  __ addl(ESP, Immediate(target::kWordSize));
 
   Label donetest16;
   __ movl(EDX, Immediate(0x80000000));
@@ -2645,10 +2646,10 @@
 ASSEMBLER_TEST_GENERATE(SingleFPOperationsStack, assembler) {
   __ movl(EAX, Immediate(bit_cast<int32_t, float>(12.3f)));
   __ movd(XMM0, EAX);
-  __ addss(XMM0, Address(ESP, kWordSize));  // 15.7f
-  __ mulss(XMM0, Address(ESP, kWordSize));  // 53.38f
-  __ subss(XMM0, Address(ESP, kWordSize));  // 49.98f
-  __ divss(XMM0, Address(ESP, kWordSize));  // 14.7f
+  __ addss(XMM0, Address(ESP, target::kWordSize));  // 15.7f
+  __ mulss(XMM0, Address(ESP, target::kWordSize));  // 53.38f
+  __ subss(XMM0, Address(ESP, target::kWordSize));  // 49.98f
+  __ divss(XMM0, Address(ESP, target::kWordSize));  // 14.7f
   __ pushl(EAX);
   __ movss(Address(ESP, 0), XMM0);
   __ flds(Address(ESP, 0));
@@ -2689,7 +2690,7 @@
   __ movsd(XMM6, XMM5);
   __ movsd(XMM7, XMM6);
   __ movl(Address(ESP, 0), Immediate(0));
-  __ movl(Address(ESP, kWordSize), Immediate(0));
+  __ movl(Address(ESP, target::kWordSize), Immediate(0));
   __ movsd(XMM0, Address(ESP, 0));
   __ movsd(Address(ESP, 0), XMM7);
   __ movsd(XMM7, Address(ESP, 0));
@@ -2701,7 +2702,7 @@
   __ movaps(XMM1, XMM2);
   __ movaps(XMM0, XMM1);
   __ movl(Address(ESP, 0), Immediate(0));
-  __ movl(Address(ESP, kWordSize), Immediate(0));
+  __ movl(Address(ESP, target::kWordSize), Immediate(0));
   __ movsd(Address(ESP, 0), XMM0);
   __ fldl(Address(ESP, 0));
   __ popl(EAX);
@@ -2755,7 +2756,7 @@
   __ pushl(EAX);
   __ fldl(Address(ESP, 0));
   __ movl(Address(ESP, 0), Immediate(0));
-  __ movl(Address(ESP, kWordSize), Immediate(0));
+  __ movl(Address(ESP, target::kWordSize), Immediate(0));
   __ fstpl(Address(ESP, 0));
   __ popl(EAX);
   __ popl(EDX);
@@ -2844,10 +2845,10 @@
   __ popl(EAX);
   __ popl(EAX);
 
-  __ addsd(XMM0, Address(ESP, kWordSize));  // 15.7
-  __ mulsd(XMM0, Address(ESP, kWordSize));  // 53.38
-  __ subsd(XMM0, Address(ESP, kWordSize));  // 49.98
-  __ divsd(XMM0, Address(ESP, kWordSize));  // 14.7
+  __ addsd(XMM0, Address(ESP, target::kWordSize));  // 15.7
+  __ mulsd(XMM0, Address(ESP, target::kWordSize));  // 53.38
+  __ subsd(XMM0, Address(ESP, target::kWordSize));  // 49.98
+  __ divsd(XMM0, Address(ESP, target::kWordSize));  // 14.7
 
   __ pushl(EAX);
   __ pushl(EAX);
@@ -2913,7 +2914,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) {
-  __ filds(Address(ESP, kWordSize));
+  __ filds(Address(ESP, target::kWordSize));
   __ ret();
 }
 
@@ -3004,7 +3005,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(FloatToIntConversionRound, assembler) {
-  __ movsd(XMM1, Address(ESP, kWordSize));
+  __ movsd(XMM1, Address(ESP, target::kWordSize));
   __ cvtss2si(EDX, XMM1);
   __ movl(EAX, EDX);
   __ ret();
@@ -3025,7 +3026,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(FloatToIntConversionTrunc, assembler) {
-  __ movsd(XMM1, Address(ESP, kWordSize));
+  __ movsd(XMM1, Address(ESP, target::kWordSize));
   __ cvttss2si(EDX, XMM1);
   __ movl(EAX, EDX);
   __ ret();
@@ -3286,7 +3287,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(DoubleToIntConversionRound, assembler) {
-  __ movsd(XMM3, Address(ESP, kWordSize));
+  __ movsd(XMM3, Address(ESP, target::kWordSize));
   __ cvtsd2si(EAX, XMM3);
   __ ret();
 }
@@ -3305,7 +3306,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(DoubleToIntConversionTrunc, assembler) {
-  __ movsd(XMM3, Address(ESP, kWordSize));
+  __ movsd(XMM3, Address(ESP, target::kWordSize));
   __ cvttsd2si(EAX, XMM3);
   __ ret();
 }
@@ -3324,7 +3325,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(DoubleToDoubleTrunc, assembler) {
-  __ movsd(XMM3, Address(ESP, kWordSize));
+  __ movsd(XMM3, Address(ESP, target::kWordSize));
   __ roundsd(XMM2, XMM3, Assembler::kRoundToZero);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -3386,7 +3387,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(Sine, assembler) {
-  __ flds(Address(ESP, kWordSize));
+  __ flds(Address(ESP, target::kWordSize));
   __ fsin();
   __ ret();
 }
@@ -3403,7 +3404,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(Cosine, assembler) {
-  __ flds(Address(ESP, kWordSize));
+  __ flds(Address(ESP, target::kWordSize));
   __ fcos();
   __ ret();
 }
@@ -3420,9 +3421,9 @@
 }
 
 ASSEMBLER_TEST_GENERATE(SinCos, assembler) {
-  __ fldl(Address(ESP, kWordSize));
+  __ fldl(Address(ESP, target::kWordSize));
   __ fsincos();
-  __ subl(ESP, Immediate(2 * kWordSize));
+  __ subl(ESP, Immediate(2 * target::kWordSize));
   __ fstpl(Address(ESP, 0));  // cos result.
   __ movsd(XMM0, Address(ESP, 0));
   __ fstpl(Address(ESP, 0));  // sin result.
@@ -3430,7 +3431,7 @@
   __ subsd(XMM1, XMM0);  // sin - cos.
   __ movsd(Address(ESP, 0), XMM1);
   __ fldl(Address(ESP, 0));
-  __ addl(ESP, Immediate(2 * kWordSize));
+  __ addl(ESP, Immediate(2 * target::kWordSize));
   __ ret();
 }
 
@@ -3456,7 +3457,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(Tangent, assembler) {
-  __ fldl(Address(ESP, kWordSize));
+  __ fldl(Address(ESP, target::kWordSize));
   __ fptan();
   __ ffree(0);
   __ fincstp();
@@ -3477,7 +3478,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(SquareRootFloat, assembler) {
-  __ movss(XMM0, Address(ESP, kWordSize));
+  __ movss(XMM0, Address(ESP, target::kWordSize));
   __ sqrtss(XMM1, XMM0);
   __ pushl(EAX);
   __ movss(Address(ESP, 0), XMM1);
@@ -3502,7 +3503,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(SquareRootDouble, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ sqrtsd(XMM1, XMM0);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -3563,7 +3564,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(FloatNegate, assembler) {
-  __ movss(XMM0, Address(ESP, kWordSize));
+  __ movss(XMM0, Address(ESP, target::kWordSize));
   __ FloatNegate(XMM0);
   __ pushl(EAX);
   __ movss(Address(ESP, 0), XMM0);
@@ -3588,7 +3589,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(DoubleNegate, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ DoubleNegate(XMM0);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -3617,8 +3618,8 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LongMulReg, assembler) {
-  __ movl(ECX, Address(ESP, kWordSize));
-  __ movl(EAX, Address(ESP, 2 * kWordSize));
+  __ movl(ECX, Address(ESP, target::kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));
   __ imull(ECX);
   __ ret();
 }
@@ -3638,8 +3639,8 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LongMulAddress, assembler) {
-  __ movl(EAX, Address(ESP, 2 * kWordSize));
-  __ imull(Address(ESP, kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));
+  __ imull(Address(ESP, target::kWordSize));
   __ ret();
 }
 
@@ -3657,8 +3658,8 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LongUnsignedMulReg, assembler) {
-  __ movl(ECX, Address(ESP, kWordSize));
-  __ movl(EAX, Address(ESP, 2 * kWordSize));
+  __ movl(ECX, Address(ESP, target::kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));
   __ mull(ECX);
   __ ret();
 }
@@ -3683,8 +3684,8 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LongUnsignedMulAddress, assembler) {
-  __ movl(EAX, Address(ESP, 2 * kWordSize));
-  __ mull(Address(ESP, kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));
+  __ mull(Address(ESP, target::kWordSize));
   __ ret();
 }
 
@@ -3710,10 +3711,10 @@
 ASSEMBLER_TEST_GENERATE(LongAddReg, assembler) {
   // Preserve clobbered callee-saved register (EBX).
   __ pushl(EBX);
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // left low.
-  __ movl(EDX, Address(ESP, 3 * kWordSize));  // left high.
-  __ movl(ECX, Address(ESP, 4 * kWordSize));  // right low.
-  __ movl(EBX, Address(ESP, 5 * kWordSize));  // right high
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));  // left low.
+  __ movl(EDX, Address(ESP, 3 * target::kWordSize));  // left high.
+  __ movl(ECX, Address(ESP, 4 * target::kWordSize));  // right low.
+  __ movl(EBX, Address(ESP, 5 * target::kWordSize));  // right high
   __ addl(EAX, ECX);
   __ adcl(EDX, EBX);
   __ popl(EBX);
@@ -3744,10 +3745,10 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) {
-  __ movl(EAX, Address(ESP, 1 * kWordSize));  // left low.
-  __ movl(EDX, Address(ESP, 2 * kWordSize));  // left high.
-  __ addl(EAX, Address(ESP, 3 * kWordSize));  // low.
-  __ adcl(EDX, Address(ESP, 4 * kWordSize));  // high.
+  __ movl(EAX, Address(ESP, 1 * target::kWordSize));  // left low.
+  __ movl(EDX, Address(ESP, 2 * target::kWordSize));  // left high.
+  __ addl(EAX, Address(ESP, 3 * target::kWordSize));  // low.
+  __ adcl(EDX, Address(ESP, 4 * target::kWordSize));  // high.
   // Result is in EAX/EDX.
   __ ret();
 }
@@ -3773,10 +3774,10 @@
 ASSEMBLER_TEST_GENERATE(LongSubReg, assembler) {
   // Preserve clobbered callee-saved register (EBX).
   __ pushl(EBX);
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // left low.
-  __ movl(EDX, Address(ESP, 3 * kWordSize));  // left high.
-  __ movl(ECX, Address(ESP, 4 * kWordSize));  // right low.
-  __ movl(EBX, Address(ESP, 5 * kWordSize));  // right high
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));  // left low.
+  __ movl(EDX, Address(ESP, 3 * target::kWordSize));  // left high.
+  __ movl(ECX, Address(ESP, 4 * target::kWordSize));  // right low.
+  __ movl(EBX, Address(ESP, 5 * target::kWordSize));  // right high
   __ subl(EAX, ECX);
   __ sbbl(EDX, EBX);
   __ popl(EBX);
@@ -3807,10 +3808,10 @@
 }
 
 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) {
-  __ movl(EAX, Address(ESP, 1 * kWordSize));  // left low.
-  __ movl(EDX, Address(ESP, 2 * kWordSize));  // left high.
-  __ subl(EAX, Address(ESP, 3 * kWordSize));  // low.
-  __ sbbl(EDX, Address(ESP, 4 * kWordSize));  // high.
+  __ movl(EAX, Address(ESP, 1 * target::kWordSize));  // left low.
+  __ movl(EDX, Address(ESP, 2 * target::kWordSize));  // left high.
+  __ subl(EAX, Address(ESP, 3 * target::kWordSize));  // low.
+  __ sbbl(EDX, Address(ESP, 4 * target::kWordSize));  // high.
   // Result is in EAX/EDX.
   __ ret();
 }
@@ -3836,18 +3837,18 @@
 ASSEMBLER_TEST_GENERATE(LongSubAddress2, assembler) {
   // Preserve clobbered callee-saved register (EBX).
   __ pushl(EBX);
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // left low.
-  __ movl(EDX, Address(ESP, 3 * kWordSize));  // left high.
-  __ movl(ECX, Address(ESP, 4 * kWordSize));  // right low.
-  __ movl(EBX, Address(ESP, 5 * kWordSize));  // right high
-  __ subl(ESP, Immediate(2 * kWordSize));
-  __ movl(Address(ESP, 0 * kWordSize), EAX);  // left low.
-  __ movl(Address(ESP, 1 * kWordSize), EDX);  // left high.
-  __ subl(Address(ESP, 0 * kWordSize), ECX);
-  __ sbbl(Address(ESP, 1 * kWordSize), EBX);
-  __ movl(EAX, Address(ESP, 0 * kWordSize));
-  __ movl(EDX, Address(ESP, 1 * kWordSize));
-  __ addl(ESP, Immediate(2 * kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));  // left low.
+  __ movl(EDX, Address(ESP, 3 * target::kWordSize));  // left high.
+  __ movl(ECX, Address(ESP, 4 * target::kWordSize));  // right low.
+  __ movl(EBX, Address(ESP, 5 * target::kWordSize));  // right high
+  __ subl(ESP, Immediate(2 * target::kWordSize));
+  __ movl(Address(ESP, 0 * target::kWordSize), EAX);  // left low.
+  __ movl(Address(ESP, 1 * target::kWordSize), EDX);  // left high.
+  __ subl(Address(ESP, 0 * target::kWordSize), ECX);
+  __ sbbl(Address(ESP, 1 * target::kWordSize), EBX);
+  __ movl(EAX, Address(ESP, 0 * target::kWordSize));
+  __ movl(EDX, Address(ESP, 1 * target::kWordSize));
+  __ addl(ESP, Immediate(2 * target::kWordSize));
   __ popl(EBX);
   // Result is in EAX/EDX.
   __ ret();
@@ -3884,18 +3885,18 @@
 ASSEMBLER_TEST_GENERATE(LongAddAddress2, assembler) {
   // Preserve clobbered callee-saved register (EBX).
   __ pushl(EBX);
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // left low.
-  __ movl(EDX, Address(ESP, 3 * kWordSize));  // left high.
-  __ movl(ECX, Address(ESP, 4 * kWordSize));  // right low.
-  __ movl(EBX, Address(ESP, 5 * kWordSize));  // right high
-  __ subl(ESP, Immediate(2 * kWordSize));
-  __ movl(Address(ESP, 0 * kWordSize), EAX);  // left low.
-  __ movl(Address(ESP, 1 * kWordSize), EDX);  // left high.
-  __ addl(Address(ESP, 0 * kWordSize), ECX);
-  __ adcl(Address(ESP, 1 * kWordSize), EBX);
-  __ movl(EAX, Address(ESP, 0 * kWordSize));
-  __ movl(EDX, Address(ESP, 1 * kWordSize));
-  __ addl(ESP, Immediate(2 * kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));  // left low.
+  __ movl(EDX, Address(ESP, 3 * target::kWordSize));  // left high.
+  __ movl(ECX, Address(ESP, 4 * target::kWordSize));  // right low.
+  __ movl(EBX, Address(ESP, 5 * target::kWordSize));  // right high
+  __ subl(ESP, Immediate(2 * target::kWordSize));
+  __ movl(Address(ESP, 0 * target::kWordSize), EAX);  // left low.
+  __ movl(Address(ESP, 1 * target::kWordSize), EDX);  // left high.
+  __ addl(Address(ESP, 0 * target::kWordSize), ECX);
+  __ adcl(Address(ESP, 1 * target::kWordSize), EBX);
+  __ movl(EAX, Address(ESP, 0 * target::kWordSize));
+  __ movl(EDX, Address(ESP, 1 * target::kWordSize));
+  __ addl(ESP, Immediate(2 * target::kWordSize));
   __ popl(EBX);
   // Result is in EAX/EDX.
   __ ret();
@@ -3931,7 +3932,7 @@
 
 // Testing only the lower 64-bit value of 'cvtdq2pd'.
 ASSEMBLER_TEST_GENERATE(IntegerToDoubleConversion, assembler) {
-  __ movsd(XMM1, Address(ESP, kWordSize));
+  __ movsd(XMM1, Address(ESP, target::kWordSize));
   __ cvtdq2pd(XMM2, XMM1);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -3962,21 +3963,21 @@
 
 // Implement with truncation.
 ASSEMBLER_TEST_GENERATE(FPUStoreLong, assembler) {
-  __ fldl(Address(ESP, kWordSize));
+  __ fldl(Address(ESP, target::kWordSize));
   __ pushl(EAX);
   __ pushl(EAX);
   __ fnstcw(Address(ESP, 0));
   __ movzxw(EAX, Address(ESP, 0));
   __ orl(EAX, Immediate(0x0c00));
-  __ movw(Address(ESP, kWordSize), EAX);
-  __ fldcw(Address(ESP, kWordSize));
+  __ movw(Address(ESP, target::kWordSize), EAX);
+  __ fldcw(Address(ESP, target::kWordSize));
   __ pushl(EAX);
   __ pushl(EAX);
   __ fistpl(Address(ESP, 0));
   __ popl(EAX);
   __ popl(EDX);
   __ fldcw(Address(ESP, 0));
-  __ addl(ESP, Immediate(kWordSize * 2));
+  __ addl(ESP, Immediate(target::kWordSize * 2));
   __ ret();
 }
 
@@ -4014,7 +4015,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(XorpdZeroing, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ xorpd(XMM0, XMM0);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -4042,7 +4043,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(Pxor, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ pxor(XMM0, XMM0);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -4070,7 +4071,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(Orpd, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ xorpd(XMM1, XMM1);
   __ DoubleNegate(XMM1);
   __ orpd(XMM0, XMM1);
@@ -4103,7 +4104,7 @@
 
 ASSEMBLER_TEST_GENERATE(Pextrd0, assembler) {
   if (TargetCPUFeatures::sse4_1_supported()) {
-    __ movsd(XMM0, Address(ESP, kWordSize));
+    __ movsd(XMM0, Address(ESP, target::kWordSize));
     __ pextrd(EAX, XMM0, Immediate(0));
   }
   __ ret();
@@ -4123,7 +4124,7 @@
 
 ASSEMBLER_TEST_GENERATE(Pextrd1, assembler) {
   if (TargetCPUFeatures::sse4_1_supported()) {
-    __ movsd(XMM0, Address(ESP, kWordSize));
+    __ movsd(XMM0, Address(ESP, target::kWordSize));
     __ pextrd(EAX, XMM0, Immediate(1));
   }
   __ ret();
@@ -4143,7 +4144,7 @@
 
 ASSEMBLER_TEST_GENERATE(Pmovsxdq, assembler) {
   if (TargetCPUFeatures::sse4_1_supported()) {
-    __ movsd(XMM0, Address(ESP, kWordSize));
+    __ movsd(XMM0, Address(ESP, target::kWordSize));
     __ pmovsxdq(XMM0, XMM0);
     __ pextrd(EAX, XMM0, Immediate(1));
   }
@@ -4165,7 +4166,7 @@
 
 ASSEMBLER_TEST_GENERATE(Pcmpeqq, assembler) {
   if (TargetCPUFeatures::sse4_1_supported()) {
-    __ movsd(XMM0, Address(ESP, kWordSize));
+    __ movsd(XMM0, Address(ESP, target::kWordSize));
     __ xorpd(XMM1, XMM1);
     __ pcmpeqq(XMM0, XMM1);
     __ movd(EAX, XMM0);
@@ -4188,7 +4189,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(AndPd, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ andpd(XMM0, XMM0);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -4216,7 +4217,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(Movq, assembler) {
-  __ movq(XMM0, Address(ESP, kWordSize));
+  __ movq(XMM0, Address(ESP, target::kWordSize));
   __ subl(ESP, Immediate(kDoubleSize));
   __ movq(Address(ESP, 0), XMM0);
   __ fldl(Address(ESP, 0));
@@ -4238,7 +4239,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(DoubleAbs, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ DoubleAbs(XMM0);
   __ pushl(EAX);
   __ pushl(EAX);
@@ -4270,7 +4271,7 @@
 }
 
 ASSEMBLER_TEST_GENERATE(ExtractSignBits, assembler) {
-  __ movsd(XMM0, Address(ESP, kWordSize));
+  __ movsd(XMM0, Address(ESP, target::kWordSize));
   __ movmskpd(EAX, XMM0);
   __ andl(EAX, Immediate(0x1));
   __ ret();
@@ -4296,7 +4297,7 @@
   // Preserve clobbered callee-saved register (EBX).
   __ pushl(EBX);
 
-  __ movl(EDX, Address(ESP, 2 * kWordSize));
+  __ movl(EDX, Address(ESP, 2 * target::kWordSize));
   __ xorl(EAX, EAX);
   __ movl(EBX, Immediate(1));
   __ movl(ECX, Immediate(-1));
@@ -4332,8 +4333,8 @@
 
 // Return 1 if overflow, 0 if no overflow.
 ASSEMBLER_TEST_GENERATE(ConditionalMovesNoOverflow, assembler) {
-  __ movl(EDX, Address(ESP, 1 * kWordSize));
-  __ addl(EDX, Address(ESP, 2 * kWordSize));
+  __ movl(EDX, Address(ESP, 1 * target::kWordSize));
+  __ addl(EDX, Address(ESP, 2 * target::kWordSize));
   __ movl(EAX, Immediate(1));
   __ movl(ECX, Immediate(0));
   __ cmovno(EAX, ECX);
@@ -4360,7 +4361,7 @@
 ASSEMBLER_TEST_GENERATE(ConditionalMovesEqual, assembler) {
   __ xorl(EAX, EAX);
   __ movl(ECX, Immediate(1));
-  __ movl(EDX, Address(ESP, 1 * kWordSize));
+  __ movl(EDX, Address(ESP, 1 * target::kWordSize));
   __ cmpl(EDX, Immediate(785));
   __ cmove(EAX, ECX);
   __ ret();
@@ -4385,7 +4386,7 @@
 ASSEMBLER_TEST_GENERATE(ConditionalMovesNotEqual, assembler) {
   __ xorl(EAX, EAX);
   __ movl(ECX, Immediate(1));
-  __ movl(EDX, Address(ESP, 1 * kWordSize));
+  __ movl(EDX, Address(ESP, 1 * target::kWordSize));
   __ cmpl(EDX, Immediate(785));
   __ cmovne(EAX, ECX);
   __ ret();
@@ -4409,8 +4410,8 @@
 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) {
   __ movl(EDX, Immediate(1));   // Greater equal.
   __ movl(ECX, Immediate(-1));  // Less
-  __ movl(EAX, Address(ESP, 1 * kWordSize));
-  __ cmpl(EAX, Address(ESP, 2 * kWordSize));
+  __ movl(EAX, Address(ESP, 1 * target::kWordSize));
+  __ cmpl(EAX, Address(ESP, 2 * target::kWordSize));
   __ cmovlessl(EAX, ECX);
   __ cmovgel(EAX, EDX);
   __ ret();
@@ -4620,9 +4621,9 @@
   __ pushl(ESI);
   __ pushl(EDI);
   __ pushl(ECX);
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // from.
-  __ movl(EDI, Address(ESP, 5 * kWordSize));  // to.
-  __ movl(ECX, Address(ESP, 6 * kWordSize));  // count.
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // from.
+  __ movl(EDI, Address(ESP, 5 * target::kWordSize));  // to.
+  __ movl(ECX, Address(ESP, 6 * target::kWordSize));  // count.
   __ rep_movsb();
   __ popl(ECX);
   __ popl(EDI);
@@ -4657,9 +4658,9 @@
 // Called from assembler_test.cc.
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
   __ pushl(THR);
-  __ movl(EAX, Address(ESP, 2 * kWordSize));
-  __ movl(ECX, Address(ESP, 3 * kWordSize));
-  __ movl(THR, Address(ESP, 4 * kWordSize));
+  __ movl(EAX, Address(ESP, 2 * target::kWordSize));
+  __ movl(ECX, Address(ESP, 3 * target::kWordSize));
+  __ movl(THR, Address(ESP, 4 * target::kWordSize));
   __ pushl(EAX);
   __ StoreIntoObject(ECX, FieldAddress(ECX, GrowableObjectArray::data_offset()),
                      EAX);
@@ -4804,6 +4805,7 @@
                Address(ESP, 0),
                __ popl(EAX))
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/compiler/assembler/assembler_test.cc b/runtime/vm/compiler/assembler/assembler_test.cc
index 77947ed..7a7b54a 100644
--- a/runtime/vm/compiler/assembler/assembler_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_test.cc
@@ -11,7 +11,9 @@
 
 namespace dart {
 
+namespace compiler {
 ASSEMBLER_TEST_EXTERN(StoreIntoObject);
+}  // namespace compiler
 
 ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
 #define TEST_CODE(value, growable_array, thread)                               \
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 74f20d2..af6b564 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -5,29 +5,45 @@
 #include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_X64)
 
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/class_id.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
-#include "vm/cpu.h"
-#include "vm/heap/heap.h"
 #include "vm/instructions.h"
-#include "vm/memory_region.h"
-#include "vm/runtime_entry.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
 
 namespace dart {
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-
 DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 DECLARE_FLAG(bool, precompiled_mode);
+#endif
 
-Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
+namespace compiler {
+
+using target::ClassTable;
+using target::Heap;
+using target::Instance;
+using target::Instructions;
+using target::Isolate;
+using target::RawObject;
+using target::Thread;
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+Assembler::Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches)
-    : AssemblerBase(object_pool_wrapper), constant_pool_allowed_(false) {
+    : AssemblerBase(object_pool_builder), constant_pool_allowed_(false) {
   // Far branching mode is only needed and implemented for ARM.
   ASSERT(!use_far_branches);
+
+  generate_invoke_write_barrier_wrapper_ = [&](Register reg) {
+    call(Address(THR, Thread::write_barrier_wrappers_thread_offset(reg)));
+  };
+  generate_invoke_array_write_barrier_ = [&]() {
+    call(Address(THR, Thread::array_write_barrier_entry_point_offset()));
+  };
 }
 
 void Assembler::InitializeMemoryWithBreakpoints(uword data, intptr_t length) {
@@ -41,11 +57,12 @@
   EmitLabel(label, kSize);
 }
 
-void Assembler::LoadNativeEntry(Register dst,
-                                const ExternalLabel* label,
-                                ObjectPool::Patchability patchable) {
-  const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper().FindNativeFunction(label, patchable));
+void Assembler::LoadNativeEntry(
+    Register dst,
+    const ExternalLabel* label,
+    ObjectPoolBuilderEntry::Patchability patchable) {
+  const int32_t offset = target::ObjectPool::element_offset(
+      object_pool_builder().FindNativeFunction(label, patchable));
   LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
 }
 
@@ -59,32 +76,33 @@
   call(TMP);
 }
 
-void Assembler::CallPatchable(const Code& target, Code::EntryKind entry_kind) {
+void Assembler::CallPatchable(const Code& target, CodeEntryKind entry_kind) {
   ASSERT(constant_pool_allowed());
-  const intptr_t idx =
-      object_pool_wrapper().AddObject(target, ObjectPool::kPatchable);
-  const int32_t offset = ObjectPool::element_offset(idx);
+  const intptr_t idx = object_pool_builder().AddObject(
+      ToObject(target), ObjectPoolBuilderEntry::kPatchable);
+  const int32_t offset = target::ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
-  call(FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
+  call(FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
 }
 
 void Assembler::CallWithEquivalence(const Code& target,
                                     const Object& equivalence,
-                                    Code::EntryKind entry_kind) {
+                                    CodeEntryKind entry_kind) {
   ASSERT(constant_pool_allowed());
-  const intptr_t idx = object_pool_wrapper().FindObject(target, equivalence);
-  const int32_t offset = ObjectPool::element_offset(idx);
+  const intptr_t idx =
+      object_pool_builder().FindObject(ToObject(target), equivalence);
+  const int32_t offset = target::ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
-  call(FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
+  call(FieldAddress(CODE_REG, target::Code::entry_point_offset(entry_kind)));
 }
 
 void Assembler::Call(const Code& target) {
   ASSERT(constant_pool_allowed());
-  const intptr_t idx =
-      object_pool_wrapper().FindObject(target, ObjectPool::kNotPatchable);
-  const int32_t offset = ObjectPool::element_offset(idx);
+  const intptr_t idx = object_pool_builder().FindObject(
+      ToObject(target), ObjectPoolBuilderEntry::kNotPatchable);
+  const int32_t offset = target::ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
-  call(FieldAddress(CODE_REG, Code::entry_point_offset()));
+  call(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
 }
 
 void Assembler::CallToRuntime() {
@@ -918,21 +936,21 @@
 
 void Assembler::JmpPatchable(const Code& target, Register pp) {
   ASSERT((pp != PP) || constant_pool_allowed());
-  const intptr_t idx =
-      object_pool_wrapper().AddObject(target, ObjectPool::kPatchable);
-  const int32_t offset = ObjectPool::element_offset(idx);
+  const intptr_t idx = object_pool_builder().AddObject(
+      ToObject(target), ObjectPoolBuilderEntry::kPatchable);
+  const int32_t offset = target::ObjectPool::element_offset(idx);
   movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
-  movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  movq(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   jmp(TMP);
 }
 
 void Assembler::Jmp(const Code& target, Register pp) {
   ASSERT((pp != PP) || constant_pool_allowed());
-  const intptr_t idx =
-      object_pool_wrapper().FindObject(target, ObjectPool::kNotPatchable);
-  const int32_t offset = ObjectPool::element_offset(idx);
+  const intptr_t idx = object_pool_builder().FindObject(
+      ToObject(target), ObjectPoolBuilderEntry::kNotPatchable);
+  const int32_t offset = target::ObjectPool::element_offset(idx);
   movq(CODE_REG, FieldAddress(pp, offset));
-  movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  movq(TMP, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
   jmp(TMP);
 }
 
@@ -1071,26 +1089,23 @@
     }
     return;
   }
-  addq(RSP, Immediate(stack_elements * kWordSize));
+  addq(RSP, Immediate(stack_elements * target::kWordSize));
 }
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  ASSERT(!Thread::CanLoadFromThread(object));
+  ASSERT(IsOriginalObject(object));
+  ASSERT(!target::CanLoadFromThread(object));
   if (!constant_pool_allowed()) {
     return false;
   }
 
-  // TODO(zra, kmillikin): Also load other large immediates from the object
-  // pool
-  if (object.IsSmi()) {
+  if (target::IsSmi(object)) {
     // If the raw smi does not fit into a 32-bit signed int, then we'll keep
     // the raw value in the object pool.
-    return !Utils::IsInt(32, reinterpret_cast<int64_t>(object.raw()));
+    return !Utils::IsInt(32, target::ToRawSmi(object));
   }
-  ASSERT(object.IsNotTemporaryScopedHandle());
-  ASSERT(object.IsOld());
+  ASSERT(IsNotTemporaryScopedHandle(object));
+  ASSERT(IsInOldSpace(object));
   return true;
 }
 
@@ -1108,18 +1123,19 @@
 void Assembler::LoadObjectHelper(Register dst,
                                  const Object& object,
                                  bool is_unique) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
-    movq(dst, Address(THR, Thread::OffsetFromThread(object)));
+  ASSERT(IsOriginalObject(object));
+
+  target::word 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_wrapper().AddObject(object)
-                                   : object_pool_wrapper().FindObject(object);
-    const int32_t offset = ObjectPool::element_offset(idx);
+    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(object.IsSmi());
-    LoadImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
+    ASSERT(target::IsSmi(object));
+    LoadImmediate(dst, Immediate(target::ToRawSmi(object)));
   }
 }
 
@@ -1128,9 +1144,9 @@
                                            Register new_pp) {
   ASSERT(!constant_pool_allowed());
   ASSERT(new_pp != PP);
-  const intptr_t idx =
-      object_pool_wrapper().FindObject(function, ObjectPool::kNotPatchable);
-  const int32_t offset = ObjectPool::element_offset(idx);
+  const intptr_t idx = object_pool_builder().FindObject(
+      ToObject(function), ObjectPoolBuilderEntry::kNotPatchable);
+  const int32_t offset = target::ObjectPool::element_offset(idx);
   movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
 }
 
@@ -1143,52 +1159,55 @@
 }
 
 void Assembler::StoreObject(const Address& dst, const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
-    movq(TMP, Address(THR, Thread::OffsetFromThread(object)));
+  ASSERT(IsOriginalObject(object));
+
+  target::word offset_from_thread;
+  if (target::CanLoadFromThread(object, &offset_from_thread)) {
+    movq(TMP, Address(THR, offset_from_thread));
     movq(dst, TMP);
   } else if (CanLoadFromObjectPool(object)) {
     LoadObject(TMP, object);
     movq(dst, TMP);
   } else {
-    ASSERT(object.IsSmi());
-    MoveImmediate(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
+    ASSERT(target::IsSmi(object));
+    MoveImmediate(dst, Immediate(target::ToRawSmi(object)));
   }
 }
 
 void Assembler::PushObject(const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
-    pushq(Address(THR, Thread::OffsetFromThread(object)));
+  ASSERT(IsOriginalObject(object));
+
+  target::word offset_from_thread;
+  if (target::CanLoadFromThread(object, &offset_from_thread)) {
+    pushq(Address(THR, offset_from_thread));
   } else if (CanLoadFromObjectPool(object)) {
     LoadObject(TMP, object);
     pushq(TMP);
   } else {
-    ASSERT(object.IsSmi());
-    PushImmediate(Immediate(reinterpret_cast<int64_t>(object.raw())));
+    ASSERT(target::IsSmi(object));
+    PushImmediate(Immediate(target::ToRawSmi(object)));
   }
 }
 
 void Assembler::CompareObject(Register reg, const Object& object) {
-  ASSERT(!object.IsICData() || ICData::Cast(object).IsOriginal());
-  ASSERT(!object.IsField() || Field::Cast(object).IsOriginal());
-  if (Thread::CanLoadFromThread(object)) {
-    cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
+  ASSERT(IsOriginalObject(object));
+
+  target::word offset_from_thread;
+  if (target::CanLoadFromThread(object, &offset_from_thread)) {
+    cmpq(reg, Address(THR, offset_from_thread));
   } else if (CanLoadFromObjectPool(object)) {
-    const intptr_t idx =
-        object_pool_wrapper().FindObject(object, ObjectPool::kNotPatchable);
-    const int32_t offset = ObjectPool::element_offset(idx);
+    const intptr_t idx = object_pool_builder().FindObject(
+        object, ObjectPoolBuilderEntry::kNotPatchable);
+    const int32_t offset = target::ObjectPool::element_offset(idx);
     cmpq(reg, Address(PP, offset - kHeapObjectTag));
   } else {
-    ASSERT(object.IsSmi());
-    CompareImmediate(reg, Immediate(reinterpret_cast<int64_t>(object.raw())));
+    ASSERT(target::IsSmi(object));
+    CompareImmediate(reg, Immediate(target::ToRawSmi(object)));
   }
 }
 
 intptr_t Assembler::FindImmediate(int64_t imm) {
-  return object_pool_wrapper().FindImmediate(imm);
+  return object_pool_builder().FindImmediate(imm);
 }
 
 void Assembler::LoadImmediate(Register reg, const Immediate& imm) {
@@ -1197,7 +1216,8 @@
   } else if (imm.is_int32() || !constant_pool_allowed()) {
     movq(reg, imm);
   } else {
-    int32_t offset = ObjectPool::element_offset(FindImmediate(imm.value()));
+    int32_t offset =
+        target::ObjectPool::element_offset(FindImmediate(imm.value()));
     LoadWordFromPoolOffset(reg, offset - kHeapObjectTag);
   }
 }
@@ -1217,8 +1237,9 @@
                                       Label* label,
                                       CanBeSmi can_be_smi,
                                       BarrierFilterMode how_to_jump) {
-  COMPILE_ASSERT((kNewObjectAlignmentOffset == kWordSize) &&
-                 (kOldObjectAlignmentOffset == 0));
+  COMPILE_ASSERT((target::ObjectAlignment::kNewObjectAlignmentOffset ==
+                  target::kWordSize) &&
+                 (target::ObjectAlignment::kOldObjectAlignmentOffset == 0));
 
   if (can_be_smi == kValueIsNotSmi) {
 #if defined(DEBUG)
@@ -1235,7 +1256,7 @@
     // ~value | object instead and skip the write barrier if the bit is set.
     notl(value);
     orl(value, object);
-    testl(value, Immediate(kNewObjectAlignmentOffset));
+    testl(value, Immediate(target::ObjectAlignment::kNewObjectAlignmentOffset));
   } else {
     ASSERT(kHeapObjectTag == 1);
     // Detect value being ...1001 and object being ...0001.
@@ -1271,13 +1292,13 @@
     testq(value, Immediate(kSmiTagMask));
     j(ZERO, &done, kNearJump);
   }
-  movb(TMP, FieldAddress(object, Object::tags_offset()));
+  movb(TMP, FieldAddress(object, target::Object::tags_offset()));
   shrl(TMP, Immediate(RawObject::kBarrierOverlapShift));
   andl(TMP, Address(THR, Thread::write_barrier_mask_offset()));
-  testb(FieldAddress(value, Object::tags_offset()), TMP);
+  testb(FieldAddress(value, target::Object::tags_offset()), TMP);
   j(ZERO, &done, kNearJump);
 
-  Register objectForCall = object;
+  Register object_for_call = object;
   if (value != kWriteBarrierValueReg) {
     // Unlikely. Only non-graph intrinsics.
     // TODO(rmacnak): Shuffle registers in intrinsics.
@@ -1285,16 +1306,16 @@
     if (object == kWriteBarrierValueReg) {
       COMPILE_ASSERT(RBX != kWriteBarrierValueReg);
       COMPILE_ASSERT(RCX != kWriteBarrierValueReg);
-      objectForCall = (value == RBX) ? RCX : RBX;
-      pushq(objectForCall);
-      movq(objectForCall, object);
+      object_for_call = (value == RBX) ? RCX : RBX;
+      pushq(object_for_call);
+      movq(object_for_call, object);
     }
     movq(kWriteBarrierValueReg, value);
   }
-  call(Address(THR, Thread::write_barrier_wrappers_offset(objectForCall)));
+  generate_invoke_write_barrier_wrapper_(object_for_call);
   if (value != kWriteBarrierValueReg) {
     if (object == kWriteBarrierValueReg) {
-      popq(objectForCall);
+      popq(object_for_call);
     }
     popq(kWriteBarrierValueReg);
   }
@@ -1323,10 +1344,10 @@
     testq(value, Immediate(kSmiTagMask));
     j(ZERO, &done, kNearJump);
   }
-  movb(TMP, FieldAddress(object, Object::tags_offset()));
-  shrl(TMP, Immediate(RawObject::kBarrierOverlapShift));
+  movb(TMP, FieldAddress(object, target::Object::tags_offset()));
+  shrl(TMP, Immediate(target::RawObject::kBarrierOverlapShift));
   andl(TMP, Address(THR, Thread::write_barrier_mask_offset()));
-  testb(FieldAddress(value, Object::tags_offset()), TMP);
+  testb(FieldAddress(value, target::Object::tags_offset()), TMP);
   j(ZERO, &done, kNearJump);
 
   if ((object != kWriteBarrierObjectReg) || (value != kWriteBarrierValueReg) ||
@@ -1337,7 +1358,7 @@
     UNIMPLEMENTED();
   }
 
-  call(Address(THR, Thread::array_write_barrier_entry_point_offset()));
+  generate_invoke_array_write_barrier_();
 
   Bind(&done);
 }
@@ -1360,8 +1381,6 @@
 void Assembler::StoreIntoObjectNoBarrier(Register object,
                                          const Address& dest,
                                          const Object& value) {
-  ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
-  ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
   StoreObject(dest, value);
 }
 
@@ -1377,32 +1396,17 @@
 }
 
 void Assembler::ZeroInitSmiField(const Address& dest) {
-  Immediate zero(Smi::RawValue(0));
+  Immediate zero(target::ToRawSmi(0));
   movq(dest, zero);
 }
 
 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
   // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
   // the length of this instruction sequence.
-  Immediate inc_imm(Smi::RawValue(increment));
+  Immediate inc_imm(target::ToRawSmi(increment));
   addq(dest, inc_imm);
 }
 
-void Assembler::Stop(const char* message) {
-  if (FLAG_print_stop_message) {
-    int64_t message_address = reinterpret_cast<int64_t>(message);
-    pushq(TMP);  // Preserve TMP register.
-    pushq(RDI);  // Preserve RDI register.
-    LoadImmediate(RDI, Immediate(message_address));
-    ExternalLabel label(StubCode::PrintStopMessage().EntryPoint());
-    call(&label);
-    popq(RDI);  // Restore RDI register.
-    popq(TMP);  // Restore TMP register.
-  }
-  // Emit the int3 instruction.
-  int3();  // Execution can be resumed with the 'cont' command in gdb.
-}
-
 void Assembler::Bind(Label* label) {
   intptr_t bound = buffer_.Size();
   ASSERT(!label->IsBound());  // Labels can only be bound once.
@@ -1530,10 +1534,10 @@
   const intptr_t kPushedXmmRegistersCount =
       RegisterSet::RegisterCount(CallingConventions::kVolatileXmmRegisters);
   const intptr_t kPushedRegistersSize =
-      kPushedCpuRegistersCount * kWordSize +
+      kPushedCpuRegistersCount * target::kWordSize +
       kPushedXmmRegistersCount * kFpuRegisterSize +
-      (compiler_frame_layout.dart_fixed_frame_size - 2) *
-          kWordSize;  // From EnterStubFrame (excluding PC / FP)
+      (target::frame_layout.dart_fixed_frame_size - 2) *
+          target::kWordSize;  // From EnterStubFrame (excluding PC / FP)
 
   leaq(RSP, Address(RBP, -kPushedRegistersSize));
 
@@ -1558,13 +1562,14 @@
 }
 
 void Assembler::RestoreCodePointer() {
-  movq(CODE_REG, Address(RBP, compiler_frame_layout.code_from_fp * kWordSize));
+  movq(CODE_REG,
+       Address(RBP, target::frame_layout.code_from_fp * target::kWordSize));
 }
 
 void Assembler::LoadPoolPointer(Register pp) {
   // Load new pool pointer.
   CheckCodePointer();
-  movq(pp, FieldAddress(CODE_REG, Code::object_pool_offset()));
+  movq(pp, FieldAddress(CODE_REG, target::Code::object_pool_offset()));
   set_constant_pool_allowed(pp == PP);
 }
 
@@ -1590,8 +1595,8 @@
   // Restore caller's PP register that was pushed in EnterDartFrame.
   if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
     if (restore_pp == kRestoreCallerPP) {
-      movq(PP, Address(RBP, (compiler_frame_layout.saved_caller_pp_from_fp *
-                             kWordSize)));
+      movq(PP, Address(RBP, (target::frame_layout.saved_caller_pp_from_fp *
+                             target::kWordSize)));
     }
   }
   set_constant_pool_allowed(false);
@@ -1620,7 +1625,7 @@
     leaq(RAX, Address::AddressRIPRelative(-header_to_rip_offset));
     ASSERT(CodeSize() == (header_to_rip_offset - header_to_entry_offset));
   }
-  cmpq(RAX, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
+  cmpq(RAX, FieldAddress(CODE_REG, target::Code::saved_instructions_offset()));
   j(EQUAL, &instructions_ok);
   int3();
   Bind(&instructions_ok);
@@ -1704,16 +1709,16 @@
       Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid);
   movq(temp_reg, Address(temp_reg, table_offset));
   testb(Address(temp_reg, state_offset),
-        Immediate(ClassHeapStats::TraceAllocationMask()));
+        Immediate(target::ClassHeapStats::TraceAllocationMask()));
   // We are tracing for this class, jump to the trace label which will use
   // the allocation stub.
   j(NOT_ZERO, trace, near_jump);
 }
 
-void Assembler::UpdateAllocationStats(intptr_t cid, Heap::Space space) {
+void Assembler::UpdateAllocationStats(intptr_t cid) {
   ASSERT(cid > 0);
   intptr_t counter_offset =
-      ClassTable::CounterOffsetFor(cid, space == Heap::kNew);
+      ClassTable::CounterOffsetFor(cid, /*is_new_space=*/true);
   Register temp_reg = TMP;
   LoadIsolate(temp_reg);
   intptr_t table_offset =
@@ -1722,25 +1727,22 @@
   incq(Address(temp_reg, counter_offset));
 }
 
-void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
-                                              Register size_reg,
-                                              Heap::Space space) {
+void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, Register size_reg) {
   ASSERT(cid > 0);
   ASSERT(cid < kNumPredefinedCids);
-  UpdateAllocationStats(cid, space);
+  UpdateAllocationStats(cid);
   Register temp_reg = TMP;
-  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
+  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, /*is_new_space=*/true);
   addq(Address(temp_reg, size_offset), size_reg);
 }
 
 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid,
-                                              intptr_t size_in_bytes,
-                                              Heap::Space space) {
+                                              intptr_t size_in_bytes) {
   ASSERT(cid > 0);
   ASSERT(cid < kNumPredefinedCids);
-  UpdateAllocationStats(cid, space);
+  UpdateAllocationStats(cid);
   Register temp_reg = TMP;
-  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, space == Heap::kNew);
+  intptr_t size_offset = ClassTable::SizeOffsetFor(cid, /*is_new_space=*/true);
   addq(Address(temp_reg, size_offset), Immediate(size_in_bytes));
 }
 #endif  // !PRODUCT
@@ -1751,13 +1753,13 @@
                             Register instance_reg,
                             Register temp) {
   ASSERT(failure != NULL);
-  const intptr_t instance_size = cls.instance_size();
+  const intptr_t instance_size = target::Class::GetInstanceSize(cls);
   if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+    const classid_t cid = target::Class::GetId(cls);
     // If this allocation is traced, program will jump to failure path
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
-    NOT_IN_PRODUCT(MaybeTraceAllocation(cls.id(), failure, near_jump));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
+    NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, near_jump));
     movq(instance_reg, Address(THR, Thread::top_offset()));
     addq(instance_reg, Immediate(instance_size));
     // instance_reg: potential next object start.
@@ -1766,17 +1768,14 @@
     // Successfully allocated the object, now update top to point to
     // next object start and store the class in the class field of object.
     movq(Address(THR, Thread::top_offset()), instance_reg);
-    NOT_IN_PRODUCT(UpdateAllocationStats(cls.id(), space));
+    NOT_IN_PRODUCT(UpdateAllocationStats(cid));
     ASSERT(instance_size >= kHeapObjectTag);
     AddImmediate(instance_reg, Immediate(kHeapObjectTag - instance_size));
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
     // Extends the 32 bit tags with zeros, which is the uninitialized
     // hash code.
-    MoveImmediate(FieldAddress(instance_reg, Object::tags_offset()),
+    MoveImmediate(FieldAddress(instance_reg, target::Object::tags_offset()),
                   Immediate(tags));
   } else {
     jmp(failure);
@@ -1796,7 +1795,6 @@
     // (i.e. the allocation stub) which will allocate the object and trace the
     // allocation call site.
     NOT_IN_PRODUCT(MaybeTraceAllocation(cid, failure, near_jump));
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
     movq(instance, Address(THR, Thread::top_offset()));
     movq(end_address, instance);
 
@@ -1813,26 +1811,29 @@
     // next object start and initialize the object.
     movq(Address(THR, Thread::top_offset()), end_address);
     addq(instance, Immediate(kHeapObjectTag));
-    NOT_IN_PRODUCT(UpdateAllocationStatsWithSize(cid, instance_size, space));
+    NOT_IN_PRODUCT(UpdateAllocationStatsWithSize(cid, instance_size));
 
     // Initialize the tags.
     // instance: new object start as a tagged pointer.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, instance_size);
     // Extends the 32 bit tags with zeros, which is the uninitialized
     // hash code.
-    movq(FieldAddress(instance, Array::tags_offset()), Immediate(tags));
+    movq(FieldAddress(instance, target::Object::tags_offset()),
+         Immediate(tags));
   } else {
     jmp(failure);
   }
 }
 
-void Assembler::GenerateUnRelocatedPcRelativeCall() {
+void Assembler::GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   buffer_.Emit<uint8_t>(0xe8);
-  buffer_.Emit<int32_t>(0x68686868);
+  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) {
@@ -1963,6 +1964,7 @@
 }
 
 void Assembler::LoadClassId(Register result, Register object) {
+  using target::Object;
   ASSERT(RawObject::kClassIdTagPos == 16);
   ASSERT(RawObject::kClassIdTagSize == 16);
   ASSERT(sizeof(classid_t) == sizeof(uint16_t));
@@ -1977,7 +1979,7 @@
   const intptr_t offset =
       Isolate::class_table_offset() + ClassTable::table_offset();
   movq(result, Address(result, offset));
-  ASSERT(kSizeOfClassPairLog2 == 4);
+  ASSERT(ClassTable::kSizeOfClassPairLog2 == 4);
   // TIMES_16 is not a real scale factor on x64, so we double the class id
   // and use TIMES_8.
   addq(class_id, class_id);
@@ -1995,6 +1997,7 @@
 void Assembler::SmiUntagOrCheckClass(Register object,
                                      intptr_t class_id,
                                      Label* is_smi) {
+  using target::Object;
   ASSERT(kSmiTagShift == 1);
   ASSERT(RawObject::kClassIdTagPos == 16);
   ASSERT(RawObject::kClassIdTagSize == 16);
@@ -2049,7 +2052,7 @@
     jmp(&join, Assembler::kNearJump);
 
     Bind(&smi);
-    movq(result, Immediate(Smi::RawValue(kSmiCid)));
+    movq(result, Immediate(target::ToRawSmi(kSmiCid)));
 
     Bind(&join);
   } else {
@@ -2063,6 +2066,10 @@
   }
 }
 
+Address Assembler::VMTagAddress() {
+  return Address(THR, Thread::vm_tag_offset());
+}
+
 Address Assembler::ElementAddressForIntIndex(bool is_external,
                                              intptr_t cid,
                                              intptr_t index_scale,
@@ -2135,6 +2142,7 @@
   return cpu_reg_names[reg];
 }
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_X64)
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index dc61bb9..db70602 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -9,17 +9,21 @@
 #error Do not include assembler_x64.h directly; use assembler.h instead.
 #endif
 
+#include <functional>
+
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/constants_x64.h"
 #include "vm/constants_x86.h"
 #include "vm/hash_map.h"
-#include "vm/object.h"
+#include "vm/pointer_tagging.h"
 
 namespace dart {
 
 // Forward declarations.
-class RuntimeEntry;
+class FlowGraphCompiler;
+
+namespace compiler {
 
 class Immediate : public ValueObject {
  public:
@@ -276,7 +280,7 @@
 
 class Assembler : public AssemblerBase {
  public:
-  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+  explicit Assembler(ObjectPoolBuilder* object_pool_builder,
                      bool use_far_branches = false);
 
   ~Assembler() {}
@@ -470,6 +474,10 @@
   // for proper unwinding of Dart frames (use --generate_gdb_symbols and -O0).
   void movq(Register dst, Register src) { EmitQ(src, dst, 0x89); }
 
+  void movq(XmmRegister dst, Register src) {
+    EmitQ(dst, src, 0x6E, 0x0F, 0x66);
+  }
+
   void movd(XmmRegister dst, Register src) {
     EmitL(dst, src, 0x6E, 0x0F, 0x66);
   }
@@ -684,7 +692,7 @@
   void LoadUniqueObject(Register dst, const Object& obj);
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
-                       ObjectPool::Patchability patchable);
+                       ObjectPoolBuilderEntry::Patchability patchable);
   void LoadFunctionFromCalleePool(Register dst,
                                   const Function& function,
                                   Register new_pp);
@@ -692,7 +700,7 @@
   void Jmp(const Code& code, Register pp = PP);
   void J(Condition condition, const Code& code, Register pp);
   void CallPatchable(const Code& code,
-                     Code::EntryKind entry_kind = Code::EntryKind::kNormal);
+                     CodeEntryKind entry_kind = CodeEntryKind::kNormal);
   void Call(const Code& stub_entry);
   void CallToRuntime();
 
@@ -700,10 +708,9 @@
 
   // 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,
-      Code::EntryKind entry_kind = Code::EntryKind::kNormal);
+  void CallWithEquivalence(const Code& code,
+                           const Object& equivalence,
+                           CodeEntryKind entry_kind = CodeEntryKind::kNormal);
 
   // Unaware of write barrier (use StoreInto* methods for storing to objects).
   // TODO(koda): Add StackAddress/HeapAddress types to prevent misuse.
@@ -772,8 +779,6 @@
   void LeaveCallRuntimeFrame();
 
   void CallRuntime(const RuntimeEntry& entry, intptr_t argument_count);
-  void CallRuntimeSavingRegisters(const RuntimeEntry& entry,
-                                  intptr_t argument_count);
 
   // Call runtime function. Reserves shadow space on the stack before calling
   // if platform ABI requires that. Does not restore RSP after the call itself.
@@ -869,14 +874,10 @@
 
   void MonomorphicCheckedEntry();
 
-  void UpdateAllocationStats(intptr_t cid, Heap::Space space);
+  void UpdateAllocationStats(intptr_t cid);
 
-  void UpdateAllocationStatsWithSize(intptr_t cid,
-                                     Register size_reg,
-                                     Heap::Space space);
-  void UpdateAllocationStatsWithSize(intptr_t cid,
-                                     intptr_t instance_size,
-                                     Heap::Space space);
+  void UpdateAllocationStatsWithSize(intptr_t cid, Register size_reg);
+  void UpdateAllocationStatsWithSize(intptr_t cid, intptr_t instance_size);
 
   // If allocation tracing for |cid| is enabled, will jump to |trace| label,
   // which will allocate in the runtime where tracing occurs.
@@ -911,7 +912,11 @@
   //   (Code::kPcRelativeCall & pc_offset, <target-code>, <target-function>)
   //
   // will be used during relocation to fix the offset.
-  void GenerateUnRelocatedPcRelativeCall();
+  //
+  // The provided [offset_into_target] will be added to calculate the final
+  // destination.  It can be used e.g. for calling into the middle of a
+  // function.
+  void GenerateUnRelocatedPcRelativeCall(intptr_t offset_into_target = 0);
 
   // Debugging and bringup support.
   void Breakpoint() { int3(); }
@@ -934,14 +939,12 @@
                                            Register array,
                                            Register index);
 
-  static Address VMTagAddress() {
-    return Address(THR, Thread::vm_tag_offset());
-  }
+  static Address VMTagAddress();
 
   // On some other platforms, we draw a distinction between safe and unsafe
   // smis.
   static bool IsSafe(const Object& object) { return true; }
-  static bool IsSafeSmi(const Object& object) { return object.IsSmi(); }
+  static bool IsSafeSmi(const Object& object) { return target::IsSmi(object); }
 
  private:
   bool constant_pool_allowed_;
@@ -1040,10 +1043,10 @@
   // Unaware of write barrier (use StoreInto* methods for storing to objects).
   void MoveImmediate(const Address& dst, const Immediate& imm);
 
-  void ComputeCounterAddressesForCid(intptr_t cid,
-                                     Heap::Space space,
-                                     Address* count_address,
-                                     Address* size_address);
+  friend class dart::FlowGraphCompiler;
+  std::function<void(Register reg)> generate_invoke_write_barrier_wrapper_;
+  std::function<void()> generate_invoke_array_write_barrier_;
+
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Assembler);
 };
@@ -1095,6 +1098,13 @@
   EmitUint8(0x66);
 }
 
+}  // namespace compiler
+
+using compiler::Address;
+using compiler::FieldAddress;
+using compiler::Immediate;
+using compiler::Label;
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_ASSEMBLER_ASSEMBLER_X64_H_
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index c06b96a..9e380a4 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -11,6 +11,7 @@
 #include "vm/virtual_memory.h"
 
 namespace dart {
+namespace compiler {
 
 #define __ assembler->
 
@@ -72,33 +73,33 @@
   __ movq(RAX, Address(R13, 0));
   __ movq(R10, Address(RAX, 0));
 
-  __ movq(RAX, Address(RSP, kWordSize));
-  __ movq(RAX, Address(RBP, kWordSize));
-  __ movq(RAX, Address(RAX, kWordSize));
-  __ movq(RAX, Address(R10, kWordSize));
-  __ movq(RAX, Address(R12, kWordSize));
-  __ movq(RAX, Address(R13, kWordSize));
+  __ movq(RAX, Address(RSP, target::kWordSize));
+  __ movq(RAX, Address(RBP, target::kWordSize));
+  __ movq(RAX, Address(RAX, target::kWordSize));
+  __ movq(RAX, Address(R10, target::kWordSize));
+  __ movq(RAX, Address(R12, target::kWordSize));
+  __ movq(RAX, Address(R13, target::kWordSize));
 
-  __ movq(RAX, Address(RSP, -kWordSize));
-  __ movq(RAX, Address(RBP, -kWordSize));
-  __ movq(RAX, Address(RAX, -kWordSize));
-  __ movq(RAX, Address(R10, -kWordSize));
-  __ movq(RAX, Address(R12, -kWordSize));
-  __ movq(RAX, Address(R13, -kWordSize));
+  __ movq(RAX, Address(RSP, -target::kWordSize));
+  __ movq(RAX, Address(RBP, -target::kWordSize));
+  __ movq(RAX, Address(RAX, -target::kWordSize));
+  __ movq(RAX, Address(R10, -target::kWordSize));
+  __ movq(RAX, Address(R12, -target::kWordSize));
+  __ movq(RAX, Address(R13, -target::kWordSize));
 
-  __ movq(RAX, Address(RSP, 256 * kWordSize));
-  __ movq(RAX, Address(RBP, 256 * kWordSize));
-  __ movq(RAX, Address(RAX, 256 * kWordSize));
-  __ movq(RAX, Address(R10, 256 * kWordSize));
-  __ movq(RAX, Address(R12, 256 * kWordSize));
-  __ movq(RAX, Address(R13, 256 * kWordSize));
+  __ movq(RAX, Address(RSP, 256 * target::kWordSize));
+  __ movq(RAX, Address(RBP, 256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, 256 * target::kWordSize));
+  __ movq(RAX, Address(R10, 256 * target::kWordSize));
+  __ movq(RAX, Address(R12, 256 * target::kWordSize));
+  __ movq(RAX, Address(R13, 256 * target::kWordSize));
 
-  __ movq(RAX, Address(RSP, -256 * kWordSize));
-  __ movq(RAX, Address(RBP, -256 * kWordSize));
-  __ movq(RAX, Address(RAX, -256 * kWordSize));
-  __ movq(RAX, Address(R10, -256 * kWordSize));
-  __ movq(RAX, Address(R12, -256 * kWordSize));
-  __ movq(RAX, Address(R13, -256 * kWordSize));
+  __ movq(RAX, Address(RSP, -256 * target::kWordSize));
+  __ movq(RAX, Address(RBP, -256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, -256 * target::kWordSize));
+  __ movq(RAX, Address(R10, -256 * target::kWordSize));
+  __ movq(RAX, Address(R12, -256 * target::kWordSize));
+  __ movq(RAX, Address(R13, -256 * target::kWordSize));
 
   __ movq(RAX, Address(RAX, TIMES_1, 0));
   __ movq(RAX, Address(RAX, TIMES_2, 0));
@@ -111,17 +112,17 @@
   __ movq(RAX, Address(R12, TIMES_2, 0));
   __ movq(RAX, Address(R13, TIMES_2, 0));
 
-  __ movq(RAX, Address(RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R13, TIMES_2, 256 * target::kWordSize));
 
   __ movq(RAX, Address(RAX, RBP, TIMES_2, 0));
   __ movq(RAX, Address(RAX, RAX, TIMES_2, 0));
@@ -159,77 +160,77 @@
   __ movq(RAX, Address(R13, R12, TIMES_2, 0));
   __ movq(RAX, Address(R13, R13, TIMES_2, 0));
 
-  __ movq(RAX, Address(RAX, RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RAX, RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RAX, R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RAX, R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RAX, R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(RAX, RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RAX, RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RAX, R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RAX, R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RAX, R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(RBP, RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RBP, RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RBP, R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RBP, R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RBP, R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(RBP, RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RBP, RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RBP, R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RBP, R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RBP, R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(RSP, RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RSP, RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RSP, R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RSP, R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(RSP, R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(RSP, RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RSP, RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RSP, R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RSP, R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(RSP, R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(R10, RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R10, RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R10, R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R10, R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R10, R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(R10, RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R10, RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R10, R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R10, R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R10, R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(R12, RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R12, RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R12, R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R12, R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R12, R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(R12, RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R12, RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R12, R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R12, R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R12, R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(R13, RBP, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R13, RAX, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R13, R10, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R13, R12, TIMES_2, kWordSize));
-  __ movq(RAX, Address(R13, R13, TIMES_2, kWordSize));
+  __ movq(RAX, Address(R13, RBP, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R13, RAX, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R13, R10, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R13, R12, TIMES_2, target::kWordSize));
+  __ movq(RAX, Address(R13, R13, TIMES_2, target::kWordSize));
 
-  __ movq(RAX, Address(RAX, RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RAX, RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RAX, R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RAX, R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RAX, R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(RAX, RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RAX, R13, TIMES_2, 256 * target::kWordSize));
 
-  __ movq(RAX, Address(RBP, RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RBP, RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RBP, R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RBP, R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RBP, R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(RBP, RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RBP, RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RBP, R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RBP, R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RBP, R13, TIMES_2, 256 * target::kWordSize));
 
-  __ movq(RAX, Address(RSP, RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RSP, RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RSP, R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RSP, R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(RSP, R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(RSP, RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RSP, RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RSP, R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RSP, R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(RSP, R13, TIMES_2, 256 * target::kWordSize));
 
-  __ movq(RAX, Address(R10, RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R10, RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R10, R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R10, R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R10, R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(R10, RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R10, RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R10, R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R10, R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R10, R13, TIMES_2, 256 * target::kWordSize));
 
-  __ movq(RAX, Address(R12, RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R12, RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R12, R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R12, R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R12, R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(R12, RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R12, RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R12, R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R12, R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R12, R13, TIMES_2, 256 * target::kWordSize));
 
-  __ movq(RAX, Address(R13, RBP, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R13, RAX, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R13, R10, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R13, R12, TIMES_2, 256 * kWordSize));
-  __ movq(RAX, Address(R13, R13, TIMES_2, 256 * kWordSize));
+  __ movq(RAX, Address(R13, RBP, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R13, RAX, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R13, R10, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R13, R12, TIMES_2, 256 * target::kWordSize));
+  __ movq(RAX, Address(R13, R13, TIMES_2, 256 * target::kWordSize));
 
   __ movq(RAX, Address::AddressBaseImm32(RSP, 0));
   __ movq(RAX, Address::AddressBaseImm32(RBP, 0));
@@ -239,19 +240,19 @@
   __ movq(RAX, Address::AddressBaseImm32(R13, 0));
   __ movq(R10, Address::AddressBaseImm32(RAX, 0));
 
-  __ movq(RAX, Address::AddressBaseImm32(RSP, kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(RBP, kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(RAX, kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(R10, kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(R12, kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(R13, kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(RSP, target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(RBP, target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(RAX, target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(R10, target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(R12, target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(R13, target::kWordSize));
 
-  __ movq(RAX, Address::AddressBaseImm32(RSP, -kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(RBP, -kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(RAX, -kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(R10, -kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(R12, -kWordSize));
-  __ movq(RAX, Address::AddressBaseImm32(R13, -kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(RSP, -target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(RBP, -target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(RAX, -target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(R10, -target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(R12, -target::kWordSize));
+  __ movq(RAX, Address::AddressBaseImm32(R13, -target::kWordSize));
 }
 
 ASSEMBLER_TEST_RUN(AddressingModes, test) {
@@ -1163,7 +1164,7 @@
   __ movzxb(RAX, Address(RSP, 0));  // RAX = 0xff
   __ movsxw(R8, Address(RSP, 0));   // R8 = -1
   __ movzxw(RCX, Address(RSP, 0));  // RCX = 0xffff
-  __ addq(RSP, Immediate(kWordSize));
+  __ addq(RSP, Immediate(target::kWordSize));
 
   __ addq(R8, RCX);
   __ addq(RAX, R8);
@@ -1189,9 +1190,9 @@
 ASSEMBLER_TEST_GENERATE(MoveExtend32Memory, assembler) {
   __ pushq(Immediate(0xffffffff));
   __ pushq(Immediate(0x7fffffff));
-  __ movsxd(RDX, Address(RSP, kWordSize));
+  __ movsxd(RDX, Address(RSP, target::kWordSize));
   __ movsxd(RAX, Address(RSP, 0));
-  __ addq(RSP, Immediate(kWordSize * 2));
+  __ addq(RSP, Immediate(target::kWordSize * 2));
 
   __ addq(RAX, RDX);
   __ ret();
@@ -1218,7 +1219,7 @@
   __ movq(RCX, Immediate(-1));
   __ movw(Address(RAX, 0), RCX);
   __ movzxw(RAX, Address(RAX, 0));  // RAX = 0xffff
-  __ addq(RSP, Immediate(kWordSize));
+  __ addq(RSP, Immediate(target::kWordSize));
   __ ret();
 }
 
@@ -1298,7 +1299,7 @@
   __ movzxw(R8, Address(R8, 0));  // 0xffff
   __ xorq(RAX, RAX);
   __ addq(RAX, R8);  // RAX = 0xffff
-  __ addq(RSP, Immediate(kWordSize));
+  __ addq(RSP, Immediate(target::kWordSize));
   __ ret();
 }
 
@@ -1615,10 +1616,10 @@
   __ pushq(CallingConventions::kArg3Reg);
   __ pushq(CallingConventions::kArg2Reg);
   __ pushq(CallingConventions::kArg1Reg);
-  __ movq(R10, Address(RSP, 0 * kWordSize));  // al.
-  __ addq(R10, Address(RSP, 2 * kWordSize));  // bl.
-  __ movq(RAX, Address(RSP, 1 * kWordSize));  // ah.
-  __ adcq(RAX, Address(RSP, 3 * kWordSize));  // bh.
+  __ movq(R10, Address(RSP, 0 * target::kWordSize));  // al.
+  __ addq(R10, Address(RSP, 2 * target::kWordSize));  // bl.
+  __ movq(RAX, Address(RSP, 1 * target::kWordSize));  // ah.
+  __ adcq(RAX, Address(RSP, 3 * target::kWordSize));  // bh.
   // RAX = high64(ah:al + bh:bl).
   __ Drop(4);
   __ ret();
@@ -1711,10 +1712,10 @@
   __ pushq(CallingConventions::kArg3Reg);
   __ pushq(CallingConventions::kArg2Reg);
   __ pushq(CallingConventions::kArg1Reg);
-  __ movq(R10, Address(RSP, 0 * kWordSize));  // al.
-  __ subq(R10, Address(RSP, 2 * kWordSize));  // bl.
-  __ movq(RAX, Address(RSP, 1 * kWordSize));  // ah.
-  __ sbbq(RAX, Address(RSP, 3 * kWordSize));  // bh.
+  __ movq(R10, Address(RSP, 0 * target::kWordSize));  // al.
+  __ subq(R10, Address(RSP, 2 * target::kWordSize));  // bl.
+  __ movq(RAX, Address(RSP, 1 * target::kWordSize));  // ah.
+  __ sbbq(RAX, Address(RSP, 3 * target::kWordSize));  // bh.
   // RAX = high64(ah:al - bh:bl).
   __ Drop(4);
   __ ret();
@@ -5417,9 +5418,9 @@
   __ pushq(CallingConventions::kArg1Reg);     // from.
   __ pushq(CallingConventions::kArg2Reg);     // to.
   __ pushq(CallingConventions::kArg3Reg);     // count.
-  __ movq(RSI, Address(RSP, 2 * kWordSize));  // from.
-  __ movq(RDI, Address(RSP, 1 * kWordSize));  // to.
-  __ movq(RCX, Address(RSP, 0 * kWordSize));  // count.
+  __ movq(RSI, Address(RSP, 2 * target::kWordSize));  // from.
+  __ movq(RDI, Address(RSP, 1 * target::kWordSize));  // to.
+  __ movq(RCX, Address(RSP, 0 * target::kWordSize));  // count.
   __ rep_movsb();
   // Remove saved arguments.
   __ popq(RAX);
@@ -5835,6 +5836,8 @@
                __ pushq(RAX),
                Address(RSP, 0),
                __ popq(RAX))
+
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/compiler/assembler/disassembler.h b/runtime/vm/compiler/assembler/disassembler.h
index f23f08c..a58339a 100644
--- a/runtime/vm/compiler/assembler/disassembler.h
+++ b/runtime/vm/compiler/assembler/disassembler.h
@@ -9,6 +9,7 @@
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/globals.h"
 #include "vm/log.h"
+#include "vm/object.h"
 
 namespace dart {
 
diff --git a/runtime/vm/compiler/assembler/disassembler_arm.cc b/runtime/vm/compiler/assembler/disassembler_arm.cc
index d3880c0..f5266ae 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm.cc
@@ -655,16 +655,6 @@
         case 7: {
           if ((instr->Bits(21, 2) == 0x1) && (instr->ConditionField() == AL)) {
             Format(instr, "bkpt #'imm12_4");
-            if (instr->BkptField() == Instr::kStopMessageCode) {
-              const char* message = "Stop messages not enabled";
-              if (FLAG_print_stop_message) {
-                message = *reinterpret_cast<const char**>(
-                    reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
-              }
-              buffer_pos_ += Utils::SNPrint(current_position_in_buffer(),
-                                            remaining_size_in_buffer(),
-                                            " ; \"%s\"", message);
-            }
           } else {
             // Format(instr, "smc'cond");
             Unknown(instr);  // Not used.
diff --git a/runtime/vm/compiler/assembler/disassembler_arm64.cc b/runtime/vm/compiler/assembler/disassembler_arm64.cc
index 2abe750..e074048 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm64.cc
@@ -885,16 +885,6 @@
   } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
              (instr->Bits(21, 3) == 1)) {
     Format(instr, "brk 'imm16");
-    if (instr->Imm16Field() == Instr::kStopMessageCode) {
-      const char* message = "Stop messages not enabled";
-      if (FLAG_print_stop_message) {
-        message = *reinterpret_cast<const char**>(
-            reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize);
-      }
-      buffer_pos_ +=
-          Utils::SNPrint(current_position_in_buffer(),
-                         remaining_size_in_buffer(), " ; \"%s\"", message);
-    }
   } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
              (instr->Bits(21, 3) == 2)) {
     Format(instr, "hlt 'imm16");
diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc
index 151429a..e0c7f8a 100644
--- a/runtime/vm/compiler/assembler/disassembler_kbc.cc
+++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc
@@ -234,7 +234,7 @@
   KBCInstr instr = KernelBytecode::At(pc);
   if (HasLoadFromPool(instr)) {
     uint16_t index = KernelBytecode::DecodeD(instr);
-    if (object_pool.TypeAt(index) == ObjectPool::kTaggedObject) {
+    if (object_pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
       *obj = object_pool.ObjectAt(index);
       return true;
     }
diff --git a/runtime/vm/compiler/assembler/disassembler_test.cc b/runtime/vm/compiler/assembler/disassembler_test.cc
index fa208ec..2ced70e 100644
--- a/runtime/vm/compiler/assembler/disassembler_test.cc
+++ b/runtime/vm/compiler/assembler/disassembler_test.cc
@@ -14,8 +14,8 @@
 #if !defined(PRODUCT) && !defined(TARGET_ARCH_DBC)
 
 ISOLATE_UNIT_TEST_CASE(Disassembler) {
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
 
   // The used instructions work on all platforms.
   Register reg = static_cast<Register>(0);
diff --git a/runtime/vm/compiler/assembler/disassembler_x86.cc b/runtime/vm/compiler/assembler/disassembler_x86.cc
index 01e0c0c..fb00c01 100644
--- a/runtime/vm/compiler/assembler/disassembler_x86.cc
+++ b/runtime/vm/compiler/assembler/disassembler_x86.cc
@@ -308,7 +308,7 @@
   }
 
   const char* NameOfCPURegister(int reg) const {
-    return Assembler::RegisterName(static_cast<Register>(reg));
+    return compiler::Assembler::RegisterName(static_cast<Register>(reg));
   }
 
   const char* NameOfByteCPURegister(int reg) const {
@@ -344,7 +344,6 @@
   const char* TwoByteMnemonic(uint8_t opcode);
   int TwoByteOpcodeInstruction(uint8_t* data);
   int Print660F38Instruction(uint8_t* data);
-  void CheckPrintStop(uint8_t* data);
 
   int F6F7Instruction(uint8_t* data);
   int ShiftInstruction(uint8_t* data);
@@ -1229,20 +1228,6 @@
   }
 }
 
-// Called when disassembling test eax, 0xXXXXX.
-void DisassemblerX64::CheckPrintStop(uint8_t* data) {
-#if defined(TARGET_ARCH_IA32)
-  // Recognize stop pattern.
-  if (*data == 0xCC) {
-    const char* message = "Stop messages not enabled";
-    if (FLAG_print_stop_message) {
-      message = *reinterpret_cast<const char**>(data - 4);
-    }
-    Print("  STOP:'%s'", message);
-  }
-#endif
-}
-
 // Handle all two-byte opcodes, which start with 0x0F.
 // These instructions may be affected by an 0x66, 0xF2, or 0xF3 prefix.
 // We do not use any three-byte opcodes, which start with 0x0F38 or 0x0F3A.
@@ -1854,12 +1839,8 @@
 
       case 0xA9: {
         data++;
-        bool check_for_stop = operand_size() == DOUBLEWORD_SIZE;
         Print("test%s %s,", operand_size_code(), Rax());
         data += PrintImmediate(data, operand_size());
-        if (check_for_stop) {
-          CheckPrintStop(data);
-        }
         break;
       }
       case 0xD1:  // fall through
diff --git a/runtime/vm/compiler/assembler/object_pool_builder.h b/runtime/vm/compiler/assembler/object_pool_builder.h
new file mode 100644
index 0000000..2202954
--- /dev/null
+++ b/runtime/vm/compiler/assembler/object_pool_builder.h
@@ -0,0 +1,187 @@
+// 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.
+
+#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
+#define RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
+
+#include "platform/globals.h"
+#include "vm/bitfield.h"
+#include "vm/hash_map.h"
+
+namespace dart {
+
+class Object;
+
+namespace compiler {
+
+class ExternalLabel;
+
+bool IsSameObject(const Object& a, const Object& b);
+
+struct ObjectPoolBuilderEntry {
+  enum Patchability {
+    kPatchable,
+    kNotPatchable,
+  };
+
+  enum EntryType {
+    kTaggedObject,
+    kImmediate,
+    kNativeFunction,
+    kNativeFunctionWrapper,
+    kNativeEntryData,
+  };
+
+  using TypeBits = BitField<uint8_t, EntryType, 0, 7>;
+  using PatchableBit = BitField<uint8_t, Patchability, TypeBits::kNextBit, 1>;
+
+  static inline uint8_t EncodeTraits(EntryType type, Patchability patchable) {
+    return TypeBits::encode(type) | PatchableBit::encode(patchable);
+  }
+
+  ObjectPoolBuilderEntry() : raw_value_(), entry_bits_(0), equivalence_() {}
+  ObjectPoolBuilderEntry(const Object* obj, Patchability patchable)
+      : ObjectPoolBuilderEntry(obj, obj, patchable) {}
+  ObjectPoolBuilderEntry(const Object* obj,
+                         const Object* eqv,
+                         Patchability patchable)
+      : obj_(obj),
+        entry_bits_(EncodeTraits(kTaggedObject, patchable)),
+        equivalence_(eqv) {}
+  ObjectPoolBuilderEntry(uword value, EntryType info, Patchability patchable)
+      : raw_value_(value),
+        entry_bits_(EncodeTraits(info, patchable)),
+        equivalence_() {}
+
+  EntryType type() const { return TypeBits::decode(entry_bits_); }
+
+  Patchability patchable() const { return PatchableBit::decode(entry_bits_); }
+
+  union {
+    const Object* obj_;
+    uword raw_value_;
+  };
+  uint8_t entry_bits_;
+  const Object* equivalence_;
+};
+
+// Pair type parameter for DirectChainedHashMap used for the constant pool.
+class ObjIndexPair {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef ObjectPoolBuilderEntry Key;
+  typedef intptr_t Value;
+  typedef ObjIndexPair Pair;
+
+  static const intptr_t kNoIndex = -1;
+
+  ObjIndexPair()
+      : key_(reinterpret_cast<uword>(nullptr),
+             ObjectPoolBuilderEntry::kTaggedObject,
+             ObjectPoolBuilderEntry::kPatchable),
+        value_(kNoIndex) {}
+
+  ObjIndexPair(Key key, Value value) : value_(value) {
+    key_.entry_bits_ = key.entry_bits_;
+    if (key.type() == ObjectPoolBuilderEntry::kTaggedObject) {
+      key_.obj_ = key.obj_;
+      key_.equivalence_ = key.equivalence_;
+    } else {
+      key_.raw_value_ = key.raw_value_;
+    }
+  }
+
+  static Key KeyOf(Pair kv) { return kv.key_; }
+
+  static Value ValueOf(Pair kv) { return kv.value_; }
+
+  static intptr_t Hashcode(Key key);
+
+  static inline bool IsKeyEqual(Pair kv, Key key) {
+    if (kv.key_.entry_bits_ != key.entry_bits_) return false;
+    if (kv.key_.type() == ObjectPoolBuilderEntry::kTaggedObject) {
+      return IsSameObject(*kv.key_.obj_, *key.obj_) &&
+             IsSameObject(*kv.key_.equivalence_, *key.equivalence_);
+    }
+    return kv.key_.raw_value_ == key.raw_value_;
+  }
+
+ private:
+  Key key_;
+  Value value_;
+};
+
+class ObjectPoolBuilder : public ValueObject {
+ public:
+  ObjectPoolBuilder() : zone_(nullptr) {}
+  ~ObjectPoolBuilder() {
+    if (zone_ != nullptr) {
+      Reset();
+      zone_ = nullptr;
+    }
+  }
+
+  // Clears all existing entries in this object pool builder.
+  //
+  // Note: Any code which has been compiled via this builder might use offsets
+  // into the pool which are not correct anymore.
+  void Reset();
+
+  // Initialize this object pool builder with a [zone].
+  //
+  // Any objects added later on will be referenced using handles from [zone].
+  void InitializeWithZone(Zone* zone) {
+    ASSERT(object_pool_.length() == 0);
+    ASSERT(zone_ == nullptr && zone != nullptr);
+    zone_ = zone;
+  }
+
+  intptr_t AddObject(const Object& obj,
+                     ObjectPoolBuilderEntry::Patchability patchable =
+                         ObjectPoolBuilderEntry::kNotPatchable);
+  intptr_t AddImmediate(uword imm);
+
+  intptr_t FindObject(const Object& obj,
+                      ObjectPoolBuilderEntry::Patchability patchable =
+                          ObjectPoolBuilderEntry::kNotPatchable);
+  intptr_t FindObject(const Object& obj, const Object& equivalence);
+  intptr_t FindImmediate(uword imm);
+  intptr_t FindNativeFunction(const ExternalLabel* label,
+                              ObjectPoolBuilderEntry::Patchability patchable);
+  intptr_t FindNativeFunctionWrapper(
+      const ExternalLabel* label,
+      ObjectPoolBuilderEntry::Patchability patchable);
+
+  intptr_t CurrentLength() const { return object_pool_.length(); }
+  ObjectPoolBuilderEntry& EntryAt(intptr_t i) { return object_pool_[i]; }
+  const ObjectPoolBuilderEntry& EntryAt(intptr_t i) const {
+    return object_pool_[i];
+  }
+
+  intptr_t AddObject(ObjectPoolBuilderEntry entry);
+
+ private:
+  intptr_t FindObject(ObjectPoolBuilderEntry entry);
+
+  // Objects and jump targets.
+  GrowableArray<ObjectPoolBuilderEntry> object_pool_;
+
+  // Hashmap for fast lookup in object pool.
+  DirectChainedHashMap<ObjIndexPair> object_pool_index_table_;
+
+  // The zone used for allocating the handles we keep in the map and array (or
+  // NULL, in which case allocations happen using the zone active at the point
+  // of insertion).
+  Zone* zone_;
+};
+
+}  // namespace compiler
+
+}  // namespace dart
+
+namespace dart {
+using compiler::ObjectPoolBuilder;
+}
+
+#endif  // RUNTIME_VM_COMPILER_ASSEMBLER_OBJECT_POOL_BUILDER_H_
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index 217ab1e..ded5fa6 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -80,7 +80,13 @@
   // abstract type. The pair is assumed to be coherent.
   static CompileType Create(intptr_t cid, const AbstractType& type);
 
-  CompileType CopyNonNullable() const {
+  // Return the non-nullable version of this type.
+  CompileType CopyNonNullable() {
+    if (IsNull()) {
+      // Represent a non-nullable null type (typically arising for
+      // unreachable values) as None.
+      return None();
+    }
     return CompileType(kNonNullable, kIllegalCid, type_);
   }
 
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 47e4be6..56f2a36 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -272,6 +272,14 @@
 void ConstantPropagator::VisitCheckEitherNonSmi(CheckEitherNonSmiInstr* instr) {
 }
 
+void ConstantPropagator::VisitStoreIndexedUnsafe(
+    StoreIndexedUnsafeInstr* instr) {}
+
+void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {}
+
+void ConstantPropagator::VisitStoreInstanceField(
+    StoreInstanceFieldInstr* instr) {}
+
 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) {
   // TODO(vegorov) remove all code after DeoptimizeInstr as dead.
 }
@@ -402,6 +410,23 @@
 }
 
 void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) {
+  const Function& function = instr->function();
+  switch (MethodRecognizer::RecognizeKind(function)) {
+    case MethodRecognizer::kOneByteString_equality:
+    case MethodRecognizer::kTwoByteString_equality: {
+      ASSERT(instr->FirstArgIndex() == 0);
+      // Use pure identity as a fast equality test.
+      if (instr->ArgumentAt(0)->OriginalDefinition() ==
+          instr->ArgumentAt(1)->OriginalDefinition()) {
+        SetValue(instr, Bool::True());
+        return;
+      }
+      break;
+    }
+    default:
+      // TODO(ajcbik): consider more cases
+      break;
+  }
   SetValue(instr, non_constant_);
 }
 
@@ -684,20 +709,6 @@
   SetValue(instr, non_constant_);
 }
 
-void ConstantPropagator::VisitStoreIndexedUnsafe(
-    StoreIndexedUnsafeInstr* instr) {
-  SetValue(instr, non_constant_);
-}
-
-void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
-  SetValue(instr, instr->value()->definition()->constant_value());
-}
-
-void ConstantPropagator::VisitStoreInstanceField(
-    StoreInstanceFieldInstr* instr) {
-  SetValue(instr, instr->value()->definition()->constant_value());
-}
-
 void ConstantPropagator::VisitInitStaticField(InitStaticFieldInstr* instr) {
   // Nothing to do.
 }
@@ -1364,6 +1375,14 @@
   }
 }
 
+static void RemovePushArguments(StaticCallInstr* call) {
+  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+    PushArgumentInstr* push = call->PushArgumentAt(i);
+    push->ReplaceUsesWith(push->value()->definition());
+    push->RemoveFromGraph();
+  }
+}
+
 void ConstantPropagator::Transform() {
   // We will recompute dominators, block ordering, block ids, block last
   // instructions, previous pointers, predecessors, etc. after eliminating
@@ -1454,6 +1473,9 @@
           value = Instance::Cast(value).CheckAndCanonicalize(T, &error_str);
           ASSERT(!value.IsNull() && (error_str == nullptr));
         }
+        if (auto call = defn->AsStaticCall()) {
+          RemovePushArguments(call);
+        }
         ConstantInstr* constant = graph_->GetConstant(value);
         defn->ReplaceUsesWith(constant);
         i.RemoveCurrentFromGraph();
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index b5d2201..b8806bd 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -284,8 +284,8 @@
       merged->Add(successor->postorder_number());
       changed = true;
       if (FLAG_trace_optimization) {
-        OS::PrintErr("Merged blocks B%" Pd " and B%" Pd "\n", block->block_id(),
-                     successor->block_id());
+        THR_Print("Merged blocks B%" Pd " and B%" Pd "\n", block->block_id(),
+                  successor->block_id());
       }
     }
     // The new block inherits the block id of the last successor to maintain
@@ -696,25 +696,25 @@
 }
 
 static void PrintBitVector(const char* tag, BitVector* v) {
-  OS::PrintErr("%s:", tag);
+  THR_Print("%s:", tag);
   for (BitVector::Iterator it(v); !it.Done(); it.Advance()) {
-    OS::PrintErr(" %" Pd "", it.Current());
+    THR_Print(" %" Pd "", it.Current());
   }
-  OS::PrintErr("\n");
+  THR_Print("\n");
 }
 
 void LivenessAnalysis::Dump() {
   const intptr_t block_count = postorder_.length();
   for (intptr_t i = 0; i < block_count; i++) {
     BlockEntryInstr* block = postorder_[i];
-    OS::PrintErr("block @%" Pd " -> ", block->block_id());
+    THR_Print("block @%" Pd " -> ", block->block_id());
 
     Instruction* last = block->last_instruction();
     for (intptr_t j = 0; j < last->SuccessorCount(); j++) {
       BlockEntryInstr* succ = last->SuccessorAt(j);
-      OS::PrintErr(" @%" Pd "", succ->block_id());
+      THR_Print(" @%" Pd "", succ->block_id());
     }
-    OS::PrintErr("\n");
+    THR_Print("\n");
 
     PrintBitVector("  live out", live_out_[i]);
     PrintBitVector("  kill", kill_[i]);
@@ -1559,7 +1559,13 @@
     }
   }
   RedefinitionInstr* redef = new RedefinitionInstr(new Value(original));
-  redef->set_constrained_type(new CompileType(compile_type));
+
+  // Don't set the constrained type when the type is None(), which denotes an
+  // unreachable value (e.g. using value null after an explicit null check).
+  if (!compile_type.IsNone()) {
+    redef->set_constrained_type(new CompileType(compile_type));
+  }
+
   InsertAfter(prev, redef, NULL, FlowGraph::kValue);
   RenameDominatedUses(original, redef, redef);
   return redef;
@@ -1807,8 +1813,36 @@
       break;
   }
 
-  if ((unboxed == kTagged) && phi->Type()->IsInt() &&
-      RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt64)) {
+  // If all the inputs are unboxed, leave the Phi unboxed.
+  if ((unboxed == kTagged) && phi->Type()->IsInt()) {
+    bool should_unbox = true;
+    Representation new_representation = kTagged;
+    for (intptr_t i = 0; i < phi->InputCount(); i++) {
+      Definition* input = phi->InputAt(i)->definition();
+      if (input->representation() != kUnboxedInt64 &&
+          input->representation() != kUnboxedInt32 &&
+          input->representation() != kUnboxedUint32 && !(input == phi)) {
+        should_unbox = false;
+        break;
+      }
+
+      if (new_representation == kTagged) {
+        new_representation = input->representation();
+      } else if (new_representation != input->representation()) {
+        new_representation = kNoRepresentation;
+      }
+    }
+    if (should_unbox) {
+      unboxed = new_representation != kNoRepresentation
+                    ? new_representation
+                    : RangeUtils::Fits(phi->range(),
+                                       RangeBoundary::kRangeBoundaryInt32)
+                          ? kUnboxedInt32
+                          : kUnboxedInt64;
+    }
+  }
+
+  if ((unboxed == kTagged) && phi->Type()->IsInt()) {
     // Conservatively unbox phis that:
     //   - are proven to be of type Int;
     //   - fit into 64bits range;
@@ -1818,9 +1852,7 @@
     bool should_unbox = false;
     for (intptr_t i = 0; i < phi->InputCount(); i++) {
       Definition* input = phi->InputAt(i)->definition();
-      if (input->IsBox() &&
-          RangeUtils::Fits(input->range(),
-                           RangeBoundary::kRangeBoundaryInt64)) {
+      if (input->IsBox()) {
         should_unbox = true;
       } else if (!input->IsConstant()) {
         should_unbox = false;
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 854aa81..0012962 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -17,6 +17,10 @@
 class LoopHierarchy;
 class VariableLivenessAnalysis;
 
+namespace compiler {
+class GraphIntrinsifier;
+}
+
 class BlockIterator : public ValueObject {
  public:
   explicit BlockIterator(const GrowableArray<BlockEntryInstr*>& block_order)
@@ -410,11 +414,12 @@
 
  private:
   friend class FlowGraphCompiler;  // TODO(ajcbik): restructure
+  friend class FlowGraphChecker;
   friend class IfConverter;
   friend class BranchSimplifier;
   friend class ConstantPropagator;
   friend class DeadCodeElimination;
-  friend class Intrinsifier;
+  friend class compiler::GraphIntrinsifier;
 
   // SSA transformation methods and fields.
   void ComputeDominators(GrowableArray<BitVector*>* dominance_frontier);
diff --git a/runtime/vm/compiler/backend/flow_graph_checker.cc b/runtime/vm/compiler/backend/flow_graph_checker.cc
new file mode 100644
index 0000000..a07ed6d
--- /dev/null
+++ b/runtime/vm/compiler/backend/flow_graph_checker.cc
@@ -0,0 +1,210 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"
+
+#include "vm/compiler/backend/flow_graph.h"
+#include "vm/compiler/backend/il.h"
+#include "vm/compiler/backend/loops.h"
+
+namespace dart {
+
+// Returns true if block is a predecessor of succ.
+static bool IsPred(BlockEntryInstr* block, BlockEntryInstr* succ) {
+  for (intptr_t i = 0, n = succ->PredecessorCount(); i < n; ++i) {
+    if (succ->PredecessorAt(i) == block) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Returns true if block is a successor of pred.
+static bool IsSucc(BlockEntryInstr* block, BlockEntryInstr* pred) {
+  Instruction* last = pred->last_instruction();
+  for (intptr_t i = 0, n = last->SuccessorCount(); i < n; ++i) {
+    if (last->SuccessorAt(i) == block) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Returns true if dom directly dominates block.
+static bool IsDirectlyDominated(BlockEntryInstr* block, BlockEntryInstr* dom) {
+  for (intptr_t i = 0, n = dom->dominated_blocks().length(); i < n; ++i) {
+    if (dom->dominated_blocks()[i] == block) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Returns true if instruction forces control flow.
+static bool IsControlFlow(Instruction* instruction) {
+  return instruction->IsBranch() || instruction->IsGoto() ||
+         instruction->IsIndirectGoto() || instruction->IsReturn() ||
+         instruction->IsThrow() || instruction->IsReThrow() ||
+         instruction->IsStop() || instruction->IsTailCall();
+}
+
+void FlowGraphChecker::VisitBlocks() {
+  const GrowableArray<BlockEntryInstr*>& preorder = flow_graph_->preorder();
+  const GrowableArray<BlockEntryInstr*>& postorder = flow_graph_->postorder();
+  const GrowableArray<BlockEntryInstr*>& rev_postorder =
+      flow_graph_->reverse_postorder();
+
+  // Make sure lengths match.
+  const intptr_t block_count = preorder.length();
+  ASSERT(block_count == postorder.length());
+  ASSERT(block_count == rev_postorder.length());
+
+  // Make sure postorder has true reverse.
+  for (intptr_t i = 0; i < block_count; ++i) {
+    ASSERT(postorder[i] == rev_postorder[block_count - i - 1]);
+  }
+
+  // Iterate over all basic blocks.
+  const intptr_t max_block_id = flow_graph_->max_block_id();
+  for (BlockIterator it = flow_graph_->reverse_postorder_iterator(); !it.Done();
+       it.Advance()) {
+    BlockEntryInstr* block = it.Current();
+    ASSERT(block->block_id() <= max_block_id);
+    // Make sure ordering is consistent.
+    ASSERT(block->preorder_number() <= block_count);
+    ASSERT(block->postorder_number() <= block_count);
+    ASSERT(preorder[block->preorder_number()] == block);
+    ASSERT(postorder[block->postorder_number()] == block);
+    // Make sure predecessors and successors agree.
+    Instruction* last = block->last_instruction();
+    for (intptr_t i = 0, n = last->SuccessorCount(); i < n; ++i) {
+      ASSERT(IsPred(block, last->SuccessorAt(i)));
+    }
+    for (intptr_t i = 0, n = block->PredecessorCount(); i < n; ++i) {
+      ASSERT(IsSucc(block, block->PredecessorAt(i)));
+    }
+    // Make sure dominance relations agree.
+    for (intptr_t i = 0, n = block->dominated_blocks().length(); i < n; ++i) {
+      ASSERT(block->dominated_blocks()[i]->dominator() == block);
+    }
+    if (block->dominator() != nullptr) {
+      ASSERT(IsDirectlyDominated(block, block->dominator()));
+    }
+    // Visit all instructions in this block.
+    VisitInstructions(block);
+  }
+
+  // Flow graph built-in verification.
+  // TODO(ajcbik): migrate actual code into checker too?
+  ASSERT(flow_graph_->VerifyUseLists());
+}
+
+void FlowGraphChecker::VisitInstructions(BlockEntryInstr* block) {
+  // To avoid excessive runtimes, skip the instructions check if there
+  // are many definitions (as happens in e.g. an initialization block).
+  if (flow_graph_->current_ssa_temp_index() > 10000) {
+    return;
+  }
+  // Give all visitors quick access.
+  current_block_ = block;
+  // Visit phis in join.
+  if (auto join_entry = block->AsJoinEntry()) {
+    for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
+      VisitInstruction(it.Current());
+    }
+  }
+  // Visit regular instructions.
+  Instruction* last = block->last_instruction();
+  Instruction* prev = block;
+  ASSERT(prev->previous() == nullptr);
+  for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+    Instruction* instruction = it.Current();
+    // Make sure block lookup agrees (scan in scan).
+    ASSERT(instruction->GetBlock() == block);
+    // Make sure linked list agrees.
+    ASSERT(prev->next() == instruction);
+    ASSERT(instruction->previous() == prev);
+    prev = instruction;
+    // Make sure control flow makes sense.
+    ASSERT(IsControlFlow(instruction) == (instruction == last));
+    // Perform instruction specific checks.
+    VisitInstruction(instruction);
+  }
+  ASSERT(prev == last);
+  // Make sure loop information, when up-to-date, agrees.
+  if (flow_graph_->loop_hierarchy_ != nullptr) {
+    for (LoopInfo* loop = block->loop_info(); loop != nullptr;
+         loop = loop->outer()) {
+      ASSERT(loop->Contains(block));
+    }
+  }
+}
+
+void FlowGraphChecker::VisitInstruction(Instruction* instruction) {
+  if (auto def = instruction->AsDefinition()) {
+    VisitDefinition(def);
+  }
+  instruction->Accept(this);
+}
+
+void FlowGraphChecker::VisitDefinition(Definition* def) {
+  // Make sure each outgoing use is dominated by this def, or is a
+  // Phi instruction (note that the proper dominance relation on
+  // the input values of Phis are checked by the Phi visitor below).
+  for (Value* use = def->input_use_list(); use != nullptr;
+       use = use->next_use()) {
+    Instruction* use_instr = use->instruction();
+    ASSERT(use_instr != nullptr);
+    ASSERT(use_instr->IsPhi() ||
+           use_instr->IsMaterializeObject() ||  // not in graph
+           use_instr->IsDominatedBy(def));
+  }
+}
+
+void FlowGraphChecker::VisitConstant(ConstantInstr* constant) {
+  // TODO(ajcbik): Is this a property we eventually want (all constants
+  // generated by utility that queries pool and put in the graph entry
+  // when seen first)? The inliner still creates some direct constants.
+  // ASSERT(constant->GetBlock() == flow_graph_->graph_entry());
+}
+
+void FlowGraphChecker::VisitPhi(PhiInstr* phi) {
+  ASSERT(phi->next() == nullptr);
+  ASSERT(phi->previous() == nullptr);
+  // Make sure each incoming input value of a Phi is dominated
+  // on the corresponding incoming edge, as defined by order.
+  ASSERT(phi->InputCount() == current_block_->PredecessorCount());
+  for (intptr_t i = 0, n = phi->InputCount(); i < n; ++i) {
+    Definition* input_def = phi->InputAt(i)->definition();
+    BlockEntryInstr* edge = current_block_->PredecessorAt(i);
+    ASSERT(input_def->IsConstant() ||  // some constants are in initial defs
+           edge->last_instruction()->IsDominatedBy(input_def));
+  }
+}
+
+void FlowGraphChecker::VisitGoto(GotoInstr* jmp) {
+  ASSERT(jmp->SuccessorCount() == 1);
+}
+
+void FlowGraphChecker::VisitIndirectGoto(IndirectGotoInstr* jmp) {
+  ASSERT(jmp->SuccessorCount() >= 1);
+}
+
+void FlowGraphChecker::VisitBranch(BranchInstr* branch) {
+  ASSERT(branch->SuccessorCount() == 2);
+}
+
+// Main entry point of graph checker.
+void FlowGraphChecker::Check() {
+  ASSERT(flow_graph_ != nullptr);
+  VisitBlocks();
+}
+
+}  // 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
new file mode 100644
index 0000000..fba159f
--- /dev/null
+++ b/runtime/vm/compiler/backend/flow_graph_checker.h
@@ -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.
+
+#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(DEBUG)
+
+#include "vm/compiler/backend/flow_graph.h"
+#include "vm/compiler/backend/il.h"
+
+namespace dart {
+
+// Class responsible for performing sanity checks on the flow graph.
+// The intended use is running the checks after each compiler pass
+// in debug mode in order to detect graph inconsistencies as soon
+// as possible. This way, culprit passes are more easily identified.
+//
+// All important assumptions on the flow graph structure that can be
+// verified in reasonable time should be made explicit in this pass
+// so that we no longer rely on asserts that are dispersed throughout
+// the passes or, worse, unwritten assumptions once agreed upon but
+// so easily forgotten. Since the graph checker runs only in debug
+// mode, it is acceptable to perform slightly elaborate tests.
+class FlowGraphChecker : public FlowGraphVisitor {
+ public:
+  // Constructs graph checker. The checker uses some custom-made
+  // visitation to perform additional checks, and uses the
+  // FlowGraphVisitor structure for anything else.
+  explicit FlowGraphChecker(FlowGraph* flow_graph)
+      : FlowGraphVisitor(flow_graph->preorder()),
+        flow_graph_(flow_graph),
+        current_block_(nullptr) {}
+
+  // Performs a sanity check on the flow graph.
+  void Check();
+
+ private:
+  // Custom-made visitors.
+  void VisitBlocks() override;
+  void VisitInstructions(BlockEntryInstr* block);
+  void VisitInstruction(Instruction* instruction);
+  void VisitDefinition(Definition* def);
+
+  // Instruction visitors.
+  void VisitConstant(ConstantInstr* constant) override;
+  void VisitPhi(PhiInstr* phi) override;
+  void VisitGoto(GotoInstr* jmp) override;
+  void VisitIndirectGoto(IndirectGotoInstr* jmp) override;
+  void VisitBranch(BranchInstr* branch) override;
+
+  FlowGraph* const flow_graph_;
+  BlockEntryInstr* current_block_;
+};
+
+}  // 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 c87bfc8..cd503e0 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -80,7 +80,8 @@
     if (it.CurrentLocation().IsInvalid() &&
         it.CurrentValue()->definition()->IsPushArgument()) {
       it.SetCurrentLocation(Location::StackSlot(
-          compiler_frame_layout.FrameSlotForVariableIndex(-*stack_height)));
+          compiler::target::frame_layout.FrameSlotForVariableIndex(
+              -*stack_height)));
       (*stack_height)++;
     }
   }
@@ -164,6 +165,8 @@
   code_source_map_builder_ = new (zone_)
       CodeSourceMapBuilder(stack_traces_only, caller_inline_id,
                            inline_id_to_token_pos, inline_id_to_function);
+
+  ArchSpecificInitialization();
 }
 
 bool FlowGraphCompiler::IsUnboxedField(const Field& field) {
@@ -354,7 +357,8 @@
 #if defined(DART_PRECOMPILER)
 static intptr_t LocationToStackIndex(const Location& src) {
   ASSERT(src.HasStackIndex());
-  return -compiler_frame_layout.VariableIndexForFrameSlot(src.stack_index());
+  return -compiler::target::frame_layout.VariableIndexForFrameSlot(
+      src.stack_index());
 }
 
 static CatchEntryMove CatchEntryMoveFor(Assembler* assembler,
@@ -367,7 +371,7 @@
       return CatchEntryMove();
     }
     const intptr_t pool_index =
-        assembler->object_pool_wrapper().FindObject(src.constant());
+        assembler->object_pool_builder().FindObject(src.constant());
     return CatchEntryMove::FromSlot(CatchEntryMove::SourceKind::kConstant,
                                     pool_index, dst_index);
   }
@@ -471,10 +475,11 @@
 void FlowGraphCompiler::EmitCallsiteMetadata(TokenPosition token_pos,
                                              intptr_t deopt_id,
                                              RawPcDescriptors::Kind kind,
-                                             LocationSummary* locs) {
+                                             LocationSummary* locs,
+                                             Environment* env) {
   AddCurrentDescriptor(kind, deopt_id, token_pos);
   RecordSafepoint(locs);
-  RecordCatchEntryMoves();
+  RecordCatchEntryMoves(env);
   if (deopt_id != DeoptId::kNone) {
     // Marks either the continuation point in unoptimized code or the
     // deoptimization point in optimized code, after call.
@@ -751,6 +756,16 @@
   return info;
 }
 
+CompilerDeoptInfo* FlowGraphCompiler::AddSlowPathDeoptInfo(intptr_t deopt_id,
+                                                           Environment* env) {
+  ASSERT(deopt_id != DeoptId::kNone);
+  CompilerDeoptInfo* info =
+      new (zone()) CompilerDeoptInfo(deopt_id, ICData::kDeoptUnknown, 0, env);
+  info->set_pc_offset(assembler()->CodeSize());
+  deopt_infos_.Add(info);
+  return info;
+}
+
 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters
 // and FlowGraphCompiler::SlowPathEnvironmentFor.
 // See StackFrame::VisitObjectPointers for the details of how stack map is
@@ -1048,7 +1063,7 @@
 
 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
 #if defined(PRODUCT)
-  // No debugger: no var descriptors.
+// No debugger: no var descriptors.
 #else
   // TODO(alexmarkov): revise local vars descriptors when compiling bytecode
   if (code.is_optimized() || flow_graph().function().HasBytecode()) {
@@ -1070,7 +1085,7 @@
     info.scope_id = 0;
     info.begin_pos = TokenPosition::kMinSource;
     info.end_pos = TokenPosition::kMinSource;
-    info.set_index(compiler_frame_layout.FrameSlotForVariable(
+    info.set_index(compiler::target::frame_layout.FrameSlotForVariable(
         parsed_function().current_context_var()));
     var_descs.SetVar(0, Symbols::CurrentContextVar(), &info);
   }
@@ -1205,7 +1220,7 @@
   EnterIntrinsicMode();
 
   SpecialStatsBegin(CombinedCodeStatistics::kTagIntrinsics);
-  bool complete = Intrinsifier::Intrinsify(parsed_function(), this);
+  bool complete = compiler::Intrinsifier::Intrinsify(parsed_function(), this);
   SpecialStatsEnd(CombinedCodeStatistics::kTagIntrinsics);
 
   ExitIntrinsicMode();
@@ -1413,8 +1428,7 @@
 
 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
   ASSERT(!is_optimizing());
-  instr->InitializeLocationSummary(zone(),
-                                   false);  // Not optimizing.
+  instr->InitializeLocationSummary(zone(), false);  // Not optimizing.
 
 // No need to allocate registers based on LocationSummary on DBC as in
 // unoptimized mode it's a stack based bytecode just like IR itself.
@@ -1751,9 +1765,6 @@
       zone(), ICData::New(parsed_function().function(), target_name,
                           arguments_descriptor, deopt_id, num_args_tested,
                           ICData::kInstance, receiver_type));
-#if defined(TAG_IC_DATA)
-  ic_data.set_tag(ICData::Tag::kInstanceCall);
-#endif
   if (deopt_id_to_ic_data_ != NULL) {
     (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
   }
@@ -1785,9 +1796,6 @@
                   String::Handle(zone(), target.name()), arguments_descriptor,
                   deopt_id, num_args_tested, rebind_rule));
   ic_data.AddTarget(target);
-#if defined(TAG_IC_DATA)
-  ic_data.set_tag(ICData::Tag::kStaticCall);
-#endif
   if (deopt_id_to_ic_data_ != NULL) {
     (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
   }
@@ -2284,7 +2292,7 @@
     __ PushRegister(locs->in(i).reg());
   }
   if (use_shared_stub) {
-    EmitSharedStubCall(compiler->assembler(), live_fpu_registers);
+    EmitSharedStubCall(compiler, live_fpu_registers);
   } else {
     __ CallRuntime(runtime_entry_, num_args_);
   }
@@ -2303,7 +2311,11 @@
       (compiler->CurrentTryIndex() != kInvalidTryIndex)) {
     Environment* env =
         compiler->SlowPathEnvironmentFor(instruction(), num_args_);
-    compiler->RecordCatchEntryMoves(env, try_index_);
+    if (FLAG_precompiled_mode) {
+      compiler->RecordCatchEntryMoves(env, try_index_);
+    } else if (env != nullptr) {
+      compiler->AddSlowPathDeoptInfo(deopt_id, env);
+    }
   }
   if (!use_shared_stub) {
     __ Breakpoint();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index f0c0af9..8cfee57 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_COMPILER_H_
 #define RUNTIME_VM_COMPILER_BACKEND_FLOW_GRAPH_COMPILER_H_
 
+#include <functional>
+
 #include "vm/allocation.h"
 #include "vm/code_descriptors.h"
 #include "vm/compiler/assembler/assembler.h"
@@ -262,7 +264,7 @@
   virtual void EmitCodeAtSlowPathEntry(FlowGraphCompiler* compiler) {}
   virtual void AddMetadataForRuntimeCall(FlowGraphCompiler* compiler) {}
 
-  virtual void EmitSharedStubCall(Assembler* assembler,
+  virtual void EmitSharedStubCall(FlowGraphCompiler* compiler,
                                   bool save_fpu_registers) {
     UNREACHABLE();
   }
@@ -275,6 +277,27 @@
   const intptr_t try_index_;
 };
 
+class NullErrorSlowPath : public ThrowErrorSlowPathCode {
+ public:
+  static const intptr_t kNumberOfArguments = 0;
+
+  NullErrorSlowPath(CheckNullInstr* instruction, intptr_t try_index)
+      : ThrowErrorSlowPathCode(instruction,
+                               kNullErrorRuntimeEntry,
+                               kNumberOfArguments,
+                               try_index) {}
+
+  const char* name() override { return "check null"; }
+
+  void EmitSharedStubCall(FlowGraphCompiler* compiler,
+                          bool save_fpu_registers) override;
+
+  void AddMetadataForRuntimeCall(FlowGraphCompiler* compiler) override {
+    CheckNullInstr::AddMetadataForRuntimeCall(instruction()->AsCheckNull(),
+                                              compiler);
+  }
+};
+
 #endif  // !defined(TARGET_ARCH_DBC)
 
 class FlowGraphCompiler : public ValueObject {
@@ -326,6 +349,8 @@
                     ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data,
                     CodeStatistics* stats = NULL);
 
+  void ArchSpecificInitialization();
+
   ~FlowGraphCompiler();
 
   static bool SupportsUnboxedDoubles();
@@ -597,10 +622,20 @@
   void RecordCatchEntryMoves(Environment* env = NULL,
                              intptr_t try_index = kInvalidTryIndex);
 
+  // Emits the following metadata for the current PC:
+  //
+  //   * Attaches current try index
+  //   * Attaches stackmaps
+  //   * Attaches catch entry moves (in AOT)
+  //   * Deoptimization information (in JIT)
+  //
+  // If [env] is not `nullptr` it will be used instead of the
+  // `pending_deoptimization_env`.
   void EmitCallsiteMetadata(TokenPosition token_pos,
                             intptr_t deopt_id,
                             RawPcDescriptors::Kind kind,
-                            LocationSummary* locs);
+                            LocationSummary* locs,
+                            Environment* env = nullptr);
 
   void EmitComment(Instruction* instr);
 
@@ -658,6 +693,7 @@
 #endif  // defined(TARGET_ARCH_DBC)
 
   CompilerDeoptInfo* AddDeoptIndexAtCall(intptr_t deopt_id);
+  CompilerDeoptInfo* AddSlowPathDeoptInfo(intptr_t deopt_id, Environment* env);
 
   void AddSlowPathCode(SlowPathCode* slow_path);
 
@@ -767,6 +803,11 @@
   bool IsEmptyBlock(BlockEntryInstr* block) const;
 
  private:
+  friend class CheckNullInstr;           // For AddPcRelativeCallStubTarget().
+  friend class NullErrorSlowPath;        // For AddPcRelativeCallStubTarget().
+  friend class CheckStackOverflowInstr;  // For AddPcRelativeCallStubTarget().
+  friend class StoreIndexedInstr;        // For AddPcRelativeCallStubTarget().
+  friend class StoreInstanceFieldInstr;  // For AddPcRelativeCallStubTarget().
   friend class CheckStackOverflowSlowPath;  // For pending_deoptimization_env_.
   friend class CheckedSmiSlowPath;          // Same.
   friend class CheckedSmiComparisonSlowPath;  // Same.
@@ -1004,7 +1045,6 @@
   Environment* pending_deoptimization_env_;
 
   ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_;
-
   Array& edge_counters_array_;
 
   DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index c711b59..70f614f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -27,6 +27,35 @@
 DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
 
+void FlowGraphCompiler::ArchSpecificInitialization() {
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    auto object_store = isolate()->object_store();
+
+    const auto& stub =
+        Code::ZoneHandle(object_store->write_barrier_wrappers_stub());
+    if (!stub.InVMHeap()) {
+      assembler_->generate_invoke_write_barrier_wrapper_ =
+          [&](Condition condition, Register reg) {
+            const intptr_t offset_into_target =
+                Thread::WriteBarrierWrappersOffsetForRegister(reg);
+            AddPcRelativeCallStubTarget(stub);
+            assembler_->GenerateUnRelocatedPcRelativeCall(condition,
+                                                          offset_into_target);
+          };
+    }
+
+    const auto& array_stub =
+        Code::ZoneHandle(object_store->array_write_barrier_stub());
+    if (!array_stub.InVMHeap()) {
+      assembler_->generate_invoke_array_write_barrier_ =
+          [&](Condition condition) {
+            AddPcRelativeCallStubTarget(array_stub);
+            assembler_->GenerateUnRelocatedPcRelativeCall(condition);
+          };
+    }
+  }
+}
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -343,8 +372,6 @@
   }
   const Register kClassIdReg = R2;
   __ LoadClassId(kClassIdReg, kInstanceReg);
-  // See ClassFinalizer::CheckSuperTypeAndInterfaces for list of restricted
-  // interfaces.
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ CompareImmediate(kClassIdReg, kBoolCid);
@@ -742,11 +769,11 @@
   // (see runtime/vm/runtime_entry.cc:TypeCheck).  It will use pattern matching
   // on the call site to find out at which pool index the destination name is
   // located.
-  const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+  const intptr_t sub_type_cache_index = __ object_pool_builder().AddObject(
       Object::null_object(), ObjectPool::Patchability::kPatchable);
   const intptr_t sub_type_cache_offset =
       ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
-  const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
+  const intptr_t dst_name_index = __ object_pool_builder().AddObject(
       dst_name, ObjectPool::Patchability::kPatchable);
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
@@ -781,9 +808,9 @@
   const Code& build_method_extractor = Code::ZoneHandle(
       isolate()->object_store()->build_method_extractor_code());
 
-  const intptr_t stub_index = __ object_pool_wrapper().AddObject(
+  const intptr_t stub_index = __ object_pool_builder().AddObject(
       build_method_extractor, ObjectPool::Patchability::kNotPatchable);
-  const intptr_t function_index = __ object_pool_wrapper().AddObject(
+  const intptr_t function_index = __ object_pool_builder().AddObject(
       extracted_method, ObjectPool::Patchability::kNotPatchable);
 
   // We use a custom pool register to preserve caller PP.
@@ -854,8 +881,8 @@
     }
     __ CompareImmediate(R3, GetOptimizationThreshold());
     ASSERT(function_reg == R8);
-    __ Branch(StubCode::OptimizeFunction(), ObjectPool::kNotPatchable, new_pp,
-              GE);
+    __ Branch(StubCode::OptimizeFunction(),
+              compiler::ObjectPoolBuilderEntry::kNotPatchable, new_pp, GE);
   }
   __ Comment("Enter frame");
   if (flow_graph().IsCompiledForOsr()) {
@@ -878,7 +905,7 @@
 
     intptr_t args_desc_slot = -1;
     if (parsed_function().has_arg_desc_var()) {
-      args_desc_slot = compiler_frame_layout.FrameSlotForVariable(
+      args_desc_slot = compiler::target::frame_layout.FrameSlotForVariable(
           parsed_function().arg_desc_var());
     }
 
@@ -888,7 +915,7 @@
     }
     for (intptr_t i = 0; i < num_locals; ++i) {
       const intptr_t slot_index =
-          compiler_frame_layout.FrameSlotForVariableIndex(-i);
+          compiler::target::frame_layout.FrameSlotForVariableIndex(-i);
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : R0;
       __ StoreToOffset(kWord, value_reg, FP, slot_index * kWordSize);
     }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 408f0c7..b128224 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -26,6 +26,32 @@
 DECLARE_FLAG(bool, enable_simd_inline);
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 
+void FlowGraphCompiler::ArchSpecificInitialization() {
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    auto object_store = isolate()->object_store();
+
+    const auto& stub =
+        Code::ZoneHandle(object_store->write_barrier_wrappers_stub());
+    if (!stub.InVMHeap()) {
+      assembler_->generate_invoke_write_barrier_wrapper_ = [&](Register reg) {
+        const intptr_t offset_into_target =
+            Thread::WriteBarrierWrappersOffsetForRegister(reg);
+        AddPcRelativeCallStubTarget(stub);
+        assembler_->GenerateUnRelocatedPcRelativeCall(offset_into_target);
+      };
+    }
+
+    const auto& array_stub =
+        Code::ZoneHandle(object_store->array_write_barrier_stub());
+    if (!array_stub.InVMHeap()) {
+      assembler_->generate_invoke_array_write_barrier_ = [&]() {
+        AddPcRelativeCallStubTarget(array_stub);
+        assembler_->GenerateUnRelocatedPcRelativeCall();
+      };
+    }
+  }
+}
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -332,8 +358,6 @@
   }
   const Register kClassIdReg = R2;
   __ LoadClassId(kClassIdReg, kInstanceReg);
-  // See ClassFinalizer::CheckSuperTypeAndInterfaces for list of restricted
-  // interfaces.
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ CompareImmediate(kClassIdReg, kBoolCid);
@@ -722,11 +746,11 @@
   // (see runtime/vm/runtime_entry.cc:TypeCheck).  It will use pattern matching
   // on the call site to find out at which pool index the destination name is
   // located.
-  const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
+  const intptr_t sub_type_cache_index = __ object_pool_builder().AddObject(
       Object::null_object(), ObjectPool::Patchability::kPatchable);
   const intptr_t sub_type_cache_offset =
       ObjectPool::element_offset(sub_type_cache_index);
-  const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
+  const intptr_t dst_name_index = __ object_pool_builder().AddObject(
       dst_name, ObjectPool::Patchability::kPatchable);
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
@@ -760,9 +784,9 @@
   const Code& build_method_extractor = Code::ZoneHandle(
       isolate()->object_store()->build_method_extractor_code());
 
-  const intptr_t stub_index = __ object_pool_wrapper().AddObject(
+  const intptr_t stub_index = __ object_pool_builder().AddObject(
       build_method_extractor, ObjectPool::Patchability::kNotPatchable);
-  const intptr_t function_index = __ object_pool_wrapper().AddObject(
+  const intptr_t function_index = __ object_pool_builder().AddObject(
       extracted_method, ObjectPool::Patchability::kNotPatchable);
 
   // We use a custom pool register to preserve caller PP.
@@ -892,7 +916,7 @@
 
     intptr_t args_desc_slot = -1;
     if (parsed_function().has_arg_desc_var()) {
-      args_desc_slot = compiler_frame_layout.FrameSlotForVariable(
+      args_desc_slot = compiler::target::frame_layout.FrameSlotForVariable(
           parsed_function().arg_desc_var());
     }
 
@@ -902,7 +926,7 @@
     }
     for (intptr_t i = 0; i < num_locals; ++i) {
       const intptr_t slot_index =
-          compiler_frame_layout.FrameSlotForVariableIndex(-i);
+          compiler::target::frame_layout.FrameSlotForVariableIndex(-i);
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : R0;
       __ StoreToOffset(value_reg, FP, slot_index * kWordSize);
     }
@@ -1085,7 +1109,7 @@
   ASSERT(ic_data.NumArgsTested() == 1);
   const Code& initial_stub = StubCode::ICCallThroughFunction();
 
-  auto& op = __ object_pool_wrapper();
+  auto& op = __ object_pool_builder();
 
   __ Comment("SwitchableCall");
   __ LoadFromOffset(R0, SP, (ic_data.CountWithoutTypeArgs() - 1) * kWordSize);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
index b28c6cd..09c490bd 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_dbc.cc
@@ -29,6 +29,8 @@
 DECLARE_FLAG(bool, enable_simd_inline);
 DECLARE_FLAG(charp, optimization_filter);
 
+void FlowGraphCompiler::ArchSpecificInitialization() {}
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -110,7 +112,8 @@
     builder->AddCopy(
         NULL,
         Location::StackSlot(
-            compiler_frame_layout.FrameSlotForVariableIndex(-stack_height)),
+            compiler::target::frame_layout.FrameSlotForVariableIndex(
+                -stack_height)),
         slot_ix++);
   }
 
@@ -280,7 +283,7 @@
 }
 
 void FlowGraphCompiler::GenerateGetterIntrinsic(intptr_t offset) {
-  __ Move(0, -(1 + compiler_frame_layout.param_end_from_fp));
+  __ Move(0, -(1 + compiler::target::frame_layout.param_end_from_fp));
   ASSERT(offset % kWordSize == 0);
   if (Utils::IsInt(8, offset / kWordSize)) {
     __ LoadField(0, 0, offset / kWordSize);
@@ -292,8 +295,8 @@
 }
 
 void FlowGraphCompiler::GenerateSetterIntrinsic(intptr_t offset) {
-  __ Move(0, -(2 + compiler_frame_layout.param_end_from_fp));
-  __ Move(1, -(1 + compiler_frame_layout.param_end_from_fp));
+  __ Move(0, -(2 + compiler::target::frame_layout.param_end_from_fp));
+  __ Move(1, -(1 + compiler::target::frame_layout.param_end_from_fp));
   ASSERT(offset % kWordSize == 0);
   if (Utils::IsInt(8, offset / kWordSize)) {
     __ StoreField(0, offset / kWordSize, 1);
@@ -326,8 +329,9 @@
     if (parsed_function().has_arg_desc_var()) {
       // TODO(kustermann): If dbc simulator put the args_desc_ into the
       // _special_regs, we could replace these 3 with the MoveSpecial bytecode.
-      const intptr_t slot_index = compiler_frame_layout.FrameSlotForVariable(
-          parsed_function().arg_desc_var());
+      const intptr_t slot_index =
+          compiler::target::frame_layout.FrameSlotForVariable(
+              parsed_function().arg_desc_var());
       __ LoadArgDescriptor();
       __ StoreLocal(LocalVarIndex(0, slot_index));
       __ Drop(1);
@@ -367,7 +371,8 @@
     // Only allow access to the arguments (which have in the non-inverted stack
     // positive indices).
     ASSERT(source.base_reg() == FPREG);
-    ASSERT(source.stack_index() > compiler_frame_layout.param_end_from_fp);
+    ASSERT(source.stack_index() >
+           compiler::target::frame_layout.param_end_from_fp);
     __ Move(destination.reg(), -source.stack_index());
   } else if (source.IsRegister() && destination.IsRegister()) {
     __ Move(destination.reg(), source.reg());
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 31be382..b1c4671 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -29,6 +29,8 @@
 
 DECLARE_FLAG(bool, enable_simd_inline);
 
+void FlowGraphCompiler::ArchSpecificInitialization() {}
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -348,8 +350,6 @@
   }
   const Register kClassIdReg = ECX;
   __ LoadClassId(kClassIdReg, kInstanceReg);
-  // See ClassFinalizer::CheckSuperTypeAndInterfaces for list of restricted
-  // interfaces.
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ cmpl(kClassIdReg, Immediate(kBoolCid));
@@ -804,7 +804,7 @@
 
     intptr_t args_desc_slot = -1;
     if (parsed_function().has_arg_desc_var()) {
-      args_desc_slot = compiler_frame_layout.FrameSlotForVariable(
+      args_desc_slot = compiler::target::frame_layout.FrameSlotForVariable(
           parsed_function().arg_desc_var());
     }
 
@@ -816,7 +816,7 @@
     }
     for (intptr_t i = 0; i < num_locals; ++i) {
       const intptr_t slot_index =
-          compiler_frame_layout.FrameSlotForVariableIndex(-i);
+          compiler::target::frame_layout.FrameSlotForVariableIndex(-i);
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : EAX;
       __ movl(Address(EBP, slot_index * kWordSize), value_reg);
     }
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index aa1c822..0f087fa 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -25,6 +25,32 @@
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
 
+void FlowGraphCompiler::ArchSpecificInitialization() {
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    auto object_store = isolate()->object_store();
+
+    const auto& stub =
+        Code::ZoneHandle(object_store->write_barrier_wrappers_stub());
+    if (!stub.InVMHeap()) {
+      assembler_->generate_invoke_write_barrier_wrapper_ = [&](Register reg) {
+        const intptr_t offset_into_target =
+            Thread::WriteBarrierWrappersOffsetForRegister(reg);
+        AddPcRelativeCallStubTarget(stub);
+        assembler_->GenerateUnRelocatedPcRelativeCall(offset_into_target);
+      };
+    }
+
+    const auto& array_stub =
+        Code::ZoneHandle(object_store->array_write_barrier_stub());
+    if (!array_stub.InVMHeap()) {
+      assembler_->generate_invoke_array_write_barrier_ = [&]() {
+        AddPcRelativeCallStubTarget(array_stub);
+        assembler_->GenerateUnRelocatedPcRelativeCall();
+      };
+    }
+  }
+}
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -347,8 +373,6 @@
   }
   const Register kClassIdReg = R10;
   __ LoadClassId(kClassIdReg, kInstanceReg);
-  // See ClassFinalizer::CheckSuperTypeAndInterfaces for list of restricted
-  // interfaces.
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ cmpl(kClassIdReg, Immediate(kBoolCid));
@@ -735,12 +759,12 @@
   // (see runtime/vm/runtime_entry.cc:TypeCheck).  It will use pattern matching
   // on the call site to find out at which pool index the destination name is
   // located.
-  const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
-      Object::null_object(), ObjectPool::Patchability::kPatchable);
+  const intptr_t sub_type_cache_index = __ object_pool_builder().AddObject(
+      Object::null_object(), compiler::ObjectPoolBuilderEntry::kPatchable);
   const intptr_t sub_type_cache_offset =
       ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
-  const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
-      dst_name, ObjectPool::Patchability::kPatchable);
+  const intptr_t dst_name_index = __ object_pool_builder().AddObject(
+      dst_name, compiler::ObjectPoolBuilderEntry::kPatchable);
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
@@ -779,10 +803,10 @@
       isolate()->object_store()->build_method_extractor_code());
   ASSERT(!build_method_extractor.IsNull());
 
-  const intptr_t stub_index = __ object_pool_wrapper().AddObject(
-      build_method_extractor, ObjectPool::Patchability::kNotPatchable);
-  const intptr_t function_index = __ object_pool_wrapper().AddObject(
-      extracted_method, ObjectPool::Patchability::kNotPatchable);
+  const intptr_t stub_index = __ object_pool_builder().AddObject(
+      build_method_extractor, compiler::ObjectPoolBuilderEntry::kNotPatchable);
+  const intptr_t function_index = __ object_pool_builder().AddObject(
+      extracted_method, compiler::ObjectPoolBuilderEntry::kNotPatchable);
 
   // We use a custom pool register to preserve caller PP.
   Register kPoolReg = RAX;
@@ -875,7 +899,7 @@
 
     intptr_t args_desc_slot = -1;
     if (parsed_function().has_arg_desc_var()) {
-      args_desc_slot = compiler_frame_layout.FrameSlotForVariable(
+      args_desc_slot = compiler::target::frame_layout.FrameSlotForVariable(
           parsed_function().arg_desc_var());
     }
 
@@ -885,7 +909,7 @@
     }
     for (intptr_t i = 0; i < num_locals; ++i) {
       const intptr_t slot_index =
-          compiler_frame_layout.FrameSlotForVariableIndex(-i);
+          compiler::target::frame_layout.FrameSlotForVariableIndex(-i);
       Register value_reg = slot_index == args_desc_slot ? ARGS_DESC_REG : RAX;
       __ movq(Address(RBP, slot_index * kWordSize), value_reg);
     }
@@ -1281,13 +1305,13 @@
     } else {
       ASSERT(destination.IsStackSlot());
       ASSERT((destination.base_reg() != FPREG) ||
-             ((-compiler_frame_layout.VariableIndexForFrameSlot(
+             ((-compiler::target::frame_layout.VariableIndexForFrameSlot(
                   destination.stack_index())) < compiler_->StackSize()));
       __ movq(destination.ToStackSlotAddress(), source.reg());
     }
   } else if (source.IsStackSlot()) {
     ASSERT((source.base_reg() != FPREG) ||
-           ((-compiler_frame_layout.VariableIndexForFrameSlot(
+           ((-compiler::target::frame_layout.VariableIndexForFrameSlot(
                 source.stack_index())) < compiler_->StackSize()));
     if (destination.IsRegister()) {
       __ movq(destination.reg(), source.ToStackSlotAddress());
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 65d80af..c8b82ed 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -485,24 +485,22 @@
   ASSERT(deopt_id_ != DeoptId::kNone);
   if (deopt_id_ < ic_data_array.length()) {
     const ICData* result = ic_data_array[deopt_id_];
-#if defined(TAG_IC_DATA)
+#if defined(DEBUG)
     if (result != NULL) {
-      ICData::Tag ic_data_tag = ICData::Tag::kUnknown;
       switch (tag()) {
         case kInstanceCall:
-          ic_data_tag = ICData::Tag::kInstanceCall;
+          if (result->is_static_call()) {
+            FATAL("ICData tag mismatch");
+          }
           break;
         case kStaticCall:
-          ic_data_tag = ICData::Tag::kStaticCall;
+          if (!result->is_static_call()) {
+            FATAL("ICData tag mismatch");
+          }
           break;
         default:
           UNREACHABLE();
       }
-      if (result->tag() == ICData::Tag::kUnknown) {
-        result->set_tag(ic_data_tag);
-      } else if (result->tag() != ic_data_tag) {
-        FATAL("ICData tag mismatch");
-      }
     }
 #endif
     return result;
@@ -1076,10 +1074,12 @@
 BlockEntryInstr* Instruction::GetBlock() {
   // TODO(fschneider): Implement a faster way to get the block of an
   // instruction.
-  ASSERT(previous() != NULL);
   Instruction* result = previous();
-  while (!result->IsBlockEntry())
+  ASSERT(result != nullptr);
+  while (!result->IsBlockEntry()) {
     result = result->previous();
+    ASSERT(result != nullptr);
+  }
   return result->AsBlockEntry();
 }
 
@@ -1316,33 +1316,29 @@
   return (kInstructionAttrs[tag()] & InstrAttrs::kNoGC) == 0;
 }
 
-void Definition::ReplaceWith(Definition* other,
-                             ForwardInstructionIterator* iterator) {
-  // Record other's input uses.
-  for (intptr_t i = other->InputCount() - 1; i >= 0; --i) {
-    Value* input = other->InputAt(i);
+void Definition::ReplaceWithResult(Instruction* replacement,
+                                   Definition* replacement_for_uses,
+                                   ForwardInstructionIterator* iterator) {
+  // Record replacement's input uses.
+  for (intptr_t i = replacement->InputCount() - 1; i >= 0; --i) {
+    Value* input = replacement->InputAt(i);
     input->definition()->AddInputUse(input);
   }
-  // Take other's environment from this definition.
-  ASSERT(other->env() == NULL);
-  other->SetEnvironment(env());
+  // Take replacement's environment from this definition.
+  ASSERT(replacement->env() == NULL);
+  replacement->SetEnvironment(env());
   ClearEnv();
-  // Replace all uses of this definition with other.
-  ReplaceUsesWith(other);
-  // Reuse this instruction's SSA name for other.
-  ASSERT(!other->HasSSATemp());
-  if (HasSSATemp()) {
-    other->set_ssa_temp_index(ssa_temp_index());
-  }
+  // Replace all uses of this definition with replacement_for_uses.
+  ReplaceUsesWith(replacement_for_uses);
 
-  // Finally insert the other definition in place of this one in the graph.
-  previous()->LinkTo(other);
+  // Finally replace this one with the replacement instruction in the graph.
+  previous()->LinkTo(replacement);
   if ((iterator != NULL) && (this == iterator->Current())) {
     // Remove through the iterator.
-    other->LinkTo(this);
+    replacement->LinkTo(this);
     iterator->RemoveCurrentFromGraph();
   } else {
-    other->LinkTo(next());
+    replacement->LinkTo(next());
     // Remove this definition's input uses.
     UnuseAllInputs();
   }
@@ -1350,6 +1346,16 @@
   set_next(NULL);
 }
 
+void Definition::ReplaceWith(Definition* other,
+                             ForwardInstructionIterator* iterator) {
+  // Reuse this instruction's SSA name for other.
+  ASSERT(!other->HasSSATemp());
+  if (HasSSATemp()) {
+    other->set_ssa_temp_index(ssa_temp_index());
+  }
+  ReplaceWithResult(other, other, iterator);
+}
+
 void BranchInstr::SetComparison(ComparisonInstr* new_comparison) {
   for (intptr_t i = new_comparison->InputCount() - 1; i >= 0; --i) {
     Value* input = new_comparison->InputAt(i);
@@ -2879,7 +2885,7 @@
     return box_defn->value()->definition();
   }
 
-  if ((representation() == kUnboxedDouble) && value()->BindsToConstant()) {
+  if (representation() == kUnboxedDouble && value()->BindsToConstant()) {
     UnboxedConstantInstr* uc = NULL;
 
     const Object& val = value()->BoundConstant();
@@ -3214,7 +3220,7 @@
       comp->RemoveFromGraph();
       SetComparison(comp);
       if (FLAG_trace_optimization) {
-        OS::PrintErr("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
+        THR_Print("Merging comparison v%" Pd "\n", comp->ssa_temp_index());
       }
       // Clear the comparison's temp index and ssa temp index since the
       // value of the comparison is not used outside the branch anymore.
@@ -3235,7 +3241,7 @@
     }
     if (bit_and != NULL) {
       if (FLAG_trace_optimization) {
-        OS::PrintErr("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index());
+        THR_Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index());
       }
       TestSmiInstr* test = new TestSmiInstr(
           comparison()->token_pos(),
@@ -3444,6 +3450,7 @@
     case kUnboxedFloat32x4:
     case kUnboxedFloat64x2:
     case kUnboxedInt32x4:
+      ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles());
       return new UnboxInstr(to, value, deopt_id, speculative_mode);
 
     default:
@@ -4528,43 +4535,16 @@
   return locs;
 }
 
-class NullErrorSlowPath : public ThrowErrorSlowPathCode {
- public:
-  static const intptr_t kNumberOfArguments = 0;
-
-  NullErrorSlowPath(CheckNullInstr* instruction, intptr_t try_index)
-      : ThrowErrorSlowPathCode(instruction,
-                               kNullErrorRuntimeEntry,
-                               kNumberOfArguments,
-                               try_index) {}
-
-  const char* name() override { return "check null"; }
-
-  void EmitSharedStubCall(Assembler* assembler,
-                          bool save_fpu_registers) override {
-    assembler->CallNullErrorShared(save_fpu_registers);
-  }
-
-  void AddMetadataForRuntimeCall(FlowGraphCompiler* compiler) override {
-    const String& function_name = instruction()->AsCheckNull()->function_name();
-    const intptr_t name_index =
-        compiler->assembler()->object_pool_wrapper().FindObject(function_name);
-    compiler->AddNullCheck(compiler->assembler()->CodeSize(),
-                           instruction()->token_pos(), name_index);
-  }
-};
-
-void CheckNullInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  NullErrorSlowPath* slow_path =
-      new NullErrorSlowPath(this, compiler->CurrentTryIndex());
-  compiler->AddSlowPathCode(slow_path);
-
-  Register value_reg = locs()->in(0).reg();
-  // TODO(dartbug.com/30480): Consider passing `null` literal as an argument
-  // in order to be able to allocate it on register.
-  __ CompareObject(value_reg, Object::null_object());
-  __ BranchIf(EQUAL, slow_path->entry_label());
+#if !defined(TARGET_ARCH_DBC)
+void CheckNullInstr::AddMetadataForRuntimeCall(CheckNullInstr* check_null,
+                                               FlowGraphCompiler* compiler) {
+  const String& function_name = check_null->function_name();
+  const intptr_t name_index =
+      compiler->assembler()->object_pool_builder().FindObject(function_name);
+  compiler->AddNullCheck(compiler->assembler()->CodeSize(),
+                         check_null->token_pos(), name_index);
 }
+#endif  // !defined(TARGET_ARCH_DBC)
 
 void UnboxInstr::EmitLoadFromBoxWithDeopt(FlowGraphCompiler* compiler) {
   const intptr_t box_cid = BoxCid();
@@ -4992,7 +4972,7 @@
                                      AlignmentType alignment,
                                      intptr_t deopt_id,
                                      TokenPosition token_pos)
-    : TemplateDefinition(deopt_id),
+    : TemplateInstruction(deopt_id),
       emit_store_barrier_(emit_store_barrier),
       index_scale_(index_scale),
       class_id_(class_id),
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 7020590..6241f4b 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -17,6 +17,7 @@
 #include "vm/native_entry.h"
 #include "vm/object.h"
 #include "vm/parser.h"
+#include "vm/static_type_exactness_state.h"
 #include "vm/token_position.h"
 
 namespace dart {
@@ -44,6 +45,10 @@
 class UnboxIntegerInstr;
 class TypeUsageInfo;
 
+namespace compiler {
+class BlockBuilder;
+}
+
 class Value : public ZoneAllocated {
  public:
   // A forward iterator that allows removing the current value from the
@@ -1869,6 +1874,14 @@
   // Postcondition: use lists and use values are still valid.
   void ReplaceUsesWith(Definition* other);
 
+  // Replace this definition with another instruction. Use the provided result
+  // definition to replace uses of the original definition. If replacing during
+  // iteration, pass the iterator so that the instruction can be replaced
+  // without affecting iteration order, otherwise pass a NULL iterator.
+  void ReplaceWithResult(Instruction* replacement,
+                         Definition* replacement_for_uses,
+                         ForwardInstructionIterator* iterator);
+
   // Replace this definition and all uses with another definition.  If
   // replacing during iteration, pass the iterator so that the instruction
   // can be replaced without affecting iteration order, otherwise pass a
@@ -2125,7 +2138,7 @@
 //
 // This low-level instruction is non-inlinable since it makes assumptions about
 // the frame.  This is asserted via `inliner.cc::CalleeGraphValidator`.
-class StoreIndexedUnsafeInstr : public TemplateDefinition<2, NoThrow> {
+class StoreIndexedUnsafeInstr : public TemplateInstruction<2, NoThrow> {
  public:
   StoreIndexedUnsafeInstr(Value* index, Value* value, intptr_t offset)
       : offset_(offset) {
@@ -3090,12 +3103,10 @@
   }
 
   RawString* Selector() {
-    // The Token::Kind we have does unfortunately not encode whether the call is
-    // a dyn: call or not.
     if (auto static_call = this->AsStaticCall()) {
-      return static_call->ic_data()->target_name();
+      return static_call->function().name();
     } else if (auto instance_call = this->AsInstanceCall()) {
-      return instance_call->ic_data()->target_name();
+      return instance_call->function_name().raw();
     } else {
       UNREACHABLE();
     }
@@ -4109,7 +4120,7 @@
 // field initializers *must* be marked as initializing. Initializing stores
 // into unboxed fields are responsible for allocating the mutable box which
 // would be mutated by subsequent stores.
-class StoreInstanceFieldInstr : public TemplateDefinition<2, NoThrow> {
+class StoreInstanceFieldInstr : public TemplateInstruction<2, NoThrow> {
  public:
   enum class Kind {
     // Store is known to be the first store into a slot of an object after
@@ -4581,7 +4592,7 @@
   DISALLOW_COPY_AND_ASSIGN(StringInterpolateInstr);
 };
 
-class StoreIndexedInstr : public TemplateDefinition<3, NoThrow> {
+class StoreIndexedInstr : public TemplateInstruction<3, NoThrow> {
  public:
   StoreIndexedInstr(Value* array,
                     Value* index,
@@ -7167,6 +7178,9 @@
 
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
+  static void AddMetadataForRuntimeCall(CheckNullInstr* check_null,
+                                        FlowGraphCompiler* compiler);
+
  private:
   const TokenPosition token_pos_;
   const String& function_name_;
@@ -7824,7 +7838,7 @@
 
  private:
   friend class ShallowIterator;
-  friend class BlockBuilder;  // For Environment constructor.
+  friend class compiler::BlockBuilder;  // For Environment constructor.
 
   Environment(intptr_t length,
               intptr_t fixed_parameter_count,
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 94c7519..6c3ea35 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -127,7 +127,8 @@
   Label stack_ok;
   __ Comment("Stack Check");
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ sub(R2, SP, Operand(FP));
@@ -282,9 +283,8 @@
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register result = locs()->out(0).reg();
-  __ LoadFromOffset(
-      kWord, result, FP,
-      compiler_frame_layout.FrameOffsetInBytesForVariable(&local()));
+  __ LoadFromOffset(kWord, result, FP,
+                    compiler::target::FrameOffsetInBytesForVariable(&local()));
 }
 
 LocationSummary* StoreLocalInstr::MakeLocationSummary(Zone* zone,
@@ -297,9 +297,8 @@
   const Register value = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
   ASSERT(result == value);  // Assert that register assignment is correct.
-  __ StoreToOffset(
-      kWord, value, FP,
-      compiler_frame_layout.FrameOffsetInBytesForVariable(&local()));
+  __ StoreToOffset(kWord, value, FP,
+                   compiler::target::FrameOffsetInBytesForVariable(&local()));
 }
 
 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone,
@@ -967,9 +966,10 @@
   }
   __ LoadImmediate(R1, argc_tag);
   ExternalLabel label(entry);
-  __ LoadNativeEntry(
-      R9, &label,
-      link_lazily() ? ObjectPool::kPatchable : ObjectPool::kNotPatchable);
+  __ LoadNativeEntry(R9, &label,
+                     link_lazily()
+                         ? compiler::ObjectPoolBuilderEntry::kPatchable
+                         : compiler::ObjectPoolBuilderEntry::kNotPatchable);
   if (link_lazily()) {
     compiler->GeneratePatchableCall(token_pos(), *stub,
                                     RawPcDescriptors::kOther, locs());
@@ -2965,21 +2965,22 @@
   // Restore SP from FP as we are coming from a throw and the code for
   // popping arguments has not been run.
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ AddImmediate(SP, FP, fp_sp_dist);
 
   if (!compiler->is_optimizing()) {
     if (raw_exception_var_ != nullptr) {
-      __ StoreToOffset(kWord, kExceptionObjectReg, FP,
-                       compiler_frame_layout.FrameOffsetInBytesForVariable(
-                           raw_exception_var_));
+      __ StoreToOffset(
+          kWord, kExceptionObjectReg, FP,
+          compiler::target::FrameOffsetInBytesForVariable(raw_exception_var_));
     }
     if (raw_stacktrace_var_ != nullptr) {
-      __ StoreToOffset(kWord, kStackTraceObjectReg, FP,
-                       compiler_frame_layout.FrameOffsetInBytesForVariable(
-                           raw_stacktrace_var_));
+      __ StoreToOffset(
+          kWord, kStackTraceObjectReg, FP,
+          compiler::target::FrameOffsetInBytesForVariable(raw_stacktrace_var_));
     }
   }
 }
@@ -3029,11 +3030,9 @@
     compiler->pending_deoptimization_env_ = env;
 
     if (using_shared_stub) {
-      uword entry_point_offset =
-          instruction()->locs()->live_registers()->FpuRegisterCount() > 0
-              ? Thread::stack_overflow_shared_with_fpu_regs_entry_point_offset()
-              : Thread::
-                    stack_overflow_shared_without_fpu_regs_entry_point_offset();
+      const uword entry_point_offset =
+          Thread::stack_overflow_shared_stub_entry_point_offset(
+              instruction()->locs()->live_registers()->FpuRegisterCount() > 0);
       __ ldr(LR, Address(THR, entry_point_offset));
       __ blx(LR);
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
@@ -3072,11 +3071,34 @@
 };
 
 void CheckStackOverflowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
-  compiler->AddSlowPathCode(slow_path);
-
   __ ldr(IP, Address(THR, Thread::stack_limit_offset()));
   __ cmp(SP, Operand(IP));
+
+  auto object_store = compiler->isolate()->object_store();
+  const bool live_fpu_regs = locs()->live_registers()->FpuRegisterCount() > 0;
+  const auto& stub = Code::ZoneHandle(
+      compiler->zone(),
+      live_fpu_regs
+          ? object_store->stack_overflow_stub_with_fpu_regs_stub()
+          : object_store->stack_overflow_stub_without_fpu_regs_stub());
+  const bool using_shared_stub = locs()->call_on_shared_slow_path();
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
+      using_shared_stub && !stub.InVMHeap()) {
+    compiler->AddPcRelativeCallStubTarget(stub);
+    __ GenerateUnRelocatedPcRelativeCall(LS);
+
+    // We use the "extended" environment which has the locations updated to
+    // reflect live registers being saved in the shared spilling stubs (see
+    // the stub above).
+    auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
+    compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
+                                   RawPcDescriptors::kOther, locs(),
+                                   extended_env);
+    return;
+  }
+
+  CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
+  compiler->AddSlowPathCode(slow_path);
   __ b(slow_path->entry_label(), LS);
   if (compiler->CanOSRFunction() && in_loop()) {
     const Register temp = locs()->temp(0).reg();
@@ -5742,6 +5764,47 @@
   __ BranchIfNotSmi(value, deopt);
 }
 
+void CheckNullInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Register value_reg = locs()->in(0).reg();
+  // TODO(dartbug.com/30480): Consider passing `null` literal as an argument
+  // in order to be able to allocate it on register.
+  __ CompareObject(value_reg, Object::null_object());
+
+  auto object_store = compiler->isolate()->object_store();
+  const bool live_fpu_regs = locs()->live_registers()->FpuRegisterCount() > 0;
+  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());
+  const bool using_shared_stub = locs()->call_on_shared_slow_path();
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
+      using_shared_stub && !stub.InVMHeap()) {
+    compiler->AddPcRelativeCallStubTarget(stub);
+    __ GenerateUnRelocatedPcRelativeCall(EQUAL);
+
+    // We use the "extended" environment which has the locations updated to
+    // reflect live registers being saved in the shared spilling stubs (see
+    // the stub above).
+    auto extended_env = compiler->SlowPathEnvironmentFor(this, 0);
+    compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
+                                   RawPcDescriptors::kOther, locs(),
+                                   extended_env);
+    CheckNullInstr::AddMetadataForRuntimeCall(this, compiler);
+    return;
+  }
+
+  NullErrorSlowPath* slow_path =
+      new NullErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  __ BranchIf(EQUAL, slow_path->entry_label());
+}
+
+void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
+                                           bool save_fpu_registers) {
+  compiler->assembler()->CallNullErrorShared(save_fpu_registers);
+}
+
 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -6162,7 +6225,7 @@
     Register shift = locs()->in(1).reg();
     __ SmiUntag(shift);
 
-    // Deopt if shift is larger than 63 or less than 0.
+    // Deopt if shift is larger than 63 or less than 0 (or not a smi).
     if (!IsShiftCountInRange()) {
       ASSERT(CanDeoptimize());
       Label* deopt =
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 9c03a18..ba567b0 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -127,7 +127,8 @@
   Label stack_ok;
   __ Comment("Stack Check");
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ sub(R2, SP, Operand(FP));
@@ -281,9 +282,8 @@
 
 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register result = locs()->out(0).reg();
-  __ LoadFromOffset(
-      result, FP,
-      compiler_frame_layout.FrameOffsetInBytesForVariable(&local()));
+  __ LoadFromOffset(result, FP,
+                    compiler::target::FrameOffsetInBytesForVariable(&local()));
 }
 
 LocationSummary* StoreLocalInstr::MakeLocationSummary(Zone* zone,
@@ -296,8 +296,8 @@
   const Register value = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
   ASSERT(result == value);  // Assert that register assignment is correct.
-  __ StoreToOffset(
-      value, FP, compiler_frame_layout.FrameOffsetInBytesForVariable(&local()));
+  __ StoreToOffset(value, FP,
+                   compiler::target::FrameOffsetInBytesForVariable(&local()));
 }
 
 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone,
@@ -857,9 +857,9 @@
   }
   __ LoadImmediate(R1, argc_tag);
   ExternalLabel label(entry);
-  __ LoadNativeEntry(
-      R5, &label,
-      link_lazily() ? ObjectPool::kPatchable : ObjectPool::kNotPatchable);
+  __ LoadNativeEntry(R5, &label,
+                     link_lazily() ? ObjectPool::Patchability::kPatchable
+                                   : ObjectPool::Patchability::kNotPatchable);
   if (link_lazily()) {
     compiler->GeneratePatchableCall(token_pos(), *stub,
                                     RawPcDescriptors::kOther, locs());
@@ -2653,21 +2653,22 @@
   // Restore SP from FP as we are coming from a throw and the code for
   // popping arguments has not been run.
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ AddImmediate(SP, FP, fp_sp_dist);
 
   if (!compiler->is_optimizing()) {
     if (raw_exception_var_ != nullptr) {
-      __ StoreToOffset(kExceptionObjectReg, FP,
-                       compiler_frame_layout.FrameOffsetInBytesForVariable(
-                           raw_exception_var_));
+      __ StoreToOffset(
+          kExceptionObjectReg, FP,
+          compiler::target::FrameOffsetInBytesForVariable(raw_exception_var_));
     }
     if (raw_stacktrace_var_ != nullptr) {
-      __ StoreToOffset(kStackTraceObjectReg, FP,
-                       compiler_frame_layout.FrameOffsetInBytesForVariable(
-                           raw_stacktrace_var_));
+      __ StoreToOffset(
+          kStackTraceObjectReg, FP,
+          compiler::target::FrameOffsetInBytesForVariable(raw_stacktrace_var_));
     }
   }
 }
@@ -2695,8 +2696,9 @@
       : TemplateSlowPathCode(instruction) {}
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    auto locs = instruction()->locs();
     if (compiler->isolate()->use_osr() && osr_entry_label()->IsLinked()) {
-      const Register value = instruction()->locs()->temp(0).reg();
+      const Register value = locs->temp(0).reg();
       __ Comment("CheckStackOverflowSlowPathOsr");
       __ Bind(osr_entry_label());
       __ LoadImmediate(value, Thread::kOsrRequest);
@@ -2704,10 +2706,9 @@
     }
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
-    const bool using_shared_stub =
-        instruction()->locs()->call_on_shared_slow_path();
+    const bool using_shared_stub = locs->call_on_shared_slow_path();
     if (!using_shared_stub) {
-      compiler->SaveLiveRegisters(instruction()->locs());
+      compiler->SaveLiveRegisters(locs);
     }
     // pending_deoptimization_env_ is needed to generate a runtime call that
     // may throw an exception.
@@ -2717,14 +2718,27 @@
     compiler->pending_deoptimization_env_ = env;
 
     if (using_shared_stub) {
-      uword entry_point_offset =
-          instruction()->locs()->live_registers()->FpuRegisterCount() > 0
-              ? Thread::stack_overflow_shared_with_fpu_regs_entry_point_offset()
-              : Thread::
-                    stack_overflow_shared_without_fpu_regs_entry_point_offset();
-      __ ldr(LR, Address(THR, entry_point_offset));
-      __ blr(LR);
-      compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
+      auto object_store = compiler->isolate()->object_store();
+      const bool live_fpu_regs = locs->live_registers()->FpuRegisterCount() > 0;
+      const auto& stub = Code::Handle(
+          compiler->zone(),
+          live_fpu_regs
+              ? object_store->stack_overflow_stub_with_fpu_regs_stub()
+              : object_store->stack_overflow_stub_without_fpu_regs_stub());
+
+      if (FLAG_precompiled_mode && FLAG_use_bare_instructions &&
+          using_shared_stub && !stub.InVMHeap()) {
+        compiler->AddPcRelativeCallStubTarget(stub);
+        __ GenerateUnRelocatedPcRelativeCall();
+
+      } else {
+        const uword entry_point_offset =
+            Thread::stack_overflow_shared_stub_entry_point_offset(
+                locs->live_registers()->FpuRegisterCount() > 0);
+        __ ldr(LR, Address(THR, entry_point_offset));
+        __ blr(LR);
+      }
+      compiler->RecordSafepoint(locs, kNumSlowPathArgs);
       compiler->RecordCatchEntryMoves();
       compiler->AddDescriptor(
           RawPcDescriptors::kOther, compiler->assembler()->CodeSize(),
@@ -2733,7 +2747,7 @@
     } else {
       compiler->GenerateRuntimeCall(
           instruction()->token_pos(), instruction()->deopt_id(),
-          kStackOverflowRuntimeEntry, kNumSlowPathArgs, instruction()->locs());
+          kStackOverflowRuntimeEntry, kNumSlowPathArgs, locs);
     }
 
     if (compiler->isolate()->use_osr() && !compiler->is_optimizing() &&
@@ -2745,7 +2759,7 @@
     }
     compiler->pending_deoptimization_env_ = NULL;
     if (!using_shared_stub) {
-      compiler->RestoreLiveRegisters(instruction()->locs());
+      compiler->RestoreLiveRegisters(locs);
     }
     __ b(exit_label());
   }
@@ -4956,6 +4970,40 @@
   __ BranchIfNotSmi(value, deopt);
 }
 
+void CheckNullInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  NullErrorSlowPath* slow_path =
+      new NullErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Register value_reg = locs()->in(0).reg();
+  // TODO(dartbug.com/30480): Consider passing `null` literal as an argument
+  // in order to be able to allocate it on register.
+  __ CompareObject(value_reg, Object::null_object());
+  __ 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::Handle(
+      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.InVMHeap()) {
+    compiler->AddPcRelativeCallStubTarget(stub);
+    compiler->assembler()->GenerateUnRelocatedPcRelativeCall();
+    return;
+  }
+
+  compiler->assembler()->CallNullErrorShared(save_fpu_registers);
+}
+
 LocationSummary* CheckArrayBoundInstr::MakeLocationSummary(Zone* zone,
                                                            bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -5445,7 +5493,7 @@
     __ SmiUntag(TMP, shift);
     shift = TMP;
 
-    // Deopt if shift is larger than 63 or less than 0.
+    // Deopt if shift is larger than 63 or less than 0 (or not a smi).
     if (!IsShiftCountInRange()) {
       ASSERT(CanDeoptimize());
       Label* deopt =
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 42beb69..70f8e2b 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -332,14 +332,14 @@
 EMIT_NATIVE_CODE(LoadLocal, 0) {
   ASSERT(!compiler->is_optimizing());
   const intptr_t slot_index =
-      compiler_frame_layout.FrameSlotForVariable(&local());
+      compiler::target::frame_layout.FrameSlotForVariable(&local());
   __ Push(LocalVarIndex(0, slot_index));
 }
 
 EMIT_NATIVE_CODE(StoreLocal, 0) {
   ASSERT(!compiler->is_optimizing());
   const intptr_t slot_index =
-      compiler_frame_layout.FrameSlotForVariable(&local());
+      compiler::target::frame_layout.FrameSlotForVariable(&local());
   if (HasTemp()) {
     __ StoreLocal(LocalVarIndex(0, slot_index));
   } else {
@@ -984,13 +984,13 @@
 
   const ExternalLabel trampoline_label(reinterpret_cast<uword>(trampoline));
   const intptr_t trampoline_kidx =
-      __ object_pool_wrapper().FindNativeFunctionWrapper(
-          &trampoline_label, ObjectPool::kPatchable);
+      __ object_pool_builder().FindNativeFunctionWrapper(
+          &trampoline_label, ObjectPool::Patchability::kPatchable);
   const ExternalLabel label(reinterpret_cast<uword>(function));
-  const intptr_t target_kidx = __ object_pool_wrapper().FindNativeFunction(
-      &label, ObjectPool::kPatchable);
+  const intptr_t target_kidx = __ object_pool_builder().FindNativeFunction(
+      &label, ObjectPool::Patchability::kPatchable);
   const intptr_t argc_tag_kidx =
-      __ object_pool_wrapper().FindImmediate(static_cast<uword>(argc_tag));
+      __ object_pool_builder().FindImmediate(static_cast<uword>(argc_tag));
   __ NativeCall(trampoline_kidx, target_kidx, argc_tag_kidx);
   compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, DeoptId::kNone,
@@ -1085,7 +1085,6 @@
 }
 
 EMIT_NATIVE_CODE(StoreInstanceField, 2) {
-  ASSERT(!HasTemp());
   ASSERT(OffsetInBytes() % kWordSize == 0);
   if (compiler->is_optimizing()) {
     const Register value = locs()->in(1).reg();
@@ -1200,13 +1199,13 @@
   if (!compiler->is_optimizing()) {
     if (raw_exception_var_ != nullptr) {
       __ MoveSpecial(
-          LocalVarIndex(0, compiler_frame_layout.FrameSlotForVariable(
+          LocalVarIndex(0, compiler::target::frame_layout.FrameSlotForVariable(
                                raw_exception_var_)),
           Simulator::kExceptionSpecialIndex);
     }
     if (raw_stacktrace_var_ != nullptr) {
       __ MoveSpecial(
-          LocalVarIndex(0, compiler_frame_layout.FrameSlotForVariable(
+          LocalVarIndex(0, compiler::target::frame_layout.FrameSlotForVariable(
                                raw_stacktrace_var_)),
           Simulator::kStackTraceSpecialIndex);
     }
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index ce677dc..3f6ee68 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -118,7 +118,8 @@
   __ Comment("Stack Check");
   Label done;
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ movl(EDI, ESP);
@@ -136,7 +137,7 @@
                                                      bool opt) const {
   const intptr_t kNumInputs = 0;
   const intptr_t stack_index =
-      compiler_frame_layout.FrameSlotForVariable(&local());
+      compiler::target::frame_layout.FrameSlotForVariable(&local());
   return LocationSummary::Make(zone, kNumInputs,
                                Location::StackSlot(stack_index),
                                LocationSummary::kNoCall);
@@ -158,9 +159,9 @@
   Register value = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
   ASSERT(result == value);  // Assert that register assignment is correct.
-  __ movl(Address(EBP, compiler_frame_layout.FrameOffsetInBytesForVariable(
-                           &local())),
-          value);
+  __ movl(
+      Address(EBP, compiler::target::FrameOffsetInBytesForVariable(&local())),
+      value);
 }
 
 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone,
@@ -2544,19 +2545,20 @@
   // Restore ESP from EBP as we are coming from a throw and the code for
   // popping arguments has not been run.
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ leal(ESP, Address(EBP, fp_sp_dist));
 
   if (!compiler->is_optimizing()) {
     if (raw_exception_var_ != nullptr) {
-      __ movl(Address(EBP, compiler_frame_layout.FrameOffsetInBytesForVariable(
+      __ movl(Address(EBP, compiler::target::FrameOffsetInBytesForVariable(
                                raw_exception_var_)),
               kExceptionObjectReg);
     }
     if (raw_stacktrace_var_ != nullptr) {
-      __ movl(Address(EBP, compiler_frame_layout.FrameOffsetInBytesForVariable(
+      __ movl(Address(EBP, compiler::target::FrameOffsetInBytesForVariable(
                                raw_stacktrace_var_)),
               kStackTraceObjectReg);
     }
@@ -5102,6 +5104,24 @@
   __ BranchIfNotSmi(value, deopt);
 }
 
+void CheckNullInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  NullErrorSlowPath* slow_path =
+      new NullErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Register value_reg = locs()->in(0).reg();
+  // TODO(dartbug.com/30480): Consider passing `null` literal as an argument
+  // in order to be able to allocate it on register.
+  __ CompareObject(value_reg, Object::null_object());
+  __ 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();
+}
+
 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -5579,7 +5599,7 @@
     ASSERT(locs()->in(1).reg() == ECX);
     __ SmiUntag(ECX);
 
-    // Deoptimize if shift count is > 63 or negative.
+    // Deoptimize if shift count is > 63 or negative (or not a smi).
     if (!IsShiftCountInRange()) {
       ASSERT(CanDeoptimize());
       Label* deopt =
@@ -5971,8 +5991,8 @@
   Register target_reg = locs()->temp_slot(0)->reg();
 
   // Load code object from frame.
-  __ movl(target_reg,
-          Address(EBP, compiler_frame_layout.code_from_fp * kWordSize));
+  __ movl(target_reg, Address(EBP, compiler::target::frame_layout.code_from_fp *
+                                       kWordSize));
   // Load instructions object (active_instructions and Code::entry_point() may
   // not point to this instruction object any more; see Code::DisableDartCode).
   __ movl(target_reg,
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 4ae5a22..aa045cf 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -118,7 +118,8 @@
   __ Comment("Stack Check");
   Label done;
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ movq(RDI, RSP);
@@ -238,7 +239,7 @@
                                                      bool opt) const {
   const intptr_t kNumInputs = 0;
   const intptr_t stack_index =
-      compiler_frame_layout.FrameSlotForVariable(&local());
+      compiler::target::frame_layout.FrameSlotForVariable(&local());
   return LocationSummary::Make(zone, kNumInputs,
                                Location::StackSlot(stack_index),
                                LocationSummary::kNoCall);
@@ -260,9 +261,9 @@
   Register value = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
   ASSERT(result == value);  // Assert that register assignment is correct.
-  __ movq(Address(RBP, compiler_frame_layout.FrameOffsetInBytesForVariable(
-                           &local())),
-          value);
+  __ movq(
+      Address(RBP, compiler::target::FrameOffsetInBytesForVariable(&local())),
+      value);
 }
 
 LocationSummary* ConstantInstr::MakeLocationSummary(Zone* zone,
@@ -853,7 +854,8 @@
   if (link_lazily()) {
     stub = &StubCode::CallBootstrapNative();
     ExternalLabel label(NativeEntry::LinkNativeCallEntry());
-    __ LoadNativeEntry(RBX, &label, ObjectPool::kPatchable);
+    __ LoadNativeEntry(RBX, &label,
+                       compiler::ObjectPoolBuilderEntry::kPatchable);
     compiler->GeneratePatchableCall(token_pos(), *stub,
                                     RawPcDescriptors::kOther, locs());
   } else {
@@ -865,7 +867,8 @@
       stub = &StubCode::CallNoScopeNative();
     }
     const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
-    __ LoadNativeEntry(RBX, &label, ObjectPool::kNotPatchable);
+    __ LoadNativeEntry(RBX, &label,
+                       compiler::ObjectPoolBuilderEntry::kNotPatchable);
     compiler->GenerateCall(token_pos(), *stub, RawPcDescriptors::kOther,
                            locs());
   }
@@ -2668,19 +2671,20 @@
   // Restore RSP from RBP as we are coming from a throw and the code for
   // popping arguments has not been run.
   const intptr_t fp_sp_dist =
-      (compiler_frame_layout.first_local_from_fp + 1 - compiler->StackSize()) *
+      (compiler::target::frame_layout.first_local_from_fp + 1 -
+       compiler->StackSize()) *
       kWordSize;
   ASSERT(fp_sp_dist <= 0);
   __ leaq(RSP, Address(RBP, fp_sp_dist));
 
   if (!compiler->is_optimizing()) {
     if (raw_exception_var_ != nullptr) {
-      __ movq(Address(RBP, compiler_frame_layout.FrameOffsetInBytesForVariable(
+      __ movq(Address(RBP, compiler::target::FrameOffsetInBytesForVariable(
                                raw_exception_var_)),
               kExceptionObjectReg);
     }
     if (raw_stacktrace_var_ != nullptr) {
-      __ movq(Address(RBP, compiler_frame_layout.FrameOffsetInBytesForVariable(
+      __ movq(Address(RBP, compiler::target::FrameOffsetInBytesForVariable(
                                raw_stacktrace_var_)),
               kStackTraceObjectReg);
     }
@@ -2730,11 +2734,9 @@
     compiler->pending_deoptimization_env_ = env;
 
     if (using_shared_stub) {
-      uword entry_point_offset =
-          instruction()->locs()->live_registers()->FpuRegisterCount() > 0
-              ? Thread::stack_overflow_shared_with_fpu_regs_entry_point_offset()
-              : Thread::
-                    stack_overflow_shared_without_fpu_regs_entry_point_offset();
+      const uword entry_point_offset =
+          Thread::stack_overflow_shared_stub_entry_point_offset(
+              instruction()->locs()->live_registers()->FpuRegisterCount() > 0);
       __ call(Address(THR, entry_point_offset));
       compiler->RecordSafepoint(instruction()->locs(), kNumSlowPathArgs);
       compiler->RecordCatchEntryMoves();
@@ -5193,6 +5195,23 @@
   __ BranchIfNotSmi(value, deopt);
 }
 
+void CheckNullInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  NullErrorSlowPath* slow_path =
+      new NullErrorSlowPath(this, compiler->CurrentTryIndex());
+  compiler->AddSlowPathCode(slow_path);
+
+  Register value_reg = locs()->in(0).reg();
+  // TODO(dartbug.com/30480): Consider passing `null` literal as an argument
+  // in order to be able to allocate it on register.
+  __ CompareObject(value_reg, Object::null_object());
+  __ BranchIf(EQUAL, slow_path->entry_label());
+}
+
+void NullErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
+                                           bool save_fpu_registers) {
+  compiler->assembler()->CallNullErrorShared(save_fpu_registers);
+}
+
 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -5776,7 +5795,7 @@
     ASSERT(locs()->in(1).reg() == RCX);
     __ SmiUntag(RCX);
 
-    // Deoptimize if shift count is > 63 or negative.
+    // Deoptimize if shift count is > 63 or negative (or not a smi).
     if (!IsShiftCountInRange()) {
       ASSERT(CanDeoptimize());
       Label* deopt =
@@ -6168,7 +6187,7 @@
     ASSERT(__ CodeSize() == entry_to_rip_offset);
   }
 
-  // Load from [current frame pointer] + compiler_frame_layout.code_from_fp.
+  // Load from FP+compiler::target::frame_layout.code_from_fp.
 
   // Calculate the final absolute address.
   if (offset()->definition()->representation() == kTagged) {
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 3b48fc5..159a903 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -56,6 +56,10 @@
             80,
             "Do not inline callees larger than threshold");
 DEFINE_FLAG(int,
+            inlining_small_leaf_size_threshold,
+            50,
+            "Do not inline leaf callees larger than threshold");
+DEFINE_FLAG(int,
             inlining_caller_size_threshold,
             50000,
             "Stop inlining once caller reaches the threshold.");
@@ -332,19 +336,16 @@
   static intptr_t AotCallCountApproximation(intptr_t nesting_depth) {
     switch (nesting_depth) {
       case 0:
-        // Note that we use value 0, and not 1, i.e. any straightline code
-        // outside a loop is assumed to be very cold. With value 1, inlining
-        // inside loops is still favored over inlining inside straightline
-        // code, but for a method without loops, *all* call sites are inlined
-        // (potentially more performance, at the expense of larger code size).
-        // TODO(ajcbik): use 1 and fine tune other heuristics
-        return 0;
+        // The value 1 makes most sense, but it may give a high ratio to call
+        // sites outside loops. Therefore, such call sites are subject to
+        // subsequent stricter heuristic to limit code size increase.
+        return 1;
       case 1:
         return 10;
       case 2:
-        return 100;
+        return 10 * 10;
       default:
-        return 1000;
+        return 10 * 10 * 10;
     }
   }
 
@@ -512,6 +513,36 @@
   DISALLOW_COPY_AND_ASSIGN(CallSites);
 };
 
+// Determines if inlining this graph yields a small leaf node.
+static bool IsSmallLeaf(FlowGraph* graph) {
+  intptr_t instruction_count = 0;
+  for (BlockIterator block_it = graph->postorder_iterator(); !block_it.Done();
+       block_it.Advance()) {
+    BlockEntryInstr* entry = block_it.Current();
+    for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+      Instruction* current = it.Current();
+      ++instruction_count;
+      if (current->IsInstanceCall() || current->IsPolymorphicInstanceCall() ||
+          current->IsClosureCall()) {
+        return false;
+      } else if (current->IsStaticCall()) {
+        const Function& function = current->AsStaticCall()->function();
+        const intptr_t inl_size = function.optimized_instruction_count();
+        // Accept a static call is always inlined in some way and add the
+        // cached size to the total instruction count. A reasonable guess
+        // is made if the count has not been collected yet (listed methods
+        // are never very large).
+        if (!function.always_inline() && !function.IsRecognized()) {
+          return false;
+        }
+        static constexpr intptr_t kAvgListedMethodSize = 20;
+        instruction_count += (inl_size == 0 ? kAvgListedMethodSize : inl_size);
+      }
+    }
+  }
+  return instruction_count <= FLAG_inlining_small_leaf_size_threshold;
+}
+
 struct InlinedCallData {
   InlinedCallData(Definition* call,
                   const Array& arguments_descriptor,
@@ -863,7 +894,8 @@
 
   bool TryInlining(const Function& function,
                    const Array& argument_names,
-                   InlinedCallData* call_data) {
+                   InlinedCallData* call_data,
+                   bool stricter_heuristic) {
     if (trace_inlining()) {
       String& name = String::Handle(function.QualifiedUserVisibleName());
       THR_Print("  => %s (deopt count %d)\n", name.ToCString(),
@@ -1174,7 +1206,7 @@
 
         if (FLAG_support_il_printer && trace_inlining() &&
             (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
-          THR_Print("Callee graph for inlining %s\n",
+          THR_Print("Callee graph for inlining %s (optimized)\n",
                     function.ToFullyQualifiedCString());
           FlowGraphPrinter printer(*callee_graph);
           printer.PrintBlocks();
@@ -1215,6 +1247,19 @@
           return false;
         }
 
+        // If requested, a stricter heuristic is applied to this inlining. This
+        // heuristic always scans the method (rather than possibly reusing
+        // cached results) to make sure all specializations are accounted for.
+        if (stricter_heuristic) {
+          if (!IsSmallLeaf(callee_graph)) {
+            TRACE_INLINING(
+                THR_Print("     Bailout: heuristics (no small leaf)\n"));
+            PRINT_INLINING_TREE("Heuristic fail (no small leaf)",
+                                &call_data->caller, &function, call_data->call);
+            return false;
+          }
+        }
+
         // Inline dispatcher methods regardless of the current depth.
         const intptr_t depth =
             function.IsDispatcherOrImplicitAccessor() ? 0 : inlining_depth_;
@@ -1436,7 +1481,17 @@
           call, Array::ZoneHandle(Z, call->GetArgumentsDescriptor()),
           call->FirstArgIndex(), &arguments, call_info[call_idx].caller(),
           call_info[call_idx].caller_graph->inlining_id());
-      if (TryInlining(call->function(), call->argument_names(), &call_data)) {
+
+      // Under AOT, calls outside loops may pass our regular heuristics due
+      // to a relatively high ratio. So, unless we are optimizing solely for
+      // speed, such call sites are subject to subsequent stricter heuristic
+      // to limit code size increase.
+      bool stricter_heuristic = FLAG_precompiled_mode &&
+                                FLAG_optimization_level <= 2 &&
+                                !inliner_->AlwaysInline(target) &&
+                                call_info[call_idx].nesting_depth == 0;
+      if (TryInlining(call->function(), call->argument_names(), &call_data,
+                      stricter_heuristic)) {
         InlineCall(&call_data);
         inlined = true;
       }
@@ -1489,7 +1544,7 @@
           call, arguments_descriptor, call->FirstArgIndex(), &arguments,
           call_info[call_idx].caller(),
           call_info[call_idx].caller_graph->inlining_id());
-      if (TryInlining(target, call->argument_names(), &call_data)) {
+      if (TryInlining(target, call->argument_names(), &call_data, false)) {
         InlineCall(&call_data);
         inlined = true;
       }
@@ -1751,7 +1806,7 @@
                             caller_function_, caller_inlining_id_);
   Function& target = Function::ZoneHandle(zone(), target_info.target->raw());
   if (!owner_->TryInlining(target, call_->instance_call()->argument_names(),
-                           &call_data)) {
+                           &call_data, false)) {
     return false;
   }
 
@@ -3386,20 +3441,25 @@
       entry->UnuseAllInputs();  // Entry block is not in the graph.
       if (last != NULL) {
         BlockEntryInstr* link = call->GetBlock();
-        Instruction* exit = last->GetBlock();
+        BlockEntryInstr* exit = last->GetBlock();
         if (link != exit) {
           // Dominance relation and SSA are updated incrementally when
           // conditionals are inserted. But succ/pred and ordering needs
           // to be redone. TODO(ajcbik): do this incrementally too.
+          for (intptr_t i = 0, n = link->dominated_blocks().length(); i < n;
+               ++i) {
+            exit->AddDominatedBlock(link->dominated_blocks()[i]);
+          }
           link->ClearDominatedBlocks();
           for (intptr_t i = 0, n = entry->dominated_blocks().length(); i < n;
                ++i) {
             link->AddDominatedBlock(entry->dominated_blocks()[i]);
           }
-          while (exit->next()) {
-            exit = exit->next();
+          Instruction* scan = exit;
+          while (scan->next() != nullptr) {
+            scan = scan->next();
           }
-          exit->LinkTo(call);
+          scan->LinkTo(call);
           flow_graph->DiscoverBlocks();
         } else {
           last->LinkTo(call);
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index 15184b1..b09079d 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -474,7 +474,7 @@
   assigned_location().Print();
   if (spill_slot_.HasStackIndex()) {
     const intptr_t stack_slot =
-        -compiler_frame_layout.VariableIndexForFrameSlot(
+        -compiler::target::frame_layout.VariableIndexForFrameSlot(
             spill_slot_.stack_index());
     THR_Print(" allocated spill slot: %" Pd "", stack_slot);
   }
@@ -750,7 +750,8 @@
     }
 #endif  // defined(TARGET_ARCH_DBC)
     if (param->base_reg() == FPREG) {
-      slot_index = compiler_frame_layout.FrameSlotForVariableIndex(-slot_index);
+      slot_index =
+          compiler::target::frame_layout.FrameSlotForVariableIndex(-slot_index);
     }
     range->set_assigned_location(
         Location::StackSlot(slot_index, param->base_reg()));
@@ -793,7 +794,8 @@
   ConvertAllUses(range);
   Location spill_slot = range->spill_slot();
   if (spill_slot.IsStackSlot() && spill_slot.base_reg() == FPREG &&
-      spill_slot.stack_index() <= compiler_frame_layout.first_local_from_fp) {
+      spill_slot.stack_index() <=
+          compiler::target::frame_layout.first_local_from_fp) {
     // On entry to the function, range is stored on the stack above the FP in
     // the same space which is used for spill slots. Update spill slot state to
     // reflect that and prevent register allocator from reusing this space as a
@@ -2039,15 +2041,16 @@
   // Assign spill slot to the range.
   if (register_kind_ == Location::kRegister) {
     const intptr_t slot_index =
-        compiler_frame_layout.FrameSlotForVariableIndex(-idx);
+        compiler::target::frame_layout.FrameSlotForVariableIndex(-idx);
     range->set_spill_slot(Location::StackSlot(slot_index));
   } else {
     // We use the index of the slot with the lowest address as an index for the
     // FPU register spill slot. In terms of indexes this relation is inverted:
     // so we have to take the highest index.
-    const intptr_t slot_idx = compiler_frame_layout.FrameSlotForVariableIndex(
-        -(cpu_spill_slot_count_ + idx * kDoubleSpillFactor +
-          (kDoubleSpillFactor - 1)));
+    const intptr_t slot_idx =
+        compiler::target::frame_layout.FrameSlotForVariableIndex(
+            -(cpu_spill_slot_count_ + idx * kDoubleSpillFactor +
+              (kDoubleSpillFactor - 1)));
 
     Location location;
     if ((range->representation() == kUnboxedFloat32x4) ||
@@ -2069,7 +2072,7 @@
   Location spill_slot = range->spill_slot();
   intptr_t stack_index = spill_slot.stack_index();
   if (spill_slot.base_reg() == FPREG) {
-    stack_index = -compiler_frame_layout.VariableIndexForFrameSlot(
+    stack_index = -compiler::target::frame_layout.VariableIndexForFrameSlot(
         spill_slot.stack_index());
   }
   ASSERT(stack_index >= 0);
diff --git a/runtime/vm/compiler/backend/locations.cc b/runtime/vm/compiler/backend/locations.cc
index 569be42..e549879 100644
--- a/runtime/vm/compiler/backend/locations.cc
+++ b/runtime/vm/compiler/backend/locations.cc
@@ -23,6 +23,23 @@
   return count;
 }
 
+void RegisterSet::DebugPrint() {
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
+    Register r = static_cast<Register>(i);
+    if (ContainsRegister(r)) {
+      THR_Print("%s %s\n", Assembler::RegisterName(r),
+                IsTagged(r) ? "tagged" : "untagged");
+    }
+  }
+
+  for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
+    FpuRegister r = static_cast<FpuRegister>(i);
+    if (ContainsFpuRegister(r)) {
+      THR_Print("%s\n", Assembler::FpuRegisterName(r));
+    }
+  }
+}
+
 LocationSummary::LocationSummary(Zone* zone,
                                  intptr_t input_count,
                                  intptr_t temp_count,
@@ -233,20 +250,20 @@
     intptr_t index = cpu_reg_slots[reg()];
     ASSERT(index >= 0);
     return Location::StackSlot(
-        compiler_frame_layout.FrameSlotForVariableIndex(-index));
+        compiler::target::frame_layout.FrameSlotForVariableIndex(-index));
   } else if (IsFpuRegister()) {
     intptr_t index = fpu_reg_slots[fpu_reg()];
     ASSERT(index >= 0);
     switch (def->representation()) {
       case kUnboxedDouble:
         return Location::DoubleStackSlot(
-            compiler_frame_layout.FrameSlotForVariableIndex(-index));
+            compiler::target::frame_layout.FrameSlotForVariableIndex(-index));
 
       case kUnboxedFloat32x4:
       case kUnboxedInt32x4:
       case kUnboxedFloat64x2:
         return Location::QuadStackSlot(
-            compiler_frame_layout.FrameSlotForVariableIndex(-index));
+            compiler::target::frame_layout.FrameSlotForVariableIndex(-index));
 
       default:
         UNREACHABLE();
@@ -258,7 +275,7 @@
     intptr_t index_hi;
 
     if (value_pair->At(0).IsRegister()) {
-      index_lo = compiler_frame_layout.FrameSlotForVariableIndex(
+      index_lo = compiler::target::frame_layout.FrameSlotForVariableIndex(
           -cpu_reg_slots[value_pair->At(0).reg()]);
     } else {
       ASSERT(value_pair->At(0).IsStackSlot());
@@ -266,7 +283,7 @@
     }
 
     if (value_pair->At(1).IsRegister()) {
-      index_hi = compiler_frame_layout.FrameSlotForVariableIndex(
+      index_hi = compiler::target::frame_layout.FrameSlotForVariableIndex(
           -cpu_reg_slots[value_pair->At(1).reg()]);
     } else {
       ASSERT(value_pair->At(1).IsStackSlot());
diff --git a/runtime/vm/compiler/backend/locations.h b/runtime/vm/compiler/backend/locations.h
index 8da9934..9c76dd6 100644
--- a/runtime/vm/compiler/backend/locations.h
+++ b/runtime/vm/compiler/backend/locations.h
@@ -7,8 +7,8 @@
 
 #include "vm/allocation.h"
 #include "vm/bitfield.h"
+#include "vm/bitmap.h"
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/log.h"
 
 namespace dart {
 
@@ -17,7 +17,6 @@
 class Definition;
 class PairLocation;
 class Value;
-struct FrameLayout;
 
 enum Representation {
   kNoRepresentation,
@@ -561,22 +560,7 @@
     }
   }
 
-  void DebugPrint() {
-    for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
-      Register r = static_cast<Register>(i);
-      if (ContainsRegister(r)) {
-        THR_Print("%s %s\n", Assembler::RegisterName(r),
-                  IsTagged(r) ? "tagged" : "untagged");
-      }
-    }
-
-    for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
-      FpuRegister r = static_cast<FpuRegister>(i);
-      if (ContainsFpuRegister(r)) {
-        THR_Print("%s\n", Assembler::FpuRegisterName(r));
-      }
-    }
-  }
+  void DebugPrint();
 
   void MarkUntagged(Location loc) {
     ASSERT(loc.IsRegister());
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 28f2199..e0f096b 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2801,10 +2801,12 @@
 }
 
 void ShiftIntegerOpInstr::InferRange(RangeAnalysis* analysis, Range* range) {
+  const Range* right_range = RequiredInputRepresentation(1) == kTagged
+                                 ? analysis->GetSmiRange(right())
+                                 : right()->definition()->range();
   CacheRange(&shift_range_, right()->definition()->range(),
              RangeBoundary::kRangeBoundaryInt64);
-  InferRangeHelper(left()->definition()->range(),
-                   right()->definition()->range(), range);
+  InferRangeHelper(left()->definition()->range(), right_range, range);
 }
 
 void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index cb7360e..4f707cd 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -40,12 +40,8 @@
 }
 
 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
-#ifndef PRODUCT
-  Thread* thread = flow_graph->thread();
-  TimelineStream* compiler_timeline = Timeline::GetCompilerStream();
-  TimelineDurationScope tds2(thread, compiler_timeline,
-                             "FlowGraphTypePropagator");
-#endif  // !PRODUCT
+  TIMELINE_DURATION(flow_graph->thread(), CompilerVerbose,
+                    "FlowGraphTypePropagator");
   FlowGraphTypePropagator propagator(flow_graph);
   propagator.Propagate();
 }
@@ -283,7 +279,7 @@
 void FlowGraphTypePropagator::VisitCheckNull(CheckNullInstr* check) {
   Definition* receiver = check->value()->definition();
   CompileType* type = TypeOf(receiver);
-  if (type->is_nullable() && !type->IsNull()) {
+  if (type->is_nullable()) {
     // Insert redefinition for the receiver to guard against invalid
     // code motion.
     EnsureMoreAccurateRedefinition(check, receiver, type->CopyNonNullable());
@@ -305,7 +301,7 @@
   if (target.IsNull()) {
     // If the selector is not defined on Null, we can propagate non-nullness.
     CompileType* type = TypeOf(receiver);
-    if (type->is_nullable() && !type->IsNull()) {
+    if (type->is_nullable()) {
       // Insert redefinition for the receiver to guard against invalid
       // code motion.
       EnsureMoreAccurateRedefinition(call, receiver, type->CopyNonNullable());
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 3d3404e..42e2f9b 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -311,14 +311,25 @@
   call->ReplaceWith(specialized, current_iterator());
 }
 
-void CallSpecializer::ReplaceCall(Definition* call, Definition* replacement) {
+void CallSpecializer::ReplaceCallWithResult(Definition* call,
+                                            Instruction* replacement,
+                                            Definition* result) {
   // Remove the original push arguments.
   for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
     PushArgumentInstr* push = call->PushArgumentAt(i);
     push->ReplaceUsesWith(push->value()->definition());
     push->RemoveFromGraph();
   }
-  call->ReplaceWith(replacement, current_iterator());
+  if (result == nullptr) {
+    ASSERT(replacement->IsDefinition());
+    call->ReplaceWith(replacement->AsDefinition(), current_iterator());
+  } else {
+    call->ReplaceWithResult(replacement, result, current_iterator());
+  }
+}
+
+void CallSpecializer::ReplaceCall(Definition* call, Definition* replacement) {
+  ReplaceCallWithResult(call, replacement, nullptr);
 }
 
 void CallSpecializer::AddCheckSmi(Definition* to_check,
@@ -1065,7 +1076,7 @@
   // Discard the environment from the original instruction because the store
   // can't deoptimize.
   instr->RemoveEnvironment();
-  ReplaceCall(instr, store);
+  ReplaceCallWithResult(instr, store, flow_graph()->constant_null());
   return true;
 }
 
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h
index c830e02..cb9ca8c 100644
--- a/runtime/vm/compiler/call_specializer.h
+++ b/runtime/vm/compiler/call_specializer.h
@@ -83,6 +83,12 @@
   bool TryInlineInstanceMethod(InstanceCallInstr* call);
   void ReplaceWithInstanceOf(InstanceCallInstr* instr);
 
+  // Replaces a call where the replacement code does not end in a
+  // value-returning instruction, so we must specify what definition should be
+  // used instead to replace uses of the call return value.
+  void ReplaceCallWithResult(Definition* call,
+                             Instruction* replacement,
+                             Definition* result);
   void ReplaceCall(Definition* call, Definition* replacement);
 
   // Add a class check for the call's first argument (receiver).
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index e72f1a3..4befad9 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -9,6 +9,7 @@
 #include "vm/compiler/backend/block_scheduler.h"
 #include "vm/compiler/backend/branch_optimizer.h"
 #include "vm/compiler/backend/constant_propagator.h"
+#include "vm/compiler/backend/flow_graph_checker.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/linearscan.h"
@@ -173,11 +174,12 @@
 
     PrintGraph(state, kTraceBefore, round);
     {
-      NOT_IN_PRODUCT(
-          TimelineDurationScope tds2(thread, state->compiler_timeline, name()));
+      TIMELINE_DURATION(thread, CompilerVerbose, name());
       repeat = DoBody(state);
-      DEBUG_ASSERT(state->flow_graph->VerifyUseLists());
       thread->CheckForSafepoint();
+#if defined(DEBUG)
+      FlowGraphChecker(state->flow_graph).Check();
+#endif
     }
     PrintGraph(state, kTraceAfter, round);
   }
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index 1e0f613..044ae6e 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -52,6 +52,7 @@
 class Precompiler;
 class SpeculativeInliningPolicy;
 class TimelineStream;
+class Thread;
 
 struct CompilerPassState {
   CompilerPassState(Thread* thread,
@@ -63,9 +64,6 @@
         precompiler(precompiler),
         inlining_depth(0),
         sinking(NULL),
-#ifndef PRODUCT
-        compiler_timeline(NULL),
-#endif
         call_specializer(NULL),
         speculative_policy(speculative_policy),
         reorder_blocks(false),
@@ -79,8 +77,6 @@
   int inlining_depth;
   AllocationSinking* sinking;
 
-  NOT_IN_PRODUCT(TimelineStream* compiler_timeline);
-
   // Maps inline_id_to_function[inline_id] -> function. Top scope
   // function has inline_id 0. The map is populated by the inliner.
   GrowableArray<const Function*> inline_id_to_function;
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index 1b6e95f..24c985a 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -9,6 +9,13 @@
   "aot/aot_call_specializer.h",
   "aot/precompiler.cc",
   "aot/precompiler.h",
+  "asm_intrinsifier.cc",
+  "asm_intrinsifier.h",
+  "asm_intrinsifier_arm.cc",
+  "asm_intrinsifier_arm64.cc",
+  "asm_intrinsifier_dbc.cc",
+  "asm_intrinsifier_ia32.cc",
+  "asm_intrinsifier_x64.cc",
   "assembler/assembler.cc",
   "assembler/assembler.h",
   "assembler/assembler_arm.cc",
@@ -29,17 +36,20 @@
   "assembler/disassembler_kbc.cc",
   "assembler/disassembler_kbc.h",
   "assembler/disassembler_x86.cc",
+  "assembler/object_pool_builder.h",
   "backend/block_scheduler.cc",
   "backend/block_scheduler.h",
   "backend/branch_optimizer.cc",
   "backend/branch_optimizer.h",
   "backend/code_statistics.cc",
   "backend/code_statistics.h",
+  "backend/compile_type.h",
   "backend/constant_propagator.cc",
   "backend/constant_propagator.h",
-  "backend/compile_type.h",
   "backend/flow_graph.cc",
   "backend/flow_graph.h",
+  "backend/flow_graph_checker.cc",
+  "backend/flow_graph_checker.h",
   "backend/flow_graph_compiler.cc",
   "backend/flow_graph_compiler.h",
   "backend/flow_graph_compiler_arm.cc",
@@ -104,21 +114,31 @@
   "frontend/prologue_builder.h",
   "frontend/scope_builder.cc",
   "frontend/scope_builder.h",
+  "graph_intrinsifier.cc",
+  "graph_intrinsifier.h",
+  "graph_intrinsifier_arm.cc",
+  "graph_intrinsifier_arm64.cc",
+  "graph_intrinsifier_ia32.cc",
+  "graph_intrinsifier_x64.cc",
   "intrinsifier.cc",
   "intrinsifier.h",
-  "intrinsifier_arm.cc",
-  "intrinsifier_arm64.cc",
-  "intrinsifier_dbc.cc",
-  "intrinsifier_ia32.cc",
-  "intrinsifier_x64.cc",
   "jit/compiler.cc",
   "jit/compiler.h",
   "jit/jit_call_specializer.cc",
   "jit/jit_call_specializer.h",
   "method_recognizer.cc",
   "method_recognizer.h",
+  "recognized_methods_list.h",
   "relocation.cc",
   "relocation.h",
+  "runtime_api.cc",
+  "runtime_api.h",
+  "stub_code_compiler.h",
+  "stub_code_compiler_arm.cc",
+  "stub_code_compiler_arm64.cc",
+  "stub_code_compiler_dbc.cc",
+  "stub_code_compiler_ia32.cc",
+  "stub_code_compiler_x64.cc",
 ]
 
 compiler_sources_tests = [
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index eadab31..eebb0b8 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -451,7 +451,6 @@
       Pop(),  // Array.
       index, value, emit_store_barrier, Instance::ElementSizeFor(class_id),
       class_id, kAlignedAccess, DeoptId::kNone, TokenPosition::kNoSource);
-  Push(store);
   return Fragment(store);
 }
 
@@ -631,7 +630,6 @@
   Value* index = Pop();
   StoreIndexedUnsafeInstr* instr =
       new (Z) StoreIndexedUnsafeInstr(index, value, offset);
-  Push(instr);
   return Fragment(instr);
 }
 
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index 361da68..3853076 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -508,11 +508,11 @@
   PrologueBuilder prologue_builder(parsed_function(), B->last_used_block_id_,
                                    B->IsCompiledForOsr(), B->IsInlining());
 
-  B->last_used_block_id_ = prologue_builder.last_used_block_id();
-
   copy_args_prologue += prologue_builder.BuildOptionalParameterHandling(
       throw_no_such_method_, temp_var);
 
+  B->last_used_block_id_ = prologue_builder.last_used_block_id();
+
   JoinEntryInstr* prologue_exit = B->BuildJoinEntry();
   copy_args_prologue += B->Goto(prologue_exit);
   copy_args_prologue.current = prologue_exit;
@@ -597,7 +597,7 @@
     store_type_args += B->LoadArgDescriptor();
     store_type_args += B->LoadNativeField(Slot::ArgumentsDescriptor_count());
     store_type_args += B->LoadFpRelativeSlot(
-        kWordSize * (1 + compiler_frame_layout.param_end_from_fp));
+        kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp));
     store_type_args +=
         B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var);
     store_type_args += B->Drop();
@@ -701,6 +701,33 @@
   B->Push(call);
 }
 
+void BytecodeFlowGraphBuilder::BuildDirectCall() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value());
+  const Array& arg_desc_array =
+      Array::Cast(ConstantAt(DecodeOperandD(), 1).value());
+  const ArgumentsDescriptor arg_desc(arg_desc_array);
+  intptr_t argc = DecodeOperandA().value();
+
+  ArgumentArray arguments = GetArguments(argc);
+
+  // TODO(alexmarkov): pass ICData::kSuper for super calls
+  // (need to distinguish them in bytecode).
+  StaticCallInstr* call = new (Z) StaticCallInstr(
+      position_, target, arg_desc.TypeArgsLen(),
+      Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), arguments,
+      *ic_data_array_, B->GetNextDeoptId(), ICData::kStatic);
+
+  // TODO(alexmarkov): add type info
+  // SetResultTypeForStaticCall(call, target, argument_count, result_type);
+
+  code_ <<= call;
+  B->Push(call);
+}
+
 void BytecodeFlowGraphBuilder::BuildInterfaceCall() {
   if (is_generating_interpreter()) {
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
@@ -994,7 +1021,6 @@
 void BytecodeFlowGraphBuilder::BuildStoreIndexedTOS() {
   LoadStackSlots(3);
   code_ += B->StoreIndexed(kArrayCid);
-  code_ += B->Drop();
 }
 
 void BytecodeFlowGraphBuilder::BuildBooleanNegateTOS() {
@@ -1365,7 +1391,7 @@
 }
 
 static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) {
-  if (object_pool.TypeAt(index) != ObjectPool::kTaggedObject) {
+  if (object_pool.TypeAt(index) != ObjectPool::EntryType::kTaggedObject) {
     return false;
   }
   RawObject* entry = object_pool.ObjectAt(index);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index e1379bd..3c7e344 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -17,9 +17,8 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
-#define Z (helper_->zone_)
+#define Z (zone_)
 #define H (translation_helper_)
-#define T (type_translator_)
 #define I Isolate::Current()
 
 namespace dart {
@@ -29,14 +28,9 @@
 namespace kernel {
 
 BytecodeMetadataHelper::BytecodeMetadataHelper(KernelReaderHelper* helper,
-                                               TypeTranslator* type_translator,
                                                ActiveClass* active_class)
     : MetadataHelper(helper, tag(), /* precompiler_only = */ false),
-      type_translator_(*type_translator),
-      active_class_(active_class),
-      bytecode_component_(nullptr),
-      closures_(nullptr),
-      function_type_type_parameters_(nullptr) {}
+      active_class_(active_class) {}
 
 bool BytecodeMetadataHelper::HasBytecode(intptr_t node_offset) {
   const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
@@ -44,7 +38,7 @@
 }
 
 void BytecodeMetadataHelper::ReadMetadata(const Function& function) {
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
   TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
                             "BytecodeMetadataHelper::ReadMetadata");
   // This increases bytecode reading time by ~7%, so only keep it around for
@@ -64,13 +58,44 @@
   ASSERT(Thread::Current()->IsMutatorThread());
 
   Array& bytecode_component_array =
-      Array::Handle(Z, translation_helper_.GetBytecodeComponent());
+      Array::Handle(helper_->zone_, translation_helper_.GetBytecodeComponent());
   if (bytecode_component_array.IsNull()) {
     bytecode_component_array = ReadBytecodeComponent();
     ASSERT(!bytecode_component_array.IsNull());
   }
+
   BytecodeComponentData bytecode_component(bytecode_component_array);
-  bytecode_component_ = &bytecode_component;
+  BytecodeReaderHelper bytecode_reader(helper_, active_class_,
+                                       &bytecode_component);
+
+  bytecode_reader.ReadMemberBytecode(function, md_offset);
+}
+
+RawArray* BytecodeMetadataHelper::ReadBytecodeComponent() {
+  const intptr_t md_offset = GetComponentMetadataPayloadOffset();
+  if (md_offset < 0) {
+    return Array::null();
+  }
+
+  BytecodeReaderHelper component_reader(helper_, nullptr, nullptr);
+  return component_reader.ReadBytecodeComponent(md_offset);
+}
+
+BytecodeReaderHelper::BytecodeReaderHelper(
+    KernelReaderHelper* helper,
+    ActiveClass* active_class,
+    BytecodeComponentData* bytecode_component)
+    : helper_(helper),
+      translation_helper_(helper->translation_helper_),
+      active_class_(active_class),
+      zone_(helper_->zone_),
+      bytecode_component_(bytecode_component),
+      closures_(nullptr),
+      function_type_type_parameters_(nullptr) {}
+
+void BytecodeReaderHelper::ReadMemberBytecode(const Function& function,
+                                              intptr_t md_offset) {
+  ASSERT(Thread::Current()->IsMutatorThread());
 
   AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
                               md_offset);
@@ -97,8 +122,7 @@
 
   // Create object pool and read pool entries.
   const intptr_t obj_count = helper_->reader_.ReadListLength();
-  const ObjectPool& pool =
-      ObjectPool::Handle(helper_->zone_, ObjectPool::New(obj_count));
+  const ObjectPool& pool = ObjectPool::Handle(Z, ObjectPool::New(obj_count));
 
   {
     // While reading pool entries, deopt_ids are allocated for
@@ -111,11 +135,9 @@
   }
 
   // Read bytecode and attach to function.
-  const Bytecode& bytecode =
-      Bytecode::Handle(helper_->zone_, ReadBytecode(pool));
+  const Bytecode& bytecode = Bytecode::Handle(Z, ReadBytecode(pool));
   function.AttachBytecode(bytecode);
-  ASSERT(bytecode.GetBinary(helper_->zone_) ==
-         helper_->reader_.typed_data()->raw());
+  ASSERT(bytecode.GetBinary(Z) == helper_->reader_.typed_data()->raw());
 
   ReadExceptionsTable(bytecode, has_exceptions_table);
 
@@ -131,7 +153,7 @@
     ASSERT(function.IsGenerativeConstructor());
     const intptr_t num_fields = helper_->ReadListLength();
     if (I->use_field_guards()) {
-      Field& field = Field::Handle(helper_->zone_);
+      Field& field = Field::Handle(Z);
       for (intptr_t i = 0; i < num_fields; i++) {
         field ^= ReadObject();
         field.RecordStore(Object::null_object());
@@ -145,8 +167,8 @@
 
   // Read closures.
   if (has_closures) {
-    Function& closure = Function::Handle(helper_->zone_);
-    Bytecode& closure_bytecode = Bytecode::Handle(helper_->zone_);
+    Function& closure = Function::Handle(Z);
+    Bytecode& closure_bytecode = Bytecode::Handle(Z);
     for (intptr_t i = 0; i < num_closures; i++) {
       closure ^= closures_->At(i);
 
@@ -157,8 +179,7 @@
       // Read closure bytecode and attach to closure function.
       closure_bytecode = ReadBytecode(pool);
       closure.AttachBytecode(closure_bytecode);
-      ASSERT(bytecode.GetBinary(helper_->zone_) ==
-             helper_->reader_.typed_data()->raw());
+      ASSERT(bytecode.GetBinary(Z) == helper_->reader_.typed_data()->raw());
 
       ReadExceptionsTable(closure_bytecode, has_exceptions_table);
 
@@ -169,12 +190,10 @@
       }
     }
   }
-
-  bytecode_component_ = nullptr;
 }
 
-void BytecodeMetadataHelper::ReadClosureDeclaration(const Function& function,
-                                                    intptr_t closureIndex) {
+void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function,
+                                                  intptr_t closureIndex) {
   const int kHasOptionalPositionalParams = 1 << 0;
   const int kHasOptionalNamedParams = 1 << 1;
   const int kHasTypeParams = 1 << 2;
@@ -208,7 +227,7 @@
   closure.SetSignatureType(signature_type);
 }
 
-RawType* BytecodeMetadataHelper::ReadFunctionSignature(
+RawType* BytecodeReaderHelper::ReadFunctionSignature(
     const Function& func,
     bool has_optional_positional_params,
     bool has_optional_named_params,
@@ -270,7 +289,7 @@
   return Type::Cast(type).raw();
 }
 
-void BytecodeMetadataHelper::ReadTypeParametersDeclaration(
+void BytecodeReaderHelper::ReadTypeParametersDeclaration(
     const Class& parameterized_class,
     const Function& parameterized_function,
     intptr_t num_type_params) {
@@ -308,22 +327,20 @@
   }
 }
 
-void BytecodeMetadataHelper::ReadConstantPool(const Function& function,
-                                              const ObjectPool& pool) {
-#if !defined(PRODUCT)
-  TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
-                            "BytecodeMetadataHelper::ReadConstantPool");
-#endif  // !defined(PRODUCT)
+void BytecodeReaderHelper::ReadConstantPool(const Function& function,
+                                            const ObjectPool& pool) {
+  TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
+                    "BytecodeReaderHelper::ReadConstantPool");
 
   // These enums and the code below reading the constant pool from kernel must
   // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart.
   enum ConstantPoolTag {
     kInvalid,
-    kNull,
-    kString,
-    kInt,
-    kDouble,
-    kBool,
+    kNull,    // TODO(alexmarkov): obsolete, remove
+    kString,  // TODO(alexmarkov): obsolete, remove
+    kInt,     // TODO(alexmarkov): obsolete, remove
+    kDouble,  // TODO(alexmarkov): obsolete, remove
+    kBool,    // TODO(alexmarkov): obsolete, remove
     kArgDesc,
     kICData,
     kStaticICData,
@@ -331,19 +348,22 @@
     kInstanceField,
     kClass,
     kTypeArgumentsField,
-    kTearOff,
+    kTearOff,  // TODO(alexmarkov): obsolete, remove
     kType,
-    kTypeArguments,
-    kList,
-    kInstance,
-    kTypeArgumentsForInstanceAllocation,
+    kTypeArguments,                       // TODO(alexmarkov): obsolete, remove
+    kList,                                // TODO(alexmarkov): obsolete, remove
+    kInstance,                            // TODO(alexmarkov): obsolete, remove
+    kTypeArgumentsForInstanceAllocation,  // TODO(alexmarkov): obsolete, remove
     kClosureFunction,
     kEndClosureFunctionScope,
     kNativeEntry,
     kSubtypeTestCache,
-    kPartialTearOffInstantiation,
+    kPartialTearOffInstantiation,  // TODO(alexmarkov): obsolete, remove
     kEmptyTypeArguments,
-    kSymbol,
+    kSymbol,           // TODO(alexmarkov): obsolete, remove
+    kInterfaceCallV1,  // TODO(alexmarkov): obsolete, remove
+    kObjectRef,
+    kDirectCall,
     kInterfaceCall,
   };
 
@@ -356,13 +376,13 @@
   const int kInvocationKindMask = 0x3;
   const int kFlagDynamic = 1 << 2;
 
-  Object& obj = Object::Handle(helper_->zone_);
-  Object& elem = Object::Handle(helper_->zone_);
-  Array& array = Array::Handle(helper_->zone_);
-  Field& field = Field::Handle(helper_->zone_);
-  Class& cls = Class::Handle(helper_->zone_);
-  String& name = String::Handle(helper_->zone_);
-  TypeArguments& type_args = TypeArguments::Handle(helper_->zone_);
+  Object& obj = Object::Handle(Z);
+  Object& elem = Object::Handle(Z);
+  Array& array = Array::Handle(Z);
+  Field& field = Field::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  String& name = String::Handle(Z);
+  TypeArguments& type_args = TypeArguments::Handle(Z);
   Class* symbol_class = nullptr;
   Field* symbol_name_field = nullptr;
   const String* simpleInstanceOf = nullptr;
@@ -455,9 +475,6 @@
                         array,  // Arguments descriptor.
                         H.thread()->compiler_state().GetNextDeoptId(),
                         checked_argument_count, ICData::RebindRule::kInstance);
-#if defined(TAG_IC_DATA)
-        ICData::Cast(obj).set_tag(ICData::Tag::kInstanceCall);
-#endif
       } break;
       case ConstantPoolTag::kStaticICData: {
         elem = ReadObject();
@@ -473,9 +490,6 @@
                           H.thread()->compiler_state().GetNextDeoptId(),
                           num_args_checked, ICData::RebindRule::kStatic);
         ICData::Cast(obj).AddTarget(Function::Cast(elem));
-#if defined(TAG_IC_DATA)
-        ICData::Cast(obj).set_tag(ICData::Tag::kStaticCall);
-#endif
       } break;
       case ConstantPoolTag::kStaticField:
         obj = ReadObject();
@@ -486,7 +500,8 @@
         // InstanceField constant occupies 2 entries.
         // The first entry is used for field offset.
         obj = Smi::New(field.Offset() / kWordSize);
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
+        pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
+                       ObjectPool::Patchability::kNotPatchable);
         pool.SetObjectAt(i, obj);
         ++i;
         ASSERT(i < obj_count);
@@ -570,8 +585,8 @@
       case ConstantPoolTag::kNativeEntry: {
         name = ReadString();
         obj = NativeEntry(function, name);
-        pool.SetTypeAt(i, ObjectPool::kNativeEntryData,
-                       ObjectPool::kNotPatchable);
+        pool.SetTypeAt(i, ObjectPool::EntryType::kNativeEntryData,
+                       ObjectPool::Patchability::kNotPatchable);
         pool.SetObjectAt(i, obj);
         continue;
       }
@@ -581,20 +596,18 @@
       case ConstantPoolTag::kPartialTearOffInstantiation: {
         intptr_t tearoff_index = helper_->ReadUInt();
         ASSERT(tearoff_index < i);
-        const Closure& old_closure = Closure::CheckedHandle(
-            helper_->zone_, pool.ObjectAt(tearoff_index));
+        const Closure& old_closure =
+            Closure::CheckedHandle(Z, pool.ObjectAt(tearoff_index));
 
         intptr_t type_args_index = helper_->ReadUInt();
         ASSERT(type_args_index < i);
         type_args ^= pool.ObjectAt(type_args_index);
 
         obj = Closure::New(
-            TypeArguments::Handle(helper_->zone_,
-                                  old_closure.instantiator_type_arguments()),
-            TypeArguments::Handle(helper_->zone_,
-                                  old_closure.function_type_arguments()),
-            type_args, Function::Handle(helper_->zone_, old_closure.function()),
-            Context::Handle(helper_->zone_, old_closure.context()), Heap::kOld);
+            TypeArguments::Handle(Z, old_closure.instantiator_type_arguments()),
+            TypeArguments::Handle(Z, old_closure.function_type_arguments()),
+            type_args, Function::Handle(Z, old_closure.function()),
+            Context::Handle(Z, old_closure.context()), Heap::kOld);
         obj = H.Canonicalize(Instance::Cast(obj));
       } break;
       case ConstantPoolTag::kEmptyTypeArguments:
@@ -607,11 +620,10 @@
           elem = Library::InternalLibrary();
           ASSERT(!elem.IsNull());
           symbol_class = &Class::Handle(
-              helper_->zone_,
-              Library::Cast(elem).LookupClass(Symbols::Symbol()));
+              Z, Library::Cast(elem).LookupClass(Symbols::Symbol()));
           ASSERT(!symbol_class->IsNull());
           symbol_name_field = &Field::Handle(
-              helper_->zone_,
+              Z,
               symbol_class->LookupInstanceFieldAllowPrivate(Symbols::_name()));
           ASSERT(!symbol_name_field->IsNull());
         }
@@ -619,7 +631,7 @@
         Instance::Cast(obj).SetField(*symbol_name_field, name);
         obj = H.Canonicalize(Instance::Cast(obj));
       } break;
-      case ConstantPoolTag::kInterfaceCall: {
+      case ConstantPoolTag::kInterfaceCallV1: {
         helper_->ReadByte();  // TODO(regis): Remove, unneeded.
         name ^= ReadObject();
         ASSERT(name.IsSymbol());
@@ -628,59 +640,81 @@
         array ^= pool.ObjectAt(arg_desc_index);
         // InterfaceCall constant occupies 2 entries.
         // The first entry is used for selector name.
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
+        pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
+                       ObjectPool::Patchability::kNotPatchable);
         pool.SetObjectAt(i, name);
         ++i;
         ASSERT(i < obj_count);
         // The second entry is used for arguments descriptor.
         obj = array.raw();
       } break;
+      case ConstantPoolTag::kObjectRef:
+        obj = ReadObject();
+        break;
+      case ConstantPoolTag::kDirectCall: {
+        // DirectCall constant occupies 2 entries.
+        // The first entry is used for target function.
+        obj = ReadObject();
+        ASSERT(obj.IsFunction());
+        pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
+                       ObjectPool::Patchability::kNotPatchable);
+        pool.SetObjectAt(i, obj);
+        ++i;
+        ASSERT(i < obj_count);
+        // The second entry is used for arguments descriptor.
+        obj = ReadObject();
+      } break;
+      case ConstantPoolTag::kInterfaceCall: {
+        elem = ReadObject();
+        ASSERT(elem.IsFunction());
+        name = Function::Cast(elem).name();
+        ASSERT(name.IsSymbol());
+        // InterfaceCall constant occupies 2 entries.
+        // The first entry is used for selector name.
+        pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
+                       ObjectPool::Patchability::kNotPatchable);
+        pool.SetObjectAt(i, name);
+        ++i;
+        ASSERT(i < obj_count);
+        // The second entry is used for arguments descriptor.
+        obj = ReadObject();
+      } break;
       default:
         UNREACHABLE();
     }
-    pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
+    pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
+                   ObjectPool::Patchability::kNotPatchable);
     pool.SetObjectAt(i, obj);
   }
 }
 
-RawBytecode* BytecodeMetadataHelper::ReadBytecode(const ObjectPool& pool) {
-#if !defined(PRODUCT)
-  TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
-                            "BytecodeMetadataHelper::ReadBytecode");
-#endif  // !defined(PRODUCT)
+RawBytecode* BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) {
+  TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
+                    "BytecodeReaderHelper::ReadBytecode");
   intptr_t size = helper_->ReadUInt();
   intptr_t offset = Utils::RoundUp(helper_->reader_.offset(), sizeof(KBCInstr));
   const uint8_t* data = helper_->reader_.BufferAt(offset);
   ASSERT(Utils::IsAligned(data, sizeof(KBCInstr)));
   helper_->reader_.set_offset(offset + size);
 
-  const ExternalTypedData& instructions = ExternalTypedData::Handle(
-      helper_->zone_,
-      ExternalTypedData::New(kExternalTypedDataInt8ArrayCid,
-                             const_cast<uint8_t*>(data), size, Heap::kOld));
-
   // Create and return bytecode object.
-  return Bytecode::New(instructions, pool);
+  return Bytecode::New(reinterpret_cast<uword>(data), size, offset, pool);
 }
 
-void BytecodeMetadataHelper::ReadExceptionsTable(const Bytecode& bytecode,
-                                                 bool has_exceptions_table) {
-#if !defined(PRODUCT)
-  TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
-                            "BytecodeMetadataHelper::ReadExceptionsTable");
-#endif  // !defined(PRODUCT)
+void BytecodeReaderHelper::ReadExceptionsTable(const Bytecode& bytecode,
+                                               bool has_exceptions_table) {
+  TIMELINE_DURATION(Thread::Current(), CompilerVerbose,
+                    "BytecodeReaderHelper::ReadExceptionsTable");
 
   const intptr_t try_block_count =
       has_exceptions_table ? helper_->reader_.ReadListLength() : 0;
   if (try_block_count > 0) {
-    const ObjectPool& pool =
-        ObjectPool::Handle(helper_->zone_, bytecode.object_pool());
-    AbstractType& handler_type = AbstractType::Handle(helper_->zone_);
-    Array& handler_types = Array::ZoneHandle(helper_->zone_);
-    DescriptorList* pc_descriptors_list =
-        new (helper_->zone_) DescriptorList(64);
+    const ObjectPool& pool = ObjectPool::Handle(Z, bytecode.object_pool());
+    AbstractType& handler_type = AbstractType::Handle(Z);
+    Array& handler_types = Array::ZoneHandle(Z);
+    DescriptorList* pc_descriptors_list = new (Z) DescriptorList(64);
     ExceptionHandlerList* exception_handlers_list =
-        new (helper_->zone_) ExceptionHandlerList();
+        new (Z) ExceptionHandlerList();
 
     // Encoding of ExceptionsTable is described in
     // pkg/vm/lib/bytecode/exceptions.dart.
@@ -720,12 +754,11 @@
           is_generated, handler_types, needs_stacktrace);
     }
     const PcDescriptors& descriptors = PcDescriptors::Handle(
-        helper_->zone_,
-        pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart()));
+        Z, pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart()));
     bytecode.set_pc_descriptors(descriptors);
     const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
-        helper_->zone_, exception_handlers_list->FinalizeExceptionHandlers(
-                            bytecode.PayloadStart()));
+        Z, exception_handlers_list->FinalizeExceptionHandlers(
+               bytecode.PayloadStart()));
     bytecode.set_exception_handlers(handlers);
   } else {
     bytecode.set_pc_descriptors(Object::empty_descriptors());
@@ -733,8 +766,8 @@
   }
 }
 
-void BytecodeMetadataHelper::ReadSourcePositions(const Bytecode& bytecode,
-                                                 bool has_source_positions) {
+void BytecodeReaderHelper::ReadSourcePositions(const Bytecode& bytecode,
+                                               bool has_source_positions) {
   if (!has_source_positions) {
     return;
   }
@@ -744,9 +777,8 @@
   helper_->SkipBytes(length);
 }
 
-RawTypedData* BytecodeMetadataHelper::NativeEntry(const Function& function,
-                                                  const String& external_name) {
-  Zone* zone = helper_->zone_;
+RawTypedData* BytecodeReaderHelper::NativeEntry(const Function& function,
+                                                const String& external_name) {
   MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
   // This list of recognized methods must be kept in sync with the list of
   // methods handled specially by the NativeCall bytecode in the interpreter.
@@ -781,8 +813,8 @@
   intptr_t argc_tag = 0;
   if (kind == MethodRecognizer::kUnknown) {
     if (!FLAG_link_natives_lazily) {
-      const Class& cls = Class::Handle(zone, function.Owner());
-      const Library& library = Library::Handle(zone, cls.library());
+      const Class& cls = Class::Handle(Z, function.Owner());
+      const Library& library = Library::Handle(Z, cls.library());
       Dart_NativeEntryResolver resolver = library.native_entry_resolver();
       const bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver);
       const int num_params =
@@ -804,12 +836,7 @@
   return NativeEntryData::New(kind, trampoline, native_function, argc_tag);
 }
 
-RawArray* BytecodeMetadataHelper::ReadBytecodeComponent() {
-  const intptr_t md_offset = GetComponentMetadataPayloadOffset();
-  if (md_offset < 0) {
-    return Array::null();
-  }
-
+RawArray* BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) {
   ASSERT(Thread::Current()->IsMutatorThread());
 
   AlternativeReadingScope alt(&helper_->reader_, &H.metadata_payloads(),
@@ -853,7 +880,7 @@
   BytecodeComponentData bytecode_component(bytecode_component_array);
 
   // Read object offsets.
-  Smi& offs = Smi::Handle(helper_->zone_);
+  Smi& offs = Smi::Handle(Z);
   for (intptr_t i = 0; i < num_objects; ++i) {
     offs = Smi::New(helper_->reader_.ReadUInt());
     bytecode_component.SetObject(i, offs);
@@ -864,9 +891,7 @@
   return bytecode_component_array.raw();
 }
 
-// TODO(alexmarkov): create a helper class with cached handles to avoid handle
-// allocations.
-RawObject* BytecodeMetadataHelper::ReadObject() {
+RawObject* BytecodeReaderHelper::ReadObject() {
   uint32_t header = helper_->reader_.ReadUInt();
   if ((header & kReferenceBit) != 0) {
     intptr_t index = header >> kIndexShift;
@@ -899,7 +924,7 @@
   return ReadObjectContents(header);
 }
 
-RawObject* BytecodeMetadataHelper::ReadObjectContents(uint32_t header) {
+RawObject* BytecodeReaderHelper::ReadObjectContents(uint32_t header) {
   ASSERT(((header & kReferenceBit) == 0));
 
   // Must be in sync with enum ObjectKind in
@@ -915,6 +940,10 @@
     kGenericType,
     kFunctionType,
     kName,
+    kTypeArguments,
+    kFinalizedGenericType,
+    kConstObject,
+    kArgDesc,
   };
 
   // Member flags, must be in sync with _MemberHandle constants in
@@ -933,6 +962,11 @@
   const int kFlagHasOptionalNamedParams = kFlagBit1;
   const int kFlagHasTypeParams = kFlagBit2;
 
+  // ArgDesc flags, must be in sync with _ArgDescHandle constants in
+  // pkg/vm/lib/bytecode/object_table.dart.
+  const int kFlagHasNamedArgs = kFlagBit0;
+  const int kFlagHasTypeArgs = kFlagBit1;
+
   const intptr_t kind = (header >> kKindShift) & kKindMask;
   const intptr_t flags = header & kFlagsMask;
 
@@ -1056,7 +1090,7 @@
           Z, Function::NewSignatureFunction(*active_class_->klass,
                                             active_class_->enclosing != NULL
                                                 ? *active_class_->enclosing
-                                                : Function::Handle(Z),
+                                                : Function::null_function(),
                                             TokenPosition::kNoSource));
 
       return ReadFunctionSignature(
@@ -1075,12 +1109,157 @@
         return library.PrivateName(name);
       }
     }
+    case kTypeArguments: {
+      return ReadTypeArguments(Class::Handle(Z));
+    }
+    case kFinalizedGenericType: {
+      const Class& cls = Class::CheckedHandle(Z, ReadObject());
+      const TypeArguments& type_arguments =
+          TypeArguments::CheckedHandle(Z, ReadObject());
+      const Type& type = Type::Handle(
+          Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
+      type.SetIsFinalized();
+      return type.Canonicalize();
+    }
+    case kConstObject: {
+      const intptr_t tag = flags / kFlagBit0;
+      return ReadConstObject(tag);
+    }
+    case kArgDesc: {
+      const intptr_t num_arguments = helper_->ReadUInt();
+      const intptr_t num_type_args =
+          ((flags & kFlagHasTypeArgs) != 0) ? helper_->ReadUInt() : 0;
+      if ((flags & kFlagHasNamedArgs) == 0) {
+        return ArgumentsDescriptor::New(num_type_args, num_arguments);
+      } else {
+        const intptr_t num_arg_names = helper_->ReadListLength();
+        const Array& array = Array::Handle(Z, Array::New(num_arg_names));
+        String& name = String::Handle(Z);
+        for (intptr_t i = 0; i < num_arg_names; ++i) {
+          name ^= ReadObject();
+          array.SetAt(i, name);
+        }
+        return ArgumentsDescriptor::New(num_type_args, num_arguments, array);
+      }
+    }
+    default:
+      UNREACHABLE();
   }
 
   return Object::null();
 }
 
-RawString* BytecodeMetadataHelper::ReadString(bool is_canonical) {
+RawObject* BytecodeReaderHelper::ReadConstObject(intptr_t tag) {
+  // Must be in sync with enum ConstTag in
+  // pkg/vm/lib/bytecode/object_table.dart.
+  enum ConstTag {
+    kInvalid,
+    kInstance,
+    kInt,
+    kDouble,
+    kList,
+    kTearOff,
+    kBool,
+    kSymbol,
+    kTearOffInstantiation,
+  };
+
+  switch (tag) {
+    case kInvalid:
+      UNREACHABLE();
+      break;
+    case kInstance: {
+      const Type& type = Type::CheckedHandle(Z, ReadObject());
+      const Class& cls = Class::Handle(Z, type.type_class());
+      const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld));
+      if (type.arguments() != TypeArguments::null()) {
+        const TypeArguments& type_args =
+            TypeArguments::Handle(Z, type.arguments());
+        obj.SetTypeArguments(type_args);
+      }
+      const intptr_t num_fields = helper_->ReadUInt();
+      Field& field = Field::Handle(Z);
+      Object& value = Object::Handle(Z);
+      for (intptr_t i = 0; i < num_fields; ++i) {
+        field ^= ReadObject();
+        value = ReadObject();
+        obj.SetField(field, value);
+      }
+      return H.Canonicalize(obj);
+    }
+    case kInt: {
+      const int64_t value = helper_->reader_.ReadSLEB128AsInt64();
+      if (Smi::IsValid(value)) {
+        return Smi::New(static_cast<intptr_t>(value));
+      }
+      const Integer& obj = Integer::Handle(Z, Integer::New(value, Heap::kOld));
+      return H.Canonicalize(obj);
+    }
+    case kDouble: {
+      const int64_t bits = helper_->reader_.ReadSLEB128AsInt64();
+      double value = bit_cast<double, int64_t>(bits);
+      const Double& obj = Double::Handle(Z, Double::New(value, Heap::kOld));
+      return H.Canonicalize(obj);
+    }
+    case kList: {
+      const AbstractType& elem_type =
+          AbstractType::CheckedHandle(Z, ReadObject());
+      const intptr_t length = helper_->ReadUInt();
+      const Array& array = Array::Handle(Z, Array::New(length, elem_type));
+      Object& value = Object::Handle(Z);
+      for (intptr_t i = 0; i < length; ++i) {
+        value = ReadObject();
+        array.SetAt(i, value);
+      }
+      array.MakeImmutable();
+      return H.Canonicalize(array);
+    }
+    case kTearOff: {
+      Object& obj = Object::Handle(Z, ReadObject());
+      ASSERT(obj.IsFunction());
+      obj = Function::Cast(obj).ImplicitClosureFunction();
+      ASSERT(obj.IsFunction());
+      obj = Function::Cast(obj).ImplicitStaticClosure();
+      ASSERT(obj.IsInstance());
+      return H.Canonicalize(Instance::Cast(obj));
+    }
+    case kBool: {
+      bool is_true = helper_->ReadByte() != 0;
+      return is_true ? Bool::True().raw() : Bool::False().raw();
+    }
+    case kSymbol: {
+      const String& name = String::CheckedHandle(Z, ReadObject());
+      ASSERT(name.IsSymbol());
+      const Library& library = Library::Handle(Z, Library::InternalLibrary());
+      ASSERT(!library.IsNull());
+      const Class& cls =
+          Class::Handle(Z, library.LookupClass(Symbols::Symbol()));
+      ASSERT(!cls.IsNull());
+      const Field& field = Field::Handle(
+          Z, cls.LookupInstanceFieldAllowPrivate(Symbols::_name()));
+      ASSERT(!field.IsNull());
+      const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld));
+      obj.SetField(field, name);
+      return H.Canonicalize(obj);
+    }
+    case kTearOffInstantiation: {
+      Closure& closure = Closure::CheckedHandle(Z, ReadObject());
+      const TypeArguments& type_args =
+          TypeArguments::CheckedHandle(Z, ReadObject());
+      closure = Closure::New(
+          TypeArguments::Handle(Z, closure.instantiator_type_arguments()),
+          TypeArguments::Handle(Z, closure.function_type_arguments()),
+          type_args, Function::Handle(Z, closure.function()),
+          Context::Handle(Z, closure.context()), Heap::kOld);
+      return H.Canonicalize(closure);
+    }
+    default:
+      UNREACHABLE();
+  }
+  return Object::null();
+}
+
+RawString* BytecodeReaderHelper::ReadString(bool is_canonical) {
   const int kFlagTwoByteString = 1;
   const int kHeaderFields = 2;
   const int kUInt32Size = 4;
@@ -1130,7 +1309,7 @@
   }
 }
 
-RawTypeArguments* BytecodeMetadataHelper::ReadTypeArguments(
+RawTypeArguments* BytecodeReaderHelper::ReadTypeArguments(
     const Class& instantiator) {
   const intptr_t length = helper_->reader_.ReadUInt();
   TypeArguments& type_arguments =
@@ -1234,11 +1413,9 @@
         ExternalTypedData::Handle(zone, function.KernelData()),
         function.KernelDataProgramOffset());
     ActiveClass active_class;
-    TypeTranslator type_translator(&reader_helper, &active_class,
-                                   /* finalize= */ true);
 
-    BytecodeMetadataHelper bytecode_metadata_helper(
-        &reader_helper, &type_translator, &active_class);
+    BytecodeMetadataHelper bytecode_metadata_helper(&reader_helper,
+                                                    &active_class);
 
     // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used
     // e.g. for type translation.
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h
index ad1fef8..600dc84 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.h
+++ b/runtime/vm/compiler/frontend/bytecode_reader.h
@@ -22,7 +22,6 @@
   static const char* tag() { return "vm.bytecode"; }
 
   explicit BytecodeMetadataHelper(KernelReaderHelper* helper,
-                                  TypeTranslator* type_translator,
                                   ActiveClass* active_class);
 
   bool HasBytecode(intptr_t node_offset);
@@ -32,6 +31,23 @@
   RawArray* ReadBytecodeComponent();
 
  private:
+  ActiveClass* const active_class_;
+
+  DISALLOW_COPY_AND_ASSIGN(BytecodeMetadataHelper);
+};
+
+// Helper class for reading bytecode.
+class BytecodeReaderHelper : public ValueObject {
+ public:
+  explicit BytecodeReaderHelper(KernelReaderHelper* helper,
+                                ActiveClass* active_class,
+                                BytecodeComponentData* bytecode_component);
+
+  void ReadMemberBytecode(const Function& function, intptr_t md_offset);
+
+  RawArray* ReadBytecodeComponent(intptr_t md_offset);
+
+ private:
   // These constants should match corresponding constants in class ObjectHandle
   // (pkg/vm/lib/bytecode/object_table.dart).
   static const int kReferenceBit = 1 << 0;
@@ -41,11 +57,12 @@
   static const int kFlagBit0 = 1 << 5;
   static const int kFlagBit1 = 1 << 6;
   static const int kFlagBit2 = 1 << 7;
-  static const int kFlagsMask = (kFlagBit0 | kFlagBit1 | kFlagBit2);
+  static const int kFlagBit3 = 1 << 8;
+  static const int kFlagsMask = (kFlagBit0 | kFlagBit1 | kFlagBit2 | kFlagBit3);
 
   class FunctionTypeScope : public ValueObject {
    public:
-    explicit FunctionTypeScope(BytecodeMetadataHelper* bytecode_reader)
+    explicit FunctionTypeScope(BytecodeReaderHelper* bytecode_reader)
         : bytecode_reader_(bytecode_reader),
           saved_type_parameters_(
               bytecode_reader->function_type_type_parameters_) {}
@@ -55,7 +72,7 @@
     }
 
    private:
-    BytecodeMetadataHelper* bytecode_reader_;
+    BytecodeReaderHelper* bytecode_reader_;
     TypeArguments* const saved_type_parameters_;
   };
 
@@ -78,16 +95,19 @@
 
   RawObject* ReadObject();
   RawObject* ReadObjectContents(uint32_t header);
+  RawObject* ReadConstObject(intptr_t tag);
   RawString* ReadString(bool is_canonical = true);
   RawTypeArguments* ReadTypeArguments(const Class& instantiator);
 
-  TypeTranslator& type_translator_;
+  KernelReaderHelper* const helper_;
+  TranslationHelper& translation_helper_;
   ActiveClass* const active_class_;
-  BytecodeComponentData* bytecode_component_;
+  Zone* const zone_;
+  BytecodeComponentData* const bytecode_component_;
   Array* closures_;
   TypeArguments* function_type_type_parameters_;
 
-  DISALLOW_COPY_AND_ASSIGN(BytecodeMetadataHelper);
+  DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper);
 };
 
 class BytecodeComponentData : ValueObject {
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index 3ac3ecc..9c9b8ec 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -1293,9 +1293,6 @@
         // Note: This is already lowered to InstanceConstant/ListConstant.
         UNREACHABLE();
         break;
-      case kEnvironmentBoolConstant:
-      case kEnvironmentIntConstant:
-      case kEnvironmentStringConstant:
       case kUnevaluatedConstant:
         // We should not see unevaluated constants in the constant table, they
         // should have been fully evaluated before we get them.
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 3d14de6..00ff453 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -276,6 +276,17 @@
     call_->ReplaceUsesWith(caller_graph_->constant_null());
 
     // Update dominator tree.
+    for (intptr_t i = 0, n = callee_entry->dominated_blocks().length(); i < n;
+         i++) {
+      BlockEntryInstr* block = callee_entry->dominated_blocks()[i];
+      true_target->AddDominatedBlock(block);
+    }
+    for (intptr_t i = 0, n = call_block->dominated_blocks().length(); i < n;
+         i++) {
+      BlockEntryInstr* block = call_block->dominated_blocks()[i];
+      false_block->AddDominatedBlock(block);
+    }
+    call_block->ClearDominatedBlocks();
     call_block->AddDominatedBlock(true_target);
     call_block->AddDominatedBlock(false_block);
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 8bcbb49..bf8977a 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -692,17 +692,15 @@
       body += LoadLocal(parsed_function()->current_context_var());
       body += B->LoadNativeField(
           Slot::GetContextVariableSlotFor(thread(), *scopes()->this_variable));
-      body += B->StoreFpRelativeSlot(kWordSize *
-                                     compiler_frame_layout.param_end_from_fp);
-      body += Drop();
+      body += B->StoreFpRelativeSlot(
+          kWordSize * compiler::target::frame_layout.param_end_from_fp);
     } else {
       body += LoadLocal(parsed_function()->current_context_var());
       body += B->LoadNativeField(
           Slot::GetContextVariableSlotFor(thread(), *scopes()->this_variable));
       body += B->StoreFpRelativeSlot(
-          kWordSize *
-          (compiler_frame_layout.param_end_from_fp + function.NumParameters()));
-      body += Drop();
+          kWordSize * (compiler::target::frame_layout.param_end_from_fp +
+                       function.NumParameters()));
     }
   }
 
@@ -781,7 +779,6 @@
       store += IntConstant(0);
       store += LoadFunctionTypeArguments();
       store += StoreIndexed(kArrayCid);
-      store += Drop();
       store += IntConstant(1);
       store += StoreLocal(TokenPosition::kNoSource, index);
       store += Drop();
@@ -807,10 +804,9 @@
     loop_body += LoadLocal(argument_count);
     loop_body += LoadLocal(index);
     loop_body += B->SmiBinaryOp(Token::kSUB, /*truncate=*/true);
-    loop_body += B->LoadFpRelativeSlot(kWordSize *
-                                       compiler_frame_layout.param_end_from_fp);
+    loop_body += B->LoadFpRelativeSlot(
+        kWordSize * compiler::target::frame_layout.param_end_from_fp);
     loop_body += StoreIndexed(kArrayCid);
-    loop_body += Drop();
 
     // ++i
     loop_body += LoadLocal(index);
@@ -2034,6 +2030,7 @@
       return flow_graph_builder_->BuildGraphOfInvokeFieldDispatcher(function);
     case RawFunction::kSignatureFunction:
     case RawFunction::kIrregexpFunction:
+    case RawFunction::kFfiTrampoline:
       break;
   }
   UNREACHABLE();
@@ -3159,7 +3156,6 @@
   instructions += IntConstant(num_type_arguments == 0 ? 0 : 1);  // index
   instructions += LoadLocal(scopes()->this_variable);            // receiver
   instructions += StoreIndexed(kArrayCid);
-  instructions += Drop();  // dispose of stored value
   instructions += build_rest_of_actuals;
 
   // First argument is receiver.
@@ -3302,7 +3298,6 @@
     build_rest_of_actuals += BuildExpression();         // value.
     build_rest_of_actuals += StoreLocal(position, value);
     build_rest_of_actuals += StoreIndexed(kArrayCid);
-    build_rest_of_actuals += Drop();  // dispose of stored value
 
     instructions += BuildAllocateInvocationMirrorCall(
         position, setter_name, /* num_type_arguments = */ 0,
@@ -3860,7 +3855,6 @@
       build_rest_of_actuals +=
           TranslateInstantiatedTypeArguments(type_arguments);
       build_rest_of_actuals += StoreIndexed(kArrayCid);
-      build_rest_of_actuals += Drop();  // dispose of stored value
       ++actuals_array_index;
     }
 
@@ -3873,7 +3867,6 @@
       build_rest_of_actuals += IntConstant(actuals_array_index + i);  // index
       build_rest_of_actuals += BuildExpression();                     // value.
       build_rest_of_actuals += StoreIndexed(kArrayCid);
-      build_rest_of_actuals += Drop();  // dispose of stored value
       ++i;
     }
     // Read named arguments
@@ -3886,7 +3879,6 @@
         build_rest_of_actuals += IntConstant(i + actuals_array_index);  // index
         build_rest_of_actuals += BuildExpression();  // value.
         build_rest_of_actuals += StoreIndexed(kArrayCid);
-        build_rest_of_actuals += Drop();  // dispose of stored value
         ++i;
       }
     }
@@ -4298,7 +4290,6 @@
       instructions += IntConstant(i);
       instructions += BuildExpression();  // read ith expression.
       instructions += StoreIndexed(kArrayCid);
-      instructions += Drop();
     }
 
     instructions += StringInterpolate(position);
@@ -4499,7 +4490,6 @@
       instructions += IntConstant(i);
       instructions += BuildExpression();  // read ith expression.
       instructions += StoreIndexed(kArrayCid);
-      instructions += Drop();
     }
   }
   instructions += PushArgument();  // The array.
@@ -4555,13 +4545,11 @@
       instructions += IntConstant(2 * i);
       instructions += BuildExpression();  // read ith key.
       instructions += StoreIndexed(kArrayCid);
-      instructions += Drop();
 
       instructions += LoadLocal(array);
       instructions += IntConstant(2 * i + 1);
       instructions += BuildExpression();  // read ith value.
       instructions += StoreIndexed(kArrayCid);
-      instructions += Drop();
     }
   }
   instructions += PushArgument();  // The array.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index b16d914..01b6693 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -39,7 +39,7 @@
                             &type_translator_,
                             active_class_,
                             flow_graph_builder),
-        bytecode_metadata_helper_(this, &type_translator_, active_class_),
+        bytecode_metadata_helper_(this, active_class_),
         direct_call_metadata_helper_(this),
         inferred_type_metadata_helper_(this),
         procedure_attributes_metadata_helper_(this),
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index cd0f7f7..dcc617c 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1214,14 +1214,12 @@
     body += IntConstant(0);
     body += LoadLocal(type_args);
     body += StoreIndexed(kArrayCid);
-    body += Drop();
   }
   for (intptr_t i = 0; i < descriptor.PositionalCount(); ++i) {
     body += LoadLocal(array);
     body += IntConstant(receiver_index + i);
     body += LoadLocal(scope->VariableAt(i));
     body += StoreIndexed(kArrayCid);
-    body += Drop();
   }
   String& name = String::Handle(Z);
   for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
@@ -1232,7 +1230,6 @@
     body += IntConstant(receiver_index + descriptor.PositionAt(i));
     body += LoadLocal(scope->VariableAt(parameter_index));
     body += StoreIndexed(kArrayCid);
-    body += Drop();
   }
   body += PushArgument();
 
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index b6a2164..082fd39 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -1257,6 +1257,14 @@
       helper_->set_current_script_id(source_uri_index_);
       if (++next_read_ == field) return;
       /* Falls through */
+    case kProblemsAsJson: {
+      intptr_t length = helper_->ReadUInt();  // read length of table.
+      for (intptr_t i = 0; i < length; ++i) {
+        helper_->SkipBytes(helper_->ReadUInt());  // read strings.
+      }
+      if (++next_read_ == field) return;
+      /* Falls through */
+    }
     case kAnnotations:
       helper_->SkipListOfExpressions();  // read annotations.
       if (++next_read_ == field) return;
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 3a184a1..d50712e 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -699,6 +699,7 @@
     kCanonicalName,
     kName,
     kSourceUriIndex,
+    kProblemsAsJson,
     kAnnotations,
     kDependencies,
     kAdditionalExports,
@@ -712,7 +713,8 @@
   };
 
   enum Flag {
-    kExternal = 1,
+    kExternal = 1 << 0,
+    kSynthetic = 1 << 1,
   };
 
   explicit LibraryHelper(KernelReaderHelper* helper)
@@ -728,6 +730,7 @@
   void SetJustRead(Field field) { next_read_ = field + 1; }
 
   bool IsExternal() const { return (flags_ & kExternal) != 0; }
+  bool IsSynthetic() const { return (flags_ & kSynthetic) != 0; }
 
   uint8_t flags_;
   NameIndex canonical_name_;
@@ -1072,6 +1075,7 @@
   intptr_t data_program_offset_;
 
   friend class BytecodeMetadataHelper;
+  friend class BytecodeReaderHelper;
   friend class ClassHelper;
   friend class CallSiteAttributesMetadataHelper;
   friend class ConstantEvaluator;
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 1ec7fd2..1149d15 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -181,8 +181,8 @@
   for (; param < num_fixed_params; ++param) {
     copy_args_prologue += LoadLocal(optional_count_var);
     copy_args_prologue += LoadFpRelativeSlot(
-        kWordSize *
-        (compiler_frame_layout.param_end_from_fp + num_fixed_params - param));
+        kWordSize * (compiler::target::frame_layout.param_end_from_fp +
+                     num_fixed_params - param));
     copy_args_prologue +=
         StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
     copy_args_prologue += Drop();
@@ -201,8 +201,8 @@
       Fragment good(supplied);
       good += LoadLocal(optional_count_var);
       good += LoadFpRelativeSlot(
-          kWordSize *
-          (compiler_frame_layout.param_end_from_fp + num_fixed_params - param));
+          kWordSize * (compiler::target::frame_layout.param_end_from_fp +
+                       num_fixed_params - param));
       good += StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
       good += Drop();
 
@@ -286,7 +286,7 @@
       Fragment good(supplied);
 
       {
-        // fp[compiler_frame_layout.param_end_from_fp + (count_var - pos)]
+        // fp[target::frame_layout.param_end_from_fp + (count_var - pos)]
         good += LoadLocal(count_var);
         {
           // pos = arg_desc[names_offset + arg_desc_name_index + positionOffset]
@@ -299,8 +299,8 @@
           good += LoadIndexed(/* index_scale = */ kWordSize);
         }
         good += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
-        good += LoadFpRelativeSlot(kWordSize *
-                                   compiler_frame_layout.param_end_from_fp);
+        good += LoadFpRelativeSlot(
+            kWordSize * compiler::target::frame_layout.param_end_from_fp);
 
         // Copy down.
         good += StoreLocalRaw(TokenPosition::kNoSource,
@@ -407,7 +407,7 @@
   store_type_args += LoadArgDescriptor();
   store_type_args += LoadNativeField(Slot::ArgumentsDescriptor_count());
   store_type_args += LoadFpRelativeSlot(
-      kWordSize * (1 + compiler_frame_layout.param_end_from_fp));
+      kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp));
   store_type_args += StoreLocal(TokenPosition::kNoSource, type_args_var);
   store_type_args += Drop();
 
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 201c724..d585002 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -267,13 +267,8 @@
       break;
     }
     case RawFunction::kImplicitGetter:
-    case RawFunction::kImplicitStaticFinalGetter:
     case RawFunction::kImplicitSetter: {
       ASSERT(helper_.PeekTag() == kField);
-      if (IsFieldInitializer(function, Z)) {
-        VisitNode();
-        break;
-      }
       const bool is_setter = function.IsImplicitSetterFunction();
       const bool is_method = !function.IsStaticFunction();
       intptr_t pos = 0;
@@ -309,6 +304,18 @@
       }
       break;
     }
+    case RawFunction::kImplicitStaticFinalGetter: {
+      ASSERT(helper_.PeekTag() == kField);
+      ASSERT(function.IsStaticFunction());
+      // 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 (IsFieldInitializer(function, Z) ||
+          Field::Handle(Z, function.accessor_field()).is_const()) {
+        VisitNode();
+      }
+      break;
+    }
     case RawFunction::kDynamicInvocationForwarder: {
       if (helper_.PeekTag() == kField) {
 #ifdef DEBUG
@@ -376,6 +383,7 @@
       break;
     case RawFunction::kSignatureFunction:
     case RawFunction::kIrregexpFunction:
+    case RawFunction::kFfiTrampoline:
       UNREACHABLE();
   }
   if (needs_expr_temp_) {
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
new file mode 100644
index 0000000..d537054
--- /dev/null
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -0,0 +1,1039 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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.
+
+// DBC does not use graph intrinsics.
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_ARCH_DBC)
+
+#include "vm/compiler/graph_intrinsifier.h"
+#include "vm/compiler/backend/flow_graph.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/backend/il.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/linearscan.h"
+#include "vm/compiler/jit/compiler.h"
+#include "vm/cpu.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, code_comments);
+DECLARE_FLAG(bool, print_flow_graph);
+DECLARE_FLAG(bool, print_flow_graph_optimized);
+
+namespace compiler {
+
+static void EmitCodeFor(FlowGraphCompiler* compiler, FlowGraph* graph) {
+  // The FlowGraph here is constructed by the intrinsics builder methods, and
+  // is different from compiler->flow_graph(), the original method's flow graph.
+  compiler->assembler()->Comment("Graph intrinsic begin");
+  for (intptr_t i = 0; i < graph->reverse_postorder().length(); i++) {
+    BlockEntryInstr* block = graph->reverse_postorder()[i];
+    if (block->IsGraphEntry()) continue;  // No code for graph entry needed.
+
+    if (block->HasParallelMove()) {
+      compiler->parallel_move_resolver()->EmitNativeCode(
+          block->parallel_move());
+    }
+
+    for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+      Instruction* instr = it.Current();
+      if (FLAG_code_comments) compiler->EmitComment(instr);
+      if (instr->IsParallelMove()) {
+        compiler->parallel_move_resolver()->EmitNativeCode(
+            instr->AsParallelMove());
+      } else if (instr->IsInvokeMathCFunction()) {
+        ASSERT(instr->locs() != NULL);
+        GraphIntrinsifier::IntrinsicCallPrologue(compiler->assembler());
+        instr->EmitNativeCode(compiler);
+        GraphIntrinsifier::IntrinsicCallEpilogue(compiler->assembler());
+      } else {
+        ASSERT(instr->locs() != NULL);
+        // Calls are not supported in intrinsics code.
+        ASSERT(!instr->locs()->always_calls());
+        instr->EmitNativeCode(compiler);
+      }
+    }
+  }
+  compiler->assembler()->Comment("Graph intrinsic end");
+}
+
+bool GraphIntrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function,
+                                        FlowGraphCompiler* compiler) {
+  ASSERT(!parsed_function.function().HasOptionalParameters());
+  PrologueInfo prologue_info(-1, -1);
+
+  auto graph_entry =
+      new GraphEntryInstr(parsed_function, Compiler::kNoOSRDeoptId);
+
+  intptr_t block_id = 1;  // 0 is GraphEntry.
+  graph_entry->set_normal_entry(
+      new FunctionEntryInstr(graph_entry, block_id, kInvalidTryIndex,
+                             CompilerState::Current().GetNextDeoptId()));
+
+  FlowGraph* graph =
+      new FlowGraph(parsed_function, graph_entry, block_id, prologue_info);
+  const Function& function = parsed_function.function();
+  switch (function.recognized_kind()) {
+#define EMIT_CASE(class_name, function_name, enum_name, fp)                    \
+  case MethodRecognizer::k##enum_name:                                         \
+    if (!Build_##enum_name(graph)) return false;                               \
+    break;
+
+    GRAPH_INTRINSICS_LIST(EMIT_CASE);
+    default:
+      return false;
+#undef EMIT_CASE
+  }
+
+  if (FLAG_support_il_printer && FLAG_print_flow_graph &&
+      FlowGraphPrinter::ShouldPrint(function)) {
+    THR_Print("Intrinsic graph before\n");
+    FlowGraphPrinter printer(*graph);
+    printer.PrintBlocks();
+  }
+
+  // Prepare for register allocation (cf. FinalizeGraph).
+  graph->RemoveRedefinitions();
+
+  // Ensure loop hierarchy has been computed.
+  GrowableArray<BitVector*> dominance_frontier;
+  graph->ComputeDominators(&dominance_frontier);
+  graph->GetLoopHierarchy();
+
+  // Perform register allocation on the SSA graph.
+  FlowGraphAllocator allocator(*graph, true);  // Intrinsic mode.
+  allocator.AllocateRegisters();
+
+  if (FLAG_support_il_printer && FLAG_print_flow_graph &&
+      FlowGraphPrinter::ShouldPrint(function)) {
+    THR_Print("Intrinsic graph after\n");
+    FlowGraphPrinter printer(*graph);
+    printer.PrintBlocks();
+  }
+  EmitCodeFor(compiler, graph);
+  return true;
+}
+
+static intptr_t CidForRepresentation(Representation rep) {
+  switch (rep) {
+    case kUnboxedDouble:
+      return kDoubleCid;
+    case kUnboxedFloat32x4:
+      return kFloat32x4Cid;
+    case kUnboxedInt32x4:
+      return kInt32x4Cid;
+    case kUnboxedFloat64x2:
+      return kFloat64x2Cid;
+    case kUnboxedUint32:
+      return kDynamicCid;  // smi or mint.
+    default:
+      UNREACHABLE();
+      return kIllegalCid;
+  }
+}
+
+static Representation RepresentationForCid(intptr_t cid) {
+  switch (cid) {
+    case kDoubleCid:
+      return kUnboxedDouble;
+    case kFloat32x4Cid:
+      return kUnboxedFloat32x4;
+    case kInt32x4Cid:
+      return kUnboxedInt32x4;
+    case kFloat64x2Cid:
+      return kUnboxedFloat64x2;
+    default:
+      UNREACHABLE();
+      return kNoRepresentation;
+  }
+}
+
+// Notes about the graph intrinsics:
+//
+// IR instructions which would jump to a deoptimization sequence on failure
+// instead branch to the intrinsic slow path.
+//
+class BlockBuilder : public ValueObject {
+ public:
+  BlockBuilder(FlowGraph* flow_graph, BlockEntryInstr* entry)
+      : flow_graph_(flow_graph),
+        entry_(entry),
+        current_(entry),
+        fall_through_env_(new Environment(0,
+                                          0,
+                                          DeoptId::kNone,
+                                          flow_graph->parsed_function(),
+                                          NULL)) {}
+
+  Definition* AddToInitialDefinitions(Definition* def) {
+    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+    auto normal_entry = flow_graph_->graph_entry()->normal_entry();
+    flow_graph_->AddToInitialDefinitions(normal_entry, def);
+    return def;
+  }
+
+  Definition* AddDefinition(Definition* def) {
+    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+    AddInstruction(def);
+    return def;
+  }
+
+  Instruction* AddInstruction(Instruction* instr) {
+    if (instr->ComputeCanDeoptimize()) {
+      // Since we use the presence of an environment to determine if an
+      // instructions can deoptimize, we need an empty environment for
+      // instructions that "deoptimize" to the intrinsic fall-through code.
+      instr->SetEnvironment(fall_through_env_);
+    }
+    current_ = current_->AppendInstruction(instr);
+    return instr;
+  }
+
+  void AddIntrinsicReturn(Value* value) {
+    ReturnInstr* instr = new ReturnInstr(
+        TokenPos(), value, CompilerState::Current().GetNextDeoptId());
+    AddInstruction(instr);
+    entry_->set_last_instruction(instr);
+  }
+
+  Definition* AddParameter(intptr_t index) {
+    intptr_t adjustment = GraphIntrinsifier::ParameterSlotFromSp();
+    return AddToInitialDefinitions(new ParameterInstr(
+        adjustment + index, flow_graph_->graph_entry(), SPREG));
+  }
+
+  TokenPosition TokenPos() { return flow_graph_->function().token_pos(); }
+
+  Definition* AddNullDefinition() {
+    return AddDefinition(new ConstantInstr(Object::ZoneHandle(Object::null())));
+  }
+
+  Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) {
+    Definition* unboxed_value =
+        AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone));
+    if (is_checked) {
+      // The type of |value| has already been checked and it is safe to
+      // adjust reaching type. This is done manually because there is no type
+      // propagation when building intrinsics.
+      unboxed_value->AsUnbox()->value()->SetReachingType(
+          new CompileType(CompileType::FromCid(CidForRepresentation(rep))));
+    }
+    return unboxed_value;
+  }
+
+  Definition* AddUnboxInstr(Representation rep,
+                            Definition* boxed,
+                            bool is_checked) {
+    return AddUnboxInstr(rep, new Value(boxed), is_checked);
+  }
+
+  Definition* InvokeMathCFunction(MethodRecognizer::Kind recognized_kind,
+                                  ZoneGrowableArray<Value*>* args) {
+    return InvokeMathCFunctionHelper(recognized_kind, args);
+  }
+
+ private:
+  Definition* InvokeMathCFunctionHelper(MethodRecognizer::Kind recognized_kind,
+                                        ZoneGrowableArray<Value*>* args) {
+    InvokeMathCFunctionInstr* invoke_math_c_function =
+        new InvokeMathCFunctionInstr(args, DeoptId::kNone, recognized_kind,
+                                     TokenPos());
+    AddDefinition(invoke_math_c_function);
+    return invoke_math_c_function;
+  }
+
+  FlowGraph* flow_graph_;
+  BlockEntryInstr* entry_;
+  Instruction* current_;
+  Environment* fall_through_env_;
+};
+
+static Definition* PrepareIndexedOp(FlowGraph* flow_graph,
+                                    BlockBuilder* builder,
+                                    Definition* array,
+                                    Definition* index,
+                                    const Slot& length_field) {
+  Definition* length = builder->AddDefinition(new LoadFieldInstr(
+      new Value(array), length_field, TokenPosition::kNoSource));
+  // Note that the intrinsifier must always use deopting array bound
+  // checks, because intrinsics currently don't support calls.
+  Definition* safe_index = new CheckArrayBoundInstr(
+      new Value(length), new Value(index), DeoptId::kNone);
+  builder->AddDefinition(safe_index);
+  return safe_index;
+}
+
+static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph,
+                                      intptr_t array_cid) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* index = builder.AddParameter(1);
+  Definition* array = builder.AddParameter(2);
+
+  index = PrepareIndexedOp(flow_graph, &builder, array, index,
+                           Slot::GetLengthFieldForArrayCid(array_cid));
+
+  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    array = builder.AddDefinition(new LoadUntaggedInstr(
+        new Value(array), ExternalTypedData::data_offset()));
+  }
+
+  Definition* result = builder.AddDefinition(new LoadIndexedInstr(
+      new Value(array), new Value(index),
+      Instance::ElementSizeFor(array_cid),  // index scale
+      array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+  // Box and/or convert result if necessary.
+  switch (array_cid) {
+    case kTypedDataInt32ArrayCid:
+    case kExternalTypedDataInt32ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedInt32, new Value(result)));
+      break;
+    case kTypedDataUint32ArrayCid:
+    case kExternalTypedDataUint32ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedUint32, new Value(result)));
+      break;
+    case kTypedDataFloat32ArrayCid:
+      result = builder.AddDefinition(
+          new FloatToDoubleInstr(new Value(result), DeoptId::kNone));
+    // Fall through.
+    case kTypedDataFloat64ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedDouble, new Value(result)));
+      break;
+    case kTypedDataFloat32x4ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedFloat32x4, new Value(result)));
+      break;
+    case kTypedDataInt32x4ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedInt32x4, new Value(result)));
+      break;
+    case kTypedDataFloat64x2ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedFloat64x2, new Value(result)));
+      break;
+    case kArrayCid:
+    case kImmutableArrayCid:
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+      // Nothing to do.
+      break;
+    case kTypedDataInt64ArrayCid:
+    case kTypedDataUint64ArrayCid:
+      result = builder.AddDefinition(
+          BoxInstr::Create(kUnboxedInt64, new Value(result)));
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
+                                      intptr_t array_cid) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* value = builder.AddParameter(1);
+  Definition* index = builder.AddParameter(2);
+  Definition* array = builder.AddParameter(3);
+
+  index = PrepareIndexedOp(flow_graph, &builder, array, index,
+                           Slot::GetLengthFieldForArrayCid(array_cid));
+
+  // Value check/conversion.
+  switch (array_cid) {
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+      builder.AddInstruction(new CheckSmiInstr(new Value(value), DeoptId::kNone,
+                                               builder.TokenPos()));
+      break;
+    case kTypedDataInt32ArrayCid:
+    case kExternalTypedDataInt32ArrayCid:
+    // Use same truncating unbox-instruction for int32 and uint32.
+    // Fall-through.
+    case kTypedDataUint32ArrayCid:
+    case kExternalTypedDataUint32ArrayCid:
+      // Supports smi and mint, slow-case for bigints.
+      value = builder.AddUnboxInstr(kUnboxedUint32, new Value(value),
+                                    /* is_checked = */ false);
+      break;
+    case kTypedDataInt64ArrayCid:
+    case kTypedDataUint64ArrayCid:
+      value = builder.AddUnboxInstr(kUnboxedInt64, new Value(value),
+                                    /* is_checked = */ false);
+      break;
+
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+    case kTypedDataFloat32x4ArrayCid:
+    case kTypedDataInt32x4ArrayCid:
+    case kTypedDataFloat64x2ArrayCid: {
+      intptr_t value_check_cid = kDoubleCid;
+      Representation rep = kUnboxedDouble;
+      switch (array_cid) {
+        case kTypedDataFloat32x4ArrayCid:
+          value_check_cid = kFloat32x4Cid;
+          rep = kUnboxedFloat32x4;
+          break;
+        case kTypedDataInt32x4ArrayCid:
+          value_check_cid = kInt32x4Cid;
+          rep = kUnboxedInt32x4;
+          break;
+        case kTypedDataFloat64x2ArrayCid:
+          value_check_cid = kFloat64x2Cid;
+          rep = kUnboxedFloat64x2;
+          break;
+        default:
+          // Float32/Float64 case already handled.
+          break;
+      }
+      Zone* zone = flow_graph->zone();
+      Cids* value_check = Cids::CreateMonomorphic(zone, value_check_cid);
+      builder.AddInstruction(new CheckClassInstr(
+          new Value(value), DeoptId::kNone, *value_check, builder.TokenPos()));
+      value = builder.AddUnboxInstr(rep, new Value(value),
+                                    /* is_checked = */ true);
+      if (array_cid == kTypedDataFloat32ArrayCid) {
+        value = builder.AddDefinition(
+            new DoubleToFloatInstr(new Value(value), DeoptId::kNone));
+      }
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
+
+  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+    array = builder.AddDefinition(new LoadUntaggedInstr(
+        new Value(array), ExternalTypedData::data_offset()));
+  }
+  // No store barrier.
+  ASSERT(RawObject::IsExternalTypedDataClassId(array_cid) ||
+         RawObject::IsTypedDataClassId(array_cid));
+  builder.AddInstruction(new StoreIndexedInstr(
+      new Value(array), new Value(index), new Value(value), kNoStoreBarrier,
+      Instance::ElementSizeFor(array_cid),  // index scale
+      array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+  // Return null.
+  Definition* null_def = builder.AddNullDefinition();
+  builder.AddIntrinsicReturn(new Value(null_def));
+  return true;
+}
+
+#define DEFINE_ARRAY_GETTER_INTRINSIC(enum_name)                               \
+  bool GraphIntrinsifier::Build_##enum_name##GetIndexed(                       \
+      FlowGraph* flow_graph) {                                                 \
+    return IntrinsifyArrayGetIndexed(                                          \
+        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
+                        MethodRecognizer::k##enum_name##GetIndexed));          \
+  }
+
+#define DEFINE_ARRAY_SETTER_INTRINSIC(enum_name)                               \
+  bool GraphIntrinsifier::Build_##enum_name##SetIndexed(                       \
+      FlowGraph* flow_graph) {                                                 \
+    return IntrinsifyArraySetIndexed(                                          \
+        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
+                        MethodRecognizer::k##enum_name##SetIndexed));          \
+  }
+
+DEFINE_ARRAY_GETTER_INTRINSIC(ObjectArray)
+DEFINE_ARRAY_GETTER_INTRINSIC(ImmutableArray)
+
+#define DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                       \
+  DEFINE_ARRAY_GETTER_INTRINSIC(enum_name)                                     \
+  DEFINE_ARRAY_SETTER_INTRINSIC(enum_name)
+
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int8Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint8Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(ExternalUint8Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint8ClampedArray)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(ExternalUint8ClampedArray)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int16Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint16Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int32Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint32Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int64Array)
+DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint64Array)
+
+#undef DEFINE_ARRAY_GETTER_SETTER_INTRINSICS
+#undef DEFINE_ARRAY_GETTER_INTRINSIC
+#undef DEFINE_ARRAY_SETTER_INTRINSIC
+
+#define DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name)                         \
+  bool GraphIntrinsifier::Build_##enum_name##GetIndexed(                       \
+      FlowGraph* flow_graph) {                                                 \
+    if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {                        \
+      return false;                                                            \
+    }                                                                          \
+    return IntrinsifyArrayGetIndexed(                                          \
+        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
+                        MethodRecognizer::k##enum_name##GetIndexed));          \
+  }
+
+#define DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name)                         \
+  bool GraphIntrinsifier::Build_##enum_name##SetIndexed(                       \
+      FlowGraph* flow_graph) {                                                 \
+    if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {                        \
+      return false;                                                            \
+    }                                                                          \
+    return IntrinsifyArraySetIndexed(                                          \
+        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
+                        MethodRecognizer::k##enum_name##SetIndexed));          \
+  }
+
+#define DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                 \
+  DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name)                               \
+  DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name)
+
+DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float64Array)
+DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array)
+
+#undef DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS
+#undef DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC
+#undef DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC
+
+#define DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name)                          \
+  bool GraphIntrinsifier::Build_##enum_name##GetIndexed(                       \
+      FlowGraph* flow_graph) {                                                 \
+    if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {                        \
+      return false;                                                            \
+    }                                                                          \
+    return IntrinsifyArrayGetIndexed(                                          \
+        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
+                        MethodRecognizer::k##enum_name##GetIndexed));          \
+  }
+
+#define DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name)                          \
+  bool GraphIntrinsifier::Build_##enum_name##SetIndexed(                       \
+      FlowGraph* flow_graph) {                                                 \
+    if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {                        \
+      return false;                                                            \
+    }                                                                          \
+    return IntrinsifyArraySetIndexed(                                          \
+        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
+                        MethodRecognizer::k##enum_name##SetIndexed));          \
+  }
+
+#define DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                  \
+  DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name)                                \
+  DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name)
+
+DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float32x4Array)
+DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Int32x4Array)
+DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float64x2Array)
+
+#undef DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS
+#undef DEFINE_SIMD_ARRAY_GETTER_INTRINSIC
+#undef DEFINE_SIMD_ARRAY_SETTER_INTRINSIC
+
+static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* index = builder.AddParameter(1);
+  Definition* str = builder.AddParameter(2);
+
+  index =
+      PrepareIndexedOp(flow_graph, &builder, str, index, Slot::String_length());
+
+  // For external strings: Load external data.
+  if (cid == kExternalOneByteStringCid) {
+    str = builder.AddDefinition(new LoadUntaggedInstr(
+        new Value(str), ExternalOneByteString::external_data_offset()));
+  } else if (cid == kExternalTwoByteStringCid) {
+    str = builder.AddDefinition(new LoadUntaggedInstr(
+        new Value(str), ExternalTwoByteString::external_data_offset()));
+  }
+
+  Definition* result = builder.AddDefinition(new LoadIndexedInstr(
+      new Value(str), new Value(index), Instance::ElementSizeFor(cid), cid,
+      kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_OneByteStringCodeUnitAt(FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kOneByteStringCid);
+}
+
+bool GraphIntrinsifier::Build_TwoByteStringCodeUnitAt(FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kTwoByteStringCid);
+}
+
+bool GraphIntrinsifier::Build_ExternalOneByteStringCodeUnitAt(
+    FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kExternalOneByteStringCid);
+}
+
+bool GraphIntrinsifier::Build_ExternalTwoByteStringCodeUnitAt(
+    FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kExternalTwoByteStringCid);
+}
+
+static bool BuildSimdOp(FlowGraph* flow_graph, intptr_t cid, Token::Kind kind) {
+  if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
+
+  const Representation rep = RepresentationForCid(cid);
+
+  Zone* zone = flow_graph->zone();
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* right = builder.AddParameter(1);
+  Definition* left = builder.AddParameter(2);
+
+  Cids* value_check = Cids::CreateMonomorphic(zone, cid);
+  // Check argument. Receiver (left) is known to be a Float32x4.
+  builder.AddInstruction(new CheckClassInstr(new Value(right), DeoptId::kNone,
+                                             *value_check, builder.TokenPos()));
+  Definition* left_simd = builder.AddUnboxInstr(rep, new Value(left),
+                                                /* is_checked = */ true);
+
+  Definition* right_simd = builder.AddUnboxInstr(rep, new Value(right),
+                                                 /* is_checked = */ true);
+
+  Definition* unboxed_result = builder.AddDefinition(SimdOpInstr::Create(
+      SimdOpInstr::KindForOperator(cid, kind), new Value(left_simd),
+      new Value(right_simd), DeoptId::kNone));
+  Definition* result =
+      builder.AddDefinition(BoxInstr::Create(rep, new Value(unboxed_result)));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) {
+  return BuildSimdOp(flow_graph, kFloat32x4Cid, Token::kMUL);
+}
+
+bool GraphIntrinsifier::Build_Float32x4Sub(FlowGraph* flow_graph) {
+  return BuildSimdOp(flow_graph, kFloat32x4Cid, Token::kSUB);
+}
+
+bool GraphIntrinsifier::Build_Float32x4Add(FlowGraph* flow_graph) {
+  return BuildSimdOp(flow_graph, kFloat32x4Cid, Token::kADD);
+}
+
+static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph,
+                                  MethodRecognizer::Kind kind) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles() ||
+      !FlowGraphCompiler::SupportsUnboxedSimd128()) {
+    return false;
+  }
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* receiver = builder.AddParameter(1);
+
+  Definition* unboxed_receiver =
+      builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver),
+                            /* is_checked = */ true);
+
+  Definition* unboxed_result = builder.AddDefinition(
+      SimdOpInstr::Create(kind, new Value(unboxed_receiver), DeoptId::kNone));
+
+  Definition* result = builder.AddDefinition(
+      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) {
+  return BuildFloat32x4Shuffle(flow_graph,
+                               MethodRecognizer::kFloat32x4ShuffleX);
+}
+
+bool GraphIntrinsifier::Build_Float32x4ShuffleY(FlowGraph* flow_graph) {
+  return BuildFloat32x4Shuffle(flow_graph,
+                               MethodRecognizer::kFloat32x4ShuffleY);
+}
+
+bool GraphIntrinsifier::Build_Float32x4ShuffleZ(FlowGraph* flow_graph) {
+  return BuildFloat32x4Shuffle(flow_graph,
+                               MethodRecognizer::kFloat32x4ShuffleZ);
+}
+
+bool GraphIntrinsifier::Build_Float32x4ShuffleW(FlowGraph* flow_graph) {
+  return BuildFloat32x4Shuffle(flow_graph,
+                               MethodRecognizer::kFloat32x4ShuffleW);
+}
+
+static bool BuildLoadField(FlowGraph* flow_graph, const Slot& field) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* array = builder.AddParameter(1);
+
+  Definition* length = builder.AddDefinition(
+      new LoadFieldInstr(new Value(array), field, builder.TokenPos()));
+  builder.AddIntrinsicReturn(new Value(length));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_ObjectArrayLength(FlowGraph* flow_graph) {
+  return BuildLoadField(flow_graph, Slot::Array_length());
+}
+
+bool GraphIntrinsifier::Build_ImmutableArrayLength(FlowGraph* flow_graph) {
+  return BuildLoadField(flow_graph, Slot::Array_length());
+}
+
+bool GraphIntrinsifier::Build_GrowableArrayLength(FlowGraph* flow_graph) {
+  return BuildLoadField(flow_graph, Slot::GrowableObjectArray_length());
+}
+
+bool GraphIntrinsifier::Build_StringBaseLength(FlowGraph* flow_graph) {
+  return BuildLoadField(flow_graph, Slot::String_length());
+}
+
+bool GraphIntrinsifier::Build_TypedDataLength(FlowGraph* flow_graph) {
+  return BuildLoadField(flow_graph, Slot::TypedData_length());
+}
+
+bool GraphIntrinsifier::Build_GrowableArrayCapacity(FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* array = builder.AddParameter(1);
+
+  Definition* backing_store = builder.AddDefinition(new LoadFieldInstr(
+      new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos()));
+  Definition* capacity = builder.AddDefinition(new LoadFieldInstr(
+      new Value(backing_store), Slot::Array_length(), builder.TokenPos()));
+  builder.AddIntrinsicReturn(new Value(capacity));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* index = builder.AddParameter(1);
+  Definition* growable_array = builder.AddParameter(2);
+
+  index = PrepareIndexedOp(flow_graph, &builder, growable_array, index,
+                           Slot::GrowableObjectArray_length());
+
+  Definition* backing_store = builder.AddDefinition(
+      new LoadFieldInstr(new Value(growable_array),
+                         Slot::GrowableObjectArray_data(), builder.TokenPos()));
+  Definition* result = builder.AddDefinition(new LoadIndexedInstr(
+      new Value(backing_store), new Value(index),
+      Instance::ElementSizeFor(kArrayCid),  // index scale
+      kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_ObjectArraySetIndexed(FlowGraph* flow_graph) {
+  if (Isolate::Current()->argument_type_checks()) {
+    return false;
+  }
+
+  return Build_ObjectArraySetIndexedUnchecked(flow_graph);
+}
+
+bool GraphIntrinsifier::Build_ObjectArraySetIndexedUnchecked(
+    FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* value = builder.AddParameter(1);
+  Definition* index = builder.AddParameter(2);
+  Definition* array = builder.AddParameter(3);
+
+  index = PrepareIndexedOp(flow_graph, &builder, array, index,
+                           Slot::Array_length());
+
+  builder.AddInstruction(new StoreIndexedInstr(
+      new Value(array), new Value(index), new Value(value), kEmitStoreBarrier,
+      Instance::ElementSizeFor(kArrayCid),  // index scale
+      kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+  // Return null.
+  Definition* null_def = builder.AddNullDefinition();
+  builder.AddIntrinsicReturn(new Value(null_def));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
+  if (Isolate::Current()->argument_type_checks()) {
+    return false;
+  }
+
+  return Build_GrowableArraySetIndexedUnchecked(flow_graph);
+}
+
+bool GraphIntrinsifier::Build_GrowableArraySetIndexedUnchecked(
+    FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* value = builder.AddParameter(1);
+  Definition* index = builder.AddParameter(2);
+  Definition* array = builder.AddParameter(3);
+
+  index = PrepareIndexedOp(flow_graph, &builder, array, index,
+                           Slot::GrowableObjectArray_length());
+
+  Definition* backing_store = builder.AddDefinition(new LoadFieldInstr(
+      new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos()));
+
+  builder.AddInstruction(new StoreIndexedInstr(
+      new Value(backing_store), new Value(index), new Value(value),
+      kEmitStoreBarrier,
+      Instance::ElementSizeFor(kArrayCid),  // index scale
+      kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
+  // Return null.
+  Definition* null_def = builder.AddNullDefinition();
+  builder.AddIntrinsicReturn(new Value(null_def));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* data = builder.AddParameter(1);
+  Definition* growable_array = builder.AddParameter(2);
+  Zone* zone = flow_graph->zone();
+
+  Cids* value_check = Cids::CreateMonomorphic(zone, kArrayCid);
+  builder.AddInstruction(new CheckClassInstr(new Value(data), DeoptId::kNone,
+                                             *value_check, builder.TokenPos()));
+
+  builder.AddInstruction(new StoreInstanceFieldInstr(
+      Slot::GrowableObjectArray_data(), new Value(growable_array),
+      new Value(data), kEmitStoreBarrier, builder.TokenPos()));
+  // Return null.
+  Definition* null_def = builder.AddNullDefinition();
+  builder.AddIntrinsicReturn(new Value(null_def));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* length = builder.AddParameter(1);
+  Definition* growable_array = builder.AddParameter(2);
+
+  builder.AddInstruction(
+      new CheckSmiInstr(new Value(length), DeoptId::kNone, builder.TokenPos()));
+  builder.AddInstruction(new StoreInstanceFieldInstr(
+      Slot::GrowableObjectArray_length(), new Value(growable_array),
+      new Value(length), kNoStoreBarrier, builder.TokenPos()));
+  Definition* null_def = builder.AddNullDefinition();
+  builder.AddIntrinsicReturn(new Value(null_def));
+  return true;
+}
+
+bool GraphIntrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
+    return false;
+  }
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* receiver = builder.AddParameter(1);
+  Definition* unboxed_value =
+      builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver),
+                            /* is_checked = */ true);
+  Definition* unboxed_result = builder.AddDefinition(new UnaryDoubleOpInstr(
+      Token::kNEGATE, new Value(unboxed_value), DeoptId::kNone));
+  Definition* result = builder.AddDefinition(
+      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+static bool BuildInvokeMathCFunction(BlockBuilder* builder,
+                                     MethodRecognizer::Kind kind,
+                                     intptr_t num_parameters = 1) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
+    return false;
+  }
+  ZoneGrowableArray<Value*>* args =
+      new ZoneGrowableArray<Value*>(num_parameters);
+
+  for (intptr_t i = 0; i < num_parameters; i++) {
+    const intptr_t parameter_index = (num_parameters - i);
+    Definition* value = builder->AddParameter(parameter_index);
+    Definition* unboxed_value =
+        builder->AddUnboxInstr(kUnboxedDouble, value, /* is_checked = */ false);
+    args->Add(new Value(unboxed_value));
+  }
+
+  Definition* unboxed_result = builder->InvokeMathCFunction(kind, args);
+
+  Definition* result = builder->AddDefinition(
+      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
+
+  builder->AddIntrinsicReturn(new Value(result));
+
+  return true;
+}
+
+bool GraphIntrinsifier::Build_MathSin(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathSin);
+}
+
+bool GraphIntrinsifier::Build_MathCos(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathCos);
+}
+
+bool GraphIntrinsifier::Build_MathTan(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathTan);
+}
+
+bool GraphIntrinsifier::Build_MathAsin(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAsin);
+}
+
+bool GraphIntrinsifier::Build_MathAcos(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAcos);
+}
+
+bool GraphIntrinsifier::Build_MathAtan(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan);
+}
+
+bool GraphIntrinsifier::Build_MathAtan2(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan2,
+                                  /* num_parameters = */ 2);
+}
+
+bool GraphIntrinsifier::Build_DoubleMod(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleMod,
+                                  /* num_parameters = */ 2);
+}
+
+bool GraphIntrinsifier::Build_DoubleCeil(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+  // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
+  // way.
+  if (TargetCPUFeatures::double_truncate_round_supported()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleCeil);
+}
+
+bool GraphIntrinsifier::Build_DoubleFloor(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+  // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
+  // way.
+  if (TargetCPUFeatures::double_truncate_round_supported()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleFloor);
+}
+
+bool GraphIntrinsifier::Build_DoubleTruncate(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+  // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
+  // way.
+  if (TargetCPUFeatures::double_truncate_round_supported()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleTruncate);
+}
+
+bool GraphIntrinsifier::Build_DoubleRound(FlowGraph* flow_graph) {
+  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
+
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  auto normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound);
+}
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_ARCH_DBC)
diff --git a/runtime/vm/compiler/graph_intrinsifier.h b/runtime/vm/compiler/graph_intrinsifier.h
new file mode 100644
index 0000000..6282b58
--- /dev/null
+++ b/runtime/vm/compiler/graph_intrinsifier.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Class for intrinsifying functions.
+
+#ifndef RUNTIME_VM_COMPILER_GRAPH_INTRINSIFIER_H_
+#define RUNTIME_VM_COMPILER_GRAPH_INTRINSIFIER_H_
+
+#include "vm/allocation.h"
+#include "vm/compiler/recognized_methods_list.h"
+
+namespace dart {
+
+// Forward declarations.
+class FlowGraphCompiler;
+class ParsedFunction;
+class FlowGraph;
+
+namespace compiler {
+class Assembler;
+class Label;
+
+#if !defined(TARGET_ARCH_DBC)
+
+class GraphIntrinsifier : public AllStatic {
+ public:
+  static intptr_t ParameterSlotFromSp();
+
+  static bool GraphIntrinsify(const ParsedFunction& parsed_function,
+                              FlowGraphCompiler* compiler);
+
+  static void IntrinsicCallPrologue(Assembler* assembler);
+  static void IntrinsicCallEpilogue(Assembler* assembler);
+
+ private:
+#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp)             \
+  static void enum_name(Assembler* assembler, Label* normal_ir_body);
+
+  // On DBC graph intrinsics are handled in the same way as non-graph ones.
+  GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
+
+#undef DECLARE_FUNCTION
+
+#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp)             \
+  static bool Build_##enum_name(FlowGraph* flow_graph);
+
+  GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
+
+#undef DECLARE_FUNCTION
+};
+
+#else  // !defined(TARGET_ARCH_DBC)
+
+class GraphIntrinsifier : public AllStatic {
+ public:
+  static bool GraphIntrinsify(const ParsedFunction& parsed_function,
+                              FlowGraphCompiler* compiler) {
+    return false;
+  }
+};
+
+#endif  // !defined(TARGET_ARCH_DBC)
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_GRAPH_INTRINSIFIER_H_
diff --git a/runtime/vm/compiler/graph_intrinsifier_arm.cc b/runtime/vm/compiler/graph_intrinsifier_arm.cc
new file mode 100644
index 0000000..39b30c2
--- /dev/null
+++ b/runtime/vm/compiler/graph_intrinsifier_arm.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"  // Needed here to get TARGET_ARCH_ARM.
+#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/graph_intrinsifier.h"
+
+namespace dart {
+namespace compiler {
+
+#define __ assembler->
+
+intptr_t GraphIntrinsifier::ParameterSlotFromSp() {
+  return -1;
+}
+
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
+void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+
+  // Save LR by moving it to a callee saved temporary register.
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->mov(CALLEE_SAVED_TEMP, Operand(LR));
+}
+
+void GraphIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  // Restore LR.
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->mov(LR, Operand(CALLEE_SAVED_TEMP));
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/graph_intrinsifier_arm64.cc b/runtime/vm/compiler/graph_intrinsifier_arm64.cc
new file mode 100644
index 0000000..0dc98a7
--- /dev/null
+++ b/runtime/vm/compiler/graph_intrinsifier_arm64.cc
@@ -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.
+
+#include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
+#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/graph_intrinsifier.h"
+
+namespace dart {
+namespace compiler {
+
+#define __ assembler->
+
+intptr_t GraphIntrinsifier::ParameterSlotFromSp() {
+  return -1;
+}
+
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
+void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
+
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->mov(CALLEE_SAVED_TEMP, LR);
+  assembler->mov(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
+}
+
+void GraphIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->mov(LR, CALLEE_SAVED_TEMP);
+  assembler->mov(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/graph_intrinsifier_ia32.cc b/runtime/vm/compiler/graph_intrinsifier_ia32.cc
new file mode 100644
index 0000000..e89c176
--- /dev/null
+++ b/runtime/vm/compiler/graph_intrinsifier_ia32.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"  // Needed here to get TARGET_ARCH_IA32.
+#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/graph_intrinsifier.h"
+
+namespace dart {
+namespace compiler {
+
+#define __ assembler->
+
+intptr_t GraphIntrinsifier::ParameterSlotFromSp() {
+  return 0;
+}
+
+void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->movl(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
+}
+
+void GraphIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/graph_intrinsifier_x64.cc b/runtime/vm/compiler/graph_intrinsifier_x64.cc
new file mode 100644
index 0000000..46a8004
--- /dev/null
+++ b/runtime/vm/compiler/graph_intrinsifier_x64.cc
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"  // Needed here to get TARGET_ARCH_X64.
+#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/graph_intrinsifier.h"
+
+namespace dart {
+namespace compiler {
+
+#define __ assembler->
+
+intptr_t GraphIntrinsifier::ParameterSlotFromSp() {
+  return 0;
+}
+
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
+}
+
+void GraphIntrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
+  assembler->Comment("IntrinsicCallPrologue");
+  assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
+}
+
+void GraphIntrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
+  assembler->Comment("IntrinsicCallEpilogue");
+  assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 3902dac..ee1649f 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -24,9 +24,8 @@
 
 DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible");
 DEFINE_FLAG(bool, trace_intrinsifier, false, "Trace intrinsifier");
-DECLARE_FLAG(bool, code_comments);
-DECLARE_FLAG(bool, print_flow_graph);
-DECLARE_FLAG(bool, print_flow_graph_optimized);
+
+namespace compiler {
 
 bool Intrinsifier::CanIntrinsify(const Function& function) {
   if (FLAG_trace_intrinsifier) {
@@ -174,105 +173,6 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-// DBC does not use graph intrinsics.
-#if !defined(TARGET_ARCH_DBC)
-static void EmitCodeFor(FlowGraphCompiler* compiler, FlowGraph* graph) {
-  // The FlowGraph here is constructed by the intrinsics builder methods, and
-  // is different from compiler->flow_graph(), the original method's flow graph.
-  compiler->assembler()->Comment("Graph intrinsic begin");
-  for (intptr_t i = 0; i < graph->reverse_postorder().length(); i++) {
-    BlockEntryInstr* block = graph->reverse_postorder()[i];
-    if (block->IsGraphEntry()) continue;  // No code for graph entry needed.
-
-    if (block->HasParallelMove()) {
-      compiler->parallel_move_resolver()->EmitNativeCode(
-          block->parallel_move());
-    }
-
-    for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
-      Instruction* instr = it.Current();
-      if (FLAG_code_comments) compiler->EmitComment(instr);
-      if (instr->IsParallelMove()) {
-        compiler->parallel_move_resolver()->EmitNativeCode(
-            instr->AsParallelMove());
-      } else if (instr->IsInvokeMathCFunction()) {
-        ASSERT(instr->locs() != NULL);
-        Intrinsifier::IntrinsicCallPrologue(compiler->assembler());
-        instr->EmitNativeCode(compiler);
-        Intrinsifier::IntrinsicCallEpilogue(compiler->assembler());
-      } else {
-        ASSERT(instr->locs() != NULL);
-        // Calls are not supported in intrinsics code.
-        ASSERT(!instr->locs()->always_calls());
-        instr->EmitNativeCode(compiler);
-      }
-    }
-  }
-  compiler->assembler()->Comment("Graph intrinsic end");
-}
-#endif
-
-bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function,
-                                   FlowGraphCompiler* compiler) {
-#if !defined(TARGET_ARCH_DBC)
-  ASSERT(!parsed_function.function().HasOptionalParameters());
-  PrologueInfo prologue_info(-1, -1);
-
-  auto graph_entry =
-      new GraphEntryInstr(parsed_function, Compiler::kNoOSRDeoptId);
-
-  intptr_t block_id = 1;  // 0 is GraphEntry.
-  graph_entry->set_normal_entry(
-      new FunctionEntryInstr(graph_entry, block_id, kInvalidTryIndex,
-                             CompilerState::Current().GetNextDeoptId()));
-
-  FlowGraph* graph =
-      new FlowGraph(parsed_function, graph_entry, block_id, prologue_info);
-  const Function& function = parsed_function.function();
-  switch (function.recognized_kind()) {
-#define EMIT_CASE(class_name, function_name, enum_name, fp)                    \
-  case MethodRecognizer::k##enum_name:                                         \
-    if (!Build_##enum_name(graph)) return false;                               \
-    break;
-
-    GRAPH_INTRINSICS_LIST(EMIT_CASE);
-    default:
-      return false;
-#undef EMIT_CASE
-  }
-
-  if (FLAG_support_il_printer && FLAG_print_flow_graph &&
-      FlowGraphPrinter::ShouldPrint(function)) {
-    THR_Print("Intrinsic graph before\n");
-    FlowGraphPrinter printer(*graph);
-    printer.PrintBlocks();
-  }
-
-  // Prepare for register allocation (cf. FinalizeGraph).
-  graph->RemoveRedefinitions();
-
-  // Ensure loop hierarchy has been computed.
-  GrowableArray<BitVector*> dominance_frontier;
-  graph->ComputeDominators(&dominance_frontier);
-  graph->GetLoopHierarchy();
-
-  // Perform register allocation on the SSA graph.
-  FlowGraphAllocator allocator(*graph, true);  // Intrinsic mode.
-  allocator.AllocateRegisters();
-
-  if (FLAG_support_il_printer && FLAG_print_flow_graph &&
-      FlowGraphPrinter::ShouldPrint(function)) {
-    THR_Print("Intrinsic graph after\n");
-    FlowGraphPrinter printer(*graph);
-    printer.PrintBlocks();
-  }
-  EmitCodeFor(compiler, graph);
-  return true;
-#else
-  return false;
-#endif  // !defined(TARGET_ARCH_DBC)
-}
-
 // Returns true if fall-through code can be omitted.
 bool Intrinsifier::Intrinsify(const ParsedFunction& parsed_function,
                               FlowGraphCompiler* compiler) {
@@ -282,7 +182,7 @@
   }
 
   ASSERT(!compiler->flow_graph().IsCompiledForOsr());
-  if (GraphIntrinsify(parsed_function, compiler)) {
+  if (GraphIntrinsifier::GraphIntrinsify(parsed_function, compiler)) {
     return compiler->intrinsic_slow_path_label()->IsUnused();
   }
 
@@ -308,7 +208,7 @@
     compiler->assembler()->Comment("Intrinsic");                               \
     Label normal_ir_body;                                                      \
     const auto size_before = compiler->assembler()->CodeSize();                \
-    enum_name(compiler->assembler(), &normal_ir_body);                         \
+    AsmIntrinsifier::enum_name(compiler->assembler(), &normal_ir_body);        \
     const auto size_after = compiler->assembler()->CodeSize();                 \
     if (size_before == size_after) return false;                               \
     if (!normal_ir_body.IsBound()) {                                           \
@@ -345,939 +245,7 @@
   return false;
 }
 
-#if !defined(TARGET_ARCH_DBC)
-static intptr_t CidForRepresentation(Representation rep) {
-  switch (rep) {
-    case kUnboxedDouble:
-      return kDoubleCid;
-    case kUnboxedFloat32x4:
-      return kFloat32x4Cid;
-    case kUnboxedInt32x4:
-      return kInt32x4Cid;
-    case kUnboxedFloat64x2:
-      return kFloat64x2Cid;
-    case kUnboxedUint32:
-      return kDynamicCid;  // smi or mint.
-    default:
-      UNREACHABLE();
-      return kIllegalCid;
-  }
-}
-
-static Representation RepresentationForCid(intptr_t cid) {
-  switch (cid) {
-    case kDoubleCid:
-      return kUnboxedDouble;
-    case kFloat32x4Cid:
-      return kUnboxedFloat32x4;
-    case kInt32x4Cid:
-      return kUnboxedInt32x4;
-    case kFloat64x2Cid:
-      return kUnboxedFloat64x2;
-    default:
-      UNREACHABLE();
-      return kNoRepresentation;
-  }
-}
-
-// Notes about the graph intrinsics:
-//
-// IR instructions which would jump to a deoptimization sequence on failure
-// instead branch to the intrinsic slow path.
-//
-class BlockBuilder : public ValueObject {
- public:
-  BlockBuilder(FlowGraph* flow_graph, BlockEntryInstr* entry)
-      : flow_graph_(flow_graph),
-        entry_(entry),
-        current_(entry),
-        fall_through_env_(new Environment(0,
-                                          0,
-                                          DeoptId::kNone,
-                                          flow_graph->parsed_function(),
-                                          NULL)) {}
-
-  Definition* AddToInitialDefinitions(Definition* def) {
-    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
-    auto normal_entry = flow_graph_->graph_entry()->normal_entry();
-    flow_graph_->AddToInitialDefinitions(normal_entry, def);
-    return def;
-  }
-
-  Definition* AddDefinition(Definition* def) {
-    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
-    AddInstruction(def);
-    return def;
-  }
-
-  Instruction* AddInstruction(Instruction* instr) {
-    if (instr->ComputeCanDeoptimize()) {
-      // Since we use the presence of an environment to determine if an
-      // instructions can deoptimize, we need an empty environment for
-      // instructions that "deoptimize" to the intrinsic fall-through code.
-      instr->SetEnvironment(fall_through_env_);
-    }
-    current_ = current_->AppendInstruction(instr);
-    return instr;
-  }
-
-  void AddIntrinsicReturn(Value* value) {
-    ReturnInstr* instr = new ReturnInstr(
-        TokenPos(), value, CompilerState::Current().GetNextDeoptId());
-    AddInstruction(instr);
-    entry_->set_last_instruction(instr);
-  }
-
-  Definition* AddParameter(intptr_t index) {
-    intptr_t adjustment = Intrinsifier::ParameterSlotFromSp();
-    return AddToInitialDefinitions(new ParameterInstr(
-        adjustment + index, flow_graph_->graph_entry(), SPREG));
-  }
-
-  TokenPosition TokenPos() { return flow_graph_->function().token_pos(); }
-
-  Definition* AddNullDefinition() {
-    return AddDefinition(new ConstantInstr(Object::ZoneHandle(Object::null())));
-  }
-
-  Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) {
-    Definition* unboxed_value =
-        AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone));
-    if (is_checked) {
-      // The type of |value| has already been checked and it is safe to
-      // adjust reaching type. This is done manually because there is no type
-      // propagation when building intrinsics.
-      unboxed_value->AsUnbox()->value()->SetReachingType(
-          new CompileType(CompileType::FromCid(CidForRepresentation(rep))));
-    }
-    return unboxed_value;
-  }
-
-  Definition* AddUnboxInstr(Representation rep,
-                            Definition* boxed,
-                            bool is_checked) {
-    return AddUnboxInstr(rep, new Value(boxed), is_checked);
-  }
-
-  Definition* InvokeMathCFunction(MethodRecognizer::Kind recognized_kind,
-                                  ZoneGrowableArray<Value*>* args) {
-    return InvokeMathCFunctionHelper(recognized_kind, args);
-  }
-
- private:
-  Definition* InvokeMathCFunctionHelper(MethodRecognizer::Kind recognized_kind,
-                                        ZoneGrowableArray<Value*>* args) {
-    InvokeMathCFunctionInstr* invoke_math_c_function =
-        new InvokeMathCFunctionInstr(args, DeoptId::kNone, recognized_kind,
-                                     TokenPos());
-    AddDefinition(invoke_math_c_function);
-    return invoke_math_c_function;
-  }
-
-  FlowGraph* flow_graph_;
-  BlockEntryInstr* entry_;
-  Instruction* current_;
-  Environment* fall_through_env_;
-};
-
-static Definition* PrepareIndexedOp(FlowGraph* flow_graph,
-                                    BlockBuilder* builder,
-                                    Definition* array,
-                                    Definition* index,
-                                    const Slot& length_field) {
-  Definition* length = builder->AddDefinition(new LoadFieldInstr(
-      new Value(array), length_field, TokenPosition::kNoSource));
-  // Note that the intrinsifier must always use deopting array bound
-  // checks, because intrinsics currently don't support calls.
-  Definition* safe_index = new CheckArrayBoundInstr(
-      new Value(length), new Value(index), DeoptId::kNone);
-  builder->AddDefinition(safe_index);
-  return safe_index;
-}
-
-static bool IntrinsifyArrayGetIndexed(FlowGraph* flow_graph,
-                                      intptr_t array_cid) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* array = builder.AddParameter(2);
-
-  index = PrepareIndexedOp(flow_graph, &builder, array, index,
-                           Slot::GetLengthFieldForArrayCid(array_cid));
-
-  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
-    array = builder.AddDefinition(new LoadUntaggedInstr(
-        new Value(array), ExternalTypedData::data_offset()));
-  }
-
-  Definition* result = builder.AddDefinition(new LoadIndexedInstr(
-      new Value(array), new Value(index),
-      Instance::ElementSizeFor(array_cid),  // index scale
-      array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  // Box and/or convert result if necessary.
-  switch (array_cid) {
-    case kTypedDataInt32ArrayCid:
-    case kExternalTypedDataInt32ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedInt32, new Value(result)));
-      break;
-    case kTypedDataUint32ArrayCid:
-    case kExternalTypedDataUint32ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedUint32, new Value(result)));
-      break;
-    case kTypedDataFloat32ArrayCid:
-      result = builder.AddDefinition(
-          new FloatToDoubleInstr(new Value(result), DeoptId::kNone));
-    // Fall through.
-    case kTypedDataFloat64ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedDouble, new Value(result)));
-      break;
-    case kTypedDataFloat32x4ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedFloat32x4, new Value(result)));
-      break;
-    case kTypedDataInt32x4ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedInt32x4, new Value(result)));
-      break;
-    case kTypedDataFloat64x2ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedFloat64x2, new Value(result)));
-      break;
-    case kArrayCid:
-    case kImmutableArrayCid:
-    case kTypedDataInt8ArrayCid:
-    case kTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ArrayCid:
-    case kTypedDataUint8ClampedArrayCid:
-    case kExternalTypedDataUint8ClampedArrayCid:
-    case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid:
-      // Nothing to do.
-      break;
-    case kTypedDataInt64ArrayCid:
-    case kTypedDataUint64ArrayCid:
-      result = builder.AddDefinition(
-          BoxInstr::Create(kUnboxedInt64, new Value(result)));
-      break;
-    default:
-      UNREACHABLE();
-      break;
-  }
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-static bool IntrinsifyArraySetIndexed(FlowGraph* flow_graph,
-                                      intptr_t array_cid) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
-
-  index = PrepareIndexedOp(flow_graph, &builder, array, index,
-                           Slot::GetLengthFieldForArrayCid(array_cid));
-
-  // Value check/conversion.
-  switch (array_cid) {
-    case kTypedDataInt8ArrayCid:
-    case kTypedDataUint8ArrayCid:
-    case kExternalTypedDataUint8ArrayCid:
-    case kTypedDataUint8ClampedArrayCid:
-    case kExternalTypedDataUint8ClampedArrayCid:
-    case kTypedDataInt16ArrayCid:
-    case kTypedDataUint16ArrayCid:
-      builder.AddInstruction(new CheckSmiInstr(new Value(value), DeoptId::kNone,
-                                               builder.TokenPos()));
-      break;
-    case kTypedDataInt32ArrayCid:
-    case kExternalTypedDataInt32ArrayCid:
-    // Use same truncating unbox-instruction for int32 and uint32.
-    // Fall-through.
-    case kTypedDataUint32ArrayCid:
-    case kExternalTypedDataUint32ArrayCid:
-      // Supports smi and mint, slow-case for bigints.
-      value = builder.AddUnboxInstr(kUnboxedUint32, new Value(value),
-                                    /* is_checked = */ false);
-      break;
-    case kTypedDataInt64ArrayCid:
-    case kTypedDataUint64ArrayCid:
-      value = builder.AddUnboxInstr(kUnboxedInt64, new Value(value),
-                                    /* is_checked = */ false);
-      break;
-
-    case kTypedDataFloat32ArrayCid:
-    case kTypedDataFloat64ArrayCid:
-    case kTypedDataFloat32x4ArrayCid:
-    case kTypedDataInt32x4ArrayCid:
-    case kTypedDataFloat64x2ArrayCid: {
-      intptr_t value_check_cid = kDoubleCid;
-      Representation rep = kUnboxedDouble;
-      switch (array_cid) {
-        case kTypedDataFloat32x4ArrayCid:
-          value_check_cid = kFloat32x4Cid;
-          rep = kUnboxedFloat32x4;
-          break;
-        case kTypedDataInt32x4ArrayCid:
-          value_check_cid = kInt32x4Cid;
-          rep = kUnboxedInt32x4;
-          break;
-        case kTypedDataFloat64x2ArrayCid:
-          value_check_cid = kFloat64x2Cid;
-          rep = kUnboxedFloat64x2;
-          break;
-        default:
-          // Float32/Float64 case already handled.
-          break;
-      }
-      Zone* zone = flow_graph->zone();
-      Cids* value_check = Cids::CreateMonomorphic(zone, value_check_cid);
-      builder.AddInstruction(new CheckClassInstr(
-          new Value(value), DeoptId::kNone, *value_check, builder.TokenPos()));
-      value = builder.AddUnboxInstr(rep, new Value(value),
-                                    /* is_checked = */ true);
-      if (array_cid == kTypedDataFloat32ArrayCid) {
-        value = builder.AddDefinition(
-            new DoubleToFloatInstr(new Value(value), DeoptId::kNone));
-      }
-      break;
-    }
-    default:
-      UNREACHABLE();
-  }
-
-  if (RawObject::IsExternalTypedDataClassId(array_cid)) {
-    array = builder.AddDefinition(new LoadUntaggedInstr(
-        new Value(array), ExternalTypedData::data_offset()));
-  }
-  // No store barrier.
-  ASSERT(RawObject::IsExternalTypedDataClassId(array_cid) ||
-         RawObject::IsTypedDataClassId(array_cid));
-  builder.AddInstruction(new StoreIndexedInstr(
-      new Value(array), new Value(index), new Value(value), kNoStoreBarrier,
-      Instance::ElementSizeFor(array_cid),  // index scale
-      array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-#define DEFINE_ARRAY_GETTER_INTRINSIC(enum_name)                               \
-  bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) {    \
-    return IntrinsifyArrayGetIndexed(                                          \
-        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
-                        MethodRecognizer::k##enum_name##GetIndexed));          \
-  }
-
-#define DEFINE_ARRAY_SETTER_INTRINSIC(enum_name)                               \
-  bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) {    \
-    return IntrinsifyArraySetIndexed(                                          \
-        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
-                        MethodRecognizer::k##enum_name##SetIndexed));          \
-  }
-
-DEFINE_ARRAY_GETTER_INTRINSIC(ObjectArray)
-DEFINE_ARRAY_GETTER_INTRINSIC(ImmutableArray)
-
-#define DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                       \
-  DEFINE_ARRAY_GETTER_INTRINSIC(enum_name)                                     \
-  DEFINE_ARRAY_SETTER_INTRINSIC(enum_name)
-
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int8Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint8Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(ExternalUint8Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint8ClampedArray)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(ExternalUint8ClampedArray)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int16Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint16Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int32Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint32Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Int64Array)
-DEFINE_ARRAY_GETTER_SETTER_INTRINSICS(Uint64Array)
-
-#undef DEFINE_ARRAY_GETTER_SETTER_INTRINSICS
-#undef DEFINE_ARRAY_GETTER_INTRINSIC
-#undef DEFINE_ARRAY_SETTER_INTRINSIC
-
-#define DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name)                         \
-  bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) {    \
-    if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {                        \
-      return false;                                                            \
-    }                                                                          \
-    return IntrinsifyArrayGetIndexed(                                          \
-        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
-                        MethodRecognizer::k##enum_name##GetIndexed));          \
-  }
-
-#define DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name)                         \
-  bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) {    \
-    if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {                        \
-      return false;                                                            \
-    }                                                                          \
-    return IntrinsifyArraySetIndexed(                                          \
-        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
-                        MethodRecognizer::k##enum_name##SetIndexed));          \
-  }
-
-#define DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                 \
-  DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC(enum_name)                               \
-  DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name)
-
-DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float64Array)
-DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array)
-
-#undef DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS
-#undef DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC
-#undef DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC
-
-#define DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name)                          \
-  bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) {    \
-    if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {                        \
-      return false;                                                            \
-    }                                                                          \
-    return IntrinsifyArrayGetIndexed(                                          \
-        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
-                        MethodRecognizer::k##enum_name##GetIndexed));          \
-  }
-
-#define DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name)                          \
-  bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) {    \
-    if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {                        \
-      return false;                                                            \
-    }                                                                          \
-    return IntrinsifyArraySetIndexed(                                          \
-        flow_graph, MethodRecognizer::MethodKindToReceiverCid(                 \
-                        MethodRecognizer::k##enum_name##SetIndexed));          \
-  }
-
-#define DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(enum_name)                  \
-  DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name)                                \
-  DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name)
-
-DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float32x4Array)
-DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Int32x4Array)
-DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float64x2Array)
-
-#undef DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS
-#undef DEFINE_SIMD_ARRAY_GETTER_INTRINSIC
-#undef DEFINE_SIMD_ARRAY_SETTER_INTRINSIC
-
-static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* str = builder.AddParameter(2);
-
-  index =
-      PrepareIndexedOp(flow_graph, &builder, str, index, Slot::String_length());
-
-  // For external strings: Load external data.
-  if (cid == kExternalOneByteStringCid) {
-    str = builder.AddDefinition(new LoadUntaggedInstr(
-        new Value(str), ExternalOneByteString::external_data_offset()));
-  } else if (cid == kExternalTwoByteStringCid) {
-    str = builder.AddDefinition(new LoadUntaggedInstr(
-        new Value(str), ExternalTwoByteString::external_data_offset()));
-  }
-
-  Definition* result = builder.AddDefinition(new LoadIndexedInstr(
-      new Value(str), new Value(index), Instance::ElementSizeFor(cid), cid,
-      kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-bool Intrinsifier::Build_OneByteStringCodeUnitAt(FlowGraph* flow_graph) {
-  return BuildCodeUnitAt(flow_graph, kOneByteStringCid);
-}
-
-bool Intrinsifier::Build_TwoByteStringCodeUnitAt(FlowGraph* flow_graph) {
-  return BuildCodeUnitAt(flow_graph, kTwoByteStringCid);
-}
-
-bool Intrinsifier::Build_ExternalOneByteStringCodeUnitAt(
-    FlowGraph* flow_graph) {
-  return BuildCodeUnitAt(flow_graph, kExternalOneByteStringCid);
-}
-
-bool Intrinsifier::Build_ExternalTwoByteStringCodeUnitAt(
-    FlowGraph* flow_graph) {
-  return BuildCodeUnitAt(flow_graph, kExternalTwoByteStringCid);
-}
-
-static bool BuildSimdOp(FlowGraph* flow_graph, intptr_t cid, Token::Kind kind) {
-  if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
-
-  const Representation rep = RepresentationForCid(cid);
-
-  Zone* zone = flow_graph->zone();
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* right = builder.AddParameter(1);
-  Definition* left = builder.AddParameter(2);
-
-  Cids* value_check = Cids::CreateMonomorphic(zone, cid);
-  // Check argument. Receiver (left) is known to be a Float32x4.
-  builder.AddInstruction(new CheckClassInstr(new Value(right), DeoptId::kNone,
-                                             *value_check, builder.TokenPos()));
-  Definition* left_simd = builder.AddUnboxInstr(rep, new Value(left),
-                                                /* is_checked = */ true);
-
-  Definition* right_simd = builder.AddUnboxInstr(rep, new Value(right),
-                                                 /* is_checked = */ true);
-
-  Definition* unboxed_result = builder.AddDefinition(SimdOpInstr::Create(
-      SimdOpInstr::KindForOperator(cid, kind), new Value(left_simd),
-      new Value(right_simd), DeoptId::kNone));
-  Definition* result =
-      builder.AddDefinition(BoxInstr::Create(rep, new Value(unboxed_result)));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) {
-  return BuildSimdOp(flow_graph, kFloat32x4Cid, Token::kMUL);
-}
-
-bool Intrinsifier::Build_Float32x4Sub(FlowGraph* flow_graph) {
-  return BuildSimdOp(flow_graph, kFloat32x4Cid, Token::kSUB);
-}
-
-bool Intrinsifier::Build_Float32x4Add(FlowGraph* flow_graph) {
-  return BuildSimdOp(flow_graph, kFloat32x4Cid, Token::kADD);
-}
-
-static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph,
-                                  MethodRecognizer::Kind kind) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles() ||
-      !FlowGraphCompiler::SupportsUnboxedSimd128()) {
-    return false;
-  }
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* receiver = builder.AddParameter(1);
-
-  Definition* unboxed_receiver =
-      builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver),
-                            /* is_checked = */ true);
-
-  Definition* unboxed_result = builder.AddDefinition(
-      SimdOpInstr::Create(kind, new Value(unboxed_receiver), DeoptId::kNone));
-
-  Definition* result = builder.AddDefinition(
-      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) {
-  return BuildFloat32x4Shuffle(flow_graph,
-                               MethodRecognizer::kFloat32x4ShuffleX);
-}
-
-bool Intrinsifier::Build_Float32x4ShuffleY(FlowGraph* flow_graph) {
-  return BuildFloat32x4Shuffle(flow_graph,
-                               MethodRecognizer::kFloat32x4ShuffleY);
-}
-
-bool Intrinsifier::Build_Float32x4ShuffleZ(FlowGraph* flow_graph) {
-  return BuildFloat32x4Shuffle(flow_graph,
-                               MethodRecognizer::kFloat32x4ShuffleZ);
-}
-
-bool Intrinsifier::Build_Float32x4ShuffleW(FlowGraph* flow_graph) {
-  return BuildFloat32x4Shuffle(flow_graph,
-                               MethodRecognizer::kFloat32x4ShuffleW);
-}
-
-static bool BuildLoadField(FlowGraph* flow_graph, const Slot& field) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* array = builder.AddParameter(1);
-
-  Definition* length = builder.AddDefinition(
-      new LoadFieldInstr(new Value(array), field, builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(length));
-  return true;
-}
-
-bool Intrinsifier::Build_ObjectArrayLength(FlowGraph* flow_graph) {
-  return BuildLoadField(flow_graph, Slot::Array_length());
-}
-
-bool Intrinsifier::Build_ImmutableArrayLength(FlowGraph* flow_graph) {
-  return BuildLoadField(flow_graph, Slot::Array_length());
-}
-
-bool Intrinsifier::Build_GrowableArrayLength(FlowGraph* flow_graph) {
-  return BuildLoadField(flow_graph, Slot::GrowableObjectArray_length());
-}
-
-bool Intrinsifier::Build_StringBaseLength(FlowGraph* flow_graph) {
-  return BuildLoadField(flow_graph, Slot::String_length());
-}
-
-bool Intrinsifier::Build_TypedDataLength(FlowGraph* flow_graph) {
-  return BuildLoadField(flow_graph, Slot::TypedData_length());
-}
-
-bool Intrinsifier::Build_GrowableArrayCapacity(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* array = builder.AddParameter(1);
-
-  Definition* backing_store = builder.AddDefinition(new LoadFieldInstr(
-      new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos()));
-  Definition* capacity = builder.AddDefinition(new LoadFieldInstr(
-      new Value(backing_store), Slot::Array_length(), builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(capacity));
-  return true;
-}
-
-bool Intrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* index = builder.AddParameter(1);
-  Definition* growable_array = builder.AddParameter(2);
-
-  index = PrepareIndexedOp(flow_graph, &builder, growable_array, index,
-                           Slot::GrowableObjectArray_length());
-
-  Definition* backing_store = builder.AddDefinition(
-      new LoadFieldInstr(new Value(growable_array),
-                         Slot::GrowableObjectArray_data(), builder.TokenPos()));
-  Definition* result = builder.AddDefinition(new LoadIndexedInstr(
-      new Value(backing_store), new Value(index),
-      Instance::ElementSizeFor(kArrayCid),  // index scale
-      kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-bool Intrinsifier::Build_ObjectArraySetIndexed(FlowGraph* flow_graph) {
-  if (Isolate::Current()->argument_type_checks()) {
-    return false;
-  }
-
-  return Build_ObjectArraySetIndexedUnchecked(flow_graph);
-}
-
-bool Intrinsifier::Build_ObjectArraySetIndexedUnchecked(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
-
-  index = PrepareIndexedOp(flow_graph, &builder, array, index,
-                           Slot::Array_length());
-
-  builder.AddInstruction(new StoreIndexedInstr(
-      new Value(array), new Value(index), new Value(value), kEmitStoreBarrier,
-      Instance::ElementSizeFor(kArrayCid),  // index scale
-      kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
-  if (Isolate::Current()->argument_type_checks()) {
-    return false;
-  }
-
-  return Build_GrowableArraySetIndexedUnchecked(flow_graph);
-}
-
-bool Intrinsifier::Build_GrowableArraySetIndexedUnchecked(
-    FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
-
-  index = PrepareIndexedOp(flow_graph, &builder, array, index,
-                           Slot::GrowableObjectArray_length());
-
-  Definition* backing_store = builder.AddDefinition(new LoadFieldInstr(
-      new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos()));
-
-  builder.AddInstruction(new StoreIndexedInstr(
-      new Value(backing_store), new Value(index), new Value(value),
-      kEmitStoreBarrier,
-      Instance::ElementSizeFor(kArrayCid),  // index scale
-      kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* data = builder.AddParameter(1);
-  Definition* growable_array = builder.AddParameter(2);
-  Zone* zone = flow_graph->zone();
-
-  Cids* value_check = Cids::CreateMonomorphic(zone, kArrayCid);
-  builder.AddInstruction(new CheckClassInstr(new Value(data), DeoptId::kNone,
-                                             *value_check, builder.TokenPos()));
-
-  builder.AddInstruction(new StoreInstanceFieldInstr(
-      Slot::GrowableObjectArray_data(), new Value(growable_array),
-      new Value(data), kEmitStoreBarrier, builder.TokenPos()));
-  // Return null.
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) {
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* length = builder.AddParameter(1);
-  Definition* growable_array = builder.AddParameter(2);
-
-  builder.AddInstruction(
-      new CheckSmiInstr(new Value(length), DeoptId::kNone, builder.TokenPos()));
-  builder.AddInstruction(new StoreInstanceFieldInstr(
-      Slot::GrowableObjectArray_length(), new Value(growable_array),
-      new Value(length), kNoStoreBarrier, builder.TokenPos()));
-  Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
-  return true;
-}
-
-bool Intrinsifier::Build_DoubleFlipSignBit(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
-    return false;
-  }
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  Definition* receiver = builder.AddParameter(1);
-  Definition* unboxed_value =
-      builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver),
-                            /* is_checked = */ true);
-  Definition* unboxed_result = builder.AddDefinition(new UnaryDoubleOpInstr(
-      Token::kNEGATE, new Value(unboxed_value), DeoptId::kNone));
-  Definition* result = builder.AddDefinition(
-      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
-  builder.AddIntrinsicReturn(new Value(result));
-  return true;
-}
-
-static bool BuildInvokeMathCFunction(BlockBuilder* builder,
-                                     MethodRecognizer::Kind kind,
-                                     intptr_t num_parameters = 1) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
-    return false;
-  }
-  ZoneGrowableArray<Value*>* args =
-      new ZoneGrowableArray<Value*>(num_parameters);
-
-  for (intptr_t i = 0; i < num_parameters; i++) {
-    const intptr_t parameter_index = (num_parameters - i);
-    Definition* value = builder->AddParameter(parameter_index);
-    Definition* unboxed_value =
-        builder->AddUnboxInstr(kUnboxedDouble, value, /* is_checked = */ false);
-    args->Add(new Value(unboxed_value));
-  }
-
-  Definition* unboxed_result = builder->InvokeMathCFunction(kind, args);
-
-  Definition* result = builder->AddDefinition(
-      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
-
-  builder->AddIntrinsicReturn(new Value(result));
-
-  return true;
-}
-
-bool Intrinsifier::Build_MathSin(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathSin);
-}
-
-bool Intrinsifier::Build_MathCos(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathCos);
-}
-
-bool Intrinsifier::Build_MathTan(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathTan);
-}
-
-bool Intrinsifier::Build_MathAsin(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAsin);
-}
-
-bool Intrinsifier::Build_MathAcos(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAcos);
-}
-
-bool Intrinsifier::Build_MathAtan(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan);
-}
-
-bool Intrinsifier::Build_MathAtan2(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kMathAtan2,
-                                  /* num_parameters = */ 2);
-}
-
-bool Intrinsifier::Build_DoubleMod(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleMod,
-                                  /* num_parameters = */ 2);
-}
-
-bool Intrinsifier::Build_DoubleCeil(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-  // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
-  // way.
-  if (TargetCPUFeatures::double_truncate_round_supported()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleCeil);
-}
-
-bool Intrinsifier::Build_DoubleFloor(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-  // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
-  // way.
-  if (TargetCPUFeatures::double_truncate_round_supported()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleFloor);
-}
-
-bool Intrinsifier::Build_DoubleTruncate(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-  // TODO(johnmccutchan): On X86 this intrinsic can be written in a different
-  // way.
-  if (TargetCPUFeatures::double_truncate_round_supported()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleTruncate);
-}
-
-bool Intrinsifier::Build_DoubleRound(FlowGraph* flow_graph) {
-  if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
-
-  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
-  auto normal_entry = graph_entry->normal_entry();
-  BlockBuilder builder(flow_graph, normal_entry);
-
-  return BuildInvokeMathCFunction(&builder, MethodRecognizer::kDoubleRound);
-}
-
-void Intrinsifier::String_identityHash(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  String_getHashCode(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Double_identityHash(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  Double_hashCode(assembler, normal_ir_body);
-}
-
-void Intrinsifier::RegExp_ExecuteMatch(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body, /*sticky=*/false);
-}
-
-void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  IntrinsifyRegExpExecuteMatch(assembler, normal_ir_body, /*sticky=*/true);
-}
-#endif  // !defined(TARGET_ARCH_DBC)
-
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/intrinsifier.h b/runtime/vm/compiler/intrinsifier.h
index 23d5436..3aa9148 100644
--- a/runtime/vm/compiler/intrinsifier.h
+++ b/runtime/vm/compiler/intrinsifier.h
@@ -7,18 +7,20 @@
 #define RUNTIME_VM_COMPILER_INTRINSIFIER_H_
 
 #include "vm/allocation.h"
+#include "vm/compiler/asm_intrinsifier.h"
+#include "vm/compiler/graph_intrinsifier.h"
 #include "vm/compiler/method_recognizer.h"
 
 namespace dart {
 
 // Forward declarations.
-class Assembler;
-class Label;
 class FlowGraphCompiler;
 class Function;
-class TargetEntryInstr;
 class ParsedFunction;
-class FlowGraph;
+
+namespace compiler {
+class Assembler;
+class Label;
 
 class Intrinsifier : public AllStatic {
  public:
@@ -28,46 +30,11 @@
   static void InitializeState();
 #endif
 
-  static bool GraphIntrinsify(const ParsedFunction& parsed_function,
-                              FlowGraphCompiler* compiler);
-
-  static intptr_t ParameterSlotFromSp();
-
-  static void IntrinsicCallPrologue(Assembler* assembler);
-  static void IntrinsicCallEpilogue(Assembler* assembler);
-
  private:
-  // The "_A" value used in the intrinsification of
-  // `runtime/lib/math_patch.dart:_Random._nextState()`
-  static const int64_t kRandomAValue = 0xffffda61;
-
   static bool CanIntrinsify(const Function& function);
-
-#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp)             \
-  static void enum_name(Assembler* assembler, Label* normal_ir_body);
-
-  ALL_INTRINSICS_LIST(DECLARE_FUNCTION)
-#if defined(TARGET_ARCH_DBC)
-  // On DBC graph intrinsics are handled in the same way as non-graph ones.
-  GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
-#endif
-
-#undef DECLARE_FUNCTION
-
-#if !defined(TARGET_ARCH_DBC)
-#define DECLARE_FUNCTION(class_name, function_name, enum_name, fp)             \
-  static bool Build_##enum_name(FlowGraph* flow_graph);
-
-  GRAPH_INTRINSICS_LIST(DECLARE_FUNCTION)
-
-#undef DECLARE_FUNCTION
-
-  static void IntrinsifyRegExpExecuteMatch(Assembler* assembler,
-                                           Label* normal_ir_body,
-                                           bool sticky);
-#endif
 };
 
+}  // namespace compiler
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_INTRINSIFIER_H_
diff --git a/runtime/vm/compiler/intrinsifier_arm.cc b/runtime/vm/compiler/intrinsifier_arm.cc
deleted file mode 100644
index 9e516f0..0000000
--- a/runtime/vm/compiler/intrinsifier_arm.cc
+++ /dev/null
@@ -1,2260 +0,0 @@
-// 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.
-
-#include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM.
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/intrinsifier.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/object.h"
-#include "vm/object_store.h"
-#include "vm/regexp_assembler.h"
-#include "vm/symbols.h"
-#include "vm/timeline.h"
-
-namespace dart {
-
-// When entering intrinsics code:
-// R4: Arguments descriptor
-// LR: Return address
-// The R4 register can be destroyed only if there is no slow-path, i.e.
-// if the intrinsified method always executes a return.
-// The FP register should not be modified, because it is used by the profiler.
-// The PP and THR registers (see constants_arm.h) must be preserved.
-
-#define __ assembler->
-
-intptr_t Intrinsifier::ParameterSlotFromSp() {
-  return -1;
-}
-
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
-}
-
-void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-
-  // Save LR by moving it to a callee saved temporary register.
-  assembler->Comment("IntrinsicCallPrologue");
-  assembler->mov(CALLEE_SAVED_TEMP, Operand(LR));
-}
-
-void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
-  // Restore LR.
-  assembler->Comment("IntrinsicCallEpilogue");
-  assembler->mov(LR, Operand(CALLEE_SAVED_TEMP));
-}
-
-// Allocate a GrowableObjectArray using the backing array specified.
-// On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  // The newly allocated object is returned in R0.
-  const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
-  const intptr_t kArrayOffset = 0 * kWordSize;
-
-  // Try allocating in new space.
-  const Class& cls = Class::Handle(
-      Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, normal_ir_body, R0, R1);
-
-  // Store backing array object in growable array object.
-  __ ldr(R1, Address(SP, kArrayOffset));  // Data argument.
-  // R0 is new, no barrier needed.
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, GrowableObjectArray::data_offset()), R1);
-
-  // R0: new growable array object start as a tagged pointer.
-  // Store the type argument field in the growable array object.
-  __ ldr(R1, Address(SP, kTypeArgumentsOffset));  // Type argument.
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, GrowableObjectArray::type_arguments_offset()), R1);
-
-  // Set the length field in the growable array object to 0.
-  __ LoadImmediate(R1, 0);
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, GrowableObjectArray::length_offset()), R1);
-  __ Ret();  // Returns the newly allocated object in R0.
-
-  __ Bind(normal_ir_body);
-}
-
-#define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift)           \
-  Label fall_through;                                                          \
-  const intptr_t kArrayLengthStackOffset = 0 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R2, cid));                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R2, normal_ir_body));                 \
-  __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
-  /* Check that length is a positive Smi. */                                   \
-  /* R2: requested array length argument. */                                   \
-  __ tst(R2, Operand(kSmiTagMask));                                            \
-  __ b(normal_ir_body, NE);                                                    \
-  __ CompareImmediate(R2, 0);                                                  \
-  __ b(normal_ir_body, LT);                                                    \
-  __ SmiUntag(R2);                                                             \
-  /* Check for maximum allowed length. */                                      \
-  /* R2: untagged array length. */                                             \
-  __ CompareImmediate(R2, max_len);                                            \
-  __ b(normal_ir_body, GT);                                                    \
-  __ mov(R2, Operand(R2, LSL, scale_shift));                                   \
-  const intptr_t fixed_size_plus_alignment_padding =                           \
-      sizeof(Raw##type_name) + kObjectAlignment - 1;                           \
-  __ AddImmediate(R2, fixed_size_plus_alignment_padding);                      \
-  __ bic(R2, R2, Operand(kObjectAlignment - 1));                               \
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);                              \
-  __ ldr(R0, Address(THR, Thread::top_offset()));                              \
-                                                                               \
-  /* R2: allocation size. */                                                   \
-  __ adds(R1, R0, Operand(R2));                                                \
-  __ b(normal_ir_body, CS); /* Fail on unsigned overflow. */                   \
-                                                                               \
-  /* Check if the allocation fits into the remaining space. */                 \
-  /* R0: potential new object start. */                                        \
-  /* R1: potential next object start. */                                       \
-  /* R2: allocation size. */                                                   \
-  __ ldr(IP, Address(THR, Thread::end_offset()));                              \
-  __ cmp(R1, Operand(IP));                                                     \
-  __ b(normal_ir_body, CS);                                                    \
-                                                                               \
-  /* Successfully allocated the object(s), now update top to point to */       \
-  /* next object start and initialize the object. */                           \
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));                      \
-  __ str(R1, Address(THR, Thread::top_offset()));                              \
-  __ AddImmediate(R0, kHeapObjectTag);                                         \
-  /* Initialize the tags. */                                                   \
-  /* R0: new object start as a tagged pointer. */                              \
-  /* R1: new object end address. */                                            \
-  /* R2: allocation size. */                                                   \
-  /* R4: allocation stats address */                                           \
-  {                                                                            \
-    __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);                  \
-    __ mov(R3,                                                                 \
-           Operand(R2, LSL, RawObject::kSizeTagPos - kObjectAlignmentLog2),    \
-           LS);                                                                \
-    __ mov(R3, Operand(0), HI);                                                \
-                                                                               \
-    /* Get the class index and insert it into the tags. */                     \
-    uint32_t tags = 0;                                                         \
-    tags = RawObject::ClassIdTag::update(cid, tags);                           \
-    tags = RawObject::NewBit::update(true, tags);                              \
-    __ LoadImmediate(TMP, tags);                                               \
-    __ orr(R3, R3, Operand(TMP));                                              \
-    __ str(R3, FieldAddress(R0, type_name::tags_offset())); /* Tags. */        \
-  }                                                                            \
-  /* Set the length field. */                                                  \
-  /* R0: new object start as a tagged pointer. */                              \
-  /* R1: new object end address. */                                            \
-  /* R2: allocation size. */                                                   \
-  /* R4: allocation stats address. */                                          \
-  __ ldr(R3, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
-  __ StoreIntoObjectNoBarrier(                                                 \
-      R0, FieldAddress(R0, type_name::length_offset()), R3);                   \
-  /* Initialize all array elements to 0. */                                    \
-  /* R0: new object start as a tagged pointer. */                              \
-  /* R1: new object end address. */                                            \
-  /* R2: allocation size. */                                                   \
-  /* R3: iterator which initially points to the start of the variable */       \
-  /* R4: allocation stats address */                                           \
-  /* R8, R9: zero. */                                                          \
-  /* data area to be initialized. */                                           \
-  __ LoadImmediate(R8, 0);                                                     \
-  __ mov(R9, Operand(R8));                                                     \
-  __ AddImmediate(R3, R0, sizeof(Raw##type_name) - 1);                         \
-  Label init_loop;                                                             \
-  __ Bind(&init_loop);                                                         \
-  __ AddImmediate(R3, 2 * kWordSize);                                          \
-  __ cmp(R3, Operand(R1));                                                     \
-  __ strd(R8, R9, R3, -2 * kWordSize, LS);                                     \
-  __ b(&init_loop, CC);                                                        \
-  __ str(R8, Address(R3, -2 * kWordSize), HI);                                 \
-                                                                               \
-  NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2, space));          \
-  __ Ret();                                                                    \
-  __ Bind(normal_ir_body);
-
-static int GetScaleFactor(intptr_t size) {
-  switch (size) {
-    case 1:
-      return 0;
-    case 2:
-      return 1;
-    case 4:
-      return 2;
-    case 8:
-      return 3;
-    case 16:
-      return 4;
-  }
-  UNREACHABLE();
-  return -1;
-}
-
-#define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
-                                                 Label* normal_ir_body) {      \
-    intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
-    intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
-    int shift = GetScaleFactor(size);                                          \
-    TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift); \
-  }
-CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
-#undef TYPED_DATA_ALLOCATOR
-
-// Loads args from stack into R0 and R1
-// Tests if they are smis, jumps to label not_smi if not.
-static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
-  __ ldr(R0, Address(SP, +0 * kWordSize));
-  __ ldr(R1, Address(SP, +1 * kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ tst(TMP, Operand(kSmiTagMask));
-  __ b(not_smi, NE);
-}
-
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ adds(R0, R0, Operand(R1));                     // Adds.
-  __ bx(LR, VC);                                    // Return if no overflow.
-  // Otherwise fall through.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  Integer_addFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ subs(R0, R0, Operand(R1));  // Subtract.
-  __ bx(LR, VC);                 // Return if no overflow.
-  // Otherwise fall through.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ subs(R0, R1, Operand(R0));  // Subtract.
-  __ bx(LR, VC);                 // Return if no overflow.
-  // Otherwise fall through.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ SmiUntag(R0);           // Untags R0. We only want result shifted by one.
-  __ smull(R0, IP, R0, R1);  // IP:R0 <- R0 * R1.
-  __ cmp(IP, Operand(R0, ASR, 31));
-  __ bx(LR, EQ);
-  __ Bind(normal_ir_body);  // Fall through on overflow.
-}
-
-void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  Integer_mulFromInteger(assembler, normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// R1: Tagged left (dividend).
-// R0: Tagged right (divisor).
-// Returns:
-//   R1: Untagged fallthrough result (remainder to be adjusted), or
-//   R0: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label modulo;
-  const Register left = R1;
-  const Register right = R0;
-  const Register result = R1;
-  const Register tmp = R2;
-  ASSERT(left == result);
-
-  // Check for quick zero results.
-  __ cmp(left, Operand(0));
-  __ mov(R0, Operand(0), EQ);
-  __ bx(LR, EQ);  // left is 0? Return 0.
-  __ cmp(left, Operand(right));
-  __ mov(R0, Operand(0), EQ);
-  __ bx(LR, EQ);  // left == right? Return 0.
-
-  // Check if result should be left.
-  __ cmp(left, Operand(0));
-  __ b(&modulo, LT);
-  // left is positive.
-  __ cmp(left, Operand(right));
-  // left is less than right, result is left.
-  __ mov(R0, Operand(left), LT);
-  __ bx(LR, LT);
-
-  __ Bind(&modulo);
-  // result <- left - right * (left / right)
-  __ SmiUntag(left);
-  __ SmiUntag(right);
-
-  __ IntegerDivide(tmp, left, right, D1, D0);
-
-  __ mls(result, right, tmp, left);  // result <- left - right * TMP
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  if (!TargetCPUFeatures::can_divide()) {
-    return;
-  }
-  // Check to see if we have integer division
-  __ ldr(R1, Address(SP, +0 * kWordSize));
-  __ ldr(R0, Address(SP, +1 * kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ tst(TMP, Operand(kSmiTagMask));
-  __ b(normal_ir_body, NE);
-  // R1: Tagged left (dividend).
-  // R0: Tagged right (divisor).
-  // Check if modulo by zero -> exception thrown in main function.
-  __ cmp(R0, Operand(0));
-  __ b(normal_ir_body, EQ);
-  EmitRemainderOperation(assembler);
-  // Untagged right in R0. Untagged remainder result in R1.
-
-  __ cmp(R1, Operand(0));
-  __ mov(R0, Operand(R1, LSL, 1), GE);  // Tag and move result to R0.
-  __ bx(LR, GE);
-
-  // Result is negative, adjust it.
-  __ cmp(R0, Operand(0));
-  __ sub(R0, R1, Operand(R0), LT);
-  __ add(R0, R1, Operand(R0), GE);
-  __ SmiTag(R0);
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_truncDivide(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  if (!TargetCPUFeatures::can_divide()) {
-    return;
-  }
-  // Check to see if we have integer division
-
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ cmp(R0, Operand(0));
-  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
-
-  __ SmiUntag(R0);
-  __ SmiUntag(R1);
-
-  __ IntegerDivide(R0, R1, R0, D1, D0);
-
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ CompareImmediate(R0, 0x40000000);
-  __ SmiTag(R0, NE);  // Not equal. Okay to tag and return.
-  __ bx(LR, NE);      // Return.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, +0 * kWordSize));  // Grab first argument.
-  __ tst(R0, Operand(kSmiTagMask));         // Test for Smi.
-  __ b(normal_ir_body, NE);
-  __ rsbs(R0, R0, Operand(0));  // R0 is a Smi. R0 <- 0 - R0.
-  __ bx(LR, VC);  // Return if there wasn't overflow, fall through otherwise.
-  // R0 is not a Smi. Fall through.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ and_(R0, R0, Operand(R1));
-
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ orr(R0, R0, Operand(R1));
-
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitOrFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ eor(R0, R0, Operand(R1));
-
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitXorFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
-  ASSERT(kSmiTagShift == 1);
-  ASSERT(kSmiTag == 0);
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ CompareImmediate(R0, Smi::RawValue(Smi::kBits));
-  __ b(normal_ir_body, HI);
-
-  __ SmiUntag(R0);
-
-  // Check for overflow by shifting left and shifting back arithmetically.
-  // If the result is different from the original, there was overflow.
-  __ mov(IP, Operand(R1, LSL, R0));
-  __ cmp(R1, Operand(IP, ASR, R0));
-
-  // No overflow, result in R0.
-  __ mov(R0, Operand(R1, LSL, R0), EQ);
-  __ bx(LR, EQ);
-
-  // Arguments are Smi but the shift produced an overflow to Mint.
-  __ CompareImmediate(R1, 0);
-  __ b(normal_ir_body, LT);
-  __ SmiUntag(R1);
-
-  // Pull off high bits that will be shifted off of R1 by making a mask
-  // ((1 << R0) - 1), shifting it to the left, masking R1, then shifting back.
-  // high bits = (((1 << R0) - 1) << (32 - R0)) & R1) >> (32 - R0)
-  // lo bits = R1 << R0
-  __ LoadImmediate(NOTFP, 1);
-  __ mov(NOTFP, Operand(NOTFP, LSL, R0));  // NOTFP <- 1 << R0
-  __ sub(NOTFP, NOTFP, Operand(1));        // NOTFP <- NOTFP - 1
-  __ rsb(R3, R0, Operand(32));             // R3 <- 32 - R0
-  __ mov(NOTFP, Operand(NOTFP, LSL, R3));  // NOTFP <- NOTFP << R3
-  __ and_(NOTFP, R1, Operand(NOTFP));      // NOTFP <- NOTFP & R1
-  __ mov(NOTFP, Operand(NOTFP, LSR, R3));  // NOTFP <- NOTFP >> R3
-  // Now NOTFP has the bits that fall off of R1 on a left shift.
-  __ mov(R1, Operand(R1, LSL, R0));  // R1 gets the low bits.
-
-  const Class& mint_class =
-      Class::Handle(Isolate::Current()->object_store()->mint_class());
-  __ TryAllocate(mint_class, normal_ir_body, R0, R2);
-
-  __ str(R1, FieldAddress(R0, Mint::value_offset()));
-  __ str(NOTFP, FieldAddress(R0, Mint::value_offset() + kWordSize));
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-static void Get64SmiOrMint(Assembler* assembler,
-                           Register res_hi,
-                           Register res_lo,
-                           Register reg,
-                           Label* not_smi_or_mint) {
-  Label not_smi, done;
-  __ tst(reg, Operand(kSmiTagMask));
-  __ b(&not_smi, NE);
-  __ SmiUntag(reg);
-
-  // Sign extend to 64 bit
-  __ mov(res_lo, Operand(reg));
-  __ mov(res_hi, Operand(res_lo, ASR, 31));
-  __ b(&done);
-
-  __ Bind(&not_smi);
-  __ CompareClassId(reg, kMintCid, res_lo);
-  __ b(not_smi_or_mint, NE);
-
-  // Mint.
-  __ ldr(res_lo, FieldAddress(reg, Mint::value_offset()));
-  __ ldr(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize));
-  __ Bind(&done);
-}
-
-static void CompareIntegers(Assembler* assembler,
-                            Label* normal_ir_body,
-                            Condition true_condition) {
-  Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
-  TestBothArgumentsSmis(assembler, &try_mint_smi);
-  // R0 contains the right argument. R1 contains left argument
-
-  __ cmp(R1, Operand(R0));
-  __ b(&is_true, true_condition);
-  __ Bind(&is_false);
-  __ LoadObject(R0, Bool::False());
-  __ Ret();
-  __ Bind(&is_true);
-  __ LoadObject(R0, Bool::True());
-  __ Ret();
-
-  // 64-bit comparison
-  Condition hi_true_cond, hi_false_cond, lo_false_cond;
-  switch (true_condition) {
-    case LT:
-    case LE:
-      hi_true_cond = LT;
-      hi_false_cond = GT;
-      lo_false_cond = (true_condition == LT) ? CS : HI;
-      break;
-    case GT:
-    case GE:
-      hi_true_cond = GT;
-      hi_false_cond = LT;
-      lo_false_cond = (true_condition == GT) ? LS : CC;
-      break;
-    default:
-      UNREACHABLE();
-      hi_true_cond = hi_false_cond = lo_false_cond = VS;
-  }
-
-  __ Bind(&try_mint_smi);
-  // Get left as 64 bit integer.
-  Get64SmiOrMint(assembler, R3, R2, R1, normal_ir_body);
-  // Get right as 64 bit integer.
-  Get64SmiOrMint(assembler, NOTFP, R8, R0, normal_ir_body);
-  // R3: left high.
-  // R2: left low.
-  // NOTFP: right high.
-  // R8: right low.
-
-  __ cmp(R3, Operand(NOTFP));  // Compare left hi, right high.
-  __ b(&is_false, hi_false_cond);
-  __ b(&is_true, hi_true_cond);
-  __ cmp(R2, Operand(R8));  // Compare left lo, right lo.
-  __ b(&is_false, lo_false_cond);
-  // Else is true.
-  __ b(&is_true);
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LT);
-}
-
-void Intrinsifier::Integer_lessThan(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Integer_greaterThanFromInt(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_greaterThan(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GT);
-}
-
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LE);
-}
-
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GE);
-}
-
-// This is called for Smi and Mint receivers. The right argument
-// can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  Label true_label, check_for_mint;
-  // For integer receiver '===' check first.
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R1, Address(SP, 1 * kWordSize));
-  __ cmp(R0, Operand(R1));
-  __ b(&true_label, EQ);
-
-  __ orr(R2, R0, Operand(R1));
-  __ tst(R2, Operand(kSmiTagMask));
-  __ b(&check_for_mint, NE);  // If R0 or R1 is not a smi do Mint checks.
-
-  // Both arguments are smi, '===' is good enough.
-  __ LoadObject(R0, Bool::False());
-  __ Ret();
-  __ Bind(&true_label);
-  __ LoadObject(R0, Bool::True());
-  __ Ret();
-
-  // At least one of the arguments was not Smi.
-  Label receiver_not_smi;
-  __ Bind(&check_for_mint);
-
-  __ tst(R1, Operand(kSmiTagMask));  // Check receiver.
-  __ b(&receiver_not_smi, NE);
-
-  // Left (receiver) is Smi, return false if right is not Double.
-  // Note that an instance of Mint never contains a value that can be
-  // represented by Smi.
-
-  __ CompareClassId(R0, kDoubleCid, R2);
-  __ b(normal_ir_body, EQ);
-  __ LoadObject(R0, Bool::False());  // Smi == Mint -> false.
-  __ Ret();
-
-  __ Bind(&receiver_not_smi);
-  // R1:: receiver.
-
-  __ CompareClassId(R1, kMintCid, R2);
-  __ b(normal_ir_body, NE);
-  // Receiver is Mint, return false if right is Smi.
-  __ tst(R0, Operand(kSmiTagMask));
-  __ LoadObject(R0, Bool::False(), EQ);
-  __ bx(LR, EQ);
-  // TODO(srdjan): Implement Mint == Mint comparison.
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
-  Integer_equalToInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Shift amount in R0. Value to shift in R1.
-
-  // Fall through if shift amount is negative.
-  __ SmiUntag(R0);
-  __ CompareImmediate(R0, 0);
-  __ b(normal_ir_body, LT);
-
-  // If shift amount is bigger than 31, set to 31.
-  __ CompareImmediate(R0, 0x1F);
-  __ LoadImmediate(R0, 0x1F, GT);
-  __ SmiUntag(R1);
-  __ mov(R0, Operand(R1, ASR, R0));
-  __ SmiTag(R0);
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ mvn(R0, Operand(R0));
-  __ bic(R0, R0, Operand(kSmiTagMask));  // Remove inverted smi-tag.
-  __ Ret();
-}
-
-void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ SmiUntag(R0);
-  // XOR with sign bit to complement bits if value is negative.
-  __ eor(R0, R0, Operand(R0, ASR, 31));
-  __ clz(R0, R0);
-  __ rsb(R0, R0, Operand(32));
-  __ SmiTag(R0);
-  __ Ret();
-}
-
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
-  __ ldrd(R0, R1, SP, 2 * kWordSize);
-  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldrd(R2, R3, SP, 0 * kWordSize);
-  __ SmiUntag(R3);
-  // R4 = n ~/ _DIGIT_BITS
-  __ Asr(R4, R3, Operand(5));
-  // R8 = &x_digits[0]
-  __ add(R8, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // NOTFP = &x_digits[x_used]
-  __ add(NOTFP, R8, Operand(R0, LSL, 1));
-  // R6 = &r_digits[1]
-  __ add(R6, R2,
-         Operand(TypedData::data_offset() - kHeapObjectTag +
-                 kBytesPerBigIntDigit));
-  // R6 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
-  __ add(R4, R4, Operand(R0, ASR, 1));
-  __ add(R6, R6, Operand(R4, LSL, 2));
-  // R1 = n % _DIGIT_BITS
-  __ and_(R1, R3, Operand(31));
-  // R0 = 32 - R1
-  __ rsb(R0, R1, Operand(32));
-  __ mov(R9, Operand(0));
-  Label loop;
-  __ Bind(&loop);
-  __ ldr(R4, Address(NOTFP, -kBytesPerBigIntDigit, Address::PreIndex));
-  __ orr(R9, R9, Operand(R4, LSR, R0));
-  __ str(R9, Address(R6, -kBytesPerBigIntDigit, Address::PreIndex));
-  __ mov(R9, Operand(R4, LSL, R1));
-  __ teq(NOTFP, Operand(R8));
-  __ b(&loop, NE);
-  __ str(R9, Address(R6, -kBytesPerBigIntDigit, Address::PreIndex));
-  __ LoadObject(R0, Object::null_object());
-  __ Ret();
-}
-
-void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  // R0 = x_used, R1 = x_digits, x_used > 0, x_used is Smi.
-  __ ldrd(R0, R1, SP, 2 * kWordSize);
-  // R2 = r_digits, R3 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldrd(R2, R3, SP, 0 * kWordSize);
-  __ SmiUntag(R3);
-  // R4 = n ~/ _DIGIT_BITS
-  __ Asr(R4, R3, Operand(5));
-  // R6 = &r_digits[0]
-  __ add(R6, R2, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // NOTFP = &x_digits[n ~/ _DIGIT_BITS]
-  __ add(NOTFP, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-  __ add(NOTFP, NOTFP, Operand(R4, LSL, 2));
-  // R8 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
-  __ add(R4, R4, Operand(1));
-  __ rsb(R4, R4, Operand(R0, ASR, 1));
-  __ add(R8, R6, Operand(R4, LSL, 2));
-  // R1 = n % _DIGIT_BITS
-  __ and_(R1, R3, Operand(31));
-  // R0 = 32 - R1
-  __ rsb(R0, R1, Operand(32));
-  // R9 = x_digits[n ~/ _DIGIT_BITS] >> (n % _DIGIT_BITS)
-  __ ldr(R9, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
-  __ mov(R9, Operand(R9, LSR, R1));
-  Label loop_entry;
-  __ b(&loop_entry);
-  Label loop;
-  __ Bind(&loop);
-  __ ldr(R4, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
-  __ orr(R9, R9, Operand(R4, LSL, R0));
-  __ str(R9, Address(R6, kBytesPerBigIntDigit, Address::PostIndex));
-  __ mov(R9, Operand(R4, LSR, R1));
-  __ Bind(&loop_entry);
-  __ teq(R6, Operand(R8));
-  __ b(&loop, NE);
-  __ str(R9, Address(R6, 0));
-  __ LoadObject(R0, Object::null_object());
-  __ Ret();
-}
-
-void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absAdd(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  // R0 = used, R1 = digits
-  __ ldrd(R0, R1, SP, 3 * kWordSize);
-  // R1 = &digits[0]
-  __ add(R1, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R2 = a_used, R3 = a_digits
-  __ ldrd(R2, R3, SP, 1 * kWordSize);
-  // R3 = &a_digits[0]
-  __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R8 = r_digits
-  __ ldr(R8, Address(SP, 0 * kWordSize));
-  // R8 = &r_digits[0]
-  __ add(R8, R8, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // NOTFP = &digits[a_used >> 1], a_used is Smi.
-  __ add(NOTFP, R1, Operand(R2, LSL, 1));
-
-  // R6 = &digits[used >> 1], used is Smi.
-  __ add(R6, R1, Operand(R0, LSL, 1));
-
-  __ adds(R4, R4, Operand(0));  // carry flag = 0
-  Label add_loop;
-  __ Bind(&add_loop);
-  // Loop a_used times, a_used > 0.
-  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
-  __ ldr(R9, Address(R3, kBytesPerBigIntDigit, Address::PostIndex));
-  __ adcs(R4, R4, Operand(R9));
-  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
-  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&add_loop, NE);
-
-  Label last_carry;
-  __ teq(R1, Operand(R6));  // Does not affect carry flag.
-  __ b(&last_carry, EQ);    // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop used - a_used times, used - a_used > 0.
-  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
-  __ adcs(R4, R4, Operand(0));
-  __ teq(R1, Operand(R6));  // Does not affect carry flag.
-  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&carry_loop, NE);
-
-  __ Bind(&last_carry);
-  __ mov(R4, Operand(0));
-  __ adc(R4, R4, Operand(0));
-  __ str(R4, Address(R8, 0));
-
-  __ LoadObject(R0, Object::null_object());
-  __ Ret();
-}
-
-void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absSub(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  // R0 = used, R1 = digits
-  __ ldrd(R0, R1, SP, 3 * kWordSize);
-  // R1 = &digits[0]
-  __ add(R1, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R2 = a_used, R3 = a_digits
-  __ ldrd(R2, R3, SP, 1 * kWordSize);
-  // R3 = &a_digits[0]
-  __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R8 = r_digits
-  __ ldr(R8, Address(SP, 0 * kWordSize));
-  // R8 = &r_digits[0]
-  __ add(R8, R8, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // NOTFP = &digits[a_used >> 1], a_used is Smi.
-  __ add(NOTFP, R1, Operand(R2, LSL, 1));
-
-  // R6 = &digits[used >> 1], used is Smi.
-  __ add(R6, R1, Operand(R0, LSL, 1));
-
-  __ subs(R4, R4, Operand(0));  // carry flag = 1
-  Label sub_loop;
-  __ Bind(&sub_loop);
-  // Loop a_used times, a_used > 0.
-  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
-  __ ldr(R9, Address(R3, kBytesPerBigIntDigit, Address::PostIndex));
-  __ sbcs(R4, R4, Operand(R9));
-  __ teq(R1, Operand(NOTFP));  // Does not affect carry flag.
-  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&sub_loop, NE);
-
-  Label done;
-  __ teq(R1, Operand(R6));  // Does not affect carry flag.
-  __ b(&done, EQ);          // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop used - a_used times, used - a_used > 0.
-  __ ldr(R4, Address(R1, kBytesPerBigIntDigit, Address::PostIndex));
-  __ sbcs(R4, R4, Operand(0));
-  __ teq(R1, Operand(R6));  // Does not affect carry flag.
-  __ str(R4, Address(R8, kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&carry_loop, NE);
-
-  __ Bind(&done);
-  __ LoadObject(R0, Object::null_object());
-  __ Ret();
-}
-
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulAdd(Uint32List x_digits, int xi,
-  //                    Uint32List m_digits, int i,
-  //                    Uint32List a_digits, int j, int n) {
-  //   uint32_t x = x_digits[xi >> 1];  // xi is Smi.
-  //   if (x == 0 || n == 0) {
-  //     return 1;
-  //   }
-  //   uint32_t* mip = &m_digits[i >> 1];  // i is Smi.
-  //   uint32_t* ajp = &a_digits[j >> 1];  // j is Smi.
-  //   uint32_t c = 0;
-  //   SmiUntag(n);
-  //   do {
-  //     uint32_t mi = *mip++;
-  //     uint32_t aj = *ajp;
-  //     uint64_t t = x*mi + aj + c;  // 32-bit * 32-bit -> 64-bit.
-  //     *ajp++ = low32(t);
-  //     c = high32(t);
-  //   } while (--n > 0);
-  //   while (c != 0) {
-  //     uint64_t t = *ajp + c;
-  //     *ajp++ = low32(t);
-  //     c = high32(t);  // c == 0 or 1.
-  //   }
-  //   return 1;
-  // }
-
-  Label done;
-  // R3 = x, no_op if x == 0
-  __ ldrd(R0, R1, SP, 5 * kWordSize);  // R0 = xi as Smi, R1 = x_digits.
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
-  __ tst(R3, Operand(R3));
-  __ b(&done, EQ);
-
-  // R8 = SmiUntag(n), no_op if n == 0
-  __ ldr(R8, Address(SP, 0 * kWordSize));
-  __ Asrs(R8, R8, Operand(kSmiTagSize));
-  __ b(&done, EQ);
-
-  // R4 = mip = &m_digits[i >> 1]
-  __ ldrd(R0, R1, SP, 3 * kWordSize);  // R0 = i as Smi, R1 = m_digits.
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R9 = ajp = &a_digits[j >> 1]
-  __ ldrd(R0, R1, SP, 1 * kWordSize);  // R0 = j as Smi, R1 = a_digits.
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ add(R9, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R1 = c = 0
-  __ mov(R1, Operand(0));
-
-  Label muladd_loop;
-  __ Bind(&muladd_loop);
-  // x:   R3
-  // mip: R4
-  // ajp: R9
-  // c:   R1
-  // n:   R8
-
-  // uint32_t mi = *mip++
-  __ ldr(R2, Address(R4, kBytesPerBigIntDigit, Address::PostIndex));
-
-  // uint32_t aj = *ajp
-  __ ldr(R0, Address(R9, 0));
-
-  // uint64_t t = x*mi + aj + c
-  __ umaal(R0, R1, R2, R3);  // R1:R0 = R2*R3 + R1 + R0.
-
-  // *ajp++ = low32(t) = R0
-  __ str(R0, Address(R9, kBytesPerBigIntDigit, Address::PostIndex));
-
-  // c = high32(t) = R1
-
-  // while (--n > 0)
-  __ subs(R8, R8, Operand(1));  // --n
-  __ b(&muladd_loop, NE);
-
-  __ tst(R1, Operand(R1));
-  __ b(&done, EQ);
-
-  // *ajp++ += c
-  __ ldr(R0, Address(R9, 0));
-  __ adds(R0, R0, Operand(R1));
-  __ str(R0, Address(R9, kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&done, CC);
-
-  Label propagate_carry_loop;
-  __ Bind(&propagate_carry_loop);
-  __ ldr(R0, Address(R9, 0));
-  __ adds(R0, R0, Operand(1));
-  __ str(R0, Address(R9, kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&propagate_carry_loop, CS);
-
-  __ Bind(&done);
-  __ mov(R0, Operand(Smi::RawValue(1)));  // One digit processed.
-  __ Ret();
-}
-
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _sqrAdd(Uint32List x_digits, int i,
-  //                    Uint32List a_digits, int used) {
-  //   uint32_t* xip = &x_digits[i >> 1];  // i is Smi.
-  //   uint32_t x = *xip++;
-  //   if (x == 0) return 1;
-  //   uint32_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
-  //   uint32_t aj = *ajp;
-  //   uint64_t t = x*x + aj;
-  //   *ajp++ = low32(t);
-  //   uint64_t c = high32(t);
-  //   int n = ((used - i) >> 1) - 1;  // used and i are Smi.
-  //   while (--n >= 0) {
-  //     uint32_t xi = *xip++;
-  //     uint32_t aj = *ajp;
-  //     uint96_t t = 2*x*xi + aj + c;  // 2-bit * 32-bit * 32-bit -> 65-bit.
-  //     *ajp++ = low32(t);
-  //     c = high64(t);  // 33-bit.
-  //   }
-  //   uint32_t aj = *ajp;
-  //   uint64_t t = aj + c;  // 32-bit + 33-bit -> 34-bit.
-  //   *ajp++ = low32(t);
-  //   *ajp = high32(t);
-  //   return 1;
-  // }
-
-  // R4 = xip = &x_digits[i >> 1]
-  __ ldrd(R2, R3, SP, 2 * kWordSize);  // R2 = i as Smi, R3 = x_digits
-  __ add(R3, R3, Operand(R2, LSL, 1));
-  __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R3 = x = *xip++, return if x == 0
-  Label x_zero;
-  __ ldr(R3, Address(R4, kBytesPerBigIntDigit, Address::PostIndex));
-  __ tst(R3, Operand(R3));
-  __ b(&x_zero, EQ);
-
-  // NOTFP = ajp = &a_digits[i]
-  __ ldr(R1, Address(SP, 1 * kWordSize));  // a_digits
-  __ add(R1, R1, Operand(R2, LSL, 2));     // j == 2*i, i is Smi.
-  __ add(NOTFP, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R8:R0 = t = x*x + *ajp
-  __ ldr(R0, Address(NOTFP, 0));
-  __ mov(R8, Operand(0));
-  __ umaal(R0, R8, R3, R3);  // R8:R0 = R3*R3 + R8 + R0.
-
-  // *ajp++ = low32(t) = R0
-  __ str(R0, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
-
-  // R8 = low32(c) = high32(t)
-  // R9 = high32(c) = 0
-  __ mov(R9, Operand(0));
-
-  // int n = used - i - 1; while (--n >= 0) ...
-  __ ldr(R0, Address(SP, 0 * kWordSize));  // used is Smi
-  __ sub(R6, R0, Operand(R2));
-  __ mov(R0, Operand(2));  // n = used - i - 2; if (n >= 0) ... while (--n >= 0)
-  __ rsbs(R6, R0, Operand(R6, ASR, kSmiTagSize));
-
-  Label loop, done;
-  __ b(&done, MI);
-
-  __ Bind(&loop);
-  // x:   R3
-  // xip: R4
-  // ajp: NOTFP
-  // c:   R9:R8
-  // t:   R2:R1:R0 (not live at loop entry)
-  // n:   R6
-
-  // uint32_t xi = *xip++
-  __ ldr(R2, Address(R4, kBytesPerBigIntDigit, Address::PostIndex));
-
-  // uint96_t t = R9:R8:R0 = 2*x*xi + aj + c
-  __ umull(R0, R1, R2, R3);  // R1:R0 = R2*R3.
-  __ adds(R0, R0, Operand(R0));
-  __ adcs(R1, R1, Operand(R1));
-  __ mov(R2, Operand(0));
-  __ adc(R2, R2, Operand(0));  // R2:R1:R0 = 2*x*xi.
-  __ adds(R0, R0, Operand(R8));
-  __ adcs(R1, R1, Operand(R9));
-  __ adc(R2, R2, Operand(0));     // R2:R1:R0 = 2*x*xi + c.
-  __ ldr(R8, Address(NOTFP, 0));  // R8 = aj = *ajp.
-  __ adds(R0, R0, Operand(R8));
-  __ adcs(R8, R1, Operand(0));
-  __ adc(R9, R2, Operand(0));  // R9:R8:R0 = 2*x*xi + c + aj.
-
-  // *ajp++ = low32(t) = R0
-  __ str(R0, Address(NOTFP, kBytesPerBigIntDigit, Address::PostIndex));
-
-  // while (--n >= 0)
-  __ subs(R6, R6, Operand(1));  // --n
-  __ b(&loop, PL);
-
-  __ Bind(&done);
-  // uint32_t aj = *ajp
-  __ ldr(R0, Address(NOTFP, 0));
-
-  // uint64_t t = aj + c
-  __ adds(R8, R8, Operand(R0));
-  __ adc(R9, R9, Operand(0));
-
-  // *ajp = low32(t) = R8
-  // *(ajp + 1) = high32(t) = R9
-  __ strd(R8, R9, NOTFP, 0);
-
-  __ Bind(&x_zero);
-  __ mov(R0, Operand(Smi::RawValue(1)));  // One digit processed.
-  __ Ret();
-}
-
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  // No unsigned 64-bit / 32-bit divide instruction.
-}
-
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
-  //   uint32_t rho = args[_RHO];  // _RHO == 2.
-  //   uint32_t d = digits[i >> 1];  // i is Smi.
-  //   uint64_t t = rho*d;
-  //   args[_MU] = t mod DIGIT_BASE;  // _MU == 4.
-  //   return 1;
-  // }
-
-  // R4 = args
-  __ ldr(R4, Address(SP, 2 * kWordSize));  // args
-
-  // R3 = rho = args[2]
-  __ ldr(R3,
-         FieldAddress(R4, TypedData::data_offset() + 2 * kBytesPerBigIntDigit));
-
-  // R2 = digits[i >> 1]
-  __ ldrd(R0, R1, SP, 0 * kWordSize);  // R0 = i as Smi, R1 = digits
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ ldr(R2, FieldAddress(R1, TypedData::data_offset()));
-
-  // R1:R0 = t = rho*d
-  __ umull(R0, R1, R2, R3);
-
-  // args[4] = t mod DIGIT_BASE = low32(t)
-  __ str(R0,
-         FieldAddress(R4, TypedData::data_offset() + 4 * kBytesPerBigIntDigit));
-
-  __ mov(R0, Operand(Smi::RawValue(1)));  // One digit processed.
-  __ Ret();
-}
-
-// Check if the last argument is a double, jump to label 'is_smi' if smi
-// (easy to convert to double), otherwise jump to label 'not_double_smi',
-// Returns the last argument in R0.
-static void TestLastArgumentIsDouble(Assembler* assembler,
-                                     Label* is_smi,
-                                     Label* not_double_smi) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ tst(R0, Operand(kSmiTagMask));
-  __ b(is_smi, EQ);
-  __ CompareClassId(R0, kDoubleCid, R1);
-  __ b(not_double_smi, NE);
-  // Fall through with Double in R0.
-}
-
-// Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
-// type. Return true or false object in the register R0. Any NaN argument
-// returns false. Any non-double arg1 causes control flow to fall through to the
-// slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler,
-                           Label* normal_ir_body,
-                           Condition true_condition) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label is_smi, double_op;
-
-    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-    // Both arguments are double, right operand is in R0.
-
-    __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
-    __ Bind(&double_op);
-    __ ldr(R0, Address(SP, 1 * kWordSize));  // Left argument.
-    __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-
-    __ vcmpd(D0, D1);
-    __ vmstat();
-    __ LoadObject(R0, Bool::False());
-    // Return false if D0 or D1 was NaN before checking true condition.
-    __ bx(LR, VS);
-    __ LoadObject(R0, Bool::True(), true_condition);
-    __ Ret();
-
-    __ Bind(&is_smi);  // Convert R0 to a double.
-    __ SmiUntag(R0);
-    __ vmovsr(S0, R0);
-    __ vcvtdi(D1, S0);
-    __ b(&double_op);  // Then do the comparison.
-    __ Bind(normal_ir_body);
-  }
-}
-
-void Intrinsifier::Double_greaterThan(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, HI);
-}
-
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
-                                           Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, CS);
-}
-
-void Intrinsifier::Double_lessThan(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, CC);
-}
-
-void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, EQ);
-}
-
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, LS);
-}
-
-// Expects left argument to be double (receiver). Right argument is unknown.
-// Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler,
-                                       Label* normal_ir_body,
-                                       Token::Kind kind) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label is_smi, double_op;
-
-    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-    // Both arguments are double, right operand is in R0.
-    __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
-    __ Bind(&double_op);
-    __ ldr(R0, Address(SP, 1 * kWordSize));  // Left argument.
-    __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    switch (kind) {
-      case Token::kADD:
-        __ vaddd(D0, D0, D1);
-        break;
-      case Token::kSUB:
-        __ vsubd(D0, D0, D1);
-        break;
-      case Token::kMUL:
-        __ vmuld(D0, D0, D1);
-        break;
-      case Token::kDIV:
-        __ vdivd(D0, D0, D1);
-        break;
-      default:
-        UNREACHABLE();
-    }
-    const Class& double_class =
-        Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, normal_ir_body, R0,
-                   R1);  // Result register.
-    __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ Ret();
-    __ Bind(&is_smi);  // Convert R0 to a double.
-    __ SmiUntag(R0);
-    __ vmovsr(S0, R0);
-    __ vcvtdi(D1, S0);
-    __ b(&double_op);
-    __ Bind(normal_ir_body);
-  }
-}
-
-void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
-}
-
-void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
-}
-
-void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
-}
-
-void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
-}
-
-// Left is double, right is integer (Mint or Smi)
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label fall_through;
-    // Only smis allowed.
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ tst(R0, Operand(kSmiTagMask));
-    __ b(normal_ir_body, NE);
-    // Is Smi.
-    __ SmiUntag(R0);
-    __ vmovsr(S0, R0);
-    __ vcvtdi(D1, S0);
-    __ ldr(R0, Address(SP, 1 * kWordSize));
-    __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ vmuld(D0, D0, D1);
-    const Class& double_class =
-        Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, normal_ir_body, R0,
-                   R1);  // Result register.
-    __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ Ret();
-    __ Bind(normal_ir_body);
-  }
-}
-
-void Intrinsifier::DoubleFromInteger(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label fall_through;
-
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ tst(R0, Operand(kSmiTagMask));
-    __ b(normal_ir_body, NE);
-    // Is Smi.
-    __ SmiUntag(R0);
-    __ vmovsr(S0, R0);
-    __ vcvtdi(D0, S0);
-    const Class& double_class =
-        Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, normal_ir_body, R0,
-                   R1);  // Result register.
-    __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ Ret();
-    __ Bind(normal_ir_body);
-  }
-}
-
-void Intrinsifier::Double_getIsNaN(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ vcmpd(D0, D0);
-    __ vmstat();
-    __ LoadObject(R0, Bool::False(), VC);
-    __ LoadObject(R0, Bool::True(), VS);
-    __ Ret();
-  }
-}
-
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    // R1 <- value[0:31], R2 <- value[32:63]
-    __ LoadFieldFromOffset(kWord, R1, R0, Double::value_offset());
-    __ LoadFieldFromOffset(kWord, R2, R0, Double::value_offset() + kWordSize);
-
-    // If the low word isn't 0, then it isn't infinity.
-    __ cmp(R1, Operand(0));
-    __ LoadObject(R0, Bool::False(), NE);
-    __ bx(LR, NE);  // Return if NE.
-
-    // Mask off the sign bit.
-    __ AndImmediate(R2, R2, 0x7FFFFFFF);
-    // Compare with +infinity.
-    __ CompareImmediate(R2, 0x7FF00000);
-    __ LoadObject(R0, Bool::False(), NE);
-    __ bx(LR, NE);
-
-    __ LoadObject(R0, Bool::True());
-    __ Ret();
-  }
-}
-
-void Intrinsifier::Double_getIsNegative(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label is_false, is_true, is_zero;
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ vcmpdz(D0);
-    __ vmstat();
-    __ b(&is_false, VS);  // NaN -> false.
-    __ b(&is_zero, EQ);   // Check for negative zero.
-    __ b(&is_false, CS);  // >= 0 -> false.
-
-    __ Bind(&is_true);
-    __ LoadObject(R0, Bool::True());
-    __ Ret();
-
-    __ Bind(&is_false);
-    __ LoadObject(R0, Bool::False());
-    __ Ret();
-
-    __ Bind(&is_zero);
-    // Check for negative zero by looking at the sign bit.
-    __ vmovrrd(R0, R1, D0);  // R1:R0 <- D0, so sign bit is in bit 31 of R1.
-    __ mov(R1, Operand(R1, LSR, 31));
-    __ tst(R1, Operand(1));
-    __ b(&is_true, NE);  // Sign bit set.
-    __ b(&is_false);
-  }
-}
-
-void Intrinsifier::DoubleToInteger(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label fall_through;
-
-    __ ldr(R0, Address(SP, 0 * kWordSize));
-    __ LoadDFromOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-
-    // Explicit NaN check, since ARM gives an FPU exception if you try to
-    // convert NaN to an int.
-    __ vcmpd(D0, D0);
-    __ vmstat();
-    __ b(normal_ir_body, VS);
-
-    __ vcvtid(S0, D0);
-    __ vmovrs(R0, S0);
-    // Overflow is signaled with minint.
-    // Check for overflow and that it fits into Smi.
-    __ CompareImmediate(R0, 0xC0000000);
-    __ SmiTag(R0, PL);
-    __ bx(LR, PL);
-    __ Bind(normal_ir_body);
-  }
-}
-
-void Intrinsifier::Double_hashCode(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
-
-  if (!TargetCPUFeatures::vfp_supported()) return;
-
-  // Load double value and check that it isn't NaN, since ARM gives an
-  // FPU exception if you try to convert NaN to an int.
-  Label double_hash;
-  __ ldr(R1, Address(SP, 0 * kWordSize));
-  __ LoadDFromOffset(D0, R1, Double::value_offset() - kHeapObjectTag);
-  __ vcmpd(D0, D0);
-  __ vmstat();
-  __ b(&double_hash, VS);
-
-  // Convert double value to signed 32-bit int in R0.
-  __ vcvtid(S2, D0);
-  __ vmovrs(R0, S2);
-
-  // Tag the int as a Smi, making sure that it fits; this checks for
-  // overflow in the conversion from double to int. Conversion
-  // overflow is signalled by vcvt through clamping R0 to either
-  // INT32_MAX or INT32_MIN (saturation).
-  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-  __ adds(R0, R0, Operand(R0));
-  __ b(normal_ir_body, VS);
-
-  // Compare the two double values. If they are equal, we return the
-  // Smi tagged result immediately as the hash code.
-  __ vcvtdi(D1, S2);
-  __ vcmpd(D0, D1);
-  __ vmstat();
-  __ bx(LR, EQ);
-
-  // Convert the double bits to a hash code that fits in a Smi.
-  __ Bind(&double_hash);
-  __ ldr(R0, FieldAddress(R1, Double::value_offset()));
-  __ ldr(R1, FieldAddress(R1, Double::value_offset() + 4));
-  __ eor(R0, R0, Operand(R1));
-  __ AndImmediate(R0, R0, kSmiMax);
-  __ SmiTag(R0);
-  __ Ret();
-
-  // Fall into the native C++ implementation.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
-  if (TargetCPUFeatures::vfp_supported()) {
-    Label is_smi, double_op;
-    TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-    // Argument is double and is in R0.
-    __ LoadDFromOffset(D1, R0, Double::value_offset() - kHeapObjectTag);
-    __ Bind(&double_op);
-    __ vsqrtd(D0, D1);
-    const Class& double_class =
-        Class::Handle(Isolate::Current()->object_store()->double_class());
-    __ TryAllocate(double_class, normal_ir_body, R0,
-                   R1);  // Result register.
-    __ StoreDToOffset(D0, R0, Double::value_offset() - kHeapObjectTag);
-    __ Ret();
-    __ Bind(&is_smi);
-    __ SmiUntag(R0);
-    __ vmovsr(S0, R0);
-    __ vcvtdi(D1, S0);
-    __ b(&double_op);
-    __ Bind(normal_ir_body);
-  }
-}
-
-//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-//    _state[kSTATE_LO] = state & _MASK_32;
-//    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  const Library& math_lib = Library::Handle(Library::MathLibrary());
-  ASSERT(!math_lib.IsNull());
-  const Class& random_class =
-      Class::Handle(math_lib.LookupClassAllowPrivate(Symbols::_Random()));
-  ASSERT(!random_class.IsNull());
-  const Field& state_field = Field::ZoneHandle(
-      random_class.LookupInstanceFieldAllowPrivate(Symbols::_state()));
-  ASSERT(!state_field.IsNull());
-  const int64_t a_int_value = Intrinsifier::kRandomAValue;
-  // 'a_int_value' is a mask.
-  ASSERT(Utils::IsUint(32, a_int_value));
-  int32_t a_int32_value = static_cast<int32_t>(a_int_value);
-
-  // Receiver.
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  // Field '_state'.
-  __ ldr(R1, FieldAddress(R0, state_field.Offset()));
-  // Addresses of _state[0] and _state[1].
-
-  const int64_t disp_0 = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
-  const int64_t disp_1 =
-      disp_0 + Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
-
-  __ LoadImmediate(R0, a_int32_value);
-  __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
-  __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
-  __ mov(R8, Operand(0));  // Zero extend unsigned _state[kSTATE_HI].
-  // Unsigned 32-bit multiply and 64-bit accumulate into R8:R3.
-  __ umlal(R3, R8, R0, R2);  // R8:R3 <- R8:R3 + R0 * R2.
-  __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
-  __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
-  ASSERT(Smi::RawValue(0) == 0);
-  __ eor(R0, R0, Operand(R0));
-  __ Ret();
-}
-
-void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R1, Address(SP, 1 * kWordSize));
-  __ cmp(R0, Operand(R1));
-  __ LoadObject(R0, Bool::False(), NE);
-  __ LoadObject(R0, Bool::True(), EQ);
-  __ Ret();
-}
-
-static void RangeCheck(Assembler* assembler,
-                       Register val,
-                       Register tmp,
-                       intptr_t low,
-                       intptr_t high,
-                       Condition cc,
-                       Label* target) {
-  __ AddImmediate(tmp, val, -low);
-  __ CompareImmediate(tmp, high - low);
-  __ b(target, cc);
-}
-
-const Condition kIfNotInRange = HI;
-const Condition kIfInRange = LS;
-
-static void JumpIfInteger(Assembler* assembler,
-                          Register cid,
-                          Register tmp,
-                          Label* target) {
-  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfInRange, target);
-}
-
-static void JumpIfNotInteger(Assembler* assembler,
-                             Register cid,
-                             Register tmp,
-                             Label* target) {
-  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfNotInRange, target);
-}
-
-static void JumpIfString(Assembler* assembler,
-                         Register cid,
-                         Register tmp,
-                         Label* target) {
-  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfInRange, target);
-}
-
-static void JumpIfNotString(Assembler* assembler,
-                            Register cid,
-                            Register tmp,
-                            Label* target) {
-  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfNotInRange, target);
-}
-
-// Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Label use_declaration_type, not_double, not_integer;
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadClassIdMayBeSmi(R1, R0);
-
-  __ CompareImmediate(R1, kClosureCid);
-  __ b(normal_ir_body, EQ);  // Instance is a closure.
-
-  __ CompareImmediate(R1, kNumPredefinedCids);
-  __ b(&use_declaration_type, HI);
-
-  __ CompareImmediate(R1, kDoubleCid);
-  __ b(&not_double, NE);
-
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0, Isolate::object_store_offset());
-  __ LoadFromOffset(kWord, R0, R0, ObjectStore::double_type_offset());
-  __ Ret();
-
-  __ Bind(&not_double);
-  JumpIfNotInteger(assembler, R1, R0, &not_integer);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0, Isolate::object_store_offset());
-  __ LoadFromOffset(kWord, R0, R0, ObjectStore::int_type_offset());
-  __ Ret();
-
-  __ Bind(&not_integer);
-  JumpIfNotString(assembler, R1, R0, &use_declaration_type);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(kWord, R0, R0, Isolate::object_store_offset());
-  __ LoadFromOffset(kWord, R0, R0, ObjectStore::string_type_offset());
-  __ Ret();
-
-  __ Bind(&use_declaration_type);
-  __ LoadClassById(R2, R1);  // Overwrites R1.
-  __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset()));
-  __ CompareImmediate(R3, 0);
-  __ b(normal_ir_body, NE);
-
-  __ ldr(R0, FieldAddress(R2, Class::declaration_type_offset()));
-  __ CompareObject(R0, Object::null_object());
-  __ b(normal_ir_body, EQ);
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label different_cids, equal, not_equal, not_integer;
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadClassIdMayBeSmi(R1, R0);
-
-  // Check if left hand size is a closure. Closures are handled in the runtime.
-  __ CompareImmediate(R1, kClosureCid);
-  __ b(normal_ir_body, EQ);
-
-  __ ldr(R0, Address(SP, 1 * kWordSize));
-  __ LoadClassIdMayBeSmi(R2, R0);
-
-  // Check whether class ids match. If class ids don't match objects can still
-  // have the same runtime type (e.g. multiple string implementation classes
-  // map to a single String type).
-  __ cmp(R1, Operand(R2));
-  __ b(&different_cids, NE);
-
-  // Objects have the same class and neither is a closure.
-  // Check if there are no type arguments. In this case we can return true.
-  // Otherwise fall through into the runtime to handle comparison.
-  __ LoadClassById(R3, R1);
-  __ ldrh(R3, FieldAddress(R3, Class::num_type_arguments_offset()));
-  __ CompareImmediate(R3, 0);
-  __ b(normal_ir_body, NE);
-
-  __ Bind(&equal);
-  __ LoadObject(R0, Bool::True());
-  __ Ret();
-
-  // Class ids are different. Check if we are comparing runtime types of
-  // two strings (with different representations) or two integers.
-  __ Bind(&different_cids);
-  __ CompareImmediate(R1, kNumPredefinedCids);
-  __ b(&not_equal, HI);
-
-  // Check if both are integers.
-  JumpIfNotInteger(assembler, R1, R0, &not_integer);
-  JumpIfInteger(assembler, R2, R0, &equal);
-  __ b(&not_equal);
-
-  __ Bind(&not_integer);
-  // Check if both are strings.
-  JumpIfNotString(assembler, R1, R0, &not_equal);
-  JumpIfString(assembler, R2, R0, &equal);
-
-  // Neither strings nor integers and have different class ids.
-  __ Bind(&not_equal);
-  __ LoadObject(R0, Bool::False());
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::String_getHashCode(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, String::hash_offset()));
-  __ cmp(R0, Operand(0));
-  __ bx(LR, NE);
-  // Hash not yet computed.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Type_getHashCode(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, Type::hash_offset()));
-  __ cmp(R0, Operand(0));
-  __ bx(LR, NE);
-  // Hash not yet computed.
-  __ Bind(normal_ir_body);
-}
-
-void GenerateSubstringMatchesSpecialization(Assembler* assembler,
-                                            intptr_t receiver_cid,
-                                            intptr_t other_cid,
-                                            Label* return_true,
-                                            Label* return_false) {
-  __ SmiUntag(R1);
-  __ ldr(R8, FieldAddress(R0, String::length_offset()));  // this.length
-  __ SmiUntag(R8);
-  __ ldr(R9, FieldAddress(R2, String::length_offset()));  // other.length
-  __ SmiUntag(R9);
-
-  // if (other.length == 0) return true;
-  __ cmp(R9, Operand(0));
-  __ b(return_true, EQ);
-
-  // if (start < 0) return false;
-  __ cmp(R1, Operand(0));
-  __ b(return_false, LT);
-
-  // if (start + other.length > this.length) return false;
-  __ add(R3, R1, Operand(R9));
-  __ cmp(R3, Operand(R8));
-  __ b(return_false, GT);
-
-  if (receiver_cid == kOneByteStringCid) {
-    __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
-    __ add(R0, R0, Operand(R1));
-  } else {
-    ASSERT(receiver_cid == kTwoByteStringCid);
-    __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
-    __ add(R0, R0, Operand(R1));
-    __ add(R0, R0, Operand(R1));
-  }
-  if (other_cid == kOneByteStringCid) {
-    __ AddImmediate(R2, OneByteString::data_offset() - kHeapObjectTag);
-  } else {
-    ASSERT(other_cid == kTwoByteStringCid);
-    __ AddImmediate(R2, TwoByteString::data_offset() - kHeapObjectTag);
-  }
-
-  // i = 0
-  __ LoadImmediate(R3, 0);
-
-  // do
-  Label loop;
-  __ Bind(&loop);
-
-  if (receiver_cid == kOneByteStringCid) {
-    __ ldrb(R4, Address(R0, 0));  // this.codeUnitAt(i + start)
-  } else {
-    __ ldrh(R4, Address(R0, 0));  // this.codeUnitAt(i + start)
-  }
-  if (other_cid == kOneByteStringCid) {
-    __ ldrb(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
-  } else {
-    __ ldrh(NOTFP, Address(R2, 0));  // other.codeUnitAt(i)
-  }
-  __ cmp(R4, Operand(NOTFP));
-  __ b(return_false, NE);
-
-  // i++, while (i < len)
-  __ AddImmediate(R3, 1);
-  __ AddImmediate(R0, receiver_cid == kOneByteStringCid ? 1 : 2);
-  __ AddImmediate(R2, other_cid == kOneByteStringCid ? 1 : 2);
-  __ cmp(R3, Operand(R9));
-  __ b(&loop, LT);
-
-  __ b(return_true);
-}
-
-// bool _substringMatches(int start, String other)
-// This intrinsic handles a OneByteString or TwoByteString receiver with a
-// OneByteString other.
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  Label return_true, return_false, try_two_byte;
-  __ ldr(R0, Address(SP, 2 * kWordSize));  // this
-  __ ldr(R1, Address(SP, 1 * kWordSize));  // start
-  __ ldr(R2, Address(SP, 0 * kWordSize));  // other
-  __ Push(R4);                             // Make ARGS_DESC_REG available.
-
-  __ tst(R1, Operand(kSmiTagMask));
-  __ b(normal_ir_body, NE);  // 'start' is not a Smi.
-
-  __ CompareClassId(R2, kOneByteStringCid, R3);
-  __ b(normal_ir_body, NE);
-
-  __ CompareClassId(R0, kOneByteStringCid, R3);
-  __ b(&try_two_byte, NE);
-
-  GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
-                                         kOneByteStringCid, &return_true,
-                                         &return_false);
-
-  __ Bind(&try_two_byte);
-  __ CompareClassId(R0, kTwoByteStringCid, R3);
-  __ b(normal_ir_body, NE);
-
-  GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
-                                         kOneByteStringCid, &return_true,
-                                         &return_false);
-
-  __ Bind(&return_true);
-  __ Pop(R4);
-  __ LoadObject(R0, Bool::True());
-  __ Ret();
-
-  __ Bind(&return_false);
-  __ Pop(R4);
-  __ LoadObject(R0, Bool::False());
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-  __ Pop(R4);
-}
-
-void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
-  UNREACHABLE();
-}
-
-void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
-  UNREACHABLE();
-}
-
-void Intrinsifier::StringBaseCharAt(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Label try_two_byte_string;
-
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // String.
-  __ tst(R1, Operand(kSmiTagMask));
-  __ b(normal_ir_body, NE);  // Index is not a Smi.
-  // Range check.
-  __ ldr(R2, FieldAddress(R0, String::length_offset()));
-  __ cmp(R1, Operand(R2));
-  __ b(normal_ir_body, CS);  // Runtime throws exception.
-
-  __ CompareClassId(R0, kOneByteStringCid, R3);
-  __ b(&try_two_byte_string, NE);
-  __ SmiUntag(R1);
-  __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
-  __ ldrb(R1, Address(R0, R1));
-  __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(normal_ir_body, GE);
-  __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
-  __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
-  __ ldr(R0, Address(R0, R1, LSL, 2));
-  __ Ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(R0, kTwoByteStringCid, R3);
-  __ b(normal_ir_body, NE);
-  ASSERT(kSmiTagShift == 1);
-  __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
-  __ ldrh(R1, Address(R0, R1));
-  __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(normal_ir_body, GE);
-  __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
-  __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
-  __ ldr(R0, Address(R0, R1, LSL, 2));
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, String::length_offset()));
-  __ cmp(R0, Operand(Smi::RawValue(0)));
-  __ LoadObject(R0, Bool::True(), EQ);
-  __ LoadObject(R0, Bool::False(), NE);
-  __ Ret();
-}
-
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  __ ldr(R1, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R1, String::hash_offset()));
-  __ cmp(R0, Operand(0));
-  __ bx(LR, NE);  // Return if already computed.
-
-  __ ldr(R2, FieldAddress(R1, String::length_offset()));
-
-  Label done;
-  // If the string is empty, set the hash to 1, and return.
-  __ cmp(R2, Operand(Smi::RawValue(0)));
-  __ b(&done, EQ);
-
-  __ SmiUntag(R2);
-  __ mov(R3, Operand(0));
-  __ AddImmediate(R8, R1, OneByteString::data_offset() - kHeapObjectTag);
-  // R1: Instance of OneByteString.
-  // R2: String length, untagged integer.
-  // R3: Loop counter, untagged integer.
-  // R8: String data.
-  // R0: Hash code, untagged integer.
-
-  Label loop;
-  // Add to hash code: (hash_ is uint32)
-  // hash_ += ch;
-  // hash_ += hash_ << 10;
-  // hash_ ^= hash_ >> 6;
-  // Get one characters (ch).
-  __ Bind(&loop);
-  __ ldrb(NOTFP, Address(R8, 0));
-  // NOTFP: ch.
-  __ add(R3, R3, Operand(1));
-  __ add(R8, R8, Operand(1));
-  __ add(R0, R0, Operand(NOTFP));
-  __ add(R0, R0, Operand(R0, LSL, 10));
-  __ eor(R0, R0, Operand(R0, LSR, 6));
-  __ cmp(R3, Operand(R2));
-  __ b(&loop, NE);
-
-  // Finalize.
-  // hash_ += hash_ << 3;
-  // hash_ ^= hash_ >> 11;
-  // hash_ += hash_ << 15;
-  __ add(R0, R0, Operand(R0, LSL, 3));
-  __ eor(R0, R0, Operand(R0, LSR, 11));
-  __ add(R0, R0, Operand(R0, LSL, 15));
-  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
-  __ LoadImmediate(R2, (static_cast<intptr_t>(1) << String::kHashBits) - 1);
-  __ and_(R0, R0, Operand(R2));
-  __ cmp(R0, Operand(0));
-  // return hash_ == 0 ? 1 : hash_;
-  __ Bind(&done);
-  __ mov(R0, Operand(1), EQ);
-  __ SmiTag(R0);
-  __ StoreIntoSmiField(FieldAddress(R1, String::hash_offset()), R0);
-  __ Ret();
-}
-
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized.
-// 'length-reg' (R2) contains tagged length.
-// Returns new string as tagged pointer in R0.
-static void TryAllocateOnebyteString(Assembler* assembler,
-                                     Label* ok,
-                                     Label* failure) {
-  const Register length_reg = R2;
-  Label fail;
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R0, kOneByteStringCid));
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R0, failure));
-  __ mov(R8, Operand(length_reg));  // Save the length register.
-  // TODO(koda): Protect against negative length and overflow here.
-  __ SmiUntag(length_reg);
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawString) + kObjectAlignment - 1;
-  __ AddImmediate(length_reg, fixed_size_plus_alignment_padding);
-  __ bic(length_reg, length_reg, Operand(kObjectAlignment - 1));
-
-  const intptr_t cid = kOneByteStringCid;
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  __ ldr(R0, Address(THR, Thread::top_offset()));
-
-  // length_reg: allocation size.
-  __ adds(R1, R0, Operand(length_reg));
-  __ b(&fail, CS);  // Fail on unsigned overflow.
-
-  // Check if the allocation fits into the remaining space.
-  // R0: potential new object start.
-  // R1: potential next object start.
-  // R2: allocation size.
-  __ ldr(NOTFP, Address(THR, Thread::end_offset()));
-  __ cmp(R1, Operand(NOTFP));
-  __ b(&fail, CS);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
-  __ str(R1, Address(THR, Thread::top_offset()));
-  __ AddImmediate(R0, kHeapObjectTag);
-
-  // Initialize the tags.
-  // R0: new object start as a tagged pointer.
-  // R1: new object end address.
-  // R2: allocation size.
-  // R4: allocation stats address.
-  {
-    const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
-
-    __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
-    __ mov(R3, Operand(R2, LSL, shift), LS);
-    __ mov(R3, Operand(0), HI);
-
-    // Get the class index and insert it into the tags.
-    // R3: size and bit tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(TMP, tags);
-    __ orr(R3, R3, Operand(TMP));
-    __ str(R3, FieldAddress(R0, String::tags_offset()));  // Store tags.
-  }
-
-  // Set the length field using the saved length (R8).
-  __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, String::length_offset()),
-                              R8);
-  // Clear hash.
-  __ LoadImmediate(TMP, 0);
-  __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, String::hash_offset()), TMP);
-
-  NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2, space));
-  __ b(ok);
-
-  __ Bind(&fail);
-  __ b(failure);
-}
-
-// Arg0: OneByteString (receiver).
-// Arg1: Start index as Smi.
-// Arg2: End index as Smi.
-// The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
-                                                    Label* normal_ir_body) {
-  const intptr_t kStringOffset = 2 * kWordSize;
-  const intptr_t kStartIndexOffset = 1 * kWordSize;
-  const intptr_t kEndIndexOffset = 0 * kWordSize;
-  Label ok;
-
-  __ ldr(R2, Address(SP, kEndIndexOffset));
-  __ ldr(TMP, Address(SP, kStartIndexOffset));
-  __ orr(R3, R2, Operand(TMP));
-  __ tst(R3, Operand(kSmiTagMask));
-  __ b(normal_ir_body, NE);  // 'start', 'end' not Smi.
-
-  __ sub(R2, R2, Operand(TMP));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
-  __ Bind(&ok);
-  // R0: new string as tagged pointer.
-  // Copy string.
-  __ ldr(R3, Address(SP, kStringOffset));
-  __ ldr(R1, Address(SP, kStartIndexOffset));
-  __ SmiUntag(R1);
-  __ add(R3, R3, Operand(R1));
-  // Calculate start address and untag (- 1).
-  __ AddImmediate(R3, OneByteString::data_offset() - 1);
-
-  // R3: Start address to copy from (untagged).
-  // R1: Untagged start index.
-  __ ldr(R2, Address(SP, kEndIndexOffset));
-  __ SmiUntag(R2);
-  __ sub(R2, R2, Operand(R1));
-
-  // R3: Start address to copy from (untagged).
-  // R2: Untagged number of bytes to copy.
-  // R0: Tagged result string.
-  // R8: Pointer into R3.
-  // NOTFP: Pointer into R0.
-  // R1: Scratch register.
-  Label loop, done;
-  __ cmp(R2, Operand(0));
-  __ b(&done, LE);
-  __ mov(R8, Operand(R3));
-  __ mov(NOTFP, Operand(R0));
-  __ Bind(&loop);
-  __ ldrb(R1, Address(R8, 0));
-  __ AddImmediate(R8, 1);
-  __ sub(R2, R2, Operand(1));
-  __ cmp(R2, Operand(0));
-  __ strb(R1, FieldAddress(NOTFP, OneByteString::data_offset()));
-  __ AddImmediate(NOTFP, 1);
-  __ b(&loop, GT);
-
-  __ Bind(&done);
-  __ Ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ ldr(R2, Address(SP, 0 * kWordSize));  // Value.
-  __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
-  __ ldr(R0, Address(SP, 2 * kWordSize));  // OneByteString.
-  __ SmiUntag(R1);
-  __ SmiUntag(R2);
-  __ AddImmediate(R3, R0, OneByteString::data_offset() - kHeapObjectTag);
-  __ strb(R2, Address(R3, R1));
-  __ Ret();
-}
-
-void Intrinsifier::OneByteString_allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ ldr(R2, Address(SP, 0 * kWordSize));  // Length.
-  Label ok;
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
-
-  __ Bind(&ok);
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler,
-                           Label* normal_ir_body,
-                           intptr_t string_cid) {
-  Label is_true, is_false, loop;
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // This.
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Other.
-
-  // Are identical?
-  __ cmp(R0, Operand(R1));
-  __ b(&is_true, EQ);
-
-  // Is other OneByteString?
-  __ tst(R1, Operand(kSmiTagMask));
-  __ b(normal_ir_body, EQ);
-  __ CompareClassId(R1, string_cid, R2);
-  __ b(normal_ir_body, NE);
-
-  // Have same length?
-  __ ldr(R2, FieldAddress(R0, String::length_offset()));
-  __ ldr(R3, FieldAddress(R1, String::length_offset()));
-  __ cmp(R2, Operand(R3));
-  __ b(&is_false, NE);
-
-  // Check contents, no fall-through possible.
-  // TODO(zra): try out other sequences.
-  ASSERT((string_cid == kOneByteStringCid) ||
-         (string_cid == kTwoByteStringCid));
-  const intptr_t offset = (string_cid == kOneByteStringCid)
-                              ? OneByteString::data_offset()
-                              : TwoByteString::data_offset();
-  __ AddImmediate(R0, offset - kHeapObjectTag);
-  __ AddImmediate(R1, offset - kHeapObjectTag);
-  __ SmiUntag(R2);
-  __ Bind(&loop);
-  __ AddImmediate(R2, -1);
-  __ cmp(R2, Operand(0));
-  __ b(&is_true, LT);
-  if (string_cid == kOneByteStringCid) {
-    __ ldrb(R3, Address(R0));
-    __ ldrb(R4, Address(R1));
-    __ AddImmediate(R0, 1);
-    __ AddImmediate(R1, 1);
-  } else if (string_cid == kTwoByteStringCid) {
-    __ ldrh(R3, Address(R0));
-    __ ldrh(R4, Address(R1));
-    __ AddImmediate(R0, 2);
-    __ AddImmediate(R1, 2);
-  } else {
-    UNIMPLEMENTED();
-  }
-  __ cmp(R3, Operand(R4));
-  __ b(&is_false, NE);
-  __ b(&loop);
-
-  __ Bind(&is_true);
-  __ LoadObject(R0, Bool::True());
-  __ Ret();
-
-  __ Bind(&is_false);
-  __ LoadObject(R0, Bool::False());
-  __ Ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
-}
-
-void Intrinsifier::TwoByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
-}
-
-void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
-                                                Label* normal_ir_body,
-                                                bool sticky) {
-  if (FLAG_interpret_irregexp) return;
-
-  static const intptr_t kRegExpParamOffset = 2 * kWordSize;
-  static const intptr_t kStringParamOffset = 1 * kWordSize;
-  // start_index smi is located at offset 0.
-
-  // Incoming registers:
-  // R0: Function. (Will be reloaded with the specialized matcher function.)
-  // R4: Arguments descriptor. (Will be preserved.)
-  // R9: Unknown. (Must be GC safe on tail call.)
-
-  // Load the specialized function pointer into R0. Leverage the fact the
-  // string CIDs as well as stored function pointers are in sequence.
-  __ ldr(R2, Address(SP, kRegExpParamOffset));
-  __ ldr(R1, Address(SP, kStringParamOffset));
-  __ LoadClassId(R1, R1);
-  __ AddImmediate(R1, -kOneByteStringCid);
-  __ add(R1, R2, Operand(R1, LSL, kWordSizeLog2));
-  __ ldr(R0,
-         FieldAddress(R1, RegExp::function_offset(kOneByteStringCid, sticky)));
-
-  // Registers are now set up for the lazy compile stub. It expects the function
-  // in R0, the argument descriptor in R4, and IC-Data in R9.
-  __ eor(R9, R9, Operand(R9));
-
-  // Tail-call the function.
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-}
-
-// On stack: user tag (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  // R1: Isolate.
-  __ LoadIsolate(R1);
-  // R0: Current user tag.
-  __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
-  // R2: UserTag.
-  __ ldr(R2, Address(SP, +0 * kWordSize));
-  // Set Isolate::current_tag_.
-  __ str(R2, Address(R1, Isolate::current_tag_offset()));
-  // R2: UserTag's tag.
-  __ ldr(R2, FieldAddress(R2, UserTag::tag_offset()));
-  // Set Isolate::user_tag_.
-  __ str(R2, Address(R1, Isolate::user_tag_offset()));
-  __ Ret();
-}
-
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ LoadIsolate(R0);
-  __ ldr(R0, Address(R0, Isolate::default_tag_offset()));
-  __ Ret();
-}
-
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ LoadIsolate(R0);
-  __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
-  __ Ret();
-}
-
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  if (!FLAG_support_timeline) {
-    __ LoadObject(R0, Bool::False());
-    __ Ret();
-  }
-  // Load TimelineStream*.
-  __ ldr(R0, Address(THR, Thread::dart_stream_offset()));
-  // Load uintptr_t from TimelineStream*.
-  __ ldr(R0, Address(R0, TimelineStream::enabled_offset()));
-  __ cmp(R0, Operand(0));
-  __ LoadObject(R0, Bool::True(), NE);
-  __ LoadObject(R0, Bool::False(), EQ);
-  __ Ret();
-}
-
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  __ LoadObject(R0, Object::null_object());
-  __ str(R0, Address(THR, Thread::async_stack_trace_offset()));
-  __ Ret();
-}
-
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  __ ldr(R0, Address(THR, Thread::async_stack_trace_offset()));
-  __ LoadObject(R0, Object::null_object());
-  __ Ret();
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/intrinsifier_arm64.cc b/runtime/vm/compiler/intrinsifier_arm64.cc
deleted file mode 100644
index 2abf1ed..0000000
--- a/runtime/vm/compiler/intrinsifier_arm64.cc
+++ /dev/null
@@ -1,2322 +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.
-
-#include "vm/globals.h"  // Needed here to get TARGET_ARCH_ARM64.
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/intrinsifier.h"
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/dart_entry.h"
-#include "vm/object.h"
-#include "vm/object_store.h"
-#include "vm/regexp_assembler.h"
-#include "vm/symbols.h"
-#include "vm/timeline.h"
-
-namespace dart {
-
-// When entering intrinsics code:
-// R4: Arguments descriptor
-// LR: Return address
-// The R4 register can be destroyed only if there is no slow-path, i.e.
-// if the intrinsified method always executes a return.
-// The FP register should not be modified, because it is used by the profiler.
-// The PP and THR registers (see constants_arm64.h) must be preserved.
-
-#define __ assembler->
-
-intptr_t Intrinsifier::ParameterSlotFromSp() {
-  return -1;
-}
-
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
-}
-
-void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
-  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
-  ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
-
-  assembler->Comment("IntrinsicCallPrologue");
-  assembler->mov(CALLEE_SAVED_TEMP, LR);
-  assembler->mov(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
-}
-
-void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
-  assembler->Comment("IntrinsicCallEpilogue");
-  assembler->mov(LR, CALLEE_SAVED_TEMP);
-  assembler->mov(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
-}
-
-// Allocate a GrowableObjectArray using the backing array specified.
-// On stack: type argument (+1), data (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  // The newly allocated object is returned in R0.
-  const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
-  const intptr_t kArrayOffset = 0 * kWordSize;
-
-  // Try allocating in new space.
-  const Class& cls = Class::Handle(
-      Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, normal_ir_body, R0, R1);
-
-  // Store backing array object in growable array object.
-  __ ldr(R1, Address(SP, kArrayOffset));  // Data argument.
-  // R0 is new, no barrier needed.
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, GrowableObjectArray::data_offset()), R1);
-
-  // R0: new growable array object start as a tagged pointer.
-  // Store the type argument field in the growable array object.
-  __ ldr(R1, Address(SP, kTypeArgumentsOffset));  // Type argument.
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, GrowableObjectArray::type_arguments_offset()), R1);
-
-  // Set the length field in the growable array object to 0.
-  __ LoadImmediate(R1, 0);
-  __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()));
-  __ ret();  // Returns the newly allocated object in R0.
-
-  __ Bind(normal_ir_body);
-}
-
-static int GetScaleFactor(intptr_t size) {
-  switch (size) {
-    case 1:
-      return 0;
-    case 2:
-      return 1;
-    case 4:
-      return 2;
-    case 8:
-      return 3;
-    case 16:
-      return 4;
-  }
-  UNREACHABLE();
-  return -1;
-}
-
-#define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift)           \
-  Label fall_through;                                                          \
-  const intptr_t kArrayLengthStackOffset = 0 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, R2, normal_ir_body));            \
-  __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
-  /* Check that length is a positive Smi. */                                   \
-  /* R2: requested array length argument. */                                   \
-  __ BranchIfNotSmi(R2, normal_ir_body);                                       \
-  __ CompareRegisters(R2, ZR);                                                 \
-  __ b(normal_ir_body, LT);                                                    \
-  __ SmiUntag(R2);                                                             \
-  /* Check for maximum allowed length. */                                      \
-  /* R2: untagged array length. */                                             \
-  __ CompareImmediate(R2, max_len);                                            \
-  __ b(normal_ir_body, GT);                                                    \
-  __ LslImmediate(R2, R2, scale_shift);                                        \
-  const intptr_t fixed_size_plus_alignment_padding =                           \
-      sizeof(Raw##type_name) + kObjectAlignment - 1;                           \
-  __ AddImmediate(R2, fixed_size_plus_alignment_padding);                      \
-  __ andi(R2, R2, Immediate(~(kObjectAlignment - 1)));                         \
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);                              \
-  __ ldr(R0, Address(THR, Thread::top_offset()));                              \
-                                                                               \
-  /* R2: allocation size. */                                                   \
-  __ adds(R1, R0, Operand(R2));                                                \
-  __ b(normal_ir_body, CS); /* Fail on unsigned overflow. */                   \
-                                                                               \
-  /* Check if the allocation fits into the remaining space. */                 \
-  /* R0: potential new object start. */                                        \
-  /* R1: potential next object start. */                                       \
-  /* R2: allocation size. */                                                   \
-  __ ldr(R6, Address(THR, Thread::end_offset()));                              \
-  __ cmp(R1, Operand(R6));                                                     \
-  __ b(normal_ir_body, CS);                                                    \
-                                                                               \
-  /* Successfully allocated the object(s), now update top to point to */       \
-  /* next object start and initialize the object. */                           \
-  __ str(R1, Address(THR, Thread::top_offset()));                              \
-  __ AddImmediate(R0, kHeapObjectTag);                                         \
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space));            \
-  /* Initialize the tags. */                                                   \
-  /* R0: new object start as a tagged pointer. */                              \
-  /* R1: new object end address. */                                            \
-  /* R2: allocation size. */                                                   \
-  {                                                                            \
-    __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);                  \
-    __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2);    \
-    __ csel(R2, ZR, R2, HI);                                                   \
-                                                                               \
-    /* Get the class index and insert it into the tags. */                     \
-    uint32_t tags = 0;                                                         \
-    tags = RawObject::ClassIdTag::update(cid, tags);                           \
-    tags = RawObject::NewBit::update(true, tags);                              \
-    __ LoadImmediate(TMP, tags);                                               \
-    __ orr(R2, R2, Operand(TMP));                                              \
-    __ str(R2, FieldAddress(R0, type_name::tags_offset())); /* Tags. */        \
-  }                                                                            \
-  /* Set the length field. */                                                  \
-  /* R0: new object start as a tagged pointer. */                              \
-  /* R1: new object end address. */                                            \
-  __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */        \
-  __ StoreIntoObjectNoBarrier(                                                 \
-      R0, FieldAddress(R0, type_name::length_offset()), R2);                   \
-  /* Initialize all array elements to 0. */                                    \
-  /* R0: new object start as a tagged pointer. */                              \
-  /* R1: new object end address. */                                            \
-  /* R2: iterator which initially points to the start of the variable */       \
-  /* R3: scratch register. */                                                  \
-  /* data area to be initialized. */                                           \
-  __ mov(R3, ZR);                                                              \
-  __ AddImmediate(R2, R0, sizeof(Raw##type_name) - 1);                         \
-  Label init_loop, done;                                                       \
-  __ Bind(&init_loop);                                                         \
-  __ cmp(R2, Operand(R1));                                                     \
-  __ b(&done, CS);                                                             \
-  __ str(R3, Address(R2, 0));                                                  \
-  __ add(R2, R2, Operand(kWordSize));                                          \
-  __ b(&init_loop);                                                            \
-  __ Bind(&done);                                                              \
-                                                                               \
-  __ ret();                                                                    \
-  __ Bind(normal_ir_body);
-
-#define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
-                                                 Label* normal_ir_body) {      \
-    intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
-    intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
-    int shift = GetScaleFactor(size);                                          \
-    TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, shift); \
-  }
-CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
-#undef TYPED_DATA_ALLOCATOR
-
-// Loads args from stack into R0 and R1
-// Tests if they are smis, jumps to label not_smi if not.
-static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
-  __ ldr(R0, Address(SP, +0 * kWordSize));
-  __ ldr(R1, Address(SP, +1 * kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ BranchIfNotSmi(TMP, not_smi);
-}
-
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ adds(R0, R0, Operand(R1));                     // Adds.
-  __ b(normal_ir_body, VS);                         // Fall-through on overflow.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  Integer_addFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ subs(R0, R0, Operand(R1));  // Subtract.
-  __ b(normal_ir_body, VS);      // Fall-through on overflow.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ subs(R0, R1, Operand(R0));  // Subtract.
-  __ b(normal_ir_body, VS);      // Fall-through on overflow.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // checks two smis
-  __ SmiUntag(R0);  // Untags R6. We only want result shifted by one.
-
-  __ mul(TMP, R0, R1);
-  __ smulh(TMP2, R0, R1);
-  // TMP: result bits 64..127.
-  __ cmp(TMP2, Operand(TMP, ASR, 63));
-  __ b(normal_ir_body, NE);
-  __ mov(R0, TMP);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  Integer_mulFromInteger(assembler, normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// R1: Tagged left (dividend).
-// R0: Tagged right (divisor).
-// Returns:
-//   R1: Untagged fallthrough result (remainder to be adjusted), or
-//   R0: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, modulo;
-  const Register left = R1;
-  const Register right = R0;
-  const Register result = R1;
-  const Register tmp = R2;
-  ASSERT(left == result);
-
-  // Check for quick zero results.
-  __ CompareRegisters(left, ZR);
-  __ b(&return_zero, EQ);
-  __ CompareRegisters(left, right);
-  __ b(&return_zero, EQ);
-
-  // Check if result should be left.
-  __ CompareRegisters(left, ZR);
-  __ b(&modulo, LT);
-  // left is positive.
-  __ CompareRegisters(left, right);
-  // left is less than right, result is left.
-  __ b(&modulo, GT);
-  __ mov(R0, left);
-  __ ret();
-
-  __ Bind(&return_zero);
-  __ mov(R0, ZR);
-  __ ret();
-
-  __ Bind(&modulo);
-  // result <- left - right * (left / right)
-  __ SmiUntag(left);
-  __ SmiUntag(right);
-
-  __ sdiv(tmp, left, right);
-  __ msub(result, right, tmp, left);  // result <- left - right * tmp
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  // Check to see if we have integer division
-  Label neg_remainder, fall_through;
-  __ ldr(R1, Address(SP, +0 * kWordSize));
-  __ ldr(R0, Address(SP, +1 * kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ BranchIfNotSmi(TMP, normal_ir_body);
-  // R1: Tagged left (dividend).
-  // R0: Tagged right (divisor).
-  // Check if modulo by zero -> exception thrown in main function.
-  __ CompareRegisters(R0, ZR);
-  __ b(normal_ir_body, EQ);
-  EmitRemainderOperation(assembler);
-  // Untagged right in R0. Untagged remainder result in R1.
-
-  __ CompareRegisters(R1, ZR);
-  __ b(&neg_remainder, LT);
-  __ SmiTag(R0, R1);  // Tag and move result to R0.
-  __ ret();
-
-  __ Bind(&neg_remainder);
-  // Result is negative, adjust it.
-  __ CompareRegisters(R0, ZR);
-  __ sub(TMP, R1, Operand(R0));
-  __ add(TMP2, R1, Operand(R0));
-  __ csel(R0, TMP2, TMP, GE);
-  __ SmiTag(R0);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_truncDivide(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  // Check to see if we have integer division
-
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ CompareRegisters(R0, ZR);
-  __ b(normal_ir_body, EQ);  // If b is 0, fall through.
-
-  __ SmiUntag(R0);
-  __ SmiUntag(R1);
-
-  __ sdiv(R0, R1, R0);
-
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ CompareImmediate(R0, 0x4000000000000000);
-  __ b(normal_ir_body, EQ);
-  __ SmiTag(R0);  // Not equal. Okay to tag and return.
-  __ ret();       // Return.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, +0 * kWordSize));  // Grab first argument.
-  __ BranchIfNotSmi(R0, normal_ir_body);
-  __ negs(R0, R0);
-  __ b(normal_ir_body, VS);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ and_(R0, R0, Operand(R1));
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ orr(R0, R0, Operand(R1));
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitOrFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);  // Checks two smis.
-  __ eor(R0, R0, Operand(R1));
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitXorFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
-  ASSERT(kSmiTagShift == 1);
-  ASSERT(kSmiTag == 0);
-  const Register right = R0;
-  const Register left = R1;
-  const Register temp = R2;
-  const Register result = R0;
-
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ CompareImmediate(right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)));
-  __ b(normal_ir_body, CS);
-
-  // Left is not a constant.
-  // Check if count too large for handling it inlined.
-  __ SmiUntag(TMP, right);  // SmiUntag right into TMP.
-  // Overflow test (preserve left, right, and TMP);
-  __ lslv(temp, left, TMP);
-  __ asrv(TMP2, temp, TMP);
-  __ CompareRegisters(left, TMP2);
-  __ b(normal_ir_body, NE);  // Overflow.
-  // Shift for result now we know there is no overflow.
-  __ lslv(result, left, TMP);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-static void CompareIntegers(Assembler* assembler,
-                            Label* normal_ir_body,
-                            Condition true_condition) {
-  Label true_label;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // R0 contains the right argument, R1 the left.
-  __ CompareRegisters(R1, R0);
-  __ LoadObject(R0, Bool::False());
-  __ LoadObject(TMP, Bool::True());
-  __ csel(R0, TMP, R0, true_condition);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LT);
-}
-
-void Intrinsifier::Integer_lessThan(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Integer_greaterThanFromInt(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_greaterThan(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GT);
-}
-
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LE);
-}
-
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GE);
-}
-
-// This is called for Smi and Mint receivers. The right argument
-// can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  Label true_label, check_for_mint;
-  // For integer receiver '===' check first.
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R1, Address(SP, 1 * kWordSize));
-  __ cmp(R0, Operand(R1));
-  __ b(&true_label, EQ);
-
-  __ orr(R2, R0, Operand(R1));
-  __ BranchIfNotSmi(R2, &check_for_mint);
-  // If R0 or R1 is not a smi do Mint checks.
-
-  // Both arguments are smi, '===' is good enough.
-  __ LoadObject(R0, Bool::False());
-  __ ret();
-  __ Bind(&true_label);
-  __ LoadObject(R0, Bool::True());
-  __ ret();
-
-  // At least one of the arguments was not Smi.
-  Label receiver_not_smi;
-  __ Bind(&check_for_mint);
-
-  __ BranchIfNotSmi(R1, &receiver_not_smi);  // Check receiver.
-
-  // Left (receiver) is Smi, return false if right is not Double.
-  // Note that an instance of Mint never contains a value that can be
-  // represented by Smi.
-
-  __ CompareClassId(R0, kDoubleCid);
-  __ b(normal_ir_body, EQ);
-  __ LoadObject(R0, Bool::False());  // Smi == Mint -> false.
-  __ ret();
-
-  __ Bind(&receiver_not_smi);
-  // R1: receiver.
-
-  __ CompareClassId(R1, kMintCid);
-  __ b(normal_ir_body, NE);
-  // Receiver is Mint, return false if right is Smi.
-  __ BranchIfNotSmi(R0, normal_ir_body);
-  __ LoadObject(R0, Bool::False());
-  __ ret();
-  // TODO(srdjan): Implement Mint == Mint comparison.
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
-  Integer_equalToInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Shift amount in R0. Value to shift in R1.
-
-  // Fall through if shift amount is negative.
-  __ SmiUntag(R0);
-  __ CompareRegisters(R0, ZR);
-  __ b(normal_ir_body, LT);
-
-  // If shift amount is bigger than 63, set to 63.
-  __ LoadImmediate(TMP, 0x3F);
-  __ CompareRegisters(R0, TMP);
-  __ csel(R0, TMP, R0, GT);
-  __ SmiUntag(R1);
-  __ asrv(R0, R1, R0);
-  __ SmiTag(R0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ mvn(R0, R0);
-  __ andi(R0, R0, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
-  __ ret();
-}
-
-void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ SmiUntag(R0);
-  // XOR with sign bit to complement bits if value is negative.
-  __ eor(R0, R0, Operand(R0, ASR, 63));
-  __ clz(R0, R0);
-  __ LoadImmediate(R1, 64);
-  __ sub(R0, R1, Operand(R0));
-  __ SmiTag(R0);
-  __ ret();
-}
-
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
-  __ ldp(R2, R3, Address(SP, 2 * kWordSize, Address::PairOffset));
-  __ add(R2, R2, Operand(2));  // x_used > 0, Smi. R2 = x_used + 1, round up.
-  __ AsrImmediate(R2, R2, 2);  // R2 = num of digit pairs to read.
-  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldp(R4, R5, Address(SP, 0 * kWordSize, Address::PairOffset));
-  __ SmiUntag(R5);
-  // R0 = n ~/ (2*_DIGIT_BITS)
-  __ AsrImmediate(R0, R5, 6);
-  // R6 = &x_digits[0]
-  __ add(R6, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // R7 = &x_digits[2*R2]
-  __ add(R7, R6, Operand(R2, LSL, 3));
-  // R8 = &r_digits[2*1]
-  __ add(R8, R4,
-         Operand(TypedData::data_offset() - kHeapObjectTag +
-                 2 * kBytesPerBigIntDigit));
-  // R8 = &r_digits[2*(R2 + n ~/ (2*_DIGIT_BITS) + 1)]
-  __ add(R0, R0, Operand(R2));
-  __ add(R8, R8, Operand(R0, LSL, 3));
-  // R3 = n % (2 * _DIGIT_BITS)
-  __ AndImmediate(R3, R5, 63);
-  // R2 = 64 - R3
-  __ LoadImmediate(R2, 64);
-  __ sub(R2, R2, Operand(R3));
-  __ mov(R1, ZR);
-  Label loop;
-  __ Bind(&loop);
-  __ ldr(R0, Address(R7, -2 * kBytesPerBigIntDigit, Address::PreIndex));
-  __ lsrv(R4, R0, R2);
-  __ orr(R1, R1, Operand(R4));
-  __ str(R1, Address(R8, -2 * kBytesPerBigIntDigit, Address::PreIndex));
-  __ lslv(R1, R0, R3);
-  __ cmp(R7, Operand(R6));
-  __ b(&loop, NE);
-  __ str(R1, Address(R8, -2 * kBytesPerBigIntDigit, Address::PreIndex));
-  __ LoadObject(R0, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  // R2 = x_used, R3 = x_digits, x_used > 0, x_used is Smi.
-  __ ldp(R2, R3, Address(SP, 2 * kWordSize, Address::PairOffset));
-  __ add(R2, R2, Operand(2));  // x_used > 0, Smi. R2 = x_used + 1, round up.
-  __ AsrImmediate(R2, R2, 2);  // R2 = num of digit pairs to read.
-  // R4 = r_digits, R5 = n, n is Smi, n % _DIGIT_BITS != 0.
-  __ ldp(R4, R5, Address(SP, 0 * kWordSize, Address::PairOffset));
-  __ SmiUntag(R5);
-  // R0 = n ~/ (2*_DIGIT_BITS)
-  __ AsrImmediate(R0, R5, 6);
-  // R8 = &r_digits[0]
-  __ add(R8, R4, Operand(TypedData::data_offset() - kHeapObjectTag));
-  // R7 = &x_digits[2*(n ~/ (2*_DIGIT_BITS))]
-  __ add(R7, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-  __ add(R7, R7, Operand(R0, LSL, 3));
-  // R6 = &r_digits[2*(R2 - n ~/ (2*_DIGIT_BITS) - 1)]
-  __ add(R0, R0, Operand(1));
-  __ sub(R0, R2, Operand(R0));
-  __ add(R6, R8, Operand(R0, LSL, 3));
-  // R3 = n % (2*_DIGIT_BITS)
-  __ AndImmediate(R3, R5, 63);
-  // R2 = 64 - R3
-  __ LoadImmediate(R2, 64);
-  __ sub(R2, R2, Operand(R3));
-  // R1 = x_digits[n ~/ (2*_DIGIT_BITS)] >> (n % (2*_DIGIT_BITS))
-  __ ldr(R1, Address(R7, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ lsrv(R1, R1, R3);
-  Label loop_entry;
-  __ b(&loop_entry);
-  Label loop;
-  __ Bind(&loop);
-  __ ldr(R0, Address(R7, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ lslv(R4, R0, R2);
-  __ orr(R1, R1, Operand(R4));
-  __ str(R1, Address(R8, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ lsrv(R1, R0, R3);
-  __ Bind(&loop_entry);
-  __ cmp(R8, Operand(R6));
-  __ b(&loop, NE);
-  __ str(R1, Address(R8, 0));
-  __ LoadObject(R0, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absAdd(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  // R2 = used, R3 = digits
-  __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset));
-  __ add(R2, R2, Operand(2));  // used > 0, Smi. R2 = used + 1, round up.
-  __ add(R2, ZR, Operand(R2, ASR, 2));  // R2 = num of digit pairs to process.
-  // R3 = &digits[0]
-  __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R4 = a_used, R5 = a_digits
-  __ ldp(R4, R5, Address(SP, 1 * kWordSize, Address::PairOffset));
-  __ add(R4, R4, Operand(2));  // a_used > 0, Smi. R4 = a_used + 1, round up.
-  __ add(R4, ZR, Operand(R4, ASR, 2));  // R4 = num of digit pairs to process.
-  // R5 = &a_digits[0]
-  __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R6 = r_digits
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  // R6 = &r_digits[0]
-  __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R7 = &digits[a_used rounded up to even number].
-  __ add(R7, R3, Operand(R4, LSL, 3));
-
-  // R8 = &digits[a_used rounded up to even number].
-  __ add(R8, R3, Operand(R2, LSL, 3));
-
-  __ adds(R0, R0, Operand(0));  // carry flag = 0
-  Label add_loop;
-  __ Bind(&add_loop);
-  // Loop (a_used+1)/2 times, a_used > 0.
-  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ ldr(R1, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ adcs(R0, R0, R1);
-  __ sub(R9, R3, Operand(R7));  // Does not affect carry flag.
-  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ cbnz(&add_loop, R9);  // Does not affect carry flag.
-
-  Label last_carry;
-  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
-  __ cbz(&last_carry, R9);      // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop (used+1)/2 - (a_used+1)/2 times, used - a_used > 0.
-  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ adcs(R0, R0, ZR);
-  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
-  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ cbnz(&carry_loop, R9);
-
-  __ Bind(&last_carry);
-  Label done;
-  __ b(&done, CC);
-  __ LoadImmediate(R0, 1);
-  __ str(R0, Address(R6, 0));
-
-  __ Bind(&done);
-  __ LoadObject(R0, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absSub(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  // R2 = used, R3 = digits
-  __ ldp(R2, R3, Address(SP, 3 * kWordSize, Address::PairOffset));
-  __ add(R2, R2, Operand(2));  // used > 0, Smi. R2 = used + 1, round up.
-  __ add(R2, ZR, Operand(R2, ASR, 2));  // R2 = num of digit pairs to process.
-  // R3 = &digits[0]
-  __ add(R3, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R4 = a_used, R5 = a_digits
-  __ ldp(R4, R5, Address(SP, 1 * kWordSize, Address::PairOffset));
-  __ add(R4, R4, Operand(2));  // a_used > 0, Smi. R4 = a_used + 1, round up.
-  __ add(R4, ZR, Operand(R4, ASR, 2));  // R4 = num of digit pairs to process.
-  // R5 = &a_digits[0]
-  __ add(R5, R5, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R6 = r_digits
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  // R6 = &r_digits[0]
-  __ add(R6, R6, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R7 = &digits[a_used rounded up to even number].
-  __ add(R7, R3, Operand(R4, LSL, 3));
-
-  // R8 = &digits[a_used rounded up to even number].
-  __ add(R8, R3, Operand(R2, LSL, 3));
-
-  __ subs(R0, R0, Operand(0));  // carry flag = 1
-  Label sub_loop;
-  __ Bind(&sub_loop);
-  // Loop (a_used+1)/2 times, a_used > 0.
-  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ ldr(R1, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ sbcs(R0, R0, R1);
-  __ sub(R9, R3, Operand(R7));  // Does not affect carry flag.
-  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ cbnz(&sub_loop, R9);  // Does not affect carry flag.
-
-  Label done;
-  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
-  __ cbz(&done, R9);            // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop (used+1)/2 - (a_used+1)/2 times, used - a_used > 0.
-  __ ldr(R0, Address(R3, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ sbcs(R0, R0, ZR);
-  __ sub(R9, R3, Operand(R8));  // Does not affect carry flag.
-  __ str(R0, Address(R6, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ cbnz(&carry_loop, R9);
-
-  __ Bind(&done);
-  __ LoadObject(R0, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulAdd(Uint32List x_digits, int xi,
-  //                    Uint32List m_digits, int i,
-  //                    Uint32List a_digits, int j, int n) {
-  //   uint64_t x = x_digits[xi >> 1 .. (xi >> 1) + 1];  // xi is Smi and even.
-  //   if (x == 0 || n == 0) {
-  //     return 2;
-  //   }
-  //   uint64_t* mip = &m_digits[i >> 1];  // i is Smi and even.
-  //   uint64_t* ajp = &a_digits[j >> 1];  // j is Smi and even.
-  //   uint64_t c = 0;
-  //   SmiUntag(n);  // n is Smi and even.
-  //   n = (n + 1)/2;  // Number of pairs to process.
-  //   do {
-  //     uint64_t mi = *mip++;
-  //     uint64_t aj = *ajp;
-  //     uint128_t t = x*mi + aj + c;  // 64-bit * 64-bit -> 128-bit.
-  //     *ajp++ = low64(t);
-  //     c = high64(t);
-  //   } while (--n > 0);
-  //   while (c != 0) {
-  //     uint128_t t = *ajp + c;
-  //     *ajp++ = low64(t);
-  //     c = high64(t);  // c == 0 or 1.
-  //   }
-  //   return 2;
-  // }
-
-  Label done;
-  // R3 = x, no_op if x == 0
-  // R0 = xi as Smi, R1 = x_digits.
-  __ ldp(R0, R1, Address(SP, 5 * kWordSize, Address::PairOffset));
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ ldr(R3, FieldAddress(R1, TypedData::data_offset()));
-  __ tst(R3, Operand(R3));
-  __ b(&done, EQ);
-
-  // R6 = (SmiUntag(n) + 1)/2, no_op if n == 0
-  __ ldr(R6, Address(SP, 0 * kWordSize));
-  __ add(R6, R6, Operand(2));
-  __ adds(R6, ZR, Operand(R6, ASR, 2));  // SmiUntag(R6) and set cc.
-  __ b(&done, EQ);
-
-  // R4 = mip = &m_digits[i >> 1]
-  // R0 = i as Smi, R1 = m_digits.
-  __ ldp(R0, R1, Address(SP, 3 * kWordSize, Address::PairOffset));
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ add(R4, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R5 = ajp = &a_digits[j >> 1]
-  // R0 = j as Smi, R1 = a_digits.
-  __ ldp(R0, R1, Address(SP, 1 * kWordSize, Address::PairOffset));
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R1 = c = 0
-  __ mov(R1, ZR);
-
-  Label muladd_loop;
-  __ Bind(&muladd_loop);
-  // x:   R3
-  // mip: R4
-  // ajp: R5
-  // c:   R1
-  // n:   R6
-  // t:   R7:R8 (not live at loop entry)
-
-  // uint64_t mi = *mip++
-  __ ldr(R2, Address(R4, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-
-  // uint64_t aj = *ajp
-  __ ldr(R0, Address(R5, 0));
-
-  // uint128_t t = x*mi + aj + c
-  __ mul(R7, R2, R3);    // R7 = low64(R2*R3).
-  __ umulh(R8, R2, R3);  // R8 = high64(R2*R3), t = R8:R7 = x*mi.
-  __ adds(R7, R7, Operand(R0));
-  __ adc(R8, R8, ZR);            // t += aj.
-  __ adds(R0, R7, Operand(R1));  // t += c, R0 = low64(t).
-  __ adc(R1, R8, ZR);            // c = R1 = high64(t).
-
-  // *ajp++ = low64(t) = R0
-  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-
-  // while (--n > 0)
-  __ subs(R6, R6, Operand(1));  // --n
-  __ b(&muladd_loop, NE);
-
-  __ tst(R1, Operand(R1));
-  __ b(&done, EQ);
-
-  // *ajp++ += c
-  __ ldr(R0, Address(R5, 0));
-  __ adds(R0, R0, Operand(R1));
-  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&done, CC);
-
-  Label propagate_carry_loop;
-  __ Bind(&propagate_carry_loop);
-  __ ldr(R0, Address(R5, 0));
-  __ adds(R0, R0, Operand(1));
-  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ b(&propagate_carry_loop, CS);
-
-  __ Bind(&done);
-  __ LoadImmediate(R0, Smi::RawValue(2));  // Two digits processed.
-  __ ret();
-}
-
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _sqrAdd(Uint32List x_digits, int i,
-  //                    Uint32List a_digits, int used) {
-  //   uint64_t* xip = &x_digits[i >> 1];  // i is Smi and even.
-  //   uint64_t x = *xip++;
-  //   if (x == 0) return 2;
-  //   uint64_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
-  //   uint64_t aj = *ajp;
-  //   uint128_t t = x*x + aj;
-  //   *ajp++ = low64(t);
-  //   uint128_t c = high64(t);
-  //   int n = ((used - i + 2) >> 2) - 1;  // used and i are Smi. n: num pairs.
-  //   while (--n >= 0) {
-  //     uint64_t xi = *xip++;
-  //     uint64_t aj = *ajp;
-  //     uint192_t t = 2*x*xi + aj + c;  // 2-bit * 64-bit * 64-bit -> 129-bit.
-  //     *ajp++ = low64(t);
-  //     c = high128(t);  // 65-bit.
-  //   }
-  //   uint64_t aj = *ajp;
-  //   uint128_t t = aj + c;  // 64-bit + 65-bit -> 66-bit.
-  //   *ajp++ = low64(t);
-  //   *ajp = high64(t);
-  //   return 2;
-  // }
-
-  // R4 = xip = &x_digits[i >> 1]
-  // R2 = i as Smi, R3 = x_digits
-  __ ldp(R2, R3, Address(SP, 2 * kWordSize, Address::PairOffset));
-  __ add(R3, R3, Operand(R2, LSL, 1));
-  __ add(R4, R3, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R3 = x = *xip++, return if x == 0
-  Label x_zero;
-  __ ldr(R3, Address(R4, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-  __ tst(R3, Operand(R3));
-  __ b(&x_zero, EQ);
-
-  // R5 = ajp = &a_digits[i]
-  __ ldr(R1, Address(SP, 1 * kWordSize));  // a_digits
-  __ add(R1, R1, Operand(R2, LSL, 2));     // j == 2*i, i is Smi.
-  __ add(R5, R1, Operand(TypedData::data_offset() - kHeapObjectTag));
-
-  // R6:R1 = t = x*x + *ajp
-  __ ldr(R0, Address(R5, 0));
-  __ mul(R1, R3, R3);            // R1 = low64(R3*R3).
-  __ umulh(R6, R3, R3);          // R6 = high64(R3*R3).
-  __ adds(R1, R1, Operand(R0));  // R6:R1 += *ajp.
-  __ adc(R6, R6, ZR);            // R6 = low64(c) = high64(t).
-  __ mov(R7, ZR);                // R7 = high64(c) = 0.
-
-  // *ajp++ = low64(t) = R1
-  __ str(R1, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-
-  // int n = (used - i + 1)/2 - 1
-  __ ldr(R0, Address(SP, 0 * kWordSize));  // used is Smi
-  __ sub(R8, R0, Operand(R2));
-  __ add(R8, R8, Operand(2));
-  __ movn(R0, Immediate(1), 0);          // R0 = ~1 = -2.
-  __ adds(R8, R0, Operand(R8, ASR, 2));  // while (--n >= 0)
-
-  Label loop, done;
-  __ b(&done, MI);
-
-  __ Bind(&loop);
-  // x:   R3
-  // xip: R4
-  // ajp: R5
-  // c:   R7:R6
-  // t:   R2:R1:R0 (not live at loop entry)
-  // n:   R8
-
-  // uint64_t xi = *xip++
-  __ ldr(R2, Address(R4, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-
-  // uint192_t t = R2:R1:R0 = 2*x*xi + aj + c
-  __ mul(R0, R2, R3);    // R0 = low64(R2*R3) = low64(x*xi).
-  __ umulh(R1, R2, R3);  // R1 = high64(R2*R3) = high64(x*xi).
-  __ adds(R0, R0, Operand(R0));
-  __ adcs(R1, R1, R1);
-  __ adc(R2, ZR, ZR);  // R2:R1:R0 = R1:R0 + R1:R0 = 2*x*xi.
-  __ adds(R0, R0, Operand(R6));
-  __ adcs(R1, R1, R7);
-  __ adc(R2, R2, ZR);          // R2:R1:R0 += c.
-  __ ldr(R7, Address(R5, 0));  // R7 = aj = *ajp.
-  __ adds(R0, R0, Operand(R7));
-  __ adcs(R6, R1, ZR);
-  __ adc(R7, R2, ZR);  // R7:R6:R0 = 2*x*xi + aj + c.
-
-  // *ajp++ = low64(t) = R0
-  __ str(R0, Address(R5, 2 * kBytesPerBigIntDigit, Address::PostIndex));
-
-  // while (--n >= 0)
-  __ subs(R8, R8, Operand(1));  // --n
-  __ b(&loop, PL);
-
-  __ Bind(&done);
-  // uint64_t aj = *ajp
-  __ ldr(R0, Address(R5, 0));
-
-  // uint128_t t = aj + c
-  __ adds(R6, R6, Operand(R0));
-  __ adc(R7, R7, ZR);
-
-  // *ajp = low64(t) = R6
-  // *(ajp + 1) = high64(t) = R7
-  __ stp(R6, R7, Address(R5, 0, Address::PairOffset));
-
-  __ Bind(&x_zero);
-  __ LoadImmediate(R0, Smi::RawValue(2));  // Two digits processed.
-  __ ret();
-}
-
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  // There is no 128-bit by 64-bit division instruction on arm64, so we use two
-  // 64-bit by 32-bit divisions and two 64-bit by 64-bit multiplications to
-  // adjust the two 32-bit digits of the estimated quotient.
-  //
-  // Pseudo code:
-  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
-  //   uint64_t yt = args[_YT_LO .. _YT];  // _YT_LO == 0, _YT == 1.
-  //   uint64_t* dp = &digits[(i >> 1) - 1];  // i is Smi.
-  //   uint64_t dh = dp[0];  // dh == digits[(i >> 1) - 1 .. i >> 1].
-  //   uint64_t qd;
-  //   if (dh == yt) {
-  //     qd = (DIGIT_MASK << 32) | DIGIT_MASK;
-  //   } else {
-  //     dl = dp[-1];  // dl == digits[(i >> 1) - 3 .. (i >> 1) - 2].
-  //     // We cannot calculate qd = dh:dl / yt, so ...
-  //     uint64_t yth = yt >> 32;
-  //     uint64_t qh = dh / yth;
-  //     uint128_t ph:pl = yt*qh;
-  //     uint64_t tl = (dh << 32)|(dl >> 32);
-  //     uint64_t th = dh >> 32;
-  //     while ((ph > th) || ((ph == th) && (pl > tl))) {
-  //       if (pl < yt) --ph;
-  //       pl -= yt;
-  //       --qh;
-  //     }
-  //     qd = qh << 32;
-  //     tl = (pl << 32);
-  //     th = (ph << 32)|(pl >> 32);
-  //     if (tl > dl) ++th;
-  //     dl -= tl;
-  //     dh -= th;
-  //     uint64_t ql = ((dh << 32)|(dl >> 32)) / yth;
-  //     ph:pl = yt*ql;
-  //     while ((ph > dh) || ((ph == dh) && (pl > dl))) {
-  //       if (pl < yt) --ph;
-  //       pl -= yt;
-  //       --ql;
-  //     }
-  //     qd |= ql;
-  //   }
-  //   args[_QD .. _QD_HI] = qd;  // _QD == 2, _QD_HI == 3.
-  //   return 2;
-  // }
-
-  // R4 = args
-  __ ldr(R4, Address(SP, 2 * kWordSize));  // args
-
-  // R3 = yt = args[0..1]
-  __ ldr(R3, FieldAddress(R4, TypedData::data_offset()));
-
-  // R2 = dh = digits[(i >> 1) - 1 .. i >> 1]
-  // R0 = i as Smi, R1 = digits
-  __ ldp(R0, R1, Address(SP, 0 * kWordSize, Address::PairOffset));
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ ldr(R2, FieldAddress(R1, TypedData::data_offset() - kBytesPerBigIntDigit));
-
-  // R0 = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
-  __ movn(R0, Immediate(0), 0);
-
-  // Return qd if dh == yt
-  Label return_qd;
-  __ cmp(R2, Operand(R3));
-  __ b(&return_qd, EQ);
-
-  // R1 = dl = digits[(i >> 1) - 3 .. (i >> 1) - 2]
-  __ ldr(R1,
-         FieldAddress(R1, TypedData::data_offset() - 3 * kBytesPerBigIntDigit));
-
-  // R5 = yth = yt >> 32
-  __ orr(R5, ZR, Operand(R3, LSR, 32));
-
-  // R6 = qh = dh / yth
-  __ udiv(R6, R2, R5);
-
-  // R8:R7 = ph:pl = yt*qh
-  __ mul(R7, R3, R6);
-  __ umulh(R8, R3, R6);
-
-  // R9 = tl = (dh << 32)|(dl >> 32)
-  __ orr(R9, ZR, Operand(R2, LSL, 32));
-  __ orr(R9, R9, Operand(R1, LSR, 32));
-
-  // R10 = th = dh >> 32
-  __ orr(R10, ZR, Operand(R2, LSR, 32));
-
-  // while ((ph > th) || ((ph == th) && (pl > tl)))
-  Label qh_adj_loop, qh_adj, qh_ok;
-  __ Bind(&qh_adj_loop);
-  __ cmp(R8, Operand(R10));
-  __ b(&qh_adj, HI);
-  __ b(&qh_ok, NE);
-  __ cmp(R7, Operand(R9));
-  __ b(&qh_ok, LS);
-
-  __ Bind(&qh_adj);
-  // if (pl < yt) --ph
-  __ sub(TMP, R8, Operand(1));  // TMP = ph - 1
-  __ cmp(R7, Operand(R3));
-  __ csel(R8, TMP, R8, CC);  // R8 = R7 < R3 ? TMP : R8
-
-  // pl -= yt
-  __ sub(R7, R7, Operand(R3));
-
-  // --qh
-  __ sub(R6, R6, Operand(1));
-
-  // Continue while loop.
-  __ b(&qh_adj_loop);
-
-  __ Bind(&qh_ok);
-  // R0 = qd = qh << 32
-  __ orr(R0, ZR, Operand(R6, LSL, 32));
-
-  // tl = (pl << 32)
-  __ orr(R9, ZR, Operand(R7, LSL, 32));
-
-  // th = (ph << 32)|(pl >> 32);
-  __ orr(R10, ZR, Operand(R8, LSL, 32));
-  __ orr(R10, R10, Operand(R7, LSR, 32));
-
-  // if (tl > dl) ++th
-  __ add(TMP, R10, Operand(1));  // TMP = th + 1
-  __ cmp(R9, Operand(R1));
-  __ csel(R10, TMP, R10, HI);  // R10 = R9 > R1 ? TMP : R10
-
-  // dl -= tl
-  __ sub(R1, R1, Operand(R9));
-
-  // dh -= th
-  __ sub(R2, R2, Operand(R10));
-
-  // R6 = ql = ((dh << 32)|(dl >> 32)) / yth
-  __ orr(R6, ZR, Operand(R2, LSL, 32));
-  __ orr(R6, R6, Operand(R1, LSR, 32));
-  __ udiv(R6, R6, R5);
-
-  // R8:R7 = ph:pl = yt*ql
-  __ mul(R7, R3, R6);
-  __ umulh(R8, R3, R6);
-
-  // while ((ph > dh) || ((ph == dh) && (pl > dl))) {
-  Label ql_adj_loop, ql_adj, ql_ok;
-  __ Bind(&ql_adj_loop);
-  __ cmp(R8, Operand(R2));
-  __ b(&ql_adj, HI);
-  __ b(&ql_ok, NE);
-  __ cmp(R7, Operand(R1));
-  __ b(&ql_ok, LS);
-
-  __ Bind(&ql_adj);
-  // if (pl < yt) --ph
-  __ sub(TMP, R8, Operand(1));  // TMP = ph - 1
-  __ cmp(R7, Operand(R3));
-  __ csel(R8, TMP, R8, CC);  // R8 = R7 < R3 ? TMP : R8
-
-  // pl -= yt
-  __ sub(R7, R7, Operand(R3));
-
-  // --ql
-  __ sub(R6, R6, Operand(1));
-
-  // Continue while loop.
-  __ b(&ql_adj_loop);
-
-  __ Bind(&ql_ok);
-  // qd |= ql;
-  __ orr(R0, R0, Operand(R6));
-
-  __ Bind(&return_qd);
-  // args[2..3] = qd
-  __ str(R0,
-         FieldAddress(R4, TypedData::data_offset() + 2 * kBytesPerBigIntDigit));
-
-  __ LoadImmediate(R0, Smi::RawValue(2));  // Two digits processed.
-  __ ret();
-}
-
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
-  //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
-  //   uint64_t d = digits[i >> 1 .. (i >> 1) + 1];  // i is Smi and even.
-  //   uint128_t t = rho*d;
-  //   args[_MU .. _MU_HI] = t mod DIGIT_BASE^2;  // _MU == 4, _MU_HI == 5.
-  //   return 2;
-  // }
-
-  // R4 = args
-  __ ldr(R4, Address(SP, 2 * kWordSize));  // args
-
-  // R3 = rho = args[2..3]
-  __ ldr(R3,
-         FieldAddress(R4, TypedData::data_offset() + 2 * kBytesPerBigIntDigit));
-
-  // R2 = digits[i >> 1 .. (i >> 1) + 1]
-  // R0 = i as Smi, R1 = digits
-  __ ldp(R0, R1, Address(SP, 0 * kWordSize, Address::PairOffset));
-  __ add(R1, R1, Operand(R0, LSL, 1));
-  __ ldr(R2, FieldAddress(R1, TypedData::data_offset()));
-
-  // R0 = rho*d mod DIGIT_BASE
-  __ mul(R0, R2, R3);  // R0 = low64(R2*R3).
-
-  // args[4 .. 5] = R0
-  __ str(R0,
-         FieldAddress(R4, TypedData::data_offset() + 4 * kBytesPerBigIntDigit));
-
-  __ LoadImmediate(R0, Smi::RawValue(2));  // Two digits processed.
-  __ ret();
-}
-
-// Check if the last argument is a double, jump to label 'is_smi' if smi
-// (easy to convert to double), otherwise jump to label 'not_double_smi',
-// Returns the last argument in R0.
-static void TestLastArgumentIsDouble(Assembler* assembler,
-                                     Label* is_smi,
-                                     Label* not_double_smi) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ BranchIfSmi(R0, is_smi);
-  __ CompareClassId(R0, kDoubleCid);
-  __ b(not_double_smi, NE);
-  // Fall through with Double in R0.
-}
-
-// Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
-// type. Return true or false object in the register R0. Any NaN argument
-// returns false. Any non-double arg1 causes control flow to fall through to the
-// slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler,
-                           Label* normal_ir_body,
-                           Condition true_condition) {
-  Label is_smi, double_op, not_nan;
-
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Both arguments are double, right operand is in R0.
-
-  __ LoadDFieldFromOffset(V1, R0, Double::value_offset());
-  __ Bind(&double_op);
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // Left argument.
-  __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
-
-  __ fcmpd(V0, V1);
-  __ LoadObject(R0, Bool::False());
-  // Return false if D0 or D1 was NaN before checking true condition.
-  __ b(&not_nan, VC);
-  __ ret();
-  __ Bind(&not_nan);
-  __ LoadObject(TMP, Bool::True());
-  __ csel(R0, TMP, R0, true_condition);
-  __ ret();
-
-  __ Bind(&is_smi);  // Convert R0 to a double.
-  __ SmiUntag(R0);
-  __ scvtfdx(V1, R0);
-  __ b(&double_op);  // Then do the comparison.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_greaterThan(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, HI);
-}
-
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
-                                           Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, CS);
-}
-
-void Intrinsifier::Double_lessThan(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, CC);
-}
-
-void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, EQ);
-}
-
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, LS);
-}
-
-// Expects left argument to be double (receiver). Right argument is unknown.
-// Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler,
-                                       Label* normal_ir_body,
-                                       Token::Kind kind) {
-  Label is_smi, double_op;
-
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Both arguments are double, right operand is in R0.
-  __ LoadDFieldFromOffset(V1, R0, Double::value_offset());
-  __ Bind(&double_op);
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // Left argument.
-  __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
-  switch (kind) {
-    case Token::kADD:
-      __ faddd(V0, V0, V1);
-      break;
-    case Token::kSUB:
-      __ fsubd(V0, V0, V1);
-      break;
-    case Token::kMUL:
-      __ fmuld(V0, V0, V1);
-      break;
-    case Token::kDIV:
-      __ fdivd(V0, V0, V1);
-      break;
-    default:
-      UNREACHABLE();
-  }
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, R0, R1);
-  __ StoreDFieldToOffset(V0, R0, Double::value_offset());
-  __ ret();
-
-  __ Bind(&is_smi);  // Convert R0 to a double.
-  __ SmiUntag(R0);
-  __ scvtfdx(V1, R0);
-  __ b(&double_op);
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
-}
-
-void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
-}
-
-void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
-}
-
-void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
-}
-
-// Left is double, right is integer (Mint or Smi)
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  // Only smis allowed.
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ BranchIfNotSmi(R0, normal_ir_body);
-  // Is Smi.
-  __ SmiUntag(R0);
-  __ scvtfdx(V1, R0);
-  __ ldr(R0, Address(SP, 1 * kWordSize));
-  __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
-  __ fmuld(V0, V0, V1);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, R0, R1);
-  __ StoreDFieldToOffset(V0, R0, Double::value_offset());
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::DoubleFromInteger(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ BranchIfNotSmi(R0, normal_ir_body);
-  // Is Smi.
-  __ SmiUntag(R0);
-  __ scvtfdx(V0, R0);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, R0, R1);
-  __ StoreDFieldToOffset(V0, R0, Double::value_offset());
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_getIsNaN(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
-  __ fcmpd(V0, V0);
-  __ LoadObject(TMP, Bool::False());
-  __ LoadObject(R0, Bool::True());
-  __ csel(R0, TMP, R0, VC);
-  __ ret();
-}
-
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadFieldFromOffset(R0, R0, Double::value_offset());
-  // Mask off the sign.
-  __ AndImmediate(R0, R0, 0x7FFFFFFFFFFFFFFFLL);
-  // Compare with +infinity.
-  __ CompareImmediate(R0, 0x7FF0000000000000LL);
-  __ LoadObject(R0, Bool::False());
-  __ LoadObject(TMP, Bool::True());
-  __ csel(R0, TMP, R0, EQ);
-  __ ret();
-}
-
-void Intrinsifier::Double_getIsNegative(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  const Register false_reg = R0;
-  const Register true_reg = R2;
-  Label is_false, is_true, is_zero;
-
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
-  __ fcmpdz(V0);
-  __ LoadObject(true_reg, Bool::True());
-  __ LoadObject(false_reg, Bool::False());
-  __ b(&is_false, VS);  // NaN -> false.
-  __ b(&is_zero, EQ);   // Check for negative zero.
-  __ b(&is_false, CS);  // >= 0 -> false.
-
-  __ Bind(&is_true);
-  __ mov(R0, true_reg);
-
-  __ Bind(&is_false);
-  __ ret();
-
-  __ Bind(&is_zero);
-  // Check for negative zero by looking at the sign bit.
-  __ fmovrd(R1, V0);
-  __ LsrImmediate(R1, R1, 63);
-  __ tsti(R1, Immediate(1));
-  __ csel(R0, true_reg, false_reg, NE);  // Sign bit set.
-  __ ret();
-}
-
-void Intrinsifier::DoubleToInteger(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadDFieldFromOffset(V0, R0, Double::value_offset());
-
-  // Explicit NaN check, since ARM gives an FPU exception if you try to
-  // convert NaN to an int.
-  __ fcmpd(V0, V0);
-  __ b(normal_ir_body, VS);
-
-  __ fcvtzds(R0, V0);
-  // Overflow is signaled with minint.
-  // Check for overflow and that it fits into Smi.
-  __ CompareImmediate(R0, 0xC000000000000000);
-  __ b(normal_ir_body, MI);
-  __ SmiTag(R0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_hashCode(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
-
-  // Load double value and check that it isn't NaN, since ARM gives an
-  // FPU exception if you try to convert NaN to an int.
-  Label double_hash;
-  __ ldr(R1, Address(SP, 0 * kWordSize));
-  __ LoadDFieldFromOffset(V0, R1, Double::value_offset());
-  __ fcmpd(V0, V0);
-  __ b(&double_hash, VS);
-
-  // Convert double value to signed 64-bit int in R0 and back to a
-  // double value in V1.
-  __ fcvtzds(R0, V0);
-  __ scvtfdx(V1, R0);
-
-  // Tag the int as a Smi, making sure that it fits; this checks for
-  // overflow in the conversion from double to int. Conversion
-  // overflow is signalled by fcvt through clamping R0 to either
-  // INT64_MAX or INT64_MIN (saturation).
-  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-  __ adds(R0, R0, Operand(R0));
-  __ b(normal_ir_body, VS);
-
-  // Compare the two double values. If they are equal, we return the
-  // Smi tagged result immediately as the hash code.
-  __ fcmpd(V0, V1);
-  __ b(&double_hash, NE);
-  __ ret();
-
-  // Convert the double bits to a hash code that fits in a Smi.
-  __ Bind(&double_hash);
-  __ fmovrd(R0, V0);
-  __ eor(R0, R0, Operand(R0, LSR, 32));
-  __ AndImmediate(R0, R0, kSmiMax);
-  __ SmiTag(R0);
-  __ ret();
-
-  // Fall into the native C++ implementation.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
-  Label is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Argument is double and is in R0.
-  __ LoadDFieldFromOffset(V1, R0, Double::value_offset());
-  __ Bind(&double_op);
-  __ fsqrtd(V0, V1);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, R0, R1);
-  __ StoreDFieldToOffset(V0, R0, Double::value_offset());
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(R0);
-  __ scvtfdx(V1, R0);
-  __ b(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-//    _state[kSTATE_LO] = state & _MASK_32;
-//    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  const Library& math_lib = Library::Handle(Library::MathLibrary());
-  ASSERT(!math_lib.IsNull());
-  const Class& random_class =
-      Class::Handle(math_lib.LookupClassAllowPrivate(Symbols::_Random()));
-  ASSERT(!random_class.IsNull());
-  const Field& state_field = Field::ZoneHandle(
-      random_class.LookupInstanceFieldAllowPrivate(Symbols::_state()));
-  ASSERT(!state_field.IsNull());
-  const int64_t a_int_value = Intrinsifier::kRandomAValue;
-
-  // Receiver.
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  // Field '_state'.
-  __ ldr(R1, FieldAddress(R0, state_field.Offset()));
-
-  // Addresses of _state[0].
-  const int64_t disp =
-      Instance::DataOffsetFor(kTypedDataUint32ArrayCid) - kHeapObjectTag;
-
-  __ LoadImmediate(R0, a_int_value);
-  __ LoadFromOffset(R2, R1, disp);
-  __ LsrImmediate(R3, R2, 32);
-  __ andi(R2, R2, Immediate(0xffffffff));
-  __ mul(R2, R0, R2);
-  __ add(R2, R2, Operand(R3));
-  __ StoreToOffset(R2, R1, disp);
-  ASSERT(Smi::RawValue(0) == 0);
-  __ eor(R0, R0, Operand(R0));
-  __ ret();
-}
-
-void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R1, Address(SP, 1 * kWordSize));
-  __ cmp(R0, Operand(R1));
-  __ LoadObject(R0, Bool::False());
-  __ LoadObject(TMP, Bool::True());
-  __ csel(R0, TMP, R0, EQ);
-  __ ret();
-}
-
-static void RangeCheck(Assembler* assembler,
-                       Register val,
-                       Register tmp,
-                       intptr_t low,
-                       intptr_t high,
-                       Condition cc,
-                       Label* target) {
-  __ AddImmediate(tmp, val, -low);
-  __ CompareImmediate(tmp, high - low);
-  __ b(target, cc);
-}
-
-const Condition kIfNotInRange = HI;
-const Condition kIfInRange = LS;
-
-static void JumpIfInteger(Assembler* assembler,
-                          Register cid,
-                          Register tmp,
-                          Label* target) {
-  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfInRange, target);
-}
-
-static void JumpIfNotInteger(Assembler* assembler,
-                             Register cid,
-                             Register tmp,
-                             Label* target) {
-  RangeCheck(assembler, cid, tmp, kSmiCid, kMintCid, kIfNotInRange, target);
-}
-
-static void JumpIfString(Assembler* assembler,
-                         Register cid,
-                         Register tmp,
-                         Label* target) {
-  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfInRange, target);
-}
-
-static void JumpIfNotString(Assembler* assembler,
-                            Register cid,
-                            Register tmp,
-                            Label* target) {
-  RangeCheck(assembler, cid, tmp, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfNotInRange, target);
-}
-
-// Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Label use_declaration_type, not_double, not_integer;
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadClassIdMayBeSmi(R1, R0);
-
-  __ CompareImmediate(R1, kClosureCid);
-  __ b(normal_ir_body, EQ);  // Instance is a closure.
-
-  __ CompareImmediate(R1, kNumPredefinedCids);
-  __ b(&use_declaration_type, HI);
-
-  __ CompareImmediate(R1, kDoubleCid);
-  __ b(&not_double, NE);
-
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
-  __ LoadFromOffset(R0, R0, ObjectStore::double_type_offset());
-  __ ret();
-
-  __ Bind(&not_double);
-  JumpIfNotInteger(assembler, R1, R0, &not_integer);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
-  __ LoadFromOffset(R0, R0, ObjectStore::int_type_offset());
-  __ ret();
-
-  __ Bind(&not_integer);
-  JumpIfNotString(assembler, R1, R0, &use_declaration_type);
-  __ LoadIsolate(R0);
-  __ LoadFromOffset(R0, R0, Isolate::object_store_offset());
-  __ LoadFromOffset(R0, R0, ObjectStore::string_type_offset());
-  __ ret();
-
-  __ Bind(&use_declaration_type);
-  __ LoadClassById(R2, R1);  // Overwrites R1.
-  __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword);
-  __ CompareImmediate(R3, 0);
-  __ b(normal_ir_body, NE);
-
-  __ ldr(R0, FieldAddress(R2, Class::declaration_type_offset()));
-  __ CompareObject(R0, Object::null_object());
-  __ b(normal_ir_body, EQ);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label different_cids, equal, not_equal, not_integer;
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ LoadClassIdMayBeSmi(R1, R0);
-
-  // Check if left hand size is a closure. Closures are handled in the runtime.
-  __ CompareImmediate(R1, kClosureCid);
-  __ b(normal_ir_body, EQ);
-
-  __ ldr(R0, Address(SP, 1 * kWordSize));
-  __ LoadClassIdMayBeSmi(R2, R0);
-
-  // Check whether class ids match. If class ids don't match objects can still
-  // have the same runtime type (e.g. multiple string implementation classes
-  // map to a single String type).
-  __ cmp(R1, Operand(R2));
-  __ b(&different_cids, NE);
-
-  // Objects have the same class and neither is a closure.
-  // Check if there are no type arguments. In this case we can return true.
-  // Otherwise fall through into the runtime to handle comparison.
-  __ LoadClassById(R3, R1);  // Overwrites R1.
-  __ ldr(R3, FieldAddress(R3, Class::num_type_arguments_offset()), kHalfword);
-  __ CompareImmediate(R3, 0);
-  __ b(normal_ir_body, NE);
-
-  __ Bind(&equal);
-  __ LoadObject(R0, Bool::True());
-  __ ret();
-
-  // Class ids are different. Check if we are comparing runtime types of
-  // two strings (with different representations) or two integers.
-  __ Bind(&different_cids);
-  __ CompareImmediate(R1, kNumPredefinedCids);
-  __ b(&not_equal, HI);
-
-  // Check if both are integers.
-  JumpIfNotInteger(assembler, R1, R0, &not_integer);
-  JumpIfInteger(assembler, R2, R0, &equal);
-  __ b(&not_equal);
-
-  __ Bind(&not_integer);
-  // Check if both are strings.
-  JumpIfNotString(assembler, R1, R0, &not_equal);
-  JumpIfString(assembler, R2, R0, &equal);
-
-  // Neither strings nor integers and have different class ids.
-  __ Bind(&not_equal);
-  __ LoadObject(R0, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::String_getHashCode(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, String::hash_offset()), kUnsignedWord);
-  __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
-  __ b(normal_ir_body, EQ);
-  __ ret();
-  // Hash not yet computed.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Type_getHashCode(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, Type::hash_offset()));
-  __ cbz(normal_ir_body, R0);
-  __ ret();
-  // Hash not yet computed.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, String::hash_offset()), kUnsignedWord);
-  __ SmiTag(R0);
-  __ ret();
-}
-
-void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // Object.
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Value.
-  __ SmiUntag(R1);
-  __ str(R1, FieldAddress(R0, String::hash_offset()), kUnsignedWord);
-  __ ret();
-}
-
-void GenerateSubstringMatchesSpecialization(Assembler* assembler,
-                                            intptr_t receiver_cid,
-                                            intptr_t other_cid,
-                                            Label* return_true,
-                                            Label* return_false) {
-  __ SmiUntag(R1);
-  __ ldr(R8, FieldAddress(R0, String::length_offset()));  // this.length
-  __ SmiUntag(R8);
-  __ ldr(R9, FieldAddress(R2, String::length_offset()));  // other.length
-  __ SmiUntag(R9);
-
-  // if (other.length == 0) return true;
-  __ cmp(R9, Operand(0));
-  __ b(return_true, EQ);
-
-  // if (start < 0) return false;
-  __ cmp(R1, Operand(0));
-  __ b(return_false, LT);
-
-  // if (start + other.length > this.length) return false;
-  __ add(R3, R1, Operand(R9));
-  __ cmp(R3, Operand(R8));
-  __ b(return_false, GT);
-
-  if (receiver_cid == kOneByteStringCid) {
-    __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
-    __ add(R0, R0, Operand(R1));
-  } else {
-    ASSERT(receiver_cid == kTwoByteStringCid);
-    __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
-    __ add(R0, R0, Operand(R1));
-    __ add(R0, R0, Operand(R1));
-  }
-  if (other_cid == kOneByteStringCid) {
-    __ AddImmediate(R2, OneByteString::data_offset() - kHeapObjectTag);
-  } else {
-    ASSERT(other_cid == kTwoByteStringCid);
-    __ AddImmediate(R2, TwoByteString::data_offset() - kHeapObjectTag);
-  }
-
-  // i = 0
-  __ LoadImmediate(R3, 0);
-
-  // do
-  Label loop;
-  __ Bind(&loop);
-
-  // this.codeUnitAt(i + start)
-  __ ldr(R10, Address(R0, 0),
-         receiver_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
-  // other.codeUnitAt(i)
-  __ ldr(R11, Address(R2, 0),
-         other_cid == kOneByteStringCid ? kUnsignedByte : kUnsignedHalfword);
-  __ cmp(R10, Operand(R11));
-  __ b(return_false, NE);
-
-  // i++, while (i < len)
-  __ add(R3, R3, Operand(1));
-  __ add(R0, R0, Operand(receiver_cid == kOneByteStringCid ? 1 : 2));
-  __ add(R2, R2, Operand(other_cid == kOneByteStringCid ? 1 : 2));
-  __ cmp(R3, Operand(R9));
-  __ b(&loop, LT);
-
-  __ b(return_true);
-}
-
-// bool _substringMatches(int start, String other)
-// This intrinsic handles a OneByteString or TwoByteString receiver with a
-// OneByteString other.
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  Label return_true, return_false, try_two_byte;
-  __ ldr(R0, Address(SP, 2 * kWordSize));  // this
-  __ ldr(R1, Address(SP, 1 * kWordSize));  // start
-  __ ldr(R2, Address(SP, 0 * kWordSize));  // other
-
-  __ BranchIfNotSmi(R1, normal_ir_body);
-
-  __ CompareClassId(R2, kOneByteStringCid);
-  __ b(normal_ir_body, NE);
-
-  __ CompareClassId(R0, kOneByteStringCid);
-  __ b(normal_ir_body, NE);
-
-  GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
-                                         kOneByteStringCid, &return_true,
-                                         &return_false);
-
-  __ Bind(&try_two_byte);
-  __ CompareClassId(R0, kTwoByteStringCid);
-  __ b(normal_ir_body, NE);
-
-  GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
-                                         kOneByteStringCid, &return_true,
-                                         &return_false);
-
-  __ Bind(&return_true);
-  __ LoadObject(R0, Bool::True());
-  __ ret();
-
-  __ Bind(&return_false);
-  __ LoadObject(R0, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::StringBaseCharAt(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Label try_two_byte_string;
-
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // String.
-  __ BranchIfNotSmi(R1, normal_ir_body);   // Index is not a Smi.
-  // Range check.
-  __ ldr(R2, FieldAddress(R0, String::length_offset()));
-  __ cmp(R1, Operand(R2));
-  __ b(normal_ir_body, CS);  // Runtime throws exception.
-
-  __ CompareClassId(R0, kOneByteStringCid);
-  __ b(&try_two_byte_string, NE);
-  __ SmiUntag(R1);
-  __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
-  __ ldr(R1, Address(R0, R1), kUnsignedByte);
-  __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(normal_ir_body, GE);
-  __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
-  __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
-  __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
-  __ ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(R0, kTwoByteStringCid);
-  __ b(normal_ir_body, NE);
-  ASSERT(kSmiTagShift == 1);
-  __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
-  __ ldr(R1, Address(R0, R1), kUnsignedHalfword);
-  __ CompareImmediate(R1, Symbols::kNumberOfOneCharCodeSymbols);
-  __ b(normal_ir_body, GE);
-  __ ldr(R0, Address(THR, Thread::predefined_symbols_address_offset()));
-  __ AddImmediate(R0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
-  __ ldr(R0, Address(R0, R1, UXTX, Address::Scaled));
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R0, FieldAddress(R0, String::length_offset()));
-  __ cmp(R0, Operand(Smi::RawValue(0)));
-  __ LoadObject(R0, Bool::True());
-  __ LoadObject(TMP, Bool::False());
-  __ csel(R0, TMP, R0, NE);
-  __ ret();
-}
-
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label compute_hash;
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // OneByteString object.
-  __ ldr(R0, FieldAddress(R1, String::hash_offset()), kUnsignedWord);
-  __ adds(R0, R0, Operand(R0));  // Smi tag the hash code, setting Z flag.
-  __ b(&compute_hash, EQ);
-  __ ret();  // Return if already computed.
-
-  __ Bind(&compute_hash);
-  __ ldr(R2, FieldAddress(R1, String::length_offset()));
-  __ SmiUntag(R2);
-
-  Label done;
-  // If the string is empty, set the hash to 1, and return.
-  __ CompareRegisters(R2, ZR);
-  __ b(&done, EQ);
-
-  __ mov(R3, ZR);
-  __ AddImmediate(R6, R1, OneByteString::data_offset() - kHeapObjectTag);
-  // R1: Instance of OneByteString.
-  // R2: String length, untagged integer.
-  // R3: Loop counter, untagged integer.
-  // R6: String data.
-  // R0: Hash code, untagged integer.
-
-  Label loop;
-  // Add to hash code: (hash_ is uint32)
-  // hash_ += ch;
-  // hash_ += hash_ << 10;
-  // hash_ ^= hash_ >> 6;
-  // Get one characters (ch).
-  __ Bind(&loop);
-  __ ldr(R7, Address(R6, R3), kUnsignedByte);
-  // R7: ch.
-  __ add(R3, R3, Operand(1));
-  __ addw(R0, R0, Operand(R7));
-  __ addw(R0, R0, Operand(R0, LSL, 10));
-  __ eorw(R0, R0, Operand(R0, LSR, 6));
-  __ cmp(R3, Operand(R2));
-  __ b(&loop, NE);
-
-  // Finalize.
-  // hash_ += hash_ << 3;
-  // hash_ ^= hash_ >> 11;
-  // hash_ += hash_ << 15;
-  __ addw(R0, R0, Operand(R0, LSL, 3));
-  __ eorw(R0, R0, Operand(R0, LSR, 11));
-  __ addw(R0, R0, Operand(R0, LSL, 15));
-  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
-  __ AndImmediate(R0, R0, (static_cast<intptr_t>(1) << String::kHashBits) - 1);
-  __ CompareRegisters(R0, ZR);
-  // return hash_ == 0 ? 1 : hash_;
-  __ Bind(&done);
-  __ csinc(R0, R0, ZR, NE);  // R0 <- (R0 != 0) ? R0 : (ZR + 1).
-  __ str(R0, FieldAddress(R1, String::hash_offset()), kUnsignedWord);
-  __ SmiTag(R0);
-  __ ret();
-}
-
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized.
-// 'length-reg' (R2) contains tagged length.
-// Returns new string as tagged pointer in R0.
-static void TryAllocateOnebyteString(Assembler* assembler,
-                                     Label* ok,
-                                     Label* failure) {
-  const Register length_reg = R2;
-  Label fail;
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, R0, failure));
-  __ mov(R6, length_reg);  // Save the length register.
-  // TODO(koda): Protect against negative length and overflow here.
-  __ adds(length_reg, ZR, Operand(length_reg, ASR, kSmiTagSize));  // Smi untag.
-  // If the length is 0 then we have to make the allocated size a bit bigger,
-  // otherwise the string takes up less space than an ExternalOneByteString,
-  // and cannot be externalized.  TODO(erikcorry): We should probably just
-  // return a static zero length string here instead.
-  // length <- (length != 0) ? length : (ZR + 1).
-  __ csinc(length_reg, length_reg, ZR, NE);
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawString) + kObjectAlignment - 1;
-  __ AddImmediate(length_reg, fixed_size_plus_alignment_padding);
-  __ andi(length_reg, length_reg, Immediate(~(kObjectAlignment - 1)));
-
-  const intptr_t cid = kOneByteStringCid;
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  __ ldr(R0, Address(THR, Thread::top_offset()));
-
-  // length_reg: allocation size.
-  __ adds(R1, R0, Operand(length_reg));
-  __ b(&fail, CS);  // Fail on unsigned overflow.
-
-  // Check if the allocation fits into the remaining space.
-  // R0: potential new object start.
-  // R1: potential next object start.
-  // R2: allocation size.
-  __ ldr(R7, Address(THR, Thread::end_offset()));
-  __ cmp(R1, Operand(R7));
-  __ b(&fail, CS);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  __ str(R1, Address(THR, Thread::top_offset()));
-  __ AddImmediate(R0, kHeapObjectTag);
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space));
-
-  // Initialize the tags.
-  // R0: new object start as a tagged pointer.
-  // R1: new object end address.
-  // R2: allocation size.
-  {
-    const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
-
-    __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
-    __ LslImmediate(R2, R2, shift);
-    __ csel(R2, R2, ZR, LS);
-
-    // Get the class index and insert it into the tags.
-    // R2: size and bit tags.
-    // This also clears the hash, which is in the high word of the tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(TMP, tags);
-    __ orr(R2, R2, Operand(TMP));
-    __ str(R2, FieldAddress(R0, String::tags_offset()));  // Store tags.
-  }
-
-  // Set the length field using the saved length (R6).
-  __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, String::length_offset()),
-                              R6);
-  __ b(ok);
-
-  __ Bind(&fail);
-  __ b(failure);
-}
-
-// Arg0: OneByteString (receiver).
-// Arg1: Start index as Smi.
-// Arg2: End index as Smi.
-// The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
-                                                    Label* normal_ir_body) {
-  const intptr_t kStringOffset = 2 * kWordSize;
-  const intptr_t kStartIndexOffset = 1 * kWordSize;
-  const intptr_t kEndIndexOffset = 0 * kWordSize;
-  Label ok;
-
-  __ ldr(R2, Address(SP, kEndIndexOffset));
-  __ ldr(TMP, Address(SP, kStartIndexOffset));
-  __ orr(R3, R2, Operand(TMP));
-  __ BranchIfNotSmi(R3, normal_ir_body);  // 'start', 'end' not Smi.
-
-  __ sub(R2, R2, Operand(TMP));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
-  __ Bind(&ok);
-  // R0: new string as tagged pointer.
-  // Copy string.
-  __ ldr(R3, Address(SP, kStringOffset));
-  __ ldr(R1, Address(SP, kStartIndexOffset));
-  __ SmiUntag(R1);
-  __ add(R3, R3, Operand(R1));
-  // Calculate start address and untag (- 1).
-  __ AddImmediate(R3, OneByteString::data_offset() - 1);
-
-  // R3: Start address to copy from (untagged).
-  // R1: Untagged start index.
-  __ ldr(R2, Address(SP, kEndIndexOffset));
-  __ SmiUntag(R2);
-  __ sub(R2, R2, Operand(R1));
-
-  // R3: Start address to copy from (untagged).
-  // R2: Untagged number of bytes to copy.
-  // R0: Tagged result string.
-  // R6: Pointer into R3.
-  // R7: Pointer into R0.
-  // R1: Scratch register.
-  Label loop, done;
-  __ cmp(R2, Operand(0));
-  __ b(&done, LE);
-  __ mov(R6, R3);
-  __ mov(R7, R0);
-  __ Bind(&loop);
-  __ ldr(R1, Address(R6), kUnsignedByte);
-  __ AddImmediate(R6, 1);
-  __ sub(R2, R2, Operand(1));
-  __ cmp(R2, Operand(0));
-  __ str(R1, FieldAddress(R7, OneByteString::data_offset()), kUnsignedByte);
-  __ AddImmediate(R7, 1);
-  __ b(&loop, GT);
-
-  __ Bind(&done);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ ldr(R2, Address(SP, 0 * kWordSize));  // Value.
-  __ ldr(R1, Address(SP, 1 * kWordSize));  // Index.
-  __ ldr(R0, Address(SP, 2 * kWordSize));  // OneByteString.
-  __ SmiUntag(R1);
-  __ SmiUntag(R2);
-  __ AddImmediate(R3, R0, OneByteString::data_offset() - kHeapObjectTag);
-  __ str(R2, Address(R3, R1), kUnsignedByte);
-  __ ret();
-}
-
-void Intrinsifier::OneByteString_allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  Label ok;
-
-  __ ldr(R2, Address(SP, 0 * kWordSize));  // Length.
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body);
-
-  __ Bind(&ok);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler,
-                           Label* normal_ir_body,
-                           intptr_t string_cid) {
-  Label is_true, is_false, loop;
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // This.
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Other.
-
-  // Are identical?
-  __ cmp(R0, Operand(R1));
-  __ b(&is_true, EQ);
-
-  // Is other OneByteString?
-  __ BranchIfSmi(R1, normal_ir_body);
-  __ CompareClassId(R1, string_cid);
-  __ b(normal_ir_body, NE);
-
-  // Have same length?
-  __ ldr(R2, FieldAddress(R0, String::length_offset()));
-  __ ldr(R3, FieldAddress(R1, String::length_offset()));
-  __ cmp(R2, Operand(R3));
-  __ b(&is_false, NE);
-
-  // Check contents, no fall-through possible.
-  // TODO(zra): try out other sequences.
-  ASSERT((string_cid == kOneByteStringCid) ||
-         (string_cid == kTwoByteStringCid));
-  const intptr_t offset = (string_cid == kOneByteStringCid)
-                              ? OneByteString::data_offset()
-                              : TwoByteString::data_offset();
-  __ AddImmediate(R0, offset - kHeapObjectTag);
-  __ AddImmediate(R1, offset - kHeapObjectTag);
-  __ SmiUntag(R2);
-  __ Bind(&loop);
-  __ AddImmediate(R2, -1);
-  __ CompareRegisters(R2, ZR);
-  __ b(&is_true, LT);
-  if (string_cid == kOneByteStringCid) {
-    __ ldr(R3, Address(R0), kUnsignedByte);
-    __ ldr(R4, Address(R1), kUnsignedByte);
-    __ AddImmediate(R0, 1);
-    __ AddImmediate(R1, 1);
-  } else if (string_cid == kTwoByteStringCid) {
-    __ ldr(R3, Address(R0), kUnsignedHalfword);
-    __ ldr(R4, Address(R1), kUnsignedHalfword);
-    __ AddImmediate(R0, 2);
-    __ AddImmediate(R1, 2);
-  } else {
-    UNIMPLEMENTED();
-  }
-  __ cmp(R3, Operand(R4));
-  __ b(&is_false, NE);
-  __ b(&loop);
-
-  __ Bind(&is_true);
-  __ LoadObject(R0, Bool::True());
-  __ ret();
-
-  __ Bind(&is_false);
-  __ LoadObject(R0, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
-}
-
-void Intrinsifier::TwoByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
-}
-
-void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
-                                                Label* normal_ir_body,
-                                                bool sticky) {
-  if (FLAG_interpret_irregexp) return;
-
-  static const intptr_t kRegExpParamOffset = 2 * kWordSize;
-  static const intptr_t kStringParamOffset = 1 * kWordSize;
-  // start_index smi is located at offset 0.
-
-  // Incoming registers:
-  // R0: Function. (Will be reloaded with the specialized matcher function.)
-  // R4: Arguments descriptor. (Will be preserved.)
-  // R5: Unknown. (Must be GC safe on tail call.)
-
-  // Load the specialized function pointer into R0. Leverage the fact the
-  // string CIDs as well as stored function pointers are in sequence.
-  __ ldr(R2, Address(SP, kRegExpParamOffset));
-  __ ldr(R1, Address(SP, kStringParamOffset));
-  __ LoadClassId(R1, R1);
-  __ AddImmediate(R1, -kOneByteStringCid);
-  __ add(R1, R2, Operand(R1, LSL, kWordSizeLog2));
-  __ ldr(R0,
-         FieldAddress(R1, RegExp::function_offset(kOneByteStringCid, sticky)));
-
-  // Registers are now set up for the lazy compile stub. It expects the function
-  // in R0, the argument descriptor in R4, and IC-Data in R5.
-  __ eor(R5, R5, Operand(R5));
-
-  // Tail-call the function.
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
-  __ br(R1);
-}
-
-// On stack: user tag (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  // R1: Isolate.
-  __ LoadIsolate(R1);
-  // R0: Current user tag.
-  __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
-  // R2: UserTag.
-  __ ldr(R2, Address(SP, +0 * kWordSize));
-  // Set Isolate::current_tag_.
-  __ str(R2, Address(R1, Isolate::current_tag_offset()));
-  // R2: UserTag's tag.
-  __ ldr(R2, FieldAddress(R2, UserTag::tag_offset()));
-  // Set Isolate::user_tag_.
-  __ str(R2, Address(R1, Isolate::user_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ LoadIsolate(R0);
-  __ ldr(R0, Address(R0, Isolate::default_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ LoadIsolate(R0);
-  __ ldr(R0, Address(R0, Isolate::current_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  if (!FLAG_support_timeline) {
-    __ LoadObject(R0, Bool::False());
-    __ ret();
-  }
-  // Load TimelineStream*.
-  __ ldr(R0, Address(THR, Thread::dart_stream_offset()));
-  // Load uintptr_t from TimelineStream*.
-  __ ldr(R0, Address(R0, TimelineStream::enabled_offset()));
-  __ cmp(R0, Operand(0));
-  __ LoadObject(R0, Bool::False());
-  __ LoadObject(TMP, Bool::True());
-  __ csel(R0, TMP, R0, NE);
-  __ ret();
-}
-
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  __ LoadObject(R0, Object::null_object());
-  __ str(R0, Address(THR, Thread::async_stack_trace_offset()));
-  __ ret();
-}
-
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  __ ldr(R0, Address(THR, Thread::async_stack_trace_offset()));
-  __ LoadObject(R0, Object::null_object());
-  __ ret();
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/intrinsifier_dbc.cc b/runtime/vm/compiler/intrinsifier_dbc.cc
deleted file mode 100644
index b09a15f..0000000
--- a/runtime/vm/compiler/intrinsifier_dbc.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"  // Needed here to get TARGET_ARCH_DBC.
-#if defined(TARGET_ARCH_DBC)
-
-#include "vm/compiler/intrinsifier.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/object.h"
-#include "vm/object_store.h"
-#include "vm/regexp_assembler.h"
-#include "vm/simulator.h"
-#include "vm/symbols.h"
-
-namespace dart {
-
-DECLARE_FLAG(bool, interpret_irregexp);
-
-intptr_t Intrinsifier::ParameterSlotFromSp() {
-  return -1;
-}
-
-#define DEFINE_FUNCTION(class_name, test_function_name, enum_name, fp)         \
-  void Intrinsifier::enum_name(Assembler* assembler, Label* normal_ir_body) {  \
-    if (Simulator::IsSupportedIntrinsic(Simulator::k##enum_name##Intrinsic)) { \
-      assembler->Intrinsic(Simulator::k##enum_name##Intrinsic);                \
-    }                                                                          \
-    assembler->Bind(normal_ir_body);                                           \
-  }
-
-ALL_INTRINSICS_LIST(DEFINE_FUNCTION)
-GRAPH_INTRINSICS_LIST(DEFINE_FUNCTION)
-#undef DEFINE_FUNCTION
-
-}  // namespace dart
-
-#endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/compiler/intrinsifier_ia32.cc b/runtime/vm/compiler/intrinsifier_ia32.cc
deleted file mode 100644
index cfb50f6..0000000
--- a/runtime/vm/compiler/intrinsifier_ia32.cc
+++ /dev/null
@@ -1,2243 +0,0 @@
-// 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.
-//
-// The intrinsic code below is executed before a method has built its frame.
-// The return address is on the stack and the arguments below it.
-// Registers EDX (arguments descriptor) and ECX (function) must be preserved.
-// Each intrinsification method returns true if the corresponding
-// Dart method was intrinsified.
-
-#include "vm/globals.h"  // Needed here to get TARGET_ARCH_IA32.
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/intrinsifier.h"
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/dart_entry.h"
-#include "vm/object.h"
-#include "vm/object_store.h"
-#include "vm/os.h"
-#include "vm/regexp_assembler.h"
-#include "vm/symbols.h"
-#include "vm/timeline.h"
-
-namespace dart {
-
-// When entering intrinsics code:
-// ECX: IC Data
-// EDX: Arguments descriptor
-// TOS: Return address
-// The ECX, EDX registers can be destroyed only if there is no slow-path, i.e.
-// if the intrinsified method always executes a return.
-// The EBP register should not be modified, because it is used by the profiler.
-// The THR register (see constants_ia32.h) must be preserved.
-
-#define __ assembler->
-
-intptr_t Intrinsifier::ParameterSlotFromSp() {
-  return 0;
-}
-
-void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
-
-  assembler->Comment("IntrinsicCallPrologue");
-  assembler->movl(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
-}
-
-void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
-  assembler->Comment("IntrinsicCallEpilogue");
-  assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
-}
-
-// Allocate a GrowableObjectArray using the backing array specified.
-// On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  // This snippet of inlined code uses the following registers:
-  // EAX, EBX
-  // and the newly allocated object is returned in EAX.
-  const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
-
-  const intptr_t kArrayOffset = 1 * kWordSize;
-
-  // Try allocating in new space.
-  const Class& cls = Class::Handle(
-      Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, normal_ir_body, Assembler::kNearJump, EAX, EBX);
-
-  // Store backing array object in growable array object.
-  __ movl(EBX, Address(ESP, kArrayOffset));  // data argument.
-  // EAX is new, no barrier needed.
-  __ StoreIntoObjectNoBarrier(
-      EAX, FieldAddress(EAX, GrowableObjectArray::data_offset()), EBX);
-
-  // EAX: new growable array object start as a tagged pointer.
-  // Store the type argument field in the growable array object.
-  __ movl(EBX, Address(ESP, kTypeArgumentsOffset));  // type argument.
-  __ StoreIntoObjectNoBarrier(
-      EAX, FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()),
-      EBX);
-
-  __ ZeroInitSmiField(FieldAddress(EAX, GrowableObjectArray::length_offset()));
-  __ ret();  // returns the newly allocated object in EAX.
-
-  __ Bind(normal_ir_body);
-}
-
-#define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor)          \
-  const intptr_t kArrayLengthStackOffset = 1 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, EDI, normal_ir_body, false));    \
-  __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */     \
-  /* Check that length is a positive Smi. */                                   \
-  /* EDI: requested array length argument. */                                  \
-  __ testl(EDI, Immediate(kSmiTagMask));                                       \
-  __ j(NOT_ZERO, normal_ir_body);                                              \
-  __ cmpl(EDI, Immediate(0));                                                  \
-  __ j(LESS, normal_ir_body);                                                  \
-  __ SmiUntag(EDI);                                                            \
-  /* Check for maximum allowed length. */                                      \
-  /* EDI: untagged array length. */                                            \
-  __ cmpl(EDI, Immediate(max_len));                                            \
-  __ j(GREATER, normal_ir_body);                                               \
-  /* Special case for scaling by 16. */                                        \
-  if (scale_factor == TIMES_16) {                                              \
-    /* double length of array. */                                              \
-    __ addl(EDI, EDI);                                                         \
-    /* only scale by 8. */                                                     \
-    scale_factor = TIMES_8;                                                    \
-  }                                                                            \
-  const intptr_t fixed_size_plus_alignment_padding =                           \
-      sizeof(Raw##type_name) + kObjectAlignment - 1;                           \
-  __ leal(EDI, Address(EDI, scale_factor, fixed_size_plus_alignment_padding)); \
-  __ andl(EDI, Immediate(-kObjectAlignment));                                  \
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);                              \
-  __ movl(EAX, Address(THR, Thread::top_offset()));                            \
-  __ movl(EBX, EAX);                                                           \
-                                                                               \
-  /* EDI: allocation size. */                                                  \
-  __ addl(EBX, EDI);                                                           \
-  __ j(CARRY, normal_ir_body);                                                 \
-                                                                               \
-  /* Check if the allocation fits into the remaining space. */                 \
-  /* EAX: potential new object start. */                                       \
-  /* EBX: potential next object start. */                                      \
-  /* EDI: allocation size. */                                                  \
-  __ cmpl(EBX, Address(THR, Thread::end_offset()));                            \
-  __ j(ABOVE_EQUAL, normal_ir_body);                                           \
-                                                                               \
-  /* Successfully allocated the object(s), now update top to point to */       \
-  /* next object start and initialize the object. */                           \
-  __ movl(Address(THR, Thread::top_offset()), EBX);                            \
-  __ addl(EAX, Immediate(kHeapObjectTag));                                     \
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EDI, ECX, space));      \
-                                                                               \
-  /* Initialize the tags. */                                                   \
-  /* EAX: new object start as a tagged pointer. */                             \
-  /* EBX: new object end address. */                                           \
-  /* EDI: allocation size. */                                                  \
-  {                                                                            \
-    Label size_tag_overflow, done;                                             \
-    __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));                  \
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);                     \
-    __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));    \
-    __ jmp(&done, Assembler::kNearJump);                                       \
-                                                                               \
-    __ Bind(&size_tag_overflow);                                               \
-    __ movl(EDI, Immediate(0));                                                \
-    __ Bind(&done);                                                            \
-                                                                               \
-    /* Get the class index and insert it into the tags. */                     \
-    uint32_t tags = 0;                                                         \
-    tags = RawObject::ClassIdTag::update(cid, tags);                           \
-    tags = RawObject::NewBit::update(true, tags);                              \
-    __ orl(EDI, Immediate(tags));                                              \
-    __ movl(FieldAddress(EAX, type_name::tags_offset()), EDI); /* Tags. */     \
-  }                                                                            \
-  /* Set the length field. */                                                  \
-  /* EAX: new object start as a tagged pointer. */                             \
-  /* EBX: new object end address. */                                           \
-  __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */     \
-  __ StoreIntoObjectNoBarrier(                                                 \
-      EAX, FieldAddress(EAX, type_name::length_offset()), EDI);                \
-  /* Initialize all array elements to 0. */                                    \
-  /* EAX: new object start as a tagged pointer. */                             \
-  /* EBX: new object end address. */                                           \
-  /* EDI: iterator which initially points to the start of the variable */      \
-  /* ECX: scratch register. */                                                 \
-  /* data area to be initialized. */                                           \
-  __ xorl(ECX, ECX); /* Zero. */                                               \
-  __ leal(EDI, FieldAddress(EAX, sizeof(Raw##type_name)));                     \
-  Label done, init_loop;                                                       \
-  __ Bind(&init_loop);                                                         \
-  __ cmpl(EDI, EBX);                                                           \
-  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);                              \
-  __ movl(Address(EDI, 0), ECX);                                               \
-  __ addl(EDI, Immediate(kWordSize));                                          \
-  __ jmp(&init_loop, Assembler::kNearJump);                                    \
-  __ Bind(&done);                                                              \
-                                                                               \
-  __ ret();                                                                    \
-  __ Bind(normal_ir_body);
-
-static ScaleFactor GetScaleFactor(intptr_t size) {
-  switch (size) {
-    case 1:
-      return TIMES_1;
-    case 2:
-      return TIMES_2;
-    case 4:
-      return TIMES_4;
-    case 8:
-      return TIMES_8;
-    case 16:
-      return TIMES_16;
-  }
-  UNREACHABLE();
-  return static_cast<ScaleFactor>(0);
-}
-
-#define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
-                                                 Label* normal_ir_body) {      \
-    intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
-    intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
-    ScaleFactor scale = GetScaleFactor(size);                                  \
-    TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale); \
-  }
-CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
-#undef TYPED_DATA_ALLOCATOR
-
-// Tests if two top most arguments are smis, jumps to label not_smi if not.
-// Topmost argument is in EAX.
-static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ movl(EBX, Address(ESP, +2 * kWordSize));
-  __ orl(EBX, EAX);
-  __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, not_smi, Assembler::kNearJump);
-}
-
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ addl(EAX, Address(ESP, +2 * kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  Integer_addFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ subl(EAX, Address(ESP, +2 * kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, EAX);
-  __ movl(EAX, Address(ESP, +2 * kWordSize));
-  __ subl(EAX, EBX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
-  __ SmiUntag(EAX);
-  __ imull(EAX, Address(ESP, +2 * kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  Integer_mulFromInteger(assembler, normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// EAX: Tagged left (dividend).
-// EBX: Tagged right (divisor).
-// Returns:
-//   EDX: Untagged fallthrough result (remainder to be adjusted), or
-//   EAX: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, modulo;
-  // Check for quick zero results.
-  __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-  __ cmpl(EAX, EBX);
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-
-  // Check if result equals left.
-  __ cmpl(EAX, Immediate(0));
-  __ j(LESS, &modulo, Assembler::kNearJump);
-  // left is positive.
-  __ cmpl(EAX, EBX);
-  __ j(GREATER, &modulo, Assembler::kNearJump);
-  // left is less than right, result is left (EAX).
-  __ ret();
-
-  __ Bind(&return_zero);
-  __ xorl(EAX, EAX);
-  __ ret();
-
-  __ Bind(&modulo);
-  __ SmiUntag(EBX);
-  __ SmiUntag(EAX);
-  __ cdq();
-  __ idivl(EBX);
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label subtract;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * kWordSize));
-  // EAX: Tagged left (dividend).
-  // EBX: Tagged right (divisor).
-  // Check if modulo by zero -> exception thrown in main function.
-  __ cmpl(EBX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  EmitRemainderOperation(assembler);
-  // Untagged remainder result in EDX.
-  Label done;
-  __ movl(EAX, EDX);
-  __ cmpl(EAX, Immediate(0));
-  __ j(GREATER_EQUAL, &done, Assembler::kNearJump);
-  // Result is negative, adjust it.
-  __ cmpl(EBX, Immediate(0));
-  __ j(LESS, &subtract, Assembler::kNearJump);
-  __ addl(EAX, EBX);
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(&subtract);
-  __ subl(EAX, EBX);
-
-  __ Bind(&done);
-  // The remainder of two smis is always a smi, no overflow check needed.
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_truncDivide(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // EAX: right argument (divisor)
-  __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movl(EBX, EAX);
-  __ SmiUntag(EBX);
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Left argument (dividend).
-  __ SmiUntag(EAX);
-  __ pushl(EDX);  // Preserve EDX in case of 'fall_through'.
-  __ cdq();
-  __ idivl(EBX);
-  __ popl(EDX);
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ cmpl(EAX, Immediate(0x40000000));
-  __ j(EQUAL, normal_ir_body);
-  __ SmiTag(EAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
-  __ negl(EAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * kWordSize));
-  __ andl(EAX, EBX);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * kWordSize));
-  __ orl(EAX, EBX);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitOrFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movl(EBX, Address(ESP, +2 * kWordSize));
-  __ xorl(EAX, EBX);
-  // Result is in EAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitXorFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
-  ASSERT(kSmiTagShift == 1);
-  ASSERT(kSmiTag == 0);
-  Label overflow;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Shift value is in EAX. Compare with tagged Smi.
-  __ cmpl(EAX, Immediate(Smi::RawValue(Smi::kBits)));
-  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
-
-  __ SmiUntag(EAX);
-  __ movl(ECX, EAX);                           // Shift amount must be in ECX.
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Value.
-
-  // Overflow test - all the shifted-out bits must be same as the sign bit.
-  __ movl(EBX, EAX);
-  __ shll(EAX, ECX);
-  __ sarl(EAX, ECX);
-  __ cmpl(EAX, EBX);
-  __ j(NOT_EQUAL, &overflow, Assembler::kNearJump);
-
-  __ shll(EAX, ECX);  // Shift for result now we know there is no overflow.
-
-  // EAX is a correctly tagged Smi.
-  __ ret();
-
-  __ Bind(&overflow);
-  // Arguments are Smi but the shift produced an overflow to Mint.
-  __ cmpl(EBX, Immediate(0));
-  // TODO(srdjan): Implement negative values, for now fall through.
-  __ j(LESS, normal_ir_body, Assembler::kNearJump);
-  __ SmiUntag(EBX);
-  __ movl(EAX, EBX);
-  __ shll(EBX, ECX);
-  __ xorl(EDI, EDI);
-  __ shldl(EDI, EAX, ECX);
-  // Result in EDI (high) and EBX (low).
-  const Class& mint_class =
-      Class::Handle(Isolate::Current()->object_store()->mint_class());
-  __ TryAllocate(mint_class, normal_ir_body, Assembler::kNearJump,
-                 EAX,   // Result register.
-                 ECX);  // temp
-  // EBX and EDI are not objects but integer values.
-  __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
-  __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-static void Push64SmiOrMint(Assembler* assembler,
-                            Register reg,
-                            Register tmp,
-                            Label* not_smi_or_mint) {
-  Label not_smi, done;
-  __ testl(reg, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
-  __ SmiUntag(reg);
-  // Sign extend to 64 bit
-  __ movl(tmp, reg);
-  __ sarl(tmp, Immediate(31));
-  __ pushl(tmp);
-  __ pushl(reg);
-  __ jmp(&done);
-  __ Bind(&not_smi);
-  __ CompareClassId(reg, kMintCid, tmp);
-  __ j(NOT_EQUAL, not_smi_or_mint);
-  // Mint.
-  __ pushl(FieldAddress(reg, Mint::value_offset() + kWordSize));
-  __ pushl(FieldAddress(reg, Mint::value_offset()));
-  __ Bind(&done);
-}
-
-static void CompareIntegers(Assembler* assembler,
-                            Label* normal_ir_body,
-                            Condition true_condition) {
-  Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
-  TestBothArgumentsSmis(assembler, &try_mint_smi);
-  // EAX contains the right argument.
-  __ cmpl(Address(ESP, +2 * kWordSize), EAX);
-  __ j(true_condition, &is_true, Assembler::kNearJump);
-  __ Bind(&is_false);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-
-  // 64-bit comparison
-  Condition hi_true_cond, hi_false_cond, lo_false_cond;
-  switch (true_condition) {
-    case LESS:
-    case LESS_EQUAL:
-      hi_true_cond = LESS;
-      hi_false_cond = GREATER;
-      lo_false_cond = (true_condition == LESS) ? ABOVE_EQUAL : ABOVE;
-      break;
-    case GREATER:
-    case GREATER_EQUAL:
-      hi_true_cond = GREATER;
-      hi_false_cond = LESS;
-      lo_false_cond = (true_condition == GREATER) ? BELOW_EQUAL : BELOW;
-      break;
-    default:
-      UNREACHABLE();
-      hi_true_cond = hi_false_cond = lo_false_cond = OVERFLOW;
-  }
-  __ Bind(&try_mint_smi);
-  // Note that EDX and ECX must be preserved in case we fall through to main
-  // method.
-  // EAX contains the right argument.
-  __ movl(EBX, Address(ESP, +2 * kWordSize));  // Left argument.
-  // Push left as 64 bit integer.
-  Push64SmiOrMint(assembler, EBX, EDI, normal_ir_body);
-  // Push right as 64 bit integer.
-  Push64SmiOrMint(assembler, EAX, EDI, &drop_two_fall_through);
-  __ popl(EBX);       // Right.LO.
-  __ popl(ECX);       // Right.HI.
-  __ popl(EAX);       // Left.LO.
-  __ popl(EDX);       // Left.HI.
-  __ cmpl(EDX, ECX);  // cmpl left.HI, right.HI.
-  __ j(hi_false_cond, &is_false, Assembler::kNearJump);
-  __ j(hi_true_cond, &is_true, Assembler::kNearJump);
-  __ cmpl(EAX, EBX);  // cmpl left.LO, right.LO.
-  __ j(lo_false_cond, &is_false, Assembler::kNearJump);
-  // Else is true.
-  __ jmp(&is_true);
-
-  __ Bind(&drop_two_fall_through);
-  __ Drop(2);
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LESS);
-}
-
-void Intrinsifier::Integer_lessThan(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Integer_greaterThanFromInt(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_greaterThan(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GREATER);
-}
-
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LESS_EQUAL);
-}
-
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GREATER_EQUAL);
-}
-
-// This is called for Smi and Mint receivers. The right argument
-// can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  Label true_label, check_for_mint;
-  // For integer receiver '===' check first.
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ cmpl(EAX, Address(ESP, +2 * kWordSize));
-  __ j(EQUAL, &true_label, Assembler::kNearJump);
-  __ movl(EBX, Address(ESP, +2 * kWordSize));
-  __ orl(EAX, EBX);
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
-  // Both arguments are smi, '===' is good enough.
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&true_label);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-
-  // At least one of the arguments was not Smi.
-  Label receiver_not_smi;
-  __ Bind(&check_for_mint);
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Receiver.
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &receiver_not_smi);
-
-  // Left (receiver) is Smi, return false if right is not Double.
-  // Note that an instance of Mint never contains a value that can be
-  // represented by Smi.
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // Right argument.
-  __ CompareClassId(EAX, kDoubleCid, EDI);
-  __ j(EQUAL, normal_ir_body);
-  __ LoadObject(EAX, Bool::False());  // Smi == Mint -> false.
-  __ ret();
-
-  __ Bind(&receiver_not_smi);
-  // EAX:: receiver.
-  __ CompareClassId(EAX, kMintCid, EDI);
-  __ j(NOT_EQUAL, normal_ir_body);
-  // Receiver is Mint, return false if right is Smi.
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // Right argument.
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  // TODO(srdjan): Implement Mint == Mint comparison.
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
-  Integer_equalToInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  Label shift_count_ok;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Can destroy ECX since we are not falling through.
-  const Immediate& count_limit = Immediate(0x1F);
-  // Check that the count is not larger than what the hardware can handle.
-  // For shifting right a Smi the result is the same for all numbers
-  // >= count_limit.
-  __ SmiUntag(EAX);
-  // Negative counts throw exception.
-  __ cmpl(EAX, Immediate(0));
-  __ j(LESS, normal_ir_body, Assembler::kNearJump);
-  __ cmpl(EAX, count_limit);
-  __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
-  __ movl(EAX, count_limit);
-  __ Bind(&shift_count_ok);
-  __ movl(ECX, EAX);                           // Shift amount must be in ECX.
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Value.
-  __ SmiUntag(EAX);                            // Value.
-  __ sarl(EAX, ECX);
-  __ SmiTag(EAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Argument is Smi (receiver).
-void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // Receiver.
-  __ notl(EAX);
-  __ andl(EAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
-  __ ret();
-}
-
-void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
-  ASSERT(kSmiTagShift == 1);
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // Receiver.
-  // XOR with sign bit to complement bits if value is negative.
-  __ movl(ECX, EAX);
-  __ sarl(ECX, Immediate(31));  // All 0 or all 1.
-  __ xorl(EAX, ECX);
-  // BSR does not write the destination register if source is zero.  Put a 1 in
-  // the Smi tag bit to ensure BSR writes to destination register.
-  __ orl(EAX, Immediate(kSmiTagMask));
-  __ bsrl(EAX, EAX);
-  __ SmiTag(EAX);
-  __ ret();
-}
-
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  // Preserve THR to free ESI.
-  __ pushl(THR);
-  ASSERT(THR == ESI);
-
-  __ movl(EDI, Address(ESP, 5 * kWordSize));  // x_digits
-  __ movl(ECX, Address(ESP, 3 * kWordSize));  // n is Smi
-  __ SmiUntag(ECX);
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
-  __ movl(ESI, ECX);
-  __ sarl(ESI, Immediate(5));  // ESI = n ~/ _DIGIT_BITS.
-  __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset()));
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // x_used > 0, Smi.
-  __ SmiUntag(ESI);
-  __ decl(ESI);
-  __ xorl(EAX, EAX);  // EAX = 0.
-  __ movl(EDX, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset()));
-  __ shldl(EAX, EDX, ECX);
-  __ movl(Address(EBX, ESI, TIMES_4, kBytesPerBigIntDigit), EAX);
-  Label last;
-  __ cmpl(ESI, Immediate(0));
-  __ j(EQUAL, &last, Assembler::kNearJump);
-  Label loop;
-  __ Bind(&loop);
-  __ movl(EAX, EDX);
-  __ movl(EDX, FieldAddress(EDI, ESI, TIMES_4,
-                            TypedData::data_offset() - kBytesPerBigIntDigit));
-  __ shldl(EAX, EDX, ECX);
-  __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
-  __ decl(ESI);
-  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
-  __ Bind(&last);
-  __ shldl(EDX, ESI, ECX);  // ESI == 0.
-  __ movl(Address(EBX, 0), EDX);
-
-  // Restore THR and return.
-  __ popl(THR);
-  __ LoadObject(EAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _rsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  // Preserve THR to free ESI.
-  __ pushl(THR);
-  ASSERT(THR == ESI);
-
-  __ movl(EDI, Address(ESP, 5 * kWordSize));  // x_digits
-  __ movl(ECX, Address(ESP, 3 * kWordSize));  // n is Smi
-  __ SmiUntag(ECX);
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
-  __ movl(EDX, ECX);
-  __ sarl(EDX, Immediate(5));                 // EDX = n ~/ _DIGIT_BITS.
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // x_used > 0, Smi.
-  __ SmiUntag(ESI);
-  __ decl(ESI);
-  // EDI = &x_digits[x_used - 1].
-  __ leal(EDI, FieldAddress(EDI, ESI, TIMES_4, TypedData::data_offset()));
-  __ subl(ESI, EDX);
-  // EBX = &r_digits[x_used - 1 - (n ~/ 32)].
-  __ leal(EBX, FieldAddress(EBX, ESI, TIMES_4, TypedData::data_offset()));
-  __ negl(ESI);
-  __ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
-  Label last;
-  __ cmpl(ESI, Immediate(0));
-  __ j(EQUAL, &last, Assembler::kNearJump);
-  Label loop;
-  __ Bind(&loop);
-  __ movl(EAX, EDX);
-  __ movl(EDX, Address(EDI, ESI, TIMES_4, kBytesPerBigIntDigit));
-  __ shrdl(EAX, EDX, ECX);
-  __ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
-  __ incl(ESI);
-  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
-  __ Bind(&last);
-  __ shrdl(EDX, ESI, ECX);  // ESI == 0.
-  __ movl(Address(EBX, 0), EDX);
-
-  // Restore THR and return.
-  __ popl(THR);
-  __ LoadObject(EAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absAdd(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  // Preserve THR to free ESI.
-  __ pushl(THR);
-  ASSERT(THR == ESI);
-
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 5 * kWordSize));  // used is Smi
-  __ SmiUntag(EAX);                           // used > 0.
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
-  __ movl(ECX, Address(ESP, 3 * kWordSize));  // a_used is Smi
-  __ SmiUntag(ECX);                           // a_used > 0.
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
-
-  // Precompute 'used - a_used' now so that carry flag is not lost later.
-  __ subl(EAX, ECX);
-  __ incl(EAX);  // To account for the extra test between loops.
-  __ pushl(EAX);
-
-  __ xorl(EDX, EDX);  // EDX = 0, carry flag = 0.
-  Label add_loop;
-  __ Bind(&add_loop);
-  // Loop a_used times, ECX = a_used, ECX > 0.
-  __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
-  __ adcl(EAX, FieldAddress(ESI, EDX, TIMES_4, TypedData::data_offset()));
-  __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
-  __ incl(EDX);  // Does not affect carry flag.
-  __ decl(ECX);  // Does not affect carry flag.
-  __ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
-
-  Label last_carry;
-  __ popl(ECX);
-  __ decl(ECX);                                   // Does not affect carry flag.
-  __ j(ZERO, &last_carry, Assembler::kNearJump);  // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop used - a_used times, ECX = used - a_used, ECX > 0.
-  __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
-  __ adcl(EAX, Immediate(0));
-  __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
-  __ incl(EDX);  // Does not affect carry flag.
-  __ decl(ECX);  // Does not affect carry flag.
-  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
-
-  __ Bind(&last_carry);
-  __ movl(EAX, Immediate(0));
-  __ adcl(EAX, Immediate(0));
-  __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
-
-  // Restore THR and return.
-  __ popl(THR);
-  __ LoadObject(EAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absSub(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  // Preserve THR to free ESI.
-  __ pushl(THR);
-  ASSERT(THR == ESI);
-
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 5 * kWordSize));  // used is Smi
-  __ SmiUntag(EAX);                           // used > 0.
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
-  __ movl(ECX, Address(ESP, 3 * kWordSize));  // a_used is Smi
-  __ SmiUntag(ECX);                           // a_used > 0.
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
-
-  // Precompute 'used - a_used' now so that carry flag is not lost later.
-  __ subl(EAX, ECX);
-  __ incl(EAX);  // To account for the extra test between loops.
-  __ pushl(EAX);
-
-  __ xorl(EDX, EDX);  // EDX = 0, carry flag = 0.
-  Label sub_loop;
-  __ Bind(&sub_loop);
-  // Loop a_used times, ECX = a_used, ECX > 0.
-  __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
-  __ sbbl(EAX, FieldAddress(ESI, EDX, TIMES_4, TypedData::data_offset()));
-  __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
-  __ incl(EDX);  // Does not affect carry flag.
-  __ decl(ECX);  // Does not affect carry flag.
-  __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
-
-  Label done;
-  __ popl(ECX);
-  __ decl(ECX);                             // Does not affect carry flag.
-  __ j(ZERO, &done, Assembler::kNearJump);  // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop used - a_used times, ECX = used - a_used, ECX > 0.
-  __ movl(EAX, FieldAddress(EDI, EDX, TIMES_4, TypedData::data_offset()));
-  __ sbbl(EAX, Immediate(0));
-  __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
-  __ incl(EDX);  // Does not affect carry flag.
-  __ decl(ECX);  // Does not affect carry flag.
-  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  // Restore THR and return.
-  __ popl(THR);
-  __ LoadObject(EAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulAdd(Uint32List x_digits, int xi,
-  //                    Uint32List m_digits, int i,
-  //                    Uint32List a_digits, int j, int n) {
-  //   uint32_t x = x_digits[xi >> 1];  // xi is Smi.
-  //   if (x == 0 || n == 0) {
-  //     return 1;
-  //   }
-  //   uint32_t* mip = &m_digits[i >> 1];  // i is Smi.
-  //   uint32_t* ajp = &a_digits[j >> 1];  // j is Smi.
-  //   uint32_t c = 0;
-  //   SmiUntag(n);
-  //   do {
-  //     uint32_t mi = *mip++;
-  //     uint32_t aj = *ajp;
-  //     uint64_t t = x*mi + aj + c;  // 32-bit * 32-bit -> 64-bit.
-  //     *ajp++ = low32(t);
-  //     c = high32(t);
-  //   } while (--n > 0);
-  //   while (c != 0) {
-  //     uint64_t t = *ajp + c;
-  //     *ajp++ = low32(t);
-  //     c = high32(t);  // c == 0 or 1.
-  //   }
-  //   return 1;
-  // }
-
-  Label no_op;
-  // EBX = x, no_op if x == 0
-  __ movl(ECX, Address(ESP, 7 * kWordSize));  // x_digits
-  __ movl(EAX, Address(ESP, 6 * kWordSize));  // xi is Smi
-  __ movl(EBX, FieldAddress(ECX, EAX, TIMES_2, TypedData::data_offset()));
-  __ testl(EBX, EBX);
-  __ j(ZERO, &no_op, Assembler::kNearJump);
-
-  // EDX = SmiUntag(n), no_op if n == 0
-  __ movl(EDX, Address(ESP, 1 * kWordSize));
-  __ SmiUntag(EDX);
-  __ j(ZERO, &no_op, Assembler::kNearJump);
-
-  // Preserve THR to free ESI.
-  __ pushl(THR);
-  ASSERT(THR == ESI);
-
-  // EDI = mip = &m_digits[i >> 1]
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // m_digits
-  __ movl(EAX, Address(ESP, 5 * kWordSize));  // i is Smi
-  __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset()));
-
-  // ESI = ajp = &a_digits[j >> 1]
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
-  __ movl(EAX, Address(ESP, 3 * kWordSize));  // j is Smi
-  __ leal(ESI, FieldAddress(ESI, EAX, TIMES_2, TypedData::data_offset()));
-
-  // Save n
-  __ pushl(EDX);
-  Address n_addr = Address(ESP, 0 * kWordSize);
-
-  // ECX = c = 0
-  __ xorl(ECX, ECX);
-
-  Label muladd_loop;
-  __ Bind(&muladd_loop);
-  // x:   EBX
-  // mip: EDI
-  // ajp: ESI
-  // c:   ECX
-  // t:   EDX:EAX (not live at loop entry)
-  // n:   ESP[0]
-
-  // uint32_t mi = *mip++
-  __ movl(EAX, Address(EDI, 0));
-  __ addl(EDI, Immediate(kBytesPerBigIntDigit));
-
-  // uint64_t t = x*mi
-  __ mull(EBX);       // t = EDX:EAX = EAX * EBX
-  __ addl(EAX, ECX);  // t += c
-  __ adcl(EDX, Immediate(0));
-
-  // uint32_t aj = *ajp; t += aj
-  __ addl(EAX, Address(ESI, 0));
-  __ adcl(EDX, Immediate(0));
-
-  // *ajp++ = low32(t)
-  __ movl(Address(ESI, 0), EAX);
-  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
-
-  // c = high32(t)
-  __ movl(ECX, EDX);
-
-  // while (--n > 0)
-  __ decl(n_addr);  // --n
-  __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump);
-
-  Label done;
-  __ testl(ECX, ECX);
-  __ j(ZERO, &done, Assembler::kNearJump);
-
-  // *ajp += c
-  __ addl(Address(ESI, 0), ECX);
-  __ j(NOT_CARRY, &done, Assembler::kNearJump);
-
-  Label propagate_carry_loop;
-  __ Bind(&propagate_carry_loop);
-  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
-  __ incl(Address(ESI, 0));  // c == 0 or 1
-  __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  __ Drop(1);  // n
-  // Restore THR and return.
-  __ popl(THR);
-
-  __ Bind(&no_op);
-  __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
-  __ ret();
-}
-
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _sqrAdd(Uint32List x_digits, int i,
-  //                    Uint32List a_digits, int used) {
-  //   uint32_t* xip = &x_digits[i >> 1];  // i is Smi.
-  //   uint32_t x = *xip++;
-  //   if (x == 0) return 1;
-  //   uint32_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
-  //   uint32_t aj = *ajp;
-  //   uint64_t t = x*x + aj;
-  //   *ajp++ = low32(t);
-  //   uint64_t c = high32(t);
-  //   int n = ((used - i) >> 1) - 1;  // used and i are Smi.
-  //   while (--n >= 0) {
-  //     uint32_t xi = *xip++;
-  //     uint32_t aj = *ajp;
-  //     uint96_t t = 2*x*xi + aj + c;  // 2-bit * 32-bit * 32-bit -> 65-bit.
-  //     *ajp++ = low32(t);
-  //     c = high64(t);  // 33-bit.
-  //   }
-  //   uint32_t aj = *ajp;
-  //   uint64_t t = aj + c;  // 32-bit + 33-bit -> 34-bit.
-  //   *ajp++ = low32(t);
-  //   *ajp = high32(t);
-  //   return 1;
-  // }
-
-  // EDI = xip = &x_digits[i >> 1]
-  __ movl(EDI, Address(ESP, 4 * kWordSize));  // x_digits
-  __ movl(EAX, Address(ESP, 3 * kWordSize));  // i is Smi
-  __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset()));
-
-  // EBX = x = *xip++, return if x == 0
-  Label x_zero;
-  __ movl(EBX, Address(EDI, 0));
-  __ cmpl(EBX, Immediate(0));
-  __ j(EQUAL, &x_zero, Assembler::kNearJump);
-  __ addl(EDI, Immediate(kBytesPerBigIntDigit));
-
-  // Preserve THR to free ESI.
-  __ pushl(THR);
-  ASSERT(THR == ESI);
-
-  // ESI = ajp = &a_digits[i]
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
-  __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset()));
-
-  // EDX:EAX = t = x*x + *ajp
-  __ movl(EAX, EBX);
-  __ mull(EBX);
-  __ addl(EAX, Address(ESI, 0));
-  __ adcl(EDX, Immediate(0));
-
-  // *ajp++ = low32(t)
-  __ movl(Address(ESI, 0), EAX);
-  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
-
-  // int n = used - i - 1
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // used is Smi
-  __ subl(EAX, Address(ESP, 4 * kWordSize));  // i is Smi
-  __ SmiUntag(EAX);
-  __ decl(EAX);
-  __ pushl(EAX);  // Save n on stack.
-
-  // uint64_t c = high32(t)
-  __ pushl(Immediate(0));  // push high32(c) == 0
-  __ pushl(EDX);           // push low32(c) == high32(t)
-
-  Address n_addr = Address(ESP, 2 * kWordSize);
-  Address ch_addr = Address(ESP, 1 * kWordSize);
-  Address cl_addr = Address(ESP, 0 * kWordSize);
-
-  Label loop, done;
-  __ Bind(&loop);
-  // x:   EBX
-  // xip: EDI
-  // ajp: ESI
-  // c:   ESP[1]:ESP[0]
-  // t:   ECX:EDX:EAX (not live at loop entry)
-  // n:   ESP[2]
-
-  // while (--n >= 0)
-  __ decl(Address(ESP, 2 * kWordSize));  // --n
-  __ j(NEGATIVE, &done, Assembler::kNearJump);
-
-  // uint32_t xi = *xip++
-  __ movl(EAX, Address(EDI, 0));
-  __ addl(EDI, Immediate(kBytesPerBigIntDigit));
-
-  // uint96_t t = ECX:EDX:EAX = 2*x*xi + aj + c
-  __ mull(EBX);       // EDX:EAX = EAX * EBX
-  __ xorl(ECX, ECX);  // ECX = 0
-  __ shldl(ECX, EDX, Immediate(1));
-  __ shldl(EDX, EAX, Immediate(1));
-  __ shll(EAX, Immediate(1));     // ECX:EDX:EAX <<= 1
-  __ addl(EAX, Address(ESI, 0));  // t += aj
-  __ adcl(EDX, Immediate(0));
-  __ adcl(ECX, Immediate(0));
-  __ addl(EAX, cl_addr);  // t += low32(c)
-  __ adcl(EDX, ch_addr);  // t += high32(c) << 32
-  __ adcl(ECX, Immediate(0));
-
-  // *ajp++ = low32(t)
-  __ movl(Address(ESI, 0), EAX);
-  __ addl(ESI, Immediate(kBytesPerBigIntDigit));
-
-  // c = high64(t)
-  __ movl(cl_addr, EDX);
-  __ movl(ch_addr, ECX);
-
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  // uint64_t t = aj + c
-  __ movl(EAX, cl_addr);  // t = c
-  __ movl(EDX, ch_addr);
-  __ addl(EAX, Address(ESI, 0));  // t += *ajp
-  __ adcl(EDX, Immediate(0));
-
-  // *ajp++ = low32(t)
-  // *ajp = high32(t)
-  __ movl(Address(ESI, 0), EAX);
-  __ movl(Address(ESI, kBytesPerBigIntDigit), EDX);
-
-  // Restore THR and return.
-  __ Drop(3);
-  __ popl(THR);
-  __ Bind(&x_zero);
-  __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
-  __ ret();
-}
-
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
-  //   uint32_t yt = args[_YT];  // _YT == 1.
-  //   uint32_t* dp = &digits[i >> 1];  // i is Smi.
-  //   uint32_t dh = dp[0];  // dh == digits[i >> 1].
-  //   uint32_t qd;
-  //   if (dh == yt) {
-  //     qd = DIGIT_MASK;
-  //   } else {
-  //     dl = dp[-1];  // dl == digits[(i - 1) >> 1].
-  //     qd = dh:dl / yt;  // No overflow possible, because dh < yt.
-  //   }
-  //   args[_QD] = qd;  // _QD == 2.
-  //   return 1;
-  // }
-
-  // EDI = args
-  __ movl(EDI, Address(ESP, 3 * kWordSize));  // args
-
-  // ECX = yt = args[1]
-  __ movl(ECX,
-          FieldAddress(EDI, TypedData::data_offset() + kBytesPerBigIntDigit));
-
-  // EBX = dp = &digits[i >> 1]
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 1 * kWordSize));  // i is Smi
-  __ leal(EBX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset()));
-
-  // EDX = dh = dp[0]
-  __ movl(EDX, Address(EBX, 0));
-
-  // EAX = qd = DIGIT_MASK = -1
-  __ movl(EAX, Immediate(-1));
-
-  // Return qd if dh == yt
-  Label return_qd;
-  __ cmpl(EDX, ECX);
-  __ j(EQUAL, &return_qd, Assembler::kNearJump);
-
-  // EAX = dl = dp[-1]
-  __ movl(EAX, Address(EBX, -kBytesPerBigIntDigit));
-
-  // EAX = qd = dh:dl / yt = EDX:EAX / ECX
-  __ divl(ECX);
-
-  __ Bind(&return_qd);
-  // args[2] = qd
-  __ movl(
-      FieldAddress(EDI, TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
-      EAX);
-
-  __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
-  __ ret();
-}
-
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
-  //   uint32_t rho = args[_RHO];  // _RHO == 2.
-  //   uint32_t d = digits[i >> 1];  // i is Smi.
-  //   uint64_t t = rho*d;
-  //   args[_MU] = t mod DIGIT_BASE;  // _MU == 4.
-  //   return 1;
-  // }
-
-  // EDI = args
-  __ movl(EDI, Address(ESP, 3 * kWordSize));  // args
-
-  // ECX = rho = args[2]
-  __ movl(ECX, FieldAddress(
-                   EDI, TypedData::data_offset() + 2 * kBytesPerBigIntDigit));
-
-  // EAX = digits[i >> 1]
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 1 * kWordSize));  // i is Smi
-  __ movl(EAX, FieldAddress(EBX, EAX, TIMES_2, TypedData::data_offset()));
-
-  // EDX:EAX = t = rho*d
-  __ mull(ECX);
-
-  // args[4] = t mod DIGIT_BASE = low32(t)
-  __ movl(
-      FieldAddress(EDI, TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
-      EAX);
-
-  __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
-  __ ret();
-}
-
-// Check if the last argument is a double, jump to label 'is_smi' if smi
-// (easy to convert to double), otherwise jump to label 'not_double_smi',
-// Returns the last argument in EAX.
-static void TestLastArgumentIsDouble(Assembler* assembler,
-                                     Label* is_smi,
-                                     Label* not_double_smi) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(ZERO, is_smi, Assembler::kNearJump);  // Jump if Smi.
-  __ CompareClassId(EAX, kDoubleCid, EBX);
-  __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump);
-  // Fall through if double.
-}
-
-// Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
-// type. Return true or false object in the register EAX. Any NaN argument
-// returns false. Any non-double arg1 causes control flow to fall through to the
-// slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler,
-                           Label* normal_ir_body,
-                           Condition true_condition) {
-  Label is_false, is_true, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Both arguments are double, right operand is in EAX.
-  __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
-  __ Bind(&double_op);
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Left argument.
-  __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
-  __ comisd(XMM0, XMM1);
-  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false;
-  __ j(true_condition, &is_true, Assembler::kNearJump);
-  // Fall through false.
-  __ Bind(&is_false);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(EAX);
-  __ cvtsi2sd(XMM1, EAX);
-  __ jmp(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-// arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_greaterThan(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, ABOVE);
-}
-
-// arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
-                                           Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, ABOVE_EQUAL);
-}
-
-// arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_lessThan(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, BELOW);
-}
-
-// arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, EQUAL);
-}
-
-// arg0 is Double, arg1 is unknown.
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, BELOW_EQUAL);
-}
-
-// Expects left argument to be double (receiver). Right argument is unknown.
-// Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler,
-                                       Label* normal_ir_body,
-                                       Token::Kind kind) {
-  Label is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Both arguments are double, right operand is in EAX.
-  __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
-  __ Bind(&double_op);
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Left argument.
-  __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
-  switch (kind) {
-    case Token::kADD:
-      __ addsd(XMM0, XMM1);
-      break;
-    case Token::kSUB:
-      __ subsd(XMM0, XMM1);
-      break;
-    case Token::kMUL:
-      __ mulsd(XMM0, XMM1);
-      break;
-    case Token::kDIV:
-      __ divsd(XMM0, XMM1);
-      break;
-    default:
-      UNREACHABLE();
-  }
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
-                 EAX,  // Result register.
-                 EBX);
-  __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(EAX);
-  __ cvtsi2sd(XMM1, EAX);
-  __ jmp(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
-}
-
-void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
-}
-
-void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
-}
-
-void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
-}
-
-// Left is double, right is integer (Mint or Smi)
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  // Only smis allowed.
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);
-  // Is Smi.
-  __ SmiUntag(EAX);
-  __ cvtsi2sd(XMM1, EAX);
-  __ movl(EAX, Address(ESP, +2 * kWordSize));
-  __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
-  __ mulsd(XMM0, XMM1);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
-                 EAX,  // Result register.
-                 EBX);
-  __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::DoubleFromInteger(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);
-  // Is Smi.
-  __ SmiUntag(EAX);
-  __ cvtsi2sd(XMM0, EAX);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
-                 EAX,  // Result register.
-                 EBX);
-  __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_getIsNaN(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  Label is_true;
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
-  __ comisd(XMM0, XMM0);
-  __ j(PARITY_EVEN, &is_true, Assembler::kNearJump);  // NaN -> true;
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-}
-
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  Label not_inf;
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ movl(EBX, FieldAddress(EAX, Double::value_offset()));
-
-  // If the low word isn't zero, then it isn't infinity.
-  __ cmpl(EBX, Immediate(0));
-  __ j(NOT_EQUAL, &not_inf, Assembler::kNearJump);
-  // Check the high word.
-  __ movl(EBX, FieldAddress(EAX, Double::value_offset() + kWordSize));
-  // Mask off sign bit.
-  __ andl(EBX, Immediate(0x7FFFFFFF));
-  // Compare with +infinity.
-  __ cmpl(EBX, Immediate(0x7FF00000));
-  __ j(NOT_EQUAL, &not_inf, Assembler::kNearJump);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-
-  __ Bind(&not_inf);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-}
-
-void Intrinsifier::Double_getIsNegative(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  Label is_false, is_true, is_zero;
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
-  __ xorpd(XMM1, XMM1);  // 0.0 -> XMM1.
-  __ comisd(XMM0, XMM1);
-  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false.
-  __ j(EQUAL, &is_zero, Assembler::kNearJump);  // Check for negative zero.
-  __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump);  // >= 0 -> false.
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-  __ Bind(&is_false);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&is_zero);
-  // Check for negative zero (get the sign bit).
-  __ movmskpd(EAX, XMM0);
-  __ testl(EAX, Immediate(1));
-  __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
-  __ jmp(&is_false, Assembler::kNearJump);
-}
-
-void Intrinsifier::DoubleToInteger(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
-  __ cvttsd2si(EAX, XMM0);
-  // Overflow is signalled with minint.
-  // Check for overflow and that it fits into Smi.
-  __ cmpl(EAX, Immediate(0xC0000000));
-  __ j(NEGATIVE, normal_ir_body, Assembler::kNearJump);
-  __ SmiTag(EAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_hashCode(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
-
-  // Convert double value to signed 32-bit int in EAX and
-  // back to a double in XMM1.
-  __ movl(ECX, Address(ESP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(ECX, Double::value_offset()));
-  __ cvttsd2si(EAX, XMM0);
-  __ cvtsi2sd(XMM1, EAX);
-
-  // Tag the int as a Smi, making sure that it fits; this checks for
-  // overflow and NaN in the conversion from double to int. Conversion
-  // overflow from cvttsd2si is signalled with an INT32_MIN value.
-  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-  __ addl(EAX, EAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-
-  // Compare the two double values. If they are equal, we return the
-  // Smi tagged result immediately as the hash code.
-  Label double_hash;
-  __ comisd(XMM0, XMM1);
-  __ j(NOT_EQUAL, &double_hash, Assembler::kNearJump);
-  __ ret();
-
-  // Convert the double bits to a hash code that fits in a Smi.
-  __ Bind(&double_hash);
-  __ movl(EAX, FieldAddress(ECX, Double::value_offset()));
-  __ movl(ECX, FieldAddress(ECX, Double::value_offset() + 4));
-  __ xorl(EAX, ECX);
-  __ andl(EAX, Immediate(kSmiMax));
-  __ SmiTag(EAX);
-  __ ret();
-
-  // Fall into the native C++ implementation.
-  __ Bind(normal_ir_body);
-}
-
-// Argument type is not known
-void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
-  Label is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Argument is double and is in EAX.
-  __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
-  __ Bind(&double_op);
-  __ sqrtsd(XMM0, XMM1);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kNearJump,
-                 EAX,  // Result register.
-                 EBX);
-  __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(EAX);
-  __ cvtsi2sd(XMM1, EAX);
-  __ jmp(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-//    _state[kSTATE_LO] = state & _MASK_32;
-//    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  const Library& math_lib = Library::Handle(Library::MathLibrary());
-  ASSERT(!math_lib.IsNull());
-  const Class& random_class =
-      Class::Handle(math_lib.LookupClassAllowPrivate(Symbols::_Random()));
-  ASSERT(!random_class.IsNull());
-  const Field& state_field = Field::ZoneHandle(
-      random_class.LookupInstanceFieldAllowPrivate(Symbols::_state()));
-  ASSERT(!state_field.IsNull());
-  const int64_t a_int_value = Intrinsifier::kRandomAValue;
-  // 'a_int_value' is a mask.
-  ASSERT(Utils::IsUint(32, a_int_value));
-  int32_t a_int32_value = static_cast<int32_t>(a_int_value);
-
-  // Receiver.
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  // Field '_state'.
-  __ movl(EBX, FieldAddress(EAX, state_field.Offset()));
-  // Addresses of _state[0] and _state[1].
-  const intptr_t scale = Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
-  const intptr_t offset = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
-  Address addr_0 = FieldAddress(EBX, 0 * scale + offset);
-  Address addr_1 = FieldAddress(EBX, 1 * scale + offset);
-  __ movl(EAX, Immediate(a_int32_value));
-  // 64-bit multiply EAX * value -> EDX:EAX.
-  __ mull(addr_0);
-  __ addl(EAX, addr_1);
-  __ adcl(EDX, Immediate(0));
-  __ movl(addr_1, EDX);
-  __ movl(addr_0, EAX);
-  ASSERT(Smi::RawValue(0) == 0);
-  __ xorl(EAX, EAX);
-  __ ret();
-}
-
-// Identity comparison.
-void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
-  Label is_true;
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ cmpl(EAX, Address(ESP, +2 * kWordSize));
-  __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-}
-
-static void RangeCheck(Assembler* assembler,
-                       Register reg,
-                       intptr_t low,
-                       intptr_t high,
-                       Condition cc,
-                       Label* target) {
-  __ subl(reg, Immediate(low));
-  __ cmpl(reg, Immediate(high - low));
-  __ j(cc, target);
-}
-
-const Condition kIfNotInRange = ABOVE;
-const Condition kIfInRange = BELOW_EQUAL;
-
-static void JumpIfInteger(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfInRange, target);
-}
-
-static void JumpIfNotInteger(Assembler* assembler,
-                             Register cid,
-                             Label* target) {
-  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfNotInRange, target);
-}
-
-static void JumpIfString(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfInRange, target);
-}
-
-static void JumpIfNotString(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfNotInRange, target);
-}
-
-// Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Label use_declaration_type, not_double, not_integer;
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ LoadClassIdMayBeSmi(EDI, EAX);
-
-  __ cmpl(EDI, Immediate(kClosureCid));
-  __ j(EQUAL, normal_ir_body);  // Instance is a closure.
-
-  __ cmpl(EDI, Immediate(kNumPredefinedCids));
-  __ j(ABOVE, &use_declaration_type);
-
-  // If object is a instance of _Double return double type.
-  __ cmpl(EDI, Immediate(kDoubleCid));
-  __ j(NOT_EQUAL, &not_double);
-
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, Isolate::object_store_offset()));
-  __ movl(EAX, Address(EAX, ObjectStore::double_type_offset()));
-  __ ret();
-
-  __ Bind(&not_double);
-  // If object is an integer (smi, mint or bigint) return int type.
-  __ movl(EAX, EDI);
-  JumpIfNotInteger(assembler, EAX, &not_integer);
-
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, Isolate::object_store_offset()));
-  __ movl(EAX, Address(EAX, ObjectStore::int_type_offset()));
-  __ ret();
-
-  __ Bind(&not_integer);
-  // If object is a string (one byte, two byte or external variants) return
-  // string type.
-  __ movl(EAX, EDI);
-  JumpIfNotString(assembler, EAX, &use_declaration_type);
-
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, Isolate::object_store_offset()));
-  __ movl(EAX, Address(EAX, ObjectStore::string_type_offset()));
-  __ ret();
-
-  // Object is neither double, nor integer, nor string.
-  __ Bind(&use_declaration_type);
-  __ LoadClassById(EBX, EDI);
-  __ movzxw(EDI, FieldAddress(EBX, Class::num_type_arguments_offset()));
-  __ cmpl(EDI, Immediate(0));
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movl(EAX, FieldAddress(EBX, Class::declaration_type_offset()));
-  __ CompareObject(EAX, Object::null_object());
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label different_cids, equal, not_equal, not_integer;
-
-  __ movl(EAX, Address(ESP, +1 * kWordSize));
-  __ LoadClassIdMayBeSmi(EDI, EAX);
-
-  // Check if left hand size is a closure. Closures are handled in the runtime.
-  __ cmpl(EDI, Immediate(kClosureCid));
-  __ j(EQUAL, normal_ir_body);
-
-  __ movl(EAX, Address(ESP, +2 * kWordSize));
-  __ LoadClassIdMayBeSmi(EBX, EAX);
-
-  // Check whether class ids match. If class ids don't match objects can still
-  // have the same runtime type (e.g. multiple string implementation classes
-  // map to a single String type).
-  __ cmpl(EDI, EBX);
-  __ j(NOT_EQUAL, &different_cids);
-
-  // Objects have the same class and neither is a closure.
-  // Check if there are no type arguments. In this case we can return true.
-  // Otherwise fall through into the runtime to handle comparison.
-  __ LoadClassById(EBX, EDI);
-  __ movzxw(EBX, FieldAddress(EBX, Class::num_type_arguments_offset()));
-  __ cmpl(EBX, Immediate(0));
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-
-  __ Bind(&equal);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-
-  // Class ids are different. Check if we are comparing runtime types of
-  // two strings (with different representations) or two integers.
-  __ Bind(&different_cids);
-  __ cmpl(EDI, Immediate(kNumPredefinedCids));
-  __ j(ABOVE_EQUAL, &not_equal);
-
-  __ movl(EAX, EDI);
-  JumpIfNotInteger(assembler, EAX, &not_integer);
-
-  // First object is an integer. Check if the second is an integer too.
-  // Otherwise types are unequal because only integers have the same runtime
-  // type as other integers.
-  JumpIfInteger(assembler, EBX, &equal);
-  __ jmp(&not_equal);
-
-  __ Bind(&not_integer);
-  // Check if the first object is a string. If it is not then
-  // objects don't have the same runtime type because they have
-  // different class ids and they are not strings or integers.
-  JumpIfNotString(assembler, EDI, &not_equal);
-  // First object is a string. Check if the second is a string too.
-  JumpIfString(assembler, EBX, &equal);
-  // Strings only have the same runtime type as other strings.
-  // Fall-through to the not equal case.
-
-  __ Bind(&not_equal);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::String_getHashCode(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // String object.
-  __ movl(EAX, FieldAddress(EAX, String::hash_offset()));
-  __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ ret();
-  __ Bind(normal_ir_body);
-  // Hash not yet computed.
-}
-
-void Intrinsifier::Type_getHashCode(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // Type object.
-  __ movl(EAX, FieldAddress(EAX, Type::hash_offset()));
-  __ testl(EAX, EAX);
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ ret();
-  __ Bind(normal_ir_body);
-  // Hash not yet computed.
-}
-
-// bool _substringMatches(int start, String other)
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  // For precompilation, not implemented on IA32.
-}
-
-void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
-  UNREACHABLE();
-}
-
-void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
-  UNREACHABLE();
-}
-
-void Intrinsifier::StringBaseCharAt(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Label try_two_byte_string;
-  __ movl(EBX, Address(ESP, +1 * kWordSize));  // Index.
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // String.
-  __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi index.
-  // Range check.
-  __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
-  // Runtime throws exception.
-  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ CompareClassId(EAX, kOneByteStringCid, EDI);
-  __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
-  __ SmiUntag(EBX);
-  __ movzxb(EBX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
-  __ cmpl(EBX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, normal_ir_body);
-  __ movl(EAX,
-          Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
-  __ movl(EAX, Address(EAX, EBX, TIMES_4,
-                       Symbols::kNullCharCodeSymbolOffset * kWordSize));
-  __ ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(EAX, kTwoByteStringCid, EDI);
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-  ASSERT(kSmiTagShift == 1);
-  __ movzxw(EBX, FieldAddress(EAX, EBX, TIMES_1, TwoByteString::data_offset()));
-  __ cmpl(EBX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, normal_ir_body);
-  __ movl(EAX,
-          Immediate(reinterpret_cast<uword>(Symbols::PredefinedAddress())));
-  __ movl(EAX, Address(EAX, EBX, TIMES_4,
-                       Symbols::kNullCharCodeSymbolOffset * kWordSize));
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Label is_true;
-  // Get length.
-  __ movl(EAX, Address(ESP, +1 * kWordSize));  // String object.
-  __ movl(EAX, FieldAddress(EAX, String::length_offset()));
-  __ cmpl(EAX, Immediate(Smi::RawValue(0)));
-  __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-}
-
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label compute_hash;
-  __ movl(EBX, Address(ESP, +1 * kWordSize));  // OneByteString object.
-  __ movl(EAX, FieldAddress(EBX, String::hash_offset()));
-  __ cmpl(EAX, Immediate(0));
-  __ j(EQUAL, &compute_hash, Assembler::kNearJump);
-  __ ret();
-
-  __ Bind(&compute_hash);
-  // Hash not yet computed, use algorithm of class StringHasher.
-  __ movl(ECX, FieldAddress(EBX, String::length_offset()));
-  __ SmiUntag(ECX);
-  __ xorl(EAX, EAX);
-  __ xorl(EDI, EDI);
-  // EBX: Instance of OneByteString.
-  // ECX: String length, untagged integer.
-  // EDI: Loop counter, untagged integer.
-  // EAX: Hash code, untagged integer.
-  Label loop, done, set_hash_code;
-  __ Bind(&loop);
-  __ cmpl(EDI, ECX);
-  __ j(EQUAL, &done, Assembler::kNearJump);
-  // Add to hash code: (hash_ is uint32)
-  // hash_ += ch;
-  // hash_ += hash_ << 10;
-  // hash_ ^= hash_ >> 6;
-  // Get one characters (ch).
-  __ movzxb(EDX, FieldAddress(EBX, EDI, TIMES_1, OneByteString::data_offset()));
-  // EDX: ch and temporary.
-  __ addl(EAX, EDX);
-  __ movl(EDX, EAX);
-  __ shll(EDX, Immediate(10));
-  __ addl(EAX, EDX);
-  __ movl(EDX, EAX);
-  __ shrl(EDX, Immediate(6));
-  __ xorl(EAX, EDX);
-
-  __ incl(EDI);
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  // Finalize:
-  // hash_ += hash_ << 3;
-  // hash_ ^= hash_ >> 11;
-  // hash_ += hash_ << 15;
-  __ movl(EDX, EAX);
-  __ shll(EDX, Immediate(3));
-  __ addl(EAX, EDX);
-  __ movl(EDX, EAX);
-  __ shrl(EDX, Immediate(11));
-  __ xorl(EAX, EDX);
-  __ movl(EDX, EAX);
-  __ shll(EDX, Immediate(15));
-  __ addl(EAX, EDX);
-  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
-  __ andl(EAX,
-          Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1)));
-
-  // return hash_ == 0 ? 1 : hash_;
-  __ cmpl(EAX, Immediate(0));
-  __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
-  __ incl(EAX);
-  __ Bind(&set_hash_code);
-  __ SmiTag(EAX);
-  __ StoreIntoSmiField(FieldAddress(EBX, String::hash_offset()), EAX);
-  __ ret();
-}
-
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized. 'length-reg' contains tagged length.
-// Returns new string as tagged pointer in EAX.
-static void TryAllocateOnebyteString(Assembler* assembler,
-                                     Label* ok,
-                                     Label* failure,
-                                     Register length_reg) {
-  NOT_IN_PRODUCT(
-      __ MaybeTraceAllocation(kOneByteStringCid, EAX, failure, false));
-  if (length_reg != EDI) {
-    __ movl(EDI, length_reg);
-  }
-  Label pop_and_fail;
-  __ pushl(EDI);  // Preserve length.
-  __ SmiUntag(EDI);
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawString) + kObjectAlignment - 1;
-  __ leal(EDI, Address(EDI, TIMES_1,
-                       fixed_size_plus_alignment_padding));  // EDI is untagged.
-  __ andl(EDI, Immediate(-kObjectAlignment));
-
-  const intptr_t cid = kOneByteStringCid;
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  __ movl(EAX, Address(THR, Thread::top_offset()));
-  __ movl(EBX, EAX);
-
-  // EDI: allocation size.
-  __ addl(EBX, EDI);
-  __ j(CARRY, &pop_and_fail);
-
-  // Check if the allocation fits into the remaining space.
-  // EAX: potential new object start.
-  // EBX: potential next object start.
-  // EDI: allocation size.
-  __ cmpl(EBX, Address(THR, Thread::end_offset()));
-  __ j(ABOVE_EQUAL, &pop_and_fail);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  __ movl(Address(THR, Thread::top_offset()), EBX);
-  __ addl(EAX, Immediate(kHeapObjectTag));
-
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EDI, ECX, space));
-
-  // Initialize the tags.
-  // EAX: new object start as a tagged pointer.
-  // EBX: new object end address.
-  // EDI: allocation size.
-  {
-    Label size_tag_overflow, done;
-    __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
-    __ jmp(&done, Assembler::kNearJump);
-
-    __ Bind(&size_tag_overflow);
-    __ xorl(EDI, EDI);
-    __ Bind(&done);
-
-    // Get the class index and insert it into the tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ orl(EDI, Immediate(tags));
-    __ movl(FieldAddress(EAX, String::tags_offset()), EDI);  // Tags.
-  }
-
-  // Set the length field.
-  __ popl(EDI);
-  __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, String::length_offset()),
-                              EDI);
-  // Clear hash.
-  __ ZeroInitSmiField(FieldAddress(EAX, String::hash_offset()));
-  __ jmp(ok, Assembler::kNearJump);
-
-  __ Bind(&pop_and_fail);
-  __ popl(EDI);
-  __ jmp(failure);
-}
-
-// Arg0: OneByteString (receiver)
-// Arg1: Start index as Smi.
-// Arg2: End index as Smi.
-// The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
-                                                    Label* normal_ir_body) {
-  const intptr_t kStringOffset = 3 * kWordSize;
-  const intptr_t kStartIndexOffset = 2 * kWordSize;
-  const intptr_t kEndIndexOffset = 1 * kWordSize;
-  Label ok;
-  __ movl(EAX, Address(ESP, +kStartIndexOffset));
-  __ movl(EDI, Address(ESP, +kEndIndexOffset));
-  __ orl(EAX, EDI);
-  __ testl(EAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
-
-  __ subl(EDI, Address(ESP, +kStartIndexOffset));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
-  __ Bind(&ok);
-  // EAX: new string as tagged pointer.
-  // Copy string.
-  __ movl(EDI, Address(ESP, +kStringOffset));
-  __ movl(EBX, Address(ESP, +kStartIndexOffset));
-  __ SmiUntag(EBX);
-  __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset()));
-  // EDI: Start address to copy from (untagged).
-  // EBX: Untagged start index.
-  __ movl(ECX, Address(ESP, +kEndIndexOffset));
-  __ SmiUntag(ECX);
-  __ subl(ECX, EBX);
-  __ xorl(EDX, EDX);
-  // EDI: Start address to copy from (untagged).
-  // ECX: Untagged number of bytes to copy.
-  // EAX: Tagged result string.
-  // EDX: Loop counter.
-  // EBX: Scratch register.
-  Label loop, check;
-  __ jmp(&check, Assembler::kNearJump);
-  __ Bind(&loop);
-  __ movzxb(EBX, Address(EDI, EDX, TIMES_1, 0));
-  __ movb(FieldAddress(EAX, EDX, TIMES_1, OneByteString::data_offset()), BL);
-  __ incl(EDX);
-  __ Bind(&check);
-  __ cmpl(EDX, ECX);
-  __ j(LESS, &loop, Assembler::kNearJump);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ movl(ECX, Address(ESP, +1 * kWordSize));  // Value.
-  __ movl(EBX, Address(ESP, +2 * kWordSize));  // Index.
-  __ movl(EAX, Address(ESP, +3 * kWordSize));  // OneByteString.
-  __ SmiUntag(EBX);
-  __ SmiUntag(ECX);
-  __ movb(FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()), CL);
-  __ ret();
-}
-
-void Intrinsifier::OneByteString_allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ movl(EDI, Address(ESP, +1 * kWordSize));  // Length.
-  Label ok;
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, EDI);
-  // EDI: Start address to copy from (untagged).
-
-  __ Bind(&ok);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler,
-                           Label* normal_ir_body,
-                           intptr_t string_cid) {
-  Label is_true, is_false, loop;
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // This.
-  __ movl(EBX, Address(ESP, +1 * kWordSize));  // Other.
-
-  // Are identical?
-  __ cmpl(EAX, EBX);
-  __ j(EQUAL, &is_true, Assembler::kNearJump);
-
-  // Is other OneByteString?
-  __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(ZERO, &is_false);  // Smi
-  __ CompareClassId(EBX, string_cid, EDI);
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-
-  // Have same length?
-  __ movl(EDI, FieldAddress(EAX, String::length_offset()));
-  __ cmpl(EDI, FieldAddress(EBX, String::length_offset()));
-  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
-
-  // Check contents, no fall-through possible.
-  // TODO(srdjan): write a faster check.
-  __ SmiUntag(EDI);
-  __ Bind(&loop);
-  __ decl(EDI);
-  __ cmpl(EDI, Immediate(0));
-  __ j(LESS, &is_true, Assembler::kNearJump);
-  if (string_cid == kOneByteStringCid) {
-    __ movzxb(ECX,
-              FieldAddress(EAX, EDI, TIMES_1, OneByteString::data_offset()));
-    __ movzxb(EDX,
-              FieldAddress(EBX, EDI, TIMES_1, OneByteString::data_offset()));
-  } else if (string_cid == kTwoByteStringCid) {
-    __ movzxw(ECX,
-              FieldAddress(EAX, EDI, TIMES_2, TwoByteString::data_offset()));
-    __ movzxw(EDX,
-              FieldAddress(EBX, EDI, TIMES_2, TwoByteString::data_offset()));
-  } else {
-    UNIMPLEMENTED();
-  }
-  __ cmpl(ECX, EDX);
-  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&is_true);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-
-  __ Bind(&is_false);
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
-}
-
-void Intrinsifier::TwoByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
-}
-
-void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
-                                                Label* normal_ir_body,
-                                                bool sticky) {
-  if (FLAG_interpret_irregexp) return;
-
-  static const intptr_t kRegExpParamOffset = 3 * kWordSize;
-  static const intptr_t kStringParamOffset = 2 * kWordSize;
-  // start_index smi is located at offset 1.
-
-  // Incoming registers:
-  // EAX: Function. (Will be loaded with the specialized matcher function.)
-  // ECX: Unknown. (Must be GC safe on tail call.)
-  // EDX: Arguments descriptor. (Will be preserved.)
-
-  // Load the specialized function pointer into EAX. Leverage the fact the
-  // string CIDs as well as stored function pointers are in sequence.
-  __ movl(EBX, Address(ESP, kRegExpParamOffset));
-  __ movl(EDI, Address(ESP, kStringParamOffset));
-  __ LoadClassId(EDI, EDI);
-  __ SubImmediate(EDI, Immediate(kOneByteStringCid));
-  __ movl(EAX,
-          FieldAddress(EBX, EDI, TIMES_4,
-                       RegExp::function_offset(kOneByteStringCid, sticky)));
-
-  // Registers are now set up for the lazy compile stub. It expects the function
-  // in EAX, the argument descriptor in EDX, and IC-Data in ECX.
-  __ xorl(ECX, ECX);
-
-  // Tail-call the function.
-  __ movl(EDI, FieldAddress(EAX, Function::entry_point_offset()));
-  __ jmp(EDI);
-}
-
-// On stack: user tag (+1), return-address (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  // RDI: Isolate.
-  __ LoadIsolate(EDI);
-  // EAX: Current user tag.
-  __ movl(EAX, Address(EDI, Isolate::current_tag_offset()));
-  // EAX: UserTag.
-  __ movl(EBX, Address(ESP, +1 * kWordSize));
-  // Set Isolate::current_tag_.
-  __ movl(Address(EDI, Isolate::current_tag_offset()), EBX);
-  // EAX: UserTag's tag.
-  __ movl(EBX, FieldAddress(EBX, UserTag::tag_offset()));
-  // Set Isolate::user_tag_.
-  __ movl(Address(EDI, Isolate::user_tag_offset()), EBX);
-  __ ret();
-}
-
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, Isolate::default_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ LoadIsolate(EAX);
-  __ movl(EAX, Address(EAX, Isolate::current_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  if (!FLAG_support_timeline) {
-    __ LoadObject(EAX, Bool::False());
-    __ ret();
-  }
-  Label true_label;
-  // Load TimelineStream*.
-  __ movl(EAX, Address(THR, Thread::dart_stream_offset()));
-  // Load uintptr_t from TimelineStream*.
-  __ movl(EAX, Address(EAX, TimelineStream::enabled_offset()));
-  __ cmpl(EAX, Immediate(0));
-  __ j(NOT_ZERO, &true_label, Assembler::kNearJump);
-  // Not enabled.
-  __ LoadObject(EAX, Bool::False());
-  __ ret();
-  // Enabled.
-  __ Bind(&true_label);
-  __ LoadObject(EAX, Bool::True());
-  __ ret();
-}
-
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  __ LoadObject(EAX, Object::null_object());
-  __ movl(Address(THR, Thread::async_stack_trace_offset()), EAX);
-  __ ret();
-}
-
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  __ movl(Address(THR, Thread::async_stack_trace_offset()), EAX);
-  __ LoadObject(EAX, Object::null_object());
-  __ ret();
-}
-
-#undef __
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/intrinsifier_x64.cc b/runtime/vm/compiler/intrinsifier_x64.cc
deleted file mode 100644
index a51b665..0000000
--- a/runtime/vm/compiler/intrinsifier_x64.cc
+++ /dev/null
@@ -1,2271 +0,0 @@
-// 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.
-
-#include "vm/globals.h"  // Needed here to get TARGET_ARCH_X64.
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/intrinsifier.h"
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/dart_entry.h"
-#include "vm/instructions.h"
-#include "vm/object_store.h"
-#include "vm/regexp_assembler.h"
-#include "vm/symbols.h"
-#include "vm/timeline.h"
-
-namespace dart {
-
-// When entering intrinsics code:
-// R10: Arguments descriptor
-// TOS: Return address
-// The R10 registers can be destroyed only if there is no slow-path, i.e.
-// if the intrinsified method always executes a return.
-// The RBP register should not be modified, because it is used by the profiler.
-// The PP and THR registers (see constants_x64.h) must be preserved.
-
-#define __ assembler->
-
-intptr_t Intrinsifier::ParameterSlotFromSp() {
-  return 0;
-}
-
-static bool IsABIPreservedRegister(Register reg) {
-  return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
-}
-
-void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
-  ASSERT(IsABIPreservedRegister(CODE_REG));
-  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
-  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
-  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
-  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
-
-  assembler->Comment("IntrinsicCallPrologue");
-  assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
-}
-
-void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
-  assembler->Comment("IntrinsicCallEpilogue");
-  assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
-}
-
-// Allocate a GrowableObjectArray using the backing array specified.
-// On stack: type argument (+2), data (+1), return-address (+0).
-void Intrinsifier::GrowableArray_Allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  // This snippet of inlined code uses the following registers:
-  // RAX, RCX, R13
-  // and the newly allocated object is returned in RAX.
-  const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
-  const intptr_t kArrayOffset = 1 * kWordSize;
-
-  // Try allocating in new space.
-  const Class& cls = Class::Handle(
-      Isolate::Current()->object_store()->growable_object_array_class());
-  __ TryAllocate(cls, normal_ir_body, Assembler::kFarJump, RAX, R13);
-
-  // Store backing array object in growable array object.
-  __ movq(RCX, Address(RSP, kArrayOffset));  // data argument.
-  // RAX is new, no barrier needed.
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, GrowableObjectArray::data_offset()), RCX);
-
-  // RAX: new growable array object start as a tagged pointer.
-  // Store the type argument field in the growable array object.
-  __ movq(RCX, Address(RSP, kTypeArgumentsOffset));  // type argument.
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, GrowableObjectArray::type_arguments_offset()),
-      RCX);
-
-  // Set the length field in the growable array object to 0.
-  __ ZeroInitSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset()));
-  __ ret();  // returns the newly allocated object in RAX.
-
-  __ Bind(normal_ir_body);
-}
-
-#define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor)          \
-  Label fall_through;                                                          \
-  const intptr_t kArrayLengthStackOffset = 1 * kWordSize;                      \
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(cid, normal_ir_body, false));         \
-  __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */     \
-  /* Check that length is a positive Smi. */                                   \
-  /* RDI: requested array length argument. */                                  \
-  __ testq(RDI, Immediate(kSmiTagMask));                                       \
-  __ j(NOT_ZERO, normal_ir_body);                                              \
-  __ cmpq(RDI, Immediate(0));                                                  \
-  __ j(LESS, normal_ir_body);                                                  \
-  __ SmiUntag(RDI);                                                            \
-  /* Check for maximum allowed length. */                                      \
-  /* RDI: untagged array length. */                                            \
-  __ cmpq(RDI, Immediate(max_len));                                            \
-  __ j(GREATER, normal_ir_body);                                               \
-  /* Special case for scaling by 16. */                                        \
-  if (scale_factor == TIMES_16) {                                              \
-    /* double length of array. */                                              \
-    __ addq(RDI, RDI);                                                         \
-    /* only scale by 8. */                                                     \
-    scale_factor = TIMES_8;                                                    \
-  }                                                                            \
-  const intptr_t fixed_size_plus_alignment_padding =                           \
-      sizeof(Raw##type_name) + kObjectAlignment - 1;                           \
-  __ leaq(RDI, Address(RDI, scale_factor, fixed_size_plus_alignment_padding)); \
-  __ andq(RDI, Immediate(-kObjectAlignment));                                  \
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);                              \
-  __ movq(RAX, Address(THR, Thread::top_offset()));                            \
-  __ movq(RCX, RAX);                                                           \
-                                                                               \
-  /* RDI: allocation size. */                                                  \
-  __ addq(RCX, RDI);                                                           \
-  __ j(CARRY, normal_ir_body);                                                 \
-                                                                               \
-  /* Check if the allocation fits into the remaining space. */                 \
-  /* RAX: potential new object start. */                                       \
-  /* RCX: potential next object start. */                                      \
-  /* RDI: allocation size. */                                                  \
-  __ cmpq(RCX, Address(THR, Thread::end_offset()));                            \
-  __ j(ABOVE_EQUAL, normal_ir_body);                                           \
-                                                                               \
-  /* Successfully allocated the object(s), now update top to point to */       \
-  /* next object start and initialize the object. */                           \
-  __ movq(Address(THR, Thread::top_offset()), RCX);                            \
-  __ addq(RAX, Immediate(kHeapObjectTag));                                     \
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, RDI, space));           \
-  /* Initialize the tags. */                                                   \
-  /* RAX: new object start as a tagged pointer. */                             \
-  /* RCX: new object end address. */                                           \
-  /* RDI: allocation size. */                                                  \
-  /* R13: scratch register. */                                                 \
-  {                                                                            \
-    Label size_tag_overflow, done;                                             \
-    __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag));                  \
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);                     \
-    __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));    \
-    __ jmp(&done, Assembler::kNearJump);                                       \
-                                                                               \
-    __ Bind(&size_tag_overflow);                                               \
-    __ LoadImmediate(RDI, Immediate(0));                                       \
-    __ Bind(&done);                                                            \
-                                                                               \
-    /* Get the class index and insert it into the tags. */                     \
-    uint32_t tags = 0;                                                         \
-    tags = RawObject::ClassIdTag::update(cid, tags);                           \
-    tags = RawObject::NewBit::update(true, tags);                              \
-    __ orq(RDI, Immediate(tags));                                              \
-    __ movq(FieldAddress(RAX, type_name::tags_offset()), RDI); /* Tags. */     \
-  }                                                                            \
-  /* Set the length field. */                                                  \
-  /* RAX: new object start as a tagged pointer. */                             \
-  /* RCX: new object end address. */                                           \
-  __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */     \
-  __ StoreIntoObjectNoBarrier(                                                 \
-      RAX, FieldAddress(RAX, type_name::length_offset()), RDI);                \
-  /* Initialize all array elements to 0. */                                    \
-  /* RAX: new object start as a tagged pointer. */                             \
-  /* RCX: new object end address. */                                           \
-  /* RDI: iterator which initially points to the start of the variable */      \
-  /* RBX: scratch register. */                                                 \
-  /* data area to be initialized. */                                           \
-  __ xorq(RBX, RBX); /* Zero. */                                               \
-  __ leaq(RDI, FieldAddress(RAX, sizeof(Raw##type_name)));                     \
-  Label done, init_loop;                                                       \
-  __ Bind(&init_loop);                                                         \
-  __ cmpq(RDI, RCX);                                                           \
-  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);                              \
-  __ movq(Address(RDI, 0), RBX);                                               \
-  __ addq(RDI, Immediate(kWordSize));                                          \
-  __ jmp(&init_loop, Assembler::kNearJump);                                    \
-  __ Bind(&done);                                                              \
-                                                                               \
-  __ ret();                                                                    \
-  __ Bind(normal_ir_body);
-
-static ScaleFactor GetScaleFactor(intptr_t size) {
-  switch (size) {
-    case 1:
-      return TIMES_1;
-    case 2:
-      return TIMES_2;
-    case 4:
-      return TIMES_4;
-    case 8:
-      return TIMES_8;
-    case 16:
-      return TIMES_16;
-  }
-  UNREACHABLE();
-  return static_cast<ScaleFactor>(0);
-}
-
-#define TYPED_DATA_ALLOCATOR(clazz)                                            \
-  void Intrinsifier::TypedData_##clazz##_factory(Assembler* assembler,         \
-                                                 Label* normal_ir_body) {      \
-    intptr_t size = TypedData::ElementSizeInBytes(kTypedData##clazz##Cid);     \
-    intptr_t max_len = TypedData::MaxNewSpaceElements(kTypedData##clazz##Cid); \
-    ScaleFactor scale = GetScaleFactor(size);                                  \
-    TYPED_ARRAY_ALLOCATION(TypedData, kTypedData##clazz##Cid, max_len, scale); \
-  }
-CLASS_LIST_TYPED_DATA(TYPED_DATA_ALLOCATOR)
-#undef TYPED_DATA_ALLOCATOR
-
-// Tests if two top most arguments are smis, jumps to label not_smi if not.
-// Topmost argument is in RAX.
-static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ movq(RCX, Address(RSP, +2 * kWordSize));
-  __ orq(RCX, RAX);
-  __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, not_smi);
-}
-
-void Intrinsifier::Integer_addFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX contains right argument.
-  __ addq(RAX, Address(RSP, +2 * kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_add(Assembler* assembler, Label* normal_ir_body) {
-  Integer_addFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_subFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX contains right argument, which is the actual minuend of subtraction.
-  __ subq(RAX, Address(RSP, +2 * kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_sub(Assembler* assembler, Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX contains right argument, which is the actual subtrahend of subtraction.
-  __ movq(RCX, RAX);
-  __ movq(RAX, Address(RSP, +2 * kWordSize));
-  __ subq(RAX, RCX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mulFromInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  ASSERT(kSmiTag == 0);  // Adjust code below if not the case.
-  __ SmiUntag(RAX);
-  __ imulq(RAX, Address(RSP, +2 * kWordSize));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_mul(Assembler* assembler, Label* normal_ir_body) {
-  Integer_mulFromInteger(assembler, normal_ir_body);
-}
-
-// Optimizations:
-// - result is 0 if:
-//   - left is 0
-//   - left equals right
-// - result is left if
-//   - left > 0 && left < right
-// RAX: Tagged left (dividend).
-// RCX: Tagged right (divisor).
-// Returns:
-//   RAX: Untagged fallthrough result (remainder to be adjusted), or
-//   RAX: Tagged return result (remainder).
-static void EmitRemainderOperation(Assembler* assembler) {
-  Label return_zero, try_modulo, not_32bit, done;
-  // Check for quick zero results.
-  __ cmpq(RAX, Immediate(0));
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-  __ cmpq(RAX, RCX);
-  __ j(EQUAL, &return_zero, Assembler::kNearJump);
-
-  // Check if result equals left.
-  __ cmpq(RAX, Immediate(0));
-  __ j(LESS, &try_modulo, Assembler::kNearJump);
-  // left is positive.
-  __ cmpq(RAX, RCX);
-  __ j(GREATER, &try_modulo, Assembler::kNearJump);
-  // left is less than right, result is left (RAX).
-  __ ret();
-
-  __ Bind(&return_zero);
-  __ xorq(RAX, RAX);
-  __ ret();
-
-  __ Bind(&try_modulo);
-
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency. We are checking
-  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
-  // raises exception because quotient is too large for 32bit register.
-  __ movsxd(RBX, RAX);
-  __ cmpq(RBX, RAX);
-  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
-  __ movsxd(RBX, RCX);
-  __ cmpq(RBX, RCX);
-  __ j(NOT_EQUAL, &not_32bit, Assembler::kNearJump);
-
-  // Both operands are 31bit smis. Divide using 32bit idiv.
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cdq();
-  __ idivl(RCX);
-  __ movsxd(RAX, RDX);
-  __ jmp(&done, Assembler::kNearJump);
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cqo();
-  __ idivq(RCX);
-  __ movq(RAX, RDX);
-  __ Bind(&done);
-}
-
-// Implementation:
-//  res = left % right;
-//  if (res < 0) {
-//    if (right < 0) {
-//      res = res - right;
-//    } else {
-//      res = res + right;
-//    }
-//  }
-void Intrinsifier::Integer_moduloFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label negative_result;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  __ movq(RCX, Address(RSP, +2 * kWordSize));
-  // RAX: Tagged left (dividend).
-  // RCX: Tagged right (divisor).
-  __ cmpq(RCX, Immediate(0));
-  __ j(EQUAL, normal_ir_body);
-  EmitRemainderOperation(assembler);
-  // Untagged remainder result in RAX.
-  __ cmpq(RAX, Immediate(0));
-  __ j(LESS, &negative_result, Assembler::kNearJump);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&negative_result);
-  Label subtract;
-  // RAX: Untagged result.
-  // RCX: Untagged right.
-  __ cmpq(RCX, Immediate(0));
-  __ j(LESS, &subtract, Assembler::kNearJump);
-  __ addq(RAX, RCX);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&subtract);
-  __ subq(RAX, RCX);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_truncDivide(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  Label not_32bit;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX: right argument (divisor)
-  __ cmpq(RAX, Immediate(0));
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movq(RCX, RAX);
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Left argument (dividend).
-
-  // Check if both operands fit into 32bits as idiv with 64bit operands
-  // requires twice as many cycles and has much higher latency. We are checking
-  // this before untagging them to avoid corner case dividing INT_MAX by -1 that
-  // raises exception because quotient is too large for 32bit register.
-  __ movsxd(RBX, RAX);
-  __ cmpq(RBX, RAX);
-  __ j(NOT_EQUAL, &not_32bit);
-  __ movsxd(RBX, RCX);
-  __ cmpq(RBX, RCX);
-  __ j(NOT_EQUAL, &not_32bit);
-
-  // Both operands are 31bit smis. Divide using 32bit idiv.
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ cdq();
-  __ idivl(RCX);
-  __ movsxd(RAX, RAX);
-  __ SmiTag(RAX);  // Result is guaranteed to fit into a smi.
-  __ ret();
-
-  // Divide using 64bit idiv.
-  __ Bind(&not_32bit);
-  __ SmiUntag(RAX);
-  __ SmiUntag(RCX);
-  __ pushq(RDX);  // Preserve RDX in case of 'fall_through'.
-  __ cqo();
-  __ idivq(RCX);
-  __ popq(RDX);
-  // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
-  // cannot tag the result.
-  __ cmpq(RAX, Immediate(0x4000000000000000));
-  __ j(EQUAL, normal_ir_body);
-  __ SmiTag(RAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_negate(Assembler* assembler, Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body, Assembler::kNearJump);  // Non-smi value.
-  __ negq(RAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAndFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  __ andq(RAX, Address(RSP, +2 * kWordSize));
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitAnd(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOrFromInteger(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  __ orq(RAX, Address(RSP, +2 * kWordSize));
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitOr(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitOrFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXorFromInteger(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX is the right argument.
-  __ xorq(RAX, Address(RSP, +2 * kWordSize));
-  // Result is in RAX.
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_bitXor(Assembler* assembler, Label* normal_ir_body) {
-  Integer_bitXorFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
-  ASSERT(kSmiTagShift == 1);
-  ASSERT(kSmiTag == 0);
-  Label overflow;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // Shift value is in RAX. Compare with tagged Smi.
-  __ cmpq(RAX, Immediate(Smi::RawValue(Smi::kBits)));
-  __ j(ABOVE_EQUAL, normal_ir_body, Assembler::kNearJump);
-
-  __ SmiUntag(RAX);
-  __ movq(RCX, RAX);                           // Shift amount must be in RCX.
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Value.
-
-  // Overflow test - all the shifted-out bits must be same as the sign bit.
-  __ movq(RDI, RAX);
-  __ shlq(RAX, RCX);
-  __ sarq(RAX, RCX);
-  __ cmpq(RAX, RDI);
-  __ j(NOT_EQUAL, &overflow, Assembler::kNearJump);
-
-  __ shlq(RAX, RCX);  // Shift for result now we know there is no overflow.
-
-  // RAX is a correctly tagged Smi.
-  __ ret();
-
-  __ Bind(&overflow);
-  // Mint is rarely used on x64 (only for integers requiring 64 bit instead of
-  // 63 bits as represented by Smi).
-  __ Bind(normal_ir_body);
-}
-
-static void CompareIntegers(Assembler* assembler,
-                            Label* normal_ir_body,
-                            Condition true_condition) {
-  Label true_label;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  // RAX contains the right argument.
-  __ cmpq(Address(RSP, +2 * kWordSize), RAX);
-  __ j(true_condition, &true_label, Assembler::kNearJump);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&true_label);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_lessThan(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LESS);
-}
-
-void Intrinsifier::Integer_greaterThanFromInt(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LESS);
-}
-
-void Intrinsifier::Integer_greaterThan(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GREATER);
-}
-
-void Intrinsifier::Integer_lessEqualThan(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, LESS_EQUAL);
-}
-
-void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  CompareIntegers(assembler, normal_ir_body, GREATER_EQUAL);
-}
-
-// This is called for Smi and Mint receivers. The right argument
-// can be Smi, Mint or double.
-void Intrinsifier::Integer_equalToInteger(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  Label true_label, check_for_mint;
-  const intptr_t kReceiverOffset = 2;
-  const intptr_t kArgumentOffset = 1;
-
-  // For integer receiver '===' check first.
-  __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
-  __ movq(RCX, Address(RSP, +kReceiverOffset * kWordSize));
-  __ cmpq(RAX, RCX);
-  __ j(EQUAL, &true_label, Assembler::kNearJump);
-  __ orq(RAX, RCX);
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
-  // Both arguments are smi, '===' is good enough.
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&true_label);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-
-  // At least one of the arguments was not Smi.
-  Label receiver_not_smi;
-  __ Bind(&check_for_mint);
-  __ movq(RAX, Address(RSP, +kReceiverOffset * kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &receiver_not_smi);
-
-  // Left (receiver) is Smi, return false if right is not Double.
-  // Note that an instance of Mint never contains a value that can be
-  // represented by Smi.
-  __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
-  __ CompareClassId(RAX, kDoubleCid);
-  __ j(EQUAL, normal_ir_body);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-
-  __ Bind(&receiver_not_smi);
-  // RAX:: receiver.
-  __ CompareClassId(RAX, kMintCid);
-  __ j(NOT_EQUAL, normal_ir_body);
-  // Receiver is Mint, return false if right is Smi.
-  __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);
-  // Smi == Mint -> false.
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  // TODO(srdjan): Implement Mint == Mint comparison.
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Integer_equal(Assembler* assembler, Label* normal_ir_body) {
-  Integer_equalToInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Integer_sar(Assembler* assembler, Label* normal_ir_body) {
-  Label shift_count_ok;
-  TestBothArgumentsSmis(assembler, normal_ir_body);
-  const Immediate& count_limit = Immediate(0x3F);
-  // Check that the count is not larger than what the hardware can handle.
-  // For shifting right a Smi the result is the same for all numbers
-  // >= count_limit.
-  __ SmiUntag(RAX);
-  // Negative counts throw exception.
-  __ cmpq(RAX, Immediate(0));
-  __ j(LESS, normal_ir_body, Assembler::kNearJump);
-  __ cmpq(RAX, count_limit);
-  __ j(LESS_EQUAL, &shift_count_ok, Assembler::kNearJump);
-  __ movq(RAX, count_limit);
-  __ Bind(&shift_count_ok);
-  __ movq(RCX, RAX);                           // Shift amount must be in RCX.
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Value.
-  __ SmiUntag(RAX);                            // Value.
-  __ sarq(RAX, RCX);
-  __ SmiTag(RAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Argument is Smi (receiver).
-void Intrinsifier::Smi_bitNegate(Assembler* assembler, Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));  // Index.
-  __ notq(RAX);
-  __ andq(RAX, Immediate(~kSmiTagMask));  // Remove inverted smi-tag.
-  __ ret();
-}
-
-void Intrinsifier::Smi_bitLength(Assembler* assembler, Label* normal_ir_body) {
-  ASSERT(kSmiTagShift == 1);
-  __ movq(RAX, Address(RSP, +1 * kWordSize));  // Index.
-  // XOR with sign bit to complement bits if value is negative.
-  __ movq(RCX, RAX);
-  __ sarq(RCX, Immediate(63));  // All 0 or all 1.
-  __ xorq(RAX, RCX);
-  // BSR does not write the destination register if source is zero.  Put a 1 in
-  // the Smi tag bit to ensure BSR writes to destination register.
-  __ orq(RAX, Immediate(kSmiTagMask));
-  __ bsrq(RAX, RAX);
-  __ SmiTag(RAX);
-  __ ret();
-}
-
-void Intrinsifier::Smi_bitAndFromSmi(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Integer_bitAndFromInteger(assembler, normal_ir_body);
-}
-
-void Intrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _lsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  __ movq(RDI, Address(RSP, 4 * kWordSize));  // x_digits
-  __ movq(R8, Address(RSP, 3 * kWordSize));   // x_used is Smi
-  __ subq(R8, Immediate(2));  // x_used > 0, Smi. R8 = x_used - 1, round up.
-  __ sarq(R8, Immediate(2));  // R8 + 1 = number of digit pairs to read.
-  __ movq(RCX, Address(RSP, 2 * kWordSize));  // n is Smi
-  __ SmiUntag(RCX);
-  __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
-  __ movq(RSI, RCX);
-  __ sarq(RSI, Immediate(6));  // RSI = n ~/ (2*_DIGIT_BITS).
-  __ leaq(RBX, FieldAddress(RBX, RSI, TIMES_8, TypedData::data_offset()));
-  __ xorq(RAX, RAX);  // RAX = 0.
-  __ movq(RDX, FieldAddress(RDI, R8, TIMES_8, TypedData::data_offset()));
-  __ shldq(RAX, RDX, RCX);
-  __ movq(Address(RBX, R8, TIMES_8, 2 * kBytesPerBigIntDigit), RAX);
-  Label last;
-  __ cmpq(R8, Immediate(0));
-  __ j(EQUAL, &last, Assembler::kNearJump);
-  Label loop;
-  __ Bind(&loop);
-  __ movq(RAX, RDX);
-  __ movq(RDX,
-          FieldAddress(RDI, R8, TIMES_8,
-                       TypedData::data_offset() - 2 * kBytesPerBigIntDigit));
-  __ shldq(RAX, RDX, RCX);
-  __ movq(Address(RBX, R8, TIMES_8, 0), RAX);
-  __ decq(R8);
-  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
-  __ Bind(&last);
-  __ shldq(RDX, R8, RCX);  // R8 == 0.
-  __ movq(Address(RBX, 0), RDX);
-  __ LoadObject(RAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
-  // static void _rsh(Uint32List x_digits, int x_used, int n,
-  //                  Uint32List r_digits)
-
-  __ movq(RDI, Address(RSP, 4 * kWordSize));  // x_digits
-  __ movq(RCX, Address(RSP, 2 * kWordSize));  // n is Smi
-  __ SmiUntag(RCX);
-  __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
-  __ movq(RDX, RCX);
-  __ sarq(RDX, Immediate(6));                 // RDX = n ~/ (2*_DIGIT_BITS).
-  __ movq(RSI, Address(RSP, 3 * kWordSize));  // x_used is Smi
-  __ subq(RSI, Immediate(2));  // x_used > 0, Smi. RSI = x_used - 1, round up.
-  __ sarq(RSI, Immediate(2));
-  __ leaq(RDI, FieldAddress(RDI, RSI, TIMES_8, TypedData::data_offset()));
-  __ subq(RSI, RDX);  // RSI + 1 = number of digit pairs to read.
-  __ leaq(RBX, FieldAddress(RBX, RSI, TIMES_8, TypedData::data_offset()));
-  __ negq(RSI);
-  __ movq(RDX, Address(RDI, RSI, TIMES_8, 0));
-  Label last;
-  __ cmpq(RSI, Immediate(0));
-  __ j(EQUAL, &last, Assembler::kNearJump);
-  Label loop;
-  __ Bind(&loop);
-  __ movq(RAX, RDX);
-  __ movq(RDX, Address(RDI, RSI, TIMES_8, 2 * kBytesPerBigIntDigit));
-  __ shrdq(RAX, RDX, RCX);
-  __ movq(Address(RBX, RSI, TIMES_8, 0), RAX);
-  __ incq(RSI);
-  __ j(NOT_ZERO, &loop, Assembler::kNearJump);
-  __ Bind(&last);
-  __ shrdq(RDX, RSI, RCX);  // RSI == 0.
-  __ movq(Address(RBX, 0), RDX);
-  __ LoadObject(RAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_absAdd(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absAdd(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  __ movq(RDI, Address(RSP, 5 * kWordSize));  // digits
-  __ movq(R8, Address(RSP, 4 * kWordSize));   // used is Smi
-  __ addq(R8, Immediate(2));  // used > 0, Smi. R8 = used + 1, round up.
-  __ sarq(R8, Immediate(2));  // R8 = number of digit pairs to process.
-  __ movq(RSI, Address(RSP, 3 * kWordSize));  // a_digits
-  __ movq(RCX, Address(RSP, 2 * kWordSize));  // a_used is Smi
-  __ addq(RCX, Immediate(2));  // a_used > 0, Smi. R8 = a_used + 1, round up.
-  __ sarq(RCX, Immediate(2));  // R8 = number of digit pairs to process.
-  __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
-
-  // Precompute 'used - a_used' now so that carry flag is not lost later.
-  __ subq(R8, RCX);
-  __ incq(R8);  // To account for the extra test between loops.
-
-  __ xorq(RDX, RDX);  // RDX = 0, carry flag = 0.
-  Label add_loop;
-  __ Bind(&add_loop);
-  // Loop (a_used+1)/2 times, RCX > 0.
-  __ movq(RAX, FieldAddress(RDI, RDX, TIMES_8, TypedData::data_offset()));
-  __ adcq(RAX, FieldAddress(RSI, RDX, TIMES_8, TypedData::data_offset()));
-  __ movq(FieldAddress(RBX, RDX, TIMES_8, TypedData::data_offset()), RAX);
-  __ incq(RDX);  // Does not affect carry flag.
-  __ decq(RCX);  // Does not affect carry flag.
-  __ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
-
-  Label last_carry;
-  __ decq(R8);                                    // Does not affect carry flag.
-  __ j(ZERO, &last_carry, Assembler::kNearJump);  // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
-  __ movq(RAX, FieldAddress(RDI, RDX, TIMES_8, TypedData::data_offset()));
-  __ adcq(RAX, Immediate(0));
-  __ movq(FieldAddress(RBX, RDX, TIMES_8, TypedData::data_offset()), RAX);
-  __ incq(RDX);  // Does not affect carry flag.
-  __ decq(R8);   // Does not affect carry flag.
-  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
-
-  __ Bind(&last_carry);
-  Label done;
-  __ j(NOT_CARRY, &done);
-  __ movq(FieldAddress(RBX, RDX, TIMES_8, TypedData::data_offset()),
-          Immediate(1));
-
-  __ Bind(&done);
-  __ LoadObject(RAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_absSub(Assembler* assembler, Label* normal_ir_body) {
-  // static void _absSub(Uint32List digits, int used,
-  //                     Uint32List a_digits, int a_used,
-  //                     Uint32List r_digits)
-
-  __ movq(RDI, Address(RSP, 5 * kWordSize));  // digits
-  __ movq(R8, Address(RSP, 4 * kWordSize));   // used is Smi
-  __ addq(R8, Immediate(2));  // used > 0, Smi. R8 = used + 1, round up.
-  __ sarq(R8, Immediate(2));  // R8 = number of digit pairs to process.
-  __ movq(RSI, Address(RSP, 3 * kWordSize));  // a_digits
-  __ movq(RCX, Address(RSP, 2 * kWordSize));  // a_used is Smi
-  __ addq(RCX, Immediate(2));  // a_used > 0, Smi. R8 = a_used + 1, round up.
-  __ sarq(RCX, Immediate(2));  // R8 = number of digit pairs to process.
-  __ movq(RBX, Address(RSP, 1 * kWordSize));  // r_digits
-
-  // Precompute 'used - a_used' now so that carry flag is not lost later.
-  __ subq(R8, RCX);
-  __ incq(R8);  // To account for the extra test between loops.
-
-  __ xorq(RDX, RDX);  // RDX = 0, carry flag = 0.
-  Label sub_loop;
-  __ Bind(&sub_loop);
-  // Loop (a_used+1)/2 times, RCX > 0.
-  __ movq(RAX, FieldAddress(RDI, RDX, TIMES_8, TypedData::data_offset()));
-  __ sbbq(RAX, FieldAddress(RSI, RDX, TIMES_8, TypedData::data_offset()));
-  __ movq(FieldAddress(RBX, RDX, TIMES_8, TypedData::data_offset()), RAX);
-  __ incq(RDX);  // Does not affect carry flag.
-  __ decq(RCX);  // Does not affect carry flag.
-  __ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
-
-  Label done;
-  __ decq(R8);                              // Does not affect carry flag.
-  __ j(ZERO, &done, Assembler::kNearJump);  // If used - a_used == 0.
-
-  Label carry_loop;
-  __ Bind(&carry_loop);
-  // Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
-  __ movq(RAX, FieldAddress(RDI, RDX, TIMES_8, TypedData::data_offset()));
-  __ sbbq(RAX, Immediate(0));
-  __ movq(FieldAddress(RBX, RDX, TIMES_8, TypedData::data_offset()), RAX);
-  __ incq(RDX);  // Does not affect carry flag.
-  __ decq(R8);   // Does not affect carry flag.
-  __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  __ LoadObject(RAX, Object::null_object());
-  __ ret();
-}
-
-void Intrinsifier::Bigint_mulAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulAdd(Uint32List x_digits, int xi,
-  //                    Uint32List m_digits, int i,
-  //                    Uint32List a_digits, int j, int n) {
-  //   uint64_t x = x_digits[xi >> 1 .. (xi >> 1) + 1];  // xi is Smi and even.
-  //   if (x == 0 || n == 0) {
-  //     return 2;
-  //   }
-  //   uint64_t* mip = &m_digits[i >> 1];  // i is Smi and even.
-  //   uint64_t* ajp = &a_digits[j >> 1];  // j is Smi and even.
-  //   uint64_t c = 0;
-  //   SmiUntag(n);  // n is Smi and even.
-  //   n = (n + 1)/2;  // Number of pairs to process.
-  //   do {
-  //     uint64_t mi = *mip++;
-  //     uint64_t aj = *ajp;
-  //     uint128_t t = x*mi + aj + c;  // 64-bit * 64-bit -> 128-bit.
-  //     *ajp++ = low64(t);
-  //     c = high64(t);
-  //   } while (--n > 0);
-  //   while (c != 0) {
-  //     uint128_t t = *ajp + c;
-  //     *ajp++ = low64(t);
-  //     c = high64(t);  // c == 0 or 1.
-  //   }
-  //   return 2;
-  // }
-
-  Label done;
-  // RBX = x, done if x == 0
-  __ movq(RCX, Address(RSP, 7 * kWordSize));  // x_digits
-  __ movq(RAX, Address(RSP, 6 * kWordSize));  // xi is Smi
-  __ movq(RBX, FieldAddress(RCX, RAX, TIMES_2, TypedData::data_offset()));
-  __ testq(RBX, RBX);
-  __ j(ZERO, &done, Assembler::kNearJump);
-
-  // R8 = (SmiUntag(n) + 1)/2, no_op if n == 0
-  __ movq(R8, Address(RSP, 1 * kWordSize));
-  __ addq(R8, Immediate(2));
-  __ sarq(R8, Immediate(2));  // R8 = number of digit pairs to process.
-  __ j(ZERO, &done, Assembler::kNearJump);
-
-  // RDI = mip = &m_digits[i >> 1]
-  __ movq(RDI, Address(RSP, 5 * kWordSize));  // m_digits
-  __ movq(RAX, Address(RSP, 4 * kWordSize));  // i is Smi
-  __ leaq(RDI, FieldAddress(RDI, RAX, TIMES_2, TypedData::data_offset()));
-
-  // RSI = ajp = &a_digits[j >> 1]
-  __ movq(RSI, Address(RSP, 3 * kWordSize));  // a_digits
-  __ movq(RAX, Address(RSP, 2 * kWordSize));  // j is Smi
-  __ leaq(RSI, FieldAddress(RSI, RAX, TIMES_2, TypedData::data_offset()));
-
-  // RCX = c = 0
-  __ xorq(RCX, RCX);
-
-  Label muladd_loop;
-  __ Bind(&muladd_loop);
-  // x:   RBX
-  // mip: RDI
-  // ajp: RSI
-  // c:   RCX
-  // t:   RDX:RAX (not live at loop entry)
-  // n:   R8
-
-  // uint64_t mi = *mip++
-  __ movq(RAX, Address(RDI, 0));
-  __ addq(RDI, Immediate(2 * kBytesPerBigIntDigit));
-
-  // uint128_t t = x*mi
-  __ mulq(RBX);       // t = RDX:RAX = RAX * RBX, 64-bit * 64-bit -> 64-bit
-  __ addq(RAX, RCX);  // t += c
-  __ adcq(RDX, Immediate(0));
-
-  // uint64_t aj = *ajp; t += aj
-  __ addq(RAX, Address(RSI, 0));
-  __ adcq(RDX, Immediate(0));
-
-  // *ajp++ = low64(t)
-  __ movq(Address(RSI, 0), RAX);
-  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
-
-  // c = high64(t)
-  __ movq(RCX, RDX);
-
-  // while (--n > 0)
-  __ decq(R8);  // --n
-  __ j(NOT_ZERO, &muladd_loop, Assembler::kNearJump);
-
-  __ testq(RCX, RCX);
-  __ j(ZERO, &done, Assembler::kNearJump);
-
-  // *ajp += c
-  __ addq(Address(RSI, 0), RCX);
-  __ j(NOT_CARRY, &done, Assembler::kNearJump);
-
-  Label propagate_carry_loop;
-  __ Bind(&propagate_carry_loop);
-  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
-  __ incq(Address(RSI, 0));  // c == 0 or 1
-  __ j(CARRY, &propagate_carry_loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  __ movq(RAX, Immediate(Smi::RawValue(2)));  // Two digits processed.
-  __ ret();
-}
-
-void Intrinsifier::Bigint_sqrAdd(Assembler* assembler, Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _sqrAdd(Uint32List x_digits, int i,
-  //                    Uint32List a_digits, int used) {
-  //   uint64_t* xip = &x_digits[i >> 1];  // i is Smi and even.
-  //   uint64_t x = *xip++;
-  //   if (x == 0) return 2;
-  //   uint64_t* ajp = &a_digits[i];  // j == 2*i, i is Smi.
-  //   uint64_t aj = *ajp;
-  //   uint128_t t = x*x + aj;
-  //   *ajp++ = low64(t);
-  //   uint128_t c = high64(t);
-  //   int n = ((used - i + 2) >> 2) - 1;  // used and i are Smi. n: num pairs.
-  //   while (--n >= 0) {
-  //     uint64_t xi = *xip++;
-  //     uint64_t aj = *ajp;
-  //     uint192_t t = 2*x*xi + aj + c;  // 2-bit * 64-bit * 64-bit -> 129-bit.
-  //     *ajp++ = low64(t);
-  //     c = high128(t);  // 65-bit.
-  //   }
-  //   uint64_t aj = *ajp;
-  //   uint128_t t = aj + c;  // 64-bit + 65-bit -> 66-bit.
-  //   *ajp++ = low64(t);
-  //   *ajp = high64(t);
-  //   return 2;
-  // }
-
-  // RDI = xip = &x_digits[i >> 1]
-  __ movq(RDI, Address(RSP, 4 * kWordSize));  // x_digits
-  __ movq(RAX, Address(RSP, 3 * kWordSize));  // i is Smi
-  __ leaq(RDI, FieldAddress(RDI, RAX, TIMES_2, TypedData::data_offset()));
-
-  // RBX = x = *xip++, return if x == 0
-  Label x_zero;
-  __ movq(RBX, Address(RDI, 0));
-  __ cmpq(RBX, Immediate(0));
-  __ j(EQUAL, &x_zero);
-  __ addq(RDI, Immediate(2 * kBytesPerBigIntDigit));
-
-  // RSI = ajp = &a_digits[i]
-  __ movq(RSI, Address(RSP, 2 * kWordSize));  // a_digits
-  __ leaq(RSI, FieldAddress(RSI, RAX, TIMES_4, TypedData::data_offset()));
-
-  // RDX:RAX = t = x*x + *ajp
-  __ movq(RAX, RBX);
-  __ mulq(RBX);
-  __ addq(RAX, Address(RSI, 0));
-  __ adcq(RDX, Immediate(0));
-
-  // *ajp++ = low64(t)
-  __ movq(Address(RSI, 0), RAX);
-  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
-
-  // int n = (used - i + 1)/2 - 1
-  __ movq(R8, Address(RSP, 1 * kWordSize));  // used is Smi
-  __ subq(R8, Address(RSP, 3 * kWordSize));  // i is Smi
-  __ addq(R8, Immediate(2));
-  __ sarq(R8, Immediate(2));
-  __ decq(R8);  // R8 = number of digit pairs to process.
-
-  // uint128_t c = high64(t)
-  __ xorq(R13, R13);  // R13 = high64(c) == 0
-  __ movq(R12, RDX);  // R12 = low64(c) == high64(t)
-
-  Label loop, done;
-  __ Bind(&loop);
-  // x:   RBX
-  // xip: RDI
-  // ajp: RSI
-  // c:   R13:R12
-  // t:   RCX:RDX:RAX (not live at loop entry)
-  // n:   R8
-
-  // while (--n >= 0)
-  __ decq(R8);  // --n
-  __ j(NEGATIVE, &done, Assembler::kNearJump);
-
-  // uint64_t xi = *xip++
-  __ movq(RAX, Address(RDI, 0));
-  __ addq(RDI, Immediate(2 * kBytesPerBigIntDigit));
-
-  // uint192_t t = RCX:RDX:RAX = 2*x*xi + aj + c
-  __ mulq(RBX);       // RDX:RAX = RAX * RBX
-  __ xorq(RCX, RCX);  // RCX = 0
-  __ shldq(RCX, RDX, Immediate(1));
-  __ shldq(RDX, RAX, Immediate(1));
-  __ shlq(RAX, Immediate(1));     // RCX:RDX:RAX <<= 1
-  __ addq(RAX, Address(RSI, 0));  // t += aj
-  __ adcq(RDX, Immediate(0));
-  __ adcq(RCX, Immediate(0));
-  __ addq(RAX, R12);  // t += low64(c)
-  __ adcq(RDX, R13);  // t += high64(c) << 64
-  __ adcq(RCX, Immediate(0));
-
-  // *ajp++ = low64(t)
-  __ movq(Address(RSI, 0), RAX);
-  __ addq(RSI, Immediate(2 * kBytesPerBigIntDigit));
-
-  // c = high128(t)
-  __ movq(R12, RDX);
-  __ movq(R13, RCX);
-
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  // uint128_t t = aj + c
-  __ addq(R12, Address(RSI, 0));  // t = c, t += *ajp
-  __ adcq(R13, Immediate(0));
-
-  // *ajp++ = low64(t)
-  // *ajp = high64(t)
-  __ movq(Address(RSI, 0), R12);
-  __ movq(Address(RSI, 2 * kBytesPerBigIntDigit), R13);
-
-  __ Bind(&x_zero);
-  __ movq(RAX, Immediate(Smi::RawValue(2)));  // Two digits processed.
-  __ ret();
-}
-
-void Intrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _estQuotientDigit(Uint32List args, Uint32List digits, int i) {
-  //   uint64_t yt = args[_YT_LO .. _YT];  // _YT_LO == 0, _YT == 1.
-  //   uint64_t* dp = &digits[(i >> 1) - 1];  // i is Smi.
-  //   uint64_t dh = dp[0];  // dh == digits[(i >> 1) - 1 .. i >> 1].
-  //   uint64_t qd;
-  //   if (dh == yt) {
-  //     qd = (DIGIT_MASK << 32) | DIGIT_MASK;
-  //   } else {
-  //     dl = dp[-1];  // dl == digits[(i >> 1) - 3 .. (i >> 1) - 2].
-  //     qd = dh:dl / yt;  // No overflow possible, because dh < yt.
-  //   }
-  //   args[_QD .. _QD_HI] = qd;  // _QD == 2, _QD_HI == 3.
-  //   return 2;
-  // }
-
-  // RDI = args
-  __ movq(RDI, Address(RSP, 3 * kWordSize));  // args
-
-  // RCX = yt = args[0..1]
-  __ movq(RCX, FieldAddress(RDI, TypedData::data_offset()));
-
-  // RBX = dp = &digits[(i >> 1) - 1]
-  __ movq(RBX, Address(RSP, 2 * kWordSize));  // digits
-  __ movq(RAX, Address(RSP, 1 * kWordSize));  // i is Smi and odd.
-  __ leaq(RBX, FieldAddress(RBX, RAX, TIMES_2,
-                            TypedData::data_offset() - kBytesPerBigIntDigit));
-
-  // RDX = dh = dp[0]
-  __ movq(RDX, Address(RBX, 0));
-
-  // RAX = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
-  __ movq(RAX, Immediate(-1));
-
-  // Return qd if dh == yt
-  Label return_qd;
-  __ cmpq(RDX, RCX);
-  __ j(EQUAL, &return_qd, Assembler::kNearJump);
-
-  // RAX = dl = dp[-1]
-  __ movq(RAX, Address(RBX, -2 * kBytesPerBigIntDigit));
-
-  // RAX = qd = dh:dl / yt = RDX:RAX / RCX
-  __ divq(RCX);
-
-  __ Bind(&return_qd);
-  // args[2..3] = qd
-  __ movq(
-      FieldAddress(RDI, TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
-      RAX);
-
-  __ movq(RAX, Immediate(Smi::RawValue(2)));  // Two digits processed.
-  __ ret();
-}
-
-void Intrinsifier::Montgomery_mulMod(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  // Pseudo code:
-  // static int _mulMod(Uint32List args, Uint32List digits, int i) {
-  //   uint64_t rho = args[_RHO .. _RHO_HI];  // _RHO == 2, _RHO_HI == 3.
-  //   uint64_t d = digits[i >> 1 .. (i >> 1) + 1];  // i is Smi and even.
-  //   uint128_t t = rho*d;
-  //   args[_MU .. _MU_HI] = t mod DIGIT_BASE^2;  // _MU == 4, _MU_HI == 5.
-  //   return 2;
-  // }
-
-  // RDI = args
-  __ movq(RDI, Address(RSP, 3 * kWordSize));  // args
-
-  // RCX = rho = args[2 .. 3]
-  __ movq(RCX, FieldAddress(
-                   RDI, TypedData::data_offset() + 2 * kBytesPerBigIntDigit));
-
-  // RAX = digits[i >> 1 .. (i >> 1) + 1]
-  __ movq(RBX, Address(RSP, 2 * kWordSize));  // digits
-  __ movq(RAX, Address(RSP, 1 * kWordSize));  // i is Smi
-  __ movq(RAX, FieldAddress(RBX, RAX, TIMES_2, TypedData::data_offset()));
-
-  // RDX:RAX = t = rho*d
-  __ mulq(RCX);
-
-  // args[4 .. 5] = t mod DIGIT_BASE^2 = low64(t)
-  __ movq(
-      FieldAddress(RDI, TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
-      RAX);
-
-  __ movq(RAX, Immediate(Smi::RawValue(2)));  // Two digits processed.
-  __ ret();
-}
-
-// Check if the last argument is a double, jump to label 'is_smi' if smi
-// (easy to convert to double), otherwise jump to label 'not_double_smi',
-// Returns the last argument in RAX.
-static void TestLastArgumentIsDouble(Assembler* assembler,
-                                     Label* is_smi,
-                                     Label* not_double_smi) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(ZERO, is_smi);  // Jump if Smi.
-  __ CompareClassId(RAX, kDoubleCid);
-  __ j(NOT_EQUAL, not_double_smi);
-  // Fall through if double.
-}
-
-// Both arguments on stack, left argument is a double, right argument is of
-// unknown type. Return true or false object in RAX. Any NaN argument
-// returns false. Any non-double argument causes control flow to fall through
-// to the slow case (compiled method body).
-static void CompareDoubles(Assembler* assembler,
-                           Label* normal_ir_body,
-                           Condition true_condition) {
-  Label is_false, is_true, is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Both arguments are double, right operand is in RAX.
-  __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
-  __ Bind(&double_op);
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Left argument.
-  __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  __ comisd(XMM0, XMM1);
-  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false;
-  __ j(true_condition, &is_true, Assembler::kNearJump);
-  // Fall through false.
-  __ Bind(&is_false);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
-  __ jmp(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_greaterThan(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, ABOVE);
-}
-
-void Intrinsifier::Double_greaterEqualThan(Assembler* assembler,
-                                           Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, ABOVE_EQUAL);
-}
-
-void Intrinsifier::Double_lessThan(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, BELOW);
-}
-
-void Intrinsifier::Double_equal(Assembler* assembler, Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, EQUAL);
-}
-
-void Intrinsifier::Double_lessEqualThan(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  CompareDoubles(assembler, normal_ir_body, BELOW_EQUAL);
-}
-
-// Expects left argument to be double (receiver). Right argument is unknown.
-// Both arguments are on stack.
-static void DoubleArithmeticOperations(Assembler* assembler,
-                                       Label* normal_ir_body,
-                                       Token::Kind kind) {
-  Label is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Both arguments are double, right operand is in RAX.
-  __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
-  __ Bind(&double_op);
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Left argument.
-  __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  switch (kind) {
-    case Token::kADD:
-      __ addsd(XMM0, XMM1);
-      break;
-    case Token::kSUB:
-      __ subsd(XMM0, XMM1);
-      break;
-    case Token::kMUL:
-      __ mulsd(XMM0, XMM1);
-      break;
-    case Token::kDIV:
-      __ divsd(XMM0, XMM1);
-      break;
-    default:
-      UNREACHABLE();
-  }
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
-                 RAX,  // Result register.
-                 R13);
-  __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
-  __ jmp(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
-}
-
-void Intrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
-}
-
-void Intrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
-}
-
-void Intrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
-  DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
-}
-
-void Intrinsifier::Double_mulFromInteger(Assembler* assembler,
-                                         Label* normal_ir_body) {
-  // Only smis allowed.
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);
-  // Is Smi.
-  __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
-  __ movq(RAX, Address(RSP, +2 * kWordSize));
-  __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  __ mulsd(XMM0, XMM1);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
-                 RAX,  // Result register.
-                 R13);
-  __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-// Left is double, right is integer (Mint or Smi)
-void Intrinsifier::DoubleFromInteger(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ testq(RAX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);
-  // Is Smi.
-  __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM0, RAX);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
-                 RAX,  // Result register.
-                 R13);
-  __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_getIsNaN(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  Label is_true;
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  __ comisd(XMM0, XMM0);
-  __ j(PARITY_EVEN, &is_true, Assembler::kNearJump);  // NaN -> true;
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-}
-
-void Intrinsifier::Double_getIsInfinite(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  Label is_inf, done;
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ movq(RAX, FieldAddress(RAX, Double::value_offset()));
-  // Mask off the sign.
-  __ AndImmediate(RAX, Immediate(0x7FFFFFFFFFFFFFFFLL));
-  // Compare with +infinity.
-  __ CompareImmediate(RAX, Immediate(0x7FF0000000000000LL));
-  __ j(EQUAL, &is_inf, Assembler::kNearJump);
-  __ LoadObject(RAX, Bool::False());
-  __ jmp(&done);
-
-  __ Bind(&is_inf);
-  __ LoadObject(RAX, Bool::True());
-
-  __ Bind(&done);
-  __ ret();
-}
-
-void Intrinsifier::Double_getIsNegative(Assembler* assembler,
-                                        Label* normal_ir_body) {
-  Label is_false, is_true, is_zero;
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  __ xorpd(XMM1, XMM1);  // 0.0 -> XMM1.
-  __ comisd(XMM0, XMM1);
-  __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);  // NaN -> false.
-  __ j(EQUAL, &is_zero, Assembler::kNearJump);  // Check for negative zero.
-  __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump);  // >= 0 -> false.
-  __ Bind(&is_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-  __ Bind(&is_false);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&is_zero);
-  // Check for negative zero (get the sign bit).
-  __ movmskpd(RAX, XMM0);
-  __ testq(RAX, Immediate(1));
-  __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
-  __ jmp(&is_false, Assembler::kNearJump);
-}
-
-void Intrinsifier::DoubleToInteger(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
-  __ cvttsd2siq(RAX, XMM0);
-  // Overflow is signalled with minint.
-  // Check for overflow and that it fits into Smi.
-  __ movq(RCX, RAX);
-  __ shlq(RCX, Immediate(1));
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-  __ SmiTag(RAX);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::Double_hashCode(Assembler* assembler,
-                                   Label* normal_ir_body) {
-  // TODO(dartbug.com/31174): Convert this to a graph intrinsic.
-
-  // Convert double value to signed 64-bit int in RAX and
-  // back to a double in XMM1.
-  __ movq(RCX, Address(RSP, +1 * kWordSize));
-  __ movsd(XMM0, FieldAddress(RCX, Double::value_offset()));
-  __ cvttsd2siq(RAX, XMM0);
-  __ cvtsi2sdq(XMM1, RAX);
-
-  // Tag the int as a Smi, making sure that it fits; this checks for
-  // overflow and NaN in the conversion from double to int. Conversion
-  // overflow from cvttsd2si is signalled with an INT64_MIN value.
-  ASSERT(kSmiTag == 0 && kSmiTagShift == 1);
-  __ addq(RAX, RAX);
-  __ j(OVERFLOW, normal_ir_body, Assembler::kNearJump);
-
-  // Compare the two double values. If they are equal, we return the
-  // Smi tagged result immediately as the hash code.
-  Label double_hash;
-  __ comisd(XMM0, XMM1);
-  __ j(NOT_EQUAL, &double_hash, Assembler::kNearJump);
-  __ ret();
-
-  // Convert the double bits to a hash code that fits in a Smi.
-  __ Bind(&double_hash);
-  __ movq(RAX, FieldAddress(RCX, Double::value_offset()));
-  __ movq(RCX, RAX);
-  __ shrq(RCX, Immediate(32));
-  __ xorq(RAX, RCX);
-  __ andq(RAX, Immediate(kSmiMax));
-  __ SmiTag(RAX);
-  __ ret();
-
-  // Fall into the native C++ implementation.
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::MathSqrt(Assembler* assembler, Label* normal_ir_body) {
-  Label is_smi, double_op;
-  TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
-  // Argument is double and is in RAX.
-  __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
-  __ Bind(&double_op);
-  __ sqrtsd(XMM0, XMM1);
-  const Class& double_class =
-      Class::Handle(Isolate::Current()->object_store()->double_class());
-  __ TryAllocate(double_class, normal_ir_body, Assembler::kFarJump,
-                 RAX,  // Result register.
-                 R13);
-  __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
-  __ ret();
-  __ Bind(&is_smi);
-  __ SmiUntag(RAX);
-  __ cvtsi2sdq(XMM1, RAX);
-  __ jmp(&double_op);
-  __ Bind(normal_ir_body);
-}
-
-//    var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64;
-//    _state[kSTATE_LO] = state & _MASK_32;
-//    _state[kSTATE_HI] = state >> 32;
-void Intrinsifier::Random_nextState(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  const Library& math_lib = Library::Handle(Library::MathLibrary());
-  ASSERT(!math_lib.IsNull());
-  const Class& random_class =
-      Class::Handle(math_lib.LookupClassAllowPrivate(Symbols::_Random()));
-  ASSERT(!random_class.IsNull());
-  const Field& state_field = Field::ZoneHandle(
-      random_class.LookupInstanceFieldAllowPrivate(Symbols::_state()));
-  ASSERT(!state_field.IsNull());
-  const int64_t a_int_value = Intrinsifier::kRandomAValue;
-
-  // Receiver.
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  // Field '_state'.
-  __ movq(RBX, FieldAddress(RAX, state_field.Offset()));
-  // Addresses of _state[0] and _state[1].
-  const intptr_t scale = Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
-  const intptr_t offset = Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
-  Address addr_0 = FieldAddress(RBX, 0 * scale + offset);
-  Address addr_1 = FieldAddress(RBX, 1 * scale + offset);
-  __ movq(RAX, Immediate(a_int_value));
-  __ movl(RCX, addr_0);
-  __ imulq(RCX, RAX);
-  __ movl(RDX, addr_1);
-  __ addq(RDX, RCX);
-  __ movl(addr_0, RDX);
-  __ shrq(RDX, Immediate(32));
-  __ movl(addr_1, RDX);
-  ASSERT(Smi::RawValue(0) == 0);
-  __ xorq(RAX, RAX);
-  __ ret();
-}
-
-// Identity comparison.
-void Intrinsifier::ObjectEquals(Assembler* assembler, Label* normal_ir_body) {
-  Label is_true;
-  const intptr_t kReceiverOffset = 2;
-  const intptr_t kArgumentOffset = 1;
-
-  __ movq(RAX, Address(RSP, +kArgumentOffset * kWordSize));
-  __ cmpq(RAX, Address(RSP, +kReceiverOffset * kWordSize));
-  __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-}
-
-static void RangeCheck(Assembler* assembler,
-                       Register reg,
-                       intptr_t low,
-                       intptr_t high,
-                       Condition cc,
-                       Label* target) {
-  __ subq(reg, Immediate(low));
-  __ cmpq(reg, Immediate(high - low));
-  __ j(cc, target);
-}
-
-const Condition kIfNotInRange = ABOVE;
-const Condition kIfInRange = BELOW_EQUAL;
-
-static void JumpIfInteger(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfInRange, target);
-}
-
-static void JumpIfNotInteger(Assembler* assembler,
-                             Register cid,
-                             Label* target) {
-  RangeCheck(assembler, cid, kSmiCid, kMintCid, kIfNotInRange, target);
-}
-
-static void JumpIfString(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfInRange, target);
-}
-
-static void JumpIfNotString(Assembler* assembler, Register cid, Label* target) {
-  RangeCheck(assembler, cid, kOneByteStringCid, kExternalTwoByteStringCid,
-             kIfNotInRange, target);
-}
-
-// Return type quickly for simple types (not parameterized and not signature).
-void Intrinsifier::ObjectRuntimeType(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Label use_declaration_type, not_integer, not_double;
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ LoadClassIdMayBeSmi(RCX, RAX);
-
-  // RCX: untagged cid of instance (RAX).
-  __ cmpq(RCX, Immediate(kClosureCid));
-  __ j(EQUAL, normal_ir_body);  // Instance is a closure.
-
-  __ cmpl(RCX, Immediate(kNumPredefinedCids));
-  __ j(ABOVE, &use_declaration_type);
-
-  // If object is a instance of _Double return double type.
-  __ cmpl(RCX, Immediate(kDoubleCid));
-  __ j(NOT_EQUAL, &not_double);
-
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
-  __ movq(RAX, Address(RAX, ObjectStore::double_type_offset()));
-  __ ret();
-
-  __ Bind(&not_double);
-  // If object is an integer (smi, mint or bigint) return int type.
-  __ movl(RAX, RCX);
-  JumpIfNotInteger(assembler, RAX, &not_integer);
-
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
-  __ movq(RAX, Address(RAX, ObjectStore::int_type_offset()));
-  __ ret();
-
-  __ Bind(&not_integer);
-  // If object is a string (one byte, two byte or external variants) return
-  // string type.
-  __ movq(RAX, RCX);
-  JumpIfNotString(assembler, RAX, &use_declaration_type);
-
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, Isolate::object_store_offset()));
-  __ movq(RAX, Address(RAX, ObjectStore::string_type_offset()));
-  __ ret();
-
-  // Object is neither double, nor integer, nor string.
-  __ Bind(&use_declaration_type);
-  __ LoadClassById(RDI, RCX);
-  __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
-  __ cmpq(RCX, Immediate(0));
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-  __ movq(RAX, FieldAddress(RDI, Class::declaration_type_offset()));
-  __ CompareObject(RAX, Object::null_object());
-  __ j(EQUAL, normal_ir_body, Assembler::kNearJump);  // Not yet set.
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label different_cids, equal, not_equal, not_integer;
-
-  __ movq(RAX, Address(RSP, +1 * kWordSize));
-  __ LoadClassIdMayBeSmi(RCX, RAX);
-
-  // Check if left hand size is a closure. Closures are handled in the runtime.
-  __ cmpq(RCX, Immediate(kClosureCid));
-  __ j(EQUAL, normal_ir_body);
-
-  __ movq(RAX, Address(RSP, +2 * kWordSize));
-  __ LoadClassIdMayBeSmi(RDX, RAX);
-
-  // Check whether class ids match. If class ids don't match objects can still
-  // have the same runtime type (e.g. multiple string implementation classes
-  // map to a single String type).
-  __ cmpq(RCX, RDX);
-  __ j(NOT_EQUAL, &different_cids);
-
-  // Objects have the same class and neither is a closure.
-  // Check if there are no type arguments. In this case we can return true.
-  // Otherwise fall through into the runtime to handle comparison.
-  __ LoadClassById(RDI, RCX);
-  __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
-  __ cmpq(RCX, Immediate(0));
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-
-  __ Bind(&equal);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-
-  // Class ids are different. Check if we are comparing runtime types of
-  // two strings (with different representations) or two integers.
-  __ Bind(&different_cids);
-  __ cmpq(RCX, Immediate(kNumPredefinedCids));
-  __ j(ABOVE_EQUAL, &not_equal);
-
-  __ movq(RAX, RCX);
-  JumpIfNotInteger(assembler, RAX, &not_integer);
-
-  // First object is an integer. Check if the second is an integer too.
-  // Otherwise types are unequal because only integers have the same runtime
-  // type as other integers.
-  JumpIfInteger(assembler, RDX, &equal);
-  __ jmp(&not_equal);
-
-  __ Bind(&not_integer);
-  // Check if the first object is a string. If it is not then
-  // objects don't have the same runtime type because they have
-  // different class ids and they are not strings or integers.
-  JumpIfNotString(assembler, RCX, &not_equal);
-  // First object is a string. Check if the second is a string too.
-  JumpIfString(assembler, RDX, &equal);
-  // Strings only have the same runtime type as other strings.
-  // Fall-through to the not equal case.
-
-  __ Bind(&not_equal);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::String_getHashCode(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));  // String object.
-  __ movl(RAX, FieldAddress(RAX, String::hash_offset()));
-  ASSERT(kSmiTag == 0);
-  ASSERT(kSmiTagShift == 1);
-  __ addq(RAX, RAX);  // Smi tag RAX, setting Z flag.
-  __ j(ZERO, normal_ir_body, Assembler::kNearJump);
-  __ ret();
-  __ Bind(normal_ir_body);
-  // Hash not yet computed.
-}
-
-void Intrinsifier::Type_getHashCode(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));  // Type object.
-  __ movq(RAX, FieldAddress(RAX, Type::hash_offset()));
-  ASSERT(kSmiTag == 0);
-  ASSERT(kSmiTagShift == 1);
-  __ testq(RAX, RAX);
-  __ j(ZERO, normal_ir_body, Assembler::kNearJump);
-  __ ret();
-  __ Bind(normal_ir_body);
-  // Hash not yet computed.
-}
-
-void Intrinsifier::Object_getHash(Assembler* assembler, Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +1 * kWordSize));  // Object.
-  __ movl(RAX, FieldAddress(RAX, String::hash_offset()));
-  __ SmiTag(RAX);
-  __ ret();
-}
-
-void Intrinsifier::Object_setHash(Assembler* assembler, Label* normal_ir_body) {
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Object.
-  __ movq(RDX, Address(RSP, +1 * kWordSize));  // Value.
-  __ SmiUntag(RDX);
-  __ movl(FieldAddress(RAX, String::hash_offset()), RDX);
-  __ ret();
-}
-
-void GenerateSubstringMatchesSpecialization(Assembler* assembler,
-                                            intptr_t receiver_cid,
-                                            intptr_t other_cid,
-                                            Label* return_true,
-                                            Label* return_false) {
-  __ movq(R8, FieldAddress(RAX, String::length_offset()));
-  __ movq(R9, FieldAddress(RCX, String::length_offset()));
-
-  // if (other.length == 0) return true;
-  __ testq(R9, R9);
-  __ j(ZERO, return_true);
-
-  // if (start < 0) return false;
-  __ testq(RBX, RBX);
-  __ j(SIGN, return_false);
-
-  // if (start + other.length > this.length) return false;
-  __ movq(R11, RBX);
-  __ addq(R11, R9);
-  __ cmpq(R11, R8);
-  __ j(GREATER, return_false);
-
-  __ SmiUntag(RBX);            // start
-  __ SmiUntag(R9);             // other.length
-  __ LoadImmediate(R11, Immediate(0));  // i = 0
-
-  // do
-  Label loop;
-  __ Bind(&loop);
-
-  // this.codeUnitAt(i + start)
-  // clobbering this.length
-  __ movq(R8, R11);
-  __ addq(R8, RBX);
-  if (receiver_cid == kOneByteStringCid) {
-    __ movzxb(R12,
-              FieldAddress(RAX, R8, TIMES_1, OneByteString::data_offset()));
-  } else {
-    ASSERT(receiver_cid == kTwoByteStringCid);
-    __ movzxw(R12,
-              FieldAddress(RAX, R8, TIMES_2, TwoByteString::data_offset()));
-  }
-  // other.codeUnitAt(i)
-  if (other_cid == kOneByteStringCid) {
-    __ movzxb(R13,
-              FieldAddress(RCX, R11, TIMES_1, OneByteString::data_offset()));
-  } else {
-    ASSERT(other_cid == kTwoByteStringCid);
-    __ movzxw(R13,
-              FieldAddress(RCX, R11, TIMES_2, TwoByteString::data_offset()));
-  }
-  __ cmpq(R12, R13);
-  __ j(NOT_EQUAL, return_false);
-
-  // i++, while (i < len)
-  __ addq(R11, Immediate(1));
-  __ cmpq(R11, R9);
-  __ j(LESS, &loop, Assembler::kNearJump);
-
-  __ jmp(return_true);
-}
-
-// bool _substringMatches(int start, String other)
-// This intrinsic handles a OneByteString or TwoByteString receiver with a
-// OneByteString other.
-void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  Label return_true, return_false, try_two_byte;
-  __ movq(RAX, Address(RSP, +3 * kWordSize));  // receiver
-  __ movq(RBX, Address(RSP, +2 * kWordSize));  // start
-  __ movq(RCX, Address(RSP, +1 * kWordSize));  // other
-
-  __ testq(RBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);  // 'start' is not Smi.
-
-  __ CompareClassId(RCX, kOneByteStringCid);
-  __ j(NOT_EQUAL, normal_ir_body);
-
-  __ CompareClassId(RAX, kOneByteStringCid);
-  __ j(NOT_EQUAL, &try_two_byte);
-
-  GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
-                                         kOneByteStringCid, &return_true,
-                                         &return_false);
-
-  __ Bind(&try_two_byte);
-  __ CompareClassId(RAX, kTwoByteStringCid);
-  __ j(NOT_EQUAL, normal_ir_body);
-
-  GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
-                                         kOneByteStringCid, &return_true,
-                                         &return_false);
-
-  __ Bind(&return_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-
-  __ Bind(&return_false);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::StringBaseCharAt(Assembler* assembler,
-                                    Label* normal_ir_body) {
-  Label try_two_byte_string;
-  __ movq(RCX, Address(RSP, +1 * kWordSize));  // Index.
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // String.
-  __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);  // Non-smi index.
-  // Range check.
-  __ cmpq(RCX, FieldAddress(RAX, String::length_offset()));
-  // Runtime throws exception.
-  __ j(ABOVE_EQUAL, normal_ir_body);
-  __ CompareClassId(RAX, kOneByteStringCid);
-  __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
-  __ SmiUntag(RCX);
-  __ movzxb(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
-  __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, normal_ir_body);
-  __ movq(RAX, Address(THR, Thread::predefined_symbols_address_offset()));
-  __ movq(RAX, Address(RAX, RCX, TIMES_8,
-                       Symbols::kNullCharCodeSymbolOffset * kWordSize));
-  __ ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(RAX, kTwoByteStringCid);
-  __ j(NOT_EQUAL, normal_ir_body);
-  ASSERT(kSmiTagShift == 1);
-  __ movzxw(RCX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
-  __ cmpq(RCX, Immediate(Symbols::kNumberOfOneCharCodeSymbols));
-  __ j(GREATER_EQUAL, normal_ir_body);
-  __ movq(RAX, Address(THR, Thread::predefined_symbols_address_offset()));
-  __ movq(RAX, Address(RAX, RCX, TIMES_8,
-                       Symbols::kNullCharCodeSymbolOffset * kWordSize));
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::StringBaseIsEmpty(Assembler* assembler,
-                                     Label* normal_ir_body) {
-  Label is_true;
-  // Get length.
-  __ movq(RAX, Address(RSP, +1 * kWordSize));  // String object.
-  __ movq(RAX, FieldAddress(RAX, String::length_offset()));
-  __ cmpq(RAX, Immediate(Smi::RawValue(0)));
-  __ j(EQUAL, &is_true, Assembler::kNearJump);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  __ Bind(&is_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-}
-
-void Intrinsifier::OneByteString_getHashCode(Assembler* assembler,
-                                             Label* normal_ir_body) {
-  Label compute_hash;
-  __ movq(RBX, Address(RSP, +1 * kWordSize));  // OneByteString object.
-  __ movl(RAX, FieldAddress(RBX, String::hash_offset()));
-  __ cmpq(RAX, Immediate(0));
-  __ j(EQUAL, &compute_hash, Assembler::kNearJump);
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&compute_hash);
-  // Hash not yet computed, use algorithm of class StringHasher.
-  __ movq(RCX, FieldAddress(RBX, String::length_offset()));
-  __ SmiUntag(RCX);
-  __ xorq(RAX, RAX);
-  __ xorq(RDI, RDI);
-  // RBX: Instance of OneByteString.
-  // RCX: String length, untagged integer.
-  // RDI: Loop counter, untagged integer.
-  // RAX: Hash code, untagged integer.
-  Label loop, done, set_hash_code;
-  __ Bind(&loop);
-  __ cmpq(RDI, RCX);
-  __ j(EQUAL, &done, Assembler::kNearJump);
-  // Add to hash code: (hash_ is uint32)
-  // hash_ += ch;
-  // hash_ += hash_ << 10;
-  // hash_ ^= hash_ >> 6;
-  // Get one characters (ch).
-  __ movzxb(RDX, FieldAddress(RBX, RDI, TIMES_1, OneByteString::data_offset()));
-  // RDX: ch and temporary.
-  __ addl(RAX, RDX);
-  __ movq(RDX, RAX);
-  __ shll(RDX, Immediate(10));
-  __ addl(RAX, RDX);
-  __ movq(RDX, RAX);
-  __ shrl(RDX, Immediate(6));
-  __ xorl(RAX, RDX);
-
-  __ incq(RDI);
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&done);
-  // Finalize:
-  // hash_ += hash_ << 3;
-  // hash_ ^= hash_ >> 11;
-  // hash_ += hash_ << 15;
-  __ movq(RDX, RAX);
-  __ shll(RDX, Immediate(3));
-  __ addl(RAX, RDX);
-  __ movq(RDX, RAX);
-  __ shrl(RDX, Immediate(11));
-  __ xorl(RAX, RDX);
-  __ movq(RDX, RAX);
-  __ shll(RDX, Immediate(15));
-  __ addl(RAX, RDX);
-  // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1);
-  __ andl(RAX,
-          Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1)));
-
-  // return hash_ == 0 ? 1 : hash_;
-  __ cmpq(RAX, Immediate(0));
-  __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump);
-  __ incq(RAX);
-  __ Bind(&set_hash_code);
-  __ movl(FieldAddress(RBX, String::hash_offset()), RAX);
-  __ SmiTag(RAX);
-  __ ret();
-}
-
-// Allocates one-byte string of length 'end - start'. The content is not
-// initialized. 'length-reg' contains tagged length.
-// Returns new string as tagged pointer in RAX.
-static void TryAllocateOnebyteString(Assembler* assembler,
-                                     Label* ok,
-                                     Label* failure,
-                                     Register length_reg) {
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, failure, false));
-  if (length_reg != RDI) {
-    __ movq(RDI, length_reg);
-  }
-  Label pop_and_fail, not_zero_length;
-  __ pushq(RDI);                          // Preserve length.
-  __ sarq(RDI, Immediate(kSmiTagShift));  // Untag length.
-  // If the length is 0 then we have to make the allocated size a bit bigger,
-  // otherwise the string takes up less space than an ExternalOneByteString,
-  // and cannot be externalized.  TODO(erikcorry): We should probably just
-  // return a static zero length string here instead.
-  __ j(NOT_ZERO, &not_zero_length);
-  __ addq(RDI, Immediate(1));
-  __ Bind(&not_zero_length);
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawString) + kObjectAlignment - 1;
-  __ addq(RDI, Immediate(fixed_size_plus_alignment_padding));
-  __ andq(RDI, Immediate(-kObjectAlignment));
-
-  const intptr_t cid = kOneByteStringCid;
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  __ movq(RAX, Address(THR, Thread::top_offset()));
-
-  // RDI: allocation size.
-  __ movq(RCX, RAX);
-  __ addq(RCX, RDI);
-  __ j(CARRY, &pop_and_fail);
-
-  // Check if the allocation fits into the remaining space.
-  // RAX: potential new object start.
-  // RCX: potential next object start.
-  // RDI: allocation size.
-  __ cmpq(RCX, Address(THR, Thread::end_offset()));
-  __ j(ABOVE_EQUAL, &pop_and_fail);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  __ movq(Address(THR, Thread::top_offset()), RCX);
-  __ addq(RAX, Immediate(kHeapObjectTag));
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, RDI, space));
-
-  // Initialize the tags.
-  // RAX: new object start as a tagged pointer.
-  // RDI: allocation size.
-  {
-    Label size_tag_overflow, done;
-    __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
-    __ jmp(&done, Assembler::kNearJump);
-
-    __ Bind(&size_tag_overflow);
-    __ xorq(RDI, RDI);
-    __ Bind(&done);
-
-    // Get the class index and insert it into the tags.
-    // This also clears the hash, which is in the high bits of the tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ orq(RDI, Immediate(tags));
-    __ movq(FieldAddress(RAX, String::tags_offset()), RDI);  // Tags.
-  }
-
-  // Set the length field.
-  __ popq(RDI);
-  __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, String::length_offset()),
-                              RDI);
-  __ jmp(ok, Assembler::kNearJump);
-
-  __ Bind(&pop_and_fail);
-  __ popq(RDI);
-  __ jmp(failure);
-}
-
-// Arg0: OneByteString (receiver).
-// Arg1: Start index as Smi.
-// Arg2: End index as Smi.
-// The indexes must be valid.
-void Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
-                                                    Label* normal_ir_body) {
-  const intptr_t kStringOffset = 3 * kWordSize;
-  const intptr_t kStartIndexOffset = 2 * kWordSize;
-  const intptr_t kEndIndexOffset = 1 * kWordSize;
-  Label ok;
-  __ movq(RSI, Address(RSP, +kStartIndexOffset));
-  __ movq(RDI, Address(RSP, +kEndIndexOffset));
-  __ orq(RSI, RDI);
-  __ testq(RSI, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, normal_ir_body);  // 'start', 'end' not Smi.
-
-  __ subq(RDI, Address(RSP, +kStartIndexOffset));
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
-  __ Bind(&ok);
-  // RAX: new string as tagged pointer.
-  // Copy string.
-  __ movq(RSI, Address(RSP, +kStringOffset));
-  __ movq(RBX, Address(RSP, +kStartIndexOffset));
-  __ SmiUntag(RBX);
-  __ leaq(RSI, FieldAddress(RSI, RBX, TIMES_1, OneByteString::data_offset()));
-  // RSI: Start address to copy from (untagged).
-  // RBX: Untagged start index.
-  __ movq(RCX, Address(RSP, +kEndIndexOffset));
-  __ SmiUntag(RCX);
-  __ subq(RCX, RBX);
-  __ xorq(RDX, RDX);
-  // RSI: Start address to copy from (untagged).
-  // RCX: Untagged number of bytes to copy.
-  // RAX: Tagged result string
-  // RDX: Loop counter.
-  // RBX: Scratch register.
-  Label loop, check;
-  __ jmp(&check, Assembler::kNearJump);
-  __ Bind(&loop);
-  __ movzxb(RBX, Address(RSI, RDX, TIMES_1, 0));
-  __ movb(FieldAddress(RAX, RDX, TIMES_1, OneByteString::data_offset()), RBX);
-  __ incq(RDX);
-  __ Bind(&check);
-  __ cmpq(RDX, RCX);
-  __ j(LESS, &loop, Assembler::kNearJump);
-  __ ret();
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteStringSetAt(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ movq(RCX, Address(RSP, +1 * kWordSize));  // Value.
-  __ movq(RBX, Address(RSP, +2 * kWordSize));  // Index.
-  __ movq(RAX, Address(RSP, +3 * kWordSize));  // OneByteString.
-  __ SmiUntag(RBX);
-  __ SmiUntag(RCX);
-  __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
-  __ ret();
-}
-
-void Intrinsifier::OneByteString_allocate(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ movq(RDI, Address(RSP, +1 * kWordSize));  // Length.v=
-  Label ok;
-  TryAllocateOnebyteString(assembler, &ok, normal_ir_body, RDI);
-  // RDI: Start address to copy from (untagged).
-
-  __ Bind(&ok);
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
-static void StringEquality(Assembler* assembler,
-                           Label* normal_ir_body,
-                           intptr_t string_cid) {
-  Label is_true, is_false, loop;
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // This.
-  __ movq(RCX, Address(RSP, +1 * kWordSize));  // Other.
-
-  // Are identical?
-  __ cmpq(RAX, RCX);
-  __ j(EQUAL, &is_true, Assembler::kNearJump);
-
-  // Is other OneByteString?
-  __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(ZERO, &is_false);  // Smi
-  __ CompareClassId(RCX, string_cid);
-  __ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
-
-  // Have same length?
-  __ movq(RDI, FieldAddress(RAX, String::length_offset()));
-  __ cmpq(RDI, FieldAddress(RCX, String::length_offset()));
-  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
-
-  // Check contents, no fall-through possible.
-  // TODO(srdjan): write a faster check.
-  __ SmiUntag(RDI);
-  __ Bind(&loop);
-  __ decq(RDI);
-  __ cmpq(RDI, Immediate(0));
-  __ j(LESS, &is_true, Assembler::kNearJump);
-  if (string_cid == kOneByteStringCid) {
-    __ movzxb(RBX,
-              FieldAddress(RAX, RDI, TIMES_1, OneByteString::data_offset()));
-    __ movzxb(RDX,
-              FieldAddress(RCX, RDI, TIMES_1, OneByteString::data_offset()));
-  } else if (string_cid == kTwoByteStringCid) {
-    __ movzxw(RBX,
-              FieldAddress(RAX, RDI, TIMES_2, TwoByteString::data_offset()));
-    __ movzxw(RDX,
-              FieldAddress(RCX, RDI, TIMES_2, TwoByteString::data_offset()));
-  } else {
-    UNIMPLEMENTED();
-  }
-  __ cmpq(RBX, RDX);
-  __ j(NOT_EQUAL, &is_false, Assembler::kNearJump);
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&is_true);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-
-  __ Bind(&is_false);
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-
-  __ Bind(normal_ir_body);
-}
-
-void Intrinsifier::OneByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kOneByteStringCid);
-}
-
-void Intrinsifier::TwoByteString_equality(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  StringEquality(assembler, normal_ir_body, kTwoByteStringCid);
-}
-
-void Intrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
-                                                Label* normal_ir_body,
-                                                bool sticky) {
-  if (FLAG_interpret_irregexp) return;
-
-  static const intptr_t kRegExpParamOffset = 3 * kWordSize;
-  static const intptr_t kStringParamOffset = 2 * kWordSize;
-  // start_index smi is located at offset 1.
-
-  // Incoming registers:
-  // RAX: Function. (Will be loaded with the specialized matcher function.)
-  // RCX: Unknown. (Must be GC safe on tail call.)
-  // R10: Arguments descriptor. (Will be preserved.)
-
-  // Load the specialized function pointer into RAX. Leverage the fact the
-  // string CIDs as well as stored function pointers are in sequence.
-  __ movq(RBX, Address(RSP, kRegExpParamOffset));
-  __ movq(RDI, Address(RSP, kStringParamOffset));
-  __ LoadClassId(RDI, RDI);
-  __ SubImmediate(RDI, Immediate(kOneByteStringCid));
-  __ movq(RAX,
-          FieldAddress(RBX, RDI, TIMES_8,
-                       RegExp::function_offset(kOneByteStringCid, sticky)));
-
-  // Registers are now set up for the lazy compile stub. It expects the function
-  // in RAX, the argument descriptor in R10, and IC-Data in RCX.
-  __ xorq(RCX, RCX);
-
-  // Tail-call the function.
-  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RDI, FieldAddress(RAX, Function::entry_point_offset()));
-  __ jmp(RDI);
-}
-
-// On stack: user tag (+1), return-address (+0).
-void Intrinsifier::UserTag_makeCurrent(Assembler* assembler,
-                                       Label* normal_ir_body) {
-  // RBX: Isolate.
-  __ LoadIsolate(RBX);
-  // RAX: Current user tag.
-  __ movq(RAX, Address(RBX, Isolate::current_tag_offset()));
-  // R10: UserTag.
-  __ movq(R10, Address(RSP, +1 * kWordSize));
-  // Set Isolate::current_tag_.
-  __ movq(Address(RBX, Isolate::current_tag_offset()), R10);
-  // R10: UserTag's tag.
-  __ movq(R10, FieldAddress(R10, UserTag::tag_offset()));
-  // Set Isolate::user_tag_.
-  __ movq(Address(RBX, Isolate::user_tag_offset()), R10);
-  __ ret();
-}
-
-void Intrinsifier::UserTag_defaultTag(Assembler* assembler,
-                                      Label* normal_ir_body) {
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, Isolate::default_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler,
-                                          Label* normal_ir_body) {
-  __ LoadIsolate(RAX);
-  __ movq(RAX, Address(RAX, Isolate::current_tag_offset()));
-  __ ret();
-}
-
-void Intrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
-                                                Label* normal_ir_body) {
-  if (!FLAG_support_timeline) {
-    __ LoadObject(RAX, Bool::False());
-    __ ret();
-    return;
-  }
-  Label true_label;
-  // Load TimelineStream*.
-  __ movq(RAX, Address(THR, Thread::dart_stream_offset()));
-  // Load uintptr_t from TimelineStream*.
-  __ movq(RAX, Address(RAX, TimelineStream::enabled_offset()));
-  __ cmpq(RAX, Immediate(0));
-  __ j(NOT_ZERO, &true_label, Assembler::kNearJump);
-  // Not enabled.
-  __ LoadObject(RAX, Bool::False());
-  __ ret();
-  // Enabled.
-  __ Bind(&true_label);
-  __ LoadObject(RAX, Bool::True());
-  __ ret();
-}
-
-void Intrinsifier::ClearAsyncThreadStackTrace(Assembler* assembler,
-                                              Label* normal_ir_body) {
-  __ LoadObject(RAX, Object::null_object());
-  __ movq(Address(THR, Thread::async_stack_trace_offset()), RAX);
-  __ ret();
-}
-
-void Intrinsifier::SetAsyncThreadStackTrace(Assembler* assembler,
-                                            Label* normal_ir_body) {
-  __ movq(Address(THR, Thread::async_stack_trace_offset()), RAX);
-  __ LoadObject(RAX, Object::null_object());
-  __ ret();
-}
-
-#undef __
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index c63af58..66292fa 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -103,6 +103,9 @@
     FLAG_background_compilation = false;
     FLAG_collect_code = false;
     FLAG_enable_mirrors = false;
+    // TODO(dacoharkes): Ffi support in AOT
+    // https://github.com/dart-lang/sdk/issues/35765
+    FLAG_enable_ffi = false;
     FLAG_fields_may_be_reset = true;
     FLAG_interpret_irregexp = true;
     FLAG_lazy_dispatchers = false;
@@ -125,7 +128,6 @@
     FLAG_deoptimize_alot = false;  // Used in some tests.
     FLAG_deoptimize_every = 0;     // Used in some tests.
     FLAG_load_deferred_eagerly = true;
-    FLAG_print_stop_message = false;
     FLAG_use_osr = false;
 #endif
   }
@@ -557,8 +559,6 @@
     return Code::null();
   }
   Zone* const zone = thread()->zone();
-  NOT_IN_PRODUCT(TimelineStream* compiler_timeline =
-                     Timeline::GetCompilerStream());
   HANDLESCOPE(thread());
 
   // We may reattempt compilation if the function needs to be assembled using
@@ -619,8 +619,7 @@
           }
         }
 
-        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
-                                                 "BuildFlowGraph"));
+        TIMELINE_DURATION(thread(), CompilerVerbose, "BuildFlowGraph");
         flow_graph = pipeline->BuildFlowGraph(
             zone, parsed_function(), ic_data_array, osr_id(), optimized());
       }
@@ -638,19 +637,17 @@
       const bool reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized());
       if (reorder_blocks) {
-        NOT_IN_PRODUCT(TimelineDurationScope tds(
-            thread(), compiler_timeline, "BlockScheduler::AssignEdgeWeights"));
+        TIMELINE_DURATION(thread(), CompilerVerbose,
+                          "BlockScheduler::AssignEdgeWeights");
         block_scheduler.AssignEdgeWeights();
       }
 
       CompilerPassState pass_state(thread(), flow_graph, &speculative_policy);
-      NOT_IN_PRODUCT(pass_state.compiler_timeline = compiler_timeline);
       pass_state.block_scheduler = &block_scheduler;
       pass_state.reorder_blocks = reorder_blocks;
 
       if (optimized()) {
-        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
-                                                 "OptimizationPasses"));
+        TIMELINE_DURATION(thread(), CompilerVerbose, "OptimizationPasses");
 
         pass_state.inline_id_to_function.Add(&function);
         // We do not add the token position now because we don't know the
@@ -669,22 +666,20 @@
 
       ASSERT(pass_state.inline_id_to_function.length() ==
              pass_state.caller_inline_id.length());
-      ObjectPoolWrapper object_pool_wrapper;
-      Assembler assembler(&object_pool_wrapper, use_far_branches);
+      ObjectPoolBuilder object_pool_builder;
+      Assembler assembler(&object_pool_builder, use_far_branches);
       FlowGraphCompiler graph_compiler(
           &assembler, flow_graph, *parsed_function(), optimized(),
           &speculative_policy, pass_state.inline_id_to_function,
           pass_state.inline_id_to_token_pos, pass_state.caller_inline_id,
           ic_data_array);
       {
-        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
-                                                 "CompileGraph"));
+        TIMELINE_DURATION(thread(), CompilerVerbose, "CompileGraph");
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation(flow_graph);
       }
       {
-        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(), compiler_timeline,
-                                                 "FinalizeCompilation"));
+        TIMELINE_DURATION(thread(), CompilerVerbose, "FinalizeCompilation");
         if (thread()->IsMutatorThread()) {
           *result =
               FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
@@ -708,6 +703,19 @@
           }
         }
       }
+      if (!result->IsNull()) {
+#if !defined(PRODUCT)
+        if (!function.HasOptimizedCode()) {
+          isolate()->debugger()->NotifyCompilation(function);
+        }
+#endif
+        if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
+          Disassembler::DisassembleCode(function, *result, optimized());
+        } else if (FLAG_disassemble_optimized && optimized() &&
+                   FlowGraphPrinter::ShouldPrint(function)) {
+          Disassembler::DisassembleCode(function, *result, true);
+        }
+      }
       // Exit the loop and the function with the correct result value.
       done = true;
     } else {
@@ -882,17 +890,6 @@
                 per_compile_timer.TotalElapsedTime());
     }
 
-#if !defined(PRODUCT)
-    isolate->debugger()->NotifyCompilation(function);
-#endif
-
-    if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
-      Disassembler::DisassembleCode(function, result, optimized);
-    } else if (FLAG_disassemble_optimized && optimized &&
-               FlowGraphPrinter::ShouldPrint(function)) {
-      Disassembler::DisassembleCode(function, result, true);
-    }
-
     return result.raw();
   } else {
     Thread* const thread = Thread::Current();
@@ -1201,11 +1198,12 @@
     ASSERT(thread->IsMutatorThread());
     NoOOBMessageScope no_msg_scope(thread);
     NoReloadScope no_reload_scope(thread->isolate(), thread);
-    // Under lazy compilation initializer has not yet been created, so create
-    // it now, but don't bother remembering it because it won't be used again.
-    ASSERT(!field.HasPrecompiledInitializer());
+    if (field.HasInitializer()) {
+      const Function& initializer = Function::Handle(field.Initializer());
+      return DartEntry::InvokeFunction(initializer, Object::empty_array());
+    }
     {
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
       VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
       TimelineDurationScope tds(thread, Timeline::GetCompilerStream(),
                                 "CompileStaticInitializer");
@@ -1706,9 +1704,8 @@
 }
 
 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
-  ASSERT(field.HasPrecompiledInitializer());
-  const Function& initializer =
-      Function::Handle(field.PrecompiledInitializer());
+  ASSERT(field.HasInitializer());
+  const Function& initializer = Function::Handle(field.Initializer());
   return DartEntry::InvokeFunction(initializer, Object::empty_array());
 }
 
diff --git a/runtime/vm/compiler/jit/jit_call_specializer.cc b/runtime/vm/compiler/jit/jit_call_specializer.cc
index 3b97b71..f073878 100644
--- a/runtime/vm/compiler/jit/jit_call_specializer.cc
+++ b/runtime/vm/compiler/jit/jit_call_specializer.cc
@@ -212,12 +212,10 @@
       if (FLAG_trace_optimization || FLAG_trace_field_guards) {
         THR_Print("Disabling unboxing of %s\n", field.ToCString());
         if (!setter.IsNull()) {
-          OS::PrintErr("  setter usage count: %" Pd "\n",
-                       setter.usage_counter());
+          THR_Print("  setter usage count: %" Pd "\n", setter.usage_counter());
         }
         if (!getter.IsNull()) {
-          OS::PrintErr("  getter usage count: %" Pd "\n",
-                       getter.usage_counter());
+          THR_Print("  getter usage count: %" Pd "\n", getter.usage_counter());
         }
       }
       ASSERT(field.IsOriginal());
@@ -244,7 +242,7 @@
                                             context_variables.length());
   alloc->ReplaceWith(replacement, current_iterator());
 
-  Definition* cursor = replacement;
+  Instruction* cursor = replacement;
 
   Value* initial_value;
   if (context_value != NULL) {
diff --git a/runtime/vm/compiler/method_recognizer.h b/runtime/vm/compiler/method_recognizer.h
index e901118..dbde9de 100644
--- a/runtime/vm/compiler/method_recognizer.h
+++ b/runtime/vm/compiler/method_recognizer.h
@@ -6,501 +6,12 @@
 #define RUNTIME_VM_COMPILER_METHOD_RECOGNIZER_H_
 
 #include "vm/allocation.h"
+#include "vm/compiler/recognized_methods_list.h"
 #include "vm/growable_array.h"
 #include "vm/token.h"
 
 namespace dart {
 
-// clang-format off
-// (class-name, function-name, recognized enum, result type, fingerprint).
-// When adding a new function add a 0 as fingerprint, build and run to get the
-// correct fingerprint from the mismatch error (or use Library::GetFunction()
-// and print func.SourceFingerprint()).
-#define OTHER_RECOGNIZED_LIST(V)                                               \
-  V(::, identical, ObjectIdentical, 0x49c6e96a)                                \
-  V(ClassID, getID, ClassIDgetID, 0x7b18b257)                                  \
-  V(Object, Object., ObjectConstructor, 0x681617fe)                            \
-  V(List, ., ListFactory, 0x629f8324)                                          \
-  V(_List, ., ObjectArrayAllocate, 0x2121902f)                                 \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a)                    \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6)                \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x7db75d78)                  \
-  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x1487cfc6)                \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f)              \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x12bae36a)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 0x15821cc9)                  \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x1f8237fa)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 0x181e5d16)                \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x7ddb9f87)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74094f8d)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x4741396e)                  \
-  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x3b398ae4)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x03db087b)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
-  V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x564b0435)                 \
-  V(_StringBase, _interpolate, StringBaseInterpolate, 0x01ecb15a)              \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 0x05da96ed)             \
-  V(_Double, _add, DoubleAdd, 0x2a38277b)                                      \
-  V(_Double, _sub, DoubleSub, 0x4f466391)                                      \
-  V(_Double, _mul, DoubleMul, 0x175e4f66)                                      \
-  V(_Double, _div, DoubleDiv, 0x0854181b)                                      \
-  V(::, min, MathMin, 0x32ebc57d)                                              \
-  V(::, max, MathMax, 0x377e8889)                                              \
-  V(::, _doublePow, MathDoublePow, 0x5add0ec1)                                 \
-  V(::, _intPow, MathIntPow, 0x11b45569)                                       \
-  V(Float32x4, Float32x4., Float32x4Constructor, 0x26ea459b)                   \
-  V(Float32x4, Float32x4.zero, Float32x4Zero, 0x16eca604)                      \
-  V(Float32x4, Float32x4.splat, Float32x4Splat, 0x694e83e3)                    \
-  V(Float32x4, Float32x4.fromInt32x4Bits, Int32x4ToFloat32x4, 0x2f62ebd3)      \
-  V(Float32x4, Float32x4.fromFloat64x2, Float64x2ToFloat32x4, 0x50ed6910)      \
-  V(_Float32x4, shuffle, Float32x4Shuffle, 0x7829101f)                         \
-  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 0x4182c06b)                   \
-  V(_Float32x4, get:signMask, Float32x4GetSignMask, 0x1d08b351)                \
-  V(_Float32x4, equal, Float32x4Equal, 0x11adb239)                             \
-  V(_Float32x4, greaterThan, Float32x4GreaterThan, 0x48adaf58)                 \
-  V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, 0x32db94ca)   \
-  V(_Float32x4, lessThan, Float32x4LessThan, 0x425b000c)                       \
-  V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, 0x0278c2f8)         \
-  V(_Float32x4, notEqual, Float32x4NotEqual, 0x2987cd26)                       \
-  V(_Float32x4, min, Float32x4Min, 0x5ed74b6f)                                 \
-  V(_Float32x4, max, Float32x4Max, 0x68696442)                                 \
-  V(_Float32x4, scale, Float32x4Scale, 0x704e4122)                             \
-  V(_Float32x4, sqrt, Float32x4Sqrt, 0x2c967a6f)                               \
-  V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, 0x6264bfe8)           \
-  V(_Float32x4, reciprocal, Float32x4Reciprocal, 0x3cd7e819)                   \
-  V(_Float32x4, unary-, Float32x4Negate, 0x37accb52)                           \
-  V(_Float32x4, abs, Float32x4Abs, 0x471cdd87)                                 \
-  V(_Float32x4, clamp, Float32x4Clamp, 0x2cb30492)                             \
-  V(_Float32x4, withX, Float32x4WithX, 0x4e336aff)                             \
-  V(_Float32x4, withY, Float32x4WithY, 0x0a72b910)                             \
-  V(_Float32x4, withZ, Float32x4WithZ, 0x31e93658)                             \
-  V(_Float32x4, withW, Float32x4WithW, 0x60ddc105)                             \
-  V(Float64x2, Float64x2., Float64x2Constructor, 0x43054b9f)                   \
-  V(Float64x2, Float64x2.zero, Float64x2Zero, 0x4af12f9d)                      \
-  V(Float64x2, Float64x2.splat, Float64x2Splat, 0x134edef0)                    \
-  V(Float64x2, Float64x2.fromFloat32x4, Float32x4ToFloat64x2, 0x17d6b5e4)      \
-  V(_Float64x2, get:x, Float64x2GetX, 0x58c09c58)                              \
-  V(_Float64x2, get:y, Float64x2GetY, 0x3cf5e5b8)                              \
-  V(_Float64x2, unary-, Float64x2Negate, 0x415ca009)                           \
-  V(_Float64x2, abs, Float64x2Abs, 0x031f9e47)                                 \
-  V(_Float64x2, sqrt, Float64x2Sqrt, 0x77f711dd)                               \
-  V(_Float64x2, get:signMask, Float64x2GetSignMask, 0x27deda4b)                \
-  V(_Float64x2, scale, Float64x2Scale, 0x26830a61)                             \
-  V(_Float64x2, withX, Float64x2WithX, 0x1d2bcaf5)                             \
-  V(_Float64x2, withY, Float64x2WithY, 0x383ed6ac)                             \
-  V(_Float64x2, min, Float64x2Min,  0x28d7ddf6)                                \
-  V(_Float64x2, max, Float64x2Max,  0x0bd74e5b)                                \
-  V(Int32x4, Int32x4., Int32x4Constructor, 0x480555a9)                         \
-  V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 0x36aa6963)                 \
-  V(Int32x4, Int32x4.fromFloat32x4Bits, Float32x4ToInt32x4, 0x6715388a)        \
-  V(_Int32x4, get:flagX, Int32x4GetFlagX, 0x56396c82)                          \
-  V(_Int32x4, get:flagY, Int32x4GetFlagY, 0x44704738)                          \
-  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 0x20d6ff37)                          \
-  V(_Int32x4, get:flagW, Int32x4GetFlagW, 0x5045616a)                          \
-  V(_Int32x4, get:signMask, Int32x4GetSignMask, 0x2c1fb2a3)                    \
-  V(_Int32x4, shuffle, Int32x4Shuffle, 0x20bc0b16)                             \
-  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 0x5c7056e1)                       \
-  V(_Int32x4, select, Int32x4Select, 0x6b49654f)                               \
-  V(_Int32x4, withFlagX, Int32x4WithFlagX, 0x0ef58fcf)                         \
-  V(_Int32x4, withFlagY, Int32x4WithFlagY, 0x6485a9c4)                         \
-  V(_Int32x4, withFlagZ, Int32x4WithFlagZ, 0x267acdfa)                         \
-  V(_Int32x4, withFlagW, Int32x4WithFlagW, 0x345ac675)                         \
-  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x02477157)               \
-  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4fc8d5e0)               \
-  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x2d7a70ac)                 \
-  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x0ec032e8)                 \
-  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x088599ed)         \
-  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x5f42ca86)         \
-  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x32f3b13b)         \
-  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x7219c45b)         \
-  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x558481c2)   \
-  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x5aa9888d)   \
-  V(::, _classRangeCheck, ClassRangeCheck, 0x2ae76b84)                         \
-  V(::, _classRangeCheckNegative, ClassRangeCheckNegated, 0x5acdfb75)          \
-
-
-// List of intrinsics:
-// (class-name, function-name, intrinsification method, fingerprint).
-#define CORE_LIB_INTRINSIC_LIST(V)                                             \
-  V(_Smi, ~, Smi_bitNegate, 0x67299f4f)                                        \
-  V(_Smi, get:bitLength, Smi_bitLength, 0x25b3cb0a)                            \
-  V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, 0x562d5047)                       \
-  V(_BigIntImpl, _lsh, Bigint_lsh, 0x5b6cfc8b)                                 \
-  V(_BigIntImpl, _rsh, Bigint_rsh, 0x6ff14a49)                                 \
-  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x5bf14238)                           \
-  V(_BigIntImpl, _absSub, Bigint_absSub, 0x1de5bd32)                           \
-  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0x6f277966)                           \
-  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x68e4c8ea)                           \
-  V(_BigIntImpl, _estimateQuotientDigit, Bigint_estimateQuotientDigit,         \
-    0x35456d91)                                                                \
-  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x0f7b0375)        \
-  V(_Double, >, Double_greaterThan, 0x4f1375a3)                                \
-  V(_Double, >=, Double_greaterEqualThan, 0x4260c184)                          \
-  V(_Double, <, Double_lessThan, 0x365d1eba)                                   \
-  V(_Double, <=, Double_lessEqualThan, 0x74b5eb64)                             \
-  V(_Double, ==, Double_equal, 0x613492fc)                                     \
-  V(_Double, +, Double_add, 0x53994370)                                        \
-  V(_Double, -, Double_sub, 0x3b69d466)                                        \
-  V(_Double, *, Double_mul, 0x2bb9bd5d)                                        \
-  V(_Double, /, Double_div, 0x483eee28)                                        \
-  V(_Double, get:hashCode, Double_hashCode, 0x702b77b7)                        \
-  V(_Double, get:_identityHashCode, Double_identityHash, 0x7bda5549)           \
-  V(_Double, get:isNaN, Double_getIsNaN, 0x0af9d4a9)                           \
-  V(_Double, get:isInfinite, Double_getIsInfinite, 0x0f7acb47)                 \
-  V(_Double, get:isNegative, Double_getIsNegative, 0x3a59e7f4)                 \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 0x2017fcf6)               \
-  V(_Double, .fromInteger, DoubleFromInteger, 0x6d234f4b)                      \
-  V(_GrowableList, .withData, GrowableArray_Allocate, 0x28b2138e)              \
-  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0x380184b1)                   \
-  V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0x79b8f955)       \
-  V(Object, ==, ObjectEquals, 0x7b32a55a)                                      \
-  V(Object, get:runtimeType, ObjectRuntimeType, 0x00e8ab29)                    \
-  V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, 0x4dc50799)       \
-  V(_StringBase, get:hashCode, String_getHashCode, 0x78c3d446)                 \
-  V(_StringBase, get:_identityHashCode, String_identityHash, 0x0472b1d8)       \
-  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 0x4a8b29c8)                   \
-  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 0x46de4f10)    \
-  V(_StringBase, [], StringBaseCharAt, 0x7cbb8603)                             \
-  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 0x78c3d446)       \
-  V(_OneByteString, _substringUncheckedNative,                                 \
-    OneByteString_substringUnchecked,  0x3538ad86)                             \
-  V(_OneByteString, _setAt, OneByteStringSetAt, 0x11ffddd1)                    \
-  V(_OneByteString, _allocate, OneByteString_allocate,          0x74933376)    \
-  V(_OneByteString, ==, OneByteString_equality, 0x4eda197e)                    \
-  V(_TwoByteString, ==, TwoByteString_equality, 0x4eda197e)                    \
-  V(_Type, get:hashCode, Type_getHashCode, 0x18d1523f)                         \
-  V(::, _getHash, Object_getHash, 0x2827856d)                                  \
-  V(::, _setHash, Object_setHash, 0x690faebd)                                  \
-
-
-#define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
-  V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
-    0x6a10c54a)                                                                \
-  V(_IntegerImplementation, +, Integer_add, 0x43d53af7)                        \
-  V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
-    0x3fa4b1ed)                                                                \
-  V(_IntegerImplementation, -, Integer_sub, 0x2dc22e03)                        \
-  V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
-    0x3216e299)                                                                \
-  V(_IntegerImplementation, *, Integer_mul, 0x4e7a1c24)                        \
-  V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
-     0x6348b974)                                                               \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 0x4efb2d39)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 0x428bf6fa)                \
-  V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger,     \
-    0x395b1678)                                                                \
-  V(_IntegerImplementation, &, Integer_bitAnd, 0x5ab35f30)                     \
-  V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger,       \
-    0x6a36b395)                                                                \
-  V(_IntegerImplementation, |, Integer_bitOr, 0x267fa107)                      \
-  V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger,     \
-    0x72da93f0)                                                                \
-  V(_IntegerImplementation, ^, Integer_bitXor, 0x0c7b0230)                     \
-  V(_IntegerImplementation, _greaterThanFromInteger,                           \
-    Integer_greaterThanFromInt, 0x4a50ed58)                                    \
-  V(_IntegerImplementation, >, Integer_greaterThan, 0x6599a6e1)                \
-  V(_IntegerImplementation, ==, Integer_equal, 0x58abc487)                     \
-  V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
-    0x063be842)                                                                \
-  V(_IntegerImplementation, <, Integer_lessThan, 0x365d1eba)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x74b5eb64)             \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x4260c184)          \
-  V(_IntegerImplementation, <<, Integer_shl, 0x371c45fa)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 0x2b630578)                       \
-  V(_Double, toInt, DoubleToInteger, 0x26ef344b)                               \
-
-#define MATH_LIB_INTRINSIC_LIST(V)                                             \
-  V(::, sqrt, MathSqrt, 0x70482cf3)                                            \
-  V(_Random, _nextState, Random_nextState, 0x2842c4d5)                         \
-
-#define GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                       \
-  V(::, sin, MathSin, 0x6b7bd98c)                                              \
-  V(::, cos, MathCos, 0x459bf5fe)                                              \
-  V(::, tan, MathTan, 0x3bcd772a)                                              \
-  V(::, asin, MathAsin, 0x2ecc2fcd)                                            \
-  V(::, acos, MathAcos, 0x08cf2212)                                            \
-  V(::, atan, MathAtan, 0x1e2731d5)                                            \
-  V(::, atan2, MathAtan2, 0x39f1fa41)                                          \
-
-#define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
-  V(Int8List, ., TypedData_Int8Array_factory, 0x7e39a3a1)                      \
-  V(Uint8List, ., TypedData_Uint8Array_factory, 0x3a79adf7)                    \
-  V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 0x67f38395)      \
-  V(Int16List, ., TypedData_Int16Array_factory, 0x6477bda8)                    \
-  V(Uint16List, ., TypedData_Uint16Array_factory, 0x5707c5a2)                  \
-  V(Int32List, ., TypedData_Int32Array_factory, 0x2b96ec0e)                    \
-  V(Uint32List, ., TypedData_Uint32Array_factory, 0x0c1c0d62)                  \
-  V(Int64List, ., TypedData_Int64Array_factory, 0x279ab485)                    \
-  V(Uint64List, ., TypedData_Uint64Array_factory, 0x7bcb89c2)                  \
-  V(Float32List, ., TypedData_Float32Array_factory, 0x43506c09)                \
-  V(Float64List, ., TypedData_Float64Array_factory, 0x1fde3eaf)                \
-  V(Float32x4List, ., TypedData_Float32x4Array_factory, 0x4a4030d6)            \
-  V(Int32x4List, ., TypedData_Int32x4Array_factory, 0x6dd02406)                \
-  V(Float64x2List, ., TypedData_Float64x2Array_factory, 0x688e4e97)            \
-
-#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
-  V(_Int8List, [], Int8ArrayGetIndexed, 0x49767a2c)                            \
-  V(_Int8List, []=, Int8ArraySetIndexed, 0x24f42cd0)                           \
-  V(_Uint8List, [], Uint8ArrayGetIndexed, 0x088d86d4)                          \
-  V(_Uint8List, []=, Uint8ArraySetIndexed, 0x12639541)                         \
-  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0x088d86d4)         \
-  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0x12639541)        \
-  V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0x088d86d4)            \
-  V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x6790dba1)           \
-  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
-    0x088d86d4)                                                                \
-  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
-    0x6790dba1)                                                                \
-  V(_Int16List, [], Int16ArrayGetIndexed, 0x5ec64948)                          \
-  V(_Int16List, []=, Int16ArraySetIndexed, 0x0e4e8221)                         \
-  V(_Uint16List, [], Uint16ArrayGetIndexed, 0x5f49d093)                        \
-  V(_Uint16List, []=, Uint16ArraySetIndexed, 0x2efbc90f)                       \
-  V(_Int32List, [], Int32ArrayGetIndexed, 0x4bc0d3dd)                          \
-  V(_Int32List, []=, Int32ArraySetIndexed, 0x1adf9823)                         \
-  V(_Uint32List, [], Uint32ArrayGetIndexed, 0x188658ce)                        \
-  V(_Uint32List, []=, Uint32ArraySetIndexed, 0x01f51a79)                       \
-  V(_Int64List, [], Int64ArrayGetIndexed, 0x51eafb97)                          \
-  V(_Int64List, []=, Int64ArraySetIndexed, 0x376181fb)                         \
-  V(_Uint64List, [], Uint64ArrayGetIndexed, 0x4b2a1ba2)                        \
-  V(_Uint64List, []=, Uint64ArraySetIndexed, 0x5f881bd4)                       \
-  V(_Float64List, [], Float64ArrayGetIndexed, 0x0a714486)                      \
-  V(_Float64List, []=, Float64ArraySetIndexed, 0x04937367)                     \
-  V(_Float32List, [], Float32ArrayGetIndexed, 0x5ade301f)                      \
-  V(_Float32List, []=, Float32ArraySetIndexed, 0x0d5c2e2b)                     \
-  V(_Float32x4List, [], Float32x4ArrayGetIndexed, 0x128cddeb)                  \
-  V(_Float32x4List, []=, Float32x4ArraySetIndexed, 0x7ad55c72)                 \
-  V(_Int32x4List, [], Int32x4ArrayGetIndexed, 0x4b78af9c)                      \
-  V(_Int32x4List, []=, Int32x4ArraySetIndexed, 0x31453dab)                     \
-  V(_Float64x2List, [], Float64x2ArrayGetIndexed, 0x644a0be1)                  \
-  V(_Float64x2List, []=, Float64x2ArraySetIndexed, 0x6b836b0b)                 \
-  V(_TypedList, get:length, TypedDataLength, 0x2091c4d8)                       \
-  V(_Float32x4, get:x, Float32x4ShuffleX, 0x63d1a9fd)                          \
-  V(_Float32x4, get:y, Float32x4ShuffleY, 0x203523d9)                          \
-  V(_Float32x4, get:z, Float32x4ShuffleZ, 0x13190678)                          \
-  V(_Float32x4, get:w, Float32x4ShuffleW, 0x698a38de)                          \
-  V(_Float32x4, *, Float32x4Mul, 0x5dec68b2)                                   \
-  V(_Float32x4, -, Float32x4Sub, 0x3ea14461)                                   \
-  V(_Float32x4, +, Float32x4Add, 0x7ffcf301)                                   \
-
-#define GRAPH_CORE_INTRINSICS_LIST(V)                                          \
-  V(_List, get:length, ObjectArrayLength, 0x25952390)                          \
-  V(_List, [], ObjectArrayGetIndexed, 0x653da02e)                              \
-  V(_List, []=, ObjectArraySetIndexed, 0x16b3d2b0)                             \
-  V(_List, _setIndexed, ObjectArraySetIndexedUnchecked, 0x50d64c75)            \
-  V(_ImmutableList, get:length, ImmutableArrayLength, 0x25952390)              \
-  V(_ImmutableList, [], ImmutableArrayGetIndexed, 0x653da02e)                  \
-  V(_GrowableList, get:length, GrowableArrayLength, 0x18dd86b4)                \
-  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2e04be60)           \
-  V(_GrowableList, _setData, GrowableArraySetData, 0x3dbea348)                 \
-  V(_GrowableList, _setLength, GrowableArraySetLength, 0x753e55da)             \
-  V(_GrowableList, [], GrowableArrayGetIndexed, 0x446fe1f0)                    \
-  V(_GrowableList, []=, GrowableArraySetIndexed, 0x40a462ec)                   \
-  V(_GrowableList, _setIndexed, GrowableArraySetIndexedUnchecked, 0x297083df)  \
-  V(_StringBase, get:length, StringBaseLength, 0x2a2d03d1)                     \
-  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 0x55a0a1f3)           \
-  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 0x55a0a1f3)           \
-  V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt,       \
-    0x55a0a1f3)                                                                \
-  V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt,       \
-    0x55a0a1f3)                                                                \
-  V(_Double, unary-, DoubleFlipSignBit, 0x6db4674f)                            \
-  V(_Double, truncateToDouble, DoubleTruncate, 0x2f27e5d3)                     \
-  V(_Double, roundToDouble, DoubleRound, 0x2f89c512)                           \
-  V(_Double, floorToDouble, DoubleFloor, 0x6aa87a5f)                           \
-  V(_Double, ceilToDouble, DoubleCeil, 0x1b045e9e)                             \
-  V(_Double, _modulo, DoubleMod, 0x5b8ceed7)
-
-
-#define GRAPH_INTRINSICS_LIST(V)                                               \
-  GRAPH_CORE_INTRINSICS_LIST(V)                                                \
-  GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                          \
-  GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                             \
-
-#define DEVELOPER_LIB_INTRINSIC_LIST(V)                                        \
-  V(_UserTag, makeCurrent, UserTag_makeCurrent, 0x0b3066fd)                    \
-  V(::, _getDefaultTag, UserTag_defaultTag, 0x69f3f1ad)                        \
-  V(::, _getCurrentTag, Profiler_getCurrentTag, 0x05fa99d2)                    \
-  V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 0x72f13f7a)        \
-
-#define ASYNC_LIB_INTRINSIC_LIST(V)                                            \
-  V(::, _clearAsyncThreadStackTrace, ClearAsyncThreadStackTrace, 0x2edd4b25)   \
-  V(::, _setAsyncThreadStackTrace, SetAsyncThreadStackTrace, 0x04f429a7)       \
-
-#define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
-  ASYNC_LIB_INTRINSIC_LIST(V)                                                  \
-  CORE_LIB_INTRINSIC_LIST(V)                                                   \
-  DEVELOPER_LIB_INTRINSIC_LIST(V)                                              \
-  MATH_LIB_INTRINSIC_LIST(V)                                                   \
-  TYPED_DATA_LIB_INTRINSIC_LIST(V)                                             \
-
-#define ALL_INTRINSICS_LIST(V)                                                 \
-  ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                        \
-  CORE_INTEGER_LIB_INTRINSIC_LIST(V)
-
-#define RECOGNIZED_LIST(V)                                                     \
-  OTHER_RECOGNIZED_LIST(V)                                                     \
-  ALL_INTRINSICS_LIST(V)                                                       \
-  GRAPH_INTRINSICS_LIST(V)
-
-// A list of core function that should always be inlined.
-#define INLINE_WHITE_LIST(V)                                                   \
-  V(Object, ==, ObjectEquals, 0x7b32a55a)                                      \
-  V(_List, get:length, ObjectArrayLength, 0x25952390)                          \
-  V(_ImmutableList, get:length, ImmutableArrayLength, 0x25952390)              \
-  V(_TypedList, get:length, TypedDataLength, 0x2091c4d8)                       \
-  V(_GrowableList, get:length, GrowableArrayLength, 0x18dd86b4)                \
-  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2e04be60)           \
-  V(_GrowableList, add, GrowableListAdd, 0x40b490b8)                           \
-  V(_GrowableList, removeLast, GrowableListRemoveLast, 0x007855e5)             \
-  V(_StringBase, get:length, StringBaseLength, 0x2a2d03d1)                     \
-  V(ListIterator, moveNext, ListIteratorMoveNext, 0x2dca30ce)                  \
-  V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 0x324eb20b)  \
-  V(_GrowableList, get:iterator, GrowableArrayIterator, 0x5bd2ef37)            \
-  V(_GrowableList, forEach, GrowableArrayForEach, 0x74900bb8)                  \
-  V(_List, ., ObjectArrayAllocate, 0x2121902f)                                 \
-  V(ListMixin, get:isEmpty, ListMixinIsEmpty, 0x7be74d04)                      \
-  V(_List, get:iterator, ObjectArrayIterator, 0x6c851c55)                      \
-  V(_List, forEach, ObjectArrayForEach, 0x11406b13)                            \
-  V(_List, _slice, ObjectArraySlice, 0x4c865d1d)                               \
-  V(_ImmutableList, get:iterator, ImmutableArrayIterator, 0x6c851c55)          \
-  V(_ImmutableList, forEach, ImmutableArrayForEach, 0x11406b13)                \
-  V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 0x7d308247)                 \
-  V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 0x65ba546e)                \
-  V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 0x7e5a8458)                   \
-  V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x62f615e4)                  \
-  V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x6395293e)                   \
-  V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x79979d1f)                 \
-  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x525ec534)                 \
-  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x48eda263)               \
-  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x523666fa)                 \
-  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x5a4683da)               \
-  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x4283a650)                 \
-  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x687a1892)               \
-  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x7d5784fd)             \
-  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x00101e3f)             \
-  V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x68448b4d)                   \
-  V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x5d68cbf2)                 \
-  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x691b5ead)                 \
-  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x78b744d8)               \
-  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x3a0f4efa)                 \
-  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x583261be)               \
-  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x77de471c)                 \
-  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x0ffadc4b)               \
-  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x6a205749)             \
-  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x69f58d27)             \
-  V(::, exp, MathExp, 0x32ab9efa)                                              \
-  V(::, log, MathLog, 0x1ee8f9fc)                                              \
-  V(::, max, MathMax, 0x377e8889)                                              \
-  V(::, min, MathMin, 0x32ebc57d)                                              \
-  V(::, pow, MathPow, 0x79efc5a2)                                              \
-  V(::, _classRangeCheck, ClassRangeCheck, 0x2ae76b84)                         \
-  V(::, _classRangeCheckNegative, ClassRangeCheckNegated, 0x5acdfb75)          \
-  V(::, _toInt, ConvertMaskedInt, 0x713908fd)                                  \
-  V(::, _toInt8, ConvertIntToInt8, 0x7484a780)                                 \
-  V(::, _toUint8, ConvertIntToUint8, 0x0a15b522)                               \
-  V(::, _toInt16, ConvertIntToInt16, 0x0a83fcc6)                               \
-  V(::, _toUint16, ConvertIntToUint16, 0x6087d1af)                             \
-  V(::, _toInt32, ConvertIntToInt32, 0x62b451b9)                               \
-  V(::, _toUint32, ConvertIntToUint32, 0x17a8e085)                             \
-  V(::, _byteSwap16, ByteSwap16, 0x44f173be)                                   \
-  V(::, _byteSwap32, ByteSwap32, 0x6219333b)                                   \
-  V(::, _byteSwap64, ByteSwap64, 0x9abe57e0)                                   \
-  V(Lists, copy, ListsCopy, 0x40e974f6)                                        \
-  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x02477157)               \
-  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4fc8d5e0)               \
-  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x2d7a70ac)                 \
-  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x0ec032e8)                 \
-  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x088599ed)         \
-  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x5f42ca86)         \
-  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x32f3b13b)         \
-  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x7219c45b)         \
-  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x558481c2)   \
-  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x5aa9888d)   \
-
-// A list of core function that should never be inlined.
-#define INLINE_BLACK_LIST(V)                                                   \
-  V(::, asin, MathAsin, 0x2ecc2fcd)                                            \
-  V(::, acos, MathAcos, 0x08cf2212)                                            \
-  V(::, atan, MathAtan, 0x1e2731d5)                                            \
-  V(::, atan2, MathAtan2, 0x39f1fa41)                                          \
-  V(::, cos, MathCos, 0x459bf5fe)                                              \
-  V(::, sin, MathSin, 0x6b7bd98c)                                              \
-  V(::, sqrt, MathSqrt, 0x70482cf3)                                            \
-  V(::, tan, MathTan, 0x3bcd772a)                                              \
-  V(_BigIntImpl, _lsh, Bigint_lsh, 0x5b6cfc8b)                                 \
-  V(_BigIntImpl, _rsh, Bigint_rsh, 0x6ff14a49)                                 \
-  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x5bf14238)                           \
-  V(_BigIntImpl, _absSub, Bigint_absSub, 0x1de5bd32)                           \
-  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0x6f277966)                           \
-  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x68e4c8ea)                           \
-  V(_BigIntImpl, _estimateQuotientDigit, Bigint_estimateQuotientDigit,         \
-    0x35456d91)                                                                \
-  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x0f7b0375)        \
-  V(_Double, >, Double_greaterThan, 0x4f1375a3)                                \
-  V(_Double, >=, Double_greaterEqualThan, 0x4260c184)                          \
-  V(_Double, <, Double_lessThan, 0x365d1eba)                                   \
-  V(_Double, <=, Double_lessEqualThan, 0x74b5eb64)                             \
-  V(_Double, ==, Double_equal, 0x613492fc)                                     \
-  V(_Double, +, Double_add, 0x53994370)                                        \
-  V(_Double, -, Double_sub, 0x3b69d466)                                        \
-  V(_Double, *, Double_mul, 0x2bb9bd5d)                                        \
-  V(_Double, /, Double_div, 0x483eee28)                                        \
-  V(_IntegerImplementation, +, Integer_add, 0x43d53af7)                        \
-  V(_IntegerImplementation, -, Integer_sub, 0x2dc22e03)                        \
-  V(_IntegerImplementation, *, Integer_mul, 0x4e7a1c24)                        \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 0x4efb2d39)               \
-  V(_IntegerImplementation, unary-, Integer_negate, 0x428bf6fa)                \
-  V(_IntegerImplementation, &, Integer_bitAnd, 0x5ab35f30)                     \
-  V(_IntegerImplementation, |, Integer_bitOr, 0x267fa107)                      \
-  V(_IntegerImplementation, ^, Integer_bitXor, 0x0c7b0230)                     \
-  V(_IntegerImplementation, >, Integer_greaterThan, 0x6599a6e1)                \
-  V(_IntegerImplementation, ==, Integer_equal, 0x58abc487)                     \
-  V(_IntegerImplementation, <, Integer_lessThan, 0x365d1eba)                   \
-  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x74b5eb64)             \
-  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x4260c184)          \
-  V(_IntegerImplementation, <<, Integer_shl, 0x371c45fa)                       \
-  V(_IntegerImplementation, >>, Integer_sar, 0x2b630578)                       \
-
-// A list of core functions that internally dispatch based on received id.
-#define POLYMORPHIC_TARGET_LIST(V)                                             \
-  V(_StringBase, [], StringBaseCharAt, 0x7cbb8603)                             \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a)                    \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6)                \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x7db75d78)                  \
-  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x1487cfc6)                \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f)              \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f)              \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x12bae36a)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x15821cc9)                   \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x1f8237fa)                  \
-  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x181e5d16)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x7ddb9f87)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74094f8d)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x4741396e)                  \
-  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x3b398ae4)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x03db087b)              \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
-  V(Object, get:runtimeType, ObjectRuntimeType, 0x00e8ab29)
-
-// clang-format on
-
 // Forward declarations.
 class Function;
 class Library;
@@ -570,35 +81,6 @@
   ASSERT(f.CheckSourceFingerprint(#p0 ", " #p1 ", " #p2, fp))
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-// clang-format off
-// List of recognized list factories:
-// (factory-name-symbol, class-name-string, constructor-name-string,
-//  result-cid, fingerprint).
-#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, _List, ., kArrayCid, 0x2121902f)                             \
-  V(_GrowableListWithData, _GrowableList, .withData, kGrowableObjectArrayCid,  \
-    0x28b2138e)                                                                \
-  V(_GrowableListFactory, _GrowableList, ., kGrowableObjectArrayCid,           \
-    0x3eed680b)                                                                \
-  V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x7e39a3a1)        \
-  V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x3a79adf7)     \
-  V(_Uint8ClampedArrayFactory, Uint8ClampedList, .,                            \
-    kTypedDataUint8ClampedArrayCid, 0x67f38395)                                \
-  V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x6477bda8)     \
-  V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0x5707c5a2)  \
-  V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x2b96ec0e)     \
-  V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0x0c1c0d62)  \
-  V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0x279ab485)     \
-  V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0x7bcb89c2)  \
-  V(_Float64ArrayFactory, Float64List, ., kTypedDataFloat64ArrayCid,           \
-    0x1fde3eaf)                                                                \
-  V(_Float32ArrayFactory, Float32List, ., kTypedDataFloat32ArrayCid,           \
-    0x43506c09)                                                                \
-  V(_Float32x4ArrayFactory, Float32x4List, ., kTypedDataFloat32x4ArrayCid,     \
-    0x4a4030d6)
-
-// clang-format on
-
 // Class that recognizes factories and returns corresponding result cid.
 class FactoryRecognizer : public AllStatic {
  public:
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
new file mode 100644
index 0000000..fa35d7c
--- /dev/null
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -0,0 +1,545 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_RECOGNIZED_METHODS_LIST_H_
+#define RUNTIME_VM_COMPILER_RECOGNIZED_METHODS_LIST_H_
+
+namespace dart {
+
+// clang-format off
+// (class-name, function-name, recognized enum, result type, fingerprint).
+// When adding a new function add a 0 as fingerprint, build and run to get the
+// correct fingerprint from the mismatch error (or use Library::GetFunction()
+// and print func.SourceFingerprint()).
+#define OTHER_RECOGNIZED_LIST(V)                                               \
+  V(::, identical, ObjectIdentical, 0x49c6e96a)                                \
+  V(ClassID, getID, ClassIDgetID, 0x7b18b257)                                  \
+  V(Object, Object., ObjectConstructor, 0x681617fe)                            \
+  V(List, ., ListFactory, 0x629f8324)                                          \
+  V(_List, ., ObjectArrayAllocate, 0x2121902f)                                 \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea)                  \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20)                  \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6)                \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x7db75d78)                  \
+  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x1487cfc6)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x12bae36a)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 0x15821cc9)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x1f8237fa)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 0x181e5d16)                \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x7ddb9f87)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74094f8d)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x4741396e)                  \
+  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x3b398ae4)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x03db087b)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
+  V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x564b0435)                 \
+  V(_StringBase, _interpolate, StringBaseInterpolate, 0x01ecb15a)              \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 0x05da96ed)             \
+  V(_Double, _add, DoubleAdd, 0x2a38277b)                                      \
+  V(_Double, _sub, DoubleSub, 0x4f466391)                                      \
+  V(_Double, _mul, DoubleMul, 0x175e4f66)                                      \
+  V(_Double, _div, DoubleDiv, 0x0854181b)                                      \
+  V(::, min, MathMin, 0x32ebc57d)                                              \
+  V(::, max, MathMax, 0x377e8889)                                              \
+  V(::, _doublePow, MathDoublePow, 0x5add0ec1)                                 \
+  V(::, _intPow, MathIntPow, 0x11b45569)                                       \
+  V(Float32x4, Float32x4., Float32x4Constructor, 0x26ea459b)                   \
+  V(Float32x4, Float32x4.zero, Float32x4Zero, 0x16eca604)                      \
+  V(Float32x4, Float32x4.splat, Float32x4Splat, 0x694e83e3)                    \
+  V(Float32x4, Float32x4.fromInt32x4Bits, Int32x4ToFloat32x4, 0x2f62ebd3)      \
+  V(Float32x4, Float32x4.fromFloat64x2, Float64x2ToFloat32x4, 0x50ed6910)      \
+  V(_Float32x4, shuffle, Float32x4Shuffle, 0x7829101f)                         \
+  V(_Float32x4, shuffleMix, Float32x4ShuffleMix, 0x4182c06b)                   \
+  V(_Float32x4, get:signMask, Float32x4GetSignMask, 0x1d08b351)                \
+  V(_Float32x4, equal, Float32x4Equal, 0x11adb239)                             \
+  V(_Float32x4, greaterThan, Float32x4GreaterThan, 0x48adaf58)                 \
+  V(_Float32x4, greaterThanOrEqual, Float32x4GreaterThanOrEqual, 0x32db94ca)   \
+  V(_Float32x4, lessThan, Float32x4LessThan, 0x425b000c)                       \
+  V(_Float32x4, lessThanOrEqual, Float32x4LessThanOrEqual, 0x0278c2f8)         \
+  V(_Float32x4, notEqual, Float32x4NotEqual, 0x2987cd26)                       \
+  V(_Float32x4, min, Float32x4Min, 0x5ed74b6f)                                 \
+  V(_Float32x4, max, Float32x4Max, 0x68696442)                                 \
+  V(_Float32x4, scale, Float32x4Scale, 0x704e4122)                             \
+  V(_Float32x4, sqrt, Float32x4Sqrt, 0x2c967a6f)                               \
+  V(_Float32x4, reciprocalSqrt, Float32x4ReciprocalSqrt, 0x6264bfe8)           \
+  V(_Float32x4, reciprocal, Float32x4Reciprocal, 0x3cd7e819)                   \
+  V(_Float32x4, unary-, Float32x4Negate, 0x37accb52)                           \
+  V(_Float32x4, abs, Float32x4Abs, 0x471cdd87)                                 \
+  V(_Float32x4, clamp, Float32x4Clamp, 0x2cb30492)                             \
+  V(_Float32x4, withX, Float32x4WithX, 0x4e336aff)                             \
+  V(_Float32x4, withY, Float32x4WithY, 0x0a72b910)                             \
+  V(_Float32x4, withZ, Float32x4WithZ, 0x31e93658)                             \
+  V(_Float32x4, withW, Float32x4WithW, 0x60ddc105)                             \
+  V(Float64x2, Float64x2., Float64x2Constructor, 0x43054b9f)                   \
+  V(Float64x2, Float64x2.zero, Float64x2Zero, 0x4af12f9d)                      \
+  V(Float64x2, Float64x2.splat, Float64x2Splat, 0x134edef0)                    \
+  V(Float64x2, Float64x2.fromFloat32x4, Float32x4ToFloat64x2, 0x17d6b5e4)      \
+  V(_Float64x2, get:x, Float64x2GetX, 0x58c09c58)                              \
+  V(_Float64x2, get:y, Float64x2GetY, 0x3cf5e5b8)                              \
+  V(_Float64x2, unary-, Float64x2Negate, 0x415ca009)                           \
+  V(_Float64x2, abs, Float64x2Abs, 0x031f9e47)                                 \
+  V(_Float64x2, sqrt, Float64x2Sqrt, 0x77f711dd)                               \
+  V(_Float64x2, get:signMask, Float64x2GetSignMask, 0x27deda4b)                \
+  V(_Float64x2, scale, Float64x2Scale, 0x26830a61)                             \
+  V(_Float64x2, withX, Float64x2WithX, 0x1d2bcaf5)                             \
+  V(_Float64x2, withY, Float64x2WithY, 0x383ed6ac)                             \
+  V(_Float64x2, min, Float64x2Min,  0x28d7ddf6)                                \
+  V(_Float64x2, max, Float64x2Max,  0x0bd74e5b)                                \
+  V(Int32x4, Int32x4., Int32x4Constructor, 0x480555a9)                         \
+  V(Int32x4, Int32x4.bool, Int32x4BoolConstructor, 0x36aa6963)                 \
+  V(Int32x4, Int32x4.fromFloat32x4Bits, Float32x4ToInt32x4, 0x6715388a)        \
+  V(_Int32x4, get:flagX, Int32x4GetFlagX, 0x56396c82)                          \
+  V(_Int32x4, get:flagY, Int32x4GetFlagY, 0x44704738)                          \
+  V(_Int32x4, get:flagZ, Int32x4GetFlagZ, 0x20d6ff37)                          \
+  V(_Int32x4, get:flagW, Int32x4GetFlagW, 0x5045616a)                          \
+  V(_Int32x4, get:signMask, Int32x4GetSignMask, 0x2c1fb2a3)                    \
+  V(_Int32x4, shuffle, Int32x4Shuffle, 0x20bc0b16)                             \
+  V(_Int32x4, shuffleMix, Int32x4ShuffleMix, 0x5c7056e1)                       \
+  V(_Int32x4, select, Int32x4Select, 0x6b49654f)                               \
+  V(_Int32x4, withFlagX, Int32x4WithFlagX, 0x0ef58fcf)                         \
+  V(_Int32x4, withFlagY, Int32x4WithFlagY, 0x6485a9c4)                         \
+  V(_Int32x4, withFlagZ, Int32x4WithFlagZ, 0x267acdfa)                         \
+  V(_Int32x4, withFlagW, Int32x4WithFlagW, 0x345ac675)                         \
+  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x02477157)               \
+  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4fc8d5e0)               \
+  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x2d7a70ac)                 \
+  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x0ec032e8)                 \
+  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x088599ed)         \
+  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x5f42ca86)         \
+  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x32f3b13b)         \
+  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x7219c45b)         \
+  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x558481c2)   \
+  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x5aa9888d)   \
+  V(::, _classRangeCheck, ClassRangeCheck, 0x2ae76b84)                         \
+  V(::, _classRangeCheckNegative, ClassRangeCheckNegated, 0x5acdfb75)          \
+
+// List of intrinsics:
+// (class-name, function-name, intrinsification method, fingerprint).
+#define CORE_LIB_INTRINSIC_LIST(V)                                             \
+  V(_Smi, ~, Smi_bitNegate, 0x67299f4f)                                        \
+  V(_Smi, get:bitLength, Smi_bitLength, 0x25b3cb0a)                            \
+  V(_Smi, _bitAndFromSmi, Smi_bitAndFromSmi, 0x562d5047)                       \
+  V(_BigIntImpl, _lsh, Bigint_lsh, 0x5b6cfc8b)                                 \
+  V(_BigIntImpl, _rsh, Bigint_rsh, 0x6ff14a49)                                 \
+  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x5bf14238)                           \
+  V(_BigIntImpl, _absSub, Bigint_absSub, 0x1de5bd32)                           \
+  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0x6f277966)                           \
+  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x68e4c8ea)                           \
+  V(_BigIntImpl, _estimateQuotientDigit, Bigint_estimateQuotientDigit,         \
+    0x35456d91)                                                                \
+  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x0f7b0375)        \
+  V(_Double, >, Double_greaterThan, 0x4f1375a3)                                \
+  V(_Double, >=, Double_greaterEqualThan, 0x4260c184)                          \
+  V(_Double, <, Double_lessThan, 0x365d1eba)                                   \
+  V(_Double, <=, Double_lessEqualThan, 0x74b5eb64)                             \
+  V(_Double, ==, Double_equal, 0x613492fc)                                     \
+  V(_Double, +, Double_add, 0x53994370)                                        \
+  V(_Double, -, Double_sub, 0x3b69d466)                                        \
+  V(_Double, *, Double_mul, 0x2bb9bd5d)                                        \
+  V(_Double, /, Double_div, 0x483eee28)                                        \
+  V(_Double, get:hashCode, Double_hashCode, 0x702b77b7)                        \
+  V(_Double, get:_identityHashCode, Double_identityHash, 0x7bda5549)           \
+  V(_Double, get:isNaN, Double_getIsNaN, 0x0af9d4a9)                           \
+  V(_Double, get:isInfinite, Double_getIsInfinite, 0x0f7acb47)                 \
+  V(_Double, get:isNegative, Double_getIsNegative, 0x3a59e7f4)                 \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 0x2017fcf6)               \
+  V(_Double, .fromInteger, DoubleFromInteger, 0x6d234f4b)                      \
+  V(_GrowableList, .withData, GrowableArray_Allocate, 0x28b2138e)              \
+  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 0x380184b1)                   \
+  V(_RegExp, _ExecuteMatchSticky, RegExp_ExecuteMatchSticky, 0x79b8f955)       \
+  V(Object, ==, ObjectEquals, 0x7b32a55a)                                      \
+  V(Object, get:runtimeType, ObjectRuntimeType, 0x00e8ab29)                    \
+  V(Object, _haveSameRuntimeType, ObjectHaveSameRuntimeType, 0x4dc50799)       \
+  V(_StringBase, get:hashCode, String_getHashCode, 0x78c3d446)                 \
+  V(_StringBase, get:_identityHashCode, String_identityHash, 0x0472b1d8)       \
+  V(_StringBase, get:isEmpty, StringBaseIsEmpty, 0x4a8b29c8)                   \
+  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 0x46de4f10)    \
+  V(_StringBase, [], StringBaseCharAt, 0x7cbb8603)                             \
+  V(_OneByteString, get:hashCode, OneByteString_getHashCode, 0x78c3d446)       \
+  V(_OneByteString, _substringUncheckedNative,                                 \
+    OneByteString_substringUnchecked,  0x3538ad86)                             \
+  V(_OneByteString, _setAt, OneByteStringSetAt, 0x11ffddd1)                    \
+  V(_OneByteString, _allocate, OneByteString_allocate,          0x74933376)    \
+  V(_OneByteString, ==, OneByteString_equality, 0x4eda197e)                    \
+  V(_TwoByteString, ==, TwoByteString_equality, 0x4eda197e)                    \
+  V(_Type, get:hashCode, Type_getHashCode, 0x18d1523f)                         \
+  V(::, _getHash, Object_getHash, 0x2827856d)                                  \
+  V(::, _setHash, Object_setHash, 0x690faebd)                                  \
+
+
+#define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
+  V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
+    0x6a10c54a)                                                                \
+  V(_IntegerImplementation, +, Integer_add, 0x43d53af7)                        \
+  V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger,           \
+    0x3fa4b1ed)                                                                \
+  V(_IntegerImplementation, -, Integer_sub, 0x2dc22e03)                        \
+  V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
+    0x3216e299)                                                                \
+  V(_IntegerImplementation, *, Integer_mul, 0x4e7a1c24)                        \
+  V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
+     0x6348b974)                                                               \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 0x4efb2d39)               \
+  V(_IntegerImplementation, unary-, Integer_negate, 0x428bf6fa)                \
+  V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger,     \
+    0x395b1678)                                                                \
+  V(_IntegerImplementation, &, Integer_bitAnd, 0x5ab35f30)                     \
+  V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger,       \
+    0x6a36b395)                                                                \
+  V(_IntegerImplementation, |, Integer_bitOr, 0x267fa107)                      \
+  V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger,     \
+    0x72da93f0)                                                                \
+  V(_IntegerImplementation, ^, Integer_bitXor, 0x0c7b0230)                     \
+  V(_IntegerImplementation, _greaterThanFromInteger,                           \
+    Integer_greaterThanFromInt, 0x4a50ed58)                                    \
+  V(_IntegerImplementation, >, Integer_greaterThan, 0x6599a6e1)                \
+  V(_IntegerImplementation, ==, Integer_equal, 0x58abc487)                     \
+  V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
+    0x063be842)                                                                \
+  V(_IntegerImplementation, <, Integer_lessThan, 0x365d1eba)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x74b5eb64)             \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x4260c184)          \
+  V(_IntegerImplementation, <<, Integer_shl, 0x371c45fa)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 0x2b630578)                       \
+  V(_Double, toInt, DoubleToInteger, 0x26ef344b)                               \
+
+#define MATH_LIB_INTRINSIC_LIST(V)                                             \
+  V(::, sqrt, MathSqrt, 0x70482cf3)                                            \
+  V(_Random, _nextState, Random_nextState, 0x2842c4d5)                         \
+
+#define GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                       \
+  V(::, sin, MathSin, 0x6b7bd98c)                                              \
+  V(::, cos, MathCos, 0x459bf5fe)                                              \
+  V(::, tan, MathTan, 0x3bcd772a)                                              \
+  V(::, asin, MathAsin, 0x2ecc2fcd)                                            \
+  V(::, acos, MathAcos, 0x08cf2212)                                            \
+  V(::, atan, MathAtan, 0x1e2731d5)                                            \
+  V(::, atan2, MathAtan2, 0x39f1fa41)                                          \
+
+#define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
+  V(Int8List, ., TypedData_Int8Array_factory, 0x7e39a3a1)                      \
+  V(Uint8List, ., TypedData_Uint8Array_factory, 0x3a79adf7)                    \
+  V(Uint8ClampedList, ., TypedData_Uint8ClampedArray_factory, 0x67f38395)      \
+  V(Int16List, ., TypedData_Int16Array_factory, 0x6477bda8)                    \
+  V(Uint16List, ., TypedData_Uint16Array_factory, 0x5707c5a2)                  \
+  V(Int32List, ., TypedData_Int32Array_factory, 0x2b96ec0e)                    \
+  V(Uint32List, ., TypedData_Uint32Array_factory, 0x0c1c0d62)                  \
+  V(Int64List, ., TypedData_Int64Array_factory, 0x279ab485)                    \
+  V(Uint64List, ., TypedData_Uint64Array_factory, 0x7bcb89c2)                  \
+  V(Float32List, ., TypedData_Float32Array_factory, 0x43506c09)                \
+  V(Float64List, ., TypedData_Float64Array_factory, 0x1fde3eaf)                \
+  V(Float32x4List, ., TypedData_Float32x4Array_factory, 0x4a4030d6)            \
+  V(Int32x4List, ., TypedData_Int32x4Array_factory, 0x6dd02406)                \
+  V(Float64x2List, ., TypedData_Float64x2Array_factory, 0x688e4e97)            \
+
+#define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
+  V(_Int8List, [], Int8ArrayGetIndexed, 0x49767a2c)                            \
+  V(_Int8List, []=, Int8ArraySetIndexed, 0x24f42cd0)                           \
+  V(_Uint8List, [], Uint8ArrayGetIndexed, 0x088d86d4)                          \
+  V(_Uint8List, []=, Uint8ArraySetIndexed, 0x12639541)                         \
+  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 0x088d86d4)         \
+  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 0x12639541)        \
+  V(_Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 0x088d86d4)            \
+  V(_Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 0x6790dba1)           \
+  V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
+    0x088d86d4)                                                                \
+  V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
+    0x6790dba1)                                                                \
+  V(_Int16List, [], Int16ArrayGetIndexed, 0x5ec64948)                          \
+  V(_Int16List, []=, Int16ArraySetIndexed, 0x0e4e8221)                         \
+  V(_Uint16List, [], Uint16ArrayGetIndexed, 0x5f49d093)                        \
+  V(_Uint16List, []=, Uint16ArraySetIndexed, 0x2efbc90f)                       \
+  V(_Int32List, [], Int32ArrayGetIndexed, 0x4bc0d3dd)                          \
+  V(_Int32List, []=, Int32ArraySetIndexed, 0x1adf9823)                         \
+  V(_Uint32List, [], Uint32ArrayGetIndexed, 0x188658ce)                        \
+  V(_Uint32List, []=, Uint32ArraySetIndexed, 0x01f51a79)                       \
+  V(_Int64List, [], Int64ArrayGetIndexed, 0x51eafb97)                          \
+  V(_Int64List, []=, Int64ArraySetIndexed, 0x376181fb)                         \
+  V(_Uint64List, [], Uint64ArrayGetIndexed, 0x4b2a1ba2)                        \
+  V(_Uint64List, []=, Uint64ArraySetIndexed, 0x5f881bd4)                       \
+  V(_Float64List, [], Float64ArrayGetIndexed, 0x0a714486)                      \
+  V(_Float64List, []=, Float64ArraySetIndexed, 0x04937367)                     \
+  V(_Float32List, [], Float32ArrayGetIndexed, 0x5ade301f)                      \
+  V(_Float32List, []=, Float32ArraySetIndexed, 0x0d5c2e2b)                     \
+  V(_Float32x4List, [], Float32x4ArrayGetIndexed, 0x128cddeb)                  \
+  V(_Float32x4List, []=, Float32x4ArraySetIndexed, 0x7ad55c72)                 \
+  V(_Int32x4List, [], Int32x4ArrayGetIndexed, 0x4b78af9c)                      \
+  V(_Int32x4List, []=, Int32x4ArraySetIndexed, 0x31453dab)                     \
+  V(_Float64x2List, [], Float64x2ArrayGetIndexed, 0x644a0be1)                  \
+  V(_Float64x2List, []=, Float64x2ArraySetIndexed, 0x6b836b0b)                 \
+  V(_TypedList, get:length, TypedDataLength, 0x2091c4d8)                       \
+  V(_Float32x4, get:x, Float32x4ShuffleX, 0x63d1a9fd)                          \
+  V(_Float32x4, get:y, Float32x4ShuffleY, 0x203523d9)                          \
+  V(_Float32x4, get:z, Float32x4ShuffleZ, 0x13190678)                          \
+  V(_Float32x4, get:w, Float32x4ShuffleW, 0x698a38de)                          \
+  V(_Float32x4, *, Float32x4Mul, 0x5dec68b2)                                   \
+  V(_Float32x4, -, Float32x4Sub, 0x3ea14461)                                   \
+  V(_Float32x4, +, Float32x4Add, 0x7ffcf301)                                   \
+
+#define GRAPH_CORE_INTRINSICS_LIST(V)                                          \
+  V(_List, get:length, ObjectArrayLength, 0x25952390)                          \
+  V(_List, [], ObjectArrayGetIndexed, 0x653da02e)                              \
+  V(_List, []=, ObjectArraySetIndexed, 0x16b3d2b0)                             \
+  V(_List, _setIndexed, ObjectArraySetIndexedUnchecked, 0x50d64c75)            \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 0x25952390)              \
+  V(_ImmutableList, [], ImmutableArrayGetIndexed, 0x653da02e)                  \
+  V(_GrowableList, get:length, GrowableArrayLength, 0x18dd86b4)                \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2e04be60)           \
+  V(_GrowableList, _setData, GrowableArraySetData, 0x3dbea348)                 \
+  V(_GrowableList, _setLength, GrowableArraySetLength, 0x753e55da)             \
+  V(_GrowableList, [], GrowableArrayGetIndexed, 0x446fe1f0)                    \
+  V(_GrowableList, []=, GrowableArraySetIndexed, 0x40a462ec)                   \
+  V(_GrowableList, _setIndexed, GrowableArraySetIndexedUnchecked, 0x297083df)  \
+  V(_StringBase, get:length, StringBaseLength, 0x2a2d03d1)                     \
+  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 0x55a0a1f3)           \
+  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 0x55a0a1f3)           \
+  V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt,       \
+    0x55a0a1f3)                                                                \
+  V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt,       \
+    0x55a0a1f3)                                                                \
+  V(_Double, unary-, DoubleFlipSignBit, 0x6db4674f)                            \
+  V(_Double, truncateToDouble, DoubleTruncate, 0x2f27e5d3)                     \
+  V(_Double, roundToDouble, DoubleRound, 0x2f89c512)                           \
+  V(_Double, floorToDouble, DoubleFloor, 0x6aa87a5f)                           \
+  V(_Double, ceilToDouble, DoubleCeil, 0x1b045e9e)                             \
+  V(_Double, _modulo, DoubleMod, 0x5b8ceed7)
+
+
+#define GRAPH_INTRINSICS_LIST(V)                                               \
+  GRAPH_CORE_INTRINSICS_LIST(V)                                                \
+  GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                          \
+  GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                             \
+
+#define DEVELOPER_LIB_INTRINSIC_LIST(V)                                        \
+  V(_UserTag, makeCurrent, UserTag_makeCurrent, 0x0b3066fd)                    \
+  V(::, _getDefaultTag, UserTag_defaultTag, 0x69f3f1ad)                        \
+  V(::, _getCurrentTag, Profiler_getCurrentTag, 0x05fa99d2)                    \
+  V(::, _isDartStreamEnabled, Timeline_isDartStreamEnabled, 0x72f13f7a)        \
+
+#define ASYNC_LIB_INTRINSIC_LIST(V)                                            \
+  V(::, _clearAsyncThreadStackTrace, ClearAsyncThreadStackTrace, 0x2edd4b25)   \
+  V(::, _setAsyncThreadStackTrace, SetAsyncThreadStackTrace, 0x04f429a7)       \
+
+#define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
+  ASYNC_LIB_INTRINSIC_LIST(V)                                                  \
+  CORE_LIB_INTRINSIC_LIST(V)                                                   \
+  DEVELOPER_LIB_INTRINSIC_LIST(V)                                              \
+  MATH_LIB_INTRINSIC_LIST(V)                                                   \
+  TYPED_DATA_LIB_INTRINSIC_LIST(V)                                             \
+
+#define ALL_INTRINSICS_LIST(V)                                                 \
+  ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                        \
+  CORE_INTEGER_LIB_INTRINSIC_LIST(V)
+
+#define RECOGNIZED_LIST(V)                                                     \
+  OTHER_RECOGNIZED_LIST(V)                                                     \
+  ALL_INTRINSICS_LIST(V)                                                       \
+  GRAPH_INTRINSICS_LIST(V)
+
+// A list of core function that should always be inlined.
+#define INLINE_WHITE_LIST(V)                                                   \
+  V(Object, ==, ObjectEquals, 0x7b32a55a)                                      \
+  V(_List, get:length, ObjectArrayLength, 0x25952390)                          \
+  V(_ImmutableList, get:length, ImmutableArrayLength, 0x25952390)              \
+  V(_TypedList, get:length, TypedDataLength, 0x2091c4d8)                       \
+  V(_GrowableList, get:length, GrowableArrayLength, 0x18dd86b4)                \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 0x2e04be60)           \
+  V(_GrowableList, add, GrowableListAdd, 0x40b490b8)                           \
+  V(_GrowableList, removeLast, GrowableListRemoveLast, 0x007855e5)             \
+  V(_StringBase, get:length, StringBaseLength, 0x2a2d03d1)                     \
+  V(ListIterator, moveNext, ListIteratorMoveNext, 0x2dca30ce)                  \
+  V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 0x324eb20b)  \
+  V(_GrowableList, get:iterator, GrowableArrayIterator, 0x5bd2ef37)            \
+  V(_GrowableList, forEach, GrowableArrayForEach, 0x74900bb8)                  \
+  V(_List, ., ObjectArrayAllocate, 0x2121902f)                                 \
+  V(ListMixin, get:isEmpty, ListMixinIsEmpty, 0x7be74d04)                      \
+  V(_List, get:iterator, ObjectArrayIterator, 0x6c851c55)                      \
+  V(_List, forEach, ObjectArrayForEach, 0x11406b13)                            \
+  V(_List, _slice, ObjectArraySlice, 0x4c865d1d)                               \
+  V(_ImmutableList, get:iterator, ImmutableArrayIterator, 0x6c851c55)          \
+  V(_ImmutableList, forEach, ImmutableArrayForEach, 0x11406b13)                \
+  V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 0x7e5a8458)                   \
+  V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 0x62f615e4)                  \
+  V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 0x7d308247)                 \
+  V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 0x65ba546e)                \
+  V(_Uint8ClampedArrayView, [], Uint8ClampedArrayViewGetIndexed, 0x7d308247)   \
+  V(_Uint8ClampedArrayView, []=, Uint8ClampedArrayViewSetIndexed, 0x65ba546e)  \
+  V(_Uint16ArrayView, [], Uint16ArrayViewGetIndexed, 0xe96836dd)               \
+  V(_Uint16ArrayView, []=, Uint16ArrayViewSetIndexed, 0x15b02947)              \
+  V(_Int16ArrayView, [], Int16ArrayViewGetIndexed, 0x1b24a48b)                 \
+  V(_Int16ArrayView, []=, Int16ArrayViewSetIndexed, 0xb91ec2e6)                \
+  V(_Uint32ArrayView, [], Uint32ArrayViewGetIndexed, 0x8a4f93b3)               \
+  V(_Uint32ArrayView, []=, Uint32ArrayViewSetIndexed, 0xf54918b5)              \
+  V(_Int32ArrayView, [], Int32ArrayViewGetIndexed, 0x85040819)                 \
+  V(_Int32ArrayView, []=, Int32ArrayViewSetIndexed, 0xaec8c6f5)                \
+  V(_Uint64ArrayView, [], Uint64ArrayViewGetIndexed, 0xd0c44fe7)               \
+  V(_Uint64ArrayView, []=, Uint64ArrayViewSetIndexed, 0x402712b7)              \
+  V(_Int64ArrayView, [], Int64ArrayViewGetIndexed, 0xf3090b95)                 \
+  V(_Int64ArrayView, []=, Int64ArrayViewSetIndexed, 0xca07e497)                \
+  V(_Float32ArrayView, [], Float32ArrayViewGetIndexed, 0xef967533)             \
+  V(_Float32ArrayView, []=, Float32ArrayViewSetIndexed, 0xc9b691bd)            \
+  V(_Float64ArrayView, [], Float64ArrayViewGetIndexed, 0x9d83f585)             \
+  V(_Float64ArrayView, []=, Float64ArrayViewSetIndexed, 0x3c1adabd)            \
+  V(_ByteDataView, setInt8, ByteDataViewSetInt8, 0x6395293e)                   \
+  V(_ByteDataView, setUint8, ByteDataViewSetUint8, 0x79979d1f)                 \
+  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 0x525ec534)                 \
+  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 0x48eda263)               \
+  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 0x523666fa)                 \
+  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 0x5a4683da)               \
+  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 0x4283a650)                 \
+  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 0x687a1892)               \
+  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 0x7d5784fd)             \
+  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 0x00101e3f)             \
+  V(_ByteDataView, getInt8, ByteDataViewGetInt8, 0x68448b4d)                   \
+  V(_ByteDataView, getUint8, ByteDataViewGetUint8, 0x5d68cbf2)                 \
+  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 0x691b5ead)                 \
+  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 0x78b744d8)               \
+  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 0x3a0f4efa)                 \
+  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 0x583261be)               \
+  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 0x77de471c)                 \
+  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 0x0ffadc4b)               \
+  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 0x6a205749)             \
+  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 0x69f58d27)             \
+  V(::, exp, MathExp, 0x32ab9efa)                                              \
+  V(::, log, MathLog, 0x1ee8f9fc)                                              \
+  V(::, max, MathMax, 0x377e8889)                                              \
+  V(::, min, MathMin, 0x32ebc57d)                                              \
+  V(::, pow, MathPow, 0x79efc5a2)                                              \
+  V(::, _classRangeCheck, ClassRangeCheck, 0x2ae76b84)                         \
+  V(::, _classRangeCheckNegative, ClassRangeCheckNegated, 0x5acdfb75)          \
+  V(::, _toInt, ConvertMaskedInt, 0x713908fd)                                  \
+  V(::, _toInt8, ConvertIntToInt8, 0x7484a780)                                 \
+  V(::, _toUint8, ConvertIntToUint8, 0x0a15b522)                               \
+  V(::, _toInt16, ConvertIntToInt16, 0x0a83fcc6)                               \
+  V(::, _toUint16, ConvertIntToUint16, 0x6087d1af)                             \
+  V(::, _toInt32, ConvertIntToInt32, 0x62b451b9)                               \
+  V(::, _toUint32, ConvertIntToUint32, 0x17a8e085)                             \
+  V(::, _byteSwap16, ByteSwap16, 0x44f173be)                                   \
+  V(::, _byteSwap32, ByteSwap32, 0x6219333b)                                   \
+  V(::, _byteSwap64, ByteSwap64, 0x9abe57e0)                                   \
+  V(Lists, copy, ListsCopy, 0x40e974f6)                                        \
+  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 0x02477157)               \
+  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 0x4fc8d5e0)               \
+  V(_HashVMBase, get:_data, LinkedHashMap_getData, 0x2d7a70ac)                 \
+  V(_HashVMBase, set:_data, LinkedHashMap_setData, 0x0ec032e8)                 \
+  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 0x088599ed)         \
+  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 0x5f42ca86)         \
+  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 0x32f3b13b)         \
+  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 0x7219c45b)         \
+  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 0x558481c2)   \
+  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 0x5aa9888d)   \
+
+// A list of core function that should never be inlined.
+#define INLINE_BLACK_LIST(V)                                                   \
+  V(::, asin, MathAsin, 0x2ecc2fcd)                                            \
+  V(::, acos, MathAcos, 0x08cf2212)                                            \
+  V(::, atan, MathAtan, 0x1e2731d5)                                            \
+  V(::, atan2, MathAtan2, 0x39f1fa41)                                          \
+  V(::, cos, MathCos, 0x459bf5fe)                                              \
+  V(::, sin, MathSin, 0x6b7bd98c)                                              \
+  V(::, sqrt, MathSqrt, 0x70482cf3)                                            \
+  V(::, tan, MathTan, 0x3bcd772a)                                              \
+  V(_BigIntImpl, _lsh, Bigint_lsh, 0x5b6cfc8b)                                 \
+  V(_BigIntImpl, _rsh, Bigint_rsh, 0x6ff14a49)                                 \
+  V(_BigIntImpl, _absAdd, Bigint_absAdd, 0x5bf14238)                           \
+  V(_BigIntImpl, _absSub, Bigint_absSub, 0x1de5bd32)                           \
+  V(_BigIntImpl, _mulAdd, Bigint_mulAdd, 0x6f277966)                           \
+  V(_BigIntImpl, _sqrAdd, Bigint_sqrAdd, 0x68e4c8ea)                           \
+  V(_BigIntImpl, _estimateQuotientDigit, Bigint_estimateQuotientDigit,         \
+    0x35456d91)                                                                \
+  V(_BigIntMontgomeryReduction, _mulMod, Montgomery_mulMod, 0x0f7b0375)        \
+  V(_Double, >, Double_greaterThan, 0x4f1375a3)                                \
+  V(_Double, >=, Double_greaterEqualThan, 0x4260c184)                          \
+  V(_Double, <, Double_lessThan, 0x365d1eba)                                   \
+  V(_Double, <=, Double_lessEqualThan, 0x74b5eb64)                             \
+  V(_Double, ==, Double_equal, 0x613492fc)                                     \
+  V(_Double, +, Double_add, 0x53994370)                                        \
+  V(_Double, -, Double_sub, 0x3b69d466)                                        \
+  V(_Double, *, Double_mul, 0x2bb9bd5d)                                        \
+  V(_Double, /, Double_div, 0x483eee28)                                        \
+  V(_IntegerImplementation, +, Integer_add, 0x43d53af7)                        \
+  V(_IntegerImplementation, -, Integer_sub, 0x2dc22e03)                        \
+  V(_IntegerImplementation, *, Integer_mul, 0x4e7a1c24)                        \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 0x4efb2d39)               \
+  V(_IntegerImplementation, unary-, Integer_negate, 0x428bf6fa)                \
+  V(_IntegerImplementation, &, Integer_bitAnd, 0x5ab35f30)                     \
+  V(_IntegerImplementation, |, Integer_bitOr, 0x267fa107)                      \
+  V(_IntegerImplementation, ^, Integer_bitXor, 0x0c7b0230)                     \
+  V(_IntegerImplementation, >, Integer_greaterThan, 0x6599a6e1)                \
+  V(_IntegerImplementation, ==, Integer_equal, 0x58abc487)                     \
+  V(_IntegerImplementation, <, Integer_lessThan, 0x365d1eba)                   \
+  V(_IntegerImplementation, <=, Integer_lessEqualThan, 0x74b5eb64)             \
+  V(_IntegerImplementation, >=, Integer_greaterEqualThan, 0x4260c184)          \
+  V(_IntegerImplementation, <<, Integer_shl, 0x371c45fa)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 0x2b630578)                       \
+
+// A list of core functions that internally dispatch based on received id.
+#define POLYMORPHIC_TARGET_LIST(V)                                             \
+  V(_StringBase, [], StringBaseCharAt, 0x7cbb8603)                             \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 0x7041895a)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 0x336fa3ea)                  \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 0x231bbe2e)                  \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 0x0371785f)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 0x65ab3a20)                  \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 0x0cb0fcf6)                \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 0x7db75d78)                  \
+  V(_TypedList, _getUint64, ByteArrayBaseGetUint64, 0x1487cfc6)                \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 0x6674ea6f)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 0x236c6e7a)              \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 0x5c367ffb)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 0x772d1c0f)              \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 0x12bae36a)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 0x15821cc9)                   \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 0x1f8237fa)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 0x181e5d16)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 0x7ddb9f87)                  \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 0x74094f8d)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 0x4741396e)                  \
+  V(_TypedList, _setUint64, ByteArrayBaseSetUint64, 0x3b398ae4)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 0x03db087b)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 0x38a80b0d)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 0x40052c4e)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 0x07b89f54)              \
+  V(Object, get:runtimeType, ObjectRuntimeType, 0x00e8ab29)
+
+// List of recognized list factories:
+// (factory-name-symbol, class-name-string, constructor-name-string,
+//  result-cid, fingerprint).
+#define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
+  V(_ListFactory, _List, ., kArrayCid, 0x2121902f)                             \
+  V(_GrowableListWithData, _GrowableList, .withData, kGrowableObjectArrayCid,  \
+    0x28b2138e)                                                                \
+  V(_GrowableListFactory, _GrowableList, ., kGrowableObjectArrayCid,           \
+    0x3eed680b)                                                                \
+  V(_Int8ArrayFactory, Int8List, ., kTypedDataInt8ArrayCid, 0x7e39a3a1)        \
+  V(_Uint8ArrayFactory, Uint8List, ., kTypedDataUint8ArrayCid, 0x3a79adf7)     \
+  V(_Uint8ClampedArrayFactory, Uint8ClampedList, .,                            \
+    kTypedDataUint8ClampedArrayCid, 0x67f38395)                                \
+  V(_Int16ArrayFactory, Int16List, ., kTypedDataInt16ArrayCid, 0x6477bda8)     \
+  V(_Uint16ArrayFactory, Uint16List, ., kTypedDataUint16ArrayCid, 0x5707c5a2)  \
+  V(_Int32ArrayFactory, Int32List, ., kTypedDataInt32ArrayCid, 0x2b96ec0e)     \
+  V(_Uint32ArrayFactory, Uint32List, ., kTypedDataUint32ArrayCid, 0x0c1c0d62)  \
+  V(_Int64ArrayFactory, Int64List, ., kTypedDataInt64ArrayCid, 0x279ab485)     \
+  V(_Uint64ArrayFactory, Uint64List, ., kTypedDataUint64ArrayCid, 0x7bcb89c2)  \
+  V(_Float64ArrayFactory, Float64List, ., kTypedDataFloat64ArrayCid,           \
+    0x1fde3eaf)                                                                \
+  V(_Float32ArrayFactory, Float32List, ., kTypedDataFloat32ArrayCid,           \
+    0x43506c09)                                                                \
+  V(_Float32x4ArrayFactory, Float32x4List, ., kTypedDataFloat32x4ArrayCid,     \
+    0x4a4030d6)
+
+// clang-format on
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_RECOGNIZED_METHODS_LIST_H_
diff --git a/runtime/vm/compiler/relocation.cc b/runtime/vm/compiler/relocation.cc
index fc568c3..467aa78 100644
--- a/runtime/vm/compiler/relocation.cc
+++ b/runtime/vm/compiler/relocation.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -14,151 +14,83 @@
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
     !defined(TARGET_ARCH_IA32)
 
-class InstructionsMapTraits {
- public:
-  struct Pair {
-    RawInstructions* instructions;
-    intptr_t inst_nr;
+// Only for testing.
+DEFINE_FLAG(bool,
+            always_generate_trampolines_for_testing,
+            false,
+            "Generate always trampolines (for testing purposes).");
 
-    Pair() : instructions(nullptr), inst_nr(-1) {}
-    Pair(RawInstructions* i, intptr_t nr) : instructions(i), inst_nr(nr) {}
-  };
+// The trampolines will have a 1-word object header in front of them.
+const intptr_t kOffsetInTrampoline = kWordSize;
+const intptr_t kTrampolineSize = OS::kMaxPreferredCodeAlignment;
 
-  typedef const RawInstructions* Key;
-  typedef const intptr_t Value;
-
-  static Key KeyOf(Pair kv) { return kv.instructions; }
-  static Value ValueOf(Pair kv) { return kv.inst_nr; }
-  static inline intptr_t Hashcode(Key key) {
-    return reinterpret_cast<intptr_t>(key);
-  }
-  static inline bool IsKeyEqual(Pair pair, Key key) {
-    return pair.instructions == key;
-  }
-};
-
-typedef DirectChainedHashMap<InstructionsMapTraits> InstructionsMap;
+CodeRelocator::CodeRelocator(Thread* thread,
+                             GrowableArray<RawCode*>* code_objects,
+                             GrowableArray<ImageWriterCommand>* commands)
+    : StackResource(thread),
+      code_objects_(code_objects),
+      commands_(commands),
+      kind_type_and_offset_(Smi::Handle(thread->zone())),
+      target_(Object::Handle(thread->zone())),
+      destination_(Code::Handle(thread->zone())) {}
 
 void CodeRelocator::Relocate(bool is_vm_isolate) {
-  auto zone = Thread::Current()->zone();
-  intptr_t next_text_offsets = 0;
+  Zone* zone = Thread::Current()->zone();
+  auto& current_caller = Code::Handle(zone);
+  auto& call_targets = Array::Handle(zone);
 
-  // Keeps track of mapping from Code to the index in [commands_] at which the
-  // code object's instructions are located. This allows us to calculate the
-  // distance to the destination using commands_[index].expected_offset.
-  InstructionsMap instructions_map;
+  // Do one linear pass over all code objects and determine:
+  //
+  //    * the maximum instruction size
+  //    * the maximum number of calls
+  //    * the maximum offset into a target instruction
+  //
+  FindInstructionAndCallLimits();
 
-  // The callers which has an unresolved call.
-  GrowableArray<RawCode*> callers;
-  // The offset from the instruction at which the call happens.
-  GrowableArray<intptr_t> call_offsets;
-  // Type entry-point type we call in the destination.
-  GrowableArray<Code::CallEntryPoint> call_entry_points;
-  // The offset in the .text segment where the call happens.
-  GrowableArray<intptr_t> text_offsets;
-  // The target of the forward call.
-  GrowableArray<RawCode*> callees;
-
-  auto& targets = Array::Handle(zone);
-  auto& kind_type_and_offset = Smi::Handle(zone);
-  auto& target = Object::Handle(zone);
-  auto& destination = Code::Handle(zone);
-  auto& instructions = Instructions::Handle(zone);
-  auto& caller = Code::Handle(zone);
+  // Emit all instructions and do relocations on the way.
   for (intptr_t i = 0; i < code_objects_->length(); ++i) {
-    caller = (*code_objects_)[i];
-    instructions = caller.instructions();
+    current_caller = (*code_objects_)[i];
 
-    // If two [Code] objects point to the same [Instructions] object, we'll just
-    // use the first one (they are equivalent for all practical purposes).
-    if (instructions_map.HasKey(instructions.raw())) {
+    const intptr_t code_text_offset = next_text_offset_;
+    if (!AddInstructionsToText(current_caller.raw())) {
       continue;
     }
-    instructions_map.Insert({instructions.raw(), commands_->length()});
 
-    // First we'll add the instructions of [caller] itself.
-    const intptr_t active_code_text_offsets = next_text_offsets;
-    commands_->Add(ImageWriterCommand(
-        next_text_offsets, ImageWriterCommand::InsertInstructionOfCode,
-        caller.raw()));
+    call_targets = current_caller.static_calls_target_table();
+    ScanCallTargets(current_caller, call_targets, code_text_offset);
 
-    next_text_offsets += instructions.raw()->Size();
+    // Any unresolved calls to this instruction can be fixed now.
+    ResolveUnresolvedCallsTargeting(current_caller.instructions());
 
-    targets = caller.static_calls_target_table();
-    if (!targets.IsNull()) {
-      StaticCallsTable calls(targets);
-      for (auto call : calls) {
-        kind_type_and_offset = call.Get<Code::kSCallTableKindAndOffset>();
-        auto kind = Code::KindField::decode(kind_type_and_offset.Value());
-        auto offset = Code::OffsetField::decode(kind_type_and_offset.Value());
-        auto entry_point =
-            Code::EntryPointField::decode(kind_type_and_offset.Value());
-
-        if (kind == Code::kCallViaCode) {
-          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();
-        }
-
-        const intptr_t start_of_call =
-            active_code_text_offsets + instructions.HeaderSize() + offset;
-
-        callers.Add(caller.raw());
-        callees.Add(destination.raw());
-        text_offsets.Add(start_of_call);
-        call_offsets.Add(offset);
-        call_entry_points.Add(entry_point);
-      }
-    }
+    // If we have forward/backwards calls which are almost out-of-range, we'll
+    // create trampolines now.
+    BuildTrampolinesForAlmostOutOfRangeCalls();
   }
 
-  auto& callee = Code::Handle(zone);
-  auto& caller_instruction = Instructions::Handle(zone);
-  auto& destination_instruction = Instructions::Handle(zone);
-  for (intptr_t i = 0; i < callees.length(); ++i) {
-    caller = callers[i];
-    callee = callees[i];
-    const intptr_t text_offset = text_offsets[i];
-    const intptr_t call_offset = call_offsets[i];
-    const bool use_unchecked_entry =
-        call_entry_points[i] == Code::kUncheckedEntry;
-    caller_instruction = caller.instructions();
-    destination_instruction = callee.instructions();
+  // We're guaranteed to have all calls resolved, since
+  //   * backwards calls are resolved eagerly
+  //   * forward calls are resolved once the target is written
+  ASSERT(all_unresolved_calls_.IsEmpty());
+  ASSERT(unresolved_calls_by_destination_.IsEmpty());
 
-    const uword entry_point = use_unchecked_entry ? callee.UncheckedEntryPoint()
-                                                  : callee.EntryPoint();
-    const intptr_t unchecked_offset =
-        destination_instruction.HeaderSize() +
-        (entry_point - destination_instruction.PayloadStart());
+  // Any trampolines we created must be patched with the right offsets.
+  auto it = trampolines_by_destination_.GetIterator();
+  while (true) {
+    auto entry = it.Next();
+    if (entry == nullptr) break;
 
-    auto map_entry = instructions_map.Lookup(destination_instruction.raw());
-    auto& dst = (*commands_)[map_entry->inst_nr];
-    ASSERT(dst.op == ImageWriterCommand::InsertInstructionOfCode);
-
-    const int32_t distance =
-        (dst.expected_offset + unchecked_offset) - text_offset;
-    {
-      NoSafepointScope no_safepoint_scope;
-
-      PcRelativeCallPattern call(caller_instruction.PayloadStart() +
-                                 call_offset);
-      ASSERT(call.IsValid());
-      call.set_distance(static_cast<int32_t>(distance));
-      ASSERT(call.distance() == distance);
+    UnresolvedTrampolineList* trampoline_list = entry->value;
+    while (!trampoline_list->IsEmpty()) {
+      auto unresolved_trampoline = trampoline_list->RemoveFirst();
+      ResolveTrampoline(unresolved_trampoline);
+      delete unresolved_trampoline;
     }
+    delete trampoline_list;
   }
+  trampolines_by_destination_.Clear();
 
   // We're done now, so we clear out the targets tables.
+  auto& caller = Code::Handle(zone);
   if (!is_vm_isolate) {
     for (intptr_t i = 0; i < code_objects_->length(); ++i) {
       caller = (*code_objects_)[i];
@@ -167,6 +99,407 @@
   }
 }
 
+void CodeRelocator::FindInstructionAndCallLimits() {
+  Zone* zone = Thread::Current()->zone();
+  auto& current_caller = Code::Handle(zone);
+  auto& call_targets = Array::Handle(zone);
+
+  for (intptr_t i = 0; i < code_objects_->length(); ++i) {
+    current_caller = (*code_objects_)[i];
+    const intptr_t size = current_caller.instructions()->HeapSize();
+    if (size > max_instructions_size_) {
+      max_instructions_size_ = size;
+    }
+
+    call_targets = current_caller.static_calls_target_table();
+    if (!call_targets.IsNull()) {
+      intptr_t num_calls = 0;
+      StaticCallsTable calls(call_targets);
+      for (auto call : calls) {
+        kind_type_and_offset_ = call.Get<Code::kSCallTableKindAndOffset>();
+        auto kind = Code::KindField::decode(kind_type_and_offset_.Value());
+        auto offset = Code::OffsetField::decode(kind_type_and_offset_.Value());
+        auto call_entry_point =
+            Code::EntryPointField::decode(kind_type_and_offset_.Value());
+
+        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();
+        }
+
+        // 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;
+        {
+          PcRelativeCallPattern call(
+              Instructions::PayloadStart(current_caller.instructions()) +
+              offset);
+          ASSERT(call.IsValid());
+          offset_into_target = call.distance();
+        }
+
+        const uword destination_payload =
+            Instructions::PayloadStart(destination_.instructions());
+        const uword entry_point =
+            call_entry_point == Code::kUncheckedEntry
+                ? Instructions::UncheckedEntryPoint(destination_.instructions())
+                : Instructions::EntryPoint(destination_.instructions());
+
+        offset_into_target += (entry_point - destination_payload);
+
+        if (offset_into_target > max_offset_into_target_) {
+          max_offset_into_target_ = offset_into_target;
+        }
+      }
+
+      if (num_calls > max_calls_) {
+        max_calls_ = num_calls;
+      }
+    }
+  }
+}
+
+bool CodeRelocator::AddInstructionsToText(RawCode* code) {
+  RawInstructions* 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).
+  if (text_offsets_.HasKey(instructions)) {
+    return false;
+  }
+  text_offsets_.Insert({instructions, next_text_offset_});
+  commands_->Add(ImageWriterCommand(next_text_offset_, code));
+  next_text_offset_ += instructions->HeapSize();
+
+  return true;
+}
+
+UnresolvedTrampoline* CodeRelocator::FindTrampolineFor(
+    UnresolvedCall* unresolved_call) {
+  auto destination = Code::InstructionsOf(unresolved_call->callee);
+  auto entry = trampolines_by_destination_.Lookup(destination);
+  if (entry != nullptr) {
+    UnresolvedTrampolineList* trampolines = entry->value;
+    ASSERT(!trampolines->IsEmpty());
+
+    // For the destination of [unresolved_call] we might have multiple
+    // trampolines.  The trampolines are sorted according to insertion order,
+    // which guarantees increasing text_offset's.  So we go from the back of the
+    // list as long as we have trampolines that are in-range and then check
+    // whether the target offset matches.
+    auto it = trampolines->End();
+    --it;
+    do {
+      UnresolvedTrampoline* trampoline = *it;
+      if (!IsTargetInRangeFor(unresolved_call, trampoline->text_offset)) {
+        break;
+      }
+      if (trampoline->offset_into_target ==
+          unresolved_call->offset_into_target) {
+        return trampoline;
+      }
+      --it;
+    } while (it != trampolines->Begin());
+  }
+  return nullptr;
+}
+
+void CodeRelocator::AddTrampolineToText(RawInstructions* destination,
+                                        uint8_t* trampoline_bytes,
+                                        intptr_t trampoline_length) {
+  commands_->Add(ImageWriterCommand(next_text_offset_, trampoline_bytes,
+                                    trampoline_length));
+  next_text_offset_ += trampoline_length;
+}
+
+void CodeRelocator::ScanCallTargets(const Code& code,
+                                    const Array& call_targets,
+                                    intptr_t code_text_offset) {
+  if (call_targets.IsNull()) {
+    return;
+  }
+  StaticCallsTable calls(call_targets);
+  for (auto call : calls) {
+    kind_type_and_offset_ = call.Get<Code::kSCallTableKindAndOffset>();
+    auto kind = Code::KindField::decode(kind_type_and_offset_.Value());
+    auto offset = Code::OffsetField::decode(kind_type_and_offset_.Value());
+    auto call_entry_point =
+        Code::EntryPointField::decode(kind_type_and_offset_.Value());
+
+    if (kind == Code::kCallViaCode) {
+      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();
+    }
+
+    // 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;
+    {
+      PcRelativeCallPattern call(
+          Instructions::PayloadStart(code.instructions()) + offset);
+      ASSERT(call.IsValid());
+      offset_into_target = call.distance();
+    }
+
+    const uword destination_payload =
+        Instructions::PayloadStart(destination_.instructions());
+    const uword entry_point =
+        call_entry_point == Code::kUncheckedEntry
+            ? Instructions::UncheckedEntryPoint(destination_.instructions())
+            : Instructions::EntryPoint(destination_.instructions());
+
+    offset_into_target += (entry_point - destination_payload);
+
+    const intptr_t text_offset =
+        code_text_offset + Instructions::HeaderSize() + offset;
+    UnresolvedCall unresolved_call(code.raw(), offset, text_offset,
+                                   destination_.raw(), offset_into_target);
+    if (!TryResolveBackwardsCall(&unresolved_call)) {
+      EnqueueUnresolvedCall(new UnresolvedCall(unresolved_call));
+    }
+  }
+}
+
+void CodeRelocator::EnqueueUnresolvedCall(UnresolvedCall* unresolved_call) {
+  // Add it to the min-heap by .text offset.
+  all_unresolved_calls_.Append(unresolved_call);
+
+  // Add it to callers of destination.
+  RawInstructions* destination = Code::InstructionsOf(unresolved_call->callee);
+  if (!unresolved_calls_by_destination_.HasKey(destination)) {
+    unresolved_calls_by_destination_.Insert(
+        {destination, new SameDestinationUnresolvedCallsList()});
+  }
+  unresolved_calls_by_destination_.LookupValue(destination)
+      ->Append(unresolved_call);
+}
+
+void CodeRelocator::EnqueueUnresolvedTrampoline(
+    UnresolvedTrampoline* unresolved_trampoline) {
+  auto destination = Code::InstructionsOf(unresolved_trampoline->callee);
+  auto entry = trampolines_by_destination_.Lookup(destination);
+
+  UnresolvedTrampolineList* trampolines = nullptr;
+  if (entry == nullptr) {
+    trampolines = new UnresolvedTrampolineList();
+    trampolines_by_destination_.Insert({destination, trampolines});
+  } else {
+    trampolines = entry->value;
+  }
+  trampolines->Append(unresolved_trampoline);
+}
+
+bool CodeRelocator::TryResolveBackwardsCall(UnresolvedCall* unresolved_call) {
+  auto callee = Code::InstructionsOf(unresolved_call->callee);
+  auto map_entry = text_offsets_.Lookup(callee);
+  if (map_entry == nullptr) return false;
+
+  ResolveCall(unresolved_call);
+  return true;
+}
+
+void CodeRelocator::ResolveUnresolvedCallsTargeting(
+    const RawInstructions* instructions) {
+  if (unresolved_calls_by_destination_.HasKey(instructions)) {
+    SameDestinationUnresolvedCallsList* calls =
+        unresolved_calls_by_destination_.LookupValue(instructions);
+    auto it = calls->Begin();
+    while (it != calls->End()) {
+      UnresolvedCall* unresolved_call = *it;
+      ++it;
+      ASSERT(Code::InstructionsOf(unresolved_call->callee) == instructions);
+      ResolveCall(unresolved_call);
+
+      // Remove the call from both lists.
+      calls->Remove(unresolved_call);
+      all_unresolved_calls_.Remove(unresolved_call);
+
+      delete unresolved_call;
+    }
+    ASSERT(calls->IsEmpty());
+    delete calls;
+    bool ok = unresolved_calls_by_destination_.Remove(instructions);
+    ASSERT(ok);
+  }
+}
+
+void CodeRelocator::ResolveCall(UnresolvedCall* unresolved_call) {
+  const intptr_t destination_text =
+      FindDestinationInText(Code::InstructionsOf(unresolved_call->callee),
+                            unresolved_call->offset_into_target);
+
+  ResolveCallToDestination(unresolved_call, destination_text);
+}
+
+void CodeRelocator::ResolveCallToDestination(UnresolvedCall* unresolved_call,
+                                             intptr_t destination_text) {
+  const intptr_t call_text_offset = unresolved_call->text_offset;
+  const intptr_t call_offset = unresolved_call->call_offset;
+
+  auto caller = Code::InstructionsOf(unresolved_call->caller);
+  const int32_t distance = destination_text - call_text_offset;
+  {
+    PcRelativeCallPattern call(Instructions::PayloadStart(caller) +
+                               call_offset);
+    ASSERT(call.IsValid());
+    call.set_distance(static_cast<int32_t>(distance));
+    ASSERT(call.distance() == distance);
+  }
+
+  unresolved_call->caller = nullptr;
+  unresolved_call->callee = nullptr;
+}
+
+void CodeRelocator::ResolveTrampoline(
+    UnresolvedTrampoline* unresolved_trampoline) {
+  const intptr_t trampoline_text_offset = unresolved_trampoline->text_offset;
+  const uword trampoline_start =
+      reinterpret_cast<uword>(unresolved_trampoline->trampoline_bytes);
+
+  auto callee = Code::InstructionsOf(unresolved_trampoline->callee);
+  auto destination_text =
+      FindDestinationInText(callee, unresolved_trampoline->offset_into_target);
+  const int32_t distance = destination_text - trampoline_text_offset;
+
+  PcRelativeTrampolineJumpPattern pattern(trampoline_start +
+                                          kOffsetInTrampoline);
+  pattern.Initialize();
+  pattern.set_distance(distance);
+  ASSERT(pattern.distance() == distance);
+}
+
+bool CodeRelocator::IsTargetInRangeFor(UnresolvedCall* unresolved_call,
+                                       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;
+}
+
+static void MarkAsFreeListElement(uint8_t* trampoline_bytes,
+                                  intptr_t trampoline_length) {
+  uint32_t tags = 0;
+  tags = RawObject::SizeTag::update(trampoline_length, tags);
+  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);
+
+  auto header_word = reinterpret_cast<uintptr_t*>(trampoline_bytes);
+  *header_word = tags;
+}
+
+void CodeRelocator::BuildTrampolinesForAlmostOutOfRangeCalls() {
+  while (!all_unresolved_calls_.IsEmpty()) {
+    UnresolvedCall* unresolved_call = all_unresolved_calls_.First();
+
+    // If we can emit another instructions object without causing the unresolved
+    // forward calls to become out-of-range, we'll not resolve it yet (maybe the
+    // target function will come very soon and we don't need a trampoline at
+    // all).
+    const intptr_t future_boundary =
+        next_text_offset_ + max_instructions_size_ +
+        kTrampolineSize *
+            (unresolved_calls_by_destination_.Length() + max_calls_) +
+        kOffsetInTrampoline;
+    if (IsTargetInRangeFor(unresolved_call, future_boundary) &&
+        !FLAG_always_generate_trampolines_for_testing) {
+      break;
+    }
+
+    // We have a "critical" [unresolved_call] we have to resolve.  If an
+    // existing trampoline is in range, we use that otherwise we create a new
+    // trampoline.
+
+    // In the worst case we'll make a new trampoline here, in which case the
+    // current text offset must be in range for the "critical"
+    // [unresolved_call].
+    ASSERT(IsTargetInRangeFor(unresolved_call, next_text_offset_));
+
+    // See if there is already a trampoline we could use.
+    intptr_t trampoline_text_offset = -1;
+    auto callee = Code::InstructionsOf(unresolved_call->callee);
+
+    if (!FLAG_always_generate_trampolines_for_testing) {
+      auto old_trampoline_entry = FindTrampolineFor(unresolved_call);
+      if (old_trampoline_entry != nullptr) {
+        trampoline_text_offset = old_trampoline_entry->text_offset;
+      }
+    }
+
+    // If there is no trampoline yet, we'll create a new one.
+    if (trampoline_text_offset == -1) {
+      // The ownership of the trampoline bytes will be transferred to the
+      // [ImageWriter], which will eventually write out the bytes and delete the
+      // buffer.
+      auto trampoline_bytes = new uint8_t[kTrampolineSize];
+      memset(trampoline_bytes, 0x00, kTrampolineSize);
+      ASSERT((kOffsetInTrampoline +
+              PcRelativeTrampolineJumpPattern::kLengthInBytes) <
+             kTrampolineSize);
+      auto unresolved_trampoline = new UnresolvedTrampoline{
+          unresolved_call->callee,
+          unresolved_call->offset_into_target,
+          trampoline_bytes,
+          next_text_offset_ + kOffsetInTrampoline,
+      };
+      MarkAsFreeListElement(trampoline_bytes, kTrampolineSize);
+      AddTrampolineToText(callee, trampoline_bytes, kTrampolineSize);
+      EnqueueUnresolvedTrampoline(unresolved_trampoline);
+      trampoline_text_offset = unresolved_trampoline->text_offset;
+    }
+
+    // Let the unresolved call to [destination] jump to the trampoline
+    // instead.
+    auto destination = Code::InstructionsOf(unresolved_call->callee);
+    ResolveCallToDestination(unresolved_call, trampoline_text_offset);
+
+    // Remove this unresolved call from the global list and the per-destination
+    // list.
+    auto calls = unresolved_calls_by_destination_.LookupValue(destination);
+    calls->Remove(unresolved_call);
+    all_unresolved_calls_.Remove(unresolved_call);
+    delete unresolved_call;
+
+    // If this destination has no longer any unresolved calls, remove it.
+    if (calls->IsEmpty()) {
+      unresolved_calls_by_destination_.Remove(destination);
+      delete calls;
+    }
+  }
+}
+
+intptr_t CodeRelocator::FindDestinationInText(
+    const RawInstructions* destination,
+    intptr_t offset_into_target) {
+  auto destination_offset = text_offsets_.LookupValue(destination);
+  return destination_offset + Instructions::HeaderSize() + offset_into_target;
+}
+
 #endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
         // !defined(TARGET_ARCH_IA32)
 
diff --git a/runtime/vm/compiler/relocation.h b/runtime/vm/compiler/relocation.h
index 4c2714f..80ca95a 100644
--- a/runtime/vm/compiler/relocation.h
+++ b/runtime/vm/compiler/relocation.h
@@ -7,6 +7,7 @@
 
 #include "vm/allocation.h"
 #include "vm/image_snapshot.h"
+#include "vm/intrusive_dlist.h"
 #include "vm/object.h"
 #include "vm/type_testing_stubs.h"
 #include "vm/visitor.h"
@@ -16,6 +17,112 @@
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
     !defined(TARGET_ARCH_IA32)
 
+// Represents a pc-relative call which has not been patched up with the final
+// destination.
+class UnresolvedCall : public IntrusiveDListEntry<UnresolvedCall>,
+                       public IntrusiveDListEntry<UnresolvedCall, 2> {
+ public:
+  UnresolvedCall(RawCode* caller,
+                 intptr_t call_offset,
+                 intptr_t text_offset,
+                 RawCode* callee,
+                 intptr_t offset_into_target)
+      : caller(caller),
+        call_offset(call_offset),
+        text_offset(text_offset),
+        callee(callee),
+        offset_into_target(offset_into_target) {}
+
+  UnresolvedCall(const UnresolvedCall& other)
+      : caller(other.caller),
+        call_offset(other.call_offset),
+        text_offset(other.text_offset),
+        callee(other.callee),
+        offset_into_target(other.offset_into_target) {}
+
+  // The caller which has an unresolved call.
+  RawCode* caller;
+  // The offset from the payload of the calling code which performs the call.
+  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;
+  // The extra offset into the target.
+  intptr_t offset_into_target;
+};
+
+// A list of all unresolved calls.
+using AllUnresolvedCallsList = IntrusiveDList<UnresolvedCall>;
+
+// A list of all unresolved calls which call the same destination.
+using SameDestinationUnresolvedCallsList = IntrusiveDList<UnresolvedCall, 2>;
+
+// Represents a trampoline which has not been patched up with the final
+// destination.
+//
+// The [CodeRelocator] will insert trampolines into the ".text" segment which
+// increase the range of PC-relative calls.  If a pc-relative call in normal
+// code is too far away from it's destination, it will call a trampoline
+// instead (which will tail-call the destination).
+class UnresolvedTrampoline : public IntrusiveDListEntry<UnresolvedTrampoline> {
+ public:
+  UnresolvedTrampoline(RawCode* callee,
+                       intptr_t offset_into_target,
+                       uint8_t* trampoline_bytes,
+                       intptr_t text_offset)
+      : callee(callee),
+        offset_into_target(offset_into_target),
+        trampoline_bytes(trampoline_bytes),
+        text_offset(text_offset) {}
+
+  // The target of the forward call.
+  RawCode* callee;
+  // The extra offset into the target.
+  intptr_t offset_into_target;
+
+  // The trampoline buffer.
+  uint8_t* trampoline_bytes;
+  // The offset in the .text segment where the trampoline starts.
+  intptr_t text_offset;
+};
+
+using UnresolvedTrampolineList = IntrusiveDList<UnresolvedTrampoline>;
+
+template <typename ValueType, ValueType kNoValue>
+class InstructionsMapTraits {
+ public:
+  struct Pair {
+    RawInstructions* instructions;
+    ValueType value;
+
+    Pair() : instructions(nullptr), value(kNoValue) {}
+    Pair(RawInstructions* i, const ValueType& value)
+        : instructions(i), value(value) {}
+  };
+
+  typedef const RawInstructions* 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);
+  }
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair.instructions == key;
+  }
+};
+
+using InstructionsPosition =
+    DirectChainedHashMap<InstructionsMapTraits<intptr_t, -1>>;
+
+using TrampolinesMap = DirectChainedHashMap<
+    InstructionsMapTraits<UnresolvedTrampolineList*, nullptr>>;
+
+using InstructionsUnresolvedCalls = DirectChainedHashMap<
+    InstructionsMapTraits<SameDestinationUnresolvedCallsList*, nullptr>>;
+
 // Relocates the given code objects by patching the instructions with the
 // correct pc offsets.
 //
@@ -39,15 +146,64 @@
  private:
   CodeRelocator(Thread* thread,
                 GrowableArray<RawCode*>* code_objects,
-                GrowableArray<ImageWriterCommand>* commands)
-      : StackResource(thread),
-        code_objects_(code_objects),
-        commands_(commands) {}
+                GrowableArray<ImageWriterCommand>* commands);
 
   void Relocate(bool is_vm_isolate);
 
-  GrowableArray<RawCode*>* code_objects_;
+  void FindInstructionAndCallLimits();
+
+  bool AddInstructionsToText(RawCode* code);
+  void ScanCallTargets(const Code& code,
+                       const Array& call_targets,
+                       intptr_t code_text_offset);
+
+  UnresolvedTrampoline* FindTrampolineFor(UnresolvedCall* unresolved_call);
+  void AddTrampolineToText(RawInstructions* destination,
+                           uint8_t* trampoline_bytes,
+                           intptr_t trampoline_length);
+
+  void EnqueueUnresolvedCall(UnresolvedCall* unresolved_call);
+  void EnqueueUnresolvedTrampoline(UnresolvedTrampoline* unresolved_trampoline);
+
+  bool TryResolveBackwardsCall(UnresolvedCall* unresolved_call);
+  void ResolveUnresolvedCallsTargeting(const RawInstructions* instructions);
+  void ResolveCall(UnresolvedCall* unresolved_call);
+  void ResolveCallToDestination(UnresolvedCall* unresolved_call,
+                                intptr_t destination_text);
+  void ResolveTrampoline(UnresolvedTrampoline* unresolved_trampoline);
+
+  void BuildTrampolinesForAlmostOutOfRangeCalls();
+
+  intptr_t FindDestinationInText(const RawInstructions* destination,
+                                 intptr_t offset_into_target);
+
+  bool IsTargetInRangeFor(UnresolvedCall* unresolved_call,
+                          intptr_t target_text_offset);
+
+  // The code relocation happens during AOT snapshot writing and operates on raw
+  // objects. No allocations can be done.
+  NoSafepointScope no_savepoint_scope_;
+
+  const GrowableArray<RawCode*>* code_objects_;
   GrowableArray<ImageWriterCommand>* commands_;
+
+  // The size of largest instructions object in bytes.
+  intptr_t max_instructions_size_ = 0;
+  // The maximum number of pc-relative calls in an instructions object.
+  intptr_t max_calls_ = 0;
+  intptr_t max_offset_into_target_ = 0;
+
+  // Data structures used for relocation.
+  intptr_t next_text_offset_ = 0;
+  InstructionsPosition text_offsets_;
+  TrampolinesMap trampolines_by_destination_;
+  InstructionsUnresolvedCalls unresolved_calls_by_destination_;
+  AllUnresolvedCallsList all_unresolved_calls_;
+
+  // Reusable handles for [ScanCallTargets].
+  Smi& kind_type_and_offset_;
+  Object& target_;
+  Code& destination_;
 };
 
 #endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
new file mode 100644
index 0000000..aca31eb
--- /dev/null
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -0,0 +1,787 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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/runtime_api.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#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 {
+
+bool IsSameObject(const Object& a, const Object& b) {
+  return a.raw() == b.raw();
+}
+
+bool IsNotTemporaryScopedHandle(const Object& obj) {
+  return obj.IsNotTemporaryScopedHandle();
+}
+
+#define DO(clazz)                                                              \
+  bool Is##clazz##Handle(const Object& obj) { return obj.Is##clazz(); }
+CLASS_LIST_FOR_HANDLES(DO)
+#undef DO
+
+bool IsInOldSpace(const Object& obj) {
+  return obj.IsOld();
+}
+
+intptr_t ObjectHash(const Object& obj) {
+  if (obj.IsNull()) {
+    return 2011;
+  }
+  if (obj.IsString() || obj.IsNumber()) {
+    return Instance::Cast(obj).CanonicalizeHash();
+  }
+  if (obj.IsCode()) {
+    // Instructions don't move during compaction.
+    return Code::Cast(obj).PayloadStart();
+  }
+  if (obj.IsFunction()) {
+    return Function::Cast(obj).Hash();
+  }
+  if (obj.IsField()) {
+    return dart::String::HashRawSymbol(Field::Cast(obj).name());
+  }
+  // Unlikely.
+  return obj.GetClassId();
+}
+
+void SetToNull(Object* obj) {
+  *obj = Object::null();
+}
+
+Object& NewZoneHandle(Zone* zone) {
+  return Object::ZoneHandle(zone, Object::null());
+}
+
+Object& NewZoneHandle(Zone* zone, const Object& obj) {
+  return Object::ZoneHandle(zone, obj.raw());
+}
+
+const Object& NullObject() {
+  return Object::null_object();
+}
+
+const Bool& TrueObject() {
+  return dart::Bool::True();
+}
+
+const Bool& FalseObject() {
+  return dart::Bool::False();
+}
+
+const Object& EmptyTypeArguments() {
+  return Object::empty_type_arguments();
+}
+
+const Type& DynamicType() {
+  return dart::Type::dynamic_type();
+}
+
+const Type& ObjectType() {
+  return Type::Handle(dart::Type::ObjectType());
+}
+
+const Type& VoidType() {
+  return dart::Type::void_type();
+}
+
+const Type& IntType() {
+  return Type::Handle(dart::Type::IntType());
+}
+
+const Class& GrowableObjectArrayClass() {
+  auto object_store = Isolate::Current()->object_store();
+  return Class::Handle(object_store->growable_object_array_class());
+}
+
+const Class& MintClass() {
+  auto object_store = Isolate::Current()->object_store();
+  return Class::Handle(object_store->mint_class());
+}
+
+const Class& DoubleClass() {
+  auto object_store = Isolate::Current()->object_store();
+  return Class::Handle(object_store->double_class());
+}
+
+bool IsOriginalObject(const Object& object) {
+  if (object.IsICData()) {
+    return ICData::Cast(object).IsOriginal();
+  } else if (object.IsField()) {
+    return Field::Cast(object).IsOriginal();
+  }
+  return true;
+}
+
+const String& AllocateString(const char* buffer) {
+  return String::ZoneHandle(String::New(buffer, dart::Heap::kOld));
+}
+
+bool HasIntegerValue(const dart::Object& object, int64_t* value) {
+  if (object.IsInteger()) {
+    *value = Integer::Cast(object).AsInt64Value();
+    return true;
+  }
+  return false;
+}
+
+int32_t CreateJitCookie() {
+  return static_cast<int32_t>(Isolate::Current()->random()->NextUInt32());
+}
+
+word TypedDataElementSizeInBytes(classid_t cid) {
+  return dart::TypedData::ElementSizeInBytes(cid);
+}
+
+word TypedDataMaxNewSpaceElements(classid_t cid) {
+  return dart::TypedData::MaxNewSpaceElements(cid);
+}
+
+const Field& LookupMathRandomStateFieldOffset() {
+  const auto& math_lib = dart::Library::Handle(dart::Library::MathLibrary());
+  ASSERT(!math_lib.IsNull());
+  const auto& random_class = dart::Class::Handle(
+      math_lib.LookupClassAllowPrivate(dart::Symbols::_Random()));
+  ASSERT(!random_class.IsNull());
+  const auto& state_field = dart::Field::ZoneHandle(
+      random_class.LookupInstanceFieldAllowPrivate(dart::Symbols::_state()));
+  return state_field;
+}
+
+word LookupFieldOffsetInBytes(const Field& field) {
+  return field.Offset();
+}
+
+#if defined(TARGET_ARCH_IA32)
+uword SymbolsPredefinedAddress() {
+  return reinterpret_cast<uword>(dart::Symbols::PredefinedAddress());
+}
+#endif
+
+#if !defined(TARGET_ARCH_DBC)
+const Code& StubCodeAllocateArray() {
+  return dart::StubCode::AllocateArray();
+}
+
+const Code& StubCodeSubtype2TestCache() {
+  return dart::StubCode::Subtype2TestCache();
+}
+
+const Code& StubCodeSubtype6TestCache() {
+  return dart::StubCode::Subtype6TestCache();
+}
+#endif  // !defined(TARGET_ARCH_DBC)
+
+#define DEFINE_ALIAS(name)                                                     \
+  const RuntimeEntry& k##name##RuntimeEntry(dart::k##name##RuntimeEntry);
+RUNTIME_ENTRY_LIST(DEFINE_ALIAS)
+#undef DEFINE_ALIAS
+
+#define DEFINE_ALIAS(type, name, ...)                                          \
+  const RuntimeEntry& k##name##RuntimeEntry(dart::k##name##RuntimeEntry);
+LEAF_RUNTIME_ENTRY_LIST(DEFINE_ALIAS)
+#undef DEFINE_ALIAS
+
+void BailoutWithBranchOffsetError() {
+  Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
+}
+
+namespace target {
+
+const word kPageSize = dart::kPageSize;
+const word kPageSizeInWords = dart::kPageSizeInWords;
+const word kPageMask = dart::kPageMask;
+
+uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
+  return dart::RawObject::SizeTag::encode(instance_size) |
+         dart::RawObject::ClassIdTag::encode(cid) |
+         dart::RawObject::NewBit::encode(true);
+}
+
+word Object::tags_offset() {
+  return dart::Object::tags_offset();
+}
+
+const word RawObject::kCardRememberedBit = dart::RawObject::kCardRememberedBit;
+
+const word RawObject::kOldAndNotRememberedBit =
+    dart::RawObject::kOldAndNotRememberedBit;
+
+const word RawObject::kOldAndNotMarkedBit =
+    dart::RawObject::kOldAndNotMarkedBit;
+
+const word RawObject::kClassIdTagPos = dart::RawObject::kClassIdTagPos;
+
+const word RawObject::kClassIdTagSize = dart::RawObject::kClassIdTagSize;
+
+const word RawObject::kSizeTagMaxSizeTag =
+    dart::RawObject::SizeTag::kMaxSizeTag;
+
+const word RawObject::kTagBitsSizeTagPos =
+    dart::RawObject::TagBits::kSizeTagPos;
+
+const word RawAbstractType::kTypeStateFinalizedInstantiated =
+    dart::RawAbstractType::kFinalizedInstantiated;
+
+const word RawObject::kBarrierOverlapShift =
+    dart::RawObject::kBarrierOverlapShift;
+
+intptr_t ObjectPool::element_offset(intptr_t index) {
+  return dart::ObjectPool::element_offset(index);
+}
+
+word Class::type_arguments_field_offset_in_words_offset() {
+  return dart::Class::type_arguments_field_offset_in_words_offset();
+}
+
+word Class::declaration_type_offset() {
+  return dart::Class::declaration_type_offset();
+}
+
+word Class::num_type_arguments_offset_in_bytes() {
+  return dart::Class::num_type_arguments_offset();
+}
+
+const word Class::kNoTypeArguments = dart::Class::kNoTypeArguments;
+
+classid_t Class::GetId(const dart::Class& handle) {
+  return handle.id();
+}
+
+uword Class::GetInstanceSize(const dart::Class& handle) {
+  return handle.instance_size();
+}
+
+intptr_t Class::NumTypeArguments(const dart::Class& klass) {
+  return klass.NumTypeArguments() > 0;
+}
+
+bool Class::HasTypeArgumentsField(const dart::Class& klass) {
+  return klass.type_arguments_field_offset() != dart::Class::kNoTypeArguments;
+}
+
+intptr_t Class::TypeArgumentsFieldOffset(const dart::Class& klass) {
+  return klass.type_arguments_field_offset();
+}
+
+intptr_t Class::InstanceSize(const dart::Class& klass) {
+  return klass.instance_size();
+}
+
+bool Class::TraceAllocation(const dart::Class& klass) {
+  return klass.TraceAllocation(dart::Isolate::Current());
+}
+
+word Instance::first_field_offset() {
+  return dart::Instance::NextFieldOffset();
+}
+
+word Instance::DataOffsetFor(intptr_t cid) {
+  return dart::Instance::DataOffsetFor(cid);
+}
+
+word Instance::ElementSizeFor(intptr_t cid) {
+  return dart::Instance::ElementSizeFor(cid);
+}
+
+word Function::code_offset() {
+  return dart::Function::code_offset();
+}
+
+word Function::entry_point_offset() {
+  return dart::Function::entry_point_offset();
+}
+
+word Function::usage_counter_offset() {
+  return dart::Function::usage_counter_offset();
+}
+
+word Function::unchecked_entry_point_offset() {
+  return dart::Function::unchecked_entry_point_offset();
+}
+
+word ICData::CodeIndexFor(word num_args) {
+  return dart::ICData::CodeIndexFor(num_args);
+}
+
+word ICData::owner_offset() {
+  return dart::ICData::owner_offset();
+}
+
+word ICData::arguments_descriptor_offset() {
+  return dart::ICData::arguments_descriptor_offset();
+}
+
+word ICData::entries_offset() {
+  return dart::ICData::entries_offset();
+}
+
+word ICData::static_receiver_type_offset() {
+  return dart::ICData::static_receiver_type_offset();
+}
+
+word ICData::state_bits_offset() {
+  return dart::ICData::state_bits_offset();
+}
+
+word ICData::CountIndexFor(word num_args) {
+  return dart::ICData::CountIndexFor(num_args);
+}
+
+word ICData::TargetIndexFor(word num_args) {
+  return dart::ICData::TargetIndexFor(num_args);
+}
+
+word ICData::ExactnessOffsetFor(word num_args) {
+  return dart::ICData::ExactnessOffsetFor(num_args);
+}
+
+word ICData::TestEntryLengthFor(word num_args, bool exactness_check) {
+  return dart::ICData::TestEntryLengthFor(num_args, exactness_check);
+}
+
+word ICData::EntryPointIndexFor(word num_args) {
+  return dart::ICData::EntryPointIndexFor(num_args);
+}
+
+word ICData::NumArgsTestedShift() {
+  return dart::ICData::NumArgsTestedShift();
+}
+
+word ICData::NumArgsTestedMask() {
+  return dart::ICData::NumArgsTestedMask();
+}
+
+const word MegamorphicCache::kSpreadFactor =
+    dart::MegamorphicCache::kSpreadFactor;
+
+word MegamorphicCache::mask_offset() {
+  return dart::MegamorphicCache::mask_offset();
+}
+word MegamorphicCache::buckets_offset() {
+  return dart::MegamorphicCache::buckets_offset();
+}
+word MegamorphicCache::arguments_descriptor_offset() {
+  return dart::MegamorphicCache::arguments_descriptor_offset();
+}
+
+word SingleTargetCache::lower_limit_offset() {
+  return dart::SingleTargetCache::lower_limit_offset();
+}
+word SingleTargetCache::upper_limit_offset() {
+  return dart::SingleTargetCache::upper_limit_offset();
+}
+word SingleTargetCache::entry_point_offset() {
+  return dart::SingleTargetCache::entry_point_offset();
+}
+word SingleTargetCache::target_offset() {
+  return dart::SingleTargetCache::target_offset();
+}
+
+const word Array::kMaxNewSpaceElements = dart::Array::kMaxNewSpaceElements;
+
+word Context::InstanceSize(word n) {
+  return dart::Context::InstanceSize(n);
+}
+
+word Context::variable_offset(word n) {
+  return dart::Context::variable_offset(n);
+}
+
+word TypedData::InstanceSize() {
+  return sizeof(RawTypedData);
+}
+
+word Array::header_size() {
+  return sizeof(dart::RawArray);
+}
+
+#define CLASS_NAME_LIST(V)                                                     \
+  V(AbstractType, type_test_stub_entry_point_offset)                           \
+  V(ArgumentsDescriptor, count_offset)                                         \
+  V(ArgumentsDescriptor, type_args_len_offset)                                 \
+  V(Array, data_offset)                                                        \
+  V(Array, length_offset)                                                      \
+  V(Array, tags_offset)                                                        \
+  V(Array, type_arguments_offset)                                              \
+  V(ClassTable, table_offset)                                                  \
+  V(Closure, context_offset)                                                   \
+  V(Closure, delayed_type_arguments_offset)                                    \
+  V(Closure, function_offset)                                                  \
+  V(Closure, function_type_arguments_offset)                                   \
+  V(Closure, instantiator_type_arguments_offset)                               \
+  V(Code, object_pool_offset)                                                  \
+  V(Code, saved_instructions_offset)                                           \
+  V(Context, num_variables_offset)                                             \
+  V(Context, parent_offset)                                                    \
+  V(Double, value_offset)                                                      \
+  V(Float32x4, value_offset)                                                   \
+  V(Float64x2, value_offset)                                                   \
+  V(GrowableObjectArray, data_offset)                                          \
+  V(GrowableObjectArray, length_offset)                                        \
+  V(GrowableObjectArray, type_arguments_offset)                                \
+  V(HeapPage, card_table_offset)                                               \
+  V(Isolate, class_table_offset)                                               \
+  V(Isolate, current_tag_offset)                                               \
+  V(Isolate, default_tag_offset)                                               \
+  V(Isolate, ic_miss_code_offset)                                              \
+  V(Isolate, object_store_offset)                                              \
+  V(Isolate, user_tag_offset)                                                  \
+  V(MarkingStackBlock, pointers_offset)                                        \
+  V(MarkingStackBlock, top_offset)                                             \
+  V(Mint, value_offset)                                                        \
+  V(NativeArguments, argc_tag_offset)                                          \
+  V(NativeArguments, argv_offset)                                              \
+  V(NativeArguments, retval_offset)                                            \
+  V(NativeArguments, thread_offset)                                            \
+  V(ObjectStore, double_type_offset)                                           \
+  V(ObjectStore, int_type_offset)                                              \
+  V(ObjectStore, string_type_offset)                                           \
+  V(OneByteString, data_offset)                                                \
+  V(StoreBufferBlock, pointers_offset)                                         \
+  V(StoreBufferBlock, top_offset)                                              \
+  V(String, hash_offset)                                                       \
+  V(String, length_offset)                                                     \
+  V(SubtypeTestCache, cache_offset)                                            \
+  V(Thread, active_exception_offset)                                           \
+  V(Thread, active_stacktrace_offset)                                          \
+  V(Thread, async_stack_trace_offset)                                          \
+  V(Thread, auto_scope_native_wrapper_entry_point_offset)                      \
+  V(Thread, bool_false_offset)                                                 \
+  V(Thread, bool_true_offset)                                                  \
+  V(Thread, dart_stream_offset)                                                \
+  V(Thread, end_offset)                                                        \
+  V(Thread, global_object_pool_offset)                                         \
+  V(Thread, isolate_offset)                                                    \
+  V(Thread, marking_stack_block_offset)                                        \
+  V(Thread, no_scope_native_wrapper_entry_point_offset)                        \
+  V(Thread, object_null_offset)                                                \
+  V(Thread, predefined_symbols_address_offset)                                 \
+  V(Thread, resume_pc_offset)                                                  \
+  V(Thread, store_buffer_block_offset)                                         \
+  V(Thread, top_exit_frame_info_offset)                                        \
+  V(Thread, top_offset)                                                        \
+  V(Thread, top_resource_offset)                                               \
+  V(Thread, vm_tag_offset)                                                     \
+  V(TimelineStream, enabled_offset)                                            \
+  V(TwoByteString, data_offset)                                                \
+  V(Type, arguments_offset)                                                    \
+  V(TypedData, data_offset)                                                    \
+  V(TypedData, length_offset)                                                  \
+  V(Type, hash_offset)                                                         \
+  V(TypeRef, type_offset)                                                      \
+  V(Type, signature_offset)                                                    \
+  V(Type, type_state_offset)                                                   \
+  V(UserTag, tag_offset)
+
+#define DEFINE_FORWARDER(clazz, name)                                          \
+  word clazz::name() { return dart::clazz::name(); }
+
+CLASS_NAME_LIST(DEFINE_FORWARDER)
+#undef DEFINE_FORWARDER
+
+const word HeapPage::kBytesPerCardLog2 = dart::HeapPage::kBytesPerCardLog2;
+
+const word String::kHashBits = dart::String::kHashBits;
+
+word String::InstanceSize() {
+  return sizeof(dart::RawString);
+}
+
+bool Heap::IsAllocatableInNewSpace(intptr_t instance_size) {
+  return dart::Heap::IsAllocatableInNewSpace(instance_size);
+}
+
+#if !defined(TARGET_ARCH_DBC)
+word Thread::write_barrier_code_offset() {
+  return dart::Thread::write_barrier_code_offset();
+}
+
+word Thread::array_write_barrier_code_offset() {
+  return dart::Thread::array_write_barrier_code_offset();
+}
+
+word Thread::fix_callers_target_code_offset() {
+  return dart::Thread::fix_callers_target_code_offset();
+}
+
+word Thread::fix_allocation_stub_code_offset() {
+  return dart::Thread::fix_allocation_stub_code_offset();
+}
+
+word Thread::call_to_runtime_entry_point_offset() {
+  return dart::Thread::call_to_runtime_entry_point_offset();
+}
+
+word Thread::null_error_shared_with_fpu_regs_entry_point_offset() {
+  return dart::Thread::null_error_shared_with_fpu_regs_entry_point_offset();
+}
+
+word Thread::null_error_shared_without_fpu_regs_entry_point_offset() {
+  return dart::Thread::null_error_shared_without_fpu_regs_entry_point_offset();
+}
+
+word Thread::monomorphic_miss_entry_offset() {
+  return dart::Thread::monomorphic_miss_entry_offset();
+}
+
+word Thread::write_barrier_mask_offset() {
+  return dart::Thread::write_barrier_mask_offset();
+}
+
+word Thread::write_barrier_entry_point_offset() {
+  return dart::Thread::write_barrier_entry_point_offset();
+}
+
+word Thread::array_write_barrier_entry_point_offset() {
+  return dart::Thread::array_write_barrier_entry_point_offset();
+}
+#endif  // !defined(TARGET_ARCH_DBC)
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
+    defined(TARGET_ARCH_X64)
+word Thread::write_barrier_wrappers_thread_offset(intptr_t regno) {
+  return dart::Thread::write_barrier_wrappers_thread_offset(
+      static_cast<Register>(regno));
+}
+#endif
+
+#if !defined(TARGET_ARCH_DBC)
+
+word Thread::monomorphic_miss_stub_offset() {
+  return dart::Thread::monomorphic_miss_stub_offset();
+}
+
+word Thread::ic_lookup_through_code_stub_offset() {
+  return dart::Thread::ic_lookup_through_code_stub_offset();
+}
+
+word Thread::lazy_specialize_type_test_stub_offset() {
+  return dart::Thread::lazy_specialize_type_test_stub_offset();
+}
+
+word Thread::slow_type_test_stub_offset() {
+  return dart::Thread::slow_type_test_stub_offset();
+}
+
+word Thread::call_to_runtime_stub_offset() {
+  return dart::Thread::call_to_runtime_stub_offset();
+}
+
+word Thread::invoke_dart_code_stub_offset() {
+  return dart::Thread::invoke_dart_code_stub_offset();
+}
+
+word Thread::interpret_call_entry_point_offset() {
+  return dart::Thread::interpret_call_entry_point_offset();
+}
+
+word Thread::invoke_dart_code_from_bytecode_stub_offset() {
+  return dart::Thread::invoke_dart_code_from_bytecode_stub_offset();
+}
+
+word Thread::null_error_shared_without_fpu_regs_stub_offset() {
+  return dart::Thread::null_error_shared_without_fpu_regs_stub_offset();
+}
+
+word Thread::null_error_shared_with_fpu_regs_stub_offset() {
+  return dart::Thread::null_error_shared_with_fpu_regs_stub_offset();
+}
+
+word Thread::stack_overflow_shared_without_fpu_regs_stub_offset() {
+  return dart::Thread::stack_overflow_shared_without_fpu_regs_stub_offset();
+}
+
+word Thread::stack_overflow_shared_with_fpu_regs_stub_offset() {
+  return dart::Thread::stack_overflow_shared_with_fpu_regs_stub_offset();
+}
+
+word Thread::lazy_deopt_from_return_stub_offset() {
+  return dart::Thread::lazy_deopt_from_return_stub_offset();
+}
+
+word Thread::lazy_deopt_from_throw_stub_offset() {
+  return dart::Thread::lazy_deopt_from_throw_stub_offset();
+}
+
+word Thread::deoptimize_stub_offset() {
+  return dart::Thread::deoptimize_stub_offset();
+}
+
+#endif  // !defined(TARGET_ARCH_DBC)
+
+#define DECLARE_CONSTANT_OFFSET_GETTER(name)                                   \
+  word Thread::name##_address_offset() {                                       \
+    return dart::Thread::name##_address_offset();                              \
+  }
+THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
+#undef DECLARE_CONSTANT_OFFSET_GETTER
+
+word Thread::OffsetFromThread(const dart::Object& object) {
+  return dart::Thread::OffsetFromThread(object);
+}
+
+const word StoreBufferBlock::kSize = dart::StoreBufferBlock::kSize;
+
+const word MarkingStackBlock::kSize = dart::MarkingStackBlock::kSize;
+
+#if !defined(PRODUCT)
+word Isolate::single_step_offset() {
+  return dart::Isolate::single_step_offset();
+}
+#endif  // !defined(PRODUCT)
+
+#if !defined(PRODUCT)
+word ClassTable::ClassOffsetFor(intptr_t cid) {
+  return dart::ClassTable::ClassOffsetFor(cid);
+}
+
+word ClassTable::StateOffsetFor(intptr_t cid) {
+  return dart::ClassTable::StateOffsetFor(cid);
+}
+
+word ClassTable::TableOffsetFor(intptr_t cid) {
+  return dart::ClassTable::TableOffsetFor(cid);
+}
+
+word ClassTable::CounterOffsetFor(intptr_t cid, bool is_new) {
+  return dart::ClassTable::CounterOffsetFor(cid, is_new);
+}
+
+word ClassTable::SizeOffsetFor(intptr_t cid, bool is_new) {
+  return dart::ClassTable::SizeOffsetFor(cid, is_new);
+}
+#endif  // !defined(PRODUCT)
+
+const word ClassTable::kSizeOfClassPairLog2 = dart::kSizeOfClassPairLog2;
+
+const intptr_t Instructions::kPolymorphicEntryOffset =
+    dart::Instructions::kPolymorphicEntryOffset;
+
+const intptr_t Instructions::kMonomorphicEntryOffset =
+    dart::Instructions::kMonomorphicEntryOffset;
+
+intptr_t Instructions::HeaderSize() {
+  return dart::Instructions::HeaderSize();
+}
+
+intptr_t Code::entry_point_offset(CodeEntryKind kind) {
+  return dart::Code::entry_point_offset(kind);
+}
+
+const word SubtypeTestCache::kTestEntryLength =
+    dart::SubtypeTestCache::kTestEntryLength;
+const word SubtypeTestCache::kInstanceClassIdOrFunction =
+    dart::SubtypeTestCache::kInstanceClassIdOrFunction;
+const word SubtypeTestCache::kInstanceTypeArguments =
+    dart::SubtypeTestCache::kInstanceTypeArguments;
+const word SubtypeTestCache::kInstantiatorTypeArguments =
+    dart::SubtypeTestCache::kInstantiatorTypeArguments;
+const word SubtypeTestCache::kFunctionTypeArguments =
+    dart::SubtypeTestCache::kFunctionTypeArguments;
+const word SubtypeTestCache::kInstanceParentFunctionTypeArguments =
+    dart::SubtypeTestCache::kInstanceParentFunctionTypeArguments;
+const word SubtypeTestCache::kInstanceDelayedFunctionTypeArguments =
+    dart::SubtypeTestCache::kInstanceDelayedFunctionTypeArguments;
+const word SubtypeTestCache::kTestResult = dart::SubtypeTestCache::kTestResult;
+
+word Context::header_size() {
+  return sizeof(dart::RawContext);
+}
+
+#if !defined(PRODUCT)
+word ClassHeapStats::TraceAllocationMask() {
+  return dart::ClassHeapStats::TraceAllocationMask();
+}
+
+word ClassHeapStats::state_offset() {
+  return dart::ClassHeapStats::state_offset();
+}
+
+word ClassHeapStats::allocated_since_gc_new_space_offset() {
+  return dart::ClassHeapStats::allocated_since_gc_new_space_offset();
+}
+
+word ClassHeapStats::allocated_size_since_gc_new_space_offset() {
+  return dart::ClassHeapStats::allocated_size_since_gc_new_space_offset();
+}
+#endif  // !defined(PRODUCT)
+
+const word Smi::kBits = dart::Smi::kBits;
+bool IsSmi(const dart::Object& a) {
+  return a.IsSmi();
+}
+
+word ToRawSmi(const dart::Object& a) {
+  ASSERT(a.IsSmi());
+  return reinterpret_cast<word>(a.raw());
+}
+
+word ToRawSmi(intptr_t value) {
+  return dart::Smi::RawValue(value);
+}
+
+bool CanLoadFromThread(const dart::Object& object,
+                       word* offset /* = nullptr */) {
+  if (dart::Thread::CanLoadFromThread(object)) {
+    if (offset != nullptr) {
+      *offset = dart::Thread::OffsetFromThread(object);
+    }
+    return true;
+  }
+  return false;
+}
+
+#if defined(TARGET_ARCH_IA32)
+uword Code::EntryPointOf(const dart::Code& code) {
+  static_assert(kHostWordSize == kWordSize,
+                "Can't embed raw pointers to runtime objects when host and "
+                "target word sizes are different");
+  return code.EntryPoint();
+}
+
+bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj) {
+  return obj.IsSmi() || obj.InVMHeap();
+}
+
+word ToRawPointer(const dart::Object& a) {
+  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());
+}
+#endif  // defined(TARGET_ARCH_IA32)
+
+const word NativeEntry::kNumCallWrapperArguments =
+    dart::NativeEntry::kNumCallWrapperArguments;
+
+word NativeArguments::StructSize() {
+  return sizeof(dart::NativeArguments);
+}
+
+word RegExp::function_offset(classid_t cid, bool sticky) {
+  return dart::RegExp::function_offset(cid, sticky);
+}
+
+const word Symbols::kNumberOfOneCharCodeSymbols =
+    dart::Symbols::kNumberOfOneCharCodeSymbols;
+const word Symbols::kNullCharCodeSymbolOffset =
+    dart::Symbols::kNullCharCodeSymbolOffset;
+
+}  // namespace target
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
new file mode 100644
index 0000000..853fac0
--- /dev/null
+++ b/runtime/vm/compiler/runtime_api.h
@@ -0,0 +1,753 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_RUNTIME_API_H_
+#define RUNTIME_VM_COMPILER_RUNTIME_API_H_
+
+// This header defines the API that compiler can use to interact with the
+// underlying Dart runtime that it is embedded into.
+//
+// Compiler is not allowed to directly interact with any objects - it can only
+// use classes like dart::Object, dart::Code, dart::Function and similar as
+// opaque handles. All interactions should be done through helper methods
+// provided by this header.
+//
+// This header also provides ways to get word sizes, frame layout, field
+// offsets for the target runtime. Note that these can be different from
+// those on the host. Helpers providing access to these values live
+// in compiler::target namespace.
+
+#include "platform/globals.h"
+#include "vm/allocation.h"
+#include "vm/bitfield.h"
+#include "vm/class_id.h"
+#include "vm/code_entry_kind.h"
+#include "vm/frame_layout.h"
+#include "vm/pointer_tagging.h"
+#include "vm/runtime_entry_list.h"
+#include "vm/token.h"
+
+namespace dart {
+
+// Forward declarations.
+class LocalVariable;
+class Object;
+class RuntimeEntry;
+class Zone;
+
+#define DO(clazz) class clazz;
+CLASS_LIST_FOR_HANDLES(DO)
+#undef DO
+
+namespace compiler {
+class Assembler;
+}
+
+namespace compiler {
+
+// Host word sizes.
+//
+// Code in the compiler namespace should not use kWordSize and derived
+// constants directly because the word size on host and target might
+// be different.
+//
+// To prevent this we introduce variables that would shadow these
+// constants and introduce compilation errors when used.
+//
+// target::kWordSize and target::ObjectAlignment give access to
+// word size and object aligment offsets for the target.
+//
+// Similarly kHostWordSize gives access to the host word size.
+class InvalidClass {};
+extern InvalidClass kWordSize;
+extern InvalidClass kWordSizeLog2;
+extern InvalidClass kNewObjectAlignmentOffset;
+extern InvalidClass kOldObjectAlignmentOffset;
+extern InvalidClass kNewObjectBitPosition;
+extern InvalidClass kObjectAlignment;
+extern InvalidClass kObjectAlignmentLog2;
+extern InvalidClass kObjectAlignmentMask;
+
+static constexpr intptr_t kHostWordSize = dart::kWordSize;
+static constexpr intptr_t kHostWordSizeLog2 = dart::kWordSizeLog2;
+
+//
+// Object handles.
+//
+
+// Create an empty handle.
+Object& NewZoneHandle(Zone* zone);
+
+// Clone the given handle.
+Object& NewZoneHandle(Zone* zone, const Object&);
+
+//
+// Constant objects.
+//
+
+const Object& NullObject();
+const Bool& TrueObject();
+const Bool& FalseObject();
+const Object& EmptyTypeArguments();
+const Type& DynamicType();
+const Type& ObjectType();
+const Type& VoidType();
+const Type& IntType();
+const Class& GrowableObjectArrayClass();
+const Class& MintClass();
+const Class& DoubleClass();
+
+template <typename To, typename From>
+const To& CastHandle(const From& from) {
+  return reinterpret_cast<const To&>(from);
+}
+
+// Returns true if [a] and [b] are the same object.
+bool IsSameObject(const Object& a, const Object& b);
+
+// Returns true if the given handle is a zone handle or one of the global
+// cached handles.
+bool IsNotTemporaryScopedHandle(const Object& obj);
+
+// Returns true if [obj] resides in old space.
+bool IsInOldSpace(const Object& obj);
+
+// Returns true if [obj] is not a Field/ICData clone.
+//
+// Used to assert that we are not embedding pointers to cloned objects that are
+// used by background compiler into object pools / code.
+bool IsOriginalObject(const Object& object);
+
+// Clear the given handle.
+void SetToNull(Object* obj);
+
+// Helper functions to upcast handles.
+//
+// Note: compiler code cannot include object.h so it cannot see that Object is
+// a superclass of Code or Function - thus we have to cast these pointers using
+// reinterpret_cast.
+inline const Object& ToObject(const Code& handle) {
+  return *reinterpret_cast<const Object*>(&handle);
+}
+
+inline const Object& ToObject(const Function& handle) {
+  return *reinterpret_cast<const Object*>(&handle);
+}
+
+// Returns some hash value for the given object.
+//
+// Note: the given hash value does not necessarily match Object.get:hashCode,
+// or canonical hash.
+intptr_t ObjectHash(const Object& obj);
+
+// If the given object represents a Dart integer returns true and sets [value]
+// to the value of the integer.
+bool HasIntegerValue(const dart::Object& obj, int64_t* value);
+
+// Creates a random cookie to be used for masking constants embedded in the
+// generated code.
+int32_t CreateJitCookie();
+
+// Returns the size in bytes for the given class id.
+word TypedDataElementSizeInBytes(classid_t cid);
+
+// Returns the size in bytes for the given class id.
+word TypedDataMaxNewSpaceElements(classid_t cid);
+
+// Looks up the dart:math's _Random._A field.
+const Field& LookupMathRandomStateFieldOffset();
+
+// Returns the offset in bytes of [field].
+word LookupFieldOffsetInBytes(const Field& field);
+
+#if defined(TARGET_ARCH_IA32)
+uword SymbolsPredefinedAddress();
+#endif
+
+typedef void (*RuntimeEntryCallInternal)(const dart::RuntimeEntry*,
+                                         compiler::Assembler*,
+                                         intptr_t);
+
+#if !defined(TARGET_ARCH_DBC)
+const Code& StubCodeAllocateArray();
+const Code& StubCodeSubtype2TestCache();
+const Code& StubCodeSubtype6TestCache();
+#endif  // !defined(TARGET_ARCH_DBC)
+
+class RuntimeEntry : public ValueObject {
+ public:
+  virtual ~RuntimeEntry() {}
+
+  void Call(compiler::Assembler* assembler, intptr_t argument_count) const {
+    ASSERT(call_ != NULL);
+    ASSERT(runtime_entry_ != NULL);
+
+    // We call a manually set function pointer which points to the
+    // implementation of call for the subclass. We do this instead of just
+    // defining Call in this class as a pure virtual method and providing an
+    // implementation in the subclass as RuntimeEntry objects are declared as
+    // globals which causes problems on Windows.
+    //
+    // When exit() is called on Windows, global objects start to be destroyed.
+    // As part of an object's destruction, the vtable is reset to that of the
+    // base class. Since some threads may still be running and accessing these
+    // now destroyed globals, an invocation to dart::RuntimeEntry::Call would
+    // instead invoke dart::compiler::RuntimeEntry::Call. If
+    // dart::compiler::RuntimeEntry::Call were a pure virtual method, _purecall
+    // would be invoked to handle the invalid call and attempt to call exit(),
+    // causing the process to hang on a lock.
+    //
+    // By removing the need to rely on a potentially invalid vtable at exit,
+    // we should be able to avoid hanging or crashing the process at shutdown,
+    // even as global objects start to be destroyed. See issue #35855.
+    call_(runtime_entry_, assembler, argument_count);
+  }
+
+ protected:
+  RuntimeEntry(const dart::RuntimeEntry* runtime_entry,
+               RuntimeEntryCallInternal call)
+      : runtime_entry_(runtime_entry), call_(call) {}
+
+ private:
+  const dart::RuntimeEntry* runtime_entry_;
+  RuntimeEntryCallInternal call_;
+};
+
+#define DECLARE_RUNTIME_ENTRY(name)                                            \
+  extern const RuntimeEntry& k##name##RuntimeEntry;
+RUNTIME_ENTRY_LIST(DECLARE_RUNTIME_ENTRY)
+#undef DECLARE_RUNTIME_ENTRY
+
+#define DECLARE_RUNTIME_ENTRY(type, name, ...)                                 \
+  extern const RuntimeEntry& k##name##RuntimeEntry;
+LEAF_RUNTIME_ENTRY_LIST(DECLARE_RUNTIME_ENTRY)
+#undef DECLARE_RUNTIME_ENTRY
+
+// Allocate a string object with the given content in the runtime heap.
+const String& AllocateString(const char* buffer);
+
+DART_NORETURN void BailoutWithBranchOffsetError();
+
+// compiler::target namespace contains information about the target platform:
+//
+//    - word sizes and derived constants
+//    - offsets of fields
+//    - sizes of structures
+namespace target {
+
+// Currently we define target::word to match dart::word which represents
+// host word.
+//
+// Once refactoring of the compiler is complete we will switch target::word
+// to be independent from host word.
+typedef dart::word word;
+typedef dart::uword uword;
+
+static constexpr word kWordSize = dart::kWordSize;
+static constexpr word kWordSizeLog2 = dart::kWordSizeLog2;
+static_assert((1 << kWordSizeLog2) == kWordSize,
+              "kWordSizeLog2 should match kWordSize");
+
+using ObjectAlignment = dart::ObjectAlignment<kWordSize, kWordSizeLog2>;
+
+// Information about heap pages.
+extern const word kPageSize;
+extern const word kPageSizeInWords;
+extern const word kPageMask;
+
+// Information about frame_layout that compiler should be targeting.
+extern FrameLayout frame_layout;
+
+// Returns the FP-relative index where [variable] can be found (assumes
+// [variable] is not captured), in bytes.
+inline int FrameOffsetInBytesForVariable(const LocalVariable* variable) {
+  return frame_layout.FrameSlotForVariable(variable) * kWordSize;
+}
+
+// Encode tag word for a heap allocated object with the given class id and
+// size.
+//
+// Note: even on 64-bit platforms we only use lower 32-bits of the tag word.
+uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size);
+
+//
+// Target specific information about objects.
+//
+
+// Returns true if the given object can be represented as a Smi on the
+// target platform.
+bool IsSmi(const dart::Object& a);
+
+// Return raw Smi representation of the given object for the target platform.
+word ToRawSmi(const dart::Object& a);
+
+// Return raw Smi representation of the given integer value for the target
+// platform.
+//
+// Note: method assumes that caller has validated that value is representable
+// as a Smi.
+word ToRawSmi(intptr_t value);
+
+// If the given object can be loaded from the thread on the target then
+// return true and set offset (if provided) to the offset from the
+// thread pointer to a field that contains the object.
+bool CanLoadFromThread(const dart::Object& object, word* offset = nullptr);
+
+// On IA32 we can embed raw pointers into generated code.
+#if defined(TARGET_ARCH_IA32)
+// Returns true if the pointer to the given object can be directly embedded
+// into the generated code (because the object is immortal and immovable).
+bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj);
+
+// Returns raw pointer value for the given object. Should only be invoked
+// if CanEmbedAsRawPointerInGeneratedCode returns true.
+word ToRawPointer(const dart::Object& a);
+#endif  // defined(TARGET_ARCH_IA32)
+
+//
+// Target specific offsets and constants.
+//
+// Currently we use the same names for classes, constants and getters to make
+// migration easier.
+
+class RawObject : public AllStatic {
+ public:
+  static const word kCardRememberedBit;
+  static const word kOldAndNotRememberedBit;
+  static const word kOldAndNotMarkedBit;
+  static const word kClassIdTagPos;
+  static const word kClassIdTagSize;
+  static const word kSizeTagMaxSizeTag;
+  static const word kTagBitsSizeTagPos;
+  static const word kBarrierOverlapShift;
+};
+
+class RawAbstractType : public AllStatic {
+ public:
+  static const word kTypeStateFinalizedInstantiated;
+};
+
+class Object : public AllStatic {
+ public:
+  // Offset of the tags word.
+  static word tags_offset();
+};
+
+class ObjectPool : public AllStatic {
+ public:
+  // Return offset to the element with the given [index] in the object pool.
+  static intptr_t element_offset(intptr_t index);
+};
+
+class Class : public AllStatic {
+ public:
+  static word type_arguments_field_offset_in_words_offset();
+
+  static word declaration_type_offset();
+
+  // The offset of the RawObject::num_type_arguments_ field in bytes.
+  static word num_type_arguments_offset_in_bytes();
+
+  // The value used if no type arguments vector is present.
+  static const word kNoTypeArguments;
+
+  // Return class id of the given class on the target.
+  static classid_t GetId(const dart::Class& handle);
+
+  // Return instance size for the given class on the target.
+  static uword GetInstanceSize(const dart::Class& handle);
+
+  // Returns the number of type arguments.
+  static intptr_t NumTypeArguments(const dart::Class& klass);
+
+  // Whether [klass] has a type arguments vector field.
+  static bool HasTypeArgumentsField(const dart::Class& klass);
+
+  // Returns the offset (in bytes) of the type arguments vector.
+  static intptr_t TypeArgumentsFieldOffset(const dart::Class& klass);
+
+  // Returns the instance size (in bytes).
+  static intptr_t InstanceSize(const dart::Class& klass);
+
+  // Whether to trace allocation for this klass.
+  static bool TraceAllocation(const dart::Class& klass);
+};
+
+class Instance : public AllStatic {
+ public:
+  // Returns the offset to the first field of [RawInstance].
+  static word first_field_offset();
+  static word DataOffsetFor(intptr_t cid);
+  static word ElementSizeFor(intptr_t cid);
+};
+
+class Function : public AllStatic {
+ public:
+  static word code_offset();
+  static word entry_point_offset();
+  static word usage_counter_offset();
+  static word unchecked_entry_point_offset();
+};
+
+class ICData : public AllStatic {
+ public:
+  static word owner_offset();
+  static word arguments_descriptor_offset();
+  static word entries_offset();
+  static word static_receiver_type_offset();
+  static word state_bits_offset();
+
+  static word CodeIndexFor(word num_args);
+  static word CountIndexFor(word num_args);
+  static word TargetIndexFor(word num_args);
+  static word ExactnessOffsetFor(word num_args);
+  static word TestEntryLengthFor(word num_args, bool exactness_check);
+  static word EntryPointIndexFor(word num_args);
+  static word NumArgsTestedShift();
+  static word NumArgsTestedMask();
+};
+
+class MegamorphicCache : public AllStatic {
+ public:
+  static const word kSpreadFactor;
+  static word mask_offset();
+  static word buckets_offset();
+  static word arguments_descriptor_offset();
+};
+
+class SingleTargetCache : public AllStatic {
+ public:
+  static word lower_limit_offset();
+  static word upper_limit_offset();
+  static word entry_point_offset();
+  static word target_offset();
+};
+
+class Array : public AllStatic {
+ public:
+  static word header_size();
+  static word tags_offset();
+  static word data_offset();
+  static word type_arguments_offset();
+  static word length_offset();
+
+  static const word kMaxNewSpaceElements;
+};
+
+class GrowableObjectArray : public AllStatic {
+ public:
+  static word data_offset();
+  static word type_arguments_offset();
+  static word length_offset();
+};
+
+class TypedData : public AllStatic {
+ public:
+  static word data_offset();
+  static word length_offset();
+  static word InstanceSize();
+};
+
+class ArgumentsDescriptor : public AllStatic {
+ public:
+  static word count_offset();
+  static word type_args_len_offset();
+};
+
+class AbstractType : public AllStatic {
+ public:
+  static word type_test_stub_entry_point_offset();
+};
+
+class Type : public AllStatic {
+ public:
+  static word hash_offset();
+  static word type_state_offset();
+  static word arguments_offset();
+  static word signature_offset();
+};
+
+class TypeRef : public AllStatic {
+ public:
+  static word type_offset();
+};
+
+class Double : public AllStatic {
+ public:
+  static word value_offset();
+};
+
+class Smi : public AllStatic {
+ public:
+  static const word kBits;
+};
+
+class Mint : public AllStatic {
+ public:
+  static word value_offset();
+};
+
+class String : public AllStatic {
+ public:
+  static const word kHashBits;
+  static word hash_offset();
+  static word length_offset();
+  static word InstanceSize();
+};
+
+class OneByteString : public AllStatic {
+ public:
+  static word data_offset();
+};
+
+class TwoByteString : public AllStatic {
+ public:
+  static word data_offset();
+};
+
+class Float32x4 : public AllStatic {
+ public:
+  static word value_offset();
+};
+
+class Float64x2 : public AllStatic {
+ public:
+  static word value_offset();
+};
+
+class TimelineStream : public AllStatic {
+ public:
+  static word enabled_offset();
+};
+
+class Thread : public AllStatic {
+ public:
+  static word dart_stream_offset();
+  static word async_stack_trace_offset();
+  static word predefined_symbols_address_offset();
+
+  static word active_exception_offset();
+  static word active_stacktrace_offset();
+  static word resume_pc_offset();
+  static word marking_stack_block_offset();
+  static word top_exit_frame_info_offset();
+  static word top_resource_offset();
+  static word global_object_pool_offset();
+  static word object_null_offset();
+  static word bool_true_offset();
+  static word bool_false_offset();
+  static word top_offset();
+  static word end_offset();
+  static word isolate_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 write_barrier_mask_offset();
+  static word monomorphic_miss_entry_offset();
+  static word write_barrier_wrappers_thread_offset(intptr_t regno);
+  static word array_write_barrier_entry_point_offset();
+  static word write_barrier_entry_point_offset();
+  static word vm_tag_offset();
+
+#if !defined(TARGET_ARCH_DBC)
+  static word write_barrier_code_offset();
+  static word array_write_barrier_code_offset();
+  static word fix_callers_target_code_offset();
+  static word fix_allocation_stub_code_offset();
+
+  static word monomorphic_miss_stub_offset();
+  static word ic_lookup_through_code_stub_offset();
+  static word lazy_specialize_type_test_stub_offset();
+  static word slow_type_test_stub_offset();
+  static word call_to_runtime_stub_offset();
+  static word invoke_dart_code_stub_offset();
+  static word interpret_call_entry_point_offset();
+  static word invoke_dart_code_from_bytecode_stub_offset();
+  static word null_error_shared_without_fpu_regs_stub_offset();
+  static word null_error_shared_with_fpu_regs_stub_offset();
+  static word stack_overflow_shared_without_fpu_regs_stub_offset();
+  static word stack_overflow_shared_with_fpu_regs_stub_offset();
+  static word lazy_deopt_from_return_stub_offset();
+  static word lazy_deopt_from_throw_stub_offset();
+  static word deoptimize_stub_offset();
+#endif  // !defined(TARGET_ARCH_DBC)
+
+  static word no_scope_native_wrapper_entry_point_offset();
+  static word auto_scope_native_wrapper_entry_point_offset();
+
+#define THREAD_XMM_CONSTANT_LIST(V)                                            \
+  V(float_not)                                                                 \
+  V(float_negate)                                                              \
+  V(float_absolute)                                                            \
+  V(float_zerow)                                                               \
+  V(double_negate)                                                             \
+  V(double_abs)
+
+#define DECLARE_CONSTANT_OFFSET_GETTER(name)                                   \
+  static word name##_address_offset();
+  THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
+#undef DECLARE_CONSTANT_OFFSET_GETTER
+
+  static word OffsetFromThread(const dart::Object& object);
+};
+
+class StoreBufferBlock : public AllStatic {
+ public:
+  static word top_offset();
+  static word pointers_offset();
+  static const word kSize;
+};
+
+class MarkingStackBlock : public AllStatic {
+ public:
+  static word top_offset();
+  static word pointers_offset();
+  static const word kSize;
+};
+
+class ObjectStore : public AllStatic {
+ public:
+  static word double_type_offset();
+  static word int_type_offset();
+  static word string_type_offset();
+};
+
+class Isolate : public AllStatic {
+ public:
+  static word 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 ic_miss_code_offset();
+#if !defined(PRODUCT)
+  static word single_step_offset();
+#endif  // !defined(PRODUCT)
+};
+
+class ClassTable : public AllStatic {
+ public:
+  static word table_offset();
+#if !defined(PRODUCT)
+  static word ClassOffsetFor(intptr_t cid);
+  static word StateOffsetFor(intptr_t cid);
+  static word TableOffsetFor(intptr_t cid);
+  static word CounterOffsetFor(intptr_t cid, bool is_new);
+  static word SizeOffsetFor(intptr_t cid, bool is_new);
+#endif  // !defined(PRODUCT)
+  static const word kSizeOfClassPairLog2;
+};
+
+#if !defined(PRODUCT)
+class ClassHeapStats : public AllStatic {
+ public:
+  static word TraceAllocationMask();
+  static word state_offset();
+  static word allocated_since_gc_new_space_offset();
+  static word allocated_size_since_gc_new_space_offset();
+};
+#endif  // !defined(PRODUCT)
+
+class Instructions : public AllStatic {
+ public:
+  static const intptr_t kPolymorphicEntryOffset;
+  static const intptr_t kMonomorphicEntryOffset;
+  static intptr_t HeaderSize();
+};
+
+class Code : public AllStatic {
+ public:
+#if defined(TARGET_ARCH_IA32)
+  static uword EntryPointOf(const dart::Code& code);
+#endif  // defined(TARGET_ARCH_IA32)
+
+  static intptr_t object_pool_offset();
+  static intptr_t entry_point_offset(
+      CodeEntryKind kind = CodeEntryKind::kNormal);
+  static intptr_t saved_instructions_offset();
+};
+
+class SubtypeTestCache : public AllStatic {
+ public:
+  static word cache_offset();
+
+  static const word kTestEntryLength;
+  static const word kInstanceClassIdOrFunction;
+  static const word kInstanceTypeArguments;
+  static const word kInstantiatorTypeArguments;
+  static const word kFunctionTypeArguments;
+  static const word kInstanceParentFunctionTypeArguments;
+  static const word kInstanceDelayedFunctionTypeArguments;
+  static const word kTestResult;
+};
+
+class Context : public AllStatic {
+ public:
+  static word header_size();
+  static word parent_offset();
+  static word num_variables_offset();
+  static word variable_offset(word i);
+  static word InstanceSize(word n);
+};
+
+class Closure : public AllStatic {
+ public:
+  static word context_offset();
+  static word delayed_type_arguments_offset();
+  static word function_offset();
+  static word function_type_arguments_offset();
+  static word instantiator_type_arguments_offset();
+};
+
+class HeapPage : public AllStatic {
+ public:
+  static const word kBytesPerCardLog2;
+
+  static word card_table_offset();
+};
+
+class Heap : public AllStatic {
+ public:
+  // Return true if an object with the given instance size is allocatable
+  // in new space on the target.
+  static bool IsAllocatableInNewSpace(intptr_t instance_size);
+};
+
+class NativeArguments {
+ public:
+  static word thread_offset();
+  static word argc_tag_offset();
+  static word argv_offset();
+  static word retval_offset();
+
+  static word StructSize();
+};
+
+class NativeEntry {
+ public:
+  static const word kNumCallWrapperArguments;
+};
+
+class RegExp : public AllStatic {
+ public:
+  static word function_offset(classid_t cid, bool sticky);
+};
+
+class UserTag : public AllStatic {
+ public:
+  static word tag_offset();
+};
+
+class Symbols : public AllStatic {
+ public:
+  static const word kNumberOfOneCharCodeSymbols;
+  static const word kNullCharCodeSymbolOffset;
+};
+
+}  // namespace target
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_RUNTIME_API_H_
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
new file mode 100644
index 0000000..c227889
--- /dev/null
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -0,0 +1,86 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_STUB_CODE_COMPILER_H_
+#define RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
+
+#include "vm/allocation.h"
+#include "vm/compiler/runtime_api.h"
+#include "vm/constants.h"
+#include "vm/stub_code_list.h"
+
+namespace dart {
+
+namespace compiler {
+
+// Forward declarations.
+class Assembler;
+
+class StubCodeCompiler : public AllStatic {
+ public:
+#if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
+  static void GenerateBuildMethodExtractorStub(
+      Assembler* assembler,
+      const Object& closure_allocation_stub,
+      const Object& context_allocation_stub);
+#endif
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#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 GenerateSharedStub(Assembler* assembler,
+                                 bool save_fpu_registers,
+                                 const RuntimeEntry* target,
+                                 intptr_t self_code_stub_offset_from_thread,
+                                 bool allow_return);
+
+  static void GenerateMegamorphicMissStub(Assembler* assembler);
+  static void GenerateAllocationStubForClass(Assembler* assembler,
+                                             const Class& cls);
+  static void GenerateNArgsCheckInlineCacheStub(
+      Assembler* assembler,
+      intptr_t num_args,
+      const RuntimeEntry& handle_ic_miss,
+      Token::Kind kind,
+      bool optimized = false,
+      bool exactness_check = false);
+  static void GenerateUsageCounterIncrement(Assembler* assembler,
+                                            Register temp_reg);
+  static void GenerateOptimizedUsageCounterIncrement(Assembler* assembler);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+};
+
+}  // 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;
+
+// Zap value used to indicate unused return address in deopt.
+static const uword kZapReturnAddress = 0xe1e1e1e1;
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_STUB_CODE_COMPILER_H_
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
new file mode 100644
index 0000000..fc4b9dc
--- /dev/null
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -0,0 +1,2923 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/compiler/stub_code_compiler.h"
+
+#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/class_id.h"
+#include "vm/code_entry_kind.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/locations.h"
+#include "vm/constants_arm.h"
+#include "vm/instructions.h"
+#include "vm/static_type_exactness_state.h"
+#include "vm/tags.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
+DEFINE_FLAG(bool,
+            use_slow_path,
+            false,
+            "Set to true for debugging & verifying the slow paths.");
+DECLARE_FLAG(bool, precompiled_mode);
+
+namespace compiler {
+
+// Input parameters:
+//   LR : return address.
+//   SP : address of last argument in argument array.
+//   SP + 4*R4 - 4 : address of first argument in argument array.
+//   SP + 4*R4 : address of return value.
+//   R9 : address of the runtime function to call.
+//   R4 : number of arguments to the call.
+void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ ldr(CODE_REG, Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ StoreToOffset(kWord, FP, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing VM code.
+  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+
+  // Reserve space for arguments and align frame before entering C++ world.
+  // target::NativeArguments are passed in registers.
+  ASSERT(target::NativeArguments::StructSize() == 4 * target::kWordSize);
+  __ ReserveAlignedFrameSpace(0);
+
+  // Pass target::NativeArguments structure by value and call runtime.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(thread_offset == 0 * target::kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, Operand(THR));
+
+  // There are no runtime calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * target::kWordSize);
+  __ mov(R1, Operand(R4));  // Set argc in target::NativeArguments.
+
+  ASSERT(argv_offset == 2 * target::kWordSize);
+  __ add(R2, FP, Operand(R4, LSL, 2));  // Compute argv.
+  // Set argv in target::NativeArguments.
+  __ AddImmediate(R2,
+                  target::frame_layout.param_end_from_fp * target::kWordSize);
+
+  ASSERT(retval_offset == 3 * target::kWordSize);
+  __ add(R3, R2,
+         Operand(target::kWordSize));  // Retval is next to 1st argument.
+
+  // Call runtime or redirection via simulator.
+  __ blx(R9);
+
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+  // Restore the global object pool after returning from runtime (old space is
+  // moving, so the GOP could have been relocated).
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
+  }
+
+  __ LeaveStubFrame();
+
+  // The following return can jump to a lazy-deopt stub, which assumes R0
+  // contains a return value and will save it in a GC-visible way.  We therefore
+  // have to ensure R0 does not contain any garbage value left from the C
+  // function we called (which has return type "void").
+  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
+  __ LoadImmediate(R0, 0);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateSharedStub(
+    Assembler* assembler,
+    bool save_fpu_registers,
+    const RuntimeEntry* target,
+    intptr_t self_code_stub_offset_from_thread,
+    bool allow_return) {
+  // If the target CPU does not support VFP the caller should always use the
+  // non-FPU stub.
+  if (save_fpu_registers && !TargetCPUFeatures::vfp_supported()) {
+    __ Breakpoint();
+    return;
+  }
+
+  // We want the saved registers to appear like part of the caller's frame, so
+  // we push them before calling EnterStubFrame.
+  RegisterSet all_registers;
+  all_registers.AddAllNonReservedRegisters(save_fpu_registers);
+
+  // To make the stack map calculation architecture independent we do the same
+  // as on intel.
+  __ Push(LR);
+
+  __ PushRegisters(all_registers);
+  __ ldr(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
+  __ EnterStubFrame();
+  __ CallRuntime(*target, /*argument_count=*/0);
+  if (!allow_return) {
+    __ Breakpoint();
+    return;
+  }
+  __ LeaveStubFrame();
+  __ PopRegisters(all_registers);
+  __ Pop(LR);
+  __ bx(LR);
+}
+
+// R1: The extracted method.
+// R4: The type_arguments_field_offset (or 0)
+// SP+0: The object from which we are tearing a method off.
+void StubCodeCompiler::GenerateBuildMethodExtractorStub(
+    Assembler* assembler,
+    const Object& closure_allocation_stub,
+    const Object& context_allocation_stub) {
+  const intptr_t kReceiverOffset =
+      compiler::target::frame_layout.param_end_from_fp + 1;
+
+  __ EnterStubFrame();
+
+  // Build type_arguments vector (or null)
+  __ cmp(R4, Operand(0));
+  __ ldr(R3, Address(THR, target::Thread::object_null_offset()), EQ);
+  __ ldr(R0, Address(FP, kReceiverOffset * target::kWordSize), NE);
+  __ ldr(R3, Address(R0, R4), NE);
+
+  // Push type arguments & extracted method.
+  __ PushList(1 << R3 | 1 << R1);
+
+  // Allocate context.
+  {
+    Label done, slow_path;
+    __ TryAllocateArray(kContextCid, target::Context::InstanceSize(1),
+                        &slow_path,
+                        R0,  // instance
+                        R1,  // end address
+                        R2, R3);
+    __ ldr(R1, Address(THR, target::Thread::object_null_offset()));
+    __ str(R1, FieldAddress(R0, target::Context::parent_offset()));
+    __ LoadImmediate(R1, 1);
+    __ str(R1, FieldAddress(R0, target::Context::num_variables_offset()));
+    __ b(&done);
+
+    __ Bind(&slow_path);
+
+    __ LoadImmediate(/*num_vars=*/R1, 1);
+    __ LoadObject(CODE_REG, context_allocation_stub);
+    __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+    __ blx(R0);
+
+    __ Bind(&done);
+  }
+
+  // Store receiver in context
+  __ ldr(R1, Address(FP, target::kWordSize * kReceiverOffset));
+  __ StoreIntoObject(R0, FieldAddress(R0, target::Context::variable_offset(0)),
+                     R1);
+
+  // Push context.
+  __ Push(R0);
+
+  // Allocate closure.
+  __ LoadObject(CODE_REG, closure_allocation_stub);
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                        CodeEntryKind::kUnchecked)));
+  __ blx(R1);
+
+  // Populate closure object.
+  __ Pop(R1);  // Pop context.
+  __ StoreIntoObject(R0, FieldAddress(R0, target::Closure::context_offset()),
+                     R1);
+  __ PopList(1 << R3 | 1 << R1);  // Pop type arguments & extracted method.
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::Closure::function_offset()), R1);
+  __ StoreIntoObjectNoBarrier(
+      R0,
+      FieldAddress(R0, target::Closure::instantiator_type_arguments_offset()),
+      R3);
+  __ LoadObject(R1, EmptyTypeArguments());
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::Closure::delayed_type_arguments_offset()),
+      R1);
+
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kNullErrorRuntimeEntry,
+      target::Thread::null_error_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/false);
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kNullErrorRuntimeEntry,
+      target::Thread::null_error_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/false);
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
+      target::Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/true);
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kStackOverflowRuntimeEntry,
+      target::Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/true);
+}
+
+// Input parameters:
+//   R0 : stop message (const char*).
+// Must preserve all registers.
+void StubCodeCompiler::GeneratePrintStopMessageStub(Assembler* assembler) {
+  __ EnterCallRuntimeFrame(0);
+  // Call the runtime leaf function. R0 already contains the parameter.
+  __ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ Ret();
+}
+
+// Input parameters:
+//   LR : return address.
+//   SP : address of return value.
+//   R9 : address of the native function to call.
+//   R2 : address of first argument in argument array.
+//   R1 : argc_tag including number of arguments and function kind.
+static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
+                                              Address wrapper) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ StoreToOffset(kWord, FP, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // R0) and align frame before entering the C++ world.
+  __ ReserveAlignedFrameSpace(target::NativeArguments::StructSize());
+
+  // Initialize target::NativeArguments structure and call native function.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(thread_offset == 0 * target::kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, Operand(THR));
+
+  // There are no native calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * target::kWordSize);
+  // Set argc in target::NativeArguments: R1 already contains argc.
+
+  ASSERT(argv_offset == 2 * target::kWordSize);
+  // Set argv in target::NativeArguments: R2 already contains argv.
+
+  // Set retval in NativeArgs.
+  ASSERT(retval_offset == 3 * target::kWordSize);
+  __ add(R3, FP, Operand(2 * target::kWordSize));
+
+  // Passing the structure by value as in runtime calls would require changing
+  // Dart API for native functions.
+  // For now, space is reserved on the stack and we pass a pointer to it.
+  __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
+  __ mov(R0, Operand(SP));  // Pass the pointer to the target::NativeArguments.
+
+  __ mov(R1, Operand(R9));  // Pass the function entrypoint to call.
+
+  // Call native function invocation wrapper or redirection via simulator.
+  __ ldr(LR, wrapper);
+  __ blx(LR);
+
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateCallNoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::no_scope_native_wrapper_entry_point_offset()));
+}
+
+void StubCodeCompiler::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::auto_scope_native_wrapper_entry_point_offset()));
+}
+
+// Input parameters:
+//   LR : return address.
+//   SP : address of return value.
+//   R9 : address of the native function to call.
+//   R2 : address of first argument in argument array.
+//   R1 : argc_tag including number of arguments and function kind.
+void StubCodeCompiler::GenerateCallBootstrapNativeStub(Assembler* assembler) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ StoreToOffset(kWord, FP, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // R0) and align frame before entering the C++ world.
+  __ ReserveAlignedFrameSpace(target::NativeArguments::StructSize());
+
+  // Initialize target::NativeArguments structure and call native function.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(thread_offset == 0 * target::kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, Operand(THR));
+
+  // There are no native calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * target::kWordSize);
+  // Set argc in target::NativeArguments: R1 already contains argc.
+
+  ASSERT(argv_offset == 2 * target::kWordSize);
+  // Set argv in target::NativeArguments: R2 already contains argv.
+
+  // Set retval in NativeArgs.
+  ASSERT(retval_offset == 3 * target::kWordSize);
+  __ add(R3, FP, Operand(2 * target::kWordSize));
+
+  // Passing the structure by value as in runtime calls would require changing
+  // Dart API for native functions.
+  // For now, space is reserved on the stack and we pass a pointer to it.
+  __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
+  __ mov(R0, Operand(SP));  // Pass the pointer to the target::NativeArguments.
+
+  // Call native function or redirection via simulator.
+  __ blx(R9);
+
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+// Input parameters:
+//   R4: arguments descriptor array.
+void StubCodeCompiler::GenerateCallStaticFunctionStub(Assembler* assembler) {
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value and preserve arguments descriptor.
+  __ LoadImmediate(R0, 0);
+  __ PushList((1 << R0) | (1 << R4));
+  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
+  // Get Code object result and restore arguments descriptor array.
+  __ PopList((1 << R0) | (1 << R4));
+  // Remove the stub frame.
+  __ LeaveStubFrame();
+  // Jump to the dart function.
+  __ mov(CODE_REG, Operand(R0));
+  __ Branch(FieldAddress(R0, target::Code::entry_point_offset()));
+}
+
+// Called from a static call only when an invalid code has been entered
+// (invalid because its function was optimized or deoptimized).
+// R4: arguments descriptor array.
+void StubCodeCompiler::GenerateFixCallersTargetStub(Assembler* assembler) {
+  // Load code pointer to this stub from the thread:
+  // The one that is passed in, is not correct - it points to the code object
+  // that needs to be replaced.
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::fix_callers_target_code_offset()));
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value and preserve arguments descriptor.
+  __ LoadImmediate(R0, 0);
+  __ PushList((1 << R0) | (1 << R4));
+  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
+  // Get Code object result and restore arguments descriptor array.
+  __ PopList((1 << R0) | (1 << R4));
+  // Remove the stub frame.
+  __ LeaveStubFrame();
+  // Jump to the dart function.
+  __ mov(CODE_REG, Operand(R0));
+  __ Branch(FieldAddress(R0, target::Code::entry_point_offset()));
+}
+
+// Called from object allocate instruction when the allocation stub has been
+// disabled.
+void StubCodeCompiler::GenerateFixAllocationStubTargetStub(
+    Assembler* assembler) {
+  // Load code pointer to this stub from the thread:
+  // The one that is passed in, is not correct - it points to the code object
+  // that needs to be replaced.
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::fix_allocation_stub_code_offset()));
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  __ LoadImmediate(R0, 0);
+  __ Push(R0);
+  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
+  // Get Code object result.
+  __ Pop(R0);
+  // Remove the stub frame.
+  __ LeaveStubFrame();
+  // Jump to the dart function.
+  __ mov(CODE_REG, Operand(R0));
+  __ Branch(FieldAddress(R0, target::Code::entry_point_offset()));
+}
+
+// Input parameters:
+//   R2: smi-tagged argument count, may be zero.
+//   FP[target::frame_layout.param_end_from_fp + 1]: last argument.
+static void PushArrayOfArguments(Assembler* assembler) {
+  // Allocate array to store arguments of caller.
+  __ LoadObject(R1, NullObject());
+  // R1: null element type for raw Array.
+  // R2: smi-tagged argument count, may be zero.
+  __ BranchLink(StubCodeAllocateArray());
+  // R0: newly allocated array.
+  // R2: smi-tagged argument count, may be zero (was preserved by the stub).
+  __ Push(R0);  // Array is in R0 and on top of stack.
+  __ AddImmediate(R1, FP,
+                  target::frame_layout.param_end_from_fp * target::kWordSize);
+  __ AddImmediate(R3, R0, target::Array::data_offset() - kHeapObjectTag);
+  // Copy arguments from stack to array (starting at the end).
+  // R1: address just beyond last argument on stack.
+  // R3: address of first argument in array.
+  Label enter;
+  __ b(&enter);
+  Label loop;
+  __ Bind(&loop);
+  __ ldr(R8, Address(R1, target::kWordSize, Address::PreIndex));
+  // Generational barrier is needed, array is not necessarily in new space.
+  __ StoreIntoObject(R0, Address(R3, R2, LSL, 1), R8);
+  __ Bind(&enter);
+  __ subs(R2, R2, Operand(target::ToRawSmi(1)));  // R2 is Smi.
+  __ b(&loop, PL);
+}
+
+// Used by eager and lazy deoptimization. Preserve result in R0 if necessary.
+// This stub translates optimized frame into unoptimized frame. The optimized
+// frame can contain values in registers and on stack, the unoptimized
+// frame contains all values on stack.
+// Deoptimization occurs in following steps:
+// - Push all registers that can contain values.
+// - Call C routine to copy the stack and saved registers into temporary buffer.
+// - Adjust caller's frame to correct unoptimized frame size.
+// - Fill the unoptimized frame.
+// - Materialize objects that require allocation (e.g. Double instances).
+// GC can occur only after frame is fully rewritten.
+// Stack after EnterFrame(...) below:
+//   +------------------+
+//   | Saved PP         | <- TOS
+//   +------------------+
+//   | Saved FP         | <- FP of stub
+//   +------------------+
+//   | Saved LR         |  (deoptimization point)
+//   +------------------+
+//   | pc marker        |
+//   +------------------+
+//   | Saved CODE_REG   |
+//   +------------------+
+//   | ...              | <- SP of optimized frame
+//
+// Parts of the code cannot GC, part of the code can GC.
+static void GenerateDeoptimizationSequence(Assembler* assembler,
+                                           DeoptStubKind kind) {
+  // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+  // is no need to set the correct PC marker or load PP, since they get patched.
+  __ EnterDartFrame(0);
+  __ LoadPoolPointer();
+
+  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
+  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
+  const intptr_t saved_result_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - R0);
+  const intptr_t saved_exception_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - R0);
+  const intptr_t saved_stacktrace_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - R1);
+  // Result in R0 is preserved as part of pushing all registers below.
+
+  // Push registers in their enumeration order: lowest register number at
+  // lowest address.
+  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
+    if (i == CODE_REG) {
+      // Save the original value of CODE_REG pushed before invoking this stub
+      // instead of the value used to call this stub.
+      __ ldr(IP, Address(FP, 2 * target::kWordSize));
+      __ Push(IP);
+    } else if (i == SP) {
+      // Push(SP) has unpredictable behavior.
+      __ mov(IP, Operand(SP));
+      __ Push(IP);
+    } else {
+      __ Push(static_cast<Register>(i));
+    }
+  }
+
+  if (TargetCPUFeatures::vfp_supported()) {
+    ASSERT(kFpuRegisterSize == 4 * target::kWordSize);
+    if (kNumberOfDRegisters > 16) {
+      __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16);
+      __ vstmd(DB_W, SP, D0, 16);
+    } else {
+      __ vstmd(DB_W, SP, D0, kNumberOfDRegisters);
+    }
+  } else {
+    __ AddImmediate(SP, -kNumberOfFpuRegisters * kFpuRegisterSize);
+  }
+
+  __ mov(R0, Operand(SP));  // Pass address of saved registers block.
+  bool is_lazy =
+      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
+  __ mov(R1, Operand(is_lazy ? 1 : 0));
+  __ ReserveAlignedFrameSpace(0);
+  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
+  // Result (R0) is stack-size (FP - SP) in bytes.
+
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into R1 temporarily.
+    __ ldr(R1, Address(FP, saved_result_slot_from_fp * target::kWordSize));
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into R1 temporarily.
+    __ ldr(R1, Address(FP, saved_exception_slot_from_fp * target::kWordSize));
+    __ ldr(R2, Address(FP, saved_stacktrace_slot_from_fp * target::kWordSize));
+  }
+
+  __ RestoreCodePointer();
+  __ LeaveDartFrame();
+  __ sub(SP, FP, Operand(R0));
+
+  // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+  // is no need to set the correct PC marker or load PP, since they get patched.
+  __ EnterStubFrame();
+  __ mov(R0, Operand(FP));  // Get last FP address.
+  if (kind == kLazyDeoptFromReturn) {
+    __ Push(R1);  // Preserve result as first local.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ Push(R1);  // Preserve exception as first local.
+    __ Push(R2);  // Preserve stacktrace as second local.
+  }
+  __ ReserveAlignedFrameSpace(0);
+  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);  // Pass last FP in R0.
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into R1.
+    __ ldr(R1, Address(FP, compiler::target::frame_layout.first_local_from_fp *
+                               target::kWordSize));
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into R1.
+    __ ldr(R1, Address(FP, compiler::target::frame_layout.first_local_from_fp *
+                               target::kWordSize));
+    __ ldr(R2, Address(FP, (compiler::target::frame_layout.first_local_from_fp -
+                            1) *
+                               target::kWordSize));
+  }
+  // Code above cannot cause GC.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+
+  // Frame is fully rewritten at this point and it is safe to perform a GC.
+  // Materialize any objects that were deferred by FillFrame because they
+  // require allocation.
+  // Enter stub frame with loading PP. The caller's PP is not materialized yet.
+  __ EnterStubFrame();
+  if (kind == kLazyDeoptFromReturn) {
+    __ Push(R1);  // Preserve result, it will be GC-d here.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ Push(R1);  // Preserve exception, it will be GC-d here.
+    __ Push(R2);  // Preserve stacktrace, it will be GC-d here.
+  }
+  __ PushObject(NullObject());  // Space for the result.
+  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
+  // Result tells stub how many bytes to remove from the expression stack
+  // of the bottom-most frame. They were used as materialization arguments.
+  __ Pop(R2);
+  if (kind == kLazyDeoptFromReturn) {
+    __ Pop(R0);  // Restore result.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ Pop(R1);  // Restore stacktrace.
+    __ Pop(R0);  // Restore exception.
+  }
+  __ LeaveStubFrame();
+  // Remove materialization arguments.
+  __ add(SP, SP, Operand(R2, ASR, kSmiTagSize));
+  // The caller is responsible for emitting the return instruction.
+}
+
+// R0: result, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromReturnStub(
+    Assembler* assembler) {
+  // Push zap value instead of CODE_REG for lazy deopt.
+  __ LoadImmediate(IP, kZapCodeReg);
+  __ Push(IP);
+  // Return address for "call" to deopt stub.
+  __ LoadImmediate(LR, kZapReturnAddress);
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::lazy_deopt_from_return_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
+  __ Ret();
+}
+
+// R0: exception, must be preserved
+// R1: stacktrace, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromThrowStub(
+    Assembler* assembler) {
+  // Push zap value instead of CODE_REG for lazy deopt.
+  __ LoadImmediate(IP, kZapCodeReg);
+  __ Push(IP);
+  // Return address for "call" to deopt stub.
+  __ LoadImmediate(LR, kZapReturnAddress);
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::lazy_deopt_from_throw_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateDeoptimizeStub(Assembler* assembler) {
+  __ Push(CODE_REG);
+  __ ldr(CODE_REG, Address(THR, target::Thread::deoptimize_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+  __ 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);
+  __ EnterStubFrame();
+  // Load the receiver.
+  __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
+  __ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
+                             target::kWordSize));
+  __ LoadImmediate(IP, 0);
+  __ Push(IP);  // Result slot.
+  __ Push(R8);  // Receiver.
+  __ Push(R9);  // ICData/MegamorphicCache.
+  __ Push(R4);  // Arguments descriptor.
+
+  // Adjust arguments count.
+  __ ldr(R3,
+         FieldAddress(R4, target::ArgumentsDescriptor::type_args_len_offset()));
+  __ cmp(R3, Operand(0));
+  __ AddImmediate(R2, R2, target::ToRawSmi(1),
+                  NE);  // Include the type arguments.
+
+  // R2: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+  const intptr_t kNumArgs = 4;
+  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+  __ Drop(4);
+  __ Pop(R0);  // Return value.
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
+  __ ldr(R8, Address(IP, compiler::target::frame_layout.param_end_from_fp *
+                             target::kWordSize));
+
+  // 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()));
+}
+
+// Called for inline allocation of arrays.
+// Input parameters:
+//   LR: return address.
+//   R1: array element type (either NULL or an instantiated type).
+//   R2: array length as Smi (must be preserved).
+// The newly allocated object is returned in R0.
+void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
+  Label slow_case;
+  // Compute the size to be allocated, it is based on the array length
+  // and is computed as:
+  // RoundedAllocationSize(
+  //     (array_length * kwordSize) + target::Array::header_size()).
+  __ mov(R3, Operand(R2));  // Array length.
+  // Check that length is a positive Smi.
+  __ tst(R3, Operand(kSmiTagMask));
+  if (FLAG_use_slow_path) {
+    __ b(&slow_case);
+  } else {
+    __ b(&slow_case, NE);
+  }
+  __ cmp(R3, Operand(0));
+  __ b(&slow_case, LT);
+
+  // Check for maximum allowed length.
+  const intptr_t max_len =
+      target::ToRawSmi(target::Array::kMaxNewSpaceElements);
+  __ CompareImmediate(R3, max_len);
+  __ b(&slow_case, GT);
+
+  const intptr_t cid = kArrayCid;
+  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R4, &slow_case));
+
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
+      1;
+  __ LoadImmediate(R9, fixed_size_plus_alignment_padding);
+  __ add(R9, R9, Operand(R3, LSL, 1));  // R3 is a Smi.
+  ASSERT(kSmiTagShift == 1);
+  __ bic(R9, R9, Operand(target::ObjectAlignment::kObjectAlignment - 1));
+
+  // R9: Allocation size.
+  // Potential new object start.
+  __ ldr(R0, Address(THR, target::Thread::top_offset()));
+  __ adds(NOTFP, R0, Operand(R9));  // Potential next object start.
+  __ b(&slow_case, CS);             // Branch if unsigned overflow.
+
+  // Check if the allocation fits into the remaining space.
+  // R0: potential new object start.
+  // NOTFP: potential next object start.
+  // R9: allocation size.
+  __ ldr(R3, Address(THR, target::Thread::end_offset()));
+  __ cmp(NOTFP, Operand(R3));
+  __ b(&slow_case, CS);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R3, cid));
+  __ str(NOTFP, Address(THR, target::Thread::top_offset()));
+  __ add(R0, R0, Operand(kHeapObjectTag));
+
+  // Initialize the tags.
+  // R0: new object start as a tagged pointer.
+  // R3: allocation stats address.
+  // NOTFP: new object end address.
+  // R9: allocation size.
+  {
+    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2;
+
+    __ CompareImmediate(R9, target::RawObject::kSizeTagMaxSizeTag);
+    __ mov(R8, Operand(R9, LSL, shift), LS);
+    __ mov(R8, Operand(0), HI);
+
+    // Get the class index and insert it into the tags.
+    // R8: size and bit tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+    __ LoadImmediate(TMP, tags);
+    __ orr(R8, R8, Operand(TMP));
+    __ str(R8, FieldAddress(R0, target::Array::tags_offset()));  // Store tags.
+  }
+
+  // R0: new object start as a tagged pointer.
+  // NOTFP: new object end address.
+  // Store the type argument field.
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::Array::type_arguments_offset()), R1);
+
+  // Set the length field.
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::Array::length_offset()), R2);
+
+  // Initialize all array elements to raw_null.
+  // R0: new object start as a tagged pointer.
+  // R3: allocation stats address.
+  // R8, R9: null
+  // R4: iterator which initially points to the start of the variable
+  // data area to be initialized.
+  // NOTFP: new object end address.
+  // R9: allocation size.
+  NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R3, R9));
+
+  __ LoadObject(R8, NullObject());
+  __ mov(R9, Operand(R8));
+  __ AddImmediate(R4, R0, target::Array::header_size() - kHeapObjectTag);
+  __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9);
+  __ Ret();  // Returns the newly allocated object in R0.
+  // Unable to allocate the array using the fast inline code, just call
+  // into the runtime.
+  __ Bind(&slow_case);
+
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ LoadImmediate(IP, 0);
+  // Setup space on stack for return value.
+  // Push array length as Smi and element type.
+  __ PushList((1 << R1) | (1 << R2) | (1 << IP));
+  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
+  // Pop arguments; result is popped in IP.
+  __ PopList((1 << R1) | (1 << R2) | (1 << IP));  // R2 is restored.
+  __ mov(R0, Operand(IP));
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+// Called when invoking Dart code from C++ (VM code).
+// Input parameters:
+//   LR : points to return address.
+//   R0 : code object of the Dart function to call.
+//   R1 : arguments descriptor array.
+//   R2 : arguments array.
+//   R3 : current thread.
+void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) {
+  __ Push(LR);  // Marker for the profiler.
+  __ EnterFrame((1 << FP) | (1 << LR), 0);
+
+  // Push code object to PC marker slot.
+  __ ldr(IP, Address(R3, target::Thread::invoke_dart_code_stub_offset()));
+  __ Push(IP);
+
+  // Save new context and C++ ABI callee-saved registers.
+  __ PushList(kAbiPreservedCpuRegs);
+
+  const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
+  if (TargetCPUFeatures::vfp_supported()) {
+    ASSERT(2 * kAbiPreservedFpuRegCount < 16);
+    // Save FPU registers. 2 D registers per Q register.
+    __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
+  } else {
+    __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize));
+  }
+
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != R3) {
+    __ mov(THR, Operand(R3));
+  }
+
+  // Save the current VMTag on the stack.
+  __ LoadFromOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+  __ Push(R9);
+
+  // Save top resource and top exit frame info. Use R4-6 as temporary registers.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ LoadFromOffset(kWord, R9, THR,
+                    target::Thread::top_exit_frame_info_offset());
+  __ LoadFromOffset(kWord, R4, THR, target::Thread::top_resource_offset());
+  __ LoadImmediate(R8, 0);
+  __ StoreToOffset(kWord, R8, THR, target::Thread::top_resource_offset());
+  __ StoreToOffset(kWord, R8, THR,
+                   target::Thread::top_exit_frame_info_offset());
+
+  // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
+  // with the code below.
+  __ Push(R4);
+#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -26);
+#else
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -27);
+#endif
+  __ Push(R9);
+
+  // Mark that the thread is executing Dart code. Do this after initializing the
+  // exit link for the profiler.
+  __ LoadImmediate(R9, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset());
+
+  // Load arguments descriptor array into R4, which is passed to Dart code.
+  __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
+
+  // Load number of arguments into R9 and adjust count for type arguments.
+  __ ldr(R3,
+         FieldAddress(R4, target::ArgumentsDescriptor::type_args_len_offset()));
+  __ ldr(R9, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+  __ cmp(R3, Operand(0));
+  __ AddImmediate(R9, R9, target::ToRawSmi(1),
+                  NE);  // Include the type arguments.
+  __ SmiUntag(R9);
+
+  // Compute address of 'arguments array' data area into R2.
+  __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle));
+  __ AddImmediate(R2, target::Array::data_offset() - kHeapObjectTag);
+
+  // Set up arguments for the Dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+  __ CompareImmediate(R9, 0);  // check if there are arguments.
+  __ b(&done_push_arguments, EQ);
+  __ LoadImmediate(R1, 0);
+  __ Bind(&push_arguments);
+  __ ldr(R3, Address(R2));
+  __ Push(R3);
+  __ AddImmediate(R2, target::kWordSize);
+  __ AddImmediate(R1, 1);
+  __ cmp(R1, Operand(R9));
+  __ b(&push_arguments, LT);
+  __ Bind(&done_push_arguments);
+
+  // Call the Dart code entrypoint.
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
+  } else {
+    __ LoadImmediate(PP, 0);  // GC safe value into PP.
+  }
+  __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
+  __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ blx(R0);  // R4 is the arguments descriptor array.
+
+  // Get rid of arguments pushed on the stack.
+  __ AddImmediate(
+      SP, FP,
+      target::frame_layout.exit_link_slot_from_entry_fp * target::kWordSize);
+
+  // Restore the saved top exit frame info and top resource back into the
+  // Isolate structure. Uses R9 as a temporary register for this.
+  __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR,
+                   target::Thread::top_exit_frame_info_offset());
+  __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, target::Thread::top_resource_offset());
+
+  // Restore the current VMTag from the stack.
+  __ Pop(R4);
+  __ StoreToOffset(kWord, R4, THR, target::Thread::vm_tag_offset());
+
+  // Restore C++ ABI callee-saved registers.
+  if (TargetCPUFeatures::vfp_supported()) {
+    // Restore FPU registers. 2 D registers per Q register.
+    __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
+  } else {
+    __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize);
+  }
+  // Restore CPU registers.
+  __ PopList(kAbiPreservedCpuRegs);
+  __ set_constant_pool_allowed(false);
+
+  // Restore the frame pointer and return.
+  __ LeaveFrame((1 << FP) | (1 << LR));
+  __ Drop(1);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
+    Assembler* assembler) {
+  __ Unimplemented("Interpreter not yet supported");
+}
+
+// Called for inline allocation of contexts.
+// Input:
+//   R1: number of context variables.
+// Output:
+//   R0: new allocated RawContext object.
+void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
+  if (FLAG_inline_alloc) {
+    Label slow_case;
+    // First compute the rounded instance size.
+    // R1: number of context variables.
+    intptr_t fixed_size_plus_alignment_padding =
+        target::Context::header_size() +
+        target::ObjectAlignment::kObjectAlignment - 1;
+    __ LoadImmediate(R2, fixed_size_plus_alignment_padding);
+    __ add(R2, R2, Operand(R1, LSL, 2));
+    ASSERT(kSmiTagShift == 1);
+    __ bic(R2, R2, Operand(target::ObjectAlignment::kObjectAlignment - 1));
+
+    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R8, kContextCid));
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(R8, &slow_case));
+    // Now allocate the object.
+    // R1: number of context variables.
+    // R2: object size.
+    const intptr_t cid = kContextCid;
+    __ ldr(R0, Address(THR, target::Thread::top_offset()));
+    __ add(R3, R2, Operand(R0));
+    // Check if the allocation fits into the remaining space.
+    // R0: potential new object.
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: potential next object start.
+    __ ldr(IP, Address(THR, target::Thread::end_offset()));
+    __ cmp(R3, Operand(IP));
+    if (FLAG_use_slow_path) {
+      __ b(&slow_case);
+    } else {
+      __ b(&slow_case, CS);  // Branch if unsigned higher or equal.
+    }
+
+    // Successfully allocated the object, now update top to point to
+    // next object start and initialize the object.
+    // R0: new object start (untagged).
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: next object start.
+    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
+    __ str(R3, Address(THR, target::Thread::top_offset()));
+    __ add(R0, R0, Operand(kHeapObjectTag));
+
+    // Calculate the size tag.
+    // R0: new object (tagged).
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: next object start.
+    // R4: allocation stats address.
+    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2;
+    __ CompareImmediate(R2, target::RawObject::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);
+
+    // Get the class index and insert it into the tags.
+    // R9: size and bit tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+
+    __ LoadImmediate(IP, tags);
+    __ orr(R9, R9, Operand(IP));
+    __ str(R9, FieldAddress(R0, target::Object::tags_offset()));
+
+    // Setup up number of context variables field.
+    // R0: new object.
+    // R1: number of context variables as integer value (not object).
+    // R2: object size.
+    // R3: next object start.
+    // R4: allocation stats address.
+    __ str(R1, FieldAddress(R0, target::Context::num_variables_offset()));
+
+    // Setup the parent field.
+    // R0: new object.
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: next object start.
+    // R4: allocation stats address.
+    __ LoadObject(R8, NullObject());
+    __ StoreIntoObjectNoBarrier(
+        R0, FieldAddress(R0, target::Context::parent_offset()), R8);
+
+    // Initialize the context variables.
+    // R0: new object.
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: next object start.
+    // R8, R9: raw null.
+    // R4: allocation stats address.
+    Label loop;
+    __ AddImmediate(NOTFP, R0,
+                    target::Context::variable_offset(0) - kHeapObjectTag);
+    __ InitializeFieldsNoBarrier(R0, NOTFP, R3, R8, R9);
+    NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2));
+
+    // Done allocating and initializing the context.
+    // R0: new object.
+    __ Ret();
+
+    __ Bind(&slow_case);
+  }
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  __ LoadImmediate(R2, 0);
+  __ SmiTag(R1);
+  __ PushList((1 << R1) | (1 << R2));
+  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
+  __ Drop(1);  // Pop number of context variables argument.
+  __ Pop(R0);  // Pop the new context object.
+  // R0: new object
+  // Restore the frame pointer.
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
+  RegList saved = (1 << LR) | (1 << kWriteBarrierObjectReg);
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+    if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
+
+    Register reg = static_cast<Register>(i);
+    intptr_t start = __ CodeSize();
+    __ PushList(saved);
+    __ mov(kWriteBarrierObjectReg, Operand(reg));
+    __ ldr(LR,
+           Address(THR, target::Thread::write_barrier_entry_point_offset()));
+    __ blx(LR);
+    __ PopList(saved);
+    __ bx(LR);
+    intptr_t end = __ CodeSize();
+
+    RELEASE_ASSERT(end - start == kStoreBufferWrapperSize);
+  }
+}
+
+// Helper stub to implement Assembler::StoreIntoObject.
+// Input parameters:
+//   R1: Object (old)
+//   R0: Value (old or new)
+//   R9: Slot
+// If R0 is new, add R1 to the store buffer. Otherwise R0 is old, mark R0
+// and add it to the mark list.
+COMPILE_ASSERT(kWriteBarrierObjectReg == R1);
+COMPILE_ASSERT(kWriteBarrierValueReg == R0);
+COMPILE_ASSERT(kWriteBarrierSlotReg == R9);
+static void GenerateWriteBarrierStubHelper(Assembler* assembler,
+                                           Address stub_code,
+                                           bool cards) {
+  Label add_to_mark_stack, remember_card;
+  __ tst(R0, Operand(1 << target::ObjectAlignment::kNewObjectBitPosition));
+  __ b(&add_to_mark_stack, ZERO);
+
+  if (cards) {
+    __ ldr(TMP, FieldAddress(R1, target::Object::tags_offset()));
+    __ tst(TMP, Operand(1 << target::RawObject::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));
+    __ b(&ok, ZERO);
+    __ Stop("Wrong barrier");
+    __ Bind(&ok);
+#endif
+  }
+
+  // Save values being destroyed.
+  __ PushList((1 << R2) | (1 << R3) | (1 << R4));
+
+  if (TargetCPUFeatures::arm_version() == ARMv5TE) {
+// TODO(21263): Implement 'swp' and use it below.
+#if !defined(USING_SIMULATOR)
+    ASSERT(OS::NumberOfAvailableProcessors() <= 1);
+#endif
+    __ ldr(R2, FieldAddress(R1, target::Object::tags_offset()));
+    __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotRememberedBit));
+    __ str(R2, FieldAddress(R1, target::Object::tags_offset()));
+  } else {
+    // Atomically set the remembered bit of the object header.
+    ASSERT(target::Object::tags_offset() == 0);
+    __ sub(R3, R1, Operand(kHeapObjectTag));
+    // R3: Untagged address of header word (ldrex/strex do not support offsets).
+    Label retry;
+    __ Bind(&retry);
+    __ ldrex(R2, R3);
+    __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotRememberedBit));
+    __ strex(R4, R2, R3);
+    __ cmp(R4, Operand(1));
+    __ b(&retry, EQ);
+  }
+
+  // Load the StoreBuffer block out of the thread. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
+  __ ldr(R4, Address(THR, target::Thread::store_buffer_block_offset()));
+  __ ldr(R2, Address(R4, target::StoreBufferBlock::top_offset()));
+  __ add(R3, R4, Operand(R2, LSL, target::kWordSizeLog2));
+  __ str(R1, Address(R3, target::StoreBufferBlock::pointers_offset()));
+
+  // Increment top_ and check for overflow.
+  // R2: top_.
+  // R4: StoreBufferBlock.
+  Label overflow;
+  __ add(R2, R2, Operand(1));
+  __ str(R2, Address(R4, target::StoreBufferBlock::top_offset()));
+  __ CompareImmediate(R2, target::StoreBufferBlock::kSize);
+  // Restore values.
+  __ PopList((1 << R2) | (1 << R3) | (1 << R4));
+  __ b(&overflow, EQ);
+  __ Ret();
+
+  // Handle overflow: Call the runtime leaf function.
+  __ Bind(&overflow);
+  // Setup frame, push callee-saved registers.
+
+  __ Push(CODE_REG);
+  __ ldr(CODE_REG, stub_code);
+  __ EnterCallRuntimeFrame(0 * target::kWordSize);
+  __ mov(R0, Operand(THR));
+  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
+  // Restore callee-saved registers, tear down frame.
+  __ LeaveCallRuntimeFrame();
+  __ Pop(CODE_REG);
+  __ Ret();
+
+  __ Bind(&add_to_mark_stack);
+  __ PushList((1 << R2) | (1 << R3) | (1 << R4));  // Spill.
+
+  Label marking_retry, lost_race, marking_overflow;
+  if (TargetCPUFeatures::arm_version() == ARMv5TE) {
+// TODO(21263): Implement 'swp' and use it below.
+#if !defined(USING_SIMULATOR)
+    ASSERT(OS::NumberOfAvailableProcessors() <= 1);
+#endif
+    __ ldr(R2, FieldAddress(R0, target::Object::tags_offset()));
+    __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotMarkedBit));
+    __ str(R2, FieldAddress(R0, target::Object::tags_offset()));
+  } else {
+    // Atomically clear kOldAndNotMarkedBit.
+    ASSERT(target::Object::tags_offset() == 0);
+    __ sub(R3, R0, Operand(kHeapObjectTag));
+    // 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));
+    __ b(&lost_race, ZERO);
+    __ bic(R2, R2, Operand(1 << target::RawObject::kOldAndNotMarkedBit));
+    __ strex(R4, R2, R3);
+    __ cmp(R4, Operand(1));
+    __ b(&marking_retry, EQ);
+  }
+
+  __ ldr(R4, Address(THR, target::Thread::marking_stack_block_offset()));
+  __ ldr(R2, Address(R4, target::MarkingStackBlock::top_offset()));
+  __ add(R3, R4, Operand(R2, LSL, target::kWordSizeLog2));
+  __ str(R0, Address(R3, target::MarkingStackBlock::pointers_offset()));
+  __ add(R2, R2, Operand(1));
+  __ str(R2, Address(R4, target::MarkingStackBlock::top_offset()));
+  __ CompareImmediate(R2, target::MarkingStackBlock::kSize);
+  __ PopList((1 << R4) | (1 << R2) | (1 << R3));  // Unspill.
+  __ b(&marking_overflow, EQ);
+  __ Ret();
+
+  __ Bind(&marking_overflow);
+  __ Push(CODE_REG);
+  __ ldr(CODE_REG, stub_code);
+  __ EnterCallRuntimeFrame(0 * target::kWordSize);
+  __ mov(R0, Operand(THR));
+  __ CallRuntime(kMarkingStackBlockProcessRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ Pop(CODE_REG);
+  __ Ret();
+
+  __ Bind(&lost_race);
+  __ PopList((1 << R2) | (1 << R3) | (1 << R4));  // Unspill.
+  __ Ret();
+
+  if (cards) {
+    Label remember_card_slow;
+
+    // Get card table.
+    __ Bind(&remember_card);
+    __ AndImmediate(TMP, R1, target::kPageMask);  // HeapPage.
+    __ ldr(TMP,
+           Address(TMP, target::HeapPage::card_table_offset()));  // Card table.
+    __ cmp(TMP, Operand(0));
+    __ b(&remember_card_slow, EQ);
+
+    // Dirty the card.
+    __ AndImmediate(TMP, R1, target::kPageMask);  // HeapPage.
+    __ sub(R9, R9, Operand(TMP));                 // Offset in page.
+    __ ldr(TMP,
+           Address(TMP, target::HeapPage::card_table_offset()));  // Card table.
+    __ add(TMP, TMP,
+           Operand(R9, LSR,
+                   target::HeapPage::kBytesPerCardLog2));  // Card address.
+    __ strb(R1,
+            Address(TMP, 0));  // Low byte of R0 is non-zero from object tag.
+    __ Ret();
+
+    // Card table not yet allocated.
+    __ Bind(&remember_card_slow);
+    __ Push(CODE_REG);
+    __ Push(R0);
+    __ Push(R1);
+    __ ldr(CODE_REG, stub_code);
+    __ mov(R0, Operand(R1));  // Arg0 = Object
+    __ mov(R1, Operand(R9));  // Arg1 = Slot
+    __ EnterCallRuntimeFrame(0);
+    __ CallRuntime(kRememberCardRuntimeEntry, 2);
+    __ LeaveCallRuntimeFrame();
+    __ Pop(R1);
+    __ Pop(R0);
+    __ Pop(CODE_REG);
+    __ Ret();
+  }
+}
+
+void StubCodeCompiler::GenerateWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler, Address(THR, target::Thread::write_barrier_code_offset()),
+      false);
+}
+
+void StubCodeCompiler::GenerateArrayWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler,
+      Address(THR, target::Thread::array_write_barrier_code_offset()), true);
+}
+
+// Called for inline allocation of objects.
+// Input parameters:
+//   LR : return address.
+//   SP + 0 : 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);
+
+  const Register kNullReg = R8;
+  const Register kOtherNullReg = R9;
+  const Register kTypeArgumentsReg = R3;
+  const Register kInstanceReg = R0;
+  const Register kEndReg = R1;
+  const Register kEndOfInstanceReg = R2;
+
+  // 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::InstanceSize(cls);
+  ASSERT(instance_size > 0);
+  ASSERT(instance_size % target::ObjectAlignment::kObjectAlignment == 0);
+  if (is_cls_parameterized) {
+    __ ldr(kTypeArgumentsReg, Address(SP, 0));
+  }
+
+  __ LoadObject(kNullReg, NullObject());
+  if (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));
+    if (FLAG_use_slow_path) {
+      __ b(&slow_case);
+    } else {
+      __ b(&slow_case, CS);  // Unsigned higher or equal.
+    }
+    __ str(kEndOfInstanceReg, Address(THR, target::Thread::top_offset()));
+
+    // Load the address of the allocation stats table. We split up the load
+    // and the increment so that the dependent load is not too nearby.
+    NOT_IN_PRODUCT(static Register kAllocationStatsReg = R4);
+    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(kAllocationStatsReg,
+                                                 target::Class::GetId(cls)));
+
+    // 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);
+    }
+    if (is_cls_parameterized) {
+      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
+      __ StoreIntoObjectNoBarrier(
+          kInstanceReg, FieldAddress(kInstanceReg, offset), kTypeArgumentsReg);
+    }
+
+    // Update allocation stats.
+    NOT_IN_PRODUCT(__ IncrementAllocationStats(kAllocationStatsReg,
+                                               target::Class::GetId(cls)));
+
+    __ Ret();
+    __ Bind(&slow_case);
+  }
+  // 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).
+  __ LeaveDartFrameAndReturn();         // Restores correct SP.
+}
+
+// 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.
+// Input parameters:
+//  LR : return address.
+//  SP : address of last argument.
+//  R4: arguments descriptor array.
+void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub(
+    Assembler* assembler) {
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ ldr(R2, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
+  __ ldr(R8, Address(IP, target::frame_layout.param_end_from_fp *
+                             target::kWordSize));
+
+  // Push space for the return value.
+  // Push the receiver.
+  // Push arguments descriptor array.
+  __ LoadImmediate(IP, 0);
+  __ PushList((1 << R4) | (1 << R8) | (1 << IP));
+
+  // Adjust arguments count.
+  __ ldr(R3,
+         FieldAddress(R4, target::ArgumentsDescriptor::type_args_len_offset()));
+  __ cmp(R3, Operand(0));
+  __ AddImmediate(R2, R2, target::ToRawSmi(1),
+                  NE);  // Include the type arguments.
+
+  // R2: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+
+  const intptr_t kNumArgs = 3;
+  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+  // noSuchMethod on closures always throws an error, so it will never return.
+  __ bkpt(0);
+}
+
+//  R8: function object.
+//  R9: inline cache data object.
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
+void StubCodeCompiler::GenerateOptimizedUsageCounterIncrement(
+    Assembler* assembler) {
+  Register ic_reg = R9;
+  Register func_reg = R8;
+  if (FLAG_trace_optimized_ic_calls) {
+    __ EnterStubFrame();
+    __ PushList((1 << R9) | (1 << R8));  // Preserve.
+    __ Push(ic_reg);                     // Argument.
+    __ Push(func_reg);                   // Argument.
+    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
+    __ Drop(2);                         // Discard argument;
+    __ PopList((1 << R9) | (1 << R8));  // Restore.
+    __ LeaveStubFrame();
+  }
+  __ ldr(NOTFP,
+         FieldAddress(func_reg, target::Function::usage_counter_offset()));
+  __ add(NOTFP, NOTFP, Operand(1));
+  __ str(NOTFP,
+         FieldAddress(func_reg, target::Function::usage_counter_offset()));
+}
+
+// Loads function into 'temp_reg'.
+void StubCodeCompiler::GenerateUsageCounterIncrement(Assembler* assembler,
+                                                     Register temp_reg) {
+  if (FLAG_optimization_counter_threshold >= 0) {
+    Register ic_reg = R9;
+    Register func_reg = temp_reg;
+    ASSERT(temp_reg == R8);
+    __ Comment("Increment function counter");
+    __ ldr(func_reg, FieldAddress(ic_reg, target::ICData::owner_offset()));
+    __ ldr(NOTFP,
+           FieldAddress(func_reg, target::Function::usage_counter_offset()));
+    __ add(NOTFP, NOTFP, Operand(1));
+    __ str(NOTFP,
+           FieldAddress(func_reg, target::Function::usage_counter_offset()));
+  }
+}
+
+// Note: R9 must be preserved.
+// Attempt a quick Smi operation for known operations ('kind'). The ICData
+// must have been primed with a Smi/Smi check that will be used for counting
+// the invocations.
+static void EmitFastSmiOp(Assembler* assembler,
+                          Token::Kind kind,
+                          intptr_t num_args,
+                          Label* not_smi_or_overflow) {
+  __ Comment("Fast Smi op");
+  __ ldr(R0, Address(SP, 0 * target::kWordSize));
+  __ ldr(R1, Address(SP, 1 * target::kWordSize));
+  __ orr(TMP, R0, Operand(R1));
+  __ tst(TMP, Operand(kSmiTagMask));
+  __ b(not_smi_or_overflow, NE);
+  switch (kind) {
+    case Token::kADD: {
+      __ adds(R0, R1, Operand(R0));   // Adds.
+      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
+      break;
+    }
+    case Token::kSUB: {
+      __ subs(R0, R1, Operand(R0));   // Subtract.
+      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
+      break;
+    }
+    case Token::kEQ: {
+      __ cmp(R0, Operand(R1));
+      __ LoadObject(R0, CastHandle<Object>(TrueObject()), EQ);
+      __ LoadObject(R0, CastHandle<Object>(FalseObject()), NE);
+      break;
+    }
+    default:
+      UNIMPLEMENTED();
+  }
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, target::ICData::entries_offset()));
+  // R8: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
+// R8: points directly to the first ic data array element.
+#if defined(DEBUG)
+  // Check that first entry is for Smi/Smi.
+  Label error, ok;
+  const intptr_t imm_smi_cid = target::ToRawSmi(kSmiCid);
+  __ ldr(R1, Address(R8, 0));
+  __ CompareImmediate(R1, imm_smi_cid);
+  __ b(&error, NE);
+  __ ldr(R1, Address(R8, target::kWordSize));
+  __ CompareImmediate(R1, imm_smi_cid);
+  __ b(&ok, EQ);
+  __ Bind(&error);
+  __ Stop("Incorrect IC data");
+  __ Bind(&ok);
+#endif
+  if (FLAG_optimization_counter_threshold >= 0) {
+    // Update counter, ignore overflow.
+    const intptr_t count_offset =
+        target::ICData::CountIndexFor(num_args) * target::kWordSize;
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
+    __ adds(R1, R1, Operand(target::ToRawSmi(1)));
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
+  }
+  __ Ret();
+}
+
+// Generate inline cache check for 'num_args'.
+//  LR: return address.
+//  R9: inline cache data object.
+// Control flow:
+// - If receiver is null -> jump to IC miss.
+// - If receiver is Smi -> load Smi class.
+// - If receiver is not-Smi -> load receiver's class.
+// - Check if 'num_args' (including receiver) match any IC data group.
+// - Match found -> jump to target.
+// - Match not found -> jump to IC miss.
+void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss,
+    Token::Kind kind,
+    bool optimized,
+    bool exactness_check /* = false */) {
+  ASSERT(!exactness_check);
+  __ CheckCodePointer();
+  ASSERT(num_args == 1 || num_args == 2);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == num_args.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ ldr(R8, FieldAddress(R9, target::ICData::state_bits_offset()));
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ and_(R8, R8, Operand(target::ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R8, num_args);
+    __ b(&ok, EQ);
+    __ Stop("Incorrect stub for IC data");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  Label stepping, done_stepping;
+  if (!optimized) {
+    __ Comment("Check single stepping");
+    __ LoadIsolate(R8);
+    __ ldrb(R8, Address(R8, target::Isolate::single_step_offset()));
+    __ CompareImmediate(R8, 0);
+    __ b(&stepping, NE);
+    __ Bind(&done_stepping);
+  }
+#endif
+
+  Label not_smi_or_overflow;
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
+
+  __ Comment("Extract ICData initial values and receiver cid");
+  // Load arguments descriptor into R4.
+  __ ldr(R4, FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+  // Loop that checks if there is an IC data match.
+  Label loop, found, miss;
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, target::ICData::entries_offset()));
+  // R8: ic_data_array with check entries: classes and target functions.
+  const int kIcDataOffset = target::Array::data_offset() - kHeapObjectTag;
+  // R8: points at the IC data array.
+
+  // Get the receiver's class ID (first read number of arguments from
+  // arguments descriptor array and then access the receiver from the stack).
+  __ ldr(NOTFP, FieldAddress(R4, target::ArgumentsDescriptor::count_offset()));
+  __ sub(NOTFP, NOTFP, Operand(target::ToRawSmi(1)));
+  // NOTFP: argument_count - 1 (smi).
+
+  __ Comment("ICData loop");
+
+  __ ldr(R0, Address(SP, NOTFP, LSL, 1));  // NOTFP (argument_count - 1) is Smi.
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
+  if (num_args == 2) {
+    __ sub(R1, NOTFP, Operand(target::ToRawSmi(1)));
+    __ ldr(R1, Address(SP, R1, LSL, 1));  // R1 (argument_count - 2) is Smi.
+    __ LoadTaggedClassIdMayBeSmi(R1, R1);
+  }
+
+  // We unroll the generic one that is generated once more than the others.
+  const bool optimize = kind == Token::kILLEGAL;
+
+  __ Bind(&loop);
+  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
+    Label update;
+
+    __ ldr(R2, Address(R8, kIcDataOffset));
+    __ cmp(R0, Operand(R2));  // Class id match?
+    if (num_args == 2) {
+      __ b(&update, NE);  // Continue.
+      __ ldr(R2, Address(R8, kIcDataOffset + target::kWordSize));
+      __ cmp(R1, Operand(R2));  // Class id match?
+    }
+    __ b(&found, EQ);  // Break.
+
+    __ Bind(&update);
+
+    const intptr_t entry_size =
+        target::ICData::TestEntryLengthFor(num_args, exactness_check) *
+        target::kWordSize;
+    __ AddImmediate(R8, entry_size);  // Next entry.
+
+    __ CompareImmediate(R2, target::ToRawSmi(kIllegalCid));  // Done?
+    if (unroll == 0) {
+      __ b(&loop, NE);
+    } else {
+      __ b(&miss, EQ);
+    }
+  }
+
+  __ Bind(&miss);
+  __ Comment("IC miss");
+  // Compute address of arguments.
+  // NOTFP: argument_count - 1 (smi).
+  __ add(NOTFP, SP, Operand(NOTFP, LSL, 1));  // NOTFP is Smi.
+  // NOTFP: address of receiver.
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ LoadImmediate(R0, 0);
+  // Preserve IC data object and arguments descriptor array and
+  // setup space on stack for result (target code object).
+  __ PushList((1 << R0) | (1 << R4) | (1 << R9));
+  // Push call arguments.
+  for (intptr_t i = 0; i < num_args; i++) {
+    __ LoadFromOffset(kWord, IP, NOTFP, -i * target::kWordSize);
+    __ Push(IP);
+  }
+  // Pass IC data object.
+  __ Push(R9);
+  __ CallRuntime(handle_ic_miss, num_args + 1);
+  // Remove the call arguments pushed earlier, including the IC data object.
+  __ Drop(num_args + 1);
+  // Pop returned function object into R0.
+  // Restore arguments descriptor array and IC data array.
+  __ PopList((1 << R0) | (1 << R4) | (1 << R9));
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  Label call_target_function;
+  if (!FLAG_lazy_dispatchers) {
+    GenerateDispatcherCode(assembler, &call_target_function);
+  } else {
+    __ b(&call_target_function);
+  }
+
+  __ Bind(&found);
+  // R8: pointer to an IC data check group.
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(num_args) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(num_args) * target::kWordSize;
+  __ LoadFromOffset(kWord, R0, R8, kIcDataOffset + target_offset);
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    __ Comment("Update caller's counter");
+    __ LoadFromOffset(kWord, R1, R8, kIcDataOffset + count_offset);
+    // Ignore overflow.
+    __ adds(R1, R1, Operand(target::ToRawSmi(1)));
+    __ StoreIntoSmiField(Address(R8, kIcDataOffset + count_offset), R1);
+  }
+
+  __ Comment("Call target");
+  __ Bind(&call_target_function);
+  // R0: target function.
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+
+#if !defined(PRODUCT)
+  if (!optimized) {
+    __ Bind(&stepping);
+    __ EnterStubFrame();
+    __ Push(R9);  // Preserve IC data.
+    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+    __ Pop(R9);
+    __ RestoreCodePointer();
+    __ LeaveStubFrame();
+    __ b(&done_stepping);
+  }
+#endif
+}
+
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+//  LR: return address.
+//  R9: inline cache data object.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+//   - N classes.
+//   - 1 target function.
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
+void StubCodeCompiler::GenerateTwoArgsCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+}
+
+void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+}
+
+void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+}
+
+void StubCodeCompiler::GenerateOneArgOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
+                                    Token::kILLEGAL, true /* optimized */);
+}
+
+void StubCodeCompiler::
+    GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+        Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
+void StubCodeCompiler::GenerateTwoArgsOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL, true /* optimized */);
+}
+
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// R9: ICData
+void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == 0.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ ldr(R8, FieldAddress(R9, target::ICData::state_bits_offset()));
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ and_(R8, R8, Operand(target::ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R8, 0);
+    __ b(&ok, EQ);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(R8);
+  __ ldrb(R8, Address(R8, target::Isolate::single_step_offset()));
+  __ CompareImmediate(R8, 0);
+  __ b(&stepping, NE);
+  __ Bind(&done_stepping);
+#endif
+
+  // R9: IC data object (preserved).
+  __ ldr(R8, FieldAddress(R9, target::ICData::entries_offset()));
+  // R8: ic_data_array with entries: target functions and count.
+  __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
+  // R8: points directly to the first ic data array element.
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(0) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(0) * target::kWordSize;
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    // Increment count for this call, ignore overflow.
+    __ LoadFromOffset(kWord, R1, R8, count_offset);
+    __ adds(R1, R1, Operand(target::ToRawSmi(1)));
+    __ StoreIntoSmiField(Address(R8, count_offset), R1);
+  }
+
+  // Load arguments descriptor into R4.
+  __ ldr(R4, FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+
+  // Get function and call it, if possible.
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ Push(R9);  // Preserve IC data.
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ Pop(R9);
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ b(&done_stepping);
+#endif
+}
+
+void StubCodeCompiler::GenerateOneArgUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateTwoArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R8);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+}
+
+// Stub for compiling a function and jumping to the compiled code.
+// R4: Arguments descriptor.
+// R0: Function.
+void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ PushList((1 << R0) | (1 << R4));  // Preserve arg desc, pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ PopList((1 << R0) | (1 << R4));
+  __ LeaveStubFrame();
+
+  // When using the interpreter, the function's code may now point to the
+  // 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()));
+}
+
+void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
+  __ Unimplemented("Interpreter not yet supported");
+}
+
+// R9: Contains an ICData.
+void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ LoadImmediate(R0, 0);
+  // Preserve arguments descriptor and make room for result.
+  __ PushList((1 << R0) | (1 << R9));
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ PopList((1 << R0) | (1 << R9));
+  __ LeaveStubFrame();
+  __ mov(CODE_REG, Operand(R0));
+  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+}
+
+void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ LoadImmediate(R0, 0);
+  // Make room for result.
+  __ PushList((1 << R0));
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ PopList((1 << CODE_REG));
+  __ LeaveStubFrame();
+  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+}
+
+// Called only from unoptimized code. All relevant registers have been saved.
+void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
+#if defined(PRODUCT)
+  __ Ret();
+#else
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(R1);
+  __ ldrb(R1, Address(R1, target::Isolate::single_step_offset()));
+  __ CompareImmediate(R1, 0);
+  __ b(&stepping, NE);
+  __ Bind(&done_stepping);
+  __ Ret();
+
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ LeaveStubFrame();
+  __ b(&done_stepping);
+#endif  // defined(PRODUCT)
+}
+
+// Used to check class and type arguments. Arguments passed in registers:
+// LR: return address.
+// R0: instance (must be preserved).
+// R2: instantiator type arguments (only if n >= 4, can be raw_null).
+// R1: function type arguments (only if n >= 4, can be raw_null).
+// R3: target::SubtypeTestCache.
+//
+// Preserves R0/R2
+//
+// Result in R1: null -> not found, otherwise result (true or false).
+static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+
+  const Register kCacheReg = R3;
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+
+  const Register kInstanceCidOrFunction = R8;
+  const Register kInstanceInstantiatorTypeArgumentsReg = R4;
+  const Register kInstanceParentFunctionTypeArgumentsReg = CODE_REG;
+  const Register kInstanceDelayedFunctionTypeArgumentsReg = PP;
+
+  const Register kNullReg = NOTFP;
+
+  __ LoadObject(kNullReg, NullObject());
+
+  // Free up these 2 registers to be used for 6-value test.
+  if (n >= 6) {
+    __ PushList(1 << kInstanceParentFunctionTypeArgumentsReg |
+                1 << kInstanceDelayedFunctionTypeArgumentsReg);
+  }
+
+  // Loop initialization (moved up here to avoid having all dependent loads
+  // after each other).
+  __ ldr(kCacheReg,
+         FieldAddress(kCacheReg, target::SubtypeTestCache::cache_offset()));
+  __ AddImmediate(kCacheReg, target::Array::data_offset() - kHeapObjectTag);
+
+  Label loop, not_closure;
+  if (n >= 4) {
+    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
+  } else {
+    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
+  }
+  __ CompareImmediate(kInstanceCidOrFunction, kClosureCid);
+  __ b(&not_closure, NE);
+
+  // Closure handling.
+  {
+    __ ldr(kInstanceCidOrFunction,
+           FieldAddress(kInstanceReg, target::Closure::function_offset()));
+    if (n >= 2) {
+      __ ldr(
+          kInstanceInstantiatorTypeArgumentsReg,
+          FieldAddress(kInstanceReg,
+                       target::Closure::instantiator_type_arguments_offset()));
+      if (n >= 6) {
+        ASSERT(n == 6);
+        __ ldr(kInstanceParentFunctionTypeArgumentsReg,
+               FieldAddress(kInstanceReg,
+                            target::Closure::function_type_arguments_offset()));
+        __ ldr(kInstanceDelayedFunctionTypeArgumentsReg,
+               FieldAddress(kInstanceReg,
+                            target::Closure::delayed_type_arguments_offset()));
+      }
+    }
+    __ b(&loop);
+  }
+
+  // Non-Closure handling.
+  {
+    __ Bind(&not_closure);
+    if (n >= 2) {
+      Label has_no_type_arguments;
+      __ LoadClassById(R9, kInstanceCidOrFunction);
+      __ mov(kInstanceInstantiatorTypeArgumentsReg, Operand(kNullReg));
+      __ ldr(R9,
+             FieldAddress(
+                 R9,
+                 target::Class::type_arguments_field_offset_in_words_offset()));
+      __ CompareImmediate(R9, target::Class::kNoTypeArguments);
+      __ b(&has_no_type_arguments, EQ);
+      __ add(R9, kInstanceReg, Operand(R9, LSL, 2));
+      __ ldr(kInstanceInstantiatorTypeArgumentsReg, FieldAddress(R9, 0));
+      __ Bind(&has_no_type_arguments);
+
+      if (n >= 6) {
+        __ mov(kInstanceParentFunctionTypeArgumentsReg, Operand(kNullReg));
+        __ mov(kInstanceDelayedFunctionTypeArgumentsReg, Operand(kNullReg));
+      }
+    }
+    __ SmiTag(kInstanceCidOrFunction);
+  }
+
+  Label found, not_found, next_iteration;
+
+  // Loop header.
+  __ Bind(&loop);
+  __ ldr(R9, Address(kCacheReg,
+                     target::kWordSize *
+                         target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmp(R9, Operand(kNullReg));
+  __ b(&not_found, EQ);
+  __ cmp(R9, Operand(kInstanceCidOrFunction));
+  if (n == 1) {
+    __ b(&found, EQ);
+  } else {
+    __ b(&next_iteration, NE);
+    __ ldr(R9, Address(kCacheReg,
+                       target::kWordSize *
+                           target::SubtypeTestCache::kInstanceTypeArguments));
+    __ cmp(R9, Operand(kInstanceInstantiatorTypeArgumentsReg));
+    if (n == 2) {
+      __ b(&found, EQ);
+    } else {
+      __ b(&next_iteration, NE);
+      __ ldr(R9,
+             Address(kCacheReg,
+                     target::kWordSize *
+                         target::SubtypeTestCache::kInstantiatorTypeArguments));
+      __ cmp(R9, Operand(kInstantiatorTypeArgumentsReg));
+      __ b(&next_iteration, NE);
+      __ ldr(R9, Address(kCacheReg,
+                         target::kWordSize *
+                             target::SubtypeTestCache::kFunctionTypeArguments));
+      __ cmp(R9, Operand(kFunctionTypeArgumentsReg));
+      if (n == 4) {
+        __ b(&found, EQ);
+      } else {
+        ASSERT(n == 6);
+        __ b(&next_iteration, NE);
+
+        __ ldr(R9, Address(kCacheReg,
+                           target::kWordSize *
+                               target::SubtypeTestCache::
+                                   kInstanceParentFunctionTypeArguments));
+        __ cmp(R9, Operand(kInstanceParentFunctionTypeArgumentsReg));
+        __ b(&next_iteration, NE);
+
+        __ ldr(R9, Address(kCacheReg,
+                           target::kWordSize *
+                               target::SubtypeTestCache::
+                                   kInstanceDelayedFunctionTypeArguments));
+        __ cmp(R9, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
+        __ b(&found, EQ);
+      }
+    }
+  }
+  __ Bind(&next_iteration);
+  __ AddImmediate(kCacheReg, target::kWordSize *
+                                 target::SubtypeTestCache::kTestEntryLength);
+  __ b(&loop);
+
+  __ Bind(&found);
+  __ ldr(R1, Address(kCacheReg, target::kWordSize *
+                                    target::SubtypeTestCache::kTestResult));
+  if (n >= 6) {
+    __ PopList(1 << kInstanceParentFunctionTypeArgumentsReg |
+               1 << kInstanceDelayedFunctionTypeArgumentsReg);
+  }
+  __ Ret();
+
+  __ Bind(&not_found);
+  __ mov(R1, Operand(kNullReg));
+  if (n >= 6) {
+    __ PopList(1 << kInstanceParentFunctionTypeArgumentsReg |
+               1 << kInstanceDelayedFunctionTypeArgumentsReg);
+  }
+  __ Ret();
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype1TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 1);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 2);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 4);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 6);
+}
+
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+//   - R0 : instance to test against.
+//   - R2 : instantiator type arguments (if needed).
+//   - R1 : function type arguments (if needed).
+//
+//   - R3 : subtype test cache.
+//
+//   - R8 : type to test against.
+//   - R4 : name of destination variable.
+//
+// Preserves R0/R2.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  Label done;
+
+  const Register kInstanceReg = R0;
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
+  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  const Register kTypeRefReg = R8;
+
+  // We dereference the TypeRef and tail-call to it's type testing stub.
+  __ ldr(kTypeRefReg,
+         FieldAddress(kTypeRefReg, target::TypeRef::type_offset()));
+  __ ldr(R9, FieldAddress(
+                 kTypeRefReg,
+                 target::AbstractType::type_test_stub_entry_point_offset()));
+  __ bx(R9);
+}
+
+void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
+                                            TypeCheckMode mode) {
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+  const Register kDstTypeReg = R8;
+  const Register kSubtypeTestCacheReg = R3;
+
+  __ PushObject(NullObject());  // Make room for result.
+  __ Push(kInstanceReg);
+  __ Push(kDstTypeReg);
+  __ Push(kInstantiatorTypeArgumentsReg);
+  __ Push(kFunctionTypeArgumentsReg);
+  __ PushObject(NullObject());
+  __ Push(kSubtypeTestCacheReg);
+  __ PushImmediate(target::ToRawSmi(mode));
+  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
+  __ Drop(1);  // mode
+  __ Pop(kSubtypeTestCacheReg);
+  __ Drop(1);  // dst_name
+  __ Pop(kFunctionTypeArgumentsReg);
+  __ Pop(kInstantiatorTypeArgumentsReg);
+  __ Pop(kDstTypeReg);
+  __ Pop(kInstanceReg);
+  __ Drop(1);  // Discard return value.
+}
+
+void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
+    Assembler* assembler) {
+  const Register kInstanceReg = R0;
+  Label done;
+
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
+  __ EnterStubFrame();
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
+  __ LeaveStubFrame();
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  const Register kInstanceReg = R0;
+  const Register kFunctionTypeArgumentsReg = R1;
+  const Register kDstTypeReg = R8;
+  const Register kSubtypeTestCacheReg = R3;
+
+  __ EnterStubFrame();
+
+#ifdef DEBUG
+  // Guaranteed by caller.
+  Label no_error;
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(NOT_EQUAL, &no_error);
+  __ Breakpoint();
+  __ Bind(&no_error);
+#endif
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(kSubtypeTestCacheReg, NullObject());
+  __ BranchIf(EQUAL, &call_runtime);
+
+  const Register kTmp = NOTFP;
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple_case, is_complex_case;
+  __ LoadClassId(kTmp, kDstTypeReg);
+  __ cmp(kTmp, Operand(kTypeCid));
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ ldrb(kTmp, FieldAddress(kDstTypeReg, target::Type::type_state_offset()));
+  __ cmp(kTmp,
+         Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // Check whether this [Type] is a function type.
+  __ ldr(kTmp, FieldAddress(kDstTypeReg, target::Type::signature_offset()));
+  __ CompareObject(kTmp, NullObject());
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
+  __ BranchIfSmi(kInstanceReg, &is_complex_case);
+
+  // Fall through to &is_simple_case
+
+  const intptr_t kRegsToSave = (1 << kSubtypeTestCacheReg) |
+                               (1 << kDstTypeReg) |
+                               (1 << kFunctionTypeArgumentsReg);
+
+  __ Bind(&is_simple_case);
+  {
+    __ PushList(kRegsToSave);
+    __ BranchLink(StubCodeSubtype2TestCache());
+    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
+    __ PopList(kRegsToSave);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime);
+  }
+
+  __ Bind(&is_complex_case);
+  {
+    __ PushList(kRegsToSave);
+    __ BranchLink(StubCodeSubtype6TestCache());
+    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
+    __ PopList(kRegsToSave);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  // We cannot really ensure here that dynamic/Object/void never occur here
+  // (though it is guaranteed at dart_precompiled_runtime time).  This is
+  // because we do constant evaluation with default stubs and only install
+  // optimized versions before writing out the AOT snapshot.
+  // So dynamic/Object/void will run with default stub in constant evaluation.
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(DynamicType()));
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(ObjectType()));
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(VoidType()));
+  __ BranchIf(EQUAL, &done);
+
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
+
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+// Return the current stack pointer address, used to do stack alignment checks.
+void StubCodeCompiler::GenerateGetCStackPointerStub(Assembler* assembler) {
+  __ mov(R0, Operand(SP));
+  __ Ret();
+}
+
+// Jump to a frame on the call stack.
+// LR: return address.
+// R0: program_counter.
+// R1: stack_pointer.
+// R2: frame_pointer.
+// R3: thread.
+// Does not return.
+void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
+  ASSERT(kExceptionObjectReg == R0);
+  ASSERT(kStackTraceObjectReg == R1);
+  __ mov(IP, Operand(R1));   // Copy Stack pointer into IP.
+  __ mov(LR, Operand(R0));   // Program counter.
+  __ mov(THR, Operand(R3));  // Thread.
+  __ mov(FP, Operand(R2));   // Frame_pointer.
+  __ mov(SP, Operand(IP));   // Set Stack pointer.
+  // Set the tag.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
+  // Clear top exit frame.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR,
+                   target::Thread::top_exit_frame_info_offset());
+  // Restore the pool pointer.
+  __ RestoreCodePointer();
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
+    __ set_constant_pool_allowed(true);
+  } else {
+    __ LoadPoolPointer();
+  }
+  __ bx(LR);  // Jump to continuation point.
+}
+
+// Run an exception handler.  Execution comes from JumpToFrame
+// stub or from the simulator.
+//
+// The arguments are stored in the Thread object.
+// Does not return.
+void StubCodeCompiler::GenerateRunExceptionHandlerStub(Assembler* assembler) {
+  __ LoadFromOffset(kWord, LR, THR, target::Thread::resume_pc_offset());
+
+  word offset_from_thread = 0;
+  bool ok = target::CanLoadFromThread(NullObject(), &offset_from_thread);
+  ASSERT(ok);
+  __ LoadFromOffset(kWord, R2, THR, offset_from_thread);
+
+  // Exception object.
+  __ LoadFromOffset(kWord, R0, THR, target::Thread::active_exception_offset());
+  __ StoreToOffset(kWord, R2, THR, target::Thread::active_exception_offset());
+
+  // StackTrace object.
+  __ LoadFromOffset(kWord, R1, THR, target::Thread::active_stacktrace_offset());
+  __ StoreToOffset(kWord, R2, THR, target::Thread::active_stacktrace_offset());
+
+  __ bx(LR);  // Jump to the exception handler code.
+}
+
+// Deoptimize a frame on the call stack before rewinding.
+// The arguments are stored in the Thread object.
+// No result.
+void StubCodeCompiler::GenerateDeoptForRewindStub(Assembler* assembler) {
+  // Push zap value instead of CODE_REG.
+  __ LoadImmediate(IP, kZapCodeReg);
+  __ Push(IP);
+
+  // Load the deopt pc into LR.
+  __ LoadFromOffset(kWord, LR, THR, target::Thread::resume_pc_offset());
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+
+  // After we have deoptimized, jump to the correct frame.
+  __ EnterStubFrame();
+  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
+  __ LeaveStubFrame();
+  __ bkpt(0);
+}
+
+// Calls to the runtime to optimize the given function.
+// R8: function to be reoptimized.
+// R4: argument descriptor (preserved).
+void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R4);
+  __ LoadImmediate(IP, 0);
+  __ Push(IP);  // Setup space on stack for return value.
+  __ Push(R8);
+  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
+  __ Pop(R0);  // Discard argument.
+  __ Pop(R0);  // Get Function object
+  __ Pop(R4);  // Restore argument descriptor.
+  __ LeaveStubFrame();
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+  __ bkpt(0);
+}
+
+// Does identical check (object references are equal or not equal) with special
+// checks for boxed numbers.
+// LR: return address.
+// Return Zero condition flag set if equal.
+// Note: A Mint cannot contain a value that would fit in Smi.
+static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
+                                                 const Register left,
+                                                 const Register right,
+                                                 const Register temp) {
+  Label reference_compare, done, check_mint;
+  // If any of the arguments is Smi do reference compare.
+  __ tst(left, Operand(kSmiTagMask));
+  __ b(&reference_compare, EQ);
+  __ tst(right, Operand(kSmiTagMask));
+  __ b(&reference_compare, EQ);
+
+  // Value compare for two doubles.
+  __ CompareClassId(left, kDoubleCid, temp);
+  __ b(&check_mint, NE);
+  __ CompareClassId(right, kDoubleCid, temp);
+  __ b(&done, NE);
+
+  // Double values bitwise compare.
+  __ ldr(temp, FieldAddress(left, target::Double::value_offset() +
+                                      0 * target::kWordSize));
+  __ ldr(IP, FieldAddress(right, target::Double::value_offset() +
+                                     0 * target::kWordSize));
+  __ cmp(temp, Operand(IP));
+  __ b(&done, NE);
+  __ ldr(temp, FieldAddress(left, target::Double::value_offset() +
+                                      1 * target::kWordSize));
+  __ ldr(IP, FieldAddress(right, target::Double::value_offset() +
+                                     1 * target::kWordSize));
+  __ cmp(temp, Operand(IP));
+  __ b(&done);
+
+  __ Bind(&check_mint);
+  __ CompareClassId(left, kMintCid, temp);
+  __ b(&reference_compare, NE);
+  __ CompareClassId(right, kMintCid, temp);
+  __ b(&done, NE);
+  __ ldr(temp, FieldAddress(
+                   left, target::Mint::value_offset() + 0 * target::kWordSize));
+  __ ldr(IP, FieldAddress(
+                 right, target::Mint::value_offset() + 0 * target::kWordSize));
+  __ cmp(temp, Operand(IP));
+  __ b(&done, NE);
+  __ ldr(temp, FieldAddress(
+                   left, target::Mint::value_offset() + 1 * target::kWordSize));
+  __ ldr(IP, FieldAddress(
+                 right, target::Mint::value_offset() + 1 * target::kWordSize));
+  __ cmp(temp, Operand(IP));
+  __ b(&done);
+
+  __ Bind(&reference_compare);
+  __ cmp(left, Operand(right));
+  __ Bind(&done);
+}
+
+// Called only from unoptimized code. All relevant registers have been saved.
+// LR: return address.
+// SP + 4: left operand.
+// SP + 0: right operand.
+// Return Zero condition flag set if equal.
+void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(R1);
+  __ ldrb(R1, Address(R1, target::Isolate::single_step_offset()));
+  __ CompareImmediate(R1, 0);
+  __ b(&stepping, NE);
+  __ Bind(&done_stepping);
+#endif
+
+  const Register temp = R2;
+  const Register left = R1;
+  const Register right = R0;
+  __ ldr(left, Address(SP, 1 * target::kWordSize));
+  __ ldr(right, Address(SP, 0 * target::kWordSize));
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
+  __ Ret();
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ b(&done_stepping);
+#endif
+}
+
+// Called from optimized code only.
+// LR: return address.
+// SP + 4: left operand.
+// SP + 0: right operand.
+// Return Zero condition flag set if equal.
+void StubCodeCompiler::GenerateOptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+  const Register temp = R2;
+  const Register left = R1;
+  const Register right = R0;
+  __ ldr(left, Address(SP, 1 * target::kWordSize));
+  __ ldr(right, Address(SP, 0 * target::kWordSize));
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
+  __ Ret();
+}
+
+// Called from megamorphic calls.
+//  R0: receiver
+//  R9: MegamorphicCache (preserved)
+// Passed to target:
+//  CODE_REG: target Code
+//  R4: arguments descriptor
+void StubCodeCompiler::GenerateMegamorphicCallStub(Assembler* assembler) {
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
+  // R0: receiver cid as Smi.
+  __ ldr(R2, FieldAddress(R9, target::MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R9, target::MegamorphicCache::mask_offset()));
+  // R2: cache buckets array.
+  // R1: mask as a smi.
+
+  // Compute the table index.
+  ASSERT(target::MegamorphicCache::kSpreadFactor == 7);
+  // Use reverse substract to multiply with 7 == 8 - 1.
+  __ rsb(R3, R0, Operand(R0, LSL, 3));
+  // R3: probe.
+  Label loop;
+  __ Bind(&loop);
+  __ and_(R3, R3, Operand(R1));
+
+  const intptr_t base = target::Array::data_offset();
+  // R3 is smi tagged, but table entries are two words, so LSL 2.
+  Label probe_failed;
+  __ add(IP, R2, Operand(R3, LSL, 2));
+  __ ldr(R6, FieldAddress(IP, base));
+  __ cmp(R6, Operand(R0));
+  __ b(&probe_failed, NE);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // illegal class id was found, the target is a cache miss handler that can
+  // 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()));
+    __ 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()));
+    __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+  }
+
+  // Probe failed, check if it is a miss.
+  __ Bind(&probe_failed);
+  ASSERT(kIllegalCid == 0);
+  __ tst(R6, Operand(R6));
+  __ b(&load_target, EQ);  // branch if miss.
+
+  // Try next entry in the table.
+  __ AddImmediate(R3, target::ToRawSmi(1));
+  __ b(&loop);
+}
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R9: ICData (preserved)
+// Passed to target:
+//  CODE_REG: target Code object
+//  R4: arguments descriptor
+void StubCodeCompiler::GenerateICCallThroughFunctionStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ ldr(ARGS_DESC_REG,
+         FieldAddress(R9, target::ICData::arguments_descriptor_offset()));
+  __ ldr(R8, FieldAddress(R9, target::ICData::entries_offset()));
+  __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, target::ToRawSmi(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length =
+      target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
+      target::kWordSize;
+  __ AddImmediate(R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(1) * target::kWordSize;
+  __ LoadFromOffset(kWord, R0, R8, target_offset);
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ Branch(FieldAddress(R0, target::Function::entry_point_offset()));
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, target::Isolate::ic_miss_code_offset()));
+  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+}
+
+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()));
+  __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, target::ToRawSmi(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length =
+      target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
+      target::kWordSize;
+  __ AddImmediate(R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t code_offset =
+      target::ICData::CodeIndexFor(1) * target::kWordSize;
+  const intptr_t entry_offset =
+      target::ICData::EntryPointIndexFor(1) * target::kWordSize;
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ ldr(CODE_REG, Address(R8, code_offset));
+  }
+  __ Branch(Address(R8, entry_offset));
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, target::Isolate::ic_miss_code_offset()));
+  __ Branch(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+}
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R9: UnlinkedCall
+void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R0);  // Preserve receiver.
+
+  __ LoadImmediate(IP, 0);
+  __ Push(IP);  // Result slot
+  __ Push(R0);  // Arg0: Receiver
+  __ Push(R9);  // Arg1: UnlinkedCall
+  __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+  __ Drop(2);
+  __ Pop(R9);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ Branch(FieldAddress(
+      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kMonomorphic)));
+}
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R9: SingleTargetCache
+// Passed to target:
+//  CODE_REG: target Code object
+void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
+  Label miss;
+  __ LoadClassIdMayBeSmi(R1, R0);
+  __ ldrh(R2,
+          FieldAddress(R9, target::SingleTargetCache::lower_limit_offset()));
+  __ ldrh(R3,
+          FieldAddress(R9, target::SingleTargetCache::upper_limit_offset()));
+
+  __ cmp(R1, Operand(R2));
+  __ b(&miss, LT);
+  __ cmp(R1, Operand(R3));
+  __ b(&miss, GT);
+
+  __ ldr(CODE_REG,
+         FieldAddress(R9, target::SingleTargetCache::target_offset()));
+  __ Branch(FieldAddress(R9, target::SingleTargetCache::entry_point_offset()));
+
+  __ Bind(&miss);
+  __ EnterStubFrame();
+  __ Push(R0);  // Preserve receiver.
+
+  __ LoadImmediate(IP, 0);
+  __ Push(IP);  // Result slot
+  __ Push(R0);  // Arg0: Receiver
+  __ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(R9);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ 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(R0);  // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(R9);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ Branch(FieldAddress(
+      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kMonomorphic)));
+}
+
+void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
+    Assembler* assembler) {
+  __ bkpt(0);
+}
+
+void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
+  __ bkpt(0);
+}
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
new file mode 100644
index 0000000..30acf68
--- /dev/null
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -0,0 +1,3202 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/compiler/stub_code_compiler.h"
+
+#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/class_id.h"
+#include "vm/code_entry_kind.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/locations.h"
+#include "vm/constants_arm64.h"
+#include "vm/instructions.h"
+#include "vm/static_type_exactness_state.h"
+#include "vm/tags.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
+DEFINE_FLAG(bool,
+            use_slow_path,
+            false,
+            "Set to true for debugging & verifying the slow paths.");
+DECLARE_FLAG(bool, enable_interpreter);
+DECLARE_FLAG(bool, precompiled_mode);
+
+namespace compiler {
+
+// Input parameters:
+//   LR : return address.
+//   SP : address of last argument in argument array.
+//   SP + 8*R4 - 8 : address of first argument in argument array.
+//   SP + 8*R4 : address of return value.
+//   R5 : address of the runtime function to call.
+//   R4 : number of arguments to the call.
+void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ Comment("CallToRuntimeStub");
+  __ ldr(CODE_REG, Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  __ SetPrologueOffset();
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(R8, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing VM code.
+  __ StoreToOffset(R5, THR, target::Thread::vm_tag_offset());
+
+  // Reserve space for arguments and align frame before entering C++ world.
+  // target::NativeArguments are passed in registers.
+  __ Comment("align stack");
+  // Reserve space for arguments.
+  ASSERT(target::NativeArguments::StructSize() == 4 * target::kWordSize);
+  __ ReserveAlignedFrameSpace(target::NativeArguments::StructSize());
+
+  // Pass target::NativeArguments structure by value and call runtime.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(thread_offset == 0 * target::kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, THR);
+
+  // There are no runtime calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * target::kWordSize);
+  __ mov(R1, R4);  // Set argc in target::NativeArguments.
+
+  ASSERT(argv_offset == 2 * target::kWordSize);
+  __ add(R2, ZR, Operand(R4, LSL, 3));
+  __ add(R2, FP, Operand(R2));  // Compute argv.
+  // Set argv in target::NativeArguments.
+  __ AddImmediate(R2,
+                  target::frame_layout.param_end_from_fp * target::kWordSize);
+
+  ASSERT(retval_offset == 3 * target::kWordSize);
+  __ AddImmediate(R3, R2, target::kWordSize);
+
+  __ StoreToOffset(R0, SP, thread_offset);
+  __ StoreToOffset(R1, SP, argc_tag_offset);
+  __ StoreToOffset(R2, SP, argv_offset);
+  __ StoreToOffset(R3, SP, retval_offset);
+  __ mov(R0, SP);  // Pass the pointer to the target::NativeArguments.
+
+  // We are entering runtime code, so the C stack pointer must be restored from
+  // the stack limit to the top of the stack. We cache the stack limit address
+  // in a callee-saved register.
+  __ mov(R25, CSP);
+  __ mov(CSP, SP);
+
+  __ blr(R5);
+  __ Comment("CallToRuntimeStub return");
+
+  // Restore SP and CSP.
+  __ mov(SP, CSP);
+  __ mov(CSP, R25);
+
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+
+  // Retval is next to 1st argument.
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+
+  // Restore the global object pool after returning from runtime (old space is
+  // moving, so the GOP could have been relocated).
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
+    __ sub(PP, PP, Operand(kHeapObjectTag));  // Pool in PP is untagged!
+  }
+
+  __ LeaveStubFrame();
+
+  // The following return can jump to a lazy-deopt stub, which assumes R0
+  // contains a return value and will save it in a GC-visible way.  We therefore
+  // have to ensure R0 does not contain any garbage value left from the C
+  // function we called (which has return type "void").
+  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
+  __ LoadImmediate(R0, 0);
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateSharedStub(
+    Assembler* assembler,
+    bool save_fpu_registers,
+    const RuntimeEntry* target,
+    intptr_t self_code_stub_offset_from_thread,
+    bool allow_return) {
+  // We want the saved registers to appear like part of the caller's frame, so
+  // we push them before calling EnterStubFrame.
+  RegisterSet all_registers;
+  all_registers.AddAllNonReservedRegisters(save_fpu_registers);
+
+  // To make the stack map calculation architecture independent we do the same
+  // as on intel.
+  __ Push(LR);
+  __ PushRegisters(all_registers);
+  __ ldr(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
+  __ EnterStubFrame();
+  __ CallRuntime(*target, /*argument_count=*/0);
+  if (!allow_return) {
+    __ Breakpoint();
+    return;
+  }
+  __ LeaveStubFrame();
+  __ PopRegisters(all_registers);
+  __ Pop(LR);
+  __ ret(LR);
+}
+
+// R1: The extracted method.
+// R4: The type_arguments_field_offset (or 0)
+void StubCodeCompiler::GenerateBuildMethodExtractorStub(
+    Assembler* assembler,
+    const Object& closure_allocation_stub,
+    const Object& context_allocation_stub) {
+  const intptr_t kReceiverOffset =
+      compiler::target::frame_layout.param_end_from_fp + 1;
+
+  __ EnterStubFrame();
+
+  // Build type_arguments vector (or null)
+  Label no_type_args;
+  __ ldr(R3, Address(THR, target::Thread::object_null_offset()), kDoubleWord);
+  __ cmp(R4, Operand(0));
+  __ b(&no_type_args, EQ);
+  __ ldr(R0, Address(FP, kReceiverOffset * target::kWordSize));
+  __ ldr(R3, Address(R0, R4));
+  __ Bind(&no_type_args);
+
+  // Push type arguments & extracted method.
+  __ PushPair(R3, R1);
+
+  // Allocate context.
+  {
+    Label done, slow_path;
+    __ TryAllocateArray(kContextCid, target::Context::InstanceSize(1),
+                        &slow_path,
+                        R0,  // instance
+                        R1,  // end address
+                        R2, R3);
+    __ ldr(R1, Address(THR, target::Thread::object_null_offset()));
+    __ str(R1, FieldAddress(R0, target::Context::parent_offset()));
+    __ LoadImmediate(R1, 1);
+    __ str(R1, FieldAddress(R0, target::Context::num_variables_offset()));
+    __ b(&done);
+
+    __ Bind(&slow_path);
+
+    __ LoadImmediate(/*num_vars=*/R1, 1);
+    __ LoadObject(CODE_REG, context_allocation_stub);
+    __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+    __ blr(R0);
+
+    __ Bind(&done);
+  }
+
+  // Store receiver in context
+  __ ldr(R1, Address(FP, target::kWordSize * kReceiverOffset));
+  __ StoreIntoObject(R0, FieldAddress(R0, target::Context::variable_offset(0)),
+                     R1);
+
+  // Push context.
+  __ Push(R0);
+
+  // Allocate closure.
+  __ LoadObject(CODE_REG, closure_allocation_stub);
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                        CodeEntryKind::kUnchecked)));
+  __ blr(R1);
+
+  // Populate closure object.
+  __ Pop(R1);  // Pop context.
+  __ StoreIntoObject(R0, FieldAddress(R0, target::Closure::context_offset()),
+                     R1);
+  __ PopPair(R3, R1);  // Pop type arguments & extracted method.
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::Closure::function_offset()), R1);
+  __ StoreIntoObjectNoBarrier(
+      R0,
+      FieldAddress(R0, target::Closure::instantiator_type_arguments_offset()),
+      R3);
+  __ LoadObject(R1, EmptyTypeArguments());
+  __ StoreIntoObjectNoBarrier(
+      R0, FieldAddress(R0, target::Closure::delayed_type_arguments_offset()),
+      R1);
+
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kNullErrorRuntimeEntry,
+      target::Thread::null_error_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/false);
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kNullErrorRuntimeEntry,
+      target::Thread::null_error_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/false);
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
+      target::Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/true);
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kStackOverflowRuntimeEntry,
+      target::Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/true);
+}
+
+void StubCodeCompiler::GeneratePrintStopMessageStub(Assembler* assembler) {
+  __ Stop("GeneratePrintStopMessageStub");
+}
+
+// Input parameters:
+//   LR : return address.
+//   SP : address of return value.
+//   R5 : address of the native function to call.
+//   R2 : address of first argument in argument array.
+//   R1 : argc_tag including number of arguments and function kind.
+static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
+                                              Address wrapper) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(R6, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R6, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ StoreToOffset(R5, THR, target::Thread::vm_tag_offset());
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // R0) and align frame before entering the C++ world.
+  __ ReserveAlignedFrameSpace(target::NativeArguments::StructSize());
+
+  // Initialize target::NativeArguments structure and call native function.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(thread_offset == 0 * target::kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, THR);
+
+  // There are no native calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * target::kWordSize);
+  // Set argc in target::NativeArguments: R1 already contains argc.
+
+  ASSERT(argv_offset == 2 * target::kWordSize);
+  // Set argv in target::NativeArguments: R2 already contains argv.
+
+  // Set retval in NativeArgs.
+  ASSERT(retval_offset == 3 * target::kWordSize);
+  __ AddImmediate(R3, FP, 2 * target::kWordSize);
+
+  // Passing the structure by value as in runtime calls would require changing
+  // Dart API for native functions.
+  // For now, space is reserved on the stack and we pass a pointer to it.
+  __ StoreToOffset(R0, SP, thread_offset);
+  __ StoreToOffset(R1, SP, argc_tag_offset);
+  __ StoreToOffset(R2, SP, argv_offset);
+  __ StoreToOffset(R3, SP, retval_offset);
+  __ mov(R0, SP);  // Pass the pointer to the target::NativeArguments.
+
+  // We are entering runtime code, so the C stack pointer must be restored from
+  // the stack limit to the top of the stack. We cache the stack limit address
+  // in the Dart SP register, which is callee-saved in the C ABI.
+  __ mov(R25, CSP);
+  __ mov(CSP, SP);
+
+  __ mov(R1, R5);  // Pass the function entrypoint to call.
+
+  // Call native function invocation wrapper or redirection via simulator.
+  __ ldr(LR, wrapper);
+  __ blr(LR);
+
+  // Restore SP and CSP.
+  __ mov(SP, CSP);
+  __ mov(CSP, R25);
+
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateCallNoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::no_scope_native_wrapper_entry_point_offset()));
+}
+
+void StubCodeCompiler::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::auto_scope_native_wrapper_entry_point_offset()));
+}
+
+// Input parameters:
+//   LR : return address.
+//   SP : address of return value.
+//   R5 : address of the native function to call.
+//   R2 : address of first argument in argument array.
+//   R1 : argc_tag including number of arguments and function kind.
+void StubCodeCompiler::GenerateCallBootstrapNativeStub(Assembler* assembler) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(R6, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R6, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ StoreToOffset(R5, THR, target::Thread::vm_tag_offset());
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // R0) and align frame before entering the C++ world.
+  __ ReserveAlignedFrameSpace(target::NativeArguments::StructSize());
+
+  // Initialize target::NativeArguments structure and call native function.
+  // Registers R0, R1, R2, and R3 are used.
+
+  ASSERT(thread_offset == 0 * target::kWordSize);
+  // Set thread in NativeArgs.
+  __ mov(R0, THR);
+
+  // There are no native calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  ASSERT(argc_tag_offset == 1 * target::kWordSize);
+  // Set argc in target::NativeArguments: R1 already contains argc.
+
+  ASSERT(argv_offset == 2 * target::kWordSize);
+  // Set argv in target::NativeArguments: R2 already contains argv.
+
+  // Set retval in NativeArgs.
+  ASSERT(retval_offset == 3 * target::kWordSize);
+  __ AddImmediate(R3, FP, 2 * target::kWordSize);
+
+  // Passing the structure by value as in runtime calls would require changing
+  // Dart API for native functions.
+  // For now, space is reserved on the stack and we pass a pointer to it.
+  __ StoreToOffset(R0, SP, thread_offset);
+  __ StoreToOffset(R1, SP, argc_tag_offset);
+  __ StoreToOffset(R2, SP, argv_offset);
+  __ StoreToOffset(R3, SP, retval_offset);
+  __ mov(R0, SP);  // Pass the pointer to the target::NativeArguments.
+
+  // We are entering runtime code, so the C stack pointer must be restored from
+  // the stack limit to the top of the stack. We cache the stack limit address
+  // in the Dart SP register, which is callee-saved in the C ABI.
+  __ mov(R25, CSP);
+  __ mov(CSP, SP);
+
+  // Call native function or redirection via simulator.
+  __ blr(R5);
+
+  // Restore SP and CSP.
+  __ mov(SP, CSP);
+  __ mov(CSP, R25);
+
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+// Input parameters:
+//   R4: arguments descriptor array.
+void StubCodeCompiler::GenerateCallStaticFunctionStub(Assembler* assembler) {
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value and preserve arguments descriptor.
+  __ Push(R4);
+  __ Push(ZR);
+  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
+  // Get Code object result and restore arguments descriptor array.
+  __ Pop(CODE_REG);
+  __ Pop(R4);
+  // Remove the stub frame.
+  __ LeaveStubFrame();
+  // Jump to the dart function.
+  __ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
+  __ br(R0);
+}
+
+// Called from a static call only when an invalid code has been entered
+// (invalid because its function was optimized or deoptimized).
+// R4: arguments descriptor array.
+void StubCodeCompiler::GenerateFixCallersTargetStub(Assembler* assembler) {
+  // Load code pointer to this stub from the thread:
+  // The one that is passed in, is not correct - it points to the code object
+  // that needs to be replaced.
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::fix_callers_target_code_offset()));
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value and preserve arguments descriptor.
+  __ Push(R4);
+  __ Push(ZR);
+  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
+  // Get Code object result and restore arguments descriptor array.
+  __ Pop(CODE_REG);
+  __ Pop(R4);
+  // Remove the stub frame.
+  __ LeaveStubFrame();
+  // Jump to the dart function.
+  __ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
+  __ br(R0);
+}
+
+// Called from object allocate instruction when the allocation stub has been
+// disabled.
+void StubCodeCompiler::GenerateFixAllocationStubTargetStub(
+    Assembler* assembler) {
+  // Load code pointer to this stub from the thread:
+  // The one that is passed in, is not correct - it points to the code object
+  // that needs to be replaced.
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::fix_allocation_stub_code_offset()));
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  __ Push(ZR);
+  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
+  // Get Code object result.
+  __ Pop(CODE_REG);
+  // Remove the stub frame.
+  __ LeaveStubFrame();
+  // Jump to the dart function.
+  __ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
+  __ br(R0);
+}
+
+// Input parameters:
+//   R2: smi-tagged argument count, may be zero.
+//   FP[target::frame_layout.param_end_from_fp + 1]: last argument.
+static void PushArrayOfArguments(Assembler* assembler) {
+  // Allocate array to store arguments of caller.
+  __ LoadObject(R1, NullObject());
+  // R1: null element type for raw Array.
+  // R2: smi-tagged argument count, may be zero.
+  __ BranchLink(StubCodeAllocateArray());
+  // R0: newly allocated array.
+  // R2: smi-tagged argument count, may be zero (was preserved by the stub).
+  __ Push(R0);  // Array is in R0 and on top of stack.
+  __ add(R1, FP, Operand(R2, LSL, 2));
+  __ AddImmediate(R1,
+                  target::frame_layout.param_end_from_fp * target::kWordSize);
+  __ AddImmediate(R3, R0, target::Array::data_offset() - kHeapObjectTag);
+  // R1: address of first argument on stack.
+  // R3: address of first argument in array.
+
+  Label loop, loop_exit;
+  __ CompareRegisters(R2, ZR);
+  __ b(&loop_exit, LE);
+  __ Bind(&loop);
+  __ ldr(R7, Address(R1));
+  __ AddImmediate(R1, -target::kWordSize);
+  __ AddImmediate(R3, target::kWordSize);
+  __ AddImmediateSetFlags(R2, R2, -target::ToRawSmi(1));
+  __ str(R7, Address(R3, -target::kWordSize));
+  __ b(&loop, GE);
+  __ Bind(&loop_exit);
+}
+
+// Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
+// This stub translates optimized frame into unoptimized frame. The optimized
+// frame can contain values in registers and on stack, the unoptimized
+// frame contains all values on stack.
+// Deoptimization occurs in following steps:
+// - Push all registers that can contain values.
+// - Call C routine to copy the stack and saved registers into temporary buffer.
+// - Adjust caller's frame to correct unoptimized frame size.
+// - Fill the unoptimized frame.
+// - Materialize objects that require allocation (e.g. Double instances).
+// GC can occur only after frame is fully rewritten.
+// Stack after TagAndPushPP() below:
+//   +------------------+
+//   | Saved PP         | <- PP
+//   +------------------+
+//   | PC marker        | <- TOS
+//   +------------------+
+//   | Saved FP         | <- FP of stub
+//   +------------------+
+//   | return-address   |  (deoptimization point)
+//   +------------------+
+//   | Saved CODE_REG   |
+//   +------------------+
+//   | ...              | <- SP of optimized frame
+//
+// Parts of the code cannot GC, part of the code can GC.
+static void GenerateDeoptimizationSequence(Assembler* assembler,
+                                           DeoptStubKind kind) {
+  // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+  // is no need to set the correct PC marker or load PP, since they get patched.
+  __ EnterStubFrame();
+
+  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
+  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
+  const intptr_t saved_result_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - R0);
+  const intptr_t saved_exception_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - R0);
+  const intptr_t saved_stacktrace_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - R1);
+  // Result in R0 is preserved as part of pushing all registers below.
+
+  // Push registers in their enumeration order: lowest register number at
+  // lowest address.
+  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
+    const Register r = static_cast<Register>(i);
+    if (r == CODE_REG) {
+      // Save the original value of CODE_REG pushed before invoking this stub
+      // instead of the value used to call this stub.
+      COMPILE_ASSERT(R25 > CODE_REG);
+      __ ldr(R25, Address(FP, 2 * target::kWordSize));
+      __ str(R25, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+    } else {
+      __ str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+    }
+  }
+
+  for (intptr_t reg_idx = kNumberOfVRegisters - 1; reg_idx >= 0; reg_idx--) {
+    VRegister vreg = static_cast<VRegister>(reg_idx);
+    __ PushQuad(vreg);
+  }
+
+  __ mov(R0, SP);  // Pass address of saved registers block.
+  bool is_lazy =
+      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
+  __ LoadImmediate(R1, is_lazy ? 1 : 0);
+  __ ReserveAlignedFrameSpace(0);
+  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
+  // Result (R0) is stack-size (FP - SP) in bytes.
+
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into R1 temporarily.
+    __ LoadFromOffset(R1, FP, saved_result_slot_from_fp * target::kWordSize);
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into R1 temporarily.
+    __ LoadFromOffset(R1, FP, saved_exception_slot_from_fp * target::kWordSize);
+    __ LoadFromOffset(R2, FP,
+                      saved_stacktrace_slot_from_fp * target::kWordSize);
+  }
+
+  // There is a Dart Frame on the stack. We must restore PP and leave frame.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ sub(SP, FP, Operand(R0));
+
+  // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+  // is no need to set the correct PC marker or load PP, since they get patched.
+  __ EnterStubFrame();
+
+  if (kind == kLazyDeoptFromReturn) {
+    __ Push(R1);  // Preserve result as first local.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ Push(R1);  // Preserve exception as first local.
+    __ Push(R2);  // Preserve stacktrace as second local.
+  }
+  __ ReserveAlignedFrameSpace(0);
+  __ mov(R0, FP);  // Pass last FP as parameter in R0.
+  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into R1.
+    __ LoadFromOffset(
+        R1, FP,
+        compiler::target::frame_layout.first_local_from_fp * target::kWordSize);
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into R1.
+    __ LoadFromOffset(
+        R1, FP,
+        compiler::target::frame_layout.first_local_from_fp * target::kWordSize);
+    __ LoadFromOffset(R2, FP,
+                      (compiler::target::frame_layout.first_local_from_fp - 1) *
+                          target::kWordSize);
+  }
+  // Code above cannot cause GC.
+  // There is a Dart Frame on the stack. We must restore PP and leave frame.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+
+  // Frame is fully rewritten at this point and it is safe to perform a GC.
+  // Materialize any objects that were deferred by FillFrame because they
+  // require allocation.
+  // Enter stub frame with loading PP. The caller's PP is not materialized yet.
+  __ EnterStubFrame();
+  if (kind == kLazyDeoptFromReturn) {
+    __ Push(R1);  // Preserve result, it will be GC-d here.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ Push(R1);  // Preserve exception, it will be GC-d here.
+    __ Push(R2);  // Preserve stacktrace, it will be GC-d here.
+  }
+
+  __ Push(ZR);  // Space for the result.
+  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
+  // Result tells stub how many bytes to remove from the expression stack
+  // of the bottom-most frame. They were used as materialization arguments.
+  __ Pop(R2);
+  __ SmiUntag(R2);
+  if (kind == kLazyDeoptFromReturn) {
+    __ Pop(R0);  // Restore result.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ Pop(R1);  // Restore stacktrace.
+    __ Pop(R0);  // Restore exception.
+  }
+  __ LeaveStubFrame();
+  // Remove materialization arguments.
+  __ add(SP, SP, Operand(R2));
+  // The caller is responsible for emitting the return instruction.
+}
+
+// R0: result, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromReturnStub(
+    Assembler* assembler) {
+  // Push zap value instead of CODE_REG for lazy deopt.
+  __ LoadImmediate(TMP, kZapCodeReg);
+  __ Push(TMP);
+  // Return address for "call" to deopt stub.
+  __ LoadImmediate(LR, kZapReturnAddress);
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::lazy_deopt_from_return_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
+  __ ret();
+}
+
+// R0: exception, must be preserved
+// R1: stacktrace, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromThrowStub(
+    Assembler* assembler) {
+  // Push zap value instead of CODE_REG for lazy deopt.
+  __ LoadImmediate(TMP, kZapCodeReg);
+  __ Push(TMP);
+  // Return address for "call" to deopt stub.
+  __ LoadImmediate(LR, kZapReturnAddress);
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::lazy_deopt_from_throw_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateDeoptimizeStub(Assembler* assembler) {
+  __ Push(CODE_REG);
+  __ ldr(CODE_REG, Address(THR, target::Thread::deoptimize_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+  __ 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);
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
+  __ LoadFromOffset(R6, TMP,
+                    target::frame_layout.param_end_from_fp * target::kWordSize);
+  __ Push(ZR);  // Result slot.
+  __ Push(R6);  // Receiver.
+  __ Push(R5);  // ICData/MegamorphicCache.
+  __ Push(R4);  // Arguments descriptor.
+
+  // Adjust arguments count.
+  __ LoadFieldFromOffset(R3, R4,
+                         target::ArgumentsDescriptor::type_args_len_offset());
+  __ AddImmediate(TMP, R2, 1);  // Include the type arguments.
+  __ cmp(R3, Operand(0));
+  __ csinc(R2, R2, TMP, EQ);  // R2 <- (R3 == 0) ? R2 : TMP + 1 (R2 : R2 + 2).
+
+  // R2: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+  const intptr_t kNumArgs = 4;
+  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+  __ Drop(4);
+  __ Pop(R0);  // Return value.
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
+  __ LoadFromOffset(
+      R6, TMP,
+      compiler::target::frame_layout.param_end_from_fp * target::kWordSize);
+
+  // 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);
+}
+
+// Called for inline allocation of arrays.
+// Input parameters:
+//   LR: return address.
+//   R2: array length as Smi.
+//   R1: array element type (either NULL or an instantiated type).
+// NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
+// The newly allocated object is returned in R0.
+void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
+  Label slow_case;
+  // Compute the size to be allocated, it is based on the array length
+  // and is computed as:
+  // RoundedAllocationSize(
+  //     (array_length * kwordSize) + target::Array::header_size()).
+  // Assert that length is a Smi.
+  __ tsti(R2, Immediate(kSmiTagMask));
+  if (FLAG_use_slow_path) {
+    __ b(&slow_case);
+  } else {
+    __ b(&slow_case, NE);
+  }
+  __ cmp(R2, Operand(0));
+  __ b(&slow_case, LT);
+
+  // Check for maximum allowed length.
+  const intptr_t max_len =
+      target::ToRawSmi(target::Array::kMaxNewSpaceElements);
+  __ CompareImmediate(R2, max_len);
+  __ b(&slow_case, GT);
+
+  const intptr_t cid = kArrayCid;
+  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case));
+
+  // Calculate and align allocation size.
+  // Load new object start and calculate next object start.
+  // R1: array element type.
+  // R2: array length as Smi.
+  __ ldr(R0, Address(THR, target::Thread::top_offset()));
+  intptr_t fixed_size_plus_alignment_padding =
+      target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
+      1;
+  __ LoadImmediate(R3, fixed_size_plus_alignment_padding);
+  __ add(R3, R3, Operand(R2, LSL, 2));  // R2 is Smi.
+  ASSERT(kSmiTagShift == 1);
+  __ andi(R3, R3, Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
+  // R0: potential new object start.
+  // R3: object size in bytes.
+  __ adds(R7, R3, Operand(R0));
+  __ b(&slow_case, CS);  // Branch if unsigned overflow.
+
+  // Check if the allocation fits into the remaining space.
+  // R0: potential new object start.
+  // R1: array element type.
+  // R2: array length as Smi.
+  // R3: array size.
+  // R7: potential next object start.
+  __ LoadFromOffset(TMP, THR, target::Thread::end_offset());
+  __ CompareRegisters(R7, TMP);
+  __ b(&slow_case, CS);  // Branch if unsigned higher or equal.
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  // R0: potential new object start.
+  // R3: array size.
+  // R7: potential next object start.
+  __ str(R7, Address(THR, target::Thread::top_offset()));
+  __ add(R0, R0, Operand(kHeapObjectTag));
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R3));
+
+  // R0: new object start as a tagged pointer.
+  // R1: array element type.
+  // R2: array length as Smi.
+  // R3: array size.
+  // R7: new object end address.
+
+  // Store the type argument field.
+  __ StoreIntoObjectOffsetNoBarrier(R0, target::Array::type_arguments_offset(),
+                                    R1);
+
+  // Set the length field.
+  __ StoreIntoObjectOffsetNoBarrier(R0, target::Array::length_offset(), R2);
+
+  // Calculate the size tag.
+  // R0: new object start as a tagged pointer.
+  // R2: array length as Smi.
+  // R3: array size.
+  // R7: new object end address.
+  const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+                         target::ObjectAlignment::kObjectAlignmentLog2;
+  __ CompareImmediate(R3, target::RawObject::kSizeTagMaxSizeTag);
+  // If no size tag overflow, shift R1 left, else set R1 to zero.
+  __ LslImmediate(TMP, R3, shift);
+  __ csel(R1, TMP, R1, LS);
+  __ csel(R1, ZR, R1, HI);
+
+  // Get the class index and insert it into the tags.
+  const uint32_t tags =
+      target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+
+  __ LoadImmediate(TMP, tags);
+  __ orr(R1, R1, Operand(TMP));
+  __ StoreFieldToOffset(R1, R0, target::Array::tags_offset());
+
+  // Initialize all array elements to raw_null.
+  // R0: new object start as a tagged pointer.
+  // R7: new object end address.
+  // R2: array length as Smi.
+  __ AddImmediate(R1, R0, target::Array::data_offset() - kHeapObjectTag);
+  // R1: iterator which initially points to the start of the variable
+  // data area to be initialized.
+  __ LoadObject(TMP, NullObject());
+  Label loop, done;
+  __ Bind(&loop);
+  // TODO(cshapiro): StoreIntoObjectNoBarrier
+  __ CompareRegisters(R1, R7);
+  __ b(&done, CS);
+  __ str(TMP, Address(R1));  // Store if unsigned lower.
+  __ AddImmediate(R1, target::kWordSize);
+  __ b(&loop);  // Loop until R1 == R7.
+  __ Bind(&done);
+
+  // Done allocating and initializing the array.
+  // R0: new object.
+  // R2: array length as Smi (preserved for the caller.)
+  __ ret();
+
+  // Unable to allocate the array using the fast inline code, just call
+  // into the runtime.
+  __ Bind(&slow_case);
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  // Push array length as Smi and element type.
+  __ Push(ZR);
+  __ Push(R2);
+  __ Push(R1);
+  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
+  // Pop arguments; result is popped in IP.
+  __ Pop(R1);
+  __ Pop(R2);
+  __ Pop(R0);
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+// Called when invoking Dart code from C++ (VM code).
+// Input parameters:
+//   LR : points to return address.
+//   R0 : code object of the Dart function to call.
+//   R1 : arguments descriptor array.
+//   R2 : arguments array.
+//   R3 : current thread.
+void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) {
+  __ Comment("InvokeDartCodeStub");
+
+  // Copy the C stack pointer (R31) into the stack pointer we'll actually use
+  // to access the stack.
+  __ SetupDartSP();
+  __ Push(LR);  // Marker for the profiler.
+  __ EnterFrame(0);
+
+  // Push code object to PC marker slot.
+  __ ldr(TMP, Address(R3, target::Thread::invoke_dart_code_stub_offset()));
+  __ Push(TMP);
+
+  // Save the callee-saved registers.
+  for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
+    const Register r = static_cast<Register>(i);
+    // We use str instead of the Push macro because we will be pushing the PP
+    // register when it is not holding a pool-pointer since we are coming from
+    // C++ code.
+    __ str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+  }
+
+  // Save the bottom 64-bits of callee-saved V registers.
+  for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
+    const VRegister r = static_cast<VRegister>(i);
+    __ PushDouble(r);
+  }
+
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != R3) {
+    __ mov(THR, R3);
+  }
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+
+  // Save the current VMTag on the stack.
+  __ LoadFromOffset(R4, THR, target::Thread::vm_tag_offset());
+  __ Push(R4);
+
+  // Save top resource and top exit frame info. Use R6 as a temporary register.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ LoadFromOffset(R6, THR, target::Thread::top_resource_offset());
+  __ StoreToOffset(ZR, THR, target::Thread::top_resource_offset());
+  __ Push(R6);
+  __ LoadFromOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+  // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
+  // with the code below.
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -22);
+  __ Push(R6);
+
+  // Mark that the thread is executing Dart code. Do this after initializing the
+  // exit link for the profiler.
+  __ LoadImmediate(R6, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R6, THR, target::Thread::vm_tag_offset());
+
+  // Load arguments descriptor array into R4, which is passed to Dart code.
+  __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle);
+
+  // Load number of arguments into R5 and adjust count for type arguments.
+  __ LoadFieldFromOffset(R5, R4, target::ArgumentsDescriptor::count_offset());
+  __ LoadFieldFromOffset(R3, R4,
+                         target::ArgumentsDescriptor::type_args_len_offset());
+  __ AddImmediate(TMP, R5, 1);  // Include the type arguments.
+  __ cmp(R3, Operand(0));
+  __ csinc(R5, R5, TMP, EQ);  // R5 <- (R3 == 0) ? R5 : TMP + 1 (R5 : R5 + 2).
+  __ SmiUntag(R5);
+
+  // Compute address of 'arguments array' data area into R2.
+  __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle);
+  __ AddImmediate(R2, target::Array::data_offset() - kHeapObjectTag);
+
+  // Set up arguments for the Dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+  __ cmp(R5, Operand(0));
+  __ b(&done_push_arguments, EQ);  // check if there are arguments.
+  __ LoadImmediate(R1, 0);
+  __ Bind(&push_arguments);
+  __ ldr(R3, Address(R2));
+  __ Push(R3);
+  __ add(R1, R1, Operand(1));
+  __ add(R2, R2, Operand(target::kWordSize));
+  __ cmp(R1, Operand(R5));
+  __ b(&push_arguments, LT);
+  __ Bind(&done_push_arguments);
+
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
+    __ sub(PP, PP, Operand(kHeapObjectTag));  // Pool in PP is untagged!
+  } else {
+    // We now load the pool pointer(PP) with a GC safe value as we are about to
+    // invoke dart code. We don't need a real object pool here.
+    // Smi zero does not work because ARM64 assumes PP to be untagged.
+    __ LoadObject(PP, NullObject());
+  }
+
+  // Call the Dart code entrypoint.
+  __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
+  __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ blr(R0);  // R4 is the arguments descriptor array.
+  __ Comment("InvokeDartCodeStub return");
+
+  // Get rid of arguments pushed on the stack.
+  __ AddImmediate(
+      SP, FP,
+      target::frame_layout.exit_link_slot_from_entry_fp * target::kWordSize);
+
+  // Restore the saved top exit frame info and top resource back into the
+  // Isolate structure. Uses R6 as a temporary register for this.
+  __ Pop(R6);
+  __ StoreToOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
+  __ Pop(R6);
+  __ StoreToOffset(R6, THR, target::Thread::top_resource_offset());
+
+  // Restore the current VMTag from the stack.
+  __ Pop(R4);
+  __ StoreToOffset(R4, THR, target::Thread::vm_tag_offset());
+
+  // Restore the bottom 64-bits of callee-saved V registers.
+  for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
+    const VRegister r = static_cast<VRegister>(i);
+    __ PopDouble(r);
+  }
+
+  // Restore C++ ABI callee-saved registers.
+  for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
+    Register r = static_cast<Register>(i);
+    // We use ldr instead of the Pop macro because we will be popping the PP
+    // register when it is not holding a pool-pointer since we are returning to
+    // C++ code. We also skip the dart stack pointer SP, since we are still
+    // using it as the stack pointer.
+    __ ldr(r, Address(SP, 1 * target::kWordSize, Address::PostIndex));
+  }
+
+  // Restore the frame pointer and C stack pointer and return.
+  __ LeaveFrame();
+  __ Drop(1);
+  __ RestoreCSP();
+  __ ret();
+}
+
+// Called when invoking compiled Dart code from interpreted Dart code.
+// Input parameters:
+//   LR : points to return address.
+//   R0 : raw code object of the Dart function to call.
+//   R1 : arguments raw descriptor array.
+//   R2 : address of first argument.
+//   R3 : current thread.
+void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
+    Assembler* assembler) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter");
+#else
+  // Copy the C stack pointer (R31) into the stack pointer we'll actually use
+  // to access the stack.
+  __ SetupDartSP();
+  __ Push(LR);  // Marker for the profiler.
+  __ EnterFrame(0);
+
+  // Push code object to PC marker slot.
+  __ ldr(TMP,
+         Address(R3,
+                 target::Thread::invoke_dart_code_from_bytecode_stub_offset()));
+  __ Push(TMP);
+
+  // Save the callee-saved registers.
+  for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
+    const Register r = static_cast<Register>(i);
+    // We use str instead of the Push macro because we will be pushing the PP
+    // register when it is not holding a pool-pointer since we are coming from
+    // C++ code.
+    __ str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+  }
+
+  // Save the bottom 64-bits of callee-saved V registers.
+  for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
+    const VRegister r = static_cast<VRegister>(i);
+    __ PushDouble(r);
+  }
+
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != R3) {
+    __ mov(THR, R3);
+  }
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+
+  // Save the current VMTag on the stack.
+  __ LoadFromOffset(R4, THR, target::Thread::vm_tag_offset());
+  __ Push(R4);
+
+  // Save top resource and top exit frame info. Use R6 as a temporary register.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ LoadFromOffset(R6, THR, target::Thread::top_resource_offset());
+  __ StoreToOffset(ZR, THR, target::Thread::top_resource_offset());
+  __ Push(R6);
+  __ LoadFromOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+  // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
+  // with the code below.
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -22);
+  __ Push(R6);
+
+  // Mark that the thread is executing Dart code. Do this after initializing the
+  // exit link for the profiler.
+  __ LoadImmediate(R6, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R6, THR, target::Thread::vm_tag_offset());
+
+  // Load arguments descriptor array into R4, which is passed to Dart code.
+  __ mov(R4, R1);
+
+  // Load number of arguments into R5 and adjust count for type arguments.
+  __ LoadFieldFromOffset(R5, R4, target::ArgumentsDescriptor::count_offset());
+  __ LoadFieldFromOffset(R3, R4,
+                         target::ArgumentsDescriptor::type_args_len_offset());
+  __ AddImmediate(TMP, R5, 1);  // Include the type arguments.
+  __ cmp(R3, Operand(0));
+  __ csinc(R5, R5, TMP, EQ);  // R5 <- (R3 == 0) ? R5 : TMP + 1 (R5 : R5 + 2).
+  __ SmiUntag(R5);
+
+  // R2 points to first argument.
+  // Set up arguments for the Dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+  __ cmp(R5, Operand(0));
+  __ b(&done_push_arguments, EQ);  // check if there are arguments.
+  __ LoadImmediate(R1, 0);
+  __ Bind(&push_arguments);
+  __ ldr(R3, Address(R2));
+  __ Push(R3);
+  __ add(R1, R1, Operand(1));
+  __ add(R2, R2, Operand(target::kWordSize));
+  __ cmp(R1, Operand(R5));
+  __ b(&push_arguments, LT);
+  __ Bind(&done_push_arguments);
+
+  // We now load the pool pointer(PP) with a GC safe value as we are about to
+  // invoke dart code. We don't need a real object pool here.
+  // Smi zero does not work because ARM64 assumes PP to be untagged.
+  __ LoadObject(PP, NullObject());
+
+  // Call the Dart code entrypoint.
+  __ mov(CODE_REG, R0);
+  __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ blr(R0);  // R4 is the arguments descriptor array.
+
+  // Get rid of arguments pushed on the stack.
+  __ AddImmediate(
+      SP, FP,
+      target::frame_layout.exit_link_slot_from_entry_fp * target::kWordSize);
+
+  // Restore the saved top exit frame info and top resource back into the
+  // Isolate structure. Uses R6 as a temporary register for this.
+  __ Pop(R6);
+  __ StoreToOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
+  __ Pop(R6);
+  __ StoreToOffset(R6, THR, target::Thread::top_resource_offset());
+
+  // Restore the current VMTag from the stack.
+  __ Pop(R4);
+  __ StoreToOffset(R4, THR, target::Thread::vm_tag_offset());
+
+  // Restore the bottom 64-bits of callee-saved V registers.
+  for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
+    const VRegister r = static_cast<VRegister>(i);
+    __ PopDouble(r);
+  }
+
+  // Restore C++ ABI callee-saved registers.
+  for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
+    Register r = static_cast<Register>(i);
+    // We use ldr instead of the Pop macro because we will be popping the PP
+    // register when it is not holding a pool-pointer since we are returning to
+    // C++ code. We also skip the dart stack pointer SP, since we are still
+    // using it as the stack pointer.
+    __ ldr(r, Address(SP, 1 * target::kWordSize, Address::PostIndex));
+  }
+
+  // Restore the frame pointer and C stack pointer and return.
+  __ LeaveFrame();
+  __ Drop(1);
+  __ RestoreCSP();
+  __ ret();
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+}
+
+// Called for inline allocation of contexts.
+// Input:
+//   R1: number of context variables.
+// Output:
+//   R0: new allocated RawContext object.
+void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
+  if (FLAG_inline_alloc) {
+    Label slow_case;
+    // First compute the rounded instance size.
+    // R1: number of context variables.
+    intptr_t fixed_size_plus_alignment_padding =
+        target::Context::header_size() +
+        target::ObjectAlignment::kObjectAlignment - 1;
+    __ LoadImmediate(R2, fixed_size_plus_alignment_padding);
+    __ add(R2, R2, Operand(R1, LSL, 3));
+    ASSERT(kSmiTagShift == 1);
+    __ andi(R2, R2,
+            Immediate(~(target::ObjectAlignment::kObjectAlignment - 1)));
+
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, R4, &slow_case));
+    // Now allocate the object.
+    // R1: number of context variables.
+    // R2: object size.
+    const intptr_t cid = kContextCid;
+    __ ldr(R0, Address(THR, target::Thread::top_offset()));
+    __ add(R3, R2, Operand(R0));
+    // Check if the allocation fits into the remaining space.
+    // R0: potential new object.
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: potential next object start.
+    __ ldr(TMP, Address(THR, target::Thread::end_offset()));
+    __ CompareRegisters(R3, TMP);
+    if (FLAG_use_slow_path) {
+      __ b(&slow_case);
+    } else {
+      __ b(&slow_case, CS);  // Branch if unsigned higher or equal.
+    }
+
+    // Successfully allocated the object, now update top to point to
+    // next object start and initialize the object.
+    // R0: new object.
+    // R1: number of context variables.
+    // R2: object size.
+    // R3: next object start.
+    __ str(R3, Address(THR, target::Thread::top_offset()));
+    __ add(R0, R0, Operand(kHeapObjectTag));
+    NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2));
+
+    // Calculate the size tag.
+    // R0: new object.
+    // R1: number of context variables.
+    // R2: object size.
+    const intptr_t shift = target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2;
+    __ CompareImmediate(R2, target::RawObject::kSizeTagMaxSizeTag);
+    // If no size tag overflow, shift R2 left, else set R2 to zero.
+    __ LslImmediate(TMP, R2, shift);
+    __ csel(R2, TMP, R2, LS);
+    __ csel(R2, ZR, R2, HI);
+
+    // Get the class index and insert it into the tags.
+    // R2: size and bit tags.
+    const uint32_t tags =
+        target::MakeTagWordForNewSpaceObject(cid, /*instance_size=*/0);
+
+    __ LoadImmediate(TMP, tags);
+    __ orr(R2, R2, Operand(TMP));
+    __ StoreFieldToOffset(R2, R0, target::Object::tags_offset());
+
+    // Setup up number of context variables field.
+    // R0: new object.
+    // R1: number of context variables as integer value (not object).
+    __ StoreFieldToOffset(R1, R0, target::Context::num_variables_offset());
+
+    // Setup the parent field.
+    // R0: new object.
+    // R1: number of context variables.
+    __ LoadObject(R2, NullObject());
+    __ StoreFieldToOffset(R2, R0, target::Context::parent_offset());
+
+    // Initialize the context variables.
+    // R0: new object.
+    // R1: number of context variables.
+    // R2: raw null.
+    Label loop, done;
+    __ AddImmediate(R3, R0,
+                    target::Context::variable_offset(0) - kHeapObjectTag);
+    __ Bind(&loop);
+    __ subs(R1, R1, Operand(1));
+    __ b(&done, MI);
+    __ str(R2, Address(R3, R1, UXTX, Address::Scaled));
+    __ b(&loop, NE);  // Loop if R1 not zero.
+    __ Bind(&done);
+
+    // Done allocating and initializing the context.
+    // R0: new object.
+    __ ret();
+
+    __ Bind(&slow_case);
+  }
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  __ SmiTag(R1);
+  __ PushObject(NullObject());
+  __ Push(R1);
+  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
+  __ Drop(1);  // Pop number of context variables argument.
+  __ Pop(R0);  // Pop the new context object.
+  // R0: new object
+  // Restore the frame pointer.
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+    if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
+
+    Register reg = static_cast<Register>(i);
+    intptr_t start = __ CodeSize();
+    __ Push(LR);
+    __ Push(kWriteBarrierObjectReg);
+    __ mov(kWriteBarrierObjectReg, reg);
+    __ ldr(LR,
+           Address(THR, target::Thread::write_barrier_entry_point_offset()));
+    __ blr(LR);
+    __ Pop(kWriteBarrierObjectReg);
+    __ Pop(LR);
+    __ ret(LR);
+    intptr_t end = __ CodeSize();
+
+    RELEASE_ASSERT(end - start == kStoreBufferWrapperSize);
+  }
+}
+
+// Helper stub to implement Assembler::StoreIntoObject/Array.
+// Input parameters:
+//   R1: Object (old)
+//   R0: Value (old or new)
+//  R25: Slot
+// If R0 is new, add R1 to the store buffer. Otherwise R0 is old, mark R0
+// and add it to the mark list.
+COMPILE_ASSERT(kWriteBarrierObjectReg == R1);
+COMPILE_ASSERT(kWriteBarrierValueReg == R0);
+COMPILE_ASSERT(kWriteBarrierSlotReg == R25);
+static void GenerateWriteBarrierStubHelper(Assembler* assembler,
+                                           Address stub_code,
+                                           bool cards) {
+  Label add_to_mark_stack, remember_card;
+  __ tbz(&add_to_mark_stack, R0,
+         target::ObjectAlignment::kNewObjectBitPosition);
+
+  if (cards) {
+    __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
+    __ tbnz(&remember_card, TMP, target::RawObject::kCardRememberedBit);
+  } else {
+#if defined(DEBUG)
+    Label ok;
+    __ LoadFieldFromOffset(TMP, R1, target::Object::tags_offset(), kWord);
+    __ tbz(&ok, TMP, target::RawObject::kCardRememberedBit);
+    __ Stop("Wrong barrier");
+    __ Bind(&ok);
+#endif
+  }
+
+  // Save values being destroyed.
+  __ Push(R2);
+  __ Push(R3);
+  __ Push(R4);
+
+  // Atomically set the remembered bit of the object header.
+  ASSERT(target::Object::tags_offset() == 0);
+  __ sub(R3, R1, Operand(kHeapObjectTag));
+  // R3: Untagged address of header word (ldxr/stxr do not support offsets).
+  // Note that we use 32 bit operations here to match the size of the
+  // background sweeper which is also manipulating this 32 bit word.
+  Label retry;
+  __ Bind(&retry);
+  __ ldxr(R2, R3, kWord);
+  __ AndImmediate(R2, R2, ~(1 << target::RawObject::kOldAndNotRememberedBit));
+  __ stxr(R4, R2, R3, kWord);
+  __ cbnz(&retry, R4);
+
+  // Load the StoreBuffer block out of the thread. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
+  __ LoadFromOffset(R4, THR, target::Thread::store_buffer_block_offset());
+  __ LoadFromOffset(R2, R4, target::StoreBufferBlock::top_offset(),
+                    kUnsignedWord);
+  __ add(R3, R4, Operand(R2, LSL, target::kWordSizeLog2));
+  __ StoreToOffset(R1, R3, target::StoreBufferBlock::pointers_offset());
+
+  // Increment top_ and check for overflow.
+  // R2: top_.
+  // R4: StoreBufferBlock.
+  Label overflow;
+  __ add(R2, R2, Operand(1));
+  __ StoreToOffset(R2, R4, target::StoreBufferBlock::top_offset(),
+                   kUnsignedWord);
+  __ CompareImmediate(R2, target::StoreBufferBlock::kSize);
+  // Restore values.
+  __ Pop(R4);
+  __ Pop(R3);
+  __ Pop(R2);
+  __ b(&overflow, EQ);
+  __ ret();
+
+  // Handle overflow: Call the runtime leaf function.
+  __ Bind(&overflow);
+  // Setup frame, push callee-saved registers.
+
+  __ Push(CODE_REG);
+  __ ldr(CODE_REG, stub_code);
+  __ EnterCallRuntimeFrame(0 * target::kWordSize);
+  __ mov(R0, THR);
+  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
+  // Restore callee-saved registers, tear down frame.
+  __ LeaveCallRuntimeFrame();
+  __ Pop(CODE_REG);
+  __ ret();
+
+  __ Bind(&add_to_mark_stack);
+  __ Push(R2);  // Spill.
+  __ Push(R3);  // Spill.
+  __ Push(R4);  // Spill.
+
+  // Atomically clear kOldAndNotMarkedBit.
+  // Note that we use 32 bit operations here to match the size of the
+  // background sweeper which is also manipulating this 32 bit word.
+  Label marking_retry, lost_race, marking_overflow;
+  ASSERT(target::Object::tags_offset() == 0);
+  __ sub(R3, R0, Operand(kHeapObjectTag));
+  // R3: Untagged address of header word (ldxr/stxr do not support offsets).
+  __ Bind(&marking_retry);
+  __ ldxr(R2, R3, kWord);
+  __ tbz(&lost_race, R2, target::RawObject::kOldAndNotMarkedBit);
+  __ AndImmediate(R2, R2, ~(1 << target::RawObject::kOldAndNotMarkedBit));
+  __ stxr(R4, R2, R3, kWord);
+  __ cbnz(&marking_retry, R4);
+
+  __ LoadFromOffset(R4, THR, target::Thread::marking_stack_block_offset());
+  __ LoadFromOffset(R2, R4, target::MarkingStackBlock::top_offset(),
+                    kUnsignedWord);
+  __ add(R3, R4, Operand(R2, LSL, target::kWordSizeLog2));
+  __ StoreToOffset(R0, R3, target::MarkingStackBlock::pointers_offset());
+  __ add(R2, R2, Operand(1));
+  __ StoreToOffset(R2, R4, target::MarkingStackBlock::top_offset(),
+                   kUnsignedWord);
+  __ CompareImmediate(R2, target::MarkingStackBlock::kSize);
+  __ Pop(R4);  // Unspill.
+  __ Pop(R3);  // Unspill.
+  __ Pop(R2);  // Unspill.
+  __ b(&marking_overflow, EQ);
+  __ ret();
+
+  __ Bind(&marking_overflow);
+  __ Push(CODE_REG);
+  __ ldr(CODE_REG, stub_code);
+  __ EnterCallRuntimeFrame(0 * target::kWordSize);
+  __ mov(R0, THR);
+  __ CallRuntime(kMarkingStackBlockProcessRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ Pop(CODE_REG);
+  __ ret();
+
+  __ Bind(&lost_race);
+  __ Pop(R4);  // Unspill.
+  __ Pop(R3);  // Unspill.
+  __ Pop(R2);  // Unspill.
+  __ ret();
+
+  if (cards) {
+    Label remember_card_slow;
+
+    // Get card table.
+    __ Bind(&remember_card);
+    __ AndImmediate(TMP, R1, target::kPageMask);  // HeapPage.
+    __ ldr(TMP,
+           Address(TMP, target::HeapPage::card_table_offset()));  // Card table.
+    __ cbz(&remember_card_slow, TMP);
+
+    // Dirty the card.
+    __ AndImmediate(TMP, R1, target::kPageMask);  // HeapPage.
+    __ sub(R25, R25, Operand(TMP));               // Offset in page.
+    __ ldr(TMP,
+           Address(TMP, target::HeapPage::card_table_offset()));  // Card table.
+    __ add(TMP, TMP,
+           Operand(R25, LSR,
+                   target::HeapPage::kBytesPerCardLog2));  // Card address.
+    __ str(R1, Address(TMP, 0),
+           kUnsignedByte);  // Low byte of R1 is non-zero from object tag.
+    __ ret();
+
+    // Card table not yet allocated.
+    __ Bind(&remember_card_slow);
+    __ Push(CODE_REG);
+    __ PushPair(R0, R1);
+    __ ldr(CODE_REG, stub_code);
+    __ mov(R0, R1);   // Arg0 = Object
+    __ mov(R1, R25);  // Arg1 = Slot
+    __ EnterCallRuntimeFrame(0);
+    __ CallRuntime(kRememberCardRuntimeEntry, 2);
+    __ LeaveCallRuntimeFrame();
+    __ PopPair(R0, R1);
+    __ Pop(CODE_REG);
+    __ ret();
+  }
+}
+
+void StubCodeCompiler::GenerateWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler, Address(THR, target::Thread::write_barrier_code_offset()),
+      false);
+}
+
+void StubCodeCompiler::GenerateArrayWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler,
+      Address(THR, target::Thread::array_write_barrier_code_offset()), true);
+}
+
+// Called for inline allocation of objects.
+// Input parameters:
+//   LR : return address.
+//   SP + 0 : 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);
+
+  const Register kTypeArgumentsReg = R1;
+  const Register kInstanceReg = R0;
+  const Register kNullReg = R3;
+  const Register kTempReg = R4;
+  const Register kTopReg = R5;
+
+  // 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::InstanceSize(cls);
+  ASSERT(instance_size > 0);
+  if (is_cls_parameterized) {
+    __ ldr(kTypeArgumentsReg, Address(SP));
+  }
+
+  __ 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);
+
+    // 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;
+      }
+    } 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 (is_cls_parameterized) {
+      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
+      __ StoreToOffset(kTypeArgumentsReg, kInstanceReg, offset);
+    }
+    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
+    __ ret();
+
+    __ Bind(&slow_case);
+  }
+
+  // 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).
+  __ LeaveStubFrame();                  // Restores correct SP.
+  __ ret();
+}
+
+// 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.
+// Input parameters:
+//  LR : return address.
+//  SP : address of last argument.
+//  R4: arguments descriptor array.
+void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub(
+    Assembler* assembler) {
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
+  __ LoadFromOffset(R6, TMP,
+                    target::frame_layout.param_end_from_fp * target::kWordSize);
+
+  // Push space for the return value.
+  // Push the receiver.
+  // Push arguments descriptor array.
+  __ Push(ZR);
+  __ Push(R6);
+  __ Push(R4);
+
+  // Adjust arguments count.
+  __ LoadFieldFromOffset(R3, R4,
+                         target::ArgumentsDescriptor::type_args_len_offset());
+  __ AddImmediate(TMP, R2, 1);  // Include the type arguments.
+  __ cmp(R3, Operand(0));
+  __ csinc(R2, R2, TMP, EQ);  // R2 <- (R3 == 0) ? R2 : TMP + 1 (R2 : R2 + 2).
+
+  // R2: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+
+  const intptr_t kNumArgs = 3;
+  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+  // noSuchMethod on closures always throws an error, so it will never return.
+  __ brk(0);
+}
+
+//  R6: function object.
+//  R5: inline cache data object.
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
+void StubCodeCompiler::GenerateOptimizedUsageCounterIncrement(
+    Assembler* assembler) {
+  Register ic_reg = R5;
+  Register func_reg = R6;
+  if (FLAG_trace_optimized_ic_calls) {
+    __ EnterStubFrame();
+    __ Push(R6);        // Preserve.
+    __ Push(R5);        // Preserve.
+    __ Push(ic_reg);    // Argument.
+    __ Push(func_reg);  // Argument.
+    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
+    __ Drop(2);  // Discard argument;
+    __ Pop(R5);  // Restore.
+    __ Pop(R6);  // Restore.
+    __ LeaveStubFrame();
+  }
+  __ LoadFieldFromOffset(R7, func_reg, target::Function::usage_counter_offset(),
+                         kWord);
+  __ add(R7, R7, Operand(1));
+  __ StoreFieldToOffset(R7, func_reg, target::Function::usage_counter_offset(),
+                        kWord);
+}
+
+// Loads function into 'temp_reg'.
+void StubCodeCompiler::GenerateUsageCounterIncrement(Assembler* assembler,
+                                                     Register temp_reg) {
+  if (FLAG_optimization_counter_threshold >= 0) {
+    Register ic_reg = R5;
+    Register func_reg = temp_reg;
+    ASSERT(temp_reg == R6);
+    __ Comment("Increment function counter");
+    __ LoadFieldFromOffset(func_reg, ic_reg, target::ICData::owner_offset());
+    __ LoadFieldFromOffset(R7, func_reg,
+                           target::Function::usage_counter_offset(), kWord);
+    __ AddImmediate(R7, 1);
+    __ StoreFieldToOffset(R7, func_reg,
+                          target::Function::usage_counter_offset(), kWord);
+  }
+}
+
+// Note: R5 must be preserved.
+// Attempt a quick Smi operation for known operations ('kind'). The ICData
+// must have been primed with a Smi/Smi check that will be used for counting
+// the invocations.
+static void EmitFastSmiOp(Assembler* assembler,
+                          Token::Kind kind,
+                          intptr_t num_args,
+                          Label* not_smi_or_overflow) {
+  __ Comment("Fast Smi op");
+  __ ldr(R0, Address(SP, +0 * target::kWordSize));  // Right.
+  __ ldr(R1, Address(SP, +1 * target::kWordSize));  // Left.
+  __ orr(TMP, R0, Operand(R1));
+  __ BranchIfNotSmi(TMP, not_smi_or_overflow);
+  switch (kind) {
+    case Token::kADD: {
+      __ adds(R0, R1, Operand(R0));   // Adds.
+      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
+      break;
+    }
+    case Token::kSUB: {
+      __ subs(R0, R1, Operand(R0));   // Subtract.
+      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
+      break;
+    }
+    case Token::kEQ: {
+      __ CompareRegisters(R0, R1);
+      __ LoadObject(R0, CastHandle<Object>(TrueObject()));
+      __ LoadObject(R1, CastHandle<Object>(FalseObject()));
+      __ csel(R0, R1, R0, NE);
+      break;
+    }
+    default:
+      UNIMPLEMENTED();
+  }
+
+  // R5: IC data object (preserved).
+  __ LoadFieldFromOffset(R6, R5, target::ICData::entries_offset());
+  // R6: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R6, target::Array::data_offset() - kHeapObjectTag);
+// R6: points directly to the first ic data array element.
+#if defined(DEBUG)
+  // Check that first entry is for Smi/Smi.
+  Label error, ok;
+  const intptr_t imm_smi_cid = target::ToRawSmi(kSmiCid);
+  __ ldr(R1, Address(R6, 0));
+  __ CompareImmediate(R1, imm_smi_cid);
+  __ b(&error, NE);
+  __ ldr(R1, Address(R6, target::kWordSize));
+  __ CompareImmediate(R1, imm_smi_cid);
+  __ b(&ok, EQ);
+  __ Bind(&error);
+  __ Stop("Incorrect IC data");
+  __ Bind(&ok);
+#endif
+  if (FLAG_optimization_counter_threshold >= 0) {
+    const intptr_t count_offset =
+        target::ICData::CountIndexFor(num_args) * target::kWordSize;
+    // Update counter, ignore overflow.
+    __ LoadFromOffset(R1, R6, count_offset);
+    __ adds(R1, R1, Operand(target::ToRawSmi(1)));
+    __ StoreToOffset(R1, R6, count_offset);
+  }
+
+  __ ret();
+}
+
+// Generate inline cache check for 'num_args'.
+//  LR: return address.
+//  R5: inline cache data object.
+// Control flow:
+// - If receiver is null -> jump to IC miss.
+// - If receiver is Smi -> load Smi class.
+// - If receiver is not-Smi -> load receiver's class.
+// - Check if 'num_args' (including receiver) match any IC data group.
+// - Match found -> jump to target.
+// - Match not found -> jump to IC miss.
+void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss,
+    Token::Kind kind,
+    bool optimized,
+    bool exactness_check /* = false */) {
+  ASSERT(!exactness_check);
+  ASSERT(num_args == 1 || num_args == 2);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == num_args.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ LoadFromOffset(R6, R5,
+                      target::ICData::state_bits_offset() - kHeapObjectTag,
+                      kUnsignedWord);
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ andi(R6, R6, Immediate(target::ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R6, num_args);
+    __ b(&ok, EQ);
+    __ Stop("Incorrect stub for IC data");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  Label stepping, done_stepping;
+  if (!optimized) {
+    __ Comment("Check single stepping");
+    __ LoadIsolate(R6);
+    __ LoadFromOffset(R6, R6, target::Isolate::single_step_offset(),
+                      kUnsignedByte);
+    __ CompareRegisters(R6, ZR);
+    __ b(&stepping, NE);
+    __ Bind(&done_stepping);
+  }
+#endif
+
+  Label not_smi_or_overflow;
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
+
+  __ Comment("Extract ICData initial values and receiver cid");
+  // Load arguments descriptor into R4.
+  __ LoadFieldFromOffset(R4, R5, target::ICData::arguments_descriptor_offset());
+  // Loop that checks if there is an IC data match.
+  Label loop, found, miss;
+  // R5: IC data object (preserved).
+  __ LoadFieldFromOffset(R6, R5, target::ICData::entries_offset());
+  // R6: ic_data_array with check entries: classes and target functions.
+  __ AddImmediate(R6, target::Array::data_offset() - kHeapObjectTag);
+  // R6: points directly to the first ic data array element.
+
+  // 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());
+  __ SmiUntag(R7);  // Untag so we can use the LSL 3 addressing mode.
+  __ sub(R7, R7, Operand(1));
+
+  // R0 <- [SP + (R7 << 3)]
+  __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled));
+  __ LoadTaggedClassIdMayBeSmi(R0, R0);
+
+  if (num_args == 2) {
+    __ AddImmediate(R1, R7, -1);
+    // R1 <- [SP + (R1 << 3)]
+    __ ldr(R1, Address(SP, R1, UXTX, Address::Scaled));
+    __ LoadTaggedClassIdMayBeSmi(R1, R1);
+  }
+
+  // We unroll the generic one that is generated once more than the others.
+  const bool optimize = kind == Token::kILLEGAL;
+
+  __ Comment("ICData loop");
+  __ Bind(&loop);
+  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
+    Label update;
+
+    __ LoadFromOffset(R2, R6, 0);
+    __ CompareRegisters(R0, R2);  // Class id match?
+    if (num_args == 2) {
+      __ b(&update, NE);  // Continue.
+      __ LoadFromOffset(R2, R6, target::kWordSize);
+      __ CompareRegisters(R1, R2);  // Class id match?
+    }
+    __ b(&found, EQ);  // Break.
+
+    __ Bind(&update);
+
+    const intptr_t entry_size =
+        target::ICData::TestEntryLengthFor(num_args, exactness_check) *
+        target::kWordSize;
+    __ AddImmediate(R6, entry_size);  // Next entry.
+
+    __ CompareImmediate(R2, target::ToRawSmi(kIllegalCid));  // Done?
+    if (unroll == 0) {
+      __ b(&loop, NE);
+    } else {
+      __ b(&miss, EQ);
+    }
+  }
+
+  __ Bind(&miss);
+  __ Comment("IC miss");
+  // Compute address of arguments.
+  // R7: argument_count - 1 (untagged).
+  // R7 <- SP + (R7 << 3)
+  __ add(R7, SP, Operand(R7, UXTX, 3));  // R7 is Untagged.
+  // R7: address of receiver.
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Preserve IC data object and arguments descriptor array and
+  // setup space on stack for result (target code object).
+  __ Push(R4);  // Preserve arguments descriptor array.
+  __ Push(R5);  // Preserve IC Data.
+  // Setup space on stack for the result (target code object).
+  __ Push(ZR);
+  // Push call arguments.
+  for (intptr_t i = 0; i < num_args; i++) {
+    __ LoadFromOffset(TMP, R7, -i * target::kWordSize);
+    __ Push(TMP);
+  }
+  // Pass IC data object.
+  __ Push(R5);
+  __ CallRuntime(handle_ic_miss, num_args + 1);
+  // Remove the call arguments pushed earlier, including the IC data object.
+  __ Drop(num_args + 1);
+  // Pop returned function object into R0.
+  // Restore arguments descriptor array and IC data array.
+  __ Pop(R0);  // Pop returned function object into R0.
+  __ Pop(R5);  // Restore IC Data.
+  __ Pop(R4);  // Restore arguments descriptor array.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  Label call_target_function;
+  if (!FLAG_lazy_dispatchers) {
+    GenerateDispatcherCode(assembler, &call_target_function);
+  } else {
+    __ b(&call_target_function);
+  }
+
+  __ Bind(&found);
+  __ Comment("Update caller's counter");
+  // R6: pointer to an IC data check group.
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(num_args) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(num_args) * target::kWordSize;
+  __ LoadFromOffset(R0, R6, target_offset);
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    // Update counter, ignore overflow.
+    __ LoadFromOffset(R1, R6, count_offset);
+    __ adds(R1, R1, Operand(target::ToRawSmi(1)));
+    __ StoreToOffset(R1, R6, count_offset);
+  }
+
+  __ Comment("Call target");
+  __ Bind(&call_target_function);
+  // R0: target function.
+  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset());
+  __ br(R2);
+
+#if !defined(PRODUCT)
+  if (!optimized) {
+    __ Bind(&stepping);
+    __ EnterStubFrame();
+    __ Push(R5);  // Preserve IC data.
+    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+    __ Pop(R5);
+    __ RestoreCodePointer();
+    __ LeaveStubFrame();
+    __ b(&done_stepping);
+  }
+#endif
+}
+
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+//  LR: return address.
+//  R5: inline cache data object.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+//   - N classes.
+//   - 1 target function.
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
+void StubCodeCompiler::GenerateTwoArgsCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+}
+
+void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+}
+
+void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+}
+
+void StubCodeCompiler::GenerateOneArgOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
+                                    Token::kILLEGAL, true /* optimized */);
+}
+
+void StubCodeCompiler::
+    GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+        Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
+void StubCodeCompiler::GenerateTwoArgsOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL, true /* optimized */);
+}
+
+void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == 0.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ LoadFromOffset(R6, R5,
+                      target::ICData::state_bits_offset() - kHeapObjectTag,
+                      kUnsignedWord);
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ andi(R6, R6, Immediate(target::ICData::NumArgsTestedMask()));
+    __ CompareImmediate(R6, 0);
+    __ b(&ok, EQ);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+  // Check single stepping.
+#if !defined(PRODUCT)
+  Label stepping, done_stepping;
+  __ LoadIsolate(R6);
+  __ LoadFromOffset(R6, R6, target::Isolate::single_step_offset(),
+                    kUnsignedByte);
+  __ CompareImmediate(R6, 0);
+  __ b(&stepping, NE);
+  __ Bind(&done_stepping);
+#endif
+
+  // R5: IC data object (preserved).
+  __ LoadFieldFromOffset(R6, R5, target::ICData::entries_offset());
+  // R6: ic_data_array with entries: target functions and count.
+  __ AddImmediate(R6, target::Array::data_offset() - kHeapObjectTag);
+  // R6: points directly to the first ic data array element.
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(0) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(0) * target::kWordSize;
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    // Increment count for this call, ignore overflow.
+    __ LoadFromOffset(R1, R6, count_offset);
+    __ adds(R1, R1, Operand(target::ToRawSmi(1)));
+    __ StoreToOffset(R1, R6, count_offset);
+  }
+
+  // Load arguments descriptor into R4.
+  __ LoadFieldFromOffset(R4, R5, target::ICData::arguments_descriptor_offset());
+
+  // Get function and call it, if possible.
+  __ LoadFromOffset(R0, R6, target_offset);
+  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset());
+  __ br(R2);
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ Push(R5);  // Preserve IC data.
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ Pop(R5);
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ b(&done_stepping);
+#endif
+}
+
+void StubCodeCompiler::GenerateOneArgUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateTwoArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+}
+
+// Stub for compiling a function and jumping to the compiled code.
+// R4: Arguments descriptor.
+// R0: Function.
+void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) {
+  // Preserve arg desc.
+  __ EnterStubFrame();
+  __ Push(R4);  // Save arg. desc.
+  __ Push(R0);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ Pop(R0);  // Restore argument.
+  __ Pop(R4);  // Restore arg desc.
+  __ LeaveStubFrame();
+
+  // When using the interpreter, the function's code may now point to the
+  // InterpretCall stub. Make sure R0, R4, and R5 are preserved.
+  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset());
+  __ br(R2);
+}
+
+// Stub for interpreting a function call.
+// R4: Arguments descriptor.
+// R0: Function.
+void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter")
+#else
+  __ SetPrologueOffset();
+  __ EnterStubFrame();
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ LoadFromOffset(R8, THR, target::Thread::vm_tag_offset());
+    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
+    __ b(&ok, EQ);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Adjust arguments count for type arguments vector.
+  __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset());
+  __ SmiUntag(R2);
+  __ LoadFieldFromOffset(R1, R4,
+                         target::ArgumentsDescriptor::type_args_len_offset());
+  __ cmp(R1, Operand(0));
+  __ csinc(R2, R2, R2, EQ);  // R2 <- (R1 == 0) ? R2 : R2 + 1.
+
+  // Compute argv.
+  __ add(R3, ZR, Operand(R2, LSL, 3));
+  __ add(R3, FP, Operand(R3));
+  __ AddImmediate(R3,
+                  target::frame_layout.param_end_from_fp * target::kWordSize);
+
+  // Indicate decreasing memory addresses of arguments with negative argc.
+  __ neg(R2, R2);
+
+  // Align frame before entering C++ world. No shadow stack space required.
+  __ ReserveAlignedFrameSpace(0 * target::kWordSize);
+
+  // Pass arguments in registers.
+  // R0: Function.
+  __ mov(R1, R4);  // Arguments descriptor.
+  // R2: Negative argc.
+  // R3: Argv.
+  __ mov(R4, THR);  // Thread.
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
+
+  // Mark that the thread is executing VM code.
+  __ LoadFromOffset(R5, THR,
+                    target::Thread::interpret_call_entry_point_offset());
+  __ StoreToOffset(R5, THR, target::Thread::vm_tag_offset());
+
+  // We are entering runtime code, so the C stack pointer must be restored from
+  // the stack limit to the top of the stack. We cache the stack limit address
+  // in a callee-saved register.
+  __ mov(R25, CSP);
+  __ mov(CSP, SP);
+
+  __ blr(R5);
+
+  // Restore SP and CSP.
+  __ mov(SP, CSP);
+  __ mov(CSP, R25);
+
+  // Refresh write barrier mask.
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+
+  // Mark that the thread is executing Dart code.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
+
+  // Reset exit frame information in Isolate structure.
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+
+  __ LeaveStubFrame();
+  __ ret();
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+}
+
+// R5: Contains an ICData.
+void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R5);
+  __ Push(ZR);  // Space for result.
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ Pop(CODE_REG);
+  __ Pop(R5);
+  __ LeaveStubFrame();
+  __ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
+  __ br(R0);
+}
+
+void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(ZR);  // Space for result.
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ Pop(CODE_REG);
+  __ LeaveStubFrame();
+  __ LoadFieldFromOffset(R0, CODE_REG, target::Code::entry_point_offset());
+  __ br(R0);
+}
+
+// Called only from unoptimized code. All relevant registers have been saved.
+void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
+#if defined(PRODUCT)
+  __ ret();
+#else
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(R1);
+  __ LoadFromOffset(R1, R1, target::Isolate::single_step_offset(),
+                    kUnsignedByte);
+  __ CompareImmediate(R1, 0);
+  __ b(&stepping, NE);
+  __ Bind(&done_stepping);
+  __ ret();
+
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ LeaveStubFrame();
+  __ b(&done_stepping);
+#endif  // defined(PRODUCT)
+}
+
+// Used to check class and type arguments. Arguments passed in registers:
+// LR: return address.
+// R0: instance (must be preserved).
+// R1: instantiator type arguments (only if n == 4, can be raw_null).
+// R2: function type arguments (only if n == 4, can be raw_null).
+// R3: target::SubtypeTestCache.
+//
+// Preserves R0/R2/R8.
+//
+// Result in R1: null -> not found, otherwise result (true or false).
+static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+
+  const Register kCacheReg = R3;
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+
+  const Register kInstanceCidOrFunction = R6;
+  const Register kInstanceInstantiatorTypeArgumentsReg = R4;
+  const Register kInstanceParentFunctionTypeArgumentsReg = R9;
+  const Register kInstanceDelayedFunctionTypeArgumentsReg = R10;
+
+  const Register kNullReg = R7;
+
+  __ LoadObject(kNullReg, NullObject());
+
+  // Loop initialization (moved up here to avoid having all dependent loads
+  // after each other).
+  __ ldr(kCacheReg,
+         FieldAddress(kCacheReg, target::SubtypeTestCache::cache_offset()));
+  __ AddImmediate(kCacheReg, target::Array::data_offset() - kHeapObjectTag);
+
+  Label loop, not_closure;
+  if (n >= 4) {
+    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
+  } else {
+    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
+  }
+  __ CompareImmediate(kInstanceCidOrFunction, kClosureCid);
+  __ b(&not_closure, NE);
+
+  // Closure handling.
+  {
+    __ ldr(kInstanceCidOrFunction,
+           FieldAddress(kInstanceReg, target::Closure::function_offset()));
+    if (n >= 2) {
+      __ ldr(
+          kInstanceInstantiatorTypeArgumentsReg,
+          FieldAddress(kInstanceReg,
+                       target::Closure::instantiator_type_arguments_offset()));
+      if (n >= 6) {
+        ASSERT(n == 6);
+        __ ldr(kInstanceParentFunctionTypeArgumentsReg,
+               FieldAddress(kInstanceReg,
+                            target::Closure::function_type_arguments_offset()));
+        __ ldr(kInstanceDelayedFunctionTypeArgumentsReg,
+               FieldAddress(kInstanceReg,
+                            target::Closure::delayed_type_arguments_offset()));
+      }
+    }
+    __ b(&loop);
+  }
+
+  // Non-Closure handling.
+  {
+    __ Bind(&not_closure);
+    if (n == 1) {
+      __ SmiTag(kInstanceCidOrFunction);
+    } else {
+      ASSERT(n >= 2);
+      Label has_no_type_arguments;
+      // [LoadClassById] also tags [kInstanceCidOrFunction] as a side-effect.
+      __ LoadClassById(R5, kInstanceCidOrFunction);
+      __ mov(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
+      __ LoadFieldFromOffset(
+          R5, R5, target::Class::type_arguments_field_offset_in_words_offset(),
+          kWord);
+      __ CompareImmediate(R5, target::Class::kNoTypeArguments);
+      __ b(&has_no_type_arguments, EQ);
+      __ add(R5, kInstanceReg, Operand(R5, LSL, 3));
+      __ ldr(kInstanceInstantiatorTypeArgumentsReg, FieldAddress(R5, 0));
+      __ Bind(&has_no_type_arguments);
+
+      if (n >= 6) {
+        __ mov(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
+        __ mov(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
+      }
+    }
+  }
+
+  Label found, not_found, next_iteration;
+
+  // Loop header
+  __ Bind(&loop);
+  __ ldr(R5, Address(kCacheReg,
+                     target::kWordSize *
+                         target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmp(R5, Operand(kNullReg));
+  __ b(&not_found, EQ);
+  __ cmp(R5, Operand(kInstanceCidOrFunction));
+  if (n == 1) {
+    __ b(&found, EQ);
+  } else {
+    __ b(&next_iteration, NE);
+    __ ldr(R5, Address(kCacheReg,
+                       target::kWordSize *
+                           target::SubtypeTestCache::kInstanceTypeArguments));
+    __ cmp(R5, Operand(kInstanceInstantiatorTypeArgumentsReg));
+    if (n == 2) {
+      __ b(&found, EQ);
+    } else {
+      __ b(&next_iteration, NE);
+      __ ldr(R5,
+             Address(kCacheReg,
+                     target::kWordSize *
+                         target::SubtypeTestCache::kInstantiatorTypeArguments));
+      __ cmp(R5, Operand(kInstantiatorTypeArgumentsReg));
+      __ b(&next_iteration, NE);
+      __ ldr(R5, Address(kCacheReg,
+                         target::kWordSize *
+                             target::SubtypeTestCache::kFunctionTypeArguments));
+      __ cmp(R5, Operand(kFunctionTypeArgumentsReg));
+      if (n == 4) {
+        __ b(&found, EQ);
+      } else {
+        ASSERT(n == 6);
+        __ b(&next_iteration, NE);
+
+        __ ldr(R5, Address(kCacheReg,
+                           target::kWordSize *
+                               target::SubtypeTestCache::
+                                   kInstanceParentFunctionTypeArguments));
+        __ cmp(R5, Operand(kInstanceParentFunctionTypeArgumentsReg));
+        __ b(&next_iteration, NE);
+
+        __ ldr(R5, Address(kCacheReg,
+                           target::kWordSize *
+                               target::SubtypeTestCache::
+                                   kInstanceDelayedFunctionTypeArguments));
+        __ cmp(R5, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
+        __ b(&found, EQ);
+      }
+    }
+  }
+  __ Bind(&next_iteration);
+  __ AddImmediate(kCacheReg, target::kWordSize *
+                                 target::SubtypeTestCache::kTestEntryLength);
+  __ b(&loop);
+
+  __ Bind(&found);
+  __ ldr(R1, Address(kCacheReg, target::kWordSize *
+                                    target::SubtypeTestCache::kTestResult));
+  __ ret();
+
+  __ Bind(&not_found);
+  __ mov(R1, kNullReg);
+  __ ret();
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype1TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 1);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 2);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 4);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 6);
+}
+
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+//   - R0 : instance to test against.
+//   - R2 : instantiator type arguments (if needed).
+//   - R1 : function type arguments (if needed).
+//
+//   - R3 : subtype test cache.
+//
+//   - R8 : type to test against.
+//   - R4 : name of destination variable.
+//
+// Preserves R0/R2.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  Label done;
+
+  const Register kInstanceReg = R0;
+  const Register kDstTypeReg = R8;
+
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  // Fast case for 'int'.
+  Label not_smi;
+  __ BranchIfNotSmi(kInstanceReg, &not_smi);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(IntType()));
+  __ BranchIf(EQUAL, &done);
+  __ Bind(&not_smi);
+
+  // Tail call the [SubtypeTestCache]-based implementation.
+  __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
+  __ ldr(R9, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ br(R9);
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  const Register kTypeRefReg = R8;
+
+  // We dereference the TypeRef and tail-call to it's type testing stub.
+  __ ldr(kTypeRefReg,
+         FieldAddress(kTypeRefReg, target::TypeRef::type_offset()));
+  __ ldr(R9, FieldAddress(
+                 kTypeRefReg,
+                 target::AbstractType::type_test_stub_entry_point_offset()));
+  __ br(R9);
+}
+
+void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
+                                            TypeCheckMode mode) {
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+
+  const Register kSubtypeTestCacheReg = R3;
+  const Register kDstTypeReg = R8;
+
+  __ PushObject(NullObject());  // Make room for result.
+  __ Push(kInstanceReg);
+  __ Push(kDstTypeReg);
+  __ Push(kInstantiatorTypeArgumentsReg);
+  __ Push(kFunctionTypeArgumentsReg);
+  __ PushObject(NullObject());
+  __ Push(kSubtypeTestCacheReg);
+  __ PushImmediate(target::ToRawSmi(mode));
+  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
+  __ Drop(1);  // mode
+  __ Pop(kSubtypeTestCacheReg);
+  __ Drop(1);  // dst_name
+  __ Pop(kFunctionTypeArgumentsReg);
+  __ Pop(kInstantiatorTypeArgumentsReg);
+  __ Pop(kDstTypeReg);
+  __ Pop(kInstanceReg);
+  __ Drop(1);  // Discard return value.
+}
+
+void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
+    Assembler* assembler) {
+  const Register kInstanceReg = R0;
+  Label done;
+
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
+  __ EnterStubFrame();
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
+  __ LeaveStubFrame();
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  const Register kInstanceReg = R0;
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kSubtypeTestCacheReg = R3;
+  const Register kDstTypeReg = R8;
+
+  __ EnterStubFrame();
+
+#ifdef DEBUG
+  // Guaranteed by caller.
+  Label no_error;
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(NOT_EQUAL, &no_error);
+  __ Breakpoint();
+  __ Bind(&no_error);
+#endif
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(kSubtypeTestCacheReg, NullObject());
+  __ BranchIf(EQUAL, &call_runtime);
+
+  const Register kTmp = R9;
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple_case, is_complex_case;
+  __ LoadClassId(kTmp, kDstTypeReg);
+  __ cmp(kTmp, Operand(kTypeCid));
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ ldr(kTmp, FieldAddress(kDstTypeReg, target::Type::type_state_offset()),
+         kByte);
+  __ cmp(kTmp,
+         Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // Check whether this [Type] is a function type.
+  __ ldr(kTmp, FieldAddress(kDstTypeReg, target::Type::signature_offset()));
+  __ CompareObject(kTmp, NullObject());
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
+  __ BranchIfSmi(kInstanceReg, &is_complex_case);
+
+  // Fall through to &is_simple_case
+
+  __ Bind(&is_simple_case);
+  {
+    __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchLink(StubCodeSubtype2TestCache());
+    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
+    __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime);
+  }
+
+  __ Bind(&is_complex_case);
+  {
+    __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchLink(StubCodeSubtype6TestCache());
+    __ CompareObject(R1, CastHandle<Object>(TrueObject()));
+    __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  // We cannot really ensure here that dynamic/Object/void never occur here
+  // (though it is guaranteed at dart_precompiled_runtime time).  This is
+  // because we do constant evaluation with default stubs and only install
+  // optimized versions before writing out the AOT snapshot.
+  // So dynamic/Object/void will run with default stub in constant evaluation.
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(DynamicType()));
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(ObjectType()));
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(VoidType()));
+  __ BranchIf(EQUAL, &done);
+
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
+
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateGetCStackPointerStub(Assembler* assembler) {
+  __ mov(R0, CSP);
+  __ ret();
+}
+
+// Jump to a frame on the call stack.
+// LR: return address.
+// R0: program_counter.
+// R1: stack_pointer.
+// R2: frame_pointer.
+// R3: thread.
+// Does not return.
+void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
+  ASSERT(kExceptionObjectReg == R0);
+  ASSERT(kStackTraceObjectReg == R1);
+  __ mov(LR, R0);  // Program counter.
+  __ mov(SP, R1);  // Stack pointer.
+  __ mov(FP, R2);  // Frame_pointer.
+  __ mov(THR, R3);
+  __ ldr(BARRIER_MASK,
+         Address(THR, target::Thread::write_barrier_mask_offset()));
+  // Set the tag.
+  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
+  __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
+  // Clear top exit frame.
+  __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+  // Restore the pool pointer.
+  __ RestoreCodePointer();
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ ldr(PP, Address(THR, target::Thread::global_object_pool_offset()));
+    __ sub(PP, PP, Operand(kHeapObjectTag));  // Pool in PP is untagged!
+  } else {
+    __ LoadPoolPointer();
+  }
+  __ ret();  // Jump to continuation point.
+}
+
+// Run an exception handler.  Execution comes from JumpToFrame
+// stub or from the simulator.
+//
+// The arguments are stored in the Thread object.
+// Does not return.
+void StubCodeCompiler::GenerateRunExceptionHandlerStub(Assembler* assembler) {
+  __ LoadFromOffset(LR, THR, target::Thread::resume_pc_offset());
+
+  word offset_from_thread = 0;
+  bool ok = target::CanLoadFromThread(NullObject(), &offset_from_thread);
+  ASSERT(ok);
+  __ LoadFromOffset(R2, THR, offset_from_thread);
+
+  // Exception object.
+  __ LoadFromOffset(R0, THR, target::Thread::active_exception_offset());
+  __ StoreToOffset(R2, THR, target::Thread::active_exception_offset());
+
+  // StackTrace object.
+  __ LoadFromOffset(R1, THR, target::Thread::active_stacktrace_offset());
+  __ StoreToOffset(R2, THR, target::Thread::active_stacktrace_offset());
+
+  __ ret();  // Jump to the exception handler code.
+}
+
+// Deoptimize a frame on the call stack before rewinding.
+// The arguments are stored in the Thread object.
+// No result.
+void StubCodeCompiler::GenerateDeoptForRewindStub(Assembler* assembler) {
+  // Push zap value instead of CODE_REG.
+  __ LoadImmediate(TMP, kZapCodeReg);
+  __ Push(TMP);
+
+  // Load the deopt pc into LR.
+  __ LoadFromOffset(LR, THR, target::Thread::resume_pc_offset());
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+
+  // After we have deoptimized, jump to the correct frame.
+  __ EnterStubFrame();
+  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
+  __ LeaveStubFrame();
+  __ brk(0);
+}
+
+// Calls to the runtime to optimize the given function.
+// R6: function to be re-optimized.
+// R4: argument descriptor (preserved).
+void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R4);
+  // Setup space on stack for the return value.
+  __ Push(ZR);
+  __ Push(R6);
+  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
+  __ Pop(R0);  // Discard argument.
+  __ Pop(R0);  // Get Function object
+  __ Pop(R4);  // Restore argument descriptor.
+  __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+  __ LoadFieldFromOffset(R1, R0, target::Function::entry_point_offset());
+  __ LeaveStubFrame();
+  __ br(R1);
+  __ brk(0);
+}
+
+// Does identical check (object references are equal or not equal) with special
+// checks for boxed numbers.
+// Left and right are pushed on stack.
+// Return Zero condition flag set if equal.
+// Note: A Mint cannot contain a value that would fit in Smi.
+static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
+                                                 const Register left,
+                                                 const Register right) {
+  Label reference_compare, done, check_mint;
+  // If any of the arguments is Smi do reference compare.
+  __ BranchIfSmi(left, &reference_compare);
+  __ BranchIfSmi(right, &reference_compare);
+
+  // Value compare for two doubles.
+  __ CompareClassId(left, kDoubleCid);
+  __ b(&check_mint, NE);
+  __ CompareClassId(right, kDoubleCid);
+  __ b(&done, NE);
+
+  // Double values bitwise compare.
+  __ LoadFieldFromOffset(left, left, target::Double::value_offset());
+  __ LoadFieldFromOffset(right, right, target::Double::value_offset());
+  __ b(&reference_compare);
+
+  __ Bind(&check_mint);
+  __ CompareClassId(left, kMintCid);
+  __ b(&reference_compare, NE);
+  __ CompareClassId(right, kMintCid);
+  __ b(&done, NE);
+  __ LoadFieldFromOffset(left, left, target::Mint::value_offset());
+  __ LoadFieldFromOffset(right, right, target::Mint::value_offset());
+
+  __ Bind(&reference_compare);
+  __ CompareRegisters(left, right);
+  __ Bind(&done);
+}
+
+// Called only from unoptimized code. All relevant registers have been saved.
+// LR: return address.
+// SP + 4: left operand.
+// SP + 0: right operand.
+// Return Zero condition flag set if equal.
+void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(R1);
+  __ LoadFromOffset(R1, R1, target::Isolate::single_step_offset(),
+                    kUnsignedByte);
+  __ CompareImmediate(R1, 0);
+  __ b(&stepping, NE);
+  __ Bind(&done_stepping);
+#endif
+
+  const Register left = R1;
+  const Register right = R0;
+  __ LoadFromOffset(left, SP, 1 * target::kWordSize);
+  __ LoadFromOffset(right, SP, 0 * target::kWordSize);
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
+  __ ret();
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ b(&done_stepping);
+#endif
+}
+
+// Called from optimized code only.
+// LR: return address.
+// SP + 4: left operand.
+// SP + 0: right operand.
+// Return Zero condition flag set if equal.
+void StubCodeCompiler::GenerateOptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+  const Register left = R1;
+  const Register right = R0;
+  __ LoadFromOffset(left, SP, 1 * target::kWordSize);
+  __ LoadFromOffset(right, SP, 0 * target::kWordSize);
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
+  __ ret();
+}
+
+// Called from megamorphic calls.
+//  R0: receiver
+//  R5: MegamorphicCache (preserved)
+// Passed to target:
+//  CODE_REG: target Code
+//  R4: arguments descriptor
+void StubCodeCompiler::GenerateMegamorphicCallStub(Assembler* assembler) {
+  // Jump if receiver is a smi.
+  Label smi_case;
+  __ BranchIfSmi(R0, &smi_case);
+
+  // Loads the cid of the object.
+  __ LoadClassId(R0, R0);
+
+  Label cid_loaded;
+  __ Bind(&cid_loaded);
+  __ ldr(R2, FieldAddress(R5, target::MegamorphicCache::buckets_offset()));
+  __ ldr(R1, FieldAddress(R5, target::MegamorphicCache::mask_offset()));
+  // R2: cache buckets array.
+  // R1: mask as a smi.
+
+  // Make the cid into a smi.
+  __ SmiTag(R0);
+  // R0: class ID of the receiver (smi).
+
+  // Compute the table index.
+  ASSERT(target::MegamorphicCache::kSpreadFactor == 7);
+  // Use lsl and sub to multiply with 7 == 8 - 1.
+  __ LslImmediate(R3, R0, 3);
+  __ sub(R3, R3, Operand(R0));
+  // R3: probe.
+  Label loop;
+  __ Bind(&loop);
+  __ and_(R3, R3, Operand(R1));
+
+  const intptr_t base = target::Array::data_offset();
+  // R3 is smi tagged, but table entries are 16 bytes, so LSL 3.
+  __ add(TMP, R2, Operand(R3, LSL, 3));
+  __ ldr(R6, FieldAddress(TMP, base));
+  Label probe_failed;
+  __ CompareRegisters(R6, R0);
+  __ b(&probe_failed, NE);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // illegal class id was found, the target is a cache miss handler that can
+  // be invoked as a normal Dart function.
+  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()));
+  } 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(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  }
+  __ br(R1);
+
+  // Probe failed, check if it is a miss.
+  __ Bind(&probe_failed);
+  ASSERT(kIllegalCid == 0);
+  __ tst(R6, Operand(R6));
+  __ b(&load_target, EQ);  // branch if miss.
+
+  // Try next extry in the table.
+  __ AddImmediate(R3, target::ToRawSmi(1));
+  __ b(&loop);
+
+  // Load cid for the Smi case.
+  __ Bind(&smi_case);
+  __ LoadImmediate(R0, kSmiCid);
+  __ b(&cid_loaded);
+}
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R5: ICData (preserved)
+// Passed to target:
+//  CODE_REG: target Code object
+//  R4: arguments descriptor
+void StubCodeCompiler::GenerateICCallThroughFunctionStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ ldr(ARGS_DESC_REG,
+         FieldAddress(R5, target::ICData::arguments_descriptor_offset()));
+  __ ldr(R8, FieldAddress(R5, target::ICData::entries_offset()));
+  __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, target::ToRawSmi(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length =
+      target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
+      target::kWordSize;
+  __ AddImmediate(R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(1) * target::kWordSize;
+  __ ldr(R0, Address(R8, target_offset));
+  __ ldr(R1, FieldAddress(R0, target::Function::entry_point_offset()));
+  __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+  __ br(R1);
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, target::Isolate::ic_miss_code_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ br(R1);
+}
+
+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()));
+  __ AddImmediate(R8, target::Array::data_offset() - kHeapObjectTag);
+  // R8: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(R1, R0);
+  // R1: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ ldr(R2, Address(R8, 0));
+  __ cmp(R1, Operand(R2));
+  __ b(&found, EQ);
+  __ CompareImmediate(R2, target::ToRawSmi(kIllegalCid));
+  __ b(&miss, EQ);
+
+  const intptr_t entry_length =
+      target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
+      target::kWordSize;
+  __ AddImmediate(R8, entry_length);  // Next entry.
+  __ b(&loop);
+
+  __ Bind(&found);
+  const intptr_t code_offset =
+      target::ICData::CodeIndexFor(1) * target::kWordSize;
+  const intptr_t entry_offset =
+      target::ICData::EntryPointIndexFor(1) * target::kWordSize;
+  __ ldr(R1, Address(R8, entry_offset));
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ ldr(CODE_REG, Address(R8, code_offset));
+  }
+  __ br(R1);
+
+  __ Bind(&miss);
+  __ LoadIsolate(R2);
+  __ ldr(CODE_REG, Address(R2, target::Isolate::ic_miss_code_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ br(R1);
+}
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R5: SingleTargetCache
+void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ Push(R0);  // Preserve receiver.
+
+  __ Push(ZR);  // Result slot.
+  __ Push(R0);  // Arg0: Receiver
+  __ Push(R5);  // Arg1: UnlinkedCall
+  __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+  __ Drop(2);
+  __ Pop(R5);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                        CodeEntryKind::kMonomorphic)));
+  __ br(R1);
+}
+
+// Called from switchable IC calls.
+//  R0: receiver
+//  R5: SingleTargetCache
+// Passed to target:
+//  CODE_REG: target Code object
+void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
+  Label miss;
+  __ LoadClassIdMayBeSmi(R1, R0);
+  __ ldr(R2, FieldAddress(R5, target::SingleTargetCache::lower_limit_offset()),
+         kUnsignedHalfword);
+  __ ldr(R3, FieldAddress(R5, target::SingleTargetCache::upper_limit_offset()),
+         kUnsignedHalfword);
+
+  __ cmp(R1, Operand(R2));
+  __ b(&miss, LT);
+  __ cmp(R1, Operand(R3));
+  __ b(&miss, GT);
+
+  __ ldr(R1, FieldAddress(R5, target::SingleTargetCache::entry_point_offset()));
+  __ ldr(CODE_REG,
+         FieldAddress(R5, target::SingleTargetCache::target_offset()));
+  __ br(R1);
+
+  __ Bind(&miss);
+  __ EnterStubFrame();
+  __ Push(R0);  // Preserve receiver.
+
+  __ Push(ZR);  // Result slot.
+  __ Push(R0);  // Arg0: Receiver
+  __ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(R5);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ 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(R0);  // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ Drop(1);
+  __ Pop(R5);  // result = IC
+
+  __ Pop(R0);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ ldr(CODE_REG,
+         Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ ldr(R1, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                        CodeEntryKind::kMonomorphic)));
+  __ br(R1);
+}
+
+void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
+    Assembler* assembler) {
+  __ brk(0);
+}
+
+void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
+  __ brk(0);
+}
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/stub_code_compiler_dbc.cc b/runtime/vm/compiler/stub_code_compiler_dbc.cc
new file mode 100644
index 0000000..f303ad4
--- /dev/null
+++ b/runtime/vm/compiler/stub_code_compiler_dbc.cc
@@ -0,0 +1,143 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_DBC)
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/jit/compiler.h"
+#include "vm/cpu.h"
+#include "vm/dart_entry.h"
+#include "vm/heap/heap.h"
+#include "vm/instructions.h"
+#include "vm/object_store.h"
+#include "vm/runtime_entry.h"
+#include "vm/stack_frame.h"
+#include "vm/stub_code.h"
+#include "vm/tags.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
+DEFINE_FLAG(bool,
+            use_slow_path,
+            false,
+            "Set to true for debugging & verifying the slow paths.");
+
+namespace compiler {
+
+void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) {
+  __ Compile();
+}
+
+void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub(
+    Assembler* assembler) {
+  __ NoSuchMethod();
+}
+
+// Not executed, but used as a stack marker when calling
+// DRT_OptimizeInvokedFunction.
+void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// Not executed, but used as a sentinel in Simulator::JumpToFrame.
+void StubCodeCompiler::GenerateRunExceptionHandlerStub(Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateDeoptForRewindStub(Assembler* assembler) {
+  __ DeoptRewind();
+}
+
+// TODO(vegorov) Don't generate this stub.
+void StubCodeCompiler::GenerateFixCallersTargetStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(vegorov) Don't generate these stubs.
+void StubCodeCompiler::GenerateAllocationStubForClass(Assembler* assembler,
+                                                      const Class& cls) {
+  __ Trap();
+}
+
+// TODO(vegorov) Don't generate this stub.
+void StubCodeCompiler::GenerateMegamorphicMissStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// These deoptimization stubs are only used to populate stack frames
+// with something meaningful to make sure GC can scan the stack during
+// the last phase of deoptimization which materializes objects.
+void StubCodeCompiler::GenerateDeoptimizeLazyFromReturnStub(
+    Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateDeoptimizeLazyFromThrowStub(
+    Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateDeoptimizeStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCodeCompiler::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
+    Assembler* assembler) {
+  __ Trap();
+}
+
+// TODO(kustermann): Don't generate this stub.
+void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
+    Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
+  __ Trap();
+}
+
+void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
+    Assembler* assembler) {
+  __ Trap();
+}
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
new file mode 100644
index 0000000..0fe7e81
--- /dev/null
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -0,0 +1,2374 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/compiler/stub_code_compiler.h"
+
+#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/class_id.h"
+#include "vm/code_entry_kind.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/backend/locations.h"
+#include "vm/constants_ia32.h"
+#include "vm/instructions.h"
+#include "vm/static_type_exactness_state.h"
+#include "vm/tags.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
+DEFINE_FLAG(bool,
+            use_slow_path,
+            false,
+            "Set to true for debugging & verifying the slow paths.");
+
+namespace compiler {
+
+// Input parameters:
+//   ESP : points to return address.
+//   ESP + 4 : address of last argument in argument array.
+//   ESP + 4*EDX : address of first argument in argument array.
+//   ESP + 4*EDX + 4 : address of return value.
+//   ECX : address of the runtime function to call.
+//   EDX : number of arguments to the call.
+// Must preserve callee saved registers EDI and EBX.
+void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ movl(CODE_REG,
+          Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing VM code.
+  __ movl(Assembler::VMTagAddress(), ECX);
+
+  // Reserve space for arguments and align frame before entering C++ world.
+  __ AddImmediate(
+      ESP,
+      Immediate(-static_cast<int32_t>(target::NativeArguments::StructSize())));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Pass NativeArguments structure by value and call runtime.
+  __ movl(Address(ESP, thread_offset), THR);  // Set thread in NativeArgs.
+  // There are no runtime calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
+  // Compute argv.
+  __ leal(EAX,
+          Address(EBP, EDX, TIMES_4,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+  __ movl(Address(ESP, argv_offset), EAX);  // Set argv in NativeArguments.
+  __ addl(EAX,
+          Immediate(1 * target::kWordSize));  // Retval is next to 1st argument.
+  __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
+  __ call(ECX);
+
+  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  __ LeaveFrame();
+
+  // The following return can jump to a lazy-deopt stub, which assumes EAX
+  // contains a return value and will save it in a GC-visible way.  We therefore
+  // have to ensure EAX does not contain any garbage value left from the C
+  // function we called (which has return type "void").
+  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
+  __ xorl(EAX, EAX);
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  // TODO(sjindel): implement.
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
+    Assembler* assembler) {
+  // TODO(sjindel): implement.
+  __ Breakpoint();
+}
+
+// Input parameters:
+//   ESP : points to return address.
+//   EAX : stop message (const char*).
+// Must preserve all registers, except EAX.
+void StubCodeCompiler::GeneratePrintStopMessageStub(Assembler* assembler) {
+  __ EnterCallRuntimeFrame(1 * target::kWordSize);
+  __ movl(Address(ESP, 0), EAX);
+  __ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ ret();
+}
+
+// Input parameters:
+//   ESP : points to return address.
+//   ESP + 4 : address of return value.
+//   EAX : address of first argument in argument array.
+//   ECX : address of the native function to call.
+//   EDX : argc_tag including number of arguments and function kind.
+static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
+                                              Address wrapper_address) {
+  const intptr_t native_args_struct_offset =
+      target::NativeEntry::kNumCallWrapperArguments * target::kWordSize;
+  const intptr_t thread_offset =
+      target::NativeArguments::thread_offset() + native_args_struct_offset;
+  const intptr_t argc_tag_offset =
+      target::NativeArguments::argc_tag_offset() + native_args_struct_offset;
+  const intptr_t argv_offset =
+      target::NativeArguments::argv_offset() + native_args_struct_offset;
+  const intptr_t retval_offset =
+      target::NativeArguments::retval_offset() + native_args_struct_offset;
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to dart VM code.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ movl(Assembler::VMTagAddress(), ECX);
+
+  // Reserve space for the native arguments structure, the outgoing parameters
+  // (pointer to the native arguments structure, the C function entry point)
+  // and align frame before entering the C++ world.
+  __ AddImmediate(
+      ESP,
+      Immediate(-static_cast<int32_t>(target::NativeArguments::StructSize()) -
+                (2 * target::kWordSize)));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Pass NativeArguments structure by value and call native function.
+  __ movl(Address(ESP, thread_offset), THR);    // Set thread in NativeArgs.
+  __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
+  __ movl(Address(ESP, argv_offset), EAX);      // Set argv in NativeArguments.
+  __ leal(EAX,
+          Address(EBP, 2 * target::kWordSize));  // Compute return value addr.
+  __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
+  __ leal(
+      EAX,
+      Address(ESP, 2 * target::kWordSize));  // Pointer to the NativeArguments.
+  __ movl(Address(ESP, 0), EAX);  // Pass the pointer to the NativeArguments.
+
+  __ movl(Address(ESP, target::kWordSize), ECX);  // Function to call.
+  __ call(wrapper_address);
+
+  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  __ LeaveFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateCallNoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::no_scope_native_wrapper_entry_point_offset()));
+}
+
+void StubCodeCompiler::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::auto_scope_native_wrapper_entry_point_offset()));
+}
+
+// Input parameters:
+//   ESP : points to return address.
+//   ESP + 4 : address of return value.
+//   EAX : address of first argument in argument array.
+//   ECX : address of the native function to call.
+//   EDX : argc_tag including number of arguments and function kind.
+void StubCodeCompiler::GenerateCallBootstrapNativeStub(Assembler* assembler) {
+  const intptr_t native_args_struct_offset = target::kWordSize;
+  const intptr_t thread_offset =
+      target::NativeArguments::thread_offset() + native_args_struct_offset;
+  const intptr_t argc_tag_offset =
+      target::NativeArguments::argc_tag_offset() + native_args_struct_offset;
+  const intptr_t argv_offset =
+      target::NativeArguments::argv_offset() + native_args_struct_offset;
+  const intptr_t retval_offset =
+      target::NativeArguments::retval_offset() + native_args_struct_offset;
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to dart VM code.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ movl(Assembler::VMTagAddress(), ECX);
+
+  // Reserve space for the native arguments structure, the outgoing parameter
+  // (pointer to the native arguments structure) and align frame before
+  // entering the C++ world.
+  __ AddImmediate(
+      ESP,
+      Immediate(-static_cast<int32_t>(target::NativeArguments::StructSize()) -
+                target::kWordSize));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Pass NativeArguments structure by value and call native function.
+  __ movl(Address(ESP, thread_offset), THR);    // Set thread in NativeArgs.
+  __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
+  __ movl(Address(ESP, argv_offset), EAX);      // Set argv in NativeArguments.
+  __ leal(EAX,
+          Address(EBP, 2 * target::kWordSize));  // Compute return value addr.
+  __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
+  __ leal(EAX,
+          Address(ESP, target::kWordSize));  // Pointer to the NativeArguments.
+  __ movl(Address(ESP, 0), EAX);  // Pass the pointer to the NativeArguments.
+  __ call(ECX);
+
+  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  __ LeaveFrame();
+  __ ret();
+}
+
+// Input parameters:
+//   EDX: arguments descriptor array.
+void StubCodeCompiler::GenerateCallStaticFunctionStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushl(EDX);           // Preserve arguments descriptor array.
+  __ pushl(Immediate(0));  // Setup space on stack for return value.
+  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
+  __ popl(EAX);  // Get Code object result.
+  __ popl(EDX);  // Restore arguments descriptor array.
+  // Remove the stub frame as we are about to jump to the dart function.
+  __ LeaveFrame();
+
+  __ movl(ECX, FieldAddress(EAX, target::Code::entry_point_offset()));
+  __ jmp(ECX);
+}
+
+// Called from a static call only when an invalid code has been entered
+// (invalid because its function was optimized or deoptimized).
+// EDX: arguments descriptor array.
+void StubCodeCompiler::GenerateFixCallersTargetStub(Assembler* assembler) {
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ pushl(EDX);           // Preserve arguments descriptor array.
+  __ pushl(Immediate(0));  // Setup space on stack for return value.
+  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
+  __ popl(EAX);  // Get Code object.
+  __ popl(EDX);  // Restore arguments descriptor array.
+  __ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
+  __ LeaveFrame();
+  __ jmp(EAX);
+  __ int3();
+}
+
+// Called from object allocate instruction when the allocation stub has been
+// disabled.
+void StubCodeCompiler::GenerateFixAllocationStubTargetStub(
+    Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushl(Immediate(0));  // Setup space on stack for return value.
+  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
+  __ popl(EAX);  // Get Code object.
+  __ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
+  __ LeaveFrame();
+  __ jmp(EAX);
+  __ int3();
+}
+
+// Input parameters:
+//   EDX: smi-tagged argument count, may be zero.
+//   EBP[target::frame_layout.param_end_from_fp + 1]: last argument.
+// Uses EAX, EBX, ECX, EDX, EDI.
+static void PushArrayOfArguments(Assembler* assembler) {
+  // Allocate array to store arguments of caller.
+  const Immediate& raw_null = Immediate(target::ToRawPointer(NullObject()));
+  __ movl(ECX, raw_null);  // Null element type for raw Array.
+  __ Call(StubCodeAllocateArray());
+  __ SmiUntag(EDX);
+  // EAX: newly allocated array.
+  // EDX: length of the array (was preserved by the stub).
+  __ pushl(EAX);  // Array is in EAX and on top of stack.
+  __ leal(EBX,
+          Address(EBP, EDX, TIMES_4,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+  __ leal(ECX, FieldAddress(EAX, target::Array::data_offset()));
+  // EBX: address of first argument on stack.
+  // ECX: address of first argument in array.
+  Label loop, loop_condition;
+  __ jmp(&loop_condition, Assembler::kNearJump);
+  __ Bind(&loop);
+  __ movl(EDI, Address(EBX, 0));
+  // Generational barrier is needed, array is not necessarily in new space.
+  __ StoreIntoObject(EAX, Address(ECX, 0), EDI);
+  __ AddImmediate(ECX, Immediate(target::kWordSize));
+  __ AddImmediate(EBX, Immediate(-target::kWordSize));
+  __ Bind(&loop_condition);
+  __ decl(EDX);
+  __ j(POSITIVE, &loop, Assembler::kNearJump);
+}
+
+// Used by eager and lazy deoptimization. Preserve result in EAX if necessary.
+// This stub translates optimized frame into unoptimized frame. The optimized
+// frame can contain values in registers and on stack, the unoptimized
+// frame contains all values on stack.
+// Deoptimization occurs in following steps:
+// - Push all registers that can contain values.
+// - Call C routine to copy the stack and saved registers into temporary buffer.
+// - Adjust caller's frame to correct unoptimized frame size.
+// - Fill the unoptimized frame.
+// - Materialize objects that require allocation (e.g. Double instances).
+// GC can occur only after frame is fully rewritten.
+// Stack after EnterDartFrame(0) below:
+//   +------------------+
+//   | PC marker        | <- TOS
+//   +------------------+
+//   | Saved FP         | <- FP of stub
+//   +------------------+
+//   | return-address   |  (deoptimization point)
+//   +------------------+
+//   | ...              | <- SP of optimized frame
+//
+// Parts of the code cannot GC, part of the code can GC.
+static void GenerateDeoptimizationSequence(Assembler* assembler,
+                                           DeoptStubKind kind) {
+  // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
+  __ EnterDartFrame(0);
+  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
+  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
+  const intptr_t saved_result_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - EAX);
+  const intptr_t saved_exception_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - EAX);
+  const intptr_t saved_stacktrace_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - EDX);
+  // Result in EAX is preserved as part of pushing all registers below.
+
+  // Push registers in their enumeration order: lowest register number at
+  // lowest address.
+  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
+    if (i == CODE_REG) {
+      // Save the original value of CODE_REG pushed before invoking this stub
+      // instead of the value used to call this stub.
+      __ pushl(Address(EBP, 2 * target::kWordSize));
+    } else {
+      __ pushl(static_cast<Register>(i));
+    }
+  }
+  __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
+  intptr_t offset = 0;
+  for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
+    XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
+    __ movups(Address(ESP, offset), xmm_reg);
+    offset += kFpuRegisterSize;
+  }
+
+  __ movl(ECX, ESP);  // Preserve saved registers block.
+  __ ReserveAlignedFrameSpace(2 * target::kWordSize);
+  __ movl(Address(ESP, 0 * target::kWordSize),
+          ECX);  // Start of register block.
+  bool is_lazy =
+      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
+  __ movl(Address(ESP, 1 * target::kWordSize), Immediate(is_lazy ? 1 : 0));
+  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
+  // Result (EAX) is stack-size (FP - SP) in bytes.
+
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into EBX temporarily.
+    __ movl(EBX, Address(EBP, saved_result_slot_from_fp * target::kWordSize));
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into EBX temporarily.
+    __ movl(EBX,
+            Address(EBP, saved_exception_slot_from_fp * target::kWordSize));
+    __ movl(ECX,
+            Address(EBP, saved_stacktrace_slot_from_fp * target::kWordSize));
+  }
+
+  __ LeaveFrame();
+  __ popl(EDX);       // Preserve return address.
+  __ movl(ESP, EBP);  // Discard optimized frame.
+  __ subl(ESP, EAX);  // Reserve space for deoptimized frame.
+  __ pushl(EDX);      // Restore return address.
+
+  // Leaf runtime function DeoptimizeFillFrame expects a Dart frame.
+  __ EnterDartFrame(0);
+  if (kind == kLazyDeoptFromReturn) {
+    __ pushl(EBX);  // Preserve result as first local.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ pushl(EBX);  // Preserve exception as first local.
+    __ pushl(ECX);  // Preserve stacktrace as first local.
+  }
+  __ ReserveAlignedFrameSpace(1 * target::kWordSize);
+  __ movl(Address(ESP, 0), EBP);  // Pass last FP as parameter on stack.
+  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into EBX.
+    __ movl(EBX,
+            Address(EBP, compiler::target::frame_layout.first_local_from_fp *
+                             target::kWordSize));
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into EBX.
+    __ movl(EBX,
+            Address(EBP, compiler::target::frame_layout.first_local_from_fp *
+                             target::kWordSize));
+    __ movl(
+        ECX,
+        Address(EBP, (compiler::target::frame_layout.first_local_from_fp - 1) *
+                         target::kWordSize));
+  }
+  // Code above cannot cause GC.
+  __ LeaveFrame();
+
+  // Frame is fully rewritten at this point and it is safe to perform a GC.
+  // Materialize any objects that were deferred by FillFrame because they
+  // require allocation.
+  __ EnterStubFrame();
+  if (kind == kLazyDeoptFromReturn) {
+    __ pushl(EBX);  // Preserve result, it will be GC-d here.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ pushl(EBX);  // Preserve exception, it will be GC-d here.
+    __ pushl(ECX);  // Preserve stacktrace, it will be GC-d here.
+  }
+  __ pushl(Immediate(target::ToRawSmi(0)));  // Space for the result.
+  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
+  // Result tells stub how many bytes to remove from the expression stack
+  // of the bottom-most frame. They were used as materialization arguments.
+  __ popl(EBX);
+  __ SmiUntag(EBX);
+  if (kind == kLazyDeoptFromReturn) {
+    __ popl(EAX);  // Restore result.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ popl(EDX);  // Restore exception.
+    __ popl(EAX);  // Restore stacktrace.
+  }
+  __ LeaveFrame();
+
+  __ popl(ECX);       // Pop return address.
+  __ addl(ESP, EBX);  // Remove materialization arguments.
+  __ pushl(ECX);      // Push return address.
+  // The caller is responsible for emitting the return instruction.
+}
+
+// EAX: result, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromReturnStub(
+    Assembler* assembler) {
+  // Return address for "call" to deopt stub.
+  __ pushl(Immediate(kZapReturnAddress));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
+  __ ret();
+}
+
+// EAX: exception, must be preserved
+// EDX: stacktrace, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromThrowStub(
+    Assembler* assembler) {
+  // Return address for "call" to deopt stub.
+  __ pushl(Immediate(kZapReturnAddress));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateDeoptimizeStub(Assembler* assembler) {
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+  __ 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);
+  __ EnterStubFrame();
+  // Load the receiver.
+  __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+  __ movl(EAX,
+          Address(EBP, EDI, TIMES_HALF_WORD_SIZE,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+  __ pushl(Immediate(0));  // Setup space on stack for result.
+  __ pushl(EAX);           // Receiver.
+  __ pushl(ECX);           // ICData/MegamorphicCache.
+  __ pushl(EDX);           // Arguments descriptor array.
+
+  // Adjust arguments count.
+  __ cmpl(
+      FieldAddress(EDX, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  __ movl(EDX, EDI);
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addl(EDX, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+
+  // EDX: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+  const intptr_t kNumArgs = 4;
+  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+  __ Drop(4);
+  __ popl(EAX);  // Return value.
+  __ LeaveFrame();
+  __ 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::count_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);
+
+  __ 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);
+  }
+
+  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ jmp(EBX);
+}
+
+// Called for inline allocation of arrays.
+// Input parameters:
+//   EDX : Array length as Smi (must be preserved).
+//   ECX : array element type (either NULL or an instantiated type).
+// Uses EAX, EBX, ECX, EDI  as temporary registers.
+// The newly allocated object is returned in EAX.
+void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
+  Label slow_case;
+  // Compute the size to be allocated, it is based on the array length
+  // and is computed as:
+  // RoundedAllocationSize(
+  //     (array_length * kwordSize) + target::Array::header_size()).
+  // Assert that length is a Smi.
+  __ testl(EDX, Immediate(kSmiTagMask));
+
+  if (FLAG_use_slow_path) {
+    __ jmp(&slow_case);
+  } else {
+    __ j(NOT_ZERO, &slow_case);
+  }
+  __ cmpl(EDX, Immediate(0));
+  __ j(LESS, &slow_case);
+
+  // Check for maximum allowed length.
+  const Immediate& max_len =
+      Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
+  __ cmpl(EDX, max_len);
+  __ j(GREATER, &slow_case);
+
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(kArrayCid, EAX, &slow_case, Assembler::kFarJump));
+
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
+      1;
+  // EDX is Smi.
+  __ leal(EBX, Address(EDX, TIMES_2, fixed_size_plus_alignment_padding));
+  ASSERT(kSmiTagShift == 1);
+  __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
+
+  // ECX: array element type.
+  // EDX: array length as Smi.
+  // EBX: allocation size.
+
+  const intptr_t cid = kArrayCid;
+  __ movl(EAX, Address(THR, target::Thread::top_offset()));
+  __ addl(EBX, EAX);
+  __ j(CARRY, &slow_case);
+
+  // Check if the allocation fits into the remaining space.
+  // EAX: potential new object start.
+  // EBX: potential next object start.
+  // ECX: array element type.
+  // EDX: array length as Smi).
+  __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
+  __ j(ABOVE_EQUAL, &slow_case);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  __ movl(Address(THR, target::Thread::top_offset()), EBX);
+  __ subl(EBX, EAX);
+  __ addl(EAX, Immediate(kHeapObjectTag));
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EBX, EDI));
+
+  // Initialize the tags.
+  // EAX: new object start as a tagged pointer.
+  // EBX: allocation size.
+  // ECX: array element type.
+  // EDX: array length as Smi.
+  {
+    Label size_tag_overflow, done;
+    __ movl(EDI, EBX);
+    __ cmpl(EDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+    __ shll(EDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2));
+    __ jmp(&done, Assembler::kNearJump);
+
+    __ Bind(&size_tag_overflow);
+    __ movl(EDI, Immediate(0));
+    __ Bind(&done);
+
+    // Get the class index and insert it into the tags.
+    uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+    __ orl(EDI, Immediate(tags));
+    __ movl(FieldAddress(EAX, target::Object::tags_offset()), EDI);  // Tags.
+  }
+  // EAX: new object start as a tagged pointer.
+  // EBX: allocation size.
+  // ECX: array element type.
+  // EDX: Array length as Smi (preserved).
+  // Store the type argument field.
+  // No generational barrier needed, since we store into a new object.
+  __ StoreIntoObjectNoBarrier(
+      EAX, FieldAddress(EAX, target::Array::type_arguments_offset()), ECX);
+
+  // Set the length field.
+  __ StoreIntoObjectNoBarrier(
+      EAX, FieldAddress(EAX, target::Array::length_offset()), EDX);
+
+  // Initialize all array elements to raw_null.
+  // EAX: new object start as a tagged pointer.
+  // EBX: allocation size.
+  // EDI: iterator which initially points to the start of the variable
+  // data area to be initialized.
+  // ECX: array element type.
+  // EDX: array length as Smi.
+  __ leal(EBX, FieldAddress(EAX, EBX, TIMES_1, 0));
+  __ leal(EDI, FieldAddress(EAX, target::Array::header_size()));
+  Label done;
+  Label init_loop;
+  __ Bind(&init_loop);
+  __ cmpl(EDI, EBX);
+  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
+  // No generational barrier needed, since we are storing null.
+  __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), NullObject());
+  __ addl(EDI, Immediate(target::kWordSize));
+  __ jmp(&init_loop, Assembler::kNearJump);
+  __ Bind(&done);
+  __ ret();  // returns the newly allocated object in EAX.
+
+  // Unable to allocate the array using the fast inline code, just call
+  // into the runtime.
+  __ Bind(&slow_case);
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ pushl(Immediate(0));  // Setup space on stack for return value.
+  __ pushl(EDX);           // Array length as Smi.
+  __ pushl(ECX);           // Element type.
+  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
+  __ popl(EAX);  // Pop element type argument.
+  __ popl(EDX);  // Pop array length argument (preserved).
+  __ popl(EAX);  // Pop return value from return slot.
+  __ LeaveFrame();
+  __ ret();
+}
+
+// Called when invoking dart code from C++ (VM code).
+// Input parameters:
+//   ESP : points to return address.
+//   ESP + 4 : code object of the dart function to call.
+//   ESP + 8 : arguments descriptor array.
+//   ESP + 12 : arguments array.
+//   ESP + 16 : current thread.
+// Uses EAX, EDX, ECX, EDI as temporary registers.
+void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) {
+  const intptr_t kTargetCodeOffset = 3 * target::kWordSize;
+  const intptr_t kArgumentsDescOffset = 4 * target::kWordSize;
+  const intptr_t kArgumentsOffset = 5 * target::kWordSize;
+  const intptr_t kThreadOffset = 6 * target::kWordSize;
+
+  __ pushl(Address(ESP, 0));  // Marker for the profiler.
+  __ EnterFrame(0);
+
+  // Push code object to PC marker slot.
+  __ movl(EAX, Address(EBP, kThreadOffset));
+  __ pushl(Address(EAX, target::Thread::invoke_dart_code_stub_offset()));
+
+  // Save C++ ABI callee-saved registers.
+  __ pushl(EBX);
+  __ pushl(ESI);
+  __ pushl(EDI);
+
+  // Set up THR, which caches the current thread in Dart code.
+  __ movl(THR, EAX);
+
+  // Save the current VMTag on the stack.
+  __ movl(ECX, Assembler::VMTagAddress());
+  __ pushl(ECX);
+
+  // Save top resource and top exit frame info. Use EDX as a temporary register.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ movl(EDX, Address(THR, target::Thread::top_resource_offset()));
+  __ pushl(EDX);
+  __ movl(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+  // The constant target::frame_layout.exit_link_slot_from_entry_fp must be
+  // kept in sync with the code below.
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -7);
+  __ movl(EDX, Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ pushl(EDX);
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  // Mark that the thread is executing Dart code. Do this after initializing the
+  // exit link for the profiler.
+  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Load arguments descriptor array into EDX.
+  __ movl(EDX, Address(EBP, kArgumentsDescOffset));
+  __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle));
+
+  // Load number of arguments into EBX and adjust count for type arguments.
+  __ movl(EBX, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+  __ cmpl(
+      FieldAddress(EDX, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addl(EBX, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+  // Save number of arguments as Smi on stack, replacing ArgumentsDesc.
+  __ movl(Address(EBP, kArgumentsDescOffset), EBX);
+  __ SmiUntag(EBX);
+
+  // Set up arguments for the dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+  __ testl(EBX, EBX);  // check if there are arguments.
+  __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
+  __ movl(EAX, Immediate(0));
+
+  // Compute address of 'arguments array' data area into EDI.
+  __ movl(EDI, Address(EBP, kArgumentsOffset));
+  __ movl(EDI, Address(EDI, VMHandles::kOffsetOfRawPtrInHandle));
+  __ leal(EDI, FieldAddress(EDI, target::Array::data_offset()));
+
+  __ Bind(&push_arguments);
+  __ movl(ECX, Address(EDI, EAX, TIMES_4, 0));
+  __ pushl(ECX);
+  __ incl(EAX);
+  __ cmpl(EAX, EBX);
+  __ j(LESS, &push_arguments, Assembler::kNearJump);
+  __ Bind(&done_push_arguments);
+
+  // Call the dart code entrypoint.
+  __ movl(EAX, Address(EBP, kTargetCodeOffset));
+  __ movl(EAX, Address(EAX, VMHandles::kOffsetOfRawPtrInHandle));
+  __ call(FieldAddress(EAX, target::Code::entry_point_offset()));
+
+  // Read the saved number of passed arguments as Smi.
+  __ movl(EDX, Address(EBP, kArgumentsDescOffset));
+  // Get rid of arguments pushed on the stack.
+  __ leal(ESP, Address(ESP, EDX, TIMES_2, 0));  // EDX is a Smi.
+
+  // Restore the saved top exit frame info and top resource back into the
+  // Isolate structure.
+  __ popl(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popl(Address(THR, target::Thread::top_resource_offset()));
+
+  // Restore the current VMTag from the stack.
+  __ popl(Assembler::VMTagAddress());
+
+  // Restore C++ ABI callee-saved registers.
+  __ popl(EDI);
+  __ popl(ESI);
+  __ popl(EBX);
+
+  // Restore the frame pointer.
+  __ LeaveFrame();
+  __ popl(ECX);
+
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
+    Assembler* assembler) {
+  __ Unimplemented("Interpreter not yet supported");
+}
+
+// Called for inline allocation of contexts.
+// Input:
+// EDX: number of context variables.
+// Output:
+// EAX: new allocated RawContext object.
+// EBX and EDX are destroyed.
+void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
+  if (FLAG_inline_alloc) {
+    Label slow_case;
+    // First compute the rounded instance size.
+    // EDX: number of context variables.
+    intptr_t fixed_size_plus_alignment_padding =
+        (target::Context::header_size() +
+         target::ObjectAlignment::kObjectAlignment - 1);
+    __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
+    __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
+
+    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, EAX, &slow_case,
+                                           Assembler::kFarJump));
+
+    // Now allocate the object.
+    // EDX: number of context variables.
+    const intptr_t cid = kContextCid;
+    __ movl(EAX, Address(THR, target::Thread::top_offset()));
+    __ addl(EBX, EAX);
+    // Check if the allocation fits into the remaining space.
+    // EAX: potential new object.
+    // EBX: potential next object start.
+    // EDX: number of context variables.
+    __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
+    if (FLAG_use_slow_path) {
+      __ jmp(&slow_case);
+    } else {
+#if defined(DEBUG)
+      static const bool kJumpLength = Assembler::kFarJump;
+#else
+      static const bool kJumpLength = Assembler::kNearJump;
+#endif  // DEBUG
+      __ j(ABOVE_EQUAL, &slow_case, kJumpLength);
+    }
+
+    // Successfully allocated the object, now update top to point to
+    // next object start and initialize the object.
+    // EAX: new object.
+    // EBX: next object start.
+    // EDX: number of context variables.
+    __ movl(Address(THR, target::Thread::top_offset()), EBX);
+    // EBX: Size of allocation in bytes.
+    __ subl(EBX, EAX);
+    __ addl(EAX, Immediate(kHeapObjectTag));
+    // Generate isolate-independent code to allow sharing between isolates.
+    NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EBX, EDI));
+
+    // Calculate the size tag.
+    // EAX: new object.
+    // EDX: number of context variables.
+    {
+      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));
+      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+      __ shll(EBX, Immediate(target::RawObject::kTagBitsSizeTagPos -
+                             target::ObjectAlignment::kObjectAlignmentLog2));
+      __ jmp(&done);
+
+      __ Bind(&size_tag_overflow);
+      // Set overflow size tag value.
+      __ movl(EBX, Immediate(0));
+
+      __ Bind(&done);
+      // EAX: new object.
+      // EDX: number of context variables.
+      // EBX: size and bit tags.
+      uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+      __ orl(EBX, Immediate(tags));
+      __ movl(FieldAddress(EAX, target::Object::tags_offset()), EBX);  // Tags.
+    }
+
+    // Setup up number of context variables field.
+    // EAX: new object.
+    // EDX: number of context variables as integer value (not object).
+    __ movl(FieldAddress(EAX, target::Context::num_variables_offset()), EDX);
+
+    // Setup the parent field.
+    // EAX: new object.
+    // EDX: number of context variables.
+    // No generational barrier needed, since we are storing null.
+    __ StoreIntoObjectNoBarrier(
+        EAX, FieldAddress(EAX, target::Context::parent_offset()), NullObject());
+
+    // Initialize the context variables.
+    // EAX: new object.
+    // EDX: number of context variables.
+    {
+      Label loop, entry;
+      __ leal(EBX, FieldAddress(EAX, target::Context::variable_offset(0)));
+
+      __ jmp(&entry, Assembler::kNearJump);
+      __ Bind(&loop);
+      __ decl(EDX);
+      // No generational barrier needed, since we are storing null.
+      __ StoreIntoObjectNoBarrier(EAX, Address(EBX, EDX, TIMES_4, 0),
+                                  NullObject());
+      __ Bind(&entry);
+      __ cmpl(EDX, Immediate(0));
+      __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+    }
+
+    // Done allocating and initializing the context.
+    // EAX: new object.
+    __ ret();
+
+    __ Bind(&slow_case);
+  }
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ pushl(Immediate(0));  // Setup space on stack for return value.
+  __ SmiTag(EDX);
+  __ pushl(EDX);
+  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
+  __ popl(EAX);  // Pop number of context variables argument.
+  __ popl(EAX);  // Pop the new context object.
+  // EAX: new object
+  // Restore the frame pointer.
+  __ LeaveFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
+  // Not used on IA32.
+  __ Breakpoint();
+}
+
+// Helper stub to implement Assembler::StoreIntoObject/Array.
+// Input parameters:
+//   EDX: Object (old)
+//   EDI: Slot
+// If EDX is not remembered, mark as remembered and add to the store buffer.
+COMPILE_ASSERT(kWriteBarrierObjectReg == EDX);
+COMPILE_ASSERT(kWriteBarrierValueReg == kNoRegister);
+COMPILE_ASSERT(kWriteBarrierSlotReg == EDI);
+static void GenerateWriteBarrierStubHelper(Assembler* assembler,
+                                           Address stub_code,
+                                           bool cards) {
+  Label remember_card;
+
+  // Save values being destroyed.
+  __ pushl(EAX);
+  __ pushl(ECX);
+
+  Label add_to_buffer;
+  // Check whether this object has already been remembered. Skip adding to the
+  // store buffer if the object is in the store buffer already.
+  // Spilled: EAX, ECX
+  // EDX: Address being stored
+  __ movl(EAX, FieldAddress(EDX, target::Object::tags_offset()));
+  __ testl(EAX, Immediate(1 << target::RawObject::kOldAndNotRememberedBit));
+  __ j(NOT_EQUAL, &add_to_buffer, Assembler::kNearJump);
+  __ popl(ECX);
+  __ popl(EAX);
+  __ ret();
+
+  // Update the tags that this object has been remembered.
+  // EDX: Address being stored
+  // EAX: Current tag value
+  __ Bind(&add_to_buffer);
+
+  if (cards) {
+    // Check if this object is using remembered cards.
+    __ testl(EAX, Immediate(1 << target::RawObject::kCardRememberedBit));
+    __ j(NOT_EQUAL, &remember_card, Assembler::kFarJump);  // Unlikely.
+  } else {
+#if defined(DEBUG)
+    Label ok;
+    __ testl(EAX, Immediate(1 << target::RawObject::kCardRememberedBit));
+    __ j(ZERO, &ok, Assembler::kFarJump);  // Unlikely.
+    __ Stop("Wrong barrier");
+    __ Bind(&ok);
+#endif
+  }
+
+  // lock+andl is an atomic read-modify-write.
+  __ lock();
+  __ andl(FieldAddress(EDX, target::Object::tags_offset()),
+          Immediate(~(1 << target::RawObject::kOldAndNotRememberedBit)));
+
+  // Load the StoreBuffer block out of the thread. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
+  // Spilled: EAX, ECX
+  // EDX: Address being stored
+  __ movl(EAX, Address(THR, target::Thread::store_buffer_block_offset()));
+  __ movl(ECX, Address(EAX, target::StoreBufferBlock::top_offset()));
+  __ movl(
+      Address(EAX, ECX, TIMES_4, target::StoreBufferBlock::pointers_offset()),
+      EDX);
+
+  // Increment top_ and check for overflow.
+  // Spilled: EAX, ECX
+  // ECX: top_
+  // EAX: StoreBufferBlock
+  Label overflow;
+  __ incl(ECX);
+  __ movl(Address(EAX, target::StoreBufferBlock::top_offset()), ECX);
+  __ cmpl(ECX, Immediate(target::StoreBufferBlock::kSize));
+  // Restore values.
+  // Spilled: EAX, ECX
+  __ popl(ECX);
+  __ popl(EAX);
+  __ j(EQUAL, &overflow, Assembler::kNearJump);
+  __ ret();
+
+  // Handle overflow: Call the runtime leaf function.
+  __ Bind(&overflow);
+  // Setup frame, push callee-saved registers.
+
+  __ EnterCallRuntimeFrame(1 * target::kWordSize);
+  __ movl(Address(ESP, 0), THR);  // Push the thread as the only argument.
+  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
+  // Restore callee-saved registers, tear down frame.
+  __ LeaveCallRuntimeFrame();
+  __ ret();
+
+  if (cards) {
+    Label remember_card_slow;
+
+    // Get card table.
+    __ Bind(&remember_card);
+    __ movl(EAX, EDX);                           // Object.
+    __ andl(EAX, Immediate(target::kPageMask));  // HeapPage.
+    __ cmpl(Address(EAX, target::HeapPage::card_table_offset()), Immediate(0));
+    __ j(EQUAL, &remember_card_slow, Assembler::kNearJump);
+
+    // Dirty the card.
+    __ subl(EDI, EAX);  // Offset in page.
+    __ movl(
+        EAX,
+        Address(EAX, target::HeapPage::card_table_offset()));  // Card table.
+    __ shrl(EDI,
+            Immediate(
+                target::HeapPage::kBytesPerCardLog2));  // Index in card table.
+    __ movb(Address(EAX, EDI, TIMES_1, 0), Immediate(1));
+    __ popl(ECX);
+    __ popl(EAX);
+    __ ret();
+
+    // Card table not yet allocated.
+    __ Bind(&remember_card_slow);
+    __ EnterCallRuntimeFrame(2 * target::kWordSize);
+    __ movl(Address(ESP, 0 * target::kWordSize), EDX);  // Object
+    __ movl(Address(ESP, 1 * target::kWordSize), EDI);  // Slot
+    __ CallRuntime(kRememberCardRuntimeEntry, 2);
+    __ LeaveCallRuntimeFrame();
+    __ popl(ECX);
+    __ popl(EAX);
+    __ ret();
+  }
+}
+
+void StubCodeCompiler::GenerateWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler, Address(THR, target::Thread::write_barrier_code_offset()),
+      false);
+}
+
+void StubCodeCompiler::GenerateArrayWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler,
+      Address(THR, target::Thread::array_write_barrier_code_offset()), true);
+}
+
+// Called for inline allocation of objects.
+// Input parameters:
+//   ESP + 4 : type arguments object (only if class is parameterized).
+//   ESP : points to return address.
+// 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) {
+  const intptr_t kObjectTypeArgumentsOffset = 1 * target::kWordSize;
+  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;
+  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::InstanceSize(cls);
+  ASSERT(instance_size > 0);
+  if (is_cls_parameterized) {
+    __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
+    // EDX: instantiated type arguments.
+  }
+  if (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.
+    // EDX: instantiated type arguments (if is_cls_parameterized).
+    __ movl(EAX, Address(THR, target::Thread::top_offset()));
+    __ leal(EBX, Address(EAX, instance_size));
+    // Check if the allocation fits into the remaining space.
+    // EAX: potential new object start.
+    // EBX: potential next object start.
+    __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
+    if (FLAG_use_slow_path) {
+      __ jmp(&slow_case);
+    } else {
+      __ j(ABOVE_EQUAL, &slow_case);
+    }
+    __ movl(Address(THR, target::Thread::top_offset()), EBX);
+    NOT_IN_PRODUCT(__ UpdateAllocationStats(target::Class::GetId(cls), ECX));
+
+    // EAX: new object start (untagged).
+    // EBX: next object start.
+    // EDX: new object type arguments (if is_cls_parameterized).
+    // Set the tags.
+    ASSERT(target::Class::GetId(cls) != kIllegalCid);
+    uint32_t tags = target::MakeTagWordForNewSpaceObject(
+        target::Class::GetId(cls), instance_size);
+    __ movl(Address(EAX, target::Object::tags_offset()), Immediate(tags));
+    __ addl(EAX, Immediate(kHeapObjectTag));
+
+    // Initialize the remaining words of the object.
+
+    // EAX: new object (tagged).
+    // EBX: next object start.
+    // EDX: new object type arguments (if is_cls_parameterized).
+    // 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(EAX, FieldAddress(EAX, current_offset),
+                                    NullObject());
+      }
+    } else {
+      __ leal(ECX, FieldAddress(EAX, target::Instance::first_field_offset()));
+      // Loop until the whole object is initialized.
+      // EAX: new object (tagged).
+      // EBX: next object start.
+      // ECX: next word to be initialized.
+      // EDX: new object type arguments (if is_cls_parameterized).
+      Label init_loop;
+      Label done;
+      __ Bind(&init_loop);
+      __ cmpl(ECX, EBX);
+      __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
+      __ StoreIntoObjectNoBarrier(EAX, Address(ECX, 0), NullObject());
+      __ addl(ECX, Immediate(target::kWordSize));
+      __ jmp(&init_loop, Assembler::kNearJump);
+      __ Bind(&done);
+    }
+    if (is_cls_parameterized) {
+      // EAX: new object (tagged).
+      // EDX: new object type arguments.
+      // Set the type arguments in the new object.
+      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
+      __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, offset), EDX);
+    }
+    // Done allocating and initializing the instance.
+    // EAX: new object (tagged).
+    __ ret();
+
+    __ Bind(&slow_case);
+  }
+  // If is_cls_parameterized:
+  // EDX: new object type arguments.
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ pushl(raw_null);  // Setup space on stack for return value.
+  __ PushObject(
+      CastHandle<Object>(cls));  // Push class of object to be allocated.
+  if (is_cls_parameterized) {
+    __ pushl(EDX);  // Push type arguments of object to be allocated.
+  } else {
+    __ pushl(raw_null);  // Push null type arguments.
+  }
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
+  __ popl(EAX);  // Pop argument (type arguments of object).
+  __ popl(EAX);  // Pop argument (class of object).
+  __ popl(EAX);  // Pop result (newly allocated object).
+  // EAX: new object
+  // Restore the frame pointer.
+  __ LeaveFrame();
+  __ ret();
+}
+
+// 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.
+// Input parameters:
+//   ESP : points to return address.
+//   ESP + 4 : address of last argument.
+//   EDX : arguments descriptor array.
+// Uses EAX, EBX, EDI as temporary registers.
+void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub(
+    Assembler* assembler) {
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ movl(EDI, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+  __ movl(EAX,
+          Address(EBP, EDI, TIMES_2,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+
+  __ pushl(Immediate(0));  // Setup space on stack for result from noSuchMethod.
+  __ pushl(EAX);           // Receiver.
+  __ pushl(EDX);           // Arguments descriptor array.
+
+  // Adjust arguments count.
+  __ cmpl(
+      FieldAddress(EDX, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  __ movl(EDX, EDI);
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addl(EDX, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+
+  // EDX: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+
+  const intptr_t kNumArgs = 3;
+  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+  // noSuchMethod on closures always throws an error, so it will never return.
+  __ int3();
+}
+
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
+void StubCodeCompiler::GenerateOptimizedUsageCounterIncrement(
+    Assembler* assembler) {
+  Register ic_reg = ECX;
+  Register func_reg = EBX;
+  if (FLAG_trace_optimized_ic_calls) {
+    __ EnterStubFrame();
+    __ pushl(func_reg);  // Preserve
+    __ pushl(ic_reg);    // Preserve.
+    __ pushl(ic_reg);    // Argument.
+    __ pushl(func_reg);  // Argument.
+    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
+    __ popl(EAX);       // Discard argument;
+    __ popl(EAX);       // Discard argument;
+    __ popl(ic_reg);    // Restore.
+    __ popl(func_reg);  // Restore.
+    __ LeaveFrame();
+  }
+  __ incl(FieldAddress(func_reg, target::Function::usage_counter_offset()));
+}
+
+// Loads function into 'temp_reg'.
+void StubCodeCompiler::GenerateUsageCounterIncrement(Assembler* assembler,
+                                                     Register temp_reg) {
+  if (FLAG_optimization_counter_threshold >= 0) {
+    Register ic_reg = ECX;
+    Register func_reg = temp_reg;
+    ASSERT(ic_reg != func_reg);
+    __ Comment("Increment function counter");
+    __ movl(func_reg, FieldAddress(ic_reg, target::ICData::owner_offset()));
+    __ incl(FieldAddress(func_reg, target::Function::usage_counter_offset()));
+  }
+}
+
+// Note: ECX must be preserved.
+// Attempt a quick Smi operation for known operations ('kind'). The ICData
+// must have been primed with a Smi/Smi check that will be used for counting
+// the invocations.
+static void EmitFastSmiOp(Assembler* assembler,
+                          Token::Kind kind,
+                          intptr_t num_args,
+                          Label* not_smi_or_overflow) {
+  __ Comment("Fast Smi op");
+  ASSERT(num_args == 2);
+  __ movl(EDI, Address(ESP, +1 * target::kWordSize));  // Right
+  __ movl(EAX, Address(ESP, +2 * target::kWordSize));  // Left
+  __ movl(EBX, EDI);
+  __ orl(EBX, EAX);
+  __ testl(EBX, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, not_smi_or_overflow, Assembler::kNearJump);
+  switch (kind) {
+    case Token::kADD: {
+      __ addl(EAX, EDI);
+      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
+      break;
+    }
+    case Token::kSUB: {
+      __ subl(EAX, EDI);
+      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
+      break;
+    }
+    case Token::kMUL: {
+      __ SmiUntag(EAX);
+      __ imull(EAX, EDI);
+      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
+      break;
+    }
+    case Token::kEQ: {
+      Label done, is_true;
+      __ cmpl(EAX, EDI);
+      __ j(EQUAL, &is_true, Assembler::kNearJump);
+      __ LoadObject(EAX, CastHandle<Object>(FalseObject()));
+      __ jmp(&done, Assembler::kNearJump);
+      __ Bind(&is_true);
+      __ LoadObject(EAX, CastHandle<Object>(TrueObject()));
+      __ Bind(&done);
+      break;
+    }
+    default:
+      UNIMPLEMENTED();
+  }
+
+  // ECX: IC data object.
+  __ movl(EBX, FieldAddress(ECX, target::ICData::entries_offset()));
+  // EBX: ic_data_array with check entries: classes and target functions.
+  __ leal(EBX, FieldAddress(EBX, target::Array::data_offset()));
+#if defined(DEBUG)
+  // Check that first entry is for Smi/Smi.
+  Label error, ok;
+  const Immediate& imm_smi_cid = Immediate(target::ToRawSmi(kSmiCid));
+  __ cmpl(Address(EBX, 0 * target::kWordSize), imm_smi_cid);
+  __ j(NOT_EQUAL, &error, Assembler::kNearJump);
+  __ cmpl(Address(EBX, 1 * target::kWordSize), imm_smi_cid);
+  __ j(EQUAL, &ok, Assembler::kNearJump);
+  __ Bind(&error);
+  __ Stop("Incorrect IC data");
+  __ Bind(&ok);
+#endif
+  if (FLAG_optimization_counter_threshold >= 0) {
+    const intptr_t count_offset =
+        target::ICData::CountIndexFor(num_args) * target::kWordSize;
+    // Update counter, ignore overflow.
+    __ addl(Address(EBX, count_offset), Immediate(target::ToRawSmi(1)));
+  }
+  __ ret();
+}
+
+// Generate inline cache check for 'num_args'.
+//  ECX: Inline cache data object.
+//  TOS(0): return address
+// Control flow:
+// - If receiver is null -> jump to IC miss.
+// - If receiver is Smi -> load Smi class.
+// - If receiver is not-Smi -> load receiver's class.
+// - Check if 'num_args' (including receiver) match any IC data group.
+// - Match found -> jump to target.
+// - Match not found -> jump to IC miss.
+void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss,
+    Token::Kind kind,
+    bool optimized,
+    bool exactness_check /* = false */) {
+  ASSERT(!exactness_check);  // Not supported.
+  ASSERT(num_args == 1 || num_args == 2);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == num_args.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ movl(EBX, FieldAddress(ECX, target::ICData::state_bits_offset()));
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ andl(EBX, Immediate(target::ICData::NumArgsTestedMask()));
+    __ cmpl(EBX, Immediate(num_args));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect stub for IC data");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  Label stepping, done_stepping;
+  if (!optimized) {
+    __ Comment("Check single stepping");
+    __ LoadIsolate(EAX);
+    __ cmpb(Address(EAX, target::Isolate::single_step_offset()), Immediate(0));
+    __ j(NOT_EQUAL, &stepping);
+    __ Bind(&done_stepping);
+  }
+#endif
+  Label not_smi_or_overflow;
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
+
+  __ 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()));
+  // Loop that checks if there is an IC data match.
+  Label loop, found, miss;
+  // ECX: IC data object (preserved).
+  __ movl(EBX, FieldAddress(ECX, target::ICData::entries_offset()));
+  // EBX: ic_data_array with check entries: classes and target functions.
+  __ leal(EBX, FieldAddress(EBX, target::Array::data_offset()));
+  // EBX: points directly to the first ic data array element.
+
+  // Get argument descriptor into EAX.  In the 1-argument case this is the
+  // last time we need the argument descriptor, and we reuse EAX for the
+  // class IDs from the IC descriptor.  In the 2-argument case we preserve
+  // the argument descriptor in EAX.
+  __ movl(EAX, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+  if (num_args == 1) {
+    // Load receiver into EDI.
+    __ movl(EDI,
+            Address(ESP, EAX, TIMES_2, 0));  // EAX (argument count) is Smi.
+    __ LoadTaggedClassIdMayBeSmi(EAX, EDI);
+    // EAX: receiver class ID as Smi.
+  }
+
+  __ Comment("ICData loop");
+
+  // We unroll the generic one that is generated once more than the others.
+  bool optimize = kind == Token::kILLEGAL;
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(num_args) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(num_args) * target::kWordSize;
+  const intptr_t entry_size =
+      target::ICData::TestEntryLengthFor(num_args, exactness_check) *
+      target::kWordSize;
+
+  __ Bind(&loop);
+  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
+    Label update;
+    if (num_args == 1) {
+      __ movl(EDI, Address(EBX, 0));
+      __ cmpl(EDI, EAX);                    // Class id match?
+      __ j(EQUAL, &found);                  // Break.
+      __ addl(EBX, Immediate(entry_size));  // Next entry.
+      __ cmpl(EDI, Immediate(target::ToRawSmi(kIllegalCid)));  // Done?
+    } else {
+      ASSERT(num_args == 2);
+      // Load receiver into EDI.
+      __ movl(EDI, Address(ESP, EAX, TIMES_2, 0));
+      __ LoadTaggedClassIdMayBeSmi(EDI, EDI);
+      __ cmpl(EDI, Address(EBX, 0));  // Class id match?
+      __ j(NOT_EQUAL, &update);       // Continue.
+
+      // Load second argument into EDI.
+      __ movl(EDI, Address(ESP, EAX, TIMES_2, -target::kWordSize));
+      __ LoadTaggedClassIdMayBeSmi(EDI, EDI);
+      __ cmpl(EDI, Address(EBX, target::kWordSize));  // Class id match?
+      __ j(EQUAL, &found);                            // Break.
+
+      __ Bind(&update);
+      __ addl(EBX, Immediate(entry_size));  // Next entry.
+      __ cmpl(Address(EBX, -entry_size),
+              Immediate(target::ToRawSmi(kIllegalCid)));  // Done?
+    }
+
+    if (unroll == 0) {
+      __ j(NOT_EQUAL, &loop);
+    } else {
+      __ j(EQUAL, &miss);
+    }
+  }
+
+  __ Bind(&miss);
+  __ Comment("IC miss");
+  // Compute address of arguments (first read number of arguments from
+  // arguments descriptor array and then compute address on the stack).
+  __ movl(EAX, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset()));
+  __ leal(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX is Smi.
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  __ pushl(EDX);           // Preserve arguments descriptor array.
+  __ pushl(ECX);           // Preserve IC data object.
+  __ pushl(Immediate(0));  // Result slot.
+  // Push call arguments.
+  for (intptr_t i = 0; i < num_args; i++) {
+    __ movl(EBX, Address(EAX, -target::kWordSize * i));
+    __ pushl(EBX);
+  }
+  __ pushl(ECX);  // Pass IC data object.
+  __ CallRuntime(handle_ic_miss, num_args + 1);
+  // Remove the call arguments pushed earlier, including the IC data object.
+  for (intptr_t i = 0; i < num_args + 1; i++) {
+    __ popl(EAX);
+  }
+  __ popl(EAX);  // Pop returned function object into EAX.
+  __ popl(ECX);  // Restore IC data array.
+  __ popl(EDX);  // Restore arguments descriptor array.
+  __ LeaveFrame();
+  Label call_target_function;
+  if (!FLAG_lazy_dispatchers) {
+    GenerateDispatcherCode(assembler, &call_target_function);
+  } else {
+    __ jmp(&call_target_function);
+  }
+
+  __ Bind(&found);
+
+  // EBX: Pointer to an IC data check group.
+  if (FLAG_optimization_counter_threshold >= 0) {
+    __ Comment("Update caller's counter");
+    // Ignore overflow.
+    __ addl(Address(EBX, count_offset), Immediate(target::ToRawSmi(1)));
+  }
+
+  __ movl(EAX, Address(EBX, target_offset));
+  __ Bind(&call_target_function);
+  __ Comment("Call target");
+  // EAX: Target function.
+  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ jmp(EBX);
+
+#if !defined(PRODUCT)
+  if (!optimized) {
+    __ Bind(&stepping);
+    __ EnterStubFrame();
+    __ pushl(ECX);
+    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+    __ popl(ECX);
+    __ LeaveFrame();
+    __ jmp(&done_stepping);
+  }
+#endif
+}
+
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+//  ECX: Inline cache data object.
+//  TOS(0): Return address.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+//   - N classes.
+//   - 1 target function.
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
+void StubCodeCompiler::GenerateTwoArgsCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+}
+
+void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+}
+
+void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+}
+
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+//  EDI: function which counter needs to be incremented.
+//  ECX: Inline cache data object.
+//  TOS(0): Return address.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+//   - N classes.
+//   - 1 target function.
+void StubCodeCompiler::GenerateOneArgOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
+                                    Token::kILLEGAL, true /* optimized */);
+}
+
+void StubCodeCompiler::
+    GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+        Assembler* assembler) {
+  __ Stop("Unimplemented");
+}
+
+void StubCodeCompiler::GenerateTwoArgsOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL, true /* optimized */);
+}
+
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// ECX: ICData
+void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == num_args.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ movl(EBX, FieldAddress(ECX, target::ICData::state_bits_offset()));
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ andl(EBX, Immediate(target::ICData::NumArgsTestedMask()));
+    __ cmpl(EBX, Immediate(0));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(EAX);
+  __ cmpb(Address(EAX, target::Isolate::single_step_offset()), Immediate(0));
+  __ j(NOT_EQUAL, &stepping, Assembler::kNearJump);
+  __ Bind(&done_stepping);
+#endif
+
+  // ECX: IC data object (preserved).
+  __ movl(EBX, FieldAddress(ECX, target::ICData::entries_offset()));
+  // EBX: ic_data_array with entries: target functions and count.
+  __ leal(EBX, FieldAddress(EBX, target::Array::data_offset()));
+  // EBX: points directly to the first ic data array element.
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(0) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(0) * target::kWordSize;
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    // Increment count for this call, ignore overflow.
+    __ addl(Address(EBX, count_offset), Immediate(target::ToRawSmi(1)));
+  }
+
+  // Load arguments descriptor into EDX.
+  __ movl(EDX,
+          FieldAddress(ECX, target::ICData::arguments_descriptor_offset()));
+
+  // Get function and call it, if possible.
+  __ movl(EAX, Address(EBX, target_offset));
+  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ jmp(EBX);
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ pushl(ECX);
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ popl(ECX);
+  __ LeaveFrame();
+  __ jmp(&done_stepping, Assembler::kNearJump);
+#endif
+}
+
+void StubCodeCompiler::GenerateOneArgUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateTwoArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+}
+
+// Stub for compiling a function and jumping to the compiled code.
+// EDX: Arguments descriptor.
+// EAX: Function.
+void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushl(EDX);  // Preserve arguments descriptor array.
+  __ pushl(EAX);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ popl(EAX);  // Restore function.
+  __ popl(EDX);  // Restore arguments descriptor array.
+  __ LeaveFrame();
+
+  // When using the interpreter, the function's code may now point to the
+  // InterpretCall stub. Make sure EAX, ECX, and EDX are preserved.
+  __ movl(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ jmp(EBX);
+}
+
+void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
+  __ Unimplemented("Interpreter not yet supported");
+}
+
+// ECX: Contains an ICData.
+void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  // Save IC data.
+  __ pushl(ECX);
+  // Room for result. Debugger stub returns address of the
+  // unpatched runtime stub.
+  __ pushl(Immediate(0));  // Room for result.
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ popl(EAX);  // Code of original stub.
+  __ popl(ECX);  // Restore IC data.
+  __ LeaveFrame();
+  // Jump to original stub.
+  __ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
+  __ jmp(EAX);
+}
+
+void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  // Room for result. Debugger stub returns address of the
+  // unpatched runtime stub.
+  __ pushl(Immediate(0));  // Room for result.
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ popl(EAX);  // Code of the original stub
+  __ LeaveFrame();
+  // Jump to original stub.
+  __ movl(EAX, FieldAddress(EAX, target::Code::entry_point_offset()));
+  __ jmp(EAX);
+}
+
+// Called only from unoptimized code.
+void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
+#if defined(PRODUCT)
+  __ ret();
+#else
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(EAX);
+  __ movzxb(EAX, Address(EAX, target::Isolate::single_step_offset()));
+  __ cmpl(EAX, Immediate(0));
+  __ j(NOT_EQUAL, &stepping, Assembler::kNearJump);
+  __ Bind(&done_stepping);
+  __ ret();
+
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ LeaveFrame();
+  __ jmp(&done_stepping, Assembler::kNearJump);
+#endif  // defined(PRODUCT)
+}
+
+// Used to check class and type arguments. Arguments passed on stack:
+// TOS + 0: return address.
+// TOS + 1: function type arguments (only if n == 4, can be raw_null).
+// TOS + 2: instantiator type arguments (only if n == 4, can be raw_null).
+// TOS + 3: instance.
+// TOS + 4: SubtypeTestCache.
+// Result in ECX: null -> not found, otherwise result (true or false).
+static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+
+  static intptr_t kFunctionTypeArgumentsInBytes = 1 * target::kWordSize;
+  static intptr_t kInstantiatorTypeArgumentsInBytes = 2 * target::kWordSize;
+  static intptr_t kInstanceOffsetInBytes = 3 * target::kWordSize;
+  static intptr_t kCacheOffsetInBytes = 4 * target::kWordSize;
+
+  const Register kInstanceReg = EAX;
+
+  const Register kInstanceCidOrFunction = ECX;
+  const Register kInstanceInstantiatorTypeArgumentsReg = EBX;
+
+  const auto& raw_null = Immediate(target::ToRawPointer(NullObject()));
+
+  __ movl(kInstanceReg, Address(ESP, kInstanceOffsetInBytes));
+
+  // Loop initialization (moved up here to avoid having all dependent loads
+  // after each other)
+  __ movl(EDX, Address(ESP, kCacheOffsetInBytes));
+  __ movl(EDX, FieldAddress(EDX, target::SubtypeTestCache::cache_offset()));
+  __ addl(EDX, Immediate(target::Array::data_offset() - kHeapObjectTag));
+
+  Label loop, not_closure;
+  if (n >= 4) {
+    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
+  } else {
+    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
+  }
+  __ cmpl(kInstanceCidOrFunction, Immediate(kClosureCid));
+  __ j(NOT_EQUAL, &not_closure, Assembler::kNearJump);
+
+  // Closure handling.
+  {
+    __ movl(kInstanceCidOrFunction,
+            FieldAddress(kInstanceReg, target::Closure::function_offset()));
+    if (n >= 2) {
+      __ movl(
+          kInstanceInstantiatorTypeArgumentsReg,
+          FieldAddress(kInstanceReg,
+                       target::Closure::instantiator_type_arguments_offset()));
+      if (n >= 6) {
+        __ pushl(FieldAddress(
+            kInstanceReg, target::Closure::delayed_type_arguments_offset()));
+        __ pushl(FieldAddress(
+            kInstanceReg, target::Closure::function_type_arguments_offset()));
+      }
+    }
+    __ jmp(&loop, Assembler::kNearJump);
+  }
+
+  // Non-Closure handling.
+  {
+    __ Bind(&not_closure);
+    if (n >= 2) {
+      Label has_no_type_arguments;
+      __ LoadClassById(EDI, kInstanceCidOrFunction);
+      __ movl(kInstanceInstantiatorTypeArgumentsReg, raw_null);
+      __ movl(
+          EDI,
+          FieldAddress(
+              EDI,
+              target::Class::type_arguments_field_offset_in_words_offset()));
+      __ cmpl(EDI, Immediate(target::Class::kNoTypeArguments));
+      __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
+      __ movl(kInstanceInstantiatorTypeArgumentsReg,
+              FieldAddress(kInstanceReg, EDI, TIMES_4, 0));
+      __ Bind(&has_no_type_arguments);
+
+      if (n >= 6) {
+        __ pushl(raw_null);  // delayed.
+        __ pushl(raw_null);  // function.
+      }
+    }
+    __ SmiTag(kInstanceCidOrFunction);
+  }
+
+  const intptr_t kInstanceParentFunctionTypeArgumentsFromSp = 0;
+  const intptr_t kInstanceDelayedFunctionTypeArgumentsFromSp =
+      target::kWordSize;
+  const intptr_t args_offset = n >= 6 ? 2 * target::kWordSize : 0;
+
+  Label found, not_found, next_iteration;
+
+  // Loop header.
+  __ Bind(&loop);
+  __ movl(
+      EDI,
+      Address(EDX, target::kWordSize *
+                       target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmpl(EDI, raw_null);
+  __ j(EQUAL, &not_found, Assembler::kNearJump);
+  __ cmpl(EDI, kInstanceCidOrFunction);
+  if (n == 1) {
+    __ j(EQUAL, &found, Assembler::kNearJump);
+  } else {
+    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+    __ cmpl(kInstanceInstantiatorTypeArgumentsReg,
+            Address(EDX, target::kWordSize *
+                             target::SubtypeTestCache::kInstanceTypeArguments));
+    if (n == 2) {
+      __ j(EQUAL, &found, Assembler::kNearJump);
+    } else {
+      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+      __ movl(
+          EDI,
+          Address(EDX,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kInstantiatorTypeArguments));
+      __ cmpl(EDI,
+              Address(ESP, args_offset + kInstantiatorTypeArgumentsInBytes));
+      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+      __ movl(
+          EDI,
+          Address(EDX, target::kWordSize *
+                           target::SubtypeTestCache::kFunctionTypeArguments));
+      __ cmpl(EDI, Address(ESP, args_offset + kFunctionTypeArgumentsInBytes));
+      if (n == 4) {
+        __ j(EQUAL, &found, Assembler::kNearJump);
+      } else {
+        ASSERT(n == 6);
+        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+
+        __ movl(EDI,
+                Address(EDX, target::kWordSize *
+                                 target::SubtypeTestCache::
+                                     kInstanceParentFunctionTypeArguments));
+        __ cmpl(EDI, Address(ESP, kInstanceParentFunctionTypeArgumentsFromSp));
+        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+        __ movl(EDI,
+                Address(EDX, target::kWordSize *
+                                 target::SubtypeTestCache::
+                                     kInstanceDelayedFunctionTypeArguments));
+        __ cmpl(EDI, Address(ESP, kInstanceDelayedFunctionTypeArgumentsFromSp));
+        __ j(EQUAL, &found, Assembler::kNearJump);
+      }
+    }
+  }
+  __ Bind(&next_iteration);
+  __ addl(EDX, Immediate(target::kWordSize *
+                         target::SubtypeTestCache::kTestEntryLength));
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&found);
+  __ movl(ECX, Address(EDX, target::kWordSize *
+                                target::SubtypeTestCache::kTestResult));
+  if (n == 6) {
+    __ Drop(2);
+  }
+  __ ret();
+
+  __ Bind(&not_found);
+  __ movl(ECX, raw_null);
+  if (n == 6) {
+    __ Drop(2);
+  }
+  __ ret();
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype1TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 1);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 2);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 4);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 6);
+}
+
+void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  // Not implemented on ia32.
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  // Not implemented on ia32.
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  // Not implemented on ia32.
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  // Not implemented on ia32.
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
+    Assembler* assembler) {
+  // Not implemented on ia32.
+  __ Breakpoint();
+}
+
+void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
+  // Not implemented on ia32.
+  __ Breakpoint();
+}
+
+// Return the current stack pointer address, used to do stack alignment checks.
+// TOS + 0: return address
+// Result in EAX.
+void StubCodeCompiler::GenerateGetCStackPointerStub(Assembler* assembler) {
+  __ leal(EAX, Address(ESP, target::kWordSize));
+  __ ret();
+}
+
+// Jump to a frame on the call stack.
+// TOS + 0: return address
+// TOS + 1: program_counter
+// TOS + 2: stack_pointer
+// TOS + 3: frame_pointer
+// TOS + 4: thread
+// No Result.
+void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
+  __ movl(THR, Address(ESP, 4 * target::kWordSize));  // Load target thread.
+  __ movl(EBP,
+          Address(ESP, 3 * target::kWordSize));  // Load target frame_pointer.
+  __ movl(EBX,
+          Address(ESP, 1 * target::kWordSize));  // Load target PC into EBX.
+  __ movl(ESP,
+          Address(ESP, 2 * target::kWordSize));  // Load target stack_pointer.
+  // Set tag.
+  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+  // Clear top exit frame.
+  __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+  __ jmp(EBX);  // Jump to the exception handler code.
+}
+
+// Run an exception handler.  Execution comes from JumpToFrame stub.
+//
+// The arguments are stored in the Thread object.
+// No result.
+void StubCodeCompiler::GenerateRunExceptionHandlerStub(Assembler* assembler) {
+  ASSERT(kExceptionObjectReg == EAX);
+  ASSERT(kStackTraceObjectReg == EDX);
+  __ movl(EBX, Address(THR, target::Thread::resume_pc_offset()));
+
+  ASSERT(target::CanLoadFromThread(NullObject()));
+  __ movl(ECX, Address(THR, target::Thread::OffsetFromThread(NullObject())));
+
+  // Load the exception from the current thread.
+  Address exception_addr(THR, target::Thread::active_exception_offset());
+  __ movl(kExceptionObjectReg, exception_addr);
+  __ movl(exception_addr, ECX);
+
+  // Load the stacktrace from the current thread.
+  Address stacktrace_addr(THR, target::Thread::active_stacktrace_offset());
+  __ movl(kStackTraceObjectReg, stacktrace_addr);
+  __ movl(stacktrace_addr, ECX);
+
+  __ jmp(EBX);  // Jump to continuation point.
+}
+
+// Deoptimize a frame on the call stack before rewinding.
+// The arguments are stored in the Thread object.
+// No result.
+void StubCodeCompiler::GenerateDeoptForRewindStub(Assembler* assembler) {
+  // Push the deopt pc.
+  __ pushl(Address(THR, target::Thread::resume_pc_offset()));
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+
+  // After we have deoptimized, jump to the correct frame.
+  __ EnterStubFrame();
+  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
+  __ LeaveFrame();
+  __ int3();
+}
+
+// Calls to the runtime to optimize the given function.
+// EBX: function to be reoptimized.
+// EDX: argument descriptor (preserved).
+void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushl(EDX);
+  __ pushl(Immediate(0));  // Setup space on stack for return value.
+  __ pushl(EBX);
+  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
+  __ popl(EAX);  // Discard argument.
+  __ popl(EAX);  // Get Function object
+  __ popl(EDX);  // Restore argument descriptor.
+  __ LeaveFrame();
+  __ movl(CODE_REG, FieldAddress(EAX, target::Function::code_offset()));
+  __ movl(EAX, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ jmp(EAX);
+  __ int3();
+}
+
+// Does identical check (object references are equal or not equal) with special
+// checks for boxed numbers.
+// Return ZF set.
+// Note: A Mint cannot contain a value that would fit in Smi.
+static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
+                                                 const Register left,
+                                                 const Register right,
+                                                 const Register temp) {
+  Label reference_compare, done, check_mint;
+  // If any of the arguments is Smi do reference compare.
+  __ testl(left, Immediate(kSmiTagMask));
+  __ j(ZERO, &reference_compare, Assembler::kNearJump);
+  __ testl(right, Immediate(kSmiTagMask));
+  __ j(ZERO, &reference_compare, Assembler::kNearJump);
+
+  // Value compare for two doubles.
+  __ CompareClassId(left, kDoubleCid, temp);
+  __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump);
+  __ CompareClassId(right, kDoubleCid, temp);
+  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+
+  // Double values bitwise compare.
+  __ movl(temp, FieldAddress(left, target::Double::value_offset() +
+                                       0 * target::kWordSize));
+  __ cmpl(temp, FieldAddress(right, target::Double::value_offset() +
+                                        0 * target::kWordSize));
+  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+  __ movl(temp, FieldAddress(left, target::Double::value_offset() +
+                                       1 * target::kWordSize));
+  __ cmpl(temp, FieldAddress(right, target::Double::value_offset() +
+                                        1 * target::kWordSize));
+  __ jmp(&done, Assembler::kNearJump);
+
+  __ Bind(&check_mint);
+  __ CompareClassId(left, kMintCid, temp);
+  __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump);
+  __ CompareClassId(right, kMintCid, temp);
+  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+  __ movl(temp, FieldAddress(left, target::Mint::value_offset() +
+                                       0 * target::kWordSize));
+  __ cmpl(temp, FieldAddress(right, target::Mint::value_offset() +
+                                        0 * target::kWordSize));
+  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
+  __ movl(temp, FieldAddress(left, target::Mint::value_offset() +
+                                       1 * target::kWordSize));
+  __ cmpl(temp, FieldAddress(right, target::Mint::value_offset() +
+                                        1 * target::kWordSize));
+  __ jmp(&done, Assembler::kNearJump);
+
+  __ Bind(&reference_compare);
+  __ cmpl(left, right);
+  __ Bind(&done);
+}
+
+// Called only from unoptimized code. All relevant registers have been saved.
+// TOS + 0: return address
+// TOS + 1: right argument.
+// TOS + 2: left argument.
+// Returns ZF set.
+void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(EAX);
+  __ movzxb(EAX, Address(EAX, target::Isolate::single_step_offset()));
+  __ cmpl(EAX, Immediate(0));
+  __ j(NOT_EQUAL, &stepping);
+  __ Bind(&done_stepping);
+#endif
+
+  const Register left = EAX;
+  const Register right = EDX;
+  const Register temp = ECX;
+  __ movl(left, Address(ESP, 2 * target::kWordSize));
+  __ movl(right, Address(ESP, 1 * target::kWordSize));
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
+  __ ret();
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ LeaveFrame();
+  __ jmp(&done_stepping);
+#endif
+}
+
+// Called from optimized code only.
+// TOS + 0: return address
+// TOS + 1: right argument.
+// TOS + 2: left argument.
+// Returns ZF set.
+void StubCodeCompiler::GenerateOptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+  const Register left = EAX;
+  const Register right = EDX;
+  const Register temp = ECX;
+  __ movl(left, Address(ESP, 2 * target::kWordSize));
+  __ movl(right, Address(ESP, 1 * target::kWordSize));
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
+  __ ret();
+}
+
+// Called from megamorphic calls.
+//  EBX: receiver
+//  ECX: target::MegamorphicCache (preserved)
+// Passed to target:
+//  EBX: target entry point
+//  EDX: argument descriptor
+void StubCodeCompiler::GenerateMegamorphicCallStub(Assembler* assembler) {
+  // Jump if receiver is a smi.
+  Label smi_case;
+  // Check if object (in tmp) is a Smi.
+  __ testl(EBX, Immediate(kSmiTagMask));
+  // Jump out of line for smi case.
+  __ j(ZERO, &smi_case, Assembler::kNearJump);
+
+  // Loads the cid of the instance.
+  __ LoadClassId(EAX, EBX);
+
+  Label cid_loaded;
+  __ Bind(&cid_loaded);
+  __ movl(EBX, FieldAddress(ECX, target::MegamorphicCache::mask_offset()));
+  __ movl(EDI, FieldAddress(ECX, target::MegamorphicCache::buckets_offset()));
+  // EDI: cache buckets array.
+  // EBX: mask as a smi.
+
+  // Tag cid as a smi.
+  __ addl(EAX, EAX);
+
+  // Compute the table index.
+  ASSERT(target::MegamorphicCache::kSpreadFactor == 7);
+  // Use leal and subl multiply with 7 == 8 - 1.
+  __ leal(EDX, Address(EAX, TIMES_8, 0));
+  __ subl(EDX, EAX);
+
+  Label loop;
+  __ Bind(&loop);
+  __ andl(EDX, EBX);
+
+  const intptr_t base = target::Array::data_offset();
+  Label probe_failed;
+  // EDX is smi tagged, but table entries are two words, so TIMES_4.
+  __ cmpl(EAX, FieldAddress(EDI, EDX, TIMES_4, base));
+  __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // 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(EBX, FieldAddress(EAX, target::Function::entry_point_offset()));
+  __ ret();
+
+  __ Bind(&probe_failed);
+  // Probe failed, check if it is a miss.
+  __ cmpl(FieldAddress(EDI, EDX, TIMES_4, base),
+          Immediate(target::ToRawSmi(kIllegalCid)));
+  __ j(ZERO, &load_target, Assembler::kNearJump);
+
+  // Try next entry in the table.
+  __ AddImmediate(EDX, Immediate(target::ToRawSmi(1)));
+  __ jmp(&loop);
+
+  // Load cid for the Smi case.
+  __ Bind(&smi_case);
+  __ movl(EAX, Immediate(kSmiCid));
+  __ jmp(&cid_loaded);
+}
+
+// Called from switchable IC calls.
+//  EBX: receiver
+//  ECX: ICData (preserved)
+// Passed to target:
+//  EDX: arguments descriptor
+void StubCodeCompiler::GenerateICCallThroughFunctionStub(Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateICCallThroughCodeStub(Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
+    Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
+  __ int3();
+}
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
new file mode 100644
index 0000000..b357b77
--- /dev/null
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -0,0 +1,3233 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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"
+
+#define SHOULD_NOT_INCLUDE_RUNTIME
+
+#include "vm/compiler/stub_code_compiler.h"
+
+#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/class_id.h"
+#include "vm/code_entry_kind.h"
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/constants_x64.h"
+#include "vm/instructions.h"
+#include "vm/static_type_exactness_state.h"
+#include "vm/tags.h"
+
+#define __ assembler->
+
+namespace dart {
+
+DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
+DEFINE_FLAG(bool,
+            use_slow_path,
+            false,
+            "Set to true for debugging & verifying the slow paths.");
+DECLARE_FLAG(bool, enable_interpreter);
+DECLARE_FLAG(bool, precompiled_mode);
+
+namespace compiler {
+
+// Input parameters:
+//   RSP : points to return address.
+//   RSP + 8 : address of last argument in argument array.
+//   RSP + 8*R10 : address of first argument in argument array.
+//   RSP + 8*R10 + 8 : address of return value.
+//   RBX : address of the runtime function to call.
+//   R10 : number of arguments to the call.
+// Must preserve callee saved registers R12 and R13.
+void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) {
+  const intptr_t thread_offset = target::NativeArguments::thread_offset();
+  const intptr_t argc_tag_offset = target::NativeArguments::argc_tag_offset();
+  const intptr_t argv_offset = target::NativeArguments::argv_offset();
+  const intptr_t retval_offset = target::NativeArguments::retval_offset();
+
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::call_to_runtime_stub_offset()));
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ movq(RAX, Immediate(VMTag::kDartCompiledTagId));
+    __ cmpq(RAX, Assembler::VMTagAddress());
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing VM code.
+  __ movq(Assembler::VMTagAddress(), RBX);
+
+  // Reserve space for arguments and align frame before entering C++ world.
+  __ subq(RSP, Immediate(target::NativeArguments::StructSize()));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Pass target::NativeArguments structure by value and call runtime.
+  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
+  // There are no runtime calls to closures, so we do not need to set the tag
+  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
+  __ movq(Address(RSP, argc_tag_offset),
+          R10);  // Set argc in target::NativeArguments.
+  // Compute argv.
+  __ leaq(RAX,
+          Address(RBP, R10, TIMES_8,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+  __ movq(Address(RSP, argv_offset),
+          RAX);  // Set argv in target::NativeArguments.
+  __ addq(RAX,
+          Immediate(1 * target::kWordSize));  // Retval is next to 1st argument.
+  __ movq(Address(RSP, retval_offset),
+          RAX);  // Set retval in target::NativeArguments.
+#if defined(_WIN64)
+  ASSERT(target::NativeArguments::StructSize() >
+         CallingConventions::kRegisterTransferLimit);
+  __ movq(CallingConventions::kArg1Reg, RSP);
+#endif
+  __ CallCFunction(RBX);
+
+  // Mark that the thread is executing Dart code.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  // Restore the global object pool after returning from runtime (old space is
+  // moving, so the GOP could have been relocated).
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ movq(PP, Address(THR, target::Thread::global_object_pool_offset()));
+  }
+
+  __ LeaveStubFrame();
+
+  // The following return can jump to a lazy-deopt stub, which assumes RAX
+  // contains a return value and will save it in a GC-visible way.  We therefore
+  // have to ensure RAX does not contain any garbage value left from the C
+  // function we called (which has return type "void").
+  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
+  __ xorq(RAX, RAX);
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateSharedStub(
+    Assembler* assembler,
+    bool save_fpu_registers,
+    const RuntimeEntry* target,
+    intptr_t self_code_stub_offset_from_thread,
+    bool allow_return) {
+  // We want the saved registers to appear like part of the caller's frame, so
+  // we push them before calling EnterStubFrame.
+  __ PushRegisters(kDartAvailableCpuRegs,
+                   save_fpu_registers ? kAllFpuRegistersList : 0);
+
+  const intptr_t kSavedCpuRegisterSlots =
+      Utils::CountOneBitsWord(kDartAvailableCpuRegs);
+
+  const intptr_t kSavedFpuRegisterSlots =
+      save_fpu_registers
+          ? kNumberOfFpuRegisters * kFpuRegisterSize / target::kWordSize
+          : 0;
+
+  const intptr_t kAllSavedRegistersSlots =
+      kSavedCpuRegisterSlots + kSavedFpuRegisterSlots;
+
+  // Copy down the return address so the stack layout is correct.
+  __ pushq(Address(RSP, kAllSavedRegistersSlots * target::kWordSize));
+
+  __ movq(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
+
+  __ EnterStubFrame();
+  __ CallRuntime(*target, /*argument_count=*/0);
+  if (!allow_return) {
+    __ Breakpoint();
+    return;
+  }
+  __ LeaveStubFrame();
+
+  // Drop "official" return address -- we can just use the one stored above the
+  // saved registers.
+  __ Drop(1);
+
+  __ PopRegisters(kDartAvailableCpuRegs,
+                  save_fpu_registers ? kAllFpuRegistersList : 0);
+
+  __ ret();
+}
+
+// RBX: The extracted method.
+// RDX: The type_arguments_field_offset (or 0)
+void StubCodeCompiler::GenerateBuildMethodExtractorStub(
+    Assembler* assembler,
+    const Object& closure_allocation_stub,
+    const Object& context_allocation_stub) {
+  const intptr_t kReceiverOffsetInWords =
+      compiler::target::frame_layout.param_end_from_fp + 1;
+
+  __ EnterStubFrame();
+
+  // Push type_arguments vector (or null)
+  Label no_type_args;
+  __ movq(RCX, Address(THR, target::Thread::object_null_offset()));
+  __ cmpq(RDX, Immediate(0));
+  __ j(EQUAL, &no_type_args, Assembler::kNearJump);
+  __ movq(RAX,
+          Address(RBP, compiler::target::kWordSize * kReceiverOffsetInWords));
+  __ movq(RCX, Address(RAX, RDX, TIMES_1, 0));
+  __ Bind(&no_type_args);
+  __ pushq(RCX);
+
+  // Push extracted method.
+  __ pushq(RBX);
+
+  // Allocate context.
+  {
+    Label done, slow_path;
+    __ TryAllocateArray(kContextCid, target::Context::InstanceSize(1),
+                        &slow_path, Assembler::kFarJump,
+                        RAX,  // instance
+                        RSI,  // end address
+                        RDI);
+    __ movq(RSI, Address(THR, target::Thread::object_null_offset()));
+    __ movq(FieldAddress(RAX, target::Context::parent_offset()), RSI);
+    __ movq(FieldAddress(RAX, target::Context::num_variables_offset()),
+            Immediate(1));
+    __ jmp(&done);
+
+    __ Bind(&slow_path);
+
+    __ LoadImmediate(/*num_vars=*/R10, Immediate(1));
+    __ LoadObject(CODE_REG, context_allocation_stub);
+    __ call(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+
+    __ Bind(&done);
+  }
+
+  // Store receiver in context
+  __ movq(RSI,
+          Address(RBP, compiler::target::kWordSize * kReceiverOffsetInWords));
+  __ StoreIntoObject(
+      RAX, FieldAddress(RAX, target::Context::variable_offset(0)), RSI);
+
+  // Push context.
+  __ pushq(RAX);
+
+  // Allocate closure.
+  __ LoadObject(CODE_REG, closure_allocation_stub);
+  __ call(FieldAddress(
+      CODE_REG, target::Code::entry_point_offset(CodeEntryKind::kUnchecked)));
+
+  // Populate closure object.
+  __ popq(RCX);  // Pop context.
+  __ StoreIntoObject(RAX, FieldAddress(RAX, target::Closure::context_offset()),
+                     RCX);
+  __ popq(RCX);  // Pop extracted method.
+  __ StoreIntoObjectNoBarrier(
+      RAX, FieldAddress(RAX, target::Closure::function_offset()), RCX);
+  __ popq(RCX);  // Pop type argument vector.
+  __ StoreIntoObjectNoBarrier(
+      RAX,
+      FieldAddress(RAX, target::Closure::instantiator_type_arguments_offset()),
+      RCX);
+  __ LoadObject(RCX, EmptyTypeArguments());
+  __ StoreIntoObjectNoBarrier(
+      RAX, FieldAddress(RAX, target::Closure::delayed_type_arguments_offset()),
+      RCX);
+
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kNullErrorRuntimeEntry,
+      target::Thread::null_error_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/false);
+}
+
+void StubCodeCompiler::GenerateNullErrorSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kNullErrorRuntimeEntry,
+      target::Thread::null_error_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/false);
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithoutFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
+      target::Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
+      /*allow_return=*/true);
+}
+
+void StubCodeCompiler::GenerateStackOverflowSharedWithFPURegsStub(
+    Assembler* assembler) {
+  GenerateSharedStub(
+      assembler, /*save_fpu_registers=*/true, &kStackOverflowRuntimeEntry,
+      target::Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
+      /*allow_return=*/true);
+}
+
+// Input parameters:
+//   RSP : points to return address.
+//   RDI : stop message (const char*).
+// Must preserve all registers.
+void StubCodeCompiler::GeneratePrintStopMessageStub(Assembler* assembler) {
+  __ EnterCallRuntimeFrame(0);
+// Call the runtime leaf function. RDI already contains the parameter.
+#if defined(_WIN64)
+  __ movq(CallingConventions::kArg1Reg, RDI);
+#endif
+  __ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ ret();
+}
+
+// Input parameters:
+//   RSP : points to return address.
+//   RSP + 8 : address of return value.
+//   RAX : address of first argument in argument array.
+//   RBX : address of the native function to call.
+//   R10 : argc_tag including number of arguments and function kind.
+static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
+                                              Address wrapper_address) {
+  const intptr_t native_args_struct_offset = 0;
+  const intptr_t thread_offset =
+      target::NativeArguments::thread_offset() + native_args_struct_offset;
+  const intptr_t argc_tag_offset =
+      target::NativeArguments::argc_tag_offset() + native_args_struct_offset;
+  const intptr_t argv_offset =
+      target::NativeArguments::argv_offset() + native_args_struct_offset;
+  const intptr_t retval_offset =
+      target::NativeArguments::retval_offset() + native_args_struct_offset;
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ movq(R8, Immediate(VMTag::kDartCompiledTagId));
+    __ cmpq(R8, Assembler::VMTagAddress());
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ movq(Assembler::VMTagAddress(), RBX);
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // RDI) and align frame before entering the C++ world.
+  __ subq(RSP, Immediate(target::NativeArguments::StructSize()));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Pass target::NativeArguments structure by value and call native function.
+  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
+  __ movq(Address(RSP, argc_tag_offset),
+          R10);  // Set argc in target::NativeArguments.
+  __ movq(Address(RSP, argv_offset),
+          RAX);  // Set argv in target::NativeArguments.
+  __ leaq(RAX,
+          Address(RBP, 2 * target::kWordSize));  // Compute return value addr.
+  __ movq(Address(RSP, retval_offset),
+          RAX);  // Set retval in target::NativeArguments.
+
+  // Pass the pointer to the target::NativeArguments.
+  __ movq(CallingConventions::kArg1Reg, RSP);
+  // Pass pointer to function entrypoint.
+  __ movq(CallingConventions::kArg2Reg, RBX);
+
+  __ movq(RAX, wrapper_address);
+  __ CallCFunction(RAX);
+
+  // Mark that the thread is executing Dart code.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateCallNoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::no_scope_native_wrapper_entry_point_offset()));
+}
+
+void StubCodeCompiler::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
+  GenerateCallNativeWithWrapperStub(
+      assembler,
+      Address(THR,
+              target::Thread::auto_scope_native_wrapper_entry_point_offset()));
+}
+
+// Input parameters:
+//   RSP : points to return address.
+//   RSP + 8 : address of return value.
+//   RAX : address of first argument in argument array.
+//   RBX : address of the native function to call.
+//   R10 : argc_tag including number of arguments and function kind.
+void StubCodeCompiler::GenerateCallBootstrapNativeStub(Assembler* assembler) {
+  const intptr_t native_args_struct_offset = 0;
+  const intptr_t thread_offset =
+      target::NativeArguments::thread_offset() + native_args_struct_offset;
+  const intptr_t argc_tag_offset =
+      target::NativeArguments::argc_tag_offset() + native_args_struct_offset;
+  const intptr_t argv_offset =
+      target::NativeArguments::argv_offset() + native_args_struct_offset;
+  const intptr_t retval_offset =
+      target::NativeArguments::retval_offset() + native_args_struct_offset;
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to native code.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ movq(R8, Immediate(VMTag::kDartCompiledTagId));
+    __ cmpq(R8, Assembler::VMTagAddress());
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing native code.
+  __ movq(Assembler::VMTagAddress(), RBX);
+
+  // Reserve space for the native arguments structure passed on the stack (the
+  // outgoing pointer parameter to the native arguments structure is passed in
+  // RDI) and align frame before entering the C++ world.
+  __ subq(RSP, Immediate(target::NativeArguments::StructSize()));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Pass target::NativeArguments structure by value and call native function.
+  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
+  __ movq(Address(RSP, argc_tag_offset),
+          R10);  // Set argc in target::NativeArguments.
+  __ movq(Address(RSP, argv_offset),
+          RAX);  // Set argv in target::NativeArguments.
+  __ leaq(RAX,
+          Address(RBP, 2 * target::kWordSize));  // Compute return value addr.
+  __ movq(Address(RSP, retval_offset),
+          RAX);  // Set retval in target::NativeArguments.
+
+  // Pass the pointer to the target::NativeArguments.
+  __ movq(CallingConventions::kArg1Reg, RSP);
+  __ CallCFunction(RBX);
+
+  // Mark that the thread is executing Dart code.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+// Input parameters:
+//   R10: arguments descriptor array.
+void StubCodeCompiler::GenerateCallStaticFunctionStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(R10);  // Preserve arguments descriptor array.
+  // Setup space on stack for return value.
+  __ pushq(Immediate(0));
+  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
+  __ popq(CODE_REG);  // Get Code object result.
+  __ popq(R10);       // Restore arguments descriptor array.
+  // Remove the stub frame as we are about to jump to the dart function.
+  __ LeaveStubFrame();
+
+  __ movq(RBX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ jmp(RBX);
+}
+
+// Called from a static call only when an invalid code has been entered
+// (invalid because its function was optimized or deoptimized).
+// R10: arguments descriptor array.
+void StubCodeCompiler::GenerateFixCallersTargetStub(Assembler* assembler) {
+  // Load code pointer to this stub from the thread:
+  // The one that is passed in, is not correct - it points to the code object
+  // that needs to be replaced.
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::fix_callers_target_code_offset()));
+  __ EnterStubFrame();
+  __ pushq(R10);  // Preserve arguments descriptor array.
+  // Setup space on stack for return value.
+  __ pushq(Immediate(0));
+  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
+  __ popq(CODE_REG);  // Get Code object.
+  __ popq(R10);       // Restore arguments descriptor array.
+  __ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ LeaveStubFrame();
+  __ jmp(RAX);
+  __ int3();
+}
+
+// Called from object allocate instruction when the allocation stub has been
+// disabled.
+void StubCodeCompiler::GenerateFixAllocationStubTargetStub(
+    Assembler* assembler) {
+  // Load code pointer to this stub from the thread:
+  // The one that is passed in, is not correct - it points to the code object
+  // that needs to be replaced.
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::fix_allocation_stub_code_offset()));
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  __ pushq(Immediate(0));
+  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
+  __ popq(CODE_REG);  // Get Code object.
+  __ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ LeaveStubFrame();
+  __ jmp(RAX);
+  __ int3();
+}
+
+// Input parameters:
+//   R10: smi-tagged argument count, may be zero.
+//   RBP[target::frame_layout.param_end_from_fp + 1]: last argument.
+static void PushArrayOfArguments(Assembler* assembler) {
+  __ LoadObject(R12, NullObject());
+  // Allocate array to store arguments of caller.
+  __ movq(RBX, R12);  // Null element type for raw Array.
+  __ Call(StubCodeAllocateArray());
+  __ SmiUntag(R10);
+  // RAX: newly allocated array.
+  // R10: length of the array (was preserved by the stub).
+  __ pushq(RAX);  // Array is in RAX and on top of stack.
+  __ leaq(R12,
+          Address(RBP, R10, TIMES_8,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+  __ leaq(RBX, FieldAddress(RAX, target::Array::data_offset()));
+  // R12: address of first argument on stack.
+  // RBX: address of first argument in array.
+  Label loop, loop_condition;
+#if defined(DEBUG)
+  static const bool kJumpLength = Assembler::kFarJump;
+#else
+  static const bool kJumpLength = Assembler::kNearJump;
+#endif  // DEBUG
+  __ jmp(&loop_condition, kJumpLength);
+  __ Bind(&loop);
+  __ movq(RDI, Address(R12, 0));
+  // Generational barrier is needed, array is not necessarily in new space.
+  __ StoreIntoObject(RAX, Address(RBX, 0), RDI);
+  __ addq(RBX, Immediate(target::kWordSize));
+  __ subq(R12, Immediate(target::kWordSize));
+  __ Bind(&loop_condition);
+  __ decq(R10);
+  __ j(POSITIVE, &loop, Assembler::kNearJump);
+}
+
+// Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
+// This stub translates optimized frame into unoptimized frame. The optimized
+// frame can contain values in registers and on stack, the unoptimized
+// frame contains all values on stack.
+// Deoptimization occurs in following steps:
+// - Push all registers that can contain values.
+// - Call C routine to copy the stack and saved registers into temporary buffer.
+// - Adjust caller's frame to correct unoptimized frame size.
+// - Fill the unoptimized frame.
+// - Materialize objects that require allocation (e.g. Double instances).
+// GC can occur only after frame is fully rewritten.
+// Stack after EnterDartFrame(0, PP, kNoRegister) below:
+//   +------------------+
+//   | Saved PP         | <- PP
+//   +------------------+
+//   | PC marker        | <- TOS
+//   +------------------+
+//   | Saved FP         | <- FP of stub
+//   +------------------+
+//   | return-address   |  (deoptimization point)
+//   +------------------+
+//   | Saved CODE_REG   |
+//   +------------------+
+//   | ...              | <- SP of optimized frame
+//
+// Parts of the code cannot GC, part of the code can GC.
+static void GenerateDeoptimizationSequence(Assembler* assembler,
+                                           DeoptStubKind kind) {
+  // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+  // is no need to set the correct PC marker or load PP, since they get patched.
+  __ EnterStubFrame();
+
+  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
+  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
+  const intptr_t saved_result_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - RAX);
+  const intptr_t saved_exception_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - RAX);
+  const intptr_t saved_stacktrace_slot_from_fp =
+      compiler::target::frame_layout.first_local_from_fp + 1 -
+      (kNumberOfCpuRegisters - RDX);
+  // Result in RAX is preserved as part of pushing all registers below.
+
+  // Push registers in their enumeration order: lowest register number at
+  // lowest address.
+  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
+    if (i == CODE_REG) {
+      // Save the original value of CODE_REG pushed before invoking this stub
+      // instead of the value used to call this stub.
+      __ pushq(Address(RBP, 2 * target::kWordSize));
+    } else {
+      __ pushq(static_cast<Register>(i));
+    }
+  }
+  __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
+  intptr_t offset = 0;
+  for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
+    XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
+    __ movups(Address(RSP, offset), xmm_reg);
+    offset += kFpuRegisterSize;
+  }
+
+  // Pass address of saved registers block.
+  __ movq(CallingConventions::kArg1Reg, RSP);
+  bool is_lazy =
+      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
+  __ movq(CallingConventions::kArg2Reg, Immediate(is_lazy ? 1 : 0));
+  __ ReserveAlignedFrameSpace(0);  // Ensure stack is aligned before the call.
+  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
+  // Result (RAX) is stack-size (FP - SP) in bytes.
+
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into RBX temporarily.
+    __ movq(RBX, Address(RBP, saved_result_slot_from_fp * target::kWordSize));
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore result into RBX temporarily.
+    __ movq(RBX,
+            Address(RBP, saved_exception_slot_from_fp * target::kWordSize));
+    __ movq(RDX,
+            Address(RBP, saved_stacktrace_slot_from_fp * target::kWordSize));
+  }
+
+  // There is a Dart Frame on the stack. We must restore PP and leave frame.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+
+  __ popq(RCX);       // Preserve return address.
+  __ movq(RSP, RBP);  // Discard optimized frame.
+  __ subq(RSP, RAX);  // Reserve space for deoptimized frame.
+  __ pushq(RCX);      // Restore return address.
+
+  // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+  // is no need to set the correct PC marker or load PP, since they get patched.
+  __ EnterStubFrame();
+
+  if (kind == kLazyDeoptFromReturn) {
+    __ pushq(RBX);  // Preserve result as first local.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ pushq(RBX);  // Preserve exception as first local.
+    __ pushq(RDX);  // Preserve stacktrace as second local.
+  }
+  __ ReserveAlignedFrameSpace(0);
+  // Pass last FP as a parameter.
+  __ movq(CallingConventions::kArg1Reg, RBP);
+  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
+  if (kind == kLazyDeoptFromReturn) {
+    // Restore result into RBX.
+    __ movq(RBX,
+            Address(RBP, compiler::target::frame_layout.first_local_from_fp *
+                             target::kWordSize));
+  } else if (kind == kLazyDeoptFromThrow) {
+    // Restore exception into RBX.
+    __ movq(RBX,
+            Address(RBP, compiler::target::frame_layout.first_local_from_fp *
+                             target::kWordSize));
+    // Restore stacktrace into RDX.
+    __ movq(
+        RDX,
+        Address(RBP, (compiler::target::frame_layout.first_local_from_fp - 1) *
+                         target::kWordSize));
+  }
+  // Code above cannot cause GC.
+  // There is a Dart Frame on the stack. We must restore PP and leave frame.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+
+  // Frame is fully rewritten at this point and it is safe to perform a GC.
+  // Materialize any objects that were deferred by FillFrame because they
+  // require allocation.
+  // Enter stub frame with loading PP. The caller's PP is not materialized yet.
+  __ EnterStubFrame();
+  if (kind == kLazyDeoptFromReturn) {
+    __ pushq(RBX);  // Preserve result, it will be GC-d here.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ pushq(RBX);  // Preserve exception.
+    __ pushq(RDX);  // Preserve stacktrace.
+  }
+  __ pushq(Immediate(target::ToRawSmi(0)));  // Space for the result.
+  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
+  // Result tells stub how many bytes to remove from the expression stack
+  // of the bottom-most frame. They were used as materialization arguments.
+  __ popq(RBX);
+  __ SmiUntag(RBX);
+  if (kind == kLazyDeoptFromReturn) {
+    __ popq(RAX);  // Restore result.
+  } else if (kind == kLazyDeoptFromThrow) {
+    __ popq(RDX);  // Restore stacktrace.
+    __ popq(RAX);  // Restore exception.
+  }
+  __ LeaveStubFrame();
+
+  __ popq(RCX);       // Pop return address.
+  __ addq(RSP, RBX);  // Remove materialization arguments.
+  __ pushq(RCX);      // Push return address.
+  // The caller is responsible for emitting the return instruction.
+}
+
+// RAX: result, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromReturnStub(
+    Assembler* assembler) {
+  // Push zap value instead of CODE_REG for lazy deopt.
+  __ pushq(Immediate(kZapCodeReg));
+  // Return address for "call" to deopt stub.
+  __ pushq(Immediate(kZapReturnAddress));
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::lazy_deopt_from_return_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
+  __ ret();
+}
+
+// RAX: exception, must be preserved
+// RDX: stacktrace, must be preserved
+void StubCodeCompiler::GenerateDeoptimizeLazyFromThrowStub(
+    Assembler* assembler) {
+  // Push zap value instead of CODE_REG for lazy deopt.
+  __ pushq(Immediate(kZapCodeReg));
+  // Return address for "call" to deopt stub.
+  __ pushq(Immediate(kZapReturnAddress));
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::lazy_deopt_from_throw_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateDeoptimizeStub(Assembler* assembler) {
+  __ popq(TMP);
+  __ pushq(CODE_REG);
+  __ pushq(TMP);
+  __ movq(CODE_REG, Address(THR, target::Thread::deoptimize_stub_offset()));
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+  __ 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::count_offset()));
+  __ movq(RAX,
+          Address(RBP, RDI, TIMES_HALF_WORD_SIZE,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+  __ pushq(Immediate(0));  // Setup space on stack for result.
+  __ pushq(RAX);           // Receiver.
+  __ pushq(RBX);           // ICData/MegamorphicCache.
+  __ pushq(R10);           // Arguments descriptor array.
+
+  // Adjust arguments count.
+  __ cmpq(
+      FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  __ movq(R10, RDI);
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addq(R10, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+
+  // R10: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+  const intptr_t kNumArgs = 4;
+  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
+  __ Drop(4);
+  __ popq(RAX);  // Return value.
+  __ LeaveStubFrame();
+  __ 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::count_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,
+                       compiler::target::frame_layout.saved_below_pc() *
+                           target::kWordSize));
+  // Preserve IC data and arguments descriptor.
+  __ pushq(RBX);
+  __ pushq(R10);
+
+  // Space for the result of the runtime call.
+  __ pushq(Immediate(0));
+  __ pushq(RAX);  // 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);
+}
+
+// Called for inline allocation of arrays.
+// Input parameters:
+//   R10 : Array length as Smi.
+//   RBX : array element type (either NULL or an instantiated type).
+// NOTE: R10 cannot be clobbered here as the caller relies on it being saved.
+// The newly allocated object is returned in RAX.
+void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
+  Label slow_case;
+  // Compute the size to be allocated, it is based on the array length
+  // and is computed as:
+  // RoundedAllocationSize(
+  //     (array_length * target::kwordSize) + target::Array::header_size()).
+  __ movq(RDI, R10);  // Array Length.
+  // Check that length is a positive Smi.
+  __ testq(RDI, Immediate(kSmiTagMask));
+  if (FLAG_use_slow_path) {
+    __ jmp(&slow_case);
+  } else {
+    __ j(NOT_ZERO, &slow_case);
+  }
+  __ cmpq(RDI, Immediate(0));
+  __ j(LESS, &slow_case);
+  // Check for maximum allowed length.
+  const Immediate& max_len =
+      Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
+  __ cmpq(RDI, max_len);
+  __ j(GREATER, &slow_case);
+
+  // Check for allocation tracing.
+  NOT_IN_PRODUCT(
+      __ MaybeTraceAllocation(kArrayCid, &slow_case, Assembler::kFarJump));
+
+  const intptr_t fixed_size_plus_alignment_padding =
+      target::Array::header_size() + target::ObjectAlignment::kObjectAlignment -
+      1;
+  // RDI is a Smi.
+  __ leaq(RDI, Address(RDI, TIMES_4, fixed_size_plus_alignment_padding));
+  ASSERT(kSmiTagShift == 1);
+  __ andq(RDI, Immediate(-target::ObjectAlignment::kObjectAlignment));
+
+  const intptr_t cid = kArrayCid;
+  __ movq(RAX, Address(THR, target::Thread::top_offset()));
+
+  // RDI: allocation size.
+  __ movq(RCX, RAX);
+  __ addq(RCX, RDI);
+  __ j(CARRY, &slow_case);
+
+  // Check if the allocation fits into the remaining space.
+  // RAX: potential new object start.
+  // RCX: potential next object start.
+  // RDI: allocation size.
+  __ cmpq(RCX, Address(THR, target::Thread::end_offset()));
+  __ j(ABOVE_EQUAL, &slow_case);
+
+  // Successfully allocated the object(s), now update top to point to
+  // next object start and initialize the object.
+  __ movq(Address(THR, target::Thread::top_offset()), RCX);
+  __ addq(RAX, Immediate(kHeapObjectTag));
+  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, RDI));
+  // Initialize the tags.
+  // RAX: new object start as a tagged pointer.
+  // RDI: allocation size.
+  {
+    Label size_tag_overflow, done;
+    __ cmpq(RDI, Immediate(target::RawObject::kSizeTagMaxSizeTag));
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+    __ shlq(RDI, Immediate(target::RawObject::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2));
+    __ jmp(&done, Assembler::kNearJump);
+
+    __ Bind(&size_tag_overflow);
+    __ LoadImmediate(RDI, Immediate(0));
+    __ Bind(&done);
+
+    // Get the class index and insert it into the tags.
+    uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+    __ orq(RDI, Immediate(tags));
+    __ movq(FieldAddress(RAX, target::Array::tags_offset()), RDI);  // Tags.
+  }
+
+  // RAX: new object start as a tagged pointer.
+  // Store the type argument field.
+  // No generational barrier needed, since we store into a new object.
+  __ StoreIntoObjectNoBarrier(
+      RAX, FieldAddress(RAX, target::Array::type_arguments_offset()), RBX);
+
+  // Set the length field.
+  __ StoreIntoObjectNoBarrier(
+      RAX, FieldAddress(RAX, target::Array::length_offset()), R10);
+
+  // Initialize all array elements to raw_null.
+  // RAX: new object start as a tagged pointer.
+  // RCX: new object end address.
+  // RDI: iterator which initially points to the start of the variable
+  // data area to be initialized.
+  __ LoadObject(R12, NullObject());
+  __ leaq(RDI, FieldAddress(RAX, target::Array::header_size()));
+  Label done;
+  Label init_loop;
+  __ Bind(&init_loop);
+  __ cmpq(RDI, RCX);
+#if defined(DEBUG)
+  static const bool kJumpLength = Assembler::kFarJump;
+#else
+  static const bool kJumpLength = Assembler::kNearJump;
+#endif  // DEBUG
+  __ j(ABOVE_EQUAL, &done, kJumpLength);
+  // No generational barrier needed, since we are storing null.
+  __ StoreIntoObjectNoBarrier(RAX, Address(RDI, 0), R12);
+  __ addq(RDI, Immediate(target::kWordSize));
+  __ jmp(&init_loop, kJumpLength);
+  __ Bind(&done);
+  __ ret();  // returns the newly allocated object in RAX.
+
+  // Unable to allocate the array using the fast inline code, just call
+  // into the runtime.
+  __ Bind(&slow_case);
+  // Create a stub frame as we are pushing some objects on the stack before
+  // calling into the runtime.
+  __ EnterStubFrame();
+  // Setup space on stack for return value.
+  __ pushq(Immediate(0));
+  __ pushq(R10);  // Array length as Smi.
+  __ pushq(RBX);  // Element type.
+  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
+  __ popq(RAX);  // Pop element type argument.
+  __ popq(R10);  // Pop array length argument.
+  __ popq(RAX);  // Pop return value from return slot.
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+// Called when invoking Dart code from C++ (VM code).
+// Input parameters:
+//   RSP : points to return address.
+//   RDI : target code
+//   RSI : arguments descriptor array.
+//   RDX : arguments array.
+//   RCX : current thread.
+void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) {
+  __ pushq(Address(RSP, 0));  // Marker for the profiler.
+  __ EnterFrame(0);
+
+  const Register kTargetCodeReg = CallingConventions::kArg1Reg;
+  const Register kArgDescReg = CallingConventions::kArg2Reg;
+  const Register kArgsReg = CallingConventions::kArg3Reg;
+  const Register kThreadReg = CallingConventions::kArg4Reg;
+
+  // Push code object to PC marker slot.
+  __ pushq(Address(kThreadReg, target::Thread::invoke_dart_code_stub_offset()));
+
+  // At this point, the stack looks like:
+  // | stub code object
+  // | saved RBP                                      | <-- RBP
+  // | saved PC (return to DartEntry::InvokeFunction) |
+
+  const intptr_t kInitialOffset = 2;
+  // Save arguments descriptor array, later replaced by Smi argument count.
+  const intptr_t kArgumentsDescOffset = -(kInitialOffset)*target::kWordSize;
+  __ pushq(kArgDescReg);
+
+  // Save C++ ABI callee-saved registers.
+  __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
+                   CallingConventions::kCalleeSaveXmmRegisters);
+
+  // If any additional (or fewer) values are pushed, the offsets in
+  // target::frame_layout.exit_link_slot_from_entry_fp will need to be changed.
+
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != kThreadReg) {
+    __ movq(THR, kThreadReg);
+  }
+
+  // Save the current VMTag on the stack.
+  __ movq(RAX, Assembler::VMTagAddress());
+  __ pushq(RAX);
+
+  // Save top resource and top exit frame info. Use RAX as a temporary register.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ movq(RAX, Address(THR, target::Thread::top_resource_offset()));
+  __ pushq(RAX);
+  __ movq(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+  __ movq(RAX, Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ pushq(RAX);
+
+  // The constant target::frame_layout.exit_link_slot_from_entry_fp must be kept
+  // in sync with the code below.
+#if defined(DEBUG)
+  {
+    Label ok;
+    __ leaq(RAX,
+            Address(RBP, target::frame_layout.exit_link_slot_from_entry_fp *
+                             target::kWordSize));
+    __ cmpq(RAX, RSP);
+    __ j(EQUAL, &ok);
+    __ Stop("target::frame_layout.exit_link_slot_from_entry_fp mismatch");
+    __ Bind(&ok);
+  }
+#endif
+
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  // Mark that the thread is executing Dart code. Do this after initializing the
+  // exit link for the profiler.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Load arguments descriptor array into R10, which is passed to Dart code.
+  __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle));
+
+  // Push arguments. At this point we only need to preserve kTargetCodeReg.
+  ASSERT(kTargetCodeReg != RDX);
+
+  // Load number of arguments into RBX and adjust count for type arguments.
+  __ movq(RBX, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+  __ cmpq(
+      FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addq(RBX, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+  // Save number of arguments as Smi on stack, replacing saved ArgumentsDesc.
+  __ movq(Address(RBP, kArgumentsDescOffset), RBX);
+  __ SmiUntag(RBX);
+
+  // Compute address of 'arguments array' data area into RDX.
+  __ movq(RDX, Address(kArgsReg, VMHandles::kOffsetOfRawPtrInHandle));
+  __ leaq(RDX, FieldAddress(RDX, target::Array::data_offset()));
+
+  // Set up arguments for the Dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+  __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
+  __ LoadImmediate(RAX, Immediate(0));
+  __ Bind(&push_arguments);
+  __ pushq(Address(RDX, RAX, TIMES_8, 0));
+  __ incq(RAX);
+  __ cmpq(RAX, RBX);
+  __ j(LESS, &push_arguments, Assembler::kNearJump);
+  __ Bind(&done_push_arguments);
+
+  // Call the Dart code entrypoint.
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ movq(PP, Address(THR, target::Thread::global_object_pool_offset()));
+  } else {
+    __ xorq(PP, PP);  // GC-safe value into PP.
+  }
+  __ movq(CODE_REG,
+          Address(kTargetCodeReg, VMHandles::kOffsetOfRawPtrInHandle));
+  __ movq(kTargetCodeReg,
+          FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ call(kTargetCodeReg);  // R10 is the arguments descriptor array.
+
+  // Read the saved number of passed arguments as Smi.
+  __ movq(RDX, Address(RBP, kArgumentsDescOffset));
+
+  // Get rid of arguments pushed on the stack.
+  __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0));  // RDX is a Smi.
+
+  // Restore the saved top exit frame info and top resource back into the
+  // Isolate structure.
+  __ popq(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popq(Address(THR, target::Thread::top_resource_offset()));
+
+  // Restore the current VMTag from the stack.
+  __ popq(Assembler::VMTagAddress());
+
+  // Restore C++ ABI callee-saved registers.
+  __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
+                  CallingConventions::kCalleeSaveXmmRegisters);
+  __ set_constant_pool_allowed(false);
+
+  // Restore the frame pointer.
+  __ LeaveFrame();
+  __ popq(RCX);
+
+  __ ret();
+}
+
+// Called when invoking compiled Dart code from interpreted Dart code.
+// Input parameters:
+//   RSP : points to return address.
+//   RDI : target raw code
+//   RSI : arguments raw descriptor array.
+//   RDX : address of first argument.
+//   RCX : current thread.
+void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub(
+    Assembler* assembler) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter");
+#else
+  __ pushq(Address(RSP, 0));  // Marker for the profiler.
+  __ EnterFrame(0);
+
+  const Register kTargetCodeReg = CallingConventions::kArg1Reg;
+  const Register kArgDescReg = CallingConventions::kArg2Reg;
+  const Register kArg0Reg = CallingConventions::kArg3Reg;
+  const Register kThreadReg = CallingConventions::kArg4Reg;
+
+  // Push code object to PC marker slot.
+  __ pushq(
+      Address(kThreadReg,
+              target::Thread::invoke_dart_code_from_bytecode_stub_offset()));
+
+  // At this point, the stack looks like:
+  // | stub code object
+  // | saved RBP                                         | <-- RBP
+  // | saved PC (return to interpreter's InvokeCompiled) |
+
+  const intptr_t kInitialOffset = 2;
+  // Save arguments descriptor array, later replaced by Smi argument count.
+  const intptr_t kArgumentsDescOffset = -(kInitialOffset)*target::kWordSize;
+  __ pushq(kArgDescReg);
+
+  // Save C++ ABI callee-saved registers.
+  __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
+                   CallingConventions::kCalleeSaveXmmRegisters);
+
+  // If any additional (or fewer) values are pushed, the offsets in
+  // target::frame_layout.exit_link_slot_from_entry_fp will need to be changed.
+
+  // Set up THR, which caches the current thread in Dart code.
+  if (THR != kThreadReg) {
+    __ movq(THR, kThreadReg);
+  }
+
+  // Save the current VMTag on the stack.
+  __ movq(RAX, Assembler::VMTagAddress());
+  __ pushq(RAX);
+
+  // Save top resource and top exit frame info. Use RAX as a temporary register.
+  // StackFrameIterator reads the top exit frame info saved in this frame.
+  __ movq(RAX, Address(THR, target::Thread::top_resource_offset()));
+  __ pushq(RAX);
+  __ movq(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+  __ movq(RAX, Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ pushq(RAX);
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  // The constant target::frame_layout.exit_link_slot_from_entry_fp must be kept
+  // in sync with the code below.
+#if defined(DEBUG)
+  {
+    Label ok;
+    __ leaq(RAX,
+            Address(RBP, target::frame_layout.exit_link_slot_from_entry_fp *
+                             target::kWordSize));
+    __ cmpq(RAX, RSP);
+    __ j(EQUAL, &ok);
+    __ Stop("target::frame_layout.exit_link_slot_from_entry_fp mismatch");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Mark that the thread is executing Dart code. Do this after initializing the
+  // exit link for the profiler.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Load arguments descriptor array into R10, which is passed to Dart code.
+  __ movq(R10, kArgDescReg);
+
+  // Push arguments. At this point we only need to preserve kTargetCodeReg.
+  ASSERT(kTargetCodeReg != RDX);
+
+  // Load number of arguments into RBX and adjust count for type arguments.
+  __ movq(RBX, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+  __ cmpq(
+      FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addq(RBX, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+  // Save number of arguments as Smi on stack, replacing saved ArgumentsDesc.
+  __ movq(Address(RBP, kArgumentsDescOffset), RBX);
+  __ SmiUntag(RBX);
+
+  // Compute address of first argument into RDX.
+  if (kArg0Reg != RDX) {  // Different registers on WIN64.
+    __ movq(RDX, kArg0Reg);
+  }
+
+  // Set up arguments for the Dart call.
+  Label push_arguments;
+  Label done_push_arguments;
+  __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
+  __ LoadImmediate(RAX, Immediate(0));
+  __ Bind(&push_arguments);
+  __ pushq(Address(RDX, RAX, TIMES_8, 0));
+  __ incq(RAX);
+  __ cmpq(RAX, RBX);
+  __ j(LESS, &push_arguments, Assembler::kNearJump);
+  __ Bind(&done_push_arguments);
+
+  // Call the Dart code entrypoint.
+  __ xorq(PP, PP);  // GC-safe value into PP.
+  __ movq(CODE_REG, kTargetCodeReg);
+  __ movq(kTargetCodeReg,
+          FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ call(kTargetCodeReg);  // R10 is the arguments descriptor array.
+
+  // Read the saved number of passed arguments as Smi.
+  __ movq(RDX, Address(RBP, kArgumentsDescOffset));
+
+  // Get rid of arguments pushed on the stack.
+  __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0));  // RDX is a Smi.
+
+  // Restore the saved top exit frame info and top resource back into the
+  // Isolate structure.
+  __ popq(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popq(Address(THR, target::Thread::top_resource_offset()));
+
+  // Restore the current VMTag from the stack.
+  __ popq(Assembler::VMTagAddress());
+
+  // Restore C++ ABI callee-saved registers.
+  __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
+                  CallingConventions::kCalleeSaveXmmRegisters);
+  __ set_constant_pool_allowed(false);
+
+  // Restore the frame pointer.
+  __ LeaveFrame();
+  __ popq(RCX);
+
+  __ ret();
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+}
+
+// Called for inline allocation of contexts.
+// Input:
+// R10: number of context variables.
+// Output:
+// RAX: new allocated RawContext object.
+void StubCodeCompiler::GenerateAllocateContextStub(Assembler* assembler) {
+  __ LoadObject(R9, NullObject());
+  if (FLAG_inline_alloc) {
+    Label slow_case;
+    // First compute the rounded instance size.
+    // R10: number of context variables.
+    intptr_t fixed_size_plus_alignment_padding =
+        (target::Context::header_size() +
+         target::ObjectAlignment::kObjectAlignment - 1);
+    __ leaq(R13, Address(R10, TIMES_8, fixed_size_plus_alignment_padding));
+    __ andq(R13, Immediate(-target::ObjectAlignment::kObjectAlignment));
+
+    // Check for allocation tracing.
+    NOT_IN_PRODUCT(
+        __ MaybeTraceAllocation(kContextCid, &slow_case, Assembler::kFarJump));
+
+    // Now allocate the object.
+    // R10: number of context variables.
+    const intptr_t cid = kContextCid;
+    __ movq(RAX, Address(THR, target::Thread::top_offset()));
+    __ addq(R13, RAX);
+    // Check if the allocation fits into the remaining space.
+    // RAX: potential new object.
+    // R13: potential next object start.
+    // R10: number of context variables.
+    __ cmpq(R13, Address(THR, target::Thread::end_offset()));
+    if (FLAG_use_slow_path) {
+      __ jmp(&slow_case);
+    } else {
+      __ j(ABOVE_EQUAL, &slow_case);
+    }
+
+    // Successfully allocated the object, now update top to point to
+    // next object start and initialize the object.
+    // RAX: new object.
+    // R13: next object start.
+    // R10: number of context variables.
+    __ movq(Address(THR, target::Thread::top_offset()), R13);
+    // R13: Size of allocation in bytes.
+    __ subq(R13, RAX);
+    __ addq(RAX, Immediate(kHeapObjectTag));
+    // Generate isolate-independent code to allow sharing between isolates.
+    NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R13));
+
+    // Calculate the size tag.
+    // RAX: new object.
+    // R10: number of context variables.
+    {
+      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));
+      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+      __ shlq(R13, Immediate(target::RawObject::kTagBitsSizeTagPos -
+                             target::ObjectAlignment::kObjectAlignmentLog2));
+      __ jmp(&done);
+
+      __ Bind(&size_tag_overflow);
+      // Set overflow size tag value.
+      __ LoadImmediate(R13, Immediate(0));
+
+      __ Bind(&done);
+      // RAX: new object.
+      // R10: number of context variables.
+      // R13: size and bit tags.
+      uint32_t tags = target::MakeTagWordForNewSpaceObject(cid, 0);
+      __ orq(R13, Immediate(tags));
+      __ movq(FieldAddress(RAX, target::Object::tags_offset()), R13);  // Tags.
+    }
+
+    // Setup up number of context variables field.
+    // RAX: new object.
+    // R10: number of context variables as integer value (not object).
+    __ movq(FieldAddress(RAX, target::Context::num_variables_offset()), R10);
+
+    // Setup the parent field.
+    // RAX: new object.
+    // R10: number of context variables.
+    // No generational barrier needed, since we are storing null.
+    __ StoreIntoObjectNoBarrier(
+        RAX, FieldAddress(RAX, target::Context::parent_offset()), R9);
+
+    // Initialize the context variables.
+    // RAX: new object.
+    // R10: number of context variables.
+    {
+      Label loop, entry;
+      __ leaq(R13, FieldAddress(RAX, target::Context::variable_offset(0)));
+#if defined(DEBUG)
+      static const bool kJumpLength = Assembler::kFarJump;
+#else
+      static const bool kJumpLength = Assembler::kNearJump;
+#endif  // DEBUG
+      __ jmp(&entry, kJumpLength);
+      __ Bind(&loop);
+      __ decq(R10);
+      // No generational barrier needed, since we are storing null.
+      __ StoreIntoObjectNoBarrier(RAX, Address(R13, R10, TIMES_8, 0), R9);
+      __ Bind(&entry);
+      __ cmpq(R10, Immediate(0));
+      __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+    }
+
+    // Done allocating and initializing the context.
+    // RAX: new object.
+    __ ret();
+
+    __ Bind(&slow_case);
+  }
+  // Create a stub frame.
+  __ EnterStubFrame();
+  __ pushq(R9);  // Setup space on stack for the return value.
+  __ SmiTag(R10);
+  __ pushq(R10);  // Push number of context variables.
+  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
+  __ popq(RAX);  // Pop number of context variables argument.
+  __ popq(RAX);  // Pop the new context object.
+  // RAX: new object
+  // Restore the frame pointer.
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+void StubCodeCompiler::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
+  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+    if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
+
+    Register reg = static_cast<Register>(i);
+    intptr_t start = __ CodeSize();
+    __ pushq(kWriteBarrierObjectReg);
+    __ movq(kWriteBarrierObjectReg, reg);
+    __ call(Address(THR, target::Thread::write_barrier_entry_point_offset()));
+    __ popq(kWriteBarrierObjectReg);
+    __ ret();
+    intptr_t end = __ CodeSize();
+
+    RELEASE_ASSERT(end - start == kStoreBufferWrapperSize);
+  }
+}
+
+// Helper stub to implement Assembler::StoreIntoObject/Array.
+// Input parameters:
+//   RDX: Object (old)
+//   RAX: Value (old or new)
+//   R13: Slot
+// If RAX is new, add RDX to the store buffer. Otherwise RAX is old, mark RAX
+// and add it to the mark list.
+COMPILE_ASSERT(kWriteBarrierObjectReg == RDX);
+COMPILE_ASSERT(kWriteBarrierValueReg == RAX);
+COMPILE_ASSERT(kWriteBarrierSlotReg == R13);
+static void GenerateWriteBarrierStubHelper(Assembler* assembler,
+                                           Address stub_code,
+                                           bool cards) {
+  Label add_to_mark_stack, remember_card;
+  __ testq(RAX, Immediate(1 << target::ObjectAlignment::kNewObjectBitPosition));
+  __ j(ZERO, &add_to_mark_stack);
+
+  if (cards) {
+    __ movl(TMP, FieldAddress(RDX, target::Object::tags_offset()));
+    __ testl(TMP, Immediate(1 << target::RawObject::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));
+    __ j(ZERO, &ok, Assembler::kFarJump);
+    __ Stop("Wrong barrier");
+    __ Bind(&ok);
+#endif
+  }
+
+  // Update the tags that this object has been remembered.
+  // Note that we use 32 bit operations here to match the size of the
+  // background sweeper which is also manipulating this 32 bit word.
+  // RDX: Address being stored
+  // RAX: Current tag value
+  // lock+andl is an atomic read-modify-write.
+  __ lock();
+  __ andl(FieldAddress(RDX, target::Object::tags_offset()),
+          Immediate(~(1 << target::RawObject::kOldAndNotRememberedBit)));
+
+  // Save registers being destroyed.
+  __ pushq(RAX);
+  __ pushq(RCX);
+
+  // Load the StoreBuffer block out of the thread. Then load top_ out of the
+  // StoreBufferBlock and add the address to the pointers_.
+  // RDX: Address being stored
+  __ movq(RAX, Address(THR, target::Thread::store_buffer_block_offset()));
+  __ movl(RCX, Address(RAX, target::StoreBufferBlock::top_offset()));
+  __ movq(
+      Address(RAX, RCX, TIMES_8, target::StoreBufferBlock::pointers_offset()),
+      RDX);
+
+  // Increment top_ and check for overflow.
+  // RCX: top_
+  // RAX: StoreBufferBlock
+  Label overflow;
+  __ incq(RCX);
+  __ movl(Address(RAX, target::StoreBufferBlock::top_offset()), RCX);
+  __ cmpl(RCX, Immediate(target::StoreBufferBlock::kSize));
+  // Restore values.
+  __ popq(RCX);
+  __ popq(RAX);
+  __ j(EQUAL, &overflow, Assembler::kNearJump);
+  __ ret();
+
+  // Handle overflow: Call the runtime leaf function.
+  __ Bind(&overflow);
+  // Setup frame, push callee-saved registers.
+  __ pushq(CODE_REG);
+  __ movq(CODE_REG, stub_code);
+  __ EnterCallRuntimeFrame(0);
+  __ movq(CallingConventions::kArg1Reg, THR);
+  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ popq(CODE_REG);
+  __ ret();
+
+  __ Bind(&add_to_mark_stack);
+  __ pushq(RAX);      // Spill.
+  __ pushq(RCX);      // Spill.
+  __ movq(TMP, RAX);  // RAX is fixed implicit operand of CAS.
+
+  // Atomically clear kOldAndNotMarkedBit.
+  // Note that we use 32 bit operations here to match the size of the
+  // background marker which is also manipulating this 32 bit word.
+  Label retry, lost_race, marking_overflow;
+  __ movl(RAX, FieldAddress(TMP, target::Object::tags_offset()));
+  __ Bind(&retry);
+  __ movl(RCX, RAX);
+  __ testl(RCX, Immediate(1 << target::RawObject::kOldAndNotMarkedBit));
+  __ j(ZERO, &lost_race);  // Marked by another thread.
+  __ andl(RCX, Immediate(~(1 << target::RawObject::kOldAndNotMarkedBit)));
+  __ LockCmpxchgl(FieldAddress(TMP, target::Object::tags_offset()), RCX);
+  __ j(NOT_EQUAL, &retry, Assembler::kNearJump);
+
+  __ movq(RAX, Address(THR, target::Thread::marking_stack_block_offset()));
+  __ movl(RCX, Address(RAX, target::MarkingStackBlock::top_offset()));
+  __ movq(
+      Address(RAX, RCX, TIMES_8, target::MarkingStackBlock::pointers_offset()),
+      TMP);
+  __ incq(RCX);
+  __ movl(Address(RAX, target::MarkingStackBlock::top_offset()), RCX);
+  __ cmpl(RCX, Immediate(target::MarkingStackBlock::kSize));
+  __ popq(RCX);  // Unspill.
+  __ popq(RAX);  // Unspill.
+  __ j(EQUAL, &marking_overflow, Assembler::kNearJump);
+  __ ret();
+
+  __ Bind(&marking_overflow);
+  __ pushq(CODE_REG);
+  __ movq(CODE_REG, stub_code);
+  __ EnterCallRuntimeFrame(0);
+  __ movq(CallingConventions::kArg1Reg, THR);
+  __ CallRuntime(kMarkingStackBlockProcessRuntimeEntry, 1);
+  __ LeaveCallRuntimeFrame();
+  __ popq(CODE_REG);
+  __ ret();
+
+  __ Bind(&lost_race);
+  __ popq(RCX);  // Unspill.
+  __ popq(RAX);  // Unspill.
+  __ ret();
+
+  if (cards) {
+    Label remember_card_slow;
+
+    // Get card table.
+    __ Bind(&remember_card);
+    __ movq(TMP, RDX);                           // Object.
+    __ andq(TMP, Immediate(target::kPageMask));  // HeapPage.
+    __ cmpq(Address(TMP, target::HeapPage::card_table_offset()), Immediate(0));
+    __ j(EQUAL, &remember_card_slow, Assembler::kNearJump);
+
+    // Dirty the card.
+    __ subq(R13, TMP);  // Offset in page.
+    __ movq(
+        TMP,
+        Address(TMP, target::HeapPage::card_table_offset()));  // Card table.
+    __ shrq(R13,
+            Immediate(
+                target::HeapPage::kBytesPerCardLog2));  // Index in card table.
+    __ movb(Address(TMP, R13, TIMES_1, 0), Immediate(1));
+    __ ret();
+
+    // Card table not yet allocated.
+    __ Bind(&remember_card_slow);
+    __ pushq(CODE_REG);
+    __ movq(CODE_REG, stub_code);
+    __ EnterCallRuntimeFrame(0);
+    __ movq(CallingConventions::kArg1Reg, RDX);
+    __ movq(CallingConventions::kArg2Reg, R13);
+    __ CallRuntime(kRememberCardRuntimeEntry, 2);
+    __ LeaveCallRuntimeFrame();
+    __ popq(CODE_REG);
+    __ ret();
+  }
+}
+
+void StubCodeCompiler::GenerateWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler, Address(THR, target::Thread::write_barrier_code_offset()),
+      false);
+}
+
+void StubCodeCompiler::GenerateArrayWriteBarrierStub(Assembler* assembler) {
+  GenerateWriteBarrierStubHelper(
+      assembler,
+      Address(THR, target::Thread::array_write_barrier_code_offset()), true);
+}
+
+// Called for inline allocation of objects.
+// Input parameters:
+//   RSP + 8 : type arguments object (only if class is parameterized).
+//   RSP : points to return address.
+void StubCodeCompiler::GenerateAllocationStubForClass(Assembler* assembler,
+                                                      const Class& cls) {
+  const intptr_t kObjectTypeArgumentsOffset = 1 * target::kWordSize;
+  // 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::InstanceSize(cls);
+  ASSERT(instance_size > 0);
+  __ LoadObject(R9, NullObject());
+  if (is_cls_parameterized) {
+    __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
+    // RDX: instantiated type arguments.
+  }
+  if (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.
+    // 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()));
+    if (FLAG_use_slow_path) {
+      __ jmp(&slow_case);
+    } else {
+      __ j(ABOVE_EQUAL, &slow_case);
+    }
+    __ movq(Address(THR, target::Thread::top_offset()), RBX);
+    NOT_IN_PRODUCT(__ UpdateAllocationStats(target::Class::GetId(cls)));
+
+    // RAX: new object start (untagged).
+    // RBX: next object start.
+    // RDX: new object type arguments (if is_cls_parameterized).
+    // 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));
+    __ 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()));
+      // 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);
+#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));
+      __ jmp(&init_loop, Assembler::kNearJump);
+      __ Bind(&done);
+    }
+    if (is_cls_parameterized) {
+      // RAX: new object (tagged).
+      // RDX: new object type arguments.
+      // Set the type arguments in the new object.
+      const intptr_t offset = target::Class::TypeArgumentsFieldOffset(cls);
+      __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, offset), RDX);
+    }
+    // Done allocating and initializing the instance.
+    // RAX: new object (tagged).
+    __ ret();
+
+    __ Bind(&slow_case);
+  }
+  // If is_cls_parameterized:
+  // RDX: new object type arguments.
+  // Create a stub frame.
+  __ EnterStubFrame();  // Uses PP to access class object.
+  __ pushq(R9);         // Setup space on stack for return value.
+  __ PushObject(
+      CastHandle<Object>(cls));  // Push class of object to be allocated.
+  if (is_cls_parameterized) {
+    __ pushq(RDX);  // Push type arguments of object to be allocated.
+  } else {
+    __ pushq(R9);  // Push null type arguments.
+  }
+  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
+  __ popq(RAX);  // Pop argument (type arguments of object).
+  __ popq(RAX);  // Pop argument (class of object).
+  __ popq(RAX);  // Pop result (newly allocated object).
+  // RAX: new object
+  // Restore the frame pointer.
+  __ LeaveStubFrame();
+  __ ret();
+}
+
+// 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.
+// Input parameters:
+//   RSP : points to return address.
+//   RSP + 8 : address of last argument.
+//   R10 : arguments descriptor array.
+void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub(
+    Assembler* assembler) {
+  __ EnterStubFrame();
+
+  // Load the receiver.
+  __ movq(R13, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+  __ movq(RAX,
+          Address(RBP, R13, TIMES_4,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+
+  __ pushq(Immediate(0));  // Result slot.
+  __ pushq(RAX);           // Receiver.
+  __ pushq(R10);           // Arguments descriptor array.
+
+  // Adjust arguments count.
+  __ cmpq(
+      FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  __ movq(R10, R13);
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ addq(R10, Immediate(target::ToRawSmi(1)));  // Include the type arguments.
+  __ Bind(&args_count_ok);
+
+  // R10: Smi-tagged arguments array length.
+  PushArrayOfArguments(assembler);
+
+  const intptr_t kNumArgs = 3;
+  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
+  // noSuchMethod on closures always throws an error, so it will never return.
+  __ int3();
+}
+
+// Cannot use function object from ICData as it may be the inlined
+// function and not the top-scope function.
+void StubCodeCompiler::GenerateOptimizedUsageCounterIncrement(
+    Assembler* assembler) {
+  Register ic_reg = RBX;
+  Register func_reg = RDI;
+  if (FLAG_trace_optimized_ic_calls) {
+    __ EnterStubFrame();
+    __ pushq(func_reg);  // Preserve
+    __ pushq(ic_reg);    // Preserve.
+    __ pushq(ic_reg);    // Argument.
+    __ pushq(func_reg);  // Argument.
+    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
+    __ popq(RAX);       // Discard argument;
+    __ popq(RAX);       // Discard argument;
+    __ popq(ic_reg);    // Restore.
+    __ popq(func_reg);  // Restore.
+    __ LeaveStubFrame();
+  }
+  __ incl(FieldAddress(func_reg, target::Function::usage_counter_offset()));
+}
+
+// Loads function into 'temp_reg', preserves 'ic_reg'.
+void StubCodeCompiler::GenerateUsageCounterIncrement(Assembler* assembler,
+                                                     Register temp_reg) {
+  if (FLAG_optimization_counter_threshold >= 0) {
+    Register ic_reg = RBX;
+    Register func_reg = temp_reg;
+    ASSERT(ic_reg != func_reg);
+    __ Comment("Increment function counter");
+    __ movq(func_reg, FieldAddress(ic_reg, target::ICData::owner_offset()));
+    __ incl(FieldAddress(func_reg, target::Function::usage_counter_offset()));
+  }
+}
+
+// Note: RBX must be preserved.
+// Attempt a quick Smi operation for known operations ('kind'). The ICData
+// must have been primed with a Smi/Smi check that will be used for counting
+// the invocations.
+static void EmitFastSmiOp(Assembler* assembler,
+                          Token::Kind kind,
+                          intptr_t num_args,
+                          Label* not_smi_or_overflow) {
+  __ Comment("Fast Smi op");
+  ASSERT(num_args == 2);
+  __ movq(RCX, Address(RSP, +1 * target::kWordSize));  // Right
+  __ movq(RAX, Address(RSP, +2 * target::kWordSize));  // Left.
+  __ movq(R13, RCX);
+  __ orq(R13, RAX);
+  __ testq(R13, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, not_smi_or_overflow);
+  switch (kind) {
+    case Token::kADD: {
+      __ addq(RAX, RCX);
+      __ j(OVERFLOW, not_smi_or_overflow);
+      break;
+    }
+    case Token::kSUB: {
+      __ subq(RAX, RCX);
+      __ j(OVERFLOW, not_smi_or_overflow);
+      break;
+    }
+    case Token::kEQ: {
+      Label done, is_true;
+      __ cmpq(RAX, RCX);
+      __ j(EQUAL, &is_true, Assembler::kNearJump);
+      __ LoadObject(RAX, CastHandle<Object>(FalseObject()));
+      __ jmp(&done, Assembler::kNearJump);
+      __ Bind(&is_true);
+      __ LoadObject(RAX, CastHandle<Object>(TrueObject()));
+      __ Bind(&done);
+      break;
+    }
+    default:
+      UNIMPLEMENTED();
+  }
+
+  // RBX: IC data object (preserved).
+  __ movq(R13, FieldAddress(RBX, target::ICData::entries_offset()));
+  // R13: ic_data_array with check entries: classes and target functions.
+  __ leaq(R13, FieldAddress(R13, target::Array::data_offset()));
+// R13: points directly to the first ic data array element.
+#if defined(DEBUG)
+  // Check that first entry is for Smi/Smi.
+  Label error, ok;
+  const Immediate& imm_smi_cid = Immediate(target::ToRawSmi(kSmiCid));
+  __ cmpq(Address(R13, 0 * target::kWordSize), imm_smi_cid);
+  __ j(NOT_EQUAL, &error, Assembler::kNearJump);
+  __ cmpq(Address(R13, 1 * target::kWordSize), imm_smi_cid);
+  __ j(EQUAL, &ok, Assembler::kNearJump);
+  __ Bind(&error);
+  __ Stop("Incorrect IC data");
+  __ Bind(&ok);
+#endif
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    const intptr_t count_offset =
+        target::ICData::CountIndexFor(num_args) * target::kWordSize;
+    // Update counter, ignore overflow.
+    __ addq(Address(R13, count_offset), Immediate(target::ToRawSmi(1)));
+  }
+
+  __ ret();
+}
+
+// Generate inline cache check for 'num_args'.
+//  RBX: Inline cache data object.
+//  TOS(0): return address
+// Control flow:
+// - If receiver is null -> jump to IC miss.
+// - If receiver is Smi -> load Smi class.
+// - If receiver is not-Smi -> load receiver's class.
+// - Check if 'num_args' (including receiver) match any IC data group.
+// - Match found -> jump to target.
+// - Match not found -> jump to IC miss.
+void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
+    Assembler* assembler,
+    intptr_t num_args,
+    const RuntimeEntry& handle_ic_miss,
+    Token::Kind kind,
+    bool optimized,
+    bool exactness_check) {
+  ASSERT(num_args == 1 || num_args == 2);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == num_args.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ movl(RCX, FieldAddress(RBX, target::ICData::state_bits_offset()));
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ andq(RCX, Immediate(target::ICData::NumArgsTestedMask()));
+    __ cmpq(RCX, Immediate(num_args));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect stub for IC data");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  Label stepping, done_stepping;
+  if (!optimized) {
+    __ Comment("Check single stepping");
+    __ LoadIsolate(RAX);
+    __ cmpb(Address(RAX, target::Isolate::single_step_offset()), Immediate(0));
+    __ j(NOT_EQUAL, &stepping);
+    __ Bind(&done_stepping);
+  }
+#endif
+
+  Label not_smi_or_overflow;
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
+
+  __ Comment("Extract ICData initial values and receiver cid");
+  // Load arguments descriptor into R10.
+  __ movq(R10,
+          FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+  // Loop that checks if there is an IC data match.
+  Label loop, found, miss;
+  // RBX: IC data object (preserved).
+  __ movq(R13, FieldAddress(RBX, target::ICData::entries_offset()));
+  // R13: ic_data_array with check entries: classes and target functions.
+  __ leaq(R13, FieldAddress(R13, target::Array::data_offset()));
+  // R13: points directly to the first ic data array element.
+
+  // Get argument count as Smi into RCX.
+  __ movq(RCX, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+  // Load first argument into RDX.
+  __ movq(RDX, Address(RSP, RCX, TIMES_4, 0));
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDX);
+  // RAX: first argument class ID as Smi.
+  if (num_args == 2) {
+    // Load second argument into R9.
+    __ movq(R9, Address(RSP, RCX, TIMES_4, -target::kWordSize));
+    __ LoadTaggedClassIdMayBeSmi(RCX, R9);
+    // RCX: second argument class ID (smi).
+  }
+
+  __ Comment("ICData loop");
+
+  // We unroll the generic one that is generated once more than the others.
+  const bool optimize = kind == Token::kILLEGAL;
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(num_args) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(num_args) * target::kWordSize;
+  const intptr_t exactness_offset =
+      target::ICData::ExactnessOffsetFor(num_args) * target::kWordSize;
+
+  __ Bind(&loop);
+  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
+    Label update;
+    __ movq(R9, Address(R13, 0));
+    __ cmpq(RAX, R9);  // Class id match?
+    if (num_args == 2) {
+      __ j(NOT_EQUAL, &update);  // Continue.
+      __ movq(R9, Address(R13, target::kWordSize));
+      // R9: next class ID to check (smi).
+      __ cmpq(RCX, R9);  // Class id match?
+    }
+    __ j(EQUAL, &found);  // Break.
+
+    __ Bind(&update);
+
+    const intptr_t entry_size =
+        target::ICData::TestEntryLengthFor(num_args, exactness_check) *
+        target::kWordSize;
+    __ addq(R13, Immediate(entry_size));  // Next entry.
+
+    __ cmpq(R9, Immediate(target::ToRawSmi(kIllegalCid)));  // Done?
+    if (unroll == 0) {
+      __ j(NOT_EQUAL, &loop);
+    } else {
+      __ j(EQUAL, &miss);
+    }
+  }
+
+  __ Bind(&miss);
+  __ Comment("IC miss");
+  // Compute address of arguments (first read number of arguments from
+  // arguments descriptor array and then compute address on the stack).
+  __ movq(RAX, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+  __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0));  // RAX is Smi.
+  __ EnterStubFrame();
+  __ pushq(R10);           // Preserve arguments descriptor array.
+  __ pushq(RBX);           // Preserve IC data object.
+  __ pushq(Immediate(0));  // Result slot.
+  // Push call arguments.
+  for (intptr_t i = 0; i < num_args; i++) {
+    __ movq(RCX, Address(RAX, -target::kWordSize * i));
+    __ pushq(RCX);
+  }
+  __ pushq(RBX);  // Pass IC data object.
+  __ CallRuntime(handle_ic_miss, num_args + 1);
+  // Remove the call arguments pushed earlier, including the IC data object.
+  for (intptr_t i = 0; i < num_args + 1; i++) {
+    __ popq(RAX);
+  }
+  __ popq(RAX);  // Pop returned function object into RAX.
+  __ popq(RBX);  // Restore IC data array.
+  __ popq(R10);  // Restore arguments descriptor array.
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  Label call_target_function;
+  if (!FLAG_lazy_dispatchers) {
+    GenerateDispatcherCode(assembler, &call_target_function);
+  } else {
+    __ jmp(&call_target_function);
+  }
+
+  __ Bind(&found);
+  // R13: Pointer to an IC data check group.
+  Label call_target_function_through_unchecked_entry;
+  if (exactness_check) {
+    Label exactness_ok;
+    ASSERT(num_args == 1);
+    __ movq(RAX, Address(R13, exactness_offset));
+    __ cmpq(RAX, Immediate(target::ToRawSmi(
+                     StaticTypeExactnessState::HasExactSuperType().Encode())));
+    __ j(LESS, &exactness_ok);
+    __ j(EQUAL, &call_target_function_through_unchecked_entry);
+
+    // Check trivial exactness.
+    // Note: RawICData::static_receiver_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::static_receiver_type_offset()));
+    __ movq(RCX, FieldAddress(RCX, target::Type::arguments_offset()));
+    // RAX contains an offset to type arguments in words as a smi,
+    // hence TIMES_4. RDX is guaranteed to be non-smi because it is expected to
+    // have type arguments.
+    __ cmpq(RCX, FieldAddress(RDX, RAX, TIMES_4, 0));
+    __ j(EQUAL, &call_target_function_through_unchecked_entry);
+
+    // Update exactness state (not-exact anymore).
+    __ movq(Address(R13, exactness_offset),
+            Immediate(target::ToRawSmi(
+                StaticTypeExactnessState::NotExact().Encode())));
+    __ Bind(&exactness_ok);
+  }
+  __ movq(RAX, Address(R13, target_offset));
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    __ Comment("Update ICData counter");
+    // Ignore overflow.
+    __ addq(Address(R13, count_offset), Immediate(target::ToRawSmi(1)));
+  }
+
+  __ Comment("Call target (via checked entry point)");
+  __ Bind(&call_target_function);
+  // RAX: Target function.
+  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
+  __ jmp(RCX);
+
+  if (exactness_check) {
+    __ Bind(&call_target_function_through_unchecked_entry);
+    if (FLAG_optimization_counter_threshold >= 0) {
+      __ Comment("Update ICData counter");
+      // Ignore overflow.
+      __ addq(Address(R13, count_offset), Immediate(target::ToRawSmi(1)));
+    }
+    __ Comment("Call target (via unchecked entry point)");
+    __ movq(RAX, Address(R13, target_offset));
+    __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+    __ movq(RCX, FieldAddress(
+                     RAX, target::Function::unchecked_entry_point_offset()));
+    __ jmp(RCX);
+  }
+
+#if !defined(PRODUCT)
+  if (!optimized) {
+    __ Bind(&stepping);
+    __ EnterStubFrame();
+    __ pushq(RBX);
+    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+    __ popq(RBX);
+    __ RestoreCodePointer();
+    __ LeaveStubFrame();
+    __ jmp(&done_stepping);
+  }
+#endif
+}
+
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+//  RBX: Inline cache data object.
+//  TOS(0): Return address.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+//   - N classes.
+//   - 1 target function.
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      /*optimized=*/false, /*exactness_check=*/true);
+}
+
+void StubCodeCompiler::GenerateTwoArgsCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+}
+
+void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+}
+
+void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+}
+
+// Use inline cache data array to invoke the target or continue in inline
+// cache miss handler. Stub for 1-argument check (receiver class).
+//  RDI: function which counter needs to be incremented.
+//  RBX: Inline cache data object.
+//  TOS(0): Return address.
+// Inline cache data object structure:
+// 0: function-name
+// 1: N, number of arguments checked.
+// 2 .. (length - 1): group of checks, each check containing:
+//   - N classes.
+//   - 1 target function.
+void StubCodeCompiler::GenerateOneArgOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
+                                    Token::kILLEGAL, /*optimized=*/true);
+}
+
+void StubCodeCompiler::
+    GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
+        Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
+                                    Token::kILLEGAL, /*optimized=*/true,
+                                    /*exactness_check=*/true);
+}
+
+void StubCodeCompiler::GenerateTwoArgsOptimizedCheckInlineCacheStub(
+    Assembler* assembler) {
+  GenerateOptimizedUsageCounterIncrement(assembler);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+                                    Token::kILLEGAL, /*optimized=*/true);
+}
+
+// Intermediary stub between a static call and its target. ICData contains
+// the target function and the call count.
+// RBX: ICData
+void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that the IC data array has NumArgsTested() == 0.
+    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
+    __ movl(RCX, FieldAddress(RBX, target::ICData::state_bits_offset()));
+    ASSERT(target::ICData::NumArgsTestedShift() == 0);  // No shift needed.
+    __ andq(RCX, Immediate(target::ICData::NumArgsTestedMask()));
+    __ cmpq(RCX, Immediate(0));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect IC data for unoptimized static call");
+    __ Bind(&ok);
+  }
+#endif  // DEBUG
+
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(RAX);
+  __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset()));
+  __ cmpq(RAX, Immediate(0));
+#if defined(DEBUG)
+  static const bool kJumpLength = Assembler::kFarJump;
+#else
+  static const bool kJumpLength = Assembler::kNearJump;
+#endif  // DEBUG
+  __ j(NOT_EQUAL, &stepping, kJumpLength);
+  __ Bind(&done_stepping);
+#endif
+
+  // RBX: IC data object (preserved).
+  __ movq(R12, FieldAddress(RBX, target::ICData::entries_offset()));
+  // R12: ic_data_array with entries: target functions and count.
+  __ leaq(R12, FieldAddress(R12, target::Array::data_offset()));
+  // R12: points directly to the first ic data array element.
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(0) * target::kWordSize;
+  const intptr_t count_offset =
+      target::ICData::CountIndexFor(0) * target::kWordSize;
+
+  if (FLAG_optimization_counter_threshold >= 0) {
+    // Increment count for this call, ignore overflow.
+    __ addq(Address(R12, count_offset), Immediate(target::ToRawSmi(1)));
+  }
+
+  // Load arguments descriptor into R10.
+  __ movq(R10,
+          FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+
+  // Get function and call it, if possible.
+  __ movq(RAX, Address(R12, target_offset));
+  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
+  __ jmp(RCX);
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ pushq(RBX);  // Preserve IC data object.
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ popq(RBX);
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ jmp(&done_stepping, Assembler::kNearJump);
+#endif
+}
+
+void StubCodeCompiler::GenerateOneArgUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+}
+
+void StubCodeCompiler::GenerateTwoArgsUnoptimizedStaticCallStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(
+      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+}
+
+// Stub for compiling a function and jumping to the compiled code.
+// R10: Arguments descriptor.
+// RAX: Function.
+void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(R10);  // Preserve arguments descriptor array.
+  __ pushq(RAX);  // Pass function.
+  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
+  __ popq(RAX);  // Restore function.
+  __ popq(R10);  // Restore arguments descriptor array.
+  __ LeaveStubFrame();
+
+  // When using the interpreter, the function's code may now point to the
+  // InterpretCall stub. Make sure RAX, R10, and RBX are preserved.
+  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
+  __ jmp(RCX);
+}
+
+// Stub for interpreting a function call.
+// R10: Arguments descriptor.
+// RAX: Function.
+void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  __ Stop("Not using interpreter");
+#else
+  __ EnterStubFrame();
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ movq(R8, Immediate(VMTag::kDartCompiledTagId));
+    __ cmpq(R8, Assembler::VMTagAddress());
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Adjust arguments count for type arguments vector.
+  __ movq(R11, FieldAddress(R10, target::ArgumentsDescriptor::count_offset()));
+  __ SmiUntag(R11);
+  __ cmpq(
+      FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()),
+      Immediate(0));
+  Label args_count_ok;
+  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
+  __ incq(R11);
+  __ Bind(&args_count_ok);
+
+  // Compute argv.
+  __ leaq(R12,
+          Address(RBP, R11, TIMES_8,
+                  target::frame_layout.param_end_from_fp * target::kWordSize));
+
+  // Indicate decreasing memory addresses of arguments with negative argc.
+  __ negq(R11);
+
+  // Reserve shadow space for args and align frame before entering C++ world.
+  __ subq(RSP, Immediate(5 * target::kWordSize));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  __ movq(CallingConventions::kArg1Reg, RAX);         // Function.
+  __ movq(CallingConventions::kArg2Reg, R10);         // Arguments descriptor.
+  __ movq(CallingConventions::kArg3Reg, R11);         // Negative argc.
+  __ movq(CallingConventions::kArg4Reg, R12);         // Argv.
+
+#if defined(_WIN64)
+  __ movq(Address(RSP, 0 * target::kWordSize), THR);  // Thread.
+#else
+  __ movq(CallingConventions::kArg5Reg, THR);  // Thread.
+#endif
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
+
+  // Mark that the thread is executing VM code.
+  __ movq(RAX,
+          Address(THR, target::Thread::interpret_call_entry_point_offset()));
+  __ movq(Assembler::VMTagAddress(), RAX);
+
+  __ call(RAX);
+
+  // Mark that the thread is executing Dart code.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Reset exit frame information in Isolate structure.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+
+  __ LeaveStubFrame();
+  __ ret();
+#endif  // defined(DART_PRECOMPILED_RUNTIME)
+}
+
+// RBX: Contains an ICData.
+// TOS(0): return address (Dart code).
+void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(RBX);           // Preserve IC data.
+  __ pushq(Immediate(0));  // Result slot.
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ popq(CODE_REG);  // Original stub.
+  __ popq(RBX);       // Restore IC data.
+  __ LeaveStubFrame();
+
+  __ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ jmp(RAX);  // Jump to original stub.
+}
+
+//  TOS(0): return address (Dart code).
+void StubCodeCompiler::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(Immediate(0));  // Result slot.
+  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
+  __ popq(CODE_REG);  // Original stub.
+  __ LeaveStubFrame();
+
+  __ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ jmp(RAX);  // Jump to original stub.
+}
+
+// Called only from unoptimized code.
+void StubCodeCompiler::GenerateDebugStepCheckStub(Assembler* assembler) {
+#if defined(PRODUCT)
+  __ Ret();
+#else
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(RAX);
+  __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset()));
+  __ cmpq(RAX, Immediate(0));
+  __ j(NOT_EQUAL, &stepping, Assembler::kNearJump);
+  __ Bind(&done_stepping);
+  __ ret();
+
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ LeaveStubFrame();
+  __ jmp(&done_stepping, Assembler::kNearJump);
+#endif  // defined(PRODUCT)
+}
+
+// Used to check class and type arguments. Arguments passed in registers:
+//
+// Inputs:
+//   - R9  : RawSubtypeTestCache
+//   - RAX : instance to test against.
+//   - RDX : instantiator type arguments (for n=4).
+//   - RCX : function type arguments (for n=4).
+//
+//   - TOS + 0: return address.
+//
+// Preserves R9/RAX/RCX/RDX, RBX.
+//
+// Result in R8: null -> not found, otherwise result (true or false).
+static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
+  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
+
+  const Register kCacheReg = R9;
+  const Register kInstanceReg = RAX;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+
+  const Register kInstanceCidOrFunction = R10;
+  const Register kInstanceInstantiatorTypeArgumentsReg = R13;
+  const Register kInstanceParentFunctionTypeArgumentsReg = PP;
+  const Register kInstanceDelayedFunctionTypeArgumentsReg = CODE_REG;
+
+  const Register kNullReg = R8;
+
+  __ LoadObject(kNullReg, NullObject());
+
+  // Free up these 2 registers to be used for 6-value test.
+  if (n >= 6) {
+    __ pushq(kInstanceParentFunctionTypeArgumentsReg);
+    __ pushq(kInstanceDelayedFunctionTypeArgumentsReg);
+  }
+
+  // Loop initialization (moved up here to avoid having all dependent loads
+  // after each other).
+  __ movq(RSI,
+          FieldAddress(kCacheReg, target::SubtypeTestCache::cache_offset()));
+  __ addq(RSI, Immediate(target::Array::data_offset() - kHeapObjectTag));
+
+  Label loop, not_closure;
+  if (n >= 4) {
+    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
+  } else {
+    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
+  }
+  __ cmpq(kInstanceCidOrFunction, Immediate(kClosureCid));
+  __ j(NOT_EQUAL, &not_closure, Assembler::kNearJump);
+
+  // Closure handling.
+  {
+    __ movq(kInstanceCidOrFunction,
+            FieldAddress(kInstanceReg, target::Closure::function_offset()));
+    if (n >= 2) {
+      __ movq(
+          kInstanceInstantiatorTypeArgumentsReg,
+          FieldAddress(kInstanceReg,
+                       target::Closure::instantiator_type_arguments_offset()));
+      if (n >= 6) {
+        ASSERT(n == 6);
+        __ movq(
+            kInstanceParentFunctionTypeArgumentsReg,
+            FieldAddress(kInstanceReg,
+                         target::Closure::function_type_arguments_offset()));
+        __ movq(kInstanceDelayedFunctionTypeArgumentsReg,
+                FieldAddress(kInstanceReg,
+                             target::Closure::delayed_type_arguments_offset()));
+      }
+    }
+    __ jmp(&loop, Assembler::kNearJump);
+  }
+
+  // Non-Closure handling.
+  {
+    __ Bind(&not_closure);
+    if (n == 1) {
+      __ SmiTag(kInstanceCidOrFunction);
+    } else {
+      ASSERT(n >= 2);
+      Label has_no_type_arguments;
+      // [LoadClassById] also tags [kInstanceCidOrFunction] as a side-effect.
+      __ LoadClassById(RDI, kInstanceCidOrFunction);
+      __ movq(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
+      __ movl(
+          RDI,
+          FieldAddress(
+              RDI,
+              target::Class::type_arguments_field_offset_in_words_offset()));
+      __ cmpl(RDI, Immediate(target::Class::kNoTypeArguments));
+      __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
+      __ movq(kInstanceInstantiatorTypeArgumentsReg,
+              FieldAddress(kInstanceReg, RDI, TIMES_8, 0));
+      __ Bind(&has_no_type_arguments);
+
+      if (n >= 6) {
+        __ movq(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
+        __ movq(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
+      }
+    }
+  }
+
+  Label found, not_found, next_iteration;
+
+  // Loop header.
+  __ Bind(&loop);
+  __ movq(
+      RDI,
+      Address(RSI, target::kWordSize *
+                       target::SubtypeTestCache::kInstanceClassIdOrFunction));
+  __ cmpq(RDI, kNullReg);
+  __ j(EQUAL, &not_found, Assembler::kNearJump);
+  __ cmpq(RDI, kInstanceCidOrFunction);
+  if (n == 1) {
+    __ j(EQUAL, &found, Assembler::kNearJump);
+  } else {
+    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+    __ cmpq(kInstanceInstantiatorTypeArgumentsReg,
+            Address(RSI, target::kWordSize *
+                             target::SubtypeTestCache::kInstanceTypeArguments));
+    if (n == 2) {
+      __ j(EQUAL, &found, Assembler::kNearJump);
+    } else {
+      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+      __ cmpq(
+          kInstantiatorTypeArgumentsReg,
+          Address(RSI,
+                  target::kWordSize *
+                      target::SubtypeTestCache::kInstantiatorTypeArguments));
+      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+      __ cmpq(
+          kFunctionTypeArgumentsReg,
+          Address(RSI, target::kWordSize *
+                           target::SubtypeTestCache::kFunctionTypeArguments));
+
+      if (n == 4) {
+        __ j(EQUAL, &found, Assembler::kNearJump);
+      } else {
+        ASSERT(n == 6);
+        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+
+        __ cmpq(kInstanceParentFunctionTypeArgumentsReg,
+                Address(RSI, target::kWordSize *
+                                 target::SubtypeTestCache::
+                                     kInstanceParentFunctionTypeArguments));
+        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
+        __ cmpq(kInstanceDelayedFunctionTypeArgumentsReg,
+                Address(RSI, target::kWordSize *
+                                 target::SubtypeTestCache::
+                                     kInstanceDelayedFunctionTypeArguments));
+        __ j(EQUAL, &found, Assembler::kNearJump);
+      }
+    }
+  }
+
+  __ Bind(&next_iteration);
+  __ addq(RSI, Immediate(target::kWordSize *
+                         target::SubtypeTestCache::kTestEntryLength));
+  __ jmp(&loop, Assembler::kNearJump);
+
+  __ Bind(&found);
+  __ movq(R8, Address(RSI, target::kWordSize *
+                               target::SubtypeTestCache::kTestResult));
+  if (n >= 6) {
+    __ popq(kInstanceDelayedFunctionTypeArgumentsReg);
+    __ popq(kInstanceParentFunctionTypeArgumentsReg);
+  }
+  __ ret();
+
+  __ Bind(&not_found);
+  if (n >= 6) {
+    __ popq(kInstanceDelayedFunctionTypeArgumentsReg);
+    __ popq(kInstanceParentFunctionTypeArgumentsReg);
+  }
+  __ ret();
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype1TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 1);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype2TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 2);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype4TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 4);
+}
+
+// See comment on [GenerateSubtypeNTestCacheStub].
+void StubCodeCompiler::GenerateSubtype6TestCacheStub(Assembler* assembler) {
+  GenerateSubtypeNTestCacheStub(assembler, 6);
+}
+
+// Used to test whether a given value is of a given type (different variants,
+// all have the same calling convention).
+//
+// Inputs:
+//   - R9  : RawSubtypeTestCache
+//   - RAX : instance to test against.
+//   - RDX : instantiator type arguments (if needed).
+//   - RCX : function type arguments (if needed).
+//
+//   - RBX : type to test against.
+//   - R10 : name of destination variable.
+//
+// Preserves R9/RAX/RCX/RDX, RBX, R10.
+//
+// Note of warning: The caller will not populate CODE_REG and we have therefore
+// no access to the pool.
+void StubCodeCompiler::GenerateDefaultTypeTestStub(Assembler* assembler) {
+  Label done;
+
+  const Register kInstanceReg = RAX;
+
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ movq(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
+  __ jmp(FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTopTypeTypeTestStub(Assembler* assembler) {
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateTypeRefTypeTestStub(Assembler* assembler) {
+  const Register kTypeRefReg = RBX;
+
+  // We dereference the TypeRef and tail-call to it's type testing stub.
+  __ movq(kTypeRefReg,
+          FieldAddress(kTypeRefReg, target::TypeRef::type_offset()));
+  __ jmp(FieldAddress(
+      kTypeRefReg, target::AbstractType::type_test_stub_entry_point_offset()));
+}
+
+void StubCodeCompiler::GenerateUnreachableTypeTestStub(Assembler* assembler) {
+  __ Breakpoint();
+}
+
+static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
+                                            TypeCheckMode mode) {
+  const Register kInstanceReg = RAX;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+  const Register kDstTypeReg = RBX;
+  const Register kSubtypeTestCacheReg = R9;
+
+  __ PushObject(NullObject());  // Make room for result.
+  __ pushq(kInstanceReg);
+  __ pushq(kDstTypeReg);
+  __ pushq(kInstantiatorTypeArgumentsReg);
+  __ pushq(kFunctionTypeArgumentsReg);
+  __ PushObject(NullObject());
+  __ pushq(kSubtypeTestCacheReg);
+  __ PushImmediate(Immediate(target::ToRawSmi(mode)));
+  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
+  __ Drop(1);
+  __ popq(kSubtypeTestCacheReg);
+  __ Drop(1);
+  __ popq(kFunctionTypeArgumentsReg);
+  __ popq(kInstantiatorTypeArgumentsReg);
+  __ popq(kDstTypeReg);
+  __ popq(kInstanceReg);
+  __ Drop(1);  // Discard return value.
+}
+
+void StubCodeCompiler::GenerateLazySpecializeTypeTestStub(
+    Assembler* assembler) {
+  const Register kInstanceReg = RAX;
+
+  Label done;
+
+  // Fast case for 'null'.
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(EQUAL, &done);
+
+  __ movq(
+      CODE_REG,
+      Address(THR, target::Thread::lazy_specialize_type_test_stub_offset()));
+  __ EnterStubFrame();
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
+  __ LeaveStubFrame();
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
+  Label done, call_runtime;
+
+  const Register kInstanceReg = RAX;
+  const Register kDstTypeReg = RBX;
+  const Register kSubtypeTestCacheReg = R9;
+
+  __ EnterStubFrame();
+
+#ifdef DEBUG
+  // Guaranteed by caller.
+  Label no_error;
+  __ CompareObject(kInstanceReg, NullObject());
+  __ BranchIf(NOT_EQUAL, &no_error);
+  __ Breakpoint();
+  __ Bind(&no_error);
+#endif
+
+  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
+  __ CompareObject(kSubtypeTestCacheReg, NullObject());
+  __ BranchIf(EQUAL, &call_runtime);
+
+  const Register kTmp = RDI;
+
+  // If this is not a [Type] object, we'll go to the runtime.
+  Label is_simple_case, is_complex_case;
+  __ LoadClassId(kTmp, kDstTypeReg);
+  __ cmpq(kTmp, Immediate(kTypeCid));
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // Check whether this [Type] is instantiated/uninstantiated.
+  __ cmpb(FieldAddress(kDstTypeReg, target::Type::type_state_offset()),
+          Immediate(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // Check whether this [Type] is a function type.
+  __ movq(kTmp, FieldAddress(kDstTypeReg, target::Type::signature_offset()));
+  __ CompareObject(kTmp, NullObject());
+  __ BranchIf(NOT_EQUAL, &is_complex_case);
+
+  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
+  __ BranchIfSmi(kInstanceReg, &is_complex_case);
+
+  // Fall through to &is_simple_case
+
+  __ Bind(&is_simple_case);
+  {
+    __ Call(StubCodeSubtype2TestCache());
+    __ CompareObject(R8, CastHandle<Object>(TrueObject()));
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    __ Jump(&call_runtime);
+  }
+
+  __ Bind(&is_complex_case);
+  {
+    __ Call(StubCodeSubtype6TestCache());
+    __ CompareObject(R8, CastHandle<Object>(TrueObject()));
+    __ BranchIf(EQUAL, &done);  // Cache said: yes.
+    // Fall through to runtime_call
+  }
+
+  __ Bind(&call_runtime);
+
+  // We cannot really ensure here that dynamic/Object/void never occur here
+  // (though it is guaranteed at dart_precompiled_runtime time).  This is
+  // because we do constant evaluation with default stubs and only install
+  // optimized versions before writing out the AOT snapshot.
+  // So dynamic/Object/void will run with default stub in constant evaluation.
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(DynamicType()));
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(ObjectType()));
+  __ BranchIf(EQUAL, &done);
+  __ CompareObject(kDstTypeReg, CastHandle<Object>(VoidType()));
+  __ BranchIf(EQUAL, &done);
+
+  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
+
+  __ Bind(&done);
+  __ LeaveStubFrame();
+  __ Ret();
+}
+
+// Return the current stack pointer address, used to stack alignment
+// checks.
+// TOS + 0: return address
+// Result in RAX.
+void StubCodeCompiler::GenerateGetCStackPointerStub(Assembler* assembler) {
+  __ leaq(RAX, Address(RSP, target::kWordSize));
+  __ ret();
+}
+
+// Jump to a frame on the call stack.
+// TOS + 0: return address
+// Arg1: program counter
+// Arg2: stack pointer
+// Arg3: frame_pointer
+// Arg4: thread
+// No Result.
+void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) {
+  __ movq(THR, CallingConventions::kArg4Reg);
+  __ movq(RBP, CallingConventions::kArg3Reg);
+  __ movq(RSP, CallingConventions::kArg2Reg);
+  // Set the tag.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+  // Clear top exit frame.
+  __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
+          Immediate(0));
+  // Restore the pool pointer.
+  __ RestoreCodePointer();
+  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
+    __ movq(PP, Address(THR, target::Thread::global_object_pool_offset()));
+  } else {
+    __ LoadPoolPointer(PP);
+  }
+  __ jmp(CallingConventions::kArg1Reg);  // Jump to program counter.
+}
+
+// Run an exception handler.  Execution comes from JumpToFrame stub.
+//
+// The arguments are stored in the Thread object.
+// No result.
+void StubCodeCompiler::GenerateRunExceptionHandlerStub(Assembler* assembler) {
+  ASSERT(kExceptionObjectReg == RAX);
+  ASSERT(kStackTraceObjectReg == RDX);
+  __ movq(CallingConventions::kArg1Reg,
+          Address(THR, target::Thread::resume_pc_offset()));
+
+  word offset_from_thread = 0;
+  bool ok = target::CanLoadFromThread(NullObject(), &offset_from_thread);
+  ASSERT(ok);
+  __ movq(TMP, Address(THR, offset_from_thread));
+
+  // Load the exception from the current thread.
+  Address exception_addr(THR, target::Thread::active_exception_offset());
+  __ movq(kExceptionObjectReg, exception_addr);
+  __ movq(exception_addr, TMP);
+
+  // Load the stacktrace from the current thread.
+  Address stacktrace_addr(THR, target::Thread::active_stacktrace_offset());
+  __ movq(kStackTraceObjectReg, stacktrace_addr);
+  __ movq(stacktrace_addr, TMP);
+
+  __ jmp(CallingConventions::kArg1Reg);  // Jump to continuation point.
+}
+
+// Deoptimize a frame on the call stack before rewinding.
+// The arguments are stored in the Thread object.
+// No result.
+void StubCodeCompiler::GenerateDeoptForRewindStub(Assembler* assembler) {
+  // Push zap value instead of CODE_REG.
+  __ pushq(Immediate(kZapCodeReg));
+
+  // Push the deopt pc.
+  __ pushq(Address(THR, target::Thread::resume_pc_offset()));
+  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
+
+  // After we have deoptimized, jump to the correct frame.
+  __ EnterStubFrame();
+  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
+  __ LeaveStubFrame();
+  __ int3();
+}
+
+// Calls to the runtime to optimize the given function.
+// RDI: function to be reoptimized.
+// R10: argument descriptor (preserved).
+void StubCodeCompiler::GenerateOptimizeFunctionStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(R10);           // Preserve args descriptor.
+  __ pushq(Immediate(0));  // Result slot.
+  __ pushq(RDI);           // Arg0: function to optimize
+  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
+  __ popq(RAX);  // Discard argument.
+  __ popq(RAX);  // Get Code object.
+  __ popq(R10);  // Restore argument descriptor.
+  __ LeaveStubFrame();
+  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
+  __ jmp(RCX);
+  __ int3();
+}
+
+// Does identical check (object references are equal or not equal) with special
+// checks for boxed numbers.
+// Left and right are pushed on stack.
+// Return ZF set.
+// Note: A Mint cannot contain a value that would fit in Smi.
+static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
+                                                 const Register left,
+                                                 const Register right) {
+  Label reference_compare, done, check_mint;
+  // If any of the arguments is Smi do reference compare.
+  __ testq(left, Immediate(kSmiTagMask));
+  __ j(ZERO, &reference_compare);
+  __ testq(right, Immediate(kSmiTagMask));
+  __ j(ZERO, &reference_compare);
+
+  // Value compare for two doubles.
+  __ CompareClassId(left, kDoubleCid);
+  __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump);
+  __ CompareClassId(right, kDoubleCid);
+  __ j(NOT_EQUAL, &done, Assembler::kFarJump);
+
+  // Double values bitwise compare.
+  __ movq(left, FieldAddress(left, target::Double::value_offset()));
+  __ cmpq(left, FieldAddress(right, target::Double::value_offset()));
+  __ jmp(&done, Assembler::kFarJump);
+
+  __ Bind(&check_mint);
+  __ CompareClassId(left, kMintCid);
+  __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump);
+  __ CompareClassId(right, kMintCid);
+  __ j(NOT_EQUAL, &done, Assembler::kFarJump);
+  __ movq(left, FieldAddress(left, target::Mint::value_offset()));
+  __ cmpq(left, FieldAddress(right, target::Mint::value_offset()));
+  __ jmp(&done, Assembler::kFarJump);
+
+  __ Bind(&reference_compare);
+  __ cmpq(left, right);
+  __ Bind(&done);
+}
+
+// Called only from unoptimized code. All relevant registers have been saved.
+// TOS + 0: return address
+// TOS + 1: right argument.
+// TOS + 2: left argument.
+// Returns ZF set.
+void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+#if !defined(PRODUCT)
+  // Check single stepping.
+  Label stepping, done_stepping;
+  __ LoadIsolate(RAX);
+  __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset()));
+  __ cmpq(RAX, Immediate(0));
+  __ j(NOT_EQUAL, &stepping);
+  __ Bind(&done_stepping);
+#endif
+
+  const Register left = RAX;
+  const Register right = RDX;
+
+  __ movq(left, Address(RSP, 2 * target::kWordSize));
+  __ movq(right, Address(RSP, 1 * target::kWordSize));
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
+  __ ret();
+
+#if !defined(PRODUCT)
+  __ Bind(&stepping);
+  __ EnterStubFrame();
+  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
+  __ RestoreCodePointer();
+  __ LeaveStubFrame();
+  __ jmp(&done_stepping);
+#endif
+}
+
+// Called from optimized code only.
+// TOS + 0: return address
+// TOS + 1: right argument.
+// TOS + 2: left argument.
+// Returns ZF set.
+void StubCodeCompiler::GenerateOptimizedIdenticalWithNumberCheckStub(
+    Assembler* assembler) {
+  const Register left = RAX;
+  const Register right = RDX;
+
+  __ movq(left, Address(RSP, 2 * target::kWordSize));
+  __ movq(right, Address(RSP, 1 * target::kWordSize));
+  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
+  __ ret();
+}
+
+// Called from megamorphic calls.
+//  RDI: receiver
+//  RBX: target::MegamorphicCache (preserved)
+// Passed to target:
+//  CODE_REG: target Code
+//  R10: arguments descriptor
+void StubCodeCompiler::GenerateMegamorphicCallStub(Assembler* assembler) {
+  // Jump if receiver is a smi.
+  Label smi_case;
+  __ testq(RDI, Immediate(kSmiTagMask));
+  // Jump out of line for smi case.
+  __ j(ZERO, &smi_case, Assembler::kNearJump);
+
+  // Loads the cid of the object.
+  __ LoadClassId(RAX, RDI);
+
+  Label cid_loaded;
+  __ Bind(&cid_loaded);
+  __ movq(R9, FieldAddress(RBX, target::MegamorphicCache::mask_offset()));
+  __ movq(RDI, FieldAddress(RBX, target::MegamorphicCache::buckets_offset()));
+  // R9: mask as a smi.
+  // RDI: cache buckets array.
+
+  // Tag cid as a smi.
+  __ addq(RAX, RAX);
+
+  // Compute the table index.
+  ASSERT(target::MegamorphicCache::kSpreadFactor == 7);
+  // Use leaq and subq multiply with 7 == 8 - 1.
+  __ leaq(RCX, Address(RAX, TIMES_8, 0));
+  __ subq(RCX, RAX);
+
+  Label loop;
+  __ Bind(&loop);
+  __ andq(RCX, R9);
+
+  const intptr_t base = target::Array::data_offset();
+  // RCX is smi tagged, but table entries are two words, so TIMES_8.
+  Label probe_failed;
+  __ cmpq(RAX, FieldAddress(RDI, RCX, TIMES_8, base));
+  __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump);
+
+  Label load_target;
+  __ Bind(&load_target);
+  // Call the target found in the cache.  For a class id match, this is a
+  // proper target for the given name and arguments descriptor.  If the
+  // illegal class id was found, the target is a cache miss handler that can
+  // be invoked as a normal Dart function.
+  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()));
+    __ jmp(target_address);
+  } else {
+    __ movq(RAX, target_address);
+    __ movq(R10,
+            FieldAddress(
+                RBX, target::MegamorphicCache::arguments_descriptor_offset()));
+    __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
+    __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+    __ jmp(RCX);
+  }
+
+  // Probe failed, check if it is a miss.
+  __ Bind(&probe_failed);
+  __ cmpq(FieldAddress(RDI, RCX, TIMES_8, base),
+          Immediate(target::ToRawSmi(kIllegalCid)));
+  __ j(ZERO, &load_target, Assembler::kNearJump);
+
+  // Try next entry in the table.
+  __ AddImmediate(RCX, Immediate(target::ToRawSmi(1)));
+  __ jmp(&loop);
+
+  // Load cid for the Smi case.
+  __ Bind(&smi_case);
+  __ movq(RAX, Immediate(kSmiCid));
+  __ jmp(&cid_loaded);
+}
+
+// Called from switchable IC calls.
+//  RDI: receiver
+//  RBX: ICData (preserved)
+// Passed to target:
+//  CODE_REG: target Code object
+//  R10: arguments descriptor
+void StubCodeCompiler::GenerateICCallThroughFunctionStub(Assembler* assembler) {
+  Label loop, found, miss;
+  __ movq(R13, FieldAddress(RBX, target::ICData::entries_offset()));
+  __ movq(R10,
+          FieldAddress(RBX, target::ICData::arguments_descriptor_offset()));
+  __ leaq(R13, FieldAddress(R13, target::Array::data_offset()));
+  // R13: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
+  // RAX: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ movq(R9, Address(R13, 0));
+  __ cmpq(RAX, R9);
+  __ j(EQUAL, &found, Assembler::kNearJump);
+
+  ASSERT(target::ToRawSmi(kIllegalCid) == 0);
+  __ testq(R9, R9);
+  __ j(ZERO, &miss, Assembler::kNearJump);
+
+  const intptr_t entry_length =
+      target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
+      target::kWordSize;
+  __ addq(R13, Immediate(entry_length));  // Next entry.
+  __ jmp(&loop);
+
+  __ Bind(&found);
+  const intptr_t target_offset =
+      target::ICData::TargetIndexFor(1) * target::kWordSize;
+  __ movq(RAX, Address(R13, target_offset));
+  __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
+  __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+  __ jmp(RCX);
+
+  __ Bind(&miss);
+  __ LoadIsolate(RAX);
+  __ movq(CODE_REG, Address(RAX, target::Isolate::ic_miss_code_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ jmp(RCX);
+}
+
+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()));
+  __ leaq(R13, FieldAddress(R13, target::Array::data_offset()));
+  // R13: first IC entry
+  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
+  // RAX: receiver cid as Smi
+
+  __ Bind(&loop);
+  __ movq(R9, Address(R13, 0));
+  __ cmpq(RAX, R9);
+  __ j(EQUAL, &found, Assembler::kNearJump);
+
+  ASSERT(target::ToRawSmi(kIllegalCid) == 0);
+  __ testq(R9, R9);
+  __ j(ZERO, &miss, Assembler::kNearJump);
+
+  const intptr_t entry_length =
+      target::ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) *
+      target::kWordSize;
+  __ addq(R13, Immediate(entry_length));  // Next entry.
+  __ jmp(&loop);
+
+  __ Bind(&found);
+  const intptr_t code_offset =
+      target::ICData::CodeIndexFor(1) * target::kWordSize;
+  const intptr_t entry_offset =
+      target::ICData::EntryPointIndexFor(1) * target::kWordSize;
+  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
+    __ movq(CODE_REG, Address(R13, code_offset));
+  }
+  __ jmp(Address(R13, entry_offset));
+
+  __ Bind(&miss);
+  __ LoadIsolate(RAX);
+  __ movq(CODE_REG, Address(RAX, target::Isolate::ic_miss_code_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset()));
+  __ jmp(RCX);
+}
+
+//  RDI: receiver
+//  RBX: UnlinkedCall
+void StubCodeCompiler::GenerateUnlinkedCallStub(Assembler* assembler) {
+  __ EnterStubFrame();
+  __ pushq(RDI);  // Preserve receiver.
+
+  __ pushq(Immediate(0));  // Result slot.
+  __ pushq(RDI);           // Arg0: Receiver
+  __ pushq(RBX);           // Arg1: UnlinkedCall
+  __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+  __ popq(RBX);
+  __ popq(RBX);
+  __ popq(RBX);  // result = IC
+
+  __ popq(RDI);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                          CodeEntryKind::kMonomorphic)));
+  __ jmp(RCX);
+}
+
+// Called from switchable IC calls.
+//  RDI: receiver
+//  RBX: SingleTargetCache
+// Passed to target::
+//  CODE_REG: target Code object
+void StubCodeCompiler::GenerateSingleTargetCallStub(Assembler* assembler) {
+  Label miss;
+  __ LoadClassIdMayBeSmi(RAX, RDI);
+  __ movzxw(R9,
+            FieldAddress(RBX, target::SingleTargetCache::lower_limit_offset()));
+  __ movzxw(R10,
+            FieldAddress(RBX, target::SingleTargetCache::upper_limit_offset()));
+  __ cmpq(RAX, R9);
+  __ j(LESS, &miss, Assembler::kNearJump);
+  __ cmpq(RAX, R10);
+  __ j(GREATER, &miss, Assembler::kNearJump);
+  __ movq(RCX,
+          FieldAddress(RBX, target::SingleTargetCache::entry_point_offset()));
+  __ movq(CODE_REG,
+          FieldAddress(RBX, target::SingleTargetCache::target_offset()));
+  __ jmp(RCX);
+
+  __ Bind(&miss);
+  __ EnterStubFrame();
+  __ pushq(RDI);  // Preserve receiver.
+
+  __ pushq(Immediate(0));  // Result slot.
+  __ pushq(RDI);           // Arg0: Receiver
+  __ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
+  __ popq(RBX);
+  __ popq(RBX);  // result = IC
+
+  __ popq(RDI);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                          CodeEntryKind::kMonomorphic)));
+  __ jmp(RCX);
+}
+
+// Called from the monomorphic checked entry.
+//  RDI: receiver
+void StubCodeCompiler::GenerateMonomorphicMissStub(Assembler* assembler) {
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::monomorphic_miss_stub_offset()));
+  __ EnterStubFrame();
+  __ pushq(RDI);  // Preserve receiver.
+
+  __ pushq(Immediate(0));  // Result slot.
+  __ pushq(RDI);           // Arg0: Receiver
+  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
+  __ popq(RBX);
+  __ popq(RBX);  // result = IC
+
+  __ popq(RDI);  // Restore receiver.
+  __ LeaveStubFrame();
+
+  __ movq(CODE_REG,
+          Address(THR, target::Thread::ic_lookup_through_code_stub_offset()));
+  __ movq(RCX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
+                                          CodeEntryKind::kMonomorphic)));
+  __ jmp(RCX);
+}
+
+void StubCodeCompiler::GenerateFrameAwaitingMaterializationStub(
+    Assembler* assembler) {
+  __ int3();
+}
+
+void StubCodeCompiler::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
+  __ int3();
+}
+
+}  // namespace compiler
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 08380f8..4e272c5 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -496,7 +496,6 @@
       ((AL << kConditionShift) | (0x32 << 20) | (0xf << 12));
 
   static const int32_t kBreakPointCode = 0xdeb0;      // For breakpoint.
-  static const int32_t kStopMessageCode = 0xdeb1;     // For Stop(message).
   static const int32_t kSimulatorBreakCode = 0xdeb2;  // For breakpoint in sim.
   static const int32_t kSimulatorRedirectCode = 0xca11;  // For redirection.
 
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 6067a37..0e2d6ea 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -882,7 +882,6 @@
 
   // Reserved brk and hlt instruction codes.
   static const int32_t kBreakPointCode = 0xdeb0;      // For breakpoint.
-  static const int32_t kStopMessageCode = 0xdeb1;     // For Stop(message).
   static const int32_t kSimulatorBreakCode = 0xdeb2;  // For breakpoint in sim.
   static const int32_t kSimulatorRedirectCode = 0xca11;  // For redirection.
 
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 15506e5..aeb775e 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -271,6 +271,11 @@
 //    SP[-(1+ArgC)], ..., SP[-1] and argument descriptor PP[D], which
 //    indicates whether the first argument is a type argument vector.
 //
+//  - DirectCall ArgC, D
+//
+//    Invoke the function PP[D] with arguments
+//    SP[-(ArgC-1)], ..., SP[0] and argument descriptor PP[D+1].
+//
 //  - InterfaceCall ArgC, D
 //
 //    Lookup and invoke method using ICData in PP[D]
@@ -478,7 +483,8 @@
   V(CompareIntGt,                          0, ___, ___, ___)                   \
   V(CompareIntLt,                          0, ___, ___, ___)                   \
   V(CompareIntGe,                          0, ___, ___, ___)                   \
-  V(CompareIntLe,                          0, ___, ___, ___)
+  V(CompareIntLe,                          0, ___, ___, ___)                   \
+  V(DirectCall,                          A_D, num, num, ___)
 
 // clang-format on
 
@@ -607,6 +613,7 @@
       case KernelBytecode::kIndirectStaticCall:
       case KernelBytecode::kInterfaceCall:
       case KernelBytecode::kDynamicCall:
+      case KernelBytecode::kDirectCall:
         return true;
 
       default:
diff --git a/runtime/vm/constants_x64.cc b/runtime/vm/constants_x64.cc
new file mode 100644
index 0000000..df6fb75
--- /dev/null
+++ b/runtime/vm/constants_x64.cc
@@ -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.
+
+#include "vm/constants_x64.h"
+
+namespace dart {
+
+#if defined(_WIN64)
+const Register CallingConventions::ArgumentRegisters[] = {
+    CallingConventions::kArg1Reg, CallingConventions::kArg2Reg,
+    CallingConventions::kArg3Reg, CallingConventions::kArg4Reg};
+
+const XmmRegister CallingConventions::XmmArgumentRegisters[] = {
+    XmmRegister::XMM0, XmmRegister::XMM1, XmmRegister::XMM2, XmmRegister::XMM3};
+#else
+const Register CallingConventions::ArgumentRegisters[] = {
+    CallingConventions::kArg1Reg, CallingConventions::kArg2Reg,
+    CallingConventions::kArg3Reg, CallingConventions::kArg4Reg,
+    CallingConventions::kArg5Reg, CallingConventions::kArg6Reg};
+
+const XmmRegister CallingConventions::XmmArgumentRegisters[] = {
+    XmmRegister::XMM0, XmmRegister::XMM1, XmmRegister::XMM2, XmmRegister::XMM3,
+    XmmRegister::XMM4, XmmRegister::XMM5, XmmRegister::XMM6, XmmRegister::XMM7};
+#endif
+
+}  // namespace dart
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 512ff98..5de7ddc 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -5,6 +5,9 @@
 #ifndef RUNTIME_VM_CONSTANTS_X64_H_
 #define RUNTIME_VM_CONSTANTS_X64_H_
 
+#include "platform/assert.h"
+#include "platform/globals.h"
+
 namespace dart {
 
 enum Register {
@@ -149,6 +152,20 @@
   static const Register kArg2Reg = RDX;
   static const Register kArg3Reg = R8;
   static const Register kArg4Reg = R9;
+  static const Register ArgumentRegisters[];
+  static const intptr_t kArgumentRegisters =
+      R(kArg1Reg) | R(kArg2Reg) | R(kArg3Reg) | R(kArg4Reg);
+  static const intptr_t kNumArgRegs = 4;
+
+  static const XmmRegister XmmArgumentRegisters[];
+  static const intptr_t kXmmArgumentRegisters =
+      R(XMM0) | R(XMM1) | R(XMM2) | R(XMM3);
+  static const intptr_t kNumXmmArgRegs = 4;
+
+  // can ArgumentRegisters[i] and XmmArgumentRegisters[i] both be used at the
+  // same time? (Windows no, rest yes)
+  static const bool kArgumentIntRegXorXmmReg = true;
+
   static const intptr_t kShadowSpaceBytes = 4 * kWordSize;
 
   static const intptr_t kVolatileCpuRegisters =
@@ -164,6 +181,8 @@
       R(XMM6) | R(XMM7) | R(XMM8) | R(XMM9) | R(XMM10) | R(XMM11) | R(XMM12) |
       R(XMM13) | R(XMM14) | R(XMM15);
 
+  static const XmmRegister xmmFirstNonParameterReg = XMM4;
+
   // Windows x64 ABI specifies that small objects are passed in registers.
   // Otherwise they are passed by reference.
   static const size_t kRegisterTransferLimit = 16;
@@ -177,6 +196,22 @@
   static const Register kArg4Reg = RCX;
   static const Register kArg5Reg = R8;
   static const Register kArg6Reg = R9;
+  static const Register ArgumentRegisters[];
+  static const intptr_t kArgumentRegisters = R(kArg1Reg) | R(kArg2Reg) |
+                                             R(kArg3Reg) | R(kArg4Reg) |
+                                             R(kArg5Reg) | R(kArg6Reg);
+  static const intptr_t kNumArgRegs = 6;
+
+  static const XmmRegister XmmArgumentRegisters[];
+  static const intptr_t kXmmArgumentRegisters = R(XMM0) | R(XMM1) | R(XMM2) |
+                                                R(XMM3) | R(XMM4) | R(XMM5) |
+                                                R(XMM6) | R(XMM7);
+  static const intptr_t kNumXmmArgRegs = 8;
+
+  // can ArgumentRegisters[i] and XmmArgumentRegisters[i] both be used at the
+  // same time? (Windows no, rest yes)
+  static const bool kArgumentIntRegXorXmmReg = false;
+
   static const intptr_t kShadowSpaceBytes = 0;
 
   static const intptr_t kVolatileCpuRegisters = R(RAX) | R(RCX) | R(RDX) |
@@ -192,6 +227,8 @@
       R(RBX) | R(R12) | R(R13) | R(R14) | R(R15);
 
   static const intptr_t kCalleeSaveXmmRegisters = 0;
+
+  static const XmmRegister xmmFirstNonParameterReg = XMM8;
 };
 #endif
 
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index a951991..ad749aa 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -95,8 +95,8 @@
 #if defined(TARGET_ARCH_ARM)
   // These offsets are embedded in precompiled instructions. We need simarm
   // (compiler) and arm (runtime) to agree.
-  CHECK_OFFSET(Thread::stack_limit_offset(), 28);
-  CHECK_OFFSET(Thread::object_null_offset(), 88);
+  CHECK_OFFSET(Thread::stack_limit_offset(), 36);
+  CHECK_OFFSET(Thread::object_null_offset(), 96);
   CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 14);
   CHECK_OFFSET(Isolate::object_store_offset(), 20);
   NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 168));
@@ -104,8 +104,8 @@
 #if defined(TARGET_ARCH_ARM64)
   // These offsets are embedded in precompiled instructions. We need simarm64
   // (compiler) and arm64 (runtime) to agree.
-  CHECK_OFFSET(Thread::stack_limit_offset(), 56);
-  CHECK_OFFSET(Thread::object_null_offset(), 168);
+  CHECK_OFFSET(Thread::stack_limit_offset(), 72);
+  CHECK_OFFSET(Thread::object_null_offset(), 184);
   CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 26);
   CHECK_OFFSET(Isolate::object_store_offset(), 40);
   NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 288));
@@ -135,6 +135,27 @@
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
     return strdup("VM already initialized or flags not initialized.");
   }
+
+  const Snapshot* snapshot = nullptr;
+  if (vm_isolate_snapshot != nullptr) {
+    snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot);
+    if (snapshot == nullptr) {
+      return strdup("Invalid vm isolate snapshot seen");
+    }
+  }
+
+  // We are initializing the VM. We will take the VM-global flags used
+  // during snapshot generation time also at runtime (this avoids the need
+  // for the embedder to pass the same flags used during snapshot generation
+  // also to the runtime).
+  if (snapshot != nullptr) {
+    char* error =
+        SnapshotHeaderReader::InitializeGlobalVMFlagsFromSnapshot(snapshot);
+    if (error != nullptr) {
+      return error;
+    }
+  }
+
 #if defined(DEBUG)
   // Turn on verify_gc_contains if any of the other GC verification flag
   // is turned on.
@@ -164,11 +185,10 @@
   start_time_micros_ = OS::GetCurrentMonotonicMicros();
   VirtualMemory::Init();
   OSThread::Init();
-  if (FLAG_support_timeline) {
-    Timeline::Init();
-  }
-  NOT_IN_PRODUCT(
-      TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::Init"));
+#if defined(SUPPORT_TIMELINE)
+  Timeline::Init();
+  TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::Init");
+#endif
   Isolate::InitVM();
   PortMap::Init();
   FreeListElement::Init();
@@ -214,12 +234,10 @@
     ArgumentsDescriptor::Init();
     ICData::Init();
     if (vm_isolate_snapshot != NULL) {
-      NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
-                                               "VMIsolateSnapshot"));
-      const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot);
-      if (snapshot == NULL) {
-        return strdup("Invalid vm isolate snapshot seen");
-      }
+#if defined(SUPPORT_TIMELINE)
+      TimelineDurationScope tds(Timeline::GetVMStream(), "ReadVMSnapshot");
+#endif
+      ASSERT(snapshot != nullptr);
       vm_snapshot_kind_ = snapshot->kind();
 
       if (Snapshot::IncludesCode(vm_snapshot_kind_)) {
@@ -260,7 +278,7 @@
       ReversePcLookupCache::BuildAndAttachToIsolate(vm_isolate_);
 
       Object::FinishInit(vm_isolate_);
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
       if (tds.enabled()) {
         tds.SetNumArguments(2);
         tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
@@ -309,8 +327,9 @@
     }
 #endif
     {
-      NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
-                                               "FinalizeVMIsolate"));
+#if defined(SUPPORT_TIMELINE)
+      TimelineDurationScope tds(Timeline::GetVMStream(), "FinalizeVMIsolate");
+#endif
       Object::FinalizeVMIsolate(vm_isolate_);
     }
 #if defined(DEBUG)
@@ -526,13 +545,13 @@
                  UptimeMillis());
   }
   NOT_IN_PRODUCT(CodeObservers::Cleanup());
-  if (FLAG_support_timeline) {
-    if (FLAG_trace_shutdown) {
-      OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n",
-                   UptimeMillis());
-    }
-    Timeline::Cleanup();
+#if defined(SUPPORT_TIMELINE)
+  if (FLAG_trace_shutdown) {
+    OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n",
+                 UptimeMillis());
   }
+  Timeline::Cleanup();
+#endif
   OS::Cleanup();
   if (FLAG_trace_shutdown) {
     OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Done\n", UptimeMillis());
@@ -571,18 +590,16 @@
   // Initialize the new isolate.
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
-  NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
-                                           "InitializeIsolate");
-                 tds.SetNumArguments(1);
-                 tds.CopyArgument(0, "isolateName", I->name());)
+#if defined(SUPPORT_TIMLINE)
+  TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
+                            "InitializeIsolate");
+  tds.SetNumArguments(1);
+  tds.CopyArgument(0, "isolateName", I->name());
+#endif
   ASSERT(I != NULL);
   StackZone zone(T);
   HandleScope handle_scope(T);
-  {
-    NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
-                                             "ObjectStore::Init"));
-    ObjectStore::Init(I);
-  }
+  ObjectStore::Init(I);
 
   Error& error = Error::Handle(T->zone());
   error = Object::Init(I, kernel_buffer, kernel_buffer_size);
@@ -591,8 +608,10 @@
   }
   if ((snapshot_data != NULL) && kernel_buffer == NULL) {
     // Read the snapshot and setup the initial state.
-    NOT_IN_PRODUCT(TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
-                                             "IsolateSnapshotReader"));
+#if defined(SUPPORT_TIMELINE)
+    TimelineDurationScope tds(T, Timeline::GetIsolateStream(),
+                              "ReadIsolateSnapshot");
+#endif
     // TODO(turnidge): Remove once length is not part of the snapshot.
     const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
     if (snapshot == NULL) {
@@ -618,7 +637,7 @@
 
     ReversePcLookupCache::BuildAndAttachToIsolate(I);
 
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
     if (tds.enabled()) {
       tds.SetNumArguments(2);
       tds.FormatArgument(0, "snapshotSize", "%" Pd, snapshot->length());
@@ -719,23 +738,28 @@
   buffer.AddString("release");
 #endif
 
-#define ADD_FLAG(name, isolate_flag, flag)                                     \
+#define ADD_FLAG(name, value)                                                  \
   do {                                                                         \
-    const bool name = (isolate != NULL) ? isolate->name() : flag;              \
-    buffer.AddString(name ? (" " #name) : (" no-" #name));                     \
+    buffer.AddString(value ? (" " #name) : (" no-" #name));                    \
   } while (0);
 
+#define ADD_ISOLATE_FLAG(name, isolate_flag, flag)                             \
+  do {                                                                         \
+    const bool value = (isolate != NULL) ? isolate->name() : flag;             \
+    ADD_FLAG(#name, value);                                                    \
+  } while (0);
+
+  VM_GLOBAL_FLAG_LIST(ADD_FLAG);
   if (Snapshot::IncludesCode(kind)) {
     // enabling assertions affects deopt ids.
-    ADD_FLAG(asserts, enable_asserts, FLAG_enable_asserts);
-    if (kind == Snapshot::kFullAOT) {
-      ADD_FLAG(use_bare_instructions, use_bare_instructions,
-               FLAG_use_bare_instructions);
-    }
+    ADD_ISOLATE_FLAG(asserts, enable_asserts, FLAG_enable_asserts);
     if (kind == Snapshot::kFullJIT) {
-      ADD_FLAG(use_field_guards, use_field_guards, FLAG_use_field_guards);
-      ADD_FLAG(use_osr, use_osr, FLAG_use_osr);
+      ADD_ISOLATE_FLAG(use_field_guards, use_field_guards,
+                       FLAG_use_field_guards);
+      ADD_ISOLATE_FLAG(use_osr, use_osr, FLAG_use_osr);
     }
+    buffer.AddString(FLAG_causal_async_stacks ? " causal_async_stacks"
+                                              : " no-causal_async_stacks");
 
 // Generated code must match the host architecture and ABI.
 #if defined(TARGET_ARCH_ARM)
@@ -778,6 +802,7 @@
   if (FLAG_precompiled_mode && FLAG_dwarf_stack_traces) {
     buffer.AddString(" dwarf-stack-traces");
   }
+#undef ADD_ISOLATE_FLAG
 #undef ADD_FLAG
 
   return buffer.Steal();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b01af49..8e45f57 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -74,6 +74,14 @@
             false,
             "Dump common hash tables before snapshotting.");
 
+#define CHECK_ERROR_HANDLE(error)                                              \
+  {                                                                            \
+    RawError* err = (error);                                                   \
+    if (err != Error::null()) {                                                \
+      return Api::NewHandle(T, err);                                           \
+    }                                                                          \
+  }
+
 ThreadLocalKey Api::api_native_key_ = kUnsetThreadLocalKey;
 Dart_Handle Api::true_handle_ = NULL;
 Dart_Handle Api::false_handle_ = NULL;
@@ -1495,7 +1503,7 @@
   }
 #endif  // #if defined(DEBUG)
 
-  Symbols::Compact(I);
+  Symbols::Compact();
 
   FullSnapshotWriter writer(Snapshot::kFull, vm_snapshot_data_buffer,
                             isolate_snapshot_data_buffer, ApiReallocate,
@@ -3741,6 +3749,8 @@
         current_func, constr_name.ToCString(), error_message.ToCString()));
     return ApiError::New(message);
   }
+  RawError* error = constructor.VerifyEntryPoint();
+  if (error != Error::null()) return error;
   return constructor.raw();
 }
 
@@ -3822,6 +3832,7 @@
     cls = type_obj.type_class();
   }
   if (constructor.IsGenerativeConstructor()) {
+    CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
 #if defined(DEBUG)
     if (!cls.is_allocated() &&
         (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
@@ -3916,16 +3927,13 @@
     RETURN_TYPE_ERROR(Z, type, Type);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
+  CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
 #if defined(DEBUG)
   if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
     return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
   }
 #endif
-  const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
-  if (!error.IsNull()) {
-    // An error occurred, return error object.
-    return Api::NewHandle(T, error.raw());
-  }
+  CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
   return Api::NewHandle(T, AllocateObject(T, cls));
 }
 
@@ -3945,16 +3953,13 @@
     RETURN_NULL_ERROR(native_fields);
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
+  CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
 #if defined(DEBUG)
   if (!cls.is_allocated() && (Dart::vm_snapshot_kind() == Snapshot::kFullAOT)) {
     return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
   }
 #endif
-  const Error& error = Error::Handle(Z, cls.EnsureIsFinalized(T));
-  if (!error.IsNull()) {
-    // An error occurred, return error object.
-    return Api::NewHandle(T, error.raw());
-  }
+  CHECK_ERROR_HANDLE(cls.EnsureIsFinalized(T));
   if (num_native_fields != cls.num_native_fields()) {
     return Api::NewError(
         "%s: invalid number of native fields %" Pd " passed in, expected %d",
@@ -4038,6 +4043,7 @@
   if (!constructor.IsNull() && constructor.IsGenerativeConstructor() &&
       constructor.AreValidArgumentCounts(
           kTypeArgsLen, number_of_arguments + extra_args, 0, NULL)) {
+    CHECK_ERROR_HANDLE(constructor.VerifyEntryPoint());
     // Create the argument list.
     // Constructors get the uninitialized object.
     if (!type_arguments.IsNull()) {
@@ -4094,6 +4100,7 @@
   // This API does not provide a way to pass named parameters.
   const Array& arg_names = Object::empty_array();
   const bool respect_reflectable = false;
+  const bool check_is_entrypoint = FLAG_verify_entry_points;
   if (obj.IsType()) {
     if (!Type::Cast(obj).IsFinalized()) {
       return Api::NewError(
@@ -4113,7 +4120,8 @@
       return result;
     }
     return Api::NewHandle(
-        T, cls.Invoke(function_name, args, arg_names, respect_reflectable));
+        T, cls.Invoke(function_name, args, arg_names, respect_reflectable,
+                      check_is_entrypoint));
   } else if (obj.IsNull() || obj.IsInstance()) {
     // Since we have allocated an object it would mean that the type of the
     // receiver is already resolved and finalized, hence it is not necessary
@@ -4127,8 +4135,9 @@
       return result;
     }
     args.SetAt(0, instance);
-    return Api::NewHandle(T, instance.Invoke(function_name, args, arg_names,
-                                             respect_reflectable));
+    return Api::NewHandle(
+        T, instance.Invoke(function_name, args, arg_names, respect_reflectable,
+                           check_is_entrypoint));
   } else if (obj.IsLibrary()) {
     // Check whether class finalization is needed.
     const Library& lib = Library::Cast(obj);
@@ -4150,7 +4159,8 @@
     }
 
     return Api::NewHandle(
-        T, lib.Invoke(function_name, args, arg_names, respect_reflectable));
+        T, lib.Invoke(function_name, args, arg_names, respect_reflectable,
+                      check_is_entrypoint));
   } else {
     return Api::NewError(
         "%s expects argument 'target' to be an object, type, or library.",
@@ -4202,6 +4212,7 @@
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
   const bool throw_nsm_if_absent = true;
   const bool respect_reflectable = false;
+  const bool check_is_entrypoint = FLAG_verify_entry_points;
 
   if (obj.IsType()) {
     if (!Type::Cast(obj).IsFinalized()) {
@@ -4214,8 +4225,9 @@
       const Library& lib = Library::Handle(Z, cls.library());
       field_name = lib.PrivateName(field_name);
     }
-    return Api::NewHandle(T, cls.InvokeGetter(field_name, throw_nsm_if_absent,
-                                              respect_reflectable));
+    return Api::NewHandle(
+        T, cls.InvokeGetter(field_name, throw_nsm_if_absent,
+                            respect_reflectable, check_is_entrypoint));
   } else if (obj.IsNull() || obj.IsInstance()) {
     Instance& instance = Instance::Handle(Z);
     instance ^= obj.raw();
@@ -4224,8 +4236,9 @@
       const Library& lib = Library::Handle(Z, cls.library());
       field_name = lib.PrivateName(field_name);
     }
-    return Api::NewHandle(
-        T, instance.InvokeGetter(field_name, respect_reflectable));
+    return Api::NewHandle(T,
+                          instance.InvokeGetter(field_name, respect_reflectable,
+                                                check_is_entrypoint));
   } else if (obj.IsLibrary()) {
     const Library& lib = Library::Cast(obj);
     // Check that the library is loaded.
@@ -4237,8 +4250,9 @@
     if (Library::IsPrivate(field_name)) {
       field_name = lib.PrivateName(field_name);
     }
-    return Api::NewHandle(T, lib.InvokeGetter(field_name, throw_nsm_if_absent,
-                                              respect_reflectable));
+    return Api::NewHandle(
+        T, lib.InvokeGetter(field_name, throw_nsm_if_absent,
+                            respect_reflectable, check_is_entrypoint));
   } else if (obj.IsError()) {
     return container;
   } else {
@@ -4271,6 +4285,7 @@
 
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(container));
   const bool respect_reflectable = false;
+  const bool check_is_entrypoint = FLAG_verify_entry_points;
 
   if (obj.IsType()) {
     if (!Type::Cast(obj).IsFinalized()) {
@@ -4287,7 +4302,8 @@
       field_name = lib.PrivateName(field_name);
     }
     return Api::NewHandle(
-        T, cls.InvokeSetter(field_name, value_instance, respect_reflectable));
+        T, cls.InvokeSetter(field_name, value_instance, respect_reflectable,
+                            check_is_entrypoint));
   } else if (obj.IsNull() || obj.IsInstance()) {
     Instance& instance = Instance::Handle(Z);
     instance ^= obj.raw();
@@ -4296,8 +4312,9 @@
       const Library& lib = Library::Handle(Z, cls.library());
       field_name = lib.PrivateName(field_name);
     }
-    return Api::NewHandle(T, instance.InvokeSetter(field_name, value_instance,
-                                                   respect_reflectable));
+    return Api::NewHandle(
+        T, instance.InvokeSetter(field_name, value_instance,
+                                 respect_reflectable, check_is_entrypoint));
   } else if (obj.IsLibrary()) {
     // To access a top-level we may need to use the Field or the
     // setter Function.  The setter function may either be in the
@@ -4314,7 +4331,8 @@
       field_name = lib.PrivateName(field_name);
     }
     return Api::NewHandle(
-        T, lib.InvokeSetter(field_name, value_instance, respect_reflectable));
+        T, lib.InvokeSetter(field_name, value_instance, respect_reflectable,
+                            check_is_entrypoint));
   } else if (obj.IsError()) {
     return container;
   }
@@ -4712,6 +4730,7 @@
                                      Dart_Handle retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   ASSERT(arguments->thread()->isolate() == Isolate::Current());
+  ASSERT_CALLBACK_STATE(arguments->thread());
   if ((retval != Api::Null()) && !Api::IsInstance(retval) &&
       !Api::IsError(retval)) {
     // Print the current stack trace to make the problematic caller
@@ -4755,6 +4774,10 @@
       return Symbols::False().raw();
     }
 
+    if (!Api::ffiEnabled() && name.Equals(Symbols::DartLibraryFfi())) {
+      return Symbols::False().raw();
+    }
+
     if (name.Equals(Symbols::DartVMProduct())) {
 #ifdef PRODUCT
       return Symbols::True().raw();
@@ -4763,6 +4786,14 @@
 #endif
     }
 
+    if (name.Equals(Symbols::DartDeveloperTimeline())) {
+#ifdef SUPPORT_TIMELINE
+      return Symbols::True().raw();
+#else
+      return Symbols::False().raw();
+#endif
+    }
+
     const String& prefix = Symbols::DartLibrary();
     if (name.StartsWith(prefix)) {
       const String& library_name =
@@ -4832,6 +4863,8 @@
 DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args,
                                             bool retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  ASSERT(arguments->thread()->isolate() == Isolate::Current());
+  ASSERT_CALLBACK_STATE(arguments->thread());
   arguments->SetReturn(Bool::Get(retval));
 }
 
@@ -4839,6 +4872,7 @@
                                             int64_t retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   ASSERT(arguments->thread()->isolate() == Isolate::Current());
+  ASSERT_CALLBACK_STATE(arguments->thread());
   if (Smi::IsValid(retval)) {
     Api::SetSmiReturnValue(arguments, static_cast<intptr_t>(retval));
   } else {
@@ -4852,6 +4886,7 @@
 DART_EXPORT void Dart_SetDoubleReturnValue(Dart_NativeArguments args,
                                            double retval) {
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  ASSERT(arguments->thread()->isolate() == Isolate::Current());
   ASSERT_CALLBACK_STATE(arguments->thread());
   TransitionNativeToVM transition(arguments->thread());
   Api::SetDoubleReturnValue(arguments, retval);
@@ -4959,22 +4994,6 @@
   RETURN_TYPE_ERROR(Z, library, Library);
 }
 
-static void CheckIsEntryPoint(const Class& klass) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  // This is not a completely thorough check that the class is an entry-point,
-  // but it catches most missing annotations.
-  if (!klass.has_pragma()) {
-    OS::PrintErr(
-        "ERROR: It is illegal to access class %s through Dart C API "
-        "because it was not annotated with @pragma('vm:entry-point').\n"
-        "ERROR: See "
-        "https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/"
-        "aot/entry_point_pragma.md\n",
-        String::Handle(klass.UserVisibleName()).ToCString());
-  }
-#endif
-}
-
 DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library,
                                       Dart_Handle class_name) {
   DARTSCOPE(Thread::Current());
@@ -4993,7 +5012,7 @@
     return Api::NewError("Class '%s' not found in library '%s'.",
                          cls_name.ToCString(), lib_name.ToCString());
   }
-  CheckIsEntryPoint(cls);
+  CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
   return Api::NewHandle(T, cls.RareType());
 }
 
@@ -5022,7 +5041,7 @@
     return Api::NewError("Type '%s' not found in library '%s'.",
                          name_str.ToCString(), lib_name.ToCString());
   }
-  CheckIsEntryPoint(cls);
+  CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
   if (cls.NumTypeArguments() == 0) {
     if (number_of_type_arguments != 0) {
       return Api::NewError(
@@ -5233,6 +5252,11 @@
   Isolate* I = T->isolate();
   CHECK_CALLBACK_STATE(T);
 
+  // The kernel loader is about to allocate a bunch of new libraries, classes,
+  // and functions into old space. Force growth, and use of the bump allocator
+  // instead of freelists.
+  BumpAllocateScope bump_allocate_scope(T);
+
   I->DoneLoading();
 
   // TODO(hausner): move the remaining code below (finalization and
@@ -5255,6 +5279,8 @@
   I->debugger()->NotifyDoneLoading();
 #endif
 
+  I->heap()->old_space()->EvaluateAfterLoading();
+
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (FLAG_enable_mirrors) {
     // Notify mirrors that MirrorSystem.libraries needs to be recomputed.
@@ -5487,107 +5513,43 @@
   return OS::GetCurrentMonotonicMicros();
 }
 
-#if defined(PRODUCT)
 DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
     const char* name,
     Dart_ServiceRequestCallback callback,
     void* user_data) {
-  return;
-}
-
-DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
-    const char* name,
-    Dart_ServiceRequestCallback callback,
-    void* user_data) {
-  return;
-}
-
-DART_EXPORT void Dart_SetEmbedderInformationCallback(
-    Dart_EmbedderInformationCallback callback) {
-  return;
-}
-
-DART_EXPORT char* Dart_SetServiceStreamCallbacks(
-    Dart_ServiceStreamListenCallback listen_callback,
-    Dart_ServiceStreamCancelCallback cancel_callback) {
-  return NULL;
-}
-
-DART_EXPORT void Dart_SetNativeServiceStreamCallback(
-    Dart_NativeStreamConsumer consumer,
-    const char* stream_id) {
-  return;
-}
-
-DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
-                                                  const char* event_kind,
-                                                  const uint8_t* bytes,
-                                                  intptr_t bytes_length) {
-  return Api::Success();
-}
-
-DART_EXPORT char* Dart_SetFileModifiedCallback(
-    Dart_FileModifiedCallback file_mod_callback) {
-  return NULL;
-}
-
-DART_EXPORT bool Dart_IsReloading() {
-  return false;
-}
-
-DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) {
-  return;
-}
-
-DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
-    Dart_EmbedderTimelineStartRecording start_recording,
-    Dart_EmbedderTimelineStopRecording stop_recording) {
-  return;
-}
-
-DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
-                                             void* user_data) {
-  return false;
-}
-
-DART_EXPORT void Dart_TimelineEvent(const char* label,
-                                    int64_t timestamp0,
-                                    int64_t timestamp1_or_async_id,
-                                    Dart_Timeline_Event_Type type,
-                                    intptr_t argument_count,
-                                    const char** argument_names,
-                                    const char** argument_values) {
-  return;
-}
-#else  // defined(PRODUCT)
-DART_EXPORT void Dart_RegisterIsolateServiceRequestCallback(
-    const char* name,
-    Dart_ServiceRequestCallback callback,
-    void* user_data) {
+#if !defined(PRODUCT)
   if (FLAG_support_service) {
     Service::RegisterIsolateEmbedderCallback(name, callback, user_data);
   }
+#endif
 }
 
 DART_EXPORT void Dart_RegisterRootServiceRequestCallback(
     const char* name,
     Dart_ServiceRequestCallback callback,
     void* user_data) {
+#if !defined(PRODUCT)
   if (FLAG_support_service) {
     Service::RegisterRootEmbedderCallback(name, callback, user_data);
   }
+#endif
 }
 
 DART_EXPORT void Dart_SetEmbedderInformationCallback(
     Dart_EmbedderInformationCallback callback) {
+#if !defined(PRODUCT)
   if (FLAG_support_service) {
     Service::SetEmbedderInformationCallback(callback);
   }
+#endif
 }
 
 DART_EXPORT char* Dart_SetServiceStreamCallbacks(
     Dart_ServiceStreamListenCallback listen_callback,
     Dart_ServiceStreamCancelCallback cancel_callback) {
+#if defined(PRODUCT)
+  return NULL;
+#else
   if (!FLAG_support_service) {
     return NULL;
   }
@@ -5621,18 +5583,22 @@
   }
   Service::SetEmbedderStreamCallbacks(listen_callback, cancel_callback);
   return NULL;
+#endif
 }
 
 DART_EXPORT void Dart_SetNativeServiceStreamCallback(
     Dart_NativeStreamConsumer consumer,
     const char* stream_id) {
+#if !defined(PRODUCT)
   Service::SetNativeServiceStreamCallback(consumer, stream_id);
+#endif
 }
 
 DART_EXPORT Dart_Handle Dart_ServiceSendDataEvent(const char* stream_id,
                                                   const char* event_kind,
                                                   const uint8_t* bytes,
                                                   intptr_t bytes_length) {
+#if !defined(PRODUCT)
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   if (stream_id == NULL) {
@@ -5649,11 +5615,13 @@
                          CURRENT_FUNC);
   }
   Service::SendEmbedderEvent(I, stream_id, event_kind, bytes, bytes_length);
+#endif
   return Api::Success();
 }
 
 DART_EXPORT char* Dart_SetFileModifiedCallback(
     Dart_FileModifiedCallback file_modified_callback) {
+#if !defined(PRODUCT)
   if (!FLAG_support_service) {
     return NULL;
   }
@@ -5674,20 +5642,23 @@
   }
   IsolateReloadContext::SetFileModifiedCallback(file_modified_callback);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // !defined(PRODUCT)
   return NULL;
 }
 
 DART_EXPORT bool Dart_IsReloading() {
+#if defined(PRODUCT)
+  return false;
+#else
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
   return isolate->IsReloading();
+#endif
 }
 
 DART_EXPORT void Dart_GlobalTimelineSetRecordedStreams(int64_t stream_mask) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
+#if defined(SUPPORT_TIMELINE)
   const bool api_enabled = (stream_mask & DART_TIMELINE_STREAM_API) != 0;
   const bool compiler_enabled =
       (stream_mask & DART_TIMELINE_STREAM_COMPILER) != 0;
@@ -5708,121 +5679,7 @@
   Timeline::SetStreamGCEnabled(gc_enabled);
   Timeline::SetStreamIsolateEnabled(isolate_enabled);
   Timeline::SetStreamVMEnabled(vm_enabled);
-}
-
-static void StartStreamToConsumer(Dart_StreamConsumer consumer,
-                                  void* user_data,
-                                  const char* stream_name) {
-  // Start stream.
-  consumer(Dart_StreamConsumer_kStart, stream_name, NULL, 0, user_data);
-}
-
-static void FinishStreamToConsumer(Dart_StreamConsumer consumer,
-                                   void* user_data,
-                                   const char* stream_name) {
-  // Finish stream.
-  consumer(Dart_StreamConsumer_kFinish, stream_name, NULL, 0, user_data);
-}
-
-static void DataStreamToConsumer(Dart_StreamConsumer consumer,
-                                 void* user_data,
-                                 const char* output,
-                                 intptr_t output_length,
-                                 const char* stream_name) {
-  if (output == NULL) {
-    return;
-  }
-  const intptr_t kDataSize = 64 * KB;
-  intptr_t cursor = 0;
-  intptr_t remaining = output_length;
-  while (remaining >= kDataSize) {
-    consumer(Dart_StreamConsumer_kData, stream_name,
-             reinterpret_cast<const uint8_t*>(&output[cursor]), kDataSize,
-             user_data);
-    cursor += kDataSize;
-    remaining -= kDataSize;
-  }
-  if (remaining > 0) {
-    ASSERT(remaining < kDataSize);
-    consumer(Dart_StreamConsumer_kData, stream_name,
-             reinterpret_cast<const uint8_t*>(&output[cursor]), remaining,
-             user_data);
-    cursor += remaining;
-    remaining -= remaining;
-  }
-  ASSERT(cursor == output_length);
-  ASSERT(remaining == 0);
-}
-
-static bool StreamTraceEvents(Dart_StreamConsumer consumer,
-                              void* user_data,
-                              JSONStream* js) {
-  ASSERT(js != NULL);
-  // Steal output from JSONStream.
-  char* output = NULL;
-  intptr_t output_length = 0;
-  js->Steal(&output, &output_length);
-  if (output_length < 3) {
-    // Empty JSON array.
-    free(output);
-    return false;
-  }
-  // We want to send the JSON array without the leading '[' or trailing ']'
-  // characters.
-  ASSERT(output[0] == '[');
-  ASSERT(output[output_length - 1] == ']');
-  // Replace the ']' with the null character.
-  output[output_length - 1] = '\0';
-  char* start = &output[1];
-  // We are skipping the '['.
-  output_length -= 1;
-
-  DataStreamToConsumer(consumer, user_data, start, output_length, "timeline");
-
-  // We stole the JSONStream's output buffer, free it.
-  free(output);
-
-  return true;
-}
-
-DART_EXPORT void Dart_SetEmbedderTimelineCallbacks(
-    Dart_EmbedderTimelineStartRecording start_recording,
-    Dart_EmbedderTimelineStopRecording stop_recording) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
-  Timeline::set_start_recording_cb(start_recording);
-  Timeline::set_stop_recording_cb(stop_recording);
-}
-
-DART_EXPORT bool Dart_GlobalTimelineGetTrace(Dart_StreamConsumer consumer,
-                                             void* user_data) {
-  if (!FLAG_support_timeline) {
-    return false;
-  }
-  // To support various embedders, it must be possible to call this function
-  // from a thread for which we have not entered an Isolate and set up a Thread
-  // TLS object. Therefore, a Zone may not be available, a StackZone cannot be
-  // created, and no ZoneAllocated objects can be allocated.
-  if (consumer == NULL) {
-    return false;
-  }
-  TimelineEventRecorder* timeline_recorder = Timeline::recorder();
-  if (timeline_recorder == NULL) {
-    // Nothing has been recorded.
-    return false;
-  }
-  Timeline::ReclaimCachedBlocksFromThreads();
-  bool success = false;
-  JSONStream js;
-  TimelineEventFilter filter;
-  timeline_recorder->PrintTraceEvent(&js, &filter);
-  StartStreamToConsumer(consumer, user_data, "timeline");
-  if (StreamTraceEvents(consumer, user_data, &js)) {
-    success = true;
-  }
-  FinishStreamToConsumer(consumer, user_data, "timeline");
-  return success;
+#endif
 }
 
 DART_EXPORT void Dart_TimelineEvent(const char* label,
@@ -5832,9 +5689,7 @@
                                     intptr_t argument_count,
                                     const char** argument_names,
                                     const char** argument_values) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
+#if defined(SUPPORT_TIMELINE)
   if (type < Dart_Timeline_Event_Begin) {
     return;
   }
@@ -5891,8 +5746,8 @@
     event->CopyArgument(i, argument_names[i], argument_values[i]);
   }
   event->Complete();
+#endif
 }
-#endif  // defined(PRODUCT)
 
 DART_EXPORT void Dart_SetThreadName(const char* name) {
   OSThread* thread = OSThread::Current();
@@ -6017,10 +5872,7 @@
     return result;
   }
   CHECK_CALLBACK_STATE(T);
-  const Error& error = Error::Handle(Precompiler::CompileAll());
-  if (!error.IsNull()) {
-    return Api::NewHandle(T, error.raw());
-  }
+  CHECK_ERROR_HANDLE(Precompiler::CompileAll());
   return Api::Success();
 #endif
 }
@@ -6049,8 +5901,7 @@
   ASSERT(FLAG_load_deferred_eagerly);
   CHECK_NULL(callback);
 
-  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
-                                            "WriteAppAOTSnapshot"));
+  TIMELINE_DURATION(T, Isolate, "WriteAppAOTSnapshot");
   AssemblyImageWriter image_writer(T, callback, callback_data, NULL, NULL);
   uint8_t* vm_snapshot_data_buffer = NULL;
   uint8_t* isolate_snapshot_data_buffer = NULL;
@@ -6082,8 +5933,7 @@
   API_TIMELINE_DURATION(T);
   CHECK_NULL(callback);
 
-  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
-                                            "WriteVMAOTSnapshot"));
+  TIMELINE_DURATION(T, Isolate, "WriteVMAOTSnapshot");
   AssemblyImageWriter image_writer(T, callback, callback_data, NULL, NULL);
   uint8_t* vm_snapshot_data_buffer = NULL;
   FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data_buffer, NULL,
@@ -6138,8 +5988,7 @@
   }
   const void* shared_instructions_image = shared_instructions;
 
-  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
-                                            "WriteAppAOTSnapshot"));
+  TIMELINE_DURATION(T, Isolate, "WriteAppAOTSnapshot");
   BlobImageWriter vm_image_writer(T, vm_snapshot_instructions_buffer,
                                   ApiReallocate, 2 * MB /* initial_size */,
                                   /*shared_objects=*/nullptr,
@@ -6248,10 +6097,9 @@
   DropRegExpMatchCode(Z);
 
   ProgramVisitor::Dedup();
-  Symbols::Compact(I);
+  Symbols::Compact();
 
-  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
-                                            "WriteCoreJITSnapshot"));
+  TIMELINE_DURATION(T, Isolate, "WriteCoreJITSnapshot");
   BlobImageWriter vm_image_writer(T, vm_snapshot_instructions_buffer,
                                   ApiReallocate, 2 * MB /* initial_size */,
                                   /*shared_objects=*/nullptr,
@@ -6311,7 +6159,7 @@
     DropCodeWithoutReusableInstructions(reused_instructions);
   }
   ProgramVisitor::Dedup();
-  Symbols::Compact(I);
+  Symbols::Compact();
 
   if (FLAG_dump_tables) {
     Symbols::DumpTable(I);
@@ -6319,8 +6167,7 @@
     DumpTypeArgumentsTable(I);
   }
 
-  NOT_IN_PRODUCT(TimelineDurationScope tds2(T, Timeline::GetIsolateStream(),
-                                            "WriteAppJITSnapshot"));
+  TIMELINE_DURATION(T, Isolate, "WriteAppJITSnapshot");
   BlobImageWriter isolate_image_writer(T, isolate_snapshot_instructions_buffer,
                                        ApiReallocate, 2 * MB /* initial_size */,
                                        /*shared_objects=*/nullptr,
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 8d91094..570a855 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -102,21 +102,21 @@
     }                                                                          \
   } while (0)
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
 #define API_TIMELINE_DURATION(thread)                                          \
-  TimelineDurationScope tds(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
+  TimelineDurationScope api_tds(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
 #define API_TIMELINE_DURATION_BASIC(thread)                                    \
   API_TIMELINE_DURATION(thread);                                               \
-  tds.SetNumArguments(1);                                                      \
-  tds.CopyArgument(0, "mode", "basic");
+  api_tds.SetNumArguments(1);                                                  \
+  api_tds.CopyArgument(0, "mode", "basic");
 
 #define API_TIMELINE_BEGIN_END(thread)                                         \
-  TimelineBeginEndScope tbes(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
+  TimelineBeginEndScope api_tbes(thread, Timeline::GetAPIStream(), CURRENT_FUNC)
 
 #define API_TIMELINE_BEGIN_END_BASIC(thread)                                   \
   API_TIMELINE_BEGIN_END(thread);                                              \
-  tbes.SetNumArguments(1);                                                     \
-  tbes.CopyArgument(0, "mode", "basic");
+  api_tbes.SetNumArguments(1);                                                 \
+  api_tbes.CopyArgument(0, "mode", "basic");
 #else
 #define API_TIMELINE_DURATION(thread)                                          \
   do {                                                                         \
@@ -294,6 +294,25 @@
 
   static RawString* GetEnvironmentValue(Thread* thread, const String& name);
 
+  static bool ffiEnabled() {
+    // dart:ffi is not implemented for the following configurations
+#if !defined(TARGET_ARCH_X64)
+    // https://github.com/dart-lang/sdk/issues/35774
+    return false;
+#elif !defined(TARGET_OS_LINUX) && !defined(TARGET_OS_MACOS)
+    // https://github.com/dart-lang/sdk/issues/35760 Arm32 && Android
+    // https://github.com/dart-lang/sdk/issues/35771 Windows
+    // https://github.com/dart-lang/sdk/issues/35772 Arm64
+    // https://github.com/dart-lang/sdk/issues/35773 DBC
+    return false;
+#else
+    // dart:ffi is also not implemented for precompiled in which case
+    // FLAG_enable_ffi is set to false by --precompilation.
+    // Once dart:ffi is supported on all targets, only users will set this flag
+    return FLAG_enable_ffi;
+#endif
+  }
+
  private:
   static Dart_Handle InitNewHandle(Thread* thread, RawObject* raw);
 
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 3a3c425..b4ad32a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -7657,515 +7657,6 @@
   EXPECT_SUBSTRING("testAsyncEvent", js.ToCString());
 }
 
-struct AppendData {
-  uint8_t* buffer;
-  intptr_t buffer_length;
-};
-
-static void AppendStreamConsumer(Dart_StreamConsumer_State state,
-                                 const char* stream_name,
-                                 const uint8_t* buffer,
-                                 intptr_t buffer_length,
-                                 void* user_data) {
-  if (state == Dart_StreamConsumer_kFinish) {
-    return;
-  }
-  AppendData* data = reinterpret_cast<AppendData*>(user_data);
-  if (state == Dart_StreamConsumer_kStart) {
-    // Initialize append data.
-    data->buffer = NULL;
-    data->buffer_length = 0;
-    return;
-  }
-  ASSERT(state == Dart_StreamConsumer_kData);
-
-  // Grow buffer.
-  data->buffer = reinterpret_cast<uint8_t*>(
-      realloc(data->buffer, data->buffer_length + buffer_length));
-  // Copy new data.
-  memmove(&data->buffer[data->buffer_length], buffer, buffer_length);
-  // Update length.
-  data->buffer_length += buffer_length;
-}
-
-TEST_CASE(DartAPI_TimelineGetTrace) {
-  const char* kScriptChars =
-      "foo() => 'a';\n"
-      "main() => foo();\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-
-  const char* buffer = NULL;
-  intptr_t buffer_length = 0;
-  bool success = false;
-
-  // Enable recording of all streams.
-  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL);
-
-  // Invoke main, which will be compiled resulting in a compiler event in
-  // the timeline.
-  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
-
-  // Grab the trace.
-  AppendData data;
-  success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-  EXPECT(success);
-  buffer = reinterpret_cast<char*>(data.buffer);
-  buffer_length = data.buffer_length;
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test.
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-
-  // Free buffer allocated by AppendStreamConsumer
-  free(data.buffer);
-}
-
-TEST_CASE(DartAPI_TimelineGetTraceOnlyDartEvents) {
-  const char* kScriptChars =
-      "import 'dart:developer';\n"
-      ""
-      "main() {\n"
-      "  Timeline.startSync('DART_NAME');\n"
-      "  Timeline.finishSync();\n"
-      "}\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-
-  const char* buffer = NULL;
-  intptr_t buffer_length = 0;
-  bool success = false;
-
-  // Enable recording of the Dart stream.
-  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_DART);
-
-  // Invoke main, which will add a new timeline event from Dart.
-  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
-
-  // Grab the trace.
-  AppendData data;
-  data.buffer = NULL;
-  data.buffer_length = 0;
-  success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-  EXPECT(success);
-  buffer = reinterpret_cast<char*>(data.buffer);
-  buffer_length = data.buffer_length;
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test.
-  EXPECT_SUBSTRING("\"cat\":\"Dart\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"DART_NAME\"", buffer);
-
-  // Free buffer allocated by AppendStreamConsumer
-  free(data.buffer);
-}
-
-TEST_CASE(DartAPI_TimelineGetTraceWithDartEvents) {
-  const char* kScriptChars =
-      "import 'dart:developer';\n"
-      "\n"
-      "main() {\n"
-      "  Timeline.startSync('DART_NAME');\n"
-      "  Timeline.finishSync();\n"
-      "}\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-
-  const char* buffer = NULL;
-  intptr_t buffer_length = 0;
-  bool success = false;
-
-  // Enable recording of all streams.
-  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL);
-
-  // Invoke main, which will be compiled resulting in a compiler event in
-  // the timeline.
-  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
-
-  // Grab the trace.
-  AppendData data;
-  success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-  EXPECT(success);
-  buffer = reinterpret_cast<char*>(data.buffer);
-  buffer_length = data.buffer_length;
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test.
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-  EXPECT_SUBSTRING("\"cat\":\"Dart\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"DART_NAME\"", buffer);
-
-  // Free buffer allocated by AppendStreamConsumer
-  free(data.buffer);
-}
-
-TEST_CASE(DartAPI_TimelineGetTraceGlobalOverride) {
-  const char* kScriptChars =
-      "foo() => 'a';\n"
-      "main() => foo();\n";
-
-  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-
-  const char* buffer = NULL;
-  intptr_t buffer_length = 0;
-  bool success = false;
-
-  // Enable recording of all streams across the entire vm.
-  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL);
-
-  // Invoke main, which will be compiled resulting in a compiler event in
-  // the timeline.
-  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
-
-  // Grab the trace.
-  AppendData data;
-  success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-  EXPECT(success);
-  buffer = reinterpret_cast<char*>(data.buffer);
-  buffer_length = data.buffer_length;
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test.
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-
-  // Free buffer allocated by AppendStreamConsumer
-  free(data.buffer);
-}
-
-static const char* arg_names[] = {"arg0"};
-
-static const char* arg_values[] = {"value0"};
-
-TEST_CASE(DartAPI_GlobalTimelineGetTrace) {
-  const char* kScriptChars =
-      "bar() => 'z';\n"
-      "foo() => 'a';\n"
-      "main() => foo();\n";
-
-  // Enable all streams.
-  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL |
-                                        DART_TIMELINE_STREAM_VM);
-  Dart_Handle lib;
-  {
-    // Add something to the VM stream.
-    TimelineDurationScope tds(Timeline::GetVMStream(), "TestVMDuration");
-    lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  }
-
-  {
-    // Add something to the embedder stream.
-    Dart_TimelineEvent("TRACE_EVENT", Dart_TimelineGetMicros(), 0,
-                       Dart_Timeline_Event_Begin, 1, &arg_names[0],
-                       &arg_values[0]);
-    // Add counter to the embedder stream.
-    Dart_TimelineEvent("COUNTER_EVENT", Dart_TimelineGetMicros(), 0,
-                       Dart_Timeline_Event_Counter, 0, NULL, NULL);
-    Dart_SetThreadName("CUSTOM THREAD NAME");
-  }
-
-  // Invoke main, which will be compiled resulting in a compiler event in
-  // the timeline.
-  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
-
-  const char* buffer = NULL;
-  intptr_t buffer_length = 0;
-  bool success = false;
-
-  // Grab the global trace.
-  AppendData data;
-  {
-    Thread* T = Thread::Current();
-    StackZone zone(T);
-    success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-    EXPECT(success);
-    // The call should do no zone allocation.
-    EXPECT(zone.SizeInBytes() == 0);
-  }
-  buffer = reinterpret_cast<char*>(data.buffer);
-  buffer_length = data.buffer_length;
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test.
-  EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-  EXPECT_NOTSUBSTRING("\"function\":\"::_bar\"", buffer);
-  EXPECT_SUBSTRING("TRACE_EVENT", buffer);
-  EXPECT_SUBSTRING("arg0", buffer);
-  EXPECT_SUBSTRING("value0", buffer);
-  EXPECT_SUBSTRING("COUNTER_EVENT", buffer);
-  EXPECT_SUBSTRING("CUSTOM THREAD NAME", buffer);
-
-  // Free buffer allocated by AppendStreamConsumer
-  free(data.buffer);
-  data.buffer = NULL;
-  data.buffer_length = 0;
-
-  // Retrieving the global trace resulted in all open blocks being reclaimed.
-  // Add some new events and verify that both sets of events are present
-  // in the resulting trace.
-  {
-    // Add something to the VM stream.
-    TimelineDurationScope tds(Timeline::GetVMStream(), "TestVMDuration2");
-    // Invoke bar, which will be compiled resulting in a compiler event in
-    // the timeline.
-    result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
-  }
-
-  // Grab the global trace.
-  {
-    Thread* T = Thread::Current();
-    StackZone zone(T);
-    success = Dart_GlobalTimelineGetTrace(AppendStreamConsumer, &data);
-    EXPECT(success);
-    EXPECT(zone.SizeInBytes() == 0);
-  }
-  buffer = reinterpret_cast<char*>(data.buffer);
-  buffer_length = data.buffer_length;
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test for old events.
-  EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-
-  // Heartbeat test for new events.
-  EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer);
-
-  // Free buffer allocated by AppendStreamConsumer
-  free(data.buffer);
-}
-
-class GlobalTimelineThreadData {
- public:
-  GlobalTimelineThreadData()
-      : monitor_(new Monitor()), data_(new AppendData()), running_(true) {}
-
-  ~GlobalTimelineThreadData() {
-    delete monitor_;
-    monitor_ = NULL;
-    free(data_->buffer);
-    data_->buffer = NULL;
-    data_->buffer_length = 0;
-    delete data_;
-    data_ = NULL;
-  }
-
-  Monitor* monitor() const { return monitor_; }
-  bool running() const { return running_; }
-  AppendData* data() const { return data_; }
-  uint8_t* buffer() const { return data_->buffer; }
-  intptr_t buffer_length() const { return data_->buffer_length; }
-
-  void set_running(bool running) { running_ = running; }
-
- private:
-  Monitor* monitor_;
-  AppendData* data_;
-  bool running_;
-};
-
-static void GlobalTimelineThread(uword parameter) {
-  GlobalTimelineThreadData* data =
-      reinterpret_cast<GlobalTimelineThreadData*>(parameter);
-  Thread* T = Thread::Current();
-  // When there is no current Thread, then Zone allocation will fail.
-  EXPECT(T == NULL);
-  {
-    MonitorLocker ml(data->monitor());
-    bool success =
-        Dart_GlobalTimelineGetTrace(AppendStreamConsumer, data->data());
-    EXPECT(success);
-    data->set_running(false);
-    ml.Notify();
-  }
-}
-
-// This test is the same as the one above except that the calls to
-// Dart_GlobalTimelineGetTrace are made from a fresh thread. This ensures that
-// we can call the function from a thread for which we have not set up a
-// Thread object.
-TEST_CASE(DartAPI_GlobalTimelineGetTrace_Threaded) {
-  const char* kScriptChars =
-      "bar() => 'z';\n"
-      "foo() => 'a';\n"
-      "main() => foo();\n";
-
-  // Enable all streams.
-  Dart_GlobalTimelineSetRecordedStreams(DART_TIMELINE_STREAM_ALL |
-                                        DART_TIMELINE_STREAM_VM);
-  Dart_Handle lib;
-  {
-    // Add something to the VM stream.
-    TimelineDurationScope tds(Timeline::GetVMStream(), "TestVMDuration");
-    lib = TestCase::LoadTestScript(kScriptChars, NULL);
-  }
-
-  // Invoke main, which will be compiled resulting in a compiler event in
-  // the timeline.
-  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
-
-  const char* buffer = NULL;
-  intptr_t buffer_length = 0;
-
-  // Run Dart_GlobalTimelineGetTrace on a fresh thread.
-  GlobalTimelineThreadData data;
-  int err = OSThread::Start("Timeline test thread", GlobalTimelineThread,
-                            reinterpret_cast<uword>(&data));
-  EXPECT(err == 0);
-  {
-    MonitorLocker ml(data.monitor());
-    while (data.running()) {
-      ml.Wait();
-    }
-    buffer = reinterpret_cast<char*>(data.buffer());
-    buffer_length = data.buffer_length();
-  }
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test.
-  EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-  EXPECT_NOTSUBSTRING("\"function\":\"::_bar\"", buffer);
-
-  // Retrieving the global trace resulted in all open blocks being reclaimed.
-  // Add some new events and verify that both sets of events are present
-  // in the resulting trace.
-  {
-    // Add something to the VM stream.
-    TimelineDurationScope tds(Timeline::GetVMStream(), "TestVMDuration2");
-    // Invoke bar, which will be compiled resulting in a compiler event in
-    // the timeline.
-    result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
-  }
-
-  // Grab the global trace.
-  GlobalTimelineThreadData data2;
-  err = OSThread::Start("Timeline test thread", GlobalTimelineThread,
-                        reinterpret_cast<uword>(&data2));
-  EXPECT(err == 0);
-  {
-    MonitorLocker ml(data2.monitor());
-    while (data2.running()) {
-      ml.Wait();
-    }
-    buffer = reinterpret_cast<char*>(data2.buffer());
-    buffer_length = data2.buffer_length();
-  }
-
-  EXPECT(buffer_length > 0);
-  EXPECT(buffer != NULL);
-  // Response starts with a '{' character and not a '['.
-  EXPECT(buffer[0] == '{');
-  // Response ends with a '}' character and not a ']'.
-  EXPECT(buffer[buffer_length - 1] == '\0');
-  EXPECT(buffer[buffer_length - 2] == '}');
-
-  // Heartbeat test for old events.
-  EXPECT_SUBSTRING("\"name\":\"TestVMDuration\"", buffer);
-  EXPECT_SUBSTRING("\"cat\":\"Compiler\"", buffer);
-  EXPECT_SUBSTRING("\"name\":\"CompileFunction\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_main\"", buffer);
-
-  // Heartbeat test for new events.
-  EXPECT_SUBSTRING("\"name\":\"TestVMDuration2\"", buffer);
-  EXPECT_SUBSTRING("\"function\":\"::_bar\"", buffer);
-}
-
-static bool start_called = false;
-static bool stop_called = false;
-
-static void StartRecording() {
-  start_called = true;
-}
-
-static void StopRecording() {
-  stop_called = true;
-}
-
-TEST_CASE(DartAPI_EmbedderTimelineStartStopRecording) {
-  Dart_SetEmbedderTimelineCallbacks(StartRecording, StopRecording);
-
-  EXPECT(!start_called);
-  EXPECT(!stop_called);
-  Timeline::SetStreamEmbedderEnabled(true);
-  EXPECT(start_called);
-  EXPECT(!stop_called);
-
-  start_called = false;
-  stop_called = false;
-  EXPECT(!start_called);
-  EXPECT(!stop_called);
-  Timeline::SetStreamEmbedderEnabled(false);
-  EXPECT(!start_called);
-  EXPECT(stop_called);
-}
-
 void NotifyIdleShortNative(Dart_NativeArguments args) {
   Dart_NotifyIdle(Dart_TimelineGetMicros() + 10 * kMicrosecondsPerMillisecond);
 }
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 1153d2c..753a7c3 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -2789,17 +2789,11 @@
         if (!field.has_initializer()) {
           continue;
         }
-
-        bool has_func_literal_initializer = false;
-#ifndef DART_PRECOMPILED_RUNTIME
-        has_func_literal_initializer =
-            kernel::FieldHasFunctionLiteralInitializer(field, &start, &end);
-#endif  // !DART_PRECOMPILED_RUNTIME
-        if (has_func_literal_initializer) {
-          if ((start <= token_pos && token_pos <= end) ||
-              (token_pos <= start && start <= last_token_pos)) {
-            return true;
-          }
+        start = field.token_pos();
+        end = field.end_token_pos();
+        if ((start <= token_pos && token_pos <= end) ||
+            (token_pos <= start && start <= last_token_pos)) {
+          return true;
         }
       }
     }
@@ -3111,8 +3105,7 @@
   {
     Thread* thread = Thread::Current();
     DisableThreadInterruptsScope dtis(thread);
-    TimelineDurationScope tds(thread, Timeline::GetDebuggerStream(),
-                              "Debugger Pause");
+    TIMELINE_DURATION(thread, Debugger, "Debugger Pause");
 
     // Send the pause event.
     Service::HandleEvent(event);
@@ -3174,19 +3167,27 @@
   }
 }
 
-void Debugger::SetAsyncSteppingFramePointer() {
+void Debugger::SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace) {
   if (!FLAG_async_debugger) {
     return;
   }
-  if ((stack_trace_->Length()) > 0 &&
-      (stack_trace_->FrameAt(0)->function().IsAsyncClosure() ||
-       stack_trace_->FrameAt(0)->function().IsAsyncGenClosure())) {
-    async_stepping_fp_ = stack_trace_->FrameAt(0)->fp();
+  if ((stack_trace->Length()) > 0 &&
+      (stack_trace->FrameAt(0)->function().IsAsyncClosure() ||
+       stack_trace->FrameAt(0)->function().IsAsyncGenClosure())) {
+    async_stepping_fp_ = stack_trace->FrameAt(0)->fp();
   } else {
     async_stepping_fp_ = 0;
   }
 }
 
+void Debugger::SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace) {
+  if (stack_trace->Length() > 0) {
+    stepping_fp_ = stack_trace->FrameAt(0)->fp();
+  } else {
+    stepping_fp_ = 0;
+  }
+}
+
 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
                                      bool skip_next_step) {
   ResetSteppingFramePointers();
@@ -3200,7 +3201,7 @@
     DeoptimizeWorld();
     isolate_->set_single_step(true);
     skip_next_step_ = skip_next_step;
-    SetAsyncSteppingFramePointer();
+    SetAsyncSteppingFramePointer(stack_trace);
     if (FLAG_verbose_debug) {
       OS::PrintErr("HandleSteppingRequest- kStepInto\n");
     }
@@ -3208,9 +3209,8 @@
     DeoptimizeWorld();
     isolate_->set_single_step(true);
     skip_next_step_ = skip_next_step;
-    ASSERT(stack_trace->Length() > 0);
-    stepping_fp_ = stack_trace->FrameAt(0)->fp();
-    SetAsyncSteppingFramePointer();
+    SetSyncSteppingFramePointer(stack_trace);
+    SetAsyncSteppingFramePointer(stack_trace);
     if (FLAG_verbose_debug) {
       OS::PrintErr("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
     }
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 3e1a0c0..759a180 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -720,7 +720,8 @@
   bool SteppedForSyntheticAsyncBreakpoint() const;
   void CleanupSyntheticAsyncBreakpoint();
   void RememberTopFrameAwaiter();
-  void SetAsyncSteppingFramePointer();
+  void SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
+  void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
 
   Isolate* isolate_;
 
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 0f499e1..0a48371 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -155,8 +155,9 @@
   delete[] deferred_objects_;
   deferred_objects_ = NULL;
   deferred_objects_count_ = 0;
-#ifndef PRODUCT
-  if (FLAG_support_timeline && (deopt_start_micros_ != 0)) {
+
+#if defined(SUPPORT_TIMELINE)
+  if (deopt_start_micros_ != 0) {
     TimelineStream* compiler_stream = Timeline::GetCompilerStream();
     ASSERT(compiler_stream != NULL);
     if (compiler_stream->enabled()) {
@@ -1056,12 +1057,12 @@
       materializations_() {}
 
 intptr_t DeoptInfoBuilder::FindOrAddObjectInTable(const Object& obj) const {
-  return assembler_->object_pool_wrapper().FindObject(obj);
+  return assembler_->object_pool_builder().FindObject(obj);
 }
 
 intptr_t DeoptInfoBuilder::CalculateStackIndex(
     const Location& source_loc) const {
-  intptr_t index = -compiler_frame_layout.VariableIndexForFrameSlot(
+  intptr_t index = -compiler::target::frame_layout.VariableIndexForFrameSlot(
       source_loc.stack_index());
   return index < 0 ? index + num_args_
                    : index + num_args_ + kDartFrameFixedSize;
diff --git a/runtime/vm/ffi_trampoline_stubs_x64.cc b/runtime/vm/ffi_trampoline_stubs_x64.cc
new file mode 100644
index 0000000..9374f61
--- /dev/null
+++ b/runtime/vm/ffi_trampoline_stubs_x64.cc
@@ -0,0 +1,564 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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(dacoharkes): Move this into compiler namespace.
+
+#include "vm/globals.h"
+
+#include "vm/stub_code.h"
+
+#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
+
+#include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/assembler/disassembler.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/jit/compiler.h"
+#include "vm/constants_x64.h"
+#include "vm/dart_entry.h"
+#include "vm/heap/heap.h"
+#include "vm/heap/scavenger.h"
+#include "vm/instructions.h"
+#include "vm/object_store.h"
+#include "vm/resolver.h"
+#include "vm/stack_frame.h"
+#include "vm/tags.h"
+#include "vm/type_testing_stubs.h"
+
+#define __ assembler->
+
+namespace dart {
+
+static Representation TypeRepresentation(const AbstractType& result_type) {
+  switch (result_type.type_class_id()) {
+    case kFfiFloatCid:
+    case kFfiDoubleCid:
+      return kUnboxedDouble;
+    case kFfiInt8Cid:
+    case kFfiInt16Cid:
+    case kFfiInt32Cid:
+    case kFfiInt64Cid:
+    case kFfiUint8Cid:
+    case kFfiUint16Cid:
+    case kFfiUint32Cid:
+    case kFfiUint64Cid:
+    case kFfiIntPtrCid:
+    case kFfiPointerCid:
+    default:  // Subtypes of Pointer.
+      return kUnboxedInt64;
+  }
+}
+
+// Converts a Ffi [signature] to a list of Representations.
+// Note that this ignores first argument (receiver) which is dynamic.
+static ZoneGrowableArray<Representation>* ArgumentRepresentations(
+    const Function& signature) {
+  intptr_t num_arguments = signature.num_fixed_parameters() - 1;
+  auto result = new ZoneGrowableArray<Representation>(num_arguments);
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    AbstractType& arg_type =
+        AbstractType::Handle(signature.ParameterTypeAt(i + 1));
+    result->Add(TypeRepresentation(arg_type));
+  }
+  return result;
+}
+
+// Takes a list of argument representations, and converts it to a list of
+// argument locations based on calling convention.
+static ZoneGrowableArray<Location>* ArgumentLocations(
+    const ZoneGrowableArray<Representation>& arg_representations) {
+  intptr_t num_arguments = arg_representations.length();
+  auto result = new ZoneGrowableArray<Location>(num_arguments);
+  result->FillWith(Location(), 0, num_arguments);
+  Location* data = result->data();
+
+  // Loop through all arguments and assign a register or a stack location.
+  intptr_t int_regs_used = 0;
+  intptr_t xmm_regs_used = 0;
+  intptr_t nth_stack_argument = 0;
+  bool on_stack;
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    on_stack = true;
+    switch (arg_representations.At(i)) {
+      case kUnboxedInt64:
+        if (int_regs_used < CallingConventions::kNumArgRegs) {
+          data[i] = Location::RegisterLocation(
+              CallingConventions::ArgumentRegisters[int_regs_used]);
+          int_regs_used++;
+          if (CallingConventions::kArgumentIntRegXorXmmReg) {
+            xmm_regs_used++;
+          }
+          on_stack = false;
+        }
+        break;
+      case kUnboxedDouble:
+        if (xmm_regs_used < CallingConventions::kNumXmmArgRegs) {
+          data[i] = Location::FpuRegisterLocation(
+              CallingConventions::XmmArgumentRegisters[xmm_regs_used]);
+          xmm_regs_used++;
+          if (CallingConventions::kArgumentIntRegXorXmmReg) {
+            int_regs_used++;
+          }
+          on_stack = false;
+        }
+        break;
+      default:
+        UNREACHABLE();
+    }
+    if (on_stack) {
+      data[i] = Location::StackSlot(nth_stack_argument, RSP);
+      nth_stack_argument++;
+    }
+  }
+  return result;
+}
+
+static intptr_t NumStackArguments(
+    const ZoneGrowableArray<Location>& locations) {
+  intptr_t num_arguments = locations.length();
+  intptr_t num_stack_arguments = 0;
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    if (locations.At(i).IsStackSlot()) {
+      num_stack_arguments++;
+    }
+  }
+  return num_stack_arguments;
+}
+
+// Input parameters:
+//   Register reg : a Null, or something else
+static void GenerateNotNullCheck(Assembler* assembler, Register reg) {
+  Label not_null;
+  Address throw_null_pointer_address =
+      Address(THR, Thread::OffsetFromThread(&kArgumentNullErrorRuntimeEntry));
+
+  __ CompareObject(reg, Object::null_object());
+  __ j(NOT_EQUAL, &not_null, Assembler::kNearJump);
+
+  // TODO(dacoharkes): Create the message here and use
+  // kArgumentErrorRuntimeEntry to report which argument was null.
+  __ movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
+  __ movq(RBX, throw_null_pointer_address);
+  __ movq(R10, Immediate(0));
+  __ call(Address(THR, Thread::call_to_runtime_entry_point_offset()));
+
+  __ Bind(&not_null);
+}
+
+// Saves an int64 in the thread so GC does not trip.
+//
+// Input parameters:
+//   Register src : a C int64
+static void GenerateSaveInt64GCSafe(Assembler* assembler, Register src) {
+  __ movq(Address(THR, Thread::unboxed_int64_runtime_arg_offset()), src);
+}
+
+// Loads an int64 from the thread.
+static void GenerateLoadInt64GCSafe(Assembler* assembler, Register dst) {
+  __ movq(dst, Address(THR, Thread::unboxed_int64_runtime_arg_offset()));
+}
+
+// Takes a Dart int and converts it to a C int64.
+//
+// Input parameters:
+//   Register reg : a Dart Null, Smi, or Mint
+// Output parameters:
+//   Register reg : a C int64
+// Invariant: keeps ArgumentRegisters and XmmArgumentRegisters intact
+void GenerateMarshalInt64(Assembler* assembler, Register reg) {
+  ASSERT(reg != TMP);
+  ASSERT((1 << TMP & CallingConventions::kArgumentRegisters) == 0);
+  Label done, not_smi;
+
+  // Exception on Null
+  GenerateNotNullCheck(assembler, reg);
+
+  // Smi or Mint?
+  __ movq(TMP, reg);
+  __ testq(TMP, Immediate(kSmiTagMask));
+  __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
+
+  // Smi
+  __ SmiUntag(reg);
+  __ jmp(&done, Assembler::kNearJump);
+
+  // Mint
+  __ Bind(&not_smi);
+  __ movq(reg, FieldAddress(reg, Mint::value_offset()));
+  __ Bind(&done);
+}
+
+// Takes a C int64 and converts it to a Dart int.
+//
+// Input parameters:
+//   RAX : a C int64
+// Output paramaters:
+//   RAX : a Dart Smi or Mint
+static void GenerateUnmarshalInt64(Assembler* assembler) {
+  const Class& mint_class =
+      Class::ZoneHandle(Isolate::Current()->object_store()->mint_class());
+  ASSERT(!mint_class.IsNull());
+  const auto& mint_allocation_stub =
+      Code::ZoneHandle(StubCode::GetAllocationStubForClass(mint_class));
+  ASSERT(!mint_allocation_stub.IsNull());
+  Label done;
+
+  // Try whether it fits in a Smi.
+  __ movq(TMP, RAX);
+  __ SmiTag(RAX);
+  __ j(NO_OVERFLOW, &done, Assembler::kNearJump);
+
+  // Mint
+  // Backup result value (to avoid GC).
+  GenerateSaveInt64GCSafe(assembler, TMP);
+
+  // Allocate object (can call into runtime).
+  __ Call(mint_allocation_stub);
+
+  // Store result value.
+  GenerateLoadInt64GCSafe(assembler, TMP);
+  __ movq(FieldAddress(RAX, Mint::value_offset()), TMP);
+
+  __ Bind(&done);
+}
+
+// Takes a Dart double and converts it into a C double.
+//
+// Input parameters:
+//   Register reg : a Dart Null or Double
+// Output parameters:
+//   XmmRegister xmm_reg : a C double
+// Invariant: keeps ArgumentRegisters and other XmmArgumentRegisters intact
+static void GenerateMarshalDouble(Assembler* assembler,
+                                  Register reg,
+                                  XmmRegister xmm_reg) {
+  ASSERT((1 << reg & CallingConventions::kArgumentRegisters) == 0);
+
+  // Throw a Dart Exception on Null.
+  GenerateNotNullCheck(assembler, reg);
+
+  __ movq(reg, FieldAddress(reg, Double::value_offset()));
+  __ movq(xmm_reg, reg);
+}
+
+// Takes a C double and converts it into a Dart double.
+//
+// Input parameters:
+//   XMM0 : a C double
+// Output parameters:
+//   RAX : a Dart Double
+static void GenerateUnmarshalDouble(Assembler* assembler) {
+  const auto& double_class =
+      Class::ZoneHandle(Isolate::Current()->object_store()->double_class());
+  ASSERT(!double_class.IsNull());
+  const auto& double_allocation_stub =
+      Code::ZoneHandle(StubCode::GetAllocationStubForClass(double_class));
+  ASSERT(!double_allocation_stub.IsNull());
+
+  // Backup result value (to avoid GC).
+  __ movq(RAX, XMM0);
+  GenerateSaveInt64GCSafe(assembler, RAX);
+
+  // Allocate object (can call into runtime).
+  __ Call(double_allocation_stub);
+
+  // Store the result value.
+  GenerateLoadInt64GCSafe(assembler, TMP);
+  __ movq(FieldAddress(RAX, Double::value_offset()), TMP);
+}
+
+// Takes a Dart double and converts into a C float.
+//
+// Input parameters:
+//   Register reg : a Dart double
+// Output parameters:
+//   XmmRegister xxmReg : a C float
+// Invariant: keeps ArgumentRegisters and other XmmArgumentRegisters intact
+static void GenerateMarshalFloat(Assembler* assembler,
+                                 Register reg,
+                                 XmmRegister xmm_reg) {
+  ASSERT((1 << reg & CallingConventions::kArgumentRegisters) == 0);
+
+  GenerateMarshalDouble(assembler, reg, xmm_reg);
+
+  __ cvtsd2ss(xmm_reg, xmm_reg);
+}
+
+// Takes a C float and converts it into a Dart double.
+//
+// Input parameters:
+//   XMM0 : a C float
+// Output paramaters:
+//   RAX : a Dart Double
+static void GenerateUnmarshalFloat(Assembler* assembler) {
+  __ cvtss2sd(XMM0, XMM0);
+  GenerateUnmarshalDouble(assembler);
+}
+
+// Takes a Dart ffi.Pointer and converts it into a C pointer.
+//
+// Input parameters:
+//   Register reg : a Dart ffi.Pointer or Null
+// Output parameters:
+//   Register reg : a C pointer
+static void GenerateMarshalPointer(Assembler* assembler, Register reg) {
+  Label done, not_null;
+
+  __ CompareObject(reg, Object::null_object());
+  __ j(NOT_EQUAL, &not_null, Assembler::kNearJump);
+
+  // If null, the address is 0.
+  __ movq(reg, Immediate(0));
+  __ jmp(&done);
+
+  // If not null but a Pointer, load the address.
+  __ Bind(&not_null);
+  __ movq(reg, FieldAddress(reg, Pointer::address_offset()));
+  __ Bind(&done);
+}
+
+// Takes a C pointer and converts it into a Dart ffi.Pointer or Null.
+//
+// Input parameters:
+//   RAX : a C pointer
+// Outpot paramaters:
+//   RAX : a Dart ffi.Pointer or Null
+static void GenerateUnmarshalPointer(Assembler* assembler,
+                                     Address closure_dart,
+                                     const Class& pointer_class) {
+  Label done, not_null;
+  ASSERT(!pointer_class.IsNull());
+  const auto& pointer_allocation_stub =
+      Code::ZoneHandle(StubCode::GetAllocationStubForClass(pointer_class));
+  ASSERT(!pointer_allocation_stub.IsNull());
+
+  // If the address is 0, return a Dart Null.
+  __ cmpq(RAX, Immediate(0));
+  __ j(NOT_EQUAL, &not_null, Assembler::kNearJump);
+  __ LoadObject(RAX, Object::null_object());
+  __ jmp(&done);
+
+  // Backup result value (to avoid GC).
+  __ Bind(&not_null);
+  GenerateSaveInt64GCSafe(assembler, RAX);
+
+  // Allocate object (can call into runtime).
+  __ movq(TMP, closure_dart);
+  __ movq(TMP, FieldAddress(TMP, Closure::function_offset()));
+  __ movq(TMP, FieldAddress(TMP, Function::result_type_offset()));
+  __ pushq(FieldAddress(TMP, Type::arguments_offset()));
+  __ Call(pointer_allocation_stub);
+  __ popq(TMP);  // Pop type arguments.
+
+  // Store the result value.
+  GenerateLoadInt64GCSafe(assembler, RDX);
+  __ movq(FieldAddress(RAX, Pointer::address_offset()), RDX);
+  __ Bind(&done);
+}
+
+static void GenerateMarshalArgument(Assembler* assembler,
+                                    const AbstractType& arg_type,
+                                    Register reg,
+                                    XmmRegister xmm_reg) {
+  switch (arg_type.type_class_id()) {
+    case kFfiInt8Cid:
+    case kFfiInt16Cid:
+    case kFfiInt32Cid:
+    case kFfiInt64Cid:
+    case kFfiUint8Cid:
+    case kFfiUint16Cid:
+    case kFfiUint32Cid:
+    case kFfiUint64Cid:
+    case kFfiIntPtrCid:
+      // TODO(dacoharkes): Truncate and sign extend 8 bit and 16 bit, and write
+      // tests. https://github.com/dart-lang/sdk/issues/35787
+      GenerateMarshalInt64(assembler, reg);
+      return;
+    case kFfiFloatCid:
+      GenerateMarshalFloat(assembler, reg, xmm_reg);
+      return;
+    case kFfiDoubleCid:
+      GenerateMarshalDouble(assembler, reg, xmm_reg);
+      return;
+    case kFfiPointerCid:
+    default:  // Subtypes of Pointer.
+      GenerateMarshalPointer(assembler, reg);
+      return;
+  }
+}
+
+static void GenerateUnmarshalResult(Assembler* assembler,
+                                    const AbstractType& result_type,
+                                    Address closure_dart) {
+  switch (result_type.type_class_id()) {
+    case kFfiInt8Cid:
+    case kFfiInt16Cid:
+    case kFfiInt32Cid:
+    case kFfiInt64Cid:
+    case kFfiUint8Cid:
+    case kFfiUint16Cid:
+    case kFfiUint32Cid:
+    case kFfiUint64Cid:
+    case kFfiIntPtrCid:
+      GenerateUnmarshalInt64(assembler);
+      return;
+    case kFfiFloatCid:
+      GenerateUnmarshalFloat(assembler);
+      return;
+    case kFfiDoubleCid:
+      GenerateUnmarshalDouble(assembler);
+      return;
+    case kFfiPointerCid:
+    default:  // subtypes of Pointer
+      break;
+  }
+  Class& cls = Class::ZoneHandle(Thread::Current()->zone(),
+                                 Type::Cast(result_type).type_class());
+
+  GenerateUnmarshalPointer(assembler, closure_dart, cls);
+}
+
+// Generates a assembly for dart:ffi trampolines:
+// - marshal arguments
+// - put the arguments in registers and on the c stack
+// - invoke the c function
+// - (c result register is the same as dart, so keep in place)
+// - unmarshal c result
+// - return
+//
+// Input parameters:
+//   RSP + kWordSize *  num_arguments      : closure.
+//   RSP + kWordSize * (num_arguments - 1) : arg 1.
+//   RSP + kWordSize * (num_arguments - 2) : arg 2.
+//   RSP + kWordSize                       : arg n.
+// After entering stub:
+//   RBP = RSP (before stub) - kWordSize
+//   RBP + kWordSize * (num_arguments + 1) : closure.
+//   RBP + kWordSize *  num_arguments      : arg 1.
+//   RBP + kWordSize * (num_arguments - 1) : arg 2.
+//   RBP + kWordSize *  2                  : arg n.
+//
+// TODO(dacoharkes): Test truncation on non 64 bits ints and floats.
+void GenerateFfiTrampoline(Assembler* assembler, const Function& signature) {
+  ZoneGrowableArray<Representation>* arg_representations =
+      ArgumentRepresentations(signature);
+  ZoneGrowableArray<Location>* arg_locations =
+      ArgumentLocations(*arg_representations);
+
+  intptr_t num_dart_arguments = signature.num_fixed_parameters();
+  intptr_t num_arguments = num_dart_arguments - 1;  // ignore closure
+
+  __ EnterStubFrame();
+
+  // Save exit frame information to enable stack walking as we are about
+  // to transition to Dart VM C++ code.
+  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
+
+#if defined(DEBUG)
+  {
+    Label ok;
+    // Check that we are always entering from Dart code.
+    __ movq(TMP, Immediate(VMTag::kDartCompiledTagId));
+    __ cmpq(TMP, Assembler::VMTagAddress());
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Not coming from Dart code.");
+    __ Bind(&ok);
+  }
+#endif
+
+  // Reserve space for arguments and align frame before entering C++ world.
+  __ subq(RSP, Immediate(NumStackArguments(*arg_locations) * kWordSize));
+  if (OS::ActivationFrameAlignment() > 1) {
+    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
+  }
+
+  // Prepare address for calling the C function.
+  Address closure_dart = Address(RBP, (num_dart_arguments + 1) * kWordSize);
+  __ movq(RBX, closure_dart);
+  __ movq(RBX, FieldAddress(RBX, Closure::context_offset()));
+  __ movq(RBX, FieldAddress(RBX, Context::variable_offset(0)));
+  GenerateMarshalInt64(assembler, RBX);  // Address is a Smi or Mint.
+
+  // Marshal arguments and store in the right register.
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    Representation rep = arg_representations->At(i);
+    Location loc = arg_locations->At(i);
+
+    // We do marshalling in the the target register or in RAX.
+    Register reg = loc.IsRegister() ? loc.reg() : RAX;
+    // For doubles and floats we use target xmm register or first non param reg.
+    FpuRegister xmm_reg = loc.IsFpuRegister()
+                              ? loc.fpu_reg()
+                              : CallingConventions::xmmFirstNonParameterReg;
+
+    // Load parameter from Dart stack.
+    __ movq(reg, Address(RBP, (num_arguments + 1 - i) * kWordSize));
+
+    // Marshal argument.
+    AbstractType& arg_type =
+        AbstractType::Handle(signature.ParameterTypeAt(i + 1));
+    GenerateMarshalArgument(assembler, arg_type, reg, xmm_reg);
+
+    // Store marshalled argument where c expects value.
+    if (loc.IsStackSlot()) {
+      if (rep == kUnboxedDouble) {
+        __ movq(reg, xmm_reg);
+      }
+      __ movq(loc.ToStackSlotAddress(), reg);
+    }
+  }
+
+  // Mark that the thread is executing VM code.
+  __ movq(Assembler::VMTagAddress(), RBX);
+
+  __ CallCFunction(RBX);
+
+  // Mark that the thread is executing Dart code.
+  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
+
+  // Unmarshal result.
+  AbstractType& return_type = AbstractType::Handle(signature.result_type());
+  GenerateUnmarshalResult(assembler, return_type, closure_dart);
+
+  // Reset exit frame information in Isolate structure.
+  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
+
+  __ LeaveStubFrame();
+
+  __ ret();
+}
+
+void GenerateFfiInverseTrampoline(Assembler* assembler,
+                                  const Function& signature,
+                                  void* dart_entry_point) {
+  ZoneGrowableArray<Representation>* arg_representations =
+      ArgumentRepresentations(signature);
+  ZoneGrowableArray<Location>* arg_locations =
+      ArgumentLocations(*arg_representations);
+
+  intptr_t num_dart_arguments = signature.num_fixed_parameters();
+  intptr_t num_arguments = num_dart_arguments - 1;  // Ignore closure.
+
+  // TODO(dacoharkes): Implement this.
+  // https://github.com/dart-lang/sdk/issues/35761
+  // Look at StubCode::GenerateInvokeDartCodeStub.
+
+  __ int3();
+
+  for (intptr_t i = 0; i < num_arguments; i++) {
+    Register reg = arg_locations->At(i).reg();
+    __ SmiTag(reg);
+  }
+
+  __ movq(RBX, Immediate(reinterpret_cast<intptr_t>(dart_entry_point)));
+
+  __ int3();
+
+  __ call(RBX);
+
+  __ int3();
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index d11e203..edd0226 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -92,11 +92,11 @@
     "Compile expressions with the Kernel front-end.")                          \
   P(enable_mirrors, bool, true,                                                \
     "Disable to make importing dart:mirrors an error.")                        \
+  P(enable_ffi, bool, true, "Disable to make importing dart:ffi an error.")    \
   P(fields_may_be_reset, bool, false,                                          \
     "Don't optimize away static field initialization")                         \
   C(force_clone_compiler_objects, false, false, bool, false,                   \
     "Force cloning of objects needed in compiler (ICData and Field).")         \
-  R(gc_at_alloc, false, bool, false, "GC at every allocation.")                \
   P(getter_setter_ratio, int, 13,                                              \
     "Ratio of getter/setter usage used for double field unboxing heuristics")  \
   P(guess_icdata_cid, bool, true,                                              \
@@ -127,6 +127,8 @@
     "Initial size of new gen semi space in MB")                                \
   P(optimization_counter_threshold, int, 30000,                                \
     "Function's usage-counter value before it is optimized, -1 means never")   \
+  P(optimization_level, int, 2,                                                \
+    "Optimization level: 1 (favor size), 2 (default), 3 (favor speed)")        \
   P(old_gen_heap_size, int, kDefaultMaxOldGenHeapSize,                         \
     "Max size of old gen heap size in MB, or 0 for unlimited,"                 \
     "e.g: --old_gen_heap_size=1024 allows up to 1024MB old gen heap")          \
@@ -147,7 +149,6 @@
     "Print live ranges after allocation.")                                     \
   R(print_stacktrace_at_api_error, false, bool, false,                         \
     "Attempt to print a native stack trace when an API error is created.")     \
-  C(print_stop_message, false, false, bool, false, "Print stop message.")      \
   D(print_variable_descriptors, bool, false,                                   \
     "Print variable descriptors in disassembly.")                              \
   R(profiler, false, bool, false, "Enable the profiler.")                      \
@@ -156,12 +157,11 @@
   P(reorder_basic_blocks, bool, true, "Reorder basic blocks")                  \
   C(stress_async_stacks, false, false, bool, false,                            \
     "Stress test async stack traces")                                          \
-  P(use_bare_instructions, bool, false, "Enable bare instructions mode.")      \
+  P(use_bare_instructions, bool, true, "Enable bare instructions mode.")       \
   R(support_disassembler, false, bool, true, "Support the disassembler.")      \
   R(support_il_printer, false, bool, true, "Support the IL printer.")          \
   C(support_reload, false, false, bool, true, "Support isolate reload.")       \
   R(support_service, false, bool, true, "Support the service protocol.")       \
-  R(support_timeline, false, bool, true, "Support timeline.")                  \
   D(trace_cha, bool, false, "Trace CHA operations")                            \
   R(trace_field_guards, false, bool, false, "Trace changes in field's cids.")  \
   D(trace_ic, bool, false, "Trace IC handling")                                \
@@ -215,6 +215,19 @@
   R(eliminate_type_checks, true, bool, true,                                   \
     "Eliminate type checks when allowed by static type analysis.")             \
   P(enable_interpreter, bool, false, "Enable interpreting kernel bytecode.")   \
-  D(support_rr, bool, false, "Support running within RR.")
+  D(support_rr, bool, false, "Support running within RR.")                     \
+  P(verify_entry_points, bool, false,                                          \
+    "Throw API error on invalid member access throuh native API. See "         \
+    "entry_point_pragma.md")
+
+// List of VM-global (i.e. non-isolate specific) flags.
+//
+// The value used for those flags at snapshot generation time needs to be the
+// same as during runtime.
+//
+// Usage:
+//   P(name, command-line-flag-name)
+#define VM_GLOBAL_FLAG_LIST(V)                                                 \
+  V(use_bare_instructions, FLAG_use_bare_instructions)
 
 #endif  // RUNTIME_VM_FLAG_LIST_H_
diff --git a/runtime/vm/frame_layout.h b/runtime/vm/frame_layout.h
new file mode 100644
index 0000000..53ddcc7
--- /dev/null
+++ b/runtime/vm/frame_layout.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_FRAME_LAYOUT_H_
+#define RUNTIME_VM_FRAME_LAYOUT_H_
+
+// FrameLayout structure captures configuration specific properties of the
+// frame layout used by the runtime system and compiler.
+//
+// Runtime system uses runtime_frame_layout defined in stack_frame.h.
+// Compiler uses compiler::target::frame_layout defined in runtime_api.h
+
+namespace dart {
+
+// Forward declarations.
+class LocalVariable;
+
+struct FrameLayout {
+  // The offset (in words) from FP to the first object.
+  int first_object_from_fp;
+
+  // The offset (in words) from FP to the last fixed object.
+  int last_fixed_object_from_fp;
+
+  // The offset (in words) from FP to the first local.
+  int param_end_from_fp;
+
+  // The offset (in words) from FP to the first local.
+  int first_local_from_fp;
+
+  // The fixed size of the frame.
+  int dart_fixed_frame_size;
+
+  // The offset (in words) from FP to the saved pool (if applicable).
+  int saved_caller_pp_from_fp;
+
+  // The offset (in words) from FP to the code object (if applicable).
+  int code_from_fp;
+
+  // Entry and exit frame layout.
+  int exit_link_slot_from_entry_fp;
+
+  // The number of fixed slots below the saved PC.
+  int saved_below_pc() const { return -first_local_from_fp; }
+
+  // Returns the FP-relative index where [variable] can be found (assumes
+  // [variable] is not captured), in words.
+  int FrameSlotForVariable(const LocalVariable* variable) const;
+
+  // Returns the FP-relative index where [variable_index] can be found (assumes
+  // [variable_index] comes from a [LocalVariable::index()], which is not
+  // captured).
+  int FrameSlotForVariableIndex(int index) const;
+
+  // Returns the variable index from a FP-relative index.
+  intptr_t VariableIndexForFrameSlot(intptr_t frame_slot) const {
+    if (frame_slot <= first_local_from_fp) {
+      return frame_slot - first_local_from_fp;
+    } else {
+      ASSERT(frame_slot > param_end_from_fp);
+      return frame_slot - param_end_from_fp;
+    }
+  }
+
+  // Called to initialize the stack frame layout during startup.
+  static void Init();
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_FRAME_LAYOUT_H_
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index a261211..ad33a42 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -73,16 +73,12 @@
 #define NOT_IN_PRECOMPILED(code) code
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-#if defined(ARCH_IS_64_BIT)
-#define HASH_IN_OBJECT_HEADER 1
+#if !defined(PRODUCT) || defined(HOST_OS_FUCHSIA) || defined(TARGET_OS_FUCHSIA)
+#define SUPPORT_TIMELINE 1
 #endif
 
-// For checking deterministic graph generation, we can store instruction
-// tag in the ICData and check it when recreating the flow graph in
-// optimizing compiler. Enable it for other modes (product, release) if needed
-// for debugging.
-#if defined(DEBUG)
-#define TAG_IC_DATA
+#if defined(ARCH_IS_64_BIT)
+#define HASH_IN_OBJECT_HEADER 1
 #endif
 
 // The expression OFFSET_OF(type, field) computes the byte-offset of
diff --git a/runtime/vm/handle_visitor.h b/runtime/vm/handle_visitor.h
new file mode 100644
index 0000000..8e8a2a1
--- /dev/null
+++ b/runtime/vm/handle_visitor.h
@@ -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.
+
+#ifndef RUNTIME_VM_HANDLE_VISITOR_H_
+#define RUNTIME_VM_HANDLE_VISITOR_H_
+
+#include "vm/allocation.h"
+#include "vm/flags.h"
+#include "vm/os.h"
+
+namespace dart {
+
+class Thread;
+
+class HandleVisitor {
+ public:
+  explicit HandleVisitor(Thread* thread) : thread_(thread) {}
+  virtual ~HandleVisitor() {}
+
+  Thread* thread() const { return thread_; }
+
+  virtual void VisitHandle(uword addr) = 0;
+
+ private:
+  Thread* thread_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(HandleVisitor);
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_HANDLE_VISITOR_H_
diff --git a/runtime/vm/handles.cc b/runtime/vm/handles.cc
index 3c429ef..b276a08 100644
--- a/runtime/vm/handles.cc
+++ b/runtime/vm/handles.cc
@@ -84,7 +84,7 @@
 #endif
 }
 
-HandleScope::HandleScope(Thread* thread) : ThreadStackResource(thread) {
+HandleScope::HandleScope(ThreadState* thread) : StackResource(thread) {
   Initialize();
 }
 
diff --git a/runtime/vm/handles.h b/runtime/vm/handles.h
index 522aa02..2b3de59 100644
--- a/runtime/vm/handles.h
+++ b/runtime/vm/handles.h
@@ -8,7 +8,6 @@
 #include "vm/allocation.h"
 #include "vm/flags.h"
 #include "vm/os.h"
-#include "vm/thread_stack_resource.h"
 
 namespace dart {
 
@@ -49,25 +48,10 @@
 
 // Forward declarations.
 class ObjectPointerVisitor;
-class Thread;
+class HandleVisitor;
 
 DECLARE_FLAG(bool, verify_handles);
 
-class HandleVisitor {
- public:
-  explicit HandleVisitor(Thread* thread) : thread_(thread) {}
-  virtual ~HandleVisitor() {}
-
-  Thread* thread() const { return thread_; }
-
-  virtual void VisitHandle(uword addr) = 0;
-
- private:
-  Thread* thread_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(HandleVisitor);
-};
-
 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr>
 class Handles {
  public:
@@ -108,7 +92,6 @@
   // Returns true if specified handle is a zone handle.
   static bool IsZoneHandle(uword handle);
 
- protected:
   // Allocates space for a scoped handle.
   uword AllocateScopedHandle() {
     if (scoped_blocks_->IsFull()) {
@@ -117,6 +100,7 @@
     return scoped_blocks_->AllocateHandle();
   }
 
+ protected:
   // Returns a count of active handles (used for testing purposes).
   int CountScopedHandles() const;
   int CountZoneHandles() const;
@@ -224,7 +208,7 @@
   friend class HandleScope;
   friend class Dart;
   friend class ObjectStore;
-  friend class Thread;
+  friend class ThreadState;
   DISALLOW_ALLOCATION();
   DISALLOW_COPY_AND_ASSIGN(Handles);
 };
@@ -279,9 +263,9 @@
 //   code that creates some scoped handles.
 //   ....
 // }
-class HandleScope : public ThreadStackResource {
+class HandleScope : public StackResource {
  public:
-  explicit HandleScope(Thread* thread);
+  explicit HandleScope(ThreadState* thread);
   ~HandleScope();
 
  private:
diff --git a/runtime/vm/heap/become.cc b/runtime/vm/heap/become.cc
index 74a72dd..1b1823a 100644
--- a/runtime/vm/heap/become.cc
+++ b/runtime/vm/heap/become.cc
@@ -60,7 +60,7 @@
 }
 
 static void ForwardObjectTo(RawObject* before_obj, RawObject* after_obj) {
-  const intptr_t size_before = before_obj->Size();
+  const intptr_t size_before = before_obj->HeapSize();
 
   uword corpse_addr = reinterpret_cast<uword>(before_obj) - kHeapObjectTag;
   ForwardingCorpse* forwarder =
@@ -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->Size();
+  const intptr_t size_after = before_obj->HeapSize();
   if (size_before != size_after) {
     FATAL("become: Before and after sizes do not match.");
   }
diff --git a/runtime/vm/heap/become.h b/runtime/vm/heap/become.h
index 20804ea..1b27798 100644
--- a/runtime/vm/heap/become.h
+++ b/runtime/vm/heap/become.h
@@ -25,7 +25,7 @@
   RawObject* target() const { return target_; }
   void set_target(RawObject* target) { target_ = target; }
 
-  intptr_t Size() {
+  intptr_t HeapSize() {
     intptr_t size = RawObject::SizeTag::decode(tags_);
     if (size != 0) return size;
     return *SizeAddress();
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 859174e..e3073a0 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -293,7 +293,9 @@
   bool result =
       Thread::EnterIsolateAsHelper(isolate_, Thread::kCompactorTask, true);
   ASSERT(result);
-  NOT_IN_PRODUCT(Thread* thread = Thread::Current());
+#ifdef SUPPORT_TIMELINE
+  Thread* thread = Thread::Current();
+#endif
   {
     {
       TIMELINE_FUNCTION_GC_DURATION(thread, "Plan");
@@ -423,7 +425,7 @@
   uword current = first_object;
   while (current < block_end) {
     RawObject* obj = RawObject::FromAddr(current);
-    intptr_t size = obj->Size();
+    intptr_t size = obj->HeapSize();
     if (obj->IsMarked()) {
       forwarding_block->RecordLive(current, size);
       ASSERT(static_cast<intptr_t>(forwarding_block->Lookup(current)) ==
@@ -453,7 +455,7 @@
   uword old_addr = first_object;
   while (old_addr < block_end) {
     RawObject* old_obj = RawObject::FromAddr(old_addr);
-    intptr_t size = old_obj->Size();
+    intptr_t size = old_obj->HeapSize();
     if (old_obj->IsMarked()) {
       uword new_addr = forwarding_block->Lookup(old_addr);
       if (new_addr != free_current_) {
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index a2012d5..cacb13e 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -97,7 +97,7 @@
         // the call to SplitElementAfterAndEnqueue.
         // If the remainder size is zero, only the element itself needs to
         // be made writable.
-        intptr_t remainder_size = element->Size() - size;
+        intptr_t remainder_size = element->HeapSize() - size;
         intptr_t region_size =
             size + FreeListElement::HeaderSizeFor(remainder_size);
         VirtualMemory::Protect(reinterpret_cast<void*>(element), region_size,
@@ -121,10 +121,10 @@
   // reset the search budget.
   intptr_t tries_left = freelist_search_budget_ + (size >> kWordSizeLog2);
   while (current != NULL) {
-    if (current->Size() >= size) {
+    if (current->HeapSize() >= size) {
       // Found an element large enough to hold the requested size. Dequeue,
       // split and enqueue the remainder.
-      intptr_t remainder_size = current->Size() - size;
+      intptr_t remainder_size = current->HeapSize() - size;
       intptr_t region_size =
           size + FreeListElement::HeaderSizeFor(remainder_size);
       if (is_protected) {
@@ -270,7 +270,7 @@
     OS::PrintErr(
         "small %3d [%8d bytes] : "
         "%8" Pd " objs; %8.1f KB; %8.1f cum KB\n",
-        i, i * kObjectAlignment, list_length,
+        i, static_cast<int>(i * kObjectAlignment), list_length,
         list_bytes / static_cast<double>(KB),
         small_bytes / static_cast<double>(KB));
   }
@@ -306,10 +306,10 @@
   MallocDirectChainedHashMap<NumbersKeyValueTrait<IntptrPair> > map;
   FreeListElement* node;
   for (node = free_lists_[kNumLists]; node != NULL; node = node->next()) {
-    IntptrPair* pair = map.Lookup(node->Size());
+    IntptrPair* pair = map.Lookup(node->HeapSize());
     if (pair == NULL) {
       large_sizes += 1;
-      map.Insert(IntptrPair(node->Size(), 1));
+      map.Insert(IntptrPair(node->HeapSize(), 1));
     } else {
       pair->set_second(pair->second() + 1);
     }
@@ -345,7 +345,7 @@
   // Precondition required by AsElement and EnqueueElement: either
   // element->Size() == size, or else the (page containing the) header of
   // the remainder element starting at element + size is writable.
-  intptr_t remainder_size = element->Size() - size;
+  intptr_t remainder_size = element->HeapSize() - size;
   if (remainder_size == 0) return;
 
   uword remainder_address = reinterpret_cast<uword>(element) + size;
@@ -379,7 +379,7 @@
       freelist_search_budget_ + (minimum_size >> kWordSizeLog2);
   while (current != NULL) {
     FreeListElement* next = current->next();
-    if (current->Size() >= minimum_size) {
+    if (current->HeapSize() >= minimum_size) {
       if (previous == NULL) {
         free_lists_[kNumLists] = next;
       } else {
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index 26f2c9b..552c7a2 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -27,7 +27,7 @@
 
   void set_next(FreeListElement* next) { next_ = next; }
 
-  intptr_t Size() {
+  intptr_t HeapSize() {
     intptr_t size = RawObject::SizeTag::decode(tags_);
     if (size != 0) return size;
     return *SizeAddress();
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index da5e831..b6b1960 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -71,7 +71,7 @@
   if (size >= kObjectAlignment) {
     // ForwardingCorpse(forwarding to default null) will work as filler.
     ForwardingCorpse::AsForwarder(start, size);
-    ASSERT(RawObject::FromAddr(start)->Size() == size);
+    ASSERT(RawObject::FromAddr(start)->HeapSize() == size);
   }
 }
 
@@ -81,11 +81,6 @@
   thread->set_end(0);
 }
 
-intptr_t Heap::CalculateTLABSize() {
-  intptr_t size = new_space_.end() - new_space_.top();
-  return Utils::RoundDown(size, kObjectAlignment);
-}
-
 uword Heap::AllocateNew(intptr_t size) {
   ASSERT(Thread::Current()->no_safepoint_scope_depth() == 0);
   // Currently, only the Dart thread may allocate in new space.
@@ -96,7 +91,7 @@
     return addr;
   }
 
-  intptr_t tlab_size = CalculateTLABSize();
+  intptr_t tlab_size = GetTLABSize();
   if ((tlab_size > 0) && (size > tlab_size)) {
     return AllocateOld(size, HeapPage::kData);
   }
@@ -106,8 +101,11 @@
     uword tlab_top = new_space_.TryAllocateNewTLAB(thread, tlab_size);
     if (tlab_top != 0) {
       addr = new_space_.TryAllocateInTLAB(thread, size);
-      ASSERT(addr != 0);
-      return addr;
+      if (addr != 0) {  // but "leftover" TLAB could end smaller than tlab_size
+        return addr;
+      }
+      // Abandon "leftover" TLAB as well so we can start from scratch.
+      AbandonRemainingTLAB(thread);
     }
   }
 
@@ -117,7 +115,7 @@
   // from a different thread and will be racing to allocate the requested
   // memory with other threads being released after the collection.
   CollectGarbage(kNew);
-  tlab_size = CalculateTLABSize();
+
   uword tlab_top = new_space_.TryAllocateNewTLAB(thread, tlab_size);
   if (tlab_top != 0) {
     addr = new_space_.TryAllocateInTLAB(thread, size);
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 6935bd1..7cdb876 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_HEAP_HEAP_H_
 #define RUNTIME_VM_HEAP_HEAP_H_
 
+#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
+#error "Should not include runtime"
+#endif
+
 #include "platform/assert.h"
 #include "vm/allocation.h"
 #include "vm/flags.h"
@@ -281,7 +285,12 @@
 
   static const intptr_t kNewAllocatableSize = 256 * KB;
 
-  intptr_t CalculateTLABSize();
+  intptr_t GetTLABSize() {
+    // Inspired by V8 tlab size. More than threshold for old space allocation,
+    // less then minimal(initial) new semi-space.
+    const intptr_t size = 512 * KB;
+    return Utils::RoundDown(size, kObjectAlignment);
+  }
   void MakeTLABIterable(Thread* thread);
   void AbandonRemainingTLAB(Thread* thread);
 
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 23fe586..c246f43 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -310,7 +310,7 @@
         !raw_key->IsMarked()) {
       // Key was white. Enqueue the weak property.
       EnqueueWeakProperty(raw_weak);
-      return raw_weak->Size();
+      return raw_weak->HeapSize();
     }
     // Key is gray or black. Make the weak property black.
     return raw_weak->VisitPointersNonvirtual(this);
@@ -322,7 +322,7 @@
       ASSERT(raw_obj->IsInstructions());
       RawInstructions* instr = static_cast<RawInstructions*>(raw_obj);
       if (TryAcquireMarkBit(instr)) {
-        intptr_t size = instr->Size();
+        intptr_t size = instr->HeapSize();
         marked_bytes_ += size;
         NOT_IN_PRODUCT(UpdateLiveOld(kInstructionsCid, size));
       }
@@ -368,12 +368,6 @@
   }
 
   static bool TryAcquireMarkBit(RawObject* raw_obj) {
-    // While it might seem this is redundant with TryAcquireMarkBit, we must
-    // do this check first to avoid attempting an atomic::fetch_and on the
-    // read-only vm-isolate or image pages, which can fault even if there is no
-    // change in the value.
-    if (raw_obj->IsMarked()) return false;
-
     if (!sync) {
       raw_obj->SetMarkBitUnsynchronized();
       return true;
@@ -383,17 +377,28 @@
   }
 
   void MarkObject(RawObject* raw_obj) {
-    // Fast exit if the raw object is a Smi.
+    // Fast exit if the raw object is immediate or in new space. No memory
+    // access.
     if (raw_obj->IsSmiOrNewObject()) {
       return;
     }
 
+    // While it might seem this is redundant with TryAcquireMarkBit, we must
+    // do this check first to avoid attempting an atomic::fetch_and on the
+    // read-only vm-isolate or image pages, which can fault even if there is no
+    // change in the value.
+    // Doing this before checking for an Instructions object avoids
+    // unnecessary queueing of pre-marked objects.
+    if (raw_obj->IsMarked()) {
+      return;
+    }
+
     intptr_t class_id = raw_obj->GetClassId();
     ASSERT(class_id != kFreeListElement);
 
     if (sync && UNLIKELY(class_id == kInstructionsCid)) {
-      // If this is the concurrent marker, instruction pages may be
-      // non-writable.
+      // If this is the concurrent marker, this object may be non-writable due
+      // to W^X (--write-protect-code).
       deferred_work_list_.Push(raw_obj);
       return;
     }
@@ -519,22 +524,50 @@
   store_buffer->PushBlock(writing, StoreBuffer::kIgnoreThreshold);
 }
 
-void GCMarker::IterateRoots(ObjectPointerVisitor* visitor,
-                            intptr_t slice_index,
-                            intptr_t num_slices) {
-  ASSERT(0 <= slice_index && slice_index < num_slices);
-  if ((slice_index == 0) || (num_slices <= 1)) {
-    TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessRoots");
-    isolate_->VisitObjectPointers(visitor,
-                                  ValidationPolicy::kDontValidateFrames);
-  }
-  if ((slice_index == 1) || (num_slices <= 1)) {
-    TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessNewSpace");
-    heap_->new_space()->VisitObjectPointers(visitor);
-  }
+enum RootSlices {
+  kIsolate = 0,
+  kNewSpace = 1,
+  kNumRootSlices = 2,
+};
 
-  // For now, we just distinguish two parts of the root set, so any remaining
-  // slices are empty.
+void GCMarker::ResetRootSlices() {
+  root_slices_not_started_ = kNumRootSlices;
+  root_slices_not_finished_ = kNumRootSlices;
+}
+
+void GCMarker::IterateRoots(ObjectPointerVisitor* visitor) {
+  for (;;) {
+    intptr_t task =
+        AtomicOperations::FetchAndDecrement(&root_slices_not_started_) - 1;
+    if (task < 0) {
+      return;  // No more tasks.
+    }
+
+    switch (task) {
+      case kIsolate: {
+        TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessRoots");
+        isolate_->VisitObjectPointers(visitor,
+                                      ValidationPolicy::kDontValidateFrames);
+        break;
+      }
+      case kNewSpace: {
+        TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessNewSpace");
+        heap_->new_space()->VisitObjectPointers(visitor);
+        break;
+      }
+      default:
+        FATAL1("%" Pd, task);
+        UNREACHABLE();
+    }
+
+    intptr_t remaining =
+        AtomicOperations::FetchAndDecrement(&root_slices_not_finished_) - 1;
+    if (remaining == 0) {
+      MonitorLocker ml(&root_slices_monitor_);
+      ml.Notify();
+      return;
+    }
+  }
 }
 
 void GCMarker::IterateWeakRoots(HandleVisitor* visitor) {
@@ -589,23 +622,19 @@
 #endif  // !PRODUCT
 }
 
-class MarkTask : public ThreadPool::Task {
+class ParallelMarkTask : public ThreadPool::Task {
  public:
-  MarkTask(GCMarker* marker,
-           Isolate* isolate,
-           MarkingStack* marking_stack,
-           ThreadBarrier* barrier,
-           SyncMarkingVisitor* visitor,
-           intptr_t task_index,
-           intptr_t num_tasks,
-           uintptr_t* num_busy)
+  ParallelMarkTask(GCMarker* marker,
+                   Isolate* isolate,
+                   MarkingStack* marking_stack,
+                   ThreadBarrier* barrier,
+                   SyncMarkingVisitor* visitor,
+                   uintptr_t* num_busy)
       : marker_(marker),
         isolate_(isolate),
         marking_stack_(marking_stack),
         barrier_(barrier),
         visitor_(visitor),
-        task_index_(task_index),
-        num_tasks_(num_tasks),
         num_busy_(num_busy) {}
 
   virtual void Run() {
@@ -613,11 +642,11 @@
         Thread::EnterIsolateAsHelper(isolate_, Thread::kMarkerTask, true);
     ASSERT(result);
     {
-      TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "MarkTask");
+      TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ParallelMark");
       int64_t start = OS::GetCurrentMonotonicMicros();
 
       // Phase 1: Iterate over roots and drain marking stack in tasks.
-      marker_->IterateRoots(visitor_, task_index_, num_tasks_);
+      marker_->IterateRoots(visitor_);
 
       bool more_to_mark = false;
       do {
@@ -681,9 +710,8 @@
       int64_t stop = OS::GetCurrentMonotonicMicros();
       visitor_->AddMicros(stop - start);
       if (FLAG_log_marker_tasks) {
-        THR_Print("Task %" Pd " marked %" Pd " bytes in %" Pd64 " micros.\n",
-                  task_index_, visitor_->marked_bytes(),
-                  visitor_->marked_micros());
+        THR_Print("Task marked %" Pd " bytes in %" Pd64 " micros.\n",
+                  visitor_->marked_bytes(), visitor_->marked_micros());
       }
       marker_->FinalizeResultsFrom(visitor_);
 
@@ -701,11 +729,9 @@
   MarkingStack* marking_stack_;
   ThreadBarrier* barrier_;
   SyncMarkingVisitor* visitor_;
-  const intptr_t task_index_;
-  const intptr_t num_tasks_;
   uintptr_t* num_busy_;
 
-  DISALLOW_COPY_AND_ASSIGN(MarkTask);
+  DISALLOW_COPY_AND_ASSIGN(ParallelMarkTask);
 };
 
 class ConcurrentMarkTask : public ThreadPool::Task {
@@ -713,19 +739,11 @@
   ConcurrentMarkTask(GCMarker* marker,
                      Isolate* isolate,
                      PageSpace* page_space,
-                     SyncMarkingVisitor* visitor,
-                     intptr_t task_index,
-                     intptr_t num_tasks,
-                     Monitor* roots_monitor,
-                     intptr_t* root_tasks_remaining)
+                     SyncMarkingVisitor* visitor)
       : marker_(marker),
         isolate_(isolate),
         page_space_(page_space),
-        visitor_(visitor),
-        task_index_(task_index),
-        num_tasks_(num_tasks),
-        roots_monitor_(roots_monitor),
-        root_tasks_remaining_(root_tasks_remaining) {
+        visitor_(visitor) {
 #if defined(DEBUG)
     MonitorLocker ml(page_space_->tasks_lock());
     ASSERT(page_space_->phase() == PageSpace::kMarking);
@@ -737,23 +755,17 @@
         Thread::EnterIsolateAsHelper(isolate_, Thread::kMarkerTask, true);
     ASSERT(result);
     {
-      TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ConcurrentMarkTask");
+      TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ConcurrentMark");
       int64_t start = OS::GetCurrentMonotonicMicros();
 
-      marker_->IterateRoots(visitor_, task_index_, num_tasks_);
-      {
-        MonitorLocker ml(roots_monitor_);
-        (*root_tasks_remaining_)--;
-        ml.Notify();
-      }
+      marker_->IterateRoots(visitor_);
 
       visitor_->DrainMarkingStack();
       int64_t stop = OS::GetCurrentMonotonicMicros();
       visitor_->AddMicros(stop - start);
       if (FLAG_log_marker_tasks) {
-        THR_Print("Task %" Pd " marked %" Pd " bytes in %" Pd64 " micros.\n",
-                  task_index_, visitor_->marked_bytes(),
-                  visitor_->marked_micros());
+        THR_Print("Task marked %" Pd " bytes in %" Pd64 " micros.\n",
+                  visitor_->marked_bytes(), visitor_->marked_micros());
       }
     }
 
@@ -779,10 +791,6 @@
   Isolate* isolate_;
   PageSpace* page_space_;
   SyncMarkingVisitor* visitor_;
-  const intptr_t task_index_;
-  const intptr_t num_tasks_;
-  Monitor* const roots_monitor_;
-  intptr_t* root_tasks_remaining_;
 
   DISALLOW_COPY_AND_ASSIGN(ConcurrentMarkTask);
 };
@@ -869,8 +877,7 @@
         page_space->concurrent_marker_tasks() + num_tasks);
   }
 
-  Monitor roots_monitor;
-  intptr_t root_tasks_remaining = num_tasks;
+  ResetRootSlices();
   for (intptr_t i = 0; i < num_tasks; i++) {
     ASSERT(visitors_[i] == NULL);
     SkippedCodeFunctions* skipped_code_functions =
@@ -880,15 +887,14 @@
                                           skipped_code_functions);
 
     // Begin marking on a helper thread.
-    bool result = Dart::thread_pool()->Run(new ConcurrentMarkTask(
-        this, isolate_, page_space, visitors_[i], i, num_tasks, &roots_monitor,
-        &root_tasks_remaining));
+    bool result = Dart::thread_pool()->Run(
+        new ConcurrentMarkTask(this, isolate_, page_space, visitors_[i]));
     ASSERT(result);
   }
 
   // Wait for roots to be marked before exiting safepoint.
-  MonitorLocker ml(&roots_monitor);
-  while (root_tasks_remaining > 0) {
+  MonitorLocker ml(&root_slices_monitor_);
+  while (root_slices_not_finished_ > 0) {
     ml.Wait();
   }
 }
@@ -911,7 +917,8 @@
       UnsyncMarkingVisitor mark(isolate_, page_space, &marking_stack_,
                                 &deferred_marking_stack_,
                                 skipped_code_functions);
-      IterateRoots(&mark, 0, 1);
+      ResetRootSlices();
+      IterateRoots(&mark);
       mark.DrainMarkingStack();
       mark.FinalizeInstructions();
       {
@@ -926,6 +933,7 @@
     } else {
       ThreadBarrier barrier(num_tasks + 1, heap_->barrier(),
                             heap_->barrier_done());
+      ResetRootSlices();
       // Used to coordinate draining among tasks; all start out as 'busy'.
       uintptr_t num_busy = num_tasks;
       // Phase 1: Iterate over roots and drain marking stack in tasks.
@@ -942,11 +950,8 @@
               skipped_code_functions);
         }
 
-        MarkTask* mark_task =
-            new MarkTask(this, isolate_, &marking_stack_, &barrier, visitor, i,
-                         num_tasks, &num_busy);
-        ThreadPool* pool = Dart::thread_pool();
-        bool result = pool->Run(mark_task);
+        bool result = Dart::thread_pool()->Run(new ParallelMarkTask(
+            this, isolate_, &marking_stack_, &barrier, visitor, &num_busy));
         ASSERT(result);
       }
       bool more_to_mark = false;
diff --git a/runtime/vm/heap/marker.h b/runtime/vm/heap/marker.h
index a4424cf..6108e21 100644
--- a/runtime/vm/heap/marker.h
+++ b/runtime/vm/heap/marker.h
@@ -47,9 +47,8 @@
  private:
   void Prologue();
   void Epilogue();
-  void IterateRoots(ObjectPointerVisitor* visitor,
-                    intptr_t slice_index,
-                    intptr_t num_slices);
+  void ResetRootSlices();
+  void IterateRoots(ObjectPointerVisitor* visitor);
   void IterateWeakRoots(HandleVisitor* visitor);
   template <class MarkingVisitorType>
   void IterateWeakReferences(MarkingVisitorType* visitor);
@@ -66,12 +65,16 @@
   MarkingStack deferred_marking_stack_;
   MarkingVisitorBase<true>** visitors_;
 
+  Monitor root_slices_monitor_;
+  intptr_t root_slices_not_started_;
+  intptr_t root_slices_not_finished_;
+
   Mutex stats_mutex_;
   uintptr_t marked_bytes_;
   int64_t marked_micros_;
 
   friend class ConcurrentMarkTask;
-  friend class MarkTask;
+  friend class ParallelMarkTask;
   DISALLOW_IMPLICIT_CONSTRUCTORS(GCMarker);
 };
 
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index d90c9ec..4ba70ca 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -113,7 +113,7 @@
   while (obj_addr < end_addr) {
     RawObject* raw_obj = RawObject::FromAddr(obj_addr);
     visitor->VisitObject(raw_obj);
-    obj_addr += raw_obj->Size();
+    obj_addr += raw_obj->HeapSize();
   }
   ASSERT(obj_addr == end_addr);
 }
@@ -197,7 +197,7 @@
   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->Size();
+      uword next_obj_addr = obj_addr + raw_obj->HeapSize();
       if (visitor->VisitRange(obj_addr, next_obj_addr) &&
           raw_obj->FindObject(visitor)) {
         return raw_obj;  // Found object, return it.
@@ -860,7 +860,7 @@
  public:
   explicit HeapMapAsJSONVisitor(JSONArray* array) : array_(array) {}
   virtual void VisitObject(RawObject* obj) {
-    array_->AddValue(obj->Size() / kObjectAlignment);
+    array_->AddValue(obj->HeapSize() / kObjectAlignment);
     array_->AddValue(obj->GetClassId());
   }
 
@@ -1297,7 +1297,7 @@
       return TryAllocateInFreshPage(size, HeapPage::kData, growth_policy,
                                     is_locked);
     }
-    intptr_t block_size = block->Size();
+    intptr_t block_size = block->HeapSize();
     if (remaining > 0) {
       if (is_locked) {
         freelist_[HeapPage::kData].FreeLocked(bump_top_, remaining);
@@ -1536,7 +1536,7 @@
   }
 }
 
-void PageSpaceController::EvaluateSnapshotLoad(SpaceUsage after) {
+void PageSpaceController::EvaluateAfterLoading(SpaceUsage after) {
   // Number of pages we can allocate and still be within the desired growth
   // ratio.
   intptr_t growth_in_pages =
@@ -1559,7 +1559,7 @@
 
   if (FLAG_log_growth) {
     THR_Print("%s: threshold=%" Pd "kB, idle_threshold=%" Pd
-              "kB, reason=snapshot\n",
+              "kB, reason=loaded\n",
               heap_->isolate()->name(), gc_threshold_in_words_ / KBInWords,
               idle_gc_threshold_in_words_ / KBInWords);
   }
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 7829cc0..321b0be 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -188,7 +188,7 @@
                                  SpaceUsage after,
                                  int64_t start,
                                  int64_t end);
-  void EvaluateSnapshotLoad(SpaceUsage after);
+  void EvaluateAfterLoading(SpaceUsage after);
 
   int64_t last_code_collection_in_us() { return last_code_collection_in_us_; }
   void set_last_code_collection_in_us(int64_t t) {
@@ -266,8 +266,8 @@
   bool AlmostNeedsGarbageCollection() const {
     return page_space_controller_.AlmostNeedsGarbageCollection(usage_);
   }
-  void EvaluateSnapshotLoad() {
-    page_space_controller_.EvaluateSnapshotLoad(usage_);
+  void EvaluateAfterLoading() {
+    page_space_controller_.EvaluateAfterLoading(usage_);
   }
 
   int64_t UsedInWords() const { return usage_.used_in_words; }
@@ -518,7 +518,7 @@
   friend class ExclusiveLargePageIterator;
   friend class HeapIterationScope;
   friend class PageSpaceController;
-  friend class SweeperTask;
+  friend class ConcurrentSweeperTask;
   friend class GCCompactor;
   friend class CompactorTask;
 
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index b07afe9..b6906ae 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -134,7 +134,7 @@
       // Get the new location of the object.
       new_addr = ForwardedAddr(header);
     } else {
-      intptr_t size = raw_obj->Size();
+      intptr_t size = raw_obj->HeapSize();
       NOT_IN_PRODUCT(intptr_t cid = raw_obj->GetClassId());
       NOT_IN_PRODUCT(ClassTable* class_table = isolate()->class_table());
       // Check whether object should be promoted.
@@ -592,18 +592,14 @@
   if (!FLAG_support_service) {
     return;
   }
-  ObjectIdRing* ring = isolate->object_id_ring();
-  if (ring == NULL) {
-    // --gc_at_alloc can get us here before the ring has been initialized.
-    ASSERT(FLAG_gc_at_alloc);
-    return;
-  }
-  ring->VisitPointers(visitor);
+  isolate->object_id_ring()->VisitPointers(visitor);
 #endif  // !PRODUCT
 }
 
 void Scavenger::IterateRoots(Isolate* isolate, ScavengerVisitor* visitor) {
-  NOT_IN_PRODUCT(Thread* thread = Thread::Current());
+#ifdef SUPPORT_TIMELINE
+  Thread* thread = Thread::Current();
+#endif
   int64_t start = OS::GetCurrentMonotonicMicros();
   {
     TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessRoots");
@@ -772,7 +768,7 @@
     if (!IsForwarding(header)) {
       // Key is white.  Enqueue the weak property.
       EnqueueWeakProperty(raw_weak);
-      return raw_weak->Size();
+      return raw_weak->HeapSize();
     }
   }
   // Key is gray or black.  Make the weak property black.
@@ -896,7 +892,7 @@
   while (cur < top_) {
     RawObject* raw_obj = RawObject::FromAddr(cur);
     visitor->VisitObject(raw_obj);
-    cur += raw_obj->Size();
+    cur += raw_obj->HeapSize();
   }
 }
 
@@ -911,7 +907,7 @@
   if (visitor->VisitRange(cur, top_)) {
     while (cur < top_) {
       RawObject* raw_obj = RawObject::FromAddr(cur);
-      uword next = cur + raw_obj->Size();
+      uword next = cur + raw_obj->HeapSize();
       if (visitor->VisitRange(cur, next) && raw_obj->FindObject(visitor)) {
         return raw_obj;  // Found object, return it.
       }
@@ -930,6 +926,15 @@
   uword result = top_;
   intptr_t remaining = end_ - top_;
   if (remaining < size) {
+    // Grab whatever is remaining
+    size = remaining;
+  } else {
+    // Reduce TLAB size so we land at even TLAB size for future TLABs.
+    intptr_t survived_size = UsedInWords() * kWordSize;
+    size -= survived_size % size;
+  }
+  size = Utils::RoundDown(size, kObjectAlignment);
+  if (size == 0) {
     return 0;
   }
   ASSERT(to_->Contains(result));
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index bd8ad4f..6867278 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -151,14 +151,6 @@
     ASSERT(heap_ != Dart::vm_isolate()->heap());
     ASSERT(thread->IsMutatorThread());
     ASSERT(thread->isolate()->IsMutatorThreadScheduled());
-    ASSERT(thread->top() <= top_);
-    ASSERT((thread->end() == 0) || (thread->end() == top_));
-#if defined(DEBUG)
-    if (FLAG_gc_at_alloc) {
-      ASSERT(!scavenging_);
-      Scavenge();
-    }
-#endif
     uword top = thread->top();
     uword end = thread->end();
     uword result = top;
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc
index 7e477d7..b1e385f 100644
--- a/runtime/vm/heap/sweeper.cc
+++ b/runtime/vm/heap/sweeper.cc
@@ -34,10 +34,10 @@
     if (raw_obj->IsMarked()) {
       // Found marked object. Clear the mark bit and update swept bytes.
       raw_obj->ClearMarkBit();
-      obj_size = raw_obj->Size();
+      obj_size = raw_obj->HeapSize();
       used_in_bytes += obj_size;
     } else {
-      uword free_end = current + raw_obj->Size();
+      uword free_end = current + raw_obj->HeapSize();
       while (free_end < end) {
         RawObject* next_obj = RawObject::FromAddr(free_end);
         if (next_obj->IsMarked()) {
@@ -45,7 +45,7 @@
           break;
         }
         // Expand the free block by the size of this object.
-        free_end += next_obj->Size();
+        free_end += next_obj->HeapSize();
       }
       obj_size = free_end - current;
       if (is_executable) {
@@ -86,17 +86,17 @@
   ASSERT(HeapPage::Of(raw_obj) == page);
   if (raw_obj->IsMarked()) {
     raw_obj->ClearMarkBit();
-    words_to_end = (raw_obj->Size() >> kWordSizeLog2);
+    words_to_end = (raw_obj->HeapSize() >> kWordSizeLog2);
   }
 #ifdef DEBUG
   // String::MakeExternal and Array::MakeFixedLength create trailing filler
   // objects, but they are always unreachable. Verify that they are not marked.
-  uword current = RawObject::ToAddr(raw_obj) + raw_obj->Size();
+  uword current = RawObject::ToAddr(raw_obj) + raw_obj->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->Size();
+    intptr_t obj_size = cur_obj->HeapSize();
     memset(reinterpret_cast<void*>(current), Heap::kZapByte, obj_size);
     current += obj_size;
   }
@@ -104,13 +104,13 @@
   return words_to_end;
 }
 
-class SweeperTask : public ThreadPool::Task {
+class ConcurrentSweeperTask : public ThreadPool::Task {
  public:
-  SweeperTask(Isolate* isolate,
-              PageSpace* old_space,
-              HeapPage* first,
-              HeapPage* last,
-              FreeList* freelist)
+  ConcurrentSweeperTask(Isolate* isolate,
+                        PageSpace* old_space,
+                        HeapPage* first,
+                        HeapPage* last,
+                        FreeList* freelist)
       : task_isolate_(isolate),
         old_space_(old_space),
         first_(first),
@@ -132,7 +132,7 @@
     ASSERT(result);
     {
       Thread* thread = Thread::Current();
-      TIMELINE_FUNCTION_GC_DURATION(thread, "SweeperTask");
+      TIMELINE_FUNCTION_GC_DURATION(thread, "ConcurrentSweep");
       GCSweeper sweeper;
 
       HeapPage* page = first_;
@@ -182,10 +182,9 @@
                                 HeapPage* first,
                                 HeapPage* last,
                                 FreeList* freelist) {
-  SweeperTask* task = new SweeperTask(isolate, isolate->heap()->old_space(),
-                                      first, last, freelist);
-  ThreadPool* pool = Dart::thread_pool();
-  pool->Run(task);
+  bool result = Dart::thread_pool()->Run(new ConcurrentSweeperTask(
+      isolate, isolate->heap()->old_space(), first, last, freelist));
+  ASSERT(result);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/heap/verifier.h b/runtime/vm/heap/verifier.h
index d811be6..23ca6b4 100644
--- a/runtime/vm/heap/verifier.h
+++ b/runtime/vm/heap/verifier.h
@@ -7,6 +7,7 @@
 
 #include "vm/flags.h"
 #include "vm/globals.h"
+#include "vm/handle_visitor.h"
 #include "vm/handles.h"
 #include "vm/thread.h"
 #include "vm/visitor.h"
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 9be1458..838e2b7 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -43,7 +43,7 @@
   ASSERT(!obj->IsSmi());
 
   uword body = RawObject::ToAddr(obj) + sizeof(RawObject);
-  uword end = RawObject::ToAddr(obj) + obj->Size();
+  uword end = RawObject::ToAddr(obj) + obj->HeapSize();
 
   uint32_t hash = obj->GetClassId();
   // Don't include the header. Objects in the image are pre-marked, but objects
@@ -65,8 +65,8 @@
     return false;
   }
 
-  intptr_t heap_size = a->Size();
-  if (b->Size() != heap_size) {
+  intptr_t heap_size = a->HeapSize();
+  if (b->HeapSize() != heap_size) {
     return false;
   }
 
@@ -106,11 +106,20 @@
           RawInstructions* instructions = Code::InstructionsOf(code);
           const intptr_t offset = next_text_offset_;
           instructions_.Add(InstructionsData(instructions, code, offset));
-          next_text_offset_ += instructions->Size();
+          next_text_offset_ += instructions->HeapSize();
           ASSERT(heap_->GetObjectId(instructions) == 0);
           heap_->SetObjectId(instructions, offset);
           break;
         }
+        case ImageWriterCommand::InsertBytesOfTrampoline: {
+          auto trampoline_bytes = inst.insert_trampoline_bytes.buffer;
+          auto trampoline_length = inst.insert_trampoline_bytes.buffer_length;
+          const intptr_t offset = next_text_offset_;
+          instructions_.Add(
+              InstructionsData(trampoline_bytes, trampoline_length, offset));
+          next_text_offset_ += trampoline_length;
+          break;
+        }
         default:
           UNREACHABLE();
       }
@@ -132,7 +141,7 @@
     pair.object = raw_obj;
     pair.offset = offset;
     map->Insert(pair);
-    obj_addr += raw_obj->Size();
+    obj_addr += raw_obj->HeapSize();
   }
   ASSERT(obj_addr == end_addr);
 }
@@ -163,7 +172,7 @@
 
   offset = next_text_offset_;
   heap_->SetObjectId(instructions, offset);
-  next_text_offset_ += instructions->Size();
+  next_text_offset_ += instructions->HeapSize();
   instructions_.Add(InstructionsData(instructions, code, offset));
 
   return offset;
@@ -180,7 +189,7 @@
 }
 
 uint32_t ImageWriter::GetDataOffsetFor(RawObject* raw_object) {
-  intptr_t heap_size = raw_object->Size();
+  intptr_t heap_size = raw_object->HeapSize();
   intptr_t offset = next_data_offset_;
   next_data_offset_ += heap_size;
   objects_.Add(ObjectData(raw_object));
@@ -214,11 +223,6 @@
   js.OpenArray();
   for (intptr_t i = 0; i < instructions_.length(); i++) {
     auto& data = instructions_[i];
-    if (data.code_->IsNull()) {
-      // TODO(34650): Type testing stubs are added to the serializer without
-      // their Code.
-      continue;
-    }
     owner = data.code_->owner();
     js.OpenObject();
     if (owner.IsFunction()) {
@@ -230,7 +234,7 @@
       js.PrintPropertyStr("c", name);
     }
     js.PrintProperty("n", data.code_->QualifiedName());
-    js.PrintProperty("s", data.insns_->Size());
+    js.PrintProperty("s", data.insns_->raw()->HeapSize());
     js.CloseObject();
   }
   js.CloseArray();
@@ -272,13 +276,15 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Heap* heap = thread->isolate()->heap();
-  NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
-                                           "WriteInstructions"));
+  TIMELINE_DURATION(thread, Isolate, "WriteInstructions");
 
   // Handlify collected raw pointers as building the names below
   // will allocate on the Dart heap.
   for (intptr_t i = 0; i < instructions_.length(); i++) {
     InstructionsData& data = instructions_[i];
+    const bool is_trampoline = data.trampoline_bytes != nullptr;
+    if (is_trampoline) continue;
+
     data.insns_ = &Instructions::Handle(zone, data.raw_insns_);
     ASSERT(data.raw_code_ != NULL);
     data.code_ = &Code::Handle(zone, data.raw_code_);
@@ -323,7 +329,7 @@
 
     NoSafepointScope no_safepoint;
     uword start = reinterpret_cast<uword>(obj.raw()) - kHeapObjectTag;
-    uword end = start + obj.raw()->Size();
+    uword end = start + obj.raw()->HeapSize();
 
     // Write object header with the mark and VM heap bits set.
     uword marked_tags = obj.raw()->ptr()->tags_;
@@ -364,7 +370,7 @@
 #endif
 }
 
-static void EnsureIdentifier(char* label) {
+static void EnsureAssemblerIdentifier(char* label) {
   for (char c = *label; c != '\0'; c = *++label) {
     if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ||
         ((c >= '0') && (c <= '9'))) {
@@ -374,6 +380,29 @@
   }
 }
 
+const char* NameOfStubIsolateSpecificStub(ObjectStore* object_store,
+                                          const Code& code) {
+  if (code.raw() == object_store->build_method_extractor_code()) {
+    return "_iso_stub_BuildMethodExtractorStub";
+  } 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->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";
+  }
+  return nullptr;
+}
+
 void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
   Zone* zone = Thread::Current()->zone();
 
@@ -403,29 +432,48 @@
 
   ObjectStore* object_store = Isolate::Current()->object_store();
 
-  TypeTestingStubFinder tts;
+  TypeTestingStubNamer tts;
   intptr_t text_offset = 0;
 
+  ASSERT(offset_space_ != V8SnapshotProfileWriter::kSnapshot);
   for (intptr_t i = 0; i < instructions_.length(); i++) {
-    auto& instr = instructions_[i];
-    ASSERT((instr.text_offset_ - instructions_[0].text_offset_) == text_offset);
+    auto& data = instructions_[i];
+    const bool is_trampoline = data.trampoline_bytes != nullptr;
+    ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
+
+    if (is_trampoline) {
+      if (profile_writer_ != nullptr) {
+        const intptr_t offset = Image::kHeaderSize + text_offset;
+        profile_writer_->SetObjectTypeAndName({offset_space_, offset},
+                                              "Trampolines",
+                                              /*name=*/nullptr);
+        profile_writer_->AttributeBytesTo({offset_space_, offset},
+                                          data.trampline_length);
+      }
+
+      const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
+      const auto end = start + data.trampline_length;
+      text_offset += WriteByteSequence(start, end);
+      delete[] data.trampoline_bytes;
+      data.trampoline_bytes = nullptr;
+      continue;
+    }
 
     const intptr_t instr_start = text_offset;
 
-    const Instructions& insns = *instr.insns_;
-    const Code& code = *instr.code_;
+    const Instructions& insns = *data.insns_;
+    const Code& code = *data.code_;
 
     if (profile_writer_ != nullptr) {
       const intptr_t offset = Image::kHeaderSize + text_offset;
-      ASSERT(offset_space_ != V8SnapshotProfileWriter::kSnapshot);
       profile_writer_->SetObjectTypeAndName({offset_space_, offset},
                                             "Instructions",
                                             /*name=*/nullptr);
       profile_writer_->AttributeBytesTo({offset_space_, offset},
-                                        insns.raw()->Size());
+                                        insns.raw()->HeapSize());
     }
 
-    ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0);
+    ASSERT(insns.raw()->HeapSize() % sizeof(uint64_t) == 0);
 
     // 1. Write from the header to the entry point.
     {
@@ -451,45 +499,41 @@
       WriteWordLiteralText(marked_tags);
       beginning += sizeof(uword);
       text_offset += sizeof(uword);
-
-      WriteByteSequence(beginning, entry);
-      text_offset += (entry - beginning);
+      text_offset += WriteByteSequence(beginning, entry);
 
       ASSERT((text_offset - instr_start) == insns.HeaderSize());
     }
 
     // 2. Write a label at the entry point.
     // Linux's perf uses these labels.
-    if (code.IsNull()) {
-      const char* name = tts.StubNameFromAddresss(insns.EntryPoint());
-      assembly_stream_.Print("Precompiled_%s:\n", name);
-    } else {
-      owner = code.owner();
-      if (owner.IsNull()) {
-        const char* name = StubCode::NameOfStub(insns.EntryPoint());
-        if (name == nullptr &&
-            code.raw() == object_store->build_method_extractor_code()) {
-          name = "BuildMethodExtractor";
-        }
-        if (name != NULL) {
-          assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
-        } else {
-          const char* name = tts.StubNameFromAddresss(insns.EntryPoint());
-          assembly_stream_.Print("Precompiled__%s:\n", name);
-        }
-      } else if (owner.IsClass()) {
-        str = Class::Cast(owner).Name();
-        const char* name = str.ToCString();
-        EnsureIdentifier(const_cast<char*>(name));
-        assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name,
-                               i);
-      } else if (owner.IsFunction()) {
-        const char* name = Function::Cast(owner).ToQualifiedCString();
-        EnsureIdentifier(const_cast<char*>(name));
-        assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+    ASSERT(!code.IsNull());
+    owner = code.owner();
+    if (owner.IsNull()) {
+      const char* name = StubCode::NameOfStub(insns.EntryPoint());
+      if (name != nullptr) {
+        assembly_stream_.Print("Precompiled_Stub_%s:\n", name);
       } else {
-        UNREACHABLE();
+        if (name == nullptr) {
+          name = NameOfStubIsolateSpecificStub(object_store, code);
+        }
+        ASSERT(name != nullptr);
+        assembly_stream_.Print("Precompiled__%s:\n", name);
       }
+    } else if (owner.IsClass()) {
+      str = Class::Cast(owner).Name();
+      const char* name = str.ToCString();
+      EnsureAssemblerIdentifier(const_cast<char*>(name));
+      assembly_stream_.Print("Precompiled_AllocationStub_%s_%" Pd ":\n", name,
+                             i);
+    } else if (owner.IsAbstractType()) {
+      const char* name = tts.StubNameForType(AbstractType::Cast(owner));
+      assembly_stream_.Print("Precompiled_%s:\n", name);
+    } else if (owner.IsFunction()) {
+      const char* name = Function::Cast(owner).ToQualifiedCString();
+      EnsureAssemblerIdentifier(const_cast<char*>(name));
+      assembly_stream_.Print("Precompiled_%s_%" Pd ":\n", name, i);
+    } else {
+      UNREACHABLE();
     }
 
 #ifdef DART_PRECOMPILER
@@ -505,18 +549,17 @@
       NoSafepointScope no_safepoint;
       uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
       uword entry = beginning + Instructions::HeaderSize();
-      uword payload_size = insns.raw()->Size() - insns.HeaderSize();
+      uword payload_size = insns.raw()->HeapSize() - insns.HeaderSize();
       uword end = entry + payload_size;
 
       ASSERT(Utils::IsAligned(beginning, sizeof(uword)));
       ASSERT(Utils::IsAligned(entry, sizeof(uword)));
       ASSERT(Utils::IsAligned(end, sizeof(uword)));
 
-      WriteByteSequence(entry, end);
-      text_offset += (end - entry);
+      text_offset += WriteByteSequence(entry, end);
     }
 
-    ASSERT((text_offset - instr_start) == insns.raw()->Size());
+    ASSERT((text_offset - instr_start) == insns.raw()->HeapSize());
   }
 
   FrameUnwindEpilogue();
@@ -618,11 +661,12 @@
   assembly_stream_.Print(".cfi_endproc\n");
 }
 
-void AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
+intptr_t AssemblyImageWriter::WriteByteSequence(uword start, uword end) {
   for (uword* cursor = reinterpret_cast<uword*>(start);
        cursor < reinterpret_cast<uword*>(end); cursor++) {
     WriteWordLiteralText(*cursor);
   }
+  return end - start;
 }
 
 BlobImageWriter::BlobImageWriter(Thread* thread,
@@ -639,6 +683,14 @@
       instructions_blob_stream_(instructions_blob_buffer, alloc, initial_size) {
 }
 
+intptr_t BlobImageWriter::WriteByteSequence(uword start, uword end) {
+  for (uword* cursor = reinterpret_cast<uword*>(start);
+       cursor < reinterpret_cast<uword*>(end); cursor++) {
+    instructions_blob_stream_.WriteWord(*cursor);
+  }
+  return end - start;
+}
+
 void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
   // This header provides the gap to make the instructions snapshot look like a
   // HeapPage.
@@ -653,12 +705,24 @@
 
   NoSafepointScope no_safepoint;
   for (intptr_t i = 0; i < instructions_.length(); i++) {
-    auto& instr = instructions_[i];
-    const Instructions& insns = *instructions_[i].insns_;
-    AutoTraceImage(insns, 0, &this->instructions_blob_stream_);
-    ASSERT((instr.text_offset_ - instructions_[0].text_offset_) == text_offset);
+    auto& data = instructions_[i];
+    const bool is_trampoline = data.trampoline_bytes != nullptr;
+    ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
+
+    if (is_trampoline) {
+      const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
+      const auto end = start + data.trampline_length;
+      text_offset += WriteByteSequence(start, end);
+      delete[] data.trampoline_bytes;
+      data.trampoline_bytes = nullptr;
+      continue;
+    }
 
     const intptr_t instr_start = text_offset;
+
+    const Instructions& insns = *instructions_[i].insns_;
+    AutoTraceImage(insns, 0, &this->instructions_blob_stream_);
+
     uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
     uword entry = beginning + Instructions::HeaderSize();
     uword payload_size = insns.Size();
@@ -684,14 +748,9 @@
     instructions_blob_stream_.WriteWord(marked_tags);
     text_offset += sizeof(uword);
     beginning += sizeof(uword);
+    text_offset += WriteByteSequence(beginning, end);
 
-    for (uword* cursor = reinterpret_cast<uword*>(beginning);
-         cursor < reinterpret_cast<uword*>(end); cursor++) {
-      instructions_blob_stream_.WriteWord(*cursor);
-      text_offset += sizeof(uword);
-    }
-
-    ASSERT((text_offset - instr_start) == insns.raw()->Size());
+    ASSERT((text_offset - instr_start) == insns.raw()->HeapSize());
   }
 }
 
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index 939a653..1bc4260 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -5,6 +5,7 @@
 #ifndef RUNTIME_VM_IMAGE_SNAPSHOT_H_
 #define RUNTIME_VM_IMAGE_SNAPSHOT_H_
 
+#include <memory>
 #include <utility>
 
 #include "platform/assert.h"
@@ -102,20 +103,29 @@
 // A command which instructs the image writer to emit something into the ".text"
 // segment.
 //
-// For now this just supports emitting the instructions of a [Code] object.
-// In the future we might also want to add support for emitting trampolines.
+// For now this supports
+//
+//   * emitting the instructions of a [Code] object
+//   * emitting a trampoline of a certain size
+//
 struct ImageWriterCommand {
   enum Opcode {
     InsertInstructionOfCode,
+    InsertBytesOfTrampoline,
   };
 
-  ImageWriterCommand(intptr_t expected_offset,
-                     ImageWriterCommand::Opcode opcode,
-                     RawCode* code)
+  ImageWriterCommand(intptr_t expected_offset, RawCode* code)
       : expected_offset(expected_offset),
-        op(opcode),
+        op(ImageWriterCommand::InsertInstructionOfCode),
         insert_instruction_of_code({code}) {}
 
+  ImageWriterCommand(intptr_t expected_offset,
+                     uint8_t* trampoline_bytes,
+                     intptr_t trampoine_length)
+      : expected_offset(expected_offset),
+        op(ImageWriterCommand::InsertBytesOfTrampoline),
+        insert_trampoline_bytes({trampoline_bytes, trampoine_length}) {}
+
   // The offset (relative to the very first [ImageWriterCommand]) we expect
   // this [ImageWriterCommand] to have.
   intptr_t expected_offset;
@@ -125,6 +135,10 @@
     struct {
       RawCode* code;
     } insert_instruction_of_code;
+    struct {
+      uint8_t* buffer;
+      intptr_t buffer_length;
+    } insert_trampoline_bytes;
   };
 };
 
@@ -177,7 +191,20 @@
     InstructionsData(RawInstructions* insns,
                      RawCode* code,
                      intptr_t text_offset)
-        : raw_insns_(insns), raw_code_(code), text_offset_(text_offset) {}
+        : raw_insns_(insns),
+          raw_code_(code),
+          text_offset_(text_offset),
+          trampoline_bytes(nullptr),
+          trampline_length(0) {}
+
+    InstructionsData(uint8_t* trampoline_bytes,
+                     intptr_t trampline_length,
+                     intptr_t text_offset)
+        : raw_insns_(nullptr),
+          raw_code_(nullptr),
+          text_offset_(text_offset),
+          trampoline_bytes(trampoline_bytes),
+          trampline_length(trampline_length) {}
 
     union {
       RawInstructions* raw_insns_;
@@ -188,6 +215,9 @@
       const Code* code_;
     };
     intptr_t text_offset_;
+
+    uint8_t* trampoline_bytes;
+    intptr_t trampline_length;
   };
 
   struct ObjectData {
@@ -279,7 +309,7 @@
  private:
   void FrameUnwindPrologue();
   void FrameUnwindEpilogue();
-  void WriteByteSequence(uword start, uword end);
+  intptr_t WriteByteSequence(uword start, uword end);
   void WriteWordLiteralText(uword value) {
 // Padding is helpful for comparing the .S with --disassemble.
 #if defined(ARCH_IS_64_BIT)
@@ -312,6 +342,8 @@
   }
 
  private:
+  intptr_t WriteByteSequence(uword start, uword end);
+
   WriteStream instructions_blob_stream_;
 
   DISALLOW_COPY_AND_ASSIGN(BlobImageWriter);
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index f9137ac..785f8fb 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -144,6 +144,37 @@
   return start;
 }
 
+void InstructionPattern::EncodeLoadWordImmediate(uword end,
+                                                 Register reg,
+                                                 intptr_t value) {
+  uint16_t low16 = value & 0xffff;
+  uint16_t high16 = (value >> 16) & 0xffff;
+
+  // movw reg, #imm_lo
+  uint32_t movw_instr = 0xe3000000;
+  movw_instr |= (low16 >> 12) << 16;
+  movw_instr |= (reg << 12);
+  movw_instr |= (low16 & 0xfff);
+
+  // movt reg, #imm_hi
+  uint32_t movt_instr = 0xe3400000;
+  movt_instr |= (high16 >> 12) << 16;
+  movt_instr |= (reg << 12);
+  movt_instr |= (high16 & 0xfff);
+
+  uint32_t* cursor = reinterpret_cast<uint32_t*>(end);
+  *(--cursor) = movt_instr;
+  *(--cursor) = movw_instr;
+
+#if defined(DEBUG)
+  Register decoded_reg;
+  intptr_t decoded_value;
+  DecodeLoadWordImmediate(end, &decoded_reg, &decoded_value);
+  ASSERT(reg == decoded_reg);
+  ASSERT(value == decoded_value);
+#endif
+}
+
 static bool IsLoadWithOffset(int32_t instr,
                              Register base,
                              intptr_t* offset,
@@ -201,7 +232,7 @@
     intptr_t index = ObjectPool::IndexFromOffset(offset);
     const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
     if (!pool.IsNull()) {
-      if (pool.TypeAt(index) == ObjectPool::kTaggedObject) {
+      if (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
         *obj = pool.ObjectAt(index);
         return true;
       }
@@ -300,7 +331,8 @@
 }
 
 void BareSwitchableCallPattern::SetTarget(const Code& target) const {
-  ASSERT(object_pool_.TypeAt(target_pool_index_) == ObjectPool::kImmediate);
+  ASSERT(object_pool_.TypeAt(target_pool_index_) ==
+         ObjectPool::EntryType::kImmediate);
   object_pool_.SetRawValueAt(target_pool_index_,
                              target.MonomorphicEntryPoint());
 }
@@ -326,19 +358,63 @@
 }
 
 bool PcRelativeCallPattern::IsValid() const {
-  // bl <offset>
+  // bl.<cond> <offset>
   const uint32_t word = *reinterpret_cast<uint32_t*>(pc_);
-  const uint32_t cond_all = 0xe0;
-  const uint32_t branch_link = 0x0b;
-  return (word >> 24) == (cond_all | branch_link);
+  const uint32_t branch_link = 0x05;
+  return ((word >> kTypeShift) & ((1 << kTypeBits) - 1)) == branch_link;
 }
 
-bool PcRelativeJumpPattern::IsValid() const {
-  // b <offset>
-  const uint32_t word = *reinterpret_cast<uint32_t*>(pc_);
-  const uint32_t cond_all = 0xe0;
-  const uint32_t branch_nolink = 0x0a;
-  return (word >> 24) == (cond_all | branch_nolink);
+void PcRelativeTrampolineJumpPattern::Initialize() {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  uint32_t* add_pc =
+      reinterpret_cast<uint32_t*>(pattern_start_ + 2 * Instr::kInstrSize);
+  *add_pc = kAddPcEncoding;
+  set_distance(0);
+#else
+  UNREACHABLE();
+#endif
+}
+
+int32_t PcRelativeTrampolineJumpPattern::distance() {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  const uword end = pattern_start_ + 2 * Instr::kInstrSize;
+  Register reg;
+  intptr_t value;
+  InstructionPattern::DecodeLoadWordImmediate(end, &reg, &value);
+  value -= kDistanceOffset;
+  ASSERT(reg == TMP);
+  return value;
+#else
+  UNREACHABLE();
+  return 0;
+#endif
+}
+
+void PcRelativeTrampolineJumpPattern::set_distance(int32_t distance) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  const uword end = pattern_start_ + 2 * Instr::kInstrSize;
+  InstructionPattern::EncodeLoadWordImmediate(end, TMP,
+                                              distance + kDistanceOffset);
+#else
+  UNREACHABLE();
+#endif
+}
+
+bool PcRelativeTrampolineJumpPattern::IsValid() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  const uword end = pattern_start_ + 2 * Instr::kInstrSize;
+  Register reg;
+  intptr_t value;
+  InstructionPattern::DecodeLoadWordImmediate(end, &reg, &value);
+
+  uint32_t* add_pc =
+      reinterpret_cast<uint32_t*>(pattern_start_ + 2 * Instr::kInstrSize);
+
+  return reg == TMP && *add_pc == kAddPcEncoding;
+#else
+  UNREACHABLE();
+  return false;
+#endif
 }
 
 intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 70a7636..37b7cef 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -10,12 +10,21 @@
 #error Do not include instructions_arm.h directly; use instructions.h instead.
 #endif
 
+#include "vm/allocation.h"
+#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants_arm.h"
-#include "vm/native_entry.h"
-#include "vm/object.h"
+#include "vm/native_function.h"
 
 namespace dart {
 
+class ICData;
+class Code;
+class Object;
+class ObjectPool;
+class RawCode;
+class RawICData;
+class RawObject;
+
 class InstructionPattern : public AllStatic {
  public:
   // Decodes a load sequence ending at 'end' (the last instruction of the
@@ -37,6 +46,14 @@
                                        Register* reg,
                                        intptr_t* value);
 
+  // Encodes a load immediate sequence ending at 'end' (the last instruction of
+  // the load sequence is the instruction before the one at end).
+  //
+  // Supports only a subset of [DecodeLoadWordImmediate], namely:
+  //   movw r, #lower16
+  //   movt r, #upper16
+  static void EncodeLoadWordImmediate(uword end, Register reg, intptr_t value);
+
   // Decodes a load sequence ending at 'end' (the last instruction of the
   // load sequence is the instruction before the one at end).  Returns the
   // address of the first instruction in the sequence.  Returns the register
@@ -160,6 +177,10 @@
 
 class PcRelativeCallPattern : public ValueObject {
  public:
+  // 24 bit signed integer which will get multiplied by 4.
+  static const intptr_t kLowerCallingRange = -(1 << 25);
+  static const intptr_t kUpperCallingRange = (1 << 25) - 1;
+
   explicit PcRelativeCallPattern(uword pc) : pc_(pc) {}
 
   static const int kLengthInBytes = 1 * Instr::kInstrSize;
@@ -188,34 +209,47 @@
   uword pc_;
 };
 
-class PcRelativeJumpPattern : public ValueObject {
+// 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
+// call is not in range for the "bl.<cond> <offset>" instruction, the AOT
+// compiler will emit a trampoline which is in range. That trampoline will
+// then tail-call to the final destination (also via PC-relative offset, but it
+// supports a full signed 32-bit offset).
+//
+// The pattern of the trampoline looks like:
+//
+//     movw TMP, #lower16
+//     movt TMP, #upper16
+//     add  PC, PC, TMP lsl #0
+//
+class PcRelativeTrampolineJumpPattern : public ValueObject {
  public:
-  explicit PcRelativeJumpPattern(uword pc) : pc_(pc) {}
-
-  static const int kLengthInBytes = 1 * Instr::kInstrSize;
-
-  int32_t distance() {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-    return Assembler::DecodeBranchOffset(*reinterpret_cast<int32_t*>(pc_));
-#else
-    UNREACHABLE();
-    return 0;
-#endif
+  explicit PcRelativeTrampolineJumpPattern(uword pattern_start)
+      : pattern_start_(pattern_start) {
+    USE(pattern_start_);
   }
 
-  void set_distance(int32_t distance) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-    int32_t* word = reinterpret_cast<int32_t*>(pc_);
-    *word = Assembler::EncodeBranchOffset(distance, *word);
-#else
-    UNREACHABLE();
-#endif
-  }
+  static const int kLengthInBytes = 3 * Instr::kInstrSize;
 
+  void Initialize();
+
+  int32_t distance();
+  void set_distance(int32_t distance);
   bool IsValid() const;
 
  private:
-  uword pc_;
+  // This offset must be applied to account for the fact that
+  //   a) the actual "branch" is only in the 3rd instruction
+  //   b) when reading the PC it reports current instruction + 8
+  static const intptr_t kDistanceOffset = -4 * Instr::kInstrSize;
+
+  // add  PC, PC, TMP lsl #0
+  static const uint32_t kAddPcEncoding =
+      (ADD << kOpcodeShift) | (AL << kConditionShift) | (PC << kRnShift) |
+      (PC << kRdShift) | (TMP << kRmShift);
+
+  uword pattern_start_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 2bf7c37..ea9a118 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -12,6 +12,7 @@
 #include "vm/constants_arm64.h"
 #include "vm/cpu.h"
 #include "vm/object.h"
+#include "vm/reverse_pc_lookup_cache.h"
 
 namespace dart {
 
@@ -318,7 +319,7 @@
       intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
       const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
       if (!pool.IsNull()) {
-        if (pool.TypeAt(index) == ObjectPool::kTaggedObject) {
+        if (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
           *obj = pool.ObjectAt(index);
           return true;
         }
@@ -443,7 +444,8 @@
 }
 
 void BareSwitchableCallPattern::SetTarget(const Code& target) const {
-  ASSERT(object_pool_.TypeAt(target_pool_index_) == ObjectPool::kImmediate);
+  ASSERT(object_pool_.TypeAt(target_pool_index_) ==
+         ObjectPool::EntryType::kImmediate);
   object_pool_.SetRawValueAt(target_pool_index_,
                              target.MonomorphicEntryPoint());
 }
@@ -464,11 +466,60 @@
   return (word >> 26) == branch_link;
 }
 
-bool PcRelativeJumpPattern::IsValid() const {
-  // b <offset>
-  const uint32_t word = *reinterpret_cast<uint32_t*>(pc_);
-  const uint32_t branch_nolink = 0x5;
-  return (word >> 26) == branch_nolink;
+void PcRelativeTrampolineJumpPattern::Initialize() {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  uint32_t* pattern = reinterpret_cast<uint32_t*>(pattern_start_);
+  pattern[0] = kAdrEncoding;
+  pattern[1] = kMovzEncoding;
+  pattern[2] = kAddTmpTmp2;
+  pattern[3] = kJumpEncoding;
+  set_distance(0);
+#else
+  UNREACHABLE();
+#endif
+}
+
+int32_t PcRelativeTrampolineJumpPattern::distance() {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  uint32_t* pattern = reinterpret_cast<uint32_t*>(pattern_start_);
+  const uint32_t adr = pattern[0];
+  const uint32_t movz = pattern[1];
+  const uint32_t lower16 =
+      (((adr >> 5) & ((1 << 19) - 1)) << 2) | ((adr >> 29) & 0x3);
+  const uint32_t higher16 = (movz >> kImm16Shift) & 0xffff;
+  return (higher16 << 16) | lower16;
+#else
+  UNREACHABLE();
+  return 0;
+#endif
+}
+
+void PcRelativeTrampolineJumpPattern::set_distance(int32_t distance) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  uint32_t* pattern = reinterpret_cast<uint32_t*>(pattern_start_);
+  uint32_t low16 = distance & 0xffff;
+  uint32_t high16 = (distance >> 16) & 0xffff;
+  pattern[0] = kAdrEncoding | ((low16 & 0x3) << 29) | ((low16 >> 2) << 5);
+  pattern[1] = kMovzEncoding | (high16 << kImm16Shift);
+  ASSERT(IsValid());
+#else
+  UNREACHABLE();
+#endif
+}
+
+bool PcRelativeTrampolineJumpPattern::IsValid() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  const uint32_t adr_mask = (3 << 29) | (((1 << 19) - 1) << 5);
+  const uint32_t movz_mask = 0xffff << 5;
+  uint32_t* pattern = reinterpret_cast<uint32_t*>(pattern_start_);
+  return (pattern[0] & ~adr_mask) == kAdrEncoding &
+             (pattern[1] & ~movz_mask) == kMovzEncoding &
+             pattern[2] == kAddTmpTmp2 &&
+         pattern[3] == kJumpEncoding;
+#else
+  UNREACHABLE();
+  return false;
+#endif
 }
 
 intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 18a8cc3..c78cee3 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -10,13 +10,20 @@
 #error Do not include instructions_arm64.h directly; use instructions.h instead.
 #endif
 
+#include "vm/allocation.h"
+#include "vm/compiler/assembler/assembler.h"
 #include "vm/constants_arm64.h"
-#include "vm/native_entry.h"
-#include "vm/object.h"
-#include "vm/reverse_pc_lookup_cache.h"
+#include "vm/native_function.h"
 
 namespace dart {
 
+class Code;
+class ICData;
+class ObjectPool;
+class RawCode;
+class RawICData;
+class RawObject;
+
 class InstructionPattern : public AllStatic {
  public:
   // Decodes a load sequence ending at 'end' (the last instruction of the
@@ -180,6 +187,10 @@
 
 class PcRelativeCallPattern : 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) {}
 
   static const int kLengthInBytes = 1 * Instr::kInstrSize;
@@ -208,34 +219,55 @@
   uword pc_;
 };
 
-class PcRelativeJumpPattern : public ValueObject {
+// 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
+// call is not in range for the "bl <offset>" instruction, the AOT compiler will
+// emit a trampoline which is in range. That trampoline will then tail-call to
+// the final destination (also via PC-relative offset, but it supports a full
+// signed 32-bit offset).
+//
+// The pattern of the trampoline looks like:
+//
+//     adr TMP, #lower16  (same as TMP = PC + #lower16)
+//     movz TMP2, #higher16 lsl 16
+//     add TMP, TMP, TMP2, SXTW
+//     br TMP
+//
+class PcRelativeTrampolineJumpPattern : public ValueObject {
  public:
-  explicit PcRelativeJumpPattern(uword pc) : pc_(pc) {}
-
-  static const int kLengthInBytes = 1 * Instr::kInstrSize;
-
-  int32_t distance() {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-    return Assembler::DecodeImm26BranchOffset(*reinterpret_cast<int32_t*>(pc_));
-#else
-    UNREACHABLE();
-    return 0;
-#endif
+  explicit PcRelativeTrampolineJumpPattern(uword pattern_start)
+      : pattern_start_(pattern_start) {
+    USE(pattern_start_);
   }
 
-  void set_distance(int32_t distance) {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-    int32_t* word = reinterpret_cast<int32_t*>(pc_);
-    *word = Assembler::EncodeImm26BranchOffset(distance, *word);
-#else
-    UNREACHABLE();
-#endif
-  }
+  static const int kLengthInBytes = 4 * Instr::kInstrSize;
 
+  void Initialize();
+
+  int32_t distance();
+  void set_distance(int32_t distance);
   bool IsValid() const;
 
  private:
-  uword pc_;
+  // This offset must be applied to account for the fact that
+  //   a) the actual "branch" is only in the 3rd instruction
+  //   b) when reading the PC it reports current instruction + 8
+  static const intptr_t kDistanceOffset = -5 * Instr::kInstrSize;
+
+  // adr TMP, #lower16  (same as TMP = PC + #lower16)
+  static const uint32_t kAdrEncoding = (1 << 28) | (TMP << kRdShift);
+
+  // movz TMP2, #higher16 lsl 16
+  static const uint32_t kMovzEncoding = MOVZ | (1 << kHWShift) | TMP2;
+
+  // add TMP, TMP, TMP2, SXTW
+  static const uint32_t kAddTmpTmp2 = 0x8b31c210;
+
+  // br TMP
+  static const uint32_t kJumpEncoding = BR | (TMP << kRnShift);
+
+  uword pattern_start_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc
index 377343b..b303e95 100644
--- a/runtime/vm/instructions_dbc.cc
+++ b/runtime/vm/instructions_dbc.cc
@@ -43,7 +43,7 @@
   Instr instr = SimulatorBytecode::At(pc);
   if (HasLoadFromPool(instr)) {
     uint16_t index = SimulatorBytecode::DecodeD(instr);
-    if (object_pool.TypeAt(index) == ObjectPool::kTaggedObject) {
+    if (object_pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
       *obj = object_pool.ObjectAt(index);
       return true;
     }
diff --git a/runtime/vm/instructions_ia32.h b/runtime/vm/instructions_ia32.h
index 2bf8510..ae82c3c 100644
--- a/runtime/vm/instructions_ia32.h
+++ b/runtime/vm/instructions_ia32.h
@@ -12,15 +12,9 @@
 
 #include "vm/allocation.h"
 #include "vm/cpu.h"
-#include "vm/object.h"
 
 namespace dart {
 
-// Forward declarations.
-class RawClass;
-class Immediate;
-class RawObject;
-
 // Template class for all instruction pattern classes.
 // P has to specify a static pattern and a pattern length method.
 template <class P>
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index d95e027..70ed255 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -38,7 +38,7 @@
         intptr_t index = IndexFromPPLoadDisp32(pc + 3);
         const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
         if (!pool.IsNull()) {
-          if (pool.TypeAt(index) == ObjectPool::kTaggedObject) {
+          if (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
             *obj = pool.ObjectAt(index);
             return true;
           }
@@ -48,7 +48,7 @@
         intptr_t index = IndexFromPPLoadDisp8(pc + 3);
         const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
         if (!pool.IsNull()) {
-          if (pool.TypeAt(index) == ObjectPool::kTaggedObject) {
+          if (pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) {
             *obj = pool.ObjectAt(index);
             return true;
           }
diff --git a/runtime/vm/instructions_x64.h b/runtime/vm/instructions_x64.h
index 8258214..da8f077 100644
--- a/runtime/vm/instructions_x64.h
+++ b/runtime/vm/instructions_x64.h
@@ -7,19 +7,13 @@
 #define RUNTIME_VM_INSTRUCTIONS_X64_H_
 
 #ifndef RUNTIME_VM_INSTRUCTIONS_H_
-#error Do not include instructions_ia32.h directly; use instructions.h instead.
+#error "Do not include instructions_x64.h directly; use instructions.h instead."
 #endif
 
 #include "vm/allocation.h"
-#include "vm/object.h"
 
 namespace dart {
 
-// Forward declarations.
-class RawClass;
-class Immediate;
-class RawObject;
-
 intptr_t IndexFromPPLoadDisp8(uword start);
 intptr_t IndexFromPPLoadDisp32(uword start);
 
@@ -115,6 +109,9 @@
 // callq *[rip+offset]
 class PcRelativeCallPattern : public InstructionPattern<PcRelativeCallPattern> {
  public:
+  static const intptr_t kLowerCallingRange = -(DART_UINT64_C(1) << 31);
+  static const intptr_t kUpperCallingRange = (DART_UINT64_C(1) << 31) - 1;
+
   explicit PcRelativeCallPattern(uword pc) : InstructionPattern(pc) {}
 
   int32_t distance() {
@@ -137,29 +134,50 @@
   static const int kLengthInBytes = 5;
 };
 
-// jmpq *[rip+offset]
-class PcRelativeJumpPattern : public InstructionPattern<PcRelativeJumpPattern> {
+// 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
+// call is not in range for the "bl.<cond> <offset>" instruction, the AOT
+// compiler will emit a trampoline which is in range. That trampoline will
+// then tail-call to the final destination (also via PC-relative offset, but it
+// supports a full signed 32-bit offset).
+//
+// The pattern of the trampoline looks like:
+//
+//     jmp $rip + <offset>
+//
+// (Strictly speaking the pc-relative call distance on X64 is big enough, but
+// for making AOT relocation code (i.e. relocation.cc) platform independent and
+// allow testing of trampolines on X64 we have it nonetheless)
+class PcRelativeTrampolineJumpPattern : public ValueObject {
  public:
-  explicit PcRelativeJumpPattern(uword pc) : InstructionPattern(pc) {}
+  static const int kLengthInBytes = 5;
+
+  explicit PcRelativeTrampolineJumpPattern(uword pattern_start)
+      : pattern_start_(pattern_start) {}
+
+  void Initialize() {
+    uint8_t* pattern = reinterpret_cast<uint8_t*>(pattern_start_);
+    pattern[0] = 0xe9;
+  }
 
   int32_t distance() {
-    return *reinterpret_cast<int32_t*>(start() + 2) + kLengthInBytes;
+    return *reinterpret_cast<int32_t*>(pattern_start_ + 1) + kLengthInBytes;
   }
 
   void set_distance(int32_t distance) {
     // [distance] is relative to the start of the instruction, x64 considers the
     // offset relative to next PC.
-    *reinterpret_cast<int32_t*>(start() + 2) = distance - kLengthInBytes;
+    *reinterpret_cast<int32_t*>(pattern_start_ + 1) = distance - kLengthInBytes;
   }
 
-  static const int* pattern() {
-    static const int kPattern[kLengthInBytes] = {0xff, 0x25, -1, -1, -1, -1};
-    return kPattern;
+  bool IsValid() const {
+    uint8_t* pattern = reinterpret_cast<uint8_t*>(pattern_start_);
+    return pattern[0] == 0xe9;
   }
 
-  static int pattern_length_in_bytes() { return kLengthInBytes; }
-
-  static const int kLengthInBytes = 6;
+ private:
+  uword pattern_start_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 1e1c0f1..1500348 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -813,8 +813,7 @@
   callee_fp[kKBCSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(*pc);
   callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
   pp_ = bytecode->ptr()->object_pool_;
-  *pc =
-      reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_->ptr()->data_);
+  *pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
   pc_ = reinterpret_cast<uword>(*pc);  // For the profiler.
   *FP = callee_fp;
   fp_ = callee_fp;  // For the profiler.
@@ -909,7 +908,7 @@
 
   const intptr_t kCheckedArgs = 1;
   RawObject** args = call_base;
-  RawArray* cache = icdata->ptr()->ic_data_->ptr();
+  RawArray* cache = icdata->ptr()->entries_->ptr();
 
   const intptr_t type_args_len =
       InterpreterHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_);
@@ -954,7 +953,7 @@
 
   const intptr_t kCheckedArgs = 2;
   RawObject** args = call_base;
-  RawArray* cache = icdata->ptr()->ic_data_->ptr();
+  RawArray* cache = icdata->ptr()->entries_->ptr();
 
   const intptr_t type_args_len =
       InterpreterHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_);
@@ -1388,8 +1387,7 @@
 
   // Ready to start executing bytecode. Load entry point and corresponding
   // object pool.
-  pc =
-      reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_->ptr()->data_);
+  pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
   pc_ = reinterpret_cast<uword>(pc);  // For the profiler.
   fp_ = FP;                           // For the profiler.
   pp_ = bytecode->ptr()->object_pool_;
@@ -1805,12 +1803,14 @@
   {
     BYTECODE(IndirectStaticCall, A_D);
 
+#ifndef PRODUCT
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     // Invoke target function.
     {
@@ -1818,7 +1818,7 @@
       // Look up the function in the ICData.
       RawObject* ic_data_obj = SP[0];
       RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
-      RawObject** data = ic_data->ptr()->ic_data_->ptr()->data();
+      RawObject** data = ic_data->ptr()->entries_->ptr()->data();
       InterpreterHelpers::IncrementICUsageCount(data, 0, 0);
       SP[0] = data[ICData::TargetIndexFor(ic_data->ptr()->state_bits_ & 0x3)];
       RawObject** call_base = SP - argc;
@@ -1833,14 +1833,46 @@
   }
 
   {
-    BYTECODE(InterfaceCall, A_D);
+    BYTECODE(DirectCall, A_D);
 
+#ifndef PRODUCT
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
+
+    // Invoke target function.
+    {
+      const uint16_t argc = rA;
+      const uint16_t kidx = rD;
+
+      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));
+      if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
+        HANDLE_EXCEPTION;
+      }
+    }
+
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(InterfaceCall, A_D);
+
+#ifndef PRODUCT
+    // Check if single stepping.
+    if (thread->isolate()->single_step()) {
+      Exit(thread, FP, SP + 1, pc);
+      NativeArguments args(thread, 0, NULL, NULL);
+      INVOKE_RUNTIME(DRT_SingleStepHandler, args);
+    }
+#endif  // !PRODUCT
 
     {
       const uint16_t argc = rA;
@@ -1864,12 +1896,14 @@
   {
     BYTECODE(DynamicCall, A_D);
 
+#ifndef PRODUCT
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     {
       const uint16_t argc = rA;
diff --git a/runtime/vm/intrusive_dlist.h b/runtime/vm/intrusive_dlist.h
new file mode 100644
index 0000000..45c4365
--- /dev/null
+++ b/runtime/vm/intrusive_dlist.h
@@ -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.
+
+#ifndef RUNTIME_VM_INTRUSIVE_DLIST_H_
+#define RUNTIME_VM_INTRUSIVE_DLIST_H_
+
+#include "platform/assert.h"
+#include "platform/globals.h"
+
+namespace dart {
+
+// Abstraction for "intrusive" doubly-linked list in a type-safe way in C++.
+//
+// By "intrusive" we mean that a class Item containing various field members
+// has also next/previous pointers to the next/previous Item.
+//
+// To change a class Item to be part of such a doubly-linked list, one only
+// needs to inherit from IntrusiveDListEntry<Item> (in addition to the normal
+// base class).
+//
+// To change a class Item to be part of multiple doubly-linked lists, one can
+// inherit multiple times from IntrusiveDListEntry<Item, N>, each time with a
+// different value for <N>.
+//
+// To insert an object into a list, one uses a IntrusiveDList<Item, N>. It
+// provides support for insertion/iteration/deletion.
+//
+// Usage example:
+//
+//    class Base {
+//      <arbitrary state here>
+//    };
+//
+//    class Item : public Base,
+//                 public IntrusiveDListEntry<Item>,
+//                 public IntrusiveDListEntry<Item, 2> {
+//      <arbitrary state here>
+//    };
+//
+//    Item a1, a2, a3;
+//
+//    IntrusiveDList<Item> all;
+//    all.Append(a2);
+//    all.Prepend(a1);
+//    all.Append(a3);
+//
+//    IntrusiveDList<Item, 2> idle, ready;
+//    idle.Append(a1);
+//    ready.Append(a2);
+//    ready.Append(a3);
+//
+
+template <typename T, int N>
+class IntrusiveDList;
+
+template <typename T, int N = 1>
+class IntrusiveDListEntry {
+ public:
+  IntrusiveDListEntry() {}
+
+  ~IntrusiveDListEntry() {
+    // Either this is an unlinked entry or a head/anchor.
+    ASSERT((next_ == nullptr && prev_ == nullptr) ||
+           (next_ == this && prev_ == this));
+  }
+
+ private:
+  void MakeHead() {
+    ASSERT(next_ == nullptr && prev_ == nullptr);
+    next_ = prev_ = this;
+  }
+
+  // This uses the C++ compiler's ability to convert between classes inside a
+  // (possibly multi-) inheritance hierarchy.
+  //
+  // The non-typesafe C equivalent of this is:
+  //
+  //     ((uint8*)this) - offsetof(ContainerType, list_entry);
+  //
+  T* container() { return static_cast<T*>(this); }
+
+  void Append(IntrusiveDListEntry<T, N>* entry) {
+    ASSERT(entry->next_ == nullptr && entry->prev_ == nullptr);
+    entry->next_ = next_;
+    entry->prev_ = this;
+    next_ = entry;
+    entry->next_->prev_ = entry;
+  }
+
+  void Prepend(IntrusiveDListEntry<T, N>* entry) {
+    ASSERT(entry->next_ == nullptr && entry->prev_ == nullptr);
+    entry->next_ = this;
+    entry->prev_ = prev_;
+    prev_ = entry;
+    entry->prev_->next_ = entry;
+  }
+
+  void Remove() {
+    ASSERT(prev_->next_ == this);
+    ASSERT(next_->prev_ == this);
+    ASSERT(prev_ != this && next_ != this);
+
+    prev_->next_ = next_;
+    next_->prev_ = prev_;
+
+    next_ = nullptr;
+    prev_ = nullptr;
+  }
+
+  bool IsEmpty() {
+    bool result = next_ == this;
+    ASSERT(result == (prev_ == this));
+    return result;
+  }
+
+  bool IsLinked() {
+    ASSERT((next_ == nullptr) == (prev_ == nullptr));
+    return next_ != nullptr;
+  }
+
+  IntrusiveDListEntry<T, N>* Prev() { return prev_; }
+
+  IntrusiveDListEntry<T, N>* Next() { return next_; }
+
+  friend class IntrusiveDList<T, N>;
+
+  IntrusiveDListEntry<T, N>* next_ = nullptr;
+  IntrusiveDListEntry<T, N>* prev_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(IntrusiveDListEntry);
+};
+
+template <typename T, int N = 1>
+class IntrusiveDList {
+ public:
+  typedef IntrusiveDListEntry<T, N> Entry;
+
+  template <typename ContainerType, int I = 1>
+  class Iterator {
+   public:
+    Iterator(IntrusiveDList<ContainerType, I>* head,
+             IntrusiveDListEntry<ContainerType, I>* entry)
+        : head_(head), entry_(entry) {}
+
+    inline ContainerType* operator->() { return entry_->container(); }
+
+    inline ContainerType* operator*() { return entry_->container(); }
+
+    inline bool operator==(const Iterator<ContainerType, I>& other) const {
+      return entry_ == other.entry_;
+    }
+
+    inline bool operator!=(const Iterator<ContainerType, I>& other) const {
+      return !(*this == other);
+    }
+
+    inline Iterator<ContainerType, I>& operator++() {
+      entry_ = entry_->Next();
+      return *this;
+    }
+
+    inline Iterator<ContainerType, I>& operator--() {
+      entry_ = entry_->Prev();
+      return *this;
+    }
+
+   private:
+    friend IntrusiveDList;
+
+    IntrusiveDList<ContainerType, I>* head_;
+    IntrusiveDListEntry<ContainerType, I>* entry_;
+  };
+
+  inline IntrusiveDList() { head_.MakeHead(); }
+
+  inline void Append(T* a) { head_.Prepend(convert(a)); }
+
+  inline void Prepend(T* a) { head_.Append(convert(a)); }
+
+  // NOTE: This function only checks whether [a] is linked inside *a*
+  // [IntrusiveDList].
+  inline bool IsInList(T* a) { return convert(a)->IsLinked(); }
+
+  inline void Remove(T* a) { convert(a)->Remove(); }
+
+  inline bool IsEmpty() { return head_.IsEmpty(); }
+
+  inline T* First() {
+    ASSERT(!IsEmpty());
+    return head_.Next()->container();
+  }
+
+  inline T* Last() {
+    ASSERT(!IsEmpty());
+    return head_.Prev()->container();
+  }
+
+  inline T* RemoveFirst() {
+    ASSERT(!IsEmpty());
+    auto entry = head_.Next();
+    T* container = entry->container();
+    entry->Remove();
+    return container;
+  }
+
+  inline T* RemoveLast() {
+    ASSERT(!IsEmpty());
+    auto entry = head_.Prev();
+    T* container = entry->container();
+    entry->Remove();
+    return container;
+  }
+
+  inline Iterator<T, N> Begin() { return Iterator<T, N>(this, head_.Next()); }
+
+  inline Iterator<T, N> End() { return Iterator<T, N>(this, &head_); }
+
+  inline Iterator<T, N> begin() { return Begin(); }
+
+  inline Iterator<T, N> end() { return End(); }
+
+  inline Iterator<T, N> Erase(const Iterator<T, N>& iterator) {
+    ASSERT(iterator.head_ == this);
+    Iterator<T, N> next(this, iterator.entry_->Next());
+    iterator.entry_->Remove();
+    return next;
+  }
+
+ private:
+  Entry head_;
+
+  Entry* convert(T* entry) { return static_cast<Entry*>(entry); }
+};
+
+}  // namespace dart.
+
+#endif  // RUNTIME_VM_INTRUSIVE_DLIST_H_
diff --git a/runtime/vm/intrusive_dlist_test.cc b/runtime/vm/intrusive_dlist_test.cc
new file mode 100644
index 0000000..fdf72c0
--- /dev/null
+++ b/runtime/vm/intrusive_dlist_test.cc
@@ -0,0 +1,155 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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/intrusive_dlist.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+class Base {
+ public:
+  explicit Base(int arg) : base(arg) {}
+
+  int base;
+};
+
+class Item : public Base,
+             public IntrusiveDListEntry<Item>,
+             public IntrusiveDListEntry<Item, 2> {
+ public:
+  explicit Item(int arg0, int arg1) : Base(arg0), item(arg1) {}
+
+  int item;
+};
+
+UNIT_TEST_CASE(IntrusiveDListMultiEntryTest) {
+  Item a1(1, 11), a2(2, 12), a3(3, 13);
+
+  IntrusiveDList<Item> all;
+  IntrusiveDList<Item, 2> ready;
+
+  EXPECT(all.IsEmpty());
+  EXPECT(ready.IsEmpty());
+
+  all.Append(&a2);
+  all.Append(&a3);
+  all.Prepend(&a1);
+  EXPECT_EQ(all.First()->item, 11);
+  EXPECT_EQ(all.Last()->item, 13);
+
+  ready.Append(&a1);
+  ready.Append(&a2);
+  EXPECT_EQ(ready.First()->item, 11);
+  EXPECT_EQ(ready.Last()->item, 12);
+
+  int i = 0;
+  for (auto it = all.Begin(); it != all.End(); ++it) {
+    i++;
+    EXPECT_EQ(it->base, i);
+    EXPECT_EQ((*it)->base, i);
+    EXPECT_EQ(it->item, 10 + i);
+    EXPECT_EQ((*it)->item, 10 + i);
+  }
+  EXPECT_EQ(i, 3);
+
+  i = 0;
+  for (auto it = ready.Begin(); it != ready.End(); ++it) {
+    i++;
+    EXPECT_EQ(it->base, i);
+    EXPECT_EQ((*it)->base, i);
+    EXPECT_EQ(it->item, 10 + i);
+    EXPECT_EQ((*it)->item, 10 + i);
+  }
+  EXPECT_EQ(i, 2);
+
+  ready.Remove(&a1);
+  ready.Remove(&a2);
+
+  all.Remove(&a1);
+  all.Remove(&a2);
+  all.Remove(&a3);
+
+  EXPECT(all.IsEmpty());
+  EXPECT(ready.IsEmpty());
+}
+
+UNIT_TEST_CASE(IntrusiveDListRemoveFirstTest) {
+  Item a1(1, 11), a2(2, 12), a3(3, 13);
+
+  IntrusiveDList<Item> all;
+
+  all.Append(&a2);
+  all.Append(&a3);
+  all.Prepend(&a1);
+
+  EXPECT_EQ(&a1, all.RemoveFirst());
+  EXPECT_EQ(&a2, all.RemoveFirst());
+  EXPECT_EQ(&a3, all.RemoveFirst());
+
+  EXPECT(all.IsEmpty());
+}
+
+UNIT_TEST_CASE(IntrusiveDListRemoveLastTest) {
+  Item a1(1, 11), a2(2, 12), a3(3, 13);
+
+  IntrusiveDList<Item> all;
+
+  all.Append(&a2);
+  all.Append(&a3);
+  all.Prepend(&a1);
+
+  EXPECT_EQ(&a3, all.RemoveLast());
+  EXPECT_EQ(&a2, all.RemoveLast());
+  EXPECT_EQ(&a1, all.RemoveLast());
+  EXPECT(all.IsEmpty());
+}
+
+UNIT_TEST_CASE(IntrusiveDListIsInList) {
+  Item a1(1, 11), a2(2, 12), a3(3, 13);
+
+  IntrusiveDList<Item> all;
+
+  all.Append(&a2);
+  all.Append(&a3);
+  all.Prepend(&a1);
+
+  ASSERT(all.IsInList(&a1));
+  ASSERT(all.IsInList(&a2));
+  ASSERT(all.IsInList(&a3));
+
+  EXPECT_EQ(&a1, all.RemoveFirst());
+  EXPECT(!all.IsInList(&a1));
+  EXPECT_EQ(&a3, all.RemoveLast());
+  EXPECT(!all.IsInList(&a3));
+  EXPECT_EQ(&a2, all.RemoveFirst());
+  EXPECT(!all.IsInList(&a2));
+
+  EXPECT(all.IsEmpty());
+}
+
+UNIT_TEST_CASE(IntrusiveDListEraseIterator) {
+  Item a1(1, 11), a2(2, 12), a3(3, 13);
+
+  IntrusiveDList<Item> all;
+
+  all.Append(&a2);
+  all.Append(&a3);
+  all.Prepend(&a1);
+
+  auto it = all.Begin();
+  it = all.Erase(++it);
+  EXPECT_EQ(*it, &a3);
+  EXPECT_EQ(*it, all.Last());
+
+  it = all.Erase(all.Begin());
+  EXPECT_EQ(*it, &a3);
+  EXPECT_EQ(*it, all.First());
+  EXPECT_EQ(*it, all.Last());
+
+  it = all.Erase(all.Begin());
+  EXPECT(it == all.End());
+  EXPECT(all.IsEmpty());
+}
+
+}  // namespace dart.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 7f1e8a2..6be1715 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -89,10 +89,8 @@
     FLAG_random_seed = 0x44617274;  // "Dart"
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
     FLAG_load_deferred_eagerly = true;
-    FLAG_print_stop_message = false;  // Embedds addresses in instructions.
 #else
     COMPILE_ASSERT(FLAG_load_deferred_eagerly);
-    COMPILE_ASSERT(!FLAG_print_stop_message);
 #endif
   }
 }
@@ -496,7 +494,7 @@
   StackZone stack_zone(thread);
   Zone* zone = stack_zone.GetZone();
   HandleScope handle_scope(thread);
-#ifndef PRODUCT
+#if defined(SUPPORT_TIMELINE)
   TimelineDurationScope tds(
       thread, Timeline::GetIsolateStream(),
       message->IsOOB() ? "HandleOOBMessage" : "HandleMessage");
@@ -1359,16 +1357,16 @@
     ASSERT(this == state->isolate());
     Run();
   }
-#ifndef PRODUCT
-  if (FLAG_support_timeline) {
-    TimelineStream* stream = Timeline::GetIsolateStream();
-    ASSERT(stream != NULL);
-    TimelineEvent* event = stream->StartEvent();
-    if (event != NULL) {
-      event->Instant("Runnable");
-      event->Complete();
-    }
+#if defined(SUPPORT_TIMELINE)
+  TimelineStream* stream = Timeline::GetIsolateStream();
+  ASSERT(stream != NULL);
+  TimelineEvent* event = stream->StartEvent();
+  if (event != NULL) {
+    event->Instant("Runnable");
+    event->Complete();
   }
+#endif
+#ifndef PRODUCT
   if (FLAG_support_service && !Isolate::IsVMInternalIsolate(this) &&
       Service::isolate_stream.enabled()) {
     ServiceEvent runnableEvent(this, ServiceEvent::kIsolateRunnable);
@@ -1815,15 +1813,15 @@
   // Fail fast if anybody tries to post any more messages to this isolate.
   delete message_handler();
   set_message_handler(NULL);
-  if (FLAG_support_timeline) {
-    // Before analyzing the isolate's timeline blocks- reclaim all cached
-    // blocks.
-    Timeline::ReclaimCachedBlocksFromThreads();
-  }
+#if defined(SUPPORT_TIMELINE)
+  // Before analyzing the isolate's timeline blocks- reclaim all cached
+  // blocks.
+  Timeline::ReclaimCachedBlocksFromThreads();
+#endif
 
 // Dump all timing data for the isolate.
-#ifndef PRODUCT
-  if (FLAG_support_timeline && FLAG_timing) {
+#if defined(SUPPORT_TIMELINE) && !defined(PRODUCT)
+  if (FLAG_timing) {
     TimelinePauseTrace tpt;
     tpt.Print();
   }
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index ffa2a03..086831b 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_ISOLATE_H_
 #define RUNTIME_VM_ISOLATE_H_
 
+#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
+#error "Should not include runtime"
+#endif
+
 #include "include/dart_api.h"
 #include "platform/assert.h"
 #include "platform/atomic.h"
@@ -139,8 +143,6 @@
 //
 #define ISOLATE_FLAG_LIST(V)                                                   \
   V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
-  V(PRODUCT, use_bare_instructions, Bare, use_bare_instructions,               \
-    FLAG_use_bare_instructions)                                                \
   V(NONPRODUCT, use_field_guards, UseFieldGuards, use_field_guards,            \
     FLAG_use_field_guards)                                                     \
   V(NONPRODUCT, use_osr, UseOsr, use_osr, FLAG_use_osr)                        \
@@ -374,7 +376,6 @@
     ASSERT(debugger_ != NULL);
     return debugger_;
   }
-#endif
 
   void set_single_step(bool value) { single_step_ = value; }
   bool single_step() const { return single_step_; }
@@ -382,7 +383,6 @@
     return OFFSET_OF(Isolate, single_step_);
   }
 
-#if !defined(PRODUCT)
   bool ResumeRequest() const {
     return ResumeRequestBit::decode(isolate_flags_);
   }
@@ -885,7 +885,6 @@
   V(EnableAsserts)                                                             \
   V(ErrorOnBadType)                                                            \
   V(ErrorOnBadOverride)                                                        \
-  V(Bare)                                                                      \
   V(UseFieldGuards)                                                            \
   V(UseOsr)                                                                    \
   V(Obfuscate)                                                                 \
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 81b77be..381a50b 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -2269,10 +2269,14 @@
 
       interface_types = cls.interfaces();
       if (!interface_types.IsNull()) {
+        const intptr_t mixin_index = cls.is_transformed_mixin_application()
+                                         ? interface_types.Length() - 1
+                                         : -1;
         for (intptr_t j = 0; j < interface_types.Length(); ++j) {
           interface_type ^= interface_types.At(j);
           interface_class = interface_type.type_class();
-          interface_class.AddDirectImplementor(cls);
+          interface_class.AddDirectImplementor(
+              cls, /* is_mixin = */ i == mixin_index);
         }
       }
     }
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index c5d5442..edf12af 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -298,6 +298,7 @@
   auto& temp_function = Function::Handle(zone);
   for (intptr_t i = 0; i < libs.Length(); i++) {
     lib ^= libs.At(i);
+    lib.EnsureTopLevelClassIsFinalized();
     DictionaryIterator it(lib);
     while (it.HasNext()) {
       entry = it.GetNext();
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index 5440ddf..2dd239e 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -38,10 +38,11 @@
     "Invalid kernel binary: Indicated size is invalid";
 
 Program* Program::ReadFrom(Reader* reader, const char** error) {
-  if (reader->size() < 59) {
+  if (reader->size() < 60) {
     // A kernel file currently contains at least the following:
     //   * Magic number (32)
     //   * Kernel version (32)
+    //   * List of problems (8)
     //   * Length of source map (32)
     //   * Length of canonical name table (8)
     //   * Metadata length (32)
@@ -49,7 +50,7 @@
     //   * Length of constant table (8)
     //   * Component index (10 * 32)
     //
-    // so is at least 59 bytes.
+    // so is at least 60 bytes.
     // (Technically it will also contain an empty entry in both source map and
     // string table, taking up another 8 bytes.)
     if (error != nullptr) {
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 4710aad..85ed239 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -17,7 +17,7 @@
 // package:kernel/binary.md.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 16;
+static const uint32_t kBinaryFormatVersion = 18;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -149,10 +149,7 @@
   kTypeLiteralConstant = 11,
   // These constants are not expected to be seen by the VM, because all
   // constants are fully evaluated.
-  kEnvironmentBoolConstant = 12,
-  kEnvironmentIntConstant = 13,
-  kEnvironmentStringConstant = 14,
-  kUnevaluatedConstant = 15,
+  kUnevaluatedConstant = 12,
 };
 
 static const int SpecializedIntLiteralBias = 3;
@@ -248,7 +245,12 @@
 
   intptr_t ReadSLEB128() {
     const uint8_t* buffer = this->buffer();
-    return Utils::DecodeSLEB128(buffer, size_, &offset_);
+    return Utils::DecodeSLEB128<intptr_t>(buffer, size_, &offset_);
+  }
+
+  int64_t ReadSLEB128AsInt64() {
+    const uint8_t* buffer = this->buffer();
+    return Utils::DecodeSLEB128<int64_t>(buffer, size_, &offset_);
   }
 
   /**
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 693078c..ab90491 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -71,9 +71,9 @@
  public:
   virtual void Run() {
     ASSERT(Isolate::Current() == NULL);
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
     TimelineDurationScope tds(Timeline::GetVMStream(), "KernelIsolateStartup");
-#endif  // !PRODUCT
+#endif  // SUPPORT_TIMELINE
     char* error = NULL;
     Isolate* isolate = NULL;
 
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 43a4dbe..9817832 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -112,6 +112,15 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleExpressionConverter);
 };
 
+RawArray* 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++) {
+    res.SetAt(i, *fields_[i]);
+  }
+  return res.raw();
+}
+
 RawArray* KernelLoader::MakeFunctionsArray() {
   const intptr_t len = functions_.length();
   const Array& res = Array::Handle(zone_, Array::New(len, Heap::kOld));
@@ -185,7 +194,7 @@
               0),
       type_translator_(&helper_, &active_class_, /* finalize= */ false),
       inferred_type_metadata_helper_(&helper_),
-      bytecode_metadata_helper_(&helper_, &type_translator_, &active_class_),
+      bytecode_metadata_helper_(&helper_, &active_class_),
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
@@ -211,6 +220,7 @@
 Object& KernelLoader::LoadEntireProgram(Program* program,
                                         bool process_pending_classes) {
   Thread* thread = Thread::Current();
+  TIMELINE_DURATION(thread, Isolate, "LoadKernel");
 
   if (program->is_single_program()) {
     KernelLoader loader(program);
@@ -369,7 +379,7 @@
       helper_(zone_, &translation_helper_, script, kernel_data, 0),
       type_translator_(&helper_, &active_class_, /* finalize= */ false),
       inferred_type_metadata_helper_(&helper_),
-      bytecode_metadata_helper_(&helper_, &type_translator_, &active_class_),
+      bytecode_metadata_helper_(&helper_, &active_class_),
       external_name_class_(Class::Handle(Z)),
       external_name_field_(Field::Handle(Z)),
       potential_natives_(GrowableObjectArray::Handle(Z)),
@@ -621,6 +631,7 @@
 
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
+    // Note that `problemsAsJson` on Component is implicitly skipped.
     const intptr_t length = program_->library_count();
     Object& last_library = Library::Handle(Z);
     for (intptr_t i = 0; i < length; i++) {
@@ -889,7 +900,6 @@
 
   LibraryIndex library_index(library_kernel_data_);
   intptr_t class_count = library_index.class_count();
-  intptr_t procedure_count = library_index.procedure_count();
 
   library_helper.ReadUntilIncluding(LibraryHelper::kName);
   library.SetName(H.DartSymbolObfuscate(library_helper.name_index_));
@@ -958,13 +968,47 @@
       classes.Add(klass, Heap::kOld);
     }
   }
-  helper_.SetOffset(next_class_offset);
+
+  if (loading_native_wrappers_library_ || !register_class) {
+    FinishTopLevelClassLoading(toplevel_class, library, library_index);
+  }
+
+  if (FLAG_enable_mirrors && annotation_count > 0) {
+    ASSERT(annotations_kernel_offset > 0);
+    library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource,
+                               annotations_kernel_offset);
+  }
+
+  if (register_class) {
+    classes.Add(toplevel_class, Heap::kOld);
+  }
+  if (!library.Loaded()) library.SetLoaded();
+
+  return library.raw();
+}
+
+void KernelLoader::FinishTopLevelClassLoading(
+    const Class& toplevel_class,
+    const Library& library,
+    const LibraryIndex& library_index) {
+  if (toplevel_class.is_loaded()) {
+    return;
+  }
+
+  TIMELINE_DURATION(Thread::Current(), Isolate, "FinishTopLevelClassLoading");
+
+  // Offsets within library index are whole program offsets and not
+  // relative to the library.
+  const intptr_t correction = correction_offset_ - library_kernel_offset_;
+  helper_.SetOffset(library_index.ClassOffset(library_index.class_count()) +
+                    correction);
 
   fields_.Clear();
   functions_.Clear();
   ActiveClassScope active_class_scope(&active_class_, &toplevel_class);
+
   // Load toplevel fields.
-  intptr_t field_count = helper_.ReadListLength();  // read list length.
+  const intptr_t field_count = helper_.ReadListLength();  // read list length.
   for (intptr_t i = 0; i < field_count; ++i) {
     intptr_t field_offset = helper_.ReaderOffset() - correction_offset_;
     ActiveMemberScope active_member_scope(&active_class_, NULL);
@@ -991,7 +1035,7 @@
     // In the VM all const fields are implicitly final whereas in Kernel they
     // are not final because they are not explicitly declared that way.
     const bool is_final = field_helper.IsConst() || field_helper.IsFinal();
-    Field& field = Field::Handle(
+    const Field& field = Field::Handle(
         Z,
         Field::NewTopLevel(name, is_final, field_helper.IsConst(), script_class,
                            field_helper.position_, field_helper.end_position_));
@@ -1015,31 +1059,45 @@
       library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset);
     }
     fields_.Add(&field);
-    library.AddObject(field, name);
   }
-  toplevel_class.AddFields(fields_);
+
+  ASSERT(!toplevel_class.is_loaded());
 
   // Load toplevel procedures.
-  intptr_t next_procedure_offset = library_index.ProcedureOffset(0);
+  intptr_t next_procedure_offset =
+      library_index.ProcedureOffset(0) + correction;
+  const intptr_t procedure_count = library_index.procedure_count();
   for (intptr_t i = 0; i < procedure_count; ++i) {
     helper_.SetOffset(next_procedure_offset);
-    next_procedure_offset = library_index.ProcedureOffset(i + 1);
+    next_procedure_offset = library_index.ProcedureOffset(i + 1) + correction;
     LoadProcedure(library, toplevel_class, false, next_procedure_offset);
+    // LoadProcedure calls Library::GetMetadata which invokes Dart code
+    // which may recursively trigger class finalization and
+    // FinishTopLevelClassLoading.
+    // In such case, return immediately and avoid overwriting already finalized
+    // functions with freshly loaded and not yet finalized.
+    if (toplevel_class.is_loaded()) {
+      return;
+    }
   }
 
-  if (FLAG_enable_mirrors && annotation_count > 0) {
-    ASSERT(annotations_kernel_offset > 0);
-    library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource,
-                               annotations_kernel_offset);
-  }
-
+  toplevel_class.SetFields(Array::Handle(MakeFieldsArray()));
   toplevel_class.SetFunctions(Array::Handle(MakeFunctionsArray()));
-  if (register_class) {
-    classes.Add(toplevel_class, Heap::kOld);
-  }
-  if (!library.Loaded()) library.SetLoaded();
 
-  return library.raw();
+  String& name = String::Handle(Z);
+  for (intptr_t i = 0, n = fields_.length(); i < n; ++i) {
+    const Field* field = fields_.At(i);
+    name = field->name();
+    library.AddObject(*field, name);
+  }
+  for (intptr_t i = 0, n = functions_.length(); i < n; ++i) {
+    const Function* function = functions_.At(i);
+    name = function->name();
+    library.AddObject(*function, name);
+  }
+
+  ASSERT(!toplevel_class.is_loaded());
+  toplevel_class.set_is_loaded(true);
 }
 
 void KernelLoader::LoadLibraryImportsAndExports(Library* library,
@@ -1107,6 +1165,10 @@
         target_library.url() == Symbols::DartMirrors().raw()) {
       H.ReportError("import of dart:mirrors with --enable-mirrors=false");
     }
+    if (!Api::ffiEnabled() &&
+        target_library.url() == Symbols::DartFfi().raw()) {
+      H.ReportError("import of dart:ffi with --enable-ffi=false");
+    }
     String& prefix = H.DartSymbolPlain(dependency_helper.name_index_);
     ns = Namespace::New(target_library, show_names, hide_names);
     if (dependency_helper.flags_ & LibraryDependencyHelper::Export) {
@@ -1336,6 +1398,12 @@
                                       intptr_t class_offset,
                                       const ClassIndex& class_index,
                                       ClassHelper* class_helper) {
+  if (klass.is_loaded()) {
+    return;
+  }
+
+  TIMELINE_DURATION(Thread::Current(), Isolate, "FinishClassLoading");
+
   fields_.Clear();
   functions_.Clear();
   ActiveClassScope active_class_scope(&active_class_, &klass);
@@ -1421,7 +1489,7 @@
           TokenPosition::kNoSource, TokenPosition::kNoSource);
       fields_.Add(&deleted_enum_sentinel);
     }
-    klass.AddFields(fields_);
+    klass.SetFields(Array::Handle(Z, MakeFieldsArray()));
   }
 
   class_helper->ReadUntilExcluding(ClassHelper::kConstructors);
@@ -1496,6 +1564,8 @@
     }
   }
 
+  ASSERT(!klass.is_loaded());
+
   // Everything up til the procedures are skipped implicitly, and class_helper
   // is no longer used.
 
@@ -1509,13 +1579,23 @@
     helper_.SetOffset(next_procedure_offset);
     next_procedure_offset = class_index.ProcedureOffset(i + 1) + correction;
     LoadProcedure(library, klass, true, next_procedure_offset);
+    // LoadProcedure calls Library::GetMetadata which invokes Dart code
+    // which may recursively trigger class finalization and FinishClassLoading.
+    // In such case, return immediately and avoid overwriting already finalized
+    // functions with freshly loaded and not yet finalized.
+    if (klass.is_loaded()) {
+      return;
+    }
   }
 
   klass.SetFunctions(Array::Handle(MakeFunctionsArray()));
+
+  ASSERT(!klass.is_loaded());
+  klass.set_is_loaded(true);
 }
 
 void KernelLoader::FinishLoading(const Class& klass) {
-  ASSERT(klass.kernel_offset() > 0);
+  ASSERT(klass.IsTopLevel() || (klass.kernel_offset() > 0));
 
   Zone* zone = Thread::Current()->zone();
   const Script& script = Script::Handle(zone, klass.script());
@@ -1527,10 +1607,17 @@
   const intptr_t library_kernel_offset = library.kernel_offset();
   ASSERT(library_kernel_offset > 0);
 
-  const intptr_t class_offset = klass.kernel_offset();
   KernelLoader kernel_loader(script, library_kernel_data,
                              library_kernel_offset);
   LibraryIndex library_index(library_kernel_data);
+
+  if (klass.IsTopLevel()) {
+    ASSERT(klass.raw() == toplevel_class.raw());
+    kernel_loader.FinishTopLevelClassLoading(klass, library, library_index);
+    return;
+  }
+
+  const intptr_t class_offset = klass.kernel_offset();
   ClassIndex class_index(
       library_kernel_data, class_offset,
       // Class offsets in library index are whole program offsets.
@@ -1761,14 +1848,6 @@
   // function_node_helper are no longer used.
   helper_.SetOffset(procedure_end);
 
-  if (!in_class) {
-    library.AddObject(function, name);
-    ASSERT(!Object::Handle(
-                Z, library.LookupObjectAllowPrivate(
-                       H.DartProcedureName(procedure_helper.canonical_name_)))
-                .IsNull());
-  }
-
   if (annotation_count > 0) {
     library.AddFunctionMetadata(function, TokenPosition::kNoSource,
                                 procedure_offset);
@@ -2094,6 +2173,9 @@
 RawFunction* CreateFieldInitializerFunction(Thread* thread,
                                             Zone* zone,
                                             const Field& field) {
+  if (field.Initializer() != Function::null()) {
+    return field.Initializer();
+  }
   String& init_name = String::Handle(zone, field.name());
   init_name = Symbols::FromConcat(thread, Symbols::InitPrefix(), init_name);
 
@@ -2126,9 +2208,11 @@
                           initializer_owner, TokenPosition::kNoSource));
   initializer_fun.set_kernel_offset(field.kernel_offset());
   initializer_fun.set_result_type(AbstractType::Handle(zone, field.type()));
-  initializer_fun.set_is_debuggable(false);
   initializer_fun.set_is_reflectable(false);
   initializer_fun.set_is_inlinable(false);
+  initializer_fun.set_token_pos(field.token_pos());
+  initializer_fun.set_end_token_pos(field.end_token_pos());
+  field.SetInitializer(initializer_fun);
   return initializer_fun.raw();
 }
 
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index e162a3a2..6554706 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -178,6 +178,10 @@
 
   RawLibrary* LoadLibrary(intptr_t index);
 
+  void FinishTopLevelClassLoading(const Class& toplevel_class,
+                                  const Library& library,
+                                  const LibraryIndex& library_index);
+
   static void FinishLoading(const Class& klass);
 
   void ReadObfuscationProhibitions();
@@ -277,6 +281,7 @@
                      bool in_class,
                      intptr_t procedure_end);
 
+  RawArray* MakeFieldsArray();
   RawArray* MakeFunctionsArray();
 
   RawScript* LoadScriptAt(intptr_t index);
@@ -320,9 +325,9 @@
 
   void EnsurePragmaClassIsLookedUp() {
     if (pragma_class_.IsNull()) {
-      const Library& internal_lib =
-          Library::Handle(zone_, dart::Library::InternalLibrary());
-      pragma_class_ = internal_lib.LookupClass(Symbols::Pragma());
+      const Library& core_lib =
+          Library::Handle(zone_, dart::Library::CoreLibrary());
+      pragma_class_ = core_lib.LookupLocalClass(Symbols::Pragma());
       ASSERT(!pragma_class_.IsNull());
     }
   }
diff --git a/runtime/vm/log.h b/runtime/vm/log.h
index 1c4a6d0..467b95c 100644
--- a/runtime/vm/log.h
+++ b/runtime/vm/log.h
@@ -11,8 +11,8 @@
 
 namespace dart {
 
+class Isolate;
 class LogBlock;
-class Thread;
 
 #if defined(_MSC_VER)
 #define THR_Print(format, ...) Log::Current()->Print(format, __VA_ARGS__)
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index eba6c5f..c07452f 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -52,13 +52,13 @@
 void MegamorphicCacheTable::InitMissHandler(Isolate* isolate) {
   // The miss handler for a class ID not found in the table is invoked as a
   // normal Dart function.
-  ObjectPoolWrapper object_pool_wrapper;
-  const Code& code = Code::Handle(
-      StubCode::Generate("_stub_MegamorphicMiss", &object_pool_wrapper,
-                         StubCode::GenerateMegamorphicMissStub));
+  ObjectPoolBuilder object_pool_builder;
+  const Code& code = Code::Handle(StubCode::Generate(
+      "_stub_MegamorphicMiss", &object_pool_builder,
+      compiler::StubCodeCompiler::GenerateMegamorphicMissStub));
 
   const auto& object_pool =
-      ObjectPool::Handle(object_pool_wrapper.MakeObjectPool());
+      ObjectPool::Handle(ObjectPool::NewFromBuilder(object_pool_builder));
   code.set_object_pool(object_pool.raw());
 
   // When FLAG_lazy_dispatchers=false, this stub can be on the stack during
@@ -88,11 +88,12 @@
 }
 
 void MegamorphicCacheTable::ReInitMissHandlerCode(Isolate* isolate,
-                                                  ObjectPoolWrapper* wrapper) {
+                                                  ObjectPoolBuilder* wrapper) {
   ASSERT(FLAG_precompiled_mode && FLAG_use_bare_instructions);
 
   const Code& code = Code::Handle(StubCode::Generate(
-      "_stub_MegamorphicMiss", wrapper, StubCode::GenerateMegamorphicMissStub));
+      "_stub_MegamorphicMiss", wrapper,
+      compiler::StubCodeCompiler::GenerateMegamorphicMissStub));
   code.set_exception_handlers(Object::empty_exception_handlers());
 
   auto object_store = isolate->object_store();
diff --git a/runtime/vm/megamorphic_cache_table.h b/runtime/vm/megamorphic_cache_table.h
index 8d7788a..437fff7 100644
--- a/runtime/vm/megamorphic_cache_table.h
+++ b/runtime/vm/megamorphic_cache_table.h
@@ -9,11 +9,14 @@
 
 namespace dart {
 
+namespace compiler {
+class ObjectPoolBuilder;
+}
+
 class Array;
 class Function;
 class Isolate;
 class ObjectPointerVisitor;
-class ObjectPoolWrapper;
 class RawArray;
 class RawFunction;
 class RawCode;
@@ -33,7 +36,7 @@
   // re-generate the handler to ensure it uses the common object pool.
   NOT_IN_PRECOMPILED(
       static void ReInitMissHandlerCode(Isolate* isolate,
-                                        ObjectPoolWrapper* wrapper));
+                                        compiler::ObjectPoolBuilder* wrapper));
 
   static RawMegamorphicCache* Lookup(Isolate* isolate,
                                      const String& name,
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 251740e..86d7be5 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -155,7 +155,7 @@
       // null vector represents infinite list of dynamics
       return Type::dynamic_type().raw();
     }
-    return TypeArguments::Handle(NativeTypeArgs()).TypeAt(index);
+    return type_args.TypeAt(index);
   }
 
   void SetReturn(const Object& value) const { *retval_ = value.raw(); }
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index ff77ded..569b402 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -20,6 +20,14 @@
 
 namespace dart {
 
+void DartNativeThrowTypeArgumentCountException(int num_type_args,
+                                               int num_type_args_expected) {
+  const String& error = String::Handle(String::NewFormatted(
+      "Wrong number of type arguments (%i), expected %i type arguments",
+      num_type_args, num_type_args_expected));
+  Exceptions::ThrowArgumentError(error);
+}
+
 void DartNativeThrowArgumentException(const Instance& instance) {
   const Array& __args__ = Array::Handle(Array::New(1));
   __args__.SetAt(0, instance);
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index b98e2f4..a4a5ee5 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -8,14 +8,13 @@
 #include "platform/memory_sanitizer.h"
 
 #include "vm/allocation.h"
-#include "vm/compiler/assembler/assembler.h"
 #include "vm/exceptions.h"
 #include "vm/heap/verifier.h"
 #include "vm/log.h"
 #include "vm/native_arguments.h"
+#include "vm/native_function.h"
 #include "vm/runtime_entry.h"
 
-#include "include/dart_api.h"
 
 namespace dart {
 
@@ -23,22 +22,6 @@
 class Class;
 class String;
 
-// We have three variants of native functions:
-//  - bootstrap natives, which are called directly from stub code. The callee is
-//    responsible for safepoint transitions and setting up handle scopes as
-//    needed. Only VM-defined natives are bootstrap natives; they cannot be
-//    defined by embedders or native extensions.
-//  - no scope natives, which are called through a wrapper function. The wrapper
-//    function handles the safepoint transition. The callee is responsible for
-//    setting up API scopes as needed.
-//  - auto scope natives, which are called through a wrapper function. The
-//    wrapper function handles the safepoint transition and sets up an API
-//    scope.
-
-typedef void (*NativeFunction)(NativeArguments* arguments);
-typedef void (*NativeFunctionWrapper)(Dart_NativeArguments args,
-                                      Dart_NativeFunction func);
-
 #ifdef DEBUG
 #define TRACE_NATIVE_CALL(format, name)                                        \
   if (FLAG_trace_natives) {                                                    \
@@ -90,9 +73,22 @@
   static RawObject* DN_Helper##name(Isolate* isolate, Thread* thread,          \
                                     Zone* zone, NativeArguments* arguments)
 
-// Helper that throws an argument exception.
+// Helpers that throw an argument exception.
+void DartNativeThrowTypeArgumentCountException(int num_type_args,
+                                               int num_type_args_expected);
 void DartNativeThrowArgumentException(const Instance& instance);
 
+// Native should throw an exception if the wrong number of type arguments is
+// passed.
+#define NATIVE_TYPE_ARGUMENT_COUNT(expected)                                   \
+  int __num_type_arguments = arguments->NativeTypeArgCount();                  \
+  if (__num_type_arguments != expected) {                                      \
+    DartNativeThrowTypeArgumentCountException(__num_type_arguments, expected); \
+  }
+
+#define GET_NATIVE_TYPE_ARGUMENT(name, value)                                  \
+  AbstractType& name = AbstractType::Handle(value);
+
 // Natives should throw an exception if an illegal argument or null is passed.
 // type name = value.
 #define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)                        \
diff --git a/runtime/vm/native_function.h b/runtime/vm/native_function.h
new file mode 100644
index 0000000..f5db8fe
--- /dev/null
+++ b/runtime/vm/native_function.h
@@ -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.
+
+#ifndef RUNTIME_VM_NATIVE_FUNCTION_H_
+#define RUNTIME_VM_NATIVE_FUNCTION_H_
+
+#include "vm/allocation.h"
+
+#include "include/dart_api.h"
+
+namespace dart {
+
+// Forward declarations.
+class NativeArguments;
+
+// We have three variants of native functions:
+//  - bootstrap natives, which are called directly from stub code. The callee is
+//    responsible for safepoint transitions and setting up handle scopes as
+//    needed. Only VM-defined natives are bootstrap natives; they cannot be
+//    defined by embedders or native extensions.
+//  - no scope natives, which are called through a wrapper function. The wrapper
+//    function handles the safepoint transition. The callee is responsible for
+//    setting up API scopes as needed.
+//  - auto scope natives, which are called through a wrapper function. The
+//    wrapper function handles the safepoint transition and sets up an API
+//    scope.
+
+typedef void (*NativeFunction)(NativeArguments* arguments);
+typedef void (*NativeFunctionWrapper)(Dart_NativeArguments args,
+                                      Dart_NativeFunction func);
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_NATIVE_FUNCTION_H_
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 18b69c3..318379e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -104,6 +104,14 @@
 #endif
 #define RAW_NULL kHeapObjectTag
 
+#define CHECK_ERROR(error)                                                     \
+  {                                                                            \
+    RawError* err = (error);                                                   \
+    if (err != Error::null()) {                                                \
+      return err;                                                              \
+    }                                                                          \
+  }
+
 #define DEFINE_SHARED_READONLY_HANDLE(Type, name)                              \
   Type* Object::name##_ = nullptr;
 SHARED_READONLY_HANDLES_LIST(DEFINE_SHARED_READONLY_HANDLE)
@@ -120,6 +128,8 @@
 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);
@@ -464,7 +474,7 @@
 
   Heap* heap = isolate->heap();
 
-  // Allocate the read only object handles here.
+// Allocate the read only object handles here.
 #define INITIALIZE_SHARED_READONLY_HANDLE(Type, name)                          \
   name##_ = Type::ReadOnlyHandle();
   SHARED_READONLY_HANDLES_LIST(INITIALIZE_SHARED_READONLY_HANDLE)
@@ -574,6 +584,9 @@
   cls = Class::New<RedirectionData>();
   redirection_data_class_ = cls.raw();
 
+  cls = Class::New<FfiTrampolineData>();
+  ffi_trampoline_data_class_ = cls.raw();
+
   cls = Class::New<Field>();
   field_class_ = cls.raw();
 
@@ -929,13 +942,13 @@
   // The type testing stubs we initialize in AbstractType objects for the
   // canonical type of kDynamicCid/kVoidCid need to be set in this
   // method, which is called after StubCode::InitOnce().
-  Instructions& instr = Instructions::Handle();
+  Code& code = Code::Handle();
 
-  instr = TypeTestingStubGenerator::DefaultCodeForType(*dynamic_type_);
-  dynamic_type_->SetTypeTestingStub(instr);
+  code = TypeTestingStubGenerator::DefaultCodeForType(*dynamic_type_);
+  dynamic_type_->SetTypeTestingStub(code);
 
-  instr = TypeTestingStubGenerator::DefaultCodeForType(*void_type_);
-  void_type_->SetTypeTestingStub(instr);
+  code = TypeTestingStubGenerator::DefaultCodeForType(*void_type_);
+  void_type_->SetTypeTestingStub(code);
 }
 
 void Object::Cleanup() {
@@ -949,6 +962,7 @@
   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);
@@ -1048,6 +1062,7 @@
   SET_CLASS_NAME(closure_data, ClosureData);
   SET_CLASS_NAME(signature_data, SignatureData);
   SET_CLASS_NAME(redirection_data, RedirectionData);
+  SET_CLASS_NAME(ffi_trampoline_data, FfiTrampolineData);
   SET_CLASS_NAME(field, Field);
   SET_CLASS_NAME(script, Script);
   SET_CLASS_NAME(library, LibraryClass);
@@ -1111,9 +1126,9 @@
       String::SetCachedHash(str, hash);
     }
     intptr_t size = OneByteString::UnroundedSize(str);
-    ASSERT(size <= str->Size());
+    ASSERT(size <= str->HeapSize());
     memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
-           str->Size() - size);
+           str->HeapSize() - size);
   } else if (cid == kTwoByteStringCid) {
     RawTwoByteString* str = static_cast<RawTwoByteString*>(object);
     if (String::GetCachedHash(str) == 0) {
@@ -1122,9 +1137,9 @@
     }
     ASSERT(String::GetCachedHash(str) != 0);
     intptr_t size = TwoByteString::UnroundedSize(str);
-    ASSERT(size <= str->Size());
+    ASSERT(size <= str->HeapSize());
     memset(reinterpret_cast<void*>(RawObject::ToAddr(str) + size), 0,
-           str->Size() - size);
+           str->HeapSize() - size);
   } else if (cid == kExternalOneByteStringCid) {
     RawExternalOneByteString* str =
         static_cast<RawExternalOneByteString*>(object);
@@ -1142,21 +1157,21 @@
   } else if (cid == kCodeSourceMapCid) {
     RawCodeSourceMap* map = CodeSourceMap::RawCast(object);
     intptr_t size = CodeSourceMap::UnroundedSize(map);
-    ASSERT(size <= map->Size());
+    ASSERT(size <= map->HeapSize());
     memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
-           map->Size() - size);
+           map->HeapSize() - size);
   } else if (cid == kStackMapCid) {
     RawStackMap* map = StackMap::RawCast(object);
     intptr_t size = StackMap::UnroundedSize(map);
-    ASSERT(size <= map->Size());
+    ASSERT(size <= map->HeapSize());
     memset(reinterpret_cast<void*>(RawObject::ToAddr(map) + size), 0,
-           map->Size() - size);
+           map->HeapSize() - size);
   } else if (cid == kPcDescriptorsCid) {
     RawPcDescriptors* desc = PcDescriptors::RawCast(object);
     intptr_t size = PcDescriptors::UnroundedSize(desc);
-    ASSERT(size <= desc->Size());
+    ASSERT(size <= desc->HeapSize());
     memset(reinterpret_cast<void*>(RawObject::ToAddr(desc) + size), 0,
-           desc->Size() - size);
+           desc->HeapSize() - size);
   }
 }
 
@@ -1299,8 +1314,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   const bool is_kernel = (kernel_buffer != NULL);
 #endif
-  NOT_IN_PRODUCT(TimelineDurationScope tds(thread, Timeline::GetIsolateStream(),
-                                           "Object::Init");)
+  TIMELINE_DURATION(thread, Isolate, "Object::Init");
 
 #if defined(DART_NO_SNAPSHOT)
   bool bootstrapping =
@@ -1807,6 +1821,51 @@
     type_args = type_args.Canonicalize();
     object_store->set_type_argument_string_string(type_args);
 
+    lib = Library::LookupLibrary(thread, Symbols::DartFfi());
+    if (lib.IsNull()) {
+      lib = Library::NewLibraryHelper(Symbols::DartFfi(), true);
+      lib.SetLoadRequested();
+      lib.Register(thread);
+    }
+    object_store->set_bootstrap_library(ObjectStore::kFfi, lib);
+
+    cls = Class::New<Instance>(kFfiNativeTypeCid);
+    cls.set_num_type_arguments(0);
+    cls.set_num_own_type_arguments(0);
+    cls.set_is_prefinalized();
+    pending_classes.Add(cls);
+    object_store->set_ffi_native_type_class(cls);
+    RegisterClass(cls, Symbols::FfiNativeType(), lib);
+
+#define REGISTER_FFI_TYPE_MARKER(clazz)                                        \
+  cls = Class::New<Instance>(kFfi##clazz##Cid);                                \
+  cls.set_num_type_arguments(0);                                               \
+  cls.set_num_own_type_arguments(0);                                           \
+  cls.set_is_prefinalized();                                                   \
+  pending_classes.Add(cls);                                                    \
+  RegisterClass(cls, Symbols::Ffi##clazz(), lib);
+    CLASS_LIST_FFI_TYPE_MARKER(REGISTER_FFI_TYPE_MARKER);
+#undef REGISTER_FFI_TYPE_MARKER
+
+    cls = Class::New<Instance>(kFfiNativeFunctionCid);
+    cls.set_type_arguments_field_offset(Pointer::type_arguments_offset());
+    cls.set_num_type_arguments(1);
+    cls.set_num_own_type_arguments(1);
+    cls.set_is_prefinalized();
+    pending_classes.Add(cls);
+    RegisterClass(cls, Symbols::FfiNativeFunction(), lib);
+
+    cls = Class::NewPointerClass(kFfiPointerCid);
+    object_store->set_ffi_pointer_class(cls);
+    pending_classes.Add(cls);
+    RegisterClass(cls, Symbols::FfiPointer(), lib);
+
+    cls = Class::New<DynamicLibrary>(kFfiDynamicLibraryCid);
+    cls.set_instance_size(DynamicLibrary::InstanceSize());
+    cls.set_is_prefinalized();
+    pending_classes.Add(cls);
+    RegisterClass(cls, Symbols::FfiDynamicLibrary(), lib);
+
     // Finish the initialization by compiling the bootstrap scripts containing
     // the base interfaces and the implementation of the internal classes.
     const Error& error = Error::Handle(
@@ -1820,7 +1879,7 @@
     ClassFinalizer::VerifyBootstrapClasses();
 
     // Set up the intrinsic state of all functions (core, math and typed data).
-    Intrinsifier::InitializeState();
+    compiler::Intrinsifier::InitializeState();
 
     // Set up recognized state of all functions (core, math and typed data).
     MethodRecognizer::InitializeState();
@@ -1891,6 +1950,20 @@
     CLASS_LIST_TYPED_DATA(REGISTER_EXT_TYPED_DATA_CLASS);
 #undef REGISTER_EXT_TYPED_DATA_CLASS
 
+    cls = Class::New<Instance>(kFfiNativeTypeCid);
+    object_store->set_ffi_native_type_class(cls);
+
+#define REGISTER_FFI_CLASS(clazz) cls = Class::New<Instance>(kFfi##clazz##Cid);
+    CLASS_LIST_FFI_TYPE_MARKER(REGISTER_FFI_CLASS);
+#undef REGISTER_FFI_CLASS
+
+    cls = Class::New<Instance>(kFfiNativeFunctionCid);
+
+    cls = Class::NewPointerClass(kFfiPointerCid);
+    object_store->set_ffi_pointer_class(cls);
+
+    cls = Class::New<DynamicLibrary>(kFfiDynamicLibraryCid);
+
     cls = Class::New<Instance>(kByteBufferCid);
 
     cls = Class::New<Integer>();
@@ -2083,14 +2156,14 @@
       for (RawObject** slot = from; slot <= to; ++slot) {
         RawObject* value = *slot;
         if (value->IsHeapObject()) {
-          old_obj_->CheckHeapPointerStore(value, thread_);
+          old_obj_->CheckArrayPointerStore(slot, value, thread_);
         }
       }
     } else {
       for (RawObject** slot = from; slot <= to; ++slot) {
         RawObject* value = *slot;
         if (value->IsHeapObject()) {
-          old_obj_->CheckArrayPointerStore(slot, value, thread_);
+          old_obj_->CheckHeapPointerStore(value, thread_);
         }
       }
     }
@@ -2113,7 +2186,7 @@
 
 RawObject* Object::Clone(const Object& orig, Heap::Space space) {
   const Class& cls = Class::Handle(orig.clazz());
-  intptr_t size = orig.raw()->Size();
+  intptr_t size = orig.raw()->HeapSize();
   RawObject* raw_clone = Object::Allocate(cls.id(), size, space);
   NoSafepointScope no_safepoint;
   // Copy the body of the original into the clone.
@@ -3200,31 +3273,43 @@
 
 RawObject* Class::InvokeGetter(const String& getter_name,
                                bool throw_nsm_if_absent,
-                               bool respect_reflectable) const {
+                               bool respect_reflectable,
+                               bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
-  const Error& error = Error::Handle(zone, EnsureIsFinalized(thread));
-  if (!error.IsNull()) {
-    return error.raw();
-  }
+  CHECK_ERROR(EnsureIsFinalized(thread));
 
   // Note static fields do not have implicit getters.
   const Field& field = Field::Handle(zone, LookupStaticField(getter_name));
+
+  if (!field.IsNull() && check_is_entrypoint) {
+    CHECK_ERROR(field.VerifyEntryPoint(EntryPointPragma::kGetterOnly));
+  }
+
   if (field.IsNull() || field.IsUninitialized()) {
     const String& internal_getter_name =
         String::Handle(zone, Field::GetterName(getter_name));
     Function& getter =
         Function::Handle(zone, LookupStaticFunction(internal_getter_name));
 
+    if (field.IsNull() && !getter.IsNull() && check_is_entrypoint) {
+      CHECK_ERROR(getter.VerifyEntryPoint());
+    }
+
     if (getter.IsNull() || (respect_reflectable && !getter.is_reflectable())) {
       if (getter.IsNull()) {
         getter = LookupStaticFunction(getter_name);
         if (!getter.IsNull()) {
-          // Looking for a getter but found a regular method: closurize it.
-          const Function& closure_function =
-              Function::Handle(zone, getter.ImplicitClosureFunction());
-          return closure_function.ImplicitStaticClosure();
+          if (check_is_entrypoint) {
+            CHECK_ERROR(EntryPointClosurizationError(getter_name));
+          }
+          if (getter.SafeToClosurize()) {
+            // Looking for a getter but found a regular method: closurize it.
+            const Function& closure_function =
+                Function::Handle(zone, getter.ImplicitClosureFunction());
+            return closure_function.ImplicitStaticClosure();
+          }
         }
       }
       if (throw_nsm_if_absent) {
@@ -3248,7 +3333,8 @@
 
 RawObject* Class::InvokeSetter(const String& setter_name,
                                const Instance& value,
-                               bool respect_reflectable) const {
+                               bool respect_reflectable,
+                               bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
@@ -3262,6 +3348,10 @@
   const String& internal_setter_name =
       String::Handle(zone, Field::SetterName(setter_name));
 
+  if (!field.IsNull() && check_is_entrypoint) {
+    CHECK_ERROR(field.VerifyEntryPoint(EntryPointPragma::kSetterOnly));
+  }
+
   AbstractType& parameter_type = AbstractType::Handle(zone);
   AbstractType& argument_type =
       AbstractType::Handle(zone, value.GetType(Heap::kOld));
@@ -3269,6 +3359,9 @@
   if (field.IsNull()) {
     const Function& setter =
         Function::Handle(zone, LookupStaticFunction(internal_setter_name));
+    if (!setter.IsNull() && check_is_entrypoint) {
+      CHECK_ERROR(setter.VerifyEntryPoint());
+    }
     const int kNumArgs = 1;
     const Array& args = Array::Handle(zone, Array::New(kNumArgs));
     args.SetAt(0, value);
@@ -3316,31 +3409,30 @@
 RawObject* Class::Invoke(const String& function_name,
                          const Array& args,
                          const Array& arg_names,
-                         bool respect_reflectable) const {
+                         bool respect_reflectable,
+                         bool check_is_entrypoint) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
 
   // TODO(regis): Support invocation of generic functions with type arguments.
   const int kTypeArgsLen = 0;
-  const Error& error = Error::Handle(zone, EnsureIsFinalized(thread));
-  if (!error.IsNull()) {
-    return error.raw();
-  }
+  CHECK_ERROR(EnsureIsFinalized(thread));
 
   Function& function =
       Function::Handle(zone, LookupStaticFunction(function_name));
 
+  if (!function.IsNull() && check_is_entrypoint) {
+    CHECK_ERROR(function.VerifyEntryPoint());
+  }
+
   if (function.IsNull()) {
     // Didn't find a method: try to find a getter and invoke call on its result.
-    const String& getter_name =
-        String::Handle(zone, Field::GetterName(function_name));
-    function = LookupStaticFunction(getter_name);
-    if (!function.IsNull()) {
-      // Invoke the getter.
-      const Object& getter_result = Object::Handle(
-          zone, DartEntry::InvokeFunction(function, Object::empty_array()));
-      if (getter_result.IsError()) {
-        return getter_result.raw();
+    const Object& getter_result = Object::Handle(
+        zone, InvokeGetter(function_name, false, respect_reflectable,
+                           check_is_entrypoint));
+    if (getter_result.raw() != Object::sentinel().raw()) {
+      if (check_is_entrypoint) {
+        CHECK_ERROR(EntryPointClosurizationError(function_name));
       }
       // Make room for the closure (receiver) in the argument list.
       const intptr_t num_args = args.Length();
@@ -3634,6 +3726,17 @@
   return result.raw();
 }
 
+RawClass* Class::NewPointerClass(intptr_t class_id) {
+  ASSERT(RawObject::IsFfiPointerClassId(class_id));
+  intptr_t instance_size = Pointer::InstanceSize();
+  Class& result = Class::Handle(New<Pointer>(class_id));
+  result.set_instance_size(instance_size);
+  result.set_type_arguments_field_offset(Pointer::type_arguments_offset());
+  result.set_next_field_offset(Pointer::NextFieldOffset());
+  result.set_is_prefinalized();
+  return result.raw();
+}
+
 void Class::set_name(const String& value) const {
   ASSERT(raw_ptr()->name_ == String::null());
   ASSERT(value.IsSymbol());
@@ -3707,6 +3810,11 @@
     case kExternalTypedDataFloat64ArrayCid:
       return Symbols::Float64List().raw();
 
+    case kFfiPointerCid:
+      return Symbols::FfiPointer().raw();
+    case kFfiDynamicLibraryCid:
+      return Symbols::FfiDynamicLibrary().raw();
+
 #if !defined(PRODUCT)
     case kNullCid:
       return Symbols::Null().raw();
@@ -3728,6 +3836,8 @@
       return Symbols::SignatureData().raw();
     case kRedirectionDataCid:
       return Symbols::RedirectionData().raw();
+    case kFfiTrampolineDataCid:
+      return Symbols::FfiTrampolineData().raw();
     case kFieldCid:
       return Symbols::Field().raw();
     case kScriptCid:
@@ -3924,6 +4034,10 @@
   set_state_bits(IsAllocatedBit::update(value, raw_ptr()->state_bits_));
 }
 
+void Class::set_is_loaded(bool value) const {
+  set_state_bits(IsLoadedBit::update(value, raw_ptr()->state_bits_));
+}
+
 void Class::set_is_finalized() const {
   ASSERT(!is_finalized());
   set_state_bits(
@@ -3948,12 +4062,8 @@
   StorePointer(&raw_ptr()->interfaces_, value.raw());
 }
 
-RawClass* Class::GetPatchClass() const {
-  const Library& lib = Library::Handle(library());
-  return lib.GetPatchClass(String::Handle(Name()));
-}
-
-void Class::AddDirectImplementor(const Class& implementor) const {
+void Class::AddDirectImplementor(const Class& implementor,
+                                 bool is_mixin) const {
   ASSERT(is_implemented());
   ASSERT(!implementor.IsNull());
   GrowableObjectArray& direct_implementors =
@@ -3964,8 +4074,14 @@
   }
 #if defined(DEBUG)
   // Verify that the same class is not added twice.
-  for (intptr_t i = 0; i < direct_implementors.Length(); i++) {
-    ASSERT(direct_implementors.At(i) != implementor.raw());
+  // The only exception is mixins: when mixin application is transformed,
+  // mixin is added to the end of interfaces list and may be duplicated:
+  //   class X = A with B implements B;
+  // This is rare and harmless.
+  if (!is_mixin) {
+    for (intptr_t i = 0; i < direct_implementors.Length(); i++) {
+      ASSERT(direct_implementors.At(i) != implementor.raw());
+    }
   }
 #endif
   direct_implementors.Add(implementor, Heap::kOld);
@@ -4537,16 +4653,6 @@
   return Field::null();
 }
 
-RawLibraryPrefix* Class::LookupLibraryPrefix(const String& name) const {
-  Zone* zone = Thread::Current()->zone();
-  const Library& lib = Library::Handle(zone, library());
-  const Object& obj = Object::Handle(zone, lib.LookupLocalObject(name));
-  if (!obj.IsNull() && obj.IsLibraryPrefix()) {
-    return LibraryPrefix::Cast(obj).raw();
-  }
-  return LibraryPrefix::null();
-}
-
 const char* Class::ToCString() const {
   const Library& lib = Library::Handle(library());
   const char* library_name = lib.IsNull() ? "" : lib.ToCString();
@@ -4992,9 +5098,19 @@
 }
 
 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const {
+  ASSERT(!IsNull());
   return *TypeAddr(index);
 }
 
+RawAbstractType* TypeArguments::TypeAtNullSafe(intptr_t index) const {
+  if (IsNull()) {
+    // null vector represents infinite list of dynamics
+    return Type::dynamic_type().raw();
+  }
+  ASSERT((index >= 0) && (index < Length()));
+  return TypeAt(index);
+}
+
 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const {
   ASSERT(!IsCanonical());
   StorePointer(TypeAddr(index), value.raw());
@@ -5862,9 +5978,11 @@
   ASSERT(!obj.IsNull());
   if (IsSignatureFunction()) {
     return SignatureData::Cast(obj).signature_type();
-  } else {
-    ASSERT(IsClosureFunction());
+  } else if (IsClosureFunction()) {
     return ClosureData::Cast(obj).signature_type();
+  } else {
+    ASSERT(IsFfiTrampoline());
+    return FfiTrampolineData::Cast(obj).signature_type();
   }
 }
 
@@ -5915,9 +6033,11 @@
   if (IsSignatureFunction()) {
     SignatureData::Cast(obj).set_signature_type(value);
     ASSERT(!value.IsCanonical() || (value.signature() == this->raw()));
-  } else {
-    ASSERT(IsClosureFunction());
+  } else if (IsClosureFunction()) {
     ClosureData::Cast(obj).set_signature_type(value);
+  } else {
+    ASSERT(IsFfiTrampoline());
+    FfiTrampolineData::Cast(obj).set_signature_type(value);
   }
 }
 
@@ -6052,6 +6172,7 @@
 //   native function:         Array[0] = String native name
 //                            Array[1] = Function implicit closure function
 //   regular function:        Function for implicit closure function
+//   ffi trampoline function: FfiTrampolineData  (Dart->C)
 void Function::set_data(const Object& value) const {
   StorePointer(&raw_ptr()->data_, value.raw());
 }
@@ -6365,7 +6486,8 @@
   }
   if ((k == RawFunction::kClosureFunction) ||
       (k == RawFunction::kImplicitClosureFunction) ||
-      (k == RawFunction::kSignatureFunction)) {
+      (k == RawFunction::kSignatureFunction) ||
+      (k == RawFunction::kFfiTrampoline)) {
     return 1;  // Closure object.
   }
   if (!is_static()) {
@@ -7054,6 +7176,10 @@
     const SignatureData& data =
         SignatureData::Handle(SignatureData::New(space));
     result.set_data(data);
+  } else if (kind == RawFunction::kFfiTrampoline) {
+    const FfiTrampolineData& data =
+        FfiTrampolineData::Handle(FfiTrampolineData::New());
+    result.set_data(data);
   } else {
     // Functions other than signature functions have no reason to be allocated
     // in new space.
@@ -7137,6 +7263,14 @@
   return result.raw();
 }
 
+bool Function::SafeToClosurize() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  return HasImplicitClosureFunction();
+#else
+  return true;
+#endif
+}
+
 RawFunction* Function::ImplicitClosureFunction() const {
   // Return the existing implicit closure function if any.
   if (implicit_closure_function() != Function::null()) {
@@ -7144,7 +7278,7 @@
   }
 #if defined(DART_PRECOMPILED_RUNTIME)
   // In AOT mode all implicit closures are pre-created.
-  UNREACHABLE();
+  FATAL("Cannot create implicit closure in AOT!");
   return Function::null();
 #else
   ASSERT(!IsSignatureFunction() && !IsClosureFunction());
@@ -7985,6 +8119,27 @@
                      target_fun.IsNull() ? "null" : target_fun.ToCString());
 }
 
+void FfiTrampolineData::set_signature_type(const Type& value) const {
+  StorePointer(&raw_ptr()->signature_type_, value.raw());
+}
+
+RawFfiTrampolineData* FfiTrampolineData::New() {
+  ASSERT(Object::ffi_trampoline_data_class() != Class::null());
+  RawObject* raw =
+      Object::Allocate(FfiTrampolineData::kClassId,
+                       FfiTrampolineData::InstanceSize(), Heap::kOld);
+  return reinterpret_cast<RawFfiTrampolineData*>(raw);
+}
+
+const char* FfiTrampolineData::ToCString() const {
+  Type& signature_type = Type::Handle(this->signature_type());
+  String& signature_type_name =
+      String::Handle(signature_type.UserVisibleName());
+  return OS::SCreate(
+      Thread::Current()->zone(), "TrampolineData: signature=%s",
+      signature_type_name.IsNull() ? "null" : signature_type_name.ToCString());
+}
+
 RawField* Field::CloneFromOriginal() const {
   return this->Clone(*this);
 }
@@ -8436,14 +8591,13 @@
   return value.raw() == Object::sentinel().raw();
 }
 
-void Field::SetPrecompiledInitializer(const Function& initializer) const {
+void Field::SetInitializer(const Function& initializer) const {
   ASSERT(IsOriginal());
-  StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw());
+  StorePointer(&raw_ptr()->initializer_, initializer.raw());
 }
 
-bool Field::HasPrecompiledInitializer() const {
-  return raw_ptr()->initializer_.precompiled_->IsHeapObject() &&
-         raw_ptr()->initializer_.precompiled_->IsFunction();
+bool Field::HasInitializer() const {
+  return raw_ptr()->initializer_ != Function::null();
 }
 
 RawError* Field::EvaluateInitializer() const {
@@ -8671,8 +8825,9 @@
   const intptr_t type_arguments_offset = cls.type_arguments_field_offset();
   ASSERT(type_arguments_offset != Class::kNoTypeArguments);
   if (StaticTypeExactnessState::CanRepresentAsTriviallyExact(
-          type_arguments_offset)) {
-    return StaticTypeExactnessState::TriviallyExact(type_arguments_offset);
+          type_arguments_offset / kWordSize)) {
+    return StaticTypeExactnessState::TriviallyExact(type_arguments_offset /
+                                                    kWordSize);
   } else {
     return StaticTypeExactnessState::NotExact();
   }
@@ -8810,7 +8965,7 @@
     return "not-exact";
   } else if (IsTriviallyExact()) {
     return Thread::Current()->zone()->PrintToString(
-        "trivially-exact(%" Pd ")", GetTypeArgumentsOffsetInWords());
+        "trivially-exact(%hhu)", GetTypeArgumentsOffsetInWords());
   } else if (IsHasExactSuperType()) {
     return "has-exact-super-type";
   } else if (IsHasExactSuperClass()) {
@@ -9584,50 +9739,6 @@
   return error.raw();
 }
 
-void Library::AddPatchClass(const Class& cls) const {
-  ASSERT(Thread::Current()->IsMutatorThread());
-  ASSERT(cls.is_patch());
-  ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null());
-  const GrowableObjectArray& patch_classes =
-      GrowableObjectArray::Handle(this->patch_classes());
-  patch_classes.Add(cls);
-}
-
-RawClass* Library::GetPatchClass(const String& name) const {
-  ASSERT(Thread::Current()->IsMutatorThread());
-  const GrowableObjectArray& patch_classes =
-      GrowableObjectArray::Handle(this->patch_classes());
-  Object& obj = Object::Handle();
-  for (intptr_t i = 0; i < patch_classes.Length(); i++) {
-    obj = patch_classes.At(i);
-    if (obj.IsClass() &&
-        (Class::Cast(obj).Name() == name.raw())) {  // Names are canonicalized.
-      return Class::RawCast(obj.raw());
-    }
-  }
-  return Class::null();
-}
-
-void Library::RemovePatchClass(const Class& cls) const {
-  ASSERT(Thread::Current()->IsMutatorThread());
-  ASSERT(cls.is_patch());
-  const GrowableObjectArray& patch_classes =
-      GrowableObjectArray::Handle(this->patch_classes());
-  const intptr_t num_classes = patch_classes.Length();
-  intptr_t i = 0;
-  while (i < num_classes) {
-    if (cls.raw() == patch_classes.At(i)) break;
-    i++;
-  }
-  if (i == num_classes) return;
-  // Replace the entry with the script. We keep the script so that
-  // Library::LoadedScripts() can find it without having to iterate
-  // over the members of each class.
-  ASSERT(i < num_classes);  // We must have found a class.
-  const Script& patch_script = Script::Handle(cls.script());
-  patch_classes.SetAt(i, patch_script);
-}
-
 static RawString* MakeClassMetaName(Thread* thread,
                                     Zone* zone,
                                     const Class& cls) {
@@ -9838,6 +9949,7 @@
   if (FLAG_use_lib_cache && LookupResolvedNamesCache(name, &obj)) {
     return obj.raw();
   }
+  EnsureTopLevelClassIsFinalized();
   obj = LookupLocalObject(name);
   if (!obj.IsNull()) {
     // Names that are in this library's dictionary and are unmangled
@@ -10125,18 +10237,6 @@
   return Object::null();
 }
 
-void Library::ReplaceObject(const Object& obj, const String& name) const {
-  ASSERT(!Compiler::IsBackgroundCompilation());
-  ASSERT(obj.IsClass() || obj.IsFunction() || obj.IsField());
-  ASSERT(LookupLocalObject(name) != Object::null());
-
-  intptr_t index;
-  LookupEntry(name, &index);
-  // The value is guaranteed to be found.
-  const Array& dict = Array::Handle(dictionary());
-  dict.SetAt(index, obj);
-}
-
 void Library::AddClass(const Class& cls) const {
   ASSERT(!Compiler::IsBackgroundCompilation());
   const String& class_name = String::Handle(cls.Name());
@@ -10263,6 +10363,22 @@
   return Script::null();
 }
 
+void Library::EnsureTopLevelClassIsFinalized() const {
+  if (toplevel_class() == Object::null()) {
+    return;
+  }
+  Thread* thread = Thread::Current();
+  const Class& cls = Class::Handle(thread->zone(), toplevel_class());
+  if (cls.is_finalized()) {
+    return;
+  }
+  const Error& error =
+      Error::Handle(thread->zone(), cls.EnsureIsFinalized(thread));
+  if (!error.IsNull()) {
+    Exceptions::PropagateError(error);
+  }
+}
+
 RawObject* Library::LookupLocalObject(const String& name) const {
   intptr_t index;
   return LookupEntry(name, &index);
@@ -10270,6 +10386,7 @@
 
 RawObject* Library::LookupLocalOrReExportObject(const String& name) const {
   intptr_t index;
+  EnsureTopLevelClassIsFinalized();
   const Object& result = Object::Handle(LookupEntry(name, &index));
   if (!result.IsNull() && !result.IsLibraryPrefix()) {
     return result.raw();
@@ -10278,6 +10395,7 @@
 }
 
 RawField* Library::LookupFieldAllowPrivate(const String& name) const {
+  EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
   if (obj.IsField()) {
     return Field::Cast(obj).raw();
@@ -10286,6 +10404,7 @@
 }
 
 RawField* Library::LookupLocalField(const String& name) const {
+  EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
   if (obj.IsField()) {
     return Field::Cast(obj).raw();
@@ -10294,6 +10413,7 @@
 }
 
 RawFunction* Library::LookupFunctionAllowPrivate(const String& name) const {
+  EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupObjectAllowPrivate(name));
   if (obj.IsFunction()) {
     return Function::Cast(obj).raw();
@@ -10302,6 +10422,7 @@
 }
 
 RawFunction* Library::LookupLocalFunction(const String& name) const {
+  EnsureTopLevelClassIsFinalized();
   Object& obj = Object::Handle(LookupLocalObjectAllowPrivate(name));
   if (obj.IsFunction()) {
     return Function::Cast(obj).raw();
@@ -10399,7 +10520,10 @@
 }
 
 RawClass* Library::LookupClass(const String& name) const {
-  Object& obj = Object::Handle(ResolveName(name));
+  Object& obj = Object::Handle(LookupLocalObject(name));
+  if (obj.IsNull() && !ShouldBePrivate(name)) {
+    obj = LookupImportedObject(name);
+  }
   if (obj.IsClass()) {
     return Class::Cast(obj).raw();
   }
@@ -10487,31 +10611,6 @@
   return Namespace::RawCast(import_list.At(index));
 }
 
-bool Library::ImportsCorelib() const {
-  Zone* zone = Thread::Current()->zone();
-  Library& imported = Library::Handle(zone);
-  intptr_t count = num_imports();
-  for (int i = 0; i < count; i++) {
-    imported = ImportLibraryAt(i);
-    if (imported.IsCoreLibrary()) {
-      return true;
-    }
-  }
-  LibraryPrefix& prefix = LibraryPrefix::Handle(zone);
-  LibraryPrefixIterator it(*this);
-  while (it.HasNext()) {
-    prefix = it.GetNext();
-    count = prefix.num_imports();
-    for (int i = 0; i < count; i++) {
-      imported = prefix.GetLibrary(i);
-      if (imported.IsCoreLibrary()) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
 void Library::DropDependenciesAndCaches() const {
   StorePointer(&raw_ptr()->imports_, Object::empty_array().raw());
   StorePointer(&raw_ptr()->exports_, Object::empty_array().raw());
@@ -10627,7 +10726,6 @@
   result.set_native_entry_resolver(NULL);
   result.set_native_entry_symbol_resolver(NULL);
   result.set_is_in_fullsnapshot(false);
-  result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true);
   if (dart_private_scheme) {
     // Never debug dart:_ libraries.
     result.set_debuggable(false);
@@ -10707,11 +10805,15 @@
 
 RawObject* Library::InvokeGetter(const String& getter_name,
                                  bool throw_nsm_if_absent,
-                                 bool respect_reflectable) const {
+                                 bool respect_reflectable,
+                                 bool check_is_entrypoint) const {
   Object& obj = Object::Handle(LookupLocalOrReExportObject(getter_name));
   Function& getter = Function::Handle();
   if (obj.IsField()) {
     const Field& field = Field::Cast(obj);
+    if (check_is_entrypoint) {
+      CHECK_ERROR(field.VerifyEntryPoint(EntryPointPragma::kGetterOnly));
+    }
     if (!field.IsUninitialized()) {
       return field.StaticValue();
     }
@@ -10728,9 +10830,21 @@
     obj = LookupLocalOrReExportObject(internal_getter_name);
     if (obj.IsFunction()) {
       getter = Function::Cast(obj).raw();
+      if (check_is_entrypoint) {
+        CHECK_ERROR(getter.VerifyEntryPoint());
+      }
     } else {
       obj = LookupLocalOrReExportObject(getter_name);
-      if (obj.IsFunction()) {
+      // Normally static top-level methods cannot be closurized through the
+      // native API even if they are marked as entry-points, with the one
+      // exception of "main".
+      if (obj.IsFunction() && check_is_entrypoint) {
+        if (!getter_name.Equals(String::Handle(String::New("main"))) ||
+            raw() != Isolate::Current()->object_store()->root_library()) {
+          CHECK_ERROR(EntryPointClosurizationError(getter_name));
+        }
+      }
+      if (obj.IsFunction() && Function::Cast(obj).SafeToClosurize()) {
         // Looking for a getter but found a regular method: closurize it.
         const Function& closure_function =
             Function::Handle(Function::Cast(obj).ImplicitClosureFunction());
@@ -10759,7 +10873,8 @@
 
 RawObject* Library::InvokeSetter(const String& setter_name,
                                  const Instance& value,
-                                 bool respect_reflectable) const {
+                                 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));
@@ -10767,6 +10882,9 @@
   AbstractType& argument_type = AbstractType::Handle(value.GetType(Heap::kOld));
   if (obj.IsField()) {
     const Field& field = Field::Cast(obj);
+    if (check_is_entrypoint) {
+      CHECK_ERROR(field.VerifyEntryPoint(EntryPointPragma::kSetterOnly));
+    }
     setter_type ^= field.type();
     if (!argument_type.IsNullType() && !setter_type.IsDynamicType() &&
         !value.IsInstanceOf(setter_type, Object::null_type_arguments(),
@@ -10793,6 +10911,10 @@
     setter ^= obj.raw();
   }
 
+  if (!setter.IsNull() && check_is_entrypoint) {
+    CHECK_ERROR(setter.VerifyEntryPoint());
+  }
+
   const int kNumArgs = 1;
   const Array& args = Array::Handle(Array::New(kNumArgs));
   args.SetAt(0, value);
@@ -10816,7 +10938,8 @@
 RawObject* Library::Invoke(const String& function_name,
                            const Array& args,
                            const Array& arg_names,
-                           bool respect_reflectable) const {
+                           bool respect_reflectable,
+                           bool check_is_entrypoint) const {
   // TODO(regis): Support invocation of generic functions with type arguments.
   const int kTypeArgsLen = 0;
 
@@ -10826,11 +10949,18 @@
     function ^= obj.raw();
   }
 
+  if (!function.IsNull() && check_is_entrypoint) {
+    CHECK_ERROR(function.VerifyEntryPoint());
+  }
+
   if (function.IsNull()) {
     // Didn't find a method: try to find a getter and invoke call on its result.
-    const Object& getter_result =
-        Object::Handle(InvokeGetter(function_name, false));
+    const Object& getter_result = Object::Handle(InvokeGetter(
+        function_name, false, respect_reflectable, check_is_entrypoint));
     if (getter_result.raw() != Object::sentinel().raw()) {
+      if (check_is_entrypoint) {
+        CHECK_ERROR(EntryPointClosurizationError(function_name));
+      }
       // Make room for the closure (receiver) in arguments.
       intptr_t numArgs = args.Length();
       const Array& call_args = Array::Handle(Array::New(numArgs + 1));
@@ -11176,6 +11306,10 @@
   return Isolate::Current()->object_store()->developer_library();
 }
 
+RawLibrary* Library::FfiLibrary() {
+  return Isolate::Current()->object_store()->ffi_library();
+}
+
 RawLibrary* Library::InternalLibrary() {
   return Isolate::Current()->object_store()->_internal_library();
 }
@@ -11632,6 +11766,8 @@
     }
   }
 
+  lib.EnsureTopLevelClassIsFinalized();
+
   intptr_t ignore = 0;
   // Lookup the name in the library's symbols.
   Object& obj = Object::Handle(zone, lib.LookupEntry(name, &ignore));
@@ -11732,6 +11868,10 @@
   return Script::RawCast(script);
 }
 
+void KernelProgramInfo::set_scripts(const Array& scripts) const {
+  StorePointer(&raw_ptr()->scripts_, scripts.raw());
+}
+
 void KernelProgramInfo::set_constants(const Array& constants) const {
   StorePointer(&raw_ptr()->constants_, constants.raw());
 }
@@ -12126,7 +12266,7 @@
 intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const {
   NoSafepointScope no_safepoint;
   const uint8_t* data = raw_ptr()->data();
-  return Utils::DecodeSLEB128(data, Length(), byte_index);
+  return Utils::DecodeSLEB128<intptr_t>(data, Length(), byte_index);
 }
 
 RawObjectPool* ObjectPool::New(intptr_t len) {
@@ -12143,13 +12283,63 @@
     result ^= raw;
     result.SetLength(len);
     for (intptr_t i = 0; i < len; i++) {
-      result.SetTypeAt(i, ObjectPool::kImmediate, ObjectPool::kPatchable);
+      result.SetTypeAt(i, ObjectPool::EntryType::kImmediate,
+                       ObjectPool::Patchability::kPatchable);
     }
   }
 
   return result.raw();
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+RawObjectPool* ObjectPool::NewFromBuilder(
+    const compiler::ObjectPoolBuilder& builder) {
+  const intptr_t len = builder.CurrentLength();
+  if (len == 0) {
+    return Object::empty_object_pool().raw();
+  }
+  const ObjectPool& result = ObjectPool::Handle(ObjectPool::New(len));
+  for (intptr_t i = 0; i < len; i++) {
+    auto entry = builder.EntryAt(i);
+    auto type = entry.type();
+    auto patchable = entry.patchable();
+    result.SetTypeAt(i, type, patchable);
+    if (type == EntryType::kTaggedObject) {
+      result.SetObjectAt(i, *entry.obj_);
+    } else {
+      result.SetRawValueAt(i, entry.raw_value_);
+    }
+  }
+  return result.raw();
+}
+
+void ObjectPool::CopyInto(compiler::ObjectPoolBuilder* builder) const {
+  ASSERT(builder->CurrentLength() == 0);
+  for (intptr_t i = 0; i < Length(); i++) {
+    auto type = TypeAt(i);
+    auto patchable = PatchableAt(i);
+    switch (type) {
+      case compiler::ObjectPoolBuilderEntry::kTaggedObject: {
+        compiler::ObjectPoolBuilderEntry entry(&Object::ZoneHandle(ObjectAt(i)),
+                                               patchable);
+        builder->AddObject(entry);
+        break;
+      }
+      case compiler::ObjectPoolBuilderEntry::kImmediate:
+      case compiler::ObjectPoolBuilderEntry::kNativeFunction:
+      case compiler::ObjectPoolBuilderEntry::kNativeFunctionWrapper: {
+        compiler::ObjectPoolBuilderEntry entry(RawValueAt(i), type, patchable);
+        builder->AddObject(entry);
+        break;
+      }
+      default:
+        UNREACHABLE();
+    }
+  }
+  ASSERT(builder->CurrentLength() == Length());
+}
+#endif
+
 const char* ObjectPool::ToCString() const {
   Zone* zone = Thread::Current()->zone();
   return zone->PrintToString("ObjectPool len:%" Pd, Length());
@@ -12160,13 +12350,14 @@
   for (intptr_t i = 0; i < Length(); i++) {
     intptr_t offset = OffsetFromIndex(i);
     THR_Print("  %" Pd " PP+0x%" Px ": ", i, offset);
-    if ((TypeAt(i) == kTaggedObject) || (TypeAt(i) == kNativeEntryData)) {
+    if ((TypeAt(i) == EntryType::kTaggedObject) ||
+        (TypeAt(i) == EntryType::kNativeEntryData)) {
       RawObject* obj = ObjectAt(i);
       THR_Print("0x%" Px " %s (obj)\n", reinterpret_cast<uword>(obj),
                 Object::Handle(obj).ToCString());
-    } else if (TypeAt(i) == kNativeFunction) {
+    } else if (TypeAt(i) == EntryType::kNativeFunction) {
       THR_Print("0x%" Px " (native function)\n", RawValueAt(i));
-    } else if (TypeAt(i) == kNativeFunctionWrapper) {
+    } else if (TypeAt(i) == EntryType::kNativeFunctionWrapper) {
       THR_Print("0x%" Px " (native function wrapper)\n", RawValueAt(i));
     } else {
       THR_Print("0x%" Px " (raw)\n", RawValueAt(i));
@@ -12831,7 +13022,7 @@
 void ICData::ResetSwitchable(Zone* zone) const {
   ASSERT(NumArgsTested() == 1);
   ASSERT(!IsTrackingExactness());
-  set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1, false)));
+  set_entries(Array::Handle(zone, CachedEmptyICDataArray(1, false)));
 }
 
 const char* ICData::ToCString() const {
@@ -12900,18 +13091,12 @@
 #endif
 }
 
-void ICData::set_ic_data_array(const Array& value) const {
+void ICData::set_entries(const Array& value) const {
   ASSERT(!value.IsNull());
-  StorePointer<RawArray*, MemoryOrder::kRelease>(&raw_ptr()->ic_data_,
+  StorePointer<RawArray*, MemoryOrder::kRelease>(&raw_ptr()->entries_,
                                                  value.raw());
 }
 
-#if defined(TAG_IC_DATA)
-void ICData::set_tag(Tag value) const {
-  StoreNonPointer(&raw_ptr()->tag_, value);
-}
-#endif
-
 intptr_t ICData::NumArgsTested() const {
   return NumArgsTestedBits::decode(raw_ptr()->state_bits_);
 }
@@ -12985,7 +13170,7 @@
 }
 
 intptr_t ICData::Length() const {
-  return (Smi::Value(ic_data()->ptr()->length_) / TestEntryLength());
+  return (Smi::Value(entries()->ptr()->length_) / TestEntryLength());
 }
 
 intptr_t ICData::NumberOfChecks() const {
@@ -13065,7 +13250,7 @@
   const intptr_t len = Length();
   ASSERT(index >= 0);
   ASSERT(index < len);
-  Array& data = Array::Handle(ic_data());
+  Array& data = Array::Handle(entries());
   const intptr_t start = index * TestEntryLength();
   const intptr_t end = start + TestEntryLength();
   for (intptr_t i = start; i < end; i++) {
@@ -13091,7 +13276,7 @@
   ASSERT(IsSentinelAt(len - 1));
   if (NumArgsTested() == 0) {
     // No type feedback is being collected.
-    const Array& data = Array::Handle(ic_data());
+    const Array& data = Array::Handle(entries());
     // Static calls with no argument checks hold only one target and the
     // sentinel value.
     ASSERT(len == 2);
@@ -13105,7 +13290,7 @@
     data.SetAt(1, value);
   } else {
     // Type feedback on arguments is being collected.
-    const Array& data = Array::Handle(ic_data());
+    const Array& data = Array::Handle(entries());
 
     // Fill all but the first entry with the sentinel.
     for (intptr_t i = len - 1; i > 0; i--) {
@@ -13182,7 +13367,7 @@
   // Can add only once.
   const intptr_t old_num = NumberOfChecks();
   ASSERT(old_num == 0);
-  Array& data = Array::Handle(ic_data());
+  Array& data = Array::Handle(entries());
   const intptr_t new_len = data.Length() + TestEntryLength();
   data = Array::Grow(data, new_len, Heap::kOld);
   WriteSentinel(data, TestEntryLength());
@@ -13195,7 +13380,7 @@
   data.SetAt(data_pos, value);
   // Multithreaded access to ICData requires setting of array to be the last
   // operation.
-  set_ic_data_array(data);
+  set_entries(data);
 }
 
 bool ICData::ValidateInterceptor(const Function& target) const {
@@ -13225,7 +13410,7 @@
   ASSERT(NumArgsTested() > 1);  // Otherwise use 'AddReceiverCheck'.
   ASSERT(class_ids.length() == NumArgsTested());
   const intptr_t old_num = NumberOfChecks();
-  Array& data = Array::Handle(ic_data());
+  Array& data = Array::Handle(entries());
   // ICData of static calls with NumArgsTested() > 0 have initially a
   // dummy set of cids entered (see ICData::AddTarget). That entry is
   // overwritten by first real type feedback data.
@@ -13266,11 +13451,11 @@
   data.SetAt(data_pos++, value);
   // Multithreaded access to ICData requires setting of array to be the last
   // operation.
-  set_ic_data_array(data);
+  set_entries(data);
 }
 
 RawArray* ICData::Grow(intptr_t* index) const {
-  Array& data = Array::Handle(ic_data());
+  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.
   *index = Length() - 1;
@@ -13345,14 +13530,14 @@
   }
   // Multithreaded access to ICData requires setting of array to be the last
   // operation.
-  set_ic_data_array(data);
+  set_entries(data);
 }
 
 StaticTypeExactnessState ICData::GetExactnessAt(intptr_t index) const {
   if (!IsTrackingExactness()) {
     return StaticTypeExactnessState::NotTracking();
   }
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   intptr_t data_pos = index * TestEntryLength();
   return StaticTypeExactnessState::Decode(
       Smi::Value(Smi::RawCast(data.At(data_pos + NumArgsTested() + 2))));
@@ -13365,7 +13550,7 @@
   ASSERT(class_ids != NULL);
   ASSERT(target != NULL);
   class_ids->Clear();
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   intptr_t data_pos = index * TestEntryLength();
   for (intptr_t i = 0; i < NumArgsTested(); i++) {
     class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
@@ -13375,7 +13560,7 @@
 
 bool ICData::IsSentinelAt(intptr_t index) const {
   ASSERT(index < Length());
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t entry_length = TestEntryLength();
   intptr_t data_pos = index * TestEntryLength();
   for (intptr_t i = 0; i < entry_length; i++) {
@@ -13393,7 +13578,7 @@
   ASSERT(class_ids != NULL);
   ASSERT(!IsSentinelAt(index));
   class_ids->Clear();
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   intptr_t data_pos = index * TestEntryLength();
   for (intptr_t i = 0; i < NumArgsTested(); i++) {
     class_ids->Add(Smi::Value(Smi::RawCast(data.At(data_pos++))));
@@ -13406,7 +13591,7 @@
   ASSERT(class_id != NULL);
   ASSERT(target != NULL);
   ASSERT(NumArgsTested() == 1);
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t data_pos = index * TestEntryLength();
   *class_id = Smi::Value(Smi::RawCast(data.At(data_pos)));
   *target ^= data.At(data_pos + 1);
@@ -13414,7 +13599,7 @@
 
 intptr_t ICData::GetCidAt(intptr_t index) const {
   ASSERT(NumArgsTested() == 1);
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t data_pos = index * TestEntryLength();
   return Smi::Value(Smi::RawCast(data.At(data_pos)));
 }
@@ -13430,17 +13615,17 @@
   ASSERT(!IsSentinelAt(index));
   const intptr_t data_pos = index * TestEntryLength();
   NoSafepointScope no_safepoint;
-  RawArray* raw_data = ic_data();
+  RawArray* raw_data = entries();
   return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos]));
 }
 
 RawFunction* ICData::GetTargetAt(intptr_t index) const {
   ASSERT(Isolate::Current()->compilation_allowed());
   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
-  ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction());
+  ASSERT(Object::Handle(Array::Handle(entries()).At(data_pos)).IsFunction());
 
   NoSafepointScope no_safepoint;
-  RawArray* raw_data = ic_data();
+  RawArray* raw_data = entries();
   return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]);
 }
 
@@ -13448,7 +13633,7 @@
   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
 
   NoSafepointScope no_safepoint;
-  RawArray* raw_data = ic_data();
+  RawArray* raw_data = entries();
   return raw_data->ptr()->data()[data_pos];
 }
 
@@ -13462,7 +13647,7 @@
   ASSERT(0 <= value);
   ASSERT(value <= Smi::kMaxValue);
 
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t data_pos =
       index * TestEntryLength() + CountIndexFor(NumArgsTested());
   data.SetAt(data_pos, Smi::Handle(Smi::New(value)));
@@ -13470,7 +13655,7 @@
 
 intptr_t ICData::GetCountAt(intptr_t index) const {
   ASSERT(Isolate::Current()->compilation_allowed());
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t data_pos =
       index * TestEntryLength() + CountIndexFor(NumArgsTested());
   intptr_t value = Smi::Value(Smi::RawCast(data.At(data_pos)));
@@ -13494,7 +13679,7 @@
 
 void ICData::SetCodeAt(intptr_t index, const Code& value) const {
   ASSERT(!Isolate::Current()->compilation_allowed());
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t data_pos =
       index * TestEntryLength() + CodeIndexFor(NumArgsTested());
   data.SetAt(data_pos, value);
@@ -13502,7 +13687,7 @@
 
 void ICData::SetEntryPointAt(intptr_t index, const Smi& value) const {
   ASSERT(!Isolate::Current()->compilation_allowed());
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   const intptr_t data_pos =
       index * TestEntryLength() + EntryPointIndexFor(NumArgsTested());
   data.SetAt(data_pos, value);
@@ -13637,7 +13822,7 @@
     pos += result.TestEntryLength();
   }
   WriteSentinel(data, result.TestEntryLength());
-  result.set_ic_data_array(data);
+  result.set_entries(data);
   ASSERT(result.NumberOfChecksIs(aggregate.length()));
   return result.raw();
 }
@@ -13788,9 +13973,6 @@
   result.set_arguments_descriptor(arguments_descriptor);
   NOT_IN_PRECOMPILED(result.set_deopt_id(deopt_id));
   result.set_state_bits(0);
-#if defined(TAG_IC_DATA)
-  result.set_tag(ICData::Tag::kUnknown);
-#endif
   result.set_rebind_rule(rebind_rule);
   result.SetNumArgsTested(num_args_tested);
   NOT_IN_PRECOMPILED(result.SetStaticReceiverType(static_receiver_type));
@@ -13798,7 +13980,7 @@
 }
 
 bool ICData::IsImmutable() const {
-  const Array& data = Array::Handle(ic_data());
+  const Array& data = Array::Handle(entries());
   return data.IsImmutable();
 }
 
@@ -13813,9 +13995,6 @@
   }
   result.set_deopt_id(DeoptId::kNone);
   result.set_state_bits(0);
-#if defined(TAG_IC_DATA)
-  result.set_tag(ICData::Tag::kUnknown);
-#endif
   return result.raw();
 }
 
@@ -13831,7 +14010,7 @@
       zone,
       NewDescriptor(zone, owner, target_name, arguments_descriptor, deopt_id,
                     num_args_tested, rebind_rule, static_receiver_type));
-  result.set_ic_data_array(Array::Handle(
+  result.set_entries(Array::Handle(
       zone,
       CachedEmptyICDataArray(num_args_tested, result.IsTrackingExactness())));
   return result.raw();
@@ -13858,7 +14037,7 @@
       from.NumArgsTested(), from.rebind_rule(),
       AbstractType::Handle(from.StaticReceiverType())));
   // Clone entry array.
-  const Array& from_array = Array::Handle(zone, from.ic_data());
+  const Array& from_array = Array::Handle(zone, from.entries());
   const intptr_t len = from_array.Length();
   const Array& cloned_array = Array::Handle(zone, Array::New(len, Heap::kOld));
   Object& obj = Object::Handle(zone);
@@ -13866,7 +14045,7 @@
     obj = from_array.At(i);
     cloned_array.SetAt(i, obj);
   }
-  result.set_ic_data_array(cloned_array);
+  result.set_entries(cloned_array);
   // Copy deoptimization reasons.
   result.SetDeoptReasons(from.DeoptReasons());
   return result.raw();
@@ -14239,6 +14418,19 @@
   const Code::Comments& comments_;
   String& string_;
 };
+
+static const Code::Comments& CreateCommentsFrom(
+    compiler::Assembler* assembler) {
+  const auto& comments = assembler->comments();
+  Code::Comments& result = Code::Comments::New(comments.length());
+
+  for (intptr_t i = 0; i < comments.length(); i++) {
+    result.SetPCOffsetAt(i, comments[i]->pc_offset());
+    result.SetCommentAt(i, comments[i]->comment());
+  }
+
+  return result;
+}
 #endif
 
 RawCode* Code::FinalizeCode(const char* name,
@@ -14255,7 +14447,10 @@
   ASSERT(assembler != NULL);
   const auto object_pool =
       pool_attachment == PoolAttachment::kAttachPool
-          ? &ObjectPool::Handle(assembler->MakeObjectPool())
+          ? &ObjectPool::Handle(assembler->HasObjectPoolBuilder()
+                                    ? ObjectPool::NewFromBuilder(
+                                          assembler->object_pool_builder())
+                                    : ObjectPool::empty_object_pool().raw())
           : nullptr;
 
   // Allocate the Code and Instructions objects.  Code is allocated first
@@ -14264,7 +14459,7 @@
   intptr_t pointer_offset_count = assembler->CountPointerOffsets();
   Code& code = Code::ZoneHandle(Code::New(pointer_offset_count));
 #ifdef TARGET_ARCH_IA32
-  assembler->set_code_object(code);
+  assembler->GetSelfHandle() = code.raw();
 #endif
   Instructions& instrs = Instructions::ZoneHandle(Instructions::New(
       assembler->CodeSize(), assembler->has_single_entry_point(),
@@ -14314,7 +14509,8 @@
     if (FLAG_write_protect_code) {
       uword address = RawObject::ToAddr(instrs.raw());
       VirtualMemory::Protect(reinterpret_cast<void*>(address),
-                             instrs.raw()->Size(), VirtualMemory::kReadExecute);
+                             instrs.raw()->HeapSize(),
+                             VirtualMemory::kReadExecute);
     }
   }
   CPU::FlushICache(instrs.PayloadStart(), instrs.Size());
@@ -14327,7 +14523,7 @@
 #endif
 
 #ifndef PRODUCT
-  const Code::Comments& comments = assembler->GetCodeComments();
+  const Code::Comments& comments = CreateCommentsFrom(assembler);
 
   code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
   CodeCommentsWrapper comments_wrapper(comments);
@@ -14467,6 +14663,10 @@
     String& cls_name = String::Handle(zone, Class::Cast(obj).ScrubbedName());
     ASSERT(!cls_name.IsNull());
     return zone->PrintToString("[Stub] Allocate %s", cls_name.ToCString());
+  } else if (obj.IsAbstractType()) {
+    // Type test stub.
+    return zone->PrintToString("[Stub] Type Test %s",
+                               AbstractType::Cast(obj).ToCString());
   } else {
     ASSERT(obj.IsFunction());
     // Dart function.
@@ -14490,14 +14690,18 @@
   return Name();
 }
 
+bool Code::IsStubCode() const {
+  return owner() == Object::null();
+}
+
 bool Code::IsAllocationStubCode() const {
   const Object& obj = Object::Handle(owner());
   return obj.IsClass();
 }
 
-bool Code::IsStubCode() const {
+bool Code::IsTypeTestStubCode() const {
   const Object& obj = Object::Handle(owner());
-  return obj.IsNull();
+  return obj.IsAbstractType();
 }
 
 bool Code::IsFunctionCode() const {
@@ -14640,27 +14844,6 @@
 #endif
 }
 
-void Bytecode::set_instructions(const ExternalTypedData& instructions) const {
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  ASSERT(Thread::Current()->IsMutatorThread());
-  // The interpreter requires the instructions to be aligned.
-  ASSERT(Utils::IsAligned(instructions.DataAddr(0), sizeof(KBCInstr)));
-  StorePointer(&raw_ptr()->instructions_, instructions.raw());
-#else
-  UNREACHABLE();
-#endif
-}
-
-uword Bytecode::PayloadStart() const {
-  const ExternalTypedData& instr = ExternalTypedData::Handle(instructions());
-  return reinterpret_cast<uword>(instr.DataAddr(0));
-}
-
-intptr_t Bytecode::Size() const {
-  const ExternalTypedData& instr = ExternalTypedData::Handle(instructions());
-  return instr.LengthInBytes();
-}
-
 void Bytecode::Disassemble(DisassemblyFormatter* formatter) const {
 #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -14680,7 +14863,9 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-RawBytecode* Bytecode::New(const ExternalTypedData& instructions,
+RawBytecode* 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();
@@ -14689,9 +14874,11 @@
     RawObject* raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld);
     NoSafepointScope no_safepoint;
     result ^= raw;
-    result.set_pc_descriptors(Object::empty_descriptors());
     result.set_instructions(instructions);
+    result.set_instructions_size(instructions_size);
     result.set_object_pool(object_pool);
+    result.set_pc_descriptors(Object::empty_descriptors());
+    result.set_instructions_binary_offset(instructions_offset);
     result.set_source_positions_binary_offset(0);
   }
   return result.raw();
@@ -15480,7 +15667,8 @@
 }
 
 RawObject* Instance::InvokeGetter(const String& getter_name,
-                                  bool respect_reflectable) const {
+                                  bool respect_reflectable,
+                                  bool check_is_entrypoint) const {
   Zone* zone = Thread::Current()->zone();
 
   Class& klass = Class::Handle(zone, clazz());
@@ -15494,10 +15682,29 @@
   Function& function = Function::Handle(
       zone, Resolver::ResolveDynamicAnyArgs(zone, klass, internal_getter_name));
 
+  if (check_is_entrypoint) {
+    // 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) {
+      field = function.accessor_field();
+    }
+    if (!field.IsNull()) {
+      CHECK_ERROR(field.VerifyEntryPoint(EntryPointPragma::kGetterOnly));
+    } else if (!function.IsNull()) {
+      CHECK_ERROR(function.VerifyEntryPoint());
+    }
+  }
+
   // Check for method extraction when method extractors are not created.
   if (function.IsNull() && !FLAG_lazy_dispatchers) {
     function = Resolver::ResolveDynamicAnyArgs(zone, klass, getter_name);
-    if (!function.IsNull()) {
+
+    if (!function.IsNull() && check_is_entrypoint) {
+      CHECK_ERROR(EntryPointClosurizationError(getter_name));
+    }
+
+    if (!function.IsNull() && function.SafeToClosurize()) {
       const Function& closure_function =
           Function::Handle(zone, function.ImplicitClosureFunction());
       return closure_function.ImplicitInstanceClosure(*this);
@@ -15518,7 +15725,8 @@
 
 RawObject* Instance::InvokeSetter(const String& setter_name,
                                   const Instance& value,
-                                  bool respect_reflectable) const {
+                                  bool respect_reflectable,
+                                  bool check_is_entrypoint) const {
   Zone* zone = Thread::Current()->zone();
 
   const Class& klass = Class::Handle(zone, clazz());
@@ -15532,6 +15740,20 @@
   const Function& setter = Function::Handle(
       zone, Resolver::ResolveDynamicAnyArgs(zone, klass, internal_setter_name));
 
+  if (check_is_entrypoint) {
+    // 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) {
+      field = setter.accessor_field();
+    }
+    if (!field.IsNull()) {
+      CHECK_ERROR(field.VerifyEntryPoint(EntryPointPragma::kSetterOnly));
+    } else if (!setter.IsNull()) {
+      CHECK_ERROR(setter.VerifyEntryPoint());
+    }
+  }
+
   const int kTypeArgsLen = 0;
   const int kNumArgs = 2;
   const Array& args = Array::Handle(zone, Array::New(kNumArgs));
@@ -15548,12 +15770,17 @@
 RawObject* Instance::Invoke(const String& function_name,
                             const Array& args,
                             const Array& arg_names,
-                            bool respect_reflectable) const {
+                            bool respect_reflectable,
+                            bool check_is_entrypoint) const {
   Zone* zone = Thread::Current()->zone();
   Class& klass = Class::Handle(zone, clazz());
   Function& function = Function::Handle(
       zone, Resolver::ResolveDynamicAnyArgs(zone, klass, function_name));
 
+  if (!function.IsNull() && check_is_entrypoint) {
+    CHECK_ERROR(function.VerifyEntryPoint());
+  }
+
   // TODO(regis): Support invocation of generic functions with type arguments.
   const int kTypeArgsLen = 0;
   const Array& args_descriptor = Array::Handle(
@@ -15570,6 +15797,9 @@
         String::Handle(zone, Field::GetterName(function_name));
     function = Resolver::ResolveDynamicAnyArgs(zone, klass, getter_name);
     if (!function.IsNull()) {
+      if (check_is_entrypoint) {
+        CHECK_ERROR(EntryPointClosurizationError(function_name));
+      }
       ASSERT(function.kind() != RawFunction::kMethodExtractor);
       // Invoke the getter.
       const int kNumArgs = 1;
@@ -16682,16 +16912,16 @@
   return "AbstractType";
 }
 
-void AbstractType::SetTypeTestingStub(const Instructions& instr) const {
-  if (instr.IsNull()) {
+void AbstractType::SetTypeTestingStub(const Code& stub) const {
+  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);
     StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, 0);
   } else {
-    StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_,
-                    instr.EntryPoint());
+    StoreNonPointer(&raw_ptr()->type_test_stub_entry_point_, stub.EntryPoint());
   }
+  StorePointer(&raw_ptr()->type_test_stub_, stub.raw());
 }
 
 RawType* Type::NullType() {
@@ -17334,8 +17564,8 @@
   result.set_token_pos(token_pos);
   result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
 
-  result.SetTypeTestingStub(Instructions::Handle(
-      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
+  result.SetTypeTestingStub(
+      Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -17436,7 +17666,7 @@
   ASSERT(!instantiated_ref_type.IsTypeRef());
   instantiated_type_ref.set_type(instantiated_ref_type);
 
-  instantiated_type_ref.SetTypeTestingStub(Instructions::Handle(
+  instantiated_type_ref.SetTypeTestingStub(Code::Handle(
       TypeTestingStubGenerator::DefaultCodeForType(instantiated_type_ref)));
   return instantiated_type_ref.raw();
 }
@@ -17504,8 +17734,8 @@
   const TypeRef& result = TypeRef::Handle(Z, TypeRef::New());
   result.set_type(type);
 
-  result.SetTypeTestingStub(Instructions::Handle(
-      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
+  result.SetTypeTestingStub(
+      Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -17710,8 +17940,8 @@
   result.StoreNonPointer(&result.raw_ptr()->type_state_,
                          RawTypeParameter::kAllocated);
 
-  result.SetTypeTestingStub(Instructions::Handle(
-      Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
+  result.SetTypeTestingStub(
+      Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));
   return result.raw();
 }
 
@@ -19881,7 +20111,7 @@
 RawArray* Array::New(intptr_t len, Heap::Space space) {
   ASSERT(Isolate::Current()->object_store()->array_class() != Class::null());
   RawArray* result = New(kClassId, len, space);
-  if (result->Size() > Heap::kNewAllocatableSize) {
+  if (result->HeapSize() > Heap::kNewAllocatableSize) {
     ASSERT(result->IsOldObject());
     result->SetCardRememberedBitUnsynchronized();
   }
@@ -20546,21 +20776,6 @@
   return result.raw();
 }
 
-RawTypedData* TypedData::EmptyUint32Array(Thread* thread) {
-  ASSERT(thread != NULL);
-  Isolate* isolate = thread->isolate();
-  ASSERT(isolate != NULL);
-  ASSERT(isolate->object_store() != NULL);
-  if (isolate->object_store()->empty_uint32_array() != TypedData::null()) {
-    // Already created.
-    return isolate->object_store()->empty_uint32_array();
-  }
-  const TypedData& array = TypedData::Handle(
-      thread->zone(), TypedData::New(kTypedDataUint32ArrayCid, 0, Heap::kOld));
-  isolate->object_store()->set_empty_uint32_array(array);
-  return array.raw();
-}
-
 const char* TypedData::ToCString() const {
   switch (GetClassId()) {
 #define CASE_TYPED_DATA_CLASS(clazz)                                           \
@@ -20602,6 +20817,75 @@
   return "ExternalTypedData";
 }
 
+RawPointer* Pointer::New(const AbstractType& type_arg,
+                         uint8_t* c_memory_address,
+                         intptr_t cid,
+                         Heap::Space space) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  TypeArguments& type_args = TypeArguments::Handle(zone);
+  type_args = TypeArguments::New(1);
+  type_args.SetTypeAt(Pointer::kNativeTypeArgPos, type_arg);
+  type_args ^= type_args.Canonicalize();
+
+  const Class& cls = Class::Handle(Isolate::Current()->class_table()->At(cid));
+  cls.EnsureIsFinalized(Thread::Current());
+
+  Pointer& result = Pointer::Handle(zone);
+  result ^= Object::Allocate(cid, Pointer::InstanceSize(), space);
+  NoSafepointScope no_safepoint;
+  result.SetTypeArguments(type_args);
+  result.SetCMemoryAddress(c_memory_address);
+
+  return result.raw();
+}
+
+const char* Pointer::ToCString() const {
+  TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments());
+  String& type_args_name = String::Handle(type_args.UserVisibleName());
+  return OS::SCreate(Thread::Current()->zone(), "Pointer%s: address=%p",
+                     type_args_name.ToCString(), GetCMemoryAddress());
+}
+
+RawDynamicLibrary* DynamicLibrary::New(void* handle, Heap::Space space) {
+  DynamicLibrary& result = DynamicLibrary::Handle();
+  result ^= Object::Allocate(kFfiDynamicLibraryCid,
+                             DynamicLibrary::InstanceSize(), space);
+  NoSafepointScope no_safepoint;
+  result.SetHandle(handle);
+  return result.raw();
+}
+
+bool Pointer::IsPointer(const Instance& obj) {
+  ASSERT(!obj.IsNull());
+
+  // fast path for predefined classes
+  intptr_t cid = obj.raw()->GetClassId();
+  if (RawObject::IsFfiPointerClassId(cid)) {
+    return true;
+  }
+
+  // slow check for subtyping
+  const Class& pointer_class = Class::ZoneHandle(
+      Isolate::Current()->object_store()->ffi_pointer_class());
+  AbstractType& pointer_type =
+      AbstractType::Handle(pointer_class.DeclarationType());
+  pointer_type ^= pointer_type.InstantiateFrom(Object::null_type_arguments(),
+                                               Object::null_type_arguments(),
+                                               kNoneFree, NULL, Heap::kNew);
+  AbstractType& type = AbstractType::Handle(obj.GetType(Heap::kNew));
+  return type.IsSubtypeOf(pointer_type, Heap::kNew);
+}
+
+bool Instance::IsPointer() const {
+  return Pointer::IsPointer(*this);
+}
+
+const char* DynamicLibrary::ToCString() const {
+  return OS::SCreate(Thread::Current()->zone(), "DynamicLibrary: handle=%p",
+                     GetHandle());
+}
+
 RawCapability* Capability::New(uint64_t id, Heap::Space space) {
   Capability& result = Capability::Handle();
   {
@@ -21371,4 +21655,148 @@
   table.Release();
 }
 
+EntryPointPragma FindEntryPointPragma(Isolate* I,
+                                      const Array& metadata,
+                                      Field* reusable_field_handle,
+                                      Object* pragma) {
+  for (intptr_t i = 0; i < metadata.Length(); i++) {
+    *pragma = metadata.At(i);
+    if (pragma->clazz() != I->object_store()->pragma_class()) {
+      continue;
+    }
+    *reusable_field_handle = I->object_store()->pragma_name();
+    if (Instance::Cast(*pragma).GetField(*reusable_field_handle) !=
+        Symbols::vm_entry_point().raw()) {
+      continue;
+    }
+    *reusable_field_handle = I->object_store()->pragma_options();
+    *pragma = Instance::Cast(*pragma).GetField(*reusable_field_handle);
+    if (pragma->raw() == Bool::null() || pragma->raw() == Bool::True().raw()) {
+      return EntryPointPragma::kAlways;
+      break;
+    }
+    if (pragma->raw() == Symbols::Get().raw()) {
+      return EntryPointPragma::kGetterOnly;
+    }
+    if (pragma->raw() == Symbols::Set().raw()) {
+      return EntryPointPragma::kSetterOnly;
+    }
+  }
+  return EntryPointPragma::kNever;
+}
+
+DART_WARN_UNUSED_RESULT
+RawError* VerifyEntryPoint(const Library& lib,
+                           const Object& member,
+                           const Object& annotated,
+                           EntryPointPragma kind) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  // Annotations are discarded in the AOT snapshot, so we can't determine
+  // precisely if this member was marked as an entry-point. Instead, we use
+  // "has_pragma()" as a proxy, since that bit is usually retained.
+  bool is_marked_entrypoint = true;
+  if (annotated.IsClass() && !Class::Cast(annotated).has_pragma()) {
+    is_marked_entrypoint = false;
+  } else if (annotated.IsField() && !Field::Cast(annotated).has_pragma()) {
+    is_marked_entrypoint = false;
+  } else if (annotated.IsFunction() &&
+             !Function::Cast(annotated).has_pragma()) {
+    is_marked_entrypoint = false;
+  }
+#else
+  Object& metadata = Object::Handle(Object::empty_array().raw());
+  if (!annotated.IsNull()) {
+    metadata = lib.GetMetadata(annotated);
+  }
+  if (metadata.IsError()) return Error::RawCast(metadata.raw());
+  ASSERT(!metadata.IsNull() && metadata.IsArray());
+  EntryPointPragma pragma =
+      FindEntryPointPragma(Isolate::Current(), Array::Cast(metadata),
+                           &Field::Handle(), &Object::Handle());
+  const bool is_marked_entrypoint =
+      pragma == kind || pragma == EntryPointPragma::kAlways;
+#endif
+  if (!is_marked_entrypoint) {
+    const char* member_cstring =
+        member.IsFunction()
+            ? Function::Cast(member).ToLibNamePrefixedQualifiedCString()
+            : member.ToCString();
+    char const* error = OS::SCreate(
+        Thread::Current()->zone(),
+        "ERROR: It is illegal to access '%s' through Dart C API.\n"
+        "ERROR: See "
+        "https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/"
+        "aot/entry_point_pragma.md\n",
+        member_cstring);
+    OS::PrintErr("%s", error);
+    return ApiError::New(String::Handle(String::New(error)));
+  }
+  return Error::null();
+}
+
+DART_WARN_UNUSED_RESULT
+RawError* EntryPointClosurizationError(const String& getter_name) {
+  if (!FLAG_verify_entry_points) return Error::null();
+
+  char const* error = OS::SCreate(
+      Thread::Current()->zone(),
+      "ERROR: Entry-points do not allow closurizing methods "
+      "(failure to resolve '%s')\n"
+      "ERROR: See "
+      "https://github.com/dart-lang/sdk/blob/master/runtime/docs/compiler/"
+      "aot/entry_point_pragma.md\n",
+      getter_name.ToCString());
+  OS::PrintErr("%s", error);
+  return ApiError::New(String::Handle(String::New(error)));
+}
+
+RawError* Function::VerifyEntryPoint() 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::kGetterFunction:
+    case RawFunction::kSetterFunction:
+    case RawFunction::kConstructor:
+      return dart::VerifyEntryPoint(lib, *this, *this,
+                                    EntryPointPragma::kAlways);
+      break;
+    case RawFunction::kImplicitGetter: {
+      const Field& accessed = Field::Handle(accessor_field());
+      return dart::VerifyEntryPoint(lib, *this, accessed,
+                                    EntryPointPragma::kGetterOnly);
+      break;
+    }
+    case RawFunction::kImplicitSetter: {
+      const Field& accessed = Field::Handle(accessor_field());
+      return dart::VerifyEntryPoint(lib, *this, accessed,
+                                    EntryPointPragma::kSetterOnly);
+      break;
+    }
+    default:
+      return dart::VerifyEntryPoint(lib, *this, Object::Handle(),
+                                    EntryPointPragma::kAlways);
+      break;
+  }
+}
+
+RawError* 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 {
+  if (!FLAG_verify_entry_points) return Error::null();
+  const Library& lib = Library::Handle(library());
+  if (!lib.IsNull()) {
+    return dart::VerifyEntryPoint(lib, *this, *this, EntryPointPragma::kAlways);
+  } else {
+    return Error::null();
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index f1de141..e426c9d0 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5,12 +5,19 @@
 #ifndef RUNTIME_VM_OBJECT_H_
 #define RUNTIME_VM_OBJECT_H_
 
+#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
+#error "Should not include runtime"
+#endif
+
 #include <tuple>
 #include "include/dart_api.h"
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/bitmap.h"
+#include "vm/code_entry_kind.h"
+#include "vm/compiler/assembler/object_pool_builder.h"
 #include "vm/compiler/method_recognizer.h"
+#include "vm/compiler/runtime_api.h"
 #include "vm/dart.h"
 #include "vm/flags.h"
 #include "vm/globals.h"
@@ -22,6 +29,7 @@
 #include "vm/os.h"
 #include "vm/raw_object.h"
 #include "vm/report.h"
+#include "vm/static_type_exactness_state.h"
 #include "vm/tags.h"
 #include "vm/thread.h"
 #include "vm/token_position.h"
@@ -29,6 +37,10 @@
 namespace dart {
 
 // Forward declarations.
+namespace compiler {
+class Assembler;
+}
+
 namespace kernel {
 class Program;
 class TreeNode;
@@ -39,7 +51,6 @@
 #undef DEFINE_FORWARD_DECLARATION
 class Api;
 class ArgumentsDescriptor;
-class Assembler;
 class Closure;
 class Code;
 class DeoptInstr;
@@ -420,6 +431,9 @@
   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() {
+    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_; }
@@ -667,6 +681,8 @@
   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.
@@ -827,6 +843,9 @@
     StoreNonPointer(&raw_ptr()->id_, value);
   }
   static intptr_t id_offset() { return OFFSET_OF(RawClass, id_); }
+  static intptr_t num_type_arguments_offset() {
+    return OFFSET_OF(RawClass, num_type_arguments_);
+  }
 
   RawString* Name() const;
   RawString* ScrubbedName() const;
@@ -939,20 +958,15 @@
   // classes.
   RawClass* SuperClass(bool original_classes = false) const;
 
-  RawClass* GetPatchClass() const;
-
   // Interfaces is an array of Types.
   RawArray* interfaces() const { return raw_ptr()->interfaces_; }
   void set_interfaces(const Array& value) const;
-  static intptr_t interfaces_offset() {
-    return OFFSET_OF(RawClass, interfaces_);
-  }
 
   // Returns the list of classes directly implementing this class.
   RawGrowableObjectArray* direct_implementors() const {
     return raw_ptr()->direct_implementors_;
   }
-  void AddDirectImplementor(const Class& subclass) const;
+  void AddDirectImplementor(const Class& subclass, bool is_mixin) const;
   void ClearDirectImplementors() const;
 
   // Returns the list of classes having this class as direct superclass.
@@ -1021,6 +1035,9 @@
 
   bool IsPrivate() const;
 
+  DART_WARN_UNUSED_RESULT
+  RawError* VerifyEntryPoint() const;
+
   // Returns an array of instance and static fields defined by this class.
   RawArray* fields() const { return raw_ptr()->fields_; }
   void SetFields(const Array& value) const;
@@ -1069,8 +1086,6 @@
   RawField* LookupInstanceFieldAllowPrivate(const String& name) const;
   RawField* LookupStaticFieldAllowPrivate(const String& name) const;
 
-  RawLibraryPrefix* LookupLibraryPrefix(const String& name) const;
-
   RawDouble* LookupCanonicalDouble(Zone* zone, double value) const;
   RawMint* LookupCanonicalMint(Zone* zone, int64_t value) const;
 
@@ -1158,6 +1173,9 @@
   }
   void set_is_allocated(bool value) const;
 
+  bool is_loaded() const { return IsLoadedBit::decode(raw_ptr()->state_bits_); }
+  void set_is_loaded(bool value) const;
+
   uint16_t num_native_fields() const { return raw_ptr()->num_native_fields_; }
   void set_num_native_fields(uint16_t value) const {
     StoreNonPointer(&raw_ptr()->num_native_fields_, value);
@@ -1196,13 +1214,16 @@
   RawObject* Invoke(const String& selector,
                     const Array& arguments,
                     const Array& argument_names,
-                    bool respect_reflectable = true) const;
+                    bool respect_reflectable = true,
+                    bool check_is_entrypoint = false) const;
   RawObject* InvokeGetter(const String& selector,
                           bool throw_nsm_if_absent,
-                          bool respect_reflectable = true) const;
+                          bool respect_reflectable = true,
+                          bool check_is_entrypoint = false) const;
   RawObject* InvokeSetter(const String& selector,
                           const Instance& argument,
-                          bool respect_reflectable = true) const;
+                          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
@@ -1244,6 +1265,9 @@
   // Allocate the raw ExternalTypedData classes.
   static RawClass* NewExternalTypedDataClass(intptr_t class_id);
 
+  // Allocate the raw Pointer classes.
+  static RawClass* NewPointerClass(intptr_t class_id);
+
   // Register code that has used CHA for optimization.
   // TODO(srdjan): Also register kind of CHA optimization (e.g.: leaf class,
   // leaf method, ...).
@@ -1319,6 +1343,7 @@
     kEnumBit,
     kTransformedMixinApplicationBit,
     kIsAllocatedBit,
+    kIsLoadedBit,
   };
   class ConstBit : public BitField<uint16_t, bool, kConstBit, 1> {};
   class ImplementedBit : public BitField<uint16_t, bool, kImplementedBit, 1> {};
@@ -1339,6 +1364,7 @@
   class TransformedMixinApplicationBit
       : public BitField<uint16_t, bool, kTransformedMixinApplicationBit, 1> {};
   class IsAllocatedBit : public BitField<uint16_t, bool, kIsAllocatedBit, 1> {};
+  class IsLoadedBit : public BitField<uint16_t, bool, kIsLoadedBit, 1> {};
 
   void set_name(const String& value) const;
   void set_user_name(const String& value) const;
@@ -1374,9 +1400,6 @@
 
   int16_t num_type_arguments() const { return raw_ptr()->num_type_arguments_; }
   void set_num_type_arguments(intptr_t value) const;
-  static intptr_t num_type_arguments_offset() {
-    return OFFSET_OF(RawClass, num_type_arguments_);
-  }
 
  public:
   bool has_pragma() const {
@@ -1527,134 +1550,6 @@
   friend class Class;
 };
 
-// Representation of a state of runtime tracking of static type exactness for
-// a particular location in the program (e.g. exactness of type annotation
-// on a field).
-//
-// Given the static type G<T0, ..., Tn> we say that it is exact iff any
-// values that can be observed at this location has runtime type T such that
-// type arguments of T at G are exactly <T0, ..., Tn>.
-//
-// Currently we only support tracking for locations that are also known
-// to be monomorphic with respect to the actual class of the values it contains.
-//
-// Important: locations should never switch from tracked (kIsTriviallyExact,
-// kHasExactSuperType, kHasExactSuperClass, kNotExact) to not tracked
-// (kNotTracking) or the other way around because that would affect unoptimized
-// graphs generated by graph builder and skew deopt ids.
-class StaticTypeExactnessState final {
- public:
-  // Values stored in the location with static type G<T0, ..., Tn> are all
-  // instances of C<T0, ..., Tn> and C<U0, ..., Un> at G has type parameters
-  // <U0, ..., Un>.
-  //
-  // For trivially exact types we can simply compare type argument
-  // vectors as pointers to check exactness. That's why we represent
-  // trivially exact locations as offset in words to the type arguments of
-  // class C. All other states are represented as non-positive values.
-  //
-  // Note: we are ignoring the type argument vector sharing optimization for
-  // now.
-  static inline StaticTypeExactnessState TriviallyExact(
-      intptr_t type_arguments_offset) {
-    ASSERT((type_arguments_offset > 0) &&
-           Utils::IsAligned(type_arguments_offset, kWordSize) &&
-           Utils::IsInt(8, type_arguments_offset / kWordSize));
-    return StaticTypeExactnessState(type_arguments_offset / kWordSize);
-  }
-
-  static inline bool CanRepresentAsTriviallyExact(
-      intptr_t type_arguments_offset) {
-    return Utils::IsInt(8, type_arguments_offset / kWordSize);
-  }
-
-  // Values stored in the location with static type G<T0, ..., Tn> are all
-  // instances of class C<...> and C<U0, ..., Un> at G has type
-  // parameters <T0, ..., Tn> for any <U0, ..., Un> - that is C<...> has a
-  // supertype G<T0, ..., Tn>.
-  //
-  // For such locations we can simply check if the value stored
-  // is an instance of an expected class and we don't have to look at
-  // type arguments carried by the instance.
-  //
-  // We distinguish situations where we know that G is a superclass of C from
-  // situations where G might be superinterface of C - because in the first
-  // type arguments of G give us constant prefix of type arguments of C.
-  static inline StaticTypeExactnessState HasExactSuperType() {
-    return StaticTypeExactnessState(kHasExactSuperType);
-  }
-
-  static inline StaticTypeExactnessState HasExactSuperClass() {
-    return StaticTypeExactnessState(kHasExactSuperClass);
-  }
-
-  // Values stored in the location don't fall under either kIsTriviallyExact
-  // or kHasExactSuperType categories.
-  //
-  // Note: that does not imply that static type annotation is not exact
-  // according to a broader definition, e.g. location might simply be
-  // polymorphic and store instances of multiple different types.
-  // However for simplicity we don't track such cases yet.
-  static inline StaticTypeExactnessState NotExact() {
-    return StaticTypeExactnessState(kNotExact);
-  }
-
-  // The location does not track exactness of its static type at runtime.
-  static inline StaticTypeExactnessState NotTracking() {
-    return StaticTypeExactnessState(kNotTracking);
-  }
-
-  static inline StaticTypeExactnessState Unitialized() {
-    return StaticTypeExactnessState(kUninitialized);
-  }
-
-  static StaticTypeExactnessState Compute(const Type& static_type,
-                                          const Instance& value,
-                                          bool print_trace = false);
-
-  bool IsTracking() const { return value_ != kNotTracking; }
-  bool IsUninitialized() const { return value_ == kUninitialized; }
-  bool IsHasExactSuperClass() const { return value_ == kHasExactSuperClass; }
-  bool IsHasExactSuperType() const { return value_ == kHasExactSuperType; }
-  bool IsTriviallyExact() const { return value_ > kUninitialized; }
-  bool NeedsFieldGuard() const { return value_ >= kUninitialized; }
-  bool IsExactOrUninitialized() const { return value_ > kNotExact; }
-  bool IsExact() const {
-    return IsTriviallyExact() || IsHasExactSuperType() ||
-           IsHasExactSuperClass();
-  }
-
-  const char* ToCString() const;
-
-  StaticTypeExactnessState CollapseSuperTypeExactness() const {
-    return IsHasExactSuperClass() ? HasExactSuperType() : *this;
-  }
-
-  static inline StaticTypeExactnessState Decode(int8_t value) {
-    return StaticTypeExactnessState(value);
-  }
-
-  int8_t Encode() const { return value_; }
-  intptr_t GetTypeArgumentsOffsetInWords() const {
-    ASSERT(IsTriviallyExact());
-    return value_;
-  }
-
-  static constexpr int8_t kUninitialized = 0;
-
- private:
-  static constexpr int8_t kNotTracking = -4;
-  static constexpr int8_t kNotExact = -3;
-  static constexpr int8_t kHasExactSuperType = -2;
-  static constexpr int8_t kHasExactSuperClass = -1;
-
-  explicit StaticTypeExactnessState(int8_t value) : value_(value) {}
-
-  int8_t value_;
-
-  DISALLOW_ALLOCATION();
-};
-
 // 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
@@ -1803,7 +1698,7 @@
     return OFFSET_OF(RawICData, args_descriptor_);
   }
 
-  static intptr_t ic_data_offset() { return OFFSET_OF(RawICData, ic_data_); }
+  static intptr_t entries_offset() { return OFFSET_OF(RawICData, entries_); }
 
   static intptr_t owner_offset() { return OFFSET_OF(RawICData, owner_); }
 
@@ -1960,12 +1855,6 @@
     kCachedICDataArrayCount = kCachedICDataOneArgWithExactnessTrackingIdx + 1,
   };
 
-#if defined(TAG_IC_DATA)
-  using Tag = RawICData::Tag;
-  void set_tag(Tag value) const;
-  Tag tag() const { return raw_ptr()->tag_; }
-#endif
-
   bool is_static_call() const;
 
   intptr_t FindCheck(const GrowableArray<intptr_t>& cids) const;
@@ -1973,8 +1862,8 @@
  private:
   static RawICData* New();
 
-  RawArray* ic_data() const {
-    return AtomicOperations::LoadAcquire(&raw_ptr()->ic_data_);
+  RawArray* entries() const {
+    return AtomicOperations::LoadAcquire(&raw_ptr()->entries_);
   }
 
   // Grows the array and also sets the argument to the index that should be used
@@ -1986,7 +1875,7 @@
   void set_arguments_descriptor(const Array& value) const;
   void set_deopt_id(intptr_t value) const;
   void SetNumArgsTested(intptr_t value) const;
-  void set_ic_data_array(const Array& value) const;
+  void set_entries(const Array& value) const;
   void set_state_bits(uint32_t bits) const;
 
   bool ValidateInterceptor(const Function& target) const;
@@ -2222,6 +2111,8 @@
   // It is not the only Code object that points to this function.
   RawCode* CurrentCode() const { return CurrentCodeOf(raw()); }
 
+  bool SafeToClosurize() const;
+
   static RawCode* CurrentCodeOf(const RawFunction* function) {
     return function->ptr()->code_;
   }
@@ -2242,6 +2133,10 @@
 
   static intptr_t code_offset() { return OFFSET_OF(RawFunction, code_); }
 
+  static intptr_t result_type_offset() {
+    return OFFSET_OF(RawFunction, result_type_);
+  }
+
   static intptr_t entry_point_offset() {
     return OFFSET_OF(RawFunction, entry_point_);
   }
@@ -2668,6 +2563,14 @@
            RawFunction::kSignatureFunction;
   }
 
+  // Returns true if this function represents an ffi trampoline.
+  bool IsFfiTrampoline() const { return kind() == RawFunction::kFfiTrampoline; }
+  static bool IsFfiTrampoline(RawFunction* function) {
+    NoSafepointScope no_safepoint;
+    return KindBits::decode(function->ptr()->kind_tag_) ==
+           RawFunction::kFfiTrampoline;
+  }
+
   bool IsAsyncFunction() const { return modifier() == RawFunction::kAsync; }
 
   bool IsAsyncClosure() const {
@@ -2702,6 +2605,9 @@
     return modifier() != RawFunction::kNoModifier;
   }
 
+  DART_WARN_UNUSED_RESULT
+  RawError* VerifyEntryPoint() const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawFunction));
   }
@@ -3064,6 +2970,27 @@
   friend class HeapProfiler;
 };
 
+enum class EntryPointPragma { kAlways, kNever, kGetterOnly, kSetterOnly };
+
+class FfiTrampolineData : public Object {
+ public:
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawFfiTrampolineData));
+  }
+
+ private:
+  // Signature type of this closure function.
+  RawType* signature_type() const { return raw_ptr()->signature_type_; }
+  void set_signature_type(const Type& value) const;
+
+  static RawFfiTrampolineData* New();
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData, Object);
+  friend class Class;
+  friend class Function;
+  friend class HeapProfiler;
+};
+
 class Field : public Object {
  public:
   RawField* Original() const;
@@ -3162,6 +3089,9 @@
   // Used by class finalizer, otherwise initialized in constructor.
   void SetFieldType(const AbstractType& value) const;
 
+  DART_WARN_UNUSED_RESULT
+  RawError* VerifyEntryPoint(EntryPointPragma kind) const;
+
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawField));
   }
@@ -3329,11 +3259,9 @@
 
   DART_WARN_UNUSED_RESULT RawError* EvaluateInitializer() const;
 
-  RawFunction* PrecompiledInitializer() const {
-    return raw_ptr()->initializer_.precompiled_;
-  }
-  void SetPrecompiledInitializer(const Function& initializer) const;
-  bool HasPrecompiledInitializer() const;
+  RawFunction* Initializer() const { return raw_ptr()->initializer_; }
+  void SetInitializer(const Function& initializer) const;
+  bool HasInitializer() const;
 
   // For static fields only. Constructs a closure that gets/sets the
   // field value.
@@ -3623,10 +3551,6 @@
   void SetLoadError(const Instance& error) const;
   RawInstance* TransitiveLoadError() const;
 
-  void AddPatchClass(const Class& cls) const;
-  RawClass* GetPatchClass(const String& name) const;
-  void RemovePatchClass(const Class& cls) const;
-
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawLibrary));
   }
@@ -3636,13 +3560,16 @@
   RawObject* Invoke(const String& selector,
                     const Array& arguments,
                     const Array& argument_names,
-                    bool respect_reflectable = true) const;
+                    bool respect_reflectable = true,
+                    bool check_is_entrypoint = false) const;
   RawObject* InvokeGetter(const String& selector,
                           bool throw_nsm_if_absent,
-                          bool respect_reflectable = true) const;
+                          bool respect_reflectable = true,
+                          bool check_is_entrypoint = false) const;
   RawObject* InvokeSetter(const String& selector,
                           const Instance& argument,
-                          bool respect_reflectable = true) const;
+                          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
@@ -3663,12 +3590,9 @@
   // more regular.
   void AddClass(const Class& cls) const;
   void AddObject(const Object& obj, const String& name) const;
-  void ReplaceObject(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* LookupLocalObjectAllowPrivate(const String& name) const;
-  RawObject* LookupLocalObject(const String& name) const;
   RawObject* LookupLocalOrReExportObject(const String& name) const;
   RawObject* LookupImportedObject(const String& name) const;
   RawClass* LookupClass(const String& name) const;
@@ -3742,7 +3666,6 @@
   intptr_t num_imports() const { return raw_ptr()->num_imports_; }
   RawNamespace* ImportAt(intptr_t index) const;
   RawLibrary* ImportLibraryAt(intptr_t index) const;
-  bool ImportsCorelib() const;
 
   void DropDependenciesAndCaches() const;
 
@@ -3788,8 +3711,6 @@
     StoreNonPointer(&raw_ptr()->is_dart_scheme_, value);
   }
 
-  bool IsCoreLibrary() const { return raw() == CoreLibrary(); }
-
   // Includes 'dart:async', 'dart:typed_data', etc.
   bool IsAnyCoreLibrary() const;
 
@@ -3820,6 +3741,7 @@
   static RawLibrary* CoreLibrary();
   static RawLibrary* CollectionLibrary();
   static RawLibrary* DeveloperLibrary();
+  static RawLibrary* FfiLibrary();
   static RawLibrary* InternalLibrary();
   static RawLibrary* IsolateLibrary();
   static RawLibrary* MathLibrary();
@@ -3871,6 +3793,9 @@
   // for a top level getter 'name' that returns a closure.
   RawObject* GetFunctionClosure(const String& name) const;
 
+  // Ensures that all top-level functions and variables (fields) are loaded.
+  void EnsureTopLevelClassIsFinalized() const;
+
  private:
   static const int kInitialImportsCapacity = 4;
   static const int kImportsCapacityIncrement = 8;
@@ -3909,6 +3834,8 @@
   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;
 
   void AllocatePrivateKey() const;
 
@@ -4005,6 +3932,7 @@
   void set_constants_table(const ExternalTypedData& value) const;
 
   RawArray* scripts() const { return raw_ptr()->scripts_; }
+  void set_scripts(const Array& scripts) const;
 
   RawArray* constants() const { return raw_ptr()->constants_; }
   void set_constants(const Array& constants) const;
@@ -4058,26 +3986,15 @@
 // with it which is stored in-inline after all the entries.
 class ObjectPool : public Object {
  public:
-  enum EntryType {
-    kTaggedObject,
-    kImmediate,
-    kNativeFunction,
-    kNativeFunctionWrapper,
-    kNativeEntryData,
-  };
-
-  enum Patchability {
-    kPatchable,
-    kNotPatchable,
-  };
-
-  class TypeBits : public BitField<uint8_t, EntryType, 0, 7> {};
-  class PatchableBit
-      : public BitField<uint8_t, Patchability, TypeBits::kNextBit, 1> {};
+  using EntryType = compiler::ObjectPoolBuilderEntry::EntryType;
+  using Patchability = compiler::ObjectPoolBuilderEntry::Patchability;
+  using TypeBits = compiler::ObjectPoolBuilderEntry::TypeBits;
+  using PatchableBit = compiler::ObjectPoolBuilderEntry::PatchableBit;
 
   struct Entry {
     Entry() : raw_value_(), type_() {}
-    explicit Entry(const Object* obj) : obj_(obj), type_(kTaggedObject) {}
+    explicit Entry(const Object* obj)
+        : obj_(obj), type_(EntryType::kTaggedObject) {}
     Entry(uword value, EntryType info) : raw_value_(value), type_(info) {}
     union {
       const Object* obj_;
@@ -4115,23 +4032,23 @@
   }
 
   RawObject* ObjectAt(intptr_t index) const {
-    ASSERT((TypeAt(index) == kTaggedObject) ||
-           (TypeAt(index) == kNativeEntryData));
+    ASSERT((TypeAt(index) == EntryType::kTaggedObject) ||
+           (TypeAt(index) == EntryType::kNativeEntryData));
     return EntryAddr(index)->raw_obj_;
   }
   void SetObjectAt(intptr_t index, const Object& obj) const {
-    ASSERT((TypeAt(index) == kTaggedObject) ||
-           (TypeAt(index) == kNativeEntryData) ||
-           (TypeAt(index) == kImmediate && obj.IsSmi()));
+    ASSERT((TypeAt(index) == EntryType::kTaggedObject) ||
+           (TypeAt(index) == EntryType::kNativeEntryData) ||
+           (TypeAt(index) == EntryType::kImmediate && obj.IsSmi()));
     StorePointer(&EntryAddr(index)->raw_obj_, obj.raw());
   }
 
   uword RawValueAt(intptr_t index) const {
-    ASSERT(TypeAt(index) != kTaggedObject);
+    ASSERT(TypeAt(index) != EntryType::kTaggedObject);
     return EntryAddr(index)->raw_value_;
   }
   void SetRawValueAt(intptr_t index, uword raw_value) const {
-    ASSERT(TypeAt(index) != kTaggedObject);
+    ASSERT(TypeAt(index) != EntryType::kTaggedObject);
     StoreNonPointer(&EntryAddr(index)->raw_value_, raw_value);
   }
 
@@ -4156,8 +4073,12 @@
                                  (len * kBytesPerElement));
   }
 
+  static RawObjectPool* NewFromBuilder(
+      const compiler::ObjectPoolBuilder& builder);
   static RawObjectPool* New(intptr_t len);
 
+  void CopyInto(compiler::ObjectPoolBuilder* builder) const;
+
   // Returns the pool index from the offset relative to a tagged RawObjectPool*,
   // adjusting for the tag-bit.
   static intptr_t IndexFromOffset(intptr_t offset) {
@@ -4737,12 +4658,7 @@
     return OFFSET_OF(RawCode, instructions_);
   }
 
-  enum class EntryKind {
-    kNormal,
-    kUnchecked,
-    kMonomorphic,
-    kMonomorphicUnchecked,
-  };
+  using EntryKind = CodeEntryKind;
 
   static intptr_t entry_point_offset(EntryKind kind = EntryKind::kNormal) {
     switch (kind) {
@@ -4761,9 +4677,9 @@
 
   static intptr_t function_entry_point_offset(EntryKind kind) {
     switch (kind) {
-      case Code::EntryKind::kNormal:
+      case EntryKind::kNormal:
         return Function::entry_point_offset();
-      case Code::EntryKind::kUnchecked:
+      case EntryKind::kUnchecked:
         return Function::unchecked_entry_point_offset();
       default:
         ASSERT(false && "Invalid entry kind.");
@@ -5025,16 +4941,9 @@
   }
 
   RawObject* owner() const { return raw_ptr()->owner_; }
-
-  void set_owner(const Function& function) const {
-    ASSERT(function.IsOld());
-    StorePointer(&raw_ptr()->owner_,
-                 reinterpret_cast<RawObject*>(function.raw()));
-  }
-
-  void set_owner(const Class& cls) {
-    ASSERT(cls.IsOld());
-    StorePointer(&raw_ptr()->owner_, reinterpret_cast<RawObject*>(cls.raw()));
+  void set_owner(const Object& owner) const {
+    ASSERT(owner.IsFunction() || owner.IsClass() || owner.IsAbstractType());
+    StorePointer(&raw_ptr()->owner_, owner.raw());
   }
 
   // We would have a VisitPointers function here to traverse all the
@@ -5063,13 +4972,13 @@
   // `Object::set_object_pool()`.
   static RawCode* FinalizeCode(const Function& function,
                                FlowGraphCompiler* compiler,
-                               Assembler* assembler,
+                               compiler::Assembler* assembler,
                                PoolAttachment pool_attachment,
                                bool optimized = false,
                                CodeStatistics* stats = nullptr);
   static RawCode* FinalizeCode(const char* name,
                                FlowGraphCompiler* compiler,
-                               Assembler* assembler,
+                               compiler::Assembler* assembler,
                                PoolAttachment pool_attachment,
                                bool optimized,
                                CodeStatistics* stats = nullptr);
@@ -5099,8 +5008,9 @@
 #endif
   }
 
-  bool IsAllocationStubCode() const;
   bool IsStubCode() const;
+  bool IsAllocationStubCode() const;
+  bool IsTypeTestStubCode() const;
   bool IsFunctionCode() const;
 
   void DisableDartCode() const;
@@ -5215,11 +5125,10 @@
 
 class Bytecode : public Object {
  public:
-  RawExternalTypedData* instructions() const {
-    return raw_ptr()->instructions_;
-  }
-  uword PayloadStart() const;
-  intptr_t Size() const;
+  uword instructions() const { return raw_ptr()->instructions_; }
+
+  uword PayloadStart() const { return instructions(); }
+  intptr_t Size() const { return raw_ptr()->instructions_size_; }
 
   RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
 
@@ -5260,7 +5169,9 @@
     return RoundedAllocationSize(sizeof(RawBytecode));
   }
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static RawBytecode* New(const ExternalTypedData& instructions,
+  static RawBytecode* New(uword instructions,
+                          intptr_t instructions_size,
+                          intptr_t instructions_offset,
                           const ObjectPool& object_pool);
 #endif
 
@@ -5268,6 +5179,13 @@
 
   TokenPosition GetTokenIndexOfPC(uword pc) const;
 
+  intptr_t instructions_binary_offset() const {
+    return raw_ptr()->instructions_binary_offset_;
+  }
+  void set_instructions_binary_offset(intptr_t value) const {
+    StoreNonPointer(&raw_ptr()->instructions_binary_offset_, value);
+  }
+
   intptr_t source_positions_binary_offset() const {
     return raw_ptr()->source_positions_binary_offset_;
   }
@@ -5298,15 +5216,22 @@
   static RawBytecode* FindCode(uword pc);
 
  private:
+  void set_instructions(uword instructions) const {
+    // The interpreter requires the instructions to be aligned.
+    ASSERT(Utils::IsAligned(instructions, sizeof(uint32_t)));
+    StoreNonPointer(&raw_ptr()->instructions_, instructions);
+  }
+  void set_instructions_size(intptr_t size) const {
+    StoreNonPointer(&raw_ptr()->instructions_size_, size);
+  }
   void set_object_pool(const ObjectPool& object_pool) const {
     StorePointer(&raw_ptr()->object_pool_, object_pool.raw());
   }
 
+  friend class BytecodeDeserializationCluster;
   friend class RawObject;  // For RawObject::SizeFromClass().
   friend class RawBytecode;
 
-  void set_instructions(const ExternalTypedData& instructions) const;
-
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Bytecode, Object);
   friend class Class;
   friend class SnapshotWriter;
@@ -5811,12 +5736,15 @@
   RawObject* Invoke(const String& selector,
                     const Array& arguments,
                     const Array& argument_names,
-                    bool respect_reflectable = true) const;
+                    bool respect_reflectable = true,
+                    bool check_is_entrypoint = false) const;
   RawObject* InvokeGetter(const String& selector,
-                          bool respect_reflectable = true) const;
+                          bool respect_reflectable = true,
+                          bool check_is_entrypoint = false) const;
   RawObject* InvokeSetter(const String& selector,
                           const Instance& argument,
-                          bool respect_reflectable = true) const;
+                          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
@@ -5847,6 +5775,14 @@
   static intptr_t DataOffsetFor(intptr_t cid);
   static intptr_t ElementSizeFor(intptr_t cid);
 
+  // Pointers may be subtyped, but their subtypes may not get extra fields.
+  // The subtype runtime representation has exactly the same object layout,
+  // only the class_id is different. So, it is safe to use subtype instances in
+  // Pointer handles.
+  virtual bool IsPointer() const;
+
+  static intptr_t NextFieldOffset() { return sizeof(RawInstance); }
+
  protected:
 #ifndef PRODUCT
   virtual void PrintSharedInstanceJSON(JSONObject* jsobj, bool ref) const;
@@ -5868,8 +5804,6 @@
   }
   bool IsValidFieldOffset(intptr_t offset) const;
 
-  static intptr_t NextFieldOffset() { return sizeof(RawInstance); }
-
   // 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 {
@@ -5887,6 +5821,7 @@
   friend class ByteBuffer;
   friend class Class;
   friend class Closure;
+  friend class Pointer;
   friend class DeferredObject;
   friend class RegExp;
   friend class SnapshotWriter;
@@ -5965,6 +5900,7 @@
 
   intptr_t Length() const;
   RawAbstractType* TypeAt(intptr_t index) const;
+  RawAbstractType* TypeAtNullSafe(intptr_t index) const;
   static intptr_t type_at_offset(intptr_t index) {
     return OFFSET_OF_RETURNED_VALUE(RawTypeArguments, types) +
            index * kWordSize;
@@ -6325,8 +6261,9 @@
   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_; }
 
-  void SetTypeTestingStub(const Instructions& instr) const;
+  void SetTypeTestingStub(const Code& stub) const;
 
  private:
   // Returns true if this type is a subtype of FutureOr<T> specified by 'other'.
@@ -8292,8 +8229,6 @@
     return RawObject::IsTypedDataClassId(cid);
   }
 
-  static RawTypedData* EmptyUint32Array(Thread* thread);
-
  protected:
   void SetLength(intptr_t value) const {
     StoreSmi(&raw_ptr()->length_, Smi::New(value));
@@ -8520,6 +8455,81 @@
   };
 };
 
+class Pointer : public Instance {
+ public:
+  static RawPointer* New(const AbstractType& type_arg,
+                         uint8_t* c_memory_address,
+                         intptr_t class_id = kFfiPointerCid,
+                         Heap::Space space = Heap::kNew);
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawPointer));
+  }
+
+  static bool IsPointer(const Instance& obj);
+
+  uint8_t* GetCMemoryAddress() const {
+    ASSERT(!IsNull());
+    return raw_ptr()->c_memory_address_;
+  }
+
+  void SetCMemoryAddress(uint8_t* value) const {
+    StoreNonPointer(&raw_ptr()->c_memory_address_, value);
+  }
+
+  static intptr_t type_arguments_offset() {
+    return OFFSET_OF(RawPointer, type_arguments_);
+  }
+
+  static intptr_t address_offset() {
+    return OFFSET_OF(RawPointer, c_memory_address_);
+  }
+
+  static intptr_t NextFieldOffset() { return sizeof(RawPointer); }
+
+  static const intptr_t kNativeTypeArgPos = 0;
+
+  // Fetches the NativeType type argument.
+  RawAbstractType* type_argument() const {
+    TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments());
+    return type_args.TypeAtNullSafe(Pointer::kNativeTypeArgPos);
+  }
+
+ private:
+  HEAP_OBJECT_IMPLEMENTATION(Pointer, Instance);
+
+  friend class Class;
+};
+
+class DynamicLibrary : public Instance {
+ public:
+  static RawDynamicLibrary* New(void* handle, Heap::Space space = Heap::kNew);
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawDynamicLibrary));
+  }
+
+  static bool IsDynamicLibrary(const Instance& obj) {
+    ASSERT(!obj.IsNull());
+    intptr_t cid = obj.raw()->GetClassId();
+    return RawObject::IsFfiDynamicLibraryClassId(cid);
+  }
+
+  void* GetHandle() const {
+    ASSERT(!IsNull());
+    return raw_ptr()->handle_;
+  }
+
+  void SetHandle(void* value) const {
+    StoreNonPointer(&raw_ptr()->handle_, value);
+  }
+
+ private:
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(DynamicLibrary, Instance);
+
+  friend class Class;
+};
+
 // Corresponds to
 // - "new Map()",
 // - non-const map literals, and
@@ -9122,8 +9132,9 @@
   ASSERT(is_static());  // Valid only for static dart fields.
   StorePointer(&raw_ptr()->value_.static_value_, value.raw());
   if (save_initial_value) {
-    ASSERT(!HasPrecompiledInitializer());
-    StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw());
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    StorePointer(&raw_ptr()->saved_initial_value_, value.raw());
+#endif
   }
 }
 
@@ -9397,6 +9408,14 @@
 void DumpTypeTable(Isolate* isolate);
 void DumpTypeArgumentsTable(Isolate* isolate);
 
+EntryPointPragma FindEntryPointPragma(Isolate* I,
+                                      const Array& metadata,
+                                      Field* reusable_field_handle,
+                                      Object* reusable_object_handle);
+
+DART_WARN_UNUSED_RESULT
+RawError* EntryPointClosurizationError(const String& getter_name);
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_OBJECT_H_
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 6edb424..6b7cda3 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -135,7 +135,7 @@
   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->Size()) {
+  if (offset > 0 && offset < parent.obj->HeapSize()) {
     ASSERT(Utils::IsAligned(offset, kWordSize));
     return offset >> kWordSizeLog2;
   } else {
@@ -272,7 +272,7 @@
     if (ShouldSkip(obj)) {
       return kBacktrack;
     }
-    size_ += obj->Size();
+    size_ += obj->HeapSize();
     return kProceed;
   }
 
@@ -475,7 +475,7 @@
           uword source_start = RawObject::ToAddr(source_);
           uword current_ptr_addr = reinterpret_cast<uword>(current_ptr);
           intptr_t offset = current_ptr_addr - source_start;
-          if (offset > 0 && offset < source_->Size()) {
+          if (offset > 0 && offset < source_->HeapSize()) {
             ASSERT(Utils::IsAligned(offset, kWordSize));
             *scratch_ = Smi::New(offset >> kWordSizeLog2);
           } else {
@@ -583,7 +583,7 @@
     if ((roots_ == ObjectGraph::kVM) || obj.IsField() || obj.IsInstance() ||
         obj.IsContext()) {
       // Each object is a header + a zero-terminated list of its neighbors.
-      WriteHeader(raw_obj, raw_obj->Size(), obj.GetClassId(), stream_);
+      WriteHeader(raw_obj, raw_obj->HeapSize(), obj.GetClassId(), stream_);
       raw_obj->VisitPointers(&ptr_writer_);
       stream_->WriteUnsigned(0);
       ++count_;
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index 72cffef..c4f1515 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -23,7 +23,7 @@
       return kBacktrack;
     }
     ++count_;
-    size_ += obj->Size();
+    size_ += obj->HeapSize();
     return kProceed;
   }
 
@@ -52,10 +52,10 @@
   b.SetAt(0, c);
   b.SetAt(1, d);
   a.SetAt(11, d);
-  intptr_t a_size = a.raw()->Size();
-  intptr_t b_size = b.raw()->Size();
-  intptr_t c_size = c.raw()->Size();
-  intptr_t d_size = d.raw()->Size();
+  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();
   {
     // No more allocation; raw pointers ahead.
     SafepointOperationScope safepoint(thread);
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index c519034..ffd3cb9 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -101,7 +101,7 @@
   Object& object = Object::Handle(zone);
   for (intptr_t i = 0; i < Length(); i++) {
     ObjectPool::EntryType entry_type = TypeAt(i);
-    if (entry_type != ObjectPool::kTaggedObject) {
+    if (entry_type != ObjectPool::EntryType::kTaggedObject) {
       continue;
     }
     object = ObjectAt(i);
@@ -725,7 +725,7 @@
         // count.
         ClearCountAt(0);
         WriteSentinelAt(1);
-        const Array& array = Array::Handle(ic_data());
+        const Array& array = Array::Handle(entries());
         array.Truncate(2 * TestEntryLength());
         return;
       }
@@ -733,7 +733,7 @@
     }
     const Array& data_array = Array::Handle(
         zone, CachedEmptyICDataArray(num_args, tracking_exactness));
-    set_ic_data_array(data_array);
+    set_entries(data_array);
     return;
   } else if (rule == kNoRebind || rule == kNSMDispatch) {
     // TODO(30877) we should account for addition/removal of NSM.
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 5299079..1562714 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()->Size());
+      jsobj->AddProperty("size", raw()->HeapSize());
     } else {
       jsobj->AddProperty("size", (intptr_t)0);
     }
@@ -349,6 +349,10 @@
   Object::PrintJSONImpl(stream, ref);
 }
 
+void FfiTrampolineData::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  Object::PrintJSONImpl(stream, ref);
+}
+
 void Field::PrintJSONImpl(JSONStream* stream, bool ref) const {
   JSONObject jsobj(stream);
   Class& cls = Class::Handle(Owner());
@@ -628,27 +632,27 @@
       JSONObject jsentry(stream);
       jsentry.AddProperty("offset", OffsetFromIndex(i));
       switch (TypeAt(i)) {
-        case ObjectPool::kTaggedObject:
+        case ObjectPool::EntryType::kTaggedObject:
           obj = ObjectAt(i);
           jsentry.AddProperty("kind", "Object");
           jsentry.AddProperty("value", obj);
           break;
-        case ObjectPool::kImmediate:
+        case ObjectPool::EntryType::kImmediate:
           imm = RawValueAt(i);
           jsentry.AddProperty("kind", "Immediate");
           jsentry.AddProperty64("value", imm);
           break;
-        case ObjectPool::kNativeEntryData:
+        case ObjectPool::EntryType::kNativeEntryData:
           obj = ObjectAt(i);
           jsentry.AddProperty("kind", "NativeEntryData");
           jsentry.AddProperty("value", obj);
           break;
-        case ObjectPool::kNativeFunction:
+        case ObjectPool::EntryType::kNativeFunction:
           imm = RawValueAt(i);
           jsentry.AddProperty("kind", "NativeFunction");
           jsentry.AddProperty64("value", imm);
           break;
-        case ObjectPool::kNativeFunctionWrapper:
+        case ObjectPool::EntryType::kNativeFunctionWrapper:
           imm = RawValueAt(i);
           jsentry.AddProperty("kind", "NativeFunctionWrapper");
           jsentry.AddProperty64("value", imm);
@@ -758,7 +762,7 @@
   }
   jsobj.AddProperty("_argumentsDescriptor",
                     Object::Handle(arguments_descriptor()));
-  jsobj.AddProperty("_entries", Object::Handle(ic_data()));
+  jsobj.AddProperty("_entries", Object::Handle(entries()));
 }
 
 void ICData::PrintToJSONArray(const JSONArray& jsarray,
@@ -798,7 +802,8 @@
   const char* qualified_name = QualifiedName();
   const char* vm_name = Name();
   AddNameProperties(&jsobj, qualified_name, vm_name);
-  const bool is_stub = IsStubCode() || IsAllocationStubCode();
+  const bool is_stub =
+      IsStubCode() || IsAllocationStubCode() || IsTypeTestStubCode();
   if (is_stub) {
     jsobj.AddProperty("kind", "Stub");
   } else {
@@ -1415,6 +1420,20 @@
   }
 }
 
+void Pointer::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  // TODO(dacoharkes): what is the JSONStream used for?
+  // should it fail because it's not supported?
+  // or should it print something reasonable as default?
+  Instance::PrintJSONImpl(stream, ref);
+}
+
+void DynamicLibrary::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  // TODO(dacoharkes): what is the JSONStream used for?
+  // should it fail because it's not supported?
+  // or should it print something reasonable as default?
+  Instance::PrintJSONImpl(stream, ref);
+}
+
 void Capability::PrintJSONImpl(JSONStream* stream, bool ref) const {
   Instance::PrintJSONImpl(stream, ref);
 }
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index dd182ff..cecbe27 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -220,6 +220,8 @@
   cls = core_lib.LookupClassAllowPrivate(Symbols::Pragma());
   ASSERT(!cls.IsNull());
   set_pragma_class(cls);
+  set_pragma_name(Field::Handle(cls.LookupField(Symbols::name())));
+  set_pragma_options(Field::Handle(cls.LookupField(Symbols::options())));
 
   cls = core_lib.LookupClassAllowPrivate(Symbols::_GrowableList());
   ASSERT(!cls.IsNull());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 77c99ee..a4f0227 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -22,6 +22,7 @@
   M(Collection, collection)                                                    \
   M(Convert, convert)                                                          \
   M(Developer, developer)                                                      \
+  M(Ffi, ffi)                                                                  \
   M(Internal, _internal)                                                       \
   M(Isolate, isolate)                                                          \
   M(Math, math)                                                                \
@@ -59,6 +60,8 @@
   RW(TypeArguments, type_argument_string_string)                               \
   RW(Class, compiletime_error_class)                                           \
   RW(Class, pragma_class)                                                      \
+  RW(Field, pragma_name)                                                       \
+  RW(Field, pragma_options)                                                    \
   RW(Class, future_class)                                                      \
   RW(Class, completer_class)                                                   \
   RW(Class, symbol_class)                                                      \
@@ -87,6 +90,7 @@
   RW(Library, collection_library)                                              \
   RW(Library, convert_library)                                                 \
   RW(Library, developer_library)                                               \
+  RW(Library, ffi_library)                                                     \
   RW(Library, _internal_library)                                               \
   RW(Library, isolate_library)                                                 \
   RW(Library, math_library)                                                    \
@@ -109,7 +113,6 @@
   RW(UnhandledException, preallocated_unhandled_exception)                     \
   RW(StackTrace, preallocated_stack_trace)                                     \
   RW(Function, lookup_port_handler)                                            \
-  RW(TypedData, empty_uint32_array)                                            \
   RW(Function, handle_message_function)                                        \
   RW(Function, growable_list_factory)                                          \
   RW(Function, simple_instance_of_function)                                    \
@@ -125,12 +128,19 @@
   RW(Array, unique_dynamic_targets)                                            \
   RW(GrowableObjectArray, megamorphic_cache_table)                             \
   RW(Code, build_method_extractor_code)                                        \
+  RW(Code, null_error_stub_with_fpu_regs_stub)                                 \
+  RW(Code, null_error_stub_without_fpu_regs_stub)                              \
+  RW(Code, stack_overflow_stub_with_fpu_regs_stub)                             \
+  RW(Code, stack_overflow_stub_without_fpu_regs_stub)                          \
+  RW(Code, write_barrier_wrappers_stub)                                        \
+  RW(Code, array_write_barrier_stub)                                           \
   R_(Code, megamorphic_miss_code)                                              \
   R_(Function, megamorphic_miss_function)                                      \
   RW(Array, code_order_table)                                                  \
   RW(Array, obfuscation_map)                                                   \
-  RW(GrowableObjectArray, type_testing_stubs)                                  \
   RW(GrowableObjectArray, changed_in_last_reload)                              \
+  RW(Class, ffi_pointer_class)                                                 \
+  RW(Class, ffi_native_type_class)                                             \
 // 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
@@ -223,7 +233,7 @@
                           DECLARE_OBJECT_STORE_FIELD)
 #undef DECLARE_OBJECT_STORE_FIELD
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&changed_in_last_reload_);
+    return reinterpret_cast<RawObject**>(&ffi_pointer_class_);
   }
   RawObject** to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index c43828a..cb5d990 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2470,8 +2470,8 @@
 // Test for Code and Instruction object creation.
 ISOLATE_UNIT_TEST_CASE(Code) {
   extern void GenerateIncrement(Assembler * assembler);
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateIncrement(&_assembler_);
   const Function& function = Function::Handle(CreateFunction("Test_Code"));
   Code& code = Code::Handle(Code::FinalizeCode(
@@ -2492,8 +2492,8 @@
       MallocHooks::stack_trace_collection_enabled();
   MallocHooks::set_stack_trace_collection_enabled(false);
   extern void GenerateIncrement(Assembler * assembler);
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateIncrement(&_assembler_);
   const Function& function = Function::Handle(CreateFunction("Test_Code"));
   Code& code = Code::Handle(Code::FinalizeCode(
@@ -2519,8 +2519,8 @@
   extern void GenerateEmbedStringInCode(Assembler * assembler, const char* str);
   const char* kHello = "Hello World!";
   word expected_length = static_cast<word>(strlen(kHello));
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateEmbedStringInCode(&_assembler_, kHello);
   const Function& function =
       Function::Handle(CreateFunction("Test_EmbedStringInCode"));
@@ -2542,8 +2542,8 @@
 ISOLATE_UNIT_TEST_CASE(EmbedSmiInCode) {
   extern void GenerateEmbedSmiInCode(Assembler * assembler, intptr_t value);
   const intptr_t kSmiTestValue = 5;
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
   const Function& function =
       Function::Handle(CreateFunction("Test_EmbedSmiInCode"));
@@ -2560,8 +2560,8 @@
 ISOLATE_UNIT_TEST_CASE(EmbedSmiIn64BitCode) {
   extern void GenerateEmbedSmiInCode(Assembler * assembler, intptr_t value);
   const intptr_t kSmiTestValue = DART_INT64_C(5) << 32;
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
   const Function& function =
       Function::Handle(CreateFunction("Test_EmbedSmiIn64BitCode"));
@@ -2591,8 +2591,8 @@
                                     TokenPosition::kNoSource, true);
 
   extern void GenerateIncrement(Assembler * assembler);
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateIncrement(&_assembler_);
   Code& code = Code::Handle(
       Code::FinalizeCode(Function::Handle(CreateFunction("Test_Code")), nullptr,
@@ -2633,8 +2633,8 @@
   descriptors ^= builder->FinalizePcDescriptors(0);
 
   extern void GenerateIncrement(Assembler * assembler);
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateIncrement(&_assembler_);
   Code& code = Code::Handle(
       Code::FinalizeCode(Function::Handle(CreateFunction("Test_Code")), nullptr,
@@ -2696,8 +2696,8 @@
   descriptors ^= builder->FinalizePcDescriptors(0);
 
   extern void GenerateIncrement(Assembler * assembler);
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler _assembler_(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler _assembler_(&object_pool_builder);
   GenerateIncrement(&_assembler_);
   Code& code = Code::Handle(
       Code::FinalizeCode(Function::Handle(CreateFunction("Test_Code")), nullptr,
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index bb8bc1f..e987b5c 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -13,7 +13,6 @@
 namespace dart {
 
 // Forward declarations.
-class Isolate;
 class Zone;
 
 // Interface to the underlying OS platform.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 54bda8a..997578c 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -8,7 +8,6 @@
 #include "vm/os.h"
 
 #include <android/log.h>   // NOLINT
-#include <endian.h>        // NOLINT
 #include <errno.h>         // NOLINT
 #include <limits.h>        // NOLINT
 #include <malloc.h>        // NOLINT
@@ -249,30 +248,6 @@
       __builtin_extract_return_addr(__builtin_return_address(0)));
 }
 
-uint16_t HostToBigEndian16(uint16_t value) {
-  return htobe16(value);
-}
-
-uint32_t HostToBigEndian32(uint32_t value) {
-  return htobe32(value);
-}
-
-uint64_t HostToBigEndian64(uint64_t value) {
-  return htobe64(value);
-}
-
-uint16_t HostToLittleEndian16(uint16_t value) {
-  return htole16(value);
-}
-
-uint32_t HostToLittleEndian32(uint32_t value) {
-  return htole32(value);
-}
-
-uint64_t HostToLittleEndian64(uint64_t value) {
-  return htole64(value);
-}
-
 void OS::Print(const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc
index 22abcbb..fa5e8ea 100644
--- a/runtime/vm/os_thread.cc
+++ b/runtime/vm/os_thread.cc
@@ -29,7 +29,7 @@
 #if defined(DEBUG)
       join_id_(kInvalidThreadJoinId),
 #endif
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
       trace_id_(OSThread::GetCurrentThreadTraceId()),
 #endif
       name_(NULL),
@@ -75,11 +75,11 @@
   RemoveThreadFromList(this);
   delete log_;
   log_ = NULL;
-  if (FLAG_support_timeline) {
-    if (Timeline::recorder() != NULL) {
-      Timeline::recorder()->FinishBlock(timeline_block_);
-    }
+#if defined(SUPPORT_TIMELINE)
+  if (Timeline::recorder() != NULL) {
+    Timeline::recorder()->FinishBlock(timeline_block_);
   }
+#endif
   timeline_block_ = NULL;
   delete timeline_block_lock_;
   free(name_);
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index 1fcf0da..a82ef6f 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -44,12 +44,11 @@
 
  private:
   explicit BaseThread(bool is_os_thread) : is_os_thread_(is_os_thread) {}
-  ~BaseThread() {}
+  virtual ~BaseThread() {}
 
   bool is_os_thread_;
 
   friend class ThreadState;
-  friend class Thread;
   friend class OSThread;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(BaseThread);
@@ -69,7 +68,7 @@
     return id_;
   }
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
   ThreadId trace_id() const {
     ASSERT(trace_id_ != OSThread::kInvalidThreadId);
     return trace_id_;
@@ -230,7 +229,7 @@
   void set_thread(ThreadState* value) { thread_ = value; }
 
   static void Cleanup();
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
   static ThreadId GetCurrentThreadTraceId();
 #endif  // PRODUCT
   static OSThread* GetOSThreadFromThread(ThreadState* thread);
@@ -246,7 +245,7 @@
   // only called once per OSThread.
   ThreadJoinId join_id_;
 #endif
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
   const ThreadId trace_id_;  // Used to interface with tracing tools.
 #endif
   char* name_;  // A name for this thread.
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index 5eab0b8..e03d9b7 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -187,7 +187,7 @@
   return gettid();
 }
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return GetCurrentThreadId();
 }
diff --git a/runtime/vm/os_thread_fuchsia.cc b/runtime/vm/os_thread_fuchsia.cc
index cae2552..b465e07 100644
--- a/runtime/vm/os_thread_fuchsia.cc
+++ b/runtime/vm/os_thread_fuchsia.cc
@@ -175,7 +175,7 @@
   return info.koid;
 }
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return pthread_self();
 }
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index 4b8da4d..8c9fa0f 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -189,7 +189,7 @@
   return pthread_self();
 }
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return syscall(__NR_gettid);
 }
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index 39f0047..0fff6fd 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -165,7 +165,7 @@
   return pthread_self();
 }
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return ThreadIdFromIntPtr(pthread_mach_thread_np(pthread_self()));
 }
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index 56b5e2f..b1aed90 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -114,7 +114,7 @@
   return ::GetCurrentThreadId();
 }
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
 ThreadId OSThread::GetCurrentThreadTraceId() {
   return ::GetCurrentThreadId();
 }
diff --git a/runtime/vm/pointer_tagging.h b/runtime/vm/pointer_tagging.h
new file mode 100644
index 0000000..411b6b0
--- /dev/null
+++ b/runtime/vm/pointer_tagging.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_VM_POINTER_TAGGING_H_
+#define RUNTIME_VM_POINTER_TAGGING_H_
+
+// This header defines constants associated with pointer tagging:
+//
+//    * which bits determine whether or not this is a Smi value or a heap
+//      pointer;
+//    * which bits determine whether this is a pointer into a new or an old
+//      space.
+
+namespace dart {
+
+// 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.
+//
+// Note: these bits depend on the word size.
+template <intptr_t word_size, intptr_t word_size_log2>
+struct ObjectAlignment {
+  // Alignment offsets are used to determine object age.
+  static constexpr intptr_t kNewObjectAlignmentOffset = word_size;
+  static constexpr intptr_t kOldObjectAlignmentOffset = 0;
+  static constexpr intptr_t kNewObjectBitPosition = word_size_log2;
+
+  // Object sizes are aligned to kObjectAlignment.
+  static constexpr intptr_t kObjectAlignment = 2 * word_size;
+  static constexpr intptr_t kObjectAlignmentLog2 = word_size_log2 + 1;
+  static constexpr intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
+};
+
+using HostObjectAlignment = ObjectAlignment<kWordSize, kWordSizeLog2>;
+
+static constexpr intptr_t kNewObjectAlignmentOffset =
+    HostObjectAlignment::kNewObjectAlignmentOffset;
+static constexpr intptr_t kOldObjectAlignmentOffset =
+    HostObjectAlignment::kOldObjectAlignmentOffset;
+static constexpr intptr_t kNewObjectBitPosition =
+    HostObjectAlignment::kNewObjectBitPosition;
+static constexpr intptr_t kObjectAlignment =
+    HostObjectAlignment::kObjectAlignment;
+static constexpr intptr_t kObjectAlignmentLog2 =
+    HostObjectAlignment::kObjectAlignmentLog2;
+static constexpr intptr_t kObjectAlignmentMask =
+    HostObjectAlignment::kObjectAlignmentMask;
+
+// On all targets heap pointers are tagged by set least significant bit.
+//
+// To recover address of the actual heap object kHeapObjectTag needs to be
+// subtracted from the tagged pointer value.
+//
+// Smi-s (small integers) have least significant bit cleared.
+//
+// To recover the integer value tagged pointer value needs to be shifted
+// right by kSmiTagShift.
+enum {
+  kSmiTag = 0,
+  kHeapObjectTag = 1,
+  kSmiTagSize = 1,
+  kSmiTagMask = 1,
+  kSmiTagShift = 1,
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_POINTER_TAGGING_H_
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 482dac0..5ff50f6 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -65,7 +65,6 @@
 
 void Profiler::Init() {
   // Place some sane restrictions on user controlled flags.
-  SetSamplePeriod(FLAG_profile_period);
   SetSampleDepth(FLAG_max_profile_depth);
   Sample::Init();
   if (!FLAG_profiler) {
@@ -77,7 +76,7 @@
   // Zero counters.
   memset(&counters_, 0, sizeof(counters_));
   ThreadInterrupter::Init();
-  ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
+  SetSamplePeriod(FLAG_profile_period);
   ThreadInterrupter::Startup();
   initialized_ = true;
 }
@@ -123,6 +122,11 @@
   } else {
     FLAG_profile_period = period;
   }
+  ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
+}
+
+void Profiler::UpdateSamplePeriod() {
+  SetSamplePeriod(FLAG_profile_period);
 }
 
 intptr_t Sample::pcs_length_ = 0;
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 7ac6741..cb891a5 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -60,6 +60,9 @@
 
   static void SetSampleDepth(intptr_t depth);
   static void SetSamplePeriod(intptr_t period);
+  // Restarts sampling with a given profile period. This is called after the
+  // profile period is changed via the service protocol.
+  static void UpdateSamplePeriod();
 
   static SampleBuffer* sample_buffer() { return sample_buffer_; }
   static AllocationSampleBuffer* allocation_sample_buffer() {
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index ec0513f..8260a86 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -81,8 +81,8 @@
     fields_ = cls.fields();
     for (intptr_t j = 0; j < fields_.Length(); j++) {
       field_ ^= fields_.At(j);
-      if (field_.is_static() && field_.HasPrecompiledInitializer()) {
-        function_ ^= field_.PrecompiledInitializer();
+      if (field_.is_static() && field_.HasInitializer()) {
+        function_ ^= field_.Initializer();
         visitor_->Visit(function_);
       }
     }
@@ -115,6 +115,7 @@
   }
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 void ProgramVisitor::BindStaticCalls() {
 #if !defined(TARGET_ARCH_DBC)
   if (FLAG_precompiled_mode) {
@@ -308,6 +309,7 @@
     explicit DedupPcDescriptorsVisitor(Zone* zone)
         : zone_(zone),
           canonical_pc_descriptors_(),
+          bytecode_(Bytecode::Handle(zone)),
           code_(Code::Handle(zone)),
           pc_descriptor_(PcDescriptors::Handle(zone)) {}
 
@@ -317,6 +319,14 @@
     }
 
     void Visit(const Function& function) {
+      bytecode_ = function.bytecode();
+      if (!bytecode_.IsNull()) {
+        pc_descriptor_ = bytecode_.pc_descriptors();
+        if (!pc_descriptor_.IsNull()) {
+          pc_descriptor_ = DedupPcDescriptor(pc_descriptor_);
+          bytecode_.set_pc_descriptors(pc_descriptor_);
+        }
+      }
       if (!function.HasCode()) {
         return;
       }
@@ -341,6 +351,7 @@
    private:
     Zone* zone_;
     PcDescriptorsSet canonical_pc_descriptors_;
+    Bytecode& bytecode_;
     Code& code_;
     PcDescriptors& pc_descriptor_;
   };
@@ -380,7 +391,6 @@
 
 typedef DirectChainedHashMap<TypedDataKeyValueTrait> TypedDataSet;
 
-#if !defined(DART_PRECOMPILED_RUNTIME)
 void ProgramVisitor::DedupDeoptEntries() {
   class DedupDeoptEntriesVisitor : public FunctionVisitor {
    public:
@@ -437,7 +447,6 @@
   DedupDeoptEntriesVisitor visitor(Thread::Current()->zone());
   ProgramVisitor::VisitFunctions(&visitor);
 }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 #if defined(DART_PRECOMPILER)
 void ProgramVisitor::DedupCatchEntryMovesMaps() {
@@ -876,8 +885,10 @@
   ProgramVisitor::VisitFunctions(&visitor);
 #endif  // defined(DART_PRECOMPILER)
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 void ProgramVisitor::Dedup() {
+#if !defined(DART_PRECOMPILED_RUNTIME)
   Thread* thread = Thread::Current();
   StackZone stack_zone(thread);
   HANDLESCOPE(thread);
@@ -901,6 +912,7 @@
     DedupInstructions();
   }
 #endif
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 }
 
 }  // namespace dart
diff --git a/runtime/vm/program_visitor.h b/runtime/vm/program_visitor.h
index 5583cc3..3ba3539 100644
--- a/runtime/vm/program_visitor.h
+++ b/runtime/vm/program_visitor.h
@@ -30,11 +30,12 @@
   static void Dedup();
 
  private:
+#if !defined(DART_PRECOMPILED_RUNTIME)
   static void BindStaticCalls();
   static void ShareMegamorphicBuckets();
   static void DedupStackMaps();
   static void DedupPcDescriptors();
-  NOT_IN_PRECOMPILED(static void DedupDeoptEntries());
+  static void DedupDeoptEntries();
 #if defined(DART_PRECOMPILER)
   static void DedupCatchEntryMovesMaps();
 #endif
@@ -42,6 +43,7 @@
   static void DedupLists();
   static void DedupInstructions();
   static void DedupInstructionsWithSameMetadata();
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 };
 
 }  // namespace dart
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index e0d7945..7735f4d 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -42,7 +42,7 @@
       FATAL1("New object has kOldAndNotMarkedBit: %x\n", tags);
     }
     if (OldAndNotRememberedBit::decode(tags)) {
-      FATAL1("Mew object has kOldAndNotRememberedBit: %x\n", tags);
+      FATAL1("New object has kOldAndNotRememberedBit: %x\n", tags);
     }
   } else {
     if (NewBit::decode(tags)) {
@@ -61,16 +61,20 @@
     // Null class not yet initialized; skip.
     return;
   }
-  intptr_t size = SizeTag::decode(tags);
-  if (size != 0 && size != SizeFromClass()) {
-    FATAL1("Inconsistent class size encountered %" Pd "\n", size);
+  intptr_t size_from_tags = SizeTag::decode(tags);
+  intptr_t size_from_class = HeapSizeFromClass();
+  if ((size_from_tags != 0) && (size_from_tags != size_from_class)) {
+    FATAL3(
+        "Inconsistent size encountered "
+        "cid: %" Pd ", size_from_tags: %" Pd ", size_from_class: %" Pd "\n",
+        class_id, size_from_tags, size_from_class);
   }
 }
 
 // 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::SizeFromClass() const {
+intptr_t RawObject::HeapSizeFromClass() const {
   // Only reasonable to be called on heap objects.
   ASSERT(IsHeapObject());
 
@@ -143,6 +147,9 @@
         break;
       }
 #undef SIZE_FROM_CLASS
+    case kFfiPointerCid:
+      instance_size = Pointer::InstanceSize();
+      break;
     case kTypeArgumentsCid: {
       const RawTypeArguments* raw_array =
           reinterpret_cast<const RawTypeArguments*>(this);
@@ -187,13 +194,13 @@
     case kFreeListElement: {
       uword addr = RawObject::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
-      instance_size = element->Size();
+      instance_size = element->HeapSize();
       break;
     }
     case kForwardingCorpse: {
       uword addr = RawObject::ToAddr(this);
       ForwardingCorpse* element = reinterpret_cast<ForwardingCorpse*>(addr);
-      instance_size = element->Size();
+      instance_size = element->HeapSize();
       break;
     }
     default: {
@@ -278,20 +285,30 @@
       break;
     }
 #undef RAW_VISITPOINTERS
+    case kFfiPointerCid: {
+      RawPointer* raw_obj = reinterpret_cast<RawPointer*>(this);
+      size = RawPointer::VisitPointerPointers(raw_obj, visitor);
+      break;
+    }
+    case kFfiDynamicLibraryCid: {
+      RawDynamicLibrary* raw_obj = reinterpret_cast<RawDynamicLibrary*>(this);
+      size = RawDynamicLibrary::VisitDynamicLibraryPointers(raw_obj, visitor);
+      break;
+    }
     case kFreeListElement: {
       uword addr = RawObject::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
-      size = element->Size();
+      size = element->HeapSize();
       break;
     }
     case kForwardingCorpse: {
       uword addr = RawObject::ToAddr(this);
       ForwardingCorpse* forwarder = reinterpret_cast<ForwardingCorpse*>(addr);
-      size = forwarder->Size();
+      size = forwarder->HeapSize();
       break;
     }
     case kNullCid:
-      size = Size();
+      size = HeapSize();
       break;
     default:
       OS::PrintErr("Class Id: %" Pd "\n", class_id);
@@ -301,13 +318,13 @@
 
 #if defined(DEBUG)
   ASSERT(size != 0);
-  const intptr_t expected_size = Size();
+  const intptr_t expected_size = HeapSize();
 
-  // In general we expect that visitors return exactly the same size that Size
-  // would compute. However in case of Arrays we might have a discrepancy when
-  // concurrently visiting an array that is being shrunk with
+  // In general we expect that visitors return exactly the same size that
+  // HeapSize would compute. However in case of Arrays we might have a
+  // discrepancy when concurrently visiting an array that is being shrunk with
   // Array::MakeFixedLength: the visitor might have visited the full array while
-  // here we are observing a smaller Size().
+  // here we are observing a smaller HeapSize().
   ASSERT(size == expected_size ||
          (class_id == kArrayCid && size > expected_size));
   return size;  // Prefer larger size.
@@ -391,6 +408,7 @@
 REGULAR_VISITOR(ClosureData)
 REGULAR_VISITOR(SignatureData)
 REGULAR_VISITOR(RedirectionData)
+REGULAR_VISITOR(FfiTrampolineData)
 REGULAR_VISITOR(Field)
 REGULAR_VISITOR(Script)
 REGULAR_VISITOR(Library)
@@ -435,6 +453,8 @@
 NULL_VISITOR(Bool)
 NULL_VISITOR(Capability)
 NULL_VISITOR(SendPort)
+REGULAR_VISITOR(Pointer)
+NULL_VISITOR(DynamicLibrary)
 VARIABLE_NULL_VISITOR(Instructions, Instructions::Size(raw_obj))
 VARIABLE_NULL_VISITOR(PcDescriptors, raw_obj->ptr()->length_)
 VARIABLE_NULL_VISITOR(CodeSourceMap, raw_obj->ptr()->length_)
@@ -556,9 +576,8 @@
 bool RawBytecode::ContainsPC(RawObject* raw_obj, uword pc) {
   if (raw_obj->IsBytecode()) {
     RawBytecode* raw_bytecode = static_cast<RawBytecode*>(raw_obj);
-    RawExternalTypedData* bytes = raw_bytecode->ptr()->instructions_;
-    uword start = reinterpret_cast<uword>(bytes->ptr()->data_);
-    uword size = Smi::Value(bytes->ptr()->length_);
+    uword start = raw_bytecode->ptr()->instructions_;
+    uword size = raw_bytecode->ptr()->instructions_size_;
     return (pc - start) < size;
   }
   return false;
@@ -572,8 +591,8 @@
   for (intptr_t i = 0; i < length; ++i) {
     ObjectPool::EntryType entry_type =
         ObjectPool::TypeBits::decode(entry_bits[i]);
-    if ((entry_type == ObjectPool::kTaggedObject) ||
-        (entry_type == ObjectPool::kNativeEntryData)) {
+    if ((entry_type == ObjectPool::EntryType::kTaggedObject) ||
+        (entry_type == ObjectPool::EntryType::kNativeEntryData)) {
       visitor->VisitPointer(&entries[i].raw_obj_);
     }
   }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index dcde53e..3fecf1c 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -5,12 +5,18 @@
 #ifndef RUNTIME_VM_RAW_OBJECT_H_
 #define RUNTIME_VM_RAW_OBJECT_H_
 
+#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
+#error "Should not include runtime"
+#endif
+
 #include "platform/assert.h"
 #include "platform/atomic.h"
+#include "vm/class_id.h"
 #include "vm/compiler/method_recognizer.h"
 #include "vm/exceptions.h"
 #include "vm/globals.h"
 #include "vm/object_graph.h"
+#include "vm/pointer_tagging.h"
 #include "vm/snapshot.h"
 #include "vm/token.h"
 #include "vm/token_position.h"
@@ -20,127 +26,6 @@
 // For now there are no compressed pointers.
 typedef RawObject* RawCompressed;
 
-// Macrobatics to define the Object hierarchy of VM implementation classes.
-#define CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                           \
-  V(Class)                                                                     \
-  V(PatchClass)                                                                \
-  V(Function)                                                                  \
-  V(ClosureData)                                                               \
-  V(SignatureData)                                                             \
-  V(RedirectionData)                                                           \
-  V(Field)                                                                     \
-  V(Script)                                                                    \
-  V(Library)                                                                   \
-  V(Namespace)                                                                 \
-  V(KernelProgramInfo)                                                         \
-  V(Code)                                                                      \
-  V(Bytecode)                                                                  \
-  V(Instructions)                                                              \
-  V(ObjectPool)                                                                \
-  V(PcDescriptors)                                                             \
-  V(CodeSourceMap)                                                             \
-  V(StackMap)                                                                  \
-  V(LocalVarDescriptors)                                                       \
-  V(ExceptionHandlers)                                                         \
-  V(Context)                                                                   \
-  V(ContextScope)                                                              \
-  V(SingleTargetCache)                                                         \
-  V(UnlinkedCall)                                                              \
-  V(ICData)                                                                    \
-  V(MegamorphicCache)                                                          \
-  V(SubtypeTestCache)                                                          \
-  V(Error)                                                                     \
-  V(ApiError)                                                                  \
-  V(LanguageError)                                                             \
-  V(UnhandledException)                                                        \
-  V(UnwindError)                                                               \
-  V(Instance)                                                                  \
-  V(LibraryPrefix)                                                             \
-  V(TypeArguments)                                                             \
-  V(AbstractType)                                                              \
-  V(Type)                                                                      \
-  V(TypeRef)                                                                   \
-  V(TypeParameter)                                                             \
-  V(Closure)                                                                   \
-  V(Number)                                                                    \
-  V(Integer)                                                                   \
-  V(Smi)                                                                       \
-  V(Mint)                                                                      \
-  V(Double)                                                                    \
-  V(Bool)                                                                      \
-  V(GrowableObjectArray)                                                       \
-  V(Float32x4)                                                                 \
-  V(Int32x4)                                                                   \
-  V(Float64x2)                                                                 \
-  V(TypedData)                                                                 \
-  V(ExternalTypedData)                                                         \
-  V(Capability)                                                                \
-  V(ReceivePort)                                                               \
-  V(SendPort)                                                                  \
-  V(StackTrace)                                                                \
-  V(RegExp)                                                                    \
-  V(WeakProperty)                                                              \
-  V(MirrorReference)                                                           \
-  V(LinkedHashMap)                                                             \
-  V(UserTag)
-
-#define CLASS_LIST_ARRAYS(V)                                                   \
-  V(Array)                                                                     \
-  V(ImmutableArray)
-
-#define CLASS_LIST_STRINGS(V)                                                  \
-  V(String)                                                                    \
-  V(OneByteString)                                                             \
-  V(TwoByteString)                                                             \
-  V(ExternalOneByteString)                                                     \
-  V(ExternalTwoByteString)
-
-#define CLASS_LIST_TYPED_DATA(V)                                               \
-  V(Int8Array)                                                                 \
-  V(Uint8Array)                                                                \
-  V(Uint8ClampedArray)                                                         \
-  V(Int16Array)                                                                \
-  V(Uint16Array)                                                               \
-  V(Int32Array)                                                                \
-  V(Uint32Array)                                                               \
-  V(Int64Array)                                                                \
-  V(Uint64Array)                                                               \
-  V(Float32Array)                                                              \
-  V(Float64Array)                                                              \
-  V(Float32x4Array)                                                            \
-  V(Int32x4Array)                                                              \
-  V(Float64x2Array)
-
-#define DART_CLASS_LIST_TYPED_DATA(V)                                          \
-  V(Int8)                                                                      \
-  V(Uint8)                                                                     \
-  V(Uint8Clamped)                                                              \
-  V(Int16)                                                                     \
-  V(Uint16)                                                                    \
-  V(Int32)                                                                     \
-  V(Uint32)                                                                    \
-  V(Int64)                                                                     \
-  V(Uint64)                                                                    \
-  V(Float32)                                                                   \
-  V(Float64)                                                                   \
-  V(Float32x4)                                                                 \
-  V(Int32x4)                                                                   \
-  V(Float64x2)
-
-#define CLASS_LIST_FOR_HANDLES(V)                                              \
-  CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                                 \
-  V(Array)                                                                     \
-  V(String)
-
-#define CLASS_LIST_NO_OBJECT(V)                                                \
-  CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY(V)                                 \
-  CLASS_LIST_ARRAYS(V)                                                         \
-  CLASS_LIST_STRINGS(V)
-
-#define CLASS_LIST(V)                                                          \
-  V(Object)                                                                    \
-  CLASS_LIST_NO_OBJECT(V)
-
 // Forward declarations.
 class Isolate;
 #define DEFINE_FORWARD_DECLARATION(clazz) class Raw##clazz;
@@ -148,51 +33,6 @@
 #undef DEFINE_FORWARD_DECLARATION
 class CodeStatistics;
 
-enum ClassId {
-  // Illegal class id.
-  kIllegalCid = 0,
-
-  // A sentinel used by the vm service's heap snapshots to represent references
-  // from the stack.
-  kStackCid = 1,
-
-  // The following entries describes classes for pseudo-objects in the heap
-  // that should never be reachable from live objects. Free list elements
-  // maintain the free list for old space, and forwarding corpses are used to
-  // implement one-way become.
-  kFreeListElement,
-  kForwardingCorpse,
-
-// List of Ids for predefined classes.
-#define DEFINE_OBJECT_KIND(clazz) k##clazz##Cid,
-  CLASS_LIST(DEFINE_OBJECT_KIND)
-#undef DEFINE_OBJECT_KIND
-
-#define DEFINE_OBJECT_KIND(clazz) kTypedData##clazz##Cid,
-      CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
-#undef DEFINE_OBJECT_KIND
-
-#define DEFINE_OBJECT_KIND(clazz) kTypedData##clazz##ViewCid,
-          CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
-#undef DEFINE_OBJECT_KIND
-
-              kByteDataViewCid,
-
-#define DEFINE_OBJECT_KIND(clazz) kExternalTypedData##clazz##Cid,
-  CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
-#undef DEFINE_OBJECT_KIND
-
-      kByteBufferCid,
-
-  // The following entries do not describe a predefined class, but instead
-  // are class indexes for pre-allocated instances (Null, dynamic and Void).
-  kNullCid,
-  kDynamicCid,
-  kVoidCid,
-
-  kNumPredefinedCids,
-};
-
 #define VISIT_FROM(type, first)                                                \
   type* from() { return reinterpret_cast<type*>(&ptr()->first); }
 
@@ -215,25 +55,6 @@
 #define ASSERT_NOTHING_TO_VISIT(Type)                                          \
   ASSERT(SIZE_OF_RETURNED_VALUE(Raw##Type, NothingToVisit) == sizeof(int))
 
-enum ObjectAlignment {
-  // Alignment offsets are used to determine object age.
-  kNewObjectAlignmentOffset = kWordSize,
-  kOldObjectAlignmentOffset = 0,
-  kNewObjectBitPosition = kWordSizeLog2,
-  // Object sizes are aligned to kObjectAlignment.
-  kObjectAlignment = 2 * kWordSize,
-  kObjectAlignmentLog2 = kWordSizeLog2 + 1,
-  kObjectAlignmentMask = kObjectAlignment - 1,
-};
-
-enum {
-  kSmiTag = 0,
-  kHeapObjectTag = 1,
-  kSmiTagSize = 1,
-  kSmiTagMask = 1,
-  kSmiTagShift = 1,
-};
-
 enum TypedDataElementType {
 #define V(name) k##name##Element,
   CLASS_LIST_TYPED_DATA(V)
@@ -523,6 +344,11 @@
   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 {
@@ -542,17 +368,18 @@
     return IsHeapObject() ? GetClassId() : static_cast<intptr_t>(kSmiCid);
   }
 
-  intptr_t Size() const {
+  intptr_t HeapSize() const {
+    ASSERT(IsHeapObject());
     uint32_t tags = ptr()->tags_;
     intptr_t result = SizeTag::decode(tags);
     if (result != 0) {
 #if defined(DEBUG)
       // TODO(22501) Array::MakeFixedLength has a race with this code: we might
       // have loaded tags field and then MakeFixedLength could have updated it
-      // leading to inconsistency between SizeFromClass() and
+      // 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 = SizeFromClass();
+      const intptr_t size_from_class = HeapSizeFromClass();
       if ((result > size_from_class) && (GetClassId() == kArrayCid) &&
           (ptr()->tags_ != tags)) {
         result = SizeTag::decode(ptr()->tags_);
@@ -561,13 +388,13 @@
 #endif
       return result;
     }
-    result = SizeFromClass();
+    result = HeapSizeFromClass();
     ASSERT(result > SizeTag::kMaxSizeTag);
     return result;
   }
 
   bool Contains(uword addr) const {
-    intptr_t this_size = Size();
+    intptr_t this_size = HeapSize();
     uword this_addr = RawObject::ToAddr(this);
     return (addr >= this_addr) && (addr < (this_addr + this_size));
   }
@@ -586,7 +413,7 @@
     }
 
     // Calculate the first and last raw object pointer fields.
-    intptr_t instance_size = Size();
+    intptr_t instance_size = HeapSize();
     uword obj_addr = ToAddr(this);
     uword from = obj_addr + sizeof(RawObject);
     uword to = obj_addr + instance_size - kWordSize;
@@ -607,7 +434,7 @@
     }
 
     // Calculate the first and last raw object pointer fields.
-    intptr_t instance_size = Size();
+    intptr_t instance_size = HeapSize();
     uword obj_addr = ToAddr(this);
     uword from = obj_addr + sizeof(RawObject);
     uword to = obj_addr + instance_size - kWordSize;
@@ -649,6 +476,15 @@
   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);
@@ -672,7 +508,7 @@
   intptr_t VisitPointersPredefined(ObjectPointerVisitor* visitor,
                                    intptr_t class_id);
 
-  intptr_t SizeFromClass() const;
+  intptr_t HeapSizeFromClass() const;
 
   intptr_t GetClassId() const {
     uint32_t tags = ptr()->tags_;
@@ -842,7 +678,9 @@
   friend class CidRewriteVisitor;
   friend class Closure;
   friend class Code;
+  friend class Pointer;
   friend class Double;
+  friend class DynamicLibrary;
   friend class ForwardPointersVisitor;  // StorePointer
   friend class FreeListElement;
   friend class Function;
@@ -1033,6 +871,7 @@
     kDynamicInvocationForwarder,  // represents forwarder which performs type
                                   // checks for arguments of a dynamic
                                   // invocation.
+    kFfiTrampoline,
   };
 
   enum AsyncModifier {
@@ -1180,6 +1019,15 @@
   RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
 };
 
+class RawFfiTrampolineData : public RawObject {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData);
+
+  VISIT_FROM(RawObject*, signature_type_);
+  RawType* signature_type_;
+  VISIT_TO(RawObject*, signature_type_);
+};
+
 class RawField : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
 
@@ -1192,15 +1040,13 @@
     RawInstance* static_value_;  // Value for static fields.
     RawSmi* offset_;             // Offset in words for instance fields.
   } value_;
-  union {
-    // When precompiling we need to save the static initializer function here
-    // so that code for it can be generated.
-    RawFunction* precompiled_;  // Static initializer function - precompiling.
-    // When generating script 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.
-    RawInstance* saved_value_;  // Saved initial value - static fields.
-  } initializer_;
+  RawFunction* initializer_;  // Static initializer function.
+  // 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 - static fields.
   RawSmi* guarded_list_length_;
   RawArray* dependent_code_;
   RawObject** to_snapshot(Snapshot::Kind kind) {
@@ -1340,7 +1186,6 @@
   classid_t index_;       // Library id number.
   uint16_t num_imports_;  // Number of entries in imports_.
   int8_t load_state_;     // Of type LibraryState.
-  bool corelib_imported_;
   bool is_dart_scheme_;
   bool debuggable_;          // True if debugger can stop in library.
   bool is_in_fullsnapshot_;  // True if library is in a full snapshot.
@@ -1493,16 +1338,19 @@
 class RawBytecode : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Bytecode);
 
+  uword instructions_;
+  intptr_t instructions_size_;
+
   VISIT_FROM(RawObject*, object_pool_);
   RawObjectPool* object_pool_;
-  RawExternalTypedData* instructions_;
   RawFunction* function_;
   RawExceptionHandlers* exception_handlers_;
   RawPcDescriptors* pc_descriptors_;
   VISIT_TO(RawObject*, pc_descriptors_);
   RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
 
-  intptr_t source_positions_binary_offset_;
+  int32_t instructions_binary_offset_;
+  int32_t source_positions_binary_offset_;
 
   static bool ContainsPC(RawObject* raw_obj, uword pc);
 
@@ -1852,8 +1700,8 @@
 class RawICData : public RawObject {
   RAW_HEAP_OBJECT_IMPLEMENTATION(ICData);
 
-  VISIT_FROM(RawObject*, ic_data_);
-  RawArray* ic_data_;          // Contains class-ids, target and count.
+  VISIT_FROM(RawObject*, entries_);
+  RawArray* entries_;          // Contains class-ids, target and count.
   RawString* target_name_;     // Name of target function.
   RawArray* args_descriptor_;  // Arguments descriptor.
   // Static type of the receiver. If it is set then we are performing
@@ -1879,12 +1727,6 @@
   }
   NOT_IN_PRECOMPILED(int32_t deopt_id_);
   uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons.
-#if defined(TAG_IC_DATA)
-  enum class Tag : intptr_t{kUnknown, kInstanceCall, kStaticCall};
-
-  Tag tag_;  // Debugging, verifying that the icdata is assigned to the
-             // same instruction again.
-#endif
 };
 
 class RawMegamorphicCache : public RawObject {
@@ -2018,7 +1860,7 @@
 };
 
 class RawAbstractType : public RawInstance {
- protected:
+ public:
   enum TypeState {
     kAllocated,                // Initial state.
     kBeingFinalized,           // In the process of being finalized.
@@ -2026,13 +1868,10 @@
     kFinalizedUninstantiated,  // Uninstantiated type ready for use.
   };
 
-  // Note: we don't handle this field in GC in any special way.
-  // Instead we rely on two things:
-  //   (1) GC not moving code objects and
-  //   (2) lifetime of optimized stubs exceeding that of types;
-  // Practically (2) means that optimized stubs never die because
-  // canonical types to which they are attached never die.
+ 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.
 
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(AbstractType);
@@ -2045,7 +1884,7 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(Type);
 
-  VISIT_FROM(RawObject*, type_class_id_)
+  VISIT_FROM(RawObject*, type_test_stub_)
   RawSmi* type_class_id_;
   RawTypeArguments* arguments_;
   RawSmi* hash_;
@@ -2066,7 +1905,7 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
 
-  VISIT_FROM(RawObject*, type_)
+  VISIT_FROM(RawObject*, type_test_stub_)
   RawAbstractType* type_;  // The referenced type.
   VISIT_TO(RawObject*, type_)
   RawObject** to_snapshot(Snapshot::Kind kind) { return to(); }
@@ -2076,7 +1915,7 @@
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
 
-  VISIT_FROM(RawObject*, name_)
+  VISIT_FROM(RawObject*, type_test_stub_)
   RawString* name_;
   RawSmi* hash_;
   RawAbstractType* bound_;  // ObjectType if no explicit bound specified.
@@ -2400,6 +2239,24 @@
   friend class RawBytecode;
 };
 
+class RawPointer : public RawInstance {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(Pointer);
+  VISIT_FROM(RawCompressed, type_arguments_)
+  RawTypeArguments* type_arguments_;
+  VISIT_TO(RawCompressed, type_arguments_)
+  uint8_t* c_memory_address_;
+
+  friend class Pointer;
+};
+
+class RawDynamicLibrary : public RawInstance {
+  RAW_HEAP_OBJECT_IMPLEMENTATION(DynamicLibrary);
+  VISIT_NOTHING();
+  void* handle_;
+
+  friend class DynamicLibrary;
+};
+
 // VM implementations of the basic types in the isolate.
 class RawCapability : public RawInstance {
   RAW_HEAP_OBJECT_IMPLEMENTATION(Capability);
@@ -2670,6 +2527,56 @@
           index <= kExternalTypedDataFloat64x2ArrayCid);
 }
 
+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));
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc
index 03cbffb..7332edb 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, type_test_cache_)                                                   \
+  F(Field, initializer_)                                                       \
   F(Script, url_)                                                              \
   F(Script, resolved_url_)                                                     \
   F(Script, compile_time_constants_)                                           \
@@ -113,7 +114,7 @@
   F(SingleTargetCache, target_)                                                \
   F(UnlinkedCall, target_name_)                                                \
   F(UnlinkedCall, args_descriptor_)                                            \
-  F(ICData, ic_data_)                                                          \
+  F(ICData, entries_)                                                          \
   F(ICData, target_name_)                                                      \
   F(ICData, args_descriptor_)                                                  \
   F(ICData, owner_)                                                            \
@@ -137,11 +138,15 @@
   F(TypeArguments, instantiations_)                                            \
   F(TypeArguments, length_)                                                    \
   F(TypeArguments, hash_)                                                      \
+  F(AbstractType, type_test_stub_)                                             \
+  F(Type, type_test_stub_)                                                     \
   F(Type, type_class_id_)                                                      \
   F(Type, arguments_)                                                          \
   F(Type, hash_)                                                               \
   F(Type, signature_)                                                          \
+  F(TypeRef, type_test_stub_)                                                  \
   F(TypeRef, type_)                                                            \
+  F(TypeParameter, type_test_stub_)                                            \
   F(TypeParameter, name_)                                                      \
   F(TypeParameter, hash_)                                                      \
   F(TypeParameter, bound_)                                                     \
@@ -181,7 +186,11 @@
   F(WeakProperty, key_)                                                        \
   F(WeakProperty, value_)                                                      \
   F(MirrorReference, referent_)                                                \
-  F(UserTag, label_)
+  F(UserTag, label_)                                                           \
+  F(Pointer, type_arguments_)                                                  \
+  F(Pointer, c_memory_address_)                                                \
+  F(DynamicLibrary, handle_)                                                   \
+  F(FfiTrampolineData, signature_type_)
 
 OffsetsTable::OffsetsTable(Zone* zone) : cached_offsets_(zone) {
   for (intptr_t i = 0; offsets_table[i].class_id != -1; ++i) {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 286beb6..2222f8d 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -128,9 +128,9 @@
   }
 
   // Fill in the type testing stub.
-  Instructions& instr = *reader->InstructionsHandle();
-  instr = TypeTestingStubGenerator::DefaultCodeForType(type);
-  type.SetTypeTestingStub(instr);
+  Code& code = *reader->CodeHandle();
+  code = TypeTestingStubGenerator::DefaultCodeForType(type);
+  type.SetTypeTestingStub(code);
 
   return type.raw();
 }
@@ -203,9 +203,9 @@
                      kAsReference);
 
   // Fill in the type testing stub.
-  Instructions& instr = *reader->InstructionsHandle();
-  instr = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
-  type_ref.SetTypeTestingStub(instr);
+  Code& code = *reader->CodeHandle();
+  code = TypeTestingStubGenerator::DefaultCodeForType(type_ref);
+  type_ref.SetTypeTestingStub(code);
 
   return type_ref.raw();
 }
@@ -259,9 +259,9 @@
   type_parameter.set_parameterized_class(*reader->ClassHandle());
 
   // Fill in the type testing stub.
-  Instructions& instr = *reader->InstructionsHandle();
-  instr = TypeTestingStubGenerator::DefaultCodeForType(type_parameter);
-  type_parameter.SetTypeTestingStub(instr);
+  Code& code = *reader->CodeHandle();
+  code = TypeTestingStubGenerator::DefaultCodeForType(type_parameter);
+  type_parameter.SetTypeTestingStub(code);
 
   return type_parameter.raw();
 }
@@ -467,6 +467,22 @@
   UNREACHABLE();
 }
 
+RawFfiTrampolineData* FfiTrampolineData::ReadFrom(SnapshotReader* reader,
+                                                  intptr_t object_id,
+                                                  intptr_t tags,
+                                                  Snapshot::Kind kind,
+                                                  bool as_reference) {
+  UNREACHABLE();
+  return FfiTrampolineData::null();
+}
+
+void RawFfiTrampolineData::WriteTo(SnapshotWriter* writer,
+                                   intptr_t object_id,
+                                   Snapshot::Kind kind,
+                                   bool as_reference) {
+  UNREACHABLE();
+}
+
 RawFunction* Function::ReadFrom(SnapshotReader* reader,
                                 intptr_t object_id,
                                 intptr_t tags,
@@ -1967,6 +1983,38 @@
       IsolateMessageTypedDataFinalizer);
 }
 
+RawPointer* Pointer::ReadFrom(SnapshotReader* reader,
+                              intptr_t object_id,
+                              intptr_t tags,
+                              Snapshot::Kind kind,
+                              bool as_reference) {
+  FATAL("Snapshotting Pointers is not supported");
+  UNREACHABLE();
+}
+
+void RawPointer::WriteTo(SnapshotWriter* writer,
+                         intptr_t object_id,
+                         Snapshot::Kind kind,
+                         bool as_reference) {
+  FATAL("Snapshotting Pointers is not supported");
+}
+
+RawDynamicLibrary* DynamicLibrary::ReadFrom(SnapshotReader* reader,
+                                            intptr_t object_id,
+                                            intptr_t tags,
+                                            Snapshot::Kind kind,
+                                            bool as_reference) {
+  FATAL("Snapshotting DynamicLibraries is not supported");
+  UNREACHABLE();
+}
+
+void RawDynamicLibrary::WriteTo(SnapshotWriter* writer,
+                                intptr_t object_id,
+                                Snapshot::Kind kind,
+                                bool as_reference) {
+  FATAL("Snapshotting DynamicLibraries is not supported");
+}
+
 RawCapability* Capability::ReadFrom(SnapshotReader* reader,
                                     intptr_t object_id,
                                     intptr_t tags,
diff --git a/runtime/vm/regexp_assembler_bytecode.cc b/runtime/vm/regexp_assembler_bytecode.cc
index 3847c62..f63bfec 100644
--- a/runtime/vm/regexp_assembler_bytecode.cc
+++ b/runtime/vm/regexp_assembler_bytecode.cc
@@ -419,7 +419,7 @@
 
   if (regexp.bytecode(is_one_byte, sticky) == TypedData::null()) {
     const String& pattern = String::Handle(zone, regexp.pattern());
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
     TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
                               "CompileIrregexpBytecode");
     if (tds.enabled()) {
diff --git a/runtime/vm/regexp_interpreter.cc b/runtime/vm/regexp_interpreter.cc
index 8b960b0..c83f474 100644
--- a/runtime/vm/regexp_interpreter.cc
+++ b/runtime/vm/regexp_interpreter.cc
@@ -136,7 +136,7 @@
   intptr_t max_size() const { return kBacktrackStackSize; }
 
  private:
-  static const intptr_t kBacktrackStackSize = 10000;
+  static const intptr_t kBacktrackStackSize = 1 << 16;
 
   intptr_t* data_;
 
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index c6cee03..e707f06 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -195,6 +195,11 @@
   NullErrorHelper(zone, selector);
 }
 
+DEFINE_RUNTIME_ENTRY(ArgumentNullError, 0) {
+  const String& error = String::Handle(String::New("argument value is null"));
+  Exceptions::ThrowArgumentError(error);
+}
+
 DEFINE_RUNTIME_ENTRY(ArgumentError, 1) {
   const Instance& value = Instance::CheckedHandle(zone, arguments.ArgAt(0));
   Exceptions::ThrowArgumentError(value);
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index e0c9e56..85e9d7f2 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -6,6 +6,9 @@
 #define RUNTIME_VM_RUNTIME_ENTRY_H_
 
 #include "vm/allocation.h"
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/compiler/runtime_api.h"
+#endif
 #include "vm/flags.h"
 #include "vm/heap/safepoint.h"
 #include "vm/native_arguments.h"
@@ -13,25 +16,34 @@
 
 namespace dart {
 
-class Assembler;
-
 typedef void (*RuntimeFunction)(NativeArguments arguments);
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+using BaseRuntimeEntry = compiler::RuntimeEntry;
+#else
+using BaseRuntimeEntry = ValueObject;
+#endif
+
 // Class RuntimeEntry is used to encapsulate runtime functions, it includes
 // the entry point for the runtime function and the number of arguments expected
 // by the function.
-class RuntimeEntry : public ValueObject {
+class RuntimeEntry : public BaseRuntimeEntry {
  public:
   RuntimeEntry(const char* name,
                RuntimeFunction function,
                intptr_t argument_count,
                bool is_leaf,
                bool is_float)
-      : name_(name),
+      :
+#if !defined(DART_PRECOMPILED_RUNTIME)
+        compiler::RuntimeEntry(this, &CallInternal),
+#endif
+        name_(name),
         function_(function),
         argument_count_(argument_count),
         is_leaf_(is_leaf),
-        is_float_(is_float) {}
+        is_float_(is_float) {
+  }
 
   const char* name() const { return name_; }
   RuntimeFunction function() const { return function_; }
@@ -41,8 +53,8 @@
   uword GetEntryPoint() const;
 
   // Generate code to call the runtime entry.
-  NOT_IN_PRECOMPILED(void Call(Assembler* assembler, intptr_t argument_count)
-                         const);
+  NOT_IN_PRECOMPILED(void Call(compiler::Assembler* assembler,
+                               intptr_t argument_count) const);
 
   static uword InterpretCallEntry();
   static RawObject* InterpretCall(RawFunction* function,
@@ -51,6 +63,11 @@
                                   RawObject** argv,
                                   Thread* thread);
 
+ protected:
+  NOT_IN_PRECOMPILED(static void CallInternal(const RuntimeEntry* runtime_entry,
+                                              compiler::Assembler* assembler,
+                                              intptr_t argument_count));
+
  private:
   const char* const name_;
   const RuntimeFunction function_;
diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc
index 3ff5758..7f84226 100644
--- a/runtime/vm/runtime_entry_arm.cc
+++ b/runtime/vm/runtime_entry_arm.cc
@@ -42,10 +42,12 @@
 //   SP : points to the arguments and return value array.
 //   R9 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
-void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
-  if (is_leaf()) {
-    ASSERT(argument_count == this->argument_count());
-    __ LoadFromOffset(kWord, TMP, THR, Thread::OffsetFromThread(this));
+void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
+                                Assembler* assembler,
+                                intptr_t argument_count) {
+  if (runtime_entry->is_leaf()) {
+    ASSERT(argument_count == runtime_entry->argument_count());
+    __ LoadFromOffset(kWord, TMP, THR, Thread::OffsetFromThread(runtime_entry));
     __ str(TMP, Address(THR, Thread::vm_tag_offset()));
     __ blx(TMP);
     __ LoadImmediate(TMP, VMTag::kDartCompiledTagId);
@@ -55,7 +57,7 @@
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
-    __ LoadFromOffset(kWord, R9, THR, Thread::OffsetFromThread(this));
+    __ LoadFromOffset(kWord, R9, THR, Thread::OffsetFromThread(runtime_entry));
     __ LoadImmediate(R4, argument_count);
     __ BranchLinkToRuntime();
   }
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index a17870c..69f902e 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -42,9 +42,11 @@
 //   SP : points to the arguments and return value array.
 //   R5 : address of the runtime function to call.
 //   R4 : number of arguments to the call.
-void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
-  if (is_leaf()) {
-    ASSERT(argument_count == this->argument_count());
+void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
+                                Assembler* assembler,
+                                intptr_t argument_count) {
+  if (runtime_entry->is_leaf()) {
+    ASSERT(argument_count == runtime_entry->argument_count());
     // Since we are entering C++ code, we must restore the C stack pointer from
     // the stack limit to an aligned value nearer to the top of the stack.
     // We cache the Dart stack pointer and the stack limit in callee-saved
@@ -60,7 +62,7 @@
     __ mov(R25, SP);
     __ ReserveAlignedFrameSpace(0);
     __ mov(CSP, SP);
-    __ ldr(TMP, Address(THR, Thread::OffsetFromThread(this)));
+    __ ldr(TMP, Address(THR, Thread::OffsetFromThread(runtime_entry)));
     __ str(TMP, Address(THR, Thread::vm_tag_offset()));
     __ blr(TMP);
     __ LoadImmediate(TMP, VMTag::kDartCompiledTagId);
@@ -72,7 +74,7 @@
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
-    __ ldr(R5, Address(THR, Thread::OffsetFromThread(this)));
+    __ ldr(R5, Address(THR, Thread::OffsetFromThread(runtime_entry)));
     __ LoadImmediate(R4, argument_count);
     __ BranchLinkToRuntime();
   }
diff --git a/runtime/vm/runtime_entry_dbc.cc b/runtime/vm/runtime_entry_dbc.cc
index 2735003..b375e8d 100644
--- a/runtime/vm/runtime_entry_dbc.cc
+++ b/runtime/vm/runtime_entry_dbc.cc
@@ -17,9 +17,13 @@
   return reinterpret_cast<uword>(function());
 }
 
-void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
+                                Assembler* assembler,
+                                intptr_t argument_count) {
   UNIMPLEMENTED();
 }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 }  // namespace dart
 
diff --git a/runtime/vm/runtime_entry_ia32.cc b/runtime/vm/runtime_entry_ia32.cc
index 26f300e..425529c 100644
--- a/runtime/vm/runtime_entry_ia32.cc
+++ b/runtime/vm/runtime_entry_ia32.cc
@@ -27,17 +27,19 @@
 //   EDX : number of arguments to the call as Smi.
 // For leaf calls the caller is responsible to setup the arguments
 // and look for return values based on the C calling convention.
-void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
-  if (is_leaf()) {
-    ASSERT(argument_count == this->argument_count());
-    __ movl(EAX, Immediate(GetEntryPoint()));
+void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
+                                Assembler* assembler,
+                                intptr_t argument_count) {
+  if (runtime_entry->is_leaf()) {
+    ASSERT(argument_count == runtime_entry->argument_count());
+    __ movl(EAX, Immediate(runtime_entry->GetEntryPoint()));
     __ movl(Assembler::VMTagAddress(), EAX);
     __ call(EAX);
     __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
-    __ movl(ECX, Immediate(GetEntryPoint()));
+    __ movl(ECX, Immediate(runtime_entry->GetEntryPoint()));
     __ movl(EDX, Immediate(argument_count));
     __ CallToRuntime();
   }
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index fa97c63..4833b04 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -41,6 +41,7 @@
   V(RangeError)                                                                \
   V(NullError)                                                                 \
   V(NullErrorWithSelector)                                                     \
+  V(ArgumentNullError)                                                         \
   V(ArgumentError)                                                             \
   V(ArgumentErrorUnboxedInt64)                                                 \
   V(IntegerDivisionByZeroException)                                            \
diff --git a/runtime/vm/runtime_entry_x64.cc b/runtime/vm/runtime_entry_x64.cc
index f84db6b..b21de64 100644
--- a/runtime/vm/runtime_entry_x64.cc
+++ b/runtime/vm/runtime_entry_x64.cc
@@ -24,11 +24,13 @@
 //   RSP : points to the arguments and return value array.
 //   RBX : address of the runtime function to call.
 //   R10 : number of arguments to the call.
-void RuntimeEntry::Call(Assembler* assembler, intptr_t argument_count) const {
-  if (is_leaf()) {
-    ASSERT(argument_count == this->argument_count());
+void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry,
+                                Assembler* assembler,
+                                intptr_t argument_count) {
+  if (runtime_entry->is_leaf()) {
+    ASSERT(argument_count == runtime_entry->argument_count());
     COMPILE_ASSERT(CallingConventions::kVolatileCpuRegisters & (1 << RAX));
-    __ movq(RAX, Address(THR, Thread::OffsetFromThread(this)));
+    __ movq(RAX, Address(THR, Thread::OffsetFromThread(runtime_entry)));
     __ movq(Assembler::VMTagAddress(), RAX);
     __ CallCFunction(RAX);
     __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
@@ -37,7 +39,7 @@
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
-    __ movq(RBX, Address(THR, Thread::OffsetFromThread(this)));
+    __ movq(RBX, Address(THR, Thread::OffsetFromThread(runtime_entry)));
     __ LoadImmediate(R10, Immediate(argument_count));
     __ CallToRuntime();
   }
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 282f198..93fa9c6 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -701,27 +701,25 @@
             return -1;
           }
           bool valid_enum = false;
+          const char* id_start = cp;
+          while (IsEnumChar(*cp)) {
+            cp++;
+          }
+          if (cp == id_start) {
+            // Empty identifier, something like this [,].
+            return -1;
+          }
+          intptr_t id_len = cp - id_start;
           if (enums_ != NULL) {
             for (intptr_t i = 0; enums_[i] != NULL; i++) {
               intptr_t len = strlen(enums_[i]);
-              if (strncmp(cp, enums_[i], len) == 0) {
+              if (len == id_len && strncmp(id_start, enums_[i], len) == 0) {
                 element_count++;
                 valid_enum = true;
-                cp += len;
                 element_allowed = false;  // we need a comma first.
                 break;
               }
             }
-          } else {
-            // Allow any identifiers
-            const char* id_start = cp;
-            while (IsEnumChar(*cp)) {
-              cp++;
-            }
-            if (cp == id_start) {
-              // Empty identifier, something like this [,].
-              return -1;
-            }
           }
           if (!valid_enum) {
             return -1;
@@ -3036,6 +3034,7 @@
   return true;
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
 static const char* const report_enum_names[] = {
     SourceReport::kCallSitesStr,
     SourceReport::kCoverageStr,
@@ -3043,18 +3042,25 @@
     SourceReport::kProfileStr,
     NULL,
 };
+#endif
 
 static const MethodParameter* get_source_report_params[] = {
+#if !defined(DART_PRECOMPILED_RUNTIME)
     RUNNABLE_ISOLATE_PARAMETER,
     new EnumListParameter("reports", true, report_enum_names),
     new IdParameter("scriptId", false),
     new UIntParameter("tokenPos", false),
     new UIntParameter("endTokenPos", false),
     new BoolParameter("forceCompile", false),
+#endif
     NULL,
 };
 
 static bool GetSourceReport(Thread* thread, JSONStream* js) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  js->PrintError(kFeatureDisabled, "disabled in AOT mode and PRODUCT.");
+  return false;
+#else
   if (CheckCompilerDisabled(thread, js)) {
     return true;
   }
@@ -3116,6 +3122,7 @@
   report.PrintJSON(js, script, TokenPosition(start_pos),
                    TokenPosition(end_pos));
   return true;
+#endif  // !DART_PRECOMPILED_RUNTIME
 }
 
 static const MethodParameter* reload_sources_params[] = {
@@ -3526,6 +3533,7 @@
     NULL,
 };
 
+#if defined(SUPPORT_TIMELINE)
 static bool HasStream(const char** recorded_streams, const char* stream) {
   while (*recorded_streams != NULL) {
     if ((strstr(*recorded_streams, "all") != NULL) ||
@@ -3536,12 +3544,13 @@
   }
   return false;
 }
+#endif
 
 static bool SetVMTimelineFlags(Thread* thread, JSONStream* js) {
-  if (!FLAG_support_timeline) {
-    PrintSuccess(js);
-    return true;
-  }
+#if !defined(SUPPORT_TIMELINE)
+  PrintSuccess(js);
+  return true;
+#else
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   StackZone zone(thread);
@@ -3561,6 +3570,7 @@
   PrintSuccess(js);
 
   return true;
+#endif
 }
 
 static const MethodParameter* get_vm_timeline_flags_params[] = {
@@ -3568,16 +3578,17 @@
 };
 
 static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) {
-  if (!FLAG_support_timeline) {
-    JSONObject obj(js);
-    obj.AddProperty("type", "TimelineFlags");
-    return true;
-  }
+#if !defined(SUPPORT_TIMELINE)
+  JSONObject obj(js);
+  obj.AddProperty("type", "TimelineFlags");
+  return true;
+#else
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   StackZone zone(thread);
   Timeline::PrintFlagsToJSON(js);
   return true;
+#endif
 }
 
 static const MethodParameter* clear_vm_timeline_params[] = {
@@ -4097,7 +4108,7 @@
       return false;
     }
     uword obj_begin = RawObject::ToAddr(obj);
-    uword obj_end = obj_begin + obj->Size();
+    uword obj_end = obj_begin + obj->HeapSize();
     return obj_begin <= addr_ && addr_ < obj_end;
   }
 
@@ -4545,16 +4556,20 @@
 
   // Changing most flags at runtime is dangerous because e.g., it may leave the
   // behavior generated code and the runtime out of sync.
+  const uintptr_t kProfilePeriodIndex = 3;
   const char* kAllowedFlags[] = {
       "pause_isolates_on_start",
       "pause_isolates_on_exit",
       "pause_isolates_on_unhandled_exceptions",
+      "profile_period",
   };
 
   bool allowed = false;
+  bool profile_period = false;
   for (size_t i = 0; i < ARRAY_SIZE(kAllowedFlags); i++) {
     if (strcmp(flag_name, kAllowedFlags[i]) == 0) {
       allowed = true;
+      profile_period = (i == kProfilePeriodIndex);
       break;
     }
   }
@@ -4569,6 +4584,11 @@
   const char* error = NULL;
   if (Flags::SetFlag(flag_name, flag_value, &error)) {
     PrintSuccess(js);
+    if (profile_period) {
+      // FLAG_profile_period has already been set to the new value. Now we need
+      // to notify the ThreadInterrupter to pick up the change.
+      Profiler::UpdateSamplePeriod();
+    }
     return true;
   } else {
     JSONObject jsobj(js);
@@ -4732,6 +4752,13 @@
   }
   CLASS_LIST_TYPED_DATA(DEFINE_ADD_MAP_KEY)
 #undef DEFINE_ADD_MAP_KEY
+#define DEFINE_ADD_MAP_KEY(clazz)                                              \
+  {                                                                            \
+    JSONArray internals(&map, #clazz);                                         \
+    DEFINE_ADD_VALUE_F_CID(Ffi##clazz)                                         \
+  }
+  CLASS_LIST_FFI(DEFINE_ADD_MAP_KEY)
+#undef DEFINE_ADD_MAP_KEY
 #undef DEFINE_ADD_VALUE_F_CID
 #undef DEFINE_ADD_VALUE_F
 
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 90f3e64..3e54a6c 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 13
+#define SERVICE_PROTOCOL_MINOR_VERSION 14
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 015ecfb..f8d56fe 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.13
+# Dart VM Service Protocol 3.14
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.13_ of the Dart VM Service Protocol. This
+This document describes of _version 3.14_ 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.
@@ -842,6 +842,10 @@
  * pause_isolates_on_start
  * pause_isolates_on_exit
  * pause_isolates_on_unhandled_exceptions
+ * profile_period
+
+Note: `profile_period` can be set to a minimum value of 50. Attempting to set
+`profile_period` to a lower value will result in a value of 50 being set.
 
 See [Success](#success).
 
@@ -2389,8 +2393,9 @@
   // scripts.
   string source [optional];
 
-  // A table encoding a mapping from token position to line and column.
-  int[][] tokenPosTable;
+  // A table encoding a mapping from token position to line and column. This
+  // field is null if sources aren't available.
+  int[][] tokenPosTable [optional];
 }
 ```
 
@@ -2732,5 +2737,6 @@
 3.11 | Rename 'invoke' parameter 'receiverId' to 'targetId.
 3.12 | Add 'getScripts' RPC and `ScriptList` object.
 3.13 | Class 'mixin' field now properly set for kernel transformed mixin applications.
+3.14 | Flag 'profile_period' can now be set at runtime, allowing for the profiler sample rate to be changed while the program is running.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 869811e..945d4f9 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.14-dev
+# Dart VM Service Protocol 3.15-dev
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.14-dev_ of the Dart VM Service Protocol. This
+This document describes of _version 3.15-dev_ 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.
@@ -842,6 +842,10 @@
  * pause_isolates_on_start
  * pause_isolates_on_exit
  * pause_isolates_on_unhandled_exceptions
+ * profile_period
+
+Note: `profile_period` can be set to a minimum value of 50. Attempting to set
+`profile_period` to a lower value will result in a value of 50 being set.
 
 See [Success](#success).
 
@@ -2389,8 +2393,9 @@
   // scripts.
   string source [optional];
 
-  // A table encoding a mapping from token position to line and column.
-  int[][] tokenPosTable;
+  // A table encoding a mapping from token position to line and column. This
+  // field is null if sources aren't available.
+  int[][] tokenPosTable [optional];
 }
 ```
 
@@ -2732,5 +2737,6 @@
 3.11 | Rename 'invoke' parameter 'receiverId' to 'targetId.
 3.12 | Add 'getScripts' RPC and `ScriptList` object.
 3.13 | Class 'mixin' field now properly set for kernel transformed mixin applications.
+3.14 | Flag 'profile_period' can now be set at runtime, allowing for the profiler sample rate to be changed while the program is running.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 8d13ec6..3f7c827 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -313,9 +313,9 @@
  public:
   virtual void Run() {
     ASSERT(Isolate::Current() == NULL);
-#ifndef PRODUCT
+#if defined(SUPPORT_TIMELINE)
     TimelineDurationScope tds(Timeline::GetVMStream(), "ServiceIsolateStartup");
-#endif  // !PRODUCT
+#endif  // SUPPORT_TIMELINE
     char* error = NULL;
     Isolate* isolate = NULL;
 
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 992dd24..1047955 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -1551,20 +1551,10 @@
             // Format(instr, "bkpt #'imm12_4");
             SimulatorDebugger dbg(this);
             int32_t imm = instr->BkptField();
-            if (imm == Instr::kStopMessageCode) {
-              const char* message = "Stop messages not enabled";
-              if (FLAG_print_stop_message) {
-                message = *reinterpret_cast<const char**>(
-                    reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
-              }
-              set_pc(get_pc() + Instr::kInstrSize);
-              dbg.Stop(instr, message);
-            } else {
-              char buffer[32];
-              snprintf(buffer, sizeof(buffer), "bkpt #0x%x", imm);
-              set_pc(get_pc() + Instr::kInstrSize);
-              dbg.Stop(instr, buffer);
-            }
+            char buffer[32];
+            snprintf(buffer, sizeof(buffer), "bkpt #0x%x", imm);
+            set_pc(get_pc() + Instr::kInstrSize);
+            dbg.Stop(instr, buffer);
           } else {
             // Format(instr, "smc'cond");
             UnimplementedInstruction(instr);
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 82f12b1..d7240cb 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -1647,20 +1647,10 @@
     // Format(instr, "brk 'imm16");
     SimulatorDebugger dbg(this);
     int32_t imm = instr->Imm16Field();
-    if (imm == Instr::kStopMessageCode) {
-      const char* message = "Stop messages not enabled";
-      if (FLAG_print_stop_message) {
-        message = *reinterpret_cast<const char**>(
-            reinterpret_cast<intptr_t>(instr) - 2 * Instr::kInstrSize);
-      }
-      set_pc(get_pc() + Instr::kInstrSize);
-      dbg.Stop(instr, message);
-    } else {
-      char buffer[32];
-      snprintf(buffer, sizeof(buffer), "brk #0x%x", imm);
-      set_pc(get_pc() + Instr::kInstrSize);
-      dbg.Stop(instr, buffer);
-    }
+    char buffer[32];
+    snprintf(buffer, sizeof(buffer), "brk #0x%x", imm);
+    set_pc(get_pc() + Instr::kInstrSize);
+    dbg.Stop(instr, buffer);
   } else if ((instr->Bits(0, 2) == 0) && (instr->Bits(2, 3) == 0) &&
              (instr->Bits(21, 3) == 2)) {
     // Format(instr, "hlt 'imm16");
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 2e97a9a..b059dae 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -847,7 +847,7 @@
 
   const intptr_t kCheckedArgs = 1;
   RawObject** args = call_base;
-  RawArray* cache = icdata->ptr()->ic_data_->ptr();
+  RawArray* cache = icdata->ptr()->entries_->ptr();
 
   const intptr_t type_args_len =
       SimulatorHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_);
@@ -891,7 +891,7 @@
 
   const intptr_t kCheckedArgs = 2;
   RawObject** args = call_base;
-  RawArray* cache = icdata->ptr()->ic_data_->ptr();
+  RawArray* cache = icdata->ptr()->entries_->ptr();
 
   const intptr_t type_args_len =
       SimulatorHelpers::ArgDescTypeArgsLen(icdata->ptr()->args_descriptor_);
@@ -1067,7 +1067,7 @@
     ASSERT(SimulatorBytecode::IsCallOpcode(*pc));                              \
     const uint16_t kidx = SimulatorBytecode::DecodeD(*pc);                     \
     const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));           \
-    RawObject** entries = icdata->ptr()->ic_data_->ptr()->data();              \
+    RawObject** entries = icdata->ptr()->entries_->ptr()->data();              \
     SimulatorHelpers::IncrementICUsageCount(entries, 0, 2);                    \
   } while (0);
 
@@ -1080,8 +1080,8 @@
     const intptr_t lhs = reinterpret_cast<intptr_t>(SP[-1]);                   \
     const intptr_t rhs = reinterpret_cast<intptr_t>(SP[-0]);                   \
     ResultT* slot = reinterpret_cast<ResultT*>(SP - 1);                        \
-    if (LIKELY(!thread->isolate()->single_step()) &&                           \
-        LIKELY(AreBothSmis(lhs, rhs) && !Func(lhs, rhs, slot))) {              \
+    if (NOT_IN_PRODUCT(LIKELY(!thread->isolate()->single_step()) &&)           \
+            LIKELY(AreBothSmis(lhs, rhs) && !Func(lhs, rhs, slot))) {          \
       SMI_FASTPATH_ICDATA_INC;                                                 \
       /* Fast path succeeded. Skip the generic call that follows. */           \
       pc++;                                                                    \
@@ -1464,11 +1464,13 @@
 
   {
     BYTECODE(DebugStep, A);
+#ifndef PRODUCT
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
     DISPATCH();
   }
 
@@ -1652,12 +1654,14 @@
   {
     BYTECODE(IndirectStaticCall, A_D);
 
+#ifndef PRODUCT
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     // Invoke target function.
     {
@@ -1665,7 +1669,7 @@
       // Look up the function in the ICData.
       RawObject* ic_data_obj = SP[0];
       RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
-      RawObject** data = ic_data->ptr()->ic_data_->ptr()->data();
+      RawObject** data = ic_data->ptr()->entries_->ptr()->data();
       SimulatorHelpers::IncrementICUsageCount(data, 0, 0);
       SP[0] = data[ICData::TargetIndexFor(ic_data->ptr()->state_bits_ & 0x3)];
       RawObject** call_base = SP - argc;
@@ -1690,12 +1694,14 @@
   {
     BYTECODE(InstanceCall1, A_D);
 
+#ifndef PRODUCT
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     {
       const uint16_t argc = rA;
@@ -1716,11 +1722,14 @@
 
   {
     BYTECODE(InstanceCall2, A_D);
+
+#ifndef PRODUCT
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     {
       const uint16_t argc = rA;
@@ -3330,11 +3339,14 @@
 
   {
     BYTECODE(IfEqStrictNumTOS, 0);
+
+#ifndef PRODUCT
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     SP -= 2;
     if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) {
@@ -3345,11 +3357,14 @@
 
   {
     BYTECODE(IfNeStrictNumTOS, 0);
+
+#ifndef PRODUCT
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
       INVOKE_RUNTIME(DRT_SingleStepHandler, args);
     }
+#endif  // !PRODUCT
 
     SP -= 2;
     if (SimulatorHelpers::IsStrictEqualWithNumberCheck(SP[1], SP[2])) {
@@ -3758,7 +3773,7 @@
     RawSmi* index = RAW_CAST(Smi, SP[-1]);
     const int16_t offset = rD;
     FP[-(Smi::Value(index) + offset) - 0] = SP[-0];
-    SP--;
+    SP -= 2;
     DISPATCH();
   }
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 5a4d2f5..c3d7c8e 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -187,9 +187,9 @@
 }
 
 RawSmi* BaseReader::ReadAsSmi() {
-  intptr_t value = Read<int32_t>();
-  ASSERT((value & kSmiTagMask) == kSmiTag);
-  return reinterpret_cast<RawSmi*>(value);
+  RawSmi* value = Read<RawSmi*>();
+  ASSERT((reinterpret_cast<uword>(value) & kSmiTagMask) == kSmiTag);
+  return value;
 }
 
 intptr_t BaseReader::ReadSmiValue() {
@@ -271,14 +271,16 @@
 }
 
 void SnapshotReader::RunDelayedTypePostprocessing() {
-  if (types_to_postprocess_.Length() > 0) {
-    AbstractType& type = AbstractType::Handle();
-    Instructions& instr = Instructions::Handle();
-    for (intptr_t i = 0; i < types_to_postprocess_.Length(); ++i) {
-      type ^= types_to_postprocess_.At(i);
-      instr = TypeTestingStubGenerator::DefaultCodeForType(type);
-      type.SetTypeTestingStub(instr);
-    }
+  if (types_to_postprocess_.Length() == 0) {
+    return;
+  }
+
+  AbstractType& type = AbstractType::Handle();
+  Code& code = Code::Handle();
+  for (intptr_t i = 0; i < types_to_postprocess_.Length(); ++i) {
+    type ^= types_to_postprocess_.At(i);
+    code = TypeTestingStubGenerator::DefaultCodeForType(type);
+    type.SetTypeTestingStub(code);
   }
 }
 
@@ -481,6 +483,10 @@
       break;
     }
 #undef SNAPSHOT_READ
+#define SNAPSHOT_READ(clazz) case kFfi##clazz##Cid:
+
+    CLASS_LIST_FFI(SNAPSHOT_READ) { UNREACHABLE(); }
+#undef SNAPSHOT_READ
     default:
       UNREACHABLE();
       break;
@@ -1069,12 +1075,6 @@
     return true;
   }
 
-  // Now check if it is an object from the VM isolate. These objects are shared
-  // by all isolates.
-  if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) {
-    return true;
-  }
-
   // Check if it is a code object in that case just write a Null object
   // as we do not want code objects in the snapshot.
   if ((cid == kCodeCid) || (cid == kBytecodeCid)) {
@@ -1082,6 +1082,12 @@
     return true;
   }
 
+  // Now check if it is an object from the VM isolate. These objects are shared
+  // by all isolates.
+  if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) {
+    return true;
+  }
+
   // Check if classes are not being serialized and it is preinitialized type
   // or a predefined internal VM class in the object store.
   // Check if it is an internal VM class which is in the object store.
@@ -1173,6 +1179,10 @@
       return;
     }
 #undef SNAPSHOT_WRITE
+#define SNAPSHOT_WRITE(clazz) case kFfi##clazz##Cid:
+
+    CLASS_LIST_FFI(SNAPSHOT_WRITE) { UNREACHABLE(); }
+#undef SNAPSHOT_WRITE
     default:
       break;
   }
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 1432259..736329c 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -48,6 +48,7 @@
 class RawContextScope;
 class RawDouble;
 class RawExceptionHandlers;
+class RawFfiTrampolineData;
 class RawField;
 class RawFloat32x4;
 class RawFloat64x2;
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 7ce25de..a1e3da2 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -1,11 +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.
-#ifndef PRODUCT
+#include "vm/globals.h"
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/source_report.h"
 
 #include "vm/compiler/jit/compiler.h"
 #include "vm/isolate.h"
+#include "vm/kernel_loader.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/profiler.h"
@@ -90,6 +92,7 @@
     case RawFunction::kRegularFunction:
     case RawFunction::kClosureFunction:
     case RawFunction::kImplicitClosureFunction:
+    case RawFunction::kImplicitStaticFinalGetter:
     case RawFunction::kGetterFunction:
     case RawFunction::kSetterFunction:
     case RawFunction::kConstructor:
@@ -111,6 +114,28 @@
   return false;
 }
 
+bool SourceReport::ShouldSkipField(const Field& field) {
+  if (!field.token_pos().IsReal() || !field.end_token_pos().IsReal()) {
+    // At least one of the token positions is not known.
+    return true;
+  }
+
+  if (script_ != NULL && !script_->IsNull()) {
+    if (field.Script() != script_->raw()) {
+      // The field is from the wrong script.
+      return true;
+    }
+    if (((start_pos_ > TokenPosition::kMinSource) &&
+         (field.end_token_pos() < start_pos_)) ||
+        ((end_pos_ > TokenPosition::kMinSource) &&
+         (field.token_pos() > end_pos_))) {
+      // The field does not intersect with the requested token range.
+      return true;
+    }
+  }
+  return false;
+}
+
 intptr_t SourceReport::GetScriptIndex(const Script& script) {
   ScriptTableEntry wrapper;
   const String& url = String::Handle(zone(), script.url());
@@ -465,10 +490,25 @@
   }
 }
 
+void SourceReport::VisitField(JSONArray* jsarr, const Field& field) {
+  if (ShouldSkipField(field) || !field.has_initializer()) return;
+  const Function& func =
+      Function::Handle(zone(), GetInitializerFunction(field));
+  VisitFunction(jsarr, func);
+}
+
+RawFunction* SourceReport::GetInitializerFunction(const Field& field) {
+  Thread* const thread = Thread::Current();
+  // Create a function to evaluate the initializer
+  return kernel::CreateFieldInitializerFunction(thread, thread->zone(), field);
+}
+
 void SourceReport::VisitLibrary(JSONArray* jsarr, const Library& lib) {
   Class& cls = Class::Handle(zone());
   Array& functions = Array::Handle(zone());
+  Array& fields = Array::Handle(zone());
   Function& func = Function::Handle(zone());
+  Field& field = Field::Handle(zone());
   Script& script = Script::Handle(zone());
   ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
   while (it.HasNext()) {
@@ -505,6 +545,12 @@
       func ^= functions.At(i);
       VisitFunction(jsarr, func);
     }
+
+    fields = cls.fields();
+    for (intptr_t i = 0; i < fields.Length(); i++) {
+      field ^= fields.At(i);
+      VisitField(jsarr, field);
+    }
   }
 }
 
@@ -554,4 +600,4 @@
 }
 
 }  // namespace dart
-#endif  // PRODUCT
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 5ab147f..73a9c3d 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -5,6 +5,9 @@
 #ifndef RUNTIME_VM_SOURCE_REPORT_H_
 #define RUNTIME_VM_SOURCE_REPORT_H_
 
+#include "vm/globals.h"
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+
 #include "vm/allocation.h"
 #include "vm/flags.h"
 #include "vm/hash_map.h"
@@ -60,6 +63,7 @@
 
   bool IsReportRequested(ReportKind report_kind);
   bool ShouldSkipFunction(const Function& func);
+  bool ShouldSkipField(const Field& field);
   intptr_t GetScriptIndex(const Script& script);
   bool ScriptIsLoadedByLibrary(const Script& script, const Library& lib);
 
@@ -79,9 +83,10 @@
   void PrintScriptTable(JSONArray* jsarr);
 
   void VisitFunction(JSONArray* jsarr, const Function& func);
+  void VisitField(JSONArray* jsarr, const Field& field);
   void VisitLibrary(JSONArray* jsarr, const Library& lib);
   void VisitClosures(JSONArray* jsarr);
-
+  RawFunction* GetInitializerFunction(const Field& field);
   // An entry in the script table.
   struct ScriptTableEntry {
     ScriptTableEntry() : key(NULL), index(-1), script(NULL) {}
@@ -122,4 +127,5 @@
 
 }  // namespace dart
 
+#endif  // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 #endif  // RUNTIME_VM_SOURCE_REPORT_H_
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 5f174f8..0e98fc7 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -6,6 +6,7 @@
 
 #include "platform/memory_sanitizer.h"
 #include "vm/compiler/assembler/assembler.h"
+#include "vm/compiler/runtime_api.h"
 #include "vm/deopt_instructions.h"
 #include "vm/heap/become.h"
 #include "vm/isolate.h"
@@ -32,6 +33,7 @@
     /*.dart_fixed_frame_size = */ -1,
     /*.saved_caller_pp_from_fp = */ -1,
     /*.code_from_fp = */ -1,
+    /*.exit_link_slot_from_entry_fp = */ -1,
 };
 
 const FrameLayout default_frame_layout = {
@@ -42,6 +44,7 @@
     /*.dart_fixed_frame_size = */ kDartFrameFixedSize,
     /*.saved_caller_pp_from_fp = */ kSavedCallerPpSlotFromFp,
     /*.code_from_fp = */ kPcMarkerSlotFromFp,
+    /*.exit_link_slot_from_entry_fp = */ kExitLinkSlotFromEntryFp,
 };
 const FrameLayout bare_instructions_frame_layout = {
     /*.first_object_from_pc =*/kFirstObjectSlotFromFp,  // No saved PP slot.
@@ -54,9 +57,17 @@
         2,                              // No saved CODE, PP slots.
     /*.saved_caller_pp_from_fp = */ 0,  // No saved PP slot.
     /*.code_from_fp = */ 0,             // No saved CODE
+    /*.exit_link_slot_from_entry_fp = */ kExitLinkSlotFromEntryFp,
 };
 
-FrameLayout compiler_frame_layout = invalid_frame_layout;
+namespace compiler {
+
+namespace target {
+FrameLayout frame_layout = invalid_frame_layout;
+}
+
+}  // namespace compiler
+
 FrameLayout runtime_frame_layout = invalid_frame_layout;
 
 int FrameLayout::FrameSlotForVariable(const LocalVariable* variable) const {
@@ -75,15 +86,15 @@
 
 void FrameLayout::Init() {
   // By default we use frames with CODE_REG/PP in the frame.
-  compiler_frame_layout = default_frame_layout;
+  compiler::target::frame_layout = default_frame_layout;
   runtime_frame_layout = default_frame_layout;
 
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    compiler_frame_layout = bare_instructions_frame_layout;
+    compiler::target::frame_layout = bare_instructions_frame_layout;
   }
 #if defined(DART_PRECOMPILED_RUNTIME)
   if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    compiler_frame_layout = invalid_frame_layout;
+    compiler::target::frame_layout = invalid_frame_layout;
     runtime_frame_layout = bare_instructions_frame_layout;
   }
 #endif
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index c8b59b9..bf67520 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -6,6 +6,7 @@
 #define RUNTIME_VM_STACK_FRAME_H_
 
 #include "vm/allocation.h"
+#include "vm/frame_layout.h"
 #include "vm/interpreter.h"
 #include "vm/object.h"
 #include "vm/stack_frame_kbc.h"
@@ -32,61 +33,6 @@
 class RawContext;
 class LocalVariable;
 
-struct FrameLayout {
-  // The offset (in words) from FP to the first object.
-  int first_object_from_fp;
-
-  // The offset (in words) from FP to the last fixed object.
-  int last_fixed_object_from_fp;
-
-  // The offset (in words) from FP to the first local.
-  int param_end_from_fp;
-
-  // The offset (in words) from FP to the first local.
-  int first_local_from_fp;
-
-  // The fixed size of the frame.
-  int dart_fixed_frame_size;
-
-  // The offset (in words) from FP to the saved pool (if applicable).
-  int saved_caller_pp_from_fp;
-
-  // The offset (in words) from FP to the code object (if applicable).
-  int code_from_fp;
-
-  // The number of fixed slots below the saved PC.
-  int saved_below_pc() const { return -first_local_from_fp; }
-
-  // Returns the FP-relative index where [variable] can be found (assumes
-  // [variable] is not captured), in words.
-  int FrameSlotForVariable(const LocalVariable* variable) const;
-
-  // Returns the FP-relative index where [variable_index] can be found (assumes
-  // [variable_index] comes from a [LocalVariable::index()], which is not
-  // captured).
-  int FrameSlotForVariableIndex(int index) const;
-
-  // Returns the FP-relative index where [variable] can be found (assumes
-  // [variable] is not captured), in bytes.
-  int FrameOffsetInBytesForVariable(const LocalVariable* variable) const {
-    return FrameSlotForVariable(variable) * kWordSize;
-  }
-
-  // Returns the variable index from a FP-relative index.
-  intptr_t VariableIndexForFrameSlot(intptr_t frame_slot) const {
-    if (frame_slot <= first_local_from_fp) {
-      return frame_slot - first_local_from_fp;
-    } else {
-      ASSERT(frame_slot > param_end_from_fp);
-      return frame_slot - param_end_from_fp;
-    }
-  }
-
-  // Called to initialize the stack frame layout during startup.
-  static void Init();
-};
-
-extern FrameLayout compiler_frame_layout;
 extern FrameLayout runtime_frame_layout;
 
 // Generic stack frame.
diff --git a/runtime/vm/static_type_exactness_state.h b/runtime/vm/static_type_exactness_state.h
new file mode 100644
index 0000000..1660eba
--- /dev/null
+++ b/runtime/vm/static_type_exactness_state.h
@@ -0,0 +1,149 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_STATIC_TYPE_EXACTNESS_STATE_H_
+#define RUNTIME_VM_STATIC_TYPE_EXACTNESS_STATE_H_
+
+#include "platform/allocation.h"
+
+// This header defines the list of VM implementation classes and their ids.
+//
+// Note: we assume that all builds of Dart VM use exactly the same class ids
+// for these classes.
+
+namespace dart {
+
+class Instance;
+class Type;
+
+// Representation of a state of runtime tracking of static type exactness for
+// a particular location in the program (e.g. exactness of type annotation
+// on a field).
+//
+// Given the static type G<T0, ..., Tn> we say that it is exact iff any
+// values that can be observed at this location has runtime type T such that
+// type arguments of T at G are exactly <T0, ..., Tn>.
+//
+// Currently we only support tracking for locations that are also known
+// to be monomorphic with respect to the actual class of the values it contains.
+//
+// Important: locations should never switch from tracked (kIsTriviallyExact,
+// kHasExactSuperType, kHasExactSuperClass, kNotExact) to not tracked
+// (kNotTracking) or the other way around because that would affect unoptimized
+// graphs generated by graph builder and skew deopt ids.
+class StaticTypeExactnessState final {
+ public:
+  // Values stored in the location with static type G<T0, ..., Tn> are all
+  // instances of C<T0, ..., Tn> and C<U0, ..., Un> at G has type parameters
+  // <U0, ..., Un>.
+  //
+  // For trivially exact types we can simply compare type argument
+  // vectors as pointers to check exactness. That's why we represent
+  // trivially exact locations as offset in words to the type arguments of
+  // class C. All other states are represented as non-positive values.
+  //
+  // Note: we are ignoring the type argument vector sharing optimization for
+  // now.
+  static inline StaticTypeExactnessState TriviallyExact(
+      intptr_t type_arguments_offset_in_bytes) {
+    ASSERT((type_arguments_offset_in_bytes > 0) &&
+           Utils::IsInt(8, type_arguments_offset_in_bytes));
+    return StaticTypeExactnessState(type_arguments_offset_in_bytes);
+  }
+
+  static inline bool CanRepresentAsTriviallyExact(
+      intptr_t type_arguments_offset_in_bytes) {
+    return Utils::IsInt(8, type_arguments_offset_in_bytes);
+  }
+
+  // Values stored in the location with static type G<T0, ..., Tn> are all
+  // instances of class C<...> and C<U0, ..., Un> at G has type
+  // parameters <T0, ..., Tn> for any <U0, ..., Un> - that is C<...> has a
+  // supertype G<T0, ..., Tn>.
+  //
+  // For such locations we can simply check if the value stored
+  // is an instance of an expected class and we don't have to look at
+  // type arguments carried by the instance.
+  //
+  // We distinguish situations where we know that G is a superclass of C from
+  // situations where G might be superinterface of C - because in the first
+  // type arguments of G give us constant prefix of type arguments of C.
+  static inline StaticTypeExactnessState HasExactSuperType() {
+    return StaticTypeExactnessState(kHasExactSuperType);
+  }
+
+  static inline StaticTypeExactnessState HasExactSuperClass() {
+    return StaticTypeExactnessState(kHasExactSuperClass);
+  }
+
+  // Values stored in the location don't fall under either kIsTriviallyExact
+  // or kHasExactSuperType categories.
+  //
+  // Note: that does not imply that static type annotation is not exact
+  // according to a broader definition, e.g. location might simply be
+  // polymorphic and store instances of multiple different types.
+  // However for simplicity we don't track such cases yet.
+  static inline StaticTypeExactnessState NotExact() {
+    return StaticTypeExactnessState(kNotExact);
+  }
+
+  // The location does not track exactness of its static type at runtime.
+  static inline StaticTypeExactnessState NotTracking() {
+    return StaticTypeExactnessState(kNotTracking);
+  }
+
+  static inline StaticTypeExactnessState Unitialized() {
+    return StaticTypeExactnessState(kUninitialized);
+  }
+
+  static StaticTypeExactnessState Compute(const Type& static_type,
+                                          const Instance& value,
+                                          bool print_trace = false);
+
+  bool IsTracking() const { return value_ != kNotTracking; }
+  bool IsUninitialized() const { return value_ == kUninitialized; }
+  bool IsHasExactSuperClass() const { return value_ == kHasExactSuperClass; }
+  bool IsHasExactSuperType() const { return value_ == kHasExactSuperType; }
+  bool IsTriviallyExact() const { return value_ > kUninitialized; }
+  bool NeedsFieldGuard() const { return value_ >= kUninitialized; }
+  bool IsExactOrUninitialized() const { return value_ > kNotExact; }
+  bool IsExact() const {
+    return IsTriviallyExact() || IsHasExactSuperType() ||
+           IsHasExactSuperClass();
+  }
+
+  const char* ToCString() const;
+
+  StaticTypeExactnessState CollapseSuperTypeExactness() const {
+    return IsHasExactSuperClass() ? HasExactSuperType() : *this;
+  }
+
+  static inline StaticTypeExactnessState Decode(int8_t value) {
+    return StaticTypeExactnessState(value);
+  }
+
+  int8_t Encode() const { return value_; }
+  int8_t GetTypeArgumentsOffsetInWords() const {
+    ASSERT(IsTriviallyExact());
+    return value_;
+  }
+
+  static constexpr int8_t kUninitialized = 0;
+
+ private:
+  static constexpr int8_t kNotTracking = -4;
+  static constexpr int8_t kNotExact = -3;
+  static constexpr int8_t kHasExactSuperType = -2;
+  static constexpr int8_t kHasExactSuperClass = -1;
+
+  explicit StaticTypeExactnessState(int8_t value) : value_(value) {}
+
+  int8_t value_;
+
+  DISALLOW_ALLOCATION();
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_STATIC_TYPE_EXACTNESS_STATE_H_
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 9f48a07..9171436 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -20,6 +20,8 @@
 
 namespace dart {
 
+using compiler::ObjectPoolBuilder;
+
 DEFINE_FLAG(bool, disassemble_stubs, false, "Disassemble generated stubs.");
 DECLARE_FLAG(bool, precompiled_mode);
 
@@ -45,20 +47,22 @@
 
 #define STUB_CODE_GENERATE(name)                                               \
   entries_[k##name##Index] = Code::ReadOnlyHandle();                           \
-  *entries_[k##name##Index] = Generate("_stub_" #name, &object_pool_wrapper,   \
-                                       StubCode::Generate##name##Stub);
+  *entries_[k##name##Index] =                                                  \
+      Generate("_stub_" #name, &object_pool_builder,                           \
+               compiler::StubCodeCompiler::Generate##name##Stub);
 
 #define STUB_CODE_SET_OBJECT_POOL(name)                                        \
   entries_[k##name##Index]->set_object_pool(object_pool.raw());
 
 void StubCode::Init() {
-  ObjectPoolWrapper object_pool_wrapper;
+  ObjectPoolBuilder object_pool_builder;
 
   // Generate all the stubs.
   VM_STUB_CODE_LIST(STUB_CODE_GENERATE);
 
   const ObjectPool& object_pool =
-      ObjectPool::Handle(object_pool_wrapper.MakeObjectPool());
+      ObjectPool::Handle(ObjectPool::NewFromBuilder(object_pool_builder));
+
   VM_STUB_CODE_LIST(STUB_CODE_SET_OBJECT_POOL)
 }
 
@@ -74,9 +78,9 @@
 #undef STUB_CODE_CLEANUP
 
 RawCode* StubCode::Generate(const char* name,
-                            ObjectPoolWrapper* object_pool_wrapper,
+                            ObjectPoolBuilder* object_pool_builder,
                             void (*GenerateStub)(Assembler* assembler)) {
-  Assembler assembler(object_pool_wrapper);
+  Assembler assembler(object_pool_builder);
   GenerateStub(&assembler);
   const Code& code = Code::Handle(Code::FinalizeCode(
       name, nullptr, &assembler, Code::PoolAttachment::kNotAttachPool,
@@ -163,13 +167,13 @@
   Code& stub = Code::Handle(zone, cls.allocation_stub());
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (stub.IsNull()) {
-    ObjectPoolWrapper object_pool_wrapper;
+    ObjectPoolBuilder object_pool_builder;
     Precompiler* precompiler = Precompiler::Instance();
 
-    ObjectPoolWrapper* wrapper =
+    ObjectPoolBuilder* wrapper =
         FLAG_use_bare_instructions && precompiler != NULL
-            ? precompiler->global_object_pool_wrapper()
-            : &object_pool_wrapper;
+            ? precompiler->global_object_pool_builder()
+            : &object_pool_builder;
 
     const auto pool_attachment =
         FLAG_precompiled_mode && FLAG_use_bare_instructions
@@ -178,7 +182,7 @@
 
     Assembler assembler(wrapper);
     const char* name = cls.ToCString();
-    StubCode::GenerateAllocationStubForClass(&assembler, cls);
+    compiler::StubCodeCompiler::GenerateAllocationStubForClass(&assembler, cls);
 
     if (thread->IsMutatorThread()) {
       stub ^= Code::FinalizeCode(name, nullptr, &assembler, pool_attachment,
@@ -238,11 +242,22 @@
 }
 
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
-RawCode* StubCode::GetBuildMethodExtractorStub(ObjectPoolWrapper* pool) {
+RawCode* StubCode::GetBuildMethodExtractorStub(ObjectPoolBuilder* pool) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(pool != nullptr ? pool : &object_pool_wrapper);
-  StubCode::GenerateBuildMethodExtractorStub(&assembler);
+  auto thread = Thread::Current();
+  auto Z = thread->zone();
+  auto object_store = thread->isolate()->object_store();
+
+  const auto& closure_class =
+      Class::ZoneHandle(Z, object_store->closure_class());
+  const auto& closure_allocation_stub =
+      Code::ZoneHandle(Z, StubCode::GetAllocationStubForClass(closure_class));
+  const auto& context_allocation_stub = StubCode::AllocateContext();
+
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(pool != nullptr ? pool : &object_pool_builder);
+  compiler::StubCodeCompiler::GenerateBuildMethodExtractorStub(
+      &assembler, closure_allocation_stub, context_allocation_stub);
 
   const char* name = "BuildMethodExtractor";
   const Code& stub = Code::Handle(Code::FinalizeCode(
@@ -250,9 +265,7 @@
       /*optimized=*/false));
 
   if (pool == nullptr) {
-    const ObjectPool& object_pool =
-        ObjectPool::Handle(object_pool_wrapper.MakeObjectPool());
-    stub.set_object_pool(object_pool.raw());
+    stub.set_object_pool(ObjectPool::NewFromBuilder(object_pool_builder));
   }
 
 #ifndef PRODUCT
@@ -298,6 +311,7 @@
 const char* StubCode::NameOfStub(uword entry_point) {
 #define VM_STUB_CODE_TESTER(name)                                              \
   if (entries_[k##name##Index] != nullptr &&                                   \
+      !entries_[k##name##Index]->IsNull() &&                                   \
       entries_[k##name##Index]->EntryPoint() == entry_point) {                 \
     return "" #name;                                                           \
   }
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index fe2fcbe..2593ca00 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -7,6 +7,10 @@
 
 #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"
 
 namespace dart {
 
@@ -14,105 +18,10 @@
 class Code;
 class Isolate;
 class ObjectPointerVisitor;
-class ObjectPoolWrapper;
 class RawCode;
 class SnapshotReader;
 class SnapshotWriter;
 
-// List of stubs created in the VM isolate, these stubs are shared by different
-// isolates running in this dart process.
-#if !defined(TARGET_ARCH_DBC)
-#define VM_STUB_CODE_LIST(V)                                                   \
-  V(GetCStackPointer)                                                          \
-  V(JumpToFrame)                                                               \
-  V(RunExceptionHandler)                                                       \
-  V(DeoptForRewind)                                                            \
-  V(WriteBarrier)                                                              \
-  V(WriteBarrierWrappers)                                                      \
-  V(ArrayWriteBarrier)                                                         \
-  V(PrintStopMessage)                                                          \
-  V(AllocateArray)                                                             \
-  V(AllocateContext)                                                           \
-  V(CallToRuntime)                                                             \
-  V(LazyCompile)                                                               \
-  V(InterpretCall)                                                             \
-  V(CallBootstrapNative)                                                       \
-  V(CallNoScopeNative)                                                         \
-  V(CallAutoScopeNative)                                                       \
-  V(FixCallersTarget)                                                          \
-  V(CallStaticFunction)                                                        \
-  V(OptimizeFunction)                                                          \
-  V(InvokeDartCode)                                                            \
-  V(InvokeDartCodeFromBytecode)                                                \
-  V(DebugStepCheck)                                                            \
-  V(UnlinkedCall)                                                              \
-  V(MonomorphicMiss)                                                           \
-  V(SingleTargetCall)                                                          \
-  V(ICCallThroughFunction)                                                     \
-  V(ICCallThroughCode)                                                         \
-  V(MegamorphicCall)                                                           \
-  V(FixAllocationStubTarget)                                                   \
-  V(Deoptimize)                                                                \
-  V(DeoptimizeLazyFromReturn)                                                  \
-  V(DeoptimizeLazyFromThrow)                                                   \
-  V(UnoptimizedIdenticalWithNumberCheck)                                       \
-  V(OptimizedIdenticalWithNumberCheck)                                         \
-  V(ICCallBreakpoint)                                                          \
-  V(RuntimeCallBreakpoint)                                                     \
-  V(OneArgCheckInlineCache)                                                    \
-  V(TwoArgsCheckInlineCache)                                                   \
-  V(SmiAddInlineCache)                                                         \
-  V(SmiSubInlineCache)                                                         \
-  V(SmiEqualInlineCache)                                                       \
-  V(OneArgOptimizedCheckInlineCache)                                           \
-  V(TwoArgsOptimizedCheckInlineCache)                                          \
-  V(ZeroArgsUnoptimizedStaticCall)                                             \
-  V(OneArgUnoptimizedStaticCall)                                               \
-  V(TwoArgsUnoptimizedStaticCall)                                              \
-  V(Subtype1TestCache)                                                         \
-  V(Subtype2TestCache)                                                         \
-  V(Subtype4TestCache)                                                         \
-  V(Subtype6TestCache)                                                         \
-  V(DefaultTypeTest)                                                           \
-  V(TopTypeTypeTest)                                                           \
-  V(TypeRefTypeTest)                                                           \
-  V(UnreachableTypeTest)                                                       \
-  V(SlowTypeTest)                                                              \
-  V(LazySpecializeTypeTest)                                                    \
-  V(CallClosureNoSuchMethod)                                                   \
-  V(FrameAwaitingMaterialization)                                              \
-  V(AsynchronousGapMarker)                                                     \
-  V(NullErrorSharedWithFPURegs)                                                \
-  V(NullErrorSharedWithoutFPURegs)                                             \
-  V(StackOverflowSharedWithFPURegs)                                            \
-  V(StackOverflowSharedWithoutFPURegs)                                         \
-  V(OneArgCheckInlineCacheWithExactnessCheck)                                  \
-  V(OneArgOptimizedCheckInlineCacheWithExactnessCheck)
-
-#else
-#define VM_STUB_CODE_LIST(V)                                                   \
-  V(LazyCompile)                                                               \
-  V(OptimizeFunction)                                                          \
-  V(CallClosureNoSuchMethod)                                                   \
-  V(RunExceptionHandler)                                                       \
-  V(DeoptForRewind)                                                            \
-  V(FixCallersTarget)                                                          \
-  V(Deoptimize)                                                                \
-  V(DeoptimizeLazyFromReturn)                                                  \
-  V(DeoptimizeLazyFromThrow)                                                   \
-  V(DefaultTypeTest)                                                           \
-  V(TopTypeTypeTest)                                                           \
-  V(TypeRefTypeTest)                                                           \
-  V(UnreachableTypeTest)                                                       \
-  V(SlowTypeTest)                                                              \
-  V(LazySpecializeTypeTest)                                                    \
-  V(FrameAwaitingMaterialization)                                              \
-  V(AsynchronousGapMarker)                                                     \
-  V(InvokeDartCodeFromBytecode)                                                \
-  V(InterpretCall)
-
-#endif  // !defined(TARGET_ARCH_DBC)
-
 // Is it permitted for the stubs above to refer to Object::null(), which is
 // allocated in the VM isolate and shared across all isolates.
 // However, in cases where a simple GC-safe placeholder is needed on the stack,
@@ -152,10 +61,16 @@
   static RawCode* GetAllocationStubForClass(const Class& cls);
 
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
-  static RawCode* GetBuildMethodExtractorStub(ObjectPoolWrapper* pool);
-  static void GenerateBuildMethodExtractorStub(Assembler* assembler);
+  static RawCode* GetBuildMethodExtractorStub(ObjectPoolBuilder* pool);
 #endif
 
+  // Generate the stub and finalize the generated code into the stub
+  // code executable area.
+  static RawCode* Generate(
+      const char* name,
+      ObjectPoolBuilder* object_pool_builder,
+      void (*GenerateStub)(compiler::Assembler* assembler));
+
   static const Code& UnoptimizedStaticCallEntry(intptr_t num_args_tested);
 
   static const intptr_t kNoInstantiator = 0;
@@ -169,6 +84,17 @@
   }
   static intptr_t NumEntries() { return kNumStubEntries; }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#define GENERATE_STUB(name)                                                    \
+  static RawCode* BuildIsolateSpecific##name##Stub(ObjectPoolBuilder* opw) {   \
+    return StubCode::Generate(                                                 \
+        "_iso_stub_" #name, opw,                                               \
+        compiler::StubCodeCompiler::Generate##name##Stub);                     \
+  }
+  VM_STUB_CODE_LIST(GENERATE_STUB);
+#undef GENERATE_STUB
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
  private:
   friend class MegamorphicCacheTable;
 
@@ -180,66 +106,8 @@
   };
 
   static Code* entries_[kNumStubEntries];
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-#define STUB_CODE_GENERATE(name)                                               \
-  static void Generate##name##Stub(Assembler* assembler);
-  VM_STUB_CODE_LIST(STUB_CODE_GENERATE)
-#undef STUB_CODE_GENERATE
-
-  // Generate the stub and finalize the generated code into the stub
-  // code executable area.
-  static RawCode* Generate(const char* name,
-                           ObjectPoolWrapper* object_pool_wrapper,
-                           void (*GenerateStub)(Assembler* assembler));
-
-  static void GenerateSharedStub(Assembler* assembler,
-                                 bool save_fpu_registers,
-                                 const RuntimeEntry* target,
-                                 intptr_t self_code_stub_offset_from_thread,
-                                 bool allow_return);
-
-  static void GenerateMegamorphicMissStub(Assembler* assembler);
-  static void GenerateAllocationStubForClass(Assembler* assembler,
-                                             const Class& cls);
-  static void GenerateNArgsCheckInlineCacheStub(
-      Assembler* assembler,
-      intptr_t num_args,
-      const RuntimeEntry& handle_ic_miss,
-      Token::Kind kind,
-      bool optimized = false,
-      bool exactness_check = false);
-  static void GenerateUsageCounterIncrement(Assembler* assembler,
-                                            Register temp_reg);
-  static void GenerateOptimizedUsageCounterIncrement(Assembler* assembler);
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
 };
 
-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;
-
-// Zap value used to indicate unused return address in deopt.
-static const uword kZapReturnAddress = 0xe1e1e1e1;
-
 }  // namespace dart
 
 #endif  // RUNTIME_VM_STUB_CODE_H_
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
deleted file mode 100644
index 6709e31..0000000
--- a/runtime/vm/stub_code_arm.cc
+++ /dev/null
@@ -1,2856 +0,0 @@
-// 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.
-
-#include "vm/globals.h"
-
-#if defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/cpu.h"
-#include "vm/dart_entry.h"
-#include "vm/heap/heap.h"
-#include "vm/instructions.h"
-#include "vm/isolate.h"
-#include "vm/object_store.h"
-#include "vm/runtime_entry.h"
-#include "vm/stack_frame.h"
-#include "vm/tags.h"
-#include "vm/type_testing_stubs.h"
-
-#define __ assembler->
-
-namespace dart {
-
-DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
-DEFINE_FLAG(bool,
-            use_slow_path,
-            false,
-            "Set to true for debugging & verifying the slow paths.");
-DECLARE_FLAG(bool, precompiled_mode);
-
-// Input parameters:
-//   LR : return address.
-//   SP : address of last argument in argument array.
-//   SP + 4*R4 - 4 : address of first argument in argument array.
-//   SP + 4*R4 : address of return value.
-//   R9 : address of the runtime function to call.
-//   R4 : number of arguments to the call.
-void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ ldr(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to Dart VM C++ code.
-  __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing VM code.
-  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
-
-  // Reserve space for arguments and align frame before entering C++ world.
-  // NativeArguments are passed in registers.
-  ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
-  __ ReserveAlignedFrameSpace(0);
-
-  // Pass NativeArguments structure by value and call runtime.
-  // Registers R0, R1, R2, and R3 are used.
-
-  ASSERT(thread_offset == 0 * kWordSize);
-  // Set thread in NativeArgs.
-  __ mov(R0, Operand(THR));
-
-  // There are no runtime calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  ASSERT(argc_tag_offset == 1 * kWordSize);
-  __ mov(R1, Operand(R4));  // Set argc in NativeArguments.
-
-  ASSERT(argv_offset == 2 * kWordSize);
-  __ add(R2, FP, Operand(R4, LSL, 2));  // Compute argv.
-  // Set argv in NativeArguments.
-  __ AddImmediate(R2, kParamEndSlotFromFp * kWordSize);
-
-  ASSERT(retval_offset == 3 * kWordSize);
-  __ add(R3, R2, Operand(kWordSize));  // Retval is next to 1st argument.
-
-  // Call runtime or redirection via simulator.
-  __ blx(R9);
-
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset());
-
-  // Restore the global object pool after returning from runtime (old space is
-  // moving, so the GOP could have been relocated).
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
-  }
-
-  __ LeaveStubFrame();
-
-  // The following return can jump to a lazy-deopt stub, which assumes R0
-  // contains a return value and will save it in a GC-visible way.  We therefore
-  // have to ensure R0 does not contain any garbage value left from the C
-  // function we called (which has return type "void").
-  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
-  __ LoadImmediate(R0, 0);
-  __ Ret();
-}
-
-void StubCode::GenerateSharedStub(Assembler* assembler,
-                                  bool save_fpu_registers,
-                                  const RuntimeEntry* target,
-                                  intptr_t self_code_stub_offset_from_thread,
-                                  bool allow_return) {
-  // We want the saved registers to appear like part of the caller's frame, so
-  // we push them before calling EnterStubFrame.
-  RegisterSet all_registers;
-  all_registers.AddAllNonReservedRegisters(save_fpu_registers);
-
-  // To make the stack map calculation architecture independent we do the same
-  // as on intel.
-  __ Push(LR);
-
-  __ PushRegisters(all_registers);
-  __ ldr(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
-  __ EnterStubFrame();
-  __ CallRuntime(*target, /*argument_count=*/0);
-  if (!allow_return) {
-    __ Breakpoint();
-    return;
-  }
-  __ LeaveStubFrame();
-  __ PopRegisters(all_registers);
-  __ Pop(LR);
-  __ bx(LR);
-}
-
-// R1: The extracted method.
-// R4: The type_arguments_field_offset (or 0)
-// SP+0: The object from which we are tearing a method off.
-void StubCode::GenerateBuildMethodExtractorStub(Assembler* assembler) {
-  Thread* thread = Thread::Current();
-  Zone* Z = thread->zone();
-  ObjectStore* object_store = thread->isolate()->object_store();
-
-  const auto& closure_class =
-      Class::ZoneHandle(Z, object_store->closure_class());
-  const auto& closure_allocation_stub =
-      Code::ZoneHandle(Z, StubCode::GetAllocationStubForClass(closure_class));
-
-  const intptr_t kReceiverOffset = compiler_frame_layout.param_end_from_fp + 1;
-
-  const auto& context_allocation_stub = StubCode::AllocateContext();
-
-  __ EnterStubFrame();
-
-  // Build type_arguments vector (or null)
-  __ cmp(R4, Operand(0));
-  __ ldr(R3, Address(THR, Thread::object_null_offset()), EQ);
-  __ ldr(R0, Address(FP, kReceiverOffset * kWordSize), NE);
-  __ ldr(R3, Address(R0, R4), NE);
-
-  // Push type arguments & extracted method.
-  __ PushList(1 << R3 | 1 << R1);
-
-  // Allocate context.
-  {
-    Label done, slow_path;
-    __ TryAllocateArray(kContextCid, Context::InstanceSize(1), &slow_path,
-                        R0,  // instance
-                        R1,  // end address
-                        R2, R3);
-    __ ldr(R1, Address(THR, Thread::object_null_offset()));
-    __ str(R1, FieldAddress(R0, Context::parent_offset()));
-    __ LoadImmediate(R1, 1);
-    __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
-    __ b(&done);
-
-    __ Bind(&slow_path);
-
-    __ LoadImmediate(/*num_vars=*/R1, 1);
-    __ LoadObject(CODE_REG, context_allocation_stub);
-    __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-    __ blx(R0);
-
-    __ Bind(&done);
-  }
-
-  // Store receiver in context
-  __ ldr(R1, Address(FP, kWordSize * kReceiverOffset));
-  __ StoreIntoObject(R0, FieldAddress(R0, Context::variable_offset(0)), R1);
-
-  // Push context.
-  __ Push(R0);
-
-  // Allocate closure.
-  __ LoadObject(CODE_REG, closure_allocation_stub);
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kUnchecked)));
-  __ blx(R1);
-
-  // Populate closure object.
-  __ Pop(R1);  // Pop context.
-  __ StoreIntoObject(R0, FieldAddress(R0, Closure::context_offset()), R1);
-  __ PopList(1 << R3 | 1 << R1);  // Pop type arguments & extracted method.
-  __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, Closure::function_offset()),
-                              R1);
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, Closure::instantiator_type_arguments_offset()), R3);
-  __ LoadObject(R1, Object::empty_type_arguments());
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, Closure::delayed_type_arguments_offset()), R1);
-
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateNullErrorSharedWithoutFPURegsStub(Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/false,
-                     &kNullErrorRuntimeEntry,
-                     Thread::null_error_shared_without_fpu_regs_stub_offset(),
-                     /*allow_return=*/false);
-}
-
-void StubCode::GenerateNullErrorSharedWithFPURegsStub(Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/true,
-                     &kNullErrorRuntimeEntry,
-                     Thread::null_error_shared_with_fpu_regs_stub_offset(),
-                     /*allow_return=*/false);
-}
-
-void StubCode::GenerateStackOverflowSharedWithoutFPURegsStub(
-    Assembler* assembler) {
-  GenerateSharedStub(
-      assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
-      Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
-}
-
-void StubCode::GenerateStackOverflowSharedWithFPURegsStub(
-    Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/true,
-                     &kStackOverflowRuntimeEntry,
-                     Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
-                     /*allow_return=*/true);
-}
-
-// Input parameters:
-//   R0 : stop message (const char*).
-// Must preserve all registers.
-void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
-  __ EnterCallRuntimeFrame(0);
-  // Call the runtime leaf function. R0 already contains the parameter.
-  __ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ Ret();
-}
-
-// Input parameters:
-//   LR : return address.
-//   SP : address of return value.
-//   R9 : address of the native function to call.
-//   R2 : address of first argument in argument array.
-//   R1 : argc_tag including number of arguments and function kind.
-static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
-                                              Address wrapper) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to native code.
-  __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
-
-  // Reserve space for the native arguments structure passed on the stack (the
-  // outgoing pointer parameter to the native arguments structure is passed in
-  // R0) and align frame before entering the C++ world.
-  __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
-
-  // Initialize NativeArguments structure and call native function.
-  // Registers R0, R1, R2, and R3 are used.
-
-  ASSERT(thread_offset == 0 * kWordSize);
-  // Set thread in NativeArgs.
-  __ mov(R0, Operand(THR));
-
-  // There are no native calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  ASSERT(argc_tag_offset == 1 * kWordSize);
-  // Set argc in NativeArguments: R1 already contains argc.
-
-  ASSERT(argv_offset == 2 * kWordSize);
-  // Set argv in NativeArguments: R2 already contains argv.
-
-  ASSERT(retval_offset == 3 * kWordSize);
-  // Set retval in NativeArgs.
-  __ add(R3, FP, Operand(kCallerSpSlotFromFp * kWordSize));
-
-  // Passing the structure by value as in runtime calls would require changing
-  // Dart API for native functions.
-  // For now, space is reserved on the stack and we pass a pointer to it.
-  __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
-  __ mov(R0, Operand(SP));  // Pass the pointer to the NativeArguments.
-
-  __ mov(R1, Operand(R9));  // Pass the function entrypoint to call.
-
-  // Call native function invocation wrapper or redirection via simulator.
-  __ ldr(LR, wrapper);
-  __ blx(LR);
-
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset());
-
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateCallNoScopeNativeStub(Assembler* assembler) {
-  GenerateCallNativeWithWrapperStub(
-      assembler,
-      Address(THR, Thread::no_scope_native_wrapper_entry_point_offset()));
-}
-
-void StubCode::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
-  GenerateCallNativeWithWrapperStub(
-      assembler,
-      Address(THR, Thread::auto_scope_native_wrapper_entry_point_offset()));
-}
-
-// Input parameters:
-//   LR : return address.
-//   SP : address of return value.
-//   R9 : address of the native function to call.
-//   R2 : address of first argument in argument array.
-//   R1 : argc_tag including number of arguments and function kind.
-void StubCode::GenerateCallBootstrapNativeStub(Assembler* assembler) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to native code.
-  __ StoreToOffset(kWord, FP, THR, Thread::top_exit_frame_info_offset());
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R8, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
-
-  // Reserve space for the native arguments structure passed on the stack (the
-  // outgoing pointer parameter to the native arguments structure is passed in
-  // R0) and align frame before entering the C++ world.
-  __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
-
-  // Initialize NativeArguments structure and call native function.
-  // Registers R0, R1, R2, and R3 are used.
-
-  ASSERT(thread_offset == 0 * kWordSize);
-  // Set thread in NativeArgs.
-  __ mov(R0, Operand(THR));
-
-  // There are no native calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  ASSERT(argc_tag_offset == 1 * kWordSize);
-  // Set argc in NativeArguments: R1 already contains argc.
-
-  ASSERT(argv_offset == 2 * kWordSize);
-  // Set argv in NativeArguments: R2 already contains argv.
-
-  ASSERT(retval_offset == 3 * kWordSize);
-  // Set retval in NativeArgs.
-  __ add(R3, FP, Operand(kCallerSpSlotFromFp * kWordSize));
-
-  // Passing the structure by value as in runtime calls would require changing
-  // Dart API for native functions.
-  // For now, space is reserved on the stack and we pass a pointer to it.
-  __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3));
-  __ mov(R0, Operand(SP));  // Pass the pointer to the NativeArguments.
-
-  // Call native function or redirection via simulator.
-  __ blx(R9);
-
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset());
-
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Input parameters:
-//   R4: arguments descriptor array.
-void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value and preserve arguments descriptor.
-  __ LoadImmediate(R0, 0);
-  __ PushList((1 << R0) | (1 << R4));
-  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
-  // Get Code object result and restore arguments descriptor array.
-  __ PopList((1 << R0) | (1 << R4));
-  // Remove the stub frame.
-  __ LeaveStubFrame();
-  // Jump to the dart function.
-  __ mov(CODE_REG, Operand(R0));
-  __ Branch(FieldAddress(R0, Code::entry_point_offset()));
-}
-
-// Called from a static call only when an invalid code has been entered
-// (invalid because its function was optimized or deoptimized).
-// R4: arguments descriptor array.
-void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
-  // Load code pointer to this stub from the thread:
-  // The one that is passed in, is not correct - it points to the code object
-  // that needs to be replaced.
-  __ ldr(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset()));
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value and preserve arguments descriptor.
-  __ LoadImmediate(R0, 0);
-  __ PushList((1 << R0) | (1 << R4));
-  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
-  // Get Code object result and restore arguments descriptor array.
-  __ PopList((1 << R0) | (1 << R4));
-  // Remove the stub frame.
-  __ LeaveStubFrame();
-  // Jump to the dart function.
-  __ mov(CODE_REG, Operand(R0));
-  __ Branch(FieldAddress(R0, Code::entry_point_offset()));
-}
-
-// Called from object allocate instruction when the allocation stub has been
-// disabled.
-void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
-  // Load code pointer to this stub from the thread:
-  // The one that is passed in, is not correct - it points to the code object
-  // that needs to be replaced.
-  __ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset()));
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  __ LoadImmediate(R0, 0);
-  __ Push(R0);
-  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
-  // Get Code object result.
-  __ Pop(R0);
-  // Remove the stub frame.
-  __ LeaveStubFrame();
-  // Jump to the dart function.
-  __ mov(CODE_REG, Operand(R0));
-  __ Branch(FieldAddress(R0, Code::entry_point_offset()));
-}
-
-// Input parameters:
-//   R2: smi-tagged argument count, may be zero.
-//   FP[kParamEndSlotFromFp + 1]: last argument.
-static void PushArrayOfArguments(Assembler* assembler) {
-  // Allocate array to store arguments of caller.
-  __ LoadObject(R1, Object::null_object());
-  // R1: null element type for raw Array.
-  // R2: smi-tagged argument count, may be zero.
-  __ BranchLink(StubCode::AllocateArray());
-  // R0: newly allocated array.
-  // R2: smi-tagged argument count, may be zero (was preserved by the stub).
-  __ Push(R0);  // Array is in R0 and on top of stack.
-  __ AddImmediate(R1, FP, kParamEndSlotFromFp * kWordSize);
-  __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag);
-  // Copy arguments from stack to array (starting at the end).
-  // R1: address just beyond last argument on stack.
-  // R3: address of first argument in array.
-  Label enter;
-  __ b(&enter);
-  Label loop;
-  __ Bind(&loop);
-  __ ldr(R8, Address(R1, kWordSize, Address::PreIndex));
-  // Generational barrier is needed, array is not necessarily in new space.
-  __ StoreIntoObject(R0, Address(R3, R2, LSL, 1), R8);
-  __ Bind(&enter);
-  __ subs(R2, R2, Operand(Smi::RawValue(1)));  // R2 is Smi.
-  __ b(&loop, PL);
-}
-
-// Used by eager and lazy deoptimization. Preserve result in R0 if necessary.
-// This stub translates optimized frame into unoptimized frame. The optimized
-// frame can contain values in registers and on stack, the unoptimized
-// frame contains all values on stack.
-// Deoptimization occurs in following steps:
-// - Push all registers that can contain values.
-// - Call C routine to copy the stack and saved registers into temporary buffer.
-// - Adjust caller's frame to correct unoptimized frame size.
-// - Fill the unoptimized frame.
-// - Materialize objects that require allocation (e.g. Double instances).
-// GC can occur only after frame is fully rewritten.
-// Stack after EnterFrame(...) below:
-//   +------------------+
-//   | Saved PP         | <- TOS
-//   +------------------+
-//   | Saved FP         | <- FP of stub
-//   +------------------+
-//   | Saved LR         |  (deoptimization point)
-//   +------------------+
-//   | pc marker        |
-//   +------------------+
-//   | Saved CODE_REG   |
-//   +------------------+
-//   | ...              | <- SP of optimized frame
-//
-// Parts of the code cannot GC, part of the code can GC.
-static void GenerateDeoptimizationSequence(Assembler* assembler,
-                                           DeoptStubKind kind) {
-  // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
-  // is no need to set the correct PC marker or load PP, since they get patched.
-  __ EnterDartFrame(0);
-  __ LoadPoolPointer();
-
-  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
-  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
-  const intptr_t saved_result_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - R0);
-  const intptr_t saved_exception_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - R0);
-  const intptr_t saved_stacktrace_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - R1);
-  // Result in R0 is preserved as part of pushing all registers below.
-
-  // Push registers in their enumeration order: lowest register number at
-  // lowest address.
-  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) {
-    if (i == CODE_REG) {
-      // Save the original value of CODE_REG pushed before invoking this stub
-      // instead of the value used to call this stub.
-      __ ldr(IP, Address(FP, kCallerSpSlotFromFp * kWordSize));
-      __ Push(IP);
-    } else if (i == SP) {
-      // Push(SP) has unpredictable behavior.
-      __ mov(IP, Operand(SP));
-      __ Push(IP);
-    } else {
-      __ Push(static_cast<Register>(i));
-    }
-  }
-
-  if (TargetCPUFeatures::vfp_supported()) {
-    ASSERT(kFpuRegisterSize == 4 * kWordSize);
-    if (kNumberOfDRegisters > 16) {
-      __ vstmd(DB_W, SP, D16, kNumberOfDRegisters - 16);
-      __ vstmd(DB_W, SP, D0, 16);
-    } else {
-      __ vstmd(DB_W, SP, D0, kNumberOfDRegisters);
-    }
-  } else {
-    __ AddImmediate(SP, -kNumberOfFpuRegisters * kFpuRegisterSize);
-  }
-
-  __ mov(R0, Operand(SP));  // Pass address of saved registers block.
-  bool is_lazy =
-      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
-  __ mov(R1, Operand(is_lazy ? 1 : 0));
-  __ ReserveAlignedFrameSpace(0);
-  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
-  // Result (R0) is stack-size (FP - SP) in bytes.
-
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into R1 temporarily.
-    __ ldr(R1, Address(FP, saved_result_slot_from_fp * kWordSize));
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into R1 temporarily.
-    __ ldr(R1, Address(FP, saved_exception_slot_from_fp * kWordSize));
-    __ ldr(R2, Address(FP, saved_stacktrace_slot_from_fp * kWordSize));
-  }
-
-  __ RestoreCodePointer();
-  __ LeaveDartFrame();
-  __ sub(SP, FP, Operand(R0));
-
-  // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
-  // is no need to set the correct PC marker or load PP, since they get patched.
-  __ EnterStubFrame();
-  __ mov(R0, Operand(FP));  // Get last FP address.
-  if (kind == kLazyDeoptFromReturn) {
-    __ Push(R1);  // Preserve result as first local.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ Push(R1);  // Preserve exception as first local.
-    __ Push(R2);  // Preserve stacktrace as second local.
-  }
-  __ ReserveAlignedFrameSpace(0);
-  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);  // Pass last FP in R0.
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into R1.
-    __ ldr(R1,
-           Address(FP, compiler_frame_layout.first_local_from_fp * kWordSize));
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into R1.
-    __ ldr(R1,
-           Address(FP, compiler_frame_layout.first_local_from_fp * kWordSize));
-    __ ldr(R2, Address(FP, (compiler_frame_layout.first_local_from_fp - 1) *
-                               kWordSize));
-  }
-  // Code above cannot cause GC.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-
-  // Frame is fully rewritten at this point and it is safe to perform a GC.
-  // Materialize any objects that were deferred by FillFrame because they
-  // require allocation.
-  // Enter stub frame with loading PP. The caller's PP is not materialized yet.
-  __ EnterStubFrame();
-  if (kind == kLazyDeoptFromReturn) {
-    __ Push(R1);  // Preserve result, it will be GC-d here.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ Push(R1);  // Preserve exception, it will be GC-d here.
-    __ Push(R2);  // Preserve stacktrace, it will be GC-d here.
-  }
-  __ PushObject(Smi::ZoneHandle());  // Space for the result.
-  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
-  // Result tells stub how many bytes to remove from the expression stack
-  // of the bottom-most frame. They were used as materialization arguments.
-  __ Pop(R2);
-  if (kind == kLazyDeoptFromReturn) {
-    __ Pop(R0);  // Restore result.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ Pop(R1);  // Restore stacktrace.
-    __ Pop(R0);  // Restore exception.
-  }
-  __ LeaveStubFrame();
-  // Remove materialization arguments.
-  __ add(SP, SP, Operand(R2, ASR, kSmiTagSize));
-  // The caller is responsible for emitting the return instruction.
-}
-
-// R0: result, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG for lazy deopt.
-  __ LoadImmediate(IP, kZapCodeReg);
-  __ Push(IP);
-  // Return address for "call" to deopt stub.
-  __ LoadImmediate(LR, kZapReturnAddress);
-  __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
-  __ Ret();
-}
-
-// R0: exception, must be preserved
-// R1: stacktrace, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG for lazy deopt.
-  __ LoadImmediate(IP, kZapCodeReg);
-  __ Push(IP);
-  // Return address for "call" to deopt stub.
-  __ LoadImmediate(LR, kZapReturnAddress);
-  __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
-  __ Ret();
-}
-
-void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
-  __ Push(CODE_REG);
-  __ ldr(CODE_REG, Address(THR, Thread::deoptimize_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-  __ 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, Object::null_object());
-  __ b(call_target_function, NE);
-  __ EnterStubFrame();
-  // Load the receiver.
-  __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Result slot.
-  __ Push(R8);  // Receiver.
-  __ Push(R9);  // ICData/MegamorphicCache.
-  __ Push(R4);  // Arguments descriptor.
-
-  // Adjust arguments count.
-  __ ldr(R3, FieldAddress(R4, ArgumentsDescriptor::type_args_len_offset()));
-  __ cmp(R3, Operand(0));
-  __ AddImmediate(R2, R2, Smi::RawValue(1), NE);  // Include the type arguments.
-
-  // R2: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-  const intptr_t kNumArgs = 4;
-  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
-  __ Drop(4);
-  __ Pop(R0);  // Return value.
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R8, Address(IP, compiler_frame_layout.param_end_from_fp * kWordSize));
-
-  // 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, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-}
-
-// Called for inline allocation of arrays.
-// Input parameters:
-//   LR: return address.
-//   R1: array element type (either NULL or an instantiated type).
-//   R2: array length as Smi (must be preserved).
-// The newly allocated object is returned in R0.
-void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
-  Label slow_case;
-  // Compute the size to be allocated, it is based on the array length
-  // and is computed as:
-  // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
-  __ mov(R3, Operand(R2));  // Array length.
-  // Check that length is a positive Smi.
-  __ tst(R3, Operand(kSmiTagMask));
-  if (FLAG_use_slow_path) {
-    __ b(&slow_case);
-  } else {
-    __ b(&slow_case, NE);
-  }
-  __ cmp(R3, Operand(0));
-  __ b(&slow_case, LT);
-
-  // Check for maximum allowed length.
-  const intptr_t max_len =
-      reinterpret_cast<int32_t>(Smi::New(Array::kMaxNewSpaceElements));
-  __ CompareImmediate(R3, max_len);
-  __ b(&slow_case, GT);
-
-  const intptr_t cid = kArrayCid;
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(R4, &slow_case));
-
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawArray) + kObjectAlignment - 1;
-  __ LoadImmediate(R9, fixed_size_plus_alignment_padding);
-  __ add(R9, R9, Operand(R3, LSL, 1));  // R3 is a Smi.
-  ASSERT(kSmiTagShift == 1);
-  __ bic(R9, R9, Operand(kObjectAlignment - 1));
-
-  // R9: Allocation size.
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  // Potential new object start.
-  __ ldr(R0, Address(THR, Thread::top_offset()));
-  __ adds(NOTFP, R0, Operand(R9));  // Potential next object start.
-  __ b(&slow_case, CS);             // Branch if unsigned overflow.
-
-  // Check if the allocation fits into the remaining space.
-  // R0: potential new object start.
-  // NOTFP: potential next object start.
-  // R9: allocation size.
-  __ ldr(R3, Address(THR, Thread::end_offset()));
-  __ cmp(NOTFP, Operand(R3));
-  __ b(&slow_case, CS);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R3, cid));
-  __ str(NOTFP, Address(THR, Thread::top_offset()));
-  __ add(R0, R0, Operand(kHeapObjectTag));
-
-  // Initialize the tags.
-  // R0: new object start as a tagged pointer.
-  // R3: allocation stats address.
-  // NOTFP: new object end address.
-  // R9: allocation size.
-  {
-    const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
-
-    __ CompareImmediate(R9, RawObject::SizeTag::kMaxSizeTag);
-    __ mov(R8, Operand(R9, LSL, shift), LS);
-    __ mov(R8, Operand(0), HI);
-
-    // Get the class index and insert it into the tags.
-    // R8: size and bit tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(TMP, tags);
-    __ orr(R8, R8, Operand(TMP));
-    __ str(R8, FieldAddress(R0, Array::tags_offset()));  // Store tags.
-  }
-
-  // R0: new object start as a tagged pointer.
-  // NOTFP: new object end address.
-  // Store the type argument field.
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, Array::type_arguments_offset()), R1);
-
-  // Set the length field.
-  __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, Array::length_offset()), R2);
-
-  // Initialize all array elements to raw_null.
-  // R0: new object start as a tagged pointer.
-  // R3: allocation stats address.
-  // R8, R9: null
-  // R4: iterator which initially points to the start of the variable
-  // data area to be initialized.
-  // NOTFP: new object end address.
-  // R9: allocation size.
-  NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R3, R9, space));
-
-  __ LoadObject(R8, Object::null_object());
-  __ mov(R9, Operand(R8));
-  __ AddImmediate(R4, R0, sizeof(RawArray) - kHeapObjectTag);
-  __ InitializeFieldsNoBarrier(R0, R4, NOTFP, R8, R9);
-  __ Ret();  // Returns the newly allocated object in R0.
-  // Unable to allocate the array using the fast inline code, just call
-  // into the runtime.
-  __ Bind(&slow_case);
-
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ LoadImmediate(IP, 0);
-  // Setup space on stack for return value.
-  // Push array length as Smi and element type.
-  __ PushList((1 << R1) | (1 << R2) | (1 << IP));
-  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
-  // Pop arguments; result is popped in IP.
-  __ PopList((1 << R1) | (1 << R2) | (1 << IP));  // R2 is restored.
-  __ mov(R0, Operand(IP));
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Called when invoking Dart code from C++ (VM code).
-// Input parameters:
-//   LR : points to return address.
-//   R0 : code object of the Dart function to call.
-//   R1 : arguments descriptor array.
-//   R2 : arguments array.
-//   R3 : current thread.
-void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
-  __ Push(LR);  // Marker for the profiler.
-  __ EnterFrame((1 << FP) | (1 << LR), 0);
-
-  // Push code object to PC marker slot.
-  __ ldr(IP, Address(R3, Thread::invoke_dart_code_stub_offset()));
-  __ Push(IP);
-
-  // Save new context and C++ ABI callee-saved registers.
-  __ PushList(kAbiPreservedCpuRegs);
-
-  const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
-  if (TargetCPUFeatures::vfp_supported()) {
-    ASSERT(2 * kAbiPreservedFpuRegCount < 16);
-    // Save FPU registers. 2 D registers per Q register.
-    __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
-  } else {
-    __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize));
-  }
-
-  // Set up THR, which caches the current thread in Dart code.
-  if (THR != R3) {
-    __ mov(THR, Operand(R3));
-  }
-
-  // Save the current VMTag on the stack.
-  __ LoadFromOffset(kWord, R9, THR, Thread::vm_tag_offset());
-  __ Push(R9);
-
-  // Save top resource and top exit frame info. Use R4-6 as temporary registers.
-  // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
-  __ LoadFromOffset(kWord, R4, THR, Thread::top_resource_offset());
-  __ LoadImmediate(R8, 0);
-  __ StoreToOffset(kWord, R8, THR, Thread::top_resource_offset());
-  __ StoreToOffset(kWord, R8, THR, Thread::top_exit_frame_info_offset());
-
-  // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  __ Push(R4);
-#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-  ASSERT(kExitLinkSlotFromEntryFp == -26);
-#else
-  ASSERT(kExitLinkSlotFromEntryFp == -27);
-#endif
-  __ Push(R9);
-
-  // Mark that the thread is executing Dart code. Do this after initializing the
-  // exit link for the profiler.
-  __ LoadImmediate(R9, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(kWord, R9, THR, Thread::vm_tag_offset());
-
-  // Load arguments descriptor array into R4, which is passed to Dart code.
-  __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
-
-  // Load number of arguments into R9 and adjust count for type arguments.
-  __ ldr(R3, FieldAddress(R4, ArgumentsDescriptor::type_args_len_offset()));
-  __ ldr(R9, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ cmp(R3, Operand(0));
-  __ AddImmediate(R9, R9, Smi::RawValue(1), NE);  // Include the type arguments.
-  __ SmiUntag(R9);
-
-  // Compute address of 'arguments array' data area into R2.
-  __ ldr(R2, Address(R2, VMHandles::kOffsetOfRawPtrInHandle));
-  __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag);
-
-  // Set up arguments for the Dart call.
-  Label push_arguments;
-  Label done_push_arguments;
-  __ CompareImmediate(R9, 0);  // check if there are arguments.
-  __ b(&done_push_arguments, EQ);
-  __ LoadImmediate(R1, 0);
-  __ Bind(&push_arguments);
-  __ ldr(R3, Address(R2));
-  __ Push(R3);
-  __ AddImmediate(R2, kWordSize);
-  __ AddImmediate(R1, 1);
-  __ cmp(R1, Operand(R9));
-  __ b(&push_arguments, LT);
-  __ Bind(&done_push_arguments);
-
-  // Call the Dart code entrypoint.
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
-  } else {
-    __ LoadImmediate(PP, 0);  // GC safe value into PP.
-  }
-  __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
-  __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ blx(R0);  // R4 is the arguments descriptor array.
-
-  // Get rid of arguments pushed on the stack.
-  __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
-
-  // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure. Uses R9 as a temporary register for this.
-  __ Pop(R9);
-  __ StoreToOffset(kWord, R9, THR, Thread::top_exit_frame_info_offset());
-  __ Pop(R9);
-  __ StoreToOffset(kWord, R9, THR, Thread::top_resource_offset());
-
-  // Restore the current VMTag from the stack.
-  __ Pop(R4);
-  __ StoreToOffset(kWord, R4, THR, Thread::vm_tag_offset());
-
-  // Restore C++ ABI callee-saved registers.
-  if (TargetCPUFeatures::vfp_supported()) {
-    // Restore FPU registers. 2 D registers per Q register.
-    __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount);
-  } else {
-    __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize);
-  }
-  // Restore CPU registers.
-  __ PopList(kAbiPreservedCpuRegs);
-  __ set_constant_pool_allowed(false);
-
-  // Restore the frame pointer and return.
-  __ LeaveFrame((1 << FP) | (1 << LR));
-  __ Drop(1);
-  __ Ret();
-}
-
-void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-  __ Unimplemented("Interpreter not yet supported");
-}
-
-// Called for inline allocation of contexts.
-// Input:
-//   R1: number of context variables.
-// Output:
-//   R0: new allocated RawContext object.
-void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
-  if (FLAG_inline_alloc) {
-    Label slow_case;
-    // First compute the rounded instance size.
-    // R1: number of context variables.
-    intptr_t fixed_size_plus_alignment_padding =
-        sizeof(RawContext) + kObjectAlignment - 1;
-    __ LoadImmediate(R2, fixed_size_plus_alignment_padding);
-    __ add(R2, R2, Operand(R1, LSL, 2));
-    ASSERT(kSmiTagShift == 1);
-    __ bic(R2, R2, Operand(kObjectAlignment - 1));
-
-    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R8, kContextCid));
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(R8, &slow_case));
-    // Now allocate the object.
-    // R1: number of context variables.
-    // R2: object size.
-    const intptr_t cid = kContextCid;
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ ldr(R0, Address(THR, Thread::top_offset()));
-    __ add(R3, R2, Operand(R0));
-    // Check if the allocation fits into the remaining space.
-    // R0: potential new object.
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: potential next object start.
-    __ ldr(IP, Address(THR, Thread::end_offset()));
-    __ cmp(R3, Operand(IP));
-    if (FLAG_use_slow_path) {
-      __ b(&slow_case);
-    } else {
-      __ b(&slow_case, CS);  // Branch if unsigned higher or equal.
-    }
-
-    // Successfully allocated the object, now update top to point to
-    // next object start and initialize the object.
-    // R0: new object start (untagged).
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: next object start.
-    NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
-    __ str(R3, Address(THR, Thread::top_offset()));
-    __ add(R0, R0, Operand(kHeapObjectTag));
-
-    // Calculate the size tag.
-    // R0: new object (tagged).
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: next object start.
-    // R4: allocation stats address.
-    const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
-    __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
-    // 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);
-
-    // Get the class index and insert it into the tags.
-    // R9: size and bit tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(IP, tags);
-    __ orr(R9, R9, Operand(IP));
-    __ str(R9, FieldAddress(R0, Context::tags_offset()));
-
-    // Setup up number of context variables field.
-    // R0: new object.
-    // R1: number of context variables as integer value (not object).
-    // R2: object size.
-    // R3: next object start.
-    // R4: allocation stats address.
-    __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
-
-    // Setup the parent field.
-    // R0: new object.
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: next object start.
-    // R4: allocation stats address.
-    __ LoadObject(R8, Object::null_object());
-    __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, Context::parent_offset()),
-                                R8);
-
-    // Initialize the context variables.
-    // R0: new object.
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: next object start.
-    // R8, R9: raw null.
-    // R4: allocation stats address.
-    Label loop;
-    __ AddImmediate(NOTFP, R0, Context::variable_offset(0) - kHeapObjectTag);
-    __ InitializeFieldsNoBarrier(R0, NOTFP, R3, R8, R9);
-    NOT_IN_PRODUCT(__ IncrementAllocationStatsWithSize(R4, R2, space));
-
-    // Done allocating and initializing the context.
-    // R0: new object.
-    __ Ret();
-
-    __ Bind(&slow_case);
-  }
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  __ LoadImmediate(R2, 0);
-  __ SmiTag(R1);
-  __ PushList((1 << R1) | (1 << R2));
-  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
-  __ Drop(1);  // Pop number of context variables argument.
-  __ Pop(R0);  // Pop the new context object.
-  // R0: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
-  RegList saved = (1 << LR) | (1 << kWriteBarrierObjectReg);
-  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
-    if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
-
-    Register reg = static_cast<Register>(i);
-    intptr_t start = __ CodeSize();
-    __ PushList(saved);
-    __ mov(kWriteBarrierObjectReg, Operand(reg));
-    __ ldr(LR, Address(THR, Thread::write_barrier_entry_point_offset()));
-    __ blx(LR);
-    __ PopList(saved);
-    __ bx(LR);
-    intptr_t end = __ CodeSize();
-
-    RELEASE_ASSERT(end - start == kStoreBufferWrapperSize);
-  }
-}
-
-// Helper stub to implement Assembler::StoreIntoObject.
-// Input parameters:
-//   R1: Object (old)
-//   R0: Value (old or new)
-//   R9: Slot
-// If R0 is new, add R1 to the store buffer. Otherwise R0 is old, mark R0
-// and add it to the mark list.
-COMPILE_ASSERT(kWriteBarrierObjectReg == R1);
-COMPILE_ASSERT(kWriteBarrierValueReg == R0);
-COMPILE_ASSERT(kWriteBarrierSlotReg == R9);
-static void GenerateWriteBarrierStubHelper(Assembler* assembler,
-                                           Address stub_code,
-                                           bool cards) {
-  Label add_to_mark_stack, remember_card;
-  __ tst(R0, Operand(1 << kNewObjectBitPosition));
-  __ b(&add_to_mark_stack, ZERO);
-
-  if (cards) {
-    __ ldr(TMP, FieldAddress(R1, Object::tags_offset()));
-    __ tst(TMP, Operand(1 << RawObject::kCardRememberedBit));
-    __ b(&remember_card, NOT_ZERO);
-  } else {
-#if defined(DEBUG)
-    Label ok;
-    __ ldr(TMP, FieldAddress(R1, Object::tags_offset()));
-    __ tst(TMP, Operand(1 << RawObject::kCardRememberedBit));
-    __ b(&ok, ZERO);
-    __ Stop("Wrong barrier");
-    __ Bind(&ok);
-#endif
-  }
-
-  // Save values being destroyed.
-  __ PushList((1 << R2) | (1 << R3) | (1 << R4));
-
-  if (TargetCPUFeatures::arm_version() == ARMv5TE) {
-// TODO(21263): Implement 'swp' and use it below.
-#if !defined(USING_SIMULATOR)
-    ASSERT(OS::NumberOfAvailableProcessors() <= 1);
-#endif
-    __ ldr(R2, FieldAddress(R1, Object::tags_offset()));
-    __ bic(R2, R2, Operand(1 << RawObject::kOldAndNotRememberedBit));
-    __ str(R2, FieldAddress(R1, Object::tags_offset()));
-  } else {
-    // Atomically set the remembered bit of the object header.
-    ASSERT(Object::tags_offset() == 0);
-    __ sub(R3, R1, Operand(kHeapObjectTag));
-    // R3: Untagged address of header word (ldrex/strex do not support offsets).
-    Label retry;
-    __ Bind(&retry);
-    __ ldrex(R2, R3);
-    __ bic(R2, R2, Operand(1 << RawObject::kOldAndNotRememberedBit));
-    __ strex(R4, R2, R3);
-    __ cmp(R4, Operand(1));
-    __ b(&retry, EQ);
-  }
-
-  // Load the StoreBuffer block out of the thread. Then load top_ out of the
-  // StoreBufferBlock and add the address to the pointers_.
-  __ ldr(R4, Address(THR, Thread::store_buffer_block_offset()));
-  __ ldr(R2, Address(R4, StoreBufferBlock::top_offset()));
-  __ add(R3, R4, Operand(R2, LSL, kWordSizeLog2));
-  __ str(R1, Address(R3, StoreBufferBlock::pointers_offset()));
-
-  // Increment top_ and check for overflow.
-  // R2: top_.
-  // R4: StoreBufferBlock.
-  Label overflow;
-  __ add(R2, R2, Operand(1));
-  __ str(R2, Address(R4, StoreBufferBlock::top_offset()));
-  __ CompareImmediate(R2, StoreBufferBlock::kSize);
-  // Restore values.
-  __ PopList((1 << R2) | (1 << R3) | (1 << R4));
-  __ b(&overflow, EQ);
-  __ Ret();
-
-  // Handle overflow: Call the runtime leaf function.
-  __ Bind(&overflow);
-  // Setup frame, push callee-saved registers.
-
-  __ Push(CODE_REG);
-  __ ldr(CODE_REG, stub_code);
-  __ EnterCallRuntimeFrame(0 * kWordSize);
-  __ mov(R0, Operand(THR));
-  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
-  // Restore callee-saved registers, tear down frame.
-  __ LeaveCallRuntimeFrame();
-  __ Pop(CODE_REG);
-  __ Ret();
-
-  __ Bind(&add_to_mark_stack);
-  __ PushList((1 << R2) | (1 << R3) | (1 << R4));  // Spill.
-
-  Label marking_retry, lost_race, marking_overflow;
-  if (TargetCPUFeatures::arm_version() == ARMv5TE) {
-// TODO(21263): Implement 'swp' and use it below.
-#if !defined(USING_SIMULATOR)
-    ASSERT(OS::NumberOfAvailableProcessors() <= 1);
-#endif
-    __ ldr(R2, FieldAddress(R0, Object::tags_offset()));
-    __ bic(R2, R2, Operand(1 << RawObject::kOldAndNotMarkedBit));
-    __ str(R2, FieldAddress(R0, Object::tags_offset()));
-  } else {
-    // Atomically clear kOldAndNotMarkedBit.
-    ASSERT(Object::tags_offset() == 0);
-    __ sub(R3, R0, Operand(kHeapObjectTag));
-    // R3: Untagged address of header word (ldrex/strex do not support offsets).
-    __ Bind(&marking_retry);
-    __ ldrex(R2, R3);
-    __ tst(R2, Operand(1 << RawObject::kOldAndNotMarkedBit));
-    __ b(&lost_race, ZERO);
-    __ bic(R2, R2, Operand(1 << RawObject::kOldAndNotMarkedBit));
-    __ strex(R4, R2, R3);
-    __ cmp(R4, Operand(1));
-    __ b(&marking_retry, EQ);
-  }
-
-  __ ldr(R4, Address(THR, Thread::marking_stack_block_offset()));
-  __ ldr(R2, Address(R4, MarkingStackBlock::top_offset()));
-  __ add(R3, R4, Operand(R2, LSL, kWordSizeLog2));
-  __ str(R0, Address(R3, MarkingStackBlock::pointers_offset()));
-  __ add(R2, R2, Operand(1));
-  __ str(R2, Address(R4, MarkingStackBlock::top_offset()));
-  __ CompareImmediate(R2, MarkingStackBlock::kSize);
-  __ PopList((1 << R4) | (1 << R2) | (1 << R3));  // Unspill.
-  __ b(&marking_overflow, EQ);
-  __ Ret();
-
-  __ Bind(&marking_overflow);
-  __ Push(CODE_REG);
-  __ ldr(CODE_REG, stub_code);
-  __ EnterCallRuntimeFrame(0 * kWordSize);
-  __ mov(R0, Operand(THR));
-  __ CallRuntime(kMarkingStackBlockProcessRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ Pop(CODE_REG);
-  __ Ret();
-
-  __ Bind(&lost_race);
-  __ PopList((1 << R2) | (1 << R3) | (1 << R4));  // Unspill.
-  __ Ret();
-
-  if (cards) {
-    Label remember_card_slow;
-
-    // Get card table.
-    __ Bind(&remember_card);
-    __ AndImmediate(TMP, R1, kPageMask);                       // HeapPage.
-    __ ldr(TMP, Address(TMP, HeapPage::card_table_offset()));  // Card table.
-    __ cmp(TMP, Operand(0));
-    __ b(&remember_card_slow, EQ);
-
-    // Dirty the card.
-    __ AndImmediate(TMP, R1, kPageMask);  // HeapPage.
-    __ sub(R9, R9, Operand(TMP));         // Offset in page.
-    __ ldr(TMP, Address(TMP, HeapPage::card_table_offset()));  // Card table.
-    __ add(TMP, TMP,
-           Operand(R9, LSR, HeapPage::kBytesPerCardLog2));  // Card address.
-    __ strb(R1,
-            Address(TMP, 0));  // Low byte of R0 is non-zero from object tag.
-    __ Ret();
-
-    // Card table not yet allocated.
-    __ Bind(&remember_card_slow);
-    __ Push(CODE_REG);
-    __ Push(R0);
-    __ Push(R1);
-    __ ldr(CODE_REG, stub_code);
-    __ mov(R0, Operand(R1));  // Arg0 = Object
-    __ mov(R1, Operand(R9));  // Arg1 = Slot
-    __ EnterCallRuntimeFrame(0);
-    __ CallRuntime(kRememberCardRuntimeEntry, 2);
-    __ LeaveCallRuntimeFrame();
-    __ Pop(R1);
-    __ Pop(R0);
-    __ Pop(CODE_REG);
-    __ Ret();
-  }
-}
-
-void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::write_barrier_code_offset()), false);
-}
-
-void StubCode::GenerateArrayWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::array_write_barrier_code_offset()), true);
-}
-
-// Called for inline allocation of objects.
-// Input parameters:
-//   LR : return address.
-//   SP + 0 : type arguments object (only if class is parameterized).
-void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
-                                              const Class& cls) {
-  // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
-  ASSERT(!is_cls_parameterized ||
-         (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
-
-  const Register kNullReg = R8;
-  const Register kOtherNullReg = R9;
-  const Register kTypeArgumentsReg = R3;
-  const Register kInstanceReg = R0;
-  const Register kEndReg = R1;
-  const Register kEndOfInstanceReg = R2;
-
-  // 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 = cls.instance_size();
-  ASSERT(instance_size > 0);
-  ASSERT(instance_size % kObjectAlignment == 0);
-  if (is_cls_parameterized) {
-    __ ldr(kTypeArgumentsReg, Address(SP, 0));
-  }
-  Isolate* isolate = Isolate::Current();
-
-  __ LoadObject(kNullReg, Object::null_object());
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
-      !cls.TraceAllocation(isolate)) {
-    Label slow_case;
-
-    // Allocate the object and update top to point to
-    // next object start and initialize the allocated object.
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-
-    RELEASE_ASSERT((Thread::top_offset() + kWordSize) == Thread::end_offset());
-    __ ldrd(kInstanceReg, kEndReg, THR, Thread::top_offset());
-    __ AddImmediate(kEndOfInstanceReg, kInstanceReg, instance_size);
-    __ cmp(kEndOfInstanceReg, Operand(kEndReg));
-    if (FLAG_use_slow_path) {
-      __ b(&slow_case);
-    } else {
-      __ b(&slow_case, CS);  // Unsigned higher or equal.
-    }
-    __ str(kEndOfInstanceReg, Address(THR, Thread::top_offset()));
-
-    // Load the address of the allocation stats table. We split up the load
-    // and the increment so that the dependent load is not too nearby.
-    NOT_IN_PRODUCT(static Register kAllocationStatsReg = R4);
-    NOT_IN_PRODUCT(
-        __ LoadAllocationStatsAddress(kAllocationStatsReg, cls.id()));
-
-    // Set the tags.
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(R1, tags);
-    __ str(R1, Address(kInstanceReg, Instance::tags_offset()));
-    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
-
-    // First try inlining the initialization without a loop.
-    if (instance_size < (kInlineInstanceSize * kWordSize)) {
-      intptr_t begin_offset = Instance::NextFieldOffset() - kHeapObjectTag;
-      intptr_t end_offset = instance_size - kHeapObjectTag;
-      if ((end_offset - begin_offset) >= (2 * kWordSize)) {
-        __ mov(kOtherNullReg, Operand(kNullReg));
-      }
-      __ InitializeFieldsNoBarrierUnrolled(kInstanceReg, kInstanceReg,
-                                           begin_offset, end_offset, kNullReg,
-                                           kOtherNullReg);
-    } else {
-      __ add(R1, kInstanceReg,
-             Operand(Instance::NextFieldOffset() - kHeapObjectTag));
-      __ mov(kOtherNullReg, Operand(kNullReg));
-      __ InitializeFieldsNoBarrier(kInstanceReg, R1, kEndOfInstanceReg,
-                                   kNullReg, kOtherNullReg);
-    }
-    if (is_cls_parameterized) {
-      __ StoreIntoObjectNoBarrier(
-          kInstanceReg,
-          FieldAddress(kInstanceReg, cls.type_arguments_field_offset()),
-          kTypeArgumentsReg);
-    }
-
-    // Update allocation stats.
-    NOT_IN_PRODUCT(
-        __ IncrementAllocationStats(kAllocationStatsReg, cls.id(), space));
-
-    __ Ret();
-    __ Bind(&slow_case);
-  }
-  // 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, 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 * kWordSize));  // Pop result (newly allocated object).
-  __ LeaveDartFrameAndReturn();        // Restores correct SP.
-}
-
-// 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.
-// Input parameters:
-//  LR : return address.
-//  SP : address of last argument.
-//  R4: arguments descriptor array.
-void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) {
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ add(IP, FP, Operand(R2, LSL, 1));  // R2 is Smi.
-  __ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
-
-  // Push space for the return value.
-  // Push the receiver.
-  // Push arguments descriptor array.
-  __ LoadImmediate(IP, 0);
-  __ PushList((1 << R4) | (1 << R8) | (1 << IP));
-
-  // Adjust arguments count.
-  __ ldr(R3, FieldAddress(R4, ArgumentsDescriptor::type_args_len_offset()));
-  __ cmp(R3, Operand(0));
-  __ AddImmediate(R2, R2, Smi::RawValue(1), NE);  // Include the type arguments.
-
-  // R2: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-
-  const intptr_t kNumArgs = 3;
-  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
-  // noSuchMethod on closures always throws an error, so it will never return.
-  __ bkpt(0);
-}
-
-//  R8: function object.
-//  R9: inline cache data object.
-// Cannot use function object from ICData as it may be the inlined
-// function and not the top-scope function.
-void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register ic_reg = R9;
-  Register func_reg = R8;
-  if (FLAG_trace_optimized_ic_calls) {
-    __ EnterStubFrame();
-    __ PushList((1 << R9) | (1 << R8));  // Preserve.
-    __ Push(ic_reg);                     // Argument.
-    __ Push(func_reg);                   // Argument.
-    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
-    __ Drop(2);                         // Discard argument;
-    __ PopList((1 << R9) | (1 << R8));  // Restore.
-    __ LeaveStubFrame();
-  }
-  __ ldr(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
-  __ add(NOTFP, NOTFP, Operand(1));
-  __ str(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
-}
-
-// Loads function into 'temp_reg'.
-void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
-                                             Register temp_reg) {
-  if (FLAG_optimization_counter_threshold >= 0) {
-    Register ic_reg = R9;
-    Register func_reg = temp_reg;
-    ASSERT(temp_reg == R8);
-    __ Comment("Increment function counter");
-    __ ldr(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
-    __ ldr(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
-    __ add(NOTFP, NOTFP, Operand(1));
-    __ str(NOTFP, FieldAddress(func_reg, Function::usage_counter_offset()));
-  }
-}
-
-// Note: R9 must be preserved.
-// Attempt a quick Smi operation for known operations ('kind'). The ICData
-// must have been primed with a Smi/Smi check that will be used for counting
-// the invocations.
-static void EmitFastSmiOp(Assembler* assembler,
-                          Token::Kind kind,
-                          intptr_t num_args,
-                          Label* not_smi_or_overflow) {
-  __ Comment("Fast Smi op");
-  __ ldr(R0, Address(SP, 0 * kWordSize));
-  __ ldr(R1, Address(SP, 1 * kWordSize));
-  __ orr(TMP, R0, Operand(R1));
-  __ tst(TMP, Operand(kSmiTagMask));
-  __ b(not_smi_or_overflow, NE);
-  switch (kind) {
-    case Token::kADD: {
-      __ adds(R0, R1, Operand(R0));   // Adds.
-      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
-      break;
-    }
-    case Token::kSUB: {
-      __ subs(R0, R1, Operand(R0));   // Subtract.
-      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
-      break;
-    }
-    case Token::kEQ: {
-      __ cmp(R0, Operand(R1));
-      __ LoadObject(R0, Bool::True(), EQ);
-      __ LoadObject(R0, Bool::False(), NE);
-      break;
-    }
-    default:
-      UNIMPLEMENTED();
-  }
-  // R9: IC data object (preserved).
-  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
-  // R8: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
-// R8: points directly to the first ic data array element.
-#if defined(DEBUG)
-  // Check that first entry is for Smi/Smi.
-  Label error, ok;
-  const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid));
-  __ ldr(R1, Address(R8, 0));
-  __ CompareImmediate(R1, imm_smi_cid);
-  __ b(&error, NE);
-  __ ldr(R1, Address(R8, kWordSize));
-  __ CompareImmediate(R1, imm_smi_cid);
-  __ b(&ok, EQ);
-  __ Bind(&error);
-  __ Stop("Incorrect IC data");
-  __ Bind(&ok);
-#endif
-  if (FLAG_optimization_counter_threshold >= 0) {
-    // Update counter, ignore overflow.
-    const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-    __ LoadFromOffset(kWord, R1, R8, count_offset);
-    __ adds(R1, R1, Operand(Smi::RawValue(1)));
-    __ StoreIntoSmiField(Address(R8, count_offset), R1);
-  }
-  __ Ret();
-}
-
-// Generate inline cache check for 'num_args'.
-//  LR: return address.
-//  R9: inline cache data object.
-// Control flow:
-// - If receiver is null -> jump to IC miss.
-// - If receiver is Smi -> load Smi class.
-// - If receiver is not-Smi -> load receiver's class.
-// - Check if 'num_args' (including receiver) match any IC data group.
-// - Match found -> jump to target.
-// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(
-    Assembler* assembler,
-    intptr_t num_args,
-    const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind,
-    bool optimized,
-    bool exactness_check /* = false */) {
-  ASSERT(!exactness_check);
-  __ CheckCodePointer();
-  ASSERT(num_args == 1 || num_args == 2);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == num_args.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ ldr(R8, FieldAddress(R9, ICData::state_bits_offset()));
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ and_(R8, R8, Operand(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R8, num_args);
-    __ b(&ok, EQ);
-    __ Stop("Incorrect stub for IC data");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  Label stepping, done_stepping;
-  if (!optimized) {
-    __ Comment("Check single stepping");
-    __ LoadIsolate(R8);
-    __ ldrb(R8, Address(R8, Isolate::single_step_offset()));
-    __ CompareImmediate(R8, 0);
-    __ b(&stepping, NE);
-    __ Bind(&done_stepping);
-  }
-#endif
-
-  Label not_smi_or_overflow;
-  if (kind != Token::kILLEGAL) {
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-  }
-  __ Bind(&not_smi_or_overflow);
-
-  __ Comment("Extract ICData initial values and receiver cid");
-  // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
-  // Loop that checks if there is an IC data match.
-  Label loop, found, miss;
-  // R9: IC data object (preserved).
-  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
-  // R8: ic_data_array with check entries: classes and target functions.
-  const int kIcDataOffset = Array::data_offset() - kHeapObjectTag;
-  // R8: points at the IC data array.
-
-  // Get the receiver's class ID (first read number of arguments from
-  // arguments descriptor array and then access the receiver from the stack).
-  __ ldr(NOTFP, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
-  __ sub(NOTFP, NOTFP, Operand(Smi::RawValue(1)));
-  // NOTFP: argument_count - 1 (smi).
-
-  __ Comment("ICData loop");
-
-  __ ldr(R0, Address(SP, NOTFP, LSL, 1));  // NOTFP (argument_count - 1) is Smi.
-  __ LoadTaggedClassIdMayBeSmi(R0, R0);
-  if (num_args == 2) {
-    __ sub(R1, NOTFP, Operand(Smi::RawValue(1)));
-    __ ldr(R1, Address(SP, R1, LSL, 1));  // R1 (argument_count - 2) is Smi.
-    __ LoadTaggedClassIdMayBeSmi(R1, R1);
-  }
-
-  // We unroll the generic one that is generated once more than the others.
-  const bool optimize = kind == Token::kILLEGAL;
-
-  __ Bind(&loop);
-  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
-    Label update;
-
-    __ ldr(R2, Address(R8, kIcDataOffset));
-    __ cmp(R0, Operand(R2));  // Class id match?
-    if (num_args == 2) {
-      __ b(&update, NE);  // Continue.
-      __ ldr(R2, Address(R8, kIcDataOffset + kWordSize));
-      __ cmp(R1, Operand(R2));  // Class id match?
-    }
-    __ b(&found, EQ);  // Break.
-
-    __ Bind(&update);
-
-    const intptr_t entry_size =
-        ICData::TestEntryLengthFor(num_args, exactness_check) * kWordSize;
-    __ AddImmediate(R8, entry_size);  // Next entry.
-
-    __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));  // Done?
-    if (unroll == 0) {
-      __ b(&loop, NE);
-    } else {
-      __ b(&miss, EQ);
-    }
-  }
-
-  __ Bind(&miss);
-  __ Comment("IC miss");
-  // Compute address of arguments.
-  // NOTFP: argument_count - 1 (smi).
-  __ add(NOTFP, SP, Operand(NOTFP, LSL, 1));  // NOTFP is Smi.
-  // NOTFP: address of receiver.
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ LoadImmediate(R0, 0);
-  // Preserve IC data object and arguments descriptor array and
-  // setup space on stack for result (target code object).
-  __ PushList((1 << R0) | (1 << R4) | (1 << R9));
-  // Push call arguments.
-  for (intptr_t i = 0; i < num_args; i++) {
-    __ LoadFromOffset(kWord, IP, NOTFP, -i * kWordSize);
-    __ Push(IP);
-  }
-  // Pass IC data object.
-  __ Push(R9);
-  __ CallRuntime(handle_ic_miss, num_args + 1);
-  // Remove the call arguments pushed earlier, including the IC data object.
-  __ Drop(num_args + 1);
-  // Pop returned function object into R0.
-  // Restore arguments descriptor array and IC data array.
-  __ PopList((1 << R0) | (1 << R4) | (1 << R9));
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  Label call_target_function;
-  if (!FLAG_lazy_dispatchers) {
-    GenerateDispatcherCode(assembler, &call_target_function);
-  } else {
-    __ b(&call_target_function);
-  }
-
-  __ Bind(&found);
-  // R8: pointer to an IC data check group.
-  const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-  __ LoadFromOffset(kWord, R0, R8, kIcDataOffset + target_offset);
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    __ Comment("Update caller's counter");
-    __ LoadFromOffset(kWord, R1, R8, kIcDataOffset + count_offset);
-    // Ignore overflow.
-    __ adds(R1, R1, Operand(Smi::RawValue(1)));
-    __ StoreIntoSmiField(Address(R8, kIcDataOffset + count_offset), R1);
-  }
-
-  __ Comment("Call target");
-  __ Bind(&call_target_function);
-  // R0: target function.
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-
-#if !defined(PRODUCT)
-  if (!optimized) {
-    __ Bind(&stepping);
-    __ EnterStubFrame();
-    __ Push(R9);  // Preserve IC data.
-    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ Pop(R9);
-    __ RestoreCodePointer();
-    __ LeaveStubFrame();
-    __ b(&done_stepping);
-  }
-#endif
-}
-
-// Use inline cache data array to invoke the target or continue in inline
-// cache miss handler. Stub for 1-argument check (receiver class).
-//  LR: return address.
-//  R9: inline cache data object.
-// Inline cache data object structure:
-// 0: function-name
-// 1: N, number of arguments checked.
-// 2 .. (length - 1): group of checks, each check containing:
-//   - N classes.
-//   - 1 target function.
-void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  __ Stop("Unimplemented");
-}
-
-void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL);
-}
-
-void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
-}
-
-void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
-}
-
-void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
-}
-
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
-                                    Token::kILLEGAL, true /* optimized */);
-}
-
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  __ Stop("Unimplemented");
-}
-
-void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL, true /* optimized */);
-}
-
-// Intermediary stub between a static call and its target. ICData contains
-// the target function and the call count.
-// R9: ICData
-void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == 0.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ ldr(R8, FieldAddress(R9, ICData::state_bits_offset()));
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ and_(R8, R8, Operand(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R8, 0);
-    __ b(&ok, EQ);
-    __ Stop("Incorrect IC data for unoptimized static call");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(R8);
-  __ ldrb(R8, Address(R8, Isolate::single_step_offset()));
-  __ CompareImmediate(R8, 0);
-  __ b(&stepping, NE);
-  __ Bind(&done_stepping);
-#endif
-
-  // R9: IC data object (preserved).
-  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
-  // R8: ic_data_array with entries: target functions and count.
-  __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
-  // R8: points directly to the first ic data array element.
-  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    // Increment count for this call, ignore overflow.
-    __ LoadFromOffset(kWord, R1, R8, count_offset);
-    __ adds(R1, R1, Operand(Smi::RawValue(1)));
-    __ StoreIntoSmiField(Address(R8, count_offset), R1);
-  }
-
-  // Load arguments descriptor into R4.
-  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
-
-  // Get function and call it, if possible.
-  __ LoadFromOffset(kWord, R0, R8, target_offset);
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ Push(R9);  // Preserve IC data.
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ Pop(R9);
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ b(&done_stepping);
-#endif
-}
-
-void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R8);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
-}
-
-// Stub for compiling a function and jumping to the compiled code.
-// R4: Arguments descriptor.
-// R0: Function.
-void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ PushList((1 << R0) | (1 << R4));  // Preserve arg desc, pass function.
-  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
-  __ PopList((1 << R0) | (1 << R4));
-  __ LeaveStubFrame();
-
-  // When using the interpreter, the function's code may now point to the
-  // InterpretCall stub. Make sure R0, R4, and R9 are preserved.
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-}
-
-void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-  __ Unimplemented("Interpreter not yet supported");
-}
-
-// R9: Contains an ICData.
-void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ LoadImmediate(R0, 0);
-  // Preserve arguments descriptor and make room for result.
-  __ PushList((1 << R0) | (1 << R9));
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ PopList((1 << R0) | (1 << R9));
-  __ LeaveStubFrame();
-  __ mov(CODE_REG, Operand(R0));
-  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ LoadImmediate(R0, 0);
-  // Make room for result.
-  __ PushList((1 << R0));
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ PopList((1 << CODE_REG));
-  __ LeaveStubFrame();
-  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-// Called only from unoptimized code. All relevant registers have been saved.
-void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) {
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(R1);
-  __ ldrb(R1, Address(R1, Isolate::single_step_offset()));
-  __ CompareImmediate(R1, 0);
-  __ b(&stepping, NE);
-  __ Bind(&done_stepping);
-  __ Ret();
-
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ LeaveStubFrame();
-  __ b(&done_stepping);
-}
-
-// Used to check class and type arguments. Arguments passed in registers:
-// LR: return address.
-// R0: instance (must be preserved).
-// R2: instantiator type arguments (only if n >= 4, can be raw_null).
-// R1: function type arguments (only if n >= 4, can be raw_null).
-// R3: SubtypeTestCache.
-//
-// Preserves R0/R2
-//
-// Result in R1: null -> not found, otherwise result (true or false).
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
-
-  const Register kCacheReg = R3;
-  const Register kInstanceReg = R0;
-  const Register kInstantiatorTypeArgumentsReg = R2;
-  const Register kFunctionTypeArgumentsReg = R1;
-
-  const Register kInstanceCidOrFunction = R8;
-  const Register kInstanceInstantiatorTypeArgumentsReg = R4;
-  const Register kInstanceParentFunctionTypeArgumentsReg = CODE_REG;
-  const Register kInstanceDelayedFunctionTypeArgumentsReg = PP;
-
-  const Register kNullReg = NOTFP;
-
-  __ LoadObject(kNullReg, Object::null_object());
-
-  // Free up these 2 registers to be used for 6-value test.
-  if (n >= 6) {
-    __ PushList(1 << kInstanceParentFunctionTypeArgumentsReg |
-                1 << kInstanceDelayedFunctionTypeArgumentsReg);
-  }
-
-  // Loop initialization (moved up here to avoid having all dependent loads
-  // after each other).
-  __ ldr(kCacheReg, FieldAddress(kCacheReg, SubtypeTestCache::cache_offset()));
-  __ AddImmediate(kCacheReg, Array::data_offset() - kHeapObjectTag);
-
-  Label loop, not_closure;
-  if (n >= 4) {
-    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
-  } else {
-    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
-  }
-  __ CompareImmediate(kInstanceCidOrFunction, kClosureCid);
-  __ b(&not_closure, NE);
-
-  // Closure handling.
-  {
-    __ ldr(kInstanceCidOrFunction,
-           FieldAddress(kInstanceReg, Closure::function_offset()));
-    if (n >= 2) {
-      __ ldr(kInstanceInstantiatorTypeArgumentsReg,
-             FieldAddress(kInstanceReg,
-                          Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        ASSERT(n == 6);
-        __ ldr(kInstanceParentFunctionTypeArgumentsReg,
-               FieldAddress(kInstanceReg,
-                            Closure::function_type_arguments_offset()));
-        __ ldr(kInstanceDelayedFunctionTypeArgumentsReg,
-               FieldAddress(kInstanceReg,
-                            Closure::delayed_type_arguments_offset()));
-      }
-    }
-    __ b(&loop);
-  }
-
-  // Non-Closure handling.
-  {
-    __ Bind(&not_closure);
-    if (n >= 2) {
-      Label has_no_type_arguments;
-      __ LoadClassById(R9, kInstanceCidOrFunction);
-      __ mov(kInstanceInstantiatorTypeArgumentsReg, Operand(kNullReg));
-      __ ldr(R9, FieldAddress(
-                     R9, Class::type_arguments_field_offset_in_words_offset()));
-      __ CompareImmediate(R9, Class::kNoTypeArguments);
-      __ b(&has_no_type_arguments, EQ);
-      __ add(R9, kInstanceReg, Operand(R9, LSL, 2));
-      __ ldr(kInstanceInstantiatorTypeArgumentsReg, FieldAddress(R9, 0));
-      __ Bind(&has_no_type_arguments);
-
-      if (n >= 6) {
-        __ mov(kInstanceParentFunctionTypeArgumentsReg, Operand(kNullReg));
-        __ mov(kInstanceDelayedFunctionTypeArgumentsReg, Operand(kNullReg));
-      }
-    }
-    __ SmiTag(kInstanceCidOrFunction);
-  }
-
-  Label found, not_found, next_iteration;
-
-  // Loop header.
-  __ Bind(&loop);
-  __ ldr(R9, Address(kCacheReg,
-                     kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmp(R9, Operand(kNullReg));
-  __ b(&not_found, EQ);
-  __ cmp(R9, Operand(kInstanceCidOrFunction));
-  if (n == 1) {
-    __ b(&found, EQ);
-  } else {
-    __ b(&next_iteration, NE);
-    __ ldr(R9, Address(kCacheReg,
-                       kWordSize * SubtypeTestCache::kInstanceTypeArguments));
-    __ cmp(R9, Operand(kInstanceInstantiatorTypeArgumentsReg));
-    if (n == 2) {
-      __ b(&found, EQ);
-    } else {
-      __ b(&next_iteration, NE);
-      __ ldr(R9,
-             Address(kCacheReg,
-                     kWordSize * SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmp(R9, Operand(kInstantiatorTypeArgumentsReg));
-      __ b(&next_iteration, NE);
-      __ ldr(R9, Address(kCacheReg,
-                         kWordSize * SubtypeTestCache::kFunctionTypeArguments));
-      __ cmp(R9, Operand(kFunctionTypeArgumentsReg));
-      if (n == 4) {
-        __ b(&found, EQ);
-      } else {
-        ASSERT(n == 6);
-        __ b(&next_iteration, NE);
-
-        __ ldr(R9,
-               Address(
-                   kCacheReg,
-                   kWordSize *
-                       SubtypeTestCache::kInstanceParentFunctionTypeArguments));
-        __ cmp(R9, Operand(kInstanceParentFunctionTypeArgumentsReg));
-        __ b(&next_iteration, NE);
-
-        __ ldr(
-            R9,
-            Address(
-                kCacheReg,
-                kWordSize *
-                    SubtypeTestCache::kInstanceDelayedFunctionTypeArguments));
-        __ cmp(R9, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
-        __ b(&found, EQ);
-      }
-    }
-  }
-  __ Bind(&next_iteration);
-  __ AddImmediate(kCacheReg, kWordSize * SubtypeTestCache::kTestEntryLength);
-  __ b(&loop);
-
-  __ Bind(&found);
-  __ ldr(R1, Address(kCacheReg, kWordSize * SubtypeTestCache::kTestResult));
-  if (n >= 6) {
-    __ PopList(1 << kInstanceParentFunctionTypeArgumentsReg |
-               1 << kInstanceDelayedFunctionTypeArgumentsReg);
-  }
-  __ Ret();
-
-  __ Bind(&not_found);
-  __ mov(R1, Operand(kNullReg));
-  if (n >= 6) {
-    __ PopList(1 << kInstanceParentFunctionTypeArgumentsReg |
-               1 << kInstanceDelayedFunctionTypeArgumentsReg);
-  }
-  __ Ret();
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-// Used to test whether a given value is of a given type (different variants,
-// all have the same calling convention).
-//
-// Inputs:
-//   - R0 : instance to test against.
-//   - R2 : instantiator type arguments (if needed).
-//   - R1 : function type arguments (if needed).
-//
-//   - R3 : subtype test cache.
-//
-//   - R8 : type to test against.
-//   - R4 : name of destination variable.
-//
-// Preserves R0/R2.
-//
-// Note of warning: The caller will not populate CODE_REG and we have therefore
-// no access to the pool.
-void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  Label done;
-
-  const Register kInstanceReg = R0;
-  // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(EQUAL, &done);
-
-  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Ret();
-}
-
-void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
-  const Register kTypeRefReg = R8;
-
-  // We dereference the TypeRef and tail-call to it's type testing stub.
-  __ ldr(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
-  __ ldr(R9, FieldAddress(kTypeRefReg,
-                          AbstractType::type_test_stub_entry_point_offset()));
-  __ bx(R9);
-}
-
-void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
-    Assembler* assembler,
-    HierarchyInfo* hi,
-    const Type& type,
-    const Class& type_class) {
-  const Register kInstanceReg = R0;
-  const Register kClassIdReg = R9;
-
-  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
-                                      kInstanceReg, kClassIdReg);
-
-  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-void TypeTestingStubGenerator::
-    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
-                                                      HierarchyInfo* hi,
-                                                      const Class& type_class,
-                                                      const TypeArguments& tp,
-                                                      const TypeArguments& ta) {
-  const Register kInstanceReg = R0;
-  const Register kInstanceTypeArguments = NOTFP;
-  const Register kClassIdReg = R9;
-
-  BuildOptimizedSubclassRangeCheckWithTypeArguments(
-      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
-      kInstanceTypeArguments);
-}
-
-void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
-    Assembler* assembler,
-    HierarchyInfo* hi,
-    const AbstractType& type_arg,
-    intptr_t type_param_value_offset_i,
-    Label* check_failed) {
-  const Register kInstantiatorTypeArgumentsReg = R2;
-  const Register kFunctionTypeArgumentsReg = R1;
-  const Register kInstanceTypeArguments = NOTFP;
-
-  const Register kClassIdReg = R9;
-  const Register kOwnTypeArgumentValue = TMP;
-
-  BuildOptimizedTypeArgumentValueCheck(
-      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
-      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
-      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
-}
-
-void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
-                                            TypeCheckMode mode) {
-  const Register kInstanceReg = R0;
-  const Register kInstantiatorTypeArgumentsReg = R2;
-  const Register kFunctionTypeArgumentsReg = R1;
-  const Register kDstTypeReg = R8;
-  const Register kSubtypeTestCacheReg = R3;
-
-  __ PushObject(Object::null_object());  // Make room for result.
-  __ Push(kInstanceReg);
-  __ Push(kDstTypeReg);
-  __ Push(kInstantiatorTypeArgumentsReg);
-  __ Push(kFunctionTypeArgumentsReg);
-  __ PushObject(Object::null_object());
-  __ Push(kSubtypeTestCacheReg);
-  __ PushObject(Smi::ZoneHandle(Smi::New(mode)));
-  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
-  __ Drop(1);  // mode
-  __ Pop(kSubtypeTestCacheReg);
-  __ Drop(1);  // dst_name
-  __ Pop(kFunctionTypeArgumentsReg);
-  __ Pop(kInstantiatorTypeArgumentsReg);
-  __ Pop(kDstTypeReg);
-  __ Pop(kInstanceReg);
-  __ Drop(1);  // Discard return value.
-}
-
-void StubCode::GenerateLazySpecializeTypeTestStub(Assembler* assembler) {
-  const Register kInstanceReg = R0;
-  Label done;
-
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(EQUAL, &done);
-
-  __ ldr(CODE_REG,
-         Address(THR, Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
-  Label done, call_runtime;
-
-  const Register kInstanceReg = R0;
-  const Register kFunctionTypeArgumentsReg = R1;
-  const Register kDstTypeReg = R8;
-  const Register kSubtypeTestCacheReg = R3;
-
-  __ EnterStubFrame();
-
-#ifdef DEBUG
-  // Guaranteed by caller.
-  Label no_error;
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(NOT_EQUAL, &no_error);
-  __ Breakpoint();
-  __ Bind(&no_error);
-#endif
-
-  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
-  __ BranchIf(EQUAL, &call_runtime);
-
-  const Register kTmp = NOTFP;
-
-  // If this is not a [Type] object, we'll go to the runtime.
-  Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, kDstTypeReg);
-  __ cmp(kTmp, Operand(kTypeCid));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is instantiated/uninstantiated.
-  __ ldrb(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()));
-  __ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is a function type.
-  __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::signature_offset()));
-  __ CompareObject(kTmp, Object::null_object());
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(kInstanceReg, &is_complex_case);
-
-  // Fall through to &is_simple_case
-
-  const intptr_t kRegsToSave = (1 << kSubtypeTestCacheReg) |
-                               (1 << kDstTypeReg) |
-                               (1 << kFunctionTypeArgumentsReg);
-
-  __ Bind(&is_simple_case);
-  {
-    __ PushList(kRegsToSave);
-    __ BranchLink(StubCode::Subtype2TestCache());
-    __ CompareObject(R1, Bool::True());
-    __ PopList(kRegsToSave);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    __ Jump(&call_runtime);
-  }
-
-  __ Bind(&is_complex_case);
-  {
-    __ PushList(kRegsToSave);
-    __ BranchLink(StubCode::Subtype6TestCache());
-    __ CompareObject(R1, Bool::True());
-    __ PopList(kRegsToSave);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    // Fall through to runtime_call
-  }
-
-  __ Bind(&call_runtime);
-
-  // We cannot really ensure here that dynamic/Object/void never occur here
-  // (though it is guaranteed at dart_precompiled_runtime time).  This is
-  // because we do constant evaluation with default stubs and only install
-  // optimized versions before writing out the AOT snapshot.
-  // So dynamic/Object/void will run with default stub in constant evaluation.
-  __ CompareObject(kDstTypeReg, Type::dynamic_type());
-  __ BranchIf(EQUAL, &done);
-  __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
-  __ BranchIf(EQUAL, &done);
-  __ CompareObject(kDstTypeReg, Type::void_type());
-  __ BranchIf(EQUAL, &done);
-
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
-
-  __ Bind(&done);
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Return the current stack pointer address, used to do stack alignment checks.
-void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
-  __ mov(R0, Operand(SP));
-  __ Ret();
-}
-
-// Jump to a frame on the call stack.
-// LR: return address.
-// R0: program_counter.
-// R1: stack_pointer.
-// R2: frame_pointer.
-// R3: thread.
-// Does not return.
-void StubCode::GenerateJumpToFrameStub(Assembler* assembler) {
-  ASSERT(kExceptionObjectReg == R0);
-  ASSERT(kStackTraceObjectReg == R1);
-  __ mov(IP, Operand(R1));   // Copy Stack pointer into IP.
-  __ mov(LR, Operand(R0));   // Program counter.
-  __ mov(THR, Operand(R3));  // Thread.
-  __ mov(FP, Operand(R2));   // Frame_pointer.
-  __ mov(SP, Operand(IP));   // Set Stack pointer.
-  // Set the tag.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(kWord, R2, THR, Thread::vm_tag_offset());
-  // Clear top exit frame.
-  __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset());
-  // Restore the pool pointer.
-  __ RestoreCodePointer();
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
-    __ set_constant_pool_allowed(true);
-  } else {
-    __ LoadPoolPointer();
-  }
-  __ bx(LR);  // Jump to continuation point.
-}
-
-// Run an exception handler.  Execution comes from JumpToFrame
-// stub or from the simulator.
-//
-// The arguments are stored in the Thread object.
-// Does not return.
-void StubCode::GenerateRunExceptionHandlerStub(Assembler* assembler) {
-  __ LoadFromOffset(kWord, LR, THR, Thread::resume_pc_offset());
-
-  ASSERT(Thread::CanLoadFromThread(Object::null_object()));
-  __ LoadFromOffset(kWord, R2, THR,
-                    Thread::OffsetFromThread(Object::null_object()));
-
-  // Exception object.
-  __ LoadFromOffset(kWord, R0, THR, Thread::active_exception_offset());
-  __ StoreToOffset(kWord, R2, THR, Thread::active_exception_offset());
-
-  // StackTrace object.
-  __ LoadFromOffset(kWord, R1, THR, Thread::active_stacktrace_offset());
-  __ StoreToOffset(kWord, R2, THR, Thread::active_stacktrace_offset());
-
-  __ bx(LR);  // Jump to the exception handler code.
-}
-
-// Deoptimize a frame on the call stack before rewinding.
-// The arguments are stored in the Thread object.
-// No result.
-void StubCode::GenerateDeoptForRewindStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG.
-  __ LoadImmediate(IP, kZapCodeReg);
-  __ Push(IP);
-
-  // Load the deopt pc into LR.
-  __ LoadFromOffset(kWord, LR, THR, Thread::resume_pc_offset());
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-
-  // After we have deoptimized, jump to the correct frame.
-  __ EnterStubFrame();
-  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
-  __ LeaveStubFrame();
-  __ bkpt(0);
-}
-
-// Calls to the runtime to optimize the given function.
-// R8: function to be reoptimized.
-// R4: argument descriptor (preserved).
-void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(R4);
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Setup space on stack for return value.
-  __ Push(R8);
-  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
-  __ Pop(R0);  // Discard argument.
-  __ Pop(R0);  // Get Function object
-  __ Pop(R4);  // Restore argument descriptor.
-  __ LeaveStubFrame();
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-  __ bkpt(0);
-}
-
-// Does identical check (object references are equal or not equal) with special
-// checks for boxed numbers.
-// LR: return address.
-// Return Zero condition flag set if equal.
-// Note: A Mint cannot contain a value that would fit in Smi.
-static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
-                                                 const Register left,
-                                                 const Register right,
-                                                 const Register temp) {
-  Label reference_compare, done, check_mint;
-  // If any of the arguments is Smi do reference compare.
-  __ tst(left, Operand(kSmiTagMask));
-  __ b(&reference_compare, EQ);
-  __ tst(right, Operand(kSmiTagMask));
-  __ b(&reference_compare, EQ);
-
-  // Value compare for two doubles.
-  __ CompareClassId(left, kDoubleCid, temp);
-  __ b(&check_mint, NE);
-  __ CompareClassId(right, kDoubleCid, temp);
-  __ b(&done, NE);
-
-  // Double values bitwise compare.
-  __ ldr(temp, FieldAddress(left, Double::value_offset() + 0 * kWordSize));
-  __ ldr(IP, FieldAddress(right, Double::value_offset() + 0 * kWordSize));
-  __ cmp(temp, Operand(IP));
-  __ b(&done, NE);
-  __ ldr(temp, FieldAddress(left, Double::value_offset() + 1 * kWordSize));
-  __ ldr(IP, FieldAddress(right, Double::value_offset() + 1 * kWordSize));
-  __ cmp(temp, Operand(IP));
-  __ b(&done);
-
-  __ Bind(&check_mint);
-  __ CompareClassId(left, kMintCid, temp);
-  __ b(&reference_compare, NE);
-  __ CompareClassId(right, kMintCid, temp);
-  __ b(&done, NE);
-  __ ldr(temp, FieldAddress(left, Mint::value_offset() + 0 * kWordSize));
-  __ ldr(IP, FieldAddress(right, Mint::value_offset() + 0 * kWordSize));
-  __ cmp(temp, Operand(IP));
-  __ b(&done, NE);
-  __ ldr(temp, FieldAddress(left, Mint::value_offset() + 1 * kWordSize));
-  __ ldr(IP, FieldAddress(right, Mint::value_offset() + 1 * kWordSize));
-  __ cmp(temp, Operand(IP));
-  __ b(&done);
-
-  __ Bind(&reference_compare);
-  __ cmp(left, Operand(right));
-  __ Bind(&done);
-}
-
-// Called only from unoptimized code. All relevant registers have been saved.
-// LR: return address.
-// SP + 4: left operand.
-// SP + 0: right operand.
-// Return Zero condition flag set if equal.
-void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(R1);
-  __ ldrb(R1, Address(R1, Isolate::single_step_offset()));
-  __ CompareImmediate(R1, 0);
-  __ b(&stepping, NE);
-  __ Bind(&done_stepping);
-#endif
-
-  const Register temp = R2;
-  const Register left = R1;
-  const Register right = R0;
-  __ ldr(left, Address(SP, 1 * kWordSize));
-  __ ldr(right, Address(SP, 0 * kWordSize));
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
-  __ Ret();
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ b(&done_stepping);
-#endif
-}
-
-// Called from optimized code only.
-// LR: return address.
-// SP + 4: left operand.
-// SP + 0: right operand.
-// Return Zero condition flag set if equal.
-void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-  const Register temp = R2;
-  const Register left = R1;
-  const Register right = R0;
-  __ ldr(left, Address(SP, 1 * kWordSize));
-  __ ldr(right, Address(SP, 0 * kWordSize));
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
-  __ Ret();
-}
-
-// Called from megamorphic calls.
-//  R0: receiver
-//  R9: MegamorphicCache (preserved)
-// Passed to target:
-//  CODE_REG: target Code
-//  R4: arguments descriptor
-void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  __ LoadTaggedClassIdMayBeSmi(R0, R0);
-  // R0: receiver cid as Smi.
-  __ ldr(R2, FieldAddress(R9, MegamorphicCache::buckets_offset()));
-  __ ldr(R1, FieldAddress(R9, MegamorphicCache::mask_offset()));
-  // R2: cache buckets array.
-  // R1: mask as a smi.
-
-  // Compute the table index.
-  ASSERT(MegamorphicCache::kSpreadFactor == 7);
-  // Use reverse substract to multiply with 7 == 8 - 1.
-  __ rsb(R3, R0, Operand(R0, LSL, 3));
-  // R3: probe.
-  Label loop;
-  __ Bind(&loop);
-  __ and_(R3, R3, Operand(R1));
-
-  const intptr_t base = Array::data_offset();
-  // R3 is smi tagged, but table entries are two words, so LSL 2.
-  Label probe_failed;
-  __ add(IP, R2, Operand(R3, LSL, 2));
-  __ ldr(R6, FieldAddress(IP, base));
-  __ cmp(R6, Operand(R0));
-  __ b(&probe_failed, NE);
-
-  Label load_target;
-  __ Bind(&load_target);
-  // Call the target found in the cache.  For a class id match, this is a
-  // proper target for the given name and arguments descriptor.  If the
-  // illegal class id was found, the target is a cache miss handler that can
-  // be invoked as a normal Dart function.
-  const auto target_address = FieldAddress(IP, base + kWordSize);
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(R9, MegamorphicCache::arguments_descriptor_offset()));
-    __ Branch(target_address);
-  } else {
-    __ ldr(R0, target_address);
-    __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(R9, MegamorphicCache::arguments_descriptor_offset()));
-    __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-  }
-
-  // Probe failed, check if it is a miss.
-  __ Bind(&probe_failed);
-  ASSERT(kIllegalCid == 0);
-  __ tst(R6, Operand(R6));
-  __ b(&load_target, EQ);  // branch if miss.
-
-  // Try next entry in the table.
-  __ AddImmediate(R3, Smi::RawValue(1));
-  __ b(&loop);
-}
-
-// Called from switchable IC calls.
-//  R0: receiver
-//  R9: ICData (preserved)
-// Passed to target:
-//  CODE_REG: target Code object
-//  R4: arguments descriptor
-void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) {
-  Label loop, found, miss;
-  __ ldr(ARGS_DESC_REG,
-         FieldAddress(R9, ICData::arguments_descriptor_offset()));
-  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
-  __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
-  // R8: first IC entry
-  __ LoadTaggedClassIdMayBeSmi(R1, R0);
-  // R1: receiver cid as Smi
-
-  __ Bind(&loop);
-  __ ldr(R2, Address(R8, 0));
-  __ cmp(R1, Operand(R2));
-  __ b(&found, EQ);
-  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
-  __ b(&miss, EQ);
-
-  const intptr_t entry_length =
-      ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) * kWordSize;
-  __ AddImmediate(R8, entry_length);  // Next entry.
-  __ b(&loop);
-
-  __ Bind(&found);
-  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
-  __ LoadFromOffset(kWord, R0, R8, target_offset);
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ Branch(FieldAddress(R0, Function::entry_point_offset()));
-
-  __ Bind(&miss);
-  __ LoadIsolate(R2);
-  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
-  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) {
-  Label loop, found, miss;
-  __ ldr(R8, FieldAddress(R9, ICData::ic_data_offset()));
-  __ ldr(R4, FieldAddress(R9, ICData::arguments_descriptor_offset()));
-  __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
-  // R8: first IC entry
-  __ LoadTaggedClassIdMayBeSmi(R1, R0);
-  // R1: receiver cid as Smi
-
-  __ Bind(&loop);
-  __ ldr(R2, Address(R8, 0));
-  __ cmp(R1, Operand(R2));
-  __ b(&found, EQ);
-  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
-  __ b(&miss, EQ);
-
-  const intptr_t entry_length =
-      ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) * kWordSize;
-  __ AddImmediate(R8, entry_length);  // Next entry.
-  __ b(&loop);
-
-  __ Bind(&found);
-  const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
-  const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
-  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    __ ldr(CODE_REG, Address(R8, code_offset));
-  }
-  __ Branch(Address(R8, entry_offset));
-
-  __ Bind(&miss);
-  __ LoadIsolate(R2);
-  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
-  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-// Called from switchable IC calls.
-//  R0: receiver
-//  R9: UnlinkedCall
-void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Result slot
-  __ Push(R0);  // Arg0: Receiver
-  __ Push(R9);  // Arg1: UnlinkedCall
-  __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
-  __ Drop(2);
-  __ Pop(R9);  // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ Branch(FieldAddress(
-      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
-}
-
-// Called from switchable IC calls.
-//  R0: receiver
-//  R9: SingleTargetCache
-// Passed to target:
-//  CODE_REG: target Code object
-void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) {
-  Label miss;
-  __ LoadClassIdMayBeSmi(R1, R0);
-  __ ldrh(R2, FieldAddress(R9, SingleTargetCache::lower_limit_offset()));
-  __ ldrh(R3, FieldAddress(R9, SingleTargetCache::upper_limit_offset()));
-
-  __ cmp(R1, Operand(R2));
-  __ b(&miss, LT);
-  __ cmp(R1, Operand(R3));
-  __ b(&miss, GT);
-
-  __ ldr(CODE_REG, FieldAddress(R9, SingleTargetCache::target_offset()));
-  __ Branch(FieldAddress(R9, SingleTargetCache::entry_point_offset()));
-
-  __ Bind(&miss);
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Result slot
-  __ Push(R0);  // Arg0: Receiver
-  __ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
-  __ Drop(1);
-  __ Pop(R9);  // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ Branch(FieldAddress(
-      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
-}
-
-// Called from the monomorphic checked entry.
-//  R0: receiver
-void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ LoadImmediate(IP, 0);
-  __ Push(IP);  // Result slot
-  __ Push(R0);  // Arg0: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
-  __ Drop(1);
-  __ Pop(R9);  // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ Branch(FieldAddress(
-      CODE_REG, Code::entry_point_offset(Code::EntryKind::kMonomorphic)));
-}
-
-void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
-  __ bkpt(0);
-}
-
-void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
-  __ bkpt(0);
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_ARM) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
deleted file mode 100644
index 182a355f..0000000
--- a/runtime/vm/stub_code_arm64.cc
+++ /dev/null
@@ -1,3134 +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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/dart_entry.h"
-#include "vm/heap/heap.h"
-#include "vm/instructions.h"
-#include "vm/object_store.h"
-#include "vm/runtime_entry.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
-#include "vm/tags.h"
-#include "vm/type_testing_stubs.h"
-
-#define __ assembler->
-
-namespace dart {
-
-DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
-DEFINE_FLAG(bool,
-            use_slow_path,
-            false,
-            "Set to true for debugging & verifying the slow paths.");
-DECLARE_FLAG(bool, enable_interpreter);
-DECLARE_FLAG(bool, precompiled_mode);
-
-// Input parameters:
-//   LR : return address.
-//   SP : address of last argument in argument array.
-//   SP + 8*R4 - 8 : address of first argument in argument array.
-//   SP + 8*R4 : address of return value.
-//   R5 : address of the runtime function to call.
-//   R4 : number of arguments to the call.
-void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ Comment("CallToRuntimeStub");
-  __ ldr(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
-  __ SetPrologueOffset();
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to Dart VM C++ code.
-  __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R8, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing VM code.
-  __ StoreToOffset(R5, THR, Thread::vm_tag_offset());
-
-  // Reserve space for arguments and align frame before entering C++ world.
-  // NativeArguments are passed in registers.
-  __ Comment("align stack");
-  // Reserve space for arguments.
-  ASSERT(sizeof(NativeArguments) == 4 * kWordSize);
-  __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
-
-  // Pass NativeArguments structure by value and call runtime.
-  // Registers R0, R1, R2, and R3 are used.
-
-  ASSERT(thread_offset == 0 * kWordSize);
-  // Set thread in NativeArgs.
-  __ mov(R0, THR);
-
-  // There are no runtime calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  ASSERT(argc_tag_offset == 1 * kWordSize);
-  __ mov(R1, R4);  // Set argc in NativeArguments.
-
-  ASSERT(argv_offset == 2 * kWordSize);
-  __ add(R2, ZR, Operand(R4, LSL, 3));
-  __ add(R2, FP, Operand(R2));  // Compute argv.
-  // Set argv in NativeArguments.
-  __ AddImmediate(R2, kParamEndSlotFromFp * kWordSize);
-
-  ASSERT(retval_offset == 3 * kWordSize);
-  __ AddImmediate(R3, R2, kWordSize);
-
-  __ StoreToOffset(R0, SP, thread_offset);
-  __ StoreToOffset(R1, SP, argc_tag_offset);
-  __ StoreToOffset(R2, SP, argv_offset);
-  __ StoreToOffset(R3, SP, retval_offset);
-  __ mov(R0, SP);  // Pass the pointer to the NativeArguments.
-
-  // We are entering runtime code, so the C stack pointer must be restored from
-  // the stack limit to the top of the stack. We cache the stack limit address
-  // in a callee-saved register.
-  __ mov(R25, CSP);
-  __ mov(CSP, SP);
-
-  __ blr(R5);
-  __ Comment("CallToRuntimeStub return");
-
-  // Restore SP and CSP.
-  __ mov(SP, CSP);
-  __ mov(CSP, R25);
-
-  // Refresh write barrier mask.
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-
-  // Retval is next to 1st argument.
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-
-  // Restore the global object pool after returning from runtime (old space is
-  // moving, so the GOP could have been relocated).
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
-    __ sub(PP, PP, Operand(kHeapObjectTag));  // Pool in PP is untagged!
-  }
-
-  __ LeaveStubFrame();
-
-  // The following return can jump to a lazy-deopt stub, which assumes R0
-  // contains a return value and will save it in a GC-visible way.  We therefore
-  // have to ensure R0 does not contain any garbage value left from the C
-  // function we called (which has return type "void").
-  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
-  __ LoadImmediate(R0, 0);
-  __ ret();
-}
-
-void StubCode::GenerateSharedStub(Assembler* assembler,
-                                  bool save_fpu_registers,
-                                  const RuntimeEntry* target,
-                                  intptr_t self_code_stub_offset_from_thread,
-                                  bool allow_return) {
-  // We want the saved registers to appear like part of the caller's frame, so
-  // we push them before calling EnterStubFrame.
-  RegisterSet all_registers;
-  all_registers.AddAllNonReservedRegisters(save_fpu_registers);
-
-  // To make the stack map calculation architecture independent we do the same
-  // as on intel.
-  __ Push(LR);
-  __ PushRegisters(all_registers);
-  __ ldr(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
-  __ EnterStubFrame();
-  __ CallRuntime(*target, /*argument_count=*/0);
-  if (!allow_return) {
-    __ Breakpoint();
-    return;
-  }
-  __ LeaveStubFrame();
-  __ PopRegisters(all_registers);
-  __ Pop(LR);
-  __ ret(LR);
-}
-
-// R1: The extracted method.
-// R4: The type_arguments_field_offset (or 0)
-void StubCode::GenerateBuildMethodExtractorStub(Assembler* assembler) {
-  Thread* thread = Thread::Current();
-  Zone* Z = thread->zone();
-  ObjectStore* object_store = thread->isolate()->object_store();
-
-  const auto& closure_class =
-      Class::ZoneHandle(Z, object_store->closure_class());
-  const auto& closure_allocation_stub =
-      Code::ZoneHandle(Z, StubCode::GetAllocationStubForClass(closure_class));
-
-  const intptr_t kReceiverOffset = compiler_frame_layout.param_end_from_fp + 1;
-
-  const auto& context_allocation_stub = StubCode::AllocateContext();
-
-  __ EnterStubFrame();
-
-  // Build type_arguments vector (or null)
-  Label no_type_args;
-  __ ldr(R3, Address(THR, Thread::object_null_offset()), kDoubleWord);
-  __ cmp(R4, Operand(0));
-  __ b(&no_type_args, EQ);
-  __ ldr(R0, Address(FP, kReceiverOffset * kWordSize));
-  __ ldr(R3, Address(R0, R4));
-  __ Bind(&no_type_args);
-
-  // Push type arguments & extracted method.
-  __ PushPair(R3, R1);
-
-  // Allocate context.
-  {
-    Label done, slow_path;
-    __ TryAllocateArray(kContextCid, Context::InstanceSize(1), &slow_path,
-                        R0,  // instance
-                        R1,  // end address
-                        R2, R3);
-    __ ldr(R1, Address(THR, Thread::object_null_offset()));
-    __ str(R1, FieldAddress(R0, Context::parent_offset()));
-    __ LoadImmediate(R1, 1);
-    __ str(R1, FieldAddress(R0, Context::num_variables_offset()));
-    __ b(&done);
-
-    __ Bind(&slow_path);
-
-    __ LoadImmediate(/*num_vars=*/R1, 1);
-    __ LoadObject(CODE_REG, context_allocation_stub);
-    __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-    __ blr(R0);
-
-    __ Bind(&done);
-  }
-
-  // Store receiver in context
-  __ ldr(R1, Address(FP, kWordSize * kReceiverOffset));
-  __ StoreIntoObject(R0, FieldAddress(R0, Context::variable_offset(0)), R1);
-
-  // Push context.
-  __ Push(R0);
-
-  // Allocate closure.
-  __ LoadObject(CODE_REG, closure_allocation_stub);
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kUnchecked)));
-  __ blr(R1);
-
-  // Populate closure object.
-  __ Pop(R1);  // Pop context.
-  __ StoreIntoObject(R0, FieldAddress(R0, Closure::context_offset()), R1);
-  __ PopPair(R3, R1);  // Pop type arguments & extracted method.
-  __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, Closure::function_offset()),
-                              R1);
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, Closure::instantiator_type_arguments_offset()), R3);
-  __ LoadObject(R1, Object::empty_type_arguments());
-  __ StoreIntoObjectNoBarrier(
-      R0, FieldAddress(R0, Closure::delayed_type_arguments_offset()), R1);
-
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateNullErrorSharedWithoutFPURegsStub(Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/false,
-                     &kNullErrorRuntimeEntry,
-                     Thread::null_error_shared_without_fpu_regs_stub_offset(),
-                     /*allow_return=*/false);
-}
-
-void StubCode::GenerateNullErrorSharedWithFPURegsStub(Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/true,
-                     &kNullErrorRuntimeEntry,
-                     Thread::null_error_shared_with_fpu_regs_stub_offset(),
-                     /*allow_return=*/false);
-}
-
-void StubCode::GenerateStackOverflowSharedWithoutFPURegsStub(
-    Assembler* assembler) {
-  GenerateSharedStub(
-      assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
-      Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
-}
-
-void StubCode::GenerateStackOverflowSharedWithFPURegsStub(
-    Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/true,
-                     &kStackOverflowRuntimeEntry,
-                     Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
-                     /*allow_return=*/true);
-}
-
-void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
-  __ Stop("GeneratePrintStopMessageStub");
-}
-
-// Input parameters:
-//   LR : return address.
-//   SP : address of return value.
-//   R5 : address of the native function to call.
-//   R2 : address of first argument in argument array.
-//   R1 : argc_tag including number of arguments and function kind.
-static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
-                                              Address wrapper) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to native code.
-  __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ StoreToOffset(R5, THR, Thread::vm_tag_offset());
-
-  // Reserve space for the native arguments structure passed on the stack (the
-  // outgoing pointer parameter to the native arguments structure is passed in
-  // R0) and align frame before entering the C++ world.
-  __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
-
-  // Initialize NativeArguments structure and call native function.
-  // Registers R0, R1, R2, and R3 are used.
-
-  ASSERT(thread_offset == 0 * kWordSize);
-  // Set thread in NativeArgs.
-  __ mov(R0, THR);
-
-  // There are no native calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  ASSERT(argc_tag_offset == 1 * kWordSize);
-  // Set argc in NativeArguments: R1 already contains argc.
-
-  ASSERT(argv_offset == 2 * kWordSize);
-  // Set argv in NativeArguments: R2 already contains argv.
-
-  // Set retval in NativeArgs.
-  ASSERT(retval_offset == 3 * kWordSize);
-  __ AddImmediate(R3, FP, 2 * kWordSize);
-
-  // Passing the structure by value as in runtime calls would require changing
-  // Dart API for native functions.
-  // For now, space is reserved on the stack and we pass a pointer to it.
-  __ StoreToOffset(R0, SP, thread_offset);
-  __ StoreToOffset(R1, SP, argc_tag_offset);
-  __ StoreToOffset(R2, SP, argv_offset);
-  __ StoreToOffset(R3, SP, retval_offset);
-  __ mov(R0, SP);  // Pass the pointer to the NativeArguments.
-
-  // We are entering runtime code, so the C stack pointer must be restored from
-  // the stack limit to the top of the stack. We cache the stack limit address
-  // in the Dart SP register, which is callee-saved in the C ABI.
-  __ mov(R25, CSP);
-  __ mov(CSP, SP);
-
-  __ mov(R1, R5);  // Pass the function entrypoint to call.
-
-  // Call native function invocation wrapper or redirection via simulator.
-  __ ldr(LR, wrapper);
-  __ blr(LR);
-
-  // Restore SP and CSP.
-  __ mov(SP, CSP);
-  __ mov(CSP, R25);
-
-  // Refresh write barrier mask.
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-void StubCode::GenerateCallNoScopeNativeStub(Assembler* assembler) {
-  GenerateCallNativeWithWrapperStub(
-      assembler,
-      Address(THR, Thread::no_scope_native_wrapper_entry_point_offset()));
-}
-
-void StubCode::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
-  GenerateCallNativeWithWrapperStub(
-      assembler,
-      Address(THR, Thread::auto_scope_native_wrapper_entry_point_offset()));
-}
-
-// Input parameters:
-//   LR : return address.
-//   SP : address of return value.
-//   R5 : address of the native function to call.
-//   R2 : address of first argument in argument array.
-//   R1 : argc_tag including number of arguments and function kind.
-void StubCode::GenerateCallBootstrapNativeStub(Assembler* assembler) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to native code.
-  __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R6, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R6, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ StoreToOffset(R5, THR, Thread::vm_tag_offset());
-
-  // Reserve space for the native arguments structure passed on the stack (the
-  // outgoing pointer parameter to the native arguments structure is passed in
-  // R0) and align frame before entering the C++ world.
-  __ ReserveAlignedFrameSpace(sizeof(NativeArguments));
-
-  // Initialize NativeArguments structure and call native function.
-  // Registers R0, R1, R2, and R3 are used.
-
-  ASSERT(thread_offset == 0 * kWordSize);
-  // Set thread in NativeArgs.
-  __ mov(R0, THR);
-
-  // There are no native calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  ASSERT(argc_tag_offset == 1 * kWordSize);
-  // Set argc in NativeArguments: R1 already contains argc.
-
-  ASSERT(argv_offset == 2 * kWordSize);
-  // Set argv in NativeArguments: R2 already contains argv.
-
-  // Set retval in NativeArgs.
-  ASSERT(retval_offset == 3 * kWordSize);
-  __ AddImmediate(R3, FP, 2 * kWordSize);
-
-  // Passing the structure by value as in runtime calls would require changing
-  // Dart API for native functions.
-  // For now, space is reserved on the stack and we pass a pointer to it.
-  __ StoreToOffset(R0, SP, thread_offset);
-  __ StoreToOffset(R1, SP, argc_tag_offset);
-  __ StoreToOffset(R2, SP, argv_offset);
-  __ StoreToOffset(R3, SP, retval_offset);
-  __ mov(R0, SP);  // Pass the pointer to the NativeArguments.
-
-  // We are entering runtime code, so the C stack pointer must be restored from
-  // the stack limit to the top of the stack. We cache the stack limit address
-  // in the Dart SP register, which is callee-saved in the C ABI.
-  __ mov(R25, CSP);
-  __ mov(CSP, SP);
-
-  // Call native function or redirection via simulator.
-  __ blr(R5);
-
-  // Restore SP and CSP.
-  __ mov(SP, CSP);
-  __ mov(CSP, R25);
-
-  // Refresh write barrier mask.
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-// Input parameters:
-//   R4: arguments descriptor array.
-void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value and preserve arguments descriptor.
-  __ Push(R4);
-  __ Push(ZR);
-  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
-  // Get Code object result and restore arguments descriptor array.
-  __ Pop(CODE_REG);
-  __ Pop(R4);
-  // Remove the stub frame.
-  __ LeaveStubFrame();
-  // Jump to the dart function.
-  __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
-  __ br(R0);
-}
-
-// Called from a static call only when an invalid code has been entered
-// (invalid because its function was optimized or deoptimized).
-// R4: arguments descriptor array.
-void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
-  // Load code pointer to this stub from the thread:
-  // The one that is passed in, is not correct - it points to the code object
-  // that needs to be replaced.
-  __ ldr(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset()));
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value and preserve arguments descriptor.
-  __ Push(R4);
-  __ Push(ZR);
-  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
-  // Get Code object result and restore arguments descriptor array.
-  __ Pop(CODE_REG);
-  __ Pop(R4);
-  // Remove the stub frame.
-  __ LeaveStubFrame();
-  // Jump to the dart function.
-  __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
-  __ br(R0);
-}
-
-// Called from object allocate instruction when the allocation stub has been
-// disabled.
-void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
-  // Load code pointer to this stub from the thread:
-  // The one that is passed in, is not correct - it points to the code object
-  // that needs to be replaced.
-  __ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset()));
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  __ Push(ZR);
-  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
-  // Get Code object result.
-  __ Pop(CODE_REG);
-  // Remove the stub frame.
-  __ LeaveStubFrame();
-  // Jump to the dart function.
-  __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
-  __ br(R0);
-}
-
-// Input parameters:
-//   R2: smi-tagged argument count, may be zero.
-//   FP[kParamEndSlotFromFp + 1]: last argument.
-static void PushArrayOfArguments(Assembler* assembler) {
-  // Allocate array to store arguments of caller.
-  __ LoadObject(R1, Object::null_object());
-  // R1: null element type for raw Array.
-  // R2: smi-tagged argument count, may be zero.
-  __ BranchLink(StubCode::AllocateArray());
-  // R0: newly allocated array.
-  // R2: smi-tagged argument count, may be zero (was preserved by the stub).
-  __ Push(R0);  // Array is in R0 and on top of stack.
-  __ add(R1, FP, Operand(R2, LSL, 2));
-  __ AddImmediate(R1, kParamEndSlotFromFp * kWordSize);
-  __ AddImmediate(R3, R0, Array::data_offset() - kHeapObjectTag);
-  // R1: address of first argument on stack.
-  // R3: address of first argument in array.
-
-  Label loop, loop_exit;
-  __ CompareRegisters(R2, ZR);
-  __ b(&loop_exit, LE);
-  __ Bind(&loop);
-  __ ldr(R7, Address(R1));
-  __ AddImmediate(R1, -kWordSize);
-  __ AddImmediate(R3, kWordSize);
-  __ AddImmediateSetFlags(R2, R2, -Smi::RawValue(1));
-  __ str(R7, Address(R3, -kWordSize));
-  __ b(&loop, GE);
-  __ Bind(&loop_exit);
-}
-
-// Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
-// This stub translates optimized frame into unoptimized frame. The optimized
-// frame can contain values in registers and on stack, the unoptimized
-// frame contains all values on stack.
-// Deoptimization occurs in following steps:
-// - Push all registers that can contain values.
-// - Call C routine to copy the stack and saved registers into temporary buffer.
-// - Adjust caller's frame to correct unoptimized frame size.
-// - Fill the unoptimized frame.
-// - Materialize objects that require allocation (e.g. Double instances).
-// GC can occur only after frame is fully rewritten.
-// Stack after TagAndPushPP() below:
-//   +------------------+
-//   | Saved PP         | <- PP
-//   +------------------+
-//   | PC marker        | <- TOS
-//   +------------------+
-//   | Saved FP         | <- FP of stub
-//   +------------------+
-//   | return-address   |  (deoptimization point)
-//   +------------------+
-//   | Saved CODE_REG   |
-//   +------------------+
-//   | ...              | <- SP of optimized frame
-//
-// Parts of the code cannot GC, part of the code can GC.
-static void GenerateDeoptimizationSequence(Assembler* assembler,
-                                           DeoptStubKind kind) {
-  // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
-  // is no need to set the correct PC marker or load PP, since they get patched.
-  __ EnterStubFrame();
-
-  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
-  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
-  const intptr_t saved_result_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - R0);
-  const intptr_t saved_exception_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - R0);
-  const intptr_t saved_stacktrace_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - R1);
-  // Result in R0 is preserved as part of pushing all registers below.
-
-  // Push registers in their enumeration order: lowest register number at
-  // lowest address.
-  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
-    const Register r = static_cast<Register>(i);
-    if (r == CODE_REG) {
-      // Save the original value of CODE_REG pushed before invoking this stub
-      // instead of the value used to call this stub.
-      COMPILE_ASSERT(R25 > CODE_REG);
-      __ ldr(R25, Address(FP, 2 * kWordSize));
-      __ str(R25, Address(SP, -1 * kWordSize, Address::PreIndex));
-    } else {
-      __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex));
-    }
-  }
-
-  for (intptr_t reg_idx = kNumberOfVRegisters - 1; reg_idx >= 0; reg_idx--) {
-    VRegister vreg = static_cast<VRegister>(reg_idx);
-    __ PushQuad(vreg);
-  }
-
-  __ mov(R0, SP);  // Pass address of saved registers block.
-  bool is_lazy =
-      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
-  __ LoadImmediate(R1, is_lazy ? 1 : 0);
-  __ ReserveAlignedFrameSpace(0);
-  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
-  // Result (R0) is stack-size (FP - SP) in bytes.
-
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into R1 temporarily.
-    __ LoadFromOffset(R1, FP, saved_result_slot_from_fp * kWordSize);
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into R1 temporarily.
-    __ LoadFromOffset(R1, FP, saved_exception_slot_from_fp * kWordSize);
-    __ LoadFromOffset(R2, FP, saved_stacktrace_slot_from_fp * kWordSize);
-  }
-
-  // There is a Dart Frame on the stack. We must restore PP and leave frame.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ sub(SP, FP, Operand(R0));
-
-  // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
-  // is no need to set the correct PC marker or load PP, since they get patched.
-  __ EnterStubFrame();
-
-  if (kind == kLazyDeoptFromReturn) {
-    __ Push(R1);  // Preserve result as first local.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ Push(R1);  // Preserve exception as first local.
-    __ Push(R2);  // Preserve stacktrace as second local.
-  }
-  __ ReserveAlignedFrameSpace(0);
-  __ mov(R0, FP);  // Pass last FP as parameter in R0.
-  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into R1.
-    __ LoadFromOffset(R1, FP,
-                      compiler_frame_layout.first_local_from_fp * kWordSize);
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into R1.
-    __ LoadFromOffset(R1, FP,
-                      compiler_frame_layout.first_local_from_fp * kWordSize);
-    __ LoadFromOffset(
-        R2, FP, (compiler_frame_layout.first_local_from_fp - 1) * kWordSize);
-  }
-  // Code above cannot cause GC.
-  // There is a Dart Frame on the stack. We must restore PP and leave frame.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-
-  // Frame is fully rewritten at this point and it is safe to perform a GC.
-  // Materialize any objects that were deferred by FillFrame because they
-  // require allocation.
-  // Enter stub frame with loading PP. The caller's PP is not materialized yet.
-  __ EnterStubFrame();
-  if (kind == kLazyDeoptFromReturn) {
-    __ Push(R1);  // Preserve result, it will be GC-d here.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ Push(R1);  // Preserve exception, it will be GC-d here.
-    __ Push(R2);  // Preserve stacktrace, it will be GC-d here.
-  }
-
-  __ Push(ZR);  // Space for the result.
-  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
-  // Result tells stub how many bytes to remove from the expression stack
-  // of the bottom-most frame. They were used as materialization arguments.
-  __ Pop(R2);
-  __ SmiUntag(R2);
-  if (kind == kLazyDeoptFromReturn) {
-    __ Pop(R0);  // Restore result.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ Pop(R1);  // Restore stacktrace.
-    __ Pop(R0);  // Restore exception.
-  }
-  __ LeaveStubFrame();
-  // Remove materialization arguments.
-  __ add(SP, SP, Operand(R2));
-  // The caller is responsible for emitting the return instruction.
-}
-
-// R0: result, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG for lazy deopt.
-  __ LoadImmediate(TMP, kZapCodeReg);
-  __ Push(TMP);
-  // Return address for "call" to deopt stub.
-  __ LoadImmediate(LR, kZapReturnAddress);
-  __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
-  __ ret();
-}
-
-// R0: exception, must be preserved
-// R1: stacktrace, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG for lazy deopt.
-  __ LoadImmediate(TMP, kZapCodeReg);
-  __ Push(TMP);
-  // Return address for "call" to deopt stub.
-  __ LoadImmediate(LR, kZapReturnAddress);
-  __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
-  __ ret();
-}
-
-void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
-  __ Push(CODE_REG);
-  __ ldr(CODE_REG, Address(THR, Thread::deoptimize_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-  __ 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, Object::null_object());
-  __ b(call_target_function, NE);
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset());
-  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
-  __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize);
-  __ Push(ZR);  // Result slot.
-  __ Push(R6);  // Receiver.
-  __ Push(R5);  // ICData/MegamorphicCache.
-  __ Push(R4);  // Arguments descriptor.
-
-  // Adjust arguments count.
-  __ LoadFieldFromOffset(R3, R4, ArgumentsDescriptor::type_args_len_offset());
-  __ AddImmediate(TMP, R2, 1);  // Include the type arguments.
-  __ cmp(R3, Operand(0));
-  __ csinc(R2, R2, TMP, EQ);  // R2 <- (R3 == 0) ? R2 : TMP + 1 (R2 : R2 + 2).
-
-  // R2: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-  const intptr_t kNumArgs = 4;
-  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
-  __ Drop(4);
-  __ Pop(R0);  // Return value.
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset());
-  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
-  __ LoadFromOffset(R6, TMP,
-                    compiler_frame_layout.param_end_from_fp * kWordSize);
-
-  // 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, Function::code_offset());
-  __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
-  __ br(R2);
-}
-
-// Called for inline allocation of arrays.
-// Input parameters:
-//   LR: return address.
-//   R2: array length as Smi.
-//   R1: array element type (either NULL or an instantiated type).
-// NOTE: R2 cannot be clobbered here as the caller relies on it being saved.
-// The newly allocated object is returned in R0.
-void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
-  Label slow_case;
-  // Compute the size to be allocated, it is based on the array length
-  // and is computed as:
-  // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
-  // Assert that length is a Smi.
-  __ tsti(R2, Immediate(kSmiTagMask));
-  if (FLAG_use_slow_path) {
-    __ b(&slow_case);
-  } else {
-    __ b(&slow_case, NE);
-  }
-  __ cmp(R2, Operand(0));
-  __ b(&slow_case, LT);
-
-  // Check for maximum allowed length.
-  const intptr_t max_len =
-      reinterpret_cast<intptr_t>(Smi::New(Array::kMaxNewSpaceElements));
-  __ CompareImmediate(R2, max_len);
-  __ b(&slow_case, GT);
-
-  const intptr_t cid = kArrayCid;
-  NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case));
-
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-
-  // Calculate and align allocation size.
-  // Load new object start and calculate next object start.
-  // R1: array element type.
-  // R2: array length as Smi.
-  __ ldr(R0, Address(THR, Thread::top_offset()));
-  intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawArray) + kObjectAlignment - 1;
-  __ LoadImmediate(R3, fixed_size_plus_alignment_padding);
-  __ add(R3, R3, Operand(R2, LSL, 2));  // R2 is Smi.
-  ASSERT(kSmiTagShift == 1);
-  __ andi(R3, R3, Immediate(~(kObjectAlignment - 1)));
-  // R0: potential new object start.
-  // R3: object size in bytes.
-  __ adds(R7, R3, Operand(R0));
-  __ b(&slow_case, CS);  // Branch if unsigned overflow.
-
-  // Check if the allocation fits into the remaining space.
-  // R0: potential new object start.
-  // R1: array element type.
-  // R2: array length as Smi.
-  // R3: array size.
-  // R7: potential next object start.
-  __ LoadFromOffset(TMP, THR, Thread::end_offset());
-  __ CompareRegisters(R7, TMP);
-  __ b(&slow_case, CS);  // Branch if unsigned higher or equal.
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  // R0: potential new object start.
-  // R3: array size.
-  // R7: potential next object start.
-  __ str(R7, Address(THR, Thread::top_offset()));
-  __ add(R0, R0, Operand(kHeapObjectTag));
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R3, space));
-
-  // R0: new object start as a tagged pointer.
-  // R1: array element type.
-  // R2: array length as Smi.
-  // R3: array size.
-  // R7: new object end address.
-
-  // Store the type argument field.
-  __ StoreIntoObjectOffsetNoBarrier(R0, Array::type_arguments_offset(), R1);
-
-  // Set the length field.
-  __ StoreIntoObjectOffsetNoBarrier(R0, Array::length_offset(), R2);
-
-  // Calculate the size tag.
-  // R0: new object start as a tagged pointer.
-  // R2: array length as Smi.
-  // R3: array size.
-  // R7: new object end address.
-  const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
-  __ CompareImmediate(R3, RawObject::SizeTag::kMaxSizeTag);
-  // If no size tag overflow, shift R1 left, else set R1 to zero.
-  __ LslImmediate(TMP, R3, shift);
-  __ csel(R1, TMP, R1, LS);
-  __ csel(R1, ZR, R1, HI);
-
-  // Get the class index and insert it into the tags.
-  uint32_t tags = 0;
-  tags = RawObject::ClassIdTag::update(cid, tags);
-  tags = RawObject::NewBit::update(true, tags);
-  __ LoadImmediate(TMP, tags);
-  __ orr(R1, R1, Operand(TMP));
-  __ StoreFieldToOffset(R1, R0, Array::tags_offset());
-
-  // Initialize all array elements to raw_null.
-  // R0: new object start as a tagged pointer.
-  // R7: new object end address.
-  // R2: array length as Smi.
-  __ AddImmediate(R1, R0, Array::data_offset() - kHeapObjectTag);
-  // R1: iterator which initially points to the start of the variable
-  // data area to be initialized.
-  __ LoadObject(TMP, Object::null_object());
-  Label loop, done;
-  __ Bind(&loop);
-  // TODO(cshapiro): StoreIntoObjectNoBarrier
-  __ CompareRegisters(R1, R7);
-  __ b(&done, CS);
-  __ str(TMP, Address(R1));  // Store if unsigned lower.
-  __ AddImmediate(R1, kWordSize);
-  __ b(&loop);  // Loop until R1 == R7.
-  __ Bind(&done);
-
-  // Done allocating and initializing the array.
-  // R0: new object.
-  // R2: array length as Smi (preserved for the caller.)
-  __ ret();
-
-  // Unable to allocate the array using the fast inline code, just call
-  // into the runtime.
-  __ Bind(&slow_case);
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  // Push array length as Smi and element type.
-  __ Push(ZR);
-  __ Push(R2);
-  __ Push(R1);
-  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
-  // Pop arguments; result is popped in IP.
-  __ Pop(R1);
-  __ Pop(R2);
-  __ Pop(R0);
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-// Called when invoking Dart code from C++ (VM code).
-// Input parameters:
-//   LR : points to return address.
-//   R0 : code object of the Dart function to call.
-//   R1 : arguments descriptor array.
-//   R2 : arguments array.
-//   R3 : current thread.
-void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
-  __ Comment("InvokeDartCodeStub");
-
-  // Copy the C stack pointer (R31) into the stack pointer we'll actually use
-  // to access the stack.
-  __ SetupDartSP();
-  __ Push(LR);  // Marker for the profiler.
-  __ EnterFrame(0);
-
-  // Push code object to PC marker slot.
-  __ ldr(TMP, Address(R3, Thread::invoke_dart_code_stub_offset()));
-  __ Push(TMP);
-
-  // Save the callee-saved registers.
-  for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
-    const Register r = static_cast<Register>(i);
-    // We use str instead of the Push macro because we will be pushing the PP
-    // register when it is not holding a pool-pointer since we are coming from
-    // C++ code.
-    __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex));
-  }
-
-  // Save the bottom 64-bits of callee-saved V registers.
-  for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
-    const VRegister r = static_cast<VRegister>(i);
-    __ PushDouble(r);
-  }
-
-  // Set up THR, which caches the current thread in Dart code.
-  if (THR != R3) {
-    __ mov(THR, R3);
-  }
-  // Refresh write barrier mask.
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-
-  // Save the current VMTag on the stack.
-  __ LoadFromOffset(R4, THR, Thread::vm_tag_offset());
-  __ Push(R4);
-
-  // Save top resource and top exit frame info. Use R6 as a temporary register.
-  // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(R6, THR, Thread::top_resource_offset());
-  __ StoreToOffset(ZR, THR, Thread::top_resource_offset());
-  __ Push(R6);
-  __ LoadFromOffset(R6, THR, Thread::top_exit_frame_info_offset());
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-  // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -22);
-  __ Push(R6);
-
-  // Mark that the thread is executing Dart code. Do this after initializing the
-  // exit link for the profiler.
-  __ LoadImmediate(R6, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R6, THR, Thread::vm_tag_offset());
-
-  // Load arguments descriptor array into R4, which is passed to Dart code.
-  __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle);
-
-  // Load number of arguments into R5 and adjust count for type arguments.
-  __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset());
-  __ LoadFieldFromOffset(R3, R4, ArgumentsDescriptor::type_args_len_offset());
-  __ AddImmediate(TMP, R5, 1);  // Include the type arguments.
-  __ cmp(R3, Operand(0));
-  __ csinc(R5, R5, TMP, EQ);  // R5 <- (R3 == 0) ? R5 : TMP + 1 (R5 : R5 + 2).
-  __ SmiUntag(R5);
-
-  // Compute address of 'arguments array' data area into R2.
-  __ LoadFromOffset(R2, R2, VMHandles::kOffsetOfRawPtrInHandle);
-  __ AddImmediate(R2, Array::data_offset() - kHeapObjectTag);
-
-  // Set up arguments for the Dart call.
-  Label push_arguments;
-  Label done_push_arguments;
-  __ cmp(R5, Operand(0));
-  __ b(&done_push_arguments, EQ);  // check if there are arguments.
-  __ LoadImmediate(R1, 0);
-  __ Bind(&push_arguments);
-  __ ldr(R3, Address(R2));
-  __ Push(R3);
-  __ add(R1, R1, Operand(1));
-  __ add(R2, R2, Operand(kWordSize));
-  __ cmp(R1, Operand(R5));
-  __ b(&push_arguments, LT);
-  __ Bind(&done_push_arguments);
-
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
-    __ sub(PP, PP, Operand(kHeapObjectTag));  // Pool in PP is untagged!
-  } else {
-    // We now load the pool pointer(PP) with a GC safe value as we are about to
-    // invoke dart code. We don't need a real object pool here.
-    // Smi zero does not work because ARM64 assumes PP to be untagged.
-    __ LoadObject(PP, Object::null_object());
-  }
-
-  // Call the Dart code entrypoint.
-  __ ldr(CODE_REG, Address(R0, VMHandles::kOffsetOfRawPtrInHandle));
-  __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ blr(R0);  // R4 is the arguments descriptor array.
-  __ Comment("InvokeDartCodeStub return");
-
-  // Get rid of arguments pushed on the stack.
-  __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
-
-  // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure. Uses R6 as a temporary register for this.
-  __ Pop(R6);
-  __ StoreToOffset(R6, THR, Thread::top_exit_frame_info_offset());
-  __ Pop(R6);
-  __ StoreToOffset(R6, THR, Thread::top_resource_offset());
-
-  // Restore the current VMTag from the stack.
-  __ Pop(R4);
-  __ StoreToOffset(R4, THR, Thread::vm_tag_offset());
-
-  // Restore the bottom 64-bits of callee-saved V registers.
-  for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
-    const VRegister r = static_cast<VRegister>(i);
-    __ PopDouble(r);
-  }
-
-  // Restore C++ ABI callee-saved registers.
-  for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
-    Register r = static_cast<Register>(i);
-    // We use ldr instead of the Pop macro because we will be popping the PP
-    // register when it is not holding a pool-pointer since we are returning to
-    // C++ code. We also skip the dart stack pointer SP, since we are still
-    // using it as the stack pointer.
-    __ ldr(r, Address(SP, 1 * kWordSize, Address::PostIndex));
-  }
-
-  // Restore the frame pointer and C stack pointer and return.
-  __ LeaveFrame();
-  __ Drop(1);
-  __ RestoreCSP();
-  __ ret();
-}
-
-// Called when invoking compiled Dart code from interpreted Dart code.
-// Input parameters:
-//   LR : points to return address.
-//   R0 : raw code object of the Dart function to call.
-//   R1 : arguments raw descriptor array.
-//   R2 : address of first argument.
-//   R3 : current thread.
-void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
-  // Copy the C stack pointer (R31) into the stack pointer we'll actually use
-  // to access the stack.
-  __ SetupDartSP();
-  __ Push(LR);  // Marker for the profiler.
-  __ EnterFrame(0);
-
-  // Push code object to PC marker slot.
-  __ ldr(TMP,
-         Address(R3, Thread::invoke_dart_code_from_bytecode_stub_offset()));
-  __ Push(TMP);
-
-  // Save the callee-saved registers.
-  for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
-    const Register r = static_cast<Register>(i);
-    // We use str instead of the Push macro because we will be pushing the PP
-    // register when it is not holding a pool-pointer since we are coming from
-    // C++ code.
-    __ str(r, Address(SP, -1 * kWordSize, Address::PreIndex));
-  }
-
-  // Save the bottom 64-bits of callee-saved V registers.
-  for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
-    const VRegister r = static_cast<VRegister>(i);
-    __ PushDouble(r);
-  }
-
-  // Set up THR, which caches the current thread in Dart code.
-  if (THR != R3) {
-    __ mov(THR, R3);
-  }
-  // Refresh write barrier mask.
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-
-  // Save the current VMTag on the stack.
-  __ LoadFromOffset(R4, THR, Thread::vm_tag_offset());
-  __ Push(R4);
-
-  // Save top resource and top exit frame info. Use R6 as a temporary register.
-  // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(R6, THR, Thread::top_resource_offset());
-  __ StoreToOffset(ZR, THR, Thread::top_resource_offset());
-  __ Push(R6);
-  __ LoadFromOffset(R6, THR, Thread::top_exit_frame_info_offset());
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-  // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -22);
-  __ Push(R6);
-
-  // Mark that the thread is executing Dart code. Do this after initializing the
-  // exit link for the profiler.
-  __ LoadImmediate(R6, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R6, THR, Thread::vm_tag_offset());
-
-  // Load arguments descriptor array into R4, which is passed to Dart code.
-  __ mov(R4, R1);
-
-  // Load number of arguments into R5 and adjust count for type arguments.
-  __ LoadFieldFromOffset(R5, R4, ArgumentsDescriptor::count_offset());
-  __ LoadFieldFromOffset(R3, R4, ArgumentsDescriptor::type_args_len_offset());
-  __ AddImmediate(TMP, R5, 1);  // Include the type arguments.
-  __ cmp(R3, Operand(0));
-  __ csinc(R5, R5, TMP, EQ);  // R5 <- (R3 == 0) ? R5 : TMP + 1 (R5 : R5 + 2).
-  __ SmiUntag(R5);
-
-  // R2 points to first argument.
-  // Set up arguments for the Dart call.
-  Label push_arguments;
-  Label done_push_arguments;
-  __ cmp(R5, Operand(0));
-  __ b(&done_push_arguments, EQ);  // check if there are arguments.
-  __ LoadImmediate(R1, 0);
-  __ Bind(&push_arguments);
-  __ ldr(R3, Address(R2));
-  __ Push(R3);
-  __ add(R1, R1, Operand(1));
-  __ add(R2, R2, Operand(kWordSize));
-  __ cmp(R1, Operand(R5));
-  __ b(&push_arguments, LT);
-  __ Bind(&done_push_arguments);
-
-  // We now load the pool pointer(PP) with a GC safe value as we are about to
-  // invoke dart code. We don't need a real object pool here.
-  // Smi zero does not work because ARM64 assumes PP to be untagged.
-  __ LoadObject(PP, Object::null_object());
-
-  // Call the Dart code entrypoint.
-  __ mov(CODE_REG, R0);
-  __ ldr(R0, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ blr(R0);  // R4 is the arguments descriptor array.
-
-  // Get rid of arguments pushed on the stack.
-  __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
-
-  // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure. Uses R6 as a temporary register for this.
-  __ Pop(R6);
-  __ StoreToOffset(R6, THR, Thread::top_exit_frame_info_offset());
-  __ Pop(R6);
-  __ StoreToOffset(R6, THR, Thread::top_resource_offset());
-
-  // Restore the current VMTag from the stack.
-  __ Pop(R4);
-  __ StoreToOffset(R4, THR, Thread::vm_tag_offset());
-
-  // Restore the bottom 64-bits of callee-saved V registers.
-  for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
-    const VRegister r = static_cast<VRegister>(i);
-    __ PopDouble(r);
-  }
-
-  // Restore C++ ABI callee-saved registers.
-  for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
-    Register r = static_cast<Register>(i);
-    // We use ldr instead of the Pop macro because we will be popping the PP
-    // register when it is not holding a pool-pointer since we are returning to
-    // C++ code. We also skip the dart stack pointer SP, since we are still
-    // using it as the stack pointer.
-    __ ldr(r, Address(SP, 1 * kWordSize, Address::PostIndex));
-  }
-
-  // Restore the frame pointer and C stack pointer and return.
-  __ LeaveFrame();
-  __ Drop(1);
-  __ RestoreCSP();
-  __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-}
-
-// Called for inline allocation of contexts.
-// Input:
-//   R1: number of context variables.
-// Output:
-//   R0: new allocated RawContext object.
-void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
-  if (FLAG_inline_alloc) {
-    Label slow_case;
-    // First compute the rounded instance size.
-    // R1: number of context variables.
-    intptr_t fixed_size_plus_alignment_padding =
-        sizeof(RawContext) + kObjectAlignment - 1;
-    __ LoadImmediate(R2, fixed_size_plus_alignment_padding);
-    __ add(R2, R2, Operand(R1, LSL, 3));
-    ASSERT(kSmiTagShift == 1);
-    __ andi(R2, R2, Immediate(~(kObjectAlignment - 1)));
-
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, R4, &slow_case));
-    // Now allocate the object.
-    // R1: number of context variables.
-    // R2: object size.
-    const intptr_t cid = kContextCid;
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ ldr(R0, Address(THR, Thread::top_offset()));
-    __ add(R3, R2, Operand(R0));
-    // Check if the allocation fits into the remaining space.
-    // R0: potential new object.
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: potential next object start.
-    __ ldr(TMP, Address(THR, Thread::end_offset()));
-    __ CompareRegisters(R3, TMP);
-    if (FLAG_use_slow_path) {
-      __ b(&slow_case);
-    } else {
-      __ b(&slow_case, CS);  // Branch if unsigned higher or equal.
-    }
-
-    // Successfully allocated the object, now update top to point to
-    // next object start and initialize the object.
-    // R0: new object.
-    // R1: number of context variables.
-    // R2: object size.
-    // R3: next object start.
-    __ str(R3, Address(THR, Thread::top_offset()));
-    __ add(R0, R0, Operand(kHeapObjectTag));
-    NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R2, space));
-
-    // Calculate the size tag.
-    // R0: new object.
-    // R1: number of context variables.
-    // R2: object size.
-    const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
-    __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag);
-    // If no size tag overflow, shift R2 left, else set R2 to zero.
-    __ LslImmediate(TMP, R2, shift);
-    __ csel(R2, TMP, R2, LS);
-    __ csel(R2, ZR, R2, HI);
-
-    // Get the class index and insert it into the tags.
-    // R2: size and bit tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ LoadImmediate(TMP, tags);
-    __ orr(R2, R2, Operand(TMP));
-    __ StoreFieldToOffset(R2, R0, Context::tags_offset());
-
-    // Setup up number of context variables field.
-    // R0: new object.
-    // R1: number of context variables as integer value (not object).
-    __ StoreFieldToOffset(R1, R0, Context::num_variables_offset());
-
-    // Setup the parent field.
-    // R0: new object.
-    // R1: number of context variables.
-    __ LoadObject(R2, Object::null_object());
-    __ StoreFieldToOffset(R2, R0, Context::parent_offset());
-
-    // Initialize the context variables.
-    // R0: new object.
-    // R1: number of context variables.
-    // R2: raw null.
-    Label loop, done;
-    __ AddImmediate(R3, R0, Context::variable_offset(0) - kHeapObjectTag);
-    __ Bind(&loop);
-    __ subs(R1, R1, Operand(1));
-    __ b(&done, MI);
-    __ str(R2, Address(R3, R1, UXTX, Address::Scaled));
-    __ b(&loop, NE);  // Loop if R1 not zero.
-    __ Bind(&done);
-
-    // Done allocating and initializing the context.
-    // R0: new object.
-    __ ret();
-
-    __ Bind(&slow_case);
-  }
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  __ SmiTag(R1);
-  __ PushObject(Object::null_object());
-  __ Push(R1);
-  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
-  __ Drop(1);  // Pop number of context variables argument.
-  __ Pop(R0);  // Pop the new context object.
-  // R0: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
-  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
-    if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
-
-    Register reg = static_cast<Register>(i);
-    intptr_t start = __ CodeSize();
-    __ Push(LR);
-    __ Push(kWriteBarrierObjectReg);
-    __ mov(kWriteBarrierObjectReg, reg);
-    __ ldr(LR, Address(THR, Thread::write_barrier_entry_point_offset()));
-    __ blr(LR);
-    __ Pop(kWriteBarrierObjectReg);
-    __ Pop(LR);
-    __ ret(LR);
-    intptr_t end = __ CodeSize();
-
-    RELEASE_ASSERT(end - start == kStoreBufferWrapperSize);
-  }
-}
-
-// Helper stub to implement Assembler::StoreIntoObject/Array.
-// Input parameters:
-//   R1: Object (old)
-//   R0: Value (old or new)
-//  R25: Slot
-// If R0 is new, add R1 to the store buffer. Otherwise R0 is old, mark R0
-// and add it to the mark list.
-COMPILE_ASSERT(kWriteBarrierObjectReg == R1);
-COMPILE_ASSERT(kWriteBarrierValueReg == R0);
-COMPILE_ASSERT(kWriteBarrierSlotReg == R25);
-static void GenerateWriteBarrierStubHelper(Assembler* assembler,
-                                           Address stub_code,
-                                           bool cards) {
-  Label add_to_mark_stack, remember_card;
-  __ tbz(&add_to_mark_stack, R0, kNewObjectBitPosition);
-
-  if (cards) {
-    __ LoadFieldFromOffset(TMP, R1, Object::tags_offset(), kWord);
-    __ tbnz(&remember_card, TMP, RawObject::kCardRememberedBit);
-  } else {
-#if defined(DEBUG)
-    Label ok;
-    __ LoadFieldFromOffset(TMP, R1, Object::tags_offset(), kWord);
-    __ tbz(&ok, TMP, RawObject::kCardRememberedBit);
-    __ Stop("Wrong barrier");
-    __ Bind(&ok);
-#endif
-  }
-
-  // Save values being destroyed.
-  __ Push(R2);
-  __ Push(R3);
-  __ Push(R4);
-
-  // Atomically set the remembered bit of the object header.
-  ASSERT(Object::tags_offset() == 0);
-  __ sub(R3, R1, Operand(kHeapObjectTag));
-  // R3: Untagged address of header word (ldxr/stxr do not support offsets).
-  // Note that we use 32 bit operations here to match the size of the
-  // background sweeper which is also manipulating this 32 bit word.
-  Label retry;
-  __ Bind(&retry);
-  __ ldxr(R2, R3, kWord);
-  __ AndImmediate(R2, R2, ~(1 << RawObject::kOldAndNotRememberedBit));
-  __ stxr(R4, R2, R3, kWord);
-  __ cbnz(&retry, R4);
-
-  // Load the StoreBuffer block out of the thread. Then load top_ out of the
-  // StoreBufferBlock and add the address to the pointers_.
-  __ LoadFromOffset(R4, THR, Thread::store_buffer_block_offset());
-  __ LoadFromOffset(R2, R4, StoreBufferBlock::top_offset(), kUnsignedWord);
-  __ add(R3, R4, Operand(R2, LSL, kWordSizeLog2));
-  __ StoreToOffset(R1, R3, StoreBufferBlock::pointers_offset());
-
-  // Increment top_ and check for overflow.
-  // R2: top_.
-  // R4: StoreBufferBlock.
-  Label overflow;
-  __ add(R2, R2, Operand(1));
-  __ StoreToOffset(R2, R4, StoreBufferBlock::top_offset(), kUnsignedWord);
-  __ CompareImmediate(R2, StoreBufferBlock::kSize);
-  // Restore values.
-  __ Pop(R4);
-  __ Pop(R3);
-  __ Pop(R2);
-  __ b(&overflow, EQ);
-  __ ret();
-
-  // Handle overflow: Call the runtime leaf function.
-  __ Bind(&overflow);
-  // Setup frame, push callee-saved registers.
-
-  __ Push(CODE_REG);
-  __ ldr(CODE_REG, stub_code);
-  __ EnterCallRuntimeFrame(0 * kWordSize);
-  __ mov(R0, THR);
-  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
-  // Restore callee-saved registers, tear down frame.
-  __ LeaveCallRuntimeFrame();
-  __ Pop(CODE_REG);
-  __ ret();
-
-  __ Bind(&add_to_mark_stack);
-  __ Push(R2);  // Spill.
-  __ Push(R3);  // Spill.
-  __ Push(R4);  // Spill.
-
-  // Atomically clear kOldAndNotMarkedBit.
-  // Note that we use 32 bit operations here to match the size of the
-  // background sweeper which is also manipulating this 32 bit word.
-  Label marking_retry, lost_race, marking_overflow;
-  ASSERT(Object::tags_offset() == 0);
-  __ sub(R3, R0, Operand(kHeapObjectTag));
-  // R3: Untagged address of header word (ldxr/stxr do not support offsets).
-  __ Bind(&marking_retry);
-  __ ldxr(R2, R3, kWord);
-  __ tbz(&lost_race, R2, RawObject::kOldAndNotMarkedBit);
-  __ AndImmediate(R2, R2, ~(1 << RawObject::kOldAndNotMarkedBit));
-  __ stxr(R4, R2, R3, kWord);
-  __ cbnz(&marking_retry, R4);
-
-  __ LoadFromOffset(R4, THR, Thread::marking_stack_block_offset());
-  __ LoadFromOffset(R2, R4, MarkingStackBlock::top_offset(), kUnsignedWord);
-  __ add(R3, R4, Operand(R2, LSL, kWordSizeLog2));
-  __ StoreToOffset(R0, R3, MarkingStackBlock::pointers_offset());
-  __ add(R2, R2, Operand(1));
-  __ StoreToOffset(R2, R4, MarkingStackBlock::top_offset(), kUnsignedWord);
-  __ CompareImmediate(R2, MarkingStackBlock::kSize);
-  __ Pop(R4);  // Unspill.
-  __ Pop(R3);  // Unspill.
-  __ Pop(R2);  // Unspill.
-  __ b(&marking_overflow, EQ);
-  __ ret();
-
-  __ Bind(&marking_overflow);
-  __ Push(CODE_REG);
-  __ ldr(CODE_REG, stub_code);
-  __ EnterCallRuntimeFrame(0 * kWordSize);
-  __ mov(R0, THR);
-  __ CallRuntime(kMarkingStackBlockProcessRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ Pop(CODE_REG);
-  __ ret();
-
-  __ Bind(&lost_race);
-  __ Pop(R4);  // Unspill.
-  __ Pop(R3);  // Unspill.
-  __ Pop(R2);  // Unspill.
-  __ ret();
-
-  if (cards) {
-    Label remember_card_slow;
-
-    // Get card table.
-    __ Bind(&remember_card);
-    __ AndImmediate(TMP, R1, kPageMask);                       // HeapPage.
-    __ ldr(TMP, Address(TMP, HeapPage::card_table_offset()));  // Card table.
-    __ cbz(&remember_card_slow, TMP);
-
-    // Dirty the card.
-    __ AndImmediate(TMP, R1, kPageMask);  // HeapPage.
-    __ sub(R25, R25, Operand(TMP));       // Offset in page.
-    __ ldr(TMP, Address(TMP, HeapPage::card_table_offset()));  // Card table.
-    __ add(TMP, TMP,
-           Operand(R25, LSR, HeapPage::kBytesPerCardLog2));  // Card address.
-    __ str(R1, Address(TMP, 0),
-           kUnsignedByte);  // Low byte of R1 is non-zero from object tag.
-    __ ret();
-
-    // Card table not yet allocated.
-    __ Bind(&remember_card_slow);
-    __ Push(CODE_REG);
-    __ PushPair(R0, R1);
-    __ ldr(CODE_REG, stub_code);
-    __ mov(R0, R1);   // Arg0 = Object
-    __ mov(R1, R25);  // Arg1 = Slot
-    __ EnterCallRuntimeFrame(0);
-    __ CallRuntime(kRememberCardRuntimeEntry, 2);
-    __ LeaveCallRuntimeFrame();
-    __ PopPair(R0, R1);
-    __ Pop(CODE_REG);
-    __ ret();
-  }
-}
-
-void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::write_barrier_code_offset()), false);
-}
-
-void StubCode::GenerateArrayWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::array_write_barrier_code_offset()), true);
-}
-
-// Called for inline allocation of objects.
-// Input parameters:
-//   LR : return address.
-//   SP + 0 : type arguments object (only if class is parameterized).
-void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
-                                              const Class& cls) {
-  // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
-  ASSERT(!is_cls_parameterized ||
-         (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
-
-  const Register kTypeArgumentsReg = R1;
-  const Register kInstanceReg = R0;
-  const Register kNullReg = R3;
-  const Register kTempReg = R4;
-  const Register kTopReg = R5;
-
-  // 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 = cls.instance_size();
-  ASSERT(instance_size > 0);
-  if (is_cls_parameterized) {
-    __ ldr(kTypeArgumentsReg, Address(SP));
-  }
-  Isolate* isolate = Isolate::Current();
-
-  __ LoadObject(kNullReg, Object::null_object());
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
-      !cls.TraceAllocation(isolate)) {
-    Label slow_case;
-    // Allocate the object & initialize header word.
-    __ TryAllocate(cls, &slow_case, kInstanceReg, kTopReg,
-                   /*tag_result=*/false);
-
-    // Initialize the remaining words of the object.
-    if (instance_size < (kInlineInstanceSize * kWordSize)) {
-      intptr_t current_offset = Instance::NextFieldOffset();
-      while ((current_offset + kWordSize) < instance_size) {
-        __ stp(kNullReg, kNullReg,
-               Address(kInstanceReg, current_offset, Address::PairOffset));
-        current_offset += 2 * kWordSize;
-      }
-      while (current_offset < instance_size) {
-        __ str(kNullReg, Address(kInstanceReg, current_offset));
-        current_offset += kWordSize;
-      }
-    } else {
-      __ AddImmediate(kTempReg, kInstanceReg, Instance::NextFieldOffset());
-      Label done, init_loop;
-      __ Bind(&init_loop);
-      __ CompareRegisters(kTempReg, kTopReg);
-      __ b(&done, CS);
-      __ str(kNullReg, Address(kTempReg, kWordSize, Address::PostIndex));
-      __ b(&init_loop);
-
-      __ Bind(&done);
-    }
-    if (is_cls_parameterized) {
-      __ StoreToOffset(kTypeArgumentsReg, kInstanceReg,
-                       cls.type_arguments_field_offset());
-    }
-    __ add(kInstanceReg, kInstanceReg, Operand(kHeapObjectTag));
-    __ ret();
-
-    __ Bind(&slow_case);
-  }
-
-  // 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, cls);
-  __ PushPair(R0, kNullReg);  // Pushes cls, result slot.
-  __ Push(is_cls_parameterized ? kTypeArgumentsReg : kNullReg);
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ ldr(kInstanceReg,
-         Address(SP, 2 * kWordSize));  // Pop result (newly allocated object).
-  __ LeaveStubFrame();                 // Restores correct SP.
-  __ ret();
-}
-
-// 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.
-// Input parameters:
-//  LR : return address.
-//  SP : address of last argument.
-//  R4: arguments descriptor array.
-void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) {
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset());
-  __ add(TMP, FP, Operand(R2, LSL, 2));  // R2 is Smi.
-  __ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize);
-
-  // Push space for the return value.
-  // Push the receiver.
-  // Push arguments descriptor array.
-  __ Push(ZR);
-  __ Push(R6);
-  __ Push(R4);
-
-  // Adjust arguments count.
-  __ LoadFieldFromOffset(R3, R4, ArgumentsDescriptor::type_args_len_offset());
-  __ AddImmediate(TMP, R2, 1);  // Include the type arguments.
-  __ cmp(R3, Operand(0));
-  __ csinc(R2, R2, TMP, EQ);  // R2 <- (R3 == 0) ? R2 : TMP + 1 (R2 : R2 + 2).
-
-  // R2: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-
-  const intptr_t kNumArgs = 3;
-  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
-  // noSuchMethod on closures always throws an error, so it will never return.
-  __ brk(0);
-}
-
-//  R6: function object.
-//  R5: inline cache data object.
-// Cannot use function object from ICData as it may be the inlined
-// function and not the top-scope function.
-void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register ic_reg = R5;
-  Register func_reg = R6;
-  if (FLAG_trace_optimized_ic_calls) {
-    __ EnterStubFrame();
-    __ Push(R6);        // Preserve.
-    __ Push(R5);        // Preserve.
-    __ Push(ic_reg);    // Argument.
-    __ Push(func_reg);  // Argument.
-    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
-    __ Drop(2);  // Discard argument;
-    __ Pop(R5);  // Restore.
-    __ Pop(R6);  // Restore.
-    __ LeaveStubFrame();
-  }
-  __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset(), kWord);
-  __ add(R7, R7, Operand(1));
-  __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset(), kWord);
-}
-
-// Loads function into 'temp_reg'.
-void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
-                                             Register temp_reg) {
-  if (FLAG_optimization_counter_threshold >= 0) {
-    Register ic_reg = R5;
-    Register func_reg = temp_reg;
-    ASSERT(temp_reg == R6);
-    __ Comment("Increment function counter");
-    __ LoadFieldFromOffset(func_reg, ic_reg, ICData::owner_offset());
-    __ LoadFieldFromOffset(R7, func_reg, Function::usage_counter_offset(),
-                           kWord);
-    __ AddImmediate(R7, 1);
-    __ StoreFieldToOffset(R7, func_reg, Function::usage_counter_offset(),
-                          kWord);
-  }
-}
-
-// Note: R5 must be preserved.
-// Attempt a quick Smi operation for known operations ('kind'). The ICData
-// must have been primed with a Smi/Smi check that will be used for counting
-// the invocations.
-static void EmitFastSmiOp(Assembler* assembler,
-                          Token::Kind kind,
-                          intptr_t num_args,
-                          Label* not_smi_or_overflow) {
-  __ Comment("Fast Smi op");
-  __ ldr(R0, Address(SP, +0 * kWordSize));  // Right.
-  __ ldr(R1, Address(SP, +1 * kWordSize));  // Left.
-  __ orr(TMP, R0, Operand(R1));
-  __ BranchIfNotSmi(TMP, not_smi_or_overflow);
-  switch (kind) {
-    case Token::kADD: {
-      __ adds(R0, R1, Operand(R0));   // Adds.
-      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
-      break;
-    }
-    case Token::kSUB: {
-      __ subs(R0, R1, Operand(R0));   // Subtract.
-      __ b(not_smi_or_overflow, VS);  // Branch if overflow.
-      break;
-    }
-    case Token::kEQ: {
-      __ CompareRegisters(R0, R1);
-      __ LoadObject(R0, Bool::True());
-      __ LoadObject(R1, Bool::False());
-      __ csel(R0, R1, R0, NE);
-      break;
-    }
-    default:
-      UNIMPLEMENTED();
-  }
-
-  // R5: IC data object (preserved).
-  __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
-// R6: points directly to the first ic data array element.
-#if defined(DEBUG)
-  // Check that first entry is for Smi/Smi.
-  Label error, ok;
-  const intptr_t imm_smi_cid = reinterpret_cast<intptr_t>(Smi::New(kSmiCid));
-  __ ldr(R1, Address(R6, 0));
-  __ CompareImmediate(R1, imm_smi_cid);
-  __ b(&error, NE);
-  __ ldr(R1, Address(R6, kWordSize));
-  __ CompareImmediate(R1, imm_smi_cid);
-  __ b(&ok, EQ);
-  __ Bind(&error);
-  __ Stop("Incorrect IC data");
-  __ Bind(&ok);
-#endif
-  if (FLAG_optimization_counter_threshold >= 0) {
-    const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-    // Update counter, ignore overflow.
-    __ LoadFromOffset(R1, R6, count_offset);
-    __ adds(R1, R1, Operand(Smi::RawValue(1)));
-    __ StoreToOffset(R1, R6, count_offset);
-  }
-
-  __ ret();
-}
-
-// Generate inline cache check for 'num_args'.
-//  LR: return address.
-//  R5: inline cache data object.
-// Control flow:
-// - If receiver is null -> jump to IC miss.
-// - If receiver is Smi -> load Smi class.
-// - If receiver is not-Smi -> load receiver's class.
-// - Check if 'num_args' (including receiver) match any IC data group.
-// - Match found -> jump to target.
-// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(
-    Assembler* assembler,
-    intptr_t num_args,
-    const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind,
-    bool optimized,
-    bool exactness_check /* = false */) {
-  ASSERT(!exactness_check);
-  ASSERT(num_args == 1 || num_args == 2);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == num_args.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag,
-                      kUnsignedWord);
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R6, num_args);
-    __ b(&ok, EQ);
-    __ Stop("Incorrect stub for IC data");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  Label stepping, done_stepping;
-  if (!optimized) {
-    __ Comment("Check single stepping");
-    __ LoadIsolate(R6);
-    __ LoadFromOffset(R6, R6, Isolate::single_step_offset(), kUnsignedByte);
-    __ CompareRegisters(R6, ZR);
-    __ b(&stepping, NE);
-    __ Bind(&done_stepping);
-  }
-#endif
-
-  Label not_smi_or_overflow;
-  if (kind != Token::kILLEGAL) {
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-  }
-  __ Bind(&not_smi_or_overflow);
-
-  __ Comment("Extract ICData initial values and receiver cid");
-  // Load arguments descriptor into R4.
-  __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset());
-  // Loop that checks if there is an IC data match.
-  Label loop, found, miss;
-  // R5: IC data object (preserved).
-  __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
-  // R6: ic_data_array with check entries: classes and target functions.
-  __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
-
-  // 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, ArgumentsDescriptor::count_offset());
-  __ SmiUntag(R7);  // Untag so we can use the LSL 3 addressing mode.
-  __ sub(R7, R7, Operand(1));
-
-  // R0 <- [SP + (R7 << 3)]
-  __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled));
-  __ LoadTaggedClassIdMayBeSmi(R0, R0);
-
-  if (num_args == 2) {
-    __ AddImmediate(R1, R7, -1);
-    // R1 <- [SP + (R1 << 3)]
-    __ ldr(R1, Address(SP, R1, UXTX, Address::Scaled));
-    __ LoadTaggedClassIdMayBeSmi(R1, R1);
-  }
-
-  // We unroll the generic one that is generated once more than the others.
-  const bool optimize = kind == Token::kILLEGAL;
-
-  __ Comment("ICData loop");
-  __ Bind(&loop);
-  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
-    Label update;
-
-    __ LoadFromOffset(R2, R6, 0);
-    __ CompareRegisters(R0, R2);  // Class id match?
-    if (num_args == 2) {
-      __ b(&update, NE);  // Continue.
-      __ LoadFromOffset(R2, R6, kWordSize);
-      __ CompareRegisters(R1, R2);  // Class id match?
-    }
-    __ b(&found, EQ);  // Break.
-
-    __ Bind(&update);
-
-    const intptr_t entry_size =
-        ICData::TestEntryLengthFor(num_args, exactness_check) * kWordSize;
-    __ AddImmediate(R6, entry_size);  // Next entry.
-
-    __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));  // Done?
-    if (unroll == 0) {
-      __ b(&loop, NE);
-    } else {
-      __ b(&miss, EQ);
-    }
-  }
-
-  __ Bind(&miss);
-  __ Comment("IC miss");
-  // Compute address of arguments.
-  // R7: argument_count - 1 (untagged).
-  // R7 <- SP + (R7 << 3)
-  __ add(R7, SP, Operand(R7, UXTX, 3));  // R7 is Untagged.
-  // R7: address of receiver.
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Preserve IC data object and arguments descriptor array and
-  // setup space on stack for result (target code object).
-  __ Push(R4);  // Preserve arguments descriptor array.
-  __ Push(R5);  // Preserve IC Data.
-  // Setup space on stack for the result (target code object).
-  __ Push(ZR);
-  // Push call arguments.
-  for (intptr_t i = 0; i < num_args; i++) {
-    __ LoadFromOffset(TMP, R7, -i * kWordSize);
-    __ Push(TMP);
-  }
-  // Pass IC data object.
-  __ Push(R5);
-  __ CallRuntime(handle_ic_miss, num_args + 1);
-  // Remove the call arguments pushed earlier, including the IC data object.
-  __ Drop(num_args + 1);
-  // Pop returned function object into R0.
-  // Restore arguments descriptor array and IC data array.
-  __ Pop(R0);  // Pop returned function object into R0.
-  __ Pop(R5);  // Restore IC Data.
-  __ Pop(R4);  // Restore arguments descriptor array.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  Label call_target_function;
-  if (!FLAG_lazy_dispatchers) {
-    GenerateDispatcherCode(assembler, &call_target_function);
-  } else {
-    __ b(&call_target_function);
-  }
-
-  __ Bind(&found);
-  __ Comment("Update caller's counter");
-  // R6: pointer to an IC data check group.
-  const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-  __ LoadFromOffset(R0, R6, target_offset);
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    // Update counter, ignore overflow.
-    __ LoadFromOffset(R1, R6, count_offset);
-    __ adds(R1, R1, Operand(Smi::RawValue(1)));
-    __ StoreToOffset(R1, R6, count_offset);
-  }
-
-  __ Comment("Call target");
-  __ Bind(&call_target_function);
-  // R0: target function.
-  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-  __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
-  __ br(R2);
-
-#if !defined(PRODUCT)
-  if (!optimized) {
-    __ Bind(&stepping);
-    __ EnterStubFrame();
-    __ Push(R5);  // Preserve IC data.
-    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ Pop(R5);
-    __ RestoreCodePointer();
-    __ LeaveStubFrame();
-    __ b(&done_stepping);
-  }
-#endif
-}
-
-// Use inline cache data array to invoke the target or continue in inline
-// cache miss handler. Stub for 1-argument check (receiver class).
-//  LR: return address.
-//  R5: inline cache data object.
-// Inline cache data object structure:
-// 0: function-name
-// 1: N, number of arguments checked.
-// 2 .. (length - 1): group of checks, each check containing:
-//   - N classes.
-//   - 1 target function.
-void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  __ Stop("Unimplemented");
-}
-
-void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL);
-}
-
-void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
-}
-
-void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
-}
-
-void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
-}
-
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
-                                    Token::kILLEGAL, true /* optimized */);
-}
-
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  __ Stop("Unimplemented");
-}
-
-void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL, true /* optimized */);
-}
-
-void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == 0.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ LoadFromOffset(R6, R5, ICData::state_bits_offset() - kHeapObjectTag,
-                      kUnsignedWord);
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ andi(R6, R6, Immediate(ICData::NumArgsTestedMask()));
-    __ CompareImmediate(R6, 0);
-    __ b(&ok, EQ);
-    __ Stop("Incorrect IC data for unoptimized static call");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-  // Check single stepping.
-#if !defined(PRODUCT)
-  Label stepping, done_stepping;
-  __ LoadIsolate(R6);
-  __ LoadFromOffset(R6, R6, Isolate::single_step_offset(), kUnsignedByte);
-  __ CompareImmediate(R6, 0);
-  __ b(&stepping, NE);
-  __ Bind(&done_stepping);
-#endif
-
-  // R5: IC data object (preserved).
-  __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset());
-  // R6: ic_data_array with entries: target functions and count.
-  __ AddImmediate(R6, Array::data_offset() - kHeapObjectTag);
-  // R6: points directly to the first ic data array element.
-  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    // Increment count for this call, ignore overflow.
-    __ LoadFromOffset(R1, R6, count_offset);
-    __ adds(R1, R1, Operand(Smi::RawValue(1)));
-    __ StoreToOffset(R1, R6, count_offset);
-  }
-
-  // Load arguments descriptor into R4.
-  __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset());
-
-  // Get function and call it, if possible.
-  __ LoadFromOffset(R0, R6, target_offset);
-  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-  __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
-  __ br(R2);
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ Push(R5);  // Preserve IC data.
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ Pop(R5);
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ b(&done_stepping);
-#endif
-}
-
-void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
-}
-
-// Stub for compiling a function and jumping to the compiled code.
-// R4: Arguments descriptor.
-// R0: Function.
-void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
-  // Preserve arg desc.
-  __ EnterStubFrame();
-  __ Push(R4);  // Save arg. desc.
-  __ Push(R0);  // Pass function.
-  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
-  __ Pop(R0);  // Restore argument.
-  __ Pop(R4);  // Restore arg desc.
-  __ LeaveStubFrame();
-
-  // When using the interpreter, the function's code may now point to the
-  // InterpretCall stub. Make sure R0, R4, and R5 are preserved.
-  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-  __ LoadFieldFromOffset(R2, R0, Function::entry_point_offset());
-  __ br(R2);
-}
-
-// Stub for interpreting a function call.
-// R4: Arguments descriptor.
-// R0: Function.
-void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter")
-#else
-  __ SetPrologueOffset();
-  __ EnterStubFrame();
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R8, THR, Thread::vm_tag_offset());
-    __ CompareImmediate(R8, VMTag::kDartCompiledTagId);
-    __ b(&ok, EQ);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Adjust arguments count for type arguments vector.
-  __ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset());
-  __ SmiUntag(R2);
-  __ LoadFieldFromOffset(R1, R4, ArgumentsDescriptor::type_args_len_offset());
-  __ cmp(R1, Operand(0));
-  __ csinc(R2, R2, R2, EQ);  // R2 <- (R1 == 0) ? R2 : R2 + 1.
-
-  // Compute argv.
-  __ add(R3, ZR, Operand(R2, LSL, 3));
-  __ add(R3, FP, Operand(R3));
-  __ AddImmediate(R3, kParamEndSlotFromFp * kWordSize);
-
-  // Indicate decreasing memory addresses of arguments with negative argc.
-  __ neg(R2, R2);
-
-  // Align frame before entering C++ world. No shadow stack space required.
-  __ ReserveAlignedFrameSpace(0 * kWordSize);
-
-  // Pass arguments in registers.
-  // R0: Function.
-  __ mov(R1, R4);  // Arguments descriptor.
-  // R2: Negative argc.
-  // R3: Argv.
-  __ mov(R4, THR);  // Thread.
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to Dart VM C++ code.
-  __ StoreToOffset(FP, THR, Thread::top_exit_frame_info_offset());
-
-  // Mark that the thread is executing VM code.
-  __ LoadFromOffset(R5, THR, Thread::interpret_call_entry_point_offset());
-  __ StoreToOffset(R5, THR, Thread::vm_tag_offset());
-
-  // We are entering runtime code, so the C stack pointer must be restored from
-  // the stack limit to the top of the stack. We cache the stack limit address
-  // in a callee-saved register.
-  __ mov(R25, CSP);
-  __ mov(CSP, SP);
-
-  __ blr(R5);
-
-  // Restore SP and CSP.
-  __ mov(SP, CSP);
-  __ mov(CSP, R25);
-
-  // Refresh write barrier mask.
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-
-  // Mark that the thread is executing Dart code.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
-
-  // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-
-  __ LeaveStubFrame();
-  __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-}
-
-// R5: Contains an ICData.
-void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(R5);
-  __ Push(ZR);  // Space for result.
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ Pop(CODE_REG);
-  __ Pop(R5);
-  __ LeaveStubFrame();
-  __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
-  __ br(R0);
-}
-
-void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(ZR);  // Space for result.
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ Pop(CODE_REG);
-  __ LeaveStubFrame();
-  __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
-  __ br(R0);
-}
-
-// Called only from unoptimized code. All relevant registers have been saved.
-void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) {
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(R1);
-  __ LoadFromOffset(R1, R1, Isolate::single_step_offset(), kUnsignedByte);
-  __ CompareImmediate(R1, 0);
-  __ b(&stepping, NE);
-  __ Bind(&done_stepping);
-
-  __ ret();
-
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ LeaveStubFrame();
-  __ b(&done_stepping);
-}
-
-// Used to check class and type arguments. Arguments passed in registers:
-// LR: return address.
-// R0: instance (must be preserved).
-// R1: instantiator type arguments (only if n == 4, can be raw_null).
-// R2: function type arguments (only if n == 4, can be raw_null).
-// R3: SubtypeTestCache.
-//
-// Preserves R0/R2/R8.
-//
-// Result in R1: null -> not found, otherwise result (true or false).
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
-
-  const Register kCacheReg = R3;
-  const Register kInstanceReg = R0;
-  const Register kInstantiatorTypeArgumentsReg = R1;
-  const Register kFunctionTypeArgumentsReg = R2;
-
-  const Register kInstanceCidOrFunction = R6;
-  const Register kInstanceInstantiatorTypeArgumentsReg = R4;
-  const Register kInstanceParentFunctionTypeArgumentsReg = R9;
-  const Register kInstanceDelayedFunctionTypeArgumentsReg = R10;
-
-  const Register kNullReg = R7;
-
-  __ LoadObject(kNullReg, Object::null_object());
-
-  // Loop initialization (moved up here to avoid having all dependent loads
-  // after each other).
-  __ ldr(kCacheReg, FieldAddress(kCacheReg, SubtypeTestCache::cache_offset()));
-  __ AddImmediate(kCacheReg, Array::data_offset() - kHeapObjectTag);
-
-  Label loop, not_closure;
-  if (n >= 4) {
-    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
-  } else {
-    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
-  }
-  __ CompareImmediate(kInstanceCidOrFunction, kClosureCid);
-  __ b(&not_closure, NE);
-
-  // Closure handling.
-  {
-    __ ldr(kInstanceCidOrFunction,
-           FieldAddress(kInstanceReg, Closure::function_offset()));
-    if (n >= 2) {
-      __ ldr(kInstanceInstantiatorTypeArgumentsReg,
-             FieldAddress(kInstanceReg,
-                          Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        ASSERT(n == 6);
-        __ ldr(kInstanceParentFunctionTypeArgumentsReg,
-               FieldAddress(kInstanceReg,
-                            Closure::function_type_arguments_offset()));
-        __ ldr(kInstanceDelayedFunctionTypeArgumentsReg,
-               FieldAddress(kInstanceReg,
-                            Closure::delayed_type_arguments_offset()));
-      }
-    }
-    __ b(&loop);
-  }
-
-  // Non-Closure handling.
-  {
-    __ Bind(&not_closure);
-    if (n == 1) {
-      __ SmiTag(kInstanceCidOrFunction);
-    } else {
-      ASSERT(n >= 2);
-      Label has_no_type_arguments;
-      // [LoadClassById] also tags [kInstanceCidOrFunction] as a side-effect.
-      __ LoadClassById(R5, kInstanceCidOrFunction);
-      __ mov(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
-      __ LoadFieldFromOffset(
-          R5, R5, Class::type_arguments_field_offset_in_words_offset(), kWord);
-      __ CompareImmediate(R5, Class::kNoTypeArguments);
-      __ b(&has_no_type_arguments, EQ);
-      __ add(R5, kInstanceReg, Operand(R5, LSL, 3));
-      __ ldr(kInstanceInstantiatorTypeArgumentsReg, FieldAddress(R5, 0));
-      __ Bind(&has_no_type_arguments);
-
-      if (n >= 6) {
-        __ mov(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
-        __ mov(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
-      }
-    }
-  }
-
-  Label found, not_found, next_iteration;
-
-  // Loop header
-  __ Bind(&loop);
-  __ ldr(R5, Address(kCacheReg,
-                     kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmp(R5, Operand(kNullReg));
-  __ b(&not_found, EQ);
-  __ cmp(R5, Operand(kInstanceCidOrFunction));
-  if (n == 1) {
-    __ b(&found, EQ);
-  } else {
-    __ b(&next_iteration, NE);
-    __ ldr(R5, Address(kCacheReg,
-                       kWordSize * SubtypeTestCache::kInstanceTypeArguments));
-    __ cmp(R5, Operand(kInstanceInstantiatorTypeArgumentsReg));
-    if (n == 2) {
-      __ b(&found, EQ);
-    } else {
-      __ b(&next_iteration, NE);
-      __ ldr(R5,
-             Address(kCacheReg,
-                     kWordSize * SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmp(R5, Operand(kInstantiatorTypeArgumentsReg));
-      __ b(&next_iteration, NE);
-      __ ldr(R5, Address(kCacheReg,
-                         kWordSize * SubtypeTestCache::kFunctionTypeArguments));
-      __ cmp(R5, Operand(kFunctionTypeArgumentsReg));
-      if (n == 4) {
-        __ b(&found, EQ);
-      } else {
-        ASSERT(n == 6);
-        __ b(&next_iteration, NE);
-
-        __ ldr(R5,
-               Address(
-                   kCacheReg,
-                   kWordSize *
-                       SubtypeTestCache::kInstanceParentFunctionTypeArguments));
-        __ cmp(R5, Operand(kInstanceParentFunctionTypeArgumentsReg));
-        __ b(&next_iteration, NE);
-
-        __ ldr(
-            R5,
-            Address(
-                kCacheReg,
-                kWordSize *
-                    SubtypeTestCache::kInstanceDelayedFunctionTypeArguments));
-        __ cmp(R5, Operand(kInstanceDelayedFunctionTypeArgumentsReg));
-        __ b(&found, EQ);
-      }
-    }
-  }
-  __ Bind(&next_iteration);
-  __ AddImmediate(kCacheReg, kWordSize * SubtypeTestCache::kTestEntryLength);
-  __ b(&loop);
-
-  __ Bind(&found);
-  __ ldr(R1, Address(kCacheReg, kWordSize * SubtypeTestCache::kTestResult));
-  __ ret();
-
-  __ Bind(&not_found);
-  __ mov(R1, kNullReg);
-  __ ret();
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-// Used to test whether a given value is of a given type (different variants,
-// all have the same calling convention).
-//
-// Inputs:
-//   - R0 : instance to test against.
-//   - R2 : instantiator type arguments (if needed).
-//   - R1 : function type arguments (if needed).
-//
-//   - R3 : subtype test cache.
-//
-//   - R8 : type to test against.
-//   - R4 : name of destination variable.
-//
-// Preserves R0/R2.
-//
-// Note of warning: The caller will not populate CODE_REG and we have therefore
-// no access to the pool.
-void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  Label done;
-
-  const Register kInstanceReg = R0;
-  const Register kDstTypeReg = R8;
-
-  // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(EQUAL, &done);
-
-  // Fast case for 'int'.
-  Label not_smi;
-  __ BranchIfNotSmi(kInstanceReg, &not_smi);
-  __ CompareObject(kDstTypeReg, Object::ZoneHandle(Type::IntType()));
-  __ BranchIf(EQUAL, &done);
-  __ Bind(&not_smi);
-
-  // Tail call the [SubtypeTestCache]-based implementation.
-  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ br(R9);
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Ret();
-}
-
-void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
-  const Register kTypeRefReg = R8;
-
-  // We dereference the TypeRef and tail-call to it's type testing stub.
-  __ ldr(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
-  __ ldr(R9, FieldAddress(kTypeRefReg,
-                          AbstractType::type_test_stub_entry_point_offset()));
-  __ br(R9);
-}
-
-void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
-    Assembler* assembler,
-    HierarchyInfo* hi,
-    const Type& type,
-    const Class& type_class) {
-  const Register kInstanceReg = R0;
-  const Register kClassIdReg = R9;
-
-  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
-                                      kInstanceReg, kClassIdReg);
-
-  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ br(R9);
-}
-
-void TypeTestingStubGenerator::
-    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
-                                                      HierarchyInfo* hi,
-                                                      const Class& type_class,
-                                                      const TypeArguments& tp,
-                                                      const TypeArguments& ta) {
-  const Register kInstanceReg = R0;
-  const Register kInstanceTypeArguments = R7;
-  const Register kClassIdReg = R9;
-
-  BuildOptimizedSubclassRangeCheckWithTypeArguments(
-      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
-      kInstanceTypeArguments);
-}
-
-void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
-    Assembler* assembler,
-    HierarchyInfo* hi,
-    const AbstractType& type_arg,
-    intptr_t type_param_value_offset_i,
-    Label* check_failed) {
-  const Register kInstantiatorTypeArgumentsReg = R1;
-  const Register kFunctionTypeArgumentsReg = R2;
-  const Register kInstanceTypeArguments = R7;
-
-  const Register kClassIdReg = R9;
-  const Register kOwnTypeArgumentValue = TMP;
-
-  BuildOptimizedTypeArgumentValueCheck(
-      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
-      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
-      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
-}
-
-static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
-                                            TypeCheckMode mode) {
-  const Register kInstanceReg = R0;
-  const Register kInstantiatorTypeArgumentsReg = R1;
-  const Register kFunctionTypeArgumentsReg = R2;
-
-  const Register kSubtypeTestCacheReg = R3;
-  const Register kDstTypeReg = R8;
-
-  __ PushObject(Object::null_object());  // Make room for result.
-  __ Push(kInstanceReg);
-  __ Push(kDstTypeReg);
-  __ Push(kInstantiatorTypeArgumentsReg);
-  __ Push(kFunctionTypeArgumentsReg);
-  __ PushObject(Object::null_object());
-  __ Push(kSubtypeTestCacheReg);
-  __ PushObject(Smi::ZoneHandle(Smi::New(mode)));
-  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
-  __ Drop(1);  // mode
-  __ Pop(kSubtypeTestCacheReg);
-  __ Drop(1);  // dst_name
-  __ Pop(kFunctionTypeArgumentsReg);
-  __ Pop(kInstantiatorTypeArgumentsReg);
-  __ Pop(kDstTypeReg);
-  __ Pop(kInstanceReg);
-  __ Drop(1);  // Discard return value.
-}
-
-void StubCode::GenerateLazySpecializeTypeTestStub(Assembler* assembler) {
-  const Register kInstanceReg = R0;
-  Label done;
-
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(EQUAL, &done);
-
-  __ ldr(CODE_REG,
-         Address(THR, Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
-  Label done, call_runtime;
-
-  const Register kInstanceReg = R0;
-  const Register kInstantiatorTypeArgumentsReg = R1;
-  const Register kSubtypeTestCacheReg = R3;
-  const Register kDstTypeReg = R8;
-
-  __ EnterStubFrame();
-
-#ifdef DEBUG
-  // Guaranteed by caller.
-  Label no_error;
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(NOT_EQUAL, &no_error);
-  __ Breakpoint();
-  __ Bind(&no_error);
-#endif
-
-  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
-  __ BranchIf(EQUAL, &call_runtime);
-
-  const Register kTmp = R9;
-
-  // If this is not a [Type] object, we'll go to the runtime.
-  Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, kDstTypeReg);
-  __ cmp(kTmp, Operand(kTypeCid));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is instantiated/uninstantiated.
-  __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::type_state_offset()), kByte);
-  __ cmp(kTmp, Operand(RawType::kFinalizedInstantiated));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is a function type.
-  __ ldr(kTmp, FieldAddress(kDstTypeReg, Type::signature_offset()));
-  __ CompareObject(kTmp, Object::null_object());
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(kInstanceReg, &is_complex_case);
-
-  // Fall through to &is_simple_case
-
-  __ Bind(&is_simple_case);
-  {
-    __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
-    __ BranchLink(StubCode::Subtype2TestCache());
-    __ CompareObject(R1, Bool::True());
-    __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    __ Jump(&call_runtime);
-  }
-
-  __ Bind(&is_complex_case);
-  {
-    __ PushPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
-    __ BranchLink(StubCode::Subtype6TestCache());
-    __ CompareObject(R1, Bool::True());
-    __ PopPair(kInstantiatorTypeArgumentsReg, kSubtypeTestCacheReg);
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    // Fall through to runtime_call
-  }
-
-  __ Bind(&call_runtime);
-
-  // We cannot really ensure here that dynamic/Object/void never occur here
-  // (though it is guaranteed at dart_precompiled_runtime time).  This is
-  // because we do constant evaluation with default stubs and only install
-  // optimized versions before writing out the AOT snapshot.
-  // So dynamic/Object/void will run with default stub in constant evaluation.
-  __ CompareObject(kDstTypeReg, Type::dynamic_type());
-  __ BranchIf(EQUAL, &done);
-  __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
-  __ BranchIf(EQUAL, &done);
-  __ CompareObject(kDstTypeReg, Type::void_type());
-  __ BranchIf(EQUAL, &done);
-
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
-
-  __ Bind(&done);
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
-  __ mov(R0, CSP);
-  __ ret();
-}
-
-// Jump to a frame on the call stack.
-// LR: return address.
-// R0: program_counter.
-// R1: stack_pointer.
-// R2: frame_pointer.
-// R3: thread.
-// Does not return.
-void StubCode::GenerateJumpToFrameStub(Assembler* assembler) {
-  ASSERT(kExceptionObjectReg == R0);
-  ASSERT(kStackTraceObjectReg == R1);
-  __ mov(LR, R0);  // Program counter.
-  __ mov(SP, R1);  // Stack pointer.
-  __ mov(FP, R2);  // Frame_pointer.
-  __ mov(THR, R3);
-  __ ldr(BARRIER_MASK, Address(THR, Thread::write_barrier_mask_offset()));
-  // Set the tag.
-  __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
-  __ StoreToOffset(R2, THR, Thread::vm_tag_offset());
-  // Clear top exit frame.
-  __ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
-  // Restore the pool pointer.
-  __ RestoreCodePointer();
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(PP, Address(THR, Thread::global_object_pool_offset()));
-    __ sub(PP, PP, Operand(kHeapObjectTag));  // Pool in PP is untagged!
-  } else {
-    __ LoadPoolPointer();
-  }
-  __ ret();  // Jump to continuation point.
-}
-
-// Run an exception handler.  Execution comes from JumpToFrame
-// stub or from the simulator.
-//
-// The arguments are stored in the Thread object.
-// Does not return.
-void StubCode::GenerateRunExceptionHandlerStub(Assembler* assembler) {
-  __ LoadFromOffset(LR, THR, Thread::resume_pc_offset());
-
-  ASSERT(Thread::CanLoadFromThread(Object::null_object()));
-  __ LoadFromOffset(R2, THR, Thread::OffsetFromThread(Object::null_object()));
-
-  // Exception object.
-  __ LoadFromOffset(R0, THR, Thread::active_exception_offset());
-  __ StoreToOffset(R2, THR, Thread::active_exception_offset());
-
-  // StackTrace object.
-  __ LoadFromOffset(R1, THR, Thread::active_stacktrace_offset());
-  __ StoreToOffset(R2, THR, Thread::active_stacktrace_offset());
-
-  __ ret();  // Jump to the exception handler code.
-}
-
-// Deoptimize a frame on the call stack before rewinding.
-// The arguments are stored in the Thread object.
-// No result.
-void StubCode::GenerateDeoptForRewindStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG.
-  __ LoadImmediate(TMP, kZapCodeReg);
-  __ Push(TMP);
-
-  // Load the deopt pc into LR.
-  __ LoadFromOffset(LR, THR, Thread::resume_pc_offset());
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-
-  // After we have deoptimized, jump to the correct frame.
-  __ EnterStubFrame();
-  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
-  __ LeaveStubFrame();
-  __ brk(0);
-}
-
-// Calls to the runtime to optimize the given function.
-// R6: function to be re-optimized.
-// R4: argument descriptor (preserved).
-void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(R4);
-  // Setup space on stack for the return value.
-  __ Push(ZR);
-  __ Push(R6);
-  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
-  __ Pop(R0);  // Discard argument.
-  __ Pop(R0);  // Get Function object
-  __ Pop(R4);  // Restore argument descriptor.
-  __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
-  __ LoadFieldFromOffset(R1, R0, Function::entry_point_offset());
-  __ LeaveStubFrame();
-  __ br(R1);
-  __ brk(0);
-}
-
-// Does identical check (object references are equal or not equal) with special
-// checks for boxed numbers.
-// Left and right are pushed on stack.
-// Return Zero condition flag set if equal.
-// Note: A Mint cannot contain a value that would fit in Smi.
-static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
-                                                 const Register left,
-                                                 const Register right) {
-  Label reference_compare, done, check_mint;
-  // If any of the arguments is Smi do reference compare.
-  __ BranchIfSmi(left, &reference_compare);
-  __ BranchIfSmi(right, &reference_compare);
-
-  // Value compare for two doubles.
-  __ CompareClassId(left, kDoubleCid);
-  __ b(&check_mint, NE);
-  __ CompareClassId(right, kDoubleCid);
-  __ b(&done, NE);
-
-  // Double values bitwise compare.
-  __ LoadFieldFromOffset(left, left, Double::value_offset());
-  __ LoadFieldFromOffset(right, right, Double::value_offset());
-  __ b(&reference_compare);
-
-  __ Bind(&check_mint);
-  __ CompareClassId(left, kMintCid);
-  __ b(&reference_compare, NE);
-  __ CompareClassId(right, kMintCid);
-  __ b(&done, NE);
-  __ LoadFieldFromOffset(left, left, Mint::value_offset());
-  __ LoadFieldFromOffset(right, right, Mint::value_offset());
-
-  __ Bind(&reference_compare);
-  __ CompareRegisters(left, right);
-  __ Bind(&done);
-}
-
-// Called only from unoptimized code. All relevant registers have been saved.
-// LR: return address.
-// SP + 4: left operand.
-// SP + 0: right operand.
-// Return Zero condition flag set if equal.
-void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(R1);
-  __ LoadFromOffset(R1, R1, Isolate::single_step_offset(), kUnsignedByte);
-  __ CompareImmediate(R1, 0);
-  __ b(&stepping, NE);
-  __ Bind(&done_stepping);
-#endif
-
-  const Register left = R1;
-  const Register right = R0;
-  __ LoadFromOffset(left, SP, 1 * kWordSize);
-  __ LoadFromOffset(right, SP, 0 * kWordSize);
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
-  __ ret();
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ b(&done_stepping);
-#endif
-}
-
-// Called from optimized code only.
-// LR: return address.
-// SP + 4: left operand.
-// SP + 0: right operand.
-// Return Zero condition flag set if equal.
-void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-  const Register left = R1;
-  const Register right = R0;
-  __ LoadFromOffset(left, SP, 1 * kWordSize);
-  __ LoadFromOffset(right, SP, 0 * kWordSize);
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
-  __ ret();
-}
-
-// Called from megamorphic calls.
-//  R0: receiver
-//  R5: MegamorphicCache (preserved)
-// Passed to target:
-//  CODE_REG: target Code
-//  R4: arguments descriptor
-void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  // Jump if receiver is a smi.
-  Label smi_case;
-  __ BranchIfSmi(R0, &smi_case);
-
-  // Loads the cid of the object.
-  __ LoadClassId(R0, R0);
-
-  Label cid_loaded;
-  __ Bind(&cid_loaded);
-  __ ldr(R2, FieldAddress(R5, MegamorphicCache::buckets_offset()));
-  __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset()));
-  // R2: cache buckets array.
-  // R1: mask as a smi.
-
-  // Make the cid into a smi.
-  __ SmiTag(R0);
-  // R0: class ID of the receiver (smi).
-
-  // Compute the table index.
-  ASSERT(MegamorphicCache::kSpreadFactor == 7);
-  // Use lsl and sub to multiply with 7 == 8 - 1.
-  __ LslImmediate(R3, R0, 3);
-  __ sub(R3, R3, Operand(R0));
-  // R3: probe.
-  Label loop;
-  __ Bind(&loop);
-  __ and_(R3, R3, Operand(R1));
-
-  const intptr_t base = Array::data_offset();
-  // R3 is smi tagged, but table entries are 16 bytes, so LSL 3.
-  __ add(TMP, R2, Operand(R3, LSL, 3));
-  __ ldr(R6, FieldAddress(TMP, base));
-  Label probe_failed;
-  __ CompareRegisters(R6, R0);
-  __ b(&probe_failed, NE);
-
-  Label load_target;
-  __ Bind(&load_target);
-  // Call the target found in the cache.  For a class id match, this is a
-  // proper target for the given name and arguments descriptor.  If the
-  // illegal class id was found, the target is a cache miss handler that can
-  // be invoked as a normal Dart function.
-  const auto target_address = FieldAddress(TMP, base + kWordSize);
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ ldr(R1, target_address);
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
-  } else {
-    __ ldr(R0, target_address);
-    __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
-    __ ldr(ARGS_DESC_REG,
-           FieldAddress(R5, MegamorphicCache::arguments_descriptor_offset()));
-    __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  }
-  __ br(R1);
-
-  // Probe failed, check if it is a miss.
-  __ Bind(&probe_failed);
-  ASSERT(kIllegalCid == 0);
-  __ tst(R6, Operand(R6));
-  __ b(&load_target, EQ);  // branch if miss.
-
-  // Try next extry in the table.
-  __ AddImmediate(R3, Smi::RawValue(1));
-  __ b(&loop);
-
-  // Load cid for the Smi case.
-  __ Bind(&smi_case);
-  __ LoadImmediate(R0, kSmiCid);
-  __ b(&cid_loaded);
-}
-
-// Called from switchable IC calls.
-//  R0: receiver
-//  R5: ICData (preserved)
-// Passed to target:
-//  CODE_REG: target Code object
-//  R4: arguments descriptor
-void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) {
-  Label loop, found, miss;
-  __ ldr(ARGS_DESC_REG,
-         FieldAddress(R5, ICData::arguments_descriptor_offset()));
-  __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
-  __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
-  // R8: first IC entry
-  __ LoadTaggedClassIdMayBeSmi(R1, R0);
-  // R1: receiver cid as Smi
-
-  __ Bind(&loop);
-  __ ldr(R2, Address(R8, 0));
-  __ cmp(R1, Operand(R2));
-  __ b(&found, EQ);
-  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
-  __ b(&miss, EQ);
-
-  const intptr_t entry_length =
-      ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) * kWordSize;
-  __ AddImmediate(R8, entry_length);  // Next entry.
-  __ b(&loop);
-
-  __ Bind(&found);
-  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
-  __ ldr(R0, Address(R8, target_offset));
-  __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
-  __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ br(R1);
-
-  __ Bind(&miss);
-  __ LoadIsolate(R2);
-  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ br(R1);
-}
-
-void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) {
-  Label loop, found, miss;
-  __ ldr(R8, FieldAddress(R5, ICData::ic_data_offset()));
-  __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
-  __ AddImmediate(R8, Array::data_offset() - kHeapObjectTag);
-  // R8: first IC entry
-  __ LoadTaggedClassIdMayBeSmi(R1, R0);
-  // R1: receiver cid as Smi
-
-  __ Bind(&loop);
-  __ ldr(R2, Address(R8, 0));
-  __ cmp(R1, Operand(R2));
-  __ b(&found, EQ);
-  __ CompareImmediate(R2, Smi::RawValue(kIllegalCid));
-  __ b(&miss, EQ);
-
-  const intptr_t entry_length =
-      ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) * kWordSize;
-  __ AddImmediate(R8, entry_length);  // Next entry.
-  __ b(&loop);
-
-  __ Bind(&found);
-  const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
-  const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
-  __ ldr(R1, Address(R8, entry_offset));
-  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    __ ldr(CODE_REG, Address(R8, code_offset));
-  }
-  __ br(R1);
-
-  __ Bind(&miss);
-  __ LoadIsolate(R2);
-  __ ldr(CODE_REG, Address(R2, Isolate::ic_miss_code_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ br(R1);
-}
-
-// Called from switchable IC calls.
-//  R0: receiver
-//  R5: SingleTargetCache
-void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ Push(ZR);  // Result slot.
-  __ Push(R0);  // Arg0: Receiver
-  __ Push(R5);  // Arg1: UnlinkedCall
-  __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
-  __ Drop(2);
-  __ Pop(R5);  // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kMonomorphic)));
-  __ br(R1);
-}
-
-// Called from switchable IC calls.
-//  R0: receiver
-//  R5: SingleTargetCache
-// Passed to target:
-//  CODE_REG: target Code object
-void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) {
-  Label miss;
-  __ LoadClassIdMayBeSmi(R1, R0);
-  __ ldr(R2, FieldAddress(R5, SingleTargetCache::lower_limit_offset()),
-         kUnsignedHalfword);
-  __ ldr(R3, FieldAddress(R5, SingleTargetCache::upper_limit_offset()),
-         kUnsignedHalfword);
-
-  __ cmp(R1, Operand(R2));
-  __ b(&miss, LT);
-  __ cmp(R1, Operand(R3));
-  __ b(&miss, GT);
-
-  __ ldr(R1, FieldAddress(R5, SingleTargetCache::entry_point_offset()));
-  __ ldr(CODE_REG, FieldAddress(R5, SingleTargetCache::target_offset()));
-  __ br(R1);
-
-  __ Bind(&miss);
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ Push(ZR);  // Result slot.
-  __ Push(R0);  // Arg0: Receiver
-  __ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
-  __ Drop(1);
-  __ Pop(R5);  // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kMonomorphic)));
-  __ br(R1);
-}
-
-// Called from the monomorphic checked entry.
-//  R0: receiver
-void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
-  __ EnterStubFrame();
-  __ Push(R0);  // Preserve receiver.
-
-  __ Push(ZR);  // Result slot.
-  __ Push(R0);  // Arg0: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
-  __ Drop(1);
-  __ Pop(R5);  // result = IC
-
-  __ Pop(R0);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ ldr(R1, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                        Code::EntryKind::kMonomorphic)));
-  __ br(R1);
-}
-
-void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
-  __ brk(0);
-}
-
-void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
-  __ brk(0);
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index 6d4af28..5dbe70d 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -55,8 +55,8 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(
       Code::FinalizeCode(*CreateFunction("Test_CallRuntimeStubCode"), nullptr,
@@ -96,8 +96,8 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index c1699b7..85224e3 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -54,8 +54,8 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(
       Code::FinalizeCode(*CreateFunction("Test_CallRuntimeStubCode"), nullptr,
@@ -94,8 +94,8 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
deleted file mode 100644
index fa35e41..0000000
--- a/runtime/vm/stub_code_dbc.cc
+++ /dev/null
@@ -1,133 +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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_DBC)
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/cpu.h"
-#include "vm/dart_entry.h"
-#include "vm/heap/heap.h"
-#include "vm/instructions.h"
-#include "vm/object_store.h"
-#include "vm/runtime_entry.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
-#include "vm/tags.h"
-
-#define __ assembler->
-
-namespace dart {
-
-DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
-DEFINE_FLAG(bool,
-            use_slow_path,
-            false,
-            "Set to true for debugging & verifying the slow paths.");
-
-void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
-  __ Compile();
-}
-
-void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) {
-  __ NoSuchMethod();
-}
-
-// Not executed, but used as a stack marker when calling
-// DRT_OptimizeInvokedFunction.
-void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// Not executed, but used as a sentinel in Simulator::JumpToFrame.
-void StubCode::GenerateRunExceptionHandlerStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateDeoptForRewindStub(Assembler* assembler) {
-  __ DeoptRewind();
-}
-
-// TODO(vegorov) Don't generate this stub.
-void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(vegorov) Don't generate these stubs.
-void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
-                                              const Class& cls) {
-  __ Trap();
-}
-
-// TODO(vegorov) Don't generate this stub.
-void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// These deoptimization stubs are only used to populate stack frames
-// with something meaningful to make sure GC can scan the stack during
-// the last phase of deoptimization which materializes objects.
-void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(kustermann): Don't generate this stub.
-void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(kustermann): Don't generate this stub.
-void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(kustermann): Don't generate this stub.
-void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(kustermann): Don't generate this stub.
-void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(kustermann): Don't generate this stub.
-void StubCode::GenerateLazySpecializeTypeTestStub(Assembler* assembler) {
-  __ Trap();
-}
-
-// TODO(kustermann): Don't generate this stub.
-void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-  __ Trap();
-}
-
-void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-  __ Trap();
-}
-
-}  // namespace dart
-
-#endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
deleted file mode 100644
index 4c59d09..0000000
--- a/runtime/vm/stub_code_ia32.cc
+++ /dev/null
@@ -1,2283 +0,0 @@
-// 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.
-
-#include "vm/globals.h"
-#if defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/dart_entry.h"
-#include "vm/heap/heap.h"
-#include "vm/heap/scavenger.h"
-#include "vm/instructions.h"
-#include "vm/object_store.h"
-#include "vm/resolver.h"
-#include "vm/stack_frame.h"
-#include "vm/stub_code.h"
-#include "vm/tags.h"
-
-#define __ assembler->
-
-namespace dart {
-
-DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
-DEFINE_FLAG(bool,
-            use_slow_path,
-            false,
-            "Set to true for debugging & verifying the slow paths.");
-
-#define INT32_SIZEOF(x) static_cast<int32_t>(sizeof(x))
-
-// Input parameters:
-//   ESP : points to return address.
-//   ESP + 4 : address of last argument in argument array.
-//   ESP + 4*EDX : address of first argument in argument array.
-//   ESP + 4*EDX + 4 : address of return value.
-//   ECX : address of the runtime function to call.
-//   EDX : number of arguments to the call.
-// Must preserve callee saved registers EDI and EBX.
-void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ movl(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to Dart VM C++ code.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), EBP);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing VM code.
-  __ movl(Assembler::VMTagAddress(), ECX);
-
-  // Reserve space for arguments and align frame before entering C++ world.
-  __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments)));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  // Pass NativeArguments structure by value and call runtime.
-  __ movl(Address(ESP, thread_offset), THR);  // Set thread in NativeArgs.
-  // There are no runtime calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
-  // Compute argv.
-  __ leal(EAX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize));
-  __ movl(Address(ESP, argv_offset), EAX);    // Set argv in NativeArguments.
-  __ addl(EAX, Immediate(1 * kWordSize));     // Retval is next to 1st argument.
-  __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
-  __ call(ECX);
-
-  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  __ LeaveFrame();
-
-  // The following return can jump to a lazy-deopt stub, which assumes EAX
-  // contains a return value and will save it in a GC-visible way.  We therefore
-  // have to ensure EAX does not contain any garbage value left from the C
-  // function we called (which has return type "void").
-  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
-  __ xorl(EAX, EAX);
-  __ ret();
-}
-
-void StubCode::GenerateNullErrorSharedWithoutFPURegsStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-void StubCode::GenerateNullErrorSharedWithFPURegsStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-void StubCode::GenerateStackOverflowSharedWithoutFPURegsStub(
-    Assembler* assembler) {
-  // TODO(sjindel): implement.
-  __ Breakpoint();
-}
-
-void StubCode::GenerateStackOverflowSharedWithFPURegsStub(
-    Assembler* assembler) {
-  // TODO(sjindel): implement.
-  __ Breakpoint();
-}
-
-// Input parameters:
-//   ESP : points to return address.
-//   EAX : stop message (const char*).
-// Must preserve all registers, except EAX.
-void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
-  __ EnterCallRuntimeFrame(1 * kWordSize);
-  __ movl(Address(ESP, 0), EAX);
-  __ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ ret();
-}
-
-// Input parameters:
-//   ESP : points to return address.
-//   ESP + 4 : address of return value.
-//   EAX : address of first argument in argument array.
-//   ECX : address of the native function to call.
-//   EDX : argc_tag including number of arguments and function kind.
-static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
-                                              ExternalLabel* wrapper) {
-  const intptr_t native_args_struct_offset =
-      NativeEntry::kNumCallWrapperArguments * kWordSize;
-  const intptr_t thread_offset =
-      NativeArguments::thread_offset() + native_args_struct_offset;
-  const intptr_t argc_tag_offset =
-      NativeArguments::argc_tag_offset() + native_args_struct_offset;
-  const intptr_t argv_offset =
-      NativeArguments::argv_offset() + native_args_struct_offset;
-  const intptr_t retval_offset =
-      NativeArguments::retval_offset() + native_args_struct_offset;
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to dart VM code.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), EBP);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ movl(Assembler::VMTagAddress(), ECX);
-
-  // Reserve space for the native arguments structure, the outgoing parameters
-  // (pointer to the native arguments structure, the C function entry point)
-  // and align frame before entering the C++ world.
-  __ AddImmediate(ESP,
-                  Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize)));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  // Pass NativeArguments structure by value and call native function.
-  __ movl(Address(ESP, thread_offset), THR);    // Set thread in NativeArgs.
-  __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
-  __ movl(Address(ESP, argv_offset), EAX);      // Set argv in NativeArguments.
-  __ leal(EAX, Address(EBP, 2 * kWordSize));    // Compute return value addr.
-  __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
-  __ leal(EAX, Address(ESP, 2 * kWordSize));  // Pointer to the NativeArguments.
-  __ movl(Address(ESP, 0), EAX);  // Pass the pointer to the NativeArguments.
-
-  __ movl(Address(ESP, kWordSize), ECX);  // Function to call.
-  __ call(wrapper);
-
-  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  __ LeaveFrame();
-  __ ret();
-}
-
-void StubCode::GenerateCallNoScopeNativeStub(Assembler* assembler) {
-  ExternalLabel wrapper(NativeEntry::NoScopeNativeCallWrapperEntry());
-  GenerateCallNativeWithWrapperStub(assembler, &wrapper);
-}
-
-void StubCode::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
-  ExternalLabel wrapper(NativeEntry::AutoScopeNativeCallWrapperEntry());
-  GenerateCallNativeWithWrapperStub(assembler, &wrapper);
-}
-
-// Input parameters:
-//   ESP : points to return address.
-//   ESP + 4 : address of return value.
-//   EAX : address of first argument in argument array.
-//   ECX : address of the native function to call.
-//   EDX : argc_tag including number of arguments and function kind.
-void StubCode::GenerateCallBootstrapNativeStub(Assembler* assembler) {
-  const intptr_t native_args_struct_offset = kWordSize;
-  const intptr_t thread_offset =
-      NativeArguments::thread_offset() + native_args_struct_offset;
-  const intptr_t argc_tag_offset =
-      NativeArguments::argc_tag_offset() + native_args_struct_offset;
-  const intptr_t argv_offset =
-      NativeArguments::argv_offset() + native_args_struct_offset;
-  const intptr_t retval_offset =
-      NativeArguments::retval_offset() + native_args_struct_offset;
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to dart VM code.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), EBP);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ movl(Assembler::VMTagAddress(), ECX);
-
-  // Reserve space for the native arguments structure, the outgoing parameter
-  // (pointer to the native arguments structure) and align frame before
-  // entering the C++ world.
-  __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  // Pass NativeArguments structure by value and call native function.
-  __ movl(Address(ESP, thread_offset), THR);    // Set thread in NativeArgs.
-  __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
-  __ movl(Address(ESP, argv_offset), EAX);      // Set argv in NativeArguments.
-  __ leal(EAX, Address(EBP, 2 * kWordSize));    // Compute return value addr.
-  __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
-  __ leal(EAX, Address(ESP, kWordSize));      // Pointer to the NativeArguments.
-  __ movl(Address(ESP, 0), EAX);  // Pass the pointer to the NativeArguments.
-  __ call(ECX);
-
-  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  __ LeaveFrame();
-  __ ret();
-}
-
-// Input parameters:
-//   EDX: arguments descriptor array.
-void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushl(EDX);           // Preserve arguments descriptor array.
-  __ pushl(Immediate(0));  // Setup space on stack for return value.
-  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
-  __ popl(EAX);  // Get Code object result.
-  __ popl(EDX);  // Restore arguments descriptor array.
-  // Remove the stub frame as we are about to jump to the dart function.
-  __ LeaveFrame();
-
-  __ movl(ECX, FieldAddress(EAX, Code::entry_point_offset()));
-  __ jmp(ECX);
-}
-
-// Called from a static call only when an invalid code has been entered
-// (invalid because its function was optimized or deoptimized).
-// EDX: arguments descriptor array.
-void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ pushl(EDX);           // Preserve arguments descriptor array.
-  __ pushl(Immediate(0));  // Setup space on stack for return value.
-  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
-  __ popl(EAX);  // Get Code object.
-  __ popl(EDX);  // Restore arguments descriptor array.
-  __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
-  __ LeaveFrame();
-  __ jmp(EAX);
-  __ int3();
-}
-
-// Called from object allocate instruction when the allocation stub has been
-// disabled.
-void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushl(Immediate(0));  // Setup space on stack for return value.
-  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
-  __ popl(EAX);  // Get Code object.
-  __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
-  __ LeaveFrame();
-  __ jmp(EAX);
-  __ int3();
-}
-
-// Input parameters:
-//   EDX: smi-tagged argument count, may be zero.
-//   EBP[kParamEndSlotFromFp + 1]: last argument.
-// Uses EAX, EBX, ECX, EDX, EDI.
-static void PushArrayOfArguments(Assembler* assembler) {
-  // Allocate array to store arguments of caller.
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  __ movl(ECX, raw_null);  // Null element type for raw Array.
-  __ Call(StubCode::AllocateArray());
-  __ SmiUntag(EDX);
-  // EAX: newly allocated array.
-  // EDX: length of the array (was preserved by the stub).
-  __ pushl(EAX);  // Array is in EAX and on top of stack.
-  __ leal(EBX, Address(EBP, EDX, TIMES_4, kParamEndSlotFromFp * kWordSize));
-  __ leal(ECX, FieldAddress(EAX, Array::data_offset()));
-  // EBX: address of first argument on stack.
-  // ECX: address of first argument in array.
-  Label loop, loop_condition;
-  __ jmp(&loop_condition, Assembler::kNearJump);
-  __ Bind(&loop);
-  __ movl(EDI, Address(EBX, 0));
-  // Generational barrier is needed, array is not necessarily in new space.
-  __ StoreIntoObject(EAX, Address(ECX, 0), EDI);
-  __ AddImmediate(ECX, Immediate(kWordSize));
-  __ AddImmediate(EBX, Immediate(-kWordSize));
-  __ Bind(&loop_condition);
-  __ decl(EDX);
-  __ j(POSITIVE, &loop, Assembler::kNearJump);
-}
-
-// Used by eager and lazy deoptimization. Preserve result in EAX if necessary.
-// This stub translates optimized frame into unoptimized frame. The optimized
-// frame can contain values in registers and on stack, the unoptimized
-// frame contains all values on stack.
-// Deoptimization occurs in following steps:
-// - Push all registers that can contain values.
-// - Call C routine to copy the stack and saved registers into temporary buffer.
-// - Adjust caller's frame to correct unoptimized frame size.
-// - Fill the unoptimized frame.
-// - Materialize objects that require allocation (e.g. Double instances).
-// GC can occur only after frame is fully rewritten.
-// Stack after EnterDartFrame(0) below:
-//   +------------------+
-//   | PC marker        | <- TOS
-//   +------------------+
-//   | Saved FP         | <- FP of stub
-//   +------------------+
-//   | return-address   |  (deoptimization point)
-//   +------------------+
-//   | ...              | <- SP of optimized frame
-//
-// Parts of the code cannot GC, part of the code can GC.
-static void GenerateDeoptimizationSequence(Assembler* assembler,
-                                           DeoptStubKind kind) {
-  // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
-  __ EnterDartFrame(0);
-  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
-  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
-  const intptr_t saved_result_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - EAX);
-  const intptr_t saved_exception_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - EAX);
-  const intptr_t saved_stacktrace_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - EDX);
-  // Result in EAX is preserved as part of pushing all registers below.
-
-  // Push registers in their enumeration order: lowest register number at
-  // lowest address.
-  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
-    if (i == CODE_REG) {
-      // Save the original value of CODE_REG pushed before invoking this stub
-      // instead of the value used to call this stub.
-      __ pushl(Address(EBP, 2 * kWordSize));
-    } else {
-      __ pushl(static_cast<Register>(i));
-    }
-  }
-  __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
-  intptr_t offset = 0;
-  for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
-    XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
-    __ movups(Address(ESP, offset), xmm_reg);
-    offset += kFpuRegisterSize;
-  }
-
-  __ movl(ECX, ESP);  // Preserve saved registers block.
-  __ ReserveAlignedFrameSpace(2 * kWordSize);
-  __ movl(Address(ESP, 0 * kWordSize), ECX);  // Start of register block.
-  bool is_lazy =
-      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
-  __ movl(Address(ESP, 1 * kWordSize), Immediate(is_lazy ? 1 : 0));
-  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
-  // Result (EAX) is stack-size (FP - SP) in bytes.
-
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into EBX temporarily.
-    __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize));
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into EBX temporarily.
-    __ movl(EBX, Address(EBP, saved_exception_slot_from_fp * kWordSize));
-    __ movl(ECX, Address(EBP, saved_stacktrace_slot_from_fp * kWordSize));
-  }
-
-  __ LeaveFrame();
-  __ popl(EDX);       // Preserve return address.
-  __ movl(ESP, EBP);  // Discard optimized frame.
-  __ subl(ESP, EAX);  // Reserve space for deoptimized frame.
-  __ pushl(EDX);      // Restore return address.
-
-  // Leaf runtime function DeoptimizeFillFrame expects a Dart frame.
-  __ EnterDartFrame(0);
-  if (kind == kLazyDeoptFromReturn) {
-    __ pushl(EBX);  // Preserve result as first local.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ pushl(EBX);  // Preserve exception as first local.
-    __ pushl(ECX);  // Preserve stacktrace as first local.
-  }
-  __ ReserveAlignedFrameSpace(1 * kWordSize);
-  __ movl(Address(ESP, 0), EBP);  // Pass last FP as parameter on stack.
-  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into EBX.
-    __ movl(EBX, Address(EBP, compiler_frame_layout.first_local_from_fp *
-                                  kWordSize));
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into EBX.
-    __ movl(EBX, Address(EBP, compiler_frame_layout.first_local_from_fp *
-                                  kWordSize));
-    __ movl(ECX, Address(EBP, (compiler_frame_layout.first_local_from_fp - 1) *
-                                  kWordSize));
-  }
-  // Code above cannot cause GC.
-  __ LeaveFrame();
-
-  // Frame is fully rewritten at this point and it is safe to perform a GC.
-  // Materialize any objects that were deferred by FillFrame because they
-  // require allocation.
-  __ EnterStubFrame();
-  if (kind == kLazyDeoptFromReturn) {
-    __ pushl(EBX);  // Preserve result, it will be GC-d here.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ pushl(EBX);  // Preserve exception, it will be GC-d here.
-    __ pushl(ECX);  // Preserve stacktrace, it will be GC-d here.
-  }
-  __ pushl(Immediate(Smi::RawValue(0)));  // Space for the result.
-  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
-  // Result tells stub how many bytes to remove from the expression stack
-  // of the bottom-most frame. They were used as materialization arguments.
-  __ popl(EBX);
-  __ SmiUntag(EBX);
-  if (kind == kLazyDeoptFromReturn) {
-    __ popl(EAX);  // Restore result.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ popl(EDX);  // Restore exception.
-    __ popl(EAX);  // Restore stacktrace.
-  }
-  __ LeaveFrame();
-
-  __ popl(ECX);       // Pop return address.
-  __ addl(ESP, EBX);  // Remove materialization arguments.
-  __ pushl(ECX);      // Push return address.
-  // The caller is responsible for emitting the return instruction.
-}
-
-// EAX: result, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
-  // Return address for "call" to deopt stub.
-  __ pushl(Immediate(kZapReturnAddress));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
-  __ ret();
-}
-
-// EAX: exception, must be preserved
-// EDX: stacktrace, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
-  // Return address for "call" to deopt stub.
-  __ pushl(Immediate(kZapReturnAddress));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
-  __ ret();
-}
-
-void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-  __ 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(reinterpret_cast<intptr_t>(Object::null()));
-  __ cmpl(EAX, raw_null);
-  __ j(NOT_EQUAL, call_target_function);
-  __ EnterStubFrame();
-  // Load the receiver.
-  __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ movl(EAX, Address(EBP, EDI, TIMES_HALF_WORD_SIZE,
-                       kParamEndSlotFromFp * kWordSize));
-  __ pushl(Immediate(0));  // Setup space on stack for result.
-  __ pushl(EAX);           // Receiver.
-  __ pushl(ECX);           // ICData/MegamorphicCache.
-  __ pushl(EDX);           // Arguments descriptor array.
-
-  // Adjust arguments count.
-  __ cmpl(FieldAddress(EDX, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  __ movl(EDX, EDI);
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addl(EDX, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-
-  // EDX: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-  const intptr_t kNumArgs = 4;
-  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
-  __ Drop(4);
-  __ popl(EAX);  // Return value.
-  __ LeaveFrame();
-  __ ret();
-}
-
-void StubCode::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, ArgumentsDescriptor::count_offset()));
-  // Two words (saved fp, stub's pc marker) in the stack above the return
-  // address.
-  __ movl(EAX, Address(ESP, EAX, TIMES_2, 2 * kWordSize));
-  // Preserve IC data and arguments descriptor.
-  __ pushl(ECX);
-  __ pushl(EDX);
-
-  __ 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);
-  }
-
-  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-  __ jmp(EBX);
-}
-
-// Called for inline allocation of arrays.
-// Input parameters:
-//   EDX : Array length as Smi (must be preserved).
-//   ECX : array element type (either NULL or an instantiated type).
-// Uses EAX, EBX, ECX, EDI  as temporary registers.
-// The newly allocated object is returned in EAX.
-void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
-  Label slow_case;
-  // Compute the size to be allocated, it is based on the array length
-  // and is computed as:
-  // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
-  // Assert that length is a Smi.
-  __ testl(EDX, Immediate(kSmiTagMask));
-
-  if (FLAG_use_slow_path) {
-    __ jmp(&slow_case);
-  } else {
-    __ j(NOT_ZERO, &slow_case);
-  }
-  __ cmpl(EDX, Immediate(0));
-  __ j(LESS, &slow_case);
-
-  // Check for maximum allowed length.
-  const Immediate& max_len = Immediate(
-      reinterpret_cast<int32_t>(Smi::New(Array::kMaxNewSpaceElements)));
-  __ cmpl(EDX, max_len);
-  __ j(GREATER, &slow_case);
-
-  NOT_IN_PRODUCT(
-      __ MaybeTraceAllocation(kArrayCid, EAX, &slow_case, Assembler::kFarJump));
-
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawArray) + kObjectAlignment - 1;
-  // EDX is Smi.
-  __ leal(EBX, Address(EDX, TIMES_2, fixed_size_plus_alignment_padding));
-  ASSERT(kSmiTagShift == 1);
-  __ andl(EBX, Immediate(-kObjectAlignment));
-
-  // ECX: array element type.
-  // EDX: array length as Smi.
-  // EBX: allocation size.
-
-  const intptr_t cid = kArrayCid;
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  __ movl(EAX, Address(THR, Thread::top_offset()));
-  __ addl(EBX, EAX);
-  __ j(CARRY, &slow_case);
-
-  // Check if the allocation fits into the remaining space.
-  // EAX: potential new object start.
-  // EBX: potential next object start.
-  // ECX: array element type.
-  // EDX: array length as Smi).
-  __ cmpl(EBX, Address(THR, Thread::end_offset()));
-  __ j(ABOVE_EQUAL, &slow_case);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  __ movl(Address(THR, Thread::top_offset()), EBX);
-  __ subl(EBX, EAX);
-  __ addl(EAX, Immediate(kHeapObjectTag));
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EBX, EDI, space));
-
-  // Initialize the tags.
-  // EAX: new object start as a tagged pointer.
-  // EBX: allocation size.
-  // ECX: array element type.
-  // EDX: array length as Smi.
-  {
-    Label size_tag_overflow, done;
-    __ movl(EDI, EBX);
-    __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
-    __ jmp(&done, Assembler::kNearJump);
-
-    __ Bind(&size_tag_overflow);
-    __ movl(EDI, Immediate(0));
-    __ Bind(&done);
-
-    // Get the class index and insert it into the tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ orl(EDI, Immediate(tags));
-    __ movl(FieldAddress(EAX, Array::tags_offset()), EDI);  // Tags.
-  }
-  // EAX: new object start as a tagged pointer.
-  // EBX: allocation size.
-  // ECX: array element type.
-  // EDX: Array length as Smi (preserved).
-  // Store the type argument field.
-  // No generational barrier needed, since we store into a new object.
-  __ StoreIntoObjectNoBarrier(
-      EAX, FieldAddress(EAX, Array::type_arguments_offset()), ECX);
-
-  // Set the length field.
-  __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, Array::length_offset()),
-                              EDX);
-
-  // Initialize all array elements to raw_null.
-  // EAX: new object start as a tagged pointer.
-  // EBX: allocation size.
-  // EDI: iterator which initially points to the start of the variable
-  // data area to be initialized.
-  // ECX: array element type.
-  // EDX: array length as Smi.
-  __ leal(EBX, FieldAddress(EAX, EBX, TIMES_1, 0));
-  __ leal(EDI, FieldAddress(EAX, sizeof(RawArray)));
-  Label done;
-  Label init_loop;
-  __ Bind(&init_loop);
-  __ cmpl(EDI, EBX);
-  __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
-  // No generational barrier needed, since we are storing null.
-  __ StoreIntoObjectNoBarrier(EAX, Address(EDI, 0), Object::null_object());
-  __ addl(EDI, Immediate(kWordSize));
-  __ jmp(&init_loop, Assembler::kNearJump);
-  __ Bind(&done);
-  __ ret();  // returns the newly allocated object in EAX.
-
-  // Unable to allocate the array using the fast inline code, just call
-  // into the runtime.
-  __ Bind(&slow_case);
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ pushl(Immediate(0));  // Setup space on stack for return value.
-  __ pushl(EDX);           // Array length as Smi.
-  __ pushl(ECX);           // Element type.
-  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
-  __ popl(EAX);  // Pop element type argument.
-  __ popl(EDX);  // Pop array length argument (preserved).
-  __ popl(EAX);  // Pop return value from return slot.
-  __ LeaveFrame();
-  __ ret();
-}
-
-// Called when invoking dart code from C++ (VM code).
-// Input parameters:
-//   ESP : points to return address.
-//   ESP + 4 : code object of the dart function to call.
-//   ESP + 8 : arguments descriptor array.
-//   ESP + 12 : arguments array.
-//   ESP + 16 : current thread.
-// Uses EAX, EDX, ECX, EDI as temporary registers.
-void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
-  const intptr_t kTargetCodeOffset = 3 * kWordSize;
-  const intptr_t kArgumentsDescOffset = 4 * kWordSize;
-  const intptr_t kArgumentsOffset = 5 * kWordSize;
-  const intptr_t kThreadOffset = 6 * kWordSize;
-
-  __ pushl(Address(ESP, 0));  // Marker for the profiler.
-  __ EnterFrame(0);
-
-  // Push code object to PC marker slot.
-  __ movl(EAX, Address(EBP, kThreadOffset));
-  __ pushl(Address(EAX, Thread::invoke_dart_code_stub_offset()));
-
-  // Save C++ ABI callee-saved registers.
-  __ pushl(EBX);
-  __ pushl(ESI);
-  __ pushl(EDI);
-
-  // Set up THR, which caches the current thread in Dart code.
-  __ movl(THR, EAX);
-
-  // Save the current VMTag on the stack.
-  __ movl(ECX, Assembler::VMTagAddress());
-  __ pushl(ECX);
-
-  // Save top resource and top exit frame info. Use EDX as a temporary register.
-  // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ movl(EDX, Address(THR, Thread::top_resource_offset()));
-  __ pushl(EDX);
-  __ movl(Address(THR, Thread::top_resource_offset()), Immediate(0));
-  // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
-  // code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -7);
-  __ movl(EDX, Address(THR, Thread::top_exit_frame_info_offset()));
-  __ pushl(EDX);
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  // Mark that the thread is executing Dart code. Do this after initializing the
-  // exit link for the profiler.
-  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Load arguments descriptor array into EDX.
-  __ movl(EDX, Address(EBP, kArgumentsDescOffset));
-  __ movl(EDX, Address(EDX, VMHandles::kOffsetOfRawPtrInHandle));
-
-  // Load number of arguments into EBX and adjust count for type arguments.
-  __ movl(EBX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ cmpl(FieldAddress(EDX, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addl(EBX, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-  // Save number of arguments as Smi on stack, replacing ArgumentsDesc.
-  __ movl(Address(EBP, kArgumentsDescOffset), EBX);
-  __ SmiUntag(EBX);
-
-  // Set up arguments for the dart call.
-  Label push_arguments;
-  Label done_push_arguments;
-  __ testl(EBX, EBX);  // check if there are arguments.
-  __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
-  __ movl(EAX, Immediate(0));
-
-  // Compute address of 'arguments array' data area into EDI.
-  __ movl(EDI, Address(EBP, kArgumentsOffset));
-  __ movl(EDI, Address(EDI, VMHandles::kOffsetOfRawPtrInHandle));
-  __ leal(EDI, FieldAddress(EDI, Array::data_offset()));
-
-  __ Bind(&push_arguments);
-  __ movl(ECX, Address(EDI, EAX, TIMES_4, 0));
-  __ pushl(ECX);
-  __ incl(EAX);
-  __ cmpl(EAX, EBX);
-  __ j(LESS, &push_arguments, Assembler::kNearJump);
-  __ Bind(&done_push_arguments);
-
-  // Call the dart code entrypoint.
-  __ movl(EAX, Address(EBP, kTargetCodeOffset));
-  __ movl(EAX, Address(EAX, VMHandles::kOffsetOfRawPtrInHandle));
-  __ call(FieldAddress(EAX, Code::entry_point_offset()));
-
-  // Read the saved number of passed arguments as Smi.
-  __ movl(EDX, Address(EBP, kArgumentsDescOffset));
-  // Get rid of arguments pushed on the stack.
-  __ leal(ESP, Address(ESP, EDX, TIMES_2, 0));  // EDX is a Smi.
-
-  // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure.
-  __ popl(Address(THR, Thread::top_exit_frame_info_offset()));
-  __ popl(Address(THR, Thread::top_resource_offset()));
-
-  // Restore the current VMTag from the stack.
-  __ popl(Assembler::VMTagAddress());
-
-  // Restore C++ ABI callee-saved registers.
-  __ popl(EDI);
-  __ popl(ESI);
-  __ popl(EBX);
-
-  // Restore the frame pointer.
-  __ LeaveFrame();
-  __ popl(ECX);
-
-  __ ret();
-}
-
-void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-  __ Unimplemented("Interpreter not yet supported");
-}
-
-// Called for inline allocation of contexts.
-// Input:
-// EDX: number of context variables.
-// Output:
-// EAX: new allocated RawContext object.
-// EBX and EDX are destroyed.
-void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
-  if (FLAG_inline_alloc) {
-    Label slow_case;
-    // First compute the rounded instance size.
-    // EDX: number of context variables.
-    intptr_t fixed_size_plus_alignment_padding =
-        (sizeof(RawContext) + kObjectAlignment - 1);
-    __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
-    __ andl(EBX, Immediate(-kObjectAlignment));
-
-    NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, EAX, &slow_case,
-                                           Assembler::kFarJump));
-
-    // Now allocate the object.
-    // EDX: number of context variables.
-    const intptr_t cid = kContextCid;
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ movl(EAX, Address(THR, Thread::top_offset()));
-    __ addl(EBX, EAX);
-    // Check if the allocation fits into the remaining space.
-    // EAX: potential new object.
-    // EBX: potential next object start.
-    // EDX: number of context variables.
-    __ cmpl(EBX, Address(THR, Thread::end_offset()));
-    if (FLAG_use_slow_path) {
-      __ jmp(&slow_case);
-    } else {
-#if defined(DEBUG)
-      static const bool kJumpLength = Assembler::kFarJump;
-#else
-      static const bool kJumpLength = Assembler::kNearJump;
-#endif  // DEBUG
-      __ j(ABOVE_EQUAL, &slow_case, kJumpLength);
-    }
-
-    // Successfully allocated the object, now update top to point to
-    // next object start and initialize the object.
-    // EAX: new object.
-    // EBX: next object start.
-    // EDX: number of context variables.
-    __ movl(Address(THR, Thread::top_offset()), EBX);
-    // EBX: Size of allocation in bytes.
-    __ subl(EBX, EAX);
-    __ addl(EAX, Immediate(kHeapObjectTag));
-    // Generate isolate-independent code to allow sharing between isolates.
-    NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, EBX, EDI, space));
-
-    // Calculate the size tag.
-    // EAX: new object.
-    // EDX: number of context variables.
-    {
-      Label size_tag_overflow, done;
-      __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
-      __ andl(EBX, Immediate(-kObjectAlignment));
-      __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
-      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-      __ shll(EBX, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
-      __ jmp(&done);
-
-      __ Bind(&size_tag_overflow);
-      // Set overflow size tag value.
-      __ movl(EBX, Immediate(0));
-
-      __ Bind(&done);
-      // EAX: new object.
-      // EDX: number of context variables.
-      // EBX: size and bit tags.
-      uint32_t tags = 0;
-      tags = RawObject::ClassIdTag::update(cid, tags);
-      tags = RawObject::NewBit::update(true, tags);
-      __ orl(EBX, Immediate(tags));
-      __ movl(FieldAddress(EAX, Context::tags_offset()), EBX);  // Tags.
-    }
-
-    // Setup up number of context variables field.
-    // EAX: new object.
-    // EDX: number of context variables as integer value (not object).
-    __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX);
-
-    // Setup the parent field.
-    // EAX: new object.
-    // EDX: number of context variables.
-    // No generational barrier needed, since we are storing null.
-    __ StoreIntoObjectNoBarrier(EAX,
-                                FieldAddress(EAX, Context::parent_offset()),
-                                Object::null_object());
-
-    // Initialize the context variables.
-    // EAX: new object.
-    // EDX: number of context variables.
-    {
-      Label loop, entry;
-      __ leal(EBX, FieldAddress(EAX, Context::variable_offset(0)));
-
-      __ jmp(&entry, Assembler::kNearJump);
-      __ Bind(&loop);
-      __ decl(EDX);
-      // No generational barrier needed, since we are storing null.
-      __ StoreIntoObjectNoBarrier(EAX, Address(EBX, EDX, TIMES_4, 0),
-                                  Object::null_object());
-      __ Bind(&entry);
-      __ cmpl(EDX, Immediate(0));
-      __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
-    }
-
-    // Done allocating and initializing the context.
-    // EAX: new object.
-    __ ret();
-
-    __ Bind(&slow_case);
-  }
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ pushl(Immediate(0));  // Setup space on stack for return value.
-  __ SmiTag(EDX);
-  __ pushl(EDX);
-  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
-  __ popl(EAX);  // Pop number of context variables argument.
-  __ popl(EAX);  // Pop the new context object.
-  // EAX: new object
-  // Restore the frame pointer.
-  __ LeaveFrame();
-  __ ret();
-}
-
-void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
-  // Not used on IA32.
-  __ Breakpoint();
-}
-
-// Helper stub to implement Assembler::StoreIntoObject/Array.
-// Input parameters:
-//   EDX: Object (old)
-//   EDI: Slot
-// If EDX is not remembered, mark as remembered and add to the store buffer.
-COMPILE_ASSERT(kWriteBarrierObjectReg == EDX);
-COMPILE_ASSERT(kWriteBarrierValueReg == kNoRegister);
-COMPILE_ASSERT(kWriteBarrierSlotReg == EDI);
-static void GenerateWriteBarrierStubHelper(Assembler* assembler,
-                                           Address stub_code,
-                                           bool cards) {
-  Label remember_card;
-
-  // Save values being destroyed.
-  __ pushl(EAX);
-  __ pushl(ECX);
-
-  Label add_to_buffer;
-  // Check whether this object has already been remembered. Skip adding to the
-  // store buffer if the object is in the store buffer already.
-  // Spilled: EAX, ECX
-  // EDX: Address being stored
-  __ movl(EAX, FieldAddress(EDX, Object::tags_offset()));
-  __ testl(EAX, Immediate(1 << RawObject::kOldAndNotRememberedBit));
-  __ j(NOT_EQUAL, &add_to_buffer, Assembler::kNearJump);
-  __ popl(ECX);
-  __ popl(EAX);
-  __ ret();
-
-  // Update the tags that this object has been remembered.
-  // EDX: Address being stored
-  // EAX: Current tag value
-  __ Bind(&add_to_buffer);
-
-  if (cards) {
-    // Check if this object is using remembered cards.
-    __ testl(EAX, Immediate(1 << RawObject::kCardRememberedBit));
-    __ j(NOT_EQUAL, &remember_card, Assembler::kFarJump);  // Unlikely.
-  } else {
-#if defined(DEBUG)
-    Label ok;
-    __ testl(EAX, Immediate(1 << RawObject::kCardRememberedBit));
-    __ j(ZERO, &ok, Assembler::kFarJump);  // Unlikely.
-    __ Stop("Wrong barrier");
-    __ Bind(&ok);
-#endif
-  }
-
-  // lock+andl is an atomic read-modify-write.
-  __ lock();
-  __ andl(FieldAddress(EDX, Object::tags_offset()),
-          Immediate(~(1 << RawObject::kOldAndNotRememberedBit)));
-
-  // Load the StoreBuffer block out of the thread. Then load top_ out of the
-  // StoreBufferBlock and add the address to the pointers_.
-  // Spilled: EAX, ECX
-  // EDX: Address being stored
-  __ movl(EAX, Address(THR, Thread::store_buffer_block_offset()));
-  __ movl(ECX, Address(EAX, StoreBufferBlock::top_offset()));
-  __ movl(Address(EAX, ECX, TIMES_4, StoreBufferBlock::pointers_offset()), EDX);
-
-  // Increment top_ and check for overflow.
-  // Spilled: EAX, ECX
-  // ECX: top_
-  // EAX: StoreBufferBlock
-  Label overflow;
-  __ incl(ECX);
-  __ movl(Address(EAX, StoreBufferBlock::top_offset()), ECX);
-  __ cmpl(ECX, Immediate(StoreBufferBlock::kSize));
-  // Restore values.
-  // Spilled: EAX, ECX
-  __ popl(ECX);
-  __ popl(EAX);
-  __ j(EQUAL, &overflow, Assembler::kNearJump);
-  __ ret();
-
-  // Handle overflow: Call the runtime leaf function.
-  __ Bind(&overflow);
-  // Setup frame, push callee-saved registers.
-
-  __ EnterCallRuntimeFrame(1 * kWordSize);
-  __ movl(Address(ESP, 0), THR);  // Push the thread as the only argument.
-  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
-  // Restore callee-saved registers, tear down frame.
-  __ LeaveCallRuntimeFrame();
-  __ ret();
-
-  if (cards) {
-    Label remember_card_slow;
-
-    // Get card table.
-    __ Bind(&remember_card);
-    __ movl(EAX, EDX);                   // Object.
-    __ andl(EAX, Immediate(kPageMask));  // HeapPage.
-    __ cmpl(Address(EAX, HeapPage::card_table_offset()), Immediate(0));
-    __ j(EQUAL, &remember_card_slow, Assembler::kNearJump);
-
-    // Dirty the card.
-    __ subl(EDI, EAX);  // Offset in page.
-    __ movl(EAX, Address(EAX, HeapPage::card_table_offset()));  // Card table.
-    __ shrl(EDI,
-            Immediate(HeapPage::kBytesPerCardLog2));  // Index in card table.
-    __ movb(Address(EAX, EDI, TIMES_1, 0), Immediate(1));
-    __ popl(ECX);
-    __ popl(EAX);
-    __ ret();
-
-    // Card table not yet allocated.
-    __ Bind(&remember_card_slow);
-    __ EnterCallRuntimeFrame(2 * kWordSize);
-    __ movl(Address(ESP, 0 * kWordSize), EDX);  // Object
-    __ movl(Address(ESP, 1 * kWordSize), EDI);  // Slot
-    __ CallRuntime(kRememberCardRuntimeEntry, 2);
-    __ LeaveCallRuntimeFrame();
-    __ popl(ECX);
-    __ popl(EAX);
-    __ ret();
-  }
-}
-
-void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::write_barrier_code_offset()), false);
-}
-
-void StubCode::GenerateArrayWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::array_write_barrier_code_offset()), true);
-}
-
-// Called for inline allocation of objects.
-// Input parameters:
-//   ESP + 4 : type arguments object (only if class is parameterized).
-//   ESP : points to return address.
-// 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 StubCode::GenerateAllocationStubForClass(Assembler* assembler,
-                                              const Class& cls) {
-  const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize;
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
-  ASSERT(!is_cls_parameterized ||
-         (cls.type_arguments_field_offset() != 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 = cls.instance_size();
-  ASSERT(instance_size > 0);
-  if (is_cls_parameterized) {
-    __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
-    // EDX: instantiated type arguments.
-  }
-  Isolate* isolate = Isolate::Current();
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
-      !cls.TraceAllocation(isolate)) {
-    Label slow_case;
-    // Allocate the object and update top to point to
-    // next object start and initialize the allocated object.
-    // EDX: instantiated type arguments (if is_cls_parameterized).
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ movl(EAX, Address(THR, Thread::top_offset()));
-    __ leal(EBX, Address(EAX, instance_size));
-    // Check if the allocation fits into the remaining space.
-    // EAX: potential new object start.
-    // EBX: potential next object start.
-    __ cmpl(EBX, Address(THR, Thread::end_offset()));
-    if (FLAG_use_slow_path) {
-      __ jmp(&slow_case);
-    } else {
-      __ j(ABOVE_EQUAL, &slow_case);
-    }
-    __ movl(Address(THR, Thread::top_offset()), EBX);
-    NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), ECX, space));
-
-    // EAX: new object start (untagged).
-    // EBX: next object start.
-    // EDX: new object type arguments (if is_cls_parameterized).
-    // Set the tags.
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
-    __ addl(EAX, Immediate(kHeapObjectTag));
-
-    // Initialize the remaining words of the object.
-
-    // EAX: new object (tagged).
-    // EBX: next object start.
-    // EDX: new object type arguments (if is_cls_parameterized).
-    // First try inlining the initialization without a loop.
-    if (instance_size < (kInlineInstanceSize * 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 = Instance::NextFieldOffset();
-           current_offset < instance_size; current_offset += kWordSize) {
-        __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, current_offset),
-                                    Object::null_object());
-      }
-    } else {
-      __ leal(ECX, FieldAddress(EAX, Instance::NextFieldOffset()));
-      // Loop until the whole object is initialized.
-      // EAX: new object (tagged).
-      // EBX: next object start.
-      // ECX: next word to be initialized.
-      // EDX: new object type arguments (if is_cls_parameterized).
-      Label init_loop;
-      Label done;
-      __ Bind(&init_loop);
-      __ cmpl(ECX, EBX);
-      __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
-      __ StoreIntoObjectNoBarrier(EAX, Address(ECX, 0), Object::null_object());
-      __ addl(ECX, Immediate(kWordSize));
-      __ jmp(&init_loop, Assembler::kNearJump);
-      __ Bind(&done);
-    }
-    if (is_cls_parameterized) {
-      // EAX: new object (tagged).
-      // EDX: new object type arguments.
-      // Set the type arguments in the new object.
-      intptr_t offset = cls.type_arguments_field_offset();
-      __ StoreIntoObjectNoBarrier(EAX, FieldAddress(EAX, offset), EDX);
-    }
-    // Done allocating and initializing the instance.
-    // EAX: new object (tagged).
-    __ ret();
-
-    __ Bind(&slow_case);
-  }
-  // If is_cls_parameterized:
-  // EDX: new object type arguments.
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ pushl(raw_null);  // Setup space on stack for return value.
-  __ PushObject(cls);  // Push class of object to be allocated.
-  if (is_cls_parameterized) {
-    __ pushl(EDX);  // Push type arguments of object to be allocated.
-  } else {
-    __ pushl(raw_null);  // Push null type arguments.
-  }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ popl(EAX);  // Pop argument (type arguments of object).
-  __ popl(EAX);  // Pop argument (class of object).
-  __ popl(EAX);  // Pop result (newly allocated object).
-  // EAX: new object
-  // Restore the frame pointer.
-  __ LeaveFrame();
-  __ ret();
-}
-
-// 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.
-// Input parameters:
-//   ESP : points to return address.
-//   ESP + 4 : address of last argument.
-//   EDX : arguments descriptor array.
-// Uses EAX, EBX, EDI as temporary registers.
-void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) {
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ movl(EAX, Address(EBP, EDI, TIMES_2, kParamEndSlotFromFp * kWordSize));
-
-  __ pushl(Immediate(0));  // Setup space on stack for result from noSuchMethod.
-  __ pushl(EAX);           // Receiver.
-  __ pushl(EDX);           // Arguments descriptor array.
-
-  // Adjust arguments count.
-  __ cmpl(FieldAddress(EDX, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  __ movl(EDX, EDI);
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addl(EDX, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-
-  // EDX: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-
-  const intptr_t kNumArgs = 3;
-  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
-  // noSuchMethod on closures always throws an error, so it will never return.
-  __ int3();
-}
-
-// Cannot use function object from ICData as it may be the inlined
-// function and not the top-scope function.
-void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register ic_reg = ECX;
-  Register func_reg = EBX;
-  if (FLAG_trace_optimized_ic_calls) {
-    __ EnterStubFrame();
-    __ pushl(func_reg);  // Preserve
-    __ pushl(ic_reg);    // Preserve.
-    __ pushl(ic_reg);    // Argument.
-    __ pushl(func_reg);  // Argument.
-    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
-    __ popl(EAX);       // Discard argument;
-    __ popl(EAX);       // Discard argument;
-    __ popl(ic_reg);    // Restore.
-    __ popl(func_reg);  // Restore.
-    __ LeaveFrame();
-  }
-  __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
-}
-
-// Loads function into 'temp_reg'.
-void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
-                                             Register temp_reg) {
-  if (FLAG_optimization_counter_threshold >= 0) {
-    Register ic_reg = ECX;
-    Register func_reg = temp_reg;
-    ASSERT(ic_reg != func_reg);
-    __ Comment("Increment function counter");
-    __ movl(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
-    __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
-  }
-}
-
-// Note: ECX must be preserved.
-// Attempt a quick Smi operation for known operations ('kind'). The ICData
-// must have been primed with a Smi/Smi check that will be used for counting
-// the invocations.
-static void EmitFastSmiOp(Assembler* assembler,
-                          Token::Kind kind,
-                          intptr_t num_args,
-                          Label* not_smi_or_overflow) {
-  __ Comment("Fast Smi op");
-  ASSERT(num_args == 2);
-  __ movl(EDI, Address(ESP, +1 * kWordSize));  // Right
-  __ movl(EAX, Address(ESP, +2 * kWordSize));  // Left
-  __ movl(EBX, EDI);
-  __ orl(EBX, EAX);
-  __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, not_smi_or_overflow, Assembler::kNearJump);
-  switch (kind) {
-    case Token::kADD: {
-      __ addl(EAX, EDI);
-      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
-      break;
-    }
-    case Token::kSUB: {
-      __ subl(EAX, EDI);
-      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
-      break;
-    }
-    case Token::kMUL: {
-      __ SmiUntag(EAX);
-      __ imull(EAX, EDI);
-      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
-      break;
-    }
-    case Token::kEQ: {
-      Label done, is_true;
-      __ cmpl(EAX, EDI);
-      __ j(EQUAL, &is_true, Assembler::kNearJump);
-      __ LoadObject(EAX, Bool::False());
-      __ jmp(&done, Assembler::kNearJump);
-      __ Bind(&is_true);
-      __ LoadObject(EAX, Bool::True());
-      __ Bind(&done);
-      break;
-    }
-    default:
-      UNIMPLEMENTED();
-  }
-
-  // ECX: IC data object.
-  __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
-  // EBX: ic_data_array with check entries: classes and target functions.
-  __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
-#if defined(DEBUG)
-  // Check that first entry is for Smi/Smi.
-  Label error, ok;
-  const Immediate& imm_smi_cid =
-      Immediate(reinterpret_cast<intptr_t>(Smi::New(kSmiCid)));
-  __ cmpl(Address(EBX, 0 * kWordSize), imm_smi_cid);
-  __ j(NOT_EQUAL, &error, Assembler::kNearJump);
-  __ cmpl(Address(EBX, 1 * kWordSize), imm_smi_cid);
-  __ j(EQUAL, &ok, Assembler::kNearJump);
-  __ Bind(&error);
-  __ Stop("Incorrect IC data");
-  __ Bind(&ok);
-#endif
-  if (FLAG_optimization_counter_threshold >= 0) {
-    const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-    // Update counter, ignore overflow.
-    __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
-  }
-  __ ret();
-}
-
-// Generate inline cache check for 'num_args'.
-//  ECX: Inline cache data object.
-//  TOS(0): return address
-// Control flow:
-// - If receiver is null -> jump to IC miss.
-// - If receiver is Smi -> load Smi class.
-// - If receiver is not-Smi -> load receiver's class.
-// - Check if 'num_args' (including receiver) match any IC data group.
-// - Match found -> jump to target.
-// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(
-    Assembler* assembler,
-    intptr_t num_args,
-    const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind,
-    bool optimized,
-    bool exactness_check /* = false */) {
-  ASSERT(!exactness_check);  // Not supported.
-  ASSERT(num_args == 1 || num_args == 2);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == num_args.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset()));
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ andl(EBX, Immediate(ICData::NumArgsTestedMask()));
-    __ cmpl(EBX, Immediate(num_args));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect stub for IC data");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  Label stepping, done_stepping;
-  if (!optimized) {
-    __ Comment("Check single stepping");
-    __ LoadIsolate(EAX);
-    __ cmpb(Address(EAX, Isolate::single_step_offset()), Immediate(0));
-    __ j(NOT_EQUAL, &stepping);
-    __ Bind(&done_stepping);
-  }
-#endif
-  Label not_smi_or_overflow;
-  if (kind != Token::kILLEGAL) {
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-  }
-  __ Bind(&not_smi_or_overflow);
-
-  __ Comment("Extract ICData initial values and receiver cid");
-  // ECX: IC data object (preserved).
-  // Load arguments descriptor into EDX.
-  __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
-  // Loop that checks if there is an IC data match.
-  Label loop, found, miss;
-  // ECX: IC data object (preserved).
-  __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
-  // EBX: ic_data_array with check entries: classes and target functions.
-  __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
-  // EBX: points directly to the first ic data array element.
-
-  // Get argument descriptor into EAX.  In the 1-argument case this is the
-  // last time we need the argument descriptor, and we reuse EAX for the
-  // class IDs from the IC descriptor.  In the 2-argument case we preserve
-  // the argument descriptor in EAX.
-  __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  if (num_args == 1) {
-    // Load receiver into EDI.
-    __ movl(EDI,
-            Address(ESP, EAX, TIMES_2, 0));  // EAX (argument count) is Smi.
-    __ LoadTaggedClassIdMayBeSmi(EAX, EDI);
-    // EAX: receiver class ID as Smi.
-  }
-
-  __ Comment("ICData loop");
-
-  // We unroll the generic one that is generated once more than the others.
-  bool optimize = kind == Token::kILLEGAL;
-  const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-  const intptr_t entry_size =
-      ICData::TestEntryLengthFor(num_args, exactness_check) * kWordSize;
-
-  __ Bind(&loop);
-  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
-    Label update;
-    if (num_args == 1) {
-      __ movl(EDI, Address(EBX, 0));
-      __ cmpl(EDI, EAX);                                    // Class id match?
-      __ j(EQUAL, &found);                                  // Break.
-      __ addl(EBX, Immediate(entry_size));                  // Next entry.
-      __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid)));  // Done?
-    } else {
-      ASSERT(num_args == 2);
-      // Load receiver into EDI.
-      __ movl(EDI, Address(ESP, EAX, TIMES_2, 0));
-      __ LoadTaggedClassIdMayBeSmi(EDI, EDI);
-      __ cmpl(EDI, Address(EBX, 0));  // Class id match?
-      __ j(NOT_EQUAL, &update);       // Continue.
-
-      // Load second argument into EDI.
-      __ movl(EDI, Address(ESP, EAX, TIMES_2, -kWordSize));
-      __ LoadTaggedClassIdMayBeSmi(EDI, EDI);
-      __ cmpl(EDI, Address(EBX, kWordSize));  // Class id match?
-      __ j(EQUAL, &found);                    // Break.
-
-      __ Bind(&update);
-      __ addl(EBX, Immediate(entry_size));  // Next entry.
-      __ cmpl(Address(EBX, -entry_size),
-              Immediate(Smi::RawValue(kIllegalCid)));  // Done?
-    }
-
-    if (unroll == 0) {
-      __ j(NOT_EQUAL, &loop);
-    } else {
-      __ j(EQUAL, &miss);
-    }
-  }
-
-  __ Bind(&miss);
-  __ Comment("IC miss");
-  // Compute address of arguments (first read number of arguments from
-  // arguments descriptor array and then compute address on the stack).
-  __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
-  __ leal(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX is Smi.
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  __ pushl(EDX);           // Preserve arguments descriptor array.
-  __ pushl(ECX);           // Preserve IC data object.
-  __ pushl(Immediate(0));  // Result slot.
-  // Push call arguments.
-  for (intptr_t i = 0; i < num_args; i++) {
-    __ movl(EBX, Address(EAX, -kWordSize * i));
-    __ pushl(EBX);
-  }
-  __ pushl(ECX);  // Pass IC data object.
-  __ CallRuntime(handle_ic_miss, num_args + 1);
-  // Remove the call arguments pushed earlier, including the IC data object.
-  for (intptr_t i = 0; i < num_args + 1; i++) {
-    __ popl(EAX);
-  }
-  __ popl(EAX);  // Pop returned function object into EAX.
-  __ popl(ECX);  // Restore IC data array.
-  __ popl(EDX);  // Restore arguments descriptor array.
-  __ LeaveFrame();
-  Label call_target_function;
-  if (!FLAG_lazy_dispatchers) {
-    GenerateDispatcherCode(assembler, &call_target_function);
-  } else {
-    __ jmp(&call_target_function);
-  }
-
-  __ Bind(&found);
-
-  // EBX: Pointer to an IC data check group.
-  if (FLAG_optimization_counter_threshold >= 0) {
-    __ Comment("Update caller's counter");
-    // Ignore overflow.
-    __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
-  }
-
-  __ movl(EAX, Address(EBX, target_offset));
-  __ Bind(&call_target_function);
-  __ Comment("Call target");
-  // EAX: Target function.
-  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-  __ jmp(EBX);
-
-#if !defined(PRODUCT)
-  if (!optimized) {
-    __ Bind(&stepping);
-    __ EnterStubFrame();
-    __ pushl(ECX);
-    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ popl(ECX);
-    __ LeaveFrame();
-    __ jmp(&done_stepping);
-  }
-#endif
-}
-
-// Use inline cache data array to invoke the target or continue in inline
-// cache miss handler. Stub for 1-argument check (receiver class).
-//  ECX: Inline cache data object.
-//  TOS(0): Return address.
-// Inline cache data object structure:
-// 0: function-name
-// 1: N, number of arguments checked.
-// 2 .. (length - 1): group of checks, each check containing:
-//   - N classes.
-//   - 1 target function.
-void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  __ Stop("Unimplemented");
-}
-
-void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL);
-}
-
-void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
-}
-
-void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
-}
-
-void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
-}
-
-// Use inline cache data array to invoke the target or continue in inline
-// cache miss handler. Stub for 1-argument check (receiver class).
-//  EDI: function which counter needs to be incremented.
-//  ECX: Inline cache data object.
-//  TOS(0): Return address.
-// Inline cache data object structure:
-// 0: function-name
-// 1: N, number of arguments checked.
-// 2 .. (length - 1): group of checks, each check containing:
-//   - N classes.
-//   - 1 target function.
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
-                                    Token::kILLEGAL, true /* optimized */);
-}
-
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  __ Stop("Unimplemented");
-}
-
-void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL, true /* optimized */);
-}
-
-// Intermediary stub between a static call and its target. ICData contains
-// the target function and the call count.
-// ECX: ICData
-void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == num_args.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset()));
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ andl(EBX, Immediate(ICData::NumArgsTestedMask()));
-    __ cmpl(EBX, Immediate(0));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect IC data for unoptimized static call");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(EAX);
-  __ cmpb(Address(EAX, Isolate::single_step_offset()), Immediate(0));
-  __ j(NOT_EQUAL, &stepping, Assembler::kNearJump);
-  __ Bind(&done_stepping);
-#endif
-
-  // ECX: IC data object (preserved).
-  __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
-  // EBX: ic_data_array with entries: target functions and count.
-  __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
-  // EBX: points directly to the first ic data array element.
-  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    // Increment count for this call, ignore overflow.
-    __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
-  }
-
-  // Load arguments descriptor into EDX.
-  __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
-
-  // Get function and call it, if possible.
-  __ movl(EAX, Address(EBX, target_offset));
-  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-  __ jmp(EBX);
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ pushl(ECX);
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ popl(ECX);
-  __ LeaveFrame();
-  __ jmp(&done_stepping, Assembler::kNearJump);
-#endif
-}
-
-void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, EBX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
-}
-
-// Stub for compiling a function and jumping to the compiled code.
-// EDX: Arguments descriptor.
-// EAX: Function.
-void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushl(EDX);  // Preserve arguments descriptor array.
-  __ pushl(EAX);  // Pass function.
-  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
-  __ popl(EAX);  // Restore function.
-  __ popl(EDX);  // Restore arguments descriptor array.
-  __ LeaveFrame();
-
-  // When using the interpreter, the function's code may now point to the
-  // InterpretCall stub. Make sure EAX, ECX, and EDX are preserved.
-  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-  __ jmp(EBX);
-}
-
-void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-  __ Unimplemented("Interpreter not yet supported");
-}
-
-// ECX: Contains an ICData.
-void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  // Save IC data.
-  __ pushl(ECX);
-  // Room for result. Debugger stub returns address of the
-  // unpatched runtime stub.
-  __ pushl(Immediate(0));  // Room for result.
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ popl(EAX);  // Code of original stub.
-  __ popl(ECX);  // Restore IC data.
-  __ LeaveFrame();
-  // Jump to original stub.
-  __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
-  __ jmp(EAX);
-}
-
-void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  // Room for result. Debugger stub returns address of the
-  // unpatched runtime stub.
-  __ pushl(Immediate(0));  // Room for result.
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ popl(EAX);  // Code of the original stub
-  __ LeaveFrame();
-  // Jump to original stub.
-  __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
-  __ jmp(EAX);
-}
-
-// Called only from unoptimized code.
-void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) {
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(EAX);
-  __ movzxb(EAX, Address(EAX, Isolate::single_step_offset()));
-  __ cmpl(EAX, Immediate(0));
-  __ j(NOT_EQUAL, &stepping, Assembler::kNearJump);
-  __ Bind(&done_stepping);
-  __ ret();
-
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ LeaveFrame();
-  __ jmp(&done_stepping, Assembler::kNearJump);
-}
-
-// Used to check class and type arguments. Arguments passed on stack:
-// TOS + 0: return address.
-// TOS + 1: function type arguments (only if n == 4, can be raw_null).
-// TOS + 2: instantiator type arguments (only if n == 4, can be raw_null).
-// TOS + 3: instance.
-// TOS + 4: SubtypeTestCache.
-// Result in ECX: null -> not found, otherwise result (true or false).
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
-
-  static intptr_t kFunctionTypeArgumentsInBytes = 1 * kWordSize;
-  static intptr_t kInstantiatorTypeArgumentsInBytes = 2 * kWordSize;
-  static intptr_t kInstanceOffsetInBytes = 3 * kWordSize;
-  static intptr_t kCacheOffsetInBytes = 4 * kWordSize;
-
-  const Register kInstanceReg = EAX;
-
-  const Register kInstanceCidOrFunction = ECX;
-  const Register kInstanceInstantiatorTypeArgumentsReg = EBX;
-
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-
-  __ movl(kInstanceReg, Address(ESP, kInstanceOffsetInBytes));
-
-  // Loop initialization (moved up here to avoid having all dependent loads
-  // after each other)
-  __ movl(EDX, Address(ESP, kCacheOffsetInBytes));
-  __ movl(EDX, FieldAddress(EDX, SubtypeTestCache::cache_offset()));
-  __ addl(EDX, Immediate(Array::data_offset() - kHeapObjectTag));
-
-  Label loop, not_closure;
-  if (n >= 4) {
-    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
-  } else {
-    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
-  }
-  __ cmpl(kInstanceCidOrFunction, Immediate(kClosureCid));
-  __ j(NOT_EQUAL, &not_closure, Assembler::kNearJump);
-
-  // Closure handling.
-  {
-    __ movl(kInstanceCidOrFunction,
-            FieldAddress(kInstanceReg, Closure::function_offset()));
-    if (n >= 2) {
-      __ movl(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(kInstanceReg,
-                           Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        __ pushl(FieldAddress(kInstanceReg,
-                              Closure::delayed_type_arguments_offset()));
-        __ pushl(FieldAddress(kInstanceReg,
-                              Closure::function_type_arguments_offset()));
-      }
-    }
-    __ jmp(&loop, Assembler::kNearJump);
-  }
-
-  // Non-Closure handling.
-  {
-    __ Bind(&not_closure);
-    if (n >= 2) {
-      Label has_no_type_arguments;
-      __ LoadClassById(EDI, kInstanceCidOrFunction);
-      __ movl(kInstanceInstantiatorTypeArgumentsReg, raw_null);
-      __ movl(EDI,
-              FieldAddress(
-                  EDI, Class::type_arguments_field_offset_in_words_offset()));
-      __ cmpl(EDI, Immediate(Class::kNoTypeArguments));
-      __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
-      __ movl(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(kInstanceReg, EDI, TIMES_4, 0));
-      __ Bind(&has_no_type_arguments);
-
-      if (n >= 6) {
-        __ pushl(raw_null);  // delayed.
-        __ pushl(raw_null);  // function.
-      }
-    }
-    __ SmiTag(kInstanceCidOrFunction);
-  }
-
-  const intptr_t kInstanceParentFunctionTypeArgumentsFromSp = 0;
-  const intptr_t kInstanceDelayedFunctionTypeArgumentsFromSp = kWordSize;
-  const intptr_t args_offset = n >= 6 ? 2 * kWordSize : 0;
-
-  Label found, not_found, next_iteration;
-
-  // Loop header.
-  __ Bind(&loop);
-  __ movl(EDI, Address(EDX, kWordSize *
-                                SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmpl(EDI, raw_null);
-  __ j(EQUAL, &not_found, Assembler::kNearJump);
-  __ cmpl(EDI, kInstanceCidOrFunction);
-  if (n == 1) {
-    __ j(EQUAL, &found, Assembler::kNearJump);
-  } else {
-    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-    __ cmpl(kInstanceInstantiatorTypeArgumentsReg,
-            Address(EDX, kWordSize * SubtypeTestCache::kInstanceTypeArguments));
-    if (n == 2) {
-      __ j(EQUAL, &found, Assembler::kNearJump);
-    } else {
-      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ movl(EDI,
-              Address(EDX, kWordSize *
-                               SubtypeTestCache::kInstantiatorTypeArguments));
-      __ cmpl(EDI,
-              Address(ESP, args_offset + kInstantiatorTypeArgumentsInBytes));
-      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ movl(EDI, Address(EDX, kWordSize *
-                                    SubtypeTestCache::kFunctionTypeArguments));
-      __ cmpl(EDI, Address(ESP, args_offset + kFunctionTypeArgumentsInBytes));
-      if (n == 4) {
-        __ j(EQUAL, &found, Assembler::kNearJump);
-      } else {
-        ASSERT(n == 6);
-        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-
-        __ movl(
-            EDI,
-            Address(
-                EDX,
-                kWordSize *
-                    SubtypeTestCache::kInstanceParentFunctionTypeArguments));
-        __ cmpl(EDI, Address(ESP, kInstanceParentFunctionTypeArgumentsFromSp));
-        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-        __ movl(
-            EDI,
-            Address(
-                EDX,
-                kWordSize *
-                    SubtypeTestCache::kInstanceDelayedFunctionTypeArguments));
-        __ cmpl(EDI, Address(ESP, kInstanceDelayedFunctionTypeArgumentsFromSp));
-        __ j(EQUAL, &found, Assembler::kNearJump);
-      }
-    }
-  }
-  __ Bind(&next_iteration);
-  __ addl(EDX, Immediate(kWordSize * SubtypeTestCache::kTestEntryLength));
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&found);
-  __ movl(ECX, Address(EDX, kWordSize * SubtypeTestCache::kTestResult));
-  if (n == 6) {
-    __ Drop(2);
-  }
-  __ ret();
-
-  __ Bind(&not_found);
-  __ movl(ECX, raw_null);
-  if (n == 6) {
-    __ Drop(2);
-  }
-  __ ret();
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCode::GenerateLazySpecializeTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
-  // Not implemented on ia32.
-  __ Breakpoint();
-}
-
-// Return the current stack pointer address, used to do stack alignment checks.
-// TOS + 0: return address
-// Result in EAX.
-void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
-  __ leal(EAX, Address(ESP, kWordSize));
-  __ ret();
-}
-
-// Jump to a frame on the call stack.
-// TOS + 0: return address
-// TOS + 1: program_counter
-// TOS + 2: stack_pointer
-// TOS + 3: frame_pointer
-// TOS + 4: thread
-// No Result.
-void StubCode::GenerateJumpToFrameStub(Assembler* assembler) {
-  __ movl(THR, Address(ESP, 4 * kWordSize));  // Load target thread.
-  __ movl(EBP, Address(ESP, 3 * kWordSize));  // Load target frame_pointer.
-  __ movl(EBX, Address(ESP, 1 * kWordSize));  // Load target PC into EBX.
-  __ movl(ESP, Address(ESP, 2 * kWordSize));  // Load target stack_pointer.
-  // Set tag.
-  __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-  // Clear top exit frame.
-  __ movl(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-  __ jmp(EBX);  // Jump to the exception handler code.
-}
-
-// Run an exception handler.  Execution comes from JumpToFrame stub.
-//
-// The arguments are stored in the Thread object.
-// No result.
-void StubCode::GenerateRunExceptionHandlerStub(Assembler* assembler) {
-  ASSERT(kExceptionObjectReg == EAX);
-  ASSERT(kStackTraceObjectReg == EDX);
-  __ movl(EBX, Address(THR, Thread::resume_pc_offset()));
-
-  ASSERT(Thread::CanLoadFromThread(Object::null_object()));
-  __ movl(ECX, Address(THR, Thread::OffsetFromThread(Object::null_object())));
-
-  // Load the exception from the current thread.
-  Address exception_addr(THR, Thread::active_exception_offset());
-  __ movl(kExceptionObjectReg, exception_addr);
-  __ movl(exception_addr, ECX);
-
-  // Load the stacktrace from the current thread.
-  Address stacktrace_addr(THR, Thread::active_stacktrace_offset());
-  __ movl(kStackTraceObjectReg, stacktrace_addr);
-  __ movl(stacktrace_addr, ECX);
-
-  __ jmp(EBX);  // Jump to continuation point.
-}
-
-// Deoptimize a frame on the call stack before rewinding.
-// The arguments are stored in the Thread object.
-// No result.
-void StubCode::GenerateDeoptForRewindStub(Assembler* assembler) {
-  // Push the deopt pc.
-  __ pushl(Address(THR, Thread::resume_pc_offset()));
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-
-  // After we have deoptimized, jump to the correct frame.
-  __ EnterStubFrame();
-  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
-  __ LeaveFrame();
-  __ int3();
-}
-
-// Calls to the runtime to optimize the given function.
-// EBX: function to be reoptimized.
-// EDX: argument descriptor (preserved).
-void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushl(EDX);
-  __ pushl(Immediate(0));  // Setup space on stack for return value.
-  __ pushl(EBX);
-  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
-  __ popl(EAX);  // Discard argument.
-  __ popl(EAX);  // Get Function object
-  __ popl(EDX);  // Restore argument descriptor.
-  __ LeaveFrame();
-  __ movl(CODE_REG, FieldAddress(EAX, Function::code_offset()));
-  __ movl(EAX, FieldAddress(EAX, Function::entry_point_offset()));
-  __ jmp(EAX);
-  __ int3();
-}
-
-// Does identical check (object references are equal or not equal) with special
-// checks for boxed numbers.
-// Return ZF set.
-// Note: A Mint cannot contain a value that would fit in Smi.
-static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
-                                                 const Register left,
-                                                 const Register right,
-                                                 const Register temp) {
-  Label reference_compare, done, check_mint;
-  // If any of the arguments is Smi do reference compare.
-  __ testl(left, Immediate(kSmiTagMask));
-  __ j(ZERO, &reference_compare, Assembler::kNearJump);
-  __ testl(right, Immediate(kSmiTagMask));
-  __ j(ZERO, &reference_compare, Assembler::kNearJump);
-
-  // Value compare for two doubles.
-  __ CompareClassId(left, kDoubleCid, temp);
-  __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump);
-  __ CompareClassId(right, kDoubleCid, temp);
-  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-
-  // Double values bitwise compare.
-  __ movl(temp, FieldAddress(left, Double::value_offset() + 0 * kWordSize));
-  __ cmpl(temp, FieldAddress(right, Double::value_offset() + 0 * kWordSize));
-  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-  __ movl(temp, FieldAddress(left, Double::value_offset() + 1 * kWordSize));
-  __ cmpl(temp, FieldAddress(right, Double::value_offset() + 1 * kWordSize));
-  __ jmp(&done, Assembler::kNearJump);
-
-  __ Bind(&check_mint);
-  __ CompareClassId(left, kMintCid, temp);
-  __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump);
-  __ CompareClassId(right, kMintCid, temp);
-  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-  __ movl(temp, FieldAddress(left, Mint::value_offset() + 0 * kWordSize));
-  __ cmpl(temp, FieldAddress(right, Mint::value_offset() + 0 * kWordSize));
-  __ j(NOT_EQUAL, &done, Assembler::kNearJump);
-  __ movl(temp, FieldAddress(left, Mint::value_offset() + 1 * kWordSize));
-  __ cmpl(temp, FieldAddress(right, Mint::value_offset() + 1 * kWordSize));
-  __ jmp(&done, Assembler::kNearJump);
-
-  __ Bind(&reference_compare);
-  __ cmpl(left, right);
-  __ Bind(&done);
-}
-
-// Called only from unoptimized code. All relevant registers have been saved.
-// TOS + 0: return address
-// TOS + 1: right argument.
-// TOS + 2: left argument.
-// Returns ZF set.
-void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(EAX);
-  __ movzxb(EAX, Address(EAX, Isolate::single_step_offset()));
-  __ cmpl(EAX, Immediate(0));
-  __ j(NOT_EQUAL, &stepping);
-  __ Bind(&done_stepping);
-#endif
-
-  const Register left = EAX;
-  const Register right = EDX;
-  const Register temp = ECX;
-  __ movl(left, Address(ESP, 2 * kWordSize));
-  __ movl(right, Address(ESP, 1 * kWordSize));
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
-  __ ret();
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ LeaveFrame();
-  __ jmp(&done_stepping);
-#endif
-}
-
-// Called from optimized code only.
-// TOS + 0: return address
-// TOS + 1: right argument.
-// TOS + 2: left argument.
-// Returns ZF set.
-void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-  const Register left = EAX;
-  const Register right = EDX;
-  const Register temp = ECX;
-  __ movl(left, Address(ESP, 2 * kWordSize));
-  __ movl(right, Address(ESP, 1 * kWordSize));
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
-  __ ret();
-}
-
-// Called from megamorphic calls.
-//  EBX: receiver
-//  ECX: MegamorphicCache (preserved)
-// Passed to target:
-//  EBX: target entry point
-//  EDX: argument descriptor
-void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  // Jump if receiver is a smi.
-  Label smi_case;
-  // Check if object (in tmp) is a Smi.
-  __ testl(EBX, Immediate(kSmiTagMask));
-  // Jump out of line for smi case.
-  __ j(ZERO, &smi_case, Assembler::kNearJump);
-
-  // Loads the cid of the instance.
-  __ LoadClassId(EAX, EBX);
-
-  Label cid_loaded;
-  __ Bind(&cid_loaded);
-  __ movl(EBX, FieldAddress(ECX, MegamorphicCache::mask_offset()));
-  __ movl(EDI, FieldAddress(ECX, MegamorphicCache::buckets_offset()));
-  // EDI: cache buckets array.
-  // EBX: mask as a smi.
-
-  // Tag cid as a smi.
-  __ addl(EAX, EAX);
-
-  // Compute the table index.
-  ASSERT(MegamorphicCache::kSpreadFactor == 7);
-  // Use leal and subl multiply with 7 == 8 - 1.
-  __ leal(EDX, Address(EAX, TIMES_8, 0));
-  __ subl(EDX, EAX);
-
-  Label loop;
-  __ Bind(&loop);
-  __ andl(EDX, EBX);
-
-  const intptr_t base = Array::data_offset();
-  Label probe_failed;
-  // EDX is smi tagged, but table entries are two words, so TIMES_4.
-  __ cmpl(EAX, FieldAddress(EDI, EDX, TIMES_4, base));
-  __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump);
-
-  Label load_target;
-  __ Bind(&load_target);
-  // Call the target found in the cache.  For a class id match, this is a
-  // proper target for the given name and arguments descriptor.  If the
-  // 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 + kWordSize));
-  __ movl(EDX,
-          FieldAddress(ECX, MegamorphicCache::arguments_descriptor_offset()));
-  __ movl(EBX, FieldAddress(EAX, Function::entry_point_offset()));
-  __ ret();
-
-  __ Bind(&probe_failed);
-  // Probe failed, check if it is a miss.
-  __ cmpl(FieldAddress(EDI, EDX, TIMES_4, base),
-          Immediate(Smi::RawValue(kIllegalCid)));
-  __ j(ZERO, &load_target, Assembler::kNearJump);
-
-  // Try next entry in the table.
-  __ AddImmediate(EDX, Immediate(Smi::RawValue(1)));
-  __ jmp(&loop);
-
-  // Load cid for the Smi case.
-  __ Bind(&smi_case);
-  __ movl(EAX, Immediate(kSmiCid));
-  __ jmp(&cid_loaded);
-}
-
-// Called from switchable IC calls.
-//  EBX: receiver
-//  ECX: ICData (preserved)
-// Passed to target:
-//  EDX: arguments descriptor
-void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
-  __ int3();
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_IA32) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
new file mode 100644
index 0000000..ce9d729
--- /dev/null
+++ b/runtime/vm/stub_code_list.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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_STUB_CODE_LIST_H_
+#define RUNTIME_VM_STUB_CODE_LIST_H_
+
+namespace dart {
+
+// List of stubs created in the VM isolate, these stubs are shared by different
+// isolates running in this dart process.
+#if !defined(TARGET_ARCH_DBC)
+#define VM_STUB_CODE_LIST(V)                                                   \
+  V(GetCStackPointer)                                                          \
+  V(JumpToFrame)                                                               \
+  V(RunExceptionHandler)                                                       \
+  V(DeoptForRewind)                                                            \
+  V(WriteBarrier)                                                              \
+  V(WriteBarrierWrappers)                                                      \
+  V(ArrayWriteBarrier)                                                         \
+  V(PrintStopMessage)                                                          \
+  V(AllocateArray)                                                             \
+  V(AllocateContext)                                                           \
+  V(CallToRuntime)                                                             \
+  V(LazyCompile)                                                               \
+  V(InterpretCall)                                                             \
+  V(CallBootstrapNative)                                                       \
+  V(CallNoScopeNative)                                                         \
+  V(CallAutoScopeNative)                                                       \
+  V(FixCallersTarget)                                                          \
+  V(CallStaticFunction)                                                        \
+  V(OptimizeFunction)                                                          \
+  V(InvokeDartCode)                                                            \
+  V(InvokeDartCodeFromBytecode)                                                \
+  V(DebugStepCheck)                                                            \
+  V(UnlinkedCall)                                                              \
+  V(MonomorphicMiss)                                                           \
+  V(SingleTargetCall)                                                          \
+  V(ICCallThroughFunction)                                                     \
+  V(ICCallThroughCode)                                                         \
+  V(MegamorphicCall)                                                           \
+  V(FixAllocationStubTarget)                                                   \
+  V(Deoptimize)                                                                \
+  V(DeoptimizeLazyFromReturn)                                                  \
+  V(DeoptimizeLazyFromThrow)                                                   \
+  V(UnoptimizedIdenticalWithNumberCheck)                                       \
+  V(OptimizedIdenticalWithNumberCheck)                                         \
+  V(ICCallBreakpoint)                                                          \
+  V(RuntimeCallBreakpoint)                                                     \
+  V(OneArgCheckInlineCache)                                                    \
+  V(TwoArgsCheckInlineCache)                                                   \
+  V(SmiAddInlineCache)                                                         \
+  V(SmiSubInlineCache)                                                         \
+  V(SmiEqualInlineCache)                                                       \
+  V(OneArgOptimizedCheckInlineCache)                                           \
+  V(TwoArgsOptimizedCheckInlineCache)                                          \
+  V(ZeroArgsUnoptimizedStaticCall)                                             \
+  V(OneArgUnoptimizedStaticCall)                                               \
+  V(TwoArgsUnoptimizedStaticCall)                                              \
+  V(Subtype1TestCache)                                                         \
+  V(Subtype2TestCache)                                                         \
+  V(Subtype4TestCache)                                                         \
+  V(Subtype6TestCache)                                                         \
+  V(DefaultTypeTest)                                                           \
+  V(TopTypeTypeTest)                                                           \
+  V(TypeRefTypeTest)                                                           \
+  V(UnreachableTypeTest)                                                       \
+  V(SlowTypeTest)                                                              \
+  V(LazySpecializeTypeTest)                                                    \
+  V(CallClosureNoSuchMethod)                                                   \
+  V(FrameAwaitingMaterialization)                                              \
+  V(AsynchronousGapMarker)                                                     \
+  V(NullErrorSharedWithFPURegs)                                                \
+  V(NullErrorSharedWithoutFPURegs)                                             \
+  V(StackOverflowSharedWithFPURegs)                                            \
+  V(StackOverflowSharedWithoutFPURegs)                                         \
+  V(OneArgCheckInlineCacheWithExactnessCheck)                                  \
+  V(OneArgOptimizedCheckInlineCacheWithExactnessCheck)
+
+#else
+#define VM_STUB_CODE_LIST(V)                                                   \
+  V(LazyCompile)                                                               \
+  V(OptimizeFunction)                                                          \
+  V(CallClosureNoSuchMethod)                                                   \
+  V(RunExceptionHandler)                                                       \
+  V(DeoptForRewind)                                                            \
+  V(FixCallersTarget)                                                          \
+  V(Deoptimize)                                                                \
+  V(DeoptimizeLazyFromReturn)                                                  \
+  V(DeoptimizeLazyFromThrow)                                                   \
+  V(DefaultTypeTest)                                                           \
+  V(TopTypeTypeTest)                                                           \
+  V(TypeRefTypeTest)                                                           \
+  V(UnreachableTypeTest)                                                       \
+  V(SlowTypeTest)                                                              \
+  V(LazySpecializeTypeTest)                                                    \
+  V(FrameAwaitingMaterialization)                                              \
+  V(AsynchronousGapMarker)                                                     \
+  V(InvokeDartCodeFromBytecode)                                                \
+  V(InterpretCall)
+
+#endif  // !defined(TARGET_ARCH_DBC)
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_STUB_CODE_LIST_H_
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
deleted file mode 100644
index bcc2198..0000000
--- a/runtime/vm/stub_code_x64.cc
+++ /dev/null
@@ -1,3159 +0,0 @@
-// 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.
-
-#include "vm/globals.h"
-
-#include "vm/stub_code.h"
-
-#if defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
-
-#include "vm/compiler/assembler/assembler.h"
-#include "vm/compiler/assembler/disassembler.h"
-#include "vm/compiler/backend/flow_graph_compiler.h"
-#include "vm/compiler/jit/compiler.h"
-#include "vm/constants_x64.h"
-#include "vm/dart_entry.h"
-#include "vm/heap/heap.h"
-#include "vm/heap/scavenger.h"
-#include "vm/instructions.h"
-#include "vm/object_store.h"
-#include "vm/resolver.h"
-#include "vm/stack_frame.h"
-#include "vm/tags.h"
-#include "vm/type_testing_stubs.h"
-
-#define __ assembler->
-
-namespace dart {
-
-DEFINE_FLAG(bool, inline_alloc, true, "Inline allocation of objects.");
-DEFINE_FLAG(bool,
-            use_slow_path,
-            false,
-            "Set to true for debugging & verifying the slow paths.");
-DECLARE_FLAG(bool, enable_interpreter);
-DECLARE_FLAG(bool, precompiled_mode);
-
-// Input parameters:
-//   RSP : points to return address.
-//   RSP + 8 : address of last argument in argument array.
-//   RSP + 8*R10 : address of first argument in argument array.
-//   RSP + 8*R10 + 8 : address of return value.
-//   RBX : address of the runtime function to call.
-//   R10 : number of arguments to the call.
-// Must preserve callee saved registers R12 and R13.
-void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  const intptr_t thread_offset = NativeArguments::thread_offset();
-  const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
-  const intptr_t argv_offset = NativeArguments::argv_offset();
-  const intptr_t retval_offset = NativeArguments::retval_offset();
-
-  __ movq(CODE_REG, Address(THR, Thread::call_to_runtime_stub_offset()));
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to Dart VM C++ code.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ movq(RAX, Immediate(VMTag::kDartCompiledTagId));
-    __ cmpq(RAX, Assembler::VMTagAddress());
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing VM code.
-  __ movq(Assembler::VMTagAddress(), RBX);
-
-  // Reserve space for arguments and align frame before entering C++ world.
-  __ subq(RSP, Immediate(sizeof(NativeArguments)));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  // Pass NativeArguments structure by value and call runtime.
-  __ movq(Address(RSP, thread_offset), THR);  // Set thread in NativeArgs.
-  // There are no runtime calls to closures, so we do not need to set the tag
-  // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
-  __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
-  // Compute argv.
-  __ leaq(RAX, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize));
-  __ movq(Address(RSP, argv_offset), RAX);    // Set argv in NativeArguments.
-  __ addq(RAX, Immediate(1 * kWordSize));     // Retval is next to 1st argument.
-  __ movq(Address(RSP, retval_offset), RAX);  // Set retval in NativeArguments.
-#if defined(_WIN64)
-  ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit);
-  __ movq(CallingConventions::kArg1Reg, RSP);
-#endif
-  __ CallCFunction(RBX);
-
-  // Mark that the thread is executing Dart code.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  // Restore the global object pool after returning from runtime (old space is
-  // moving, so the GOP could have been relocated).
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ movq(PP, Address(THR, Thread::global_object_pool_offset()));
-  }
-
-  __ LeaveStubFrame();
-
-  // The following return can jump to a lazy-deopt stub, which assumes RAX
-  // contains a return value and will save it in a GC-visible way.  We therefore
-  // have to ensure RAX does not contain any garbage value left from the C
-  // function we called (which has return type "void").
-  // (See GenerateDeoptimizationSequence::saved_result_slot_from_fp.)
-  __ xorq(RAX, RAX);
-  __ ret();
-}
-
-void StubCode::GenerateSharedStub(Assembler* assembler,
-                                  bool save_fpu_registers,
-                                  const RuntimeEntry* target,
-                                  intptr_t self_code_stub_offset_from_thread,
-                                  bool allow_return) {
-  // We want the saved registers to appear like part of the caller's frame, so
-  // we push them before calling EnterStubFrame.
-  __ PushRegisters(kDartAvailableCpuRegs,
-                   save_fpu_registers ? kAllFpuRegistersList : 0);
-
-  const intptr_t kSavedCpuRegisterSlots =
-      Utils::CountOneBitsWord(kDartAvailableCpuRegs);
-
-  const intptr_t kSavedFpuRegisterSlots =
-      save_fpu_registers ? kNumberOfFpuRegisters * kFpuRegisterSize / kWordSize
-                         : 0;
-
-  const intptr_t kAllSavedRegistersSlots =
-      kSavedCpuRegisterSlots + kSavedFpuRegisterSlots;
-
-  // Copy down the return address so the stack layout is correct.
-  __ pushq(Address(RSP, kAllSavedRegistersSlots * kWordSize));
-
-  __ movq(CODE_REG, Address(THR, self_code_stub_offset_from_thread));
-
-  __ EnterStubFrame();
-  __ CallRuntime(*target, /*argument_count=*/0);
-  if (!allow_return) {
-    __ Breakpoint();
-    return;
-  }
-  __ LeaveStubFrame();
-
-  // Drop "official" return address -- we can just use the one stored above the
-  // saved registers.
-  __ Drop(1);
-
-  __ PopRegisters(kDartAvailableCpuRegs,
-                  save_fpu_registers ? kAllFpuRegistersList : 0);
-
-  __ ret();
-}
-
-// RBX: The extracted method.
-// RDX: The type_arguments_field_offset (or 0)
-void StubCode::GenerateBuildMethodExtractorStub(Assembler* assembler) {
-  Thread* thread = Thread::Current();
-  Zone* Z = thread->zone();
-  ObjectStore* object_store = thread->isolate()->object_store();
-
-  const auto& closure_class =
-      Class::ZoneHandle(Z, object_store->closure_class());
-  const auto& closure_allocation_stub =
-      Code::ZoneHandle(Z, StubCode::GetAllocationStubForClass(closure_class));
-
-  const intptr_t kReceiverOffset = compiler_frame_layout.param_end_from_fp + 1;
-
-  const auto& context_allocation_stub = StubCode::AllocateContext();
-
-  __ EnterStubFrame();
-
-  // Push type_arguments vector (or null)
-  Label no_type_args;
-  __ movq(RCX, Address(THR, Thread::object_null_offset()));
-  __ cmpq(RDX, Immediate(0));
-  __ j(EQUAL, &no_type_args, Assembler::kNearJump);
-  __ movq(RAX, Address(RBP, kWordSize * kReceiverOffset));
-  __ movq(RCX, Address(RAX, RDX, TIMES_1, 0));
-  __ Bind(&no_type_args);
-  __ pushq(RCX);
-
-  // Push extracted method.
-  __ pushq(RBX);
-
-  // Allocate context.
-  {
-    Label done, slow_path;
-    __ TryAllocateArray(kContextCid, Context::InstanceSize(1), &slow_path,
-                        Assembler::kFarJump,
-                        RAX,  // instance
-                        RSI,  // end address
-                        RDI);
-    __ movq(RSI, Address(THR, Thread::object_null_offset()));
-    __ movq(FieldAddress(RAX, Context::parent_offset()), RSI);
-    __ movq(FieldAddress(RAX, Context::num_variables_offset()), Immediate(1));
-    __ jmp(&done);
-
-    __ Bind(&slow_path);
-
-    __ LoadImmediate(/*num_vars=*/R10, Immediate(1));
-    __ LoadObject(CODE_REG, context_allocation_stub);
-    __ call(FieldAddress(CODE_REG, Code::entry_point_offset()));
-
-    __ Bind(&done);
-  }
-
-  // Store receiver in context
-  __ movq(RSI, Address(RBP, kWordSize * kReceiverOffset));
-  __ StoreIntoObject(RAX, FieldAddress(RAX, Context::variable_offset(0)), RSI);
-
-  // Push context.
-  __ pushq(RAX);
-
-  // Allocate closure.
-  __ LoadObject(CODE_REG, closure_allocation_stub);
-  __ call(FieldAddress(CODE_REG,
-                       Code::entry_point_offset(Code::EntryKind::kUnchecked)));
-
-  // Populate closure object.
-  __ popq(RCX);  // Pop context.
-  __ StoreIntoObject(RAX, FieldAddress(RAX, Closure::context_offset()), RCX);
-  __ popq(RCX);  // Pop extracted method.
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, Closure::function_offset()), RCX);
-  __ popq(RCX);  // Pop type argument vector.
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, Closure::instantiator_type_arguments_offset()),
-      RCX);
-  __ LoadObject(RCX, Object::empty_type_arguments());
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, Closure::delayed_type_arguments_offset()), RCX);
-
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-void StubCode::GenerateNullErrorSharedWithoutFPURegsStub(Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/false,
-                     &kNullErrorRuntimeEntry,
-                     Thread::null_error_shared_without_fpu_regs_stub_offset(),
-                     /*allow_return=*/false);
-}
-
-void StubCode::GenerateNullErrorSharedWithFPURegsStub(Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/true,
-                     &kNullErrorRuntimeEntry,
-                     Thread::null_error_shared_with_fpu_regs_stub_offset(),
-                     /*allow_return=*/false);
-}
-
-void StubCode::GenerateStackOverflowSharedWithoutFPURegsStub(
-    Assembler* assembler) {
-  GenerateSharedStub(
-      assembler, /*save_fpu_registers=*/false, &kStackOverflowRuntimeEntry,
-      Thread::stack_overflow_shared_without_fpu_regs_stub_offset(),
-      /*allow_return=*/true);
-}
-
-void StubCode::GenerateStackOverflowSharedWithFPURegsStub(
-    Assembler* assembler) {
-  GenerateSharedStub(assembler, /*save_fpu_registers=*/true,
-                     &kStackOverflowRuntimeEntry,
-                     Thread::stack_overflow_shared_with_fpu_regs_stub_offset(),
-                     /*allow_return=*/true);
-}
-
-// Input parameters:
-//   RSP : points to return address.
-//   RDI : stop message (const char*).
-// Must preserve all registers.
-void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
-  __ EnterCallRuntimeFrame(0);
-// Call the runtime leaf function. RDI already contains the parameter.
-#if defined(_WIN64)
-  __ movq(CallingConventions::kArg1Reg, RDI);
-#endif
-  __ CallRuntime(kPrintStopMessageRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ ret();
-}
-
-// Input parameters:
-//   RSP : points to return address.
-//   RSP + 8 : address of return value.
-//   RAX : address of first argument in argument array.
-//   RBX : address of the native function to call.
-//   R10 : argc_tag including number of arguments and function kind.
-static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
-                                              Address wrapper_address) {
-  const intptr_t native_args_struct_offset = 0;
-  const intptr_t thread_offset =
-      NativeArguments::thread_offset() + native_args_struct_offset;
-  const intptr_t argc_tag_offset =
-      NativeArguments::argc_tag_offset() + native_args_struct_offset;
-  const intptr_t argv_offset =
-      NativeArguments::argv_offset() + native_args_struct_offset;
-  const intptr_t retval_offset =
-      NativeArguments::retval_offset() + native_args_struct_offset;
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to native code.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ movq(R8, Immediate(VMTag::kDartCompiledTagId));
-    __ cmpq(R8, Assembler::VMTagAddress());
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ movq(Assembler::VMTagAddress(), RBX);
-
-  // Reserve space for the native arguments structure passed on the stack (the
-  // outgoing pointer parameter to the native arguments structure is passed in
-  // RDI) and align frame before entering the C++ world.
-  __ subq(RSP, Immediate(sizeof(NativeArguments)));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  // Pass NativeArguments structure by value and call native function.
-  __ movq(Address(RSP, thread_offset), THR);    // Set thread in NativeArgs.
-  __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
-  __ movq(Address(RSP, argv_offset), RAX);      // Set argv in NativeArguments.
-  __ leaq(RAX, Address(RBP, 2 * kWordSize));    // Compute return value addr.
-  __ movq(Address(RSP, retval_offset), RAX);  // Set retval in NativeArguments.
-
-  // Pass the pointer to the NativeArguments.
-  __ movq(CallingConventions::kArg1Reg, RSP);
-  // Pass pointer to function entrypoint.
-  __ movq(CallingConventions::kArg2Reg, RBX);
-
-  __ movq(RAX, wrapper_address);
-  __ CallCFunction(RAX);
-
-  // Mark that the thread is executing Dart code.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-void StubCode::GenerateCallNoScopeNativeStub(Assembler* assembler) {
-  GenerateCallNativeWithWrapperStub(
-      assembler,
-      Address(THR, Thread::no_scope_native_wrapper_entry_point_offset()));
-}
-
-void StubCode::GenerateCallAutoScopeNativeStub(Assembler* assembler) {
-  GenerateCallNativeWithWrapperStub(
-      assembler,
-      Address(THR, Thread::auto_scope_native_wrapper_entry_point_offset()));
-}
-
-// Input parameters:
-//   RSP : points to return address.
-//   RSP + 8 : address of return value.
-//   RAX : address of first argument in argument array.
-//   RBX : address of the native function to call.
-//   R10 : argc_tag including number of arguments and function kind.
-void StubCode::GenerateCallBootstrapNativeStub(Assembler* assembler) {
-  const intptr_t native_args_struct_offset = 0;
-  const intptr_t thread_offset =
-      NativeArguments::thread_offset() + native_args_struct_offset;
-  const intptr_t argc_tag_offset =
-      NativeArguments::argc_tag_offset() + native_args_struct_offset;
-  const intptr_t argv_offset =
-      NativeArguments::argv_offset() + native_args_struct_offset;
-  const intptr_t retval_offset =
-      NativeArguments::retval_offset() + native_args_struct_offset;
-
-  __ EnterStubFrame();
-
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to native code.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ movq(R8, Immediate(VMTag::kDartCompiledTagId));
-    __ cmpq(R8, Assembler::VMTagAddress());
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing native code.
-  __ movq(Assembler::VMTagAddress(), RBX);
-
-  // Reserve space for the native arguments structure passed on the stack (the
-  // outgoing pointer parameter to the native arguments structure is passed in
-  // RDI) and align frame before entering the C++ world.
-  __ subq(RSP, Immediate(sizeof(NativeArguments)));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  // Pass NativeArguments structure by value and call native function.
-  __ movq(Address(RSP, thread_offset), THR);    // Set thread in NativeArgs.
-  __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
-  __ movq(Address(RSP, argv_offset), RAX);      // Set argv in NativeArguments.
-  __ leaq(RAX, Address(RBP, 2 * kWordSize));    // Compute return value addr.
-  __ movq(Address(RSP, retval_offset), RAX);  // Set retval in NativeArguments.
-
-  // Pass the pointer to the NativeArguments.
-  __ movq(CallingConventions::kArg1Reg, RSP);
-  __ CallCFunction(RBX);
-
-  // Mark that the thread is executing Dart code.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-// Input parameters:
-//   R10: arguments descriptor array.
-void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(R10);  // Preserve arguments descriptor array.
-  // Setup space on stack for return value.
-  __ pushq(Immediate(0));
-  __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
-  __ popq(CODE_REG);  // Get Code object result.
-  __ popq(R10);       // Restore arguments descriptor array.
-  // Remove the stub frame as we are about to jump to the dart function.
-  __ LeaveStubFrame();
-
-  __ movq(RBX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ jmp(RBX);
-}
-
-// Called from a static call only when an invalid code has been entered
-// (invalid because its function was optimized or deoptimized).
-// R10: arguments descriptor array.
-void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
-  // Load code pointer to this stub from the thread:
-  // The one that is passed in, is not correct - it points to the code object
-  // that needs to be replaced.
-  __ movq(CODE_REG, Address(THR, Thread::fix_callers_target_code_offset()));
-  __ EnterStubFrame();
-  __ pushq(R10);  // Preserve arguments descriptor array.
-  // Setup space on stack for return value.
-  __ pushq(Immediate(0));
-  __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
-  __ popq(CODE_REG);  // Get Code object.
-  __ popq(R10);       // Restore arguments descriptor array.
-  __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ LeaveStubFrame();
-  __ jmp(RAX);
-  __ int3();
-}
-
-// Called from object allocate instruction when the allocation stub has been
-// disabled.
-void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
-  // Load code pointer to this stub from the thread:
-  // The one that is passed in, is not correct - it points to the code object
-  // that needs to be replaced.
-  __ movq(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset()));
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  __ pushq(Immediate(0));
-  __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
-  __ popq(CODE_REG);  // Get Code object.
-  __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ LeaveStubFrame();
-  __ jmp(RAX);
-  __ int3();
-}
-
-// Input parameters:
-//   R10: smi-tagged argument count, may be zero.
-//   RBP[kParamEndSlotFromFp + 1]: last argument.
-static void PushArrayOfArguments(Assembler* assembler) {
-  __ LoadObject(R12, Object::null_object());
-  // Allocate array to store arguments of caller.
-  __ movq(RBX, R12);  // Null element type for raw Array.
-  __ Call(StubCode::AllocateArray());
-  __ SmiUntag(R10);
-  // RAX: newly allocated array.
-  // R10: length of the array (was preserved by the stub).
-  __ pushq(RAX);  // Array is in RAX and on top of stack.
-  __ leaq(R12, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize));
-  __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
-  // R12: address of first argument on stack.
-  // RBX: address of first argument in array.
-  Label loop, loop_condition;
-#if defined(DEBUG)
-  static const bool kJumpLength = Assembler::kFarJump;
-#else
-  static const bool kJumpLength = Assembler::kNearJump;
-#endif  // DEBUG
-  __ jmp(&loop_condition, kJumpLength);
-  __ Bind(&loop);
-  __ movq(RDI, Address(R12, 0));
-  // Generational barrier is needed, array is not necessarily in new space.
-  __ StoreIntoObject(RAX, Address(RBX, 0), RDI);
-  __ addq(RBX, Immediate(kWordSize));
-  __ subq(R12, Immediate(kWordSize));
-  __ Bind(&loop_condition);
-  __ decq(R10);
-  __ j(POSITIVE, &loop, Assembler::kNearJump);
-}
-
-// Used by eager and lazy deoptimization. Preserve result in RAX if necessary.
-// This stub translates optimized frame into unoptimized frame. The optimized
-// frame can contain values in registers and on stack, the unoptimized
-// frame contains all values on stack.
-// Deoptimization occurs in following steps:
-// - Push all registers that can contain values.
-// - Call C routine to copy the stack and saved registers into temporary buffer.
-// - Adjust caller's frame to correct unoptimized frame size.
-// - Fill the unoptimized frame.
-// - Materialize objects that require allocation (e.g. Double instances).
-// GC can occur only after frame is fully rewritten.
-// Stack after EnterDartFrame(0, PP, kNoRegister) below:
-//   +------------------+
-//   | Saved PP         | <- PP
-//   +------------------+
-//   | PC marker        | <- TOS
-//   +------------------+
-//   | Saved FP         | <- FP of stub
-//   +------------------+
-//   | return-address   |  (deoptimization point)
-//   +------------------+
-//   | Saved CODE_REG   |
-//   +------------------+
-//   | ...              | <- SP of optimized frame
-//
-// Parts of the code cannot GC, part of the code can GC.
-static void GenerateDeoptimizationSequence(Assembler* assembler,
-                                           DeoptStubKind kind) {
-  // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
-  // is no need to set the correct PC marker or load PP, since they get patched.
-  __ EnterStubFrame();
-
-  // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
-  // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
-  const intptr_t saved_result_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - RAX);
-  const intptr_t saved_exception_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - RAX);
-  const intptr_t saved_stacktrace_slot_from_fp =
-      compiler_frame_layout.first_local_from_fp + 1 -
-      (kNumberOfCpuRegisters - RDX);
-  // Result in RAX is preserved as part of pushing all registers below.
-
-  // Push registers in their enumeration order: lowest register number at
-  // lowest address.
-  for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
-    if (i == CODE_REG) {
-      // Save the original value of CODE_REG pushed before invoking this stub
-      // instead of the value used to call this stub.
-      __ pushq(Address(RBP, 2 * kWordSize));
-    } else {
-      __ pushq(static_cast<Register>(i));
-    }
-  }
-  __ subq(RSP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize));
-  intptr_t offset = 0;
-  for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) {
-    XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
-    __ movups(Address(RSP, offset), xmm_reg);
-    offset += kFpuRegisterSize;
-  }
-
-  // Pass address of saved registers block.
-  __ movq(CallingConventions::kArg1Reg, RSP);
-  bool is_lazy =
-      (kind == kLazyDeoptFromReturn) || (kind == kLazyDeoptFromThrow);
-  __ movq(CallingConventions::kArg2Reg, Immediate(is_lazy ? 1 : 0));
-  __ ReserveAlignedFrameSpace(0);  // Ensure stack is aligned before the call.
-  __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry, 2);
-  // Result (RAX) is stack-size (FP - SP) in bytes.
-
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into RBX temporarily.
-    __ movq(RBX, Address(RBP, saved_result_slot_from_fp * kWordSize));
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore result into RBX temporarily.
-    __ movq(RBX, Address(RBP, saved_exception_slot_from_fp * kWordSize));
-    __ movq(RDX, Address(RBP, saved_stacktrace_slot_from_fp * kWordSize));
-  }
-
-  // There is a Dart Frame on the stack. We must restore PP and leave frame.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-
-  __ popq(RCX);       // Preserve return address.
-  __ movq(RSP, RBP);  // Discard optimized frame.
-  __ subq(RSP, RAX);  // Reserve space for deoptimized frame.
-  __ pushq(RCX);      // Restore return address.
-
-  // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
-  // is no need to set the correct PC marker or load PP, since they get patched.
-  __ EnterStubFrame();
-
-  if (kind == kLazyDeoptFromReturn) {
-    __ pushq(RBX);  // Preserve result as first local.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ pushq(RBX);  // Preserve exception as first local.
-    __ pushq(RDX);  // Preserve stacktrace as second local.
-  }
-  __ ReserveAlignedFrameSpace(0);
-  // Pass last FP as a parameter.
-  __ movq(CallingConventions::kArg1Reg, RBP);
-  __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry, 1);
-  if (kind == kLazyDeoptFromReturn) {
-    // Restore result into RBX.
-    __ movq(RBX, Address(RBP, compiler_frame_layout.first_local_from_fp *
-                                  kWordSize));
-  } else if (kind == kLazyDeoptFromThrow) {
-    // Restore exception into RBX.
-    __ movq(RBX, Address(RBP, compiler_frame_layout.first_local_from_fp *
-                                  kWordSize));
-    // Restore stacktrace into RDX.
-    __ movq(RDX, Address(RBP, (compiler_frame_layout.first_local_from_fp - 1) *
-                                  kWordSize));
-  }
-  // Code above cannot cause GC.
-  // There is a Dart Frame on the stack. We must restore PP and leave frame.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-
-  // Frame is fully rewritten at this point and it is safe to perform a GC.
-  // Materialize any objects that were deferred by FillFrame because they
-  // require allocation.
-  // Enter stub frame with loading PP. The caller's PP is not materialized yet.
-  __ EnterStubFrame();
-  if (kind == kLazyDeoptFromReturn) {
-    __ pushq(RBX);  // Preserve result, it will be GC-d here.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ pushq(RBX);  // Preserve exception.
-    __ pushq(RDX);  // Preserve stacktrace.
-  }
-  __ pushq(Immediate(Smi::RawValue(0)));  // Space for the result.
-  __ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
-  // Result tells stub how many bytes to remove from the expression stack
-  // of the bottom-most frame. They were used as materialization arguments.
-  __ popq(RBX);
-  __ SmiUntag(RBX);
-  if (kind == kLazyDeoptFromReturn) {
-    __ popq(RAX);  // Restore result.
-  } else if (kind == kLazyDeoptFromThrow) {
-    __ popq(RDX);  // Restore stacktrace.
-    __ popq(RAX);  // Restore exception.
-  }
-  __ LeaveStubFrame();
-
-  __ popq(RCX);       // Pop return address.
-  __ addq(RSP, RBX);  // Remove materialization arguments.
-  __ pushq(RCX);      // Push return address.
-  // The caller is responsible for emitting the return instruction.
-}
-
-// RAX: result, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG for lazy deopt.
-  __ pushq(Immediate(kZapCodeReg));
-  // Return address for "call" to deopt stub.
-  __ pushq(Immediate(kZapReturnAddress));
-  __ movq(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
-  __ ret();
-}
-
-// RAX: exception, must be preserved
-// RDX: stacktrace, must be preserved
-void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG for lazy deopt.
-  __ pushq(Immediate(kZapCodeReg));
-  // Return address for "call" to deopt stub.
-  __ pushq(Immediate(kZapReturnAddress));
-  __ movq(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
-  __ ret();
-}
-
-void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
-  __ popq(TMP);
-  __ pushq(CODE_REG);
-  __ pushq(TMP);
-  __ movq(CODE_REG, Address(THR, Thread::deoptimize_stub_offset()));
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-  __ 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, Object::null_object());
-  __ j(NOT_EQUAL, call_target_function);
-  __ EnterStubFrame();
-  // Load the receiver.
-  __ movq(RDI, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ movq(RAX, Address(RBP, RDI, TIMES_HALF_WORD_SIZE,
-                       kParamEndSlotFromFp * kWordSize));
-  __ pushq(Immediate(0));  // Setup space on stack for result.
-  __ pushq(RAX);           // Receiver.
-  __ pushq(RBX);           // ICData/MegamorphicCache.
-  __ pushq(R10);           // Arguments descriptor array.
-
-  // Adjust arguments count.
-  __ cmpq(FieldAddress(R10, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  __ movq(R10, RDI);
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addq(R10, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-
-  // R10: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-  const intptr_t kNumArgs = 4;
-  __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs);
-  __ Drop(4);
-  __ popq(RAX);  // Return value.
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-void StubCode::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, ArgumentsDescriptor::count_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,
-                       compiler_frame_layout.saved_below_pc() * kWordSize));
-  // Preserve IC data and arguments descriptor.
-  __ pushq(RBX);
-  __ pushq(R10);
-
-  // Space for the result of the runtime call.
-  __ pushq(Immediate(0));
-  __ pushq(RAX);  // 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, Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-  __ jmp(RCX);
-}
-
-// Called for inline allocation of arrays.
-// Input parameters:
-//   R10 : Array length as Smi.
-//   RBX : array element type (either NULL or an instantiated type).
-// NOTE: R10 cannot be clobbered here as the caller relies on it being saved.
-// The newly allocated object is returned in RAX.
-void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
-  Label slow_case;
-  // Compute the size to be allocated, it is based on the array length
-  // and is computed as:
-  // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
-  __ movq(RDI, R10);  // Array Length.
-  // Check that length is a positive Smi.
-  __ testq(RDI, Immediate(kSmiTagMask));
-  if (FLAG_use_slow_path) {
-    __ jmp(&slow_case);
-  } else {
-    __ j(NOT_ZERO, &slow_case);
-  }
-  __ cmpq(RDI, Immediate(0));
-  __ j(LESS, &slow_case);
-  // Check for maximum allowed length.
-  const Immediate& max_len = Immediate(
-      reinterpret_cast<int64_t>(Smi::New(Array::kMaxNewSpaceElements)));
-  __ cmpq(RDI, max_len);
-  __ j(GREATER, &slow_case);
-
-  // Check for allocation tracing.
-  NOT_IN_PRODUCT(
-      __ MaybeTraceAllocation(kArrayCid, &slow_case, Assembler::kFarJump));
-
-  const intptr_t fixed_size_plus_alignment_padding =
-      sizeof(RawArray) + kObjectAlignment - 1;
-  // RDI is a Smi.
-  __ leaq(RDI, Address(RDI, TIMES_4, fixed_size_plus_alignment_padding));
-  ASSERT(kSmiTagShift == 1);
-  __ andq(RDI, Immediate(-kObjectAlignment));
-
-  const intptr_t cid = kArrayCid;
-  NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-  __ movq(RAX, Address(THR, Thread::top_offset()));
-
-  // RDI: allocation size.
-  __ movq(RCX, RAX);
-  __ addq(RCX, RDI);
-  __ j(CARRY, &slow_case);
-
-  // Check if the allocation fits into the remaining space.
-  // RAX: potential new object start.
-  // RCX: potential next object start.
-  // RDI: allocation size.
-  __ cmpq(RCX, Address(THR, Thread::end_offset()));
-  __ j(ABOVE_EQUAL, &slow_case);
-
-  // Successfully allocated the object(s), now update top to point to
-  // next object start and initialize the object.
-  __ movq(Address(THR, Thread::top_offset()), RCX);
-  __ addq(RAX, Immediate(kHeapObjectTag));
-  NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, RDI, space));
-  // Initialize the tags.
-  // RAX: new object start as a tagged pointer.
-  // RDI: allocation size.
-  {
-    Label size_tag_overflow, done;
-    __ cmpq(RDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
-    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-    __ shlq(RDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
-    __ jmp(&done, Assembler::kNearJump);
-
-    __ Bind(&size_tag_overflow);
-    __ LoadImmediate(RDI, Immediate(0));
-    __ Bind(&done);
-
-    // Get the class index and insert it into the tags.
-    uint32_t tags = 0;
-    tags = RawObject::ClassIdTag::update(cid, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    __ orq(RDI, Immediate(tags));
-    __ movq(FieldAddress(RAX, Array::tags_offset()), RDI);  // Tags.
-  }
-
-  // RAX: new object start as a tagged pointer.
-  // Store the type argument field.
-  // No generational barrier needed, since we store into a new object.
-  __ StoreIntoObjectNoBarrier(
-      RAX, FieldAddress(RAX, Array::type_arguments_offset()), RBX);
-
-  // Set the length field.
-  __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, Array::length_offset()),
-                              R10);
-
-  // Initialize all array elements to raw_null.
-  // RAX: new object start as a tagged pointer.
-  // RCX: new object end address.
-  // RDI: iterator which initially points to the start of the variable
-  // data area to be initialized.
-  __ LoadObject(R12, Object::null_object());
-  __ leaq(RDI, FieldAddress(RAX, sizeof(RawArray)));
-  Label done;
-  Label init_loop;
-  __ Bind(&init_loop);
-  __ cmpq(RDI, RCX);
-#if defined(DEBUG)
-  static const bool kJumpLength = Assembler::kFarJump;
-#else
-  static const bool kJumpLength = Assembler::kNearJump;
-#endif  // DEBUG
-  __ j(ABOVE_EQUAL, &done, kJumpLength);
-  // No generational barrier needed, since we are storing null.
-  __ StoreIntoObjectNoBarrier(RAX, Address(RDI, 0), R12);
-  __ addq(RDI, Immediate(kWordSize));
-  __ jmp(&init_loop, kJumpLength);
-  __ Bind(&done);
-  __ ret();  // returns the newly allocated object in RAX.
-
-  // Unable to allocate the array using the fast inline code, just call
-  // into the runtime.
-  __ Bind(&slow_case);
-  // Create a stub frame as we are pushing some objects on the stack before
-  // calling into the runtime.
-  __ EnterStubFrame();
-  // Setup space on stack for return value.
-  __ pushq(Immediate(0));
-  __ pushq(R10);  // Array length as Smi.
-  __ pushq(RBX);  // Element type.
-  __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
-  __ popq(RAX);  // Pop element type argument.
-  __ popq(R10);  // Pop array length argument.
-  __ popq(RAX);  // Pop return value from return slot.
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-// Called when invoking Dart code from C++ (VM code).
-// Input parameters:
-//   RSP : points to return address.
-//   RDI : target code
-//   RSI : arguments descriptor array.
-//   RDX : arguments array.
-//   RCX : current thread.
-void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
-  __ pushq(Address(RSP, 0));  // Marker for the profiler.
-  __ EnterFrame(0);
-
-  const Register kTargetCodeReg = CallingConventions::kArg1Reg;
-  const Register kArgDescReg = CallingConventions::kArg2Reg;
-  const Register kArgsReg = CallingConventions::kArg3Reg;
-  const Register kThreadReg = CallingConventions::kArg4Reg;
-
-  // Push code object to PC marker slot.
-  __ pushq(Address(kThreadReg, Thread::invoke_dart_code_stub_offset()));
-
-  // At this point, the stack looks like:
-  // | stub code object
-  // | saved RBP                                      | <-- RBP
-  // | saved PC (return to DartEntry::InvokeFunction) |
-
-  const intptr_t kInitialOffset = 2;
-  // Save arguments descriptor array, later replaced by Smi argument count.
-  const intptr_t kArgumentsDescOffset = -(kInitialOffset)*kWordSize;
-  __ pushq(kArgDescReg);
-
-  // Save C++ ABI callee-saved registers.
-  __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                   CallingConventions::kCalleeSaveXmmRegisters);
-
-  // If any additional (or fewer) values are pushed, the offsets in
-  // kExitLinkSlotFromEntryFp will need to be changed.
-
-  // Set up THR, which caches the current thread in Dart code.
-  if (THR != kThreadReg) {
-    __ movq(THR, kThreadReg);
-  }
-
-  // Save the current VMTag on the stack.
-  __ movq(RAX, Assembler::VMTagAddress());
-  __ pushq(RAX);
-
-  // Save top resource and top exit frame info. Use RAX as a temporary register.
-  // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ movq(RAX, Address(THR, Thread::top_resource_offset()));
-  __ pushq(RAX);
-  __ movq(Address(THR, Thread::top_resource_offset()), Immediate(0));
-  __ movq(RAX, Address(THR, Thread::top_exit_frame_info_offset()));
-  __ pushq(RAX);
-
-// The constant kExitLinkSlotFromEntryFp must be kept in sync with the
-// code below.
-#if defined(DEBUG)
-  {
-    Label ok;
-    __ leaq(RAX, Address(RBP, kExitLinkSlotFromEntryFp * kWordSize));
-    __ cmpq(RAX, RSP);
-    __ j(EQUAL, &ok);
-    __ Stop("kExitLinkSlotFromEntryFp mismatch");
-    __ Bind(&ok);
-  }
-#endif
-
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  // Mark that the thread is executing Dart code. Do this after initializing the
-  // exit link for the profiler.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Load arguments descriptor array into R10, which is passed to Dart code.
-  __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle));
-
-  // Push arguments. At this point we only need to preserve kTargetCodeReg.
-  ASSERT(kTargetCodeReg != RDX);
-
-  // Load number of arguments into RBX and adjust count for type arguments.
-  __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ cmpq(FieldAddress(R10, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addq(RBX, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-  // Save number of arguments as Smi on stack, replacing saved ArgumentsDesc.
-  __ movq(Address(RBP, kArgumentsDescOffset), RBX);
-  __ SmiUntag(RBX);
-
-  // Compute address of 'arguments array' data area into RDX.
-  __ movq(RDX, Address(kArgsReg, VMHandles::kOffsetOfRawPtrInHandle));
-  __ leaq(RDX, FieldAddress(RDX, Array::data_offset()));
-
-  // Set up arguments for the Dart call.
-  Label push_arguments;
-  Label done_push_arguments;
-  __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
-  __ LoadImmediate(RAX, Immediate(0));
-  __ Bind(&push_arguments);
-  __ pushq(Address(RDX, RAX, TIMES_8, 0));
-  __ incq(RAX);
-  __ cmpq(RAX, RBX);
-  __ j(LESS, &push_arguments, Assembler::kNearJump);
-  __ Bind(&done_push_arguments);
-
-  // Call the Dart code entrypoint.
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ movq(PP, Address(THR, Thread::global_object_pool_offset()));
-  } else {
-    __ xorq(PP, PP);  // GC-safe value into PP.
-  }
-  __ movq(CODE_REG,
-          Address(kTargetCodeReg, VMHandles::kOffsetOfRawPtrInHandle));
-  __ movq(kTargetCodeReg, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ call(kTargetCodeReg);  // R10 is the arguments descriptor array.
-
-  // Read the saved number of passed arguments as Smi.
-  __ movq(RDX, Address(RBP, kArgumentsDescOffset));
-
-  // Get rid of arguments pushed on the stack.
-  __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0));  // RDX is a Smi.
-
-  // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure.
-  __ popq(Address(THR, Thread::top_exit_frame_info_offset()));
-  __ popq(Address(THR, Thread::top_resource_offset()));
-
-  // Restore the current VMTag from the stack.
-  __ popq(Assembler::VMTagAddress());
-
-  // Restore C++ ABI callee-saved registers.
-  __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                  CallingConventions::kCalleeSaveXmmRegisters);
-  __ set_constant_pool_allowed(false);
-
-  // Restore the frame pointer.
-  __ LeaveFrame();
-  __ popq(RCX);
-
-  __ ret();
-}
-
-// Called when invoking compiled Dart code from interpreted Dart code.
-// Input parameters:
-//   RSP : points to return address.
-//   RDI : target raw code
-//   RSI : arguments raw descriptor array.
-//   RDX : address of first argument.
-//   RCX : current thread.
-void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
-  __ pushq(Address(RSP, 0));  // Marker for the profiler.
-  __ EnterFrame(0);
-
-  const Register kTargetCodeReg = CallingConventions::kArg1Reg;
-  const Register kArgDescReg = CallingConventions::kArg2Reg;
-  const Register kArg0Reg = CallingConventions::kArg3Reg;
-  const Register kThreadReg = CallingConventions::kArg4Reg;
-
-  // Push code object to PC marker slot.
-  __ pushq(Address(kThreadReg,
-                   Thread::invoke_dart_code_from_bytecode_stub_offset()));
-
-  // At this point, the stack looks like:
-  // | stub code object
-  // | saved RBP                                         | <-- RBP
-  // | saved PC (return to interpreter's InvokeCompiled) |
-
-  const intptr_t kInitialOffset = 2;
-  // Save arguments descriptor array, later replaced by Smi argument count.
-  const intptr_t kArgumentsDescOffset = -(kInitialOffset)*kWordSize;
-  __ pushq(kArgDescReg);
-
-  // Save C++ ABI callee-saved registers.
-  __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                   CallingConventions::kCalleeSaveXmmRegisters);
-
-  // If any additional (or fewer) values are pushed, the offsets in
-  // kExitLinkSlotFromEntryFp will need to be changed.
-
-  // Set up THR, which caches the current thread in Dart code.
-  if (THR != kThreadReg) {
-    __ movq(THR, kThreadReg);
-  }
-
-  // Save the current VMTag on the stack.
-  __ movq(RAX, Assembler::VMTagAddress());
-  __ pushq(RAX);
-
-  // Save top resource and top exit frame info. Use RAX as a temporary register.
-  // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ movq(RAX, Address(THR, Thread::top_resource_offset()));
-  __ pushq(RAX);
-  __ movq(Address(THR, Thread::top_resource_offset()), Immediate(0));
-  __ movq(RAX, Address(THR, Thread::top_exit_frame_info_offset()));
-  __ pushq(RAX);
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-// The constant kExitLinkSlotFromEntryFp must be kept in sync with the
-// code below.
-#if defined(DEBUG)
-  {
-    Label ok;
-    __ leaq(RAX, Address(RBP, kExitLinkSlotFromEntryFp * kWordSize));
-    __ cmpq(RAX, RSP);
-    __ j(EQUAL, &ok);
-    __ Stop("kExitLinkSlotFromEntryFp mismatch");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Mark that the thread is executing Dart code. Do this after initializing the
-  // exit link for the profiler.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Load arguments descriptor array into R10, which is passed to Dart code.
-  __ movq(R10, kArgDescReg);
-
-  // Push arguments. At this point we only need to preserve kTargetCodeReg.
-  ASSERT(kTargetCodeReg != RDX);
-
-  // Load number of arguments into RBX and adjust count for type arguments.
-  __ movq(RBX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ cmpq(FieldAddress(R10, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addq(RBX, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-  // Save number of arguments as Smi on stack, replacing saved ArgumentsDesc.
-  __ movq(Address(RBP, kArgumentsDescOffset), RBX);
-  __ SmiUntag(RBX);
-
-  // Compute address of first argument into RDX.
-  if (kArg0Reg != RDX) {  // Different registers on WIN64.
-    __ movq(RDX, kArg0Reg);
-  }
-
-  // Set up arguments for the Dart call.
-  Label push_arguments;
-  Label done_push_arguments;
-  __ j(ZERO, &done_push_arguments, Assembler::kNearJump);
-  __ LoadImmediate(RAX, Immediate(0));
-  __ Bind(&push_arguments);
-  __ pushq(Address(RDX, RAX, TIMES_8, 0));
-  __ incq(RAX);
-  __ cmpq(RAX, RBX);
-  __ j(LESS, &push_arguments, Assembler::kNearJump);
-  __ Bind(&done_push_arguments);
-
-  // Call the Dart code entrypoint.
-  __ xorq(PP, PP);  // GC-safe value into PP.
-  __ movq(CODE_REG, kTargetCodeReg);
-  __ movq(kTargetCodeReg, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ call(kTargetCodeReg);  // R10 is the arguments descriptor array.
-
-  // Read the saved number of passed arguments as Smi.
-  __ movq(RDX, Address(RBP, kArgumentsDescOffset));
-
-  // Get rid of arguments pushed on the stack.
-  __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0));  // RDX is a Smi.
-
-  // Restore the saved top exit frame info and top resource back into the
-  // Isolate structure.
-  __ popq(Address(THR, Thread::top_exit_frame_info_offset()));
-  __ popq(Address(THR, Thread::top_resource_offset()));
-
-  // Restore the current VMTag from the stack.
-  __ popq(Assembler::VMTagAddress());
-
-  // Restore C++ ABI callee-saved registers.
-  __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters,
-                  CallingConventions::kCalleeSaveXmmRegisters);
-  __ set_constant_pool_allowed(false);
-
-  // Restore the frame pointer.
-  __ LeaveFrame();
-  __ popq(RCX);
-
-  __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-}
-
-// Called for inline allocation of contexts.
-// Input:
-// R10: number of context variables.
-// Output:
-// RAX: new allocated RawContext object.
-void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
-  __ LoadObject(R9, Object::null_object());
-  if (FLAG_inline_alloc) {
-    Label slow_case;
-    // First compute the rounded instance size.
-    // R10: number of context variables.
-    intptr_t fixed_size_plus_alignment_padding =
-        (sizeof(RawContext) + kObjectAlignment - 1);
-    __ leaq(R13, Address(R10, TIMES_8, fixed_size_plus_alignment_padding));
-    __ andq(R13, Immediate(-kObjectAlignment));
-
-    // Check for allocation tracing.
-    NOT_IN_PRODUCT(
-        __ MaybeTraceAllocation(kContextCid, &slow_case, Assembler::kFarJump));
-
-    // Now allocate the object.
-    // R10: number of context variables.
-    const intptr_t cid = kContextCid;
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ movq(RAX, Address(THR, Thread::top_offset()));
-    __ addq(R13, RAX);
-    // Check if the allocation fits into the remaining space.
-    // RAX: potential new object.
-    // R13: potential next object start.
-    // R10: number of context variables.
-    __ cmpq(R13, Address(THR, Thread::end_offset()));
-    if (FLAG_use_slow_path) {
-      __ jmp(&slow_case);
-    } else {
-      __ j(ABOVE_EQUAL, &slow_case);
-    }
-
-    // Successfully allocated the object, now update top to point to
-    // next object start and initialize the object.
-    // RAX: new object.
-    // R13: next object start.
-    // R10: number of context variables.
-    __ movq(Address(THR, Thread::top_offset()), R13);
-    // R13: Size of allocation in bytes.
-    __ subq(R13, RAX);
-    __ addq(RAX, Immediate(kHeapObjectTag));
-    // Generate isolate-independent code to allow sharing between isolates.
-    NOT_IN_PRODUCT(__ UpdateAllocationStatsWithSize(cid, R13, space));
-
-    // Calculate the size tag.
-    // RAX: new object.
-    // R10: number of context variables.
-    {
-      Label size_tag_overflow, done;
-      __ leaq(R13, Address(R10, TIMES_8, fixed_size_plus_alignment_padding));
-      __ andq(R13, Immediate(-kObjectAlignment));
-      __ cmpq(R13, Immediate(RawObject::SizeTag::kMaxSizeTag));
-      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-      __ shlq(R13, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
-      __ jmp(&done);
-
-      __ Bind(&size_tag_overflow);
-      // Set overflow size tag value.
-      __ LoadImmediate(R13, Immediate(0));
-
-      __ Bind(&done);
-      // RAX: new object.
-      // R10: number of context variables.
-      // R13: size and bit tags.
-      uint32_t tags = 0;
-      tags = RawObject::ClassIdTag::update(cid, tags);
-      tags = RawObject::NewBit::update(true, tags);
-      __ orq(R13, Immediate(tags));
-      __ movq(FieldAddress(RAX, Context::tags_offset()), R13);  // Tags.
-    }
-
-    // Setup up number of context variables field.
-    // RAX: new object.
-    // R10: number of context variables as integer value (not object).
-    __ movq(FieldAddress(RAX, Context::num_variables_offset()), R10);
-
-    // Setup the parent field.
-    // RAX: new object.
-    // R10: number of context variables.
-    // No generational barrier needed, since we are storing null.
-    __ StoreIntoObjectNoBarrier(
-        RAX, FieldAddress(RAX, Context::parent_offset()), R9);
-
-    // Initialize the context variables.
-    // RAX: new object.
-    // R10: number of context variables.
-    {
-      Label loop, entry;
-      __ leaq(R13, FieldAddress(RAX, Context::variable_offset(0)));
-#if defined(DEBUG)
-      static const bool kJumpLength = Assembler::kFarJump;
-#else
-      static const bool kJumpLength = Assembler::kNearJump;
-#endif  // DEBUG
-      __ jmp(&entry, kJumpLength);
-      __ Bind(&loop);
-      __ decq(R10);
-      // No generational barrier needed, since we are storing null.
-      __ StoreIntoObjectNoBarrier(RAX, Address(R13, R10, TIMES_8, 0), R9);
-      __ Bind(&entry);
-      __ cmpq(R10, Immediate(0));
-      __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
-    }
-
-    // Done allocating and initializing the context.
-    // RAX: new object.
-    __ ret();
-
-    __ Bind(&slow_case);
-  }
-  // Create a stub frame.
-  __ EnterStubFrame();
-  __ pushq(R9);  // Setup space on stack for the return value.
-  __ SmiTag(R10);
-  __ pushq(R10);  // Push number of context variables.
-  __ CallRuntime(kAllocateContextRuntimeEntry, 1);  // Allocate context.
-  __ popq(RAX);  // Pop number of context variables argument.
-  __ popq(RAX);  // Pop the new context object.
-  // RAX: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-void StubCode::GenerateWriteBarrierWrappersStub(Assembler* assembler) {
-  for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
-    if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
-
-    Register reg = static_cast<Register>(i);
-    intptr_t start = __ CodeSize();
-    __ pushq(kWriteBarrierObjectReg);
-    __ movq(kWriteBarrierObjectReg, reg);
-    __ call(Address(THR, Thread::write_barrier_entry_point_offset()));
-    __ popq(kWriteBarrierObjectReg);
-    __ ret();
-    intptr_t end = __ CodeSize();
-
-    RELEASE_ASSERT(end - start == kStoreBufferWrapperSize);
-  }
-}
-
-// Helper stub to implement Assembler::StoreIntoObject/Array.
-// Input parameters:
-//   RDX: Object (old)
-//   RAX: Value (old or new)
-//   R13: Slot
-// If RAX is new, add RDX to the store buffer. Otherwise RAX is old, mark RAX
-// and add it to the mark list.
-COMPILE_ASSERT(kWriteBarrierObjectReg == RDX);
-COMPILE_ASSERT(kWriteBarrierValueReg == RAX);
-COMPILE_ASSERT(kWriteBarrierSlotReg == R13);
-static void GenerateWriteBarrierStubHelper(Assembler* assembler,
-                                           Address stub_code,
-                                           bool cards) {
-  Label add_to_mark_stack, remember_card;
-  __ testq(RAX, Immediate(1 << kNewObjectBitPosition));
-  __ j(ZERO, &add_to_mark_stack);
-
-  if (cards) {
-    __ movl(TMP, FieldAddress(RDX, Object::tags_offset()));
-    __ testl(TMP, Immediate(1 << RawObject::kCardRememberedBit));
-    __ j(NOT_ZERO, &remember_card, Assembler::kFarJump);
-  } else {
-#if defined(DEBUG)
-    Label ok;
-    __ movl(TMP, FieldAddress(RDX, Object::tags_offset()));
-    __ testl(TMP, Immediate(1 << RawObject::kCardRememberedBit));
-    __ j(ZERO, &ok, Assembler::kFarJump);
-    __ Stop("Wrong barrier");
-    __ Bind(&ok);
-#endif
-  }
-
-  // Update the tags that this object has been remembered.
-  // Note that we use 32 bit operations here to match the size of the
-  // background sweeper which is also manipulating this 32 bit word.
-  // RDX: Address being stored
-  // RAX: Current tag value
-  // lock+andl is an atomic read-modify-write.
-  __ lock();
-  __ andl(FieldAddress(RDX, Object::tags_offset()),
-          Immediate(~(1 << RawObject::kOldAndNotRememberedBit)));
-
-  // Save registers being destroyed.
-  __ pushq(RAX);
-  __ pushq(RCX);
-
-  // Load the StoreBuffer block out of the thread. Then load top_ out of the
-  // StoreBufferBlock and add the address to the pointers_.
-  // RDX: Address being stored
-  __ movq(RAX, Address(THR, Thread::store_buffer_block_offset()));
-  __ movl(RCX, Address(RAX, StoreBufferBlock::top_offset()));
-  __ movq(Address(RAX, RCX, TIMES_8, StoreBufferBlock::pointers_offset()), RDX);
-
-  // Increment top_ and check for overflow.
-  // RCX: top_
-  // RAX: StoreBufferBlock
-  Label overflow;
-  __ incq(RCX);
-  __ movl(Address(RAX, StoreBufferBlock::top_offset()), RCX);
-  __ cmpl(RCX, Immediate(StoreBufferBlock::kSize));
-  // Restore values.
-  __ popq(RCX);
-  __ popq(RAX);
-  __ j(EQUAL, &overflow, Assembler::kNearJump);
-  __ ret();
-
-  // Handle overflow: Call the runtime leaf function.
-  __ Bind(&overflow);
-  // Setup frame, push callee-saved registers.
-  __ pushq(CODE_REG);
-  __ movq(CODE_REG, stub_code);
-  __ EnterCallRuntimeFrame(0);
-  __ movq(CallingConventions::kArg1Reg, THR);
-  __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ popq(CODE_REG);
-  __ ret();
-
-  __ Bind(&add_to_mark_stack);
-  __ pushq(RAX);  // Spill.
-  __ pushq(RCX);  // Spill.
-  __ movq(TMP, RAX);  // RAX is fixed implicit operand of CAS.
-
-  // Atomically clear kOldAndNotMarkedBit.
-  // Note that we use 32 bit operations here to match the size of the
-  // background marker which is also manipulating this 32 bit word.
-  Label retry, lost_race, marking_overflow;
-  __ movl(RAX, FieldAddress(TMP, Object::tags_offset()));
-  __ Bind(&retry);
-  __ movl(RCX, RAX);
-  __ testl(RCX, Immediate(1 << RawObject::kOldAndNotMarkedBit));
-  __ j(ZERO, &lost_race);  // Marked by another thread.
-  __ andl(RCX, Immediate(~(1 << RawObject::kOldAndNotMarkedBit)));
-  __ LockCmpxchgl(FieldAddress(TMP, Object::tags_offset()), RCX);
-  __ j(NOT_EQUAL, &retry, Assembler::kNearJump);
-
-  __ movq(RAX, Address(THR, Thread::marking_stack_block_offset()));
-  __ movl(RCX, Address(RAX, MarkingStackBlock::top_offset()));
-  __ movq(Address(RAX, RCX, TIMES_8, MarkingStackBlock::pointers_offset()),
-          TMP);
-  __ incq(RCX);
-  __ movl(Address(RAX, MarkingStackBlock::top_offset()), RCX);
-  __ cmpl(RCX, Immediate(MarkingStackBlock::kSize));
-  __ popq(RCX);  // Unspill.
-  __ popq(RAX);  // Unspill.
-  __ j(EQUAL, &marking_overflow, Assembler::kNearJump);
-  __ ret();
-
-  __ Bind(&marking_overflow);
-  __ pushq(CODE_REG);
-  __ movq(CODE_REG, stub_code);
-  __ EnterCallRuntimeFrame(0);
-  __ movq(CallingConventions::kArg1Reg, THR);
-  __ CallRuntime(kMarkingStackBlockProcessRuntimeEntry, 1);
-  __ LeaveCallRuntimeFrame();
-  __ popq(CODE_REG);
-  __ ret();
-
-  __ Bind(&lost_race);
-  __ popq(RCX);  // Unspill.
-  __ popq(RAX);  // Unspill.
-  __ ret();
-
-  if (cards) {
-    Label remember_card_slow;
-
-    // Get card table.
-    __ Bind(&remember_card);
-    __ movq(TMP, RDX);                   // Object.
-    __ andq(TMP, Immediate(kPageMask));  // HeapPage.
-    __ cmpq(Address(TMP, HeapPage::card_table_offset()), Immediate(0));
-    __ j(EQUAL, &remember_card_slow, Assembler::kNearJump);
-
-    // Dirty the card.
-    __ subq(R13, TMP);  // Offset in page.
-    __ movq(TMP, Address(TMP, HeapPage::card_table_offset()));  // Card table.
-    __ shrq(R13,
-            Immediate(HeapPage::kBytesPerCardLog2));  // Index in card table.
-    __ movb(Address(TMP, R13, TIMES_1, 0), Immediate(1));
-    __ ret();
-
-    // Card table not yet allocated.
-    __ Bind(&remember_card_slow);
-    __ pushq(CODE_REG);
-    __ movq(CODE_REG, stub_code);
-    __ EnterCallRuntimeFrame(0);
-    __ movq(CallingConventions::kArg1Reg, RDX);
-    __ movq(CallingConventions::kArg2Reg, R13);
-    __ CallRuntime(kRememberCardRuntimeEntry, 2);
-    __ LeaveCallRuntimeFrame();
-    __ popq(CODE_REG);
-    __ ret();
-  }
-}
-
-void StubCode::GenerateWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::write_barrier_code_offset()), false);
-}
-
-void StubCode::GenerateArrayWriteBarrierStub(Assembler* assembler) {
-  GenerateWriteBarrierStubHelper(
-      assembler, Address(THR, Thread::array_write_barrier_code_offset()), true);
-}
-
-// Called for inline allocation of objects.
-// Input parameters:
-//   RSP + 8 : type arguments object (only if class is parameterized).
-//   RSP : points to return address.
-void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
-                                              const Class& cls) {
-  const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize;
-  // The generated code is different if the class is parameterized.
-  const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
-  ASSERT(!is_cls_parameterized ||
-         (cls.type_arguments_field_offset() != 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 = cls.instance_size();
-  ASSERT(instance_size > 0);
-  __ LoadObject(R9, Object::null_object());
-  if (is_cls_parameterized) {
-    __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
-    // RDX: instantiated type arguments.
-  }
-  Isolate* isolate = Isolate::Current();
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
-      !cls.TraceAllocation(isolate)) {
-    Label slow_case;
-    // 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).
-    NOT_IN_PRODUCT(Heap::Space space = Heap::kNew);
-    __ movq(RAX, Address(THR, 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, Thread::end_offset()));
-    if (FLAG_use_slow_path) {
-      __ jmp(&slow_case);
-    } else {
-      __ j(ABOVE_EQUAL, &slow_case);
-    }
-    __ movq(Address(THR, Thread::top_offset()), RBX);
-    NOT_IN_PRODUCT(__ UpdateAllocationStats(cls.id(), space));
-
-    // RAX: new object start (untagged).
-    // RBX: next object start.
-    // RDX: new object type arguments (if is_cls_parameterized).
-    // Set the tags.
-    uint32_t tags = 0;
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    ASSERT(cls.id() != kIllegalCid);
-    tags = RawObject::ClassIdTag::update(cls.id(), tags);
-    tags = RawObject::NewBit::update(true, tags);
-    // 64 bit store also zeros the identity hash field.
-    __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags));
-    __ 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 * 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 = Instance::NextFieldOffset();
-           current_offset < instance_size; current_offset += kWordSize) {
-        __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, current_offset), R9);
-      }
-    } else {
-      __ leaq(RCX, FieldAddress(RAX, Instance::NextFieldOffset()));
-      // 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);
-#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(kWordSize));
-      __ jmp(&init_loop, Assembler::kNearJump);
-      __ Bind(&done);
-    }
-    if (is_cls_parameterized) {
-      // RAX: new object (tagged).
-      // RDX: new object type arguments.
-      // Set the type arguments in the new object.
-      intptr_t offset = cls.type_arguments_field_offset();
-      __ StoreIntoObjectNoBarrier(RAX, FieldAddress(RAX, offset), RDX);
-    }
-    // Done allocating and initializing the instance.
-    // RAX: new object (tagged).
-    __ ret();
-
-    __ Bind(&slow_case);
-  }
-  // If is_cls_parameterized:
-  // RDX: new object type arguments.
-  // Create a stub frame.
-  __ EnterStubFrame();  // Uses PP to access class object.
-  __ pushq(R9);         // Setup space on stack for return value.
-  __ PushObject(cls);   // Push class of object to be allocated.
-  if (is_cls_parameterized) {
-    __ pushq(RDX);  // Push type arguments of object to be allocated.
-  } else {
-    __ pushq(R9);  // Push null type arguments.
-  }
-  __ CallRuntime(kAllocateObjectRuntimeEntry, 2);  // Allocate object.
-  __ popq(RAX);  // Pop argument (type arguments of object).
-  __ popq(RAX);  // Pop argument (class of object).
-  __ popq(RAX);  // Pop result (newly allocated object).
-  // RAX: new object
-  // Restore the frame pointer.
-  __ LeaveStubFrame();
-  __ ret();
-}
-
-// 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.
-// Input parameters:
-//   RSP : points to return address.
-//   RSP + 8 : address of last argument.
-//   R10 : arguments descriptor array.
-void StubCode::GenerateCallClosureNoSuchMethodStub(Assembler* assembler) {
-  __ EnterStubFrame();
-
-  // Load the receiver.
-  __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize));
-
-  __ pushq(Immediate(0));  // Result slot.
-  __ pushq(RAX);           // Receiver.
-  __ pushq(R10);           // Arguments descriptor array.
-
-  // Adjust arguments count.
-  __ cmpq(FieldAddress(R10, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  __ movq(R10, R13);
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ addq(R10, Immediate(Smi::RawValue(1)));  // Include the type arguments.
-  __ Bind(&args_count_ok);
-
-  // R10: Smi-tagged arguments array length.
-  PushArrayOfArguments(assembler);
-
-  const intptr_t kNumArgs = 3;
-  __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs);
-  // noSuchMethod on closures always throws an error, so it will never return.
-  __ int3();
-}
-
-// Cannot use function object from ICData as it may be the inlined
-// function and not the top-scope function.
-void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
-  Register ic_reg = RBX;
-  Register func_reg = RDI;
-  if (FLAG_trace_optimized_ic_calls) {
-    __ EnterStubFrame();
-    __ pushq(func_reg);  // Preserve
-    __ pushq(ic_reg);    // Preserve.
-    __ pushq(ic_reg);    // Argument.
-    __ pushq(func_reg);  // Argument.
-    __ CallRuntime(kTraceICCallRuntimeEntry, 2);
-    __ popq(RAX);       // Discard argument;
-    __ popq(RAX);       // Discard argument;
-    __ popq(ic_reg);    // Restore.
-    __ popq(func_reg);  // Restore.
-    __ LeaveStubFrame();
-  }
-  __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
-}
-
-// Loads function into 'temp_reg', preserves 'ic_reg'.
-void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
-                                             Register temp_reg) {
-  if (FLAG_optimization_counter_threshold >= 0) {
-    Register ic_reg = RBX;
-    Register func_reg = temp_reg;
-    ASSERT(ic_reg != func_reg);
-    __ Comment("Increment function counter");
-    __ movq(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
-    __ incl(FieldAddress(func_reg, Function::usage_counter_offset()));
-  }
-}
-
-// Note: RBX must be preserved.
-// Attempt a quick Smi operation for known operations ('kind'). The ICData
-// must have been primed with a Smi/Smi check that will be used for counting
-// the invocations.
-static void EmitFastSmiOp(Assembler* assembler,
-                          Token::Kind kind,
-                          intptr_t num_args,
-                          Label* not_smi_or_overflow) {
-  __ Comment("Fast Smi op");
-  ASSERT(num_args == 2);
-  __ movq(RCX, Address(RSP, +1 * kWordSize));  // Right
-  __ movq(RAX, Address(RSP, +2 * kWordSize));  // Left.
-  __ movq(R13, RCX);
-  __ orq(R13, RAX);
-  __ testq(R13, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, not_smi_or_overflow);
-  switch (kind) {
-    case Token::kADD: {
-      __ addq(RAX, RCX);
-      __ j(OVERFLOW, not_smi_or_overflow);
-      break;
-    }
-    case Token::kSUB: {
-      __ subq(RAX, RCX);
-      __ j(OVERFLOW, not_smi_or_overflow);
-      break;
-    }
-    case Token::kEQ: {
-      Label done, is_true;
-      __ cmpq(RAX, RCX);
-      __ j(EQUAL, &is_true, Assembler::kNearJump);
-      __ LoadObject(RAX, Bool::False());
-      __ jmp(&done, Assembler::kNearJump);
-      __ Bind(&is_true);
-      __ LoadObject(RAX, Bool::True());
-      __ Bind(&done);
-      break;
-    }
-    default:
-      UNIMPLEMENTED();
-  }
-
-  // RBX: IC data object (preserved).
-  __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
-  // R13: ic_data_array with check entries: classes and target functions.
-  __ leaq(R13, FieldAddress(R13, Array::data_offset()));
-// R13: points directly to the first ic data array element.
-#if defined(DEBUG)
-  // Check that first entry is for Smi/Smi.
-  Label error, ok;
-  const Immediate& imm_smi_cid =
-      Immediate(reinterpret_cast<intptr_t>(Smi::New(kSmiCid)));
-  __ cmpq(Address(R13, 0 * kWordSize), imm_smi_cid);
-  __ j(NOT_EQUAL, &error, Assembler::kNearJump);
-  __ cmpq(Address(R13, 1 * kWordSize), imm_smi_cid);
-  __ j(EQUAL, &ok, Assembler::kNearJump);
-  __ Bind(&error);
-  __ Stop("Incorrect IC data");
-  __ Bind(&ok);
-#endif
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-    // Update counter, ignore overflow.
-    __ addq(Address(R13, count_offset), Immediate(Smi::RawValue(1)));
-  }
-
-  __ ret();
-}
-
-// Generate inline cache check for 'num_args'.
-//  RBX: Inline cache data object.
-//  TOS(0): return address
-// Control flow:
-// - If receiver is null -> jump to IC miss.
-// - If receiver is Smi -> load Smi class.
-// - If receiver is not-Smi -> load receiver's class.
-// - Check if 'num_args' (including receiver) match any IC data group.
-// - Match found -> jump to target.
-// - Match not found -> jump to IC miss.
-void StubCode::GenerateNArgsCheckInlineCacheStub(
-    Assembler* assembler,
-    intptr_t num_args,
-    const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind,
-    bool optimized,
-    bool exactness_check) {
-  ASSERT(num_args == 1 || num_args == 2);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == num_args.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset()));
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ andq(RCX, Immediate(ICData::NumArgsTestedMask()));
-    __ cmpq(RCX, Immediate(num_args));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect stub for IC data");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  Label stepping, done_stepping;
-  if (!optimized) {
-    __ Comment("Check single stepping");
-    __ LoadIsolate(RAX);
-    __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0));
-    __ j(NOT_EQUAL, &stepping);
-    __ Bind(&done_stepping);
-  }
-#endif
-
-  Label not_smi_or_overflow;
-  if (kind != Token::kILLEGAL) {
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-  }
-  __ Bind(&not_smi_or_overflow);
-
-  __ Comment("Extract ICData initial values and receiver cid");
-  // Load arguments descriptor into R10.
-  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
-  // Loop that checks if there is an IC data match.
-  Label loop, found, miss;
-  // RBX: IC data object (preserved).
-  __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
-  // R13: ic_data_array with check entries: classes and target functions.
-  __ leaq(R13, FieldAddress(R13, Array::data_offset()));
-  // R13: points directly to the first ic data array element.
-
-  // Get argument count as Smi into RCX.
-  __ movq(RCX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  // Load first argument into RDX.
-  __ movq(RDX, Address(RSP, RCX, TIMES_4, 0));
-  __ LoadTaggedClassIdMayBeSmi(RAX, RDX);
-  // RAX: first argument class ID as Smi.
-  if (num_args == 2) {
-    // Load second argument into R9.
-    __ movq(R9, Address(RSP, RCX, TIMES_4, -kWordSize));
-    __ LoadTaggedClassIdMayBeSmi(RCX, R9);
-    // RCX: second argument class ID (smi).
-  }
-
-  __ Comment("ICData loop");
-
-  // We unroll the generic one that is generated once more than the others.
-  const bool optimize = kind == Token::kILLEGAL;
-  const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
-  const intptr_t exactness_offset =
-      ICData::ExactnessOffsetFor(num_args) * kWordSize;
-
-  __ Bind(&loop);
-  for (int unroll = optimize ? 4 : 2; unroll >= 0; unroll--) {
-    Label update;
-    __ movq(R9, Address(R13, 0));
-    __ cmpq(RAX, R9);  // Class id match?
-    if (num_args == 2) {
-      __ j(NOT_EQUAL, &update);  // Continue.
-      __ movq(R9, Address(R13, kWordSize));
-      // R9: next class ID to check (smi).
-      __ cmpq(RCX, R9);  // Class id match?
-    }
-    __ j(EQUAL, &found);  // Break.
-
-    __ Bind(&update);
-
-    const intptr_t entry_size =
-        ICData::TestEntryLengthFor(num_args, exactness_check) * kWordSize;
-    __ addq(R13, Immediate(entry_size));  // Next entry.
-
-    __ cmpq(R9, Immediate(Smi::RawValue(kIllegalCid)));  // Done?
-    if (unroll == 0) {
-      __ j(NOT_EQUAL, &loop);
-    } else {
-      __ j(EQUAL, &miss);
-    }
-  }
-
-  __ Bind(&miss);
-  __ Comment("IC miss");
-  // Compute address of arguments (first read number of arguments from
-  // arguments descriptor array and then compute address on the stack).
-  __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0));  // RAX is Smi.
-  __ EnterStubFrame();
-  __ pushq(R10);           // Preserve arguments descriptor array.
-  __ pushq(RBX);           // Preserve IC data object.
-  __ pushq(Immediate(0));  // Result slot.
-  // Push call arguments.
-  for (intptr_t i = 0; i < num_args; i++) {
-    __ movq(RCX, Address(RAX, -kWordSize * i));
-    __ pushq(RCX);
-  }
-  __ pushq(RBX);  // Pass IC data object.
-  __ CallRuntime(handle_ic_miss, num_args + 1);
-  // Remove the call arguments pushed earlier, including the IC data object.
-  for (intptr_t i = 0; i < num_args + 1; i++) {
-    __ popq(RAX);
-  }
-  __ popq(RAX);  // Pop returned function object into RAX.
-  __ popq(RBX);  // Restore IC data array.
-  __ popq(R10);  // Restore arguments descriptor array.
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  Label call_target_function;
-  if (!FLAG_lazy_dispatchers) {
-    GenerateDispatcherCode(assembler, &call_target_function);
-  } else {
-    __ jmp(&call_target_function);
-  }
-
-  __ Bind(&found);
-  // R13: Pointer to an IC data check group.
-  Label call_target_function_through_unchecked_entry;
-  if (exactness_check) {
-    Label exactness_ok;
-    ASSERT(num_args == 1);
-    __ movq(RAX, Address(R13, exactness_offset));
-    __ cmpq(RAX, Immediate(Smi::RawValue(
-                     StaticTypeExactnessState::HasExactSuperType().Encode())));
-    __ j(LESS, &exactness_ok);
-    __ j(EQUAL, &call_target_function_through_unchecked_entry);
-
-    // Check trivial exactness.
-    // Note: RawICData::static_receiver_type_ is guaranteed to be not null
-    // because we only emit calls to this stub when it is not null.
-    __ movq(RCX, FieldAddress(RBX, ICData::static_receiver_type_offset()));
-    __ movq(RCX, FieldAddress(RCX, Type::arguments_offset()));
-    // RAX contains an offset to type arguments in words as a smi,
-    // hence TIMES_4. RDX is guaranteed to be non-smi because it is expected to
-    // have type arguments.
-    __ cmpq(RCX, FieldAddress(RDX, RAX, TIMES_4, 0));
-    __ j(EQUAL, &call_target_function_through_unchecked_entry);
-
-    // Update exactness state (not-exact anymore).
-    __ movq(Address(R13, exactness_offset),
-            Immediate(
-                Smi::RawValue(StaticTypeExactnessState::NotExact().Encode())));
-    __ Bind(&exactness_ok);
-  }
-  __ movq(RAX, Address(R13, target_offset));
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    __ Comment("Update ICData counter");
-    // Ignore overflow.
-    __ addq(Address(R13, count_offset), Immediate(Smi::RawValue(1)));
-  }
-
-  __ Comment("Call target (via checked entry point)");
-  __ Bind(&call_target_function);
-  // RAX: Target function.
-  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-  __ jmp(RCX);
-
-  if (exactness_check) {
-    __ Bind(&call_target_function_through_unchecked_entry);
-    if (FLAG_optimization_counter_threshold >= 0) {
-      __ Comment("Update ICData counter");
-      // Ignore overflow.
-      __ addq(Address(R13, count_offset), Immediate(Smi::RawValue(1)));
-    }
-    __ Comment("Call target (via unchecked entry point)");
-    __ movq(RAX, Address(R13, target_offset));
-    __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-    __ movq(RCX, FieldAddress(RAX, Function::unchecked_entry_point_offset()));
-    __ jmp(RCX);
-  }
-
-#if !defined(PRODUCT)
-  if (!optimized) {
-    __ Bind(&stepping);
-    __ EnterStubFrame();
-    __ pushq(RBX);
-    __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-    __ popq(RBX);
-    __ RestoreCodePointer();
-    __ LeaveStubFrame();
-    __ jmp(&done_stepping);
-  }
-#endif
-}
-
-// Use inline cache data array to invoke the target or continue in inline
-// cache miss handler. Stub for 1-argument check (receiver class).
-//  RBX: Inline cache data object.
-//  TOS(0): Return address.
-// Inline cache data object structure:
-// 0: function-name
-// 1: N, number of arguments checked.
-// 2 .. (length - 1): group of checks, each check containing:
-//   - N classes.
-//   - 1 target function.
-void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateOneArgCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
-      /*optimized=*/false, /*exactness_check=*/true);
-}
-
-void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL);
-}
-
-void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
-}
-
-void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
-}
-
-void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
-}
-
-// Use inline cache data array to invoke the target or continue in inline
-// cache miss handler. Stub for 1-argument check (receiver class).
-//  RDI: function which counter needs to be incremented.
-//  RBX: Inline cache data object.
-//  TOS(0): Return address.
-// Inline cache data object structure:
-// 0: function-name
-// 1: N, number of arguments checked.
-// 2 .. (length - 1): group of checks, each check containing:
-//   - N classes.
-//   - 1 target function.
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
-                                    Token::kILLEGAL, /*optimized=*/true);
-}
-
-void StubCode::GenerateOneArgOptimizedCheckInlineCacheWithExactnessCheckStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-                                    kInlineCacheMissHandlerOneArgRuntimeEntry,
-                                    Token::kILLEGAL, /*optimized=*/true,
-                                    /*exactness_check=*/true);
-}
-
-void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub(
-    Assembler* assembler) {
-  GenerateOptimizedUsageCounterIncrement(assembler);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-                                    kInlineCacheMissHandlerTwoArgsRuntimeEntry,
-                                    Token::kILLEGAL, /*optimized=*/true);
-}
-
-// Intermediary stub between a static call and its target. ICData contains
-// the target function and the call count.
-// RBX: ICData
-void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that the IC data array has NumArgsTested() == 0.
-    // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
-    __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset()));
-    ASSERT(ICData::NumArgsTestedShift() == 0);  // No shift needed.
-    __ andq(RCX, Immediate(ICData::NumArgsTestedMask()));
-    __ cmpq(RCX, Immediate(0));
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Incorrect IC data for unoptimized static call");
-    __ Bind(&ok);
-  }
-#endif  // DEBUG
-
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(RAX);
-  __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
-  __ cmpq(RAX, Immediate(0));
-#if defined(DEBUG)
-  static const bool kJumpLength = Assembler::kFarJump;
-#else
-  static const bool kJumpLength = Assembler::kNearJump;
-#endif  // DEBUG
-  __ j(NOT_EQUAL, &stepping, kJumpLength);
-  __ Bind(&done_stepping);
-#endif
-
-  // RBX: IC data object (preserved).
-  __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
-  // R12: ic_data_array with entries: target functions and count.
-  __ leaq(R12, FieldAddress(R12, Array::data_offset()));
-  // R12: points directly to the first ic data array element.
-  const intptr_t target_offset = ICData::TargetIndexFor(0) * kWordSize;
-  const intptr_t count_offset = ICData::CountIndexFor(0) * kWordSize;
-
-  if (FLAG_optimization_counter_threshold >= 0) {
-    // Increment count for this call, ignore overflow.
-    __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1)));
-  }
-
-  // Load arguments descriptor into R10.
-  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
-
-  // Get function and call it, if possible.
-  __ movq(RAX, Address(R12, target_offset));
-  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-  __ jmp(RCX);
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ pushq(RBX);  // Preserve IC data object.
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ popq(RBX);
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ jmp(&done_stepping, Assembler::kNearJump);
-#endif
-}
-
-void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
-}
-
-void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
-  GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(
-      assembler, 2, kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
-}
-
-// Stub for compiling a function and jumping to the compiled code.
-// R10: Arguments descriptor.
-// RAX: Function.
-void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(R10);  // Preserve arguments descriptor array.
-  __ pushq(RAX);  // Pass function.
-  __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
-  __ popq(RAX);  // Restore function.
-  __ popq(R10);  // Restore arguments descriptor array.
-  __ LeaveStubFrame();
-
-  // When using the interpreter, the function's code may now point to the
-  // InterpretCall stub. Make sure RAX, R10, and RBX are preserved.
-  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-  __ jmp(RCX);
-}
-
-// Stub for interpreting a function call.
-// R10: Arguments descriptor.
-// RAX: Function.
-void StubCode::GenerateInterpretCallStub(Assembler* assembler) {
-#if defined(DART_PRECOMPILED_RUNTIME)
-  __ Stop("Not using interpreter");
-#else
-  __ EnterStubFrame();
-
-#if defined(DEBUG)
-  {
-    Label ok;
-    // Check that we are always entering from Dart code.
-    __ movq(R8, Immediate(VMTag::kDartCompiledTagId));
-    __ cmpq(R8, Assembler::VMTagAddress());
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Not coming from Dart code.");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Adjust arguments count for type arguments vector.
-  __ movq(R11, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
-  __ SmiUntag(R11);
-  __ cmpq(FieldAddress(R10, ArgumentsDescriptor::type_args_len_offset()),
-          Immediate(0));
-  Label args_count_ok;
-  __ j(EQUAL, &args_count_ok, Assembler::kNearJump);
-  __ incq(R11);
-  __ Bind(&args_count_ok);
-
-  // Compute argv.
-  __ leaq(R12, Address(RBP, R11, TIMES_8, kParamEndSlotFromFp * kWordSize));
-
-  // Indicate decreasing memory addresses of arguments with negative argc.
-  __ negq(R11);
-
-  // Reserve shadow space for args and align frame before entering C++ world.
-  __ subq(RSP, Immediate(5 * kWordSize));
-  if (OS::ActivationFrameAlignment() > 1) {
-    __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
-  }
-
-  __ movq(CallingConventions::kArg1Reg, RAX);  // Function.
-  __ movq(CallingConventions::kArg2Reg, R10);  // Arguments descriptor.
-  __ movq(CallingConventions::kArg3Reg, R11);  // Negative argc.
-  __ movq(CallingConventions::kArg4Reg, R12);  // Argv.
-
-#if defined(_WIN64)
-  __ movq(Address(RSP, 0 * kWordSize), THR);  // Thread.
-#else
-  __ movq(CallingConventions::kArg5Reg, THR);  // Thread.
-#endif
-  // Save exit frame information to enable stack walking as we are about
-  // to transition to Dart VM C++ code.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), RBP);
-
-  // Mark that the thread is executing VM code.
-  __ movq(RAX, Address(THR, Thread::interpret_call_entry_point_offset()));
-  __ movq(Assembler::VMTagAddress(), RAX);
-
-  __ call(RAX);
-
-  // Mark that the thread is executing Dart code.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-
-  // Reset exit frame information in Isolate structure.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-
-  __ LeaveStubFrame();
-  __ ret();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-}
-
-// RBX: Contains an ICData.
-// TOS(0): return address (Dart code).
-void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(RBX);           // Preserve IC data.
-  __ pushq(Immediate(0));  // Result slot.
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ popq(CODE_REG);  // Original stub.
-  __ popq(RBX);       // Restore IC data.
-  __ LeaveStubFrame();
-
-  __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ jmp(RAX);  // Jump to original stub.
-}
-
-//  TOS(0): return address (Dart code).
-void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(Immediate(0));  // Result slot.
-  __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
-  __ popq(CODE_REG);  // Original stub.
-  __ LeaveStubFrame();
-
-  __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ jmp(RAX);  // Jump to original stub.
-}
-
-// Called only from unoptimized code.
-void StubCode::GenerateDebugStepCheckStub(Assembler* assembler) {
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(RAX);
-  __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
-  __ cmpq(RAX, Immediate(0));
-  __ j(NOT_EQUAL, &stepping, Assembler::kNearJump);
-  __ Bind(&done_stepping);
-  __ ret();
-
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ LeaveStubFrame();
-  __ jmp(&done_stepping, Assembler::kNearJump);
-}
-
-// Used to check class and type arguments. Arguments passed in registers:
-//
-// Inputs:
-//   - R9  : RawSubtypeTestCache
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments (for n=4).
-//   - RCX : function type arguments (for n=4).
-//
-//   - TOS + 0: return address.
-//
-// Preserves R9/RAX/RCX/RDX, RBX.
-//
-// Result in R8: null -> not found, otherwise result (true or false).
-static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
-  ASSERT(n == 1 || n == 2 || n == 4 || n == 6);
-
-  const Register kCacheReg = R9;
-  const Register kInstanceReg = RAX;
-  const Register kInstantiatorTypeArgumentsReg = RDX;
-  const Register kFunctionTypeArgumentsReg = RCX;
-
-  const Register kInstanceCidOrFunction = R10;
-  const Register kInstanceInstantiatorTypeArgumentsReg = R13;
-  const Register kInstanceParentFunctionTypeArgumentsReg = PP;
-  const Register kInstanceDelayedFunctionTypeArgumentsReg = CODE_REG;
-
-  const Register kNullReg = R8;
-
-  __ LoadObject(kNullReg, Object::null_object());
-
-  // Free up these 2 registers to be used for 6-value test.
-  if (n >= 6) {
-    __ pushq(kInstanceParentFunctionTypeArgumentsReg);
-    __ pushq(kInstanceDelayedFunctionTypeArgumentsReg);
-  }
-
-  // Loop initialization (moved up here to avoid having all dependent loads
-  // after each other).
-  __ movq(RSI, FieldAddress(kCacheReg, SubtypeTestCache::cache_offset()));
-  __ addq(RSI, Immediate(Array::data_offset() - kHeapObjectTag));
-
-  Label loop, not_closure;
-  if (n >= 4) {
-    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
-  } else {
-    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
-  }
-  __ cmpq(kInstanceCidOrFunction, Immediate(kClosureCid));
-  __ j(NOT_EQUAL, &not_closure, Assembler::kNearJump);
-
-  // Closure handling.
-  {
-    __ movq(kInstanceCidOrFunction,
-            FieldAddress(kInstanceReg, Closure::function_offset()));
-    if (n >= 2) {
-      __ movq(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(kInstanceReg,
-                           Closure::instantiator_type_arguments_offset()));
-      if (n >= 6) {
-        ASSERT(n == 6);
-        __ movq(kInstanceParentFunctionTypeArgumentsReg,
-                FieldAddress(kInstanceReg,
-                             Closure::function_type_arguments_offset()));
-        __ movq(kInstanceDelayedFunctionTypeArgumentsReg,
-                FieldAddress(kInstanceReg,
-                             Closure::delayed_type_arguments_offset()));
-      }
-    }
-    __ jmp(&loop, Assembler::kNearJump);
-  }
-
-  // Non-Closure handling.
-  {
-    __ Bind(&not_closure);
-    if (n == 1) {
-      __ SmiTag(kInstanceCidOrFunction);
-    } else {
-      ASSERT(n >= 2);
-      Label has_no_type_arguments;
-      // [LoadClassById] also tags [kInstanceCidOrFunction] as a side-effect.
-      __ LoadClassById(RDI, kInstanceCidOrFunction);
-      __ movq(kInstanceInstantiatorTypeArgumentsReg, kNullReg);
-      __ movl(RDI,
-              FieldAddress(
-                  RDI, Class::type_arguments_field_offset_in_words_offset()));
-      __ cmpl(RDI, Immediate(Class::kNoTypeArguments));
-      __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
-      __ movq(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(kInstanceReg, RDI, TIMES_8, 0));
-      __ Bind(&has_no_type_arguments);
-
-      if (n >= 6) {
-        __ movq(kInstanceParentFunctionTypeArgumentsReg, kNullReg);
-        __ movq(kInstanceDelayedFunctionTypeArgumentsReg, kNullReg);
-      }
-    }
-  }
-
-  Label found, not_found, next_iteration;
-
-  // Loop header.
-  __ Bind(&loop);
-  __ movq(RDI, Address(RSI, kWordSize *
-                                SubtypeTestCache::kInstanceClassIdOrFunction));
-  __ cmpq(RDI, kNullReg);
-  __ j(EQUAL, &not_found, Assembler::kNearJump);
-  __ cmpq(RDI, kInstanceCidOrFunction);
-  if (n == 1) {
-    __ j(EQUAL, &found, Assembler::kNearJump);
-  } else {
-    __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-    __ cmpq(kInstanceInstantiatorTypeArgumentsReg,
-            Address(RSI, kWordSize * SubtypeTestCache::kInstanceTypeArguments));
-    if (n == 2) {
-      __ j(EQUAL, &found, Assembler::kNearJump);
-    } else {
-      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ cmpq(kInstantiatorTypeArgumentsReg,
-              Address(RSI, kWordSize *
-                               SubtypeTestCache::kInstantiatorTypeArguments));
-      __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-      __ cmpq(
-          kFunctionTypeArgumentsReg,
-          Address(RSI, kWordSize * SubtypeTestCache::kFunctionTypeArguments));
-
-      if (n == 4) {
-        __ j(EQUAL, &found, Assembler::kNearJump);
-      } else {
-        ASSERT(n == 6);
-        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-
-        __ cmpq(
-            kInstanceParentFunctionTypeArgumentsReg,
-            Address(
-                RSI,
-                kWordSize *
-                    SubtypeTestCache::kInstanceParentFunctionTypeArguments));
-        __ j(NOT_EQUAL, &next_iteration, Assembler::kNearJump);
-        __ cmpq(
-            kInstanceDelayedFunctionTypeArgumentsReg,
-            Address(
-                RSI,
-                kWordSize *
-                    SubtypeTestCache::kInstanceDelayedFunctionTypeArguments));
-        __ j(EQUAL, &found, Assembler::kNearJump);
-      }
-    }
-  }
-
-  __ Bind(&next_iteration);
-  __ addq(RSI, Immediate(kWordSize * SubtypeTestCache::kTestEntryLength));
-  __ jmp(&loop, Assembler::kNearJump);
-
-  __ Bind(&found);
-  __ movq(R8, Address(RSI, kWordSize * SubtypeTestCache::kTestResult));
-  if (n >= 6) {
-    __ popq(kInstanceDelayedFunctionTypeArgumentsReg);
-    __ popq(kInstanceParentFunctionTypeArgumentsReg);
-  }
-  __ ret();
-
-  __ Bind(&not_found);
-  if (n >= 6) {
-    __ popq(kInstanceDelayedFunctionTypeArgumentsReg);
-    __ popq(kInstanceParentFunctionTypeArgumentsReg);
-  }
-  __ ret();
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype1TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 1);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype2TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 2);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype4TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 4);
-}
-
-// See comment on [GenerateSubtypeNTestCacheStub].
-void StubCode::GenerateSubtype6TestCacheStub(Assembler* assembler) {
-  GenerateSubtypeNTestCacheStub(assembler, 6);
-}
-
-// Used to test whether a given value is of a given type (different variants,
-// all have the same calling convention).
-//
-// Inputs:
-//   - R9  : RawSubtypeTestCache
-//   - RAX : instance to test against.
-//   - RDX : instantiator type arguments (if needed).
-//   - RCX : function type arguments (if needed).
-//
-//   - RBX : type to test against.
-//   - R10 : name of destination variable.
-//
-// Preserves R9/RAX/RCX/RDX, RBX, R10.
-//
-// Note of warning: The caller will not populate CODE_REG and we have therefore
-// no access to the pool.
-void StubCode::GenerateDefaultTypeTestStub(Assembler* assembler) {
-  Label done;
-
-  const Register kInstanceReg = RAX;
-
-  // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(EQUAL, &done);
-
-  __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCode::GenerateTopTypeTypeTestStub(Assembler* assembler) {
-  __ Ret();
-}
-
-void StubCode::GenerateTypeRefTypeTestStub(Assembler* assembler) {
-  const Register kTypeRefReg = RBX;
-
-  // We dereference the TypeRef and tail-call to it's type testing stub.
-  __ movq(kTypeRefReg, FieldAddress(kTypeRefReg, TypeRef::type_offset()));
-  __ jmp(FieldAddress(kTypeRefReg,
-                      AbstractType::type_test_stub_entry_point_offset()));
-}
-
-void StubCode::GenerateUnreachableTypeTestStub(Assembler* assembler) {
-  __ Breakpoint();
-}
-
-void TypeTestingStubGenerator::BuildOptimizedTypeTestStub(
-    Assembler* assembler,
-    HierarchyInfo* hi,
-    const Type& type,
-    const Class& type_class) {
-  const Register kInstanceReg = RAX;
-  const Register kClassIdReg = TMP;
-
-  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
-                                      kInstanceReg, kClassIdReg);
-
-  __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
-  __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
-}
-
-void TypeTestingStubGenerator::
-    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
-                                                      HierarchyInfo* hi,
-                                                      const Class& type_class,
-                                                      const TypeArguments& tp,
-                                                      const TypeArguments& ta) {
-  const Register kInstanceReg = RAX;
-  const Register kInstanceTypeArguments = RSI;
-  const Register kClassIdReg = TMP;
-
-  BuildOptimizedSubclassRangeCheckWithTypeArguments(
-      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
-      kInstanceTypeArguments);
-}
-
-void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
-    Assembler* assembler,
-    HierarchyInfo* hi,
-    const AbstractType& type_arg,
-    intptr_t type_param_value_offset_i,
-    Label* check_failed) {
-  const Register kInstanceTypeArguments = RSI;
-  const Register kInstantiatorTypeArgumentsReg = RDX;
-  const Register kFunctionTypeArgumentsReg = RCX;
-
-  const Register kClassIdReg = TMP;
-  const Register kOwnTypeArgumentValue = RDI;
-
-  BuildOptimizedTypeArgumentValueCheck(
-      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
-      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
-      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
-}
-
-static void InvokeTypeCheckFromTypeTestStub(Assembler* assembler,
-                                            TypeCheckMode mode) {
-  const Register kInstanceReg = RAX;
-  const Register kInstantiatorTypeArgumentsReg = RDX;
-  const Register kFunctionTypeArgumentsReg = RCX;
-  const Register kDstTypeReg = RBX;
-  const Register kSubtypeTestCacheReg = R9;
-
-  __ PushObject(Object::null_object());  // Make room for result.
-  __ pushq(kInstanceReg);
-  __ pushq(kDstTypeReg);
-  __ pushq(kInstantiatorTypeArgumentsReg);
-  __ pushq(kFunctionTypeArgumentsReg);
-  __ PushObject(Object::null_object());
-  __ pushq(kSubtypeTestCacheReg);
-  __ PushObject(Smi::ZoneHandle(Smi::New(mode)));
-  __ CallRuntime(kTypeCheckRuntimeEntry, 7);
-  __ Drop(1);
-  __ popq(kSubtypeTestCacheReg);
-  __ Drop(1);
-  __ popq(kFunctionTypeArgumentsReg);
-  __ popq(kInstantiatorTypeArgumentsReg);
-  __ popq(kDstTypeReg);
-  __ popq(kInstanceReg);
-  __ Drop(1);  // Discard return value.
-}
-
-void StubCode::GenerateLazySpecializeTypeTestStub(Assembler* assembler) {
-  const Register kInstanceReg = RAX;
-
-  Label done;
-
-  // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(EQUAL, &done);
-
-  __ movq(CODE_REG,
-          Address(THR, Thread::lazy_specialize_type_test_stub_offset()));
-  __ EnterStubFrame();
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromLazySpecializeStub);
-  __ LeaveStubFrame();
-
-  __ Bind(&done);
-  __ Ret();
-}
-
-void StubCode::GenerateSlowTypeTestStub(Assembler* assembler) {
-  Label done, call_runtime;
-
-  const Register kInstanceReg = RAX;
-  const Register kDstTypeReg = RBX;
-  const Register kSubtypeTestCacheReg = R9;
-
-  __ EnterStubFrame();
-
-#ifdef DEBUG
-  // Guaranteed by caller.
-  Label no_error;
-  __ CompareObject(kInstanceReg, Object::null_object());
-  __ BranchIf(NOT_EQUAL, &no_error);
-  __ Breakpoint();
-  __ Bind(&no_error);
-#endif
-
-  // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(kSubtypeTestCacheReg, Object::null_object());
-  __ BranchIf(EQUAL, &call_runtime);
-
-  const Register kTmp = RDI;
-
-  // If this is not a [Type] object, we'll go to the runtime.
-  Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, kDstTypeReg);
-  __ cmpq(kTmp, Immediate(kTypeCid));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is instantiated/uninstantiated.
-  __ cmpb(FieldAddress(kDstTypeReg, Type::type_state_offset()),
-          Immediate(RawType::kFinalizedInstantiated));
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // Check whether this [Type] is a function type.
-  __ movq(kTmp, FieldAddress(kDstTypeReg, Type::signature_offset()));
-  __ CompareObject(kTmp, Object::null_object());
-  __ BranchIf(NOT_EQUAL, &is_complex_case);
-
-  // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(kInstanceReg, &is_complex_case);
-
-  // Fall through to &is_simple_case
-
-  __ Bind(&is_simple_case);
-  {
-    __ Call(StubCode::Subtype2TestCache());
-    __ CompareObject(R8, Bool::True());
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    __ Jump(&call_runtime);
-  }
-
-  __ Bind(&is_complex_case);
-  {
-    __ Call(StubCode::Subtype6TestCache());
-    __ CompareObject(R8, Bool::True());
-    __ BranchIf(EQUAL, &done);  // Cache said: yes.
-    // Fall through to runtime_call
-  }
-
-  __ Bind(&call_runtime);
-
-  // We cannot really ensure here that dynamic/Object/void never occur here
-  // (though it is guaranteed at dart_precompiled_runtime time).  This is
-  // because we do constant evaluation with default stubs and only install
-  // optimized versions before writing out the AOT snapshot.
-  // So dynamic/Object/void will run with default stub in constant evaluation.
-  __ CompareObject(kDstTypeReg, Type::dynamic_type());
-  __ BranchIf(EQUAL, &done);
-  __ CompareObject(kDstTypeReg, Type::Handle(Type::ObjectType()));
-  __ BranchIf(EQUAL, &done);
-  __ CompareObject(kDstTypeReg, Type::void_type());
-  __ BranchIf(EQUAL, &done);
-
-  InvokeTypeCheckFromTypeTestStub(assembler, kTypeCheckFromSlowStub);
-
-  __ Bind(&done);
-  __ LeaveStubFrame();
-  __ Ret();
-}
-
-// Return the current stack pointer address, used to stack alignment
-// checks.
-// TOS + 0: return address
-// Result in RAX.
-void StubCode::GenerateGetCStackPointerStub(Assembler* assembler) {
-  __ leaq(RAX, Address(RSP, kWordSize));
-  __ ret();
-}
-
-// Jump to a frame on the call stack.
-// TOS + 0: return address
-// Arg1: program counter
-// Arg2: stack pointer
-// Arg3: frame_pointer
-// Arg4: thread
-// No Result.
-void StubCode::GenerateJumpToFrameStub(Assembler* assembler) {
-  __ movq(THR, CallingConventions::kArg4Reg);
-  __ movq(RBP, CallingConventions::kArg3Reg);
-  __ movq(RSP, CallingConventions::kArg2Reg);
-  // Set the tag.
-  __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
-  // Clear top exit frame.
-  __ movq(Address(THR, Thread::top_exit_frame_info_offset()), Immediate(0));
-  // Restore the pool pointer.
-  __ RestoreCodePointer();
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ movq(PP, Address(THR, Thread::global_object_pool_offset()));
-  } else {
-    __ LoadPoolPointer(PP);
-  }
-  __ jmp(CallingConventions::kArg1Reg);  // Jump to program counter.
-}
-
-// Run an exception handler.  Execution comes from JumpToFrame stub.
-//
-// The arguments are stored in the Thread object.
-// No result.
-void StubCode::GenerateRunExceptionHandlerStub(Assembler* assembler) {
-  ASSERT(kExceptionObjectReg == RAX);
-  ASSERT(kStackTraceObjectReg == RDX);
-  __ movq(CallingConventions::kArg1Reg,
-          Address(THR, Thread::resume_pc_offset()));
-
-  ASSERT(Thread::CanLoadFromThread(Object::null_object()));
-  __ movq(TMP, Address(THR, Thread::OffsetFromThread(Object::null_object())));
-
-  // Load the exception from the current thread.
-  Address exception_addr(THR, Thread::active_exception_offset());
-  __ movq(kExceptionObjectReg, exception_addr);
-  __ movq(exception_addr, TMP);
-
-  // Load the stacktrace from the current thread.
-  Address stacktrace_addr(THR, Thread::active_stacktrace_offset());
-  __ movq(kStackTraceObjectReg, stacktrace_addr);
-  __ movq(stacktrace_addr, TMP);
-
-  __ jmp(CallingConventions::kArg1Reg);  // Jump to continuation point.
-}
-
-// Deoptimize a frame on the call stack before rewinding.
-// The arguments are stored in the Thread object.
-// No result.
-void StubCode::GenerateDeoptForRewindStub(Assembler* assembler) {
-  // Push zap value instead of CODE_REG.
-  __ pushq(Immediate(kZapCodeReg));
-
-  // Push the deopt pc.
-  __ pushq(Address(THR, Thread::resume_pc_offset()));
-  GenerateDeoptimizationSequence(assembler, kEagerDeopt);
-
-  // After we have deoptimized, jump to the correct frame.
-  __ EnterStubFrame();
-  __ CallRuntime(kRewindPostDeoptRuntimeEntry, 0);
-  __ LeaveStubFrame();
-  __ int3();
-}
-
-// Calls to the runtime to optimize the given function.
-// RDI: function to be reoptimized.
-// R10: argument descriptor (preserved).
-void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(R10);           // Preserve args descriptor.
-  __ pushq(Immediate(0));  // Result slot.
-  __ pushq(RDI);           // Arg0: function to optimize
-  __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
-  __ popq(RAX);  // Discard argument.
-  __ popq(RAX);  // Get Code object.
-  __ popq(R10);  // Restore argument descriptor.
-  __ LeaveStubFrame();
-  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-  __ jmp(RCX);
-  __ int3();
-}
-
-// Does identical check (object references are equal or not equal) with special
-// checks for boxed numbers.
-// Left and right are pushed on stack.
-// Return ZF set.
-// Note: A Mint cannot contain a value that would fit in Smi.
-static void GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
-                                                 const Register left,
-                                                 const Register right) {
-  Label reference_compare, done, check_mint;
-  // If any of the arguments is Smi do reference compare.
-  __ testq(left, Immediate(kSmiTagMask));
-  __ j(ZERO, &reference_compare);
-  __ testq(right, Immediate(kSmiTagMask));
-  __ j(ZERO, &reference_compare);
-
-  // Value compare for two doubles.
-  __ CompareClassId(left, kDoubleCid);
-  __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump);
-  __ CompareClassId(right, kDoubleCid);
-  __ j(NOT_EQUAL, &done, Assembler::kFarJump);
-
-  // Double values bitwise compare.
-  __ movq(left, FieldAddress(left, Double::value_offset()));
-  __ cmpq(left, FieldAddress(right, Double::value_offset()));
-  __ jmp(&done, Assembler::kFarJump);
-
-  __ Bind(&check_mint);
-  __ CompareClassId(left, kMintCid);
-  __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump);
-  __ CompareClassId(right, kMintCid);
-  __ j(NOT_EQUAL, &done, Assembler::kFarJump);
-  __ movq(left, FieldAddress(left, Mint::value_offset()));
-  __ cmpq(left, FieldAddress(right, Mint::value_offset()));
-  __ jmp(&done, Assembler::kFarJump);
-
-  __ Bind(&reference_compare);
-  __ cmpq(left, right);
-  __ Bind(&done);
-}
-
-// Called only from unoptimized code. All relevant registers have been saved.
-// TOS + 0: return address
-// TOS + 1: right argument.
-// TOS + 2: left argument.
-// Returns ZF set.
-void StubCode::GenerateUnoptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-#if !defined(PRODUCT)
-  // Check single stepping.
-  Label stepping, done_stepping;
-  __ LoadIsolate(RAX);
-  __ movzxb(RAX, Address(RAX, Isolate::single_step_offset()));
-  __ cmpq(RAX, Immediate(0));
-  __ j(NOT_EQUAL, &stepping);
-  __ Bind(&done_stepping);
-#endif
-
-  const Register left = RAX;
-  const Register right = RDX;
-
-  __ movq(left, Address(RSP, 2 * kWordSize));
-  __ movq(right, Address(RSP, 1 * kWordSize));
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
-  __ ret();
-
-#if !defined(PRODUCT)
-  __ Bind(&stepping);
-  __ EnterStubFrame();
-  __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
-  __ RestoreCodePointer();
-  __ LeaveStubFrame();
-  __ jmp(&done_stepping);
-#endif
-}
-
-// Called from optimized code only.
-// TOS + 0: return address
-// TOS + 1: right argument.
-// TOS + 2: left argument.
-// Returns ZF set.
-void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
-    Assembler* assembler) {
-  const Register left = RAX;
-  const Register right = RDX;
-
-  __ movq(left, Address(RSP, 2 * kWordSize));
-  __ movq(right, Address(RSP, 1 * kWordSize));
-  GenerateIdenticalWithNumberCheckStub(assembler, left, right);
-  __ ret();
-}
-
-// Called from megamorphic calls.
-//  RDI: receiver
-//  RBX: MegamorphicCache (preserved)
-// Passed to target:
-//  CODE_REG: target Code
-//  R10: arguments descriptor
-void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) {
-  // Jump if receiver is a smi.
-  Label smi_case;
-  __ testq(RDI, Immediate(kSmiTagMask));
-  // Jump out of line for smi case.
-  __ j(ZERO, &smi_case, Assembler::kNearJump);
-
-  // Loads the cid of the object.
-  __ LoadClassId(RAX, RDI);
-
-  Label cid_loaded;
-  __ Bind(&cid_loaded);
-  __ movq(R9, FieldAddress(RBX, MegamorphicCache::mask_offset()));
-  __ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset()));
-  // R9: mask as a smi.
-  // RDI: cache buckets array.
-
-  // Tag cid as a smi.
-  __ addq(RAX, RAX);
-
-  // Compute the table index.
-  ASSERT(MegamorphicCache::kSpreadFactor == 7);
-  // Use leaq and subq multiply with 7 == 8 - 1.
-  __ leaq(RCX, Address(RAX, TIMES_8, 0));
-  __ subq(RCX, RAX);
-
-  Label loop;
-  __ Bind(&loop);
-  __ andq(RCX, R9);
-
-  const intptr_t base = Array::data_offset();
-  // RCX is smi tagged, but table entries are two words, so TIMES_8.
-  Label probe_failed;
-  __ cmpq(RAX, FieldAddress(RDI, RCX, TIMES_8, base));
-  __ j(NOT_EQUAL, &probe_failed, Assembler::kNearJump);
-
-  Label load_target;
-  __ Bind(&load_target);
-  // Call the target found in the cache.  For a class id match, this is a
-  // proper target for the given name and arguments descriptor.  If the
-  // illegal class id was found, the target is a cache miss handler that can
-  // be invoked as a normal Dart function.
-  const auto target_address = FieldAddress(RDI, RCX, TIMES_8, base + kWordSize);
-  if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
-    __ movq(R10,
-            FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset()));
-    __ jmp(target_address);
-  } else {
-    __ movq(RAX, target_address);
-    __ movq(R10,
-            FieldAddress(RBX, MegamorphicCache::arguments_descriptor_offset()));
-    __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-    __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-    __ jmp(RCX);
-  }
-
-  // Probe failed, check if it is a miss.
-  __ Bind(&probe_failed);
-  __ cmpq(FieldAddress(RDI, RCX, TIMES_8, base),
-          Immediate(Smi::RawValue(kIllegalCid)));
-  __ j(ZERO, &load_target, Assembler::kNearJump);
-
-  // Try next entry in the table.
-  __ AddImmediate(RCX, Immediate(Smi::RawValue(1)));
-  __ jmp(&loop);
-
-  // Load cid for the Smi case.
-  __ Bind(&smi_case);
-  __ movq(RAX, Immediate(kSmiCid));
-  __ jmp(&cid_loaded);
-}
-
-// Called from switchable IC calls.
-//  RDI: receiver
-//  RBX: ICData (preserved)
-// Passed to target:
-//  CODE_REG: target Code object
-//  R10: arguments descriptor
-void StubCode::GenerateICCallThroughFunctionStub(Assembler* assembler) {
-  Label loop, found, miss;
-  __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
-  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
-  __ leaq(R13, FieldAddress(R13, Array::data_offset()));
-  // R13: first IC entry
-  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
-  // RAX: receiver cid as Smi
-
-  __ Bind(&loop);
-  __ movq(R9, Address(R13, 0));
-  __ cmpq(RAX, R9);
-  __ j(EQUAL, &found, Assembler::kNearJump);
-
-  ASSERT(Smi::RawValue(kIllegalCid) == 0);
-  __ testq(R9, R9);
-  __ j(ZERO, &miss, Assembler::kNearJump);
-
-  const intptr_t entry_length =
-      ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) * kWordSize;
-  __ addq(R13, Immediate(entry_length));  // Next entry.
-  __ jmp(&loop);
-
-  __ Bind(&found);
-  const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
-  __ movq(RAX, Address(R13, target_offset));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
-  __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ jmp(RCX);
-
-  __ Bind(&miss);
-  __ LoadIsolate(RAX);
-  __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset()));
-  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ jmp(RCX);
-}
-
-void StubCode::GenerateICCallThroughCodeStub(Assembler* assembler) {
-  Label loop, found, miss;
-  __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
-  __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
-  __ leaq(R13, FieldAddress(R13, Array::data_offset()));
-  // R13: first IC entry
-  __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
-  // RAX: receiver cid as Smi
-
-  __ Bind(&loop);
-  __ movq(R9, Address(R13, 0));
-  __ cmpq(RAX, R9);
-  __ j(EQUAL, &found, Assembler::kNearJump);
-
-  ASSERT(Smi::RawValue(kIllegalCid) == 0);
-  __ testq(R9, R9);
-  __ j(ZERO, &miss, Assembler::kNearJump);
-
-  const intptr_t entry_length =
-      ICData::TestEntryLengthFor(1, /*tracking_exactness=*/false) * kWordSize;
-  __ addq(R13, Immediate(entry_length));  // Next entry.
-  __ jmp(&loop);
-
-  __ Bind(&found);
-  const intptr_t code_offset = ICData::CodeIndexFor(1) * kWordSize;
-  const intptr_t entry_offset = ICData::EntryPointIndexFor(1) * kWordSize;
-  if (!(FLAG_precompiled_mode && FLAG_use_bare_instructions)) {
-    __ movq(CODE_REG, Address(R13, code_offset));
-  }
-  __ jmp(Address(R13, entry_offset));
-
-  __ Bind(&miss);
-  __ LoadIsolate(RAX);
-  __ movq(CODE_REG, Address(RAX, Isolate::ic_miss_code_offset()));
-  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
-  __ jmp(RCX);
-}
-
-//  RDI: receiver
-//  RBX: UnlinkedCall
-void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
-  __ EnterStubFrame();
-  __ pushq(RDI);  // Preserve receiver.
-
-  __ pushq(Immediate(0));  // Result slot.
-  __ pushq(RDI);           // Arg0: Receiver
-  __ pushq(RBX);           // Arg1: UnlinkedCall
-  __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
-  __ popq(RBX);
-  __ popq(RBX);
-  __ popq(RBX);  // result = IC
-
-  __ popq(RDI);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                          Code::EntryKind::kMonomorphic)));
-  __ jmp(RCX);
-}
-
-// Called from switchable IC calls.
-//  RDI: receiver
-//  RBX: SingleTargetCache
-// Passed to target::
-//  CODE_REG: target Code object
-void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) {
-  Label miss;
-  __ LoadClassIdMayBeSmi(RAX, RDI);
-  __ movzxw(R9, FieldAddress(RBX, SingleTargetCache::lower_limit_offset()));
-  __ movzxw(R10, FieldAddress(RBX, SingleTargetCache::upper_limit_offset()));
-  __ cmpq(RAX, R9);
-  __ j(LESS, &miss, Assembler::kNearJump);
-  __ cmpq(RAX, R10);
-  __ j(GREATER, &miss, Assembler::kNearJump);
-  __ movq(RCX, FieldAddress(RBX, SingleTargetCache::entry_point_offset()));
-  __ movq(CODE_REG, FieldAddress(RBX, SingleTargetCache::target_offset()));
-  __ jmp(RCX);
-
-  __ Bind(&miss);
-  __ EnterStubFrame();
-  __ pushq(RDI);  // Preserve receiver.
-
-  __ pushq(Immediate(0));  // Result slot.
-  __ pushq(RDI);           // Arg0: Receiver
-  __ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
-  __ popq(RBX);
-  __ popq(RBX);  // result = IC
-
-  __ popq(RDI);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                          Code::EntryKind::kMonomorphic)));
-  __ jmp(RCX);
-}
-
-// Called from the monomorphic checked entry.
-//  RDI: receiver
-void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
-  __ movq(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
-  __ EnterStubFrame();
-  __ pushq(RDI);  // Preserve receiver.
-
-  __ pushq(Immediate(0));  // Result slot.
-  __ pushq(RDI);           // Arg0: Receiver
-  __ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
-  __ popq(RBX);
-  __ popq(RBX);  // result = IC
-
-  __ popq(RDI);  // Restore receiver.
-  __ LeaveStubFrame();
-
-  __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
-  __ movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset(
-                                          Code::EntryKind::kMonomorphic)));
-  __ jmp(RCX);
-}
-
-void StubCode::GenerateFrameAwaitingMaterializationStub(Assembler* assembler) {
-  __ int3();
-}
-
-void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) {
-  __ int3();
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index 7739541..53917bb 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -55,8 +55,8 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(
       Code::FinalizeCode(*CreateFunction("Test_CallRuntimeStubCode"), nullptr,
@@ -96,8 +96,8 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  ObjectPoolWrapper object_pool_wrapper;
-  Assembler assembler(&object_pool_wrapper);
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 741239a..b10f4e8 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -12,6 +12,7 @@
 #include "vm/raw_object.h"
 #include "vm/reusable_handles.h"
 #include "vm/snapshot_ids.h"
+#include "vm/type_table.h"
 #include "vm/unicode.h"
 #include "vm/visitor.h"
 
@@ -344,51 +345,104 @@
   return unified_table.Release().raw();
 }
 
-void Symbols::Compact(Isolate* isolate) {
-  ASSERT(isolate != Dart::vm_isolate());
-  Zone* zone = Thread::Current()->zone();
+void Symbols::Compact() {
+  Thread* thread = Thread::Current();
+  ASSERT(thread->isolate() != Dart::vm_isolate());
+  HANDLESCOPE(thread);
+  Zone* zone = thread->zone();
+  ObjectStore* object_store = thread->isolate()->object_store();
 
-  // 1. Drop the symbol table and do a full garbage collection.
-  isolate->object_store()->set_symbol_table(Object::empty_array());
-  isolate->heap()->CollectAllGarbage();
+  // 1. Drop the tables and do a full garbage collection.
+  object_store->set_symbol_table(Object::empty_array());
+  object_store->set_canonical_types(Object::empty_array());
+  object_store->set_canonical_type_arguments(Object::empty_array());
+  thread->heap()->CollectAllGarbage();
 
-  // 2. Walk the heap to find surviving symbols.
+  // 2. Walk the heap to find surviving canonical objects.
   GrowableArray<String*> symbols;
+  GrowableArray<class Type*> types;
+  GrowableArray<class TypeArguments*> type_args;
   class SymbolCollector : public ObjectVisitor {
    public:
-    SymbolCollector(Thread* thread, GrowableArray<String*>* symbols)
-        : symbols_(symbols), zone_(thread->zone()) {}
+    SymbolCollector(Thread* thread,
+                    GrowableArray<String*>* symbols,
+                    GrowableArray<class Type*>* types,
+                    GrowableArray<class TypeArguments*>* type_args)
+        : symbols_(symbols),
+          types_(types),
+          type_args_(type_args),
+          zone_(thread->zone()) {}
 
     void VisitObject(RawObject* obj) {
-      if (obj->IsCanonical() && obj->IsStringInstance()) {
-        symbols_->Add(&String::ZoneHandle(zone_, String::RawCast(obj)));
+      if (obj->IsCanonical()) {
+        if (obj->IsStringInstance()) {
+          symbols_->Add(&String::Handle(zone_, String::RawCast(obj)));
+        } else if (obj->IsType()) {
+          types_->Add(&Type::Handle(zone_, Type::RawCast(obj)));
+        } else if (obj->IsTypeArguments()) {
+          type_args_->Add(
+              &TypeArguments::Handle(zone_, TypeArguments::RawCast(obj)));
+        }
       }
     }
 
    private:
     GrowableArray<String*>* symbols_;
+    GrowableArray<class Type*>* types_;
+    GrowableArray<class TypeArguments*>* type_args_;
     Zone* zone_;
   };
 
   {
-    Thread* thread = Thread::Current();
     HeapIterationScope iteration(thread);
-    SymbolCollector visitor(thread, &symbols);
+    SymbolCollector visitor(thread, &symbols, &types, &type_args);
     iteration.IterateObjects(&visitor);
   }
 
-  // 3. Build a new table from the surviving symbols.
-  Array& array = Array::Handle(
-      zone, HashTables::New<SymbolTable>(symbols.length() * 4 / 3, Heap::kOld));
-  SymbolTable table(zone, array.raw());
-  for (intptr_t i = 0; i < symbols.length(); i++) {
-    String& symbol = *symbols[i];
-    ASSERT(symbol.IsString());
-    ASSERT(symbol.IsCanonical());
-    bool present = table.Insert(symbol);
-    ASSERT(!present);
+  // 3. Build new tables from the surviving canonical objects.
+  {
+    Array& array = Array::Handle(
+        zone,
+        HashTables::New<SymbolTable>(symbols.length() * 4 / 3, Heap::kOld));
+    SymbolTable table(zone, array.raw());
+    for (intptr_t i = 0; i < symbols.length(); i++) {
+      String& symbol = *symbols[i];
+      ASSERT(symbol.IsString());
+      ASSERT(symbol.IsCanonical());
+      bool present = table.Insert(symbol);
+      ASSERT(!present);
+    }
+    object_store->set_symbol_table(table.Release());
   }
-  isolate->object_store()->set_symbol_table(table.Release());
+
+  {
+    Array& array = Array::Handle(zone, HashTables::New<CanonicalTypeSet>(
+                                           types.length() * 4 / 3, Heap::kOld));
+    CanonicalTypeSet table(zone, array.raw());
+    for (intptr_t i = 0; i < types.length(); i++) {
+      class Type& type = *types[i];
+      ASSERT(type.IsType());
+      ASSERT(type.IsCanonical());
+      bool present = table.Insert(type);
+      ASSERT(!present);
+    }
+    object_store->set_canonical_types(table.Release());
+  }
+
+  {
+    Array& array =
+        Array::Handle(zone, HashTables::New<CanonicalTypeArgumentsSet>(
+                                type_args.length() * 4 / 3, Heap::kOld));
+    CanonicalTypeArgumentsSet table(zone, array.raw());
+    for (intptr_t i = 0; i < type_args.length(); i++) {
+      class TypeArguments& type_arg = *type_args[i];
+      ASSERT(type_arg.IsTypeArguments());
+      ASSERT(type_arg.IsCanonical());
+      bool present = table.Insert(type_arg);
+      ASSERT(!present);
+    }
+    object_store->set_canonical_type_arguments(table.Release());
+  }
 }
 
 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) {
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 536ad2b..68c0371 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -179,6 +179,7 @@
   V(ClosureData, "ClosureData")                                                \
   V(SignatureData, "SignatureData")                                            \
   V(RedirectionData, "RedirectionData")                                        \
+  V(FfiTrampolineData, "FfiTrampolineData")                                    \
   V(Field, "Field")                                                            \
   V(Script, "Script")                                                          \
   V(LibraryClass, "Library")                                                   \
@@ -373,6 +374,8 @@
   V(DartCore, "dart:core")                                                     \
   V(DartCollection, "dart:collection")                                         \
   V(DartDeveloper, "dart:developer")                                           \
+  V(DartFfi, "dart:ffi")                                                       \
+  V(DartFfiLibName, "ffi")                                                     \
   V(DartInternal, "dart:_internal")                                            \
   V(DartIsolate, "dart:isolate")                                               \
   V(DartMirrors, "dart:mirrors")                                               \
@@ -380,6 +383,7 @@
   V(DartVMService, "dart:_vmservice")                                          \
   V(DartIOLibName, "dart.io")                                                  \
   V(DartVMProduct, "dart.vm.product")                                          \
+  V(DartDeveloperTimeline, "dart.developer.timeline")                          \
   V(EvalSourceUri, "evaluate:source")                                          \
   V(ExternalName, "ExternalName")                                              \
   V(_Random, "_Random")                                                        \
@@ -440,6 +444,7 @@
   V(_ensureScheduleImmediate, "_ensureScheduleImmediate")                      \
   V(DartLibrary, "dart.library.")                                              \
   V(DartLibraryMirrors, "dart.library.mirrors")                                \
+  V(DartLibraryFfi, "dart.library.ffi")                                        \
   V(_name, "_name")                                                            \
   V(name, "name")                                                              \
   V(options, "options")                                                        \
@@ -459,7 +464,23 @@
   V(Get, "get")                                                                \
   V(Set, "set")                                                                \
   V(vm_trace_entrypoints, "vm:testing.unsafe.trace-entrypoints-fn")            \
-  V(BoundsCheckForPartialInstantiation, "_boundsCheckForPartialInstantiation")
+  V(BoundsCheckForPartialInstantiation, "_boundsCheckForPartialInstantiation") \
+  V(FfiPointer, "Pointer")                                                     \
+  V(FfiNativeFunction, "NativeFunction")                                       \
+  V(FfiInt8, "Int8")                                                           \
+  V(FfiInt16, "Int16")                                                         \
+  V(FfiInt32, "Int32")                                                         \
+  V(FfiInt64, "Int64")                                                         \
+  V(FfiUint8, "Uint8")                                                         \
+  V(FfiUint16, "Uint16")                                                       \
+  V(FfiUint32, "Uint32")                                                       \
+  V(FfiUint64, "Uint64")                                                       \
+  V(FfiIntPtr, "IntPtr")                                                       \
+  V(FfiFloat, "Float")                                                         \
+  V(FfiDouble, "Double")                                                       \
+  V(FfiVoid, "Void")                                                           \
+  V(FfiNativeType, "NativeType")                                               \
+  V(FfiDynamicLibrary, "DynamicLibrary")
 
 // Contains a list of frequently used strings in a canonicalized form. This
 // list is kept in the vm_isolate in order to share the copy across isolates
@@ -609,7 +630,7 @@
   static RawArray* UnifiedSymbolTable();
 
   // Treat the symbol table as weak and collect garbage.
-  static void Compact(Isolate* isolate);
+  static void Compact();
 
   // Creates a Symbol given a C string that is assumed to contain
   // UTF-8 encoded characters and '\0' is considered a termination character.
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 8756113..866af84 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -82,7 +82,6 @@
       api_top_scope_(NULL),
       no_callback_scope_depth_(0),
 #if defined(DEBUG)
-      top_handle_scope_(NULL),
       no_safepoint_scope_depth_(0),
 #endif
       reusable_handles_(),
@@ -106,7 +105,7 @@
       interpreter_(nullptr),
 #endif
       next_(NULL) {
-#if !defined(PRODUCT)
+#if defined(SUPPORT_TIMELINE)
   dart_stream_ = Timeline::GetDartStream();
   ASSERT(dart_stream_ != NULL);
 #endif
@@ -858,50 +857,6 @@
   return total;
 }
 
-bool Thread::IsValidZoneHandle(Dart_Handle object) const {
-  Zone* zone = this->zone();
-  while (zone != NULL) {
-    if (zone->handles()->IsValidZoneHandle(reinterpret_cast<uword>(object))) {
-      return true;
-    }
-    zone = zone->previous();
-  }
-  return false;
-}
-
-intptr_t Thread::CountZoneHandles() const {
-  intptr_t count = 0;
-  Zone* zone = this->zone();
-  while (zone != NULL) {
-    count += zone->handles()->CountZoneHandles();
-    zone = zone->previous();
-  }
-  ASSERT(count >= 0);
-  return count;
-}
-
-bool Thread::IsValidScopedHandle(Dart_Handle object) const {
-  Zone* zone = this->zone();
-  while (zone != NULL) {
-    if (zone->handles()->IsValidScopedHandle(reinterpret_cast<uword>(object))) {
-      return true;
-    }
-    zone = zone->previous();
-  }
-  return false;
-}
-
-intptr_t Thread::CountScopedHandles() const {
-  intptr_t count = 0;
-  Zone* zone = this->zone();
-  while (zone != NULL) {
-    count += zone->handles()->CountScopedHandles();
-    zone = zone->previous();
-  }
-  ASSERT(count >= 0);
-  return count;
-}
-
 int Thread::ZoneSizeInBytes() const {
   int total = 0;
   ApiLocalScope* scope = api_top_scope_;
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 0df7b36..1c89d5d 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -5,6 +5,10 @@
 #ifndef RUNTIME_VM_THREAD_H_
 #define RUNTIME_VM_THREAD_H_
 
+#if defined(SHOULD_NOT_INCLUDE_RUNTIME)
+#error "Should not include runtime"
+#endif
+
 #include "include/dart_api.h"
 #include "platform/assert.h"
 #include "platform/atomic.h"
@@ -16,6 +20,7 @@
 #include "vm/heap/pointer_block.h"
 #include "vm/os_thread.h"
 #include "vm/runtime_entry_list.h"
+#include "vm/thread_stack_resource.h"
 #include "vm/thread_state.h"
 
 namespace dart {
@@ -294,6 +299,14 @@
     return ++stack_overflow_count_;
   }
 
+#if !defined(TARGET_ARCH_DBC)
+  static uword stack_overflow_shared_stub_entry_point_offset(bool fpu_regs) {
+    return fpu_regs
+               ? stack_overflow_shared_with_fpu_regs_entry_point_offset()
+               : stack_overflow_shared_without_fpu_regs_entry_point_offset();
+  }
+#endif
+
   TaskKind task_kind() const { return task_kind_; }
 
   // Retrieves and clears the stack overflow flags.  These are set by
@@ -449,20 +462,6 @@
   bool bump_allocate() const { return bump_allocate_; }
   void set_bump_allocate(bool b) { bump_allocate_ = b; }
 
-  HandleScope* top_handle_scope() const {
-#if defined(DEBUG)
-    return top_handle_scope_;
-#else
-    return 0;
-#endif
-  }
-
-  void set_top_handle_scope(HandleScope* handle_scope) {
-#if defined(DEBUG)
-    top_handle_scope_ = handle_scope;
-#endif
-  }
-
   int32_t no_safepoint_scope_depth() const {
 #if defined(DEBUG)
     return no_safepoint_scope_depth_;
@@ -494,7 +493,7 @@
 
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
     defined(TARGET_ARCH_X64)
-  static intptr_t write_barrier_wrappers_offset(Register reg) {
+  static intptr_t write_barrier_wrappers_thread_offset(Register reg) {
     ASSERT((kDartAvailableCpuRegs & (1 << reg)) != 0);
     intptr_t index = 0;
     for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
@@ -505,6 +504,19 @@
     return OFFSET_OF(Thread, write_barrier_wrappers_entry_points_) +
            index * sizeof(uword);
   }
+
+  static intptr_t WriteBarrierWrappersOffsetForRegister(Register reg) {
+    intptr_t index = 0;
+    for (intptr_t i = 0; i < kNumberOfCpuRegisters; ++i) {
+      if ((kDartAvailableCpuRegs & (1 << i)) == 0) continue;
+      if (i == reg) {
+        return index * kStoreBufferWrapperSize;
+      }
+      ++index;
+    }
+    UNREACHABLE();
+    return 0;
+  }
 #endif
 
 #define DEFINE_OFFSET_METHOD(name)                                             \
@@ -693,7 +705,7 @@
     execution_state_ = static_cast<uint32_t>(state);
   }
 
-  bool MayAllocateHandles() {
+  virtual bool MayAllocateHandles() {
     return (execution_state() == kThreadInVM) ||
            (execution_state() == kThreadInGenerated);
   }
@@ -751,10 +763,6 @@
   bool IsValidHandle(Dart_Handle object) const;
   bool IsValidLocalHandle(Dart_Handle object) const;
   intptr_t CountLocalHandles() const;
-  bool IsValidZoneHandle(Dart_Handle object) const;
-  intptr_t CountZoneHandles() const;
-  bool IsValidScopedHandle(Dart_Handle object) const;
-  intptr_t CountScopedHandles() const;
   int ZoneSizeInBytes() const;
   void UnwindScopes(uword stack_marker);
 
@@ -838,7 +846,6 @@
   ApiLocalScope* api_top_scope_;
   int32_t no_callback_scope_depth_;
 #if defined(DEBUG)
-  HandleScope* top_handle_scope_;
   int32_t no_safepoint_scope_depth_;
 #endif
   VMHandles reusable_handles_;
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index d8d56b1..ebb07bd 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -116,6 +116,7 @@
 
 // Delay between interrupts.
 void ThreadInterrupter::SetInterruptPeriod(intptr_t period) {
+  MonitorLocker ml(monitor_);
   if (shutdown_) {
     return;
   }
@@ -173,6 +174,9 @@
         ASSERT(interrupted_thread_count == 0);
         // Return to regular interrupts.
         current_wait_time_ = interrupt_period_;
+      } else if (current_wait_time_ != interrupt_period_) {
+        // The interrupt period may have been updated via the service protocol.
+        current_wait_time_ = interrupt_period_;
       }
 
       // Reset count before interrupting any threads.
diff --git a/runtime/vm/thread_interrupter_fuchsia.cc b/runtime/vm/thread_interrupter_fuchsia.cc
index 3ae857c..c0f5d5e 100644
--- a/runtime/vm/thread_interrupter_fuchsia.cc
+++ b/runtime/vm/thread_interrupter_fuchsia.cc
@@ -159,7 +159,7 @@
     // Currently we sample only threads that are associated
     // with an isolate. It is safe to call 'os_thread->thread()'
     // here as the thread which is being queried is suspended.
-    Thread* thread = os_thread->thread();
+    Thread* thread = static_cast<Thread*>(os_thread->thread());
     if (thread != NULL) {
       Profiler::SampleThread(thread, its);
     }
diff --git a/runtime/vm/thread_state.cc b/runtime/vm/thread_state.cc
index d5e37e3..00deaf7 100644
--- a/runtime/vm/thread_state.cc
+++ b/runtime/vm/thread_state.cc
@@ -4,6 +4,7 @@
 
 #include "vm/thread_state.h"
 
+#include "vm/handles_impl.h"
 #include "vm/zone.h"
 
 namespace dart {
@@ -38,4 +39,48 @@
   return false;
 }
 
+bool ThreadState::IsValidZoneHandle(Dart_Handle object) const {
+  Zone* zone = this->zone();
+  while (zone != NULL) {
+    if (zone->handles()->IsValidZoneHandle(reinterpret_cast<uword>(object))) {
+      return true;
+    }
+    zone = zone->previous();
+  }
+  return false;
+}
+
+intptr_t ThreadState::CountZoneHandles() const {
+  intptr_t count = 0;
+  Zone* zone = this->zone();
+  while (zone != NULL) {
+    count += zone->handles()->CountZoneHandles();
+    zone = zone->previous();
+  }
+  ASSERT(count >= 0);
+  return count;
+}
+
+bool ThreadState::IsValidScopedHandle(Dart_Handle object) const {
+  Zone* zone = this->zone();
+  while (zone != NULL) {
+    if (zone->handles()->IsValidScopedHandle(reinterpret_cast<uword>(object))) {
+      return true;
+    }
+    zone = zone->previous();
+  }
+  return false;
+}
+
+intptr_t ThreadState::CountScopedHandles() const {
+  intptr_t count = 0;
+  Zone* zone = this->zone();
+  while (zone != NULL) {
+    count += zone->handles()->CountScopedHandles();
+    zone = zone->previous();
+  }
+  ASSERT(count >= 0);
+  return count;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/thread_state.h b/runtime/vm/thread_state.h
index 85106d2..90cd58e 100644
--- a/runtime/vm/thread_state.h
+++ b/runtime/vm/thread_state.h
@@ -5,10 +5,12 @@
 #ifndef RUNTIME_VM_THREAD_STATE_H_
 #define RUNTIME_VM_THREAD_STATE_H_
 
+#include "include/dart_api.h"
 #include "vm/os_thread.h"
 
 namespace dart {
 
+class HandleScope;
 class LongJumpScope;
 class Zone;
 
@@ -35,7 +37,7 @@
   }
 
   explicit ThreadState(bool is_os_thread);
-  ~ThreadState();
+  virtual ~ThreadState();
 
   // OSThread corresponding to this thread.
   OSThread* os_thread() const { return os_thread_; }
@@ -72,6 +74,27 @@
   LongJumpScope* long_jump_base() const { return long_jump_base_; }
   void set_long_jump_base(LongJumpScope* value) { long_jump_base_ = value; }
 
+  bool IsValidZoneHandle(Dart_Handle object) const;
+  intptr_t CountZoneHandles() const;
+  bool IsValidScopedHandle(Dart_Handle object) const;
+  intptr_t CountScopedHandles() const;
+
+  virtual bool MayAllocateHandles() = 0;
+
+  HandleScope* top_handle_scope() const {
+#if defined(DEBUG)
+    return top_handle_scope_;
+#else
+    return 0;
+#endif
+  }
+
+  void set_top_handle_scope(HandleScope* handle_scope) {
+#if defined(DEBUG)
+    top_handle_scope_ = handle_scope;
+#endif
+  }
+
  private:
   void set_zone(Zone* zone) { zone_ = zone; }
 
@@ -82,6 +105,11 @@
   StackResource* top_resource_ = nullptr;
   LongJumpScope* long_jump_base_ = nullptr;
 
+  // This field is only used in the DEBUG builds, but we don't exclude it
+  // because it would cause RELEASE and DEBUG builds to have different
+  // offsets for various Thread fields that are used from generated code.
+  HandleScope* top_handle_scope_ = nullptr;
+
   friend class ApiZone;
   friend class StackZone;
 };
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index d71628e..7eeb900 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -420,7 +420,7 @@
         for (intptr_t cnt = 0; cnt < 0x1000; cnt++) {
           for (intptr_t i = 0; i < len_; i++) {
             ic_data ^= ic_datas_.AtAcquire(i);
-            arr = ic_data.ic_data();
+            arr = ic_data.entries();
             intptr_t num_checks = arr.Length() / 3;
             if (num_checks < 0 || num_checks > 5) {
               OS::PrintErr("Failure: %" Pd " checks!\n", num_checks);
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index e343cdd..1f96aac 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "platform/globals.h"
-#ifndef PRODUCT
+#include "vm/globals.h"
+#if defined(SUPPORT_TIMELINE)
 
 #include "vm/timeline.h"
 
@@ -47,8 +47,8 @@
             timeline_streams,
             NULL,
             "Comma separated list of timeline streams to record. "
-            "Valid values: all, API, Compiler, Dart, Debugger, Embedder, "
-            "GC, Isolate, and VM.");
+            "Valid values: all, API, Compiler, CompilerVerbose, Dart, "
+            "Debugger, Embedder, GC, Isolate, and VM.");
 DEFINE_FLAG(charp,
             timeline_recorder,
             "ring",
@@ -209,39 +209,16 @@
   stream_##name##_.Init(#name, HasStream(enabled_streams_, #name));
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAG_DEFAULT)
 #undef TIMELINE_STREAM_FLAG_DEFAULT
-
-  if (Timeline::stream_Embedder_.enabled() &&
-      (Timeline::get_start_recording_cb() != NULL)) {
-    Timeline::get_start_recording_cb()();
-  }
-}
-
-void Timeline::StreamStateChange(const char* stream_name,
-                                 bool prev,
-                                 bool curr) {
-  if (prev == curr) {
-    return;
-  }
-  if (strcmp(stream_name, "Embedder") == 0) {
-    if (curr && (Timeline::get_start_recording_cb() != NULL)) {
-      Timeline::get_start_recording_cb()();
-    } else if (!curr && (Timeline::get_stop_recording_cb() != NULL)) {
-      Timeline::get_stop_recording_cb()();
-    }
-  }
 }
 
 void Timeline::Cleanup() {
   ASSERT(recorder_ != NULL);
 
-  if (Timeline::stream_Embedder_.enabled() &&
-      (Timeline::get_stop_recording_cb() != NULL)) {
-    Timeline::get_stop_recording_cb()();
-  }
-
+#ifndef PRODUCT
   if (FLAG_timeline_dir != NULL) {
     recorder_->WriteTo(FLAG_timeline_dir);
   }
+#endif
 
 // Disable global streams.
 #define TIMELINE_STREAM_DISABLE(name, not_used)                                \
@@ -281,6 +258,7 @@
   }
 }
 
+#ifndef PRODUCT
 void Timeline::PrintFlagsToJSON(JSONStream* js) {
   JSONObject obj(js);
   obj.AddProperty("type", "TimelineFlags");
@@ -306,6 +284,7 @@
 #undef ADD_RECORDED_STREAM_NAME
   }
 }
+#endif
 
 void Timeline::Clear() {
   TimelineEventRecorder* recorder = Timeline::recorder();
@@ -397,8 +376,6 @@
 
 TimelineEventRecorder* Timeline::recorder_ = NULL;
 MallocGrowableArray<char*>* Timeline::enabled_streams_ = NULL;
-Dart_EmbedderTimelineStartRecording Timeline::start_recording_cb_ = NULL;
-Dart_EmbedderTimelineStopRecording Timeline::stop_recording_cb_ = NULL;
 
 #define TIMELINE_STREAM_DEFINE(name, enabled_by_default)                       \
   TimelineStream Timeline::stream_##name##_;
@@ -621,6 +598,7 @@
   return (delta >= 0) && (delta <= time_extent_micros);
 }
 
+#ifndef PRODUCT
 void TimelineEvent::PrintJSON(JSONStream* stream) const {
   if (!FLAG_support_service) {
     return;
@@ -712,6 +690,7 @@
     }
   }
 }
+#endif
 
 int64_t TimelineEvent::TimeOrigin() const {
   return timestamp0_;
@@ -860,7 +839,7 @@
 TimelineDurationScope::TimelineDurationScope(TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(stream, label) {
-  if (!FLAG_support_timeline || !enabled()) {
+  if (!enabled()) {
     return;
   }
   timestamp_ = OS::GetCurrentMonotonicMicros();
@@ -871,7 +850,7 @@
                                              TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(thread, stream, label) {
-  if (!FLAG_support_timeline || !enabled()) {
+  if (!enabled()) {
     return;
   }
   timestamp_ = OS::GetCurrentMonotonicMicros();
@@ -879,9 +858,6 @@
 }
 
 TimelineDurationScope::~TimelineDurationScope() {
-  if (!FLAG_support_timeline) {
-    return;
-  }
   if (!ShouldEmitEvent()) {
     return;
   }
@@ -901,9 +877,6 @@
 TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(stream, label) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
   EmitBegin();
 }
 
@@ -911,23 +884,14 @@
                                              TimelineStream* stream,
                                              const char* label)
     : TimelineEventScope(thread, stream, label) {
-  if (!FLAG_support_timeline) {
-    return;
-  }
   EmitBegin();
 }
 
 TimelineBeginEndScope::~TimelineBeginEndScope() {
-  if (!FLAG_support_timeline) {
-    return;
-  }
   EmitEnd();
 }
 
 void TimelineBeginEndScope::EmitBegin() {
-  if (!FLAG_support_timeline) {
-    return;
-  }
   if (!ShouldEmitEvent()) {
     return;
   }
@@ -944,9 +908,6 @@
 }
 
 void TimelineBeginEndScope::EmitEnd() {
-  if (!FLAG_support_timeline) {
-    return;
-  }
   if (!ShouldEmitEvent()) {
     return;
   }
@@ -983,6 +944,7 @@
 TimelineEventRecorder::TimelineEventRecorder()
     : async_id_(0), time_low_micros_(0), time_high_micros_(0) {}
 
+#ifndef PRODUCT
 void TimelineEventRecorder::PrintJSONMeta(JSONArray* events) const {
   if (!FLAG_support_service) {
     return;
@@ -1009,6 +971,7 @@
     }
   }
 }
+#endif
 
 TimelineEvent* TimelineEventRecorder::ThreadBlockStartEvent() {
   // Grab the current thread.
@@ -1105,6 +1068,7 @@
   thread_block_lock->Unlock();
 }
 
+#ifndef PRODUCT
 void TimelineEventRecorder::WriteTo(const char* directory) {
   if (!FLAG_support_service) {
     return;
@@ -1143,6 +1107,7 @@
 
   return;
 }
+#endif
 
 int64_t TimelineEventRecorder::GetNextAsyncId() {
   // TODO(johnmccutchan): Gracefully handle wrap around.
@@ -1195,6 +1160,7 @@
   delete memory_;
 }
 
+#ifndef PRODUCT
 void TimelineEventFixedBufferRecorder::PrintJSONEvents(
     JSONArray* events,
     TimelineEventFilter* filter) {
@@ -1253,6 +1219,7 @@
   PrintJSONMeta(&events);
   PrintJSONEvents(&events, filter);
 }
+#endif
 
 TimelineEventBlock* TimelineEventFixedBufferRecorder::GetHeadBlockLocked() {
   return &blocks_[0];
@@ -1320,6 +1287,7 @@
 
 TimelineEventCallbackRecorder::~TimelineEventCallbackRecorder() {}
 
+#ifndef PRODUCT
 void TimelineEventCallbackRecorder::PrintJSON(JSONStream* js,
                                               TimelineEventFilter* filter) {
   if (!FLAG_support_service) {
@@ -1341,6 +1309,7 @@
   }
   JSONArray events(js);
 }
+#endif
 
 TimelineEvent* TimelineEventCallbackRecorder::StartEvent() {
   TimelineEvent* event = new TimelineEvent();
@@ -1356,6 +1325,7 @@
 
 TimelineEventPlatformRecorder::~TimelineEventPlatformRecorder() {}
 
+#ifndef PRODUCT
 void TimelineEventPlatformRecorder::PrintJSON(JSONStream* js,
                                               TimelineEventFilter* filter) {
   if (!FLAG_support_service) {
@@ -1377,6 +1347,7 @@
   }
   JSONArray events(js);
 }
+#endif
 
 TimelineEvent* TimelineEventPlatformRecorder::StartEvent() {
   TimelineEvent* event = new TimelineEvent();
@@ -1402,6 +1373,7 @@
   }
 }
 
+#ifndef PRODUCT
 void TimelineEventEndlessRecorder::PrintJSON(JSONStream* js,
                                              TimelineEventFilter* filter) {
   if (!FLAG_support_service) {
@@ -1428,6 +1400,7 @@
   PrintJSONMeta(&events);
   PrintJSONEvents(&events, filter);
 }
+#endif
 
 TimelineEventBlock* TimelineEventEndlessRecorder::GetHeadBlockLocked() {
   return head_;
@@ -1455,6 +1428,7 @@
   return head_;
 }
 
+#ifndef PRODUCT
 static int TimelineEventBlockCompare(TimelineEventBlock* const* a,
                                      TimelineEventBlock* const* b) {
   return (*a)->LowerTimeBound() - (*b)->LowerTimeBound();
@@ -1500,6 +1474,7 @@
     }
   }
 }
+#endif
 
 void TimelineEventEndlessRecorder::Clear() {
   TimelineEventBlock* current = head_;
@@ -1525,6 +1500,7 @@
   Reset();
 }
 
+#ifndef PRODUCT
 void TimelineEventBlock::PrintJSON(JSONStream* js) const {
   ASSERT(!in_use());
   JSONArray events(js);
@@ -1533,6 +1509,7 @@
     events.AddValue(event);
   }
 }
+#endif
 
 TimelineEvent* TimelineEventBlock::StartEvent() {
   ASSERT(!IsFull());
@@ -1598,11 +1575,13 @@
     OS::PrintErr("Finish block %p\n", this);
   }
   in_use_ = false;
+#ifndef PRODUCT
   if (Service::timeline_stream.enabled()) {
     ServiceEvent service_event(NULL, ServiceEvent::kTimelineEvents);
     service_event.set_timeline_event_block(this);
     Service::HandleEvent(&service_event);
   }
+#endif
 }
 
 TimelineEventBlockIterator::TimelineEventBlockIterator(
@@ -1727,4 +1706,4 @@
 
 }  // namespace dart
 
-#endif  // !PRODUCT
+#endif  // defined(SUPPORT_TIMELINE)
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 92f33a3..0f50fbd 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -34,6 +34,7 @@
 #define TIMELINE_STREAM_LIST(V)                                                \
   V(API, false)                                                                \
   V(Compiler, false)                                                           \
+  V(CompilerVerbose, false)                                                    \
   V(Dart, false)                                                               \
   V(Debugger, false)                                                           \
   V(Embedder, false)                                                           \
@@ -89,8 +90,10 @@
 
   static void Clear();
 
+#ifndef PRODUCT
   // Print information about streams to JSON.
   static void PrintFlagsToJSON(JSONStream* json);
+#endif
 
 #define TIMELINE_STREAM_ACCESSOR(name, not_used)                               \
   static TimelineStream* Get##name##Stream() { return &stream_##name##_; }
@@ -99,36 +102,14 @@
 
 #define TIMELINE_STREAM_FLAGS(name, not_used)                                  \
   static void SetStream##name##Enabled(bool enabled) {                         \
-    StreamStateChange(#name, stream_##name##_.enabled(), enabled);             \
     stream_##name##_.set_enabled(enabled);                                     \
   }
   TIMELINE_STREAM_LIST(TIMELINE_STREAM_FLAGS)
 #undef TIMELINE_STREAM_FLAGS
 
-  static void set_start_recording_cb(
-      Dart_EmbedderTimelineStartRecording start_recording_cb) {
-    start_recording_cb_ = start_recording_cb;
-  }
-
-  static Dart_EmbedderTimelineStartRecording get_start_recording_cb() {
-    return start_recording_cb_;
-  }
-
-  static void set_stop_recording_cb(
-      Dart_EmbedderTimelineStopRecording stop_recording_cb) {
-    stop_recording_cb_ = stop_recording_cb;
-  }
-
-  static Dart_EmbedderTimelineStopRecording get_stop_recording_cb() {
-    return stop_recording_cb_;
-  }
-
  private:
-  static void StreamStateChange(const char* stream_name, bool prev, bool curr);
   static TimelineEventRecorder* recorder_;
   static MallocGrowableArray<char*>* enabled_streams_;
-  static Dart_EmbedderTimelineStartRecording start_recording_cb_;
-  static Dart_EmbedderTimelineStopRecording stop_recording_cb_;
 
 #define TIMELINE_STREAM_DECLARE(name, not_used)                                \
   static bool stream_##name##_enabled_;                                        \
@@ -311,7 +292,9 @@
   // The highest time value stored in this event.
   int64_t HighTime() const;
 
+#ifndef PRODUCT
   void PrintJSON(JSONStream* stream) const;
+#endif
 
   ThreadId thread() const { return thread_; }
 
@@ -447,7 +430,9 @@
   DISALLOW_COPY_AND_ASSIGN(TimelineEvent);
 };
 
-#ifndef PRODUCT
+#ifdef SUPPORT_TIMELINE
+#define TIMELINE_DURATION(thread, stream, name)                                \
+  TimelineDurationScope tds(thread, Timeline::Get##stream##Stream(), name);
 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function)         \
   TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), name);      \
   if (tds.enabled()) {                                                         \
@@ -463,6 +448,7 @@
   tds.SetNumArguments(1);                                                      \
   tds.CopyArgument(0, "mode", "basic");
 #else
+#define TIMELINE_DURATION(thread, stream, name)
 #define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, name, function)
 #define TIMELINE_FUNCTION_GC_DURATION(thread, name)
 #define TIMELINE_FUNCTION_GC_DURATION_BASIC(thread, name)
@@ -598,7 +584,9 @@
   ThreadId thread_id() const { return thread_id_; }
 
  protected:
+#ifndef PRODUCT
   void PrintJSON(JSONStream* stream) const;
+#endif
 
   TimelineEvent* StartEvent();
 
@@ -689,15 +677,19 @@
   TimelineEventBlock* GetNewBlock();
 
   // Interface method(s) which must be implemented.
+#ifndef PRODUCT
   virtual void PrintJSON(JSONStream* js, TimelineEventFilter* filter) = 0;
   virtual void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter) = 0;
+#endif
   virtual const char* name() const = 0;
   int64_t GetNextAsyncId();
 
   void FinishBlock(TimelineEventBlock* block);
 
  protected:
+#ifndef PRODUCT
   void WriteTo(const char* directory);
+#endif
 
   // Interface method(s) which must be implemented.
   virtual TimelineEvent* StartEvent() = 0;
@@ -707,7 +699,9 @@
   virtual void Clear() = 0;
 
   // Utility method(s).
+#ifndef PRODUCT
   void PrintJSONMeta(JSONArray* array) const;
+#endif
   TimelineEvent* ThreadBlockStartEvent();
   void ThreadBlockCompleteEvent(TimelineEvent* event);
 
@@ -739,8 +733,10 @@
   explicit TimelineEventFixedBufferRecorder(intptr_t capacity);
   virtual ~TimelineEventFixedBufferRecorder();
 
+#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
+#endif
 
  protected:
   TimelineEvent* StartEvent();
@@ -749,7 +745,9 @@
   intptr_t FindOldestBlockIndex() const;
   void Clear();
 
+#ifndef PRODUCT
   void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
+#endif
 
   VirtualMemory* memory_;
   TimelineEventBlock* blocks_;
@@ -793,8 +791,10 @@
   TimelineEventCallbackRecorder();
   virtual ~TimelineEventCallbackRecorder();
 
+#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
+#endif
 
   // Called when |event| is completed. It is unsafe to keep a reference to
   // |event| as it may be freed as soon as this function returns.
@@ -818,8 +818,10 @@
   TimelineEventEndlessRecorder();
   virtual ~TimelineEventEndlessRecorder();
 
+#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
+#endif
 
   const char* name() const { return "Endless"; }
 
@@ -830,7 +832,9 @@
   TimelineEventBlock* GetHeadBlockLocked();
   void Clear();
 
+#ifndef PRODUCT
   void PrintJSONEvents(JSONArray* array, TimelineEventFilter* filter);
+#endif
 
   TimelineEventBlock* head_;
   intptr_t block_index_;
@@ -865,8 +869,10 @@
   TimelineEventPlatformRecorder();
   virtual ~TimelineEventPlatformRecorder();
 
+#ifndef PRODUCT
   void PrintJSON(JSONStream* js, TimelineEventFilter* filter);
   void PrintTraceEvent(JSONStream* js, TimelineEventFilter* filter);
+#endif
 
   // Called when |event| is completed. It is unsafe to keep a reference to
   // |event| as it may be freed as soon as this function returns.
diff --git a/runtime/vm/timeline_android.cc b/runtime/vm/timeline_android.cc
index cd316eb..5ca038b 100644
--- a/runtime/vm/timeline_android.cc
+++ b/runtime/vm/timeline_android.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "platform/globals.h"
-#if defined(HOST_OS_ANDROID) && !defined(PRODUCT)
+#include "vm/globals.h"
+#if defined(HOST_OS_ANDROID) && defined(SUPPORT_TIMELINE)
 
 #include <errno.h>
 #include <fcntl.h>
diff --git a/runtime/vm/timeline_fuchsia.cc b/runtime/vm/timeline_fuchsia.cc
index f39cc20..9c0dab4 100644
--- a/runtime/vm/timeline_fuchsia.cc
+++ b/runtime/vm/timeline_fuchsia.cc
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "platform/globals.h"
-#if defined(HOST_OS_FUCHSIA) && !defined(PRODUCT)
+#include "vm/globals.h"
+#if defined(HOST_OS_FUCHSIA) && defined(SUPPORT_TIMELINE)
 
 #include <trace-engine/context.h>
 #include <trace-engine/instrumentation.h>
diff --git a/runtime/vm/timeline_linux.cc b/runtime/vm/timeline_linux.cc
index c1c5d53..05ddb69 100644
--- a/runtime/vm/timeline_linux.cc
+++ b/runtime/vm/timeline_linux.cc
@@ -2,14 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "platform/globals.h"
-#if defined(HOST_OS_LINUX) && !defined(PRODUCT)
+#include "vm/globals.h"
+#if defined(HOST_OS_LINUX) && defined(SUPPORT_TIMELINE)
 
 #include <errno.h>
 #include <fcntl.h>
 #include <cstdlib>
 
 #include "platform/atomic.h"
+#include "platform/signal_blocker.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/lockers.h"
@@ -23,16 +24,25 @@
 
 DECLARE_FLAG(bool, trace_timeline);
 
-TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
-    : TimelineEventPlatformRecorder(), systrace_fd_(-1) {
-  const char* kSystracePath = "/sys/kernel/debug/tracing/trace_marker";
-  systrace_fd_ = open(kSystracePath, O_WRONLY);
-  if ((systrace_fd_ < 0) && FLAG_trace_timeline) {
-    OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s`\n",
-                 kSystracePath);
+static int OpenTraceFD() {
+  const char* kSystraceDebugPath = "/sys/kernel/debug/tracing/trace_marker";
+  const char* kSystracePath = "/sys/kernel/tracing/trace_marker";
+
+  int fd = TEMP_FAILURE_RETRY(::open(kSystraceDebugPath, O_WRONLY));
+  if (fd < 0) {
+    fd = TEMP_FAILURE_RETRY(::open(kSystracePath, O_WRONLY));
   }
+
+  if (fd < 0 && FLAG_trace_timeline) {
+    OS::PrintErr("TimelineEventSystraceRecorder: Could not open `%s` or `%s`\n",
+                 kSystraceDebugPath, kSystracePath);
+  }
+  return fd;
 }
 
+TimelineEventSystraceRecorder::TimelineEventSystraceRecorder()
+    : TimelineEventPlatformRecorder(), systrace_fd_(OpenTraceFD()) {}
+
 TimelineEventSystraceRecorder::~TimelineEventSystraceRecorder() {
   if (systrace_fd_ >= 0) {
     close(systrace_fd_);
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index bca4938..4b37b7f 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -7,6 +7,7 @@
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/il_printer.h"
 #include "vm/object_store.h"
+#include "vm/timeline.h"
 
 #define __ assembler->
 
@@ -91,7 +92,7 @@
   return cname;
 }
 
-RawInstructions* TypeTestingStubGenerator::DefaultCodeForType(
+RawCode* TypeTestingStubGenerator::DefaultCodeForType(
     const AbstractType& type,
     bool lazy_specialize /* = true */) {
   // During bootstrapping we have no access to stubs yet, so we'll just return
@@ -100,25 +101,25 @@
     ASSERT(type.IsType());
     const intptr_t cid = Type::Cast(type).type_class_id();
     ASSERT(cid == kDynamicCid || cid == kVoidCid);
-    return Instructions::null();
+    return Code::null();
   }
 
   if (type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType() ||
       type.raw() == Type::VoidType()) {
-    return StubCode::TopTypeTypeTest().instructions();
+    return StubCode::TopTypeTypeTest().raw();
   }
 
   if (type.IsTypeRef()) {
-    return StubCode::TypeRefTypeTest().instructions();
+    return StubCode::TypeRefTypeTest().raw();
   }
 
   if (type.IsType() || type.IsTypeParameter()) {
     const bool should_specialize = !FLAG_precompiled_mode && lazy_specialize;
-    return should_specialize ? StubCode::LazySpecializeTypeTest().instructions()
-                             : StubCode::DefaultTypeTest().instructions();
-  } else {
-    return StubCode::UnreachableTypeTest().instructions();
+    return should_specialize ? StubCode::LazySpecializeTypeTest().raw()
+                             : StubCode::DefaultTypeTest().raw();
   }
+
+  return StubCode::UnreachableTypeTest().raw();
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -126,215 +127,61 @@
                                                  const AbstractType& type) {
   HierarchyInfo hi(thread);
   TypeTestingStubGenerator generator;
-  const Instructions& instr = Instructions::Handle(
-      thread->zone(), generator.OptimizedCodeForType(type));
-  type.SetTypeTestingStub(instr);
+  const Code& code =
+      Code::Handle(thread->zone(), generator.OptimizedCodeForType(type));
+  type.SetTypeTestingStub(code);
 }
 #endif
 
 TypeTestingStubGenerator::TypeTestingStubGenerator()
-    : object_store_(Isolate::Current()->object_store()),
-      array_(GrowableObjectArray::Handle()),
-      instr_(Instructions::Handle()) {}
+    : object_store_(Isolate::Current()->object_store()) {}
 
-RawInstructions* TypeTestingStubGenerator::OptimizedCodeForType(
+RawCode* TypeTestingStubGenerator::OptimizedCodeForType(
     const AbstractType& type) {
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
   ASSERT(StubCode::HasBeenInitialized());
 
   if (type.IsTypeRef()) {
-    return StubCode::TypeRefTypeTest().instructions();
+    return StubCode::TypeRefTypeTest().raw();
   }
 
   if (type.raw() == Type::ObjectType() || type.raw() == Type::DynamicType()) {
-    return StubCode::TopTypeTypeTest().instructions();
+    return StubCode::TopTypeTypeTest().raw();
   }
 
   if (type.IsCanonical()) {
     if (type.IsType()) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      // Lazily create the type testing stubs array.
-      array_ = object_store_->type_testing_stubs();
-      if (array_.IsNull()) {
-        array_ = GrowableObjectArray::New(Heap::kOld);
-        object_store_->set_type_testing_stubs(array_);
+      const Code& code = Code::Handle(
+          TypeTestingStubGenerator::BuildCodeForType(Type::Cast(type)));
+      if (!code.IsNull()) {
+        return code.raw();
       }
 
-      instr_ = TypeTestingStubGenerator::BuildCodeForType(Type::Cast(type));
-      if (!instr_.IsNull()) {
-        array_.Add(type);
-        array_.Add(instr_);
-      } else {
-        // Fall back to default.
-        instr_ = StubCode::DefaultTypeTest().instructions();
-      }
+      // Fall back to default.
+      return StubCode::DefaultTypeTest().raw();
 #else
       // In the precompiled runtime we cannot lazily create new optimized type
       // testing stubs, so if we cannot find one, we'll just return the default
       // one.
-      instr_ = StubCode::DefaultTypeTest().instructions();
+      return StubCode::DefaultTypeTest().raw();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-      return instr_.raw();
     }
   }
 #endif  // !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
   return TypeTestingStubGenerator::DefaultCodeForType(type, false);
 }
 
-TypeTestingStubFinder::TypeTestingStubFinder()
-    : array_(GrowableObjectArray::Handle()),
-      type_(Type::Handle()),
-      code_(Code::Handle()),
-      instr_(Instructions::Handle()) {
-  array_ = Isolate::Current()->object_store()->type_testing_stubs();
-  if (!array_.IsNull()) {
-    SortTableForFastLookup();
-  }
-}
-
-// TODO(kustermann): Use sorting/hashtables to speed this up.
-RawInstructions* TypeTestingStubFinder::LookupByAddresss(
-    uword entry_point) const {
-  // First test the 4 common ones:
-  code_ = StubCode::DefaultTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return code_.instructions();
-  }
-  code_ = StubCode::LazySpecializeTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return code_.instructions();
-  }
-  code_ = StubCode::TopTypeTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return code_.instructions();
-  }
-  code_ = StubCode::TypeRefTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return code_.instructions();
-  }
-  code_ = StubCode::UnreachableTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return code_.instructions();
-  }
-
-  const intptr_t tuple_idx = LookupInSortedArray(entry_point);
-  return Instructions::RawCast(array_.At(2 * tuple_idx + 1));
-}
-
-const char* TypeTestingStubFinder::StubNameFromAddresss(
-    uword entry_point) const {
-  // First test the 4 common ones:
-  code_ = StubCode::DefaultTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return "TypeTestingStub_Default";
-  }
-  code_ = StubCode::LazySpecializeTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return "TypeTestingStub_LazySpecialize";
-  }
-  code_ = StubCode::TopTypeTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return "TypeTestingStub_Top";
-  }
-  code_ = StubCode::TypeRefTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return "TypeTestingStub_Ref";
-  }
-  code_ = StubCode::UnreachableTypeTest().raw();
-  if (entry_point == code_.EntryPoint()) {
-    return "TypeTestingStub_Unreachable";
-  }
-
-  const intptr_t tuple_idx = LookupInSortedArray(entry_point);
-  type_ = AbstractType::RawCast(array_.At(2 * tuple_idx));
-  return namer_.StubNameForType(type_);
-}
-
-void TypeTestingStubFinder::SortTableForFastLookup() {
-  struct Sorter {
-    explicit Sorter(const GrowableObjectArray& array)
-        : array_(array),
-          object_(AbstractType::Handle()),
-          object2_(AbstractType::Handle()) {}
-
-    void Sort() {
-      const intptr_t tuples = array_.Length() / 2;
-      InsertionSort(0, tuples - 1);
-    }
-
-    void InsertionSort(intptr_t start, intptr_t end) {
-      for (intptr_t i = start + 1; i <= end; ++i) {
-        intptr_t j = i;
-        while (j > start && Value(j - 1) > Value(j)) {
-          Swap(j - 1, j);
-          j--;
-        }
-      }
-    }
-
-    void Swap(intptr_t i, intptr_t j) {
-      // Swap type.
-      object_ = array_.At(2 * i);
-      object2_ = array_.At(2 * j);
-      array_.SetAt(2 * i, object2_);
-      array_.SetAt(2 * j, object_);
-
-      // Swap instructions.
-      object_ = array_.At(2 * i + 1);
-      object2_ = array_.At(2 * j + 1);
-      array_.SetAt(2 * i + 1, object2_);
-      array_.SetAt(2 * j + 1, object_);
-    }
-
-    uword Value(intptr_t i) {
-      return Instructions::EntryPoint(
-          Instructions::RawCast(array_.At(2 * i + 1)));
-    }
-
-    const GrowableObjectArray& array_;
-    Object& object_;
-    Object& object2_;
-  };
-
-  Sorter sorter(array_);
-  sorter.Sort();
-}
-
-intptr_t TypeTestingStubFinder::LookupInSortedArray(uword entry_point) const {
-  intptr_t left = 0;
-  intptr_t right = array_.Length() / 2 - 1;
-
-  while (left <= right) {
-    const intptr_t mid = left + (right - left) / 2;
-    RawInstructions* instr = Instructions::RawCast(array_.At(2 * mid + 1));
-    const uword mid_value = Instructions::EntryPoint(instr);
-
-    if (entry_point < mid_value) {
-      right = mid - 1;
-    } else if (mid_value == entry_point) {
-      return mid;
-    } else {
-      left = mid + 1;
-    }
-  }
-
-  // The caller should only call this function if [entry_point] is a real type
-  // testing entrypoint, in which case it must be guaranteed to find it.
-  UNREACHABLE();
-  return NULL;
-}
-
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
-RawInstructions* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
+RawCode* TypeTestingStubGenerator::BuildCodeForType(const Type& type) {
   HierarchyInfo* hi = Thread::Current()->hierarchy_info();
   ASSERT(hi != NULL);
 
-  if (!hi->CanUseSubtypeRangeCheckFor(type)) {
-    if (!hi->CanUseGenericSubtypeRangeCheckFor(type)) {
-      return Instructions::null();
-    }
+  if (!hi->CanUseSubtypeRangeCheckFor(type) &&
+      !hi->CanUseGenericSubtypeRangeCheckFor(type)) {
+    return Code::null();
   }
 
   const Class& type_class = Class::Handle(type.type_class());
@@ -350,6 +197,7 @@
                                    : Code::PoolAttachment::kAttachPool;
   const Code& code = Code::Handle(Code::FinalizeCode(
       name, nullptr, &assembler, pool_attachment, false /* optimized */));
+  code.set_owner(type);
 #ifndef PRODUCT
   if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
     LogBlock lb;
@@ -364,7 +212,7 @@
   }
 #endif  // !PRODUCT
 
-  return code.instructions();
+  return code.raw();
 }
 
 void TypeTestingStubGenerator::BuildOptimizedTypeTestStubFastCases(
@@ -1003,19 +851,45 @@
 #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
 
 void DeoptimizeTypeTestingStubs() {
-  auto isolate = Isolate::Current();
-  auto& tts_array = GrowableObjectArray::Handle(
-      isolate->object_store()->type_testing_stubs());
-  auto& type = AbstractType::Handle();
-  auto& instr = Instructions::Handle();
+  class CollectTypes : public ObjectVisitor {
+   public:
+    CollectTypes(GrowableArray<AbstractType*>* types, Zone* zone)
+        : types_(types), object_(Object::Handle(zone)), zone_(zone) {}
+
+    void VisitObject(RawObject* object) {
+      if (object->IsPseudoObject()) {
+        // Cannot even be wrapped in handles.
+        return;
+      }
+      object_ = object;
+      if (object_.IsAbstractType()) {
+        types_->Add(
+            &AbstractType::Handle(zone_, AbstractType::RawCast(object)));
+      }
+    }
+
+   private:
+    GrowableArray<AbstractType*>* types_;
+    Object& object_;
+    Zone* zone_;
+  };
+
+  Thread* thread = Thread::Current();
+  TIMELINE_DURATION(thread, Isolate, "DeoptimizeTypeTestingStubs");
+  HANDLESCOPE(thread);
+  Zone* zone = thread->zone();
+  GrowableArray<AbstractType*> types;
+  {
+    HeapIterationScope iter(thread);
+    CollectTypes visitor(&types, zone);
+    iter.IterateObjects(&visitor);
+  }
 
   TypeTestingStubGenerator generator;
-  if (!tts_array.IsNull()) {
-    for (intptr_t i = 0; i < tts_array.Length(); i += 2) {
-      type ^= tts_array.At(i);
-      instr = generator.DefaultCodeForType(type);
-      type.SetTypeTestingStub(instr);
-    }
+  Code& code = Code::Handle(zone);
+  for (intptr_t i = 0; i < types.length(); i++) {
+    code = generator.DefaultCodeForType(*types[i]);
+    types[i]->SetTypeTestingStub(code);
   }
 }
 
diff --git a/runtime/vm/type_testing_stubs.h b/runtime/vm/type_testing_stubs.h
index e8c7044..7c1913a 100644
--- a/runtime/vm/type_testing_stubs.h
+++ b/runtime/vm/type_testing_stubs.h
@@ -10,7 +10,6 @@
 
 namespace dart {
 
-class ObjectPoolWrapper;
 
 class TypeTestingStubNamer {
  public:
@@ -38,8 +37,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 RawInstructions* DefaultCodeForType(const AbstractType& type,
-                                             bool lazy_specialize = true);
+  static RawCode* DefaultCodeForType(const AbstractType& type,
+                                     bool lazy_specialize = true);
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   static void SpecializeStubFor(Thread* thread, const AbstractType& type);
@@ -49,12 +48,12 @@
 
   // Creates new stub for [type] (and registers the tuple in object store
   // array) or returns default stub.
-  RawInstructions* OptimizedCodeForType(const AbstractType& type);
+  RawCode* OptimizedCodeForType(const AbstractType& type);
 
  private:
 #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32)
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  RawInstructions* BuildCodeForType(const Type& type);
+  RawCode* BuildCodeForType(const Type& type);
   static void BuildOptimizedTypeTestStub(Assembler* assembler,
                                          HierarchyInfo* hi,
                                          const Type& type,
@@ -120,42 +119,6 @@
 
   TypeTestingStubNamer namer_;
   ObjectStore* object_store_;
-  GrowableObjectArray& array_;
-  Instructions& instr_;
-};
-
-// It is assumed that the caller ensures, while this object lives there is no
-// other access to [Isolate::Current()->object_store()->type_testing_stubs()].
-class TypeTestingStubFinder {
- public:
-  TypeTestingStubFinder();
-
-  // When serializing an AOT snapshot via our clustered snapshot writer, we
-  // write out references to the [Instructions] object for all the
-  // [AbstractType] objects we encounter.
-  //
-  // This method is used for this mapping of stub entrypoint addresses to the
-  // corresponding [Instructions] object.
-  RawInstructions* LookupByAddresss(uword entry_point) const;
-
-  // When generating an AOT snapshot as an assembly file (i.e. ".S" file) we
-  // need to generate labels for the type testing stubs.
-  //
-  // This method maps stub entrypoint addresses to meaningful names.
-  const char* StubNameFromAddresss(uword entry_point) const;
-
- private:
-  // Sorts the tuples in [array_] according to entrypoint.
-  void SortTableForFastLookup();
-
-  // Returns the tuple index where [entry_point] was found.
-  intptr_t LookupInSortedArray(uword entry_point) const;
-
-  TypeTestingStubNamer namer_;
-  GrowableObjectArray& array_;
-  AbstractType& type_;
-  Code& code_;
-  Instructions& instr_;
 };
 
 template <typename T>
diff --git a/runtime/vm/type_testing_stubs_arm.cc b/runtime/vm/type_testing_stubs_arm.cc
new file mode 100644
index 0000000..30f1de07
--- /dev/null
+++ b/runtime/vm/type_testing_stubs_arm.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  const Register kInstanceReg = R0;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+                                      kInstanceReg, kClassIdReg);
+
+  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ Branch(FieldAddress(CODE_REG, Code::entry_point_offset()));
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+                                                      HierarchyInfo* hi,
+                                                      const Class& type_class,
+                                                      const TypeArguments& tp,
+                                                      const TypeArguments& ta) {
+  const Register kInstanceReg = R0;
+  const Register kInstanceTypeArguments = NOTFP;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+      kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    Label* check_failed) {
+  const Register kInstantiatorTypeArgumentsReg = R2;
+  const Register kFunctionTypeArgumentsReg = R1;
+  const Register kInstanceTypeArguments = NOTFP;
+
+  const Register kClassIdReg = R9;
+  const Register kOwnTypeArgumentValue = TMP;
+
+  BuildOptimizedTypeArgumentValueCheck(
+      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+}  // 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
new file mode 100644
index 0000000..0f2981e
--- /dev/null
+++ b/runtime/vm/type_testing_stubs_arm64.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#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(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  const Register kInstanceReg = R0;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+                                      kInstanceReg, kClassIdReg);
+
+  __ ldr(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ ldr(R9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+  __ br(R9);
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+                                                      HierarchyInfo* hi,
+                                                      const Class& type_class,
+                                                      const TypeArguments& tp,
+                                                      const TypeArguments& ta) {
+  const Register kInstanceReg = R0;
+  const Register kInstanceTypeArguments = R7;
+  const Register kClassIdReg = R9;
+
+  BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+      kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    Label* check_failed) {
+  const Register kInstantiatorTypeArgumentsReg = R1;
+  const Register kFunctionTypeArgumentsReg = R2;
+  const Register kInstanceTypeArguments = R7;
+
+  const Register kClassIdReg = R9;
+  const Register kOwnTypeArgumentValue = TMP;
+
+  BuildOptimizedTypeArgumentValueCheck(
+      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_ARM64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/type_testing_stubs_x64.cc b/runtime/vm/type_testing_stubs_x64.cc
new file mode 100644
index 0000000..69991de
--- /dev/null
+++ b/runtime/vm/type_testing_stubs_x64.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const Type& type,
+    const Class& type_class) {
+  const Register kInstanceReg = RAX;
+  const Register kClassIdReg = TMP;
+
+  BuildOptimizedTypeTestStubFastCases(assembler, hi, type, type_class,
+                                      kInstanceReg, kClassIdReg);
+
+  __ movq(CODE_REG, Address(THR, Thread::slow_type_test_stub_offset()));
+  __ jmp(FieldAddress(CODE_REG, Code::entry_point_offset()));
+}
+
+void TypeTestingStubGenerator::
+    BuildOptimizedSubclassRangeCheckWithTypeArguments(Assembler* assembler,
+                                                      HierarchyInfo* hi,
+                                                      const Class& type_class,
+                                                      const TypeArguments& tp,
+                                                      const TypeArguments& ta) {
+  const Register kInstanceReg = RAX;
+  const Register kInstanceTypeArguments = RSI;
+  const Register kClassIdReg = TMP;
+
+  BuildOptimizedSubclassRangeCheckWithTypeArguments(
+      assembler, hi, type_class, tp, ta, kClassIdReg, kInstanceReg,
+      kInstanceTypeArguments);
+}
+
+void TypeTestingStubGenerator::BuildOptimizedTypeArgumentValueCheck(
+    Assembler* assembler,
+    HierarchyInfo* hi,
+    const AbstractType& type_arg,
+    intptr_t type_param_value_offset_i,
+    Label* check_failed) {
+  const Register kInstanceTypeArguments = RSI;
+  const Register kInstantiatorTypeArgumentsReg = RDX;
+  const Register kFunctionTypeArgumentsReg = RCX;
+
+  const Register kClassIdReg = TMP;
+  const Register kOwnTypeArgumentValue = RDI;
+
+  BuildOptimizedTypeArgumentValueCheck(
+      assembler, hi, type_arg, type_param_value_offset_i, kClassIdReg,
+      kInstanceTypeArguments, kInstantiatorTypeArgumentsReg,
+      kFunctionTypeArgumentsReg, kOwnTypeArgumentValue, check_failed);
+}
+
+}  // namespace dart
+
+#endif  // defined(TARGET_ARCH_X64) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 6c53746..e8f1391 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -92,8 +92,8 @@
       bool use_far_branches = false;                                           \
       LongJumpScope jump;                                                      \
       if (setjmp(*jump.Set()) == 0) {                                          \
-        ObjectPoolWrapper object_pool_wrapper;                                 \
-        Assembler assembler(&object_pool_wrapper, use_far_branches);           \
+        ObjectPoolBuilder object_pool_builder;                                 \
+        Assembler assembler(&object_pool_builder, use_far_branches);           \
         AssemblerTest test("" #name, &assembler);                              \
         AssemblerTestGenerate##name(test.assembler());                         \
         test.Assemble();                                                       \
@@ -105,8 +105,8 @@
     const Error& error = Error::Handle(Thread::Current()->sticky_error());     \
     if (error.raw() == Object::branch_offset_error().raw()) {                  \
       bool use_far_branches = true;                                            \
-      ObjectPoolWrapper object_pool_wrapper;                                   \
-      Assembler assembler(&object_pool_wrapper, use_far_branches);             \
+      ObjectPoolBuilder object_pool_builder;                                   \
+      Assembler assembler(&object_pool_builder, use_far_branches);             \
       AssemblerTest test("" #name, &assembler);                                \
       AssemblerTestGenerate##name(test.assembler());                           \
       test.Assemble();                                                         \
@@ -198,7 +198,9 @@
 namespace dart {
 
 // Forward declarations.
+namespace compiler {
 class Assembler;
+}
 class CodeGenerator;
 class VirtualMemory;
 
diff --git a/runtime/vm/virtual_memory.cc b/runtime/vm/virtual_memory.cc
index ab89a53..6d73ba0 100644
--- a/runtime/vm/virtual_memory.cc
+++ b/runtime/vm/virtual_memory.cc
@@ -14,14 +14,12 @@
           Utils::RoundDown(address1, PageSize()));
 }
 
-void VirtualMemory::Truncate(intptr_t new_size, bool try_unmap) {
-  ASSERT((new_size & (PageSize() - 1)) == 0);
+void VirtualMemory::Truncate(intptr_t new_size) {
+  ASSERT(Utils::IsAligned(new_size, PageSize()));
   ASSERT(new_size <= size());
-  if (try_unmap &&
-      (reserved_.size() ==
-       region_.size()) && /* Don't create holes in reservation. */
-      FreeSubSegment(reinterpret_cast<void*>(start() + new_size),
-                     size() - new_size)) {
+  if (reserved_.size() == region_.size()) { // Don't create holes in reservation.
+    FreeSubSegment(reinterpret_cast<void*>(start() + new_size),
+                   size() - new_size);
     reserved_.set_size(new_size);
   }
   region_.Subregion(region_, 0, new_size);
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index 0ccdb41..6d74541 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -41,7 +41,9 @@
   // the requested size cannot be allocated, NULL is returned.
   static VirtualMemory* Allocate(intptr_t size,
                                  bool is_executable,
-                                 const char* name);
+                                 const char* name) {
+    return AllocateAligned(size, PageSize(), is_executable, name);
+  }
   static VirtualMemory* AllocateAligned(intptr_t size,
                                         intptr_t alignment,
                                         bool is_executable,
@@ -55,10 +57,8 @@
 
   static bool InSamePage(uword address0, uword address1);
 
-  // Truncate this virtual memory segment. If try_unmap is false, the
-  // memory beyond the new end is still accessible, but will be returned
-  // upon destruction.
-  void Truncate(intptr_t new_size, bool try_unmap = true);
+  // Truncate this virtual memory segment.
+  void Truncate(intptr_t new_size);
 
   // False for a part of a snapshot added directly to the Dart heap, which
   // belongs to the embedder and must not be deallocated or have its
@@ -70,7 +70,7 @@
  private:
   // Free a sub segment. On operating systems that support it this
   // can give back the virtual memory to the system. Returns true on success.
-  static bool FreeSubSegment(void* address, intptr_t size);
+  static void FreeSubSegment(void* address, intptr_t size);
 
   // This constructor is only used internally when reserving new virtual spaces.
   // It does not reserve any virtual address space on its own.
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
deleted file mode 100644
index 1ebce26..0000000
--- a/runtime/vm/virtual_memory_android.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(HOST_OS_ANDROID)
-
-#include "vm/virtual_memory.h"
-
-#include <errno.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "platform/assert.h"
-#include "platform/utils.h"
-
-#include "vm/isolate.h"
-
-namespace dart {
-
-// standard MAP_FAILED causes "error: use of old-style cast" as it
-// defines MAP_FAILED as ((void *) -1)
-#undef MAP_FAILED
-#define MAP_FAILED reinterpret_cast<void*>(-1)
-
-uword VirtualMemory::page_size_ = 0;
-
-void VirtualMemory::Init() {
-  page_size_ = getpagesize();
-}
-
-static void unmap(void* address, intptr_t size) {
-  if (size == 0) {
-    return;
-  }
-
-  if (munmap(address, size) != 0) {
-    int error = errno;
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    FATAL2("munmap error: %d (%s)", error,
-           Utils::StrError(error, error_buf, kBufferSize));
-  }
-}
-
-VirtualMemory* VirtualMemory::Allocate(intptr_t size,
-                                       bool is_executable,
-                                       const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* address = mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-  if (address == MAP_FAILED) {
-    return NULL;
-  }
-  MemoryRegion region(address, size);
-  return new VirtualMemory(region, region);
-}
-
-VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
-                                              intptr_t alignment,
-                                              bool is_executable,
-                                              const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  ASSERT(Utils::IsAligned(alignment, page_size_));
-  intptr_t allocated_size = size + alignment;
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* address =
-      mmap(NULL, allocated_size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-  if (address == MAP_FAILED) {
-    return NULL;
-  }
-
-  uword base = reinterpret_cast<uword>(address);
-  uword aligned_base = Utils::RoundUp(base, alignment);
-  ASSERT(base <= aligned_base);
-
-  if (base != aligned_base) {
-    uword extra_leading_size = aligned_base - base;
-    unmap(reinterpret_cast<void*>(base), extra_leading_size);
-    allocated_size -= extra_leading_size;
-  }
-
-  if (allocated_size != size) {
-    uword extra_trailing_size = allocated_size - size;
-    unmap(reinterpret_cast<void*>(aligned_base + size), extra_trailing_size);
-  }
-
-  MemoryRegion region(reinterpret_cast<void*>(aligned_base), size);
-  return new VirtualMemory(region, region);
-}
-
-VirtualMemory::~VirtualMemory() {
-  if (vm_owns_region()) {
-    unmap(reserved_.pointer(), reserved_.size());
-  }
-}
-
-bool VirtualMemory::FreeSubSegment(void* address,
-                                   intptr_t size) {
-  unmap(address, size);
-  return true;
-}
-
-void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
-#if defined(DEBUG)
-  Thread* thread = Thread::Current();
-  ASSERT((thread == nullptr) || thread->IsMutatorThread() ||
-         thread->isolate()->mutator_thread()->IsAtSafepoint());
-#endif
-  uword start_address = reinterpret_cast<uword>(address);
-  uword end_address = start_address + size;
-  uword page_address = Utils::RoundDown(start_address, PageSize());
-  int prot = 0;
-  switch (mode) {
-    case kNoAccess:
-      prot = PROT_NONE;
-      break;
-    case kReadOnly:
-      prot = PROT_READ;
-      break;
-    case kReadWrite:
-      prot = PROT_READ | PROT_WRITE;
-      break;
-    case kReadExecute:
-      prot = PROT_READ | PROT_EXEC;
-      break;
-    case kReadWriteExecute:
-      prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-      break;
-  }
-  if (mprotect(reinterpret_cast<void*>(page_address),
-               end_address - page_address, prot) != 0) {
-    int error = errno;
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    FATAL2("mprotect error: %d (%s)", error,
-           Utils::StrError(error, error_buf, kBufferSize));
-  }
-}
-
-}  // namespace dart
-
-#endif  // defined(HOST_OS_ANDROID)
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index bcbf3b0..63c47ae 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -35,62 +35,43 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, write_protect_code);
+
 uword VirtualMemory::page_size_ = 0;
 
 void VirtualMemory::Init() {
   page_size_ = getpagesize();
 }
 
-VirtualMemory* VirtualMemory::Allocate(intptr_t size,
-                                       bool is_executable,
-                                       const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  zx_handle_t vmo = ZX_HANDLE_INVALID;
-  zx_status_t status = zx_vmo_create(size, 0u, &vmo);
+static void unmap(zx_handle_t vmar, uword start, uword end) {
+  ASSERT(start <= end);
+  const uword size = end - start;
+  if (size == 0) {
+    return;
+  }
+
+  zx_status_t status = zx_vmar_unmap(vmar, start, size);
   if (status != ZX_OK) {
-    LOG_ERR("zx_vmo_create(%ld) failed: %s\n", size,
-            zx_status_get_string(status));
-    return NULL;
+    FATAL1("zx_vmar_unmap failed: %s\n", zx_status_get_string(status));
   }
-
-  if (name != NULL) {
-    zx_object_set_property(vmo, ZX_PROP_NAME, name, strlen(name));
-  }
-
-  if (is_executable) {
-    // Add ZX_PERM_EXECUTE permission to VMO, so it can be mapped
-    // into memory as executable.
-    status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &vmo);
-    if (status != ZX_OK) {
-      LOG_ERR("zx_vmo_replace_as_executable() failed: %s\n",
-              zx_status_get_string(status));
-      return NULL;
-    }
-  }
-
-  const uint32_t flags = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE |
-                         (is_executable ? ZX_VM_PERM_EXECUTE : 0);
-  uword address;
-  status = zx_vmar_map(zx_vmar_root_self(), flags, 0, vmo, 0, size, &address);
-  zx_handle_close(vmo);
-  if (status != ZX_OK) {
-    LOG_ERR("zx_vmar_map(%u, %ld) failed: %s\n", flags, size,
-            zx_status_get_string(status));
-    return NULL;
-  }
-  LOG_INFO("zx_vmar_map(%u,%ld) success\n", flags, size);
-
-  MemoryRegion region(reinterpret_cast<void*>(address), size);
-  return new VirtualMemory(region, region);
 }
 
 VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                               intptr_t alignment,
                                               bool is_executable,
                                               const char* name) {
+  // When FLAG_write_protect_code is active, the VM allocates code
+  // memory with !is_executable, and later changes to executable via
+  // VirtualMemory::Protect, which requires ZX_RIGHT_EXECUTE on the
+  // underlying VMO. Conservatively assume all memory needs to be
+  // executable in this mode.
+  // TODO(mdempsky): Make into parameter.
+  const bool can_prot_exec = FLAG_write_protect_code;
+
   ASSERT(Utils::IsAligned(size, page_size_));
+  ASSERT(Utils::IsPowerOfTwo(alignment));
   ASSERT(Utils::IsAligned(alignment, page_size_));
-  intptr_t allocated_size = size + alignment;
+  const intptr_t allocated_size = size + alignment - page_size_;
 
   zx_handle_t vmar = zx_vmar_root_self();
   zx_handle_t vmo = ZX_HANDLE_INVALID;
@@ -105,8 +86,8 @@
     zx_object_set_property(vmo, ZX_PROP_NAME, name, strlen(name));
   }
 
-  if (is_executable) {
-    // Add ZX_PERM_EXECUTE permission to VMO, so it can be mapped
+  if (is_executable || can_prot_exec) {
+    // Add ZX_RIGHT_EXECUTE permission to VMO, so it can be mapped
     // into memory as executable.
     status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &vmo);
     if (status != ZX_OK) {
@@ -127,25 +108,10 @@
     return NULL;
   }
 
-  uword aligned_base = Utils::RoundUp(base, alignment);
-  ASSERT(base <= aligned_base);
+  const uword aligned_base = Utils::RoundUp(base, alignment);
 
-  if (base != aligned_base) {
-    uword extra_leading_size = aligned_base - base;
-    status = zx_vmar_unmap(vmar, base, extra_leading_size);
-    if (status != ZX_OK) {
-      FATAL1("zx_vmar_unmap failed: %s\n", zx_status_get_string(status));
-    }
-    allocated_size -= extra_leading_size;
-  }
-
-  if (allocated_size != size) {
-    uword extra_trailing_size = allocated_size - size;
-    status = zx_vmar_unmap(vmar, aligned_base + size, extra_trailing_size);
-    if (status != ZX_OK) {
-      FATAL1("zx_vmar_unmap failed: %s\n", zx_status_get_string(status));
-    }
-  }
+  unmap(vmar, base, aligned_base);
+  unmap(vmar, aligned_base + size, base + allocated_size);
 
   MemoryRegion region(reinterpret_cast<void*>(aligned_base), size);
   return new VirtualMemory(region, region);
@@ -154,27 +120,16 @@
 VirtualMemory::~VirtualMemory() {
   // Reserved region may be empty due to VirtualMemory::Truncate.
   if (vm_owns_region() && reserved_.size() != 0) {
-    zx_status_t status =
-        zx_vmar_unmap(zx_vmar_root_self(), reserved_.start(), reserved_.size());
-    if (status != ZX_OK) {
-      FATAL3("zx_vmar_unmap(%lx, %lx) failed: %s\n", reserved_.start(),
-             reserved_.size(), zx_status_get_string(status));
-    }
+    unmap(zx_vmar_root_self(), reserved_.start(), reserved_.end());
     LOG_INFO("zx_vmar_unmap(%lx, %lx) success\n", reserved_.start(),
              reserved_.size());
   }
 }
 
-bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
-  zx_status_t status = zx_vmar_unmap(
-      zx_vmar_root_self(), reinterpret_cast<uintptr_t>(address), size);
-  if (status != ZX_OK) {
-    LOG_ERR("zx_vmar_unmap(%p, %lx) failed: %s\n", address, size,
-            zx_status_get_string(status));
-    return false;
-  }
+void VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
+  const uword start = reinterpret_cast<uword>(address);
+  unmap(zx_vmar_root_self(), start, start + size);
   LOG_INFO("zx_vmar_unmap(%p, %lx) success\n", address, size);
-  return true;
 }
 
 void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
deleted file mode 100644
index bd76de5..0000000
--- a/runtime/vm/virtual_memory_linux.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(HOST_OS_LINUX)
-
-#include "vm/virtual_memory.h"
-
-#include <errno.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "platform/assert.h"
-#include "platform/utils.h"
-
-#include "vm/isolate.h"
-
-namespace dart {
-
-// standard MAP_FAILED causes "error: use of old-style cast" as it
-// defines MAP_FAILED as ((void *) -1)
-#undef MAP_FAILED
-#define MAP_FAILED reinterpret_cast<void*>(-1)
-
-uword VirtualMemory::page_size_ = 0;
-
-void VirtualMemory::Init() {
-  page_size_ = getpagesize();
-}
-
-static void unmap(void* address, intptr_t size) {
-  if (size == 0) {
-    return;
-  }
-
-  if (munmap(address, size) != 0) {
-    int error = errno;
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    FATAL2("munmap error: %d (%s)", error,
-           Utils::StrError(error, error_buf, kBufferSize));
-  }
-}
-
-VirtualMemory* VirtualMemory::Allocate(intptr_t size,
-                                       bool is_executable,
-                                       const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* address = mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-  if (address == MAP_FAILED) {
-    return NULL;
-  }
-  MemoryRegion region(address, size);
-  return new VirtualMemory(region, region);
-}
-
-VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
-                                              intptr_t alignment,
-                                              bool is_executable,
-                                              const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  ASSERT(Utils::IsAligned(alignment, page_size_));
-  intptr_t allocated_size = size + alignment;
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* address =
-      mmap(NULL, allocated_size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-  if (address == MAP_FAILED) {
-    return NULL;
-  }
-
-  uword base = reinterpret_cast<uword>(address);
-  uword aligned_base = Utils::RoundUp(base, alignment);
-  ASSERT(base <= aligned_base);
-
-  if (base != aligned_base) {
-    uword extra_leading_size = aligned_base - base;
-    unmap(reinterpret_cast<void*>(base), extra_leading_size);
-    allocated_size -= extra_leading_size;
-  }
-
-  if (allocated_size != size) {
-    uword extra_trailing_size = allocated_size - size;
-    unmap(reinterpret_cast<void*>(aligned_base + size), extra_trailing_size);
-  }
-
-  MemoryRegion region(reinterpret_cast<void*>(aligned_base), size);
-  return new VirtualMemory(region, region);
-}
-
-VirtualMemory::~VirtualMemory() {
-  if (vm_owns_region()) {
-    unmap(reserved_.pointer(), reserved_.size());
-  }
-}
-
-bool VirtualMemory::FreeSubSegment(void* address,
-                                   intptr_t size) {
-  unmap(address, size);
-  return true;
-}
-
-void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
-#if defined(DEBUG)
-  Thread* thread = Thread::Current();
-  ASSERT((thread == nullptr) || thread->IsMutatorThread() ||
-         thread->isolate()->mutator_thread()->IsAtSafepoint());
-#endif
-  uword start_address = reinterpret_cast<uword>(address);
-  uword end_address = start_address + size;
-  uword page_address = Utils::RoundDown(start_address, PageSize());
-  int prot = 0;
-  switch (mode) {
-    case kNoAccess:
-      prot = PROT_NONE;
-      break;
-    case kReadOnly:
-      prot = PROT_READ;
-      break;
-    case kReadWrite:
-      prot = PROT_READ | PROT_WRITE;
-      break;
-    case kReadExecute:
-      prot = PROT_READ | PROT_EXEC;
-      break;
-    case kReadWriteExecute:
-      prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-      break;
-  }
-  if (mprotect(reinterpret_cast<void*>(page_address),
-               end_address - page_address, prot) != 0) {
-    int error = errno;
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    FATAL2("mprotect error: %d (%s)", error,
-           Utils::StrError(error, error_buf, kBufferSize));
-  }
-}
-
-}  // namespace dart
-
-#endif  // defined(HOST_OS_LINUX)
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
deleted file mode 100644
index dc75b44..0000000
--- a/runtime/vm/virtual_memory_macos.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(HOST_OS_MACOS)
-
-#include "vm/virtual_memory.h"
-
-#include <errno.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "platform/assert.h"
-#include "platform/utils.h"
-
-#include "vm/isolate.h"
-
-namespace dart {
-
-// standard MAP_FAILED causes "error: use of old-style cast" as it
-// defines MAP_FAILED as ((void *) -1)
-#undef MAP_FAILED
-#define MAP_FAILED reinterpret_cast<void*>(-1)
-
-uword VirtualMemory::page_size_ = 0;
-
-void VirtualMemory::Init() {
-  page_size_ = getpagesize();
-}
-
-static void unmap(void* address, intptr_t size) {
-  if (size == 0) {
-    return;
-  }
-
-  if (munmap(address, size) != 0) {
-    int error = errno;
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    FATAL2("munmap error: %d (%s)", error,
-           Utils::StrError(error, error_buf, kBufferSize));
-  }
-}
-
-VirtualMemory* VirtualMemory::Allocate(intptr_t size,
-                                       bool is_executable,
-                                       const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* address = mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-  if (address == MAP_FAILED) {
-    return NULL;
-  }
-  MemoryRegion region(address, size);
-  return new VirtualMemory(region, region);
-}
-
-VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
-                                              intptr_t alignment,
-                                              bool is_executable,
-                                              const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  ASSERT(Utils::IsAligned(alignment, page_size_));
-  intptr_t allocated_size = size + alignment;
-  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
-  void* address =
-      mmap(NULL, allocated_size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
-  if (address == MAP_FAILED) {
-    return NULL;
-  }
-
-  uword base = reinterpret_cast<uword>(address);
-  uword aligned_base = Utils::RoundUp(base, alignment);
-  ASSERT(base <= aligned_base);
-
-  if (base != aligned_base) {
-    uword extra_leading_size = aligned_base - base;
-    unmap(reinterpret_cast<void*>(base), extra_leading_size);
-    allocated_size -= extra_leading_size;
-  }
-
-  if (allocated_size != size) {
-    uword extra_trailing_size = allocated_size - size;
-    unmap(reinterpret_cast<void*>(aligned_base + size), extra_trailing_size);
-  }
-
-  MemoryRegion region(reinterpret_cast<void*>(aligned_base), size);
-  return new VirtualMemory(region, region);
-}
-
-VirtualMemory::~VirtualMemory() {
-  if (vm_owns_region()) {
-    unmap(reserved_.pointer(), reserved_.size());
-  }
-}
-
-bool VirtualMemory::FreeSubSegment(void* address,
-                                   intptr_t size) {
-  unmap(address, size);
-  return true;
-}
-
-void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
-#if defined(DEBUG)
-  Thread* thread = Thread::Current();
-  ASSERT((thread == nullptr) || thread->IsMutatorThread() ||
-         thread->isolate()->mutator_thread()->IsAtSafepoint());
-#endif
-  uword start_address = reinterpret_cast<uword>(address);
-  uword end_address = start_address + size;
-  uword page_address = Utils::RoundDown(start_address, PageSize());
-  int prot = 0;
-  switch (mode) {
-    case kNoAccess:
-      prot = PROT_NONE;
-      break;
-    case kReadOnly:
-      prot = PROT_READ;
-      break;
-    case kReadWrite:
-      prot = PROT_READ | PROT_WRITE;
-      break;
-    case kReadExecute:
-      prot = PROT_READ | PROT_EXEC;
-      break;
-    case kReadWriteExecute:
-      prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-      break;
-  }
-  if (mprotect(reinterpret_cast<void*>(page_address),
-               end_address - page_address, prot) != 0) {
-    int error = errno;
-    const int kBufferSize = 1024;
-    char error_buf[kBufferSize];
-    FATAL2("mprotect error: %d (%s)", error,
-           Utils::StrError(error, error_buf, kBufferSize));
-  }
-}
-
-}  // namespace dart
-
-#endif  // defined(HOST_OS_MACOS)
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
new file mode 100644
index 0000000..31c7f15
--- /dev/null
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -0,0 +1,124 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/globals.h"
+#if defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS)
+
+#include "vm/virtual_memory.h"
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "platform/assert.h"
+#include "platform/utils.h"
+
+#include "vm/isolate.h"
+
+namespace dart {
+
+// standard MAP_FAILED causes "error: use of old-style cast" as it
+// defines MAP_FAILED as ((void *) -1)
+#undef MAP_FAILED
+#define MAP_FAILED reinterpret_cast<void*>(-1)
+
+uword VirtualMemory::page_size_ = 0;
+
+void VirtualMemory::Init() {
+  page_size_ = getpagesize();
+}
+
+static void unmap(uword start, uword end) {
+  ASSERT(start <= end);
+  uword size = end - start;
+  if (size == 0) {
+    return;
+  }
+
+  if (munmap(reinterpret_cast<void*>(start), size) != 0) {
+    int error = errno;
+    const int kBufferSize = 1024;
+    char error_buf[kBufferSize];
+    FATAL2("munmap error: %d (%s)", error,
+           Utils::StrError(error, error_buf, kBufferSize));
+  }
+}
+
+VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
+                                              intptr_t alignment,
+                                              bool is_executable,
+                                              const char* name) {
+  ASSERT(Utils::IsAligned(size, page_size_));
+  ASSERT(Utils::IsPowerOfTwo(alignment));
+  ASSERT(Utils::IsAligned(alignment, page_size_));
+  const intptr_t allocated_size = size + alignment - page_size_;
+  const int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
+  void* address =
+      mmap(NULL, allocated_size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (address == MAP_FAILED) {
+    return NULL;
+  }
+
+  const uword base = reinterpret_cast<uword>(address);
+  const uword aligned_base = Utils::RoundUp(base, alignment);
+
+  unmap(base, aligned_base);
+  unmap(aligned_base + size, base + allocated_size);
+
+  MemoryRegion region(reinterpret_cast<void*>(aligned_base), size);
+  return new VirtualMemory(region, region);
+}
+
+VirtualMemory::~VirtualMemory() {
+  if (vm_owns_region()) {
+    unmap(reserved_.start(), reserved_.end());
+  }
+}
+
+void VirtualMemory::FreeSubSegment(void* address,
+                                   intptr_t size) {
+  const uword start = reinterpret_cast<uword>(address);
+  unmap(start, start + size);
+}
+
+void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
+#if defined(DEBUG)
+  Thread* thread = Thread::Current();
+  ASSERT((thread == nullptr) || thread->IsMutatorThread() ||
+         thread->isolate()->mutator_thread()->IsAtSafepoint());
+#endif
+  uword start_address = reinterpret_cast<uword>(address);
+  uword end_address = start_address + size;
+  uword page_address = Utils::RoundDown(start_address, PageSize());
+  int prot = 0;
+  switch (mode) {
+    case kNoAccess:
+      prot = PROT_NONE;
+      break;
+    case kReadOnly:
+      prot = PROT_READ;
+      break;
+    case kReadWrite:
+      prot = PROT_READ | PROT_WRITE;
+      break;
+    case kReadExecute:
+      prot = PROT_READ | PROT_EXEC;
+      break;
+    case kReadWriteExecute:
+      prot = PROT_READ | PROT_WRITE | PROT_EXEC;
+      break;
+  }
+  if (mprotect(reinterpret_cast<void*>(page_address),
+               end_address - page_address, prot) != 0) {
+    int error = errno;
+    const int kBufferSize = 1024;
+    char error_buf[kBufferSize];
+    FATAL2("mprotect error: %d (%s)", error,
+           Utils::StrError(error, error_buf, kBufferSize));
+  }
+}
+
+}  // namespace dart
+
+#endif  // defined(HOST_OS_ANDROID) || defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS)
diff --git a/runtime/vm/virtual_memory_test.cc b/runtime/vm/virtual_memory_test.cc
index 9454ecf..d54fe28 100644
--- a/runtime/vm/virtual_memory_test.cc
+++ b/runtime/vm/virtual_memory_test.cc
@@ -77,25 +77,13 @@
   for (intptr_t i = 0; i < kIterations; ++i) {
     VirtualMemory* vm =
         VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, NULL);
-    vm->Truncate(kVirtualMemoryBlockSize / 2, true);
+    vm->Truncate(kVirtualMemoryBlockSize / 2);
     delete vm;
   }
   for (intptr_t i = 0; i < kIterations; ++i) {
     VirtualMemory* vm =
         VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, NULL);
-    vm->Truncate(kVirtualMemoryBlockSize / 2, false);
-    delete vm;
-  }
-  for (intptr_t i = 0; i < kIterations; ++i) {
-    VirtualMemory* vm =
-        VirtualMemory::Allocate(kVirtualMemoryBlockSize, true, NULL);
-    vm->Truncate(0, true);
-    delete vm;
-  }
-  for (intptr_t i = 0; i < kIterations; ++i) {
-    VirtualMemory* vm =
-        VirtualMemory::Allocate(kVirtualMemoryBlockSize, false, NULL);
-    vm->Truncate(0, false);
+    vm->Truncate(0);
     delete vm;
   }
 }
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index a36128a..9c917b3 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -22,26 +22,14 @@
   page_size_ = info.dwPageSize;
 }
 
-VirtualMemory* VirtualMemory::Allocate(intptr_t size,
-                                       bool is_executable,
-                                       const char* name) {
-  ASSERT(Utils::IsAligned(size, page_size_));
-  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
-  void* address = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, prot);
-  if (address == NULL) {
-    return NULL;
-  }
-  MemoryRegion region(address, size);
-  return new VirtualMemory(region, region);
-}
-
 VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
                                               intptr_t alignment,
                                               bool is_executable,
                                               const char* name) {
   ASSERT(Utils::IsAligned(size, page_size_));
+  ASSERT(Utils::IsPowerOfTwo(alignment));
   ASSERT(Utils::IsAligned(alignment, page_size_));
-  intptr_t reserved_size = size + alignment;
+  intptr_t reserved_size = size + alignment - page_size_;
   int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
   void* address = VirtualAlloc(NULL, reserved_size, MEM_RESERVE, prot);
   if (address == NULL) {
@@ -74,12 +62,11 @@
   }
 }
 
-bool VirtualMemory::FreeSubSegment(void* address,
+void VirtualMemory::FreeSubSegment(void* address,
                                    intptr_t size) {
   if (VirtualFree(address, size, MEM_DECOMMIT) == 0) {
     FATAL1("VirtualFree failed: Error code %d\n", GetLastError());
   }
-  return true;
 }
 
 void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 82b9645..198d04e 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -22,12 +22,14 @@
   "bootstrap_natives.h",
   "class_finalizer.cc",
   "class_finalizer.h",
+  "class_id.h",
   "class_table.cc",
   "class_table.h",
   "clustered_snapshot.cc",
   "clustered_snapshot.h",
   "code_descriptors.cc",
   "code_descriptors.h",
+  "code_entry_kind.h",
   "code_observers.cc",
   "code_observers.h",
   "code_patcher.cc",
@@ -45,6 +47,7 @@
   "constants_dbc.h",
   "constants_ia32.h",
   "constants_kbc.h",
+  "constants_x64.cc",
   "constants_x64.h",
   "cpu.h",
   "cpu_arm.cc",
@@ -89,14 +92,17 @@
   "dwarf.h",
   "exceptions.cc",
   "exceptions.h",
+  "ffi_trampoline_stubs_x64.cc",
   "finalizable_data.h",
   "fixed_cache.h",
   "flag_list.h",
   "flags.cc",
   "flags.h",
+  "frame_layout.h",
   "gdb_helpers.cc",
   "globals.h",
   "growable_array.h",
+  "handle_visitor.h",
   "handles.cc",
   "handles.h",
   "handles_impl.h",
@@ -119,6 +125,7 @@
   "instructions_x64.h",
   "interpreter.cc",
   "interpreter.h",
+  "intrusive_dlist.h",
   "isolate.cc",
   "isolate.h",
   "isolate_reload.cc",
@@ -201,6 +208,7 @@
   "os_win.cc",
   "parser.cc",
   "parser.h",
+  "pointer_tagging.h",
   "port.cc",
   "port.h",
   "proccpuinfo.cc",
@@ -287,13 +295,10 @@
   "stack_frame_x64.h",
   "stack_trace.cc",
   "stack_trace.h",
+  "static_type_exactness_state.h",
   "stub_code.cc",
   "stub_code.h",
-  "stub_code_arm.cc",
-  "stub_code_arm64.cc",
-  "stub_code_dbc.cc",
-  "stub_code_ia32.cc",
-  "stub_code_x64.cc",
+  "stub_code_list.h",
   "symbols.cc",
   "symbols.h",
   "tags.cc",
@@ -331,6 +336,9 @@
   "token_position.h",
   "type_table.h",
   "type_testing_stubs.cc",
+  "type_testing_stubs_arm.cc",
+  "type_testing_stubs_arm64.cc",
+  "type_testing_stubs_x64.cc",
   "type_testing_stubs.h",
   "unibrow-inl.h",
   "unibrow.cc",
@@ -344,10 +352,8 @@
   "v8_snapshot_writer.h",
   "virtual_memory.cc",
   "virtual_memory.h",
-  "virtual_memory_android.cc",
   "virtual_memory_fuchsia.cc",
-  "virtual_memory_linux.cc",
-  "virtual_memory_macos.cc",
+  "virtual_memory_posix.cc",
   "virtual_memory_win.cc",
   "visitor.h",
   "zone.cc",
@@ -394,6 +400,7 @@
   "instructions_arm_test.cc",
   "instructions_ia32_test.cc",
   "instructions_x64_test.cc",
+  "intrusive_dlist_test.cc",
   "isolate_reload_test.cc",
   "isolate_test.cc",
   "json_test.cc",
diff --git a/samples/ffi/coordinate.dart b/samples/ffi/coordinate.dart
new file mode 100644
index 0000000..f8ac7d48
--- /dev/null
+++ b/samples/ffi/coordinate.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.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+/// Sample struct for dart:ffi library.
+@ffi.struct
+class Coordinate extends ffi.Pointer<ffi.Void> {
+  @ffi.Double()
+  double x;
+
+  @ffi.Double()
+  double y;
+
+  @ffi.Pointer()
+  Coordinate next;
+
+  // Implementation generated by @ffi.struct annotation.
+  external static int sizeOf();
+
+  Coordinate offsetBy(int offsetInBytes) =>
+      super.offsetBy(offsetInBytes).cast();
+
+  Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
+
+  static Coordinate allocate({int count: 1}) =>
+      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
+
+  /// Allocate a new [Coordinate] in C memory and populate its fields.
+  factory Coordinate(double x, double y, Coordinate next) {
+    Coordinate result = Coordinate.allocate()
+      ..x = x
+      ..y = y
+      ..next = next;
+    return result;
+  }
+}
diff --git a/samples/ffi/sample_ffi_data.dart b/samples/ffi/sample_ffi_data.dart
new file mode 100644
index 0000000..ba05601
--- /dev/null
+++ b/samples/ffi/sample_ffi_data.dart
@@ -0,0 +1,274 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi' as ffi;
+
+main(List<String> arguments) {
+  print('start main');
+
+  {
+    // basic operation: allocate, get, set, and free
+    ffi.Pointer<ffi.Int64> p = ffi.allocate();
+    p.store(42);
+    int pValue = p.load();
+    print('${p.runtimeType} value: ${pValue}');
+    p.free();
+  }
+
+  {
+    // undefined behavior before set
+    ffi.Pointer<ffi.Int64> p = ffi.allocate();
+    int pValue = p.load();
+    print('If not set, returns garbage: ${pValue}');
+    p.free();
+  }
+
+  {
+    // pointers can be created from an address
+    ffi.Pointer<ffi.Int64> pHelper = ffi.allocate();
+    pHelper.store(1337);
+
+    int address = pHelper.address;
+    print('Address: ${address}');
+
+    ffi.Pointer<ffi.Int64> p = ffi.fromAddress(address);
+    print('${p.runtimeType} value: ${p.load<int>()}');
+
+    pHelper.free();
+  }
+
+  {
+    // address is zeroed out after free
+    ffi.Pointer<ffi.Int64> p = ffi.allocate();
+    p.free();
+    print('After free, address is zero: ${p.address}');
+  }
+
+  {
+    // pointer arithmetic can be done with element offsets or bytes
+    ffi.Pointer<ffi.Int64> p1 = ffi.allocate<ffi.Int64>(count: 2);
+    print('p1 address: ${p1.address}');
+
+    ffi.Pointer<ffi.Int64> p2 = p1.elementAt(1);
+    print('p1.elementAt(1) address: ${p2.address}');
+    p2.store(100);
+
+    ffi.Pointer<ffi.Int64> p3 = p1.offsetBy(8);
+    print('p1.offsetBy(8) address: ${p3.address}');
+    print('p1.offsetBy(8) value: ${p3.load<int>()}');
+    p1.free();
+  }
+
+  {
+    // allocating too much throws an exception
+    try {
+      int maxMint = 9223372036854775807; // 2^63 - 1
+      ffi.allocate<ffi.Int64>(count: maxMint);
+    } on RangeError {
+      print('Expected exception on allocating too much');
+    }
+    try {
+      int maxInt1_8 = 1152921504606846975; // 2^60 -1
+      ffi.allocate<ffi.Int64>(count: maxInt1_8);
+    } on ArgumentError {
+      print('Expected exception on allocating too much');
+    }
+  }
+
+  {
+    // pointers can be cast into another type
+    // resulting in the corresponding bits read
+    ffi.Pointer<ffi.Int64> p1 = ffi.allocate();
+    p1.store(9223372036854775807); // 2^63 - 1
+
+    ffi.Pointer<ffi.Int32> p2 = p1.cast();
+    print('${p2.runtimeType} value: ${p2.load<int>()}'); // -1
+
+    ffi.Pointer<ffi.Int32> p3 = p2.elementAt(1);
+    print('${p3.runtimeType} value: ${p3.load<int>()}'); // 2^31 - 1
+
+    p1.free();
+  }
+
+  {
+    // data can be tightly packed in memory
+    ffi.Pointer<ffi.Int8> p = ffi.allocate(count: 8);
+    for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+      p.elementAt(i).store(i * 3);
+    }
+    for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+      print('p.elementAt($i) value: ${p.elementAt(i).load<int>()}');
+    }
+    p.free();
+  }
+
+  {
+    // exception on storing a value that does not fit
+    ffi.Pointer<ffi.Int32> p11 = ffi.allocate();
+
+    try {
+      p11.store(9223372036854775807);
+    } on ArgumentError {
+      print('Expected exception on calling set with a value that does not fit');
+    }
+
+    p11.free();
+  }
+
+  {
+    // doubles
+    ffi.Pointer<ffi.Double> p = ffi.allocate();
+    p.store(3.14159265359);
+    print('${p.runtimeType} value: ${p.load<double>()}');
+    p.store(3.14);
+    print('${p.runtimeType} value: ${p.load<double>()}');
+    p.free();
+  }
+
+  {
+    // floats
+    ffi.Pointer<ffi.Float> p = ffi.allocate();
+    p.store(3.14159265359);
+    print('${p.runtimeType} value: ${p.load<double>()}');
+    p.store(3.14);
+    print('${p.runtimeType} value: ${p.load<double>()}');
+    p.free();
+  }
+
+  {
+    // ffi.IntPtr varies in size based on whether the platform is 32 or 64 bit
+    // addresses of pointers fit in this size
+    ffi.Pointer<ffi.IntPtr> p = ffi.allocate();
+    int p14addr = p.address;
+    p.store(p14addr);
+    int pValue = p.load();
+    print('${p.runtimeType} value: ${pValue}');
+    p.free();
+  }
+
+  {
+    // void pointers are unsized
+    // the size of the element it is pointing to is undefined
+    // this means they cannot be ffi.allocated, read, or written
+    // this would would fail to compile:
+    // ffi.allocate<ffi.Void>();
+
+    ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+    ffi.Pointer<ffi.Void> p2 = p1.cast();
+    print('${p2.runtimeType} address: ${p2.address}');
+
+    // this fails to compile, we cannot read something unsized
+    // p2.load<int>();
+
+    // this fails to compile, we cannot write something unsized
+    // p2.store(1234);
+
+    p1.free();
+  }
+
+  {
+    // pointer to a pointer to something
+    ffi.Pointer<ffi.Int16> pHelper = ffi.allocate();
+    pHelper.store(17);
+
+    ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
+
+    // storing into a pointer pointer automatically unboxes
+    p.store(pHelper);
+
+    // reading from a pointer pointer automatically boxes
+    ffi.Pointer<ffi.Int16> pHelper2 = p.load();
+    print('${pHelper2.runtimeType} value: ${pHelper2.load<int>()}');
+
+    int pValue = p.load<ffi.Pointer<ffi.Int16>>().load();
+    print('${p.runtimeType} value\'s value: ${pValue}');
+
+    p.free();
+    pHelper.free();
+  }
+
+  {
+    // the pointer to pointer types must match up
+    ffi.Pointer<ffi.Int8> pHelper = ffi.allocate();
+    pHelper.store(123);
+
+    ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
+
+    // this fails to compile due to type mismatch
+    // p.store(pHelper);
+
+    pHelper.free();
+    p.free();
+  }
+
+  {
+    // null pointer in Dart points to address 0 in c++
+    ffi.Pointer<ffi.Pointer<ffi.Int8>> pointerToPointer = ffi.allocate();
+    ffi.Pointer<ffi.Int8> value = null;
+    pointerToPointer.store(value);
+    value = pointerToPointer.load();
+    print("Loading a pointer to the 0 address is null: ${value}");
+    pointerToPointer.free();
+  }
+
+  {
+    // sizeof returns element size in bytes
+    print('sizeOf<ffi.Double>(): ${ffi.sizeOf<ffi.Double>()}');
+    print('sizeOf<ffi.Int16>(): ${ffi.sizeOf<ffi.Int16>()}');
+    print('sizeOf<ffi.IntPtr>(): ${ffi.sizeOf<ffi.IntPtr>()}');
+  }
+
+  {
+    // only concrete sub types of NativeType can be ffi.allocated
+    // this would fail to compile:
+    // ffi.allocate();
+  }
+
+  {
+    // only concrete sub types of NativeType can be asked for size
+    // this would fail to compile:
+    // ffi.sizeOf();
+  }
+
+  {
+    // with ffi.IntPtr pointers, one can manually setup aribtrary data
+    // structres in C memory.
+
+    void createChain(ffi.Pointer<ffi.IntPtr> head, int length, int value) {
+      if (length == 0) {
+        head.store(value);
+        return;
+      }
+      ffi.Pointer<ffi.IntPtr> next = ffi.allocate<ffi.IntPtr>();
+      head.store(next.address);
+      createChain(next, length - 1, value);
+    }
+
+    int getChainValue(ffi.Pointer<ffi.IntPtr> head, int length) {
+      if (length == 0) {
+        return head.load();
+      }
+      ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+      return getChainValue(next, length - 1);
+    }
+
+    void freeChain(ffi.Pointer<ffi.IntPtr> head, int length) {
+      ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+      head.free();
+      if (length == 0) {
+        return;
+      }
+      freeChain(next, length - 1);
+    }
+
+    int length = 10;
+    ffi.Pointer<ffi.IntPtr> head = ffi.allocate();
+    createChain(head, length, 512);
+    int tailValue = getChainValue(head, length);
+    print('tailValue: ${tailValue}');
+    freeChain(head, length);
+  }
+
+  print("end main");
+}
diff --git a/samples/ffi/sample_ffi_dynamic_library.dart b/samples/ffi/sample_ffi_dynamic_library.dart
new file mode 100644
index 0000000..cf83400
--- /dev/null
+++ b/samples/ffi/sample_ffi_dynamic_library.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.
+
+import 'dart:ffi' as ffi;
+
+typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
+
+typedef DoubleUnOp = double Function(double);
+
+main(List<String> arguments) {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  print(l);
+  print(l.runtimeType);
+
+  var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
+  print(timesFour);
+  print(timesFour.runtimeType);
+
+  print(timesFour(3.0));
+}
diff --git a/samples/ffi/sample_ffi_functions.dart b/samples/ffi/sample_ffi_functions.dart
new file mode 100644
index 0000000..62b5718
--- /dev/null
+++ b/samples/ffi/sample_ffi_functions.dart
@@ -0,0 +1,267 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi' as ffi;
+
+typedef NativeUnaryOp = ffi.Int32 Function(ffi.Int32);
+typedef NativeBinaryOp = ffi.Int32 Function(ffi.Int32, ffi.Int32);
+typedef UnaryOp = int Function(int);
+typedef BinaryOp = int Function(int, int);
+typedef GenericBinaryOp<T> = int Function(int, T);
+typedef NativeQuadOpSigned = ffi.Int64 Function(
+    ffi.Int64, ffi.Int32, ffi.Int16, ffi.Int8);
+typedef NativeQuadOpUnsigned = ffi.Uint64 Function(
+    ffi.Uint64, ffi.Uint32, ffi.Uint16, ffi.Uint8);
+typedef NativeFunc4 = ffi.IntPtr Function(ffi.IntPtr);
+typedef NativeDoubleUnaryOp = ffi.Double Function(ffi.Double);
+typedef NativeFloatUnaryOp = ffi.Float Function(ffi.Float);
+typedef NativeOctenaryOp = ffi.IntPtr Function(
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr);
+typedef NativeDoubleOctenaryOp = ffi.Double Function(
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double);
+typedef NativeVigesimalOp = ffi.Double Function(
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double);
+typedef Int64PointerUnOp = ffi.Pointer<ffi.Int64> Function(
+    ffi.Pointer<ffi.Int64>);
+typedef QuadOp = int Function(int, int, int, int);
+typedef DoubleUnaryOp = double Function(double);
+typedef OctenaryOp = int Function(
+    int, int, int, int, int, int, int, int, int, int);
+typedef DoubleOctenaryOp = double Function(double, double, double, double,
+    double, double, double, double, double, double);
+typedef VigesimalOp = double Function(
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double);
+
+main(List<String> arguments) {
+  print('start main');
+
+  ffi.DynamicLibrary ffiTestFunctions =
+      ffi.DynamicLibrary.open("ffi_test_functions");
+
+  {
+    // int32 bin op
+    BinaryOp sumPlus42 =
+        ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
+
+    var result = sumPlus42(3, 17);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // various size arguments
+    QuadOp intComputation = ffiTestFunctions
+        .lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
+    var result = intComputation(125, 250, 500, 1000);
+    print(result);
+    print(result.runtimeType);
+
+    var mint = 0x7FFFFFFFFFFFFFFF; // 2 ^ 63 - 1
+    result = intComputation(1, 1, 0, mint);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // unsigned int parameters
+    QuadOp uintComputation = ffiTestFunctions
+        .lookupFunction<NativeQuadOpUnsigned, QuadOp>("UintComputation");
+    var result = uintComputation(0xFF, 0xFFFF, 0xFFFFFFFF, -1);
+    result = uintComputation(1, 1, 0, -1);
+    print(result);
+    print(result.runtimeType);
+    print(-0xFF + 0xFFFF - 0xFFFFFFFF);
+  }
+
+  {
+    // architecture size argument
+    ffi.Pointer<ffi.NativeFunction<NativeFunc4>> p =
+        ffiTestFunctions.lookup("Times3");
+    UnaryOp f6 = p.asFunction();
+    var result = f6(1337);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // function with double
+    DoubleUnaryOp times1_337Double = ffiTestFunctions
+        .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
+    var result = times1_337Double(2.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // function with float
+    DoubleUnaryOp times1_337Float = ffiTestFunctions
+        .lookupFunction<NativeFloatUnaryOp, DoubleUnaryOp>("Times1_337Float");
+    var result = times1_337Float(1000.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // function with many arguments: arguments get passed in registers and stack
+    OctenaryOp sumManyInts = ffiTestFunctions
+        .lookupFunction<NativeOctenaryOp, OctenaryOp>("SumManyInts");
+    var result = sumManyInts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // function with many double arguments
+    DoubleOctenaryOp sumManyDoubles = ffiTestFunctions.lookupFunction<
+        NativeDoubleOctenaryOp, DoubleOctenaryOp>("SumManyDoubles");
+    var result =
+        sumManyDoubles(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // function with many arguments, ints and doubles mixed
+    VigesimalOp sumManyNumbers = ffiTestFunctions
+        .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+    var result = sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11,
+        12.0, 13, 14.0, 15, 16.0, 17, 18.0, 19, 20.0);
+    print(result);
+    print(result.runtimeType);
+  }
+
+  {
+    // pass an array / pointer as argument
+    Int64PointerUnOp assign1337Index1 = ffiTestFunctions
+        .lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
+    ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+    p2.store(42);
+    p2.elementAt(1).store(1000);
+    print(p2.elementAt(1).address.toRadixString(16));
+    print(p2.elementAt(1).load<int>());
+    ffi.Pointer<ffi.Int64> result = assign1337Index1(p2);
+    print(p2.elementAt(1).load<int>());
+    print(assign1337Index1);
+    print(assign1337Index1.runtimeType);
+    print(result);
+    print(result.runtimeType);
+    print(result.address.toRadixString(16));
+    print(result.load<int>());
+  }
+
+  {
+    // passing in null for an int argument throws a null pointer exception
+    BinaryOp sumPlus42 =
+        ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
+
+    int x = null;
+    try {
+      sumPlus42(43, x);
+    } on ArgumentError {
+      print('Expected exception on passing null for int');
+    }
+  }
+
+  {
+    // passing in null for a double argument throws a null pointer exception
+    DoubleUnaryOp times1_337Double = ffiTestFunctions
+        .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
+
+    double x = null;
+    try {
+      times1_337Double(x);
+    } on ArgumentError {
+      print('Expected exception on passing null for double');
+    }
+  }
+
+  {
+    // passing in null for an int argument throws a null pointer exception
+    VigesimalOp sumManyNumbers = ffiTestFunctions
+        .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+
+    int x = null;
+    try {
+      sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13,
+          14.0, 15, 16.0, 17, 18.0, x, 20.0);
+    } on ArgumentError {
+      print('Expected exception on passing null for int');
+    }
+  }
+
+  {
+    // passing in null for a pointer argument results in a nullptr in c
+    Int64PointerUnOp nullableInt64ElemAt1 =
+        ffiTestFunctions.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>(
+            "NullableInt64ElemAt1");
+
+    ffi.Pointer<ffi.Int64> result = nullableInt64ElemAt1(null);
+    print(result);
+    print(result.runtimeType);
+
+    ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+    result = nullableInt64ElemAt1(p2);
+    print(result);
+    print(result.runtimeType);
+    p2.free();
+  }
+
+  print("end main");
+}
diff --git a/samples/ffi/sample_ffi_functions_callbacks.dart b/samples/ffi/sample_ffi_functions_callbacks.dart
new file mode 100644
index 0000000..ddd6840
--- /dev/null
+++ b/samples/ffi/sample_ffi_functions_callbacks.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi' as ffi;
+
+import 'coordinate.dart';
+
+typedef NativeCoordinateOp = Coordinate Function(Coordinate);
+
+typedef CoordinateTrice = Coordinate Function(
+    ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>>, Coordinate);
+
+typedef BinaryOp = int Function(int, int);
+typedef NativeIntptrBinOp = ffi.IntPtr Function(ffi.IntPtr, ffi.IntPtr);
+typedef NativeIntptrBinOpLookup
+    = ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>> Function();
+
+typedef NativeApplyTo42And74Type = ffi.IntPtr Function(
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>>);
+
+typedef ApplyTo42And74Type = int Function(
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>>);
+
+int myPlus(int a, int b) {
+  print("myPlus");
+  print(a);
+  print(b);
+  return a + b;
+}
+
+main(List<String> arguments) {
+  print('start main');
+
+  ffi.DynamicLibrary ffiTestFunctions =
+      ffi.DynamicLibrary.open("ffi_test_functions");
+
+  {
+    // pass a c pointer to a c function as an argument to a c function
+    ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>>
+        transposeCoordinatePointer =
+        ffiTestFunctions.lookup("TransposeCoordinate");
+    ffi.Pointer<ffi.NativeFunction<CoordinateTrice>> p2 =
+        ffiTestFunctions.lookup("CoordinateUnOpTrice");
+    CoordinateTrice coordinateUnOpTrice = p2.asFunction();
+    Coordinate c1 = Coordinate(10.0, 20.0, null);
+    c1.next = c1;
+    Coordinate result = coordinateUnOpTrice(transposeCoordinatePointer, c1);
+    print(result.runtimeType);
+    print(result.x);
+    print(result.y);
+  }
+
+  {
+    // return a c pointer to a c function from a c function
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOpLookup>> p14 =
+        ffiTestFunctions.lookup("IntptrAdditionClosure");
+    NativeIntptrBinOpLookup intptrAdditionClosure = p14.asFunction();
+
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>> intptrAdditionPointer =
+        intptrAdditionClosure();
+    BinaryOp intptrAddition = intptrAdditionPointer.asFunction();
+    print(intptrAddition(10, 27));
+  }
+
+  {
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>> pointer =
+        ffi.fromFunction(myPlus);
+    print(pointer);
+
+    ffi.Pointer<ffi.NativeFunction<NativeApplyTo42And74Type>> p17 =
+        ffiTestFunctions.lookup("ApplyTo42And74");
+    ApplyTo42And74Type applyTo42And74 = p17.asFunction();
+
+    // int result = applyTo42And74(pointer);
+    // print(result);
+  }
+
+  print("end main");
+}
diff --git a/samples/ffi/sample_ffi_functions_structs.dart b/samples/ffi/sample_ffi_functions_structs.dart
new file mode 100644
index 0000000..ba076e0
--- /dev/null
+++ b/samples/ffi/sample_ffi_functions_structs.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:ffi' as ffi;
+
+import 'coordinate.dart';
+
+typedef NativeCoordinateOp = Coordinate Function(Coordinate);
+
+main(List<String> arguments) {
+  print('start main');
+
+  ffi.DynamicLibrary ffiTestFunctions =
+      ffi.DynamicLibrary.open("ffi_test_functions");
+
+  {
+    // pass a struct to a c function and get a struct as return value
+    ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>> p1 =
+        ffiTestFunctions.lookup("TransposeCoordinate");
+    NativeCoordinateOp f1 = p1.asFunction();
+
+    Coordinate c1 = Coordinate(10.0, 20.0, null);
+    Coordinate c2 = Coordinate(42.0, 84.0, c1);
+    c1.next = c2;
+
+    Coordinate result = f1(c1);
+
+    print(c1.x);
+    print(c1.y);
+
+    print(result.runtimeType);
+
+    print(result.x);
+    print(result.y);
+  }
+
+  {
+    // pass an array of structs to a c funtion
+    ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>> p1 =
+        ffiTestFunctions.lookup("CoordinateElemAt1");
+    NativeCoordinateOp f1 = p1.asFunction();
+
+    Coordinate c1 = Coordinate.allocate(count: 3);
+    Coordinate c2 = c1.elementAt(1);
+    Coordinate c3 = c1.elementAt(2);
+    c1.x = 10.0;
+    c1.y = 10.0;
+    c1.next = c3;
+    c2.x = 20.0;
+    c2.y = 20.0;
+    c2.next = c1;
+    c3.x = 30.0;
+    c3.y = 30.0;
+    c3.next = c2;
+
+    Coordinate result = f1(c1);
+
+    print(result.x);
+    print(result.y);
+  }
+
+  print("end main");
+}
diff --git a/samples/ffi/sample_ffi_structs.dart b/samples/ffi/sample_ffi_structs.dart
new file mode 100644
index 0000000..fd757e5
--- /dev/null
+++ b/samples/ffi/sample_ffi_structs.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.
+
+import 'dart:ffi' as ffi;
+
+import 'coordinate.dart';
+
+main(List<String> arguments) {
+  print('start main');
+
+  {
+    // allocates each coordinate separately in c memory
+    Coordinate c1 = Coordinate(10.0, 10.0, null);
+    Coordinate c2 = Coordinate(20.0, 20.0, c1);
+    Coordinate c3 = Coordinate(30.0, 30.0, c2);
+    c1.next = c3;
+
+    Coordinate currentCoordinate = c1;
+    for (var i in [0, 1, 2, 3, 4]) {
+      currentCoordinate = currentCoordinate.next;
+      print("${currentCoordinate.x}; ${currentCoordinate.y}");
+    }
+
+    c1.free();
+    c2.free();
+    c3.free();
+  }
+
+  {
+    // allocates coordinates consecutively in c memory
+    Coordinate c1 = Coordinate.allocate(count: 3);
+    Coordinate c2 = c1.elementAt(1);
+    Coordinate c3 = c1.elementAt(2);
+    c1.x = 10.0;
+    c1.y = 10.0;
+    c1.next = c3;
+    c2.x = 20.0;
+    c2.y = 20.0;
+    c2.next = c1;
+    c3.x = 30.0;
+    c3.y = 30.0;
+    c3.next = c2;
+
+    Coordinate currentCoordinate = c1;
+    for (var i in [0, 1, 2, 3, 4]) {
+      currentCoordinate = currentCoordinate.next;
+      print("${currentCoordinate.x}; ${currentCoordinate.y}");
+    }
+
+    c1.free();
+  }
+
+  {
+    Coordinate c = Coordinate(10, 10, null);
+    print(c is Coordinate);
+    print(c is ffi.Pointer<ffi.Void>);
+    print(c is ffi.Pointer);
+    c.free();
+  }
+
+  print("end main");
+}
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index ec27270..3f48b0a 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -183,6 +183,7 @@
   "convert",
   "core",
   "developer",
+  "ffi",
   "html",
   "_http",
   "indexed_db",
@@ -856,14 +857,20 @@
   ]
 }
 
-# This rule copies the dartdoc_options.yaml file.
-copy("copy_dartdoc_options") {
+# This rule generates a custom dartdoc_options.yaml file.
+action("write_dartdoc_options") {
   visibility = [ ":create_common_sdk" ]
-  sources = [
-    "../dartdoc_options.yaml",
+  inputs = [
+    "../.git/logs/HEAD",
   ]
+  output = "$root_out_dir/dart-sdk/dartdoc_options.yaml"
   outputs = [
-    "$root_out_dir/dart-sdk/dartdoc_options.yaml",
+    output,
+  ]
+  script = "../tools/write_dartdoc_options_file.py"
+  args = [
+    "--output",
+    rebase_path(output),
   ]
 }
 
@@ -886,13 +893,13 @@
     ":copy_api_readme",
     ":copy_dart",
     ":copy_dartdoc_files",
-    ":copy_dartdoc_options",
     ":copy_headers",
     ":copy_libraries_dart",
     ":copy_license",
     ":copy_libraries_specification",
     ":copy_readme",
     ":copy_vm_dill_files",
+    ":write_dartdoc_options",
     ":write_revision_file",
     ":write_version_file",
   ]
diff --git a/sdk/lib/_http/http.dart b/sdk/lib/_http/http.dart
index 393045f..f1e72be 100644
--- a/sdk/lib/_http/http.dart
+++ b/sdk/lib/_http/http.dart
@@ -16,7 +16,7 @@
         UnmodifiableMapView;
 import 'dart:convert';
 import 'dart:developer' hide log;
-import 'dart:_internal' show Since;
+import 'dart:_internal' show Since, HttpStatus;
 import 'dart:math';
 import 'dart:io';
 import 'dart:typed_data';
@@ -32,184 +32,6 @@
 part 'websocket_impl.dart';
 
 /**
- * HTTP status codes.
- */
-abstract class HttpStatus {
-  static const int continue_ = 100;
-  static const int switchingProtocols = 101;
-  @Since("2.1")
-  static const int processing = 102;
-  static const int ok = 200;
-  static const int created = 201;
-  static const int accepted = 202;
-  static const int nonAuthoritativeInformation = 203;
-  static const int noContent = 204;
-  static const int resetContent = 205;
-  static const int partialContent = 206;
-  @Since("2.1")
-  static const int multiStatus = 207;
-  @Since("2.1")
-  static const int alreadyReported = 208;
-  @Since("2.1")
-  static const int imUsed = 226;
-  static const int multipleChoices = 300;
-  static const int movedPermanently = 301;
-  static const int found = 302;
-  static const int movedTemporarily = 302; // Common alias for found.
-  static const int seeOther = 303;
-  static const int notModified = 304;
-  static const int useProxy = 305;
-  static const int temporaryRedirect = 307;
-  @Since("2.1")
-  static const int permanentRedirect = 308;
-  static const int badRequest = 400;
-  static const int unauthorized = 401;
-  static const int paymentRequired = 402;
-  static const int forbidden = 403;
-  static const int notFound = 404;
-  static const int methodNotAllowed = 405;
-  static const int notAcceptable = 406;
-  static const int proxyAuthenticationRequired = 407;
-  static const int requestTimeout = 408;
-  static const int conflict = 409;
-  static const int gone = 410;
-  static const int lengthRequired = 411;
-  static const int preconditionFailed = 412;
-  static const int requestEntityTooLarge = 413;
-  static const int requestUriTooLong = 414;
-  static const int unsupportedMediaType = 415;
-  static const int requestedRangeNotSatisfiable = 416;
-  static const int expectationFailed = 417;
-  @Since("2.1")
-  static const int misdirectedRequest = 421;
-  @Since("2.1")
-  static const int unprocessableEntity = 422;
-  @Since("2.1")
-  static const int locked = 423;
-  @Since("2.1")
-  static const int failedDependency = 424;
-  static const int upgradeRequired = 426;
-  @Since("2.1")
-  static const int preconditionRequired = 428;
-  @Since("2.1")
-  static const int tooManyRequests = 429;
-  @Since("2.1")
-  static const int requestHeaderFieldsTooLarge = 431;
-  @Since("2.1")
-  static const int connectionClosedWithoutResponse = 444;
-  @Since("2.1")
-  static const int unavailableForLegalReasons = 451;
-  @Since("2.1")
-  static const int clientClosedRequest = 499;
-  static const int internalServerError = 500;
-  static const int notImplemented = 501;
-  static const int badGateway = 502;
-  static const int serviceUnavailable = 503;
-  static const int gatewayTimeout = 504;
-  static const int httpVersionNotSupported = 505;
-  @Since("2.1")
-  static const int variantAlsoNegotiates = 506;
-  @Since("2.1")
-  static const int insufficientStorage = 507;
-  @Since("2.1")
-  static const int loopDetected = 508;
-  @Since("2.1")
-  static const int notExtended = 510;
-  @Since("2.1")
-  static const int networkAuthenticationRequired = 511;
-  // Client generated status code.
-  static const int networkConnectTimeoutError = 599;
-
-  @Deprecated("Use continue_ instead")
-  static const int CONTINUE = continue_;
-  @Deprecated("Use switchingProtocols instead")
-  static const int SWITCHING_PROTOCOLS = switchingProtocols;
-  @Deprecated("Use ok instead")
-  static const int OK = ok;
-  @Deprecated("Use created instead")
-  static const int CREATED = created;
-  @Deprecated("Use accepted instead")
-  static const int ACCEPTED = accepted;
-  @Deprecated("Use nonAuthoritativeInformation instead")
-  static const int NON_AUTHORITATIVE_INFORMATION = nonAuthoritativeInformation;
-  @Deprecated("Use noContent instead")
-  static const int NO_CONTENT = noContent;
-  @Deprecated("Use resetContent instead")
-  static const int RESET_CONTENT = resetContent;
-  @Deprecated("Use partialContent instead")
-  static const int PARTIAL_CONTENT = partialContent;
-  @Deprecated("Use multipleChoices instead")
-  static const int MULTIPLE_CHOICES = multipleChoices;
-  @Deprecated("Use movedPermanently instead")
-  static const int MOVED_PERMANENTLY = movedPermanently;
-  @Deprecated("Use found instead")
-  static const int FOUND = found;
-  @Deprecated("Use movedTemporarily instead")
-  static const int MOVED_TEMPORARILY = movedTemporarily;
-  @Deprecated("Use seeOther instead")
-  static const int SEE_OTHER = seeOther;
-  @Deprecated("Use notModified instead")
-  static const int NOT_MODIFIED = notModified;
-  @Deprecated("Use useProxy instead")
-  static const int USE_PROXY = useProxy;
-  @Deprecated("Use temporaryRedirect instead")
-  static const int TEMPORARY_REDIRECT = temporaryRedirect;
-  @Deprecated("Use badRequest instead")
-  static const int BAD_REQUEST = badRequest;
-  @Deprecated("Use unauthorized instead")
-  static const int UNAUTHORIZED = unauthorized;
-  @Deprecated("Use paymentRequired instead")
-  static const int PAYMENT_REQUIRED = paymentRequired;
-  @Deprecated("Use forbidden instead")
-  static const int FORBIDDEN = forbidden;
-  @Deprecated("Use notFound instead")
-  static const int NOT_FOUND = notFound;
-  @Deprecated("Use methodNotAllowed instead")
-  static const int METHOD_NOT_ALLOWED = methodNotAllowed;
-  @Deprecated("Use notAcceptable instead")
-  static const int NOT_ACCEPTABLE = notAcceptable;
-  @Deprecated("Use proxyAuthenticationRequired instead")
-  static const int PROXY_AUTHENTICATION_REQUIRED = proxyAuthenticationRequired;
-  @Deprecated("Use requestTimeout instead")
-  static const int REQUEST_TIMEOUT = requestTimeout;
-  @Deprecated("Use conflict instead")
-  static const int CONFLICT = conflict;
-  @Deprecated("Use gone instead")
-  static const int GONE = gone;
-  @Deprecated("Use lengthRequired instead")
-  static const int LENGTH_REQUIRED = lengthRequired;
-  @Deprecated("Use preconditionFailed instead")
-  static const int PRECONDITION_FAILED = preconditionFailed;
-  @Deprecated("Use requestEntityTooLarge instead")
-  static const int REQUEST_ENTITY_TOO_LARGE = requestEntityTooLarge;
-  @Deprecated("Use requestUriTooLong instead")
-  static const int REQUEST_URI_TOO_LONG = requestUriTooLong;
-  @Deprecated("Use unsupportedMediaType instead")
-  static const int UNSUPPORTED_MEDIA_TYPE = unsupportedMediaType;
-  @Deprecated("Use requestedRangeNotSatisfiable instead")
-  static const int REQUESTED_RANGE_NOT_SATISFIABLE =
-      requestedRangeNotSatisfiable;
-  @Deprecated("Use expectationFailed instead")
-  static const int EXPECTATION_FAILED = expectationFailed;
-  @Deprecated("Use upgradeRequired instead")
-  static const int UPGRADE_REQUIRED = upgradeRequired;
-  @Deprecated("Use internalServerError instead")
-  static const int INTERNAL_SERVER_ERROR = internalServerError;
-  @Deprecated("Use notImplemented instead")
-  static const int NOT_IMPLEMENTED = notImplemented;
-  @Deprecated("Use badGateway instead")
-  static const int BAD_GATEWAY = badGateway;
-  @Deprecated("Use serviceUnavailable instead")
-  static const int SERVICE_UNAVAILABLE = serviceUnavailable;
-  @Deprecated("Use gatewayTimeout instead")
-  static const int GATEWAY_TIMEOUT = gatewayTimeout;
-  @Deprecated("Use httpVersionNotSupported instead")
-  static const int HTTP_VERSION_NOT_SUPPORTED = httpVersionNotSupported;
-  @Deprecated("Use networkConnectTimeoutError instead")
-  static const int NETWORK_CONNECT_TIMEOUT_ERROR = networkConnectTimeoutError;
-}
-
-/**
  * A server that delivers content, such as web pages, using the HTTP protocol.
  *
  * The HttpServer is a [Stream] that provides [HttpRequest] objects. Each
diff --git a/sdk/lib/_http/http_impl.dart b/sdk/lib/_http/http_impl.dart
index 80a5589..f0e365d 100644
--- a/sdk/lib/_http/http_impl.dart
+++ b/sdk/lib/_http/http_impl.dart
@@ -531,24 +531,16 @@
 
   _StreamSinkImpl(this._target);
 
-  void _reportClosedSink() {
-    stderr.writeln("StreamSink is closed and adding to it is an error.");
-    stderr.writeln("  See http://dartbug.com/29554.");
-    stderr.writeln(StackTrace.current);
-  }
-
   void add(T data) {
     if (_isClosed) {
-      _reportClosedSink();
-      return;
+      throw StateError("StreamSink is closed");
     }
     _controller.add(data);
   }
 
   void addError(error, [StackTrace stackTrace]) {
     if (_isClosed) {
-      _reportClosedSink();
-      return;
+      throw StateError("StreamSink is closed");
     }
     _controller.addError(error, stackTrace);
   }
@@ -2926,6 +2918,14 @@
     return _socket.setOption(option, enabled);
   }
 
+  Uint8List getRawOption(RawSocketOption option) {
+    return _socket.getRawOption(option);
+  }
+
+  void setRawOption(RawSocketOption option) {
+    _socket.setRawOption(option);
+  }
+
   Map _toJSON(bool ref) {
     return (_socket as dynamic)._toJSON(ref);
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 40e7c73..b8619d1 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -501,6 +501,14 @@
 }
 
 @patch
+class RawSocketOption {
+  @patch
+  static int _getOptionValue(int key) {
+    throw UnsupportedError("RawSocketOption._getOptionValue");
+  }
+}
+
+@patch
 class SecurityContext {
   @patch
   factory SecurityContext({bool withTrustedRoots: false}) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 9457101..0befba60 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -377,167 +377,6 @@
   }
 }
 
-class ReflectionInfo {
-  static const int REQUIRED_PARAMETERS_INFO = 0;
-  static const int OPTIONAL_PARAMETERS_INFO = 1;
-  static const int FUNCTION_TYPE_INDEX = 2;
-  static const int FIRST_DEFAULT_ARGUMENT = 3;
-
-  /// A JavaScript function object.
-  final jsFunction;
-
-  /// Raw reflection information.
-  final List data;
-
-  /// Is this a getter or a setter.
-  final bool isAccessor;
-
-  /// Number of required parameters.
-  final int requiredParameterCount;
-
-  /// Number of optional parameters.
-  final int optionalParameterCount;
-
-  /// Are optional parameters named.
-  final bool areOptionalParametersNamed;
-
-  /// Either an index to the function type in the embedded `metadata` global or
-  /// a JavaScript function object which can compute such a type (presumably
-  /// due to free type variables).
-  final functionType;
-
-  List cachedSortedIndices;
-
-  ReflectionInfo.internal(
-      this.jsFunction,
-      this.data,
-      this.isAccessor,
-      this.requiredParameterCount,
-      this.optionalParameterCount,
-      this.areOptionalParametersNamed,
-      this.functionType);
-
-  factory ReflectionInfo(jsFunction) {
-    List data = JS('JSExtendableArray|Null', r'#.$reflectionInfo', jsFunction);
-    if (data == null) return null;
-    data = JSArray.markFixedList(data);
-
-    int requiredParametersInfo =
-        JS('int', '#[#]', data, REQUIRED_PARAMETERS_INFO);
-    int requiredParameterCount = JS('int', '# >> 2', requiredParametersInfo);
-    bool isAccessor = (requiredParametersInfo & 2) == 2;
-
-    int optionalParametersInfo =
-        JS('int', '#[#]', data, OPTIONAL_PARAMETERS_INFO);
-    int optionalParameterCount = JS('int', '# >> 1', optionalParametersInfo);
-    bool areOptionalParametersNamed = (optionalParametersInfo & 1) == 1;
-
-    var functionType = JS('', '#[#]', data, FUNCTION_TYPE_INDEX);
-    return new ReflectionInfo.internal(
-        jsFunction,
-        data,
-        isAccessor,
-        requiredParameterCount,
-        optionalParameterCount,
-        areOptionalParametersNamed,
-        functionType);
-  }
-
-  String parameterName(int parameter) {
-    int metadataIndex;
-    if (JS_GET_FLAG('MUST_RETAIN_METADATA')) {
-      metadataIndex = JS('int', '#[2 * # + # + #]', data, parameter,
-          optionalParameterCount, FIRST_DEFAULT_ARGUMENT);
-    } else {
-      metadataIndex = JS('int', '#[# + # + #]', data, parameter,
-          optionalParameterCount, FIRST_DEFAULT_ARGUMENT);
-    }
-    var name = getMetadata(metadataIndex);
-    return JS('String', '#', name);
-  }
-
-  List<int> parameterMetadataAnnotations(int parameter) {
-    if (!JS_GET_FLAG('MUST_RETAIN_METADATA')) {
-      throw new StateError('metadata has not been preserved');
-    } else {
-      return JS('', '#[2 * # + # + # + 1]', data, parameter,
-          optionalParameterCount, FIRST_DEFAULT_ARGUMENT);
-    }
-  }
-
-  int defaultValue(int parameter) {
-    if (parameter < requiredParameterCount) return null;
-    return JS('int', '#[# + # - #]', data, FIRST_DEFAULT_ARGUMENT, parameter,
-        requiredParameterCount);
-  }
-
-  /// Returns the default value of the [parameter]th entry of the list of
-  /// parameters sorted by name.
-  int defaultValueInOrder(int parameter) {
-    if (parameter < requiredParameterCount) return null;
-
-    if (!areOptionalParametersNamed || optionalParameterCount == 1) {
-      return defaultValue(parameter);
-    }
-
-    int index = sortedIndex(parameter - requiredParameterCount);
-    return defaultValue(index);
-  }
-
-  /// Returns the default value of the [parameter]th entry of the list of
-  /// parameters sorted by name.
-  String parameterNameInOrder(int parameter) {
-    if (parameter < requiredParameterCount) return null;
-
-    if (!areOptionalParametersNamed || optionalParameterCount == 1) {
-      return parameterName(parameter);
-    }
-
-    int index = sortedIndex(parameter - requiredParameterCount);
-    return parameterName(index);
-  }
-
-  /// Computes the index of the parameter in the list of named parameters sorted
-  /// by their name.
-  int sortedIndex(int unsortedIndex) {
-    if (cachedSortedIndices == null) {
-      // TODO(karlklose): cache this between [ReflectionInfo] instances or cache
-      // [ReflectionInfo] instances by [jsFunction].
-      cachedSortedIndices = new List(optionalParameterCount);
-      Map<String, int> positions = <String, int>{};
-      for (int i = 0; i < optionalParameterCount; i++) {
-        int index = requiredParameterCount + i;
-        positions[parameterName(index)] = index;
-      }
-      int index = 0;
-      (positions.keys.toList()..sort()).forEach((String name) {
-        cachedSortedIndices[index++] = positions[name];
-      });
-    }
-    return cachedSortedIndices[unsortedIndex];
-  }
-
-  @NoInline()
-  computeFunctionRti(jsConstructor) {
-    if (JS('bool', 'typeof # == "number"', functionType)) {
-      return getType(functionType);
-    } else if (JS('bool', 'typeof # == "function"', functionType)) {
-      if (jsConstructor != null) {
-        var fakeInstance = JS('', 'new #()', jsConstructor);
-        setRuntimeTypeInfo(
-            fakeInstance, JS('JSExtendableArray', '#["<>"]', fakeInstance));
-        return JS('=Object|Null', r'#.apply({$receiver:#})', functionType,
-            fakeInstance);
-      }
-      return functionType;
-    } else {
-      throw new RuntimeError('Unexpected function type');
-    }
-  }
-
-  String get reflectionName => JS('String', r'#.$reflectionName', jsFunction);
-}
-
 class Primitives {
   static int objectHashCode(object) {
     int hash = JS('int|Null', r'#.$identityHash', object);
@@ -1397,22 +1236,22 @@
 }
 
 @NoInline()
-checkNum(value) {
+num checkNum(value) {
   if (value is! num) throw argumentErrorValue(value);
   return value;
 }
 
-checkInt(value) {
+int checkInt(value) {
   if (value is! int) throw argumentErrorValue(value);
   return value;
 }
 
-checkBool(value) {
+bool checkBool(value) {
   if (value is! bool) throw argumentErrorValue(value);
   return value;
 }
 
-checkString(value) {
+String checkString(value) {
   if (value is! String) throw argumentErrorValue(value);
   return value;
 }
@@ -2196,14 +2035,7 @@
     // This variable holds either an index into the types-table, or a function
     // that can compute a function-rti. (The latter is necessary if the type
     // is dependent on generic arguments).
-    var functionType;
-    if (reflectionInfo is List) {
-      JS('', '#.\$reflectionInfo = #', function, reflectionInfo);
-      ReflectionInfo info = new ReflectionInfo(function);
-      functionType = info.functionType;
-    } else {
-      functionType = reflectionInfo;
-    }
+    var functionType = reflectionInfo;
 
     // function tmp() {};
     // tmp.prototype = BC.prototype;
@@ -3353,7 +3185,19 @@
 String _computeCspNonce() {
   var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
   if (currentScript == null) return null;
-  return JS('String', 'String(#.nonce)', currentScript);
+  String nonce = JS('String|Null', '#.nonce', currentScript);
+  return (nonce != null && nonce != '')
+      ? nonce
+      : JS('String|Null', '#.getAttribute("nonce")', currentScript);
+}
+
+/// The 'crossOrigin' value on the current script used for CORS, if any.
+String _crossOrigin = _computeCrossOrigin();
+
+String _computeCrossOrigin() {
+  var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
+  if (currentScript == null) return null;
+  return JS('String|Null', '#.crossOrigin', currentScript);
 }
 
 /// Returns true if we are currently in a worker context.
@@ -3500,6 +3344,10 @@
     JS('', '#.src = #', script, uri);
     if (_cspNonce != null && _cspNonce != '') {
       JS('', '#.nonce = #', script, _cspNonce);
+      JS('', '#.setAttribute("nonce", #)', script, _cspNonce);
+    }
+    if (_crossOrigin != null && _crossOrigin != '') {
+      JS('', '#.crossOrigin = #', script, _crossOrigin);
     }
     JS('', '#.addEventListener("load", #, false)', script, jsSuccess);
     JS('', '#.addEventListener("error", #, false)', script, jsFailure);
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index 9a6ef99..bdef059 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -60,6 +60,7 @@
   // TODO(ahe): This is a poor hashCode as it collides with its name.
   int get hashCode => _hashCode ??= _typeName.hashCode;
 
+  @pragma('dart2js:noInline')
   bool operator ==(other) {
     return (other is TypeImpl) && _typeName == other._typeName;
   }
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index 5e1c046..58a9e90 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -63,6 +63,11 @@
       categories: "Client,Server,Embedded",
       maturity: Maturity.UNSTABLE,
       dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
+  "ffi": const LibraryInfo("ffi/ffi.dart",
+      categories: "Server",
+      // TODO(dacoharkes): Update maturity when we release dart:ffi.
+      // https://github.com/dart-lang/sdk/issues/34452
+      maturity: Maturity.EXPERIMENTAL),
   "html": const LibraryInfo("html/dart2js/html_dart2js.dart",
       categories: "Client",
       maturity: Maturity.WEB_STABLE,
diff --git a/sdk/lib/async/stream_transformers.dart b/sdk/lib/async/stream_transformers.dart
index 9a4b1dc..b656dea 100644
--- a/sdk/lib/async/stream_transformers.dart
+++ b/sdk/lib/async/stream_transformers.dart
@@ -220,17 +220,9 @@
 
   bool get _isClosed => _sink == null;
 
-  _reportClosedSink() {
-    // TODO(29554): throw a StateError, and don't just report the problem.
-    Zone.root
-      ..print("Sink is closed and adding to it is an error.")
-      ..print("  See http://dartbug.com/29554.")
-      ..print(StackTrace.current.toString());
-  }
-
   void add(S data) {
     if (_isClosed) {
-      _reportClosedSink();
+      throw StateError("Sink is closed");
     }
     if (_handleData != null) {
       _handleData(data, _sink);
@@ -241,7 +233,7 @@
 
   void addError(Object error, [StackTrace stackTrace]) {
     if (_isClosed) {
-      _reportClosedSink();
+      throw StateError("Sink is closed");
     }
     if (_handleError != null) {
       _handleError(error, stackTrace, _sink);
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 4e78c2a..66de4e5 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -607,7 +607,7 @@
    * Returns an [Iterable] that iterates over the objects in the range
    * [start] inclusive to [end] exclusive.
    *
-   * The provide range, given by [start] and [end], must be valid at the time
+   * The provided range, given by [start] and [end], must be valid at the time
    * of the call.
    *
    * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
@@ -636,7 +636,7 @@
    *     list1.setRange(1, 3, list2, 3);
    *     list1.join(', '); // '1, 8, 9, 4'
    *
-   * The provide range, given by [start] and [end], must be valid.
+   * The provided range, given by [start] and [end], must be valid.
    * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
    * `len` is this list's `length`. The range starts at `start` and has length
    * `end - start`. An empty range (with `end == start`) is valid.
@@ -656,7 +656,7 @@
   /**
    * Removes the objects in the range [start] inclusive to [end] exclusive.
    *
-   * The provide range, given by [start] and [end], must be valid.
+   * The provided range, given by [start] and [end], must be valid.
    * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
    * `len` is this list's `length`. The range starts at `start` and has length
    * `end - start`. An empty range (with `end == start`) is valid.
@@ -670,7 +670,7 @@
    * Sets the objects in the range [start] inclusive to [end] exclusive
    * to the given [fillValue].
    *
-   * The provide range, given by [start] and [end], must be valid.
+   * The provided range, given by [start] and [end], must be valid.
    * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
    * `len` is this list's `length`. The range starts at `start` and has length
    * `end - start`. An empty range (with `end == start`) is valid.
@@ -685,7 +685,7 @@
    *     list.replaceRange(1, 4, [6, 7]);
    *     list.join(', '); // '1, 6, 7, 5'
    *
-   * The provide range, given by [start] and [end], must be valid.
+   * The provided range, given by [start] and [end], must be valid.
    * A range from [start] to [end] is valid if `0 <= start <= end <= len`, where
    * `len` is this list's `length`. The range starts at `start` and has length
    * `end - start`. An empty range (with `end == start`) is valid.
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index 42b606a..0c2f586 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -358,7 +358,7 @@
    *
    * The values are iterated in the order of their corresponding keys.
    * This means that iterating [keys] and [values] in parallel will
-   * provided matching pairs of keys and values.
+   * provide matching pairs of keys and values.
    *
    * The returned iterable has an efficient `length` method based on the
    * [length] of the map. Its [Iterable.contains] method is based on
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 37ae997..b3075bf 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -4,10 +4,11 @@
 
 part of dart.developer;
 
-const bool _isProduct = const bool.fromEnvironment("dart.vm.product");
+const bool _hasTimeline =
+    const bool.fromEnvironment("dart.developer.timeline", defaultValue: true);
 
 /// A typedef for the function argument to [Timeline.timeSync].
-typedef dynamic TimelineSyncFunction();
+typedef TimelineSyncFunction<T> = T Function();
 
 // TODO: This typedef is not used.
 typedef Future TimelineAsyncFunction();
@@ -100,7 +101,7 @@
   /// a [Flow] event. This operation must be finished before
   /// returning to the event queue.
   static void startSync(String name, {Map arguments, Flow flow}) {
-    if (_isProduct) return;
+    if (!_hasTimeline) return;
     ArgumentError.checkNotNull(name, 'name');
     if (!_isDartStreamEnabled()) {
       // Push a null onto the stack and return.
@@ -119,7 +120,7 @@
 
   /// Finish the last synchronous operation that was started.
   static void finishSync() {
-    if (_isProduct) {
+    if (!_hasTimeline) {
       return;
     }
     if (_stack.length == 0) {
@@ -137,7 +138,7 @@
 
   /// Emit an instant event.
   static void instantSync(String name, {Map arguments}) {
-    if (_isProduct) return;
+    if (!_hasTimeline) return;
     ArgumentError.checkNotNull(name, 'name');
     if (!_isDartStreamEnabled()) {
       // Stream is disabled.
@@ -153,7 +154,7 @@
 
   /// A utility method to time a synchronous [function]. Internally calls
   /// [function] bracketed by calls to [startSync] and [finishSync].
-  static dynamic timeSync(String name, TimelineSyncFunction function,
+  static T timeSync<T>(String name, TimelineSyncFunction<T> function,
       {Map arguments, Flow flow}) {
     startSync(name, arguments: arguments, flow: flow);
     try {
@@ -187,7 +188,7 @@
   /// Start a synchronous operation within this task named [name].
   /// Optionally takes a [Map] of [arguments].
   void start(String name, {Map arguments}) {
-    if (_isProduct) return;
+    if (!_hasTimeline) return;
     ArgumentError.checkNotNull(name, 'name');
     var block = new _AsyncBlock._(name, _taskId);
     if (arguments != null) {
@@ -199,7 +200,7 @@
 
   /// Emit an instant event for this task.
   void instant(String name, {Map arguments}) {
-    if (_isProduct) return;
+    if (!_hasTimeline) return;
     ArgumentError.checkNotNull(name, 'name');
     Map instantArguments;
     if (arguments != null) {
@@ -211,7 +212,7 @@
 
   /// Finish the last synchronous operation that was started.
   void finish() {
-    if (_isProduct) {
+    if (!_hasTimeline) {
       return;
     }
     if (_stack.length == 0) {
diff --git a/sdk/lib/ffi/annotations.dart b/sdk/lib/ffi/annotations.dart
new file mode 100644
index 0000000..24401e6
--- /dev/null
+++ b/sdk/lib/ffi/annotations.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.
+
+part of dart.ffi;
+
+class Struct {
+  const Struct();
+}
+
+/// This Dart class represents a C struct.
+///
+/// Fields in this struct, annotated with a subtype of [NativeType], are
+/// automatically transformed into wrappers to access the fields of the struct
+/// in C memory.
+///
+/// Fields without a [NativeType] annotation are not supported.
+const struct = const Struct();
+
+class DartRepresentationOf {
+  /// Represents the Dart type corresponding to a [NativeType].
+  ///
+  /// [Int8]                               -> [int]
+  /// [Int16]                              -> [int]
+  /// [Int32]                              -> [int]
+  /// [Int64]                              -> [int]
+  /// [Uint8]                              -> [int]
+  /// [Uint16]                             -> [int]
+  /// [Uint32]                             -> [int]
+  /// [Uint64]                             -> [int]
+  /// [IntPtr]                             -> [int]
+  /// [Double]                             -> [double]
+  /// [Float]                              -> [double]
+  /// [Pointer]<T>                         -> [Pointer]<T>
+  /// T extends [Pointer]                  -> T
+  /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
+  ///    where DartRepresentationOf(Tn) -> Sn
+  const DartRepresentationOf(String nativeType);
+}
+
+class Unsized {
+  const Unsized();
+}
+
+/// This [NativeType] does not have predefined size.
+///
+/// Unsized NativeTypes do not support [sizeOf] because their size is unknown.
+/// Consequently, [allocate], [Pointer.load], [Pointer.store], and
+/// [Pointer.elementAt] are not available.
+const unsized = const Unsized();
diff --git a/sdk/lib/ffi/dynamic_library.dart b/sdk/lib/ffi/dynamic_library.dart
new file mode 100644
index 0000000..98aa64a
--- /dev/null
+++ b/sdk/lib/ffi/dynamic_library.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.
+
+part of dart.ffi;
+
+/// Represents a dynamically loaded C library.
+class DynamicLibrary {
+  /// Loads a dynamic library file. This is the equivalent of dlopen.
+  ///
+  /// Throws an [ArgumentError] if loading the dynamic library fails.
+  ///
+  /// Note that it loads the functions in the library lazily (RTLD_LAZY).
+  external factory DynamicLibrary.open(String name);
+
+  /// Looks up a symbol in the [DynamicLibrary] and returns its address in
+  /// memory. Equivalent of dlsym.
+  ///
+  /// Throws an [ArgumentError] if it fails to lookup the symbol.
+  external Pointer<T> lookup<T extends NativeType>(String symbolName);
+
+  /// Helper that combines lookup and cast to a Dart function.
+  F lookupFunction<T extends Function, F extends Function>(String symbolName) {
+    return lookup<NativeFunction<T>>(symbolName)?.asFunction<F>();
+  }
+
+  /// Dynamic libraries are equal if they load the same library.
+  external bool operator ==(other);
+
+  /// The hash code for a DynamicLibrary only depends on the loaded library
+  external int get hashCode;
+}
diff --git a/sdk/lib/ffi/ffi.dart b/sdk/lib/ffi/ffi.dart
new file mode 100644
index 0000000..5176ebb
--- /dev/null
+++ b/sdk/lib/ffi/ffi.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file
+
+/// {@category VM}
+/// {@nodoc}
+library dart.ffi;
+
+part "native_type.dart";
+part "annotations.dart";
+part "dynamic_library.dart";
+
+/// Allocate [count] elements of type [T] on the C heap with malloc() and return
+/// a pointer to the newly allocated memory.
+///
+/// Note that the memory are uninitialized.
+///
+/// TODO(dacoharkes): change signature to T allocate<T extends Pointer>() ?
+/// This would enable us to allocate structs. However how do we know the size of
+/// structs? https://github.com/dart-lang/sdk/issues/35782
+external Pointer<T> allocate<T extends NativeType>({int count: 1});
+
+/// Construction from raw value
+external T fromAddress<T extends Pointer>(int ptr);
+
+/// number of bytes used by native type T
+external int sizeOf<T extends NativeType>();
+
+/// Convert Dart function to a C function pointer, automatically marshalling
+/// the arguments and return value
+///
+/// Note: this is not implemented, always returns Pointer with address 0.
+///
+/// TODO(dacoharkes): Implement this feature.
+/// https://github.com/dart-lang/sdk/issues/35761
+external Pointer<NativeFunction<T>> fromFunction<T extends Function>(
+    @DartRepresentationOf("T") Function f);
+
+/*
+/// TODO(dacoharkes): Implement this feature.
+/// https://github.com/dart-lang/sdk/issues/35770
+/// Return a pointer object that has a finalizer attached to it. When this
+/// pointer object is collected by GC the given finalizer is invoked.
+///
+/// Note: the pointer object passed to the finalizer is not the same as
+/// the pointer object that is returned from [finalizable] - it points
+/// to the same memory region but has different identity.
+external Pointer<T> finalizable<T extends NativeType>(
+    Pointer<T> p, void finalizer(Pointer<T> ptr));
+*/
+
+/// Represents a pointer into the native C memory.
+class Pointer<T extends NativeType> extends NativeType {
+  const Pointer();
+
+  /// Store a Dart value into this location.
+  ///
+  /// The [value] is automatically marshalled into its C representation.
+  /// Note that ints which do not fit in [T] are truncated and sign extended,
+  /// and doubles stored into Pointer<[Float]> lose precision.
+  external void store(@DartRepresentationOf("T") Object value);
+
+  /// Load a Dart value from this location.
+  ///
+  /// The value is automatically unmarshalled from its C representation.
+  external R load<@DartRepresentationOf("T") R>();
+
+  /// Access to the raw pointer value.
+  external int get address;
+
+  /// Pointer arithmetic (takes element size into account).
+  external Pointer<T> elementAt(int index);
+
+  /// Pointer arithmetic (byte offset).
+  ///
+  /// TODO(dacoharkes): remove this?
+  /// https://github.com/dart-lang/sdk/issues/35883
+  external Pointer<T> offsetBy(int offsetInBytes);
+
+  /// Cast Pointer<T> to a (subtype of) Pointer<V>.
+  external U cast<U extends Pointer>();
+
+  /// Convert to Dart function, automatically marshalling the arguments
+  /// and return value.
+  ///
+  /// Can only be called on [Pointer]<[NativeFunction]>.
+  external R asFunction<@DartRepresentationOf("T") R extends Function>();
+
+  /// Free memory on the C heap pointed to by this pointer with free().
+  ///
+  /// Note that this zeros out the address.
+  external void free();
+
+  /// Equality for Pointers only depends on their address.
+  bool operator ==(other) {
+    if (other == null) return false;
+    return address == other.address;
+  }
+
+  /// The hash code for a Pointer only depends on its address.
+  int get hashCode {
+    return address.hashCode;
+  }
+}
diff --git a/sdk/lib/ffi/ffi_sources.gni b/sdk/lib/ffi/ffi_sources.gni
new file mode 100644
index 0000000..d67b267
--- /dev/null
+++ b/sdk/lib/ffi/ffi_sources.gni
@@ -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.
+
+ffi_sdk_sources = [
+  "ffi.dart",
+
+  # The above file needs to be first as it lists the parts below.
+  "annotations.dart",
+  "dynamic_library.dart",
+  "native_type.dart"
+]
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
new file mode 100644
index 0000000..61f9cde
--- /dev/null
+++ b/sdk/lib/ffi/native_type.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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.ffi;
+
+/// [NativeType]'s subtypes represent a native type in C.
+///
+/// [NativeType]'s subtypes are not constructible in the Dart code and serve
+/// purely as markers in type signatures.
+class NativeType {
+  const NativeType();
+}
+
+/// [_NativeInteger]'s subtypes represent a native integer in C.
+///
+/// [_NativeInteger]'s subtypes are not constructible in the Dart code and serve
+/// purely as markers in type signatures.
+class _NativeInteger extends NativeType {
+  const _NativeInteger();
+}
+
+/// [_NativeDouble]'s subtypes represent a native float or double in C.
+///
+/// [_NativeDouble]'s subtypes are not constructible in the Dart code and serve
+/// purely as markers in type signatures.
+class _NativeDouble extends NativeType {
+  const _NativeDouble();
+}
+
+/// Represents a native signed 8 bit integer in C.
+///
+/// [Int8] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int8 extends _NativeInteger {
+  const Int8();
+}
+
+/// Represents a native signed 16 bit integer in C.
+///
+/// [Int16] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int16 extends _NativeInteger {
+  const Int16();
+}
+
+/// Represents a native signed 32 bit integer in C.
+///
+/// [Int32] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int32 extends _NativeInteger {
+  const Int32();
+}
+
+/// Represents a native signed 64 bit integer in C.
+///
+/// [Int64] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Int64 extends _NativeInteger {
+  const Int64();
+}
+
+/// Represents a native unsigned 8 bit integer in C.
+///
+/// [Uint8] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+class Uint8 extends _NativeInteger {
+  const Uint8();
+}
+
+/// Represents a native unsigned 16 bit integer in C.
+///
+/// [Uint16] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Uint16 extends _NativeInteger {
+  const Uint16();
+}
+
+/// Represents a native unsigned 32 bit integer in C.
+///
+/// [Uint32] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Uint32 extends _NativeInteger {
+  const Uint32();
+}
+
+/// Represents a native unsigned 64 bit integer in C.
+///
+/// [Uint64] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Uint64 extends _NativeInteger {
+  const Uint64();
+}
+
+/// Represents a native pointer-sized integer in C.
+///
+/// [IntPtr] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class IntPtr extends _NativeInteger {
+  const IntPtr();
+}
+
+/// Represents a native 32 bit float in C.
+///
+/// [Float] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Float extends _NativeDouble {
+  const Float();
+}
+
+/// Represents a native 64 bit double in C.
+///
+/// [Double] is not constructible in the Dart code and serves purely as marker
+/// in type signatures.
+class Double extends _NativeDouble {
+  const Double();
+}
+
+/// Represents a void type in C.
+///
+/// [Void] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+@unsized
+class Void extends NativeType {
+  const Void();
+}
+
+/// Represents a function type in C.
+///
+/// [NativeFunction] is not constructible in the Dart code and serves purely as
+/// marker in type signatures.
+@unsized
+class NativeFunction<T extends Function> extends NativeType {}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index d5d6287..51d104c 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -67,6 +67,7 @@
         setDispatchProperty;
 
 export 'dart:math' show Rectangle, Point;
+export 'dart:_internal' show HttpStatus;
 
 /**
  * Top-level container for a web page, which is usually a browser tab or window.
@@ -144,7 +145,6 @@
     FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
 
 WorkerGlobalScope get _workerSelf => JS('WorkerGlobalScope', 'self');
-
 // 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.
@@ -1967,8 +1967,6 @@
   @Returns('CanvasRenderingContext2D|RenderingContext|RenderingContext2|Null')
   Object _getContext_2(contextId) native;
 
-  void toBlob(BlobCallback callback, String type, [Object arguments]) native;
-
   @JSName('toDataURL')
   String _toDataUrl(String type, [arguments_OR_quality]) native;
 
@@ -2062,6 +2060,17 @@
    */
   String toDataUrl([String type = 'image/png', num quality]) =>
       _toDataUrl(type, quality);
+
+  @JSName('toBlob')
+  void _toBlob(BlobCallback callback, String type, [Object arguments]) native;
+
+  Future<Blob> toBlob(String type, [Object arguments]) {
+    var completer = new Completer<Blob>();
+    _toBlob((value) {
+      completer.complete(value);
+    }, type, arguments);
+    return completer.future;
+  }
 }
 // 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
@@ -8553,12 +8562,25 @@
 
   void setDragImage(Element image, int x, int y) native;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
 @Native("DataTransferItem")
 class DataTransferItem extends Interceptor {
+  Entry getAsEntry() {
+    Entry entry = _webkitGetAsEntry();
+
+    if (entry.isFile)
+      applyExtension('FileEntry', entry);
+    else if (entry.isDirectory)
+      applyExtension('DirectoryEntry', entry);
+    else
+      applyExtension('Entry', entry);
+
+    return entry;
+  }
+
   // To suppress missing implicit constructor warnings.
   factory DataTransferItem._() {
     throw new UnsupportedError("Not supported");
@@ -8573,7 +8595,7 @@
   @JSName('webkitGetAsEntry')
   @SupportedBrowser(SupportedBrowser.CHROME)
   @SupportedBrowser(SupportedBrowser.SAFARI)
-  Entry getAsEntry() native;
+  Entry _webkitGetAsEntry() native;
 }
 // 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
@@ -9155,8 +9177,15 @@
 
   Future<List<Entry>> readEntries() {
     var completer = new Completer<List<Entry>>();
-    _readEntries((value) {
-      completer.complete(new List<Entry>.from(value));
+    _readEntries((values) {
+      values.forEach((value) {
+        applyExtension('Entry', value);
+        Entry entry = value as Entry;
+        if (entry.isFile)
+          applyExtension('FileEntry', entry);
+        else if (entry.isDirectory) applyExtension('DirectoryEntry', entry);
+      });
+      completer.complete(new List<Entry>.from(values));
     }, (error) {
       completer.completeError(error);
     });
@@ -9573,6 +9602,7 @@
   Stream<ClipboardEvent> get onCut => Element.cutEvent.forTarget(this);
 
   /// Stream of `doubleclick` events handled by this [Document].
+  @DomName('Document.ondblclick')
   Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
 
   /// Stream of `drag` events handled by this [Document].
@@ -11357,6 +11387,7 @@
   ElementStream<ClipboardEvent> get onCut;
 
   /// Stream of `doubleclick` events handled by this [Element].
+  @DomName('Element.ondblclick')
   ElementStream<Event> get onDoubleClick;
 
   /**
@@ -11721,6 +11752,7 @@
       Element.cutEvent._forElementList(this);
 
   /// Stream of `doubleclick` events handled by this [Element].
+  @DomName('Element.ondblclick')
   ElementStream<Event> get onDoubleClick =>
       Element.doubleClickEvent._forElementList(this);
 
@@ -12274,6 +12306,66 @@
     }
   }
 
+  @pragma('dart2js:tryInline')
+  String getAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    return _getAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  String getAttributeNS(String namespaceURI, String name) {
+    // 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');
+    return _getAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  bool hasAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    return _hasAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  bool hasAttributeNS(String namespaceURI, String name) {
+    // 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');
+    return _hasAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void removeAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    _removeAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void removeAttributeNS(String namespaceURI, String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    _removeAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void setAttribute(String name, String value) {
+    // 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.');
+    _setAttribute(name, value);
+  }
+
+  @pragma('dart2js:tryInline')
+  void setAttributeNS(String namespaceURI, String name, String value) {
+    // 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.');
+    _setAttributeNS(namespaceURI, name, value);
+  }
+
   /**
    * List of the direct children of this element.
    *
@@ -12310,6 +12402,30 @@
   ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
       new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
 
+  @JSName('setApplyScroll')
+  void _setApplyScroll(ScrollStateCallback scrollStateCallback,
+      String nativeScrollBehavior) native;
+
+  Future<ScrollState> setApplyScroll(String nativeScrollBehavior) {
+    var completer = new Completer<ScrollState>();
+    _setApplyScroll((value) {
+      completer.complete(value);
+    }, nativeScrollBehavior);
+    return completer.future;
+  }
+
+  @JSName('setDistributeScroll')
+  void _setDistributeScroll(ScrollStateCallback scrollStateCallback,
+      String nativeScrollBehavior) native;
+
+  Future<ScrollState> setDistributeScroll(String nativeScrollBehavior) {
+    var completer = new Completer<ScrollState>();
+    _setDistributeScroll((value) {
+      completer.complete(value);
+    }, nativeScrollBehavior);
+    return completer.future;
+  }
+
   /**
    * The set of CSS classes applied to this element.
    *
@@ -13275,6 +13391,7 @@
    *
    * See [EventStreamProvider] for usage information.
    */
+  @DomName('Element.dblclickEvent')
   static const EventStreamProvider<Event> doubleClickEvent =
       const EventStreamProvider<Event>('dblclick');
 
@@ -13858,9 +13975,11 @@
 
   List<Animation> getAnimations() native;
 
-  String getAttribute(String name) native;
+  @JSName('getAttribute')
+  String _getAttribute(String name) native;
 
-  String getAttributeNS(String namespaceURI, String localName) native;
+  @JSName('getAttributeNS')
+  String _getAttributeNS(String namespaceURI, String localName) native;
 
   List<String> getAttributeNames() native;
 
@@ -14025,15 +14144,11 @@
   @JSName('scrollTo')
   void _scrollTo_3(num x, y) native;
 
-  void setApplyScroll(ScrollStateCallback scrollStateCallback,
-      String nativeScrollBehavior) native;
+  @JSName('setAttribute')
+  void _setAttribute(String name, String value) native;
 
-  void setAttribute(String name, String value) native;
-
-  void setAttributeNS(String namespaceURI, String name, String value) native;
-
-  void setDistributeScroll(ScrollStateCallback scrollStateCallback,
-      String nativeScrollBehavior) native;
+  @JSName('setAttributeNS')
+  void _setAttributeNS(String namespaceURI, String name, String value) native;
 
   void setPointerCapture(int pointerId) native;
 
@@ -14140,6 +14255,7 @@
   ElementStream<ClipboardEvent> get onCut => cutEvent.forElement(this);
 
   /// Stream of `doubleclick` events handled by this [Element].
+  @DomName('Element.ondblclick')
   ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
 
   /**
@@ -14549,6 +14665,7 @@
   Future<Entry> getParent() {
     var completer = new Completer<Entry>();
     _getParent((value) {
+      applyExtension('Entry', value);
       completer.complete(value);
     }, (error) {
       completer.completeError(error);
@@ -16090,47 +16207,53 @@
   void _getCurrentPosition(_PositionCallback successCallback,
       [_PositionErrorCallback errorCallback, Map options]) {
     if (options != null) {
-      var options_1 = convertDartToNative_Dictionary(options);
-      _getCurrentPosition_1(successCallback, errorCallback, options_1);
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      var options_2 = convertDartToNative_Dictionary(options);
+      _getCurrentPosition_1(successCallback_1, errorCallback, options_2);
       return;
     }
     if (errorCallback != null) {
-      _getCurrentPosition_2(successCallback, errorCallback);
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      _getCurrentPosition_2(successCallback_1, errorCallback);
       return;
     }
-    _getCurrentPosition_3(successCallback);
+    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+    _getCurrentPosition_3(successCallback_1);
     return;
   }
 
   @JSName('getCurrentPosition')
-  void _getCurrentPosition_1(_PositionCallback successCallback,
-      _PositionErrorCallback errorCallback, options) native;
+  void _getCurrentPosition_1(
+      successCallback, _PositionErrorCallback errorCallback, options) native;
   @JSName('getCurrentPosition')
-  void _getCurrentPosition_2(_PositionCallback successCallback,
-      _PositionErrorCallback errorCallback) native;
+  void _getCurrentPosition_2(
+      successCallback, _PositionErrorCallback errorCallback) native;
   @JSName('getCurrentPosition')
-  void _getCurrentPosition_3(_PositionCallback successCallback) native;
+  void _getCurrentPosition_3(successCallback) native;
 
   int _watchPosition(_PositionCallback successCallback,
       [_PositionErrorCallback errorCallback, Map options]) {
     if (options != null) {
-      var options_1 = convertDartToNative_Dictionary(options);
-      return _watchPosition_1(successCallback, errorCallback, options_1);
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return _watchPosition_1(successCallback_1, errorCallback, options_2);
     }
     if (errorCallback != null) {
-      return _watchPosition_2(successCallback, errorCallback);
+      var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+      return _watchPosition_2(successCallback_1, errorCallback);
     }
-    return _watchPosition_3(successCallback);
+    var successCallback_1 = convertDartClosureToJS(successCallback, 1);
+    return _watchPosition_3(successCallback_1);
   }
 
   @JSName('watchPosition')
-  int _watchPosition_1(_PositionCallback successCallback,
-      _PositionErrorCallback errorCallback, options) native;
+  int _watchPosition_1(
+      successCallback, _PositionErrorCallback errorCallback, options) native;
   @JSName('watchPosition')
-  int _watchPosition_2(_PositionCallback successCallback,
-      _PositionErrorCallback errorCallback) native;
+  int _watchPosition_2(successCallback, _PositionErrorCallback errorCallback)
+      native;
   @JSName('watchPosition')
-  int _watchPosition_3(_PositionCallback successCallback) native;
+  int _watchPosition_3(successCallback) native;
 }
 
 /**
@@ -16201,6 +16324,7 @@
   static const EventStreamProvider<MouseEvent> contextMenuEvent =
       const EventStreamProvider<MouseEvent>('contextmenu');
 
+  @DomName('GlobalEventHandlers.dblclickEvent')
   static const EventStreamProvider<Event> doubleClickEvent =
       const EventStreamProvider<Event>('dblclick');
 
@@ -16365,6 +16489,7 @@
 
   Stream<MouseEvent> get onContextMenu => contextMenuEvent.forTarget(this);
 
+  @DomName('GlobalEventHandlers.ondblclick')
   Stream<Event> get onDoubleClick => doubleClickEvent.forTarget(this);
 
   Stream<MouseEvent> get onDrag => dragEvent.forTarget(this);
@@ -18781,10 +18906,12 @@
   factory IntersectionObserver(IntersectionObserverCallback callback,
       [Map options]) {
     if (options != null) {
-      var options_1 = convertDartToNative_Dictionary(options);
-      return IntersectionObserver._create_1(callback, options_1);
+      var callback_1 = convertDartClosureToJS(callback, 2);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return IntersectionObserver._create_1(callback_1, options_2);
     }
-    return IntersectionObserver._create_2(callback);
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return IntersectionObserver._create_2(callback_1);
   }
   static IntersectionObserver _create_1(callback, options) => JS(
       'IntersectionObserver',
@@ -20350,6 +20477,10 @@
 
   final String origin;
 
+  @Unstable()
+  @Creates('JSExtendableArray')
+  final List<MessagePort> ports;
+
   EventTarget get source => _convertNativeToDart_EventTarget(this._get_source);
   @JSName('source')
   @Creates('Null')
@@ -23883,7 +24014,8 @@
   }
 
   factory PerformanceObserver(PerformanceObserverCallback callback) {
-    return PerformanceObserver._create_1(callback);
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return PerformanceObserver._create_1(callback_1);
   }
   static PerformanceObserver _create_1(callback) =>
       JS('PerformanceObserver', 'new PerformanceObserver(#)', callback);
@@ -25024,7 +25156,8 @@
   }
 
   factory ReportingObserver(ReportingObserverCallback callback) {
-    return ReportingObserver._create_1(callback);
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return ReportingObserver._create_1(callback_1);
   }
   static ReportingObserver _create_1(callback) =>
       JS('ReportingObserver', 'new ReportingObserver(#)', callback);
@@ -25060,7 +25193,8 @@
   }
 
   factory ResizeObserver(ResizeObserverCallback callback) {
-    return ResizeObserver._create_1(callback);
+    var callback_1 = convertDartClosureToJS(callback, 2);
+    return ResizeObserver._create_1(callback_1);
   }
   static ResizeObserver _create_1(callback) =>
       JS('ResizeObserver', 'new ResizeObserver(#)', callback);
@@ -26275,7 +26409,21 @@
 
   final String state;
 
-  void postMessage(Object message, [List<Object> transfer]) native;
+  void postMessage(/*any*/ message, [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message) native;
 
   Stream<Event> get onError => errorEvent.forTarget(this);
 }
@@ -31257,16 +31405,18 @@
 
   int requestIdleCallback(IdleRequestCallback callback, [Map options]) {
     if (options != null) {
-      var options_1 = convertDartToNative_Dictionary(options);
-      return _requestIdleCallback_1(callback, options_1);
+      var callback_1 = convertDartClosureToJS(callback, 1);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return _requestIdleCallback_1(callback_1, options_2);
     }
-    return _requestIdleCallback_2(callback);
+    var callback_1 = convertDartClosureToJS(callback, 1);
+    return _requestIdleCallback_2(callback_1);
   }
 
   @JSName('requestIdleCallback')
-  int _requestIdleCallback_1(IdleRequestCallback callback, options) native;
+  int _requestIdleCallback_1(callback, options) native;
   @JSName('requestIdleCallback')
-  int _requestIdleCallback_2(IdleRequestCallback callback) native;
+  int _requestIdleCallback_2(callback) native;
 
   /**
    * Resizes this window by an offset.
@@ -31295,7 +31445,7 @@
    *
    * ## Other resources
    *
-   * * [Window scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
    *   from MDN.
    */
   void scroll([options_OR_x, y, Map scrollOptions]) {
@@ -31332,7 +31482,7 @@
    *
    * ## Other resources
    *
-   * * [Window scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
    *   from MDN.
    */
   void _scroll_1() native;
@@ -31344,7 +31494,7 @@
    *
    * ## Other resources
    *
-   * * [Window scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
    *   from MDN.
    */
   void _scroll_2(options) native;
@@ -31356,7 +31506,7 @@
    *
    * ## Other resources
    *
-   * * [Window scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
    *   from MDN.
    */
   void _scroll_3(num x, num y) native;
@@ -31368,7 +31518,7 @@
    *
    * ## Other resources
    *
-   * * [Window scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
    *   from MDN.
    */
   void _scroll_4(int x, int y) native;
@@ -31380,7 +31530,7 @@
    *
    * ## Other resources
    *
-   * * [Window scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
+   * * [Window.scroll](https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll)
    *   from MDN.
    */
   void _scroll_5(int x, int y, scrollOptions) native;
@@ -31390,7 +31540,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
    *   from MDN.
    */
   void scrollBy([options_OR_x, y, Map scrollOptions]) {
@@ -31425,7 +31575,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
    *   from MDN.
    */
   void _scrollBy_1() native;
@@ -31435,7 +31585,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
    *   from MDN.
    */
   void _scrollBy_2(options) native;
@@ -31445,7 +31595,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
    *   from MDN.
    */
   void _scrollBy_3(num x, num y) native;
@@ -31455,7 +31605,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
    *   from MDN.
    */
   void _scrollBy_4(int x, int y) native;
@@ -31465,7 +31615,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
+   * * [Window.scrollBy](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy)
    *   from MDN.
    */
   void _scrollBy_5(int x, int y, scrollOptions) native;
@@ -31477,7 +31627,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
    *   from MDN.
    */
   void scrollTo([options_OR_x, y, Map scrollOptions]) {
@@ -31514,7 +31664,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
    *   from MDN.
    */
   void _scrollTo_1() native;
@@ -31526,7 +31676,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
    *   from MDN.
    */
   void _scrollTo_2(options) native;
@@ -31538,7 +31688,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
    *   from MDN.
    */
   void _scrollTo_3(num x, num y) native;
@@ -31550,7 +31700,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
    *   from MDN.
    */
   void _scrollTo_4(int x, int y) native;
@@ -31562,7 +31712,7 @@
    *
    * ## Other resources
    *
-   * * [Window scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
+   * * [Window.scrollTo](https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo)
    *   from MDN.
    */
   void _scrollTo_5(int x, int y, scrollOptions) native;
@@ -31686,6 +31836,7 @@
       Element.contextMenuEvent.forTarget(this);
 
   /// Stream of `doubleclick` events handled by this [Window].
+  @DomName('Window.ondblclick')
   Stream<Event> get onDoubleClick => Element.doubleClickEvent.forTarget(this);
 
   /// Stream of `devicemotion` events handled by this [Window].
@@ -32141,7 +32292,21 @@
   static bool get supported =>
       JS('bool', '(typeof window.Worker != "undefined")');
 
-  void postMessage(Object message, [List<Object> transfer]) native;
+  void postMessage(/*any*/ message, [List<Object> transfer]) {
+    if (transfer != null) {
+      var message_1 = convertDartToNative_SerializedScriptValue(message);
+      _postMessage_1(message_1, transfer);
+      return;
+    }
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
+    return;
+  }
+
+  @JSName('postMessage')
+  void _postMessage_1(message, List<Object> transfer) native;
+  @JSName('postMessage')
+  void _postMessage_2(message) native;
 
   void terminate() native;
 
@@ -34049,11 +34214,8 @@
     _element.setAttribute(key, value);
   }
 
-  String remove(Object key) {
-    String value = _element.getAttribute(key);
-    _element._removeAttribute(key);
-    return value;
-  }
+  @pragma('dart2js:tryInline')
+  String remove(Object key) => key is String ? _remove(_element, key) : null;
 
   /**
    * The number of {key, value} pairs in the map.
@@ -34063,6 +34225,21 @@
   }
 
   bool _matches(_Attr node) => node._namespaceUri == null;
+
+  // 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(
+        // 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)',
+        '#.getAttribute(#)',
+        element,
+        key);
+    JS('', '#.removeAttribute(#)', element, key);
+    return value;
+  }
 }
 
 /**
@@ -34085,11 +34262,9 @@
     _element.setAttributeNS(_namespace, key, value);
   }
 
-  String remove(Object key) {
-    String value = this[key];
-    _element._removeAttributeNS(_namespace, key);
-    return value;
-  }
+  @pragma('dart2js:tryInline')
+  String remove(Object key) =>
+      key is String ? _remove(_namespace, _element, key) : null;
 
   /**
    * The number of {key, value} pairs in the map.
@@ -34099,6 +34274,23 @@
   }
 
   bool _matches(_Attr node) => node._namespaceUri == _namespace;
+
+  // Inline this because almost all call sites of [remove] do not use the
+  // 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(
+        // 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)',
+        '#.getAttributeNS(#, #)',
+        element,
+        namespace,
+        key);
+    JS('', '#.removeAttributeNS(#, #)', element, namespace, key);
+    return value;
+  }
 }
 
 /**
@@ -35076,9 +35268,9 @@
     }
   }
 
-  static void _removeAll(Element _element, Iterable<String> iterable) {
+  static void _removeAll(Element _element, Iterable<Object> iterable) {
     DomTokenList list = _classListOf(_element);
-    for (var value in iterable) {
+    for (String value in iterable) {
       _classListRemove(list, value);
     }
   }
diff --git a/sdk/lib/html/html_common/conversions_dart2js.dart b/sdk/lib/html/html_common/conversions_dart2js.dart
index f99b357..36153cf 100644
--- a/sdk/lib/html/html_common/conversions_dart2js.dart
+++ b/sdk/lib/html/html_common/conversions_dart2js.dart
@@ -56,7 +56,8 @@
   newJsMap() => JS('var', '{}');
   putIntoMap(map, key, value) => JS('void', '#[#] = #', map, key, value);
   newJsList(length) => JS('JSExtendableArray', 'new Array(#)', length);
-  cloneNotRequired(e) => (e is NativeByteBuffer || e is NativeTypedData);
+  cloneNotRequired(e) =>
+      (e is NativeByteBuffer || e is NativeTypedData || e is MessagePort);
 }
 
 class _AcceptStructuredCloneDart2Js extends _AcceptStructuredClone {
@@ -96,7 +97,7 @@
 
 const String _serializedScriptValue = 'num|String|bool|'
     'JSExtendableArray|=Object|'
-    'Blob|File|NativeByteBuffer|NativeTypedData'
+    'Blob|File|NativeByteBuffer|NativeTypedData|MessagePort'
     // TODO(sra): Add Date, RegExp.
     ;
 const annotation_Creates_SerializedScriptValue =
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 7dd739d..50962df 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -82,6 +82,7 @@
 import 'dart:_js_helper' show Creates, Returns, JSName, Native;
 import 'dart:_foreign_helper' show JS;
 import 'dart:_interceptors' show Interceptor, JSExtendableArray;
+import 'dart:_js_helper' show convertDartClosureToJS;
 // 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.
@@ -1039,7 +1040,8 @@
   }
 
   factory Observer(ObserverCallback callback) {
-    return Observer._create_1(callback);
+    var callback_1 = convertDartClosureToJS(callback, 1);
+    return Observer._create_1(callback_1);
   }
   static Observer _create_1(callback) =>
       JS('Observer', 'new IDBObserver(#)', callback);
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index f5ae6a1..11ee996 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -202,3 +202,181 @@
   final String version;
   const Since(this.version);
 }
+
+/**
+ * HTTP status codes.  Exported in dart:io and dart:html.
+ */
+abstract class HttpStatus {
+  static const int continue_ = 100;
+  static const int switchingProtocols = 101;
+  @Since("2.1")
+  static const int processing = 102;
+  static const int ok = 200;
+  static const int created = 201;
+  static const int accepted = 202;
+  static const int nonAuthoritativeInformation = 203;
+  static const int noContent = 204;
+  static const int resetContent = 205;
+  static const int partialContent = 206;
+  @Since("2.1")
+  static const int multiStatus = 207;
+  @Since("2.1")
+  static const int alreadyReported = 208;
+  @Since("2.1")
+  static const int imUsed = 226;
+  static const int multipleChoices = 300;
+  static const int movedPermanently = 301;
+  static const int found = 302;
+  static const int movedTemporarily = 302; // Common alias for found.
+  static const int seeOther = 303;
+  static const int notModified = 304;
+  static const int useProxy = 305;
+  static const int temporaryRedirect = 307;
+  @Since("2.1")
+  static const int permanentRedirect = 308;
+  static const int badRequest = 400;
+  static const int unauthorized = 401;
+  static const int paymentRequired = 402;
+  static const int forbidden = 403;
+  static const int notFound = 404;
+  static const int methodNotAllowed = 405;
+  static const int notAcceptable = 406;
+  static const int proxyAuthenticationRequired = 407;
+  static const int requestTimeout = 408;
+  static const int conflict = 409;
+  static const int gone = 410;
+  static const int lengthRequired = 411;
+  static const int preconditionFailed = 412;
+  static const int requestEntityTooLarge = 413;
+  static const int requestUriTooLong = 414;
+  static const int unsupportedMediaType = 415;
+  static const int requestedRangeNotSatisfiable = 416;
+  static const int expectationFailed = 417;
+  @Since("2.1")
+  static const int misdirectedRequest = 421;
+  @Since("2.1")
+  static const int unprocessableEntity = 422;
+  @Since("2.1")
+  static const int locked = 423;
+  @Since("2.1")
+  static const int failedDependency = 424;
+  static const int upgradeRequired = 426;
+  @Since("2.1")
+  static const int preconditionRequired = 428;
+  @Since("2.1")
+  static const int tooManyRequests = 429;
+  @Since("2.1")
+  static const int requestHeaderFieldsTooLarge = 431;
+  @Since("2.1")
+  static const int connectionClosedWithoutResponse = 444;
+  @Since("2.1")
+  static const int unavailableForLegalReasons = 451;
+  @Since("2.1")
+  static const int clientClosedRequest = 499;
+  static const int internalServerError = 500;
+  static const int notImplemented = 501;
+  static const int badGateway = 502;
+  static const int serviceUnavailable = 503;
+  static const int gatewayTimeout = 504;
+  static const int httpVersionNotSupported = 505;
+  @Since("2.1")
+  static const int variantAlsoNegotiates = 506;
+  @Since("2.1")
+  static const int insufficientStorage = 507;
+  @Since("2.1")
+  static const int loopDetected = 508;
+  @Since("2.1")
+  static const int notExtended = 510;
+  @Since("2.1")
+  static const int networkAuthenticationRequired = 511;
+  // Client generated status code.
+  static const int networkConnectTimeoutError = 599;
+
+  @Deprecated("Use continue_ instead")
+  static const int CONTINUE = continue_;
+  @Deprecated("Use switchingProtocols instead")
+  static const int SWITCHING_PROTOCOLS = switchingProtocols;
+  @Deprecated("Use ok instead")
+  static const int OK = ok;
+  @Deprecated("Use created instead")
+  static const int CREATED = created;
+  @Deprecated("Use accepted instead")
+  static const int ACCEPTED = accepted;
+  @Deprecated("Use nonAuthoritativeInformation instead")
+  static const int NON_AUTHORITATIVE_INFORMATION = nonAuthoritativeInformation;
+  @Deprecated("Use noContent instead")
+  static const int NO_CONTENT = noContent;
+  @Deprecated("Use resetContent instead")
+  static const int RESET_CONTENT = resetContent;
+  @Deprecated("Use partialContent instead")
+  static const int PARTIAL_CONTENT = partialContent;
+  @Deprecated("Use multipleChoices instead")
+  static const int MULTIPLE_CHOICES = multipleChoices;
+  @Deprecated("Use movedPermanently instead")
+  static const int MOVED_PERMANENTLY = movedPermanently;
+  @Deprecated("Use found instead")
+  static const int FOUND = found;
+  @Deprecated("Use movedTemporarily instead")
+  static const int MOVED_TEMPORARILY = movedTemporarily;
+  @Deprecated("Use seeOther instead")
+  static const int SEE_OTHER = seeOther;
+  @Deprecated("Use notModified instead")
+  static const int NOT_MODIFIED = notModified;
+  @Deprecated("Use useProxy instead")
+  static const int USE_PROXY = useProxy;
+  @Deprecated("Use temporaryRedirect instead")
+  static const int TEMPORARY_REDIRECT = temporaryRedirect;
+  @Deprecated("Use badRequest instead")
+  static const int BAD_REQUEST = badRequest;
+  @Deprecated("Use unauthorized instead")
+  static const int UNAUTHORIZED = unauthorized;
+  @Deprecated("Use paymentRequired instead")
+  static const int PAYMENT_REQUIRED = paymentRequired;
+  @Deprecated("Use forbidden instead")
+  static const int FORBIDDEN = forbidden;
+  @Deprecated("Use notFound instead")
+  static const int NOT_FOUND = notFound;
+  @Deprecated("Use methodNotAllowed instead")
+  static const int METHOD_NOT_ALLOWED = methodNotAllowed;
+  @Deprecated("Use notAcceptable instead")
+  static const int NOT_ACCEPTABLE = notAcceptable;
+  @Deprecated("Use proxyAuthenticationRequired instead")
+  static const int PROXY_AUTHENTICATION_REQUIRED = proxyAuthenticationRequired;
+  @Deprecated("Use requestTimeout instead")
+  static const int REQUEST_TIMEOUT = requestTimeout;
+  @Deprecated("Use conflict instead")
+  static const int CONFLICT = conflict;
+  @Deprecated("Use gone instead")
+  static const int GONE = gone;
+  @Deprecated("Use lengthRequired instead")
+  static const int LENGTH_REQUIRED = lengthRequired;
+  @Deprecated("Use preconditionFailed instead")
+  static const int PRECONDITION_FAILED = preconditionFailed;
+  @Deprecated("Use requestEntityTooLarge instead")
+  static const int REQUEST_ENTITY_TOO_LARGE = requestEntityTooLarge;
+  @Deprecated("Use requestUriTooLong instead")
+  static const int REQUEST_URI_TOO_LONG = requestUriTooLong;
+  @Deprecated("Use unsupportedMediaType instead")
+  static const int UNSUPPORTED_MEDIA_TYPE = unsupportedMediaType;
+  @Deprecated("Use requestedRangeNotSatisfiable instead")
+  static const int REQUESTED_RANGE_NOT_SATISFIABLE =
+      requestedRangeNotSatisfiable;
+  @Deprecated("Use expectationFailed instead")
+  static const int EXPECTATION_FAILED = expectationFailed;
+  @Deprecated("Use upgradeRequired instead")
+  static const int UPGRADE_REQUIRED = upgradeRequired;
+  @Deprecated("Use internalServerError instead")
+  static const int INTERNAL_SERVER_ERROR = internalServerError;
+  @Deprecated("Use notImplemented instead")
+  static const int NOT_IMPLEMENTED = notImplemented;
+  @Deprecated("Use badGateway instead")
+  static const int BAD_GATEWAY = badGateway;
+  @Deprecated("Use serviceUnavailable instead")
+  static const int SERVICE_UNAVAILABLE = serviceUnavailable;
+  @Deprecated("Use gatewayTimeout instead")
+  static const int GATEWAY_TIMEOUT = gatewayTimeout;
+  @Deprecated("Use httpVersionNotSupported instead")
+  static const int HTTP_VERSION_NOT_SUPPORTED = httpVersionNotSupported;
+  @Deprecated("Use networkConnectTimeoutError instead")
+  static const int NETWORK_CONNECT_TIMEOUT_ERROR = networkConnectTimeoutError;
+}
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index 6131c0e..c640c5b 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -196,6 +196,7 @@
 import 'dart:typed_data';
 
 export 'dart:_http';
+export 'dart:_internal' show HttpStatus;
 
 part 'bytes_builder.dart';
 part 'common.dart';
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index e8e4a08..5481265 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -149,32 +149,16 @@
 
   _StreamSinkImpl(this._target);
 
-  void _reportClosedSink() {
-    // TODO(29554): this is very brittle and depends on the layout of the
-    // stderr class.
-    if (this == stderr._sink) {
-      // We can't report on stderr anymore (as we would otherwise
-      // have an infinite recursion.
-      throw new StateError("Stderr is closed.");
-    }
-    // TODO(29554): throw a StateError, and don't just report the problem.
-    stderr.writeln("StreamSink is closed and adding to it is an error.");
-    stderr.writeln("  See http://dartbug.com/29554.");
-    stderr.writeln(StackTrace.current);
-  }
-
   void add(T data) {
     if (_isClosed) {
-      _reportClosedSink();
-      return;
+      throw StateError("StreamSink is closed");
     }
     _controller.add(data);
   }
 
   void addError(error, [StackTrace stackTrace]) {
     if (_isClosed) {
-      _reportClosedSink();
-      return;
+      throw StateError("StreamSink is closed");
     }
     _controller.addError(error, stackTrace);
   }
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index b43c13a..79f8656 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -50,11 +50,11 @@
    * components are created. The directories in the path of [target] are
    * not affected, unless they are also in [path].
    *
-   * On the Windows platform, this will only work with directories, and the
-   * target directory must exist. The link will be created as a Junction.
-   * Only absolute links will be created, and relative paths to the target
-   * will be converted to absolute paths by joining them with the path of the
-   * directory the link is contained in.
+   * On the Windows platform, this call will create a true symbolic link
+   * instead of a Junction. In order to create a symbolic link on Windows, Dart
+   * must be run in Administrator mode or the system must have Developer Mode
+   * enabled, otherwise a [FileSystemException] will be raised with 
+   * `ERROR_PRIVILEGE_NOT_HELD` set as the errno when this call is made.
    *
    * On other platforms, the posix symlink() call is used to make a symbolic
    * link containing the string [target].  If [target] is a relative path,
@@ -71,10 +71,11 @@
    * non-existing path components are created. The directories in
    * the path of [target] are not affected, unless they are also in [path].
    *
-   * On the Windows platform, this will only work with directories, and the
-   * target directory must exist. The link will be created as a Junction.
-   * Only absolute links will be created, and relative paths to the target
-   * will be converted to absolute paths.
+   * On the Windows platform, this call will create a true symbolic link
+   * instead of a Junction. In order to create a symbolic link on Windows, Dart
+   * must be run in Administrator mode or the system must have Developer Mode
+   * enabled, otherwise a [FileSystemException] will be raised with 
+   * `ERROR_PRIVILEGE_NOT_HELD` set as the errno when this call is made.
    *
    * On other platforms, the posix symlink() call is used to make a symbolic
    * link containing the string [target].  If [target] is a relative path,
@@ -85,9 +86,6 @@
   /**
    * Synchronously updates the link. Calling [updateSync] on a non-existing link
    * will throw an exception.
-   *
-   * On the Windows platform, this will only work with directories, and the
-   * target directory must exist.
    */
   void updateSync(String target);
 
@@ -95,9 +93,6 @@
    * Updates the link. Returns a [:Future<Link>:] that completes with the
    * link when it has been updated.  Calling [update] on a non-existing link
    * will complete its returned future with an exception.
-   *
-   * On the Windows platform, this will only work with directories, and the
-   * target directory must exist.
    */
   Future<Link> update(String target);
 
@@ -183,9 +178,6 @@
   Link get absolute => new Link.fromRawPath(_rawAbsolutePath);
 
   Future<Link> create(String target, {bool recursive: false}) {
-    if (Platform.isWindows) {
-      target = _makeWindowsLinkTarget(target);
-    }
     var result =
         recursive ? parent.create(recursive: true) : new Future.value(null);
     return result
@@ -204,28 +196,10 @@
     if (recursive) {
       parent.createSync(recursive: true);
     }
-    if (Platform.isWindows) {
-      target = _makeWindowsLinkTarget(target);
-    }
     var result = _File._createLink(_Namespace._namespace, _rawPath, target);
     throwIfError(result, "Cannot create link", path);
   }
 
-  // Put target into the form "\??\C:\my\target\dir".
-  String _makeWindowsLinkTarget(String target) {
-    Uri base = new Uri.file('${Directory.current.path}\\');
-    Uri link = new Uri.file(path);
-    Uri destination = new Uri.file(target);
-    String result = base.resolveUri(link).resolveUri(destination).toFilePath();
-    if (result.length > 3 && result[1] == ':' && result[2] == '\\') {
-      return '\\??\\$result';
-    } else {
-      throw new FileSystemException(
-          'Target $result of Link.create on Windows cannot be converted'
-          ' to start with a drive letter.  Unexpected error.');
-    }
-  }
-
   void updateSync(String target) {
     // TODO(12414): Replace with atomic update, where supported by platform.
     // Atomically changing a link can be done by creating the new link, with
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index b4c0132..463a445 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -736,6 +736,14 @@
     return _socket.setOption(option, enabled);
   }
 
+  Uint8List getRawOption(RawSocketOption option) {
+    return _socket?.getRawOption(option);
+  }
+
+  void setRawOption(RawSocketOption option) {
+    _socket?.setRawOption(option);
+  }
+
   void _eventDispatcher(RawSocketEvent event) {
     try {
       if (event == RawSocketEvent.read) {
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index fb46acf..02fb46a 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -395,6 +395,109 @@
   const SocketOption._(this._value);
 }
 
+// Must be kept in sync with enum in socket.cc
+enum _RawSocketOptions {
+  SOL_SOCKET, // 0
+  IPPROTO_IP, // 1
+  IP_MULTICAST_IF, // 2
+  IPPROTO_IPV6, // 3
+  IPV6_MULTICAST_IF, // 4
+  IPPROTO_TCP, // 5
+  IPPROTO_UDP, // 6
+}
+
+/// The [RawSocketOption] is used as a parameter to [Socket.setRawOption] and
+/// [RawSocket.setRawOption] to set customize the behaviour of the underlying
+/// socket.
+///
+/// It allows for fine grained control of the socket options, and its values will
+/// be passed to the underlying platform's implementation of setsockopt and
+/// getsockopt.
+class RawSocketOption {
+  /// Creates a RawSocketOption for getRawOption andSetRawOption.
+  ///
+  /// All arguments are required and must not be null.
+  ///
+  /// The level and option arguments correspond to level and optname arguments
+  /// on the get/setsockopt native calls.
+  ///
+  /// The value argument and its length correspond to the optval and length
+  /// arguments on the native call.
+  ///
+  /// For a [getRawOption] call, the value parameter will be updated after a
+  /// successful call (although its length will not be changed).
+  ///
+  /// For a [setRawOption] call, the value parameter will be used set the
+  /// option.
+  const RawSocketOption(this.level, this.option, this.value);
+
+  /// Convenience constructor for creating an int based RawSocketOption.
+  factory RawSocketOption.fromInt(int level, int option, int value) {
+    if (value == null) {
+      value = 0;
+    }
+    final Uint8List list = Uint8List(4);
+    final buffer = ByteData.view(list.buffer);
+    buffer.setInt32(0, value);
+    return RawSocketOption(level, option, list);
+  }
+
+  /// Convenience constructor for creating a bool based RawSocketOption.
+  factory RawSocketOption.fromBool(int level, int option, bool value) =>
+      RawSocketOption.fromInt(level, option, value == true ? 1 : 0);
+
+  /// The level for the option to set or get.
+  ///
+  /// See also:
+  ///   * [RawSocketOption.levelSocket]
+  ///   * [RawSocketOption.levelIPv4]
+  ///   * [RawSocketOption.levelIPv6]
+  ///   * [RawSocketOption.levelTcp]
+  ///   * [RawSocketOption.levelUdp]
+  final int level;
+
+  /// The option to set or get.
+  final int option;
+
+  /// The raw data to set, or the array to write the current option value into.
+  ///
+  /// This list must be the correct length for the expected option. For most
+  /// options that take int or bool values, the length should be 4. For options
+  /// that expect a struct (such as an in_addr_t), the length should be the
+  /// correct length for that struct.
+  final Uint8List value;
+
+  /// Socket level option for SOL_SOCKET.
+  static int get levelSocket =>
+      _getOptionValue(_RawSocketOptions.SOL_SOCKET.index);
+
+  /// Socket level option for IPPROTO_IP.
+  static int get levelIPv4 =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_IP.index);
+
+  /// Socket option for IP_MULTICAST_IF.
+  static int get IPv4MulticastInterface =>
+      _getOptionValue(_RawSocketOptions.IP_MULTICAST_IF.index);
+
+  /// Socket level option for IPPROTO_IPV6.
+  static int get levelIPv6 =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_IPV6.index);
+
+  /// Socket option for IPV6_MULTICAST_IF.
+  static int get IPv6MulticastInterface =>
+      _getOptionValue(_RawSocketOptions.IPV6_MULTICAST_IF.index);
+
+  /// Socket level option for IPPROTO_TCP.
+  static int get levelTcp =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_TCP.index);
+
+  /// Socket level option for IPPROTO_UDP.
+  static int get levelUdp =>
+      _getOptionValue(_RawSocketOptions.IPPROTO_UDP.index);
+
+  external static int _getOptionValue(int key);
+}
+
 /**
  * Events for the [RawSocket].
  */
@@ -573,6 +676,24 @@
    * Returns [:true:] if the option was set successfully, false otherwise.
    */
   bool setOption(SocketOption option, bool enabled);
+
+  /**
+   * Use [getRawOption] to get low level information about the [RawSocket]. See
+   * [RawSocketOption] for available options.
+   *
+   * Returns the [RawSocketOption.value] on success.
+   *
+   * Throws an [OSError] on failure.
+   */
+  Uint8List getRawOption(RawSocketOption option);
+
+  /**
+   * Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
+   * available options.
+   *
+   * Throws an [OSError] on failure.
+   */
+  void setRawOption(RawSocketOption option);
 }
 
 /**
@@ -653,6 +774,24 @@
   bool setOption(SocketOption option, bool enabled);
 
   /**
+   * Use [getRawOption] to get low level information about the [RawSocket]. See
+   * [RawSocketOption] for available options.
+   *
+   * Returns the [RawSocketOption.value] on success.
+   *
+   * Throws an [OSError] on failure.
+   */
+  Uint8List getRawOption(RawSocketOption option);
+
+  /**
+   * Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
+   * available options.
+   *
+   * Throws an [OSError] on failure.
+   */
+  void setRawOption(RawSocketOption option);
+
+  /**
    * Returns the port used by this socket.
    */
   int get port;
@@ -739,6 +878,8 @@
    *
    * By default this value is `null`
    */
+  @Deprecated("This property is not implemented. Use getRawOption and "
+      "setRawOption instead.")
   NetworkInterface multicastInterface;
 
   /**
@@ -805,6 +946,24 @@
    * exception is thrown.
    */
   void leaveMulticast(InternetAddress group, [NetworkInterface interface]);
+
+  /**
+   * Use [getRawOption] to get low level information about the [RawSocket]. See
+   * [RawSocketOption] for available options.
+   *
+   * Returns [RawSocketOption.value] on success.
+   *
+   * Throws an [OSError] on failure.
+   */
+  Uint8List getRawOption(RawSocketOption option);
+
+  /**
+   * Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
+   * available options.
+   *
+   * Throws an [OSError] on failure.
+   */
+  void setRawOption(RawSocketOption option);
 }
 
 class SocketException implements IOException {
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index db0bf0c..9b239ff 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -63,6 +63,14 @@
         ],
         "uri": "collection/collection.dart"
       },
+      "ffi": {
+        "patches": [
+          "../../runtime/lib/ffi_dynamic_library_patch.dart",
+          "../../runtime/lib/ffi_native_type_patch.dart",
+          "../../runtime/lib/ffi_patch.dart"
+        ],
+        "uri": "ffi/ffi.dart"
+      },
       "typed_data": {
         "patches": "../../runtime/lib/typed_data_patch.dart",
         "uri": "typed_data/typed_data.dart"
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index e2d0f7c..a53b69a 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -87,6 +87,13 @@
         - "../../runtime/lib/profiler.dart"
         - "../../runtime/lib/timeline.dart"
 
+    ffi:
+      uri: "ffi/ffi.dart"
+      patches:
+        - "../../runtime/lib/ffi_dynamic_library_patch.dart"
+        - "../../runtime/lib/ffi_native_type_patch.dart"
+        - "../../runtime/lib/ffi_patch.dart"
+
     _http:
       uri: "_http/http.dart"
 
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index fdd5a68..7966fd7 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -3021,6 +3021,7 @@
   static const EventStreamProvider<MouseEvent> contextMenuEvent =
       const EventStreamProvider<MouseEvent>('contextmenu');
 
+  @DomName('SVGElement.dblclickEvent')
   static const EventStreamProvider<Event> doubleClickEvent =
       const EventStreamProvider<Event>('dblclick');
 
@@ -3215,6 +3216,7 @@
   ElementStream<MouseEvent> get onContextMenu =>
       contextMenuEvent.forElement(this);
 
+  @DomName('SVGElement.ondblclick')
   ElementStream<Event> get onDoubleClick => doubleClickEvent.forElement(this);
 
   ElementStream<MouseEvent> get onDrag => dragEvent.forElement(this);
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index cce7a93..0f703f9 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -80,6 +80,7 @@
 
   final String version;
 
+  @JSName('changeVersion')
   /**
    * Atomically update the database version to [newVersion], asynchronously
    * running [callback] on the [SqlTransaction] representing this
@@ -94,15 +95,52 @@
    *
    * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.
    */
-  void changeVersion(String oldVersion, String newVersion,
+  void _changeVersion(String oldVersion, String newVersion,
       [SqlTransactionCallback callback,
       SqlTransactionErrorCallback errorCallback,
       VoidCallback successCallback]) native;
 
-  void readTransaction(SqlTransactionCallback callback,
+  @JSName('changeVersion')
+  /**
+   * Atomically update the database version to [newVersion], asynchronously
+   * running [callback] on the [SqlTransaction] representing this
+   * [changeVersion] transaction.
+   *
+   * If [callback] runs successfully, then [successCallback] is called.
+   * Otherwise, [errorCallback] is called.
+   *
+   * [oldVersion] should match the database's current [version] exactly.
+   *
+   * See also:
+   *
+   * * [Database.changeVersion](http://www.w3.org/TR/webdatabase/#dom-database-changeversion) from W3C.
+   */
+  Future<SqlTransaction> changeVersion(String oldVersion, String newVersion) {
+    var completer = new Completer<SqlTransaction>();
+    _changeVersion(oldVersion, newVersion, (value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
+  @JSName('readTransaction')
+  void _readTransaction(SqlTransactionCallback callback,
       [SqlTransactionErrorCallback errorCallback,
       VoidCallback successCallback]) native;
 
+  @JSName('readTransaction')
+  Future<SqlTransaction> readTransaction() {
+    var completer = new Completer<SqlTransaction>();
+    _readTransaction((value) {
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
+
   void transaction(SqlTransactionCallback callback,
       [SqlTransactionErrorCallback errorCallback,
       VoidCallback successCallback]) native;
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
index 9de243e..108c0ed 100644
--- a/tests/co19_2/co19_2-analyzer.status
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -3,15 +3,15 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2analyzer ]
-Language/Classes/Abstract_Instance_Members/override_default_value_t01: MissingCompileTimeError # Issue 33995
-Language/Classes/Abstract_Instance_Members/override_default_value_t02: MissingCompileTimeError # Issue 33995
-Language/Classes/Abstract_Instance_Members/override_default_value_t03: MissingCompileTimeError # Issue 33995
-Language/Classes/Abstract_Instance_Members/override_default_value_t04: MissingCompileTimeError # Issue 33995
-Language/Classes/Abstract_Instance_Members/override_default_value_t05: MissingCompileTimeError # Issue 33995
+Language/Classes/Abstract_Instance_Members/override_default_value_t01: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
+Language/Classes/Abstract_Instance_Members/override_default_value_t02: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
+Language/Classes/Abstract_Instance_Members/override_default_value_t03: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
+Language/Classes/Abstract_Instance_Members/override_default_value_t04: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
+Language/Classes/Abstract_Instance_Members/override_default_value_t05: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
 Language/Classes/Getters/type_object_t01: CompileTimeError # Issue 33995
 Language/Classes/Getters/type_object_t02: CompileTimeError # Issue 33995
-Language/Classes/Instance_Methods/override_different_default_values_t01: MissingCompileTimeError # Issue 33995
-Language/Classes/Instance_Methods/override_different_default_values_t02: MissingCompileTimeError # Issue 33995
+Language/Classes/Instance_Methods/override_different_default_values_t01: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
+Language/Classes/Instance_Methods/override_different_default_values_t02: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
 Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Invalid test, see #33237
 Language/Classes/method_definition_t06: MissingCompileTimeError # Please triage this failure
 Language/Enums/syntax_t08: CompileTimeError # Issue 33995
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index a5c9730..a4d8adc 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -14,3 +14,322 @@
 LayoutTests/*: SkipByDesign # d8 is not a browser
 LibTest/html/*: SkipByDesign # d8 is not a browser
 WebPlatformTest/*: SkipByDesign # d8 is not a browser
+
+[ $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/Types/Interface_Types/subtype_t27: Skip # Times out
+Language/Types/Interface_Types/subtype_t28: Skip # Times out
+LayoutTests/fast/backgrounds/001_t01: Skip # Times out
+LayoutTests/fast/backgrounds/animated-gif-as-background_t01: Skip # Times out
+LayoutTests/fast/backgrounds/multiple-backgrounds-assert_t01: Skip # Times out
+LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: Skip # Times out
+LayoutTests/fast/canvas/DrawImageSinglePixelStretch_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-before-css_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-alpha_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-canvas_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-image_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-css-crazy_t01: Skip # Times out
+LayoutTests/fast/canvas/canvas-imageSmoothingEnabled-repaint_t01: Skip # Times out
+LayoutTests/fast/canvas/drawImage-with-valid-image_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/texture-color-profile_t01: Skip # Times out
+LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/inline-splitting-with-after-float-crash_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Times out
+LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/auto-content-resolution-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/breadth-size-resolution-grid_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/calc-resolution-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/display-grid-set-get_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/flex-and-minmax-content-resolution-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/flex-content-resolution-columns_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/flex-content-resolution-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-auto-columns-rows-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-auto-flow-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-auto-flow-update_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-container-change-explicit-grid-recompute-child_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-bad-cast-addchild_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-border-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-border-padding-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-empty-row-column_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-min-max-height_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-padding-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-padding-margin_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-remove-svg-child_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-element-shrink-to-fit_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-area-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-bad-named-area-auto-placement_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-bad-resolution-double-span_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-change-order-auto-flow_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-display_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-horiz-bt_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-lr_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows-vert-rl_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-auto-columns-rows_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-margin-resolution_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-item-order-auto-flow-resolution_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-strict-ordering-crash_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/grid-template-areas-get-set_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/implicit-rows-auto-resolution_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/justify-self-cell_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-height-only_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/minmax-fixed-logical-width-only_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-in-percent-grid_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track-update_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-grid-item-in-percent-grid-track_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item-update_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: Skip # Times out
+LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/tables_t01: Skip # Times out
+LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: Skip # Times out
+LayoutTests/fast/css/cached-sheet-restore-crash_t01: Skip # Times out
+LayoutTests/fast/css/comment-before-charset-external_t01: Skip # Times out
+LayoutTests/fast/css/comment-before-charset_t01: Skip # Times out
+LayoutTests/fast/css/counters/asterisk-counter-update-after-layout-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/complex-before_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-before-selector-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-reparent-table-children-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-reset-subtree-insert-crash_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-ruby-text-cleared_t01: Skip # Times out
+LayoutTests/fast/css/counters/counter-traverse-object-crash_t01: Skip # Times out
+LayoutTests/fast/css/font-face-svg-decoding-error_t01: Skip # Times out
+LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: Skip # Times out
+LayoutTests/fast/css/implicit-attach-marking_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-1_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-2_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-3_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-4_t01: Skip # Times out
+LayoutTests/fast/css/link-alternate-stylesheet-5_t01: Skip # Times out
+LayoutTests/fast/css/link-disabled-attr-parser_t01: Skip # Times out
+LayoutTests/fast/css/nested-at-rules_t01: Skip # Times out
+LayoutTests/fast/css/percent-min-width-img-src-change_t01: Skip # Times out
+LayoutTests/fast/css/percent-width-img-src-change_t01: Skip # Times out
+LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out
+LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out
+LayoutTests/fast/css/remove-fixed-resizer-crash_t01: Skip # Times out
+LayoutTests/fast/css/sheet-collection-link_t01: Skip # Times out
+LayoutTests/fast/css/sheet-title_t01: Skip # Times out
+LayoutTests/fast/css/space-before-charset-external_t01: Skip # Times out
+LayoutTests/fast/css/space-before-charset_t01: Skip # Times out
+LayoutTests/fast/css/sticky/remove-inline-sticky-crash_t01: Skip # Times out
+LayoutTests/fast/css/sticky/remove-sticky-crash_t01: Skip # Times out
+LayoutTests/fast/css/sticky/sticky-table-col-crash_t01: Skip # Times out
+LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-first-alternate-link_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-link_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: Skip # Times out
+LayoutTests/fast/css/stylesheet-parentStyleSheet_t01: Skip # Times out
+LayoutTests/fast/css/webkit-keyframes-crash_t01: Skip # Times out
+LayoutTests/fast/css/webkit-marquee-speed-unit-in-quirksmode_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLDocument/active-element-gets-unforcusable_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLDocument/set-focus-on-valid-element_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLImageElement/image-loading-gc_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLImageElement/image-natural-width-height_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-onload-before-page-load_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/link-onload2_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/onload-completion-test_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/prefetch-onload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/defer-onbeforeload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/defer-script-invalid-url_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/dont-load-unknown-type_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/remove-source_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-for-attribute-unexpected-execution_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-load-events_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-reexecution_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLStyleElement/style-onload-before-page-load_t01: Skip # Times out
+LayoutTests/fast/dom/HTMLTemplateElement/innerHTML-inert_t01: Skip # Times out
+LayoutTests/fast/dom/SelectorAPI/bug-17313_t01: Skip # Times out
+LayoutTests/fast/dom/StyleSheet/detached-style-2_t01: Skip # Times out
+LayoutTests/fast/dom/StyleSheet/detached-style_t01: Skip # Times out
+LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Times out
+LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Times out
+LayoutTests/fast/dom/css-insert-import-rule-twice_t01: Skip # Times out
+LayoutTests/fast/dom/css-insert-import-rule_t01: Skip # Times out
+LayoutTests/fast/dom/css-mediarule-deleteRule-update_t01: Skip # Times out
+LayoutTests/fast/dom/css-mediarule-insertRule-update_t01: Skip # Times out
+LayoutTests/fast/dom/domtimestamp-is-number_t01: Skip # Times out
+LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Times out
+LayoutTests/fast/dom/gc-image-element-2_t01: Skip # Times out
+LayoutTests/fast/dom/gc-image-element_t01: Skip # Times out
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: Skip # Times out
+LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: Skip # Times out
+LayoutTests/fast/dom/icon-url-change_t01: Skip # Times out
+LayoutTests/fast/dom/icon-url-list_t01: Skip # Times out
+LayoutTests/fast/dom/id-attribute-with-namespace-crash_t01: Skip # Times out
+LayoutTests/fast/dom/image-object_t01: Skip # Times out
+LayoutTests/fast/dom/inner-text_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/link-in-shadow-tree_t01: Skip # Times out
+LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: Skip # Times out
+LayoutTests/fast/dom/text-node-attach-crash_t01: Skip # Times out
+LayoutTests/fast/dom/vertical-scrollbar-when-dir-change_t01: Skip # Times out
+LayoutTests/fast/dynamic/continuation-detach-crash_t01: Skip # Times out
+LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Skip # Times out
+LayoutTests/fast/events/clipboard-clearData_t01: Skip # Times out
+LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Times out
+LayoutTests/fast/events/dispatch-event-being-dispatched_t01: Skip # Times out
+LayoutTests/fast/events/document-elementFromPoint_t01: Skip # Times out
+LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Times out
+LayoutTests/fast/events/no-window-load_t01: Skip # Times out
+LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: Skip # Times out
+LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Skip # Times out
+LayoutTests/fast/events/window-load-capture_t01: Skip # Times out
+LayoutTests/fast/flexbox/crash-flexbox-no-layout-child_t01: Skip # Times out
+LayoutTests/fast/flexbox/layoutHorizontalBox-crash_t01: Skip # Times out
+LayoutTests/fast/flexbox/overhanging-floats-not-removed-crash_t01: Skip # Times out
+LayoutTests/fast/forms/HTMLOptionElement_selected_t01: Skip # Times out
+LayoutTests/fast/forms/activate-and-disabled-elements_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out
+LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out
+LayoutTests/fast/forms/button/button-disabled-blur_t01: Skip # Times out
+LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out
+LayoutTests/fast/forms/form-added-to-table_t01: Skip # Times out
+LayoutTests/fast/forms/input-type-change_t01: Skip # Times out
+LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: Skip # Times out
+LayoutTests/fast/forms/input-width-height-attributes-without-renderer_t01: Skip # Times out
+LayoutTests/fast/forms/search-popup-crasher_t01: Skip # Times out
+LayoutTests/fast/forms/select-change-popup-to-listbox-in-event-handler_t01: Skip # Times out
+LayoutTests/fast/forms/select-generated-content_t01: Skip # Times out
+LayoutTests/fast/forms/textarea-placeholder-relayout-assertion_t01: Skip # Times out
+LayoutTests/fast/forms/textarea-scrollbar-height_t01: Skip # Times out
+LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out
+LayoutTests/fast/html/imports/import-element-removed-flag_t01: Skip # Times out
+LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out
+LayoutTests/fast/loader/about-blank-hash-kept_t01: Skip # Times out
+LayoutTests/fast/loader/hashchange-event-async_t01: Skip # Times out
+LayoutTests/fast/loader/hashchange-event-properties_t01: Skip # Times out
+LayoutTests/fast/loader/local-css-allowed-in-strict-mode_t01: Skip # Times out
+LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out
+LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Skip # Times out
+LayoutTests/fast/loader/scroll-position-restored-on-back_t01: Skip # Times out
+LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out
+LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: Skip # Times out
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Skip # Times out
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Skip # Times out
+LayoutTests/fast/replaced/table-percent-height-text-controls_t01: Skip # Times out
+LayoutTests/fast/replaced/table-percent-height_t01: Skip # Times out
+LayoutTests/fast/replaced/table-percent-width_t01: Skip # Times out
+LayoutTests/fast/replaced/table-replaced-element_t01: Skip # Times out
+LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: Skip # Times out
+LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Skip # Times out
+LayoutTests/fast/sub-pixel/float-list-inside_t01: 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
+WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out
+WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # Times out
+WebPlatformTest/dom/nodes/Node-isEqualNode_t01: Skip # Times out
+WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_key_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_newvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_oldvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_storagearea_t01: Skip # Times out
+WebPlatformTest/webstorage/event_local_url_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_key_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_newvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_oldvalue_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_storagearea_t01: Skip # Times out
+WebPlatformTest/webstorage/event_session_url_t01: Skip # Times out
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index b620f62..717b34e4 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -2,6 +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.
 
+[ $compiler == dartk ]
+LanguageFeatures/Set-literals/semantics_A05_t02: RuntimeError
+LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError
+
 [ $compiler == dartkp ]
 Language/Expressions/Instance_Creation/New/evaluation_t20: RuntimeError
 Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: DartkCrash
@@ -14,13 +18,25 @@
 Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError
 Language/Types/Interface_Types/subtype_t03: RuntimeError
 Language/Types/Interface_Types/subtype_t26: RuntimeError
+LanguageFeatures/Constant_update2018/CastOperator_A03_t01/none: RuntimeError
+LanguageFeatures/Constant_update2018/CastOperator_A03_t03/none: RuntimeError
+LanguageFeatures/Constant_update2018/EqualityOperator_A01_t01: RuntimeError
+LanguageFeatures/Constant_update2018/EqualityOperator_A01_t02: RuntimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t03/none: RuntimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t06/none: RuntimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t09/none: RuntimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t02: RuntimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t04: RuntimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t05/none: RuntimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t06/none: RuntimeError
+LanguageFeatures/Set-literals/semantics_A05_t02: RuntimeError
+LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError
 LanguageFeatures/Subtyping/static/generated/left_bottom_global_variable_A02_t01: DartkCrash
 LanguageFeatures/Subtyping/static/generated/left_promoted_variable_global_variable_A02_t01: DartkCrash
-LibTest/async/Stream/Stream.periodic_A02_t01: RuntimeError
 LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t02: RuntimeError
 LibTest/core/StackOverflowError/stackTrace_A01_t02: RuntimeError
 LibTest/core/Uri/Uri.dataFromString_A01_t01: RuntimeError
-LibTest/core/double/round_A01_t03: RuntimeError
 LibTest/io/Cookie/Cookie_A01_t02: RuntimeError
 LibTest/io/File/openRead_A01_t04: RuntimeError
 LibTest/io/HttpClientRequest/addStream_A02_t02: RuntimeError
@@ -56,55 +72,8 @@
 [ $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_update2018/*: Crash, Pass # Please triage these failures
-LanguageFeatures/Set-literals/constant_set_literals_A02_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/03: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/04: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A02_t03/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A02_t03/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A02_t03/03: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A03_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/03: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/04: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/05: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/06: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/07: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/08: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/09: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t01/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t01/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t01/04: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/05: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/06: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/08: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/non_constant_set_literals_A01_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/non_constant_set_literals_A02_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/semantics_A04_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/semantics_A01_t01/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/semantics_A01_t01/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/semantics_A01_t01/09: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/semantics_A01_t01/10: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/semantics_A05_t01: Pass
-LanguageFeatures/Set-literals/semantics_A05_t05/01: MissingCompileTimeError # Exact types
-LanguageFeatures/Set-literals/semantics_A05_t05/02: MissingCompileTimeError # Exact types
-LanguageFeatures/Set-literals/semantics_A05_t05/03: MissingCompileTimeError # Exact types
-LanguageFeatures/Set-literals/set_literals_A01_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/set_literals_A02_t01: Pass # CompileTimeError on $fasta
-LanguageFeatures/Set-literals/set_literals_A04_t02/01: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/02: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/03: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/04: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/05: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/11: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/12: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/set_literals_A04_t02/13: MissingCompileTimeError # Issue 35608
-LanguageFeatures/Set-literals/syntax_compatibility_A01_t01: Pass # CompileTimeError on $fasta
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: Crash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t04: Crash
 
 [ $runtime == vm ]
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Slow # Does many calls
@@ -122,18 +91,6 @@
 LibTest/io/RawDatagramSocket/timeout_A02_t01: Pass, Fail # Issue https://github.com/dart-lang/co19/issues/170
 LibTest/io/RawDatagramSocket/timeout_A06_t01: Pass, Fail # Next roll might fix it (see https://github.com/dart-lang/co19/commit/8b2e2be5bc3bb9fec41efec8ac6fc777e231d915)
 LibTest/io/RawDatagramSocket/where_A01_t01: Pass, Fail # Issue https://github.com/dart-lang/co19/issues/170
-LibTest/io/Stdin/first_A04_t01: Pass, Fail # Issue https://github.com/dart-lang/co19/issues/193
-LibTest/io/Stdin/last_A02_t01: Pass, Fail # Issue https://github.com/dart-lang/co19/issues/182
-LibTest/io/Stdout/add_A02_t03: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/add_A02_t04: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/add_A02_t05: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/add_A02_t06: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/add_A02_t07: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/add_A02_t08: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/add_A02_t09: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/writeCharCode_A01_t03: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/write_A01_t04: Skip # https://github.com/dart-lang/co19/pull/204
-LibTest/io/Stdout/write_A01_t05: Skip # https://github.com/dart-lang/co19/pull/204
 
 [ $fasta ]
 Language/Classes/Abstract_Instance_Members/override_default_value_t01: MissingCompileTimeError # Issue 34190
@@ -233,29 +190,78 @@
 Language/Statements/Continue/label_t07: MissingCompileTimeError # Issue 34206
 Language/Statements/Try/catch_scope_t01: CompileTimeError
 Language/Types/Interface_Types/subtype_t30: CompileTimeError
-LanguageFeatures/Constant_update2018/CastOperator_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/CastOperator_A02_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/CastOperator_A02_t02: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/CastOperator_A03_t01/none: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/CastOperator_A03_t02/none: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/NewOperators_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/NewOperators_A01_t02: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t02: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t03: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t03: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t05: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A04_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A04_t02: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t02: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t03/none: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t04/none: CompileTimeError # This feature is not implemented yet
+LanguageFeatures/Constant_update2018/CastOperator_A01_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/CastOperator_A02_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/CastOperator_A02_t02: CompileTimeError
+LanguageFeatures/Constant_update2018/CastOperator_A03_t02/none: CompileTimeError
+LanguageFeatures/Constant_update2018/CastOperator_A04_t01/none: CompileTimeError
+LanguageFeatures/Constant_update2018/CastOperator_A04_t02/none: CompileTimeError
+LanguageFeatures/Constant_update2018/EqualityOperator_A01_t03/none: CompileTimeError
+LanguageFeatures/Constant_update2018/EqualityOperator_A01_t04/none: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A01_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A01_t02: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t02: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t04: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t05: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t07: CompileTimeError
+LanguageFeatures/Constant_update2018/NewOperators_A02_t08: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t02/none: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t03: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t05/none: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t02/none: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t03: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t05/none: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A04_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A04_t02: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A04_t03/none: CompileTimeError
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A04_t04/none: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t02: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t01/none: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t02/none: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t03/none: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t04/none: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t01/none: CompileTimeError
+LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t02/none: CompileTimeError
+LanguageFeatures/Control-flow-collections/scoping_A01_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/scoping_A02_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A01_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A02_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A03_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A04_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A05_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A06_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A07_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A08_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A09_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A10_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_errors_A11_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_semantics_A01_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_semantics_A01_t02: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_semantics_A02_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/static_semantics_A02_t02: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/syntax_A01_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/syntax_A01_t02: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/syntax_A01_t03: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/syntax_A02_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/syntax_A02_t02: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/syntax_A03_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A01_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A02_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A03_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A04_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A05_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A06_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A07_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_inference_A08_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_promotion_A01_t01: CompileTimeError, Crash, Pass # This feature is not implemented yet
+LanguageFeatures/Control-flow-collections/type_promotion_A01_t02: CompileTimeError, Crash, Pass # This feature is not implemented yet
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t02: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash
@@ -286,6 +292,7 @@
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/02: Crash, Pass
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/none: Crash
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t02/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t03/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/01: Crash, Pass
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t04/none: Crash, Pass
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l2_t06/none: CompileTimeError
@@ -332,6 +339,7 @@
 LanguageFeatures/Instantiate-to-bound/typedef/dynamic/typedef_typedef_l1_t06: RuntimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_FutureOr_l1_t02/none: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t02/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t03/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t04/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t04/02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t04/03: MissingCompileTimeError
@@ -340,6 +348,7 @@
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t04/06: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t04/07: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t07/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t08/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t09/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t09/02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t09/03: MissingCompileTimeError
@@ -347,22 +356,127 @@
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t09/05: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t09/06: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t09/07: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t04: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l1_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t01/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t02/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t03/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t04/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t05/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t06/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t07/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t08/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t09/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t11/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t12/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t13/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t16/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t19/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_01_t20/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t01/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t02/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t03/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t04/none: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t05/none: CompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t12: CompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t13: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t06/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t07/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t08/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t09/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t11/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t12/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t13/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t16/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t19/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_02_t20/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t01/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t02/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t03/none: CompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t05: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t04/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t05/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t06/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t07/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t08/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t09/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t10: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t11: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t12/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t13/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t16/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t19/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_03_t20/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t01/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t02/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t03/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t04/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t05/none: CompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t05: CompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t04: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t06/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t07/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t08/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t09/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t11/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t12/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t13/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t16/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t19/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_04_t20/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t01/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t02/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t03/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t04/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t05/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t06/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t07/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t08/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t09/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t11/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t12/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t13/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t16/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t19/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_05_t20/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t01/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t02/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t03/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t04/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t05/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t06/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t07/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t08/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t09/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t11/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t12/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t13/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t16/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t19/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_06_t20/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_t01/none: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_t02/none: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_l2_t06/none: CompileTimeError
@@ -378,6 +492,7 @@
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t04/07: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t05/none: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t06/none: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t07/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t08/01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t08/02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t08/03: MissingCompileTimeError
@@ -385,25 +500,32 @@
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t08/05: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t08/06: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t08/07: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/constant_set_literals_A03_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/constant_set_literals_A04_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t03: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/non_constant_set_literals_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/non_constant_set_literals_A02_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/semantics_A04_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/semantics_A05_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/semantics_A05_t02: RuntimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/set_literals_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/set_literals_A02_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/set_literals_A04_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/syntax_compatibility_A01_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: CompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t09/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t10/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t11/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t13/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t14/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t15/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t17/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t18/01: MissingCompileTimeError
+LanguageFeatures/Instantiate-to-bound/typedef/static/typedef_typedef_l1_t19/01: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t02/01: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t02/02: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t02/03: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t02/04: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t03/01: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t03/02: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t03/03: MissingCompileTimeError
+LanguageFeatures/Set-literals/exact_types_of_literals_A01_t03: CompileTimeError
+LanguageFeatures/Set-literals/semantics_A05_t01: CompileTimeError
+LanguageFeatures/Set-literals/set_literals_A04_t01: CompileTimeError
 LanguageFeatures/Simple-bounds/dynamic/class_FutureOr_l1_t02: CompileTimeError
-LanguageFeatures/Simple-bounds/static/class_FutureOr_l1_t02: CompileTimeError
+LanguageFeatures/Simple-bounds/static/class_FutureOr_l1_t02/none: CompileTimeError
 LanguageFeatures/Simple-bounds/static/typedef_FutureOr_l1_t02/none: CompileTimeError
 LanguageFeatures/Simple-bounds/static/typedef_l1_t07/none: CompileTimeError
 LanguageFeatures/Simple-bounds/static/typedef_l2_t02/none: CompileTimeError
+LanguageFeatures/Simple-bounds/static/typedef_typedef_l1_t04/01: MissingCompileTimeError
+LanguageFeatures/Simple-bounds/static/typedef_typedef_l1_t04/02: MissingCompileTimeError
 LanguageFeatures/Simple-bounds/static/typedef_typedef_l1_t10: CompileTimeError
 LanguageFeatures/Super-mixins/covariance_t03: MissingCompileTimeError # Issue 35111
 LanguageFeatures/Super-mixins/covariance_t06: MissingCompileTimeError # Issue 35111
@@ -415,9 +537,14 @@
 LanguageFeatures/regression/34635_t03: CompileTimeError
 LanguageFeatures/regression/34803_t01: Crash
 LanguageFeatures/regression/34803_t02: Crash
-LibTest/async/Future/Future_A01_t01: CompileTimeError
 
 [ $arch == simdbc64 && $compiler == dartk ]
+LanguageFeatures/Constant_update2018/NewOperators_A02_t01: Pass
+LanguageFeatures/Constant_update2018/NewOperators_A02_t02: Pass
+LanguageFeatures/Constant_update2018/NewOperators_A02_t04: Pass
+LanguageFeatures/Constant_update2018/NewOperators_A02_t05: Pass
+LanguageFeatures/Constant_update2018/NewOperators_A02_t07: Pass
+LanguageFeatures/Constant_update2018/NewOperators_A02_t08: Pass
 LibTest/collection/ListBase/ListBase_class_A01_t02: Crash # Issue http://dartbug.com/35242
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Crash # Issue http://dartbug.com/35242
 LibTest/core/List/List_class_A01_t02: Crash # Issue http://dartbug.com/35242
@@ -434,6 +561,7 @@
 LibTest/io/Stdout/writeCharCode_A01_t03: Timeout, Pass
 
 [ $arch == simdbc64 && ($compiler == dartk || $compiler == dartkb) ]
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: CompileTimeError
 LibTest/collection/ListBase/ListBase_class_A01_t02: Timeout, Pass # https://github.com/dart-lang/sdk/issues/35316 as well?
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Timeout, Pass # https://github.com/dart-lang/sdk/issues/35316 as well?
 LibTest/io/Link/renameSync_A02_t01: RuntimeError, Pass
@@ -498,6 +626,9 @@
 LibTest/isolate/Isolate/ping_A03_t02: RuntimeError, Pass
 LibTest/isolate/Isolate/removeErrorListener_A02_t01: Crash, Pass
 
+[ $arch != simdbc64 && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t03: CompileTimeError
+
 [ $compiler != dart2js && $runtime != vm && $fasta ]
 Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError # Issue 34191
 Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError # Issue 34191
@@ -516,6 +647,23 @@
 Language/Statements/Switch/equal_operator_t01: MissingCompileTimeError # Issue 32557
 Language/Statements/Switch/equal_operator_t02: MissingCompileTimeError # Issue 32557
 
+[ $compiler != dartkp && $fasta ]
+LanguageFeatures/Set-literals/constant_set_literals_A02_t04/01: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t04/02: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t04/03: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t04/04: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t04/05: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A02_t04/06: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/01: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/02: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/03: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/04: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/05: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/06: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/07: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/08: MissingCompileTimeError
+LanguageFeatures/Set-literals/constant_set_literals_A05_t01/09: MissingCompileTimeError
+
 [ $mode == debug && $runtime == vm && $system == linux && ($compiler == dartk || $compiler == dartkb) ]
 LibTest/io/Stdin/readByteSync_A02_t01: RuntimeError, Pass
 LibTest/io/WebSocket/pingInterval_A01_t01: RuntimeError, Pass
@@ -688,13 +836,38 @@
 LibTest/io/RawDatagramSocket/receive_A02_t02: RuntimeError
 
 [ $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
-Language/Classes/definition_t23: CompileTimeError
 Language/Expressions/Constants/exception_t02/01: MissingRuntimeError
 Language/Expressions/Function_Invocation/async_invokation_t02: RuntimeError
 Language/Expressions/Logical_Boolean_Expressions/syntax_t01: RuntimeError
-Language/Mixins/Mixin_Application/syntax_t16: CompileTimeError
 Language/Statements/Assert/execution_t08: RuntimeError
 Language/Types/Function_Types/call_t01: RuntimeError
+LanguageFeatures/Constant_update2018/CastOperator_A01_t01: DartkCrash
+LanguageFeatures/Constant_update2018/CastOperator_A02_t01: DartkCrash
+LanguageFeatures/Constant_update2018/CastOperator_A02_t02: DartkCrash
+LanguageFeatures/Constant_update2018/CastOperator_A03_t01/02: Pass
+LanguageFeatures/Constant_update2018/CastOperator_A03_t01/03: Pass
+LanguageFeatures/Constant_update2018/CastOperator_A04_t01: Pass
+LanguageFeatures/Constant_update2018/EqualityOperator_A01_t03: Pass
+LanguageFeatures/Constant_update2018/EqualityOperator_A01_t04: Pass
+LanguageFeatures/Constant_update2018/NewOperators_A01_t01: DartkCrash
+LanguageFeatures/Constant_update2018/NewOperators_A01_t02: DartkCrash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t01: Fail
+LanguageFeatures/Constant_update2018/NewOperators_A02_t02: DartkCrash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t04: Fail
+LanguageFeatures/Constant_update2018/NewOperators_A02_t05: DartkCrash
+LanguageFeatures/Constant_update2018/NewOperators_A02_t07: Fail
+LanguageFeatures/Constant_update2018/NewOperators_A02_t08: DartkCrash
+LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t05: Pass
+LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: DartkCrash
+LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: DartkCrash
+LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: DartkCrash
+LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t02: DartkCrash
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t01: Pass
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t02: Pass
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t03/01: Pass
+LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t04/01: Pass
+LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t01: Pass
+LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t02: Pass
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_typedef_l2_t06: RuntimeError
 LanguageFeatures/Instantiate-to-bound/class/static/class_FutureOr_l1_t04/none: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t04/none: CompileTimeError
@@ -748,9 +921,7 @@
 LanguageFeatures/regression/33701_t01: MissingCompileTimeError
 LanguageFeatures/regression/34803_t01: DartkCrash
 LanguageFeatures/regression/34803_t02: DartkCrash
-LibTest/async/Stream/Stream.fromFutures_A04_t01: RuntimeError
 LibTest/async/Stream/Stream.fromIterable_A02_t01: RuntimeError
-LibTest/async/StreamController/addStream_A03_t01: RuntimeError
 LibTest/async/StreamSink/addStream_A01_t02: RuntimeError
 LibTest/core/Function/Function_class_A01_t01: RuntimeError
 LibTest/io/Cookie/Cookie_A01_t04: RuntimeError
@@ -817,93 +988,6 @@
 LibTest/isolate/ReceivePort/firstWhere_A02_t01: RuntimeError
 LibTest/isolate/ReceivePort/transform_A01_t01: RuntimeError
 
-[ $runtime == vm && $arch != simdbc64 && ($compiler == dartk || $compiler == dartkb) ]
-LanguageFeatures/Constant_update2018/CastOperator_A01_t01: DartkCrash
-LanguageFeatures/Constant_update2018/CastOperator_A02_t01: DartkCrash
-LanguageFeatures/Constant_update2018/CastOperator_A02_t02: DartkCrash
-LanguageFeatures/Constant_update2018/CastOperator_A03_t01/02: Pass
-LanguageFeatures/Constant_update2018/CastOperator_A03_t01/03: Pass
-LanguageFeatures/Constant_update2018/CastOperator_A03_t02/01: DartkCrash
-LanguageFeatures/Constant_update2018/CastOperator_A04_t01: Pass
-LanguageFeatures/Constant_update2018/CastOperator_A04_t02: DartkCrash
-LanguageFeatures/Constant_update2018/EqualityOperator_A01_t03: DartkCrash
-LanguageFeatures/Constant_update2018/EqualityOperator_A01_t04: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A01_t01: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A01_t02: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A02_t01: Fail
-LanguageFeatures/Constant_update2018/NewOperators_A02_t02: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A02_t03: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A02_t04: Fail
-LanguageFeatures/Constant_update2018/NewOperators_A02_t05: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A02_t06: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A02_t07: Fail
-LanguageFeatures/Constant_update2018/NewOperators_A02_t08: DartkCrash
-LanguageFeatures/Constant_update2018/NewOperators_A02_t09: DartkCrash
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t02: DartkCrash
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A01_t05: DartkCrash
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t02: DartkCrash
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A02_t05: DartkCrash
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t05: DartkCrash
-LanguageFeatures/Constant_update2018/ShortCircuitOperators_A03_t06: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t01: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A01_t02: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t01: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A02_t02: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t01: Pass
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t02: Pass
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t03/01: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A03_t04/01: DartkCrash
-LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t01: Pass
-LanguageFeatures/Constant_update2018/TypeTestOperator_A04_t02: Pass
-LanguageFeatures/Set-literals/constant_set_literals_A02_t01: Pass
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/03: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t02/04: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t03/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t03/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A02_t03/03: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A03_t01: Pass
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/03: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/04: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/05: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/06: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/07: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/08: MissingCompileTimeError
-LanguageFeatures/Set-literals/constant_set_literals_A05_t01/09: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t01/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t01/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t01/04: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/05: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/06: MissingCompileTimeError
-LanguageFeatures/Set-literals/exact_types_of_literals_A01_t02/08: MissingCompileTimeError
-LanguageFeatures/Set-literals/non_constant_set_literals_A01_t01: Pass
-LanguageFeatures/Set-literals/non_constant_set_literals_A02_t01: RuntimeError
-LanguageFeatures/Set-literals/semantics_A01_t01/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A01_t01/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A01_t01/09: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A01_t01/10: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A04_t01: Pass
-LanguageFeatures/Set-literals/semantics_A05_t05/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A05_t05/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A05_t05/03: MissingCompileTimeError
-LanguageFeatures/Set-literals/semantics_A05_t01: RuntimeError
-LanguageFeatures/Set-literals/set_literals_A01_t01: Pass
-LanguageFeatures/Set-literals/set_literals_A02_t01: Pass
-LanguageFeatures/Set-literals/set_literals_A04_t02/01: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/02: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/03: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/04: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/05: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/11: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/12: MissingCompileTimeError
-LanguageFeatures/Set-literals/set_literals_A04_t02/13: MissingCompileTimeError
-LanguageFeatures/Set-literals/syntax_compatibility_A01_t01: Pass
-
 [ $runtime != vm && $fasta ]
 Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: MissingCompileTimeError # Issue 34192
 
@@ -1114,41 +1198,25 @@
 Language/Types/Type_Declarations/Typedef/dynamic_param_type_t02: RuntimeError
 Language/Variables/constant_initialization_t03: RuntimeError
 Language/Variables/constant_variable_t09: RuntimeError
+LanguageFeatures/Instantiate-to-bound/class/dynamic/class_typedef_l1_t02: RuntimeError
 LanguageFeatures/Instantiate-to-bound/typedef/dynamic/typedef_l1_t02: RuntimeError
 LanguageFeatures/Instantiate-to-bound/typedef/dynamic/typedef_l2_t01: RuntimeError
 LibTest/async/Future/asStream_A01_t02: RuntimeError
-LibTest/async/Stream/Stream.fromFutures_A04_t02: RuntimeError
 LibTest/async/Stream/Stream.fromFutures_A04_t03: RuntimeError
 LibTest/async/Stream/Stream.fromIterable_A03_t02: RuntimeError
-LibTest/async/Stream/Stream.periodic_A02_t01: RuntimeError
-LibTest/async/Stream/Stream.periodic_A03_t01: RuntimeError
-LibTest/async/Stream/Stream.periodic_A04_t02: RuntimeError
 LibTest/async/Stream/Stream.periodic_A04_t03: RuntimeError
 LibTest/async/StreamController/StreamController.broadcast_A03_t02: RuntimeError
-LibTest/async/StreamController/StreamController.broadcast_A09_t02: RuntimeError
 LibTest/async/StreamController/StreamController.broadcast_A09_t03: RuntimeError
-LibTest/async/StreamController/StreamController.broadcast_A10_t02: RuntimeError
 LibTest/async/StreamController/StreamController.broadcast_A10_t03: RuntimeError
 LibTest/async/StreamController/StreamController_A03_t03: RuntimeError
-LibTest/async/StreamController/stream_A02_t02: RuntimeError
 LibTest/async/StreamController/stream_A02_t03: RuntimeError
-LibTest/async/StreamController/stream_A03_t02: RuntimeError
 LibTest/async/StreamController/stream_A03_t03: RuntimeError
-LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t03: RuntimeError
-LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t04: RuntimeError
-LibTest/async/StreamTransformer/StreamTransformer_A01_t02: RuntimeError
-LibTest/async/StreamTransformer/StreamTransformer_A01_t03: RuntimeError
-LibTest/async/StreamTransformer/StreamTransformer_A02_t01: RuntimeError
-LibTest/async/StreamTransformer/StreamTransformer_A02_t02: RuntimeError
-LibTest/async/Zone/registerBinaryCallback_A01_t01: RuntimeError
 LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t02: RuntimeError
 LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t03: RuntimeError
 LibTest/collection/DoubleLinkedQueue/retainWhere_A02_t02: RuntimeError
 LibTest/collection/DoubleLinkedQueue/retainWhere_A02_t03: RuntimeError
-LibTest/convert/ByteConversionSink/ByteConversionSink.from_A01_t01: RuntimeError
 LibTest/convert/ByteConversionSink/ByteConversionSink_class_A01_t01: RuntimeError
 LibTest/convert/LineSplitter/fuse_A01_t01: RuntimeError
-LibTest/convert/StringConversionSink/StringConversionSink.from_A01_t01: RuntimeError
 LibTest/convert/StringConversionSink/asStringSink_A02_t01: RuntimeError
 LibTest/convert/StringConversionSink/asUtf8Sink_A02_t01: RuntimeError
 LibTest/convert/Utf8Codec/Utf8Codec_A01_t02: RuntimeError
@@ -1196,12 +1264,6 @@
 LibTest/core/UriData/isBase64_A01_t01: RuntimeError
 LibTest/core/UriData/parse_A01_t01: RuntimeError
 LibTest/core/UriData/toString_A01_t01: RuntimeError
-LibTest/core/double/ceil_A01_t04: RuntimeError
-LibTest/core/double/floor_A01_t04: RuntimeError
-LibTest/core/double/round_A01_t03: RuntimeError
-LibTest/core/double/toInt_A01_t05: RuntimeError
-LibTest/core/double/truncate_A01_t05: RuntimeError
-LibTest/core/int/toStringAsFixed_A03_t01: RuntimeError
 LibTest/io/CompressionOptions/DEFAULT_A01_t01: RuntimeError
 LibTest/io/Cookie/Cookie_A01_t01: RuntimeError
 LibTest/io/Cookie/Cookie_A01_t02: RuntimeError
@@ -1246,7 +1308,6 @@
 LibTest/io/HttpClientDigestCredentials/HttpClientDigestCredentials_A01_t01: RuntimeError
 LibTest/io/HttpClientRequest/addStream_A02_t02: RuntimeError
 LibTest/io/HttpClientRequest/add_A03_t01: RuntimeError
-LibTest/io/HttpClientRequest/close_A02_t01: RuntimeError
 LibTest/io/HttpClientRequest/done_A02_t01: RuntimeError, Timeout, Pass
 LibTest/io/HttpClientResponse/certificate_A01_t01: RuntimeError
 LibTest/io/HttpClientResponse/isRedirect_A01_t02: RuntimeError
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
index 3de7200..acb6832 100644
--- a/tests/co19_2/co19_2-runtime.status
+++ b/tests/co19_2/co19_2-runtime.status
@@ -9,7 +9,7 @@
 [ $compiler != dart2js && $runtime != none && $runtime != vm && !$checked ]
 LibTest/async/Future/catchError_A03_t05: RuntimeError
 
-[ $compiler == fasta || $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
+[ $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/allocator_analysis/kallocator_analysis_test.dart b/tests/compiler/dart2js/allocator_analysis/kallocator_analysis_test.dart
new file mode 100644
index 0000000..a4b8e88
--- /dev/null
+++ b/tests/compiler/dart2js/allocator_analysis/kallocator_analysis_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.
+
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/constants/values.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/ir/util.dart';
+import 'package:compiler/src/js_backend/allocator_analysis.dart';
+import 'package:compiler/src/kernel/kernel_strategy.dart';
+import 'package:compiler/src/util/features.dart';
+import 'package:kernel/ast.dart' as ir;
+import '../equivalence/id_equivalence.dart';
+import '../equivalence/id_equivalence_helper.dart';
+
+main(List<String> args) {
+  asyncTest(() async {
+    Directory dataDir = new Directory.fromUri(Platform.script.resolve('kdata'));
+    await checkTests(dataDir, const KAllocatorAnalysisDataComputer(),
+        args: args, testOmit: false, testFrontend: true);
+  });
+}
+
+class Tags {
+  static const String initialValue = 'initial';
+}
+
+class KAllocatorAnalysisDataComputer extends DataComputer<Features> {
+  const KAllocatorAnalysisDataComputer();
+
+  @override
+  void computeMemberData(Compiler compiler, MemberEntity member,
+      Map<Id, ActualData<Features>> actualMap,
+      {bool verbose: false}) {
+    if (member.isField) {
+      KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
+      KAllocatorAnalysis allocatorAnalysis =
+          compiler.backend.allocatorResolutionAnalysisForTesting;
+      ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
+      ConstantValue initialValue =
+          allocatorAnalysis.getFixedInitializerForTesting(member);
+      Features features = new Features();
+      if (initialValue != null) {
+        features[Tags.initialValue] = initialValue.toStructuredText();
+      }
+      Id id = computeEntityId(node);
+      actualMap[id] = new ActualData<Features>(
+          id, features, computeSourceSpanFromTreeNode(node), member);
+    }
+  }
+
+  @override
+  DataInterpreter<Features> get dataValidator =>
+      const FeaturesDataInterpreter();
+}
diff --git a/tests/compiler/dart2js/allocator_analysis/kdata/simple_initializers.dart b/tests/compiler/dart2js/allocator_analysis/kdata/simple_initializers.dart
new file mode 100644
index 0000000..be12d6c
--- /dev/null
+++ b/tests/compiler/dart2js/allocator_analysis/kdata/simple_initializers.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.
+
+main() {
+  new Class1();
+  new Class2();
+}
+
+const bool const1 = true;
+
+class Class1 {
+  /*element: Class1.field0:initial=NullConstant*/
+  var field0;
+
+  /*element: Class1.field1:initial=NullConstant*/
+  var field1 = null;
+
+  /*element: Class1.field2:initial=BoolConstant(true)*/
+  var field2 = true;
+
+  /*element: Class1.field3:initial=BoolConstant(false)*/
+  var field3 = false;
+
+  /*element: Class1.field4:initial=IntConstant(0)*/
+  var field4 = 0;
+
+  /*element: Class1.field5:initial=IntConstant(1)*/
+  var field5 = 1;
+
+  /*element: Class1.field6:initial=StringConstant("")*/
+  var field6 = '';
+
+  /*element: Class1.field7:initial=StringConstant("foo")*/
+  var field7 = 'foo';
+
+  /*element: Class1.field8:*/
+  var field8 = 0.5;
+
+  /*element: Class1.field9:*/
+  var field9 = const [];
+
+  /*element: Class1.field10:*/
+  var field10 = const {};
+
+  /*element: Class1.field11:*/
+  var field11 = #foo;
+
+  /*element: Class1.field12:*/
+  var field12 = 2 + 3;
+
+  /*element: Class1.field13:*/
+  var field13 = const1;
+}
+
+class Class2 {
+  /*element: Class2.field1:*/
+  var field1;
+
+  /*element: Class2.field2:*/
+  var field2;
+
+  /*element: Class2.field3:*/
+  var field3;
+
+  /*element: Class2.field4:*/
+  var field4;
+
+  /*element: Class2.field5:*/
+  var field5;
+
+  /*element: Class2.field6:*/
+  var field6;
+
+  /*element: Class2.field7:*/
+  var field7;
+
+  /*element: Class2.field8:*/
+  var field8;
+
+  /*element: Class2.field9:*/
+  var field9;
+
+  /*element: Class2.field10:*/
+  var field10;
+
+  /*element: Class2.field11:*/
+  var field11;
+
+  /*element: Class2.field12:*/
+  var field12;
+
+  /*element: Class2.field13:*/
+  var field13;
+
+  Class2()
+      : field1 = null,
+        field2 = true,
+        field3 = false,
+        field4 = 0,
+        field5 = 1,
+        field6 = '',
+        field7 = 'foo',
+        field8 = 0.5,
+        field9 = const [],
+        field10 = const {},
+        field11 = #foo,
+        field12 = 2 + 3,
+        field13 = const1;
+}
diff --git a/tests/compiler/dart2js/closure/closure_test.dart b/tests/compiler/dart2js/closure/closure_test.dart
index 705638c..26d0d92 100644
--- a/tests/compiler/dart2js/closure/closure_test.dart
+++ b/tests/compiler/dart2js/closure/closure_test.dart
@@ -273,7 +273,8 @@
         addLocals('fields', (f(Local local, _)) {
           codegenWorldBuilder.forEachInstanceField(
               closureRepresentationInfo.closureClassEntity,
-              (_, FieldEntity field) {
+              (_, FieldEntity field, {bool isElided}) {
+            if (isElided) return;
             f(closureRepresentationInfo.getLocalForField(field), field);
           });
         });
diff --git a/tests/compiler/dart2js/codegen/class_codegen_test.dart b/tests/compiler/dart2js/codegen/class_codegen_test.dart
index bb22e20..a38938e 100644
--- a/tests/compiler/dart2js/codegen/class_codegen_test.dart
+++ b/tests/compiler/dart2js/codegen/class_codegen_test.dart
@@ -40,11 +40,14 @@
 const String TEST_FOUR = r"""
 var g = 0;
 class A {
+  @pragma('dart2js:noElision')
   var x = g++;
 }
 
 class B extends A {
+  @pragma('dart2js:noElision')
   var y = g++;
+  @pragma('dart2js:noElision')
   var z = g++;
 }
 
@@ -55,6 +58,7 @@
 
 const String TEST_FIVE = r"""
 class A {
+  @pragma('dart2js:noElision')
   var a;
   A(a) : this.a = a {}
 }
@@ -90,8 +94,8 @@
 
 constructor1() async {
   String generated = await compileAll(TEST_FIVE);
-  print('--------------------\n$generated\n');
-  Expect.isTrue(generated.contains(new RegExp(r"new [$A-Z]+\.A\(a\);")));
+  Expect.isTrue(generated.contains(new RegExp(r"new [$A-Z]+\.A\(a\);")),
+      '--------------------\n$generated\n');
 }
 
 main() {
diff --git a/tests/compiler/dart2js/codegen/constant_namer_test.dart b/tests/compiler/dart2js/codegen/constant_namer_test.dart
index 076f377..8893422 100644
--- a/tests/compiler/dart2js/codegen/constant_namer_test.dart
+++ b/tests/compiler/dart2js/codegen/constant_namer_test.dart
@@ -8,7 +8,9 @@
 
 const String TEST_ONE = r"""
   class Token {
+    @pragma('dart2js:noElision')
     final name;
+    @pragma('dart2js:noElision')
     final value;
     const Token(this.name, [this.value]);
     use() { print(this); }
diff --git a/tests/compiler/dart2js/codegen/expect_annotations_test.dart b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
index bcff3bd..f4e5903 100644
--- a/tests/compiler/dart2js/codegen/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/expect_annotations_test.dart
@@ -75,11 +75,11 @@
     Expect.isNotNull(method);
     Expect.equals(
         expectNoInline,
-        closedWorld.annotationsData.nonInlinableFunctions.contains(method),
+        closedWorld.annotationsData.hasNoInline(method),
         "Unexpected annotation of @NoInline() on '$method'.");
     Expect.equals(
         expectAssumeDynamic,
-        closedWorld.annotationsData.assumeDynamicMembers.contains(method),
+        closedWorld.annotationsData.hasAssumeDynamic(method),
         "Unexpected annotation of @AssumeDynamic() on '$method'.");
     GlobalTypeInferenceResults results =
         compiler.globalInference.resultsForTesting;
diff --git a/tests/compiler/dart2js/codegen/model_data/capture.dart b/tests/compiler/dart2js/codegen/model_data/capture.dart
new file mode 100644
index 0000000..ca9279e
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/capture.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.
+
+/*element: method1:params=0*/
+@pragma('dart2js:noInline')
+method1([a]) => /*params=0*/ () => a;
+
+class Class {
+  /*element: Class.f:emitted*/
+  @pragma('dart2js:noElision')
+  var f;
+
+  /*element: Class.capture:params=0*/
+  @pragma('dart2js:noInline')
+  Class.capture([a]) : f = (/*params=0*/ () => a);
+
+  // TODO(johnniwinther): Remove the redundant assignment of elided boxed
+  // parameters.
+  /*element: Class.box:assign=[a,a],params=0*/
+  @pragma('dart2js:noInline')
+  Class.box([a])
+      : f = (/*assign=[a],params=0*/ () {
+          a = 42;
+        });
+
+  Class.internal(this.f);
+}
+
+class Subclass extends Class {
+  /*element: Subclass.capture:params=0*/
+  @pragma('dart2js:noInline')
+  Subclass.capture([a]) : super.internal(/*params=0*/ () => a);
+
+  /*element: Subclass.box:assign=[a,a],params=0*/
+  @pragma('dart2js:noInline')
+  Subclass.box([a])
+      : super.internal(/*assign=[a],params=0*/ () {
+          a = 42;
+        });
+}
+
+/*element: main:calls=*,params=0*/
+main() {
+  method1();
+  new Class.capture();
+  new Class.box();
+  new Subclass.capture();
+  new Subclass.box();
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/constructors.dart b/tests/compiler/dart2js/codegen/model_data/constructors.dart
new file mode 100644
index 0000000..69be657
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/constructors.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.
+
+class Class {
+  /*element: Class.constructor1:params=0*/
+  @pragma('dart2js:noInline')
+  Class.constructor1() {}
+
+  /*element: Class.constructor2a:params=0*/
+  @pragma('dart2js:noInline')
+  Class.constructor2a([a]) {}
+
+  /*element: Class.constructor2b:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor2b([a]) {}
+
+  /*element: Class.constructor2c:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor2c([a]) {}
+
+  /*element: Class.constructor3a:params=0*/
+  @pragma('dart2js:noInline')
+  Class.constructor3a([a, b]) {}
+
+  /*element: Class.constructor3b:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor3b([a, b]) {}
+
+  /*element: Class.constructor3c:params=2*/
+  @pragma('dart2js:noInline')
+  Class.constructor3c([a, b]) {}
+
+  /*element: Class.constructor4a:params=0*/
+  @pragma('dart2js:noInline')
+  Class.constructor4a({a}) {}
+
+  /*element: Class.constructor4b:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor4b({a}) {}
+
+  /*element: Class.constructor4c:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor4c({a}) {}
+
+  /*element: Class.constructor5a:params=0*/
+  @pragma('dart2js:noInline')
+  Class.constructor5a({a, b}) {}
+
+  /*element: Class.constructor5b:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor5b({a, b}) {}
+
+  /*element: Class.constructor5c:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor5c({a, b}) {}
+
+  /*element: Class.constructor6a:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor6a(a, [b, c]) {}
+
+  /*element: Class.constructor6b:params=2*/
+  @pragma('dart2js:noInline')
+  Class.constructor6b(a, [b, c]) {}
+
+  /*element: Class.constructor6c:params=3*/
+  @pragma('dart2js:noInline')
+  Class.constructor6c(a, [b, c]) {}
+
+  /*element: Class.constructor7a:params=1*/
+  @pragma('dart2js:noInline')
+  Class.constructor7a(a, {b, c}) {}
+
+  /*element: Class.constructor7b:params=2*/
+  @pragma('dart2js:noInline')
+  Class.constructor7b(a, {b, c}) {}
+
+  /*element: Class.constructor7c:params=2*/
+  @pragma('dart2js:noInline')
+  Class.constructor7c(a, {b, c}) {}
+}
+
+/*element: main:
+ calls=[
+  Class$constructor1(0),
+  Class$constructor2a(0),
+  Class$constructor2b(1),
+  Class$constructor2c(1),
+  Class$constructor2c(1),
+  Class$constructor3a(0),
+  Class$constructor3b(1),
+  Class$constructor3b(1),
+  Class$constructor3c(2),
+  Class$constructor4a(0),
+  Class$constructor4b(1),
+  Class$constructor4c(1),
+  Class$constructor4c(1),
+  Class$constructor5a(0),
+  Class$constructor5b(1),
+  Class$constructor5c(1),
+  Class$constructor6a(1),
+  Class$constructor6b(2),
+  Class$constructor6b(2),
+  Class$constructor6c(3),
+  Class$constructor7a(1),
+  Class$constructor7b(2),
+  Class$constructor7c(2)],
+ params=0
+*/
+main() {
+  new Class.constructor1();
+
+  new Class.constructor2a();
+  new Class.constructor2b(null);
+  new Class.constructor2c();
+  new Class.constructor2c(null);
+
+  new Class.constructor3a();
+  new Class.constructor3b();
+  new Class.constructor3b(null);
+  new Class.constructor3c(null, null);
+
+  new Class.constructor4a();
+  new Class.constructor4b(a: null);
+  new Class.constructor4c();
+  new Class.constructor4c(a: null);
+
+  new Class.constructor5a();
+  new Class.constructor5b(a: null);
+  new Class.constructor5c(b: null);
+
+  new Class.constructor6a(null);
+  new Class.constructor6b(null);
+  new Class.constructor6b(null, null);
+  new Class.constructor6c(null, null, null);
+
+  new Class.constructor7a(null);
+  new Class.constructor7b(null, b: null);
+  new Class.constructor7c(null, c: null);
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
index c014519..f519f30 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_get.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_get.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.
 
+/*element: main:calls=*,params=0*/
 main() {
   method1(new Class1a());
   method2(new Class2a<int>());
@@ -12,50 +13,54 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:*/
+  /*element: Class1a.field1:emitted*/
   int field1;
 }
 
+/*element: method1:params=1*/
 @pragma('dart2js:noInline')
 method1(dynamic c) {
   return c.field1;
 }
 
 class Class2a<T> {
-  /*element: Class2a.field2:*/
+  /*element: Class2a.field2:emitted*/
   T field2;
 }
 
+/*element: method2:params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   return c.field2;
 }
 
 class Class3a {
-  /*element: Class3a.field3:get=simple*/
+  /*element: Class3a.field3:emitted,get=simple*/
   int field3;
 }
 
 class Class3b {
-  /*element: Class3b.field3:get=simple*/
+  /*element: Class3b.field3:emitted,get=simple*/
   int field3;
 }
 
+/*element: method3:calls=[get$field3(0)],params=1*/
 @pragma('dart2js:noInline')
 method3(dynamic c) {
   return c.field3;
 }
 
 class Class4a {
-  /*element: Class4a.field4:get=simple*/
+  /*element: Class4a.field4:emitted,get=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*element: Class4b.field4:get=simple*/
+  /*element: Class4b.field4:emitted,get=simple*/
   int field4;
 }
 
+/*element: method4:calls=[get$field4(0)],params=1*/
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   return c.field4;
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index ac96348..8df2ee2 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.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.
 
+/*element: main:calls=*,params=0*/
 main() {
   method1(new Class1a());
   method2(new Class2a<int>());
@@ -12,55 +13,60 @@
 }
 
 class Class1a {
-  /*element: Class1a.field1:*/
+  /*element: Class1a.field1:elided*/
   int field1;
 }
 
+/*element: method1:params=1*/
 @pragma('dart2js:noInline')
 method1(dynamic c) {
   c.field1 = 42;
 }
 
 class Class2a<T> {
-  /*strong.element: Class2a.field2:checked*/
-  /*omit.element: Class2a.field2:*/
+  /*strong.element: Class2a.field2:checked,elided*/
+  /*omit.element: Class2a.field2:elided*/
   T field2;
 }
 
+/*strong.element: method2:calls=[set$field2(1)],params=1*/
+/*omit.element: method2:params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*strong.element: Class3a.field3:checked*/
-  /*omit.element: Class3a.field3:set=simple*/
+  /*strong.element: Class3a.field3:checked,elided*/
+  /*omit.element: Class3a.field3:elided,set=simple*/
   int field3;
 }
 
 class Class3b {
-  /*strong.element: Class3b.field3:checked*/
-  /*omit.element: Class3b.field3:set=simple*/
+  /*strong.element: Class3b.field3:checked,elided*/
+  /*omit.element: Class3b.field3:elided,set=simple*/
   int field3;
 }
 
+/*element: method3:calls=[set$field3(1)],params=1*/
 @pragma('dart2js:noInline')
 method3(dynamic c) {
   c.field3 = 42;
 }
 
 class Class4a {
-  /*strong.element: Class4a.field4:checked*/
-  /*omit.element: Class4a.field4:set=simple*/
+  /*strong.element: Class4a.field4:checked,elided*/
+  /*omit.element: Class4a.field4:elided,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*strong.element: Class4b.field4:checked*/
-  /*omit.element: Class4b.field4:set=simple*/
+  /*strong.element: Class4b.field4:checked,elided*/
+  /*omit.element: Class4b.field4:elided,set=simple*/
   int field4;
 }
 
+/*element: method4:calls=[set$field4(1)],params=1*/
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   c.field4 = 42;
diff --git a/tests/compiler/dart2js/codegen/model_data/field_set.dart b/tests/compiler/dart2js/codegen/model_data/field_set.dart
new file mode 100644
index 0000000..6c23abe
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/field_set.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: main:calls=*,params=0*/
+main() {
+  method1(new Class1a());
+  method2(new Class2a());
+  method2(new Class2b());
+
+  method3(new Class3a());
+  Class3b b = new Class3b();
+  method3(b);
+  print(b.field3);
+
+  method5(new Class5a());
+  method6(new Class6a());
+  method6(new Class6b());
+  method7();
+  method8();
+  method9();
+  method10();
+}
+
+class Class1a {
+  /*element: Class1a.field1:emitted*/
+  @pragma('dart2js:noElision')
+  int field1;
+}
+
+/*element: method1:assign=[field1],params=1*/
+@pragma('dart2js:noInline')
+method1(Class1a c) {
+  c.field1 = 42;
+}
+
+class Class2a {
+  /*element: Class2a.field2:emitted*/
+  @pragma('dart2js:noElision')
+  int field2 = 42;
+}
+
+class Class2b extends Class2a {}
+
+/*element: method2:assign=[field2],params=1*/
+@pragma('dart2js:noInline')
+method2(Class2a c) {
+  c.field2 = 42;
+}
+
+class Class3a {
+  /*element: Class3a.field3:elided,set=simple*/
+  var field3;
+}
+
+class Class3b implements Class3a {
+  /*element: Class3b.field3:emitted,set=simple*/
+  var field3;
+}
+
+/*element: method3:calls=[set$field3(1)],params=1*/
+@pragma('dart2js:noInline')
+method3(Class3a a) => a.field3 = 42;
+
+class Class5a {
+  /*element: Class5a.field5:elided*/
+  int field5;
+}
+
+/*element: method5:params=1*/
+@pragma('dart2js:noInline')
+method5(Class5a c) {
+  c.field5 = 42;
+}
+
+class Class6a {
+  /*element: Class6a.field6:elided*/
+  int field6 = 42;
+}
+
+class Class6b extends Class6a {}
+
+@pragma('dart2js:noInline')
+method6(Class6a c) {
+  /*element: method6:params=1*/
+  c.field6 = 42;
+}
+
+/*element: field7:emitted*/
+@pragma('dart2js:noElision')
+int field7;
+
+/*element: method7:assign=[field7],params=0*/
+@pragma('dart2js:noInline')
+method7() {
+  field7 = 42;
+}
+
+int field8;
+
+/*element: method8:params=0*/
+@pragma('dart2js:noInline')
+method8() {
+  field8 = 42;
+}
+
+/*element: field9:emitted,lazy*/
+@pragma('dart2js:noElision')
+int field9 = throw 'field9';
+
+/*element: method9:assign=[field9],params=0*/
+@pragma('dart2js:noInline')
+method9() {
+  field9 = 42;
+}
+
+int field10 = throw 'field9';
+
+/*element: method10:params=0*/
+@pragma('dart2js:noInline')
+method10() {
+  field10 = 42;
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/fields.dart b/tests/compiler/dart2js/codegen/model_data/fields.dart
new file mode 100644
index 0000000..62c3b52
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/fields.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 field1a;
+
+var field1b;
+
+var field1c;
+
+/*element: field2a:params=0*/
+@pragma('dart2js:noInline')
+get field2a => 42;
+
+@pragma('dart2js:noInline')
+set field2a(_) {}
+
+@pragma('dart2js:noInline')
+get field2b => 42;
+
+/*element: field2b=:params=1*/
+@pragma('dart2js:noInline')
+set field2b(_) {}
+
+/*element: field2c:params=0*/
+@pragma('dart2js:noInline')
+get field2c => 42;
+
+/*element: field2c=:params=1*/
+@pragma('dart2js:noInline')
+set field2c(_) {}
+
+class Class {
+  /*element: Class.field1a:emitted*/
+  var field1a;
+
+  /*element: Class.field1b:elided*/
+  var field1b;
+
+  /*element: Class.field1c:emitted*/
+  var field1c;
+
+  /*element: Class.field2a:params=0*/
+  @pragma('dart2js:noInline')
+  get field2a => 42;
+
+  @pragma('dart2js:noInline')
+  set field2a(_) {}
+
+  @pragma('dart2js:noInline')
+  get field2b => 42;
+
+  /*element: Class.field2b=:params=1*/
+  @pragma('dart2js:noInline')
+  set field2b(_) {}
+
+  /*element: Class.field2c:params=0*/
+  @pragma('dart2js:noInline')
+  get field2c => 42;
+
+  set field2c(_) {}
+
+  /*element: Class.field3a:elided*/
+  var field3a = 0;
+
+  /*element: Class.field3b:elided*/
+  var field3b;
+
+  /*element: Class.:params=0*/
+  @pragma('dart2js:noInline')
+  Class([this.field3b]);
+
+  /*element: Class.test:calls=[get$field2a(0),get$field2c(0),set$field2b(1)],params=0*/
+  @pragma('dart2js:noInline')
+  test() {
+    field1a;
+    field1b = 42;
+    field1c = field1c;
+
+    field2a;
+    field2b = 42;
+    field2c = field2c;
+  }
+}
+
+/*element: main:calls=[Class$(0),field2a(0),field2b(1),field2c(0),field2c0(1),test$0(0)],params=0*/
+main() {
+  field1a;
+  field1b = 42;
+  field1c = field1c;
+
+  field2a;
+  field2b = 42;
+  field2c = field2c;
+
+  new Class().test();
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart b/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.dart
new file mode 100644
index 0000000..a861c04
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/instance_method_parameters.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.
+
+class Class {
+  /*element: Class.method1:params=0*/
+  @pragma('dart2js:noInline')
+  method1() {}
+
+  /*element: Class.method2a:params=0*/
+  @pragma('dart2js:noInline')
+  method2a([a]) {}
+
+  /*element: Class.method2b:params=1*/
+  @pragma('dart2js:noInline')
+  method2b([a]) {}
+
+  /*element: Class.method2c:params=1,stubs=[method2c$0:method2c$1(1)]*/
+  @pragma('dart2js:noInline')
+  method2c([a]) {}
+
+  /*element: Class.method3a:params=0*/
+  @pragma('dart2js:noInline')
+  method3a([a, b]) {}
+
+  /*element: Class.method3b:params=1,stubs=[method3b$0:method3b$1(1)]*/
+  @pragma('dart2js:noInline')
+  method3b([a, b]) {}
+
+  /*element: Class.method3c:params=2*/
+  @pragma('dart2js:noInline')
+  method3c([a, b]) {}
+
+  /*element: Class.method4a:params=0*/
+  @pragma('dart2js:noInline')
+  method4a({a}) {}
+
+  /*element: Class.method4b:params=1*/
+  @pragma('dart2js:noInline')
+  method4b({a}) {}
+
+  /*element: Class.method4c:params=1,stubs=[method4c$0:method4c$1$a(1)]*/
+  @pragma('dart2js:noInline')
+  method4c({a}) {}
+
+  /*element: Class.method5a:params=0*/
+  @pragma('dart2js:noInline')
+  method5a({a, b}) {}
+
+  /*element: Class.method5b:params=1*/
+  @pragma('dart2js:noInline')
+  method5b({a, b}) {}
+
+  /*element: Class.method5c:params=1*/
+  @pragma('dart2js:noInline')
+  method5c({a, b}) {}
+
+  /*element: Class.method6a:params=0,stubs=[method6a$0:method6a$1$0(1)]*/
+  @pragma('dart2js:noInline')
+  method6a<T>() {}
+
+  /*element: Class.method7a:params=1*/
+  @pragma('dart2js:noInline')
+  method7a(a, [b, c]) {}
+
+  /*element: Class.method7b:params=2,stubs=[method7b$1:method7b$2(2)]*/
+  @pragma('dart2js:noInline')
+  method7b(a, [b, c]) {}
+
+  /*element: Class.method7c:params=3*/
+  @pragma('dart2js:noInline')
+  method7c(a, [b, c]) {}
+
+  /*element: Class.method8a:params=1*/
+  @pragma('dart2js:noInline')
+  method8a(a, {b, c}) {}
+
+  /*element: Class.method8b:params=2*/
+  @pragma('dart2js:noInline')
+  method8b(a, {b, c}) {}
+
+  /*element: Class.method8c:params=2*/
+  @pragma('dart2js:noInline')
+  method8c(a, {b, c}) {}
+
+  /*element: Class.test:calls=*,params=0*/
+  @pragma('dart2js:noInline')
+  test() {
+    method1();
+
+    method2a();
+    method2b(null);
+    method2c();
+    method2c(null);
+
+    method3a();
+    method3b();
+    method3b(null);
+    method3c(null, null);
+
+    method4a();
+    method4b(a: null);
+    method4c();
+    method4c(a: null);
+
+    method5a();
+    method5b(a: null);
+    method5c(b: null);
+
+    method6a();
+
+    method7a(null);
+    method7b(null);
+    method7b(null, null);
+    method7c(null, null, null);
+
+    method8a(null);
+    method8b(null, b: null);
+    method8c(null, c: null);
+  }
+}
+
+/*element: main:calls=[test$0(0)],params=0*/
+main() {
+  new Class().test();
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/native.dart b/tests/compiler/dart2js/codegen/model_data/native.dart
new file mode 100644
index 0000000..23dcd6e
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/native.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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: import_internal_library
+import 'dart:_js_helper';
+
+@Native('Class')
+class Class {
+  factory Class() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  @pragma('dart2js:noElision')
+  int field1;
+
+  int field2;
+
+  /*element: Class.method1:
+   calls=[method1(a,b,c)],
+   params=4,
+   stubs=[
+    method1$1:method1(a),
+    method1$2:method1(a,b)]
+  */
+  @pragma('dart2js:noInline')
+  method1(a, [b, c])
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+
+  /*element: Class.method2:
+   calls=[method2(a,b,c)],
+   params=4,
+   stubs=[
+    method2$1:method2(a),
+    method2$2$b:method2(a,b),
+    method2$2$c:method2(a,null,c)]
+  */
+  @pragma('dart2js:noInline')
+  method2(a, {b, c})
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+
+  // TODO(johnniwinther): Control the order of the named arguments. Currently
+  // we sort them lexicographically but that doesn't match the target
+  // expectations.
+  /*element: Class.method3:
+   calls=[method3(a,c,b)],
+   params=4,
+   stubs=[
+    method3$1:method3(a),
+    method3$2$b:method3(a,null,b),
+    method3$2$c:method3(a,c)]
+  */
+  @pragma('dart2js:noInline')
+  method3(a, {c, b})
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+
+  // TODO(johnniwinther): Control the order of the named arguments. Currently
+  // we sort them lexicographically but that doesn't match the target
+  // expectations.
+  /*element: Class.method4:
+   calls=[method4(a,c,d,b)],
+   params=5,
+   stubs=[
+    method4$1:method4(a),
+    method4$2$b:method4(a,null,null,b),
+    method4$2$c:method4(a,c),
+    method4$3$b$c:method4(a,c,null,b),
+    method4$3$b$d:method4(a,null,d,b),
+    method4$3$c$d:method4(a,c,d)]
+  */
+  @pragma('dart2js:noInline')
+  method4(a, {c, d, b})
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+}
+
+/*element: makeClass:params=0*/
+@Creates('Class')
+makeClass()
+    // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+    native;
+
+/*element: main:calls=[test(1),*],params=0*/
+main() {
+  test(makeClass());
+}
+
+/*element: test:
+ assign=[field1,field2],
+ calls=[
+  method1$1(2),
+  method1$2(3),
+  method1$3(4),
+  method2$1(2),
+  method2$2$b(3),
+  method2$2$c(3),
+  method2$3$b$c(4),
+  method3$1(2),
+  method3$2$b(3),
+  method3$2$c(3),
+  method3$3$b$c(4),
+  method4$1(2),
+  method4$2$b(3),
+  method4$2$c(3),
+  method4$3$b$c(4),
+  method4$3$b$d(4),
+  method4$3$c$d(4)],
+ params=1
+*/
+@pragma('dart2js:noInline')
+test(Class o) {
+  o.field1 = 42;
+  o.field2 = 42;
+  o.method1(0);
+  o.method1(0, 1);
+  o.method1(0, 1, 2);
+  o.method2(0);
+  o.method2(0, b: 1);
+  o.method2(0, b: 1, c: 2);
+  o.method2(0, c: 2);
+  o.method3(0);
+  o.method3(0, b: 1);
+  o.method3(0, b: 1, c: 2);
+  o.method3(0, c: 2);
+  o.method4(0);
+  o.method4(0, b: 1);
+  o.method4(0, b: 1, c: 2);
+  o.method4(0, c: 2);
+  o.method4(0, c: 2, d: 3);
+  o.method4(0, b: 1, d: 3);
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/native_inlined.dart b/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
new file mode 100644
index 0000000..7e99271
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/native_inlined.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_js_helper';
+
+@Native('Class')
+class Class {
+  factory Class() {
+    throw new UnsupportedError("Not supported");
+  }
+
+  method1(a, [b, c])
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+
+  /*element: Class.method2:
+   calls=[method2(a,b,c)],
+   params=4,
+   stubs=[
+    method2$1:method2(a),
+    method2$2$b:method2(a,b),
+    method2$2$c:method2(a,null,c)]
+  */
+  method2(a, {b, c})
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+
+  // TODO(johnniwinther): Control the order of the named arguments. Currently
+  // we sort them lexicographically but that doesn't match the target
+  // expectations.
+  /*element: Class.method3:
+   calls=[method3(a,c,b)],
+   params=4,
+   stubs=[
+    method3$1:method3(a),
+    method3$2$b:method3(a,null,b),
+    method3$2$c:method3(a,c)]
+  */
+  method3(a, {c, b})
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+
+  // TODO(johnniwinther): Control the order of the named arguments. Currently
+  // we sort them lexicographically but that doesn't match the target
+  // expectations.
+  /*element: Class.method4:
+   calls=[method4(a,c,d,b)],
+   params=5,
+   stubs=[
+    method4$1:method4(a),
+    method4$2$b:method4(a,null,null,b),
+    method4$2$c:method4(a,c),
+    method4$3$b$c:method4(a,c,null,b),
+    method4$3$b$d:method4(a,null,d,b),
+    method4$3$c$d:method4(a,c,d)]
+  */
+  method4(a, {c, d, b})
+      // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+      native;
+}
+
+/*element: makeClass:params=0*/
+@Creates('Class')
+makeClass()
+    // ignore: NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+    native;
+
+/*element: main:calls=[test(1),*],params=0*/
+main() {
+  test(makeClass());
+}
+
+/*element: test:
+ calls=[
+  method1(0),
+  method1(0,1),
+  method1(0,1,2),
+  method2$1(2),
+  method2$2$b(3),
+  method2$2$c(3),
+  method2$3$b$c(4),
+  method3$1(2),
+  method3$2$b(3),
+  method3$2$c(3),
+  method3$3$b$c(4),
+  method4$1(2),
+  method4$2$b(3),
+  method4$2$c(3),
+  method4$3$b$c(4),
+  method4$3$b$d(4),
+  method4$3$c$d(4)],
+ params=1
+*/
+@pragma('dart2js:noInline')
+test(Class o) {
+  if (o == null) return;
+  o.method1(0);
+  o.method1(0, 1);
+  o.method1(0, 1, 2);
+  o.method2(0);
+  o.method2(0, b: 1);
+  o.method2(0, b: 1, c: 2);
+  o.method2(0, c: 2);
+  o.method3(0);
+  o.method3(0, b: 1);
+  o.method3(0, b: 1, c: 2);
+  o.method3(0, c: 2);
+  o.method4(0);
+  o.method4(0, b: 1);
+  o.method4(0, b: 1, c: 2);
+  o.method4(0, c: 2);
+  o.method4(0, c: 2, d: 3);
+  o.method4(0, b: 1, d: 3);
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart b/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
new file mode 100644
index 0000000..36197db
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/native_unused_parameters.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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: import_internal_library
+import 'dart:_js_helper';
+
+/*element: Class.:params=1*/
+@Native('Class')
+class Class {
+  /*element: Class.method1:calls=[method1()],params=1*/
+  @pragma('dart2js:noInline')
+  method1([a, b])
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method2:calls=[method2(a)],params=2*/
+  @pragma('dart2js:noInline')
+  method2([a, b])
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method3:calls=[method3(a,b)],params=3*/
+  @pragma('dart2js:noInline')
+  method3([a, b])
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method4:
+   calls=[method4(a,b)],
+   params=3,
+   stubs=[method4$0:method4()]
+  */
+  @pragma('dart2js:noInline')
+  method4([a, b])
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method5:
+   calls=[method5(a,b)],
+   params=3,
+   stubs=[method5$1:method5(a)]
+  */
+  @pragma('dart2js:noInline')
+  method5([a, b])
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method6:
+   calls=[method6(a,b,c)],
+   params=4,
+   stubs=[method6$1:method6(a)]
+  */
+  @pragma('dart2js:noInline')
+  method6(a, {b, c})
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method7:
+   calls=[method7(a,b,c)],
+   params=4,
+   stubs=[method7$2$b:method7(a,b)]
+  */
+  @pragma('dart2js:noInline')
+  method7(a, {b, c})
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+
+  /*element: Class.method8:
+   calls=[method8(a,b,c)],
+   params=4,
+   stubs=[
+    method8$2$b:method8(a,b),
+    method8$2$c:method8(a,null,c)]
+  */
+  @pragma('dart2js:noInline')
+  method8(a, {b, c})
+      // ignore: native_function_body_in_non_sdk_code
+      native;
+}
+
+/*element: test:
+ calls=[
+  method1$0(1),
+  method2$1(2),
+  method3$2(3),
+  method4$0(1),
+  method4$2(3),
+  method5$1(2),
+  method5$2(3),
+  method6$1(2),
+  method6$3$b$c(4),
+  method7$2$b(3),
+  method7$3$b$c(4),
+  method8$2$b(3),
+  method8$2$c(3)],
+ params=1
+*/
+@pragma('dart2js:noInline')
+test(Class c) {
+  c.method1();
+  c.method2(null);
+  c.method3(null, null);
+  c.method4();
+  c.method4(null, null);
+  c.method5(null);
+  c.method5(null, null);
+  c.method6(null);
+  c.method6(null, b: null, c: null);
+  c.method7(null, b: null);
+  c.method7(null, b: null, c: null);
+  c.method8(null, b: null);
+  c.method8(null, c: null);
+}
+
+/*element: main:calls=*,params=0*/
+main() {
+  test(new Class());
+}
diff --git a/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart b/tests/compiler/dart2js/codegen/model_data/static_method_parameters.dart
new file mode 100644
index 0000000..5fb0bfd
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/static_method_parameters.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.
+
+/*element: method1:params=0*/
+@pragma('dart2js:noInline')
+method1() {}
+
+/*element: method2a:params=0*/
+@pragma('dart2js:noInline')
+method2a([a]) {}
+
+/*element: method2b:params=1*/
+@pragma('dart2js:noInline')
+method2b([a]) {}
+
+/*element: method2c:params=1*/
+@pragma('dart2js:noInline')
+method2c([a]) {}
+
+/*element: method3a:params=0*/
+@pragma('dart2js:noInline')
+method3a([a, b]) {}
+
+/*element: method3b:params=1*/
+@pragma('dart2js:noInline')
+method3b([a, b]) {}
+
+/*element: method3c:params=2*/
+@pragma('dart2js:noInline')
+method3c([a, b]) {}
+
+/*element: method4a:params=0*/
+@pragma('dart2js:noInline')
+method4a({a}) {}
+
+/*element: method4b:params=1*/
+@pragma('dart2js:noInline')
+method4b({a}) {}
+
+/*element: method4c:params=1*/
+@pragma('dart2js:noInline')
+method4c({a}) {}
+
+/*element: method5a:params=0*/
+@pragma('dart2js:noInline')
+method5a({a, b}) {}
+
+/*element: method5b:params=1*/
+@pragma('dart2js:noInline')
+method5b({a, b}) {}
+
+/*element: method5c:params=1*/
+@pragma('dart2js:noInline')
+method5c({a, b}) {}
+
+/*element: method6a:params=0*/
+@pragma('dart2js:noInline')
+method6a<T>() {}
+
+/*element: method7a:params=1*/
+@pragma('dart2js:noInline')
+method7a(a, [b, c]) {}
+
+/*element: method7b:params=2*/
+@pragma('dart2js:noInline')
+method7b(a, [b, c]) {}
+
+/*element: method7c:params=3*/
+@pragma('dart2js:noInline')
+method7c(a, [b, c]) {}
+
+/*element: method8a:params=1*/
+@pragma('dart2js:noInline')
+method8a(a, {b, c}) {}
+
+/*element: method8b:params=2*/
+@pragma('dart2js:noInline')
+method8b(a, {b, c}) {}
+
+/*element: method8c:params=2*/
+@pragma('dart2js:noInline')
+method8c(a, {b, c}) {}
+
+/*element: main:
+ calls=[
+  method1(0),
+  method2a(0),
+  method2b(1),
+  method2c(1),
+  method2c(1),
+  method3a(0),
+  method3b(1),
+  method3b(1),
+  method3c(2),
+  method4a(0),
+  method4b(1),
+  method4c(1),
+  method4c(1),
+  method5a(0),
+  method5b(1),
+  method5c(1),
+  method6a(0),
+  method7a(1),
+  method7b(2),
+  method7b(2),
+  method7c(3),
+  method8a(1),
+  method8b(2),
+  method8c(2)],
+ params=0
+*/
+main() {
+  method1();
+
+  method2a();
+  method2b(null);
+  method2c();
+  method2c(null);
+
+  method3a();
+  method3b();
+  method3b(null);
+  method3c(null, null);
+
+  method4a();
+  method4b(a: null);
+  method4c();
+  method4c(a: null);
+
+  method5a();
+  method5b(a: null);
+  method5c(b: null);
+
+  method6a();
+
+  method7a(null);
+  method7b(null);
+  method7b(null, null);
+  method7c(null, null, null);
+
+  method8a(null);
+  method8b(null, b: null);
+  method8c(null, c: null);
+}
diff --git a/tests/compiler/dart2js/codegen/model_test.dart b/tests/compiler/dart2js/codegen/model_test.dart
index fffbce8..e00c78d 100644
--- a/tests/compiler/dart2js/codegen/model_test.dart
+++ b/tests/compiler/dart2js/codegen/model_test.dart
@@ -9,10 +9,13 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/js_backend/namer.dart';
 import 'package:compiler/src/js_emitter/model.dart';
 import 'package:compiler/src/js_model/element_map.dart';
 import 'package:compiler/src/js_model/js_world.dart';
 import 'package:compiler/src/util/features.dart';
+import 'package:js_ast/js_ast.dart' as js;
 import 'package:kernel/ast.dart' as ir;
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
@@ -26,7 +29,7 @@
   });
 }
 
-class ModelDataComputer extends DataComputer<String> {
+class ModelDataComputer extends DataComputer<Features> {
   const ModelDataComputer();
 
   /// Compute type inference data for [member] from kernel based inference.
@@ -34,7 +37,7 @@
   /// Fills [actualMap] with the data.
   @override
   void computeMemberData(Compiler compiler, MemberEntity member,
-      Map<Id, ActualData<String>> actualMap,
+      Map<Id, ActualData<Features>> actualMap,
       {bool verbose: false}) {
     JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
     JsToElementMap elementMap = closedWorld.elementMap;
@@ -45,24 +48,32 @@
   }
 
   @override
-  DataInterpreter<String> get dataValidator => const StringDataInterpreter();
+  DataInterpreter<Features> get dataValidator =>
+      const FeaturesDataInterpreter();
 }
 
 class Tags {
   static const String needsCheckedSetter = 'checked';
   static const String getterFlags = 'get';
   static const String setterFlags = 'set';
+  static const String parameterCount = 'params';
+  static const String call = 'calls';
+  static const String parameterStub = 'stubs';
+  static const String isEmitted = 'emitted';
+  static const String isElided = 'elided';
+  static const String assignment = 'assign';
+  static const String isLazy = 'lazy';
 }
 
 /// AST visitor for computing inference data for a member.
-class ModelIrComputer extends IrDataExtractor<String> {
+class ModelIrComputer extends IrDataExtractor<Features> {
   final JsToElementMap _elementMap;
   final ClosureData _closureDataLookup;
   final ProgramLookup _programLookup;
 
   ModelIrComputer(
       DiagnosticReporter reporter,
-      Map<Id, ActualData<String>> actualMap,
+      Map<Id, ActualData<Features>> actualMap,
       this._elementMap,
       MemberEntity member,
       Compiler compiler,
@@ -70,7 +81,7 @@
       : _programLookup = new ProgramLookup(compiler),
         super(reporter, actualMap);
 
-  String getMemberValue(MemberEntity member) {
+  Features getMemberValue(MemberEntity member) {
     if (member is FieldEntity) {
       Field field = _programLookup.getField(member);
       if (field != null) {
@@ -78,6 +89,11 @@
         if (field.needsCheckedSetter) {
           features.add(Tags.needsCheckedSetter);
         }
+        if (field.isElided) {
+          features.add(Tags.isElided);
+        } else {
+          features.add(Tags.isEmitted);
+        }
         void registerFlags(String tag, int flags) {
           switch (flags) {
             case 0:
@@ -97,19 +113,91 @@
         registerFlags(Tags.getterFlags, field.getterFlags);
         registerFlags(Tags.setterFlags, field.setterFlags);
 
-        return features.getText();
+        return features;
+      }
+      StaticField staticField = _programLookup.getStaticField(member);
+      if (staticField != null) {
+        Features features = new Features();
+        features.add(Tags.isEmitted);
+        if (staticField.isLazy) {
+          features.add(Tags.isLazy);
+        }
+        return features;
+      }
+    } else if (member is FunctionEntity) {
+      Method method = _programLookup.getMethod(member);
+      if (method != null) {
+        Features features = new Features();
+        js.Expression code = method.code;
+        if (code is js.Fun) {
+          features[Tags.parameterCount] = '${code.params.length}';
+        }
+
+        void registerCalls(String tag, js.Node node, [String prefix = '']) {
+          forEachNode(node, onCall: (js.Call node) {
+            js.Node target = node.target;
+            if (target is js.PropertyAccess) {
+              js.Node selector = target.selector;
+              bool fixedNameCall = false;
+              String name;
+              if (selector is js.Name) {
+                name = selector.key;
+                fixedNameCall = selector is StringBackedName;
+              } else if (selector is js.LiteralString) {
+                /// Call to fixed backend name, so we include the argument
+                /// values to test encoding of optional parameters in native
+                /// methods.
+                name = selector.value.substring(1, selector.value.length - 1);
+                fixedNameCall = true;
+              }
+              if (name != null) {
+                if (fixedNameCall) {
+                  String arguments =
+                      node.arguments.map(js.nodeToString).join(',');
+                  features.addElement(tag, '${prefix}${name}(${arguments})');
+                } else {
+                  features.addElement(
+                      tag, '${prefix}${name}(${node.arguments.length})');
+                }
+              }
+            }
+          });
+        }
+
+        registerCalls(Tags.call, code);
+        if (method is DartMethod) {
+          for (ParameterStubMethod stub in method.parameterStubs) {
+            registerCalls(Tags.parameterStub, stub.code, '${stub.name.key}:');
+          }
+        }
+        forEachNode(code, onAssignment: (js.Assignment node) {
+          js.Expression leftHandSide = node.leftHandSide;
+          if (leftHandSide is js.PropertyAccess) {
+            js.Node selector = leftHandSide.selector;
+            String name;
+            if (selector is js.Name) {
+              name = selector.key;
+            } else if (selector is js.LiteralString) {
+              name = selector.value.substring(1, selector.value.length - 1);
+            }
+            if (name != null) {
+              features.addElement(Tags.assignment, '${name}');
+            }
+          }
+        });
+        return features;
       }
     }
     return null;
   }
 
   @override
-  String computeMemberValue(Id id, ir.Member node) {
+  Features computeMemberValue(Id id, ir.Member node) {
     return getMemberValue(_elementMap.getMember(node));
   }
 
   @override
-  String computeNodeValue(Id id, ir.TreeNode node) {
+  Features computeNodeValue(Id id, ir.TreeNode node) {
     if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
       ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
       return getMemberValue(info.callMethod);
diff --git a/tests/compiler/dart2js/codegen/pragma_annotations_test.dart b/tests/compiler/dart2js/codegen/pragma_annotations_test.dart
index d2ae5aa..a4487ec 100644
--- a/tests/compiler/dart2js/codegen/pragma_annotations_test.dart
+++ b/tests/compiler/dart2js/codegen/pragma_annotations_test.dart
@@ -53,11 +53,11 @@
     Expect.isNotNull(method, "Cannot find method '$name'");
     Expect.equals(
         expectNoInline,
-        closedWorld.annotationsData.nonInlinableFunctions.contains(method),
+        closedWorld.annotationsData.hasNoInline(method),
         "Unexpected annotation of 'noInline' on '$method'.");
     Expect.equals(
         expectTryInline,
-        closedWorld.annotationsData.tryInlineFunctions.contains(method),
+        closedWorld.annotationsData.hasTryInline(method),
         "Unexpected annotation of 'tryInline' on '$method'.");
   }
 
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
index 50487ca..5c72752 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
@@ -91,7 +91,7 @@
 
 // Make sure that deferred constants are not inlined into the main hunk.
 const Map<String, String> MEMORY_SOURCE_FILES = const {
-  "main.dart": """
+  "main.dart": r"""
 import "dart:async";
 
 import 'lib1.dart' deferred as lib1;
@@ -102,6 +102,8 @@
 class C {
   final p;
   const C(this.p);
+
+  String toString() => 'C($p)';
 }
 
 foo() => print("main");
diff --git a/tests/compiler/dart2js/end_to_end/bad_output_io_test.dart b/tests/compiler/dart2js/end_to_end/bad_output_io_test.dart
index 487af98..b386ea1 100644
--- a/tests/compiler/dart2js/end_to_end/bad_output_io_test.dart
+++ b/tests/compiler/dart2js/end_to_end/bad_output_io_test.dart
@@ -44,7 +44,7 @@
 
   final messages = [];
 
-  void info(var message, [kind]) {
+  void info(var message, [kind = Diagnostic.VERBOSE_INFO]) {
     messages.add([message, kind]);
   }
 
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index e7becbd..5369eb2 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -7,6 +7,7 @@
 
 import 'package:compiler/src/colors.dart' as colors;
 import 'package:compiler/src/common.dart';
+import 'package:compiler/compiler_new.dart';
 import 'package:compiler/src/common_elements.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
@@ -147,13 +148,16 @@
     {List<String> options: const <String>[],
     bool verbose: false,
     bool testFrontend: false,
+    bool printCode: false,
     bool forUserLibrariesOnly: true,
     bool skipUnprocessedMembers: false,
     bool skipFailedCompilations: false,
     Iterable<Id> globalIds: const <Id>[]}) async {
+  OutputCollector outputCollector = new OutputCollector();
   CompilationResult result = await runCompiler(
       entryPoint: entryPoint,
       memorySourceFiles: memorySourceFiles,
+      outputProvider: outputCollector,
       options: options,
       beforeRun: (compiler) {
         compiler.stopAfterTypeInference =
@@ -163,6 +167,11 @@
     if (skipFailedCompilations) return null;
     Expect.isTrue(result.isSuccess, "Unexpected compilation error.");
   }
+  if (printCode) {
+    print('--code------------------------------------------------------------');
+    print(outputCollector.getOutput('', OutputType.js));
+    print('------------------------------------------------------------------');
+  }
   Compiler compiler = result.compiler;
   dataComputer.onCompilation(compiler);
   dynamic closedWorld = testFrontend
@@ -409,12 +418,11 @@
       String unexpectedMessage =
           dataValidator.isAsExpected(actualValue, expectedValue?.value);
       if (unexpectedMessage != null) {
-        /*if (data.value != expectedValue || expectedValue == null && data.value.value != '') {*/
         String expected = expectedValue?.toString() ?? '';
         String actual = dataValidator.getText(actualValue);
         int offset = getOffsetFromId(id, uri);
         String value1 = '${expected}';
-        String value2 = '${actual}';
+        String value2 = IdValue.idToString(id, '${actual}');
         annotations
             .putIfAbsent(offset, () => [])
             .add(colorizeDiff(value1, ' | ', value2));
@@ -528,6 +536,7 @@
   bool verbose = args.remove('-v');
   bool shouldContinue = args.remove('-c');
   bool testAfterFailures = args.remove('-a');
+  bool printCode = args.remove('-p');
   bool continued = false;
   bool hasFailures = false;
 
@@ -607,6 +616,7 @@
           entryPoint, memorySourceFiles, dataComputer,
           options: options,
           verbose: verbose,
+          printCode: printCode,
           testFrontend: testFrontend,
           forUserLibrariesOnly: forUserLibrariesOnly,
           globalIds: annotations.globalData.keys);
@@ -700,9 +710,13 @@
     } else {
       List<String> errorsFound = [];
       Features expectedFeatures = Features.fromText(expectedData);
+      Set<String> validatedFeatures = new Set<String>();
       expectedFeatures.forEach((String key, Object expectedValue) {
-        Object actualValue = actualFeatures[key] ?? '';
-        if (expectedValue == '') {
+        validatedFeatures.add(key);
+        Object actualValue = actualFeatures[key];
+        if (!actualFeatures.containsKey(key)) {
+          errorsFound.add('No data found for $key');
+        } else if (expectedValue == '') {
           if (actualValue != '') {
             errorsFound.add('Non-empty data found for $key');
           }
@@ -751,10 +765,19 @@
           }
         } else if (expectedValue != actualValue) {
           errorsFound.add(
-              "Mismatch for $key: expected '$expectedValue', found '${actualValue}");
+              "Mismatch for $key: expected '$expectedValue', found '${actualValue}'");
         }
       });
-      return errorsFound.isNotEmpty ? errorsFound.join(', ') : null;
+      actualFeatures.forEach((String key, Object value) {
+        if (!validatedFeatures.contains(key)) {
+          if (value == '') {
+            errorsFound.add("Extra data found '$key'");
+          } else {
+            errorsFound.add("Extra data found $key=$value");
+          }
+        }
+      });
+      return errorsFound.isNotEmpty ? errorsFound.join('\n ') : null;
     }
   }
 
diff --git a/tests/compiler/dart2js/helpers/compiler_helper.dart b/tests/compiler/dart2js/helpers/compiler_helper.dart
index 1bbca1b..9fab31d 100644
--- a/tests/compiler/dart2js/helpers/compiler_helper.dart
+++ b/tests/compiler/dart2js/helpers/compiler_helper.dart
@@ -60,15 +60,21 @@
     options.add(Flags.disableInlining);
   }
 
+  // Pretend this is a dart2js_native test to allow use of 'native' keyword
+  // and import of private libraries.
+  String commonTestPath = 'sdk/tests/compiler';
+  Uri entryPoint = Uri.parse('memory:$commonTestPath/dart2js_native/main.dart');
+
   Map<String, String> source;
   methodName ??= entry;
   if (entry != 'main') {
-    source = {'main.dart': "$code\n\nmain() => $entry;"};
+    source = {entryPoint.path: "$code\n\nmain() => $entry;"};
   } else {
-    source = {'main.dart': code};
+    source = {entryPoint.path: code};
   }
 
   CompilationResult result = await runCompiler(
+      entryPoint: entryPoint,
       memorySourceFiles: source,
       options: options,
       outputProvider: outputCollector);
@@ -101,8 +107,15 @@
   if (minify) {
     options.add(Flags.minify);
   }
+
+  // Pretend this is a dart2js_native test to allow use of 'native' keyword
+  // and import of private libraries.
+  String commonTestPath = 'sdk/tests/compiler';
+  Uri entryPoint = Uri.parse('memory:$commonTestPath/dart2js_native/main.dart');
+
   CompilationResult result = await runCompiler(
-      memorySourceFiles: {'main.dart': code},
+      entryPoint: entryPoint,
+      memorySourceFiles: {entryPoint.path: code},
       options: options,
       outputProvider: outputCollector,
       diagnosticHandler: diagnosticCollector);
diff --git a/tests/compiler/dart2js/helpers/memory_compiler.dart b/tests/compiler/dart2js/helpers/memory_compiler.dart
index 6062660..ce4eda7 100644
--- a/tests/compiler/dart2js/helpers/memory_compiler.dart
+++ b/tests/compiler/dart2js/helpers/memory_compiler.dart
@@ -114,9 +114,7 @@
   Uri platformBinaries = computePlatformBinariesLocation();
 
   if (packageRoot == null && packageConfig == null) {
-    if (Platform.packageRoot != null) {
-      packageRoot = Uri.base.resolve(Platform.packageRoot);
-    } else if (Platform.packageConfig != null) {
+    if (Platform.packageConfig != null) {
       packageConfig = Uri.base.resolve(Platform.packageConfig);
     } else {
       // The tests are run with the base directory as the SDK root
diff --git a/tests/compiler/dart2js/helpers/program_lookup.dart b/tests/compiler/dart2js/helpers/program_lookup.dart
index e01108d..cac728c 100644
--- a/tests/compiler/dart2js/helpers/program_lookup.dart
+++ b/tests/compiler/dart2js/helpers/program_lookup.dart
@@ -53,7 +53,7 @@
       for (Fragment fragment in program.fragments) {
         for (Library library in fragment.libraries) {
           assert(!libraryMap.containsKey(library.element));
-          libraryMap[library.element] = new LibraryData(library);
+          libraryMap[library.element] = new LibraryData(library, fragment);
         }
       }
     }
@@ -74,17 +74,25 @@
 
   Method getMethod(FunctionEntity function) {
     if (function.enclosingClass != null) {
-      return getClassData(function.enclosingClass).getMethod(function);
+      return getClassData(function.enclosingClass)?.getMethod(function);
     } else {
-      return getLibraryData(function.library).getMethod(function);
+      return getLibraryData(function.library)?.getMethod(function);
     }
   }
 
   Field getField(FieldEntity field) {
     if (field.enclosingClass != null) {
-      return getClassData(field.enclosingClass).getField(field);
+      return getClassData(field.enclosingClass)?.getField(field);
     } else {
-      return getLibraryData(field.library).getField(field);
+      return getLibraryData(field.library)?.getField(field);
+    }
+  }
+
+  StaticField getStaticField(FieldEntity field) {
+    if (field.enclosingClass != null) {
+      return getClassData(field.enclosingClass)?.getStaticField(field);
+    } else {
+      return getLibraryData(field.library)?.getStaticField(field);
     }
   }
 }
@@ -94,8 +102,9 @@
   Map<ClassEntity, ClassData> _classMap = {};
   Map<FunctionEntity, StaticMethod> _methodMap = {};
   Map<FieldEntity, Field> _fieldMap = {};
+  Map<FieldEntity, StaticField> _staticFieldMap = {};
 
-  LibraryData(this.library) {
+  LibraryData(this.library, Fragment fragment) {
     for (Class cls in library.classes) {
       assert(!_classMap.containsKey(cls.element));
       _classMap[cls.element] = new ClassData(cls);
@@ -112,7 +121,8 @@
         _methodMap[method.element] = method;
       }
     }
-    for (Field field in library.staticFieldsForReflection) {
+
+    void addField(Field field) {
       ClassEntity enclosingClass = field.element?.enclosingClass;
       if (enclosingClass != null) {
         ClassData data =
@@ -124,6 +134,30 @@
         _fieldMap[field.element] = field;
       }
     }
+
+    for (Field field in library.staticFieldsForReflection) {
+      addField(field);
+    }
+
+    void addStaticField(StaticField field) {
+      ClassEntity enclosingClass = field.element?.enclosingClass;
+      if (enclosingClass != null) {
+        ClassData data =
+            _classMap.putIfAbsent(enclosingClass, () => new ClassData(null));
+        assert(!data._fieldMap.containsKey(field.element));
+        data._staticFieldMap[field.element] = field;
+      } else if (field.element != null) {
+        assert(!_fieldMap.containsKey(field.element));
+        _staticFieldMap[field.element] = field;
+      }
+    }
+
+    for (StaticField field in fragment.staticNonFinalFields) {
+      addStaticField(field);
+    }
+    for (StaticField field in fragment.staticLazilyInitializedFields) {
+      addStaticField(field);
+    }
   }
 
   ClassData getClassData(ClassEntity element) {
@@ -137,12 +171,20 @@
   Field getField(FieldEntity field) {
     return _fieldMap[field];
   }
+
+  StaticField getStaticField(FieldEntity field) {
+    return _staticFieldMap[field];
+  }
+
+  String toString() => 'LibraryData(library=$library,_classMap=$_classMap,'
+      '_methodMap=$_methodMap,_fieldMap=$_fieldMap)';
 }
 
 class ClassData {
   final Class cls;
   Map<FunctionEntity, Method> _methodMap = {};
   Map<FieldEntity, Field> _fieldMap = {};
+  Map<FieldEntity, StaticField> _staticFieldMap = {};
   Map<FieldEntity, StubMethod> _checkedSetterMap = {};
 
   ClassData(this.cls) {
@@ -170,24 +212,35 @@
     return _fieldMap[field];
   }
 
+  StaticField getStaticField(FieldEntity field) {
+    return _staticFieldMap[field];
+  }
+
   StubMethod getCheckedSetter(FieldEntity field) {
     return _checkedSetterMap[field];
   }
+
+  String toString() => 'ClassData(cls=$cls,'
+      '_methodMap=$_methodMap,_fieldMap=$_fieldMap)';
 }
 
 void forEachNode(js.Node root,
     {void Function(js.Call) onCall,
-    void Function(js.PropertyAccess) onPropertyAccess}) {
-  CallbackVisitor visitor =
-      new CallbackVisitor(onCall: onCall, onPropertyAccess: onPropertyAccess);
+    void Function(js.PropertyAccess) onPropertyAccess,
+    void Function(js.Assignment) onAssignment}) {
+  CallbackVisitor visitor = new CallbackVisitor(
+      onCall: onCall,
+      onPropertyAccess: onPropertyAccess,
+      onAssignment: onAssignment);
   root.accept(visitor);
 }
 
 class CallbackVisitor extends js.BaseVisitor {
   final void Function(js.Call) onCall;
   final void Function(js.PropertyAccess) onPropertyAccess;
+  final void Function(js.Assignment) onAssignment;
 
-  CallbackVisitor({this.onCall, this.onPropertyAccess});
+  CallbackVisitor({this.onCall, this.onPropertyAccess, this.onAssignment});
 
   @override
   visitCall(js.Call node) {
@@ -200,4 +253,10 @@
     if (onPropertyAccess != null) onPropertyAccess(node);
     super.visitAccess(node);
   }
+
+  @override
+  visitAssignment(js.Assignment node) {
+    if (onAssignment != null) onAssignment(node);
+    return super.visitAssignment(node);
+  }
 }
diff --git a/tests/compiler/dart2js/impact/data/async.dart b/tests/compiler/dart2js/impact/data/async.dart
index 24ab850..b8cb04a 100644
--- a/tests/compiler/dart2js/impact/data/async.dart
+++ b/tests/compiler/dart2js/impact/data/async.dart
@@ -33,45 +33,48 @@
 
 /*element: testSyncStar:
  static=[
-  _IterationMarker.endOfIteration,
-  _IterationMarker.uncaughtError,
-  _IterationMarker.yieldStar,
+  _IterationMarker.endOfIteration(0),
+  _IterationMarker.uncaughtError(1),
+  _IterationMarker.yieldStar(1),
   _makeSyncStarIterable<dynamic>(1)]
 */
 testSyncStar() sync* {}
 
 /*element: testAsync:
  static=[
-  StreamIterator.,
-  _asyncAwait,
-  _asyncRethrow,
-  _asyncReturn,
-  _asyncStartSync,
+  StreamIterator.(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
   _makeAsyncAwaitCompleter<dynamic>(0),
-  _wrapJsFunctionForAsync]
+  _wrapJsFunctionForAsync(1)]
 */
 testAsync() async {}
 
-/*element: testAsyncStar:static=[StreamIterator.,
-  _IterationMarker.yieldSingle,
-  _IterationMarker.yieldStar,
-  _asyncStarHelper,
+/*element: testAsyncStar:
+ static=[
+  StreamIterator.(1),
+  _IterationMarker.yieldSingle(1),
+  _IterationMarker.yieldStar(1),
+  _asyncStarHelper(3),
   _makeAsyncStarStreamController<dynamic>(1),
-  _streamOfController,
-  _wrapJsFunctionForAsync]*/
+  _streamOfController(1),
+  _wrapJsFunctionForAsync(1)]
+*/
 testAsyncStar() async* {}
 
 /*strong.element: testLocalSyncStar:
  static=[
-  _IterationMarker.endOfIteration,
-  _IterationMarker.uncaughtError,
-  _IterationMarker.yieldStar,
+  _IterationMarker.endOfIteration(0),
+  _IterationMarker.uncaughtError(1),
+  _IterationMarker.yieldStar(1),
   _makeSyncStarIterable<Null>(1),
-  computeSignature,
+  computeSignature(3),
   def:local,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -87,18 +90,18 @@
 
 /*strong.element: testLocalAsync:
  static=[
-  StreamIterator.,
-  _asyncAwait,
-  _asyncRethrow,
-  _asyncReturn,
-  _asyncStartSync,
+  StreamIterator.(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
   _makeAsyncAwaitCompleter<Null>(0),
-  _wrapJsFunctionForAsync,
-  computeSignature,
+  _wrapJsFunctionForAsync(1),
+  computeSignature(3),
   def:local,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -114,18 +117,18 @@
 
 /*strong.element: testLocalAsyncStar:
  static=[
-  StreamIterator.,
-  _IterationMarker.yieldSingle,
-  _IterationMarker.yieldStar,
-  _asyncStarHelper,
+  StreamIterator.(1),
+  _IterationMarker.yieldSingle(1),
+  _IterationMarker.yieldStar(1),
+  _asyncStarHelper(3),
   _makeAsyncStarStreamController<Null>(1),
-  _streamOfController,
-  _wrapJsFunctionForAsync,
-  computeSignature,
+  _streamOfController(1),
+  _wrapJsFunctionForAsync(1),
+  computeSignature(3),
   def:local,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -141,15 +144,15 @@
 
 /*strong.element: testAnonymousSyncStar:
  static=[
-  _IterationMarker.endOfIteration,
-  _IterationMarker.uncaughtError,
-  _IterationMarker.yieldStar,
+  _IterationMarker.endOfIteration(0),
+  _IterationMarker.uncaughtError(1),
+  _IterationMarker.yieldStar(1),
   _makeSyncStarIterable<Null>(1),
-  computeSignature,
+  computeSignature(3),
   def:<anonymous>,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -164,18 +167,18 @@
 
 /*strong.element: testAnonymousAsync:
  static=[
-  StreamIterator.,
-  _asyncAwait,
-  _asyncRethrow,
-  _asyncReturn,
-  _asyncStartSync,
+  StreamIterator.(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
   _makeAsyncAwaitCompleter<Null>(0),
-  _wrapJsFunctionForAsync,
-  computeSignature,
+  _wrapJsFunctionForAsync(1),
+  computeSignature(3),
   def:<anonymous>,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -190,18 +193,18 @@
 
 /*strong.element: testAnonymousAsyncStar:
  static=[
-  StreamIterator.,
-  _IterationMarker.yieldSingle,
-  _IterationMarker.yieldStar,
-  _asyncStarHelper,
+  StreamIterator.(1),
+  _IterationMarker.yieldSingle(1),
+  _IterationMarker.yieldStar(1),
+  _asyncStarHelper(3),
   _makeAsyncStarStreamController<Null>(1),
-  _streamOfController,
-  _wrapJsFunctionForAsync,
-  computeSignature,
+  _streamOfController(1),
+  _wrapJsFunctionForAsync(1),
+  computeSignature(3),
   def:<anonymous>,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -220,13 +223,13 @@
   current,
   moveNext(0)],
  static=[
-  StreamIterator.,
-  _asyncAwait,
-  _asyncRethrow,
-  _asyncReturn,
-  _asyncStartSync,
+  StreamIterator.(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
   _makeAsyncAwaitCompleter<dynamic>(0),
-  _wrapJsFunctionForAsync],
+  _wrapJsFunctionForAsync(1)],
  type=[
   impl:Stream<dynamic>,
   inst:JSBool,
@@ -244,13 +247,13 @@
   current,
   moveNext(0)],
  static=[
-  StreamIterator.,
-  _asyncAwait,
-  _asyncRethrow,
-  _asyncReturn,
-  _asyncStartSync,
+  StreamIterator.(1),
+  _asyncAwait(2),
+  _asyncRethrow(2),
+  _asyncReturn(2),
+  _asyncStartSync(2),
   _makeAsyncAwaitCompleter<dynamic>(0),
-  _wrapJsFunctionForAsync],
+  _wrapJsFunctionForAsync(1)],
  type=[
   impl:Stream<dynamic>,
   impl:int,
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index bacab72..ca5fc71 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -157,13 +157,13 @@
   /*strong.element: ForwardingConstructorGenericSuperClass.:
    static=[
     Object.(0),
-    checkSubtype,
-    checkSubtypeOfRuntimeType,
-    getRuntimeTypeArgument,
-    getRuntimeTypeArgumentIntercepted,
-    getRuntimeTypeInfo,
-    getTypeArgumentByIndex,
-    setRuntimeTypeInfo],
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    setRuntimeTypeInfo(2)],
    type=[
     inst:JSArray<dynamic>,
     inst:JSBool,
@@ -182,8 +182,8 @@
 /*element: testForwardingConstructorGeneric:
  static=[
   ForwardingConstructorGenericClass.(1),
-  assertIsSubtype,
-  throwTypeError],
+  assertIsSubtype(5),
+  throwTypeError(1)],
  type=[inst:JSNull]
 */
 testForwardingConstructorGeneric() {
@@ -211,13 +211,13 @@
 
 /*strong.element: staticGenericMethod:
  static=[
-  checkSubtype,
-  checkSubtypeOfRuntimeType,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  checkSubtypeOfRuntimeType(2),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -243,8 +243,8 @@
  dynamic=[exact:GenericClass.genericMethod<bool>(1)],
  static=[
   GenericClass.generative(0),
-  assertIsSubtype,
-  throwTypeError],
+  assertIsSubtype(5),
+  throwTypeError(1)],
  type=[inst:JSBool]
 */
 testInstanceGenericMethod() {
@@ -271,16 +271,16 @@
 /*element: testGenericMixinInstantiation:
  static=[
   GenericSub.(0),
-  assertIsSubtype,
-  throwTypeError]
+  assertIsSubtype(5),
+  throwTypeError(1)]
 */
 testGenericMixinInstantiation() => new GenericSub<int, String>();
 
 /*element: testGenericNamedMixinInstantiation:
  static=[
   GenericNamedMixin.(0),
-  assertIsSubtype,
-  throwTypeError]
+  assertIsSubtype(5),
+  throwTypeError(1)]
 */
 testGenericNamedMixinInstantiation() => new GenericNamedMixin<int, String>();
 
@@ -294,13 +294,13 @@
 
   /*strong.element: GenericClass.genericMethod:
    static=[
-    checkSubtype,
-    checkSubtypeOfRuntimeType,
-    getRuntimeTypeArgument,
-    getRuntimeTypeArgumentIntercepted,
-    getRuntimeTypeInfo,
-    getTypeArgumentByIndex,
-    setRuntimeTypeInfo],
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    setRuntimeTypeInfo(2)],
    type=[
     inst:JSArray<dynamic>,
     inst:JSBool,
diff --git a/tests/compiler/dart2js/impact/data/constructors.dart b/tests/compiler/dart2js/impact/data/constructors.dart
index ab690a7..60fb2ae 100644
--- a/tests/compiler/dart2js/impact/data/constructors.dart
+++ b/tests/compiler/dart2js/impact/data/constructors.dart
@@ -49,7 +49,7 @@
   new Class.generative();
 }
 
-/*element: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+/*element: testConstructorInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
 testConstructorInvokeGeneric() {
   new GenericClass<int, String>.generative();
 }
@@ -69,7 +69,7 @@
   new Class.fact();
 }
 
-/*element: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype,throwTypeError]*/
+/*element: testFactoryInvokeGeneric:static=[GenericClass.fact(0),assertIsSubtype(5),throwTypeError(1)]*/
 testFactoryInvokeGeneric() {
   new GenericClass<int, String>.fact();
 }
@@ -89,7 +89,7 @@
   new Class.redirect();
 }
 
-/*element: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+/*element: testRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
 testRedirectingFactoryInvokeGeneric() {
   new GenericClass<int, String>.redirect();
 }
@@ -109,7 +109,7 @@
   const Class.redirect();
 }
 
-/*element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype,throwTypeError]*/
+/*element: testConstRedirectingFactoryInvokeGeneric:static=[GenericClass.generative(0),assertIsSubtype(5),throwTypeError(1)]*/
 testConstRedirectingFactoryInvokeGeneric() {
   const GenericClass<int, String>.redirect();
 }
diff --git a/tests/compiler/dart2js/impact/data/expressions.dart b/tests/compiler/dart2js/impact/data/expressions.dart
index c1570bf..ca8a80d 100644
--- a/tests/compiler/dart2js/impact/data/expressions.dart
+++ b/tests/compiler/dart2js/impact/data/expressions.dart
@@ -110,12 +110,12 @@
 
 /*element: testIsGeneric:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -143,12 +143,12 @@
 
 /*element: testIsNotGeneric:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -173,12 +173,12 @@
 
 /*element: testIsTypedef:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -193,12 +193,12 @@
 
 /*element: testIsTypedefGeneric:
  static=[
- checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+ checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -212,12 +212,12 @@
 
 /*element: testIsTypedefGenericRaw:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -231,12 +231,12 @@
 
 /*element: testIsTypedefGenericDynamic:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -250,12 +250,12 @@
 
 /*element: testIsTypedefDeep:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -268,19 +268,19 @@
 testIsTypedefDeep() => null is List<GenericTypedef<int, GenericTypedef>>;
 
 /*element: testAs:
- static=[throwRuntimeError],
+ static=[throwRuntimeError(1)],
  type=[as:Class,inst:JSBool]
 */
 // ignore: UNNECESSARY_CAST
 testAs(dynamic o) => o as Class;
 
-/*element: testAsGeneric:static=[checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo,
-  throwRuntimeError],
+/*element: testAsGeneric:static=[checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2),
+  throwRuntimeError(1)],
   type=[as:GenericClass<int,
   String>,
   inst:JSArray<dynamic>,
@@ -293,21 +293,21 @@
 testAsGeneric(dynamic o) => o as GenericClass<int, String>;
 
 /*element: testAsGenericRaw:
- static=[throwRuntimeError],
+ static=[throwRuntimeError(1)],
  type=[as:GenericClass<dynamic,dynamic>,inst:JSBool]
 */
 // ignore: UNNECESSARY_CAST
 testAsGenericRaw(dynamic o) => o as GenericClass;
 
 /*element: testAsGenericDynamic:
- static=[throwRuntimeError],
+ static=[throwRuntimeError(1)],
  type=[as:GenericClass<dynamic,dynamic>,inst:JSBool]
 */
 // ignore: UNNECESSARY_CAST
 testAsGenericDynamic(dynamic o) => o as GenericClass<dynamic, dynamic>;
 
 /*element: testThrow:
- static=[throwExpression,wrapException],
+ static=[throwExpression(1),wrapException(1)],
  type=[inst:JSString]*/
 testThrow() => throw '';
 
diff --git a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
index defa672..0f7f42a 100644
--- a/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
+++ b/tests/compiler/dart2js/impact/data/extract_type_arguments.dart
@@ -15,13 +15,13 @@
 /*element: testA:
  dynamic=[call<A.T>(0)],
  static=[
-  checkSubtype,
+  checkSubtype(4),
   extractTypeArguments<A<dynamic>>(2),
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   impl:A<dynamic>,
   impl:Function,
@@ -37,13 +37,13 @@
 /*element: testB:
  dynamic=[call<B.S,B.U>(0)],
  static=[
-  checkSubtype,
+  checkSubtype(4),
   extractTypeArguments<B<dynamic,dynamic>>(2),
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   impl:B<dynamic,dynamic>,
   impl:Function,
diff --git a/tests/compiler/dart2js/impact/data/future_or.dart b/tests/compiler/dart2js/impact/data/future_or.dart
index c119fbe..21f6b17 100644
--- a/tests/compiler/dart2js/impact/data/future_or.dart
+++ b/tests/compiler/dart2js/impact/data/future_or.dart
@@ -7,7 +7,7 @@
 /*element: main:
  dynamic=[runtimeType],
  runtimeType=[unknown:FutureOr<int>],
- static=[Future.value(1),assertIsSubtype,print(1),throwTypeError],
+ static=[Future.value(1),assertIsSubtype(5),print(1),throwTypeError(1)],
  type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]
 */
 @pragma('dart2js:disableFinal')
diff --git a/tests/compiler/dart2js/impact/data/initializers.dart b/tests/compiler/dart2js/impact/data/initializers.dart
index 0155408..d8e2fd5 100644
--- a/tests/compiler/dart2js/impact/data/initializers.dart
+++ b/tests/compiler/dart2js/impact/data/initializers.dart
@@ -123,13 +123,13 @@
   /*strong.element: ClassGeneric.:
    static=[
     Object.(0),
-    checkSubtype,
-    checkSubtypeOfRuntimeType,
-    getRuntimeTypeArgument,
-    getRuntimeTypeArgumentIntercepted,
-    getRuntimeTypeInfo,
-    getTypeArgumentByIndex,
-    setRuntimeTypeInfo],
+    checkSubtype(4),
+    checkSubtypeOfRuntimeType(2),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    setRuntimeTypeInfo(2)],
    type=[
     inst:JSArray<dynamic>,
     inst:JSBool,
@@ -142,5 +142,5 @@
   ClassGeneric(T arg);
 }
 
-/*element: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype,throwTypeError],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
+/*element: testGenericClass:static=[ClassGeneric.(1),assertIsSubtype(5),throwTypeError(1)],type=[inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSUInt31,inst:JSUInt32]*/
 testGenericClass() => new ClassGeneric<int>(0);
diff --git a/tests/compiler/dart2js/impact/data/invokes.dart b/tests/compiler/dart2js/impact/data/invokes.dart
index ae0262a..aa2b472 100644
--- a/tests/compiler/dart2js/impact/data/invokes.dart
+++ b/tests/compiler/dart2js/impact/data/invokes.dart
@@ -130,12 +130,12 @@
 
 /*strong.element: topLevelFunction3Typed:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -190,12 +190,12 @@
 
 /*strong.element: topLevelFunctionTyped1:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -209,12 +209,12 @@
 
 /*strong.element: topLevelFunctionTyped2:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -228,12 +228,12 @@
 
 /*strong.element: topLevelFunctionTyped3:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -247,12 +247,12 @@
 
 /*strong.element: topLevelFunctionTyped4:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -312,7 +312,7 @@
 /*element: testTopLevelField:static=[topLevelField]*/
 testTopLevelField() => topLevelField;
 
-/*element: topLevelFieldLazy:static=[throwCyclicInit,topLevelFunction1(1)],type=[inst:JSNull]*/
+/*element: topLevelFieldLazy:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
 var topLevelFieldLazy = topLevelFunction1(null);
 
 /*element: testTopLevelFieldLazy:static=[topLevelFieldLazy]*/
@@ -324,7 +324,7 @@
 /*element: testTopLevelFieldConst:static=[topLevelFieldConst]*/
 testTopLevelFieldConst() => topLevelFieldConst;
 
-/*element: topLevelFieldFinal:static=[throwCyclicInit,topLevelFunction1(1)],type=[inst:JSNull]*/
+/*element: topLevelFieldFinal:static=[throwCyclicInit(1),topLevelFunction1(1)],type=[inst:JSNull]*/
 final topLevelFieldFinal = topLevelFunction1(null);
 
 /*element: testTopLevelFieldFinal:static=[topLevelFieldFinal]*/
@@ -350,12 +350,12 @@
 
 /*strong.element: topLevelFieldGeneric3:
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -472,11 +472,11 @@
 
 /*strong.element: testLocalFunction:
  static=[
-  computeSignature,
+  computeSignature(3),
   def:localFunction,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:Function,
   inst:JSArray<dynamic>,
@@ -492,11 +492,11 @@
 
 /*strong.element: testLocalFunctionTyped:
  static=[
-  computeSignature,
+  computeSignature(3),
   def:localFunction,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
   type=[inst:Function,
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -513,12 +513,12 @@
 
 /*strong.element: testLocalFunctionInvoke:
  dynamic=[call(0)],
- static=[computeSignature,
+ static=[computeSignature(3),
   def:localFunction,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
   localFunction(0),
-  setRuntimeTypeInfo],
+  setRuntimeTypeInfo(2)],
   type=[inst:Function,
   inst:JSArray<dynamic>,
   inst:JSExtendableArray<dynamic>,
@@ -530,11 +530,11 @@
   localFunction();
 }
 
-/*strong.element: testLocalFunctionGet:static=[computeSignature,
+/*strong.element: testLocalFunctionGet:static=[computeSignature(3),
   def:localFunction,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
   type=[inst:Function,
   inst:JSArray<dynamic>,
   inst:JSExtendableArray<dynamic>,
@@ -546,11 +546,11 @@
   localFunction;
 }
 
-/*strong.element: testClosure:static=[computeSignature,
+/*strong.element: testClosure:static=[computeSignature(3),
   def:<anonymous>,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
   type=[inst:Function,
   inst:JSArray<dynamic>,
   inst:JSExtendableArray<dynamic>,
@@ -563,11 +563,11 @@
 
 /*strong.element: testClosureInvoke:
  dynamic=[call(0)],
- static=[computeSignature,
+ static=[computeSignature(3),
   def:<anonymous>,
-  getRuntimeTypeArguments,
-  getRuntimeTypeInfo,
-  setRuntimeTypeInfo],
+  getRuntimeTypeArguments(3),
+  getRuntimeTypeInfo(1),
+  setRuntimeTypeInfo(2)],
   type=[inst:Function,
   inst:JSArray<dynamic>,
   inst:JSExtendableArray<dynamic>,
diff --git a/tests/compiler/dart2js/impact/data/jsinterop.dart b/tests/compiler/dart2js/impact/data/jsinterop.dart
index b36d583..8e77d6ac 100644
--- a/tests/compiler/dart2js/impact/data/jsinterop.dart
+++ b/tests/compiler/dart2js/impact/data/jsinterop.dart
@@ -56,12 +56,12 @@
 class GenericClass<T> {
   /*strong.element: GenericClass.method:
    static=[
-    checkSubtype,
-    getRuntimeTypeArgument,
-    getRuntimeTypeArgumentIntercepted,
-    getRuntimeTypeInfo,
-    getTypeArgumentByIndex,
-    setRuntimeTypeInfo],
+    checkSubtype(4),
+    getRuntimeTypeArgument(3),
+    getRuntimeTypeArgumentIntercepted(4),
+    getRuntimeTypeInfo(1),
+    getTypeArgumentByIndex(2),
+    setRuntimeTypeInfo(2)],
    type=[
     inst:JSArray<dynamic>,
     inst:JSBool,
diff --git a/tests/compiler/dart2js/impact/data/literals.dart b/tests/compiler/dart2js/impact/data/literals.dart
index 1239e44..925896a0 100644
--- a/tests/compiler/dart2js/impact/data/literals.dart
+++ b/tests/compiler/dart2js/impact/data/literals.dart
@@ -80,22 +80,35 @@
 /*element: testString:type=[inst:JSString]*/
 testString() => 'foo';
 
-/*element: testStringInterpolation:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSString]*/
+/*element: testStringInterpolation:
+ dynamic=[toString(0)],
+ static=[S(1)],type=[inst:JSBool,inst:JSString]
+*/
 testStringInterpolation() => '${true}';
 
-/*element: testStringInterpolationConst:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSString]*/
+/*element: testStringInterpolationConst:
+ dynamic=[toString(0)],
+ static=[S(1)],type=[inst:JSBool,inst:JSString]
+*/
 testStringInterpolationConst() {
   const b = '${true}';
   return b;
 }
 
-/*element: testStringJuxtaposition:dynamic=[toString(0)],static=[S],type=[inst:JSString]*/
+/*element: testStringJuxtaposition:
+ dynamic=[toString(0)],
+ static=[S(1)],
+ type=[inst:JSString]
+*/
 testStringJuxtaposition() => 'a' 'b';
 
-/*element: testSymbol:static=[Symbol.],type=[inst:Symbol]*/
+/*element: testSymbol:static=[Symbol.(1)],type=[inst:Symbol]*/
 testSymbol() => #main;
 
-/*element: testConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated],type=[inst:JSString,inst:Symbol]*/
+/*element: testConstSymbol:
+ static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
+ type=[inst:JSString,inst:Symbol]
+*/
 testConstSymbol() => const Symbol('main');
 
 /*strong.element: complexSymbolField1:
@@ -104,7 +117,11 @@
 */
 const complexSymbolField1 = "true".length == 4;
 
-/*strong.element: complexSymbolField2:dynamic=[toString(0)],static=[S],type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]*/
+/*strong.element: complexSymbolField2:
+ dynamic=[toString(0)],
+ static=[S(1)],
+ type=[inst:JSBool,inst:JSNull,inst:JSString,param:String]
+*/
 const complexSymbolField2 = "true" "false" "${true}${null}";
 
 /*strong.element: complexSymbolField3:
@@ -112,20 +129,20 @@
   static=[
    GenericClass.generative(0),
    String.fromEnvironment(1),
-   Symbol.,
-   assertIsSubtype,
+   Symbol.(1),
+   assertIsSubtype(5),
    bool.fromEnvironment(1,defaultValue),
-   checkSubtype,
-   getRuntimeTypeArgument,
-   getRuntimeTypeArgumentIntercepted,
-   getRuntimeTypeInfo,
-   getTypeArgumentByIndex,
+   checkSubtype(4),
+   getRuntimeTypeArgument(3),
+   getRuntimeTypeArgumentIntercepted(4),
+   getRuntimeTypeInfo(1),
+   getTypeArgumentByIndex(2),
    identical(2),
    int.fromEnvironment(1,defaultValue),
    override,
-   setRuntimeTypeInfo,
+   setRuntimeTypeInfo(2),
    testComplexConstSymbol,
-   throwTypeError],
+   throwTypeError(1)],
   type=[
    inst:ConstantMap<dynamic,dynamic>,
    inst:ConstantProtoMap<dynamic,dynamic>,
@@ -159,17 +176,33 @@
   override: const GenericClass<int, String>.generative(),
 };
 
-/*strong.element: complexSymbolField:static=[complexSymbolField1,complexSymbolField2,complexSymbolField3],type=[inst:JSBool,param:Object]*/
+/*strong.element: complexSymbolField:
+ static=[
+  complexSymbolField1,
+  complexSymbolField2,
+  complexSymbolField3],
+ type=[inst:JSBool,param:Object]
+*/
 const complexSymbolField =
     complexSymbolField1 ? complexSymbolField2 : complexSymbolField3;
 
-/*strong.element: testComplexConstSymbol:static=[Symbol.,Symbol.(1),Symbol.validated,complexSymbolField],type=[impl:String,inst:JSBool,inst:Symbol]*/
+/*strong.element: testComplexConstSymbol:
+ static=[Symbol.(1),Symbol.(1),Symbol.validated(1),complexSymbolField],
+ type=[impl:String,inst:JSBool,inst:Symbol]
+*/
 testComplexConstSymbol() => const Symbol(complexSymbolField);
 
-/*element: testIfNullConstSymbol:dynamic=[Null.==],static=[Symbol.,Symbol.(1),Symbol.validated],type=[inst:JSNull,inst:JSString,inst:Symbol]*/
+/*element: testIfNullConstSymbol:
+ dynamic=[Null.==],
+ static=[Symbol.(1),Symbol.(1),Symbol.validated(1)],
+ type=[inst:JSNull,inst:JSString,inst:Symbol]
+*/
 testIfNullConstSymbol() => const Symbol(null ?? 'foo');
 
-/*element: testTypeLiteral:static=[createRuntimeType],type=[inst:Type,inst:TypeImpl,lit:Object]*/
+/*element: testTypeLiteral:
+ static=[createRuntimeType(1)],
+ type=[inst:Type,inst:TypeImpl,lit:Object]
+*/
 testTypeLiteral() => Object;
 
 /*element: testBoolFromEnvironment:static=[bool.fromEnvironment(1)],type=[inst:JSString]*/
diff --git a/tests/compiler/dart2js/impact/data/native.dart b/tests/compiler/dart2js/impact/data/native.dart
index 47d2ce2..b314794 100644
--- a/tests/compiler/dart2js/impact/data/native.dart
+++ b/tests/compiler/dart2js/impact/data/native.dart
@@ -78,7 +78,7 @@
 
 /*strong.element: testNativeField:
  dynamic=[NativeClass.field],
- static=[defineProperty],
+ static=[defineProperty(3)],
  type=[inst:JSBool,param:NativeClass]
 */
 testNativeField(NativeClass c) => c.field;
diff --git a/tests/compiler/dart2js/impact/data/runtime_type.dart b/tests/compiler/dart2js/impact/data/runtime_type.dart
index 96fac37..d5d911b 100644
--- a/tests/compiler/dart2js/impact/data/runtime_type.dart
+++ b/tests/compiler/dart2js/impact/data/runtime_type.dart
@@ -64,13 +64,13 @@
  dynamic=[Class2.runtimeType,toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
-  S,
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  S(1),
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -87,13 +87,13 @@
  dynamic=[Class2.==,Class2.runtimeType,toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
-  S,
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  S(1),
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -111,12 +111,12 @@
  dynamic=[Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -132,12 +132,12 @@
  dynamic=[Class2.runtimeType,Type.==,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -154,12 +154,12 @@
  dynamic=[Class2.==,Class2.runtimeType,Type.==,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -176,12 +176,12 @@
  dynamic=[Class2.==,Class2.runtimeType,Type.toString(0)],
  runtimeType=[string:Class2<int>],
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -198,12 +198,12 @@
  dynamic=[Class2.runtimeType],
  runtimeType=[unknown:Class2<int>],
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -219,12 +219,12 @@
  dynamic=[Class1a.==,Class1a.runtimeType,Class1d.==,Class1d.runtimeType,Type.==],
  runtimeType=[equals:Class1a<int>/Class1d<int>],
  static=[
-  checkSubtype,
-  getRuntimeTypeArgument,
-  getRuntimeTypeArgumentIntercepted,
-  getRuntimeTypeInfo,
-  getTypeArgumentByIndex,
-  setRuntimeTypeInfo],
+  checkSubtype(4),
+  getRuntimeTypeArgument(3),
+  getRuntimeTypeArgumentIntercepted(4),
+  getRuntimeTypeInfo(1),
+  getTypeArgumentByIndex(2),
+  setRuntimeTypeInfo(2)],
  type=[
   inst:JSArray<dynamic>,
   inst:JSBool,
@@ -404,14 +404,14 @@
   almostToString2(1),
   almostToString3(1),
   almostToString4(1),
-  assertIsSubtype,
+  assertIsSubtype(5),
   equals1(2),
   notEquals1(2),
   notEquals2(2),
   notEquals3(2),
   notEquals4(2),
   print(1),
-  throwTypeError,
+  throwTypeError(1),
   toString1(1),
   toString2(1),
   toString3(1),
diff --git a/tests/compiler/dart2js/impact/data/statements.dart b/tests/compiler/dart2js/impact/data/statements.dart
index d7b466f..4603006 100644
--- a/tests/compiler/dart2js/impact/data/statements.dart
+++ b/tests/compiler/dart2js/impact/data/statements.dart
@@ -70,7 +70,7 @@
   current,
   iterator,
   moveNext(0)],
- static=[checkConcurrentModificationError],
+ static=[checkConcurrentModificationError(2)],
  type=[
   impl:Iterable<dynamic>,
   inst:JSBool,
@@ -87,7 +87,7 @@
   current,
   iterator,
   moveNext(0)],
- static=[checkConcurrentModificationError],
+ static=[checkConcurrentModificationError(2)],
  type=[
   impl:Iterable<dynamic>,
   impl:int,
@@ -101,7 +101,7 @@
 }
 
 /*element: testTryCatch:
- static=[unwrapException],
+ static=[unwrapException(1)],
  type=[
   inst:PlainJavaScriptObject,
   inst:UnknownJavaScriptObject]
@@ -111,7 +111,7 @@
 }
 
 /*element: testTryCatchOn:
- static=[unwrapException],
+ static=[unwrapException(1)],
  type=[
   catch:String,
   inst:JSBool,
@@ -125,8 +125,8 @@
 
 /*element: testTryCatchStackTrace:
  static=[
-  getTraceFromException,
-  unwrapException],
+  getTraceFromException(1),
+  unwrapException(1)],
  type=[
   inst:PlainJavaScriptObject,
   inst:UnknownJavaScriptObject,
@@ -144,8 +144,8 @@
 
 /*element: testSwitchWithoutFallthrough:
  static=[
-  throwExpression,
-  wrapException],
+  throwExpression(1),
+  wrapException(1)],
  type=[
   inst:JSDouble,
   inst:JSInt,
@@ -171,12 +171,12 @@
   }
 }
 
-/*element: testAssert:static=[assertHelper],type=[inst:JSBool]*/
+/*element: testAssert:static=[assertHelper(1)],type=[inst:JSBool]*/
 testAssert() {
   assert(true);
 }
 
-/*element: testAssertWithMessage:static=[assertTest,assertThrow],type=[inst:JSBool,inst:JSString]*/
+/*element: testAssertWithMessage:static=[assertTest(1),assertThrow(1)],type=[inst:JSBool,inst:JSString]*/
 testAssertWithMessage() {
   assert(true, 'ok');
 }
diff --git a/tests/compiler/dart2js/impact/impact_test.dart b/tests/compiler/dart2js/impact/impact_test.dart
index e59b077..2dc7d40 100644
--- a/tests/compiler/dart2js/impact/impact_test.dart
+++ b/tests/compiler/dart2js/impact/impact_test.dart
@@ -9,6 +9,7 @@
 import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/ir/util.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
+import 'package:compiler/src/kernel/element_map_impl.dart';
 import 'package:compiler/src/universe/feature.dart';
 import 'package:compiler/src/universe/use.dart';
 import 'package:compiler/src/universe/world_impact.dart';
@@ -20,6 +21,15 @@
 main(List<String> args) {
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
+    print('Testing direct computation of ResolutionImpact');
+    print('==================================================================');
+    useImpactDataForTesting = false;
+    await checkTests(dataDir, const ImpactDataComputer(),
+        args: args, testOmit: false, testFrontend: true);
+
+    print('Testing computation of ResolutionImpact through ImpactData');
+    print('==================================================================');
+    useImpactDataForTesting = true;
     await checkTests(dataDir, const ImpactDataComputer(),
         args: args, testOmit: false, testFrontend: true);
   });
diff --git a/tests/compiler/dart2js/inference/data/call_site.dart b/tests/compiler/dart2js/inference/data/call_site.dart
index 5fd4eea..5af853c 100644
--- a/tests/compiler/dart2js/inference/data/call_site.dart
+++ b/tests/compiler/dart2js/inference/data/call_site.dart
@@ -221,8 +221,10 @@
 class A15 {
   /*element: A15.x15:[exact=JSUInt31]*/
   x15(/*[exact=JSUInt31]*/ p1,
-          [/*Value([exact=JSString], value: "s")*/ p2 = "s"]) =>
-      1;
+      [/*Value([exact=JSString], value: "s")*/ p2 = "s"]) {
+    p2. /*Value([exact=JSString], value: "s")*/ length;
+    return 1;
+  }
 }
 
 /*element: test15:[null]*/
diff --git a/tests/compiler/dart2js/inference/data/field_type.dart b/tests/compiler/dart2js/inference/data/field_type.dart
index 8e2e9c04..4f499a9 100644
--- a/tests/compiler/dart2js/inference/data/field_type.dart
+++ b/tests/compiler/dart2js/inference/data/field_type.dart
@@ -352,7 +352,7 @@
   // TODO(johnniwinther): Investigate why these include `null`. The ast version
   // didn't.
 
-  /*element: A16.f16:Union([exact=JSString], [null|exact=JSUInt31])*/
+  /*element: A16.f16:Union([exact=JSUInt31], [null|exact=JSString])*/
   var f16;
 
   /*element: A16.:[exact=A16]*/
diff --git a/tests/compiler/dart2js/inlining/meta_annotations_test.dart b/tests/compiler/dart2js/inlining/meta_annotations_test.dart
index e62db8e..8904107 100644
--- a/tests/compiler/dart2js/inlining/meta_annotations_test.dart
+++ b/tests/compiler/dart2js/inlining/meta_annotations_test.dart
@@ -49,11 +49,11 @@
       Expect.isNotNull(method);
       Expect.equals(
           expectNoInline,
-          closedWorld.annotationsData.nonInlinableFunctions.contains(method),
+          closedWorld.annotationsData.hasNoInline(method),
           "Unexpected annotation of @noInline on '$method'.");
       Expect.equals(
           expectTryInline,
-          closedWorld.annotationsData.tryInlineFunctions.contains(method),
+          closedWorld.annotationsData.hasTryInline(method),
           "Unexpected annotation of @tryInline on '$method'.");
     }
 
diff --git a/tests/compiler/dart2js/js/js_spec_string_test.dart b/tests/compiler/dart2js/js/js_spec_string_test.dart
index 1e7080d..0dc8344 100644
--- a/tests/compiler/dart2js/js/js_spec_string_test.dart
+++ b/tests/compiler/dart2js/js/js_spec_string_test.dart
@@ -270,12 +270,11 @@
   testWithSideEffects(' returns:A|B|C;   creates:A;  ',
       returns: ['A', 'B', 'C'], creates: ['A']);
 
-  test('throws:must', expectedThrows: NativeThrowBehavior.MUST);
   test('throws:may', expectedThrows: NativeThrowBehavior.MAY);
   test('throws:never', expectedThrows: NativeThrowBehavior.NEVER);
-  test('throws:null(1)',
-      expectedThrows:
-          NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS);
+  test('throws:null(1)', expectedThrows: NativeThrowBehavior.NULL_NSM);
+  test('throws:null(1)+may',
+      expectedThrows: NativeThrowBehavior.NULL_NSM_THEN_MAY);
 
   test('new:true', expectedNew: true);
   test('new:false', expectedNew: false);
diff --git a/tests/compiler/dart2js/js/js_throw_behavior_test.dart b/tests/compiler/dart2js/js/js_throw_behavior_test.dart
index 22fb733..0c3ecea 100644
--- a/tests/compiler/dart2js/js/js_throw_behavior_test.dart
+++ b/tests/compiler/dart2js/js/js_throw_behavior_test.dart
@@ -16,9 +16,9 @@
 
 void main() {
   final MAY = NativeThrowBehavior.MAY;
-  final MUST = NativeThrowBehavior.MUST;
   final NEVER = NativeThrowBehavior.NEVER;
-  final NULL_NSM = NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS;
+  final NULL_NSM = NativeThrowBehavior.NULL_NSM;
+  final NULL_NSM_THEN_MAY = NativeThrowBehavior.NULL_NSM_THEN_MAY;
 
   test('0', NEVER);
   test('void 0', NEVER);
@@ -86,6 +86,7 @@
 
   test('console', MAY);
   test('Array', NEVER);
+  test('Math', NEVER);
   test('Object', NEVER);
 
   test('typeof #', NEVER);
@@ -93,8 +94,25 @@
   test('typeof foo.#', MAY);
   test('typeof #.foo', NULL_NSM);
 
-  test('throw 123', MUST);
-  test('throw #', MUST);
-  test('throw #.x', MUST); // Could be better: is also an NSM guard.
-  test('throw #.x = 123', MUST);
+  test('throw 123', MAY);
+  test('throw #', MAY);
+  test('throw #.x', NULL_NSM_THEN_MAY);
+  test('throw #.x = 123', MAY);
+
+  test('#.f()', NULL_NSM_THEN_MAY);
+  test('#.f(#, #)', NULL_NSM_THEN_MAY);
+  test('#[#](#, #)', NULL_NSM_THEN_MAY);
+  test('#[f()](#, #)', MAY); // f() evaluated before
+
+  test('[]', NEVER);
+  test('[,,6,,,]', NEVER);
+  test('[#.f()]', NULL_NSM_THEN_MAY);
+  test('[,,#.f(),,f(),,]', NULL_NSM_THEN_MAY);
+  test('[,,f(),,#.f(),,]', MAY);
+
+  test('{}', NEVER);
+  test('{one: 1}', NEVER);
+  test('{one: #.f()}', NULL_NSM_THEN_MAY);
+  test('{one: #.f(), two: f()}', NULL_NSM_THEN_MAY);
+  test('{one: f(), two: #.f()}', MAY);
 }
diff --git a/tests/compiler/dart2js/member_usage/data/constructors.dart b/tests/compiler/dart2js/member_usage/data/constructors.dart
new file mode 100644
index 0000000..fe9889d
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/constructors.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.
+
+class Class {
+  /*element: Class.constructor1:invoke*/
+  Class.constructor1() {}
+
+  /*element: Class.constructor2a:invoke=(0)*/
+  Class.constructor2a([a]) {}
+
+  /*element: Class.constructor2b:invoke*/
+  Class.constructor2b([a]) {}
+
+  /*element: Class.constructor2c:invoke*/
+  Class.constructor2c([a]) {}
+
+  /*element: Class.constructor3a:invoke=(0)*/
+  Class.constructor3a([a, b]) {}
+
+  /*element: Class.constructor3b:invoke=(1)*/
+  Class.constructor3b([a, b]) {}
+
+  /*element: Class.constructor3c:invoke*/
+  Class.constructor3c([a, b]) {}
+
+  /*element: Class.constructor4a:invoke=(0)*/
+  Class.constructor4a({a}) {}
+
+  /*element: Class.constructor4b:invoke*/
+  Class.constructor4b({a}) {}
+
+  /*element: Class.constructor4c:invoke*/
+  Class.constructor4c({a}) {}
+
+  /*element: Class.constructor5a:invoke=(0)*/
+  Class.constructor5a({a, b}) {}
+
+  /*element: Class.constructor5b:invoke=(0,a)*/
+  Class.constructor5b({a, b}) {}
+
+  /*element: Class.constructor5c:invoke=(0,b)*/
+  Class.constructor5c({a, b}) {}
+
+  /*element: Class.constructor6a:invoke=(1)*/
+  Class.constructor6a(a, [b, c]) {}
+
+  /*element: Class.constructor6b:invoke=(2)*/
+  Class.constructor6b(a, [b, c]) {}
+
+  /*element: Class.constructor6c:invoke*/
+  Class.constructor6c(a, [b, c]) {}
+
+  /*element: Class.constructor7a:invoke=(1)*/
+  Class.constructor7a(a, {b, c}) {}
+
+  /*element: Class.constructor7b:invoke=(1,b)*/
+  Class.constructor7b(a, {b, c}) {}
+
+  /*element: Class.constructor7c:invoke=(1,c)*/
+  Class.constructor7c(a, {b, c}) {}
+}
+
+/*element: main:invoke*/
+main() {
+  new Class.constructor1();
+
+  new Class.constructor2a();
+  new Class.constructor2b(null);
+  new Class.constructor2c();
+  new Class.constructor2c(null);
+
+  new Class.constructor3a();
+  new Class.constructor3b();
+  new Class.constructor3b(null);
+  new Class.constructor3c(null, null);
+
+  new Class.constructor4a();
+  new Class.constructor4b(a: null);
+  new Class.constructor4c();
+  new Class.constructor4c(a: null);
+
+  new Class.constructor5a();
+  new Class.constructor5b(a: null);
+  new Class.constructor5c(b: null);
+
+  new Class.constructor6a(null);
+  new Class.constructor6b(null);
+  new Class.constructor6b(null, null);
+  new Class.constructor6c(null, null, null);
+
+  new Class.constructor7a(null);
+  new Class.constructor7b(null, b: null);
+  new Class.constructor7c(null, c: null);
+}
diff --git a/tests/compiler/dart2js/member_usage/data/fields.dart b/tests/compiler/dart2js/member_usage/data/fields.dart
new file mode 100644
index 0000000..5d95285
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/fields.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: field1a:init,read*/
+var field1a;
+
+/*element: field1b:init,write*/
+var field1b;
+
+/*element: field1c:init,read,write*/
+var field1c;
+
+/*element: field2a:read*/
+get field2a => 42;
+
+set field2a(_) {}
+
+get field2b => 42;
+
+/*element: field2b=:write*/
+set field2b(_) {}
+
+/*element: field2c:read*/
+get field2c => 42;
+
+/*element: field2c=:write*/
+set field2c(_) {}
+
+class Class {
+  /*element: Class.field1a:init,read*/
+  var field1a;
+
+  /*element: Class.field1b:init,write*/
+  var field1b;
+
+  /*element: Class.field1c:init,read,write*/
+  var field1c;
+
+  /*element: Class.field2a:read*/
+  get field2a => 42;
+
+  set field2a(_) {}
+
+  get field2b => 42;
+
+  /*element: Class.field2b=:write*/
+  set field2b(_) {}
+
+  /*element: Class.field2c:read*/
+  get field2c => 42;
+
+  /*element: Class.field2c=:write*/
+  set field2c(_) {}
+
+  /*element: Class.field3a:init*/
+  var field3a = 0;
+
+  /*element: Class.field3b:init*/
+  var field3b;
+
+  /*element: Class.:invoke=(0)*/
+  Class([this.field3b]);
+
+  /*element: Class.test:invoke*/
+  test() {
+    field1a;
+    field1b = 42;
+    field1c = field1c;
+
+    field2a;
+    field2b = 42;
+    field2c = field2c;
+  }
+}
+
+/*element: main:invoke*/
+main() {
+  field1a;
+  field1b = 42;
+  field1c = field1c;
+
+  field2a;
+  field2b = 42;
+  field2c = field2c;
+
+  new Class().test();
+}
diff --git a/tests/compiler/dart2js/member_usage/data/general.dart b/tests/compiler/dart2js/member_usage/data/general.dart
new file mode 100644
index 0000000..ffab22b
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/general.dart
@@ -0,0 +1,212 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: A.:invoke*/
+class A {
+  /*element: A.method1:invoke*/
+  method1() {}
+
+  method2() {}
+
+  /*element: A.method4:invoke*/
+  method4() {}
+
+  /*element: A.getter:read*/
+  get getter => 42;
+
+  set setter(_) {}
+}
+
+/*element: B.:invoke*/
+class B {
+  method1() {}
+  method2() {}
+
+  /*element: B.method5:invoke*/
+  method5() {}
+  get getter => 42;
+
+  /*element: B.setter=:write*/
+  set setter(_) {}
+}
+
+/*element: C.:invoke*/
+class C extends A {
+  /*element: C.method1:invoke*/
+  method1() {}
+
+  /*element: B.method2:invoke*/
+  method2() {}
+  method4() {}
+
+  /*element: C.getter:read*/
+  get getter => 42;
+  set setter(_) {}
+}
+
+/*element: D.:invoke*/
+class D implements B {
+  method1() {}
+
+  /*element: D.method2:invoke*/
+  method2() {}
+  method5() {}
+  get getter => 42;
+
+  /*element: D.setter=:write*/
+  set setter(_) {}
+}
+
+class E implements A {
+  method1() {}
+  method2() {}
+  method4() {}
+  get getter => 42;
+  set setter(_) {}
+}
+
+class F extends B {
+  method1() {}
+  method2() {}
+  method5() {}
+  get getter => 42;
+  set setter(_) {}
+}
+
+class G {
+  /*element: G.method1:invoke*/
+  method1() {}
+  method2() {}
+  method4() {}
+
+  /*element: G.getter:read*/
+  get getter => 42;
+  set setter(_) {}
+}
+
+/*element: H.:invoke*/
+class H extends Object with G implements A {}
+
+/*element: I.:invoke*/
+class I {
+  /*element: I.method1:invoke*/
+  method1() {}
+  method2() {}
+  method4() {}
+
+  /*element: I.getter:read*/
+  get getter => 42;
+  set setter(_) {}
+}
+
+/*element: J.:invoke*/
+class J extends I implements A {}
+
+class K {
+  /*element: K.method1:invoke*/
+  method1() {}
+  method2() {}
+
+  /*element: K.getter:read*/
+  get getter => 42;
+  set setter(_) {}
+}
+
+class L = Object with K;
+class L2 = Object with L;
+
+/*element: M.:invoke*/
+class M extends L {}
+
+/*element: M2.:invoke*/
+class M2 extends L2 {}
+
+/*element: N.:invoke*/
+class N {
+  method1() {}
+  get getter => 42;
+  set setter(_) {}
+}
+
+abstract class O extends N {}
+
+/*element: P.:invoke*/
+class P implements O {
+  /*element: P.method1:invoke*/
+  method1() {}
+
+  /*element: P.getter:read*/
+  get getter => 42;
+
+  /*element: P.setter=:write*/
+  set setter(_) {}
+}
+
+/*element: Q.:invoke*/
+class Q {
+  /*element: Q.method3:invoke*/
+  method3() {}
+}
+
+/*element: R.:invoke*/
+class R extends Q {}
+
+/*element: Class1a.:invoke*/
+class Class1a {
+  /*element: Class1a.call:invoke*/
+  call(a, b, c) {} // Call structure only used in Class1a and Class2b.
+}
+
+/*element: Class1b.:invoke*/
+class Class1b {
+  call(a, b, c) {}
+}
+
+/*element: Class2.:invoke*/
+class Class2 {
+  /*element: Class2.c:init,read*/
+  Class1a c;
+}
+
+/*element: main:invoke*/
+main() {
+  method1();
+  method2();
+}
+
+/*element: method1:invoke*/
+@pragma('dart2js:disableFinal')
+method1() {
+  A a = new A();
+  B b = new B();
+  a.method1();
+  a.getter;
+  b.method2();
+  b.setter = 42;
+  new C();
+  new D();
+  new H();
+  new J();
+  new M().method1();
+  new M2().getter;
+  new N();
+  O o = new P();
+  o.method1();
+  o.getter;
+  o.setter = 42;
+  R r;
+  r.method3();
+  r = new R(); // Create R after call.
+  new Class1a();
+  new Class1b();
+  new Class2().c(0, 1, 2);
+}
+
+/*element: method2:invoke*/
+method2() {
+  A a = new A();
+  B b = new B();
+  a.method4();
+  b.method5();
+}
diff --git a/tests/compiler/dart2js/member_usage/data/generic.dart b/tests/compiler/dart2js/member_usage/data/generic.dart
new file mode 100644
index 0000000..9cf10de
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/generic.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.
+
+/*element: Class.:invoke*/
+class Class {
+  // The type parameter is never provided but needed nonetheless.
+  /*element: Class.method1:invoke=(0)*/
+  method1<S>([a]) => S;
+
+  /*element: Class.method2:invoke=<1>(0)*/
+  method2<S>([a]) => S;
+
+  /*element: Class.method3:invoke=<1>(0)*/
+  method3<S>([a]) => S;
+
+  /*element: Class.method4:invoke=(1)*/
+  method4<S>([a]) => S;
+
+  /*element: Class.method5:invoke*/
+  method5<S>([a]) => S;
+
+  /*element: Class.method6:invoke*/
+  method6<S>([a]) => S;
+}
+
+/*element: main:invoke*/
+main() {
+  dynamic c = new Class();
+  c.method1();
+  c.method2<int>();
+  c.method3();
+  c.method3<int>();
+  c.method4(0);
+  c.method5<int>(0);
+  c.method6(0);
+  c.method6<int>(0);
+}
diff --git a/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart b/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
new file mode 100644
index 0000000..28754c5
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/instance_method_parameters.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: Class.:invoke*/
+class Class {
+  /*element: Class.method1:invoke*/
+  method1() {}
+
+  /*element: Class.method2a:invoke=(0)*/
+  method2a([a]) {}
+
+  /*element: Class.method2b:invoke*/
+  method2b([a]) {}
+
+  /*element: Class.method2c:invoke*/
+  method2c([a]) {}
+
+  /*element: Class.method2d:invoke,read*/
+  method2d([a]) {}
+
+  /*element: Class.method3a:invoke=(0)*/
+  method3a([a, b]) {}
+
+  /*element: Class.method3b:invoke=(1)*/
+  method3b([a, b]) {}
+
+  /*element: Class.method3c:invoke*/
+  method3c([a, b]) {}
+
+  /*element: Class.method3d:invoke,read*/
+  method3d([a, b]) {}
+
+  /*element: Class.method4a:invoke=(0)*/
+  method4a({a}) {}
+
+  /*element: Class.method4b:invoke*/
+  method4b({a}) {}
+
+  /*element: Class.method4c:invoke*/
+  method4c({a}) {}
+
+  /*element: Class.method4d:invoke,read*/
+  method4d({a}) {}
+
+  /*element: Class.method5a:invoke=(0)*/
+  method5a({a, b}) {}
+
+  /*element: Class.method5b:invoke=(0,a)*/
+  method5b({a, b}) {}
+
+  /*element: Class.method5c:invoke=(0,b)*/
+  method5c({a, b}) {}
+
+  /*element: Class.method5d:invoke,read*/
+  method5d({a, b}) {}
+
+  /*element: Class.method6a:invoke*/
+  method6a<T>() {}
+
+  /*element: Class.method6b:invoke,read*/
+  method6b<T>() {}
+
+  /*element: Class.method7a:invoke=(1)*/
+  method7a(a, [b, c]) {}
+
+  /*element: Class.method7b:invoke=(2)*/
+  method7b(a, [b, c]) {}
+
+  /*element: Class.method7c:invoke*/
+  method7c(a, [b, c]) {}
+
+  /*element: Class.method7d:invoke,read*/
+  method7d(a, [b, c]) {}
+
+  /*element: Class.method8a:invoke=(1)*/
+  method8a(a, {b, c}) {}
+
+  /*element: Class.method8b:invoke=(1,b)*/
+  method8b(a, {b, c}) {}
+
+  /*element: Class.method8c:invoke=(1,c)*/
+  method8c(a, {b, c}) {}
+
+  /*element: Class.method8d:invoke,read*/
+  method8d(a, {b, c}) {}
+
+  /*element: Class.test:invoke*/
+  test() {
+    method1();
+
+    method2a();
+    method2b(null);
+    method2c();
+    method2c(null);
+    method2d;
+
+    method3a();
+    method3b();
+    method3b(null);
+    method3c(null, null);
+    method3d;
+
+    method4a();
+    method4b(a: null);
+    method4c();
+    method4c(a: null);
+    method4d;
+
+    method5a();
+    method5b(a: null);
+    method5c(b: null);
+    method5d;
+
+    method6a();
+    method6b;
+
+    method7a(null);
+    method7b(null);
+    method7b(null, null);
+    method7c(null, null, null);
+    method7d;
+
+    method8a(null);
+    method8b(null, b: null);
+    method8c(null, c: null);
+    method8d;
+  }
+}
+
+/*element: main:invoke*/
+main() {
+  new Class().test();
+}
diff --git a/tests/compiler/dart2js/member_usage/data/native.dart b/tests/compiler/dart2js/member_usage/data/native.dart
new file mode 100644
index 0000000..a787af4
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/native.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// ignore: import_internal_library
+import 'dart:_js_helper';
+
+/*element: field2a:read*/
+@JSName('field2a')
+get field2a => 42;
+
+@JSName('field2a')
+set field2a(_) {}
+
+@JSName('field2b')
+get field2b => 42;
+
+/*element: field2b=:write*/
+@JSName('field2b')
+set field2b(_) {}
+
+/*element: field2c:read*/
+@JSName('field2c')
+get field2c => 42;
+
+/*element: field2c=:write*/
+@JSName('field2c')
+set field2c(_) {}
+
+@Native('Class')
+class Class {
+  /*element: Class.field1a:read*/
+  var field1a;
+
+  /*element: Class.field1b:write*/
+  var field1b;
+
+  /*element: Class.field1c:read,write*/
+  var field1c;
+
+  /*element: Class.field2a:read*/
+  get field2a => 42;
+
+  set field2a(_) {}
+
+  get field2b => 42;
+
+  /*element: Class.field2b=:write*/
+  set field2b(_) {}
+
+  /*element: Class.field2c:read*/
+  get field2c => 42;
+
+  /*element: Class.field2c=:write*/
+  set field2c(_) {}
+
+  var field3a = 0;
+
+  /*element: Class.field3b:init*/
+  var field3b;
+
+  /*element: Class.:invoke=(0)*/
+  Class([this.field3b]);
+
+  /*element: Class.test:invoke*/
+  test() {
+    field1a;
+    field1b = 42;
+    field1c = field1c;
+
+    field2a;
+    field2b = 42;
+    field2c = field2c;
+  }
+}
+
+/*element: main:invoke*/
+main() {
+  field2a;
+  field2b = 42;
+  field2c = field2c;
+
+  new Class().test();
+}
diff --git a/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart b/tests/compiler/dart2js/member_usage/data/static_method_parameters.dart
new file mode 100644
index 0000000..bb133a2
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/data/static_method_parameters.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.
+
+/*element: method1:invoke*/
+method1() {}
+
+/*element: method2a:invoke=(0)*/
+method2a([a]) {}
+
+/*element: method2b:invoke*/
+method2b([a]) {}
+
+/*element: method2c:invoke*/
+method2c([a]) {}
+
+/*element: method2d:invoke,read*/
+method2d([a]) {}
+
+/*element: method3a:invoke=(0)*/
+method3a([a, b]) {}
+
+/*element: method3b:invoke=(1)*/
+method3b([a, b]) {}
+
+/*element: method3c:invoke*/
+method3c([a, b]) {}
+
+/*element: method3d:invoke,read*/
+method3d([a, b]) {}
+
+/*element: method4a:invoke=(0)*/
+method4a({a}) {}
+
+/*element: method4b:invoke*/
+method4b({a}) {}
+
+/*element: method4c:invoke*/
+method4c({a}) {}
+
+/*element: method4d:invoke,read*/
+method4d({a}) {}
+
+/*element: method5a:invoke=(0)*/
+method5a({a, b}) {}
+
+/*element: method5b:invoke=(0,a)*/
+method5b({a, b}) {}
+
+/*element: method5c:invoke=(0,b)*/
+method5c({a, b}) {}
+
+/*element: method5d:invoke,read*/
+method5d({a, b}) {}
+
+/*element: method6a:invoke*/
+method6a<T>() {}
+
+/*element: method6b:invoke,read*/
+method6b<T>() {}
+
+/*element: method7a:invoke=(1)*/
+method7a(a, [b, c]) {}
+
+/*element: method7b:invoke=(2)*/
+method7b(a, [b, c]) {}
+
+/*element: method7c:invoke*/
+method7c(a, [b, c]) {}
+
+/*element: method7d:invoke,read*/
+method7d(a, [b, c]) {}
+
+/*element: method8a:invoke=(1)*/
+method8a(a, {b, c}) {}
+
+/*element: method8b:invoke=(1,b)*/
+method8b(a, {b, c}) {}
+
+/*element: method8c:invoke=(1,c)*/
+method8c(a, {b, c}) {}
+
+/*element: method8d:invoke,read*/
+method8d(a, {b, c}) {}
+
+/*element: main:invoke*/
+main() {
+  method1();
+
+  method2a();
+  method2b(null);
+  method2c();
+  method2c(null);
+  method2d;
+
+  method3a();
+  method3b();
+  method3b(null);
+  method3c(null, null);
+  method3d;
+
+  method4a();
+  method4b(a: null);
+  method4c();
+  method4c(a: null);
+  method4d;
+
+  method5a();
+  method5b(a: null);
+  method5c(b: null);
+  method5d;
+
+  method6a();
+  method6b;
+
+  method7a(null);
+  method7b(null);
+  method7b(null, null);
+  method7c(null, null, null);
+  method7d;
+
+  method8a(null);
+  method8b(null, b: null);
+  method8c(null, c: null);
+  method8d;
+}
diff --git a/tests/compiler/dart2js/member_usage/member_usage_test.dart b/tests/compiler/dart2js/member_usage/member_usage_test.dart
new file mode 100644
index 0000000..b7e95ee
--- /dev/null
+++ b/tests/compiler/dart2js/member_usage/member_usage_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All 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:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/enqueue.dart';
+import 'package:compiler/src/ir/util.dart';
+import 'package:compiler/src/kernel/kernel_strategy.dart';
+import 'package:compiler/src/universe/member_usage.dart';
+import 'package:compiler/src/universe/resolution_world_builder.dart';
+import 'package:compiler/src/util/features.dart';
+import 'package:kernel/ast.dart' as ir;
+import '../equivalence/id_equivalence.dart';
+import '../equivalence/id_equivalence_helper.dart';
+
+main(List<String> args) {
+  asyncTest(() async {
+    Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
+    print('------------------------------------------------------------------');
+    print(' Test with enqueuer checks');
+    print('------------------------------------------------------------------');
+    await checkTests(dataDir, const ClosedWorldDataComputer(false),
+        args: args, testOmit: false, testFrontend: true);
+    print('------------------------------------------------------------------');
+    print(' Test without enqueuer checks');
+    print('------------------------------------------------------------------');
+    await checkTests(dataDir, const ClosedWorldDataComputer(true),
+        args: args, testOmit: false, testFrontend: true);
+  });
+}
+
+class Tags {
+  static const String init = 'init';
+  static const String read = 'read';
+  static const String write = 'write';
+  static const String invoke = 'invoke';
+}
+
+class ClosedWorldDataComputer extends DataComputer<Features> {
+  final bool skipEnqueuerCheck;
+
+  const ClosedWorldDataComputer(this.skipEnqueuerCheck);
+
+  @override
+  void setup() {
+    Enqueuer.skipEnqueuerCheckForTesting = skipEnqueuerCheck;
+  }
+
+  @override
+  void computeMemberData(Compiler compiler, MemberEntity member,
+      Map<Id, ActualData<Features>> actualMap,
+      {bool verbose: false}) {
+    KernelFrontEndStrategy frontendStrategy = compiler.frontendStrategy;
+    ResolutionWorldBuilderImpl resolutionWorldBuilder =
+        compiler.resolutionWorldBuilder;
+    ir.Member node = frontendStrategy.elementMap.getMemberNode(member);
+    Features features = new Features();
+    MemberUsage memberUsage =
+        resolutionWorldBuilder.memberUsageForTesting[member];
+    if (memberUsage != null) {
+      if (member.isField && memberUsage.hasInit) {
+        features.add(Tags.init);
+      }
+      if (memberUsage.hasRead) {
+        features.add(Tags.read);
+      }
+      if (memberUsage.hasWrite) {
+        features.add(Tags.write);
+      }
+      if (memberUsage.isFullyInvoked) {
+        features.add(Tags.invoke);
+      } else if (memberUsage.hasInvoke) {
+        features[Tags.invoke] = memberUsage.invokedParameters.shortText;
+      }
+    }
+    Id id = computeEntityId(node);
+    actualMap[id] = new ActualData<Features>(
+        id, features, computeSourceSpanFromTreeNode(node), member);
+  }
+
+  @override
+  DataInterpreter<Features> get dataValidator =>
+      const FeaturesDataInterpreter();
+}
diff --git a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
index 3b16a86..c35cadf 100644
--- a/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_evaluate_test.dart
@@ -67,6 +67,8 @@
 
   bool get checkCasts => true;
 
+  bool get immediateUnderSetLiteral => _environment.immediateUnderSetLiteral;
+
   @override
   String readFromEnvironment(String name) => env[name];
 
@@ -130,6 +132,11 @@
   }
 
   @override
+  ConstantValue evaluateMapBody(ConstantValue evaluate()) {
+    return _environment.evaluateMapBody(evaluate);
+  }
+
+  @override
   bool get enableAssertions => true;
 }
 
diff --git a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
index aeb3108..ccc0c12 100644
--- a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
+++ b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
@@ -205,7 +205,7 @@
     List<String> expectedLiveMembers =
         expectedLiveMembersMap[cls.name] ?? const <String>[];
     List<String> actualLiveMembers = <String>[];
-    closedWorld.processedMembers.forEach((MemberEntity member) {
+    closedWorld.liveMemberUsage.forEach((MemberEntity member, _) {
       if (member.enclosingClass != cls) return;
       if (member.isConstructor) return;
       actualLiveMembers.add(member.name);
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index 40907d7..04a8e63 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -31,8 +31,7 @@
 }
 
 void testTypes(TypeEnvironment env, DartType subtype, DartType supertype,
-    bool expectSubtype, bool expectMoreSpecific) {
-  if (expectMoreSpecific == null) expectMoreSpecific = expectSubtype;
+    bool expectSubtype) {
   Expect.equals(expectSubtype, env.isSubtype(subtype, supertype),
       '$subtype <: $supertype');
   if (expectSubtype) {
@@ -41,11 +40,11 @@
   }
 }
 
-void testElementTypes(TypeEnvironment env, String subname, String supername,
-    bool expectSubtype, bool expectMoreSpecific) {
+void testElementTypes(
+    TypeEnvironment env, String subname, String supername, bool expectSubtype) {
   DartType subtype = env.getElementType(subname);
   DartType supertype = env.getElementType(supername);
-  testTypes(env, subtype, supertype, expectSubtype, expectMoreSpecific);
+  testTypes(env, subtype, supertype, expectSubtype);
 }
 
 Future testInterfaceSubtype() async {
@@ -60,9 +59,8 @@
         new C();
       }
       """, expectNoErrors: true).then((env) {
-    void expect(bool expectSubtype, DartType T, DartType S,
-        {bool expectMoreSpecific}) {
-      testTypes(env, T, S, expectSubtype, expectMoreSpecific);
+    void expect(bool expectSubtype, DartType T, DartType S) {
+      testTypes(env, T, S, expectSubtype);
     }
 
     ClassEntity A = env.getClass('A');
@@ -79,7 +77,7 @@
     expect(true, void_, void_);
     expect(true, void_, dynamic_);
     // Unsure about the next one, see dartbug.com/14933.
-    expect(true, dynamic_, void_, expectMoreSpecific: false);
+    expect(true, dynamic_, void_);
     expect(true, void_, Object_);
     expect(true, Object_, void_);
     expect(true, Null_, void_);
@@ -88,28 +86,28 @@
     expect(true, num_, Object_);
     expect(true, int_, Object_);
     expect(true, String_, Object_);
-    expect(true, dynamic_, Object_, expectMoreSpecific: false);
+    expect(true, dynamic_, Object_);
     expect(true, Null_, Object_);
 
     expect(false, Object_, num_);
     expect(true, num_, num_);
     expect(true, int_, num_);
     expect(false, String_, num_);
-    expect(false, dynamic_, num_, expectMoreSpecific: false);
+    expect(false, dynamic_, num_);
     expect(true, Null_, num_);
 
     expect(false, Object_, int_);
     expect(false, num_, int_);
     expect(true, int_, int_);
     expect(false, String_, int_);
-    expect(false, dynamic_, int_, expectMoreSpecific: false);
+    expect(false, dynamic_, int_);
     expect(true, Null_, int_);
 
     expect(false, Object_, String_);
     expect(false, num_, String_);
     expect(false, int_, String_);
     expect(true, String_, String_);
-    expect(false, dynamic_, String_, expectMoreSpecific: false);
+    expect(false, dynamic_, String_);
     expect(true, Null_, String_);
 
     expect(true, Object_, dynamic_);
@@ -123,7 +121,7 @@
     expect(false, num_, Null_);
     expect(false, int_, Null_);
     expect(false, String_, Null_);
-    expect(false, dynamic_, Null_, expectMoreSpecific: false);
+    expect(false, dynamic_, Null_);
     expect(true, Null_, Null_);
 
     DartType A_Object = instantiate(A, [Object_]);
@@ -144,28 +142,28 @@
     expect(true, A_num, A_Object);
     expect(true, A_int, A_Object);
     expect(true, A_String, A_Object);
-    expect(true, A_dynamic, A_Object, expectMoreSpecific: false);
+    expect(true, A_dynamic, A_Object);
     expect(true, A_Null, A_Object);
 
     expect(false, A_Object, A_num);
     expect(true, A_num, A_num);
     expect(true, A_int, A_num);
     expect(false, A_String, A_num);
-    expect(false, A_dynamic, A_num, expectMoreSpecific: false);
+    expect(false, A_dynamic, A_num);
     expect(true, A_Null, A_num);
 
     expect(false, A_Object, A_int);
     expect(false, A_num, A_int);
     expect(true, A_int, A_int);
     expect(false, A_String, A_int);
-    expect(false, A_dynamic, A_int, expectMoreSpecific: false);
+    expect(false, A_dynamic, A_int);
     expect(true, A_Null, A_int);
 
     expect(false, A_Object, A_String);
     expect(false, A_num, A_String);
     expect(false, A_int, A_String);
     expect(true, A_String, A_String);
-    expect(false, A_dynamic, A_String, expectMoreSpecific: false);
+    expect(false, A_dynamic, A_String);
     expect(true, A_Null, A_String);
 
     expect(true, A_Object, A_dynamic);
@@ -179,7 +177,7 @@
     expect(false, A_num, A_Null);
     expect(false, A_int, A_Null);
     expect(false, A_String, A_Null);
-    expect(false, A_dynamic, A_Null, expectMoreSpecific: false);
+    expect(false, A_dynamic, A_Null);
     expect(true, A_Null, A_Null);
 
     DartType B_Object_Object = instantiate(B, [Object_, Object_]);
@@ -210,10 +208,10 @@
     expect(true, B_int_num, A_dynamic);
 
     expect(true, B_dynamic_dynamic, Object_);
-    expect(true, B_dynamic_dynamic, A_Object, expectMoreSpecific: false);
-    expect(false, B_dynamic_dynamic, A_num, expectMoreSpecific: false);
-    expect(false, B_dynamic_dynamic, A_int, expectMoreSpecific: false);
-    expect(false, B_dynamic_dynamic, A_String, expectMoreSpecific: false);
+    expect(true, B_dynamic_dynamic, A_Object);
+    expect(false, B_dynamic_dynamic, A_num);
+    expect(false, B_dynamic_dynamic, A_int);
+    expect(false, B_dynamic_dynamic, A_String);
     expect(true, B_dynamic_dynamic, A_dynamic);
 
     expect(true, B_String_dynamic, Object_);
@@ -226,19 +224,19 @@
     expect(true, B_Object_Object, B_Object_Object);
     expect(true, B_num_num, B_Object_Object);
     expect(true, B_int_num, B_Object_Object);
-    expect(true, B_dynamic_dynamic, B_Object_Object, expectMoreSpecific: false);
-    expect(true, B_String_dynamic, B_Object_Object, expectMoreSpecific: false);
+    expect(true, B_dynamic_dynamic, B_Object_Object);
+    expect(true, B_String_dynamic, B_Object_Object);
 
     expect(false, B_Object_Object, B_num_num);
     expect(true, B_num_num, B_num_num);
     expect(true, B_int_num, B_num_num);
-    expect(false, B_dynamic_dynamic, B_num_num, expectMoreSpecific: false);
+    expect(false, B_dynamic_dynamic, B_num_num);
     expect(false, B_String_dynamic, B_num_num);
 
     expect(false, B_Object_Object, B_int_num);
     expect(false, B_num_num, B_int_num);
     expect(true, B_int_num, B_int_num);
-    expect(false, B_dynamic_dynamic, B_int_num, expectMoreSpecific: false);
+    expect(false, B_dynamic_dynamic, B_int_num);
     expect(false, B_String_dynamic, B_int_num);
 
     expect(true, B_Object_Object, B_dynamic_dynamic);
@@ -250,8 +248,7 @@
     expect(false, B_Object_Object, B_String_dynamic);
     expect(false, B_num_num, B_String_dynamic);
     expect(false, B_int_num, B_String_dynamic);
-    expect(false, B_dynamic_dynamic, B_String_dynamic,
-        expectMoreSpecific: false);
+    expect(false, B_dynamic_dynamic, B_String_dynamic);
     expect(true, B_String_dynamic, B_String_dynamic);
 
     DartType C_Object_Object = instantiate(C, [Object_, Object_]);
@@ -277,12 +274,11 @@
     expect(true, C_int_String, B_dynamic_dynamic);
     expect(true, C_int_String, B_String_dynamic);
 
-    expect(true, C_dynamic_dynamic, B_Object_Object, expectMoreSpecific: false);
-    expect(false, C_dynamic_dynamic, B_num_num, expectMoreSpecific: false);
-    expect(false, C_dynamic_dynamic, B_int_num, expectMoreSpecific: false);
+    expect(true, C_dynamic_dynamic, B_Object_Object);
+    expect(false, C_dynamic_dynamic, B_num_num);
+    expect(false, C_dynamic_dynamic, B_int_num);
     expect(true, C_dynamic_dynamic, B_dynamic_dynamic);
-    expect(false, C_dynamic_dynamic, B_String_dynamic,
-        expectMoreSpecific: false);
+    expect(false, C_dynamic_dynamic, B_String_dynamic);
 
     expect(false, C_int_String, A_int);
     expect(true, C_int_String, A_String);
@@ -319,9 +315,8 @@
         a.m5(null, null);
       }
       """, expectNoErrors: true).then((env) {
-    void expect(bool expectSubtype, DartType T, DartType S,
-        {bool expectMoreSpecific}) {
-      testTypes(env, T, S, expectSubtype, expectMoreSpecific);
+    void expect(bool expectSubtype, DartType T, DartType S) {
+      testTypes(env, T, S, expectSubtype);
     }
 
     ClassEntity classA = env.getClass('A');
@@ -338,7 +333,7 @@
     expect(false, A, call);
     expect(false, call, m1);
     expect(false, A, m1);
-    expect(false, A, m2, expectMoreSpecific: false);
+    expect(false, A, m2);
     expect(false, A, m3);
     expect(false, A, m4);
     expect(false, A, m5);
@@ -388,9 +383,8 @@
 }
 
 functionSubtypingHelper(TypeEnvironment env) {
-  void expect(bool expectSubtype, String sub, String sup,
-      {bool expectMoreSpecific}) {
-    testElementTypes(env, sub, sup, expectSubtype, expectMoreSpecific);
+  void expect(bool expectSubtype, String sub, String sup) {
+    testElementTypes(env, sub, sup, expectSubtype);
   }
 
   // () -> int <: Function
@@ -403,7 +397,7 @@
   // () -> dynamic <: () -> void
   expect(true, '_', 'void_');
   // () -> void <: () -> dynamic
-  expect(true, 'void_', '_', expectMoreSpecific: false);
+  expect(true, 'void_', '_');
 
   // () -> int <: () -> void
   expect(true, 'int_', 'void_');
@@ -426,7 +420,7 @@
   // (int) -> int <: (int) -> int
   expect(true, 'int__int', 'int__int2');
   // (Object) -> int <: (int) -> Object
-  expect(true, 'int__Object', 'Object__int', expectMoreSpecific: false);
+  expect(true, 'int__Object', 'Object__int');
   // (int) -> int <: (double) -> int
   expect(false, 'int__int', 'int__double');
   // () -> int <: (int) -> int
@@ -482,9 +476,8 @@
 }
 
 functionSubtypingOptionalHelper(TypeEnvironment env) {
-  void expect(bool expectSubtype, String sub, String sup,
-      {bool expectMoreSpecific}) {
-    testElementTypes(env, sub, sup, expectSubtype, expectMoreSpecific);
+  void expect(bool expectSubtype, String sub, String sup) {
+    testElementTypes(env, sub, sup, expectSubtype);
   }
 
   // Test ([int])->void <: ()->void.
@@ -496,7 +489,7 @@
   // Test ([int])->void <: ([int])->void.
   expect(true, 'void___int', 'void___int2');
   // Test ([Object])->void <: ([int])->void.
-  expect(true, 'void___Object', 'void___int', expectMoreSpecific: false);
+  expect(true, 'void___Object', 'void___int');
   // Test ([int])->void <: ([Object])->void.
   expect(false, 'void___int', 'void___Object');
   // Test (int,[int])->void <: (int)->void.
@@ -520,7 +513,7 @@
   // Test ([int,int])->void <: ([int])->void.
   expect(true, 'void___int_int', 'void___int');
   // Test ([Object,int])->void <: ([int])->void.
-  expect(true, 'void___Object_int', 'void___int', expectMoreSpecific: false);
+  expect(true, 'void___Object_int', 'void___int');
 }
 
 const List<FunctionTypeData> namedFunctionTypesData = const <FunctionTypeData>[
@@ -564,9 +557,8 @@
 }
 
 functionSubtypingNamedHelper(TypeEnvironment env) {
-  expect(bool expectSubtype, String sub, String sup,
-      {bool expectMoreSpecific}) {
-    testElementTypes(env, sub, sup, expectSubtype, expectMoreSpecific);
+  expect(bool expectSubtype, String sub, String sup) {
+    testElementTypes(env, sub, sup, expectSubtype);
   }
 
   // Test ({int a})->void <: ()->void.
@@ -580,7 +572,7 @@
   // Test ({int a})->void <: ({int b})->void.
   expect(false, 'void___a_int', 'void___b_int');
   // Test ({Object a})->void <: ({int a})->void.
-  expect(true, 'void___a_Object', 'void___a_int', expectMoreSpecific: false);
+  expect(true, 'void___a_Object', 'void___a_int');
   // Test ({int a})->void <: ({Object a})->void.
   expect(false, 'void___a_int', 'void___a_Object');
   // Test (int,{int a})->void <: (int,{int a})->void.
@@ -617,9 +609,8 @@
         new F();
       }
       """, expectNoErrors: true).then((env) {
-    void expect(bool expectSubtype, DartType T, DartType S,
-        {bool expectMoreSpecific}) {
-      testTypes(env, T, S, expectSubtype, expectMoreSpecific);
+    void expect(bool expectSubtype, DartType T, DartType S) {
+      testTypes(env, T, S, expectSubtype);
     }
 
     TypeVariableType getTypeVariable(ClassEntity cls, int index) {
diff --git a/tests/compiler/dart2js/optimization/data/arithmetic.dart b/tests/compiler/dart2js/optimization/data/arithmetic.dart
new file mode 100644
index 0000000..f8aad1b
--- /dev/null
+++ b/tests/compiler/dart2js/optimization/data/arithmetic.dart
@@ -0,0 +1,489 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  negate(1);
+  negateNum(1);
+  negateNum(1.5);
+  negateNull(1);
+  negateNull(null);
+  negateString(1);
+  negateString('');
+
+  add(1, 2);
+  addNumInt(1, 2);
+  addNumInt(1.5, 2);
+  addIntNum(2, 1);
+  addIntNum(2, 1.5);
+  addNumNum(1, 1.5);
+  addNumNum(1.5, 1);
+  addIntNull(2, 1);
+  addIntNull(2, null);
+  addNullInt(1, 2);
+  addNullInt(null, 2);
+  addStringInt(1, 2);
+  addStringInt('', 2);
+  addIntString(2, 1);
+  addIntString(2, '');
+
+  subtract(1, 2);
+  subtractNumInt(1, 2);
+  subtractNumInt(1.5, 2);
+  subtractIntNum(2, 1);
+  subtractIntNum(2, 1.5);
+  subtractNumNum(1, 1.5);
+  subtractNumNum(1.5, 1);
+  subtractIntNull(2, 1);
+  subtractIntNull(2, null);
+  subtractNullInt(1, 2);
+  subtractNullInt(null, 2);
+  subtractStringInt(1, 2);
+  subtractStringInt('', 2);
+  subtractIntString(2, 1);
+  subtractIntString(2, '');
+
+  multiply(1, 2);
+  multiplyNumInt(1, 2);
+  multiplyNumInt(1.5, 2);
+  multiplyIntNum(2, 1);
+  multiplyIntNum(2, 1.5);
+  multiplyNumNum(1, 1.5);
+  multiplyNumNum(1.5, 1);
+  multiplyIntNull(2, 1);
+  multiplyIntNull(2, null);
+  multiplyNullInt(1, 2);
+  multiplyNullInt(null, 2);
+  multiplyStringInt(1, 2);
+  multiplyStringInt('', 2);
+  multiplyIntString(2, 1);
+  multiplyIntString(2, '');
+
+  divide(1, 2);
+  divideZero(1);
+  divideNumInt(1, 2);
+  divideNumInt(1.5, 2);
+  divideIntNum(2, 1);
+  divideIntNum(2, 1.5);
+  divideNumNum(1, 1.5);
+  divideNumNum(1.5, 1);
+  divideIntNull(2, 1);
+  divideIntNull(2, null);
+  divideNullInt(1, 2);
+  divideNullInt(null, 2);
+  divideStringInt(1, 2);
+  divideStringInt('', 2);
+  divideIntString(2, 1);
+  divideIntString(2, '');
+
+  truncatingDivide(1, 2);
+  truncatingDivideZero(1);
+  truncatingDivideIntNonZero1(1);
+  truncatingDivideIntNonZero2(2);
+  truncatingDivideNumInt(1, 2);
+  truncatingDivideNumInt(1.5, 2);
+  truncatingDivideNumNonZero(1);
+  truncatingDivideNumNonZero(1.5);
+  truncatingDivideIntNum(2, 1);
+  truncatingDivideIntNum(2, 1.5);
+  truncatingDivideNumNum(1, 1.5);
+  truncatingDivideNumNum(1.5, 1);
+  truncatingDivideIntNull(2, 1);
+  truncatingDivideIntNull(2, null);
+  truncatingDivideNullInt(1, 2);
+  truncatingDivideNullInt(null, 2);
+  truncatingDivideStringInt(1, 2);
+  truncatingDivideStringInt('', 2);
+  truncatingDivideIntString(2, 1);
+  truncatingDivideIntString(2, '');
+
+  abs(1);
+  absNum(1);
+  absNum(1.5);
+  absNull(1);
+  absNull(null);
+  absString(1);
+  absString('');
+
+  round(1);
+  roundNum(1);
+  roundNum(1.5);
+  roundNull(1);
+  roundNull(null);
+  roundString(1);
+  roundString('');
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Negation
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: negate:Specializer=[Negate],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+negate(o) {
+  return -o;
+}
+
+/*element: negateNum:Specializer=[Negate],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+negateNum(o) {
+  return -o;
+}
+
+/*element: negateNull:Specializer=[Negate],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+negateNull(o) {
+  return -o;
+}
+
+/*element: negateString:Specializer=[!Negate]*/
+@pragma('dart2js:noInline')
+negateString(o) {
+  return -o;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Addition
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: add:Specializer=[Add],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+add(a, b) {
+  return a + b;
+}
+
+/*element: addNumInt:Specializer=[Add],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+addNumInt(a, b) {
+  return a + b;
+}
+
+/*element: addIntNum:Specializer=[Add],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+addIntNum(a, b) {
+  return a + b;
+}
+
+/*element: addNumNum:Specializer=[Add],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+addNumNum(a, b) {
+  return a + b;
+}
+
+/*element: addNullInt:Specializer=[Add],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+addNullInt(a, b) {
+  return a + b;
+}
+
+/*element: addIntNull:Specializer=[Add],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+addIntNull(a, b) {
+  return a + b;
+}
+
+/*element: addStringInt:Specializer=[!Add]*/
+@pragma('dart2js:noInline')
+addStringInt(a, b) {
+  return a + b;
+}
+
+/*element: addIntString:Specializer=[Add],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+addIntString(a, b) {
+  return a + b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Subtraction
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: subtract:Specializer=[Subtract],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+subtract(a, b) {
+  return a - b;
+}
+
+/*element: subtractNumInt:Specializer=[Subtract],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+subtractNumInt(a, b) {
+  return a - b;
+}
+
+/*element: subtractIntNum:Specializer=[Subtract],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+subtractIntNum(a, b) {
+  return a - b;
+}
+
+/*element: subtractNumNum:Specializer=[Subtract],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+subtractNumNum(a, b) {
+  return a - b;
+}
+
+/*element: subtractNullInt:Specializer=[Subtract],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+subtractNullInt(a, b) {
+  return a - b;
+}
+
+/*element: subtractIntNull:Specializer=[Subtract],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+subtractIntNull(a, b) {
+  return a - b;
+}
+
+/*element: subtractStringInt:Specializer=[Subtract],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+subtractStringInt(a, b) {
+  return a - b;
+}
+
+/*element: subtractIntString:Specializer=[Subtract],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+subtractIntString(a, b) {
+  return a - b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Multiplication
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: multiply:Specializer=[Multiply],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+multiply(a, b) {
+  return a * b;
+}
+
+/*element: multiplyNumInt:Specializer=[Multiply],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+multiplyNumInt(a, b) {
+  return a * b;
+}
+
+/*element: multiplyIntNum:Specializer=[Multiply],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+multiplyIntNum(a, b) {
+  return a * b;
+}
+
+/*element: multiplyNumNum:Specializer=[Multiply],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+multiplyNumNum(a, b) {
+  return a * b;
+}
+
+/*element: multiplyNullInt:Specializer=[Multiply],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+multiplyNullInt(a, b) {
+  return a * b;
+}
+
+/*element: multiplyIntNull:Specializer=[Multiply],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+multiplyIntNull(a, b) {
+  return a * b;
+}
+
+/*element: multiplyStringInt:Specializer=[!Multiply]*/
+@pragma('dart2js:noInline')
+multiplyStringInt(a, b) {
+  return a * b;
+}
+
+/*element: multiplyIntString:Specializer=[Multiply],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+multiplyIntString(a, b) {
+  return a * b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Division
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: divide:Specializer=[Divide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+divide(a, b) {
+  return a / b;
+}
+
+/*element: divideZero:Specializer=[Divide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+divideZero(a) {
+  return a / 0;
+}
+
+/*element: divideNumInt:Specializer=[Divide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+divideNumInt(a, b) {
+  return a / b;
+}
+
+/*element: divideIntNum:Specializer=[Divide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+divideIntNum(a, b) {
+  return a / b;
+}
+
+/*element: divideNumNum:Specializer=[Divide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+divideNumNum(a, b) {
+  return a / b;
+}
+
+/*element: divideNullInt:Specializer=[Divide],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+divideNullInt(a, b) {
+  return a / b;
+}
+
+/*element: divideIntNull:Specializer=[Divide],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+divideIntNull(a, b) {
+  return a / b;
+}
+
+/*element: divideStringInt:Specializer=[Divide],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+divideStringInt(a, b) {
+  return a / b;
+}
+
+/*element: divideIntString:Specializer=[Divide],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+divideIntString(a, b) {
+  return a / b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Truncating division
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: truncatingDivide:Specializer=[TruncatingDivide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+truncatingDivide(a, b) {
+  return a ~/ 2;
+}
+
+/*element: truncatingDivideZero:Specializer=[!TruncatingDivide]*/
+@pragma('dart2js:noInline')
+truncatingDivideZero(a) {
+  return a ~/ 0;
+}
+
+/*element: truncatingDivideIntNonZero1:Specializer=[TruncatingDivide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+truncatingDivideIntNonZero1(a) {
+  return a ~/ 1;
+}
+
+/*element: truncatingDivideIntNonZero2:Specializer=[TruncatingDivide],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+truncatingDivideIntNonZero2(a) {
+  return a ~/ 2;
+}
+
+/*element: truncatingDivideNumInt:Specializer=[!TruncatingDivide]*/
+@pragma('dart2js:noInline')
+truncatingDivideNumInt(a, b) {
+  return a ~/ b;
+}
+
+/*element: truncatingDivideNumNonZero:Specializer=[TruncatingDivide._tdivFast],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+truncatingDivideNumNonZero(a) {
+  return a ~/ 2;
+}
+
+/*element: truncatingDivideIntNum:Specializer=[!TruncatingDivide]*/
+@pragma('dart2js:noInline')
+truncatingDivideIntNum(a, b) {
+  return a ~/ b;
+}
+
+/*element: truncatingDivideNumNum:Specializer=[!TruncatingDivide]*/
+@pragma('dart2js:noInline')
+truncatingDivideNumNum(a, b) {
+  return a ~/ b;
+}
+
+/*element: truncatingDivideNullInt:Specializer=[!TruncatingDivide],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+truncatingDivideNullInt(a, b) {
+  return a ~/ b;
+}
+
+/*element: truncatingDivideIntNull:Specializer=[!TruncatingDivide],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+truncatingDivideIntNull(a, b) {
+  return a ~/ b;
+}
+
+/*element: truncatingDivideStringInt:Specializer=[!TruncatingDivide],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+truncatingDivideStringInt(a, b) {
+  return a ~/ b;
+}
+
+/*element: truncatingDivideIntString:Specializer=[!TruncatingDivide],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+truncatingDivideIntString(a, b) {
+  return a ~/ b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// .abs()
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: abs:Specializer=[Abs]*/
+@pragma('dart2js:noInline')
+abs(o) {
+  return o.abs();
+}
+
+/*element: absNum:Specializer=[Abs]*/
+@pragma('dart2js:noInline')
+absNum(o) {
+  return o.abs();
+}
+
+/*element: absNull:Specializer=[Abs]*/
+@pragma('dart2js:noInline')
+absNull(o) {
+  return o.abs();
+}
+
+/*element: absString:Specializer=[!Abs]*/
+@pragma('dart2js:noInline')
+absString(o) {
+  return o.abs();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// .round()
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: round:Specializer=[Round]*/
+@pragma('dart2js:noInline')
+round(o) {
+  return o.round();
+}
+
+/*element: roundNum:Specializer=[Round]*/
+@pragma('dart2js:noInline')
+roundNum(o) {
+  return o.round();
+}
+
+/*element: roundNull:Specializer=[Round]*/
+@pragma('dart2js:noInline')
+roundNull(o) {
+  return o.round();
+}
+
+/*element: roundString:Specializer=[!Round]*/
+@pragma('dart2js:noInline')
+roundString(o) {
+  return o.round();
+}
diff --git a/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart b/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
new file mode 100644
index 0000000..c479a96
--- /dev/null
+++ b/tests/compiler/dart2js/optimization/data/arithmetic_simplification.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 constant folding on numbers.
+
+import 'package:expect/expect.dart';
+
+@AssumeDynamic()
+@pragma('dart2js:noInline')
+int confuse(int x) => x;
+
+/*element: intPlusZero:Specializer=[Add,BitAnd]*/
+@pragma('dart2js:noInline')
+intPlusZero() {
+  int x = confuse(0);
+  return (x & 1) + 0;
+}
+
+/*element: zeroPlusInt:Specializer=[Add,BitAnd]*/
+@pragma('dart2js:noInline')
+zeroPlusInt() {
+  int x = confuse(0);
+  return 0 + (x & 1);
+}
+
+/*element: numPlusZero:Specializer=[Add]*/
+@pragma('dart2js:noInline')
+numPlusZero() {
+  num x = confuse(0);
+  return x + 0;
+}
+
+/*element: zeroPlusNum:Specializer=[Add]*/
+@pragma('dart2js:noInline')
+zeroPlusNum() {
+  num x = confuse(0);
+  return 0 + x;
+}
+
+/*element: intTimesOne:Specializer=[BitAnd,Multiply]*/
+@pragma('dart2js:noInline')
+intTimesOne() {
+  int x = confuse(0);
+  return (x & 1) * 1;
+}
+
+/*element: oneTimesInt:Specializer=[BitAnd,Multiply]*/
+@pragma('dart2js:noInline')
+oneTimesInt() {
+  int x = confuse(0);
+  return 1 * (x & 1);
+}
+
+/*element: numTimesOne:Specializer=[Multiply]*/
+@pragma('dart2js:noInline')
+numTimesOne() {
+  num x = confuse(0);
+  return x * 1;
+}
+
+/*element: oneTimesNum:Specializer=[Multiply]*/
+@pragma('dart2js:noInline')
+oneTimesNum() {
+  num x = confuse(0);
+  return 1 * x;
+}
+
+main() {
+  intPlusZero();
+  zeroPlusInt();
+  numPlusZero();
+  zeroPlusNum();
+  intTimesOne();
+  oneTimesInt();
+  numTimesOne();
+  oneTimesNum();
+}
diff --git a/tests/compiler/dart2js/optimization/data/bit.dart b/tests/compiler/dart2js/optimization/data/bit.dart
new file mode 100644
index 0000000..51e3741
--- /dev/null
+++ b/tests/compiler/dart2js/optimization/data/bit.dart
@@ -0,0 +1,245 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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() {
+  bitNot(1);
+  bitNotNum(1);
+  bitNotNum(1.5);
+  bitNotNull(1);
+  bitNotNull(null);
+  bitNotString(1);
+  bitNotString('');
+
+  bitAnd(1, 2);
+  bitAndNumInt(1, 2);
+  bitAndNumInt(1.5, 2);
+  bitAndIntNum(2, 1);
+  bitAndIntNum(2, 1.5);
+  bitAndNumNum(1, 1.5);
+  bitAndNumNum(1.5, 1);
+  bitAndIntNull(2, 1);
+  bitAndIntNull(2, null);
+  bitAndNullInt(1, 2);
+  bitAndNullInt(null, 2);
+  bitAndStringInt(1, 2);
+  bitAndStringInt('', 2);
+  bitAndIntString(2, 1);
+  bitAndIntString(2, '');
+
+  bitOr(1, 2);
+  bitOrNumInt(1, 2);
+  bitOrNumInt(1.5, 2);
+  bitOrIntNum(2, 1);
+  bitOrIntNum(2, 1.5);
+  bitOrNumNum(1, 1.5);
+  bitOrNumNum(1.5, 1);
+  bitOrIntNull(2, 1);
+  bitOrIntNull(2, null);
+  bitOrNullInt(1, 2);
+  bitOrNullInt(null, 2);
+  bitOrStringInt(1, 2);
+  bitOrStringInt('', 2);
+  bitOrIntString(2, 1);
+  bitOrIntString(2, '');
+
+  bitXor(1, 2);
+  bitXorNumInt(1, 2);
+  bitXorNumInt(1.5, 2);
+  bitXorIntNum(2, 1);
+  bitXorIntNum(2, 1.5);
+  bitXorNumNum(1, 1.5);
+  bitXorNumNum(1.5, 1);
+  bitXorIntNull(2, 1);
+  bitXorIntNull(2, null);
+  bitXorNullInt(1, 2);
+  bitXorNullInt(null, 2);
+  bitXorStringInt(1, 2);
+  bitXorStringInt('', 2);
+  bitXorIntString(2, 1);
+  bitXorIntString(2, '');
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Bitwise not
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: bitNot:Specializer=[BitNot]*/
+@pragma('dart2js:noInline')
+bitNot(o) {
+  return ~o;
+}
+
+/*element: bitNotNum:Specializer=[BitNot]*/
+@pragma('dart2js:noInline')
+bitNotNum(o) {
+  return ~o;
+}
+
+/*element: bitNotNull:Specializer=[BitNot]*/
+@pragma('dart2js:noInline')
+bitNotNull(o) {
+  return ~o;
+}
+
+/*element: bitNotString:Specializer=[!BitNot]*/
+@pragma('dart2js:noInline')
+bitNotString(o) {
+  return ~o;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Bitwise and
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: bitAnd:Specializer=[BitAnd],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitAnd(a, b) {
+  return a & b;
+}
+
+/*element: bitAndNumInt:Specializer=[BitAnd],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitAndNumInt(a, b) {
+  return a & b;
+}
+
+/*element: bitAndIntNum:Specializer=[BitAnd],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitAndIntNum(a, b) {
+  return a & b;
+}
+
+/*element: bitAndNumNum:Specializer=[BitAnd],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitAndNumNum(a, b) {
+  return a & b;
+}
+
+/*element: bitAndNullInt:Specializer=[BitAnd],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+bitAndNullInt(a, b) {
+  return a & b;
+}
+
+/*element: bitAndIntNull:Specializer=[BitAnd],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+bitAndIntNull(a, b) {
+  return a & b;
+}
+
+/*element: bitAndStringInt:Specializer=[BitAnd],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+bitAndStringInt(a, b) {
+  return a & b;
+}
+
+/*element: bitAndIntString:Specializer=[BitAnd],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+bitAndIntString(a, b) {
+  return a & b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Bitwise or
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: bitOr:Specializer=[BitOr],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitOr(a, b) {
+  return a | b;
+}
+
+/*element: bitOrNumInt:Specializer=[BitOr],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitOrNumInt(a, b) {
+  return a | b;
+}
+
+/*element: bitOrIntNum:Specializer=[BitOr],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitOrIntNum(a, b) {
+  return a | b;
+}
+
+/*element: bitOrNumNum:Specializer=[BitOr],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitOrNumNum(a, b) {
+  return a | b;
+}
+
+/*element: bitOrNullInt:Specializer=[BitOr],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+bitOrNullInt(a, b) {
+  return a | b;
+}
+
+/*element: bitOrIntNull:Specializer=[BitOr],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+bitOrIntNull(a, b) {
+  return a | b;
+}
+
+/*element: bitOrStringInt:Specializer=[BitOr],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+bitOrStringInt(a, b) {
+  return a | b;
+}
+
+/*element: bitOrIntString:Specializer=[BitOr],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+bitOrIntString(a, b) {
+  return a | b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Bitwise xor
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: bitXor:Specializer=[BitXor],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitXor(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorNumInt:Specializer=[BitXor],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitXorNumInt(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorIntNum:Specializer=[BitXor],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitXorIntNum(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorNumNum:Specializer=[BitXor],TypeConversion=[]*/
+@pragma('dart2js:noInline')
+bitXorNumNum(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorNullInt:Specializer=[BitXor],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+bitXorNullInt(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorIntNull:Specializer=[BitXor],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+bitXorIntNull(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorStringInt:Specializer=[BitXor],TypeConversion=[kind=receiver&type=num]*/
+@pragma('dart2js:noInline')
+bitXorStringInt(a, b) {
+  return a ^ b;
+}
+
+/*element: bitXorIntString:Specializer=[BitXor],TypeConversion=[kind=argument&type=num]*/
+@pragma('dart2js:noInline')
+bitXorIntString(a, b) {
+  return a ^ b;
+}
diff --git a/tests/compiler/dart2js/optimization/data/field_get.dart b/tests/compiler/dart2js/optimization/data/field_get.dart
index e200302..349edca 100644
--- a/tests/compiler/dart2js/optimization/data/field_get.dart
+++ b/tests/compiler/dart2js/optimization/data/field_get.dart
@@ -56,8 +56,6 @@
   int field4;
 }
 
-// TODO(johnniwinther,sra): Maybe we should optimize cases like this to a direct
-// property access, because all targets are simple fields?
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   return c.field4;
diff --git a/tests/compiler/dart2js/optimization/data/field_set.dart b/tests/compiler/dart2js/optimization/data/field_set.dart
index 953fe07..3c19021 100644
--- a/tests/compiler/dart2js/optimization/data/field_set.dart
+++ b/tests/compiler/dart2js/optimization/data/field_set.dart
@@ -10,9 +10,13 @@
   method3(new Class3b());
   method4(new Class4a());
   method4(new Class4b());
+  method5(new Class5a());
+  method6(new Class6a());
+  method6(new Class6b());
 }
 
 class Class1a {
+  @pragma('dart2js:noElision')
   int field1;
 }
 
@@ -23,6 +27,7 @@
 }
 
 class Class2a {
+  @pragma('dart2js:noElision')
   int field2 = 42;
 }
 
@@ -56,9 +61,29 @@
   int field4;
 }
 
-// TODO(johnniwinther,sra): Maybe we should optimize cases like this to a direct
-// property write, because all targets are simple fields?
 @pragma('dart2js:noInline')
 method4(Class4a c) {
   c.field4 = 42;
 }
+
+class Class5a {
+  int field5;
+}
+
+/*element: method5:FieldSet=[removed=field5]*/
+@pragma('dart2js:noInline')
+method5(Class5a c) {
+  c.field5 = 42;
+}
+
+class Class6a {
+  int field6 = 42;
+}
+
+class Class6b extends Class6a {}
+
+/*element: method6:FieldSet=[removed=field6]*/
+@pragma('dart2js:noInline')
+method6(Class6a c) {
+  c.field6 = 42;
+}
diff --git a/tests/compiler/dart2js/optimization/data/index.dart b/tests/compiler/dart2js/optimization/data/index.dart
new file mode 100644
index 0000000..12586ad
--- /dev/null
+++ b/tests/compiler/dart2js/optimization/data/index.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+/*element: dynamicIndex:Specializer=[!Index]*/
+@pragma('dart2js:noInline')
+dynamicIndex(var list) {
+  return list[0]; // This not known to be an indexable primitive.
+}
+
+/*element: unknownListIndex:Specializer=[!Index]*/
+@pragma('dart2js:noInline')
+unknownListIndex(List list) {
+  return list[0]; // This not known to be an indexable primitive.
+}
+
+/*element: possiblyNullMutableListIndex:Specializer=[Index]*/
+@pragma('dart2js:noInline')
+possiblyNullMutableListIndex(bool b) {
+  var list = b ? [0] : null;
+  return list[0];
+}
+
+/*element: mutableListIndex:Specializer=[Index]*/
+@pragma('dart2js:noInline')
+mutableListIndex() {
+  var list = [0];
+  return list[0];
+}
+
+/*element: mutableListDynamicIndex:Specializer=[Index]*/
+@pragma('dart2js:noInline')
+mutableListDynamicIndex(dynamic index) {
+  var list = [0];
+  return list[index]; // CFE inserts an implicit cast of the index.
+}
+
+/*strong.element: mutableDynamicListDynamicIndex:Specializer=[!Index]*/
+/*omit.element: mutableDynamicListDynamicIndex:Specializer=[Index]*/
+@pragma('dart2js:noInline')
+mutableDynamicListDynamicIndex(dynamic index) {
+  dynamic list = [0];
+  return list[index];
+}
+
+main() {
+  dynamicIndex([]);
+  dynamicIndex({});
+  unknownListIndex([]);
+  unknownListIndex(new MyList());
+  possiblyNullMutableListIndex(true);
+  possiblyNullMutableListIndex(false);
+  mutableListIndex();
+  mutableListDynamicIndex(0);
+  mutableListDynamicIndex('');
+  mutableDynamicListDynamicIndex(0);
+  mutableDynamicListDynamicIndex('');
+}
+
+class MyList<E> extends ListBase<E> {
+  E operator [](int index) => null;
+  void operator []=(int index, E value) {}
+  int get length => 0;
+  void set length(int value) {}
+}
diff --git a/tests/compiler/dart2js/optimization/data/index_assign.dart b/tests/compiler/dart2js/optimization/data/index_assign.dart
new file mode 100644
index 0000000..35c03ff
--- /dev/null
+++ b/tests/compiler/dart2js/optimization/data/index_assign.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: dynamicIndexAssign:Specializer=[!IndexAssign]*/
+@pragma('dart2js:noInline')
+dynamicIndexAssign(var list) {
+  list[0] = 1;
+}
+
+/*strong.element: unknownListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.element: unknownListIndexAssign:Specializer=[IndexAssign]*/
+@pragma('dart2js:noInline')
+unknownListIndexAssign(List list) {
+  list[0] = 1;
+}
+
+/*strong.element: possiblyNullMutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.element: possiblyNullMutableListIndexAssign:Specializer=[IndexAssign]*/
+@pragma('dart2js:noInline')
+possiblyNullMutableListIndexAssign(bool b) {
+  var list = b ? [0] : null;
+  list[0] = 1;
+}
+
+/*strong.element: mutableListIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.element: mutableListIndexAssign:Specializer=[IndexAssign]*/
+@pragma('dart2js:noInline')
+mutableListIndexAssign() {
+  var list = [0];
+  list[0] = 1;
+}
+
+/*strong.element: mutableListDynamicIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.element: mutableListDynamicIndexAssign:Specializer=[IndexAssign]*/
+@pragma('dart2js:noInline')
+mutableListDynamicIndexAssign(dynamic index) {
+  var list = [0];
+  list[index] = 1;
+}
+
+/*strong.element: mutableListDynamicValueIndexAssign:Specializer=[!IndexAssign]*/
+/*omit.element: mutableListDynamicValueIndexAssign:Specializer=[IndexAssign]*/
+@pragma('dart2js:noInline')
+mutableListDynamicValueIndexAssign(dynamic value) {
+  var list = [0];
+  list[0] = value;
+}
+
+/*element: immutableListIndexAssign:Specializer=[!IndexAssign]*/
+@pragma('dart2js:noInline')
+immutableListIndexAssign() {
+  var list = const [0];
+  list[0] = 1;
+}
+
+main() {
+  dynamicIndexAssign([]);
+  dynamicIndexAssign({});
+  unknownListIndexAssign([]);
+  unknownListIndexAssign(null);
+  possiblyNullMutableListIndexAssign(true);
+  possiblyNullMutableListIndexAssign(false);
+  mutableListIndexAssign();
+  mutableListDynamicIndexAssign(0);
+  mutableListDynamicIndexAssign('');
+  mutableListDynamicValueIndexAssign(0);
+  mutableListDynamicValueIndexAssign('');
+  immutableListIndexAssign();
+}
diff --git a/tests/compiler/dart2js/optimization/data/modulo_remainder.dart b/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
new file mode 100644
index 0000000..9139d26
--- /dev/null
+++ b/tests/compiler/dart2js/optimization/data/modulo_remainder.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*element: mod1:Specializer=[Modulo]*/
+@pragma('dart2js:noInline')
+mod1(param) {
+  var a = param ? 0xFFFFFFFF : 1;
+  return a % 2;
+  // present: ' % 2'
+  // absent: '$mod'
+}
+
+/*element: mod2:Specializer=[!Modulo]*/
+@pragma('dart2js:noInline')
+mod2(param) {
+  var a = param ? 0xFFFFFFFF : -0.0;
+  return a % 2;
+  // Cannot optimize due to potential -0.
+  // present: '$mod'
+  // absent: ' % 2'
+}
+
+/*element: mod3:Specializer=[Modulo]*/
+@pragma('dart2js:noInline')
+mod3(param) {
+  var a = param ? 0xFFFFFFFF : -0.0;
+  return (a + 1) % 2;
+  // 'a + 1' cannot be -0.0, so we can optimize.
+  // present: ' % 2'
+  // absent: '$mod'
+}
+
+/*element: rem1:Specializer=[Remainder]*/
+@pragma('dart2js:noInline')
+rem1(param) {
+  var a = param ? 0xFFFFFFFF : 1;
+  return a.remainder(2);
+  // Above can be compiled to '%'.
+  // present: ' % 2'
+  // absent: 'remainder'
+}
+
+/*element: rem2:Specializer=[Remainder]*/
+@pragma('dart2js:noInline')
+rem2(param) {
+  var a = param ? 123.4 : -1;
+  return a.remainder(3);
+  // Above can be compiled to '%'.
+  // present: ' % 3'
+  // absent: 'remainder'
+}
+
+/*element: rem3:Specializer=[!Remainder]*/
+@pragma('dart2js:noInline')
+rem3(param) {
+  var a = param ? 123 : null;
+  return 100.remainder(a);
+  // No specialization for possibly null inputs.
+  // present: 'remainder'
+  // absent: '%'
+}
+
+main() {
+  mod1(true);
+  mod1(false);
+  mod2(true);
+  mod2(false);
+  mod3(true);
+  mod3(false);
+
+  rem1(true);
+  rem1(false);
+  rem2(true);
+  rem2(false);
+  rem3(true);
+  rem3(false);
+}
diff --git a/tests/compiler/dart2js/optimization/optimization_test.dart b/tests/compiler/dart2js/optimization/optimization_test.dart
index 0f2d013..1f56a1a 100644
--- a/tests/compiler/dart2js/optimization/optimization_test.dart
+++ b/tests/compiler/dart2js/optimization/optimization_test.dart
@@ -5,6 +5,7 @@
 import 'dart:io';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/closure.dart';
+import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
@@ -22,29 +23,35 @@
 main(List<String> args) {
   asyncTest(() async {
     Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
-    await checkTests(dataDir, const OptimizationDataComputer(), args: args);
+    bool strict = args.contains('-s');
+    await checkTests(dataDir, new OptimizationDataComputer(strict: strict),
+        options: [Flags.disableInlining], args: args);
   });
 }
 
-class OptimizationDataValidator implements DataInterpreter<OptimizationLog> {
-  const OptimizationDataValidator();
+class OptimizationDataValidator
+    implements DataInterpreter<OptimizationTestLog> {
+  final bool strict;
+
+  const OptimizationDataValidator({this.strict: false});
 
   @override
-  String getText(OptimizationLog actualData) {
+  String getText(OptimizationTestLog actualData) {
     Features features = new Features();
     for (OptimizationLogEntry entry in actualData.entries) {
-      features.addElement(entry.tag, entry.features.getText());
+      features.addElement(
+          entry.tag, entry.features.getText().replaceAll(',', '&'));
     }
     return features.getText();
   }
 
   @override
-  bool isEmpty(OptimizationLog actualData) {
+  bool isEmpty(OptimizationTestLog actualData) {
     return actualData == null || actualData.entries.isEmpty;
   }
 
   @override
-  String isAsExpected(OptimizationLog actualLog, String expectedLog) {
+  String isAsExpected(OptimizationTestLog actualLog, String expectedLog) {
     expectedLog ??= '';
     if (expectedLog == '') {
       return actualLog.entries.isEmpty
@@ -60,8 +67,12 @@
     expectedLogEntries.forEach((String tag, dynamic expectedEntryData) {
       List<OptimizationLogEntry> actualDataForTag =
           actualDataEntries.where((data) => data.tag == tag).toList();
-      if (expectedEntryData == '' ||
-          expectedEntryData is List && expectedEntryData.isEmpty) {
+      for (OptimizationLogEntry entry in actualDataForTag) {
+        actualDataEntries.remove(entry);
+      }
+      if (expectedEntryData == '') {
+        errorsFound.add("Unknown expected entry '$tag'");
+      } else if (expectedEntryData is List && expectedEntryData.isEmpty) {
         if (actualDataForTag.isNotEmpty) {
           errorsFound.add('Non-empty log found for tag $tag');
         }
@@ -69,7 +80,14 @@
         // Anything allowed.
       } else if (expectedEntryData is List) {
         for (Object object in expectedEntryData) {
-          Features expectedLogEntry = Features.fromText('$object');
+          String expectedLogEntryText = '$object';
+          bool expectMatch = true;
+          if (expectedLogEntryText.startsWith('!')) {
+            expectedLogEntryText = expectedLogEntryText.substring(1);
+            expectMatch = false;
+          }
+          expectedLogEntryText = expectedLogEntryText.replaceAll('&', ',');
+          Features expectedLogEntry = Features.fromText(expectedLogEntryText);
           bool matchFound = false;
           for (OptimizationLogEntry actualLogEntry in actualDataForTag) {
             bool validData = true;
@@ -85,27 +103,40 @@
               break;
             }
           }
-          if (!matchFound) {
-            errorsFound.add("No match found for $tag=[$object]");
+          if (expectMatch) {
+            if (!matchFound) {
+              errorsFound.add("No match found for $tag=[$object]");
+            }
+          } else {
+            if (matchFound) {
+              errorsFound.add("Unexpected match found for $tag=[$object]");
+            }
           }
         }
       } else {
-        errorsFound.add("Unknown expected entry '$expectedEntryData'");
+        errorsFound.add("Unknown expected entry $tag=$expectedEntryData");
       }
     });
+    if (strict) {
+      for (OptimizationLogEntry entry in actualDataEntries) {
+        errorsFound.add("Extra entry ${entry.tag}=${entry.features.getText()}");
+      }
+    }
     return errorsFound.isNotEmpty ? errorsFound.join(', ') : null;
   }
 }
 
-class OptimizationDataComputer extends DataComputer<OptimizationLog> {
-  const OptimizationDataComputer();
+class OptimizationDataComputer extends DataComputer<OptimizationTestLog> {
+  final bool strict;
+
+  const OptimizationDataComputer({this.strict: false});
 
   /// Compute type inference data for [member] from kernel based inference.
   ///
   /// Fills [actualMap] with the data.
   @override
   void computeMemberData(Compiler compiler, MemberEntity member,
-      Map<Id, ActualData<OptimizationLog>> actualMap,
+      Map<Id, ActualData<OptimizationTestLog>> actualMap,
       {bool verbose: false}) {
     JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
     JsToElementMap elementMap = closedWorld.elementMap;
@@ -116,31 +147,31 @@
   }
 
   @override
-  DataInterpreter<OptimizationLog> get dataValidator =>
-      const OptimizationDataValidator();
+  DataInterpreter<OptimizationTestLog> get dataValidator =>
+      new OptimizationDataValidator(strict: strict);
 }
 
 /// AST visitor for computing inference data for a member.
-class OptimizationIrComputer extends IrDataExtractor<OptimizationLog> {
+class OptimizationIrComputer extends IrDataExtractor<OptimizationTestLog> {
   final JavaScriptBackend backend;
   final JsToElementMap _elementMap;
   final ClosureData _closureDataLookup;
 
   OptimizationIrComputer(
       DiagnosticReporter reporter,
-      Map<Id, ActualData<OptimizationLog>> actualMap,
+      Map<Id, ActualData<OptimizationTestLog>> actualMap,
       this._elementMap,
       MemberEntity member,
       this.backend,
       this._closureDataLookup)
       : super(reporter, actualMap);
 
-  OptimizationLog getLog(MemberEntity member) {
+  OptimizationTestLog getLog(MemberEntity member) {
     SsaFunctionCompiler functionCompiler = backend.functionCompiler;
     return functionCompiler.optimizer.loggersForTesting[member];
   }
 
-  OptimizationLog getMemberValue(MemberEntity member) {
+  OptimizationTestLog getMemberValue(MemberEntity member) {
     if (member is FunctionEntity) {
       return getLog(member);
     }
@@ -148,12 +179,12 @@
   }
 
   @override
-  OptimizationLog computeMemberValue(Id id, ir.Member node) {
+  OptimizationTestLog computeMemberValue(Id id, ir.Member node) {
     return getMemberValue(_elementMap.getMember(node));
   }
 
   @override
-  OptimizationLog computeNodeValue(Id id, ir.TreeNode node) {
+  OptimizationTestLog computeNodeValue(Id id, ir.TreeNode node) {
     if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
       ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
       return getMemberValue(info.callMethod);
diff --git a/tests/compiler/dart2js/rti/data/no_such_method1.dart b/tests/compiler/dart2js/rti/data/no_such_method1.dart
index 3694cb0..22f13c2 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method1.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method1.dart
@@ -5,7 +5,7 @@
 import 'package:expect/expect.dart';
 
 class C {
-  /*element: C.noSuchMethod:selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
+  /*element: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
   noSuchMethod(i) => i.typeArguments;
 }
 
diff --git a/tests/compiler/dart2js/rti/data/no_such_method2.dart b/tests/compiler/dart2js/rti/data/no_such_method2.dart
index 81d823c..fc60960 100644
--- a/tests/compiler/dart2js/rti/data/no_such_method2.dart
+++ b/tests/compiler/dart2js/rti/data/no_such_method2.dart
@@ -5,7 +5,7 @@
 import 'package:expect/expect.dart';
 
 class C {
-  /*element: C.noSuchMethod:selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
+  /*element: C.noSuchMethod:needsArgs,selectors=[Selector(call, call, arity=0, types=2),Selector(call, foo, arity=0, types=2)]*/
   noSuchMethod(i) => i.typeArguments;
 }
 
diff --git a/tests/compiler/dart2js/rti/emission/dynamic_type_literal.dart b/tests/compiler/dart2js/rti/emission/dynamic_type_literal.dart
index 8f7ce92..66d91cf 100644
--- a/tests/compiler/dart2js/rti/emission/dynamic_type_literal.dart
+++ b/tests/compiler/dart2js/rti/emission/dynamic_type_literal.dart
@@ -6,7 +6,7 @@
 
 import "package:expect/expect.dart";
 
-void main() {
+void main(bool b) {
   Expect.isTrue(dynamic is Type);
-  Expect.isFalse(dynamic == Type);
+  Expect.isFalse(dynamic == (b ? Type : dynamic)); // ?: avoids constant folding
 }
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace/parameters.dart b/tests/compiler/dart2js/sourcemaps/stacktrace/parameters.dart
index f9a6d06..4170f29 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace/parameters.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace/parameters.dart
@@ -7,6 +7,15 @@
 main() {
   var c = new Class();
   c. /*1:main*/ instancePositional1(0);
+
+  // Use all optional parameters to ensure that they are not elided.
+  var d = new Class();
+  d.instancePositional1(null, null, null);
+  d.instancePositional2(null, null, null);
+  d.instanceNamed1(null, b: null, c: null, d: null);
+  d.instanceNamed2(null, b: null, c: null, d: null);
+  d.instanceNamed3(null, b: null, c: null, d: null);
+  d.instanceNamed4(null, b: null, c: null, d: null);
 }
 
 class Class {
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace/parameters_elided.dart b/tests/compiler/dart2js/sourcemaps/stacktrace/parameters_elided.dart
new file mode 100644
index 0000000..cb0bade
--- /dev/null
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace/parameters_elided.dart
@@ -0,0 +1,70 @@
+// 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:meta/dart2js.dart';
+
+main() {
+  var c = new Class();
+  c. /*1:main*/ instancePositional1(0);
+}
+
+class Class {
+  @noInline
+  instancePositional1(a, [b = 42, c = 87]) {
+    print('instancePositional1($a,$b,$c)');
+    /*2:Class.instancePositional1*/ instancePositional2(1, 2);
+  }
+
+  @noInline
+  instancePositional2(a, [b = 42, c = 87]) {
+    print('instancePositional2($a,$b,$c)');
+    /*3:Class.instancePositional2*/ instancePositional3(3, 4, 5);
+  }
+
+  @noInline
+  instancePositional3(a, [b = 42, c = 87]) {
+    print('instancePositional3($a,$b,$c)');
+    /*4:Class.instancePositional3*/ instanceNamed1(0);
+  }
+
+  @noInline
+  instanceNamed1(a, {b: 42, c: 87, d: 735}) {
+    print('instanceNamed1($a,b:$b,c:$c,d:$d)');
+    /*5:Class.instanceNamed1*/ instanceNamed2(1, b: 2);
+  }
+
+  @noInline
+  instanceNamed2(a, {b: 42, c: 87, d: 735}) {
+    print('instanceNamed2($a,b:$b,c:$c,d:$d)');
+    /*6:Class.instanceNamed2*/ instanceNamed3(3, c: 123);
+  }
+
+  @noInline
+  instanceNamed3(a, {b: 42, c: 87, d: 735}) {
+    print('instanceNamed3($a,b:$b,c:$c,d:$d)');
+    /*7:Class.instanceNamed3*/ instanceNamed4(4, c: 45, b: 76);
+  }
+
+  @noInline
+  instanceNamed4(a, {b: 42, c: 87, d: 735}) {
+    print('instanceNamed4($a,b:$b,c:$c,d:$d)');
+    /*8:Class.instanceNamed4*/ instanceNamed5(5, c: 6, b: 7, d: 8);
+  }
+
+  @noInline
+  instanceNamed5(a, {b: 42, c: 87, d: 735}) {
+    print('instanceNamed5($a,b:$b,c:$c,d:$d)');
+    /*12:Class.instanceNamed5[function-entry$0].local*/ local([e = 42]) {
+      print('instanceNamed5.local($e)');
+      /*13:Class.instanceNamed5.local*/ throw '>ExceptionMarker<';
+    }
+
+    var anonymous = /*10:Class.instanceNamed5[function-entry$0].<anonymous function>*/ (
+        {f: 87}) {
+      print('instanceNamed5.<anonymous(f:$f)');
+      /*11:Class.instanceNamed5.<anonymous function>*/ local();
+    };
+    anonymous. /*9:Class.instanceNamed5*/ call();
+  }
+}
diff --git a/tests/compiler/dart2js/sourcemaps/stacktrace/setter_inlining.dart b/tests/compiler/dart2js/sourcemaps/stacktrace/setter_inlining.dart
index 9b5ab60..5ffcaad 100644
--- a/tests/compiler/dart2js/sourcemaps/stacktrace/setter_inlining.dart
+++ b/tests/compiler/dart2js/sourcemaps/stacktrace/setter_inlining.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
 class MyClass {
   int fieldName;
 
@@ -13,4 +17,5 @@
   confuse(new MyClass(3));
   var m = confuse(null);
   m. /*0:main*/ setterName = 2;
+  print(m.fieldName);
 }
diff --git a/tests/compiler/dart2js_extra/bounds_check3c_test.dart b/tests/compiler/dart2js_extra/bounds_check3c_test.dart
new file mode 100644
index 0000000..696afdd
--- /dev/null
+++ b/tests/compiler/dart2js_extra/bounds_check3c_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class();
+  Expect.equals(c.method(), num);
+}
+
+class Class {
+  @pragma('dart2js:noInline')
+  method<S extends num>() => S;
+}
diff --git a/tests/compiler/dart2js_extra/deferred_with_cross_origin_lib.dart b/tests/compiler/dart2js_extra/deferred_with_cross_origin_lib.dart
new file mode 100644
index 0000000..48fbce6
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_with_cross_origin_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+foo() {
+  return "loaded";
+}
diff --git a/tests/compiler/dart2js_extra/deferred_with_cross_origin_test.dart b/tests/compiler/dart2js_extra/deferred_with_cross_origin_test.dart
new file mode 100644
index 0000000..51c10cf
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_with_cross_origin_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+// Test that code loaded via deferred imports uses the same crossorigin value as
+// the main page.
+
+import "deferred_with_cross_origin_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:html";
+
+main() {
+  asyncStart();
+
+  var scripts = document
+      .querySelectorAll<ScriptElement>('script')
+      .where((s) => s.src.contains("generated_compilations"))
+      .toList();
+  Expect.equals(1, scripts.length);
+  Expect.equals(null, scripts.first.crossOrigin);
+  scripts.first.crossOrigin = "anonymous";
+
+  lib.loadLibrary().then((_) {
+    print(lib.foo());
+    var scripts = document
+        .querySelectorAll<ScriptElement>('script')
+        .where((s) => s.src.contains("generated_compilations"))
+        .toList();
+    Expect.equals(2, scripts.length);
+    for (var script in scripts) {
+      Expect.equals("anonymous", script.crossOrigin);
+    }
+    asyncEnd();
+  });
+}
diff --git a/tests/compiler/dart2js_extra/deferred_with_csp_nonce2_test.dart b/tests/compiler/dart2js_extra/deferred_with_csp_nonce2_test.dart
new file mode 100644
index 0000000..5d6f596
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_with_csp_nonce2_test.dart
@@ -0,0 +1,38 @@
+// 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.
+
+// Test that code loaded via deferred imports uses the same nonce value as the
+// main page.
+
+import "deferred_with_csp_nonce_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:html";
+
+main() {
+  asyncStart();
+
+  var scripts = document
+      .querySelectorAll<ScriptElement>('script')
+      .where((s) => s.src.contains("generated_compilations"))
+      .toList();
+  Expect.equals(1, scripts.length);
+  Expect.equals('', scripts.first.nonce ?? '');
+  Expect.equals('', scripts.first.getAttribute('nonce') ?? '');
+  scripts.first.setAttribute("nonce", "an-example-nonce-string");
+
+  lib.loadLibrary().then((_) {
+    print(lib.foo());
+    var scripts = document
+        .querySelectorAll<ScriptElement>('script')
+        .where((s) => s.src.contains(".part.js"))
+        .toList();
+    Expect.equals(1, scripts.length);
+    for (var script in scripts) {
+      Expect.equals("an-example-nonce-string", script.nonce);
+      Expect.equals("an-example-nonce-string", script.getAttribute('nonce'));
+    }
+    asyncEnd();
+  });
+}
diff --git a/tests/compiler/dart2js_extra/deferred_with_csp_nonce_test.dart b/tests/compiler/dart2js_extra/deferred_with_csp_nonce_test.dart
index 90d6acb..2725df8 100644
--- a/tests/compiler/dart2js_extra/deferred_with_csp_nonce_test.dart
+++ b/tests/compiler/dart2js_extra/deferred_with_csp_nonce_test.dart
@@ -19,17 +19,19 @@
       .toList();
   Expect.equals(1, scripts.length);
   Expect.equals('', scripts.first.nonce ?? '');
+  Expect.equals('', scripts.first.getAttribute('nonce') ?? '');
   scripts.first.nonce = "an-example-nonce-string";
 
   lib.loadLibrary().then((_) {
     print(lib.foo());
     var scripts = document
         .querySelectorAll<ScriptElement>('script')
-        .where((s) => s.src.contains("generated_compilations"))
+        .where((s) => s.src.contains(".part.js"))
         .toList();
-    Expect.equals(2, scripts.length);
+    Expect.equals(1, scripts.length);
     for (var script in scripts) {
       Expect.equals("an-example-nonce-string", script.nonce);
+      Expect.equals("an-example-nonce-string", script.getAttribute('nonce'));
     }
     asyncEnd();
   });
diff --git a/tests/compiler/dart2js_extra/generator_elided_parameter_test.dart b/tests/compiler/dart2js_extra/generator_elided_parameter_test.dart
new file mode 100644
index 0000000..60bf18b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/generator_elided_parameter_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 optional arguments of methods with a generator are forwarded
+/// properly when optional parameters are elided.
+///
+/// This is a regression test for issue #35924
+import "package:expect/expect.dart";
+
+// The type parameter forces us to create a generator body. The call from the
+// method to the body needs to correctly handle elided parameters.
+Future<T> foo<T>(T Function(int, int, int) toT,
+    {int p1: 0, int p2: 1, int p3: 2}) async {
+  await null;
+  return toT(p1, p2, p3);
+}
+
+main() async {
+  Expect.equals(await foo<String>((a, b, c) => "$a $b $c", p2: 4), "0 4 2");
+}
diff --git a/tests/compiler/dart2js_extra/js_interop_no_elide_optional_arg_test.dart b/tests/compiler/dart2js_extra/js_interop_no_elide_optional_arg_test.dart
new file mode 100644
index 0000000..5d6d913
--- /dev/null
+++ b/tests/compiler/dart2js_extra/js_interop_no_elide_optional_arg_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.
+
+/// Test that optional arguments of js-interop factory constructors are not
+/// elided.
+/// This is a regression test for issue 35916
+@JS()
+library test;
+
+import "package:js/js.dart";
+import "package:expect/expect.dart";
+
+@JS()
+@anonymous
+class Margins {
+  external factory Margins(
+      {int top, int start, int end, int right, int bottom, int left});
+  external int get top;
+  external int get right;
+  external int get left;
+  external int get bottom;
+}
+
+main() {
+  var m = new Margins(bottom: 21, left: 88, right: 20, top: 24);
+  Expect.equals(m.top, 24);
+  Expect.equals(m.bottom, 21);
+  Expect.equals(m.left, 88);
+  Expect.equals(m.right, 20);
+}
diff --git a/tests/compiler/dart2js_native/native_method_inlining_test.dart b/tests/compiler/dart2js_native/native_method_inlining_test.dart
index f673eeb..9d7ddc9 100644
--- a/tests/compiler/dart2js_native/native_method_inlining_test.dart
+++ b/tests/compiler/dart2js_native/native_method_inlining_test.dart
@@ -20,7 +20,9 @@
 }
 
 class B {
+  @pragma('dart2js:noElision')
   static var g;
+
   @NoInline()
   method1(a) {
     g = '(Method1Tag)'; // Tag to identify compiled JavaScript method.
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 38b98dd..eed9d49 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -53,10 +53,10 @@
 error_stack_trace_test/static: MissingCompileTimeError
 
 [ $compiler == dartdevk ]
-bool_from_environment2_test/03: Crash
+bool_from_environment2_test/03: MissingCompileTimeError
 int_modulo_arith_test/modPow: RuntimeError
 int_modulo_arith_test/none: RuntimeError
-string_from_environment3_test/03: Crash
+string_from_environment3_test/03: MissingCompileTimeError
 
 [ $compiler == fasta ]
 bool_from_environment2_test/03: MissingCompileTimeError
@@ -71,34 +71,6 @@
 [ $mode == debug ]
 regexp/pcre_test: Pass, Slow # Issue 22008
 
-[ $runtime == flutter ]
-apply3_test: RuntimeError
-bool_from_environment_test: Fail # Flutter Issue 9111
-format_exception_test: RuntimeError # Flutter Issue 9111
-from_environment_const_type_test/01: Fail # Flutter Issue 9111
-from_environment_const_type_test/02: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/03: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/04: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/05: Fail # Flutter Issue 9111
-from_environment_const_type_test/06: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/07: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/08: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/09: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/10: Fail # Flutter Issue 9111
-from_environment_const_type_test/11: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/12: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/13: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/14: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/15: Fail # Flutter Issue 9111
-from_environment_const_type_test/16: MissingCompileTimeError # Flutter Issue 9111
-from_environment_const_type_test/none: Fail # Flutter Issue 9111
-int_from_environment2_test: Fail # Flutter Issue 9111
-int_from_environment_int64_test: Fail # Flutter Issue 9111
-int_from_environment_test: Fail # Flutter Issue 9111
-main_test: RuntimeError # Flutter Issue 9111
-string_from_environment2_test: Fail # Flutter Issue 9111
-string_from_environment_test: Fail # Flutter Issue 9111
-
 [ $runtime == jsshell ]
 string_case_test/01: Fail, OK # German double S.
 unicode_test: Fail
@@ -215,19 +187,6 @@
 map_test: Crash # tests/corelib_2/map_test.dart:903:7: Internal problem: Unhandled Null in installDefaultConstructor.
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
 
-[ $compiler == dart2js && $fast_startup && $strong ]
-error_stack_trace1_test: RuntimeError
-growable_list_test: RuntimeError
-integer_to_radix_string_test/01: RuntimeError
-integer_to_radix_string_test/02: RuntimeError
-integer_to_radix_string_test/none: RuntimeError
-integer_to_string_test/01: RuntimeError
-iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-list_concurrent_modify_test: RuntimeError
-main_test: RuntimeError
-nan_infinity_test/01: RuntimeError
-symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
-
 [ $compiler == dart2js && $minified && $strong ]
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
@@ -256,12 +215,6 @@
 integer_to_radix_string_test/none: RuntimeError
 integer_to_string_test/01: RuntimeError
 iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-list_concurrent_modify_test: RuntimeError # dart2js does not fully implement these
-list_unmodifiable_test: RuntimeError
-main_test: RuntimeError
-nan_infinity_test/01: RuntimeError
-regexp/pcre_test: RuntimeError
-symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
 
 [ $compiler == dart2js && !$strong ]
 *: SkipByDesign
@@ -308,10 +261,8 @@
 from_environment_const_type_undefined_test/13: MissingCompileTimeError
 from_environment_const_type_undefined_test/14: MissingCompileTimeError
 from_environment_const_type_undefined_test/16: MissingCompileTimeError
-string_base_vm_static_test: MissingCompileTimeError
-
-[ $compiler == none && ($runtime == flutter || $runtime == vm) ]
 iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
+string_base_vm_static_test: MissingCompileTimeError
 
 [ $compiler == precompiler && $runtime == dart_precompiled && !$checked ]
 iterable_generate_test/01: RuntimeError
@@ -575,11 +526,9 @@
 [ $compiler == precompiler || $runtime == vm && !$strong ]
 apply3_test: RuntimeError
 
-[ $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
+[ $runtime == dart_precompiled || $runtime == vm ]
 regexp/global_test: Skip # Issue 21709
 regexp/pcre_test: Pass, Slow, Timeout
-
-[ $runtime == dart_precompiled || $runtime == vm ]
 string_case_test/01: RuntimeError # Issue 18061: German double S.
 
 [ $runtime == ff || $runtime == jsshell ]
diff --git a/tests/kernel/kernel.status b/tests/kernel/kernel.status
index bb0a776..8c659a4 100644
--- a/tests/kernel/kernel.status
+++ b/tests/kernel/kernel.status
@@ -20,9 +20,6 @@
 [ $compiler == dart2analyzer && $runtime == none ]
 unsorted/super_mixin_test: CompileTimeError
 
-[ $compiler == dart2js && !$fast_startup ]
-unsorted/super_mixin_test: RuntimeError
-
 [ $compiler == dart2js && $host_checked ]
 unsorted/super_mixin_test: Crash
 
diff --git a/tests/language_2/async_this_bound_test.dart b/tests/language_2/async_this_bound_test.dart
index b71a597..fdbfa6c 100644
--- a/tests/language_2/async_this_bound_test.dart
+++ b/tests/language_2/async_this_bound_test.dart
@@ -27,8 +27,8 @@
 
 class B {
   var f;
-  @NoInline()
   var b = 10;
+
   B(this.f);
 
   bar(x) => b;
diff --git a/tests/language_2/const_types_test.dart b/tests/language_2/const_types_test.dart
index 4160878..3199c0c 100644
--- a/tests/language_2/const_types_test.dart
+++ b/tests/language_2/const_types_test.dart
@@ -18,7 +18,7 @@
     use(const <Unresolved>[]); //# 02: compile-time error
 
     use(const {});
-    use(const <Class>{}); //# 03: compile-time error
+    use(const <Class>{});
     use(const <String, Class>{});
     use(const <String, Class<int>>{});
     use(const <String, Class<Unresolved>>{}); //# 04: compile-time error
diff --git a/tests/language_2/control_flow_collections/experimental_flag_test.dart b/tests/language_2/control_flow_collections/experimental_flag_test.dart
new file mode 100644
index 0000000..aa3d8a1
--- /dev/null
+++ b/tests/language_2/control_flow_collections/experimental_flag_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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 control flow is not enabled without the experimental flag.
+
+// Do enable set literals, just not the new syntax in them.
+// SharedOptions=--enable-experiment=set-literals
+
+// TODO(rnystrom): Remove this test when the feature is enabled without a flag.
+
+void main() {
+  var _ = <int>[if (true) 1]; //# 01: compile-time error
+  var _ = <int, int>{if (true) 1: 1}; //# 02: compile-time error
+  var _ = <int>{if (true) 1}; //# 03: compile-time error
+
+  var _ = <int>[if (true) 1 else 2]; //# 04: compile-time error
+  var _ = <int, int>{if (true) 1: 1 else 2: 2}; //# 05: compile-time error
+  var _ = <int>{if (true) 1 else 2}; //# 06: compile-time error
+
+  var _ = <int>[for (var i in []) 1]; //# 07: compile-time error
+  var _ = <int, int>{for (var i in []) 1: 1}; //# 08: compile-time error
+  var _ = <int>{for (var i in []) 1}; //# 09: compile-time error
+
+  var _ = <int>[for (; false;) 1]; //# 10: compile-time error
+  var _ = <int, int>{for (; false;) 1: 1}; //# 11: compile-time error
+  var _ = <int>{for (; false;) 1}; //# 12: compile-time error
+
+  () async {
+    var _ = <int>[await for (var i in []) 1]; //# 13: compile-time error
+    var _ = <int, int>{await  for (var i in []) 1: 1}; //# 14: compile-time error
+    var _ = <int>{await for (var i in []) 1}; //# 15: compile-time error
+  }();
+}
diff --git a/tests/language_2/control_flow_collections/for_const_test.dart b/tests/language_2/control_flow_collections/for_const_test.dart
new file mode 100644
index 0000000..022ec24
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_const_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.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections
+
+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_2/control_flow_collections/for_inference_test.dart b/tests/language_2/control_flow_collections/for_inference_test.dart
new file mode 100644
index 0000000..1834edb
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_inference_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections,spread-collections
+
+// 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>>({if (true) ...[]});
+  Expect.type<Set<int>>({if (true) ...<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 not pushed into iterable.
+  Expect.listEquals(<int>[1], [for (int i in expectDynamic([1]))]);
+
+  // 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 (; false;) expectInt(1)]);
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.listEquals(<int>[1, 2], [1, for (; false;) expectDynamic(2)]);
+
+  // Maps.
+
+  // The context element type is pushed into the body.
+  Expect.mapEquals(<int, String>{1: "s"},
+      <int, String>{for (; false;) 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 (; false;) expectDynamic(2): expectDynamic("t")});
+
+  // Sets.
+
+  // The context element type is pushed into the body.
+  Expect.setEquals(<int>{1}, <int>{for (; false;) expectInt(1)});
+
+  // Bottom up-inference from elements is not pushed back down into the body.
+  Expect.setEquals(<int>{1, 2}, {1, for (; false;) expectDynamic(2)});
+}
diff --git a/tests/language_2/control_flow_collections/for_test.dart b/tests/language_2/control_flow_collections/for_test.dart
new file mode 100644
index 0000000..108b82f
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_test.dart
@@ -0,0 +1,267 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,control-flow-collections,spread-collections
+
+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();
+  testRuntimeErrors();
+}
+
+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 variable.
+  Expect.listEquals(list, <int>[for (int n in <num>[1, 2, 3, 4]) n]);
+
+  // Downcast element.
+  Expect.listEquals(list, <int>[for (num n in <num>[1, 2, 3, 4]) n]);
+
+  // Downcast condition.
+  Expect.listEquals([1], <int>[for (var i = 1; (i < 2) as dynamic; i++) i]);
+  Expect.listEquals([1], <int>[for (var i = 1; (i < 2) as Object; 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>{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 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 variable.
+  Expect.mapEquals(map, <int, int>{for (int n in <num>[1, 2, 3, 4]) n: n});
+
+  // Downcast element.
+  Expect.mapEquals(map, <int, int>{for (num n in <num>[1, 2, 3, 4]) n: n});
+
+  // Downcast condition.
+  Expect.mapEquals([1],
+      <int, int>{for (var i = 1; (i < 2) as dynamic; i++) i: i});
+  Expect.mapEquals([1],
+      <int, int>{for (var i = 1; (i < 2) as Object; 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 variable.
+  Expect.setEquals(set, <int>{for (int n in <num>[1, 2, 3, 4]) n});
+
+  // Downcast element.
+  Expect.setEquals(set, <int>{for (num n in <num>[1, 2, 3, 4]) n});
+
+  // Downcast condition.
+  Expect.setEquals({1}, <int>{for (var i = 1; (i < 2) as dynamic; i++) i});
+  Expect.setEquals({1}, <int>{for (var i = 1; (i < 2) as Object; 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
+  });
+  Expect.setEquals(set, <int>{
+    1,
+    for (var i in <int>[1, 2, 3]) i,
+    for (var i = 2; i <= 3; i++) i,
+    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 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(","));
+
+  var set = <Equality>{e1a, for (var i = 0; i < keys.length; i++) keys[i]};
+  Expect.equals("1:a,2:a", set.join(","));
+}
+
+void testRuntimeErrors() {
+  // Non-bool condition expression.
+  dynamic nonBool = 3;
+  Expect.throwsCastError(() => <int>[for (; nonBool;) 1]);
+  Expect.throwsCastError(() => <int, int>{for (; nonBool;) 1: 1});
+  Expect.throwsCastError(() => <int>{for (; nonBool;) 1});
+
+  // Null condition expression.
+  bool nullBool = null;
+  Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]);
+  Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1});
+  Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1});
+
+  // Cast for variable.
+  dynamic nonInt = "string";
+  Expect.throwsCastError(() => <int>[for (int i = nonInt; false;) 1]);
+  Expect.throwsCastError(() => <int, int>{for (int i = nonInt; false;) 1: 1});
+  Expect.throwsCastError(() => <int>{for (int i = nonInt; false;) 1});
+
+  // Cast for-in variable.
+  dynamic nonIterable = 3;
+  Expect.throwsCastError(() => <int>[for (int i in nonIterable) 1]);
+  Expect.throwsCastError(() => <int, int>{for (int i in nonIterable) 1: 1});
+  Expect.throwsCastError(() => <int>{for (int i in nonIterable) 1});
+
+  // Null iterable.
+  Iterable<int> nullIterable = null;
+  Expect.throwsNoSuchMethodError(() => <int>[for (var i in nullIterable) 1]);
+  Expect.throwsNoSuchMethodError(
+      () => <int, int>{for (var i in nullIterable) 1: 1});
+  Expect.throwsNoSuchMethodError(() => <int>{for (var i in nullIterable) 1});
+
+  // Wrong element type.
+  Expect.throwsCastError(() => <int>[for (var i = 0; i < 1; i++) nonInt]);
+  Expect.throwsCastError(
+      () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1});
+  Expect.throwsCastError(
+      () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt});
+  Expect.throwsCastError(() => <int>{for (var i = 0; i < 1; i++) nonInt});
+}
diff --git a/tests/language_2/control_flow_collections/for_variable_test.dart b/tests/language_2/control_flow_collections/for_variable_test.dart
new file mode 100644
index 0000000..732e2ca
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_variable_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.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections,spread-collections
+
+/// 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.
+  list = [for (var i = 0; capture(() => i++) < 2;) i];
+  Expect.equals(1, closures[0]());
+  Expect.equals(2, closures[1]());
+  Expect.listEquals([1, 2], list);
+  reset();
+
+  // Close over variable in increment expression.
+  list = [for (var i = 0; i < 2; capture(() => i++)) i];
+  Expect.equals(1, closures[0]());
+  Expect.equals(2, closures[1]());
+  Expect.listEquals([0, 1], list);
+  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 (var global = "for"; global != null; global = null) global
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (var staticField = "for"; staticField != null; staticField = null)
+        staticField
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (var field = "for"; field != null; field = null) field
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (var inherited = "for"; inherited != null; inherited = null) inherited
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (var local = "for"; local != null; local = null) local
+    ];
+    Expect.listEquals(["for"], list);
+
+    list = [
+      for (var outer = "outer"; outer != null; outer = null)
+        for (var 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_2/control_flow_collections/if_const_error_test.dart b/tests/language_2/control_flow_collections/if_const_error_test.dart
new file mode 100644
index 0000000..4e100a6
--- /dev/null
+++ b/tests/language_2/control_flow_collections/if_const_error_test.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,control-flow-collections
+
+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_2/control_flow_collections/if_const_test.dart b/tests/language_2/control_flow_collections/if_const_test.dart
new file mode 100644
index 0000000..8ccac19
--- /dev/null
+++ b/tests/language_2/control_flow_collections/if_const_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=set-literals,control-flow-collections,spread-collections
+
+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;
+const Object objectTrue = 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]);
+  Expect.identical(const [1], const <int>[if (objectTrue) 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]);
+
+  // Nested for in then.
+  Expect.identical(list, const <int>[if (true) for (var i in list) i]);
+
+  // Nested for in else.
+  Expect.identical(list, const <int>[if (false) 9 for (var i in list) i]);
+}
+
+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});
+  Expect.identical(const {1: 1}, const <int, int>{if (objectTrue) 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});
+
+  // Nested for in then.
+  Expect.identical(map, const <int, int>{if (true) for (var i in list) i: i});
+
+  // Nested for in else.
+  Expect.identical(map,
+      const <int, int>{if (false) 9: 9 for (var i in list) i: i});
+}
+
+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({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});
+  Expect.identical(const <int>{1}, const <int>{if (objectTrue) 1});
+
+  // Does not flatten nested collection literal.
+  Expect.identical(const <int>[1], const <int>{if (true) [1]}.first;
+  Expect.identical(const <int, int>{1: 1}, const <int>{if (true) {1: 1}}.first;
+  Expect.identical(const <int>{1}, const <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});
+
+  // Nested for in then.
+  Expect.identical(set, const <int>{if (true) for (var i in list) i});
+
+  // Nested for in else.
+  Expect.identical(set, const <int>{if (false) 9 for (var i in list) i});
+}
+
+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>{
+    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>{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_2/control_flow_collections/if_inference_test.dart b/tests/language_2/control_flow_collections/if_inference_test.dart
new file mode 100644
index 0000000..adc6e65
--- /dev/null
+++ b/tests/language_2/control_flow_collections/if_inference_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections,spread-collections
+
+// 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_2/control_flow_collections/if_test.dart b/tests/language_2/control_flow_collections/if_test.dart
new file mode 100644
index 0000000..8aa7ba5
--- /dev/null
+++ b/tests/language_2/control_flow_collections/if_test.dart
@@ -0,0 +1,243 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,control-flow-collections,spread-collections
+
+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();
+  testRuntimeFailures();
+}
+
+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]);
+  Expect.listEquals(<int>[1], <int>[if (true as Object) 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 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});
+  Expect.mapEquals(<int, int>{1: 1}, <int, int>{if (true as Object) 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 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});
+  Expect.setEquals({1}, <int>{if (true as Object) 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 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(","));
+}
+
+void testRuntimeFailures() {
+  dynamic nonBool = 3;
+  Expect.throwsCastError(() => <int>[if (nonBool) 1]);
+  Expect.throwsCastError(() => <int, int>{if (nonBool) 1: 1});
+  Expect.throwsCastError(() => <int>{if (nonBool) 1});
+
+  bool nullBool = null;
+  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_2/control_flow_collections/map_set_ambiguity_error_test.dart b/tests/language_2/control_flow_collections/map_set_ambiguity_error_test.dart
new file mode 100644
index 0000000..5296956
--- /dev/null
+++ b/tests/language_2/control_flow_collections/map_set_ambiguity_error_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.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections,spread-collections
+
+// 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_2/control_flow_collections/map_set_ambiguity_test.dart b/tests/language_2/control_flow_collections/map_set_ambiguity_test.dart
new file mode 100644
index 0000000..abd6f58
--- /dev/null
+++ b/tests/language_2/control_flow_collections/map_set_ambiguity_test.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.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections,spread-collections
+
+// 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 dyn = map;
+  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, int>({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 ...dyn});
+  // expect___Of<...>({if (true) ...map else ...iterable});
+  // expect___Of<...>({if (true) ...map else ...customSet});
+  expectMapOf<int, int>({if (true) ...map else ...customMap});
+
+  expectSetOf<int>({if (true) ...set else ...set});
+  expectSetOf<dynamic>({if (true) ...set else ...dyn});
+  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) ...dyn else ...iterable});
+  expectSetOf<dynamic>({if (true) ...dyn else ...customSet});
+  expectMapOf<dynamic, dynamic>({if (true) ...dyn 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, int>({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, int>({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;) ...dyn});
+  // expect___Of<...>({for (; false;) ...map, for (; false;) ...iterable});
+  // expect___Of<...>({for (; false;) ...map, for (; false;) ...customSet});
+  expectMapOf<int, int>(
+      {for (; false;) ...map, for (; false;) ...customMap});
+
+  expectSetOf<int>({for (; false;) ...set, for (; false;) ...set});
+  expectSetOf<dynamic>({for (; false;) ...set, for (; false;) ...dyn});
+  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;) ...dyn, for (; false;) ...iterable});
+  expectSetOf<dynamic>(
+      {for (; false;) ...dyn, for (; false;) ...customSet});
+  expectMapOf<dynamic, dynamic>(
+      {for (; false;) ...dyn, 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, int>(
+      {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_2/control_flow_collections/syntax_error_test.dart b/tests/language_2/control_flow_collections/syntax_error_test.dart
new file mode 100644
index 0000000..6e070df
--- /dev/null
+++ b/tests/language_2/control_flow_collections/syntax_error_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections
+
+void main() {
+  // No then element.
+  var _ = [if (true)]; //# 00: compile-time error
+
+  // No then element with else.
+  var _ = [if (true) else 0]; //# 01: compile-time error
+
+  // No else element.
+  var _ = [if (true) 0 else]; //# 02: compile-time error
+
+  // Spread if.
+  var _ = [...if (true) 0]; //# 03: compile-time error
+
+  // Spread for.
+  var _ = [...for (; false;) 0]; //# 04: compile-time error
+
+  // Use if in map entry.
+  var _ = {if (true) 1: 1: 2}; //# 05: compile-time error
+  var _ = {1: if (true) 2: 2}; //# 06: compile-time error
+
+  // Use for in map entry.
+  var _ = {for (; false;) 1: 1: 2}; //# 07: compile-time error
+  var _ = {1: for (; false;) 2: 2}; //# 08: compile-time 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: compile-time 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_2/control_flow_collections/syntax_test.dart b/tests/language_2/control_flow_collections/syntax_test.dart
new file mode 100644
index 0000000..48206cd2
--- /dev/null
+++ b/tests/language_2/control_flow_collections/syntax_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=set-literals,control-flow-collections
+
+// 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) else 1]);
+  Expect.listEquals([1], [if (true) if (false) else 1 else 2]);
+  Expect.listEquals([2], [if (false) if (false) 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]);
+  var 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]);
+  var a = 0;
+  Expect.listEquals([1, 2, 3], [1, for (var i = 0; i < 1; i++) a = 2, 3]);
+}
diff --git a/tests/language_2/control_flow_collections/type_error_test.dart b/tests/language_2/control_flow_collections/type_error_test.dart
new file mode 100644
index 0000000..ace6588
--- /dev/null
+++ b/tests/language_2/control_flow_collections/type_error_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=set-literals,control-flow-collections
+
+void main() {
+  Object obj = true;
+
+  // 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"]; //# 06: compile-time error
+  var _ = <int, int>{if (true) "s": 1}; //# 07: compile-time error
+  var _ = <int, int>{if (true) 1: "s"}; //# 08: compile-time error
+  var _ = <int>{if (true) "s"}; //# 09: compile-time error
+
+  // Wrong else element type.
+  var _ = <int>[if (false) 1 else "s"]; //# 10: compile-time error
+  var _ = <int, int>{if (false) 1: 1 else "s": 2}; //# 11: compile-time error
+  var _ = <int, int>{if (false) 1: 1 else 2: "s"}; //# 12: compile-time error
+  var _ = <int>{if (false) 1 else "s"}; //# 13: compile-time error
+
+  // Non-Boolean for condition.
+  var _ = <int>[for (; 1;) 2]; //# 14: compile-time error
+  var _ = <int, int>{for (; 1;) 2: 2}; //# 15: compile-time error
+  var _ = <int>{for (; 1;) 2}; //# 16: compile-time error
+
+  // Wrong for-in element type.
+  List<String> s = ["s"];
+  var _ = <int>[for (int i in s) 1]; //# 20: compile-time error
+  var _ = <int, int>[for (int i in s) 1: 1]; //# 21: compile-time error
+  var _ = <int>{for (int i in s) 1}; //# 22: compile-time error
+
+  // Wrong for declaration element type.
+  var _ = <int>[for (int i = "s";;) 1]; //# 23: compile-time error
+  var _ = <int, int>[for (int i = "s";;) 1: 1]; //# 24: compile-time error
+  var _ = <int>{for (int i = "s";;) 1}; //# 25: compile-time error
+
+  // Wrong for body element type.
+  var _ = <int>[for (; false;) "s"]; //# 26: compile-time error
+  var _ = <int, int>{for (; false;) "s": 1}; //# 27: compile-time error
+  var _ = <int, int>{for (; false;) 1: "s"}; //# 28: compile-time error
+  var _ = <int>{for (; false;) "s"}; //# 29: compile-time error
+}
diff --git a/tests/language_2/control_flow_collections/utils.dart b/tests/language_2/control_flow_collections/utils.dart
new file mode 100644
index 0000000..9684b3d
--- /dev/null
+++ b/tests/language_2/control_flow_collections/utils.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.
+
+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.identical(dynamic, T);
+  return value;
+}
+
+T expectInt<T>(dynamic value) {
+  Expect.identical(int, T);
+  return value;
+}
+
+T expectString<T>(dynamic value) {
+  Expect.identical(String, T);
+  return value;
+}
+
+Set<T> expectIntSet<T>() {
+  Expect.identical(int, T);
+  return Set();
+}
+
+Set<T> expectDynamicSet<T>() {
+  Expect.identical(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_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index fa02ab6..2ceb689 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -15,7 +15,6 @@
 config_import_corelib_test: CompileTimeError, StaticWarning, OK # failing-by-design: Will never pass, see Issue #34332
 const_cast2_test/01: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334
 const_cast2_test/none: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334
-const_constructor3_test/04: MissingCompileTimeError # Side-effect of working around issue 33441 for int-to-double
 covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
 dynamic_prefix_core_test/01: MissingCompileTimeError # failing-by-design: #34339
 emit_const_fields_test: CompileTimeError # failing-by-design: #34340
@@ -70,7 +69,6 @@
 issue34498_test: MissingCompileTimeError # Issue 34500
 large_class_declaration_test: Slow, Pass
 malformed2_test: Pass, MissingCompileTimeError # Flaky: issue 31056.
-mixin_declaration/mixin_declaration_factory_test/02: Crash # Issue 34809
 mixin_method_override_test/01: MissingCompileTimeError
 mixin_super_2_test: CompileTimeError
 mixin_super_use_test: CompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index afc42ff..9bfaf74 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -47,8 +47,9 @@
 int64_literal_test/none: RuntimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 issue23244_test: RuntimeError # Isolates - enum canonicalization - Issue 23244
 library_env_test/has_io_support: RuntimeError, OK # dart2js doesn't support io when compiling on --categories=Client
-library_env_test/has_mirror_support: RuntimeError, OK
+library_env_test/has_mirror_support: Fail # mirrors not supported on web
 library_env_test/has_no_html_support: RuntimeError, OK
+library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
 list_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 mint_arithmetic_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 mint_compares_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
@@ -375,15 +376,6 @@
 bool_condition_check_test: RuntimeError
 issue31596_super_test/05: RuntimeError
 
-[ $compiler == dart2js && $fast_startup ]
-library_env_test/has_mirror_support: Fail # mirrors not supported
-library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
-
-[ $compiler == dart2js && $fast_startup && $strong ]
-async_star_cancel_while_paused_test: RuntimeError
-covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
-issue23244_test: RuntimeError
-
 [ $compiler == dart2js && $host_checked && $strong ]
 async_return_types_test/nestedFuture: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
 async_star_cancel_while_paused_test: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
@@ -456,6 +448,7 @@
 async_await_test/02: RuntimeError
 async_await_test/03: RuntimeError
 async_await_test/none: RuntimeError
+async_star_cancel_while_paused_test: RuntimeError
 async_star_test/02: RuntimeError
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
@@ -477,7 +470,7 @@
 const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
 constructor12_test: RuntimeError
 constructor_named_arguments_test/none: RuntimeError
-covariant_subtyping_test: Crash
+covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
 ct_const_test: RuntimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
 deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
@@ -519,6 +512,7 @@
 invocation_mirror_invoke_on2_test: RuntimeError
 invocation_mirror_invoke_on_test: RuntimeError
 issue21079_test: RuntimeError
+issue23244_test: RuntimeError
 issue31596_super_test/01: CompileTimeError
 issue31596_super_test/03: CompileTimeError
 left_shift_test: RuntimeError # non JS number semantics
diff --git a/tests/language_2/language_2_flutter.status b/tests/language_2/language_2_flutter.status
deleted file mode 100644
index aa28d79..0000000
--- a/tests/language_2/language_2_flutter.status
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-# Sections in this file should contain "$runtime == flutter".
-# What tests does this comment apply to?  Please add it to each test's line
-# or file an issue an put it there, and add the issue to the relevant tests:
-
-[ $runtime == flutter ]
-async_await_syntax_test/a05c: CompileTimeError
-async_await_syntax_test/a05e: CompileTimeError
-async_await_syntax_test/d08c: CompileTimeError
-async_await_test: CompileTimeError
-asyncstar_yield_test: Skip # Flutter Issue 9110
-await_backwards_compatibility_test/none: CompileTimeError
-await_for_cancel_test: Skip # Flutter Issue 9110
-await_for_test: Skip # Flutter Issue 9110
-await_test: CompileTimeError
-bad_override_test/06: CompileTimeError
-call_constructor_on_unresolvable_class_test/01: CompileTimeError
-call_constructor_on_unresolvable_class_test/02: CompileTimeError
-call_constructor_on_unresolvable_class_test/03: CompileTimeError
-call_constructor_on_unresolvable_class_test/07: CompileTimeError
-check_method_override_test/01: CompileTimeError
-check_method_override_test/02: CompileTimeError
-class_keyword_test/02: CompileTimeError, MissingCompileTimeError # Issue 13627
-class_override_test/00: CompileTimeError
-conditional_import_string_test: CompileTimeError
-conditional_import_test: CompileTimeError
-config_import_test: RuntimeError # Flutter Issue 9110
-const_evaluation_test/01: CompileTimeError
-const_evaluation_test/none: CompileTimeError
-const_types_test/01: CompileTimeError
-const_types_test/02: CompileTimeError
-const_types_test/03: CompileTimeError
-const_types_test/04: CompileTimeError
-const_types_test/05: CompileTimeError
-const_types_test/06: CompileTimeError
-const_types_test/13: CompileTimeError
-const_types_test/35: CompileTimeError
-const_types_test/40: CompileTimeError
-default_factory_test/01: CompileTimeError
-deferred_closurize_load_library_test: Skip # Timeout
-deferred_constant_list_test: Skip # Timeout
-deferred_constraints_constants_test/none: CompileTimeError
-deferred_constraints_constants_test/reference_after_load: CompileTimeError
-deferred_constraints_type_annotation_test/as_operation: CompileTimeError
-deferred_constraints_type_annotation_test/catch_check: CompileTimeError
-deferred_constraints_type_annotation_test/is_check: CompileTimeError
-deferred_constraints_type_annotation_test/new: CompileTimeError
-deferred_constraints_type_annotation_test/new_before_load: CompileTimeError
-deferred_constraints_type_annotation_test/new_generic1: CompileTimeError
-deferred_constraints_type_annotation_test/new_generic2: CompileTimeError
-deferred_constraints_type_annotation_test/new_generic3: CompileTimeError
-deferred_constraints_type_annotation_test/none: Skip # Timeout
-deferred_constraints_type_annotation_test/static_method: Skip # Timeout
-deferred_constraints_type_annotation_test/type_annotation_generic2: CompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic3: CompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_null: CompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_top_level: CompileTimeError
-deferred_global_test: Skip # Timeout
-deferred_inheritance_constraints_test/redirecting_constructor: CompileTimeError
-deferred_mixin_test: CompileTimeError
-deferred_no_such_method_test: CompileTimeError
-deferred_not_loaded_check_test: CompileTimeError
-deferred_redirecting_factory_test: Skip # Timeout
-deferred_shadow_load_library_test: Skip # Timeout
-deferred_shared_and_unshared_classes_test: Skip # Timeout
-deferred_static_seperate_test: CompileTimeError
-deferred_super_dependency_test/01: CompileTimeError
-deferred_type_dependency_test/as: Skip # Timeout
-deferred_type_dependency_test/is: Skip # Timeout
-deferred_type_dependency_test/none: Skip # Timeout
-deferred_type_dependency_test/type_annotation: Skip # Timeout
-enum_mirror_test: CompileTimeError
-export_ambiguous_main_negative_test: Fail # Issue 14763
-f_bounded_quantification5_test: CompileTimeError
-f_bounded_quantification_test/01: CompileTimeError
-f_bounded_quantification_test/02: CompileTimeError
-factory2_test: CompileTimeError
-factory4_test: CompileTimeError
-factory6_test/00: CompileTimeError
-field_increment_bailout_test: CompileTimeError
-field_override_test/01: CompileTimeError
-function_malformed_result_type_test: CompileTimeError
-generic_function_typedef2_test/04: CompileTimeError
-instance_creation_in_function_annotation_test: CompileTimeError
-internal_library_test/01: CompileTimeError
-internal_library_test/01: MissingCompileTimeError
-internal_library_test/02: MissingCompileTimeError
-internal_library_test/02: CompileTimeError
-invocation_mirror2_test: CompileTimeError
-invocation_mirror_invoke_on2_test: CompileTimeError
-invocation_mirror_invoke_on_test: CompileTimeError
-is_malformed_type_test/94: CompileTimeError
-is_malformed_type_test/95: CompileTimeError
-is_malformed_type_test/96: CompileTimeError
-is_malformed_type_test/97: CompileTimeError
-is_malformed_type_test/98: CompileTimeError
-is_malformed_type_test/99: CompileTimeError
-is_not_class2_test: RuntimeError
-issue21079_test: CompileTimeError
-library_env_test/has_mirror_support: RuntimeError, OK
-library_env_test/has_no_mirror_support: Pass
-list_literal_syntax_test/01: CompileTimeError
-list_literal_syntax_test/02: CompileTimeError
-list_literal_syntax_test/03: CompileTimeError
-malbounded_instantiation_test/01: CompileTimeError
-malbounded_redirecting_factory_test/01: CompileTimeError
-malbounded_redirecting_factory_test/none: CompileTimeError
-malbounded_type_cast_test: CompileTimeError
-malbounded_type_literal_test: CompileTimeError
-malbounded_type_test_test/02: CompileTimeError
-malformed2_test/00: CompileTimeError
-malformed_inheritance_test/02: CompileTimeError
-malformed_inheritance_test/04: CompileTimeError
-malformed_inheritance_test/06: CompileTimeError
-malformed_test/none: CompileTimeError
-malformed_type_test: CompileTimeError
-many_overridden_no_such_method_test: CompileTimeError
-method_override2_test/01: CompileTimeError
-method_override3_test/00: CompileTimeError
-method_override3_test/01: CompileTimeError
-method_override3_test/02: CompileTimeError
-method_override4_test: CompileTimeError
-method_override5_test: CompileTimeError
-method_override6_test: CompileTimeError
-mixin_invalid_bound2_test/01: CompileTimeError
-mixin_invalid_bound2_test/04: CompileTimeError
-mixin_invalid_bound2_test/07: CompileTimeError
-mixin_invalid_bound2_test/none: CompileTimeError
-mixin_invalid_bound_test/01: CompileTimeError
-mixin_invalid_bound_test/03: CompileTimeError
-mixin_invalid_bound_test/05: CompileTimeError
-mixin_invalid_bound_test/none: CompileTimeError
-mixin_super_bound2_test/01: CompileTimeError
-mixin_super_bound_test: CompileTimeError
-mixin_type_parameters_errors_test/01: CompileTimeError
-mixin_type_parameters_errors_test/02: CompileTimeError
-mixin_type_parameters_errors_test/03: CompileTimeError
-mixin_type_parameters_errors_test/04: CompileTimeError
-mixin_type_parameters_errors_test/05: CompileTimeError
-new_expression_type_args_test/02: CompileTimeError
-no_such_method_test: CompileTimeError
-non_parameterized_factory2_test: CompileTimeError
-non_parameterized_factory_test: CompileTimeError
-null_test/none: CompileTimeError
-on_catch_malformed_type_test: CompileTimeError
-overridden_no_such_method_test: CompileTimeError
-override_inheritance_field_test/05: CompileTimeError
-override_inheritance_field_test/06: CompileTimeError
-override_inheritance_field_test/07: CompileTimeError
-override_inheritance_field_test/08: CompileTimeError
-override_inheritance_field_test/09: CompileTimeError
-override_inheritance_field_test/10: CompileTimeError
-override_inheritance_field_test/11: CompileTimeError
-override_inheritance_field_test/28: CompileTimeError
-override_inheritance_field_test/29: CompileTimeError
-override_inheritance_field_test/30: CompileTimeError
-override_inheritance_field_test/31: CompileTimeError
-override_inheritance_field_test/32: CompileTimeError
-override_inheritance_field_test/33: CompileTimeError
-override_inheritance_field_test/33a: CompileTimeError
-override_inheritance_field_test/34: CompileTimeError
-override_inheritance_field_test/44: CompileTimeError
-override_inheritance_field_test/45: CompileTimeError
-override_inheritance_field_test/47: CompileTimeError
-override_inheritance_field_test/48: CompileTimeError
-override_inheritance_field_test/53: CompileTimeError
-override_inheritance_field_test/54: CompileTimeError
-override_inheritance_method_test/04: CompileTimeError
-override_inheritance_method_test/05: CompileTimeError
-override_inheritance_method_test/06: CompileTimeError
-override_inheritance_method_test/11: CompileTimeError
-override_inheritance_method_test/12: CompileTimeError
-override_inheritance_method_test/13: CompileTimeError
-override_inheritance_method_test/14: CompileTimeError
-override_inheritance_method_test/19: CompileTimeError
-override_inheritance_method_test/20: CompileTimeError
-override_inheritance_method_test/21: CompileTimeError
-override_inheritance_method_test/27: CompileTimeError
-override_inheritance_method_test/28: CompileTimeError
-override_inheritance_method_test/29: CompileTimeError
-override_inheritance_method_test/30: CompileTimeError
-override_inheritance_method_test/31: CompileTimeError
-override_inheritance_method_test/32: CompileTimeError
-override_inheritance_method_test/33: CompileTimeError
-prefix16_test: CompileTimeError
-prefix22_test: CompileTimeError
-private_access_test/03: CompileTimeError
-private_access_test/04: CompileTimeError
-redirecting_factory_incompatible_signature_test: CompileTimeError
-redirecting_factory_reflection_test: CompileTimeError
-regress_12561_test: CompileTimeError
-regress_13462_0_test: CompileTimeError
-regress_13462_1_test: CompileTimeError
-regress_18535_test: CompileTimeError
-regress_22438_test: CompileTimeError
-regress_23408_test: CompileTimeError
-regress_28255_test: CompileTimeError
-static_initializer_type_error_test: CompileTimeError
-try_catch_on_syntax_test/07: CompileTimeError
-try_catch_syntax_test/08: CompileTimeError
-type_parameter_test/none: CompileTimeError
-type_variable_bounds_test/00: CompileTimeError
-type_variable_bounds_test/06: CompileTimeError
-type_variable_bounds_test/07: CompileTimeError
-type_variable_bounds_test/08: CompileTimeError
-type_variable_bounds_test/09: CompileTimeError
-type_variable_bounds_test/10: CompileTimeError
-type_variable_scope2_test: CompileTimeError
-type_variable_scope_test/00: CompileTimeError
-type_variable_scope_test/01: CompileTimeError
-type_variable_scope_test/02: CompileTimeError
-type_variable_scope_test/03: CompileTimeError
-type_variable_scope_test/04: CompileTimeError
-type_variable_scope_test/05: CompileTimeError
-type_variable_scope_test/none: CompileTimeError
-unicode_bom_test: CompileTimeError, Fail # Issue 16067
-vm/debug_break_enabled_vm_test/01: CompileTimeError, Crash, OK # Expected to hit breakpoint.
-vm/debug_break_enabled_vm_test/none: CompileTimeError
-vm/no_such_method_error_message_callable_vm_test: RuntimeError # Flutter Issue 9110
-vm/reflect_core_vm_test: CompileTimeError
-vm/regress_27201_test: Fail # Flutter Issue 9110
-wrong_number_type_arguments_test/00: CompileTimeError
-wrong_number_type_arguments_test/01: CompileTimeError
-wrong_number_type_arguments_test/02: CompileTimeError
-
-[ $arch == arm64 && $runtime == flutter ]
-large_class_declaration_test: SkipSlow # Uses too much memory.
-
-[ $compiler == none && $runtime == flutter && $checked ]
-assert_initializer_test/4*: MissingCompileTimeError # Issue 392. The VM doesn't enforce that potentially const expressions are actually const expressions when the constructor is called with `const`.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 03b555e..5b34f04 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -1,8 +1,6 @@
 # Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
-# Sections in this file should contain "$compiler == dartk" or
-# "$compiler == dartkp".
 
 enum_initialization_near_stack_overflow_test: Pass, CompileTimeError, OK
 
@@ -39,6 +37,16 @@
 const_nested_test: RuntimeError
 const_string_test: RuntimeError
 constructor12_test: RuntimeError
+control_flow_collections/for_inference_test: DartkCrash
+control_flow_collections/for_test: DartkCrash
+control_flow_collections/for_variable_test: DartkCrash
+control_flow_collections/if_const_test: DartkCrash
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: DartkCrash
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_error_test/09: DartkCrash
+control_flow_collections/syntax_error_test/10: DartkCrash
+control_flow_collections/syntax_test: CompileTimeError
 covariant_subtyping_test: RuntimeError
 ct_const_test: RuntimeError
 cyclic_type2_test: CompileTimeError
@@ -125,6 +133,11 @@
 regress_29025_test: CompileTimeError
 regress_29405_test: CompileTimeError
 regress_30339_test: CompileTimeError
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
 string_interpolation_and_buffer_test: RuntimeError
 super_bound_closure_test/none: CompileTimeError
 super_test: RuntimeError
@@ -151,8 +164,21 @@
 private_method_tearoff_test: RuntimeError
 
 [ $compiler == dartkp ]
+control_flow_collections/for_inference_test: CompileTimeError
+control_flow_collections/for_test: CompileTimeError
+control_flow_collections/for_variable_test: CompileTimeError
+control_flow_collections/if_const_test: CompileTimeError
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: CompileTimeError
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_test: CompileTimeError
 covariant_subtyping_test: RuntimeError
 generic_no_such_method_dispatcher_test: RuntimeError # Issue 31424
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
 web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
 
 [ $compiler == fasta ]
@@ -172,6 +198,16 @@
 const_constructor_nonconst_param_test/01: MissingCompileTimeError
 constructor5_test: CompileTimeError # Verification error
 constructor6_test: CompileTimeError # Verification error
+control_flow_collections/for_inference_test: Crash
+control_flow_collections/for_test: Crash
+control_flow_collections/for_variable_test: Crash
+control_flow_collections/if_const_test: Crash
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: Crash
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_error_test/09: Crash
+control_flow_collections/syntax_error_test/10: Crash
+control_flow_collections/syntax_test: CompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e1: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e10: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e11: MissingCompileTimeError
@@ -193,6 +229,11 @@
 implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
 mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true.
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
 vm/regress_33469_test/01: MissingCompileTimeError
 vm/regress_33469_test/02: MissingCompileTimeError
 vm/regress_33469_test/03: MissingCompileTimeError
@@ -230,7 +271,6 @@
 set_literals/invalid_set_literal_test/08: MissingCompileTimeError # Requires constant evaluation
 set_literals/invalid_set_literal_test/09: MissingCompileTimeError # Requires constant evaluation
 set_literals/invalid_set_literal_test/10: MissingCompileTimeError # Requires constant evaluation
-set_literals/invalid_set_literal_test/23: MissingCompileTimeError # Exact types
 set_literals/invalid_set_literal_test/29: MissingCompileTimeError # Requires constant evaluation
 set_literals/invalid_set_literal_test/30: MissingCompileTimeError # Requires constant evaluation
 set_literals/invalid_set_literal_test/31: MissingCompileTimeError # Requires constant evaluation
@@ -250,6 +290,38 @@
 vm/debug_break_enabled_vm_test/none: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
 vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 
+[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk ]
+control_flow_collections/for_inference_test: DartkCrash
+control_flow_collections/for_test: DartkCrash
+control_flow_collections/for_variable_test: DartkCrash
+control_flow_collections/if_const_test: DartkCrash
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: DartkCrash
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_error_test/09: DartkCrash
+control_flow_collections/syntax_error_test/10: DartkCrash
+control_flow_collections/syntax_test: CompileTimeError
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
+
+[ $arch == simdbc64 && $compiler == dartk ]
+control_flow_collections/for_inference_test: CompileTimeError
+control_flow_collections/for_test: CompileTimeError
+control_flow_collections/for_variable_test: CompileTimeError
+control_flow_collections/if_const_test: CompileTimeError
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: CompileTimeError
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_test: CompileTimeError
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
+
 [ $builder_tag == obfuscated && $compiler == dartkp ]
 generic_function_dcall_test/01: SkipByDesign # Prints type names
 invocation_mirror_test: RuntimeError # Issue 34911
@@ -328,6 +400,9 @@
 [ $compiler != dart2js && $fasta ]
 type_constants_test/01: MissingCompileTimeError # Issue 32557
 
+[ $compiler == dartk && $mode == debug && ($hot_reload || $hot_reload_rollback) ]
+inference_enum_list_test: Skip # Issue 35885
+
 [ $compiler == dartk && $runtime == vm && !$checked && $strong ]
 assertion_initializer_const_error2_test/cc01: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc02: MissingCompileTimeError # Not reporting failed assert() at compile time.
@@ -340,14 +415,44 @@
 assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
 
+[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
+control_flow_collections/for_inference_test: CompileTimeError
+control_flow_collections/for_test: CompileTimeError
+control_flow_collections/for_variable_test: CompileTimeError
+control_flow_collections/if_const_test: CompileTimeError
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: CompileTimeError
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_error_test/09: Pass
+control_flow_collections/syntax_error_test/10: Pass
+control_flow_collections/syntax_test: CompileTimeError
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
+
 [ $compiler == dartkb && $runtime == vm && $strong ]
 async_star_test/03: Pass, RuntimeError # Please triage
 async_star_test/04: Pass, RuntimeError # Please triage
 compile_time_constant_o_test/01: Pass
 compile_time_constant_o_test/02: Pass
 const_dynamic_type_literal_test/02: Pass
+control_flow_collections/for_inference_test: CompileTimeError
+control_flow_collections/for_test: CompileTimeError
+control_flow_collections/for_variable_test: CompileTimeError
+control_flow_collections/if_const_test: CompileTimeError
+control_flow_collections/if_inference_test: CompileTimeError
+control_flow_collections/if_test: CompileTimeError
+control_flow_collections/map_set_ambiguity_test: CompileTimeError
+control_flow_collections/syntax_test: CompileTimeError
 map_literal3_test/01: Pass
 map_literal3_test/02: Pass
+spread_collections/const_test: CompileTimeError
+spread_collections/inference_test: CompileTimeError
+spread_collections/map_set_ambiguity_test: CompileTimeError
+spread_collections/spread_test: CompileTimeError
+spread_collections/syntax_test: CompileTimeError
 vm/bool_check_stack_traces_test/02: Pass
 vm/causal_async_exception_stack2_test: RuntimeError # Please triage
 vm/causal_async_exception_stack_test: RuntimeError # Please triage
@@ -1998,4 +2103,10 @@
 
 [ $compiler == dartkb || $compiler == dartkp ]
 mock_writable_final_private_field_test: CompileTimeError # Test uses Symbol("_...") which is a compile-time error.
+set_literals/invalid_set_literal_test/29: Pass # Gen_kernel does does constant
+set_literals/invalid_set_literal_test/30: Pass # evalutation, so these tests
+set_literals/invalid_set_literal_test/31: Pass # throw the expected errors. The
+set_literals/invalid_set_literal_test/32: Pass # $fasta block marks these as
+set_literals/invalid_set_literal_test/33: Pass # MissingCompileTimeError, so we
+set_literals/invalid_set_literal_test/34: Pass # need to override them to Pass.
 vm/reflect_core_vm_test: CompileTimeError # Test uses Symbol("_...") which is a compile-time error.
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index 47d27f2..68980e7 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -15,13 +15,11 @@
 assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc11: MissingCompileTimeError # Not reporting failed assert() at compile time.
-set_literals/*: Skip
 
 [ $runtime == vm ]
 async_star/async_star_await_for_test: RuntimeError
 async_star/async_star_cancel_test: RuntimeError
 async_star/async_star_test: RuntimeError
-set_literals/*: Skip
 
 [ $arch == arm64 && $runtime == vm ]
 closure_cycles_test: Pass, Slow
diff --git a/tests/language_2/set_literals/const_set_flag_test.dart b/tests/language_2/set_literals/const_set_flag_test.dart
deleted file mode 100644
index 339acaf..0000000
--- a/tests/language_2/set_literals/const_set_flag_test.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Canary test to check that set literals are not enabled *without* an
-// experimental flag.
-
-// Remove this test when the set literals feature is enabled without a flag.
-
-main() {
-  var _ = {1}; //# 01: compile-time error
-  var _ = <int>{}; //# 02: compile-time error
-  Set _ = {}; //# 03: compile-time error
-  Set _ = <int>{}; //# 04: compile-time error
-  var _ = const {1}; //# 05: compile-time error
-  var _ = const <int>{}; //# 06: compile-time error
-  Set _ = const {}; //# 07: compile-time error
-  Set _ = const <int>{}; //# 08: compile-time error
-  const _ = {1}; //# 09: compile-time error
-  const _ = <int>{}; //# 10: compile-time error
-  const Set _ = {}; //# 11: compile-time error
-  const Set _ = <int>{}; //# 12: compile-time error
-}
diff --git a/tests/language_2/spread_collections/const_error_test.dart b/tests/language_2/spread_collections/const_error_test.dart
new file mode 100644
index 0000000..7ea27a5
--- /dev/null
+++ b/tests/language_2/spread_collections/const_error_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=set-literals,spread-collections
+
+import 'dart:collection';
+
+import 'package:expect/expect.dart';
+import 'helper_classes.dart';
+
+var nonConstList = <int>[];
+var nonConstMap = <int, String>{};
+const dynamic nonIterable = 3;
+const dynamic nonMap = 3;
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+}
+
+void testList() {
+  // Must be constant.
+  const _ = <int>[...nonConstList]; //# 01: compile-time error
+
+  // Must be iterable.
+  const _ = <int>[...nonIterable]; //# 02: compile-time error
+
+  // Cannot be custom iterable type.
+  const _ = <int>[...ConstIterable()]; //# 03: compile-time error
+}
+
+void testMap() {
+  // Must be constant.
+  const _ = <int, String>{...nonConstMap}; //# 04: compile-time error
+
+  // Must be map.
+  const _ = <int, String>{...nonMap}; //# 05: compile-time error
+
+  // Cannot be custom map type.
+  const _ = <int, String>{...ConstMap()}; //# 06: compile-time error
+
+  // Cannot have key collision.
+  const _ = <int, String>{1: "s", ...{1: "t"}}; //# 07: compile-time error
+  const _ = <int, String>{...{1: "s"}, ...{1: "t"}}; //# 08: compile-time error
+}
+
+void testSet() {
+  // Must be constant.
+  const _ = <int>{...nonConstList}; //# 09: compile-time error
+
+  // Must be iterable.
+  const _ = <int>{...nonIterable}; //# 10: compile-time error
+
+  // Cannot be custom iterable type.
+  const _ = <int>{...ConstIterable()}; //# 11: compile-time error
+
+  // Cannot override operator.==().
+  const obj = 0.1;
+  const _ = {...[0.1]}; //# 12: compile-time error
+  const _ = {...[Duration(seconds: 0)]}; //# 13: compile-time error
+  const _ = {...[obj]}; //# 14: compile-time error
+
+  // Cannot have collision.
+  const _ = {1, ...[1]}; //# 15: compile-time error
+  const _ = {...[1], ...[1]}; //# 16: compile-time error
+}
diff --git a/tests/language_2/spread_collections/const_test.dart b/tests/language_2/spread_collections/const_test.dart
new file mode 100644
index 0000000..7ae1df2
--- /dev/null
+++ b/tests/language_2/spread_collections/const_test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,spread-collections
+
+import 'package:expect/expect.dart';
+
+// Typed as dynamic to also test spreading a value of type dynamic.
+const dynamic list = [1, 2, 3, 4];
+const dynamic map = {1: 1, 2: 2, 3: 3, 4: 4};
+const dynamic set = {1, 2, 3, 4};
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testKeyOrder();
+}
+
+void testList() {
+  // Only spread.
+  Expect.identical(list, const <int>[...list]);
+  Expect.identical(list, const <int>[...set]);
+
+  // Spread at beginning.
+  Expect.identical(list, const <int>[...<int>[1, 2], 3, 4]);
+
+  // Spread in middle.
+  Expect.identical(list, const <int>[1, ...<int>[2, 3], 4]);
+
+  // Spread at end.
+  Expect.identical(list, const <int>[1, 2, ...<int>[3, 4]]);
+
+  // Empty spreads.
+  Expect.identical(list,
+      const <int>[...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]]);
+
+  // Multiple spreads.
+  Expect.identical(list,
+      const <int>[...<int>[1], 2, ...<int>[3, 4]]);
+
+  // Nested spreads.
+  Expect.identical(list,
+      const <int>[...<int>[...<int>[1, 2], ...<int>[3, 4]]]);
+
+  // Null-aware.
+  Expect.identical(list,
+      const <int>[1, ...?<int>[2, 3], ...?(null), ...?<int>[4]]);
+
+  // Does not deep flatten.
+  Expect.identical(
+      const <int>[1, 2, <int>[3], 4], const <int>[1, ...<int>[2, <int>[3], 4]]);
+
+  // Establishes const context.
+  Expect.identical(const <Symbol>[Symbol("sym")],
+      const <Symbol>[...<Symbol>[Symbol("sym")]]);
+}
+
+void testMap() {
+  // Only spread.
+  Expect.identical(map, const <int, int>{...map});
+
+  // Spread at beginning.
+  Expect.identical(map,
+      const <int, int>{...<int, int>{1: 1, 2: 2}, 3: 3, 4: 4});
+
+  // Spread in middle.
+  Expect.identical(map,
+      const <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});
+
+  // Spread at end.
+  Expect.identical(map,
+      const <int, int>{1: 1, 2: 2, ...<int, int>{3: 3, 4: 4}});
+
+  // Empty spreads.
+  Expect.identical(map, const <int, int>{
+    ...<int, int>{},
+    1: 1,
+    2: 2,
+    ...<int, int>{},
+    3: 3,
+    4: 4,
+    ...<int, int>{}
+  });
+
+  // Multiple spreads.
+  Expect.identical(map,
+      const <int, int>{...<int, int>{1: 1}, 2: 2, ...<int, int>{3: 3, 4: 4}});
+
+  // Nested spreads.
+  Expect.identical(map, const <int, int>{
+    ...<int, int>{
+      ...<int, int>{1: 1, 2: 2},
+      ...<int, int>{3: 3, 4: 4}
+    }
+  });
+
+  // Null-aware.
+  Expect.identical(map, const <int, int>{
+    1: 1,
+    ...?<int, int>{2: 2, 3: 3},
+    ...?(null),
+    ...?<int, int>{4: 4}
+  });
+
+  // Does not deep flatten.
+  Expect.identical(const <int, Object>{
+    1: 1,
+    2: 2,
+    3: <int, int>{3: 3},
+    4: 4
+  }, const <int, Object>{
+    1: 1,
+    ...<int, Object>{
+      2: 2,
+      3: <int, int>{3: 3},
+      4: 4
+    }
+  });
+
+  // Establishes const context.
+  Expect.identical(const <Symbol, Symbol>{
+    Symbol("sym"): Symbol("bol")
+  }, const <Symbol, Symbol>{
+    ...<Symbol, Symbol>{Symbol("sym"): Symbol("bol")}
+  });
+}
+
+void testSet() {
+  // Only spread.
+  Expect.identical(set, const <int>{...set});
+  Expect.identical(set, const <int>{...list});
+
+  // Spread at beginning.
+  Expect.identical(set, const <int>{...<int>[1, 2], 3, 4});
+
+  // Spread in middle.
+  Expect.identical(set, const <int>{1, ...<int>[2, 3], 4});
+
+  // Spread at end.
+  Expect.identical(set, const <int>{1, 2, ...<int>[3, 4]});
+
+  // Empty spreads.
+  Expect.identical(set,
+      const <int>{...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]});
+
+  // Multiple spreads.
+  Expect.identical(set, const <int>{...<int>[1], 2, ...<int>[3, 4]});
+
+  // Nested spreads.
+  Expect.identical(set, const <int>{...<int>{...<int>[1, 2], ...<int>[3, 4]}});
+
+  // Null-aware.
+  Expect.identical(set,
+      const <int>{1, ...?<int>[2, 3], ...?(null), ...?<int>[4]});
+
+  // Does not deep flatten.
+  Expect.identical(const <Object>{1, 2, <int>{3}, 4},
+      const <Object>{1, ...<Object>{2, <int>{3}, 4}});
+
+  // Establishes const context.
+  Expect.identical(const <Symbol>{Symbol("sym")},
+      const <Symbol>{...<Symbol>{Symbol("sym")}});
+}
+
+void testKeyOrder() {
+  // Canonicalization isn't affected by which elements are spread.
+  Expect.identical(map,
+      const <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});
+  Expect.identical(map,
+      const <int, int>{1: 1, ...<int, int>{2: 2}, 3: 3, ...<int, int>{4: 4}});
+
+  Expect.identical(set, const <int>{1, ...<int>{2, 3}, 4});
+  Expect.identical(set, const <int>{1, ...<int>{2}, 3, ...<int>{4}});
+
+  // Ordering does affect canonicalization.
+  Expect.notIdentical(const <int, int>{1: 1, 2: 2, 3: 3},
+      const <int, int>{1: 1, ...<int, int>{3: 3, 2: 2}});
+  Expect.notIdentical(const <int>{1, 2, 3}, const <int>{1, ...<int>{3, 2}});
+}
diff --git a/tests/language_2/spread_collections/experimental_flag_test.dart b/tests/language_2/spread_collections/experimental_flag_test.dart
new file mode 100644
index 0000000..a1c8bf7
--- /dev/null
+++ b/tests/language_2/spread_collections/experimental_flag_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.
+
+// Check that spread collections are not enabled without the experimental flag.
+
+// Do enable sets, just not spread inside them.
+// SharedOptions=--enable-experiment=set-literals
+
+// TODO(rnystrom): Remove this test when the feature is enabled without a flag.
+
+void main() {
+  var _ = <int>[...<int>[1]]; //# 01: compile-time error
+  var _ = <int, int>{...<int, int>{1: 1}}; //# 02: compile-time error
+  var _ = <int>{...<int>{1}}; //# 03: compile-time error
+  var _ = <int>[...?null]; //# 04: compile-time error
+  var _ = <int, int>{...?null}; //# 05: compile-time error
+  var _ = <int>{...?null}; //# 06: compile-time error
+}
diff --git a/tests/language_2/spread_collections/helper_classes.dart b/tests/language_2/spread_collections/helper_classes.dart
new file mode 100644
index 0000000..9c35975
--- /dev/null
+++ b/tests/language_2/spread_collections/helper_classes.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 'dart:collection';
+
+class ConstIterable extends IterableBase<int> {
+  const ConstIterable();
+
+  Iterator<int> get iterator => <int>[].iterator;
+}
+
+class ConstMap implements Map<int, String> {
+  const ConstMap();
+
+  Iterable<MapEntry<int, String>> get entries => const [];
+
+  bool get isEmpty => throw UnsupportedError("unsupported");
+  bool get isNotEmpty => throw UnsupportedError("unsupported");
+  Iterable<int> get keys => throw UnsupportedError("unsupported");
+  int get length => throw UnsupportedError("unsupported");
+  Iterable<String> get values => throw UnsupportedError("unsupported");
+  String operator [](Object key) => throw UnsupportedError("unsupported");
+  operator []=(int key, String value) => throw UnsupportedError("unsupported");
+  bool add(Object value) => throw UnsupportedError("unsupported");
+  void addAll(Map<int, String> map) => throw UnsupportedError("unsupported");
+  void addEntries(Iterable<MapEntry<int, String>> entries) =>
+      throw UnsupportedError("unsupported");
+  Map<RK, RV> cast<RK, RV>() => throw UnsupportedError("unsupported");
+  void clear() => throw UnsupportedError("unsupported");
+  bool containsKey(Object key) => throw UnsupportedError("unsupported");
+  bool containsValue(Object value) => throw UnsupportedError("unsupported");
+  void forEach(void Function(int key, String value) f) =>
+      throw UnsupportedError("unsupported");
+  Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(int key, String value) f) =>
+      throw UnsupportedError("unsupported");
+  String putIfAbsent(int key, String Function() ifAbsent) =>
+      throw UnsupportedError("unsupported");
+  String remove(Object key) => throw UnsupportedError("unsupported");
+  void removeWhere(bool Function(int key, String value) predicate) =>
+      throw UnsupportedError("unsupported");
+  String update(int key, String Function(String value) update,
+          {String Function() ifAbsent}) =>
+      throw UnsupportedError("unsupported");
+  void updateAll(String Function(int key, String value) update) =>
+      throw UnsupportedError("unsupported");
+}
+
+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";
+}
diff --git a/tests/language_2/spread_collections/inference_test.dart b/tests/language_2/spread_collections/inference_test.dart
new file mode 100644
index 0000000..0b3d4e5
--- /dev/null
+++ b/tests/language_2/spread_collections/inference_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,spread-collections
+
+// Test how spread interacts with inference.
+import 'package:expect/expect.dart';
+
+void main() {
+  testBottomUpInference();
+  testTopDownInference();
+}
+
+void testBottomUpInference() {
+  // Lists.
+  Expect.type<List<dynamic>>([...[]]);
+  Expect.type<List<int>>([...<int>[]]);
+  Expect.type<List<int>>([...[1]]);
+  Expect.type<List<int>>([1, ...[2]]);
+  Expect.type<List<num>>([1, ...[0.2]]);
+  Expect.type<List<int>>([...[1, 2]]);
+  Expect.type<List<num>>([...[1, 0.2]]);
+  Expect.type<List<int>>([...[1], ...[2]]);
+  Expect.type<List<num>>([...[1], ...[0.2]]);
+
+  // Maps.
+  Expect.type<Map<dynamic, dynamic>>({...{}});
+  Expect.type<Map<int, int>>({...<int, int>{}});
+  Expect.type<Map<int, int>>({...{1: 1}});
+  Expect.type<Map<int, int>>({1: 1, ...{2: 2}});
+  Expect.type<Map<num, num>>({1: 1, ...{0.2: 0.2}});
+  Expect.type<Map<int, int>>({...{1: 1, 2: 2}});
+  Expect.type<Map<num, num>>({...{1: 1, 0.2: 0.2}});
+  Expect.type<Map<int, int>>({...{1: 1}, ...{2: 2}});
+  Expect.type<Map<num, num>>({...{1: 1}, ...{0.2: 0.2}});
+
+  // Sets.
+  Expect.type<Set<dynamic>>({...[]});
+  Expect.type<Set<int>>({...<int>[]});
+  Expect.type<Set<int>>({...[1]});
+  Expect.type<Set<int>>({1, ...[2]});
+  Expect.type<Set<num>>({1, ...[0.2]});
+  Expect.type<Set<int>>({...[1, 2]});
+  Expect.type<Set<num>>({...[1, 0.2]});
+  Expect.type<Set<int>>({...[1], ...[2]});
+  Expect.type<Set<num>>({...[1], ...[0.2]});
+  Expect.type<Set<num>>({...{1}, ...[0.2]});
+  Expect.type<Set<num>>({...{1}, ...{0.2}});
+
+  // If the iterable's type is dynamic, the element type is inferred as dynamic.
+  Expect.type<List<dynamic>>([...([] as dynamic)]);
+  Expect.type<Set<dynamic>>({1, ...([] as dynamic)});
+
+  // If the iterable's type is dynamic, the key and value types are inferred as
+  // dynamic.
+  Expect.type<Map<dynamic, dynamic>>({1: 1, ...({} as dynamic)});
+}
+
+void testTopDownInference() {
+  // Lists.
+  Iterable<T> expectIntIterable<T>() {
+    Expect.identical(int, T);
+    return [];
+  }
+
+  Iterable<T> expectDynamicIterable<T>() {
+    Expect.identical(dynamic, T);
+    return [];
+  }
+
+  // The context element type is pushed into the spread expression if it is
+  // Iterable<T>.
+  Expect.listEquals(<int>[], <int>[...expectIntIterable()]);
+
+  // Bottom up-inference from elements is not pushed back down into spread.
+  Expect.listEquals(<int>[1], [1, ...expectDynamicIterable()]);
+
+  // Maps.
+  Map<K, V> expectIntStringMap<K, V>() {
+    Expect.identical(int, K);
+    Expect.identical(String, V);
+    return {};
+  }
+
+  Map<K, V> expectDynamicDynamicMap<K, V>() {
+    Expect.identical(dynamic, K);
+    Expect.identical(dynamic, V);
+    return {};
+  }
+
+  // The context element type is pushed into the spread expression if it is
+  // Map<K, V>.
+  Expect.mapEquals(<int, String>{}, <int, String>{...expectIntStringMap()});
+
+  // Bottom up-inference from elements is not pushed back down into spread.
+  Expect.mapEquals(<int, String>{1: "s"},
+      {1: "s", ...expectDynamicDynamicMap()});
+
+  // Sets.
+  Set<T> expectIntSet<T>() {
+    Expect.identical(int, T);
+    return Set();
+  }
+
+  Set<T> expectDynamicSet<T>() {
+    Expect.identical(dynamic, T);
+    return Set();
+  }
+
+  // The context element type is pushed into the spread expression if it is
+  // Iterable<T>.
+  Expect.setEquals(<int>{}, <int>{...expectIntSet()});
+
+  // Bottom up-inference from elements is not pushed back down into spread.
+  Expect.setEquals(<int>{}, {1, ...expectDynamicSet()});
+}
diff --git a/tests/language_2/spread_collections/map_set_ambiguity_error_test.dart b/tests/language_2/spread_collections/map_set_ambiguity_error_test.dart
new file mode 100644
index 0000000..ab9b822
--- /dev/null
+++ b/tests/language_2/spread_collections/map_set_ambiguity_error_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=set-literals,spread-collections
+
+// Test cases where the syntax is ambiguous between maps and sets.
+import 'dart:collection';
+
+import 'helper_classes.dart';
+
+void main() {
+  Map<int, int> map = {};
+  Set<int> set = Set();
+  dynamic dyn = map;
+  Iterable<int> iterable = [];
+  CustomSet customSet = CustomSet();
+  CustomMap customMap = CustomMap();
+
+  var _ = {...dyn}; //# 00: compile-time error
+  var _ = {...map, ...set}; //# 01: compile-time error
+  var _ = {...map, ...iterable}; //# 02: compile-time error
+  var _ = {...map, ...customSet}; //# 03: compile-time error
+  var _ = {...set, ...customMap}; //# 04: compile-time error
+  var _ = {...dyn, ...dyn}; //# 05: compile-time error
+  var _ = {...iterable, ...customMap}; //# 06: compile-time error
+  var _ = {...customSet, ...customMap}; //# 07: compile-time error
+}
diff --git a/tests/language_2/spread_collections/map_set_ambiguity_test.dart b/tests/language_2/spread_collections/map_set_ambiguity_test.dart
new file mode 100644
index 0000000..48ce5a7
--- /dev/null
+++ b/tests/language_2/spread_collections/map_set_ambiguity_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,spread-collections
+
+// Test cases where the syntax is ambiguous between maps and sets.
+import 'dart:collection';
+
+import 'package:expect/expect.dart';
+
+import 'helper_classes.dart';
+
+void main() {
+  testBottomUpInference();
+  testTopDownInference();
+}
+
+void testBottomUpInference() {
+  Map<int, int> map = {};
+  Set<int> set = Set();
+  dynamic dyn = map;
+  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.
+  Expect.type<Map<int, int>>({...map});
+  Expect.type<Set<int>>({...set});
+  // Expect.type<...>({...dyn});
+  Expect.type<Set<int>>({...iterable});
+  Expect.type<Set<int>>({...customSet});
+  Expect.type<Map<int, int>>({...customMap});
+
+  Expect.type<Map<int, int>>({...map, ...map});
+  // Expect.type<...>({...map, ...set});
+  Expect.type<Map<dynamic, dynamic>>({...map, ...dyn});
+  // Expect.type<...>({...map, ...iterable});
+  // Expect.type<...>({...map, ...customSet});
+  Expect.type<Map<int, int>>({...map, ...customMap});
+
+  Expect.type<Set<int>>({...set, ...set});
+  Expect.type<Set<dynamic>>({...set, ...dyn});
+  Expect.type<Set<int>>({...set, ...iterable});
+  Expect.type<Set<int>>({...set, ...customSet});
+  // Expect.type<...>({...set, ...customMap});
+
+  // Expect.type<...>({...dyn, ...dyn});
+  Expect.type<Set<dynamic>>({...dyn, ...iterable});
+  Expect.type<Set<dynamic>>({...dyn, ...customSet});
+  Expect.type<Map<dynamic, dynamic>>({...dyn, ...customMap});
+
+  Expect.type<Set<int>>({...iterable, ...iterable});
+  Expect.type<Set<int>>({...iterable, ...customSet});
+  // Expect.type<...>({...iterable, ...customMap});
+
+  Expect.type<Set<int>>({...customSet, ...customSet});
+  // Expect.type<...>({...customSet, ...customMap});
+
+  Expect.type<Map<int, int>>({...customMap, ...customMap});
+}
+
+void testTopDownInference() {
+  dynamic untypedMap = <int, int>{};
+  dynamic untypedIterable = <int>[];
+
+  Map<int, int> map = {...untypedMap};
+  Set<int> set = {...untypedIterable};
+  Iterable<int> iterable = {...untypedIterable};
+
+  Expect.type<Map<int, int>>(map);
+  Expect.type<Set<int>>(set);
+  Expect.type<Set<int>>(iterable);
+}
diff --git a/tests/language_2/spread_collections/spread_test.dart b/tests/language_2/spread_collections/spread_test.dart
new file mode 100644
index 0000000..aab98da
--- /dev/null
+++ b/tests/language_2/spread_collections/spread_test.dart
@@ -0,0 +1,222 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=set-literals,spread-collections
+
+import 'package:expect/expect.dart';
+
+import 'helper_classes.dart';
+
+// Typed as dynamic to also test spreading a value of type dynamic.
+final dynamic list = [1, 2, 3, 4];
+final dynamic map = {1: 1, 2: 2, 3: 3, 4: 4};
+final dynamic set = {1, 2, 3, 4};
+
+void main() {
+  testList();
+  testMap();
+  testSet();
+  testDuplicateKeys();
+  testKeyOrder();
+  testCastFailures();
+}
+
+void testList() {
+  // Only spread.
+  Expect.listEquals(list, <int>[...list]);
+
+  // Spread at beginning.
+  Expect.listEquals(list, <int>[...<int>[1, 2], 3, 4]);
+
+  // Spread in middle.
+  Expect.listEquals(list, <int>[1, ...<int>[2, 3], 4]);
+
+  // Spread at end.
+  Expect.listEquals(list, <int>[1, 2, ...<int>[3, 4]]);
+
+  // Empty spreads.
+  Expect.listEquals(list,
+      <int>[...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]]);
+
+  // Multiple spreads.
+  Expect.listEquals(list, <int>[...<int>[1], 2, ...<int>[3, 4]]);
+
+  // Nested spreads.
+  Expect.listEquals(list, <int>[...<int>[...<int>[1, 2], ...<int>[3, 4]]]);
+
+  // Null-aware.
+  Expect.listEquals(list, <int>[1, ...?<int>[2, 3], ...?(null), ...?<int>[4]]);
+
+  // Does not deep flatten.
+  var innerList = <int>[3];
+  Expect.listEquals(
+      <int>[1, 2, innerList, 4], <int>[1, ...<int>[2, innerList, 4]]);
+
+  // Downcast element.
+  Expect.listEquals(list, <int>[...<num>[1, 2, 3, 4]]);
+}
+
+void testMap() {
+  // Only spread.
+  Expect.mapEquals(map, <int, int>{...map});
+
+  // Spread at beginning.
+  Expect.mapEquals(map, <int, int>{...<int, int>{1: 1, 2: 2}, 3: 3, 4: 4});
+
+  // Spread in middle.
+  Expect.mapEquals(map, <int, int>{1: 1, ...<int, int>{2: 2, 3: 3}, 4: 4});
+
+  // Spread at end.
+  Expect.mapEquals(map, <int, int>{1: 1, 2: 2, ...<int, int>{3: 3, 4: 4}});
+
+  // Empty spreads.
+  Expect.mapEquals(map, <int, int>{
+    ...<int, int>{},
+    1: 1,
+    2: 2,
+    ...<int, int>{},
+    3: 3,
+    4: 4,
+    ...<int, int>{}
+  });
+
+  // Multiple spreads.
+  Expect.mapEquals(map,
+      <int, int>{...<int, int>{1: 1}, 2: 2, ...<int, int>{3: 3, 4: 4}});
+
+  // Nested spreads.
+  Expect.mapEquals(map, <int, int>{
+    ...<int, int>{
+      ...<int, int>{1: 1, 2: 2},
+      ...<int, int>{3: 3, 4: 4}
+    }
+  });
+
+  // Null-aware.
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    ...?<int, int>{2: 2, 3: 3},
+    ...?(null),
+    ...?<int, int>{4: 4}
+  });
+
+  // Does not deep flatten.
+  var innerMap = <int, int>{3: 3};
+  Expect.mapEquals(<int, Object>{
+    1: 1,
+    2: 2,
+    3: innerMap,
+    4: 4
+  }, <int, Object>{
+    1: 1,
+    ...<int, Object>{
+      2: 2,
+      3: innerMap,
+      4: 4
+    }
+  });
+
+  // Downcast element.
+  Expect.mapEquals(map, <int, int>{...<num, num>{1: 1, 2: 2, 3: 3, 4: 4}});
+}
+
+void testSet() {
+  // Only spread.
+  Expect.setEquals(set, <int>{...set});
+
+  // Spread at beginning.
+  Expect.setEquals(set, <int>{...<int>[1, 2], 3, 4});
+
+  // Spread in middle.
+  Expect.setEquals(set, <int>{1, ...<int>[2, 3], 4});
+
+  // Spread at end.
+  Expect.setEquals(set, <int>{1, 2, ...<int>[3, 4]});
+
+  // Empty spreads.
+  Expect.setEquals(set, <int>{...<int>[], 1, 2, ...<int>[], 3, 4, ...<int>[]});
+
+  // Multiple spreads.
+  Expect.setEquals(set, <int>{...<int>[1], 2, ...<int>[3, 4]});
+
+  // Nested spreads.
+  Expect.setEquals(set, <int>{...<int>{...<int>[1, 2], ...<int>[3, 4]}});
+
+  // Null-aware.
+  Expect.setEquals(set, <int>{1, ...?<int>[2, 3], ...?(null), ...?<int>[4]});
+
+  // Does not deep flatten.
+  var innerSet = <int>{3};
+  Expect.setEquals(<Object>{1, 2, innerSet, 4},
+      <Object>{1, ...<Object>[2, innerSet, 4]});
+
+  // Downcast element.
+  Expect.setEquals(set, <int>{...<num>[1, 2, 3, 4]});
+}
+
+void testDuplicateKeys() {
+  Expect.mapEquals(map, <int, int>{
+    1: 1,
+    2: 2,
+    ...<int, int>{2: 2, 3: 3, 4: 4},
+    ...<int, int>{3: 3},
+    4: 4
+  });
+  Expect.setEquals(set, <int>{1, 2, ...<int>[1, 2, 3, 4], ...<int>[2, 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 map = <Equality, int>{e1a: 1, ...<Equality, int>{e1b: 2, e2a: 3, e2b: 4}};
+  Expect.equals("1:a,2:a", map.keys.join(","));
+
+  var set = <Equality>{e1a, ...<Equality>[e1b, e2a, e2b]};
+  Expect.equals("1:a,2:a", set.join(","));
+
+  // All elements are evaluated, left to right.
+  var transcript = <String>[];
+  T log<T>(T value) {
+    transcript.add(value.toString());
+    return value;
+  }
+
+  map = <Equality, int>{
+    log(e1a): log(1),
+    ...<Equality, int>{log(e1b): log(2), log(e2a): log(3), log(e2b): log(4)}
+  };
+  Expect.equals("1:a,1,1:b,2,2:a,3,2:b,4", transcript.join(","));
+
+  transcript.clear();
+  set = <Equality>{log(e1a), ...<Equality>[log(e1b), log(e2a), log(e2b)]};
+  Expect.equals("1:a,1:b,2:a,2:b", transcript.join(","));
+}
+
+void testCastFailures() {
+  dynamic nonIterable = 3;
+  Expect.throwsCastError(() => <int>[...nonIterable]);
+  Expect.throwsCastError(() => <int>{...nonIterable});
+
+  dynamic nonMap = 3;
+  Expect.throwsCastError(() => <int, int>{...nonMap});
+
+  dynamic wrongIterableType = <String>["s"];
+  Expect.throwsCastError(() => <int>[...wrongIterableType]);
+  Expect.throwsCastError(() => <int>{...wrongIterableType});
+
+  dynamic wrongKeyType = <String, int>{"s": 1};
+  dynamic wrongValueType = <int, String>{1: "s"};
+  Expect.throwsCastError(() => <int, int>{...wrongKeyType});
+  Expect.throwsCastError(() => <int, int>{...wrongValueType});
+
+  // Mismatched collection types.
+  Expect.throwsCastError(() => <int>[...map]);
+  Expect.throwsCastError(() => <int, int>{...list});
+  Expect.throwsCastError(() => <int, int>{...set});
+  Expect.throwsCastError(() => <int>{...map});
+}
diff --git a/tests/language_2/spread_collections/syntax_error_test.dart b/tests/language_2/spread_collections/syntax_error_test.dart
new file mode 100644
index 0000000..9f38d74
--- /dev/null
+++ b/tests/language_2/spread_collections/syntax_error_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.
+
+// SharedOptions=--enable-experiment=set-literals,spread-collections
+
+void main() {
+  // Spread nothing.
+  var _ = [...]; //# 00: compile-time error
+  var _ = [...?]; //# 01: compile-time error
+  var _ = [...,]; //# 02: compile-time error
+
+  // Use `...` in map entry.
+  var _ = {"a": ...{}}; //# 03: compile-time error
+  var _ = {...{}: "b"}; //# 04: compile-time error
+  var _ = {"a": ...?{}}; //# 05: compile-time error
+  var _ = {...?{}: "b"}; //# 06: compile-time error
+
+  // Treats `...?` as single token.
+  var _ = [... ?null]; //# 07: compile-time error
+  var _ = {1: 2, ... ?null}; //# 08: compile-time error
+}
diff --git a/tests/language_2/spread_collections/syntax_test.dart b/tests/language_2/spread_collections/syntax_test.dart
new file mode 100644
index 0000000..c46b589
--- /dev/null
+++ b/tests/language_2/spread_collections/syntax_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=set-literals,spread-collections
+
+// Tests syntax edge cases.
+import 'package:expect/expect.dart';
+
+void main() {
+  // Trailing comma.
+  Expect.listEquals([1, 2], [...[1, 2],]);
+  Expect.mapEquals({1: 1, 2: 2}, {...{1: 1, 2: 2},});
+  Expect.setEquals({1, 2}, {...{1, 2},});
+
+  // Precedence.
+  Expect.listEquals([1, 2, 3], [1, ...true ? [2] : [], 3]);
+  Expect.listEquals([1, 3], [1, ...?true ? null : [], 3]);
+
+  var a = [0];
+  Expect.listEquals([1, 2, 3], [1, ...a = [2], 3]);
+  Expect.listEquals([1, 3], [1, ...?a = null, 3]);
+
+  var b = [2];
+  Expect.listEquals([1, 2, 3, 4], [1, ...b..add(3), 4]);
+  b = [2];
+  Expect.listEquals([1, 2, 3, 4], [1, ...?b..add(3), 4]);
+}
diff --git a/tests/language_2/spread_collections/type_error_test.dart b/tests/language_2/spread_collections/type_error_test.dart
new file mode 100644
index 0000000..06f1cab
--- /dev/null
+++ b/tests/language_2/spread_collections/type_error_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.
+
+// SharedOptions=--enable-experiment=set-literals,spread-collections
+
+void main() {
+  // Spread non-iterable or non-map.
+  var _ = [...(3)]; //# 00: compile-time error
+  var _ = <int, int>{...(3)}; //# 01: compile-time error
+  var _ = <int>{...(3)}; //# 02: compile-time error
+
+  // Object.
+  var _ = [...([] as Object)]; //# 03: compile-time error
+  var _ = <int, int>{...({} as Object)}; //# 04: compile-time error
+  var _ = <int>{...([] as Object)}; //# 05: compile-time error
+
+  // Wrong element type.
+  var _ = <int>[...<String>[]]; //# 06: compile-time error
+  var _ = <int, int>{...<String, int>{}}; //# 07: compile-time error
+  var _ = <int, int>{...<int, String>{}}; //# 08: compile-time error
+  var _ = <int>{...<String>[]}; //# 09: compile-time error
+}
diff --git a/tests/language_2/switch_test.dart b/tests/language_2/switch_test.dart
index a0cb2df..0b12c0e7 100644
--- a/tests/language_2/switch_test.dart
+++ b/tests/language_2/switch_test.dart
@@ -110,6 +110,37 @@
   Expect.equals(expect, result);
 }
 
+void testSwitchString(String input, int expect) {
+  int result = null;
+  switch (input) {
+    case 'one':
+      result = 1;
+      break;
+    case 'two':
+      result = 2;
+      break;
+  }
+  Expect.equals(expect, result);
+}
+
+switchConstString() {
+  const c = 'a';
+  switch (c) {
+    case 'a':
+      return 'aa';
+    case 'b':
+      return 'bb';
+    case 'c':
+      return 'cc';
+    case 'd':
+      return 'dd';
+    case 'e':
+      return 'ee';
+    case 'f':
+      return 'ff';
+  }
+}
+
 main() {
   SwitchTest.testMain();
 
@@ -127,4 +158,11 @@
 
   testSwitchBool(true, 12);
   testSwitchBool(false, 22);
+
+  testSwitchString(null, null);
+  testSwitchString('one', 1);
+  testSwitchString('two', 2);
+  testSwitchString('three', null);
+
+  Expect.equals('aa', switchConstString());
 }
diff --git a/tests/language_2/vm/modtruncdiv_int_test.dart b/tests/language_2/vm/modtruncdiv_int_test.dart
index 8314628..b838b15 100644
--- a/tests/language_2/vm/modtruncdiv_int_test.dart
+++ b/tests/language_2/vm/modtruncdiv_int_test.dart
@@ -92,6 +92,12 @@
   Expect.equals(0, mod(minInt64, 1 << 63));
 }
 
+doModVarConstant() {
+  for (int i = -10; i < 10; i++) {
+    Expect.equals(i & maxInt64, mod(i, minInt64));
+  }
+}
+
 doTruncDivConstants() {
   Expect.equals(0, truncdiv(0, 1));
   Expect.equals(0, truncdiv(0, -1));
@@ -175,6 +181,7 @@
     // Constants.
 
     doModConstants();
+    doModVarConstant();
     doTruncDivConstants();
 
     // Variable ranges.
diff --git a/tests/lib_2/convert/json_test.dart b/tests/lib_2/convert/json_test.dart
index 22e5f24..8ebfe63 100644
--- a/tests/lib_2/convert/json_test.dart
+++ b/tests/lib_2/convert/json_test.dart
@@ -15,22 +15,24 @@
       Expect.isTrue(actual is List);
       Expect.equals(expected.length, actual.length, "$path: List length");
       for (int i = 0; i < expected.length; i++) {
-        compare(expected[i], actual[i], "$path[$i]");
+        compare(expected[i], actual[i], "$path[$i] in $jsonText");
       }
     } else if (expected is Map) {
       Expect.isTrue(actual is Map);
-      Expect.equals(expected.length, actual.length, "$path: Map size");
+      Expect.equals(expected.length, actual.length,
+          "$path: Map size in $jsonText");
       expected.forEach((key, value) {
         Expect.isTrue(actual.containsKey(key));
-        compare(value, actual[key], "$path[$key]");
+        compare(value, actual[key], "$path[$key] in $jsonText");
       });
     } else if (expected is num) {
-      Expect.equals(expected is int, actual is int, "$path: same number type");
+      Expect.equals(expected is int, actual is int,
+          "$path: not same number type in $jsonText");
       Expect.isTrue(expected.compareTo(actual) == 0,
-          "$path: Expected: $expected, was: $actual");
+          "$path: Expected: $expected, was: $actual in $jsonText");
     } else {
       // String, bool, null.
-      Expect.equals(expected, actual, path);
+      Expect.equals(expected, actual, "$path in $jsonText");
     }
   }
 
@@ -142,6 +144,45 @@
     }
   }
 
+  // Regression test.
+  // Detect and handle overflow on integer literals by making them doubles
+  // (work like `num.parse`).
+  testJson("9223372036854774784", 9223372036854774784);
+  testJson("-9223372036854775808", -9223372036854775808);
+  testJson("9223372036854775808", 9223372036854775808.0);
+  testJson("-9223372036854775809", -9223372036854775809.0);
+  testJson("9223372036854775808.0", 9223372036854775808.0);
+  testJson("9223372036854775810", 9223372036854775810.0);
+  testJson("18446744073709551616.0", 18446744073709551616.0);
+  testJson("1e309", double.infinity);
+  testJson("-1e309", double.negativeInfinity);
+  testJson("1e-325", 0.0);
+  testJson("-1e-325", -0.0);
+  // No overflow on exponent.
+  testJson("1e18446744073709551616", double.infinity);
+  testJson("-1e18446744073709551616", double.negativeInfinity);
+  testJson("1e-18446744073709551616", 0.0);
+  testJson("-1e-18446744073709551616", -0.0);
+
+  // (Wrapping numbers in list because the chunked parsing handles top-level
+  // numbers by buffering and then parsing using platform parser).
+  testJson("[9223372036854774784]", [9223372036854774784]);
+  testJson("[-9223372036854775808]", [-9223372036854775808]);
+  testJson("[9223372036854775808]", [9223372036854775808.0]);
+  testJson("[-9223372036854775809]", [-9223372036854775809.0]);
+  testJson("[9223372036854775808.0]", [9223372036854775808.0]);
+  testJson("[9223372036854775810]", [9223372036854775810.0]);
+  testJson("[18446744073709551616.0]", [18446744073709551616.0]);
+  testJson("[1e309]", [double.infinity]);
+  testJson("[-1e309]", [double.negativeInfinity]);
+  testJson("[1e-325]", [0.0]);
+  testJson("[-1e-325]", [-0.0]);
+  // No overflow on exponent.
+  testJson("[1e18446744073709551616]", [double.infinity]);
+  testJson("[-1e18446744073709551616]", [double.negativeInfinity]);
+  testJson("[1e-18446744073709551616]", [0.0]);
+  testJson("[-1e-18446744073709551616]", [-0.0]);
+
   // Negative tests (syntax error).
   // testError thoroughly tests the given parts with a lot of valid
   // values for the other parts.
diff --git a/tests/lib_2/html/css_selector_test.dart b/tests/lib_2/html/css_selector_test.dart
new file mode 100644
index 0000000..5fcbd9e
--- /dev/null
+++ b/tests/lib_2/html/css_selector_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:html';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'utils.dart';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  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(para.outerHtml, '<p class=""><span>Test #1</span></p>');
+
+  para = document.body.querySelector('p') as ParagraphElement;
+  para.classes.addAll(['c']);
+
+  para = document.body.querySelector('p') as ParagraphElement;
+  expect(para.outerHtml, '<p class="c"><span>Test #1</span></p>');
+
+  var allPara = document.body.querySelectorAll('p');
+  allPara.classes.removeAll(['b', 'c']);
+
+  var checkAllPara = document.body.querySelectorAll('p');
+  expect(checkAllPara[0].outerHtml, '<p class=""><span>Test #1</span></p>');
+  expect(checkAllPara[1].outerHtml, '<p class=""><span>Test #2</span></p>');
+}
diff --git a/tests/lib_2/html/http_test.dart b/tests/lib_2/html/http_test.dart
new file mode 100644
index 0000000..905f4d5
--- /dev/null
+++ b/tests/lib_2/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_2/isolate/int32_length_overflow_test.dart b/tests/lib_2/isolate/int32_length_overflow_test.dart
new file mode 100644
index 0000000..3502ce9
--- /dev/null
+++ b/tests/lib_2/isolate/int32_length_overflow_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 "dart:async";
+import "dart:isolate";
+import "dart:typed_data";
+import "package:expect/expect.dart";
+
+const large = 1 << 30;
+
+void child(replyPort) {
+  print("Child start");
+
+  print("Child Uint8List");
+  dynamic x = new Uint8List(large);
+  for (int i = 0; i < 4; i++) {
+    x[i] = i;
+  }
+  for (int i = x.length - 4; i < x.length; i++) {
+    x[i] = x.length - i;
+  }
+  replyPort.send(x);
+  x = null;
+
+  // Too slow.
+  // print("Child Array");
+  // x = new List(large);
+  // for (int i = 0; i < 4; i++) {
+  //   x[i] = i;
+  // }
+  // replyPort.send(x);
+  // x = null;
+
+  print("Child OneByteString");
+  x = null;
+  x = "Z";
+  while (x.length < large) {
+    x = x * 2;
+  }
+  replyPort.send(x);
+  x = null;
+
+  print("Child done");
+}
+
+Future<void> main(List<String> args) async {
+  print("Parent start");
+
+  ReceivePort port = new ReceivePort();
+  Isolate.spawn(child, port.sendPort);
+  StreamIterator<dynamic> incoming = new StreamIterator<dynamic>(port);
+
+  print("Parent Uint8");
+  Expect.isTrue(await incoming.moveNext());
+  dynamic x = incoming.current;
+  Expect.isTrue(x is Uint8List);
+  Expect.equals(large, x.length);
+  for (int i = 0; i < 4; i++) {
+    Expect.equals(i, x[i]);
+  }
+  for (int i = x.length - 4; i < x.length; i++) {
+    Expect.equals(x.length - i, x[i]);
+  }
+  x = null;
+
+  // Too slow.
+  // print("Parent Array");
+  // Expect.isTrue(await incoming.moveNext());
+  // x = incoming.current;
+  // Expect.isTrue(x is List);
+  // Expect.equals(large, x.length);
+  // for (int i = 0; i < 4; i++) {
+  //   Expect.equals(i, x[i]);
+  // }
+  // x = null;
+
+  print("Parent OneByteString");
+  Expect.isTrue(await incoming.moveNext());
+  x = incoming.current;
+  Expect.isTrue(x is String);
+  Expect.equals(large, x.length);
+  for (int i = 0; i < 4; i++) {
+    Expect.equals("Z", x[i]);
+  }
+  for (int i = x.length - 4; i < x.length; i++) {
+    Expect.equals("Z", x[i]);
+  }
+  x = null;
+
+  port.close();
+  print("Parent done");
+}
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index dc0745a..3a5dc80 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -16,6 +16,42 @@
 [ $runtime == chrome ]
 html/element_animate_test/timing_dict: RuntimeError # Issue 26730
 
+[ $runtime == dart_precompiled ]
+isolate/count_test: Skip # Isolate.spawnUri
+isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
+isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
+isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
+isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
+isolate/illegal_msg_function_test: Skip # Isolate.spawnUri
+isolate/illegal_msg_mirror_test: Skip # Isolate.spawnUri
+isolate/isolate_complex_messages_test: Skip # Isolate.spawnUri
+isolate/issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
+isolate/issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
+isolate/issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
+isolate/issue_6610_test: Skip # Isolate.spawnUri
+isolate/mandel_isolate_test: Skip # Isolate.spawnUri
+isolate/message2_test: Skip # Isolate.spawnUri
+isolate/message_test: Skip # Isolate.spawnUri
+isolate/mint_maker_test: Skip # Isolate.spawnUri
+isolate/nested_spawn2_test: Skip # Isolate.spawnUri
+isolate/nested_spawn_test: Skip # Isolate.spawnUri
+isolate/raw_port_test: Skip # Isolate.spawnUri
+isolate/request_reply_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
+isolate/spawn_uri_missing_from_isolate_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_missing_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_multi_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_test: Skip # Isolate.spawnUri
+isolate/spawn_uri_vm_test: Skip # Isolate.spawnUri
+isolate/stacktrace_message_test: Skip # Isolate.spawnUri
+isolate/static_function_test: Skip # Isolate.spawnUri
+isolate/unresolved_ports_test: Skip # Isolate.spawnUri
+
 [ $runtime == ff ]
 convert/streamed_conversion_utf8_decode_test: Pass, Slow # Issue 12029
 mirrors/mirrors_reader_test: Timeout, Slow, RuntimeError # Issue 16589
@@ -183,6 +219,9 @@
 [ $arch == simarm || $arch == simarmv5te || $arch == simarmv6 ]
 convert/utf85_test: Skip # Pass, Slow Issue 12644.
 
+[ $arch != x64 || $compiler == dartkb || $runtime != vm ]
+isolate/int32_length_overflow_test: SkipSlow
+
 [ $compiler == app_jit || $mode == product || $runtime != vm ]
 isolate/checked_test: Skip # Unsupported.
 
@@ -200,43 +239,7 @@
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
 async/stream_timeout_test: SkipSlow # Times out. Issue 22050
 
-[ $runtime == dart_precompiled || $runtime == flutter ]
-isolate/count_test: Skip # Isolate.spawnUri
-isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
-isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
-isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
-isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
-isolate/illegal_msg_function_test: Skip # Isolate.spawnUri
-isolate/illegal_msg_mirror_test: Skip # Isolate.spawnUri
-isolate/isolate_complex_messages_test: Skip # Isolate.spawnUri
-isolate/issue_21398_parent_isolate1_test: Skip # Isolate.spawnUri
-isolate/issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
-isolate/issue_24243_parent_isolate_test: Skip # Isolate.spawnUri
-isolate/issue_6610_test: Skip # Isolate.spawnUri
-isolate/mandel_isolate_test: Skip # Isolate.spawnUri
-isolate/message2_test: Skip # Isolate.spawnUri
-isolate/message_test: Skip # Isolate.spawnUri
-isolate/mint_maker_test: Skip # Isolate.spawnUri
-isolate/nested_spawn2_test: Skip # Isolate.spawnUri
-isolate/nested_spawn_test: Skip # Isolate.spawnUri
-isolate/raw_port_test: Skip # Isolate.spawnUri
-isolate/request_reply_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
-isolate/spawn_uri_missing_from_isolate_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_missing_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_multi_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_nested_vm_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_test: Skip # Isolate.spawnUri
-isolate/spawn_uri_vm_test: Skip # Isolate.spawnUri
-isolate/stacktrace_message_test: Skip # Isolate.spawnUri
-isolate/static_function_test: Skip # Isolate.spawnUri
-isolate/unresolved_ports_test: Skip # Isolate.spawnUri
-
-[ $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
+[ $runtime == dart_precompiled || $runtime == vm ]
 isolate/browser/*: SkipByDesign # Browser specific tests
 isolate/isolate_stress_test: Skip # Issue 12588: Uses dart:html. This should be able to pass when we have wrapper-less tests.
 isolate/stacktrace_message_test: RuntimeError # Fails to send stacktrace object.
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 449d91a..705ddba 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -3,67 +3,27 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-async/future_or_strong_test: RuntimeError
-convert/base64_test/01: Fail, OK # Uses bit-wise operations to detect invalid values. Some large invalid values accepted by dart2js.
-convert/chunked_conversion_utf88_test: Slow, Pass
-convert/utf85_test: Slow, Pass
+convert/chunked_conversion_utf88_test: Slow
+convert/utf85_test: Slow
 developer/timeline_test: Skip # Not supported
 html/async_spawnuri_test: SkipByDesign
 html/async_test: SkipByDesign
-html/custom/document_register_type_extensions_test/construction: Pass, Timeout # Roll 50 failure
-html/custom/document_register_type_extensions_test/registration: Pass, Timeout # Roll 50 failure
-html/custom/entered_left_view_test/shadow_dom: Pass, Timeout # Roll 50 failure
-html/custom/mirrors_2_test: RuntimeError
-html/custom/mirrors_test: RuntimeError
-html/custom_elements_test: Pass, Timeout # Issue 26789
-html/debugger_test: CompileTimeError # Issue 30900
-html/indexeddb_1_test/functional: Pass, Timeout # Roll 50 failure
-html/indexeddb_1_test/functional: RuntimeError
-html/indexeddb_2_test: Pass, Timeout # Roll 50 failure
-html/indexeddb_3_test: Pass, Timeout # Roll 50 failure
-html/indexeddb_3_test: RuntimeError
-html/indexeddb_4_test: Pass, Timeout # Roll 50 failure
-html/indexeddb_5_test: Pass, Timeout # Roll 50 failure
-html/indexeddb_5_test: RuntimeError
+html/custom/document_register_basic_test: Slow
+html/custom/document_register_type_extensions_test/construction: Slow
+html/custom/document_register_type_extensions_test/registration: Slow
+html/custom/entered_left_view_test/shadow_dom: Slow
+html/custom/js_custom_test: Skip # mirrors not supported, delete this test.
+html/custom/mirrors_2_test: Skip # mirrors not supported, delete this test.
+html/custom/mirrors_test: Skip # mirrors not supported, delete this test.
+html/custom_elements_test: Slow # Issue 26789
 html/isolates_test: SkipByDesign
-html/js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue #25759
-html/js_typed_interop_default_arg_test/explicit_argument: RuntimeError
-html/js_typed_interop_side_cast_exp_test: Pass, RuntimeError # Roll 50 failure
-html/js_typed_interop_test: RuntimeError
-html/mirrors_js_typed_interop_test/01: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-html/mirrors_js_typed_interop_test/none: Pass, Slow
-html/svgelement_test/PathElement: Pass, RuntimeError # Roll 50 failure
+html/mirrors_js_typed_interop_test: Skip # mirrors not supported, delete this test.
 html/worker_api_test: SkipByDesign
 html/wrapping_collections_test: SkipByDesign # Testing an issue that is only relevant to Dartium
-html/xhr_test: Pass, Slow
+html/xhr_test: Slow
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
-math/double_pow_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-math/double_pow_test: RuntimeError
-math/low_test: RuntimeError
-math/random_big_test: RuntimeError # Using bigint seeds for random.
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-mirrors/private_types_test: RuntimeError # Issue 6490
-mirrors/raw_type_test/01: RuntimeError # Issue 6490
-mirrors/redirecting_factory_test/02: RuntimeError # Issue 6490
-mirrors/redirecting_factory_test/none: RuntimeError # Issue 6490
-mirrors/reflected_type_function_type_test: RuntimeError # Issue 12607
-mirrors/reflected_type_generics_test/01: Fail # Issues in reflecting generic typedefs.
-mirrors/reflected_type_generics_test/02: Fail # Issues in reflecting bounded type variables.
-mirrors/reflected_type_generics_test/03: Fail # Issues in reflecting generic typedefs.
-mirrors/reflected_type_generics_test/04: Fail # Issues in reflecting bounded type variables.
-mirrors/reflected_type_generics_test/05: Fail # Issues in reflecting generic typedefs.
-mirrors/reflected_type_generics_test/06: Fail # Issues in reflecting bounded type variables.
-mirrors/reflected_type_special_types_test: RuntimeError # Issue 12607
-mirrors/reflected_type_typedefs_test: RuntimeError # Issue 12607
-mirrors/reflected_type_typevars_test: RuntimeError # Issue 12607
 profiler/metrics_num_test: Skip # Because of an int / double type test.
-typed_data/int32x4_arithmetic_test/int64: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-typed_data/int32x4_arithmetic_test/int64: RuntimeError # Issue 1533
-typed_data/int32x4_arithmetic_test/none: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-typed_data/int64_list_load_store_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
-typed_data/int64_list_load_store_test: RuntimeError # Issue 10275
-typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
-typed_data/unmodifiable_typed_data_test: RuntimeError # Issue 10275
 
 [ $compiler != dart2js ]
 async/dart2js_uncaught_error_test: Skip # JS-integration only test
@@ -695,16 +655,6 @@
 html/window_mangling_test: RuntimeError
 html/window_nosuchmethod_test: RuntimeError
 
-[ $compiler == dart2js && $fast_startup ]
-html/custom/document_register_basic_test: Pass, Slow, RuntimeError # Slow and sometimes times out
-html/custom/js_custom_test: Fail # mirrors not supported
-html/custom/mirrors_2_test: Fail # mirrors not supported
-html/custom/mirrors_test: Fail # mirrors not supported
-html/mirrors_js_typed_interop_test: Fail # mirrors not supported
-html/notification_permission_test: RuntimeError
-html/xhr_test: RuntimeError
-mirrors/regress_16321_test/01: Pass # expects failure, but if fails for the wrong reason
-
 [ $compiler == dart2js && $host_checked ]
 html/custom/mirrors_2_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
 html/custom/mirrors_test: Crash # 'file:*/pkg/compiler/lib/src/common_elements.dart': Failed assertion: line 405 pos 12: 'element.name == '=='': is not true.
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index 55192e7..0532e64 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -43,6 +43,7 @@
 convert/utf85_test: Slow, Pass
 html/async_spawnuri_test: RuntimeError # Issue 29922
 html/async_test: RuntimeError # Issue 29922
+html/callback_list_test: Skip # Test requires user interaction to accept permissions.
 html/custom/attribute_changed_callback_test: Skip # Issue 31577
 html/custom/constructor_calls_created_synchronously_test: Skip # Issue 31577
 html/custom/created_callback_test: RuntimeError
diff --git a/tests/lib_2/lib_2_flutter.status b/tests/lib_2/lib_2_flutter.status
deleted file mode 100644
index 153a1b8..0000000
--- a/tests/lib_2/lib_2_flutter.status
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[ $runtime == flutter ]
-async/catch_errors11_test: Skip # Flutter Issue 9113
-async/intercept_schedule_microtask2_test: Skip # Flutter Issue 9113
-async/intercept_schedule_microtask5_test: Skip # Flutter Issue 9113
-async/intercept_schedule_microtask6_test: Skip # Flutter Issue 9113
-async/run_zoned6_test/01: Skip # Flutter Issue 9113
-async/run_zoned9_test/01: Skip # Flutter Issue 9113
-async/schedule_microtask_test: Skip # Flutter Issue 9113
-async/stream_empty_test: Skip # Flutter Issue 9113
-async/stream_event_transformed_test: Skip # Flutter Issue 9113
-html/*: Skip # dart:html will be a problem in the VM
-isolate/isolate_import_test/01: Skip # Flutter Issue 9114
-isolate/issue_21398_parent_isolate2_test/01: Skip # Flutter Issue 9114
-isolate/simple_message_test/01: Skip # Flutter Issue 9114
-math/random_secure_test: RuntimeError # Flutter Issue 9113
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index ca19533..01b0058 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -54,6 +54,9 @@
 [ $arch == x64 && $mode == debug && $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
 mirrors/invocation_fuzz_test: Skip # Because it times out, issue 29439.
 
+[ $arch == x64 && ($hot_reload || $hot_reload_rollback) ]
+isolate/int32_length_overflow_test: Timeout  # Issue 35733
+
 [ $builder_tag == obfuscated && $compiler == dartkp ]
 collection/list_test: RuntimeError # Issue 34911
 
diff --git a/tests/lib_2/lib_2_precompiled.status b/tests/lib_2/lib_2_precompiled.status
index 1083bc9..86461fe 100644
--- a/tests/lib_2/lib_2_precompiled.status
+++ b/tests/lib_2/lib_2_precompiled.status
@@ -17,7 +17,7 @@
 isolate/ping_test: Skip # Resolve test issues
 mirrors/symbol_validation_test: RuntimeError # Issue 13596
 
-[ $compiler == precompiler || $runtime == flutter ]
+[ $compiler == precompiler ]
 isolate/count_test: SkipByDesign
 isolate/cross_isolate_message_test: SkipByDesign
 isolate/illegal_msg_function_test: SkipByDesign
diff --git a/tests/lib_2/math/coin_test.dart b/tests/lib_2/math/coin_test.dart
index 47eb281..f930426 100644
--- a/tests/lib_2/math/coin_test.dart
+++ b/tests/lib_2/math/coin_test.dart
@@ -4,9 +4,6 @@
 
 // Test that a coin toss with Random.nextBool() is fair.
 
-// Library tag to allow Dartium to run the test.
-library coin_test;
-
 import "package:expect/expect.dart";
 import 'dart:math';
 
diff --git a/tests/lib_2/math/low_test.dart b/tests/lib_2/math/low_test.dart
index 80022c7..6014ef5 100644
--- a/tests/lib_2/math/low_test.dart
+++ b/tests/lib_2/math/low_test.dart
@@ -5,9 +5,6 @@
 // Test that the default PRNG does uniformly distribute values when not using
 // a power of 2.
 
-// Library tag to allow Dartium to run the test.
-library low_test;
-
 import "package:expect/expect.dart";
 import 'dart:math';
 
diff --git a/tests/lib_2/math/pi_test.dart b/tests/lib_2/math/pi_test.dart
index ea31ade..b867132 100644
--- a/tests/lib_2/math/pi_test.dart
+++ b/tests/lib_2/math/pi_test.dart
@@ -5,9 +5,6 @@
 // Test that the default PRNG does converge towards Pi when doing a Monte Carlo
 // simulation.
 
-// Library tag to allow Dartium to run the test.
-library pi_test;
-
 import "package:expect/expect.dart";
 import 'dart:math';
 
diff --git a/tests/lib_2/math/random_big_test.dart b/tests/lib_2/math/random_big_test.dart
index 649971d9..41a5651 100644
--- a/tests/lib_2/math/random_big_test.dart
+++ b/tests/lib_2/math/random_big_test.dart
@@ -4,9 +4,6 @@
 
 // Test that Random can deal with a seed outside 64-bit range.
 
-// Library tag to allow Dartium to run the test.
-library random_big;
-
 import "package:expect/expect.dart";
 import 'dart:math';
 
diff --git a/tests/lib_2/math/random_secure_test.dart b/tests/lib_2/math/random_secure_test.dart
index ef49367..a28a215 100644
--- a/tests/lib_2/math/random_secure_test.dart
+++ b/tests/lib_2/math/random_secure_test.dart
@@ -6,9 +6,6 @@
 // duplicates. Note that this test is flaky by definition, since duplicates
 // can occur. They should be extremely rare, though.
 
-// Library tag to allow Dartium to run the test.
-library random_secure;
-
 import "package:expect/expect.dart";
 import 'dart:math';
 
diff --git a/tests/standalone_2/ffi/coordinate.dart b/tests/standalone_2/ffi/coordinate.dart
new file mode 100644
index 0000000..fbca952
--- /dev/null
+++ b/tests/standalone_2/ffi/coordinate.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.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+/// Sample struct for dart:ffi library.
+@ffi.struct
+class Coordinate extends ffi.Pointer<ffi.Void> {
+  @ffi.Double()
+  double x;
+
+  @ffi.Double()
+  double y;
+
+  @ffi.Pointer()
+  Coordinate next;
+
+  /// generated by @ffi.struct annotation
+  external static int sizeOf();
+
+  Coordinate offsetBy(int offsetInBytes) =>
+      super.offsetBy(offsetInBytes).cast();
+
+  Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
+
+  static Coordinate allocate({int count: 1}) =>
+      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
+
+  /// Allocate a new [Coordinate] in C memory and populate its fields.
+  factory Coordinate(double x, double y, Coordinate next) {
+    Coordinate result = Coordinate.allocate()
+      ..x = x
+      ..y = y
+      ..next = next;
+    return result;
+  }
+}
diff --git a/tests/standalone_2/ffi/coordinate_bare.dart b/tests/standalone_2/ffi/coordinate_bare.dart
new file mode 100644
index 0000000..764cb9f
--- /dev/null
+++ b/tests/standalone_2/ffi/coordinate_bare.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.
+
+library FfiTestCoordinateBare;
+
+import 'dart:ffi' as ffi;
+
+/// Stripped down sample struct for dart:ffi library.
+@ffi.struct
+class Coordinate extends ffi.Pointer<ffi.Void> {
+  @ffi.Double()
+  double x;
+
+  @ffi.Double()
+  double y;
+
+  @ffi.Pointer()
+  Coordinate next;
+}
diff --git a/tests/standalone_2/ffi/coordinate_manual.dart b/tests/standalone_2/ffi/coordinate_manual.dart
new file mode 100644
index 0000000..d4d1aca
--- /dev/null
+++ b/tests/standalone_2/ffi/coordinate_manual.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.
+
+library FfiTestCoordinateManual;
+
+import 'dart:ffi' as ffi;
+
+/// Sample struct for dart:ffi library without use of ffi annotations.
+class Coordinate extends ffi.Pointer<ffi.Void> {
+  ffi.Pointer<ffi.Double> get _xPtr => cast();
+  set x(double v) => _xPtr.store(v);
+  double get x => _xPtr.load();
+
+  ffi.Pointer<ffi.Double> get _yPtr =>
+      offsetBy(ffi.sizeOf<ffi.Double>() * 1).cast();
+  set y(double v) => _yPtr.store(v);
+  double get y => _yPtr.load();
+
+  ffi.Pointer<Coordinate> get _nextPtr =>
+      offsetBy(ffi.sizeOf<ffi.Double>() * 2).cast();
+  set next(Coordinate v) => _nextPtr.store(v);
+  Coordinate get next => _nextPtr.load();
+
+  static int sizeOf() =>
+      ffi.sizeOf<ffi.Double>() * 2 + ffi.sizeOf<ffi.IntPtr>();
+
+  Coordinate offsetBy(int offsetInBytes) =>
+      super.offsetBy(offsetInBytes).cast();
+
+  Coordinate elementAt(int index) => offsetBy(sizeOf() * index);
+
+  static Coordinate allocate({int count: 1}) =>
+      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
+
+  /// Allocate a new [Coordinate] in C memory and populate its fields.
+  factory Coordinate(double x, double y, Coordinate next) {
+    Coordinate result = Coordinate.allocate()
+      ..x = x
+      ..y = y
+      ..next = next;
+    return result;
+  }
+}
diff --git a/tests/standalone_2/ffi/cstring.dart b/tests/standalone_2/ffi/cstring.dart
new file mode 100644
index 0000000..b976007
--- /dev/null
+++ b/tests/standalone_2/ffi/cstring.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.
+
+library FfiTest;
+
+import 'dart:convert';
+import 'dart:ffi' as ffi;
+
+/// Sample non-struct subtype of Pointer for dart:ffi library.
+class CString extends ffi.Pointer<ffi.Uint8> {
+  CString elementAt(int index) => super.elementAt(index).cast();
+
+  String fromUtf8() {
+    List<int> units = [];
+    int len = 0;
+    while (true) {
+      int char = elementAt(len++).load<int>();
+      if (char == 0) break;
+      units.add(char);
+    }
+    return Utf8Decoder().convert(units);
+  }
+
+  factory CString.toUtf8(String s) {
+    CString result = ffi.allocate<ffi.Uint8>(count: s.length + 1).cast();
+    List<int> units = Utf8Encoder().convert(s);
+    for (int i = 0; i < s.length; i++) result.elementAt(i).store(units[i]);
+    result.elementAt(s.length).store(0);
+    return result;
+  }
+}
diff --git a/tests/standalone_2/ffi/data_not_asan_test.dart b/tests/standalone_2/ffi/data_not_asan_test.dart
new file mode 100644
index 0000000..2be8598
--- /dev/null
+++ b/tests/standalone_2/ffi/data_not_asan_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.
+//
+// Dart test program for testing dart:ffi primitive data pointers.
+// This test tries to allocate too much memory on purpose to test the Exception
+// thrown on malloc failing.
+// This malloc also triggers an asan alarm, so this test is in a separate file
+// which is excluded in asan mode.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+void main() {
+  testPointerAllocateTooLarge();
+}
+
+/// This test is skipped in asan mode.
+void testPointerAllocateTooLarge() {
+  int maxInt = 9223372036854775807; // 2^63 - 1
+  Expect.throws(
+      () => ffi.allocate<ffi.Int64>(count: maxInt)); // does not fit in range
+  int maxInt1_8 = 1152921504606846975; // 2^60 -1
+  Expect.throws(
+      () => ffi.allocate<ffi.Int64>(count: maxInt1_8)); // not enough memory
+}
diff --git a/tests/standalone_2/ffi/data_test.dart b/tests/standalone_2/ffi/data_test.dart
new file mode 100644
index 0000000..26edd6f
--- /dev/null
+++ b/tests/standalone_2/ffi/data_test.dart
@@ -0,0 +1,492 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 dart:ffi primitive data pointers.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+void main() {
+  testPointerBasic();
+  testPointerFromPointer();
+  testPointerPointerArithmetic();
+  testPointerPointerArithmeticSizes();
+  testPointerAllocateNonPositive();
+  testPointerCast();
+  testCastGeneric();
+  testCastGeneric2();
+  testCastNativeType();
+  testCondensedNumbersInt8();
+  testCondensedNumbersFloat();
+  testRangeInt8();
+  testRangeUint8();
+  testRangeInt16();
+  testRangeUint16();
+  testRangeInt32();
+  testRangeUint32();
+  testRangeInt64();
+  testRangeUint64();
+  testRangeIntPtr();
+  testFloat();
+  testDouble();
+  testVoid();
+  testPointerPointer();
+  testPointerPointerNull();
+  testPointerStoreNull();
+  testSizeOf();
+  testPointerChain(100);
+  testTypeTest();
+  testToString();
+  testEquality();
+  testAllocateGeneric();
+  testAllocateVoid();
+  testAllocateNativeFunction();
+  testAllocateNativeType();
+  testSizeOfGeneric();
+  testSizeOfVoid();
+  testSizeOfNativeFunction();
+  testSizeOfNativeType();
+  testFreeZeroOut();
+}
+
+void testPointerBasic() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  p.store(42);
+  Expect.equals(42, p.load<int>());
+  p.free();
+}
+
+void testPointerFromPointer() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  p.store(1337);
+  int ptr = p.address;
+  ffi.Pointer<ffi.Int64> p2 = ffi.fromAddress(ptr);
+  Expect.equals(1337, p2.load<int>());
+  p.free();
+}
+
+void testPointerPointerArithmetic() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate(count: 2);
+  ffi.Pointer<ffi.Int64> p2 = p.elementAt(1);
+  p2.store(100);
+  ffi.Pointer<ffi.Int64> p3 = p.offsetBy(8);
+  Expect.equals(100, p3.load<int>());
+  p.free();
+}
+
+void testPointerPointerArithmeticSizes() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate(count: 2);
+  ffi.Pointer<ffi.Int64> p2 = p.elementAt(1);
+  int addr = p.address;
+  Expect.equals(addr + 8, p2.address);
+  p.free();
+
+  ffi.Pointer<ffi.Int32> p3 = ffi.allocate(count: 2);
+  ffi.Pointer<ffi.Int32> p4 = p3.elementAt(1);
+  addr = p3.address;
+  Expect.equals(addr + 4, p4.address);
+  p3.free();
+}
+
+void testPointerAllocateNonPositive() {
+  Expect.throws(() => ffi.allocate<ffi.Int8>(count: 0));
+  Expect.throws(() => ffi.allocate<ffi.Int8>(count: -1));
+}
+
+void testPointerCast() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  ffi.Pointer<ffi.Int32> p2 = p.cast(); // gets the correct type args back
+  p.free();
+}
+
+void testCastGeneric() {
+  ffi.Pointer<T> generic<T extends ffi.NativeType>(ffi.Pointer<ffi.Int16> p) {
+    return p.cast();
+  }
+
+  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  ffi.Pointer<ffi.Int64> p2 = generic(p);
+  p.free();
+}
+
+void testCastGeneric2() {
+  ffi.Pointer<ffi.Int64> generic<T extends ffi.NativeType>(ffi.Pointer<T> p) {
+    return p.cast();
+  }
+
+  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  ffi.Pointer<ffi.Int64> p2 = generic(p);
+  p.free();
+}
+
+void testCastNativeType() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  Expect.throws(() {
+    p.cast<ffi.Pointer>();
+  });
+  p.free();
+}
+
+void testCondensedNumbersInt8() {
+  ffi.Pointer<ffi.Int8> p = ffi.allocate(count: 8);
+  for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+    p.elementAt(i).store(i * 3);
+  }
+  for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+    Expect.equals(i * 3, p.elementAt(i).load<int>());
+  }
+  p.free();
+}
+
+void testCondensedNumbersFloat() {
+  ffi.Pointer<ffi.Float> p = ffi.allocate(count: 8);
+  for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+    p.elementAt(i).store(1.511366173271439e-13);
+  }
+  for (var i in [0, 1, 2, 3, 4, 5, 6, 7]) {
+    Expect.equals(1.511366173271439e-13, p.elementAt(i).load<double>());
+  }
+  p.free();
+}
+
+void testRangeInt8() {
+  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  p.store(127);
+  Expect.equals(127, p.load<int>());
+  p.store(-128);
+  Expect.equals(-128, p.load<int>());
+
+  Expect.equals(0x0000000000000080, 128);
+  Expect.equals(0xFFFFFFFFFFFFFF80, -128);
+  p.store(128);
+  Expect.equals(-128, p.load<int>()); // truncated and sign extended
+
+  Expect.equals(0xFFFFFFFFFFFFFF7F, -129);
+  Expect.equals(0x000000000000007F, 127);
+  p.store(-129);
+  Expect.equals(127, p.load<int>()); // truncated
+  p.free();
+}
+
+void testRangeUint8() {
+  ffi.Pointer<ffi.Uint8> p = ffi.allocate();
+  p.store(255);
+  Expect.equals(255, p.load<int>());
+  p.store(0);
+  Expect.equals(0, p.load<int>());
+
+  Expect.equals(0x0000000000000000, 0);
+  Expect.equals(0x0000000000000100, 256);
+  p.store(256);
+  Expect.equals(0, p.load<int>()); // truncated
+
+  Expect.equals(0xFFFFFFFFFFFFFFFF, -1);
+  Expect.equals(0x00000000000000FF, 255);
+  p.store(-1);
+  Expect.equals(255, p.load<int>()); // truncated
+  p.free();
+}
+
+void testRangeInt16() {
+  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  p.store(0x7FFF);
+  Expect.equals(0x7FFF, p.load<int>());
+  p.store(-0x8000);
+  Expect.equals(-0x8000, p.load<int>());
+  p.store(0x8000);
+  Expect.equals(
+      0xFFFFFFFFFFFF8000, p.load<int>()); // truncated and sign extended
+  p.store(-0x8001);
+  Expect.equals(0x7FFF, p.load<int>()); // truncated
+  p.free();
+}
+
+void testRangeUint16() {
+  ffi.Pointer<ffi.Uint16> p = ffi.allocate();
+  p.store(0xFFFF);
+  Expect.equals(0xFFFF, p.load<int>());
+  p.store(0);
+  Expect.equals(0, p.load<int>());
+  p.store(0x10000);
+  Expect.equals(0, p.load<int>()); // truncated
+  p.store(-1);
+  Expect.equals(0xFFFF, p.load<int>()); // truncated
+  p.free();
+}
+
+void testRangeInt32() {
+  ffi.Pointer<ffi.Int32> p = ffi.allocate();
+  p.store(0x7FFFFFFF);
+  Expect.equals(0x7FFFFFFF, p.load<int>());
+  p.store(-0x80000000);
+  Expect.equals(-0x80000000, p.load<int>());
+  p.store(0x80000000);
+  Expect.equals(
+      0xFFFFFFFF80000000, p.load<int>()); // truncated and sign extended
+  p.store(-0x80000001);
+  Expect.equals(0x7FFFFFFF, p.load<int>()); // truncated
+  p.free();
+}
+
+void testRangeUint32() {
+  ffi.Pointer<ffi.Uint32> p = ffi.allocate();
+  p.store(0xFFFFFFFF);
+  Expect.equals(0xFFFFFFFF, p.load<int>());
+  p.store(0);
+  Expect.equals(0, p.load<int>());
+  p.store(0x100000000);
+  Expect.equals(0, p.load<int>()); // truncated
+  p.store(-1);
+  Expect.equals(0xFFFFFFFF, p.load<int>()); // truncated
+  p.free();
+}
+
+void testRangeInt64() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  p.store(0x7FFFFFFFFFFFFFFF); // 2 ^ 63 - 1
+  Expect.equals(0x7FFFFFFFFFFFFFFF, p.load<int>());
+  p.store(-0x8000000000000000); // -2 ^ 63
+  Expect.equals(-0x8000000000000000, p.load<int>());
+  p.free();
+}
+
+void testRangeUint64() {
+  ffi.Pointer<ffi.Uint64> p = ffi.allocate();
+  p.store(0x7FFFFFFFFFFFFFFF); // 2 ^ 63 - 1
+  Expect.equals(0x7FFFFFFFFFFFFFFF, p.load<int>());
+  p.store(-0x8000000000000000); // -2 ^ 63 interpreted as 2 ^ 63
+  Expect.equals(-0x8000000000000000, p.load<int>());
+
+  // Dart allows interpreting bits both signed and unsigned
+  Expect.equals(0xFFFFFFFFFFFFFFFF, -1);
+  p.store(-1); // -1 interpreted as 2 ^ 64 - 1
+  Expect.equals(-1, p.load<int>());
+  Expect.equals(0xFFFFFFFFFFFFFFFF, p.load<int>());
+  p.free();
+}
+
+void testRangeIntPtr() {
+  ffi.Pointer<ffi.IntPtr> p = ffi.allocate();
+  int pAddr = p.address;
+  p.store(pAddr); // its own address should fit
+  p.store(0x7FFFFFFF); // and 32 bit addresses should fit
+  Expect.equals(0x7FFFFFFF, p.load<int>());
+  p.store(-0x80000000);
+  Expect.equals(-0x80000000, p.load<int>());
+  p.free();
+}
+
+void testFloat() {
+  ffi.Pointer<ffi.Float> p = ffi.allocate();
+  p.store(1.511366173271439e-13);
+  Expect.equals(1.511366173271439e-13, p.load<double>());
+  p.store(1.4260258159703532e-105); // float does not have enough precision
+  Expect.notEquals(1.4260258159703532e-105, p.load<double>());
+  p.free();
+}
+
+void testDouble() {
+  ffi.Pointer<ffi.Double> p = ffi.allocate();
+  p.store(1.4260258159703532e-105);
+  Expect.equals(1.4260258159703532e-105, p.load<double>());
+  p.free();
+}
+
+void testVoid() {
+  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.Void> p2 = p1.cast(); // make this dart pointer opaque
+  p2.address; // we can print the address
+  p2.free();
+}
+
+void testPointerPointer() {
+  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  p.store(17);
+  ffi.Pointer<ffi.Pointer<ffi.Int16>> p2 = ffi.allocate();
+  p2.store(p);
+  Expect.equals(17, p2.load<ffi.Pointer<ffi.Int16>>().load<int>());
+  p2.free();
+  p.free();
+}
+
+void testPointerPointerNull() {
+  ffi.Pointer<ffi.Pointer<ffi.Int8>> pointerToPointer = ffi.allocate();
+  ffi.Pointer<ffi.Int8> value = null;
+  pointerToPointer.store(value);
+  value = pointerToPointer.load();
+  Expect.isNull(value);
+  value = ffi.allocate();
+  pointerToPointer.store(value);
+  value = pointerToPointer.load();
+  Expect.isNotNull(value);
+  value.free();
+  value = null;
+  pointerToPointer.store(value);
+  value = pointerToPointer.load();
+  Expect.isNull(value);
+  pointerToPointer.free();
+}
+
+void testPointerStoreNull() {
+  int i = null;
+  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  Expect.throws(() => p.store(i));
+  p.free();
+  double d = null;
+  ffi.Pointer<ffi.Float> p2 = ffi.allocate();
+  Expect.throws(() => p2.store(d));
+  p2.free();
+}
+
+void testSizeOf() {
+  Expect.equals(1, ffi.sizeOf<ffi.Int8>());
+  Expect.equals(2, ffi.sizeOf<ffi.Int16>());
+  Expect.equals(4, ffi.sizeOf<ffi.Int32>());
+  Expect.equals(8, ffi.sizeOf<ffi.Int64>());
+  Expect.equals(1, ffi.sizeOf<ffi.Uint8>());
+  Expect.equals(2, ffi.sizeOf<ffi.Uint16>());
+  Expect.equals(4, ffi.sizeOf<ffi.Uint32>());
+  Expect.equals(8, ffi.sizeOf<ffi.Uint64>());
+  Expect.equals(
+      true, 4 == ffi.sizeOf<ffi.IntPtr>() || 8 == ffi.sizeOf<ffi.IntPtr>());
+  Expect.equals(4, ffi.sizeOf<ffi.Float>());
+  Expect.equals(8, ffi.sizeOf<ffi.Double>());
+}
+
+// note: stack overflows at around 15k calls
+void testPointerChain(int length) {
+  void createChain(ffi.Pointer<ffi.IntPtr> head, int length, int value) {
+    if (length == 0) {
+      head.store(value);
+      return;
+    }
+    ffi.Pointer<ffi.IntPtr> next = ffi.allocate();
+    head.store(next.address);
+    createChain(next, length - 1, value);
+  }
+
+  int getChainValue(ffi.Pointer<ffi.IntPtr> head, int length) {
+    if (length == 0) {
+      return head.load();
+    }
+    ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+    return getChainValue(next, length - 1);
+  }
+
+  void freeChain(ffi.Pointer<ffi.IntPtr> head, int length) {
+    ffi.Pointer<ffi.IntPtr> next = ffi.fromAddress(head.load());
+    head.free();
+    if (length == 0) {
+      return;
+    }
+    freeChain(next, length - 1);
+  }
+
+  ffi.Pointer<ffi.IntPtr> head = ffi.allocate();
+  createChain(head, length, 512);
+  int tailValue = getChainValue(head, length);
+  Expect.equals(512, tailValue);
+  freeChain(head, length);
+}
+
+void testTypeTest() {
+  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  Expect.isTrue(p is ffi.Pointer);
+  p.free();
+}
+
+void testToString() {
+  ffi.Pointer<ffi.Int16> p = ffi.allocate();
+  Expect.stringEquals(
+      "Pointer<Int16>: address=0x", p.toString().substring(0, 26));
+  p.free();
+}
+
+void testEquality() {
+  ffi.Pointer<ffi.Int8> p = ffi.fromAddress(12345678);
+  ffi.Pointer<ffi.Int8> p2 = ffi.fromAddress(12345678);
+  Expect.equals(p, p2);
+  Expect.equals(p.hashCode, p2.hashCode);
+  ffi.Pointer<ffi.Int16> p3 = p.cast();
+  Expect.equals(p, p3);
+  Expect.equals(p.hashCode, p3.hashCode);
+  Expect.notEquals(p, null);
+  Expect.notEquals(null, p);
+  ffi.Pointer<ffi.Int8> p4 = p.offsetBy(1337);
+  Expect.notEquals(p, p4);
+}
+
+typedef Int8UnOp = ffi.Int8 Function(ffi.Int8);
+
+void testAllocateGeneric() {
+  ffi.Pointer<T> generic<T extends ffi.NativeType>() {
+    ffi.Pointer<T> pointer;
+    pointer = ffi.allocate();
+    return pointer;
+  }
+
+  ffi.Pointer p = generic<ffi.Int64>();
+  p.free();
+}
+
+void testAllocateVoid() {
+  Expect.throws(() {
+    ffi.Pointer<ffi.Void> p = ffi.allocate();
+  });
+}
+
+void testAllocateNativeFunction() {
+  Expect.throws(() {
+    ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.allocate();
+  });
+}
+
+void testAllocateNativeType() {
+  Expect.throws(() {
+    ffi.allocate();
+  });
+}
+
+void testSizeOfGeneric() {
+  int generic<T extends ffi.Pointer>() {
+    int size;
+    size = ffi.sizeOf<T>();
+    return size;
+  }
+
+  int size = generic<ffi.Pointer<ffi.Int64>>();
+  Expect.equals(8, size);
+}
+
+void testSizeOfVoid() {
+  Expect.throws(() {
+    ffi.sizeOf<ffi.Void>();
+  });
+}
+
+void testSizeOfNativeFunction() {
+  Expect.throws(() {
+    ffi.sizeOf<ffi.NativeFunction<Int8UnOp>>();
+  });
+}
+
+void testSizeOfNativeType() {
+  Expect.throws(() {
+    ffi.sizeOf();
+  });
+}
+
+void testFreeZeroOut() {
+  // at least one of these pointers should have address != 0 on all platforms
+  ffi.Pointer<ffi.Int8> p1 = ffi.allocate();
+  ffi.Pointer<ffi.Int8> p2 = ffi.allocate();
+  Expect.notEquals(0, p1.address & p2.address);
+  p1.free();
+  p2.free();
+  Expect.equals(0, p1.address);
+  Expect.equals(0, p2.address);
+}
diff --git a/tests/standalone_2/ffi/dynamic_library_test.dart b/tests/standalone_2/ffi/dynamic_library_test.dart
new file mode 100644
index 0000000..1c3c45d
--- /dev/null
+++ b/tests/standalone_2/ffi/dynamic_library_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.
+//
+// Dart test program for testing dart:ffi dynamic library loading.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import 'package:expect/expect.dart';
+
+void main() {
+  testOpen();
+  testOpenError();
+  testLookup();
+  testLookupError();
+  testToString();
+  testEquality();
+}
+
+void testOpen() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  Expect.notEquals(null, l);
+}
+
+void testOpenError() {
+  Expect.throws(
+      () => ffi.DynamicLibrary.open("doesnotexistforsurelibrary123409876"));
+}
+
+typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
+
+typedef DoubleUnOp = double Function(double);
+
+void testLookup() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  var timesFour = l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>("timesFour");
+  Expect.approxEquals(12.0, timesFour(3));
+}
+
+void testLookupError() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  Expect.throws(() => l.lookupFunction<NativeDoubleUnOp, DoubleUnOp>(
+      "functionnamethatdoesnotexistforsure749237593845"));
+}
+
+void testToString() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  Expect.stringEquals(
+      "DynamicLibrary: handle=0x", l.toString().substring(0, 25));
+}
+
+void testEquality() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  ffi.DynamicLibrary l2 = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  Expect.equals(l, l2);
+  Expect.equals(l.hashCode, l2.hashCode);
+  Expect.notEquals(l, null);
+  Expect.notEquals(null, l);
+  ffi.DynamicLibrary l3 = ffi.DynamicLibrary.open("ffi_test_functions");
+  Expect.notEquals(l, l3);
+}
diff --git a/tests/standalone_2/ffi/enable_ffi_test.dart b/tests/standalone_2/ffi/enable_ffi_test.dart
new file mode 100644
index 0000000..5396312
--- /dev/null
+++ b/tests/standalone_2/ffi/enable_ffi_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.
+//
+// Dart test program for testing the --enable-ffi=false flag.
+//
+// VMOptions=--enable-ffi=false
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+void main() {
+  ffi.Pointer<ffi.Int64> p = ffi.allocate();
+  p.store(42);
+  Expect.equals(42, p.load<int>());
+  p.free();
+}
diff --git a/tests/standalone_2/ffi/function_callbacks_test.dart b/tests/standalone_2/ffi/function_callbacks_test.dart
new file mode 100644
index 0000000..2f3212b
--- /dev/null
+++ b/tests/standalone_2/ffi/function_callbacks_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.
+//
+// Dart test program for testing dart:ffi function pointers with callbacks.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+import 'coordinate.dart';
+
+typedef NativeCoordinateOp = Coordinate Function(Coordinate);
+
+typedef CoordinateTrice = Coordinate Function(
+    ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>>, Coordinate);
+
+void main() {
+  testFunctionWithFunctionPointer();
+  testNativeFunctionWithFunctionPointer();
+  testFromFunction();
+}
+
+ffi.DynamicLibrary ffiTestFunctions =
+    ffi.DynamicLibrary.open("ffi_test_functions");
+
+/// pass a pointer to a c function as an argument to a c function
+void testFunctionWithFunctionPointer() {
+  ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>>
+      transposeCoordinatePointer =
+      ffiTestFunctions.lookup("TransposeCoordinate");
+
+  ffi.Pointer<ffi.NativeFunction<CoordinateTrice>> p2 =
+      ffiTestFunctions.lookup("CoordinateUnOpTrice");
+  CoordinateTrice coordinateUnOpTrice = p2.asFunction();
+
+  Coordinate c1 = Coordinate(10.0, 20.0, null);
+  c1.next = c1;
+
+  Coordinate result = coordinateUnOpTrice(transposeCoordinatePointer, c1);
+
+  print(result.runtimeType);
+  print(result.x);
+  print(result.y);
+
+  c1.free();
+}
+
+typedef BinaryOp = int Function(int, int);
+
+typedef NativeIntptrBinOp = ffi.IntPtr Function(ffi.IntPtr, ffi.IntPtr);
+
+typedef NativeIntptrBinOpLookup
+    = ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>> Function();
+
+void testNativeFunctionWithFunctionPointer() {
+  ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOpLookup>> p1 =
+      ffiTestFunctions.lookup("IntptrAdditionClosure");
+  NativeIntptrBinOpLookup intptrAdditionClosure = p1.asFunction();
+
+  ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>> intptrAdditionPointer =
+      intptrAdditionClosure();
+  BinaryOp intptrAddition = intptrAdditionPointer.asFunction();
+  Expect.equals(37, intptrAddition(10, 27));
+}
+
+int myPlus(int a, int b) => a + b;
+
+typedef NativeApplyTo42And74Type = ffi.IntPtr Function(
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>>);
+
+typedef ApplyTo42And74Type = int Function(
+    ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>>);
+
+void testFromFunction() {
+  ffi.Pointer<ffi.NativeFunction<NativeIntptrBinOp>> pointer =
+      ffi.fromFunction(myPlus);
+  Expect.isNotNull(pointer);
+
+  ffi.Pointer<ffi.NativeFunction<NativeApplyTo42And74Type>> p17 =
+      ffiTestFunctions.lookup("ApplyTo42And74");
+  ApplyTo42And74Type applyTo42And74 = p17.asFunction();
+
+  // TODO(dacoharkes): implement this
+
+  // int result = applyTo42And74(pointer);
+  // print(result);
+}
diff --git a/tests/standalone_2/ffi/function_structs_test.dart b/tests/standalone_2/ffi/function_structs_test.dart
new file mode 100644
index 0000000..6f74a90
--- /dev/null
+++ b/tests/standalone_2/ffi/function_structs_test.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// Dart test program for testing dart:ffi function pointers with struct
+// arguments.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+import 'coordinate.dart';
+import 'very_large_struct.dart';
+
+typedef NativeCoordinateOp = Coordinate Function(Coordinate);
+
+void main() {
+  testFunctionWithStruct();
+  testFunctionWithStructArray();
+  testFunctionWithVeryLargeStruct();
+}
+
+ffi.DynamicLibrary ffiTestFunctions =
+    ffi.DynamicLibrary.open("ffi_test_functions");
+
+/// pass a struct to a c function and get a struct as return value
+void testFunctionWithStruct() {
+  ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>> p1 =
+      ffiTestFunctions.lookup("TransposeCoordinate");
+  NativeCoordinateOp f1 = p1.asFunction();
+
+  Coordinate c1 = Coordinate(10.0, 20.0, null);
+  Coordinate c2 = Coordinate(42.0, 84.0, c1);
+  c1.next = c2;
+
+  Coordinate result = f1(c1);
+
+  Expect.approxEquals(20.0, c1.x);
+  Expect.approxEquals(30.0, c1.y);
+
+  Expect.approxEquals(42.0, result.x);
+  Expect.approxEquals(84.0, result.y);
+
+  c1.free();
+  c2.free();
+}
+
+/// pass an array of structs to a c funtion
+void testFunctionWithStructArray() {
+  ffi.Pointer<ffi.NativeFunction<NativeCoordinateOp>> p1 =
+      ffiTestFunctions.lookup("CoordinateElemAt1");
+  NativeCoordinateOp f1 = p1.asFunction();
+
+  Coordinate c1 = Coordinate.allocate(count: 3);
+  Coordinate c2 = c1.elementAt(1);
+  Coordinate c3 = c1.elementAt(2);
+  c1.x = 10.0;
+  c1.y = 10.0;
+  c1.next = c3;
+  c2.x = 20.0;
+  c2.y = 20.0;
+  c2.next = c1;
+  c3.x = 30.0;
+  c3.y = 30.0;
+  c3.next = c2;
+
+  Coordinate result = f1(c1);
+  Expect.approxEquals(20.0, result.x);
+  Expect.approxEquals(20.0, result.y);
+
+  c1.free();
+}
+
+typedef VeryLargeStructSum = int Function(VeryLargeStruct);
+typedef NativeVeryLargeStructSum = ffi.Int64 Function(VeryLargeStruct);
+
+void testFunctionWithVeryLargeStruct() {
+  ffi.Pointer<ffi.NativeFunction<NativeVeryLargeStructSum>> p1 =
+      ffiTestFunctions.lookup("SumVeryLargeStruct");
+  VeryLargeStructSum f = p1.asFunction();
+
+  VeryLargeStruct vls1 = VeryLargeStruct.allocate(count: 2);
+  VeryLargeStruct vls2 = vls1.elementAt(1);
+  List<VeryLargeStruct> structs = [vls1, vls2];
+  for (VeryLargeStruct struct in structs) {
+    struct.a = 1;
+    struct.b = 2;
+    struct.c = 4;
+    struct.d = 8;
+    struct.e = 16;
+    struct.f = 32;
+    struct.g = 64;
+    struct.h = 128;
+    struct.i = 256;
+    struct.j = 512;
+    struct.k = 1024;
+    struct.smallLastField = 1;
+  }
+  vls1.parent = vls2;
+  vls1.numChidlren = 2;
+  vls1.children = vls1;
+  vls2.parent = vls2;
+  vls2.parent = null;
+  vls2.numChidlren = 0;
+  vls2.children = null;
+
+  int result = f(vls1);
+  Expect.equals(2051, result);
+
+  result = f(vls2);
+  Expect.equals(2048, result);
+
+  vls1.free();
+}
diff --git a/tests/standalone_2/ffi/function_test.dart b/tests/standalone_2/ffi/function_test.dart
new file mode 100644
index 0000000..bed0264
--- /dev/null
+++ b/tests/standalone_2/ffi/function_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.
+//
+// Dart test program for testing dart:ffi function pointers.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+void main() {
+  testNativeFunctionFromCast();
+  testNativeFunctionFromLookup();
+  test64bitInterpretations();
+  testTruncation();
+  testNativeFunctionDoubles();
+  testNativeFunctionFloats();
+  testNativeFunctionManyArguments1();
+  testNativeFunctionManyArguments2();
+  testNativeFunctionManyArguments3();
+  testNativeFunctionPointer();
+  testNullInt();
+  testNullDouble();
+  testNullManyArgs();
+  testNullPointers();
+  testFloatRounding();
+}
+
+ffi.DynamicLibrary ffiTestFunctions =
+    ffi.DynamicLibrary.open("ffi_test_functions");
+
+typedef NativeBinaryOp = ffi.Int32 Function(ffi.Int32, ffi.Int32);
+typedef UnaryOp = int Function(int);
+typedef BinaryOp = int Function(int, int);
+typedef GenericBinaryOp<T> = int Function(int, T);
+
+void testNativeFunctionFromCast() {
+  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.NativeFunction<NativeBinaryOp>> p2 = p1.cast();
+  BinaryOp f = p2.asFunction<BinaryOp>();
+  BinaryOp f2 = p2.asFunction<GenericBinaryOp<int>>();
+  p1.free();
+}
+
+typedef NativeQuadOpSigned = ffi.Int64 Function(
+    ffi.Int64, ffi.Int32, ffi.Int16, ffi.Int8);
+typedef QuadOp = int Function(int, int, int, int);
+typedef NativeQuadOpUnsigned = ffi.Uint64 Function(
+    ffi.Uint64, ffi.Uint32, ffi.Uint16, ffi.Uint8);
+
+void testNativeFunctionFromLookup() {
+  BinaryOp sumPlus42 =
+      ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
+  Expect.equals(49, sumPlus42(3, 4));
+
+  QuadOp intComputation = ffiTestFunctions
+      .lookupFunction<NativeQuadOpSigned, QuadOp>("IntComputation");
+  Expect.equals(625, intComputation(125, 250, 500, 1000));
+
+  Expect.equals(
+      0x7FFFFFFFFFFFFFFF, intComputation(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
+  Expect.equals(
+      -0x8000000000000000, intComputation(0, 0, 0, -0x8000000000000000));
+}
+
+void test64bitInterpretations() {
+  QuadOp uintComputation = ffiTestFunctions
+      .lookupFunction<NativeQuadOpUnsigned, QuadOp>("UintComputation");
+
+  // 2 ^ 63 - 1
+  Expect.equals(
+      0x7FFFFFFFFFFFFFFF, uintComputation(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
+  // -2 ^ 63 interpreted as 2 ^ 63
+  Expect.equals(
+      -0x8000000000000000, uintComputation(0, 0, 0, -0x8000000000000000));
+  // -1 interpreted as 2 ^ 64 - 1
+  Expect.equals(-1, uintComputation(0, 0, 0, -1));
+}
+
+typedef NativeSenaryOp = ffi.Int64 Function(
+    ffi.Int8, ffi.Int16, ffi.Int32, ffi.Uint8, ffi.Uint16, ffi.Uint32);
+typedef SenaryOp = int Function(int, int, int, int, int, int);
+
+void testTruncation() {
+  SenaryOp sumSmallNumbers = ffiTestFunctions
+      .lookupFunction<NativeSenaryOp, SenaryOp>("SumSmallNumbers");
+
+  // TODO(dacoharkes): implement truncation and sign extension in trampolines
+  // for values smaller than 32 bits.
+  sumSmallNumbers(128, 0, 0, 0, 0, 0);
+  sumSmallNumbers(-129, 0, 0, 0, 0, 0);
+  sumSmallNumbers(0, 0, 0, 256, 0, 0);
+  sumSmallNumbers(0, 0, 0, -1, 0, 0);
+
+  sumSmallNumbers(0, 0x8000, 0, 0, 0, 0);
+  sumSmallNumbers(0, 0xFFFFFFFFFFFF7FFF, 0, 0, 0, 0);
+  sumSmallNumbers(0, 0, 0, 0, 0x10000, 0);
+  sumSmallNumbers(0, 0, 0, 0, -1, 0);
+
+  Expect.equals(0xFFFFFFFF80000000, sumSmallNumbers(0, 0, 0x80000000, 0, 0, 0));
+  Expect.equals(
+      0x000000007FFFFFFF, sumSmallNumbers(0, 0, 0xFFFFFFFF7FFFFFFF, 0, 0, 0));
+  Expect.equals(0, sumSmallNumbers(0, 0, 0, 0, 0, 0x100000000));
+  Expect.equals(0xFFFFFFFF, sumSmallNumbers(0, 0, 0, 0, 0, -1));
+}
+
+typedef NativeDoubleUnaryOp = ffi.Double Function(ffi.Double);
+typedef DoubleUnaryOp = double Function(double);
+
+void testNativeFunctionDoubles() {
+  DoubleUnaryOp times1_337Double = ffiTestFunctions
+      .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
+  Expect.approxEquals(2.0 * 1.337, times1_337Double(2.0));
+}
+
+typedef NativeFloatUnaryOp = ffi.Float Function(ffi.Float);
+
+void testNativeFunctionFloats() {
+  DoubleUnaryOp times1_337Float = ffiTestFunctions
+      .lookupFunction<NativeFloatUnaryOp, DoubleUnaryOp>("Times1_337Float");
+  Expect.approxEquals(1337.0, times1_337Float(1000.0));
+}
+
+typedef NativeOctenaryOp = ffi.IntPtr Function(
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr,
+    ffi.IntPtr);
+typedef OctenaryOp = int Function(
+    int, int, int, int, int, int, int, int, int, int);
+
+void testNativeFunctionManyArguments1() {
+  OctenaryOp sumManyInts = ffiTestFunctions
+      .lookupFunction<NativeOctenaryOp, OctenaryOp>("SumManyInts");
+  Expect.equals(55, sumManyInts(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
+}
+
+typedef NativeDoubleOctenaryOp = ffi.Double Function(
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double,
+    ffi.Double);
+typedef DoubleOctenaryOp = double Function(double, double, double, double,
+    double, double, double, double, double, double);
+
+void testNativeFunctionManyArguments2() {
+  DoubleOctenaryOp sumManyDoubles =
+      ffiTestFunctions.lookupFunction<NativeDoubleOctenaryOp, DoubleOctenaryOp>(
+          "SumManyDoubles");
+  Expect.approxEquals(
+      55.0, sumManyDoubles(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0));
+}
+
+typedef NativeVigesimalOp = ffi.Double Function(
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double,
+    ffi.IntPtr,
+    ffi.Float,
+    ffi.IntPtr,
+    ffi.Double);
+typedef VigesimalOp = double Function(
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double,
+    int,
+    double);
+
+void testNativeFunctionManyArguments3() {
+  VigesimalOp sumManyNumbers = ffiTestFunctions
+      .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+  Expect.approxEquals(
+      210.0,
+      sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0, 11, 12.0, 13,
+          14.0, 15, 16.0, 17, 18.0, 19, 20.0));
+}
+
+typedef Int64PointerUnOp = ffi.Pointer<ffi.Int64> Function(
+    ffi.Pointer<ffi.Int64>);
+
+void testNativeFunctionPointer() {
+  Int64PointerUnOp assign1337Index1 = ffiTestFunctions
+      .lookupFunction<Int64PointerUnOp, Int64PointerUnOp>("Assign1337Index1");
+  ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+  p2.store(42);
+  p2.elementAt(1).store(1000);
+  ffi.Pointer<ffi.Int64> result = assign1337Index1(p2);
+  Expect.equals(1337, result.load<int>());
+  Expect.equals(1337, p2.elementAt(1).load<int>());
+  Expect.equals(p2.elementAt(1).address, result.address);
+  p2.free();
+}
+
+void testNullInt() {
+  BinaryOp sumPlus42 =
+      ffiTestFunctions.lookupFunction<NativeBinaryOp, BinaryOp>("SumPlus42");
+
+  Expect.throws(() => sumPlus42(43, null));
+}
+
+void testNullDouble() {
+  DoubleUnaryOp times1_337Double = ffiTestFunctions
+      .lookupFunction<NativeDoubleUnaryOp, DoubleUnaryOp>("Times1_337Double");
+  Expect.throws(() => times1_337Double(null));
+}
+
+void testNullManyArgs() {
+  VigesimalOp sumManyNumbers = ffiTestFunctions
+      .lookupFunction<NativeVigesimalOp, VigesimalOp>("SumManyNumbers");
+  Expect.throws(() => sumManyNumbers(1, 2.0, 3, 4.0, 5, 6.0, 7, 8.0, 9, 10.0,
+      11, 12.0, 13, 14.0, 15, 16.0, 17, 18.0, null, 20.0));
+}
+
+void testNullPointers() {
+  Int64PointerUnOp nullableInt64ElemAt1 =
+      ffiTestFunctions.lookupFunction<Int64PointerUnOp, Int64PointerUnOp>(
+          "NullableInt64ElemAt1");
+
+  ffi.Pointer<ffi.Int64> result = nullableInt64ElemAt1(null);
+  Expect.isNull(result);
+
+  ffi.Pointer<ffi.Int64> p2 = ffi.allocate(count: 2);
+  result = nullableInt64ElemAt1(p2);
+  Expect.isNotNull(result);
+  p2.free();
+}
+
+typedef NativeFloatPointerToBool = ffi.Uint8 Function(ffi.Pointer<ffi.Float>);
+typedef FloatPointerToBool = int Function(ffi.Pointer<ffi.Float>);
+
+void testFloatRounding() {
+  FloatPointerToBool isRoughly1337 = ffiTestFunctions.lookupFunction<
+      NativeFloatPointerToBool, FloatPointerToBool>("IsRoughly1337");
+
+  ffi.Pointer<ffi.Float> p2 = ffi.allocate();
+  p2.store(1337.0);
+
+  int result = isRoughly1337(p2);
+  Expect.equals(1, result);
+
+  p2.free();
+}
diff --git a/tests/standalone_2/ffi/static_checks_test.dart b/tests/standalone_2/ffi/static_checks_test.dart
new file mode 100644
index 0000000..422fc6f
--- /dev/null
+++ b/tests/standalone_2/ffi/static_checks_test.dart
@@ -0,0 +1,365 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 dart:ffi extra checks
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+void main() {
+  testGetGeneric();
+  testGetGeneric2();
+  testGetVoid();
+  testGetNativeFunction();
+  testGetNativeType();
+  testGetTypeMismatch();
+  testSetGeneric();
+  testSetGeneric2();
+  testSetVoid();
+  testSetNativeFunction();
+  testSetNativeType();
+  testSetTypeMismatch();
+  testAsFunctionGeneric();
+  testAsFunctionGeneric2();
+  testAsFunctionWrongNativeFunctionSignature();
+  testAsFunctionTypeMismatch();
+  testFromFunctionGeneric();
+  testFromFunctionGeneric2();
+  testFromFunctionWrongNativeFunctionSignature();
+  testFromFunctionTypeMismatch();
+  testFromFunctionClosure();
+  testFromFunctionTearOff();
+  testLookupFunctionGeneric();
+  testLookupFunctionGeneric2();
+  testLookupFunctionWrongNativeFunctionSignature();
+  testLookupFunctionTypeMismatch();
+  testNativeFunctionSignatureInvalidReturn();
+  testNativeFunctionSignatureInvalidParam();
+  testNativeFunctionSignatureInvalidOptionalNamed();
+  testNativeFunctionSignatureInvalidOptionalPositional();
+}
+
+typedef Int8UnOp = ffi.Int8 Function(ffi.Int8);
+typedef IntUnOp = int Function(int);
+
+void testGetGeneric() {
+  int generic(ffi.Pointer p) {
+    int result;
+    result = p.load<int>(); //# 20: compile-time error
+    return result;
+  }
+
+  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  p.store(123);
+  ffi.Pointer loseType = p;
+  generic(loseType);
+  p.free();
+}
+
+void testGetGeneric2() {
+  T generic<T extends Object>() {
+    ffi.Pointer<ffi.Int8> p = ffi.allocate();
+    p.store(123);
+    T result;
+    result = p.load<T>(); //# 21: compile-time error
+    p.free();
+    return result;
+  }
+
+  generic<int>();
+}
+
+void testGetVoid() {
+  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.Void> p2 = p1.cast();
+
+  p2.load<int>(); //# 22: compile-time error
+
+  p1.free();
+}
+
+void testGetNativeFunction() {
+  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  IntUnOp f = p.load(); //# 23: compile-time error
+}
+
+void testGetNativeType() {
+  // Is it possible to obtain a ffi.Pointer<ffi.NativeType> at all?
+}
+
+void testGetTypeMismatch() {
+  ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
+  ffi.Pointer<ffi.Int16> typedNull = null;
+  p.store(typedNull);
+
+  // this fails to compile due to type mismatch
+  ffi.Pointer<ffi.Int8> p2 = p.load(); //# 25: compile-time error
+
+  p.free();
+}
+
+void testSetGeneric() {
+  void generic(ffi.Pointer p) {
+    p.store(123); //# 26: compile-time error
+  }
+
+  ffi.Pointer<ffi.Int8> p = ffi.allocate();
+  p.store(123);
+  ffi.Pointer loseType = p;
+  generic(loseType);
+  p.free();
+}
+
+void testSetGeneric2() {
+  void generic<T extends Object>(T arg) {
+    ffi.Pointer<ffi.Int8> p = ffi.allocate();
+    p.store(arg); //# 27: compile-time error
+    p.free();
+  }
+
+  generic<int>(123);
+}
+
+void testSetVoid() {
+  ffi.Pointer<ffi.IntPtr> p1 = ffi.allocate();
+  ffi.Pointer<ffi.Void> p2 = p1.cast();
+
+  p2.store(1234); //# 28: compile-time error
+
+  p1.free();
+}
+
+void testSetNativeFunction() {
+  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  IntUnOp f = (a) => a + 1;
+  p.store(f); //# 29: compile-time error
+}
+
+void testSetNativeType() {
+  // Is it possible to obtain a ffi.Pointer<ffi.NativeType> at all?
+}
+
+void testSetTypeMismatch() {
+  // the pointer to pointer types must match up
+  ffi.Pointer<ffi.Int8> pHelper = ffi.allocate();
+  pHelper.store(123);
+
+  ffi.Pointer<ffi.Pointer<ffi.Int16>> p = ffi.allocate();
+
+  // this fails to compile due to type mismatch
+  p.store(pHelper); //# 40: compile-time error
+
+  pHelper.free();
+  p.free();
+}
+
+void testAsFunctionGeneric() {
+  T generic<T extends Function>() {
+    ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+    Function f;
+    f = p.asFunction<T>(); //# 11: compile-time error
+    return f;
+  }
+
+  generic<IntUnOp>();
+}
+
+void testAsFunctionGeneric2() {
+  generic(ffi.Pointer<ffi.NativeFunction> p) {
+    Function f;
+    f = p.asFunction<IntUnOp>(); //# 12: compile-time error
+    return f;
+  }
+
+  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  generic(p);
+}
+
+void testAsFunctionWrongNativeFunctionSignature() {
+  ffi.Pointer<ffi.NativeFunction<IntUnOp>> p;
+  Function f = p.asFunction<IntUnOp>(); //# 13: compile-time error
+}
+
+typedef IntBinOp = int Function(int, int);
+
+void testAsFunctionTypeMismatch() {
+  ffi.Pointer<ffi.NativeFunction<Int8UnOp>> p = ffi.fromAddress(1337);
+  IntBinOp f = p.asFunction(); //# 14: compile-time error
+}
+
+typedef NativeDoubleUnOp = ffi.Double Function(ffi.Double);
+typedef DoubleUnOp = double Function(double);
+
+double myTimesThree(double d) => d * 3;
+
+int myTimesFour(int i) => i * 4;
+
+void testFromFunctionGeneric() {
+  ffi.Pointer<ffi.NativeFunction> generic<T extends Function>(T f) {
+    ffi.Pointer<ffi.NativeFunction<NativeDoubleUnOp>> result;
+    result = ffi.fromFunction(f); //# 70: compile-time error
+    return result;
+  }
+
+  generic(myTimesThree);
+}
+
+void testFromFunctionGeneric2() {
+  ffi.Pointer<ffi.NativeFunction<T>> generic<T extends Function>() {
+    ffi.Pointer<ffi.NativeFunction<T>> result;
+    result = ffi.fromFunction(myTimesThree); //# 71: compile-time error
+    return result;
+  }
+
+  generic<NativeDoubleUnOp>();
+}
+
+void testFromFunctionWrongNativeFunctionSignature() {
+  ffi.fromFunction<IntUnOp>(myTimesFour); //# 72: compile-time error
+}
+
+void testFromFunctionTypeMismatch() {
+  ffi.Pointer<ffi.NativeFunction<NativeDoubleUnOp>> p;
+  p = ffi.fromFunction(myTimesFour); //# 73: compile-time error
+}
+
+void testFromFunctionClosure() {
+  DoubleUnOp someClosure = (double z) => z / 27.0;
+  ffi.Pointer<ffi.NativeFunction<NativeDoubleUnOp>> p;
+  p = ffi.fromFunction(someClosure); //# 74: compile-time error
+}
+
+class X {
+  double tearoff(double d) => d / 27.0;
+}
+
+DoubleUnOp fld = null;
+
+void testFromFunctionTearOff() {
+  fld = X().tearoff;
+  ffi.Pointer<ffi.NativeFunction<NativeDoubleUnOp>> p;
+  p = ffi.fromFunction(fld); //# 75: compile-time error
+}
+
+void testLookupFunctionGeneric() {
+  Function generic<T extends Function>() {
+    ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+    Function result;
+    result = l.lookupFunction<T, DoubleUnOp>("cos"); //# 15: compile-time error
+    return result;
+  }
+
+  generic<NativeDoubleUnOp>();
+}
+
+void testLookupFunctionGeneric2() {
+  Function generic<T extends Function>() {
+    ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+    Function result;
+    result = //# 16: compile-time error
+        l.lookupFunction<NativeDoubleUnOp, T>("cos"); //# 16: compile-time error
+    return result;
+  }
+
+  generic<DoubleUnOp>();
+}
+
+void testLookupFunctionWrongNativeFunctionSignature() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  l.lookupFunction<IntUnOp, IntUnOp>("cos"); //# 17: compile-time error
+}
+
+void testLookupFunctionTypeMismatch() {
+  ffi.DynamicLibrary l = ffi.DynamicLibrary.open("ffi_test_dynamic_library");
+  l.lookupFunction<NativeDoubleUnOp, IntUnOp>("cos"); //# 18: compile-time error
+}
+
+// TODO(dacoharkes): make the next 4 test compile errors
+typedef Invalid1 = int Function(ffi.Int8);
+typedef Invalid2 = ffi.Int8 Function(int);
+typedef Invalid3 = ffi.Int8 Function({ffi.Int8 named});
+typedef Invalid4 = ffi.Int8 Function([ffi.Int8 positional]);
+
+void testNativeFunctionSignatureInvalidReturn() {
+  // ffi.Pointer<ffi.NativeFunction<Invalid1>> p = ffi.fromAddress(999);
+}
+
+void testNativeFunctionSignatureInvalidParam() {
+  // ffi.Pointer<ffi.NativeFunction<Invalid2>> p = ffi.fromAddress(999);
+}
+
+void testNativeFunctionSignatureInvalidOptionalNamed() {
+  // ffi.Pointer<ffi.NativeFunction<Invalid3>> p = ffi.fromAddress(999);
+}
+
+void testNativeFunctionSignatureInvalidOptionalPositional() {
+  // ffi.Pointer<ffi.NativeFunction<Invalid4>> p = ffi.fromAddress(999);
+}
+
+// error on missing field annotation
+@ffi.struct
+class TestStruct extends ffi.Pointer<ffi.Void> {
+  @ffi.Double()
+  double x;
+
+  double y; //# 50: compile-time error
+}
+
+// error on missing struct annotation
+class TestStruct2 extends ffi.Pointer<ffi.Void> {
+  @ffi.Double() //# 51: compile-time error
+  double x; //# 51: compile-time error
+}
+
+// error on missing annotation on subtype
+@ffi.struct
+class TestStruct3 extends TestStruct {
+  double z; //# 52: compile-time error
+}
+
+// error on double annotation
+@ffi.struct
+class TestStruct4 extends ffi.Pointer<ffi.Void> {
+  @ffi.Double()
+  @ffi.Double() //# 53: compile-time error
+  double z;
+}
+
+// error on annotation not matching up
+@ffi.struct
+class TestStruct5 extends ffi.Pointer<ffi.Void> {
+  @ffi.Int64() //# 54: compile-time error
+  double z; //# 54: compile-time error
+}
+
+// error on annotation not matching up
+@ffi.struct
+class TestStruct6 extends ffi.Pointer<ffi.Void> {
+  @ffi.Void() //# 55: compile-time error
+  double z; //# 55: compile-time error
+}
+
+// error on annotation not matching up
+@ffi.struct
+class TestStruct7 extends ffi.Pointer<ffi.Void> {
+  @ffi.NativeType() //# 56: compile-time error
+  double z; //# 56: compile-time error
+}
+
+// error on field initializer on field
+@ffi.struct
+class TestStruct8 extends ffi.Pointer<ffi.Void> {
+  @ffi.Double() //# 57: compile-time error
+  double z = 10.0; //# 57: compile-time error
+}
+
+// error on field initializer in constructor
+@ffi.struct
+class TestStruct9 extends ffi.Pointer<ffi.Void> {
+  @ffi.Double()
+  double z;
+
+  TestStruct9() : z = 0.0 {} //# 58: compile-time error
+}
diff --git a/tests/standalone_2/ffi/structs_test.dart b/tests/standalone_2/ffi/structs_test.dart
new file mode 100644
index 0000000..cbb2eab
--- /dev/null
+++ b/tests/standalone_2/ffi/structs_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. 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 dart:ffi struct pointers.
+
+library FfiTest;
+
+import 'dart:ffi' as ffi;
+
+import "package:expect/expect.dart";
+
+import 'coordinate_bare.dart' as bare;
+import 'coordinate_manual.dart' as manual;
+import 'coordinate.dart';
+
+void main() {
+  testStructAllocate();
+  testStructFromAddress();
+  testStructWithNulls();
+  testBareStruct();
+  testManualStruct();
+  testTypeTest();
+}
+
+/// allocates each coordinate separately in c memory
+void testStructAllocate() {
+  Coordinate c1 = Coordinate(10.0, 10.0, null);
+  Coordinate c2 = Coordinate(20.0, 20.0, c1);
+  Coordinate c3 = Coordinate(30.0, 30.0, c2);
+  c1.next = c3;
+
+  Coordinate currentCoordinate = c1;
+  Expect.equals(10.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(30.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(20.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(10.0, currentCoordinate.x);
+
+  c1.free();
+  c2.free();
+  c3.free();
+}
+
+/// allocates coordinates consecutively in c memory
+void testStructFromAddress() {
+  Coordinate c1 = Coordinate.allocate(count: 3);
+  Coordinate c2 = c1.elementAt(1);
+  Coordinate c3 = c1.elementAt(2);
+  c1.x = 10.0;
+  c1.y = 10.0;
+  c1.next = c3;
+  c2.x = 20.0;
+  c2.y = 20.0;
+  c2.next = c1;
+  c3.x = 30.0;
+  c3.y = 30.0;
+  c3.next = c2;
+
+  Coordinate currentCoordinate = c1;
+  Expect.equals(10.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(30.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(20.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(10.0, currentCoordinate.x);
+
+  c1.free();
+}
+
+void testStructWithNulls() {
+  Coordinate coordinate = Coordinate(10.0, 10.0, null);
+  Expect.isNull(coordinate.next);
+  coordinate.next = coordinate;
+  Expect.isNotNull(coordinate.next);
+  coordinate.next = null;
+  Expect.isNull(coordinate.next);
+  coordinate.free();
+}
+
+void testBareStruct() {
+  int structSize = ffi.sizeOf<ffi.Double>() * 2 + ffi.sizeOf<ffi.IntPtr>();
+  bare.Coordinate c1 = ffi.allocate<ffi.Uint8>(count: structSize * 3).cast();
+  bare.Coordinate c2 = c1.offsetBy(structSize).cast();
+  bare.Coordinate c3 = c1.offsetBy(structSize * 2).cast();
+  c1.x = 10.0;
+  c1.y = 10.0;
+  c1.next = c3;
+  c2.x = 20.0;
+  c2.y = 20.0;
+  c2.next = c1;
+  c3.x = 30.0;
+  c3.y = 30.0;
+  c3.next = c2;
+
+  bare.Coordinate currentCoordinate = c1;
+  Expect.equals(10.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(30.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(20.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(10.0, currentCoordinate.x);
+
+  c1.free();
+}
+
+void testManualStruct() {
+  manual.Coordinate c1 = manual.Coordinate(10.0, 10.0, null);
+  manual.Coordinate c2 = manual.Coordinate(20.0, 20.0, c1);
+  manual.Coordinate c3 = manual.Coordinate(30.0, 30.0, c2);
+  c1.next = c3;
+
+  manual.Coordinate currentCoordinate = c1;
+  Expect.equals(10.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(30.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(20.0, currentCoordinate.x);
+  currentCoordinate = currentCoordinate.next;
+  Expect.equals(10.0, currentCoordinate.x);
+
+  c1.free();
+  c2.free();
+  c3.free();
+}
+
+void testTypeTest() {
+  Coordinate c = Coordinate(10, 10, null);
+  Expect.isTrue(c is ffi.Pointer);
+  Expect.isTrue(c is ffi.Pointer<ffi.Void>);
+  c.free();
+}
diff --git a/tests/standalone_2/ffi/subtype_test.dart b/tests/standalone_2/ffi/subtype_test.dart
new file mode 100644
index 0000000..fd04b50
--- /dev/null
+++ b/tests/standalone_2/ffi/subtype_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.
+//
+// Dart test program for testing dart:ffi Pointer subtypes.
+
+library FfiTest;
+
+import "package:expect/expect.dart";
+
+import 'cstring.dart';
+
+void main() {
+  CString cs = CString.toUtf8("hello world!");
+
+  Expect.equals("hello world!", cs.fromUtf8());
+
+  cs.free();
+}
diff --git a/tests/standalone_2/ffi/very_large_struct.dart b/tests/standalone_2/ffi/very_large_struct.dart
new file mode 100644
index 0000000..283cb57
--- /dev/null
+++ b/tests/standalone_2/ffi/very_large_struct.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library FfiTestCoordinateBare;
+
+import 'dart:ffi' as ffi;
+
+/// Large sample struct for dart:ffi library.
+@ffi.struct
+class VeryLargeStruct extends ffi.Pointer<ffi.Void> {
+  @ffi.Int8()
+  int a;
+
+  @ffi.Int16()
+  int b;
+
+  @ffi.Int32()
+  int c;
+
+  @ffi.Int64()
+  int d;
+
+  @ffi.Uint8()
+  int e;
+
+  @ffi.Uint16()
+  int f;
+
+  @ffi.Uint32()
+  int g;
+
+  @ffi.Uint64()
+  int h;
+
+  @ffi.IntPtr()
+  int i;
+
+  @ffi.Float()
+  double j;
+
+  @ffi.Double()
+  double k;
+
+  @ffi.Pointer()
+  VeryLargeStruct parent;
+
+  @ffi.IntPtr()
+  int numChidlren;
+
+  @ffi.Pointer()
+  VeryLargeStruct children;
+
+  @ffi.Int8()
+  int smallLastField;
+
+  // generated by @ffi.struct annotation
+  external static int sizeOf();
+
+  VeryLargeStruct offsetBy(int offsetInBytes) =>
+      super.offsetBy(offsetInBytes).cast();
+
+  VeryLargeStruct elementAt(int index) => offsetBy(sizeOf() * index);
+
+  static VeryLargeStruct allocate({int count: 1}) =>
+      ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
+}
diff --git a/tests/standalone_2/io/client_socket_exception_test.dart b/tests/standalone_2/io/client_socket_exception_test.dart
index 647804c..b6c53a28 100644
--- a/tests/standalone_2/io/client_socket_exception_test.dart
+++ b/tests/standalone_2/io/client_socket_exception_test.dart
@@ -47,7 +47,7 @@
       } catch (ex) {
         wrongExceptionCaught = true;
       }
-      Expect.isFalse(exceptionCaught);
+      Expect.isTrue(exceptionCaught);
       Expect.isFalse(wrongExceptionCaught);
 
       // From here exceptions are expected.
diff --git a/tests/standalone_2/io/entrypoints_verification_test.dart b/tests/standalone_2/io/entrypoints_verification_test.dart
new file mode 100644
index 0000000..cf12ac1
--- /dev/null
+++ b/tests/standalone_2/io/entrypoints_verification_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for 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=--verify-entry-points=true
+
+import 'dart:io';
+import 'dart:convert';
+import 'dart:math';
+import 'package:path/path.dart';
+import 'package:expect/expect.dart';
+import 'dart-ext:entrypoints_verification_test_extension';
+
+void RunTest() native "RunTest";
+
+main() {
+  RunTest();
+
+  new C();
+  new D();
+}
+
+class C {}
+
+@pragma("vm:entry-point")
+class D {
+  D();
+
+  @pragma("vm:entry-point")
+  D.defined();
+
+  @pragma("vm:entry-point")
+  factory D.fact() => E.ctor();
+
+  void fn0() {}
+
+  @pragma("vm:entry-point")
+  void fn1() {}
+
+  static void fn2() {}
+
+  @pragma("vm:entry-point")
+  static void fn3() {}
+
+  void Function() fld0;
+
+  @pragma("vm:entry-point")
+  void Function() fld1;
+
+  @pragma("vm:entry-point", "get")
+  void Function() fld2;
+
+  @pragma("vm:entry-point", "set")
+  void Function() fld3;
+}
+
+void fn0() {}
+
+@pragma("vm:entry-point")
+void fn1() {}
+
+class E extends D {
+  E.ctor();
+}
+
+@pragma("vm:entry-point")
+class F {
+  static void Function() fld0;
+
+  @pragma("vm:entry-point")
+  static void Function() fld1;
+
+  @pragma("vm:entry-point", "get")
+  static void Function() fld2;
+
+  @pragma("vm:entry-point", "set")
+  static void Function() fld3;
+}
+
+void Function() fld0;
+
+@pragma("vm:entry-point")
+void Function() fld1;
+
+@pragma("vm:entry-point", "get")
+void Function() fld2;
+
+@pragma("vm:entry-point", "set")
+void Function() fld3;
diff --git a/tests/standalone_2/io/file_test.dart b/tests/standalone_2/io/file_test.dart
index 3715504..74f57f7 100644
--- a/tests/standalone_2/io/file_test.dart
+++ b/tests/standalone_2/io/file_test.dart
@@ -988,7 +988,9 @@
     file.createSync();
     var output = file.openWrite();
     output.close();
-    output.add(buffer); // Ignored.
+    Expect.throws(() {
+      output.add(buffer);
+    });
     output.done.then((_) {
       file.deleteSync();
       asyncTestDone("testCloseExceptionStream");
diff --git a/tests/standalone_2/io/http_10_test.dart b/tests/standalone_2/io/http_10_test.dart
index 9a02f73a..92ecc6f 100644
--- a/tests/standalone_2/io/http_10_test.dart
+++ b/tests/standalone_2/io/http_10_test.dart
@@ -29,7 +29,9 @@
       response.write("Z");
       response.write("Z");
       response.close();
-      response.write("x");
+      Expect.throws(() {
+        response.write("x");
+      }, (e) => e is StateError);
     }, onError: (e, trace) {
       String msg = "Unexpected error $e";
       if (trace != null) msg += "\nStackTrace: $trace";
diff --git a/tests/standalone_2/io/http_content_length_test.dart b/tests/standalone_2/io/http_content_length_test.dart
index 6f67664..15d6520 100644
--- a/tests/standalone_2/io/http_content_length_test.dart
+++ b/tests/standalone_2/io/http_content_length_test.dart
@@ -37,7 +37,9 @@
       // After an explicit close, write becomes a state error
       // because we have said we will not add more.
       response.close();
-      response.write("x");
+      Expect.throws(() {
+        response.write("x");
+      }, (e) => e is StateError);
     }, onError: (e, trace) {
       String msg = "Unexpected server error $e";
       if (trace != null) msg += "\nStackTrace: $trace";
@@ -89,7 +91,9 @@
           }
         });
         response.close();
-        response.write("x");
+        Expect.throws(() {
+          response.write("x");
+        }, (e) => e is StateError);
       });
     }, onError: (e, trace) {
       String msg = "Unexpected error $e";
@@ -149,7 +153,9 @@
         response.write("x");
         response.write("x");
         response.close();
-        response.write("x");
+        Expect.throws(() {
+          response.write("x");
+        }, (e) => e is StateError);
       });
     }, onError: (e, trace) {
       String msg = "Unexpected error $e";
diff --git a/tests/standalone_2/io/link_test.dart b/tests/standalone_2/io/link_test.dart
index afc0f73..477d7b5 100644
--- a/tests/standalone_2/io/link_test.dart
+++ b/tests/standalone_2/io/link_test.dart
@@ -7,7 +7,6 @@
 import "package:path/path.dart";
 import "dart:async";
 import "dart:io";
-import "dart:isolate";
 
 // Test the dart:io Link class.
 
@@ -57,8 +56,8 @@
 
   // Test FileSystemEntity.identical on files, directories, and links,
   // reached by different paths.
-  Expect
-      .isTrue(FileSystemEntity.identicalSync(createdDirectly, createdDirectly));
+  Expect.isTrue(
+      FileSystemEntity.identicalSync(createdDirectly, createdDirectly));
   Expect.isFalse(
       FileSystemEntity.identicalSync(createdDirectly, createdThroughLink));
   Expect.isTrue(FileSystemEntity.identicalSync(
@@ -190,6 +189,38 @@
     Expect.isFalse(link2.existsSync());
   }
 
+  testRenameToLink(String base, String target) {
+    Link link1 = Link(join(base, '1'))..createSync(target);
+    Link link2 = Link(join(base, '2'))..createSync(target);
+    Expect.isTrue(link1.existsSync());
+    Expect.isTrue(link2.existsSync());
+    Link renamed = link1.renameSync(link2.path);
+    Expect.isFalse(link1.existsSync());
+    Expect.isTrue(renamed.existsSync());
+    renamed.deleteSync();
+    Expect.isFalse(renamed.existsSync());
+  }
+
+  testRenameToTarget(String linkName, String target, bool isDirectory) {
+    Link link = Link(linkName)..createSync(target);
+    Expect.isTrue(link.existsSync());
+    try {
+      Link renamed = link.renameSync(target);
+      if (isDirectory) {
+        Expect.fail('Renaming a link to the name of an existing directory ' +
+            'should fail');
+      }
+      Expect.isTrue(renamed.existsSync());
+      renamed.deleteSync();
+    } on FileSystemException catch (_) {
+      if (isDirectory) {
+        return;
+      }
+      Expect.fail('Renaming a link to the name of an existing file should ' +
+          'not fail');
+    }
+  }
+
   Directory baseDir = Directory.systemTemp.createTempSync('dart_link');
   String base = baseDir.path;
   Directory dir = new Directory(join(base, 'a'))..createSync();
@@ -198,6 +229,11 @@
   testRename(base, file.path);
   testRename(base, dir.path);
 
+  testRenameToLink(base, file.path);
+
+  testRenameToTarget(join(base, 'fileLink'), file.path, false);
+  testRenameToTarget(join(base, 'dirLink'), dir.path, true);
+
   baseDir.deleteSync(recursive: true);
 }
 
diff --git a/tests/standalone_2/io/raw_datagram_socket_test.dart b/tests/standalone_2/io/raw_datagram_socket_test.dart
index a933305..5e64fdb 100644
--- a/tests/standalone_2/io/raw_datagram_socket_test.dart
+++ b/tests/standalone_2/io/raw_datagram_socket_test.dart
@@ -116,6 +116,35 @@
   test(InternetAddress.loopbackIPv6, null, false);
 }
 
+testDatagramSocketMulticastIf() {
+  test(address) async {
+    asyncStart();
+    final socket = await RawDatagramSocket.bind(address, 0);
+    RawSocketOption option;
+    if (address.type == InternetAddressType.IPv4) {
+      option = RawSocketOption(RawSocketOption.levelIPv4,
+          RawSocketOption.IPv4MulticastInterface, address.rawAddress);
+    } else {
+      // We'll need a Uint8List(4) for this option, since it will be an 4 byte
+      // word value sent into get/setsockopt.
+      option = RawSocketOption(RawSocketOption.levelIPv6,
+          RawSocketOption.IPv6MulticastInterface, Uint8List(4));
+    }
+
+    socket.setRawOption(option);
+    final getResult = socket.getRawOption(option);
+
+    if (address.type == InternetAddressType.IPv4) {
+      Expect.listEquals(getResult, address.rawAddress);
+    } else {
+      Expect.listEquals(getResult, [0, 0, 0, 0]);
+    }
+
+    asyncSuccess(socket);
+    asyncEnd();
+  }
+}
+
 testBroadcast() {
   test(bindAddress, broadcastAddress, enabled) {
     asyncStart();
@@ -363,6 +392,7 @@
   testDatagramMulticastOptions();
   testDatagramSocketReuseAddress();
   testDatagramSocketTtl();
+  testDatagramSocketMulticastIf();
   testBroadcast();
   testLoopbackMulticast();
   testLoopbackMulticastError();
diff --git a/tests/standalone_2/io/socket_upgrade_to_secure_test.dart b/tests/standalone_2/io/socket_upgrade_to_secure_test.dart
index 13957ca..9209f34 100644
--- a/tests/standalone_2/io/socket_upgrade_to_secure_test.dart
+++ b/tests/standalone_2/io/socket_upgrade_to_secure_test.dart
@@ -164,7 +164,9 @@
               SecureSocket.secure(socket, host: HOST, context: clientContext);
         }
         return future.then<SecureSocket>((SecureSocket secureSocket) {
-          socket.add([0]);
+          Expect.throws(() {
+            socket.add([0]);
+          });
           return secureSocket;
         });
       });
@@ -179,7 +181,9 @@
                 SecureSocket.secure(socket, host: HOST, context: clientContext);
           }
           return future.then((secureSocket) {
-            socket.add([0]);
+            Expect.throws(() {
+              socket.add([0]);
+            });
             return secureSocket;
           });
         });
@@ -191,7 +195,9 @@
     server.listen((client) {
       if (!handshakeBeforeSecure) {
         SecureSocket.secureServer(client, serverContext).then((secureClient) {
-          client.add([0]);
+          Expect.throws(() {
+            client.add([0]);
+          });
           runServer(secureClient).then((_) => server.close());
         });
       } else {
@@ -199,7 +205,9 @@
           SecureSocket
               .secureServer(client, serverContext, bufferedData: carryOverData)
               .then((secureClient) {
-            client.add([0]);
+            Expect.throws(() {
+              client.add([0]);
+            });
             runServer(secureClient).then((_) => server.close());
           });
         });
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index 7222d67..cf60651 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -94,7 +94,7 @@
 [ $runtime == none && !$strong ]
 io/process_exit_negative_test: Fail, OK # Must be run to exit with non-zero exit code.
 
-[ $system == linux && ($runtime == flutter || $runtime == vm) ]
+[ $runtime == vm && $system == linux ]
 io/http_basic_test: Pass, Slow, Timeout # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
 io/http_launch_test: Pass, Slow, Timeout # Issue 28046, These tests might be slow on an opt counter threshold bot. They also time out on the bot occasionally => flaky test issue 28046
 
@@ -159,7 +159,7 @@
 [ $mode == product || $runtime == dart_precompiled ]
 no_assert_test: SkipByDesign
 
-[ $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
+[ $runtime == dart_precompiled || $runtime == vm ]
 deferred_transitive_import_error_test: Skip
 io/https_client_certificate_test: RuntimeError # Issue 24070 Failures in secure networking while NSS is replaced with BoringSSL
 io/non_utf8_output_test: NonUtf8Output, OK # This test checks that the test runner correctly detects and reports non-utf8 output from a test.
diff --git a/tests/standalone_2/standalone_2_flutter.status b/tests/standalone_2/standalone_2_flutter.status
deleted file mode 100644
index 6eddf96..0000000
--- a/tests/standalone_2/standalone_2_flutter.status
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[ $runtime == flutter ]
-dart_developer_disabled_env_test: RuntimeError # Flutter Issue 9115
-http_launch_test: Skip # Timeout Flutter Issue 9115
-io/addlatexhash_test: RuntimeError # Flutter Issue 9115
-io/arguments_test: RuntimeError # Flutter Issue 9115
-io/code_collection_test: RuntimeError # Flutter Issue 9115
-io/dart_std_io_pipe_test: RuntimeError # Flutter Issue 9115
-io/dependency_graph_test: CompileTimeError # Imports dart:mirrors
-io/directory_uri_test: Skip # Timeout Flutter Issue 9115
-io/file_blocking_lock_test: Skip # Timeout Flutter Issue 9115
-io/file_lock_test: Skip # Timeout Flutter Issue 9115
-io/file_stream_test: Skip # Timeout Flutter Issue 9115
-io/file_system_watcher_test: Skip # Timeout Flutter Issue 9115
-io/file_test: Skip # Timeout Flutter Issue 9115
-io/file_uri_test: Skip # Timeout Flutter Issue 9115
-io/http_client_stays_alive_test: RuntimeError # Flutter Issue 9115
-io/http_connection_close_test: Skip # Timeout Flutter Issue 9115
-io/http_cross_process_test: RuntimeError # Flutter Issue 9115
-io/http_server_close_response_after_error_test: Skip #  Flutter Issue 9115Timeout
-io/http_server_response_test: Skip # Flaky  # Flutter Issue 9115
-io/https_client_certificate_test: Skip # Timeout Flutter Issue 9115
-io/https_unauthorized_test: Skip # Timeout Flutter Issue 9115
-io/link_uri_test: Skip # Timeout Flutter Issue 9115
-io/locale_name_test: RuntimeError # Flutter Issue 9115
-io/named_pipe_script_test: Skip # Timeout Flutter Issue 9115
-io/platform_resolved_executable_test/00: Skip # Timeout Flutter Issue 9115
-io/platform_resolved_executable_test/01: Skip # Timeout Flutter Issue 9115
-io/platform_resolved_executable_test/02: Skip # Timeout Flutter Issue 9115
-io/platform_resolved_executable_test/03: Skip # Timeout Flutter Issue 9115
-io/platform_resolved_executable_test/04: Skip # Timeout Flutter Issue 9115
-io/platform_resolved_executable_test/05: Skip # Timeout Flutter Issue 9115
-io/platform_test: RuntimeError # Flutter Issue 9115
-io/print_sync_test: Skip # Timeout Flutter Issue 9115
-io/process_check_arguments_test: RuntimeError # Flutter Issue 9115
-io/process_detached_test: Skip # Timeout Flutter Issue 9115
-io/process_environment_test: Skip # Timeout Flutter Issue 9115
-io/process_exit_test: RuntimeError # Flutter Issue 9115
-io/process_kill_test: Skip # Timeout Flutter Issue 9115
-io/process_non_ascii_test: Skip # Timeout Flutter Issue 9115
-io/process_pid_test: Skip # Timeout Flutter Issue 9115
-io/process_run_output_test: Fail # Unable to parse package files Flutter Issue 9115
-io/process_run_output_test: RuntimeError # Flutter Issue 9115
-io/process_run_test: RuntimeError # Flutter Issue 9115
-io/process_segfault_test: RuntimeError # Flutter Issue 9115
-io/process_set_exit_code_test: RuntimeError # Flutter Issue 9115
-io/process_shell_test: Skip # Timeout Flutter Issue 9115
-io/process_stderr_test: RuntimeError # Flutter Issue 9115
-io/process_stdout_test: RuntimeError # Flutter Issue 9115
-io/process_sync_test: RuntimeError # Flutter Issue 9115
-io/process_working_directory_test: RuntimeError # Flutter Issue 9115
-io/raw_datagram_socket_test: Crash # Flutter Issue 9115
-io/raw_server_socket_cancel_test: RuntimeError # Flutter Issue 9115
-io/raw_socket_cross_process_test: RuntimeError # Flutter Issue 9115
-io/raw_socket_test: Skip # Timeout Flutter Issue 9115
-io/regress_7191_test: Skip # Timeout Flutter Issue 9115
-io/secure_socket_bad_data_test: Skip # Timeout Flutter Issue 9115
-io/secure_socket_renegotiate_test: Skip # Timeout Flutter Issue 9115
-io/secure_unauthorized_test: Skip # Timeout Flutter Issue 9115
-io/signals_test: Skip # Timeout Flutter Issue 9115
-io/skipping_dart2js_compilations_test: CompileTimeError # Uses mirrors
-io/socket_cross_process_test: RuntimeError # Flutter Issue 9115
-io/socket_finalizer_test: Skip # Timeout Flutter Issue 9115
-io/socket_info_ipv4_test: Skip # Timeout Flutter Issue 9115
-io/socket_info_ipv6_test: Skip # Timeout Flutter Issue 9115
-io/socket_invalid_arguments_test: Skip # Timeout Flutter Issue 9115
-io/stdin_sync_test: RuntimeError # Flutter Issue 9115
-io/stdio_implicit_close_test: Skip # Timeout Flutter Issue 9115
-io/test_extension_fail_test: RuntimeError # Flutter Issue 9115
-io/test_extension_test: RuntimeError # Flutter Issue 9115
-io/test_harness_analyzer_test: CompileTimeError # Uses mirrors
-io/test_runner_test: CompileTimeError # Uses mirrors
-io/uri_platform_test: RuntimeError # Flutter Issue 9115
-oom_error_stacktrace_test: RuntimeError # Flutter Issue 9115
-out_of_memory_test: RuntimeError # Flutter Issue 9115
-package/package1_test: Fail # Unable to parse package files Flutter Issue 9115
-package/package_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/both_dir_and_file/prefers_packages_file_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/invalid/invalid_package_name_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/invalid/same_package_twice_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/packages_dir_only/packages_dir_only_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/packages_file_in_parent/sub/packages_file_in_parent_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/packages_file_only/packages_file_only_test: Fail # Unable to parse package files Flutter Issue 9115
-package/scenarios/packages_option_only/packages_option_only_test: Fail # Unable to parse package files Flutter Issue 9115
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index f073ec4..7b2cfd6 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -34,6 +34,10 @@
 io/web_socket_protocol_processor_test: CompileTimeError
 io/zlib_test: RuntimeError
 
+[ $compiler == dartkb ]
+io/platform_resolved_executable_test/03: RuntimeError
+io/platform_resolved_executable_test/04: RuntimeError
+
 [ $compiler == dartkp ]
 io/test_runner_test: SkipByDesign # Is not relevant for AOT.
 
@@ -124,6 +128,9 @@
 regress_29350_test: MissingCompileTimeError
 regress_29350_test/none: Pass # Issue 31537
 
+[ $compiler == dartkp && $system == android ]
+io/http_close_test: Timeout # Issue 28380
+
 [ $compiler == dartkp && !$strong ]
 *: SkipByDesign
 
@@ -148,8 +155,6 @@
 
 [ $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
 io/http_client_request_test: Pass, Timeout
-io/platform_resolved_executable_test/03: Pass, RuntimeError
-io/platform_resolved_executable_test/04: Pass, RuntimeError
 io/secure_builtin_roots_test: Pass, Timeout
 io/socket_finalizer_test: Pass, Timeout
 no_support_debugger_test: Skip # kernel-service snapshot not compatible with flag disabled
@@ -221,3 +226,6 @@
 io/test_extension_test: RuntimeError
 io/web_socket_compression_test: Skip # Timeout
 io/web_socket_test: Skip # Timeout
+
+[ $hot_reload || $hot_reload_rollback || $compiler != dartk && $compiler != dartkb ]
+io/entrypoints_verification_test: Skip # Test runs in JIT mode only
diff --git a/tests/standalone_2/standalone_2_vm.status b/tests/standalone_2/standalone_2_vm.status
index fcd29ba..c59b66f 100644
--- a/tests/standalone_2/standalone_2_vm.status
+++ b/tests/standalone_2/standalone_2_vm.status
@@ -6,6 +6,9 @@
 link_natives_lazily_test: SkipByDesign # Not supported.
 no_allow_absolute_addresses_test: SkipByDesign # Not supported.
 
+[ $builder_tag == asan ]
+ffi/data_not_asan_test: Skip # this test tries to allocate too much memory on purpose
+
 [ $compiler == app_jit ]
 full_coverage_test: Skip # Platform.executable
 io/code_collection_test: Skip # Platform.executable
@@ -22,7 +25,18 @@
 io/test_runner_test: RuntimeError # Issue 33168
 regress_26031_test: Skip # Platform.resolvedExecutable
 
+[ $compiler == app_jitk ]
+ffi/dynamic_library_test: Skip # https://github.com/dart-lang/sdk/issues/35934
+ffi/function_callbacks_test: Skip # https://github.com/dart-lang/sdk/issues/35934
+ffi/function_structs_test: Skip # https://github.com/dart-lang/sdk/issues/35934
+ffi/function_test: Skip # https://github.com/dart-lang/sdk/issues/35934
+
+[ $runtime == dart_precompiled ]
+ffi: RuntimeError # https://github.com/dart-lang/sdk/issues/35765
+ffi/static_checks_test: Skip # https://github.com/dart-lang/sdk/issues/35765
+
 [ $runtime == vm ]
+ffi/enable_ffi_test: Fail # test designed to fail: --enable-ffi=false with import dart:ffi
 io/test_runner_test: Skip # Spawns a process which runs in Dart2 mode.
 
 [ $system == android ]
@@ -67,18 +81,21 @@
 [ $arch == arm && $mode == release && $runtime == dart_precompiled && $system == android ]
 io/stdout_stderr_non_blocking_test: Pass, Timeout # Issue 28426
 
-[ $arch == ia32 && $builder_tag == asan && $mode == release && $runtime == vm && $system == linux ]
-io/socket_close_test: Pass, Timeout # Issue 28502: timeout.
-
 [ $arch == simdbc64 && $mode == debug && $checked ]
 io/web_socket_test: Pass, RuntimeError # Issue 26814.
 
 [ $arch == x64 && $compiler == dartkb && $runtime == vm && $system == linux ]
 io/stdout_stderr_non_blocking_test: Pass, Timeout # Issue 35192
 
+[ $arch == x64 && $mode == debug && $system == linux && $hot_reload ]
+ffi/subtype_test: Skip # https://github.com/dart-lang/sdk/issues/35933
+
 [ $compiler != dart2analyzer && $system == windows ]
 io/platform_resolved_executable_test/06: RuntimeError # Issue 23641
 
+[ $compiler == dartkb && $mode == debug ]
+ffi/subtype_test: Skip # https://github.com/dart-lang/sdk/issues/35935
+
 [ $mode == release && $runtime == vm && $system == linux && ($arch == simdbc64 || $arch == x64) ]
 io/http_bind_test: Pass, Timeout # Issue 35192
 
@@ -88,11 +105,13 @@
 
 [ $mode == release && $runtime == vm && $system == windows ]
 io/http_server_close_response_after_error_test: Pass, Timeout # Issue 28370: timeout.
-io/regress_7191_test: Pass, Timeout # Issue 28374: timeout.
 
-[ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64) ]
+[ $runtime == dart_precompiled && $system == linux && ($arch == simarm || $arch == simarm64 || $arch == x64) ]
 io/stdout_stderr_non_blocking_test: Pass, Timeout # Issue 35192
 
+[ $runtime != dart_precompiled && $runtime != vm ]
+ffi: SkipByDesign # ffi is only supported on vm
+
 [ $runtime == vm && !$checked && !$strong ]
 io/file_constructor_test: RuntimeError
 
@@ -115,3 +134,6 @@
 full_coverage_test: Skip # TODO(vegorov) SIMDBC interpreter doesn't support coverage yet.
 link_natives_lazily_test: SkipByDesign # SIMDBC interpreter doesn't support lazy linking of natives.
 no_lazy_dispatchers_test: SkipByDesign # SIMDBC interpreter doesn't support --no_lazy_dispatchers
+
+[ $arch != x64 || $system != linux && $system != macos ]
+ffi: Skip # ffi not yet supported on other systems than linux/macos 64
diff --git a/tools/3xhead_flutter_hooks.sh b/tools/3xhead_flutter_hooks.sh
index a075705..cb4219a 100755
--- a/tools/3xhead_flutter_hooks.sh
+++ b/tools/3xhead_flutter_hooks.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
 #
 # 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
@@ -12,11 +12,14 @@
 # (run inside the root of a flutter engine checkout)
 
 set -e
-if [ ! -e src/third_party/dart ]; then
-  echo "$0: error: "\
-       "This script must be run from the root of a flutter engine checkout" >&2
-  exit 1
-fi
+
+DIR=$(dirname -- "$(which -- "$0")")
+. $DIR/patches/utils.sh
+
+ensure_in_checkout_root
+
+# Apply patches to the Flutter Framework if needed.
+src/third_party/dart/tools/patches/flutter-flutter/apply.sh
 
 # Apply patches to the Flutter Engine if needed.
 src/third_party/dart/tools/patches/flutter-engine/apply.sh
diff --git a/tools/VERSION b/tools/VERSION
index 9a869d4..11a8a37 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL stable
 MAJOR 2
-MINOR 1
-PATCH 1
+MINOR 2
+PATCH 0
 PRERELEASE 0
 PRERELEASE_PATCH 0
diff --git a/tools/approve_results.dart b/tools/approve_results.dart
index eff1878..4962072 100755
--- a/tools/approve_results.dart
+++ b/tools/approve_results.dart
@@ -197,6 +197,13 @@
       }
       final name = result["name"];
       final test = new Test(bot, name, result, approvedResult, flakiness);
+      final dropApproval =
+          test.matches ? options["failures-only"] : options["successes-only"];
+      if (dropApproval && !test.isApproved) {
+        if (approvedResult == null) continue;
+        result.clear();
+        result.addAll(approvedResult);
+      }
       tests.add(test);
     }
     // If preapproving and the CL has introduced new tests, add the new tests
@@ -222,11 +229,16 @@
 
 main(List<String> args) async {
   final parser = new ArgParser();
+  parser.addFlag("automated-approver",
+      help: "Record the approval as done by an automated process.",
+      negatable: false);
   parser.addMultiOption("bot",
       abbr: "b",
       help: "Select the bots matching the glob pattern [option is repeatable]",
       splitCommas: false);
   parser.addFlag("help", help: "Show the program usage.", negatable: false);
+  parser.addFlag("failures-only",
+      help: "Approve failures only.", negatable: false);
   parser.addFlag("list",
       abbr: "l", help: "List the available bots.", negatable: false);
   parser.addFlag("no",
@@ -235,10 +247,17 @@
       negatable: false);
   parser.addOption("preapprove",
       abbr: "p", help: "Preapprove the new failures in a gerrit CL.");
+  parser.addFlag("successes-only",
+      help: "Approve successes only.", negatable: false);
   parser.addFlag("verbose",
       abbr: "v", help: "Describe asynchronous operations.", negatable: false);
   parser.addFlag("yes",
       abbr: "y", help: "Approve the results.", negatable: false);
+  parser.addOption("table",
+      abbr: "T",
+      help: "Select table format.",
+      allowed: ["markdown", "indent"],
+      defaultsTo: "markdown");
 
   final options = parser.parse(args);
   if ((options["preapprove"] == null &&
@@ -262,6 +281,10 @@
     return;
   }
 
+  // Locate gsutil.py.
+  gsutilPy =
+      Platform.script.resolve("../third_party/gsutil/gsutil.py").toFilePath();
+
   // Load the list of bots according to the test matrix.
   final testMatrixPath =
       Platform.script.resolve("bots/test_matrix.json").toFilePath();
@@ -427,7 +450,7 @@
   for (final bot in bots) {
     if (options["preapprove"] != null &&
         changelistBuilds[bot]["status"] != "COMPLETED") {
-      stderr.writeln("error: The try run for $bot isn't complete yet" +
+      stderr.writeln("error: The try run for $bot isn't complete yet: " +
           changelistBuilds[bot]["status"]);
       anyIncomplete = true;
     }
@@ -493,26 +516,38 @@
   int longestBot = "BOT/CONFIG".length;
   int longestTest = "TEST".length;
   int longestResult = "RESULT".length;
+  int longestExpected = "EXPECTED".length;
   for (final test in unapprovedTests) {
     unapprovedBots.add(test.bot);
     final botDisplayName = getBotDisplayName(test.bot, test.configuration);
     longestBot = max(longestBot, botDisplayName.length);
-    if (!test.matches) {
-      longestTest = max(longestTest, test.name.length);
-      longestResult = max(longestResult, test.result.length);
-    }
+    longestTest = max(longestTest, test.name.length);
+    longestResult = max(longestResult, test.result.length);
+    longestExpected = max(longestExpected, test.expected.length);
   }
   longestTest = min(longestTest, 120); // Some tests names are extremely long.
 
   // Table of lists that now succeed.
   if (fixedTests.isNotEmpty) {
     print("The following tests are now succeeding:\n");
-    print("${'BOT/CONFIG'.padRight(longestBot)}  "
-        "TEST");
+    if (options["table"] == "markdown") {
+      print("| ${'BOT/CONFIG'.padRight(longestBot)} "
+          "| ${'TEST'.padRight(longestTest)} |");
+      print("| ${'-' * longestBot} "
+          "| ${'-' * longestTest} |");
+    } else if (options["table"] == "indent") {
+      print("${'BOT/CONFIG'.padRight(longestBot)}  "
+          "TEST");
+    }
     for (final test in fixedTests) {
       final botDisplayName = getBotDisplayName(test.bot, test.configuration);
-      print("${botDisplayName.padRight(longestBot)}  "
-          "${test.name}");
+      if (options["table"] == "markdown") {
+        print("| ${botDisplayName.padRight(longestBot)} "
+            "| ${test.name.padRight(longestTest)} |");
+      } else if (options["table"] == "indent") {
+        print("${botDisplayName.padRight(longestBot)}  "
+            "${test.name}");
+      }
     }
     print("");
   }
@@ -520,16 +555,34 @@
   /// Table of lists that now fail.
   if (brokenTests.isNotEmpty) {
     print("The following tests are now failing:\n");
-    print("${'BOT'.padRight(longestBot)}  "
-        "${'TEST'.padRight(longestTest)}  "
-        "${'RESULT'.padRight(longestResult)}  "
-        "EXPECTED");
+    if (options["table"] == "markdown") {
+      print("| ${'BOT'.padRight(longestBot)} "
+          "| ${'TEST'.padRight(longestTest)} "
+          "| ${'RESULT'.padRight(longestResult)} "
+          "| ${'EXPECTED'.padRight(longestExpected)} | ");
+      print("| ${'-' * longestBot} "
+          "| ${'-' * longestTest} "
+          "| ${'-' * longestResult} "
+          "| ${'-' * longestExpected} | ");
+    } else if (options["table"] == "indent") {
+      print("${'BOT'.padRight(longestBot)}  "
+          "${'TEST'.padRight(longestTest)}  "
+          "${'RESULT'.padRight(longestResult)}  "
+          "EXPECTED");
+    }
     for (final test in brokenTests) {
       final botDisplayName = getBotDisplayName(test.bot, test.configuration);
-      print("${botDisplayName.padRight(longestBot)}  "
-          "${test.name.padRight(longestTest)}  "
-          "${test.result.padRight(longestResult)}  "
-          "${test.expected}");
+      if (options["table"] == "markdown") {
+        print("| ${botDisplayName.padRight(longestBot)} "
+            "| ${test.name.padRight(longestTest)} "
+            "| ${test.result.padRight(longestResult)} "
+            "| ${test.expected.padRight(longestExpected)} |");
+      } else if (options["table"] == "indent") {
+        print("${botDisplayName.padRight(longestBot)}  "
+            "${test.name.padRight(longestTest)}  "
+            "${test.result.padRight(longestResult)}  "
+            "${test.expected}");
+      }
     }
     print("");
   }
@@ -602,9 +655,11 @@
   print("");
 
   // Log who approved these results.
-  final username = Platform.environment["LOGNAME"] ??
-      Platform.environment["USER"] ??
-      Platform.environment["USERNAME"];
+  final username =
+      (options["automated-approver"] ? "automatic-approval" : null) ??
+          Platform.environment["LOGNAME"] ??
+          Platform.environment["USER"] ??
+          Platform.environment["USERNAME"];
   if (username == null || username == "") {
     stderr.writeln("error: Your identity could not be established. "
         "Please set one of the LOGNAME, USER, USERNAME environment variables.");
@@ -629,12 +684,14 @@
     final futures = <Future>[];
     for (final String bot in unapprovedBots) {
       Map<String, dynamic> approveData(Test test) {
-        final data = new Map<String, dynamic>.from(test.resultData);
-        if (!test.isApproved) {
+        if (test.isApproved) {
+          return test.approvedResultData;
+        } else {
+          final data = new Map<String, dynamic>.from(test.resultData);
           data["approver"] = username;
           data["approved_at"] = now;
+          return data;
         }
-        return data;
       }
 
       final dataList = testsForBots[bot].map(approveData).toList();
diff --git a/tools/bots/compare_results.dart b/tools/bots/compare_results.dart
index 11e2f69..c3820a0 100755
--- a/tools/bots/compare_results.dart
+++ b/tools/bots/compare_results.dart
@@ -214,9 +214,9 @@
       help: "Show the old and new result for each test",
       negatable: false);
   parser.addOption("logs",
-      abbr: "l", help: "Path to file holding logs of failing tests.");
+      abbr: "l", help: "Path to file holding logs of failing and flaky tests.");
   parser.addFlag("logs-only",
-      help: "Only print logs of failing tests, no other output",
+      help: "Only print logs of failing and flaky tests, no other output",
       negatable: false);
 
   final options = parser.parse(args);
@@ -347,7 +347,10 @@
       final aboutApproval =
           approvalDescriptions[searchForStatus][searchForApproval];
       final sectionHeader = "The following tests $aboutStatus$aboutApproval:";
-      final logSectionArg = searchForStatus == "failing" ? logSection : null;
+      final logSectionArg =
+          searchForStatus == "failing" || searchForStatus == "flaky"
+              ? logSection
+              : null;
       bool possibleJudgement = search(sectionHeader, searchForStatus,
           searchForApproval, events, options, logs, logSectionArg);
       if ((searchForStatus == null || searchForStatus == "failing") &&
diff --git a/tools/bots/flutter/analyze_flutter.sh b/tools/bots/flutter/analyze_flutter.sh
index 0685c0e..de71818 100755
--- a/tools/bots/flutter/analyze_flutter.sh
+++ b/tools/bots/flutter/analyze_flutter.sh
@@ -7,7 +7,7 @@
 set -e
 
 checkout=$(pwd)
-dart=$checkout/tools/sdks/dart-sdk/bin/dart
+dart=$checkout/out/ReleaseX64/dart-sdk/bin/dart
 sdk=$checkout/out/ReleaseX64/dart-sdk
 tmpdir=$(mktemp -d)
 cleanup() {
@@ -30,4 +30,4 @@
 
 bin/flutter update-packages
 
-$dart dev/bots/analyze.dart --dart-sdk $sdk
+$dart --enable-asserts dev/bots/analyze.dart --dart-sdk $sdk
diff --git a/tools/bots/results.dart b/tools/bots/results.dart
index ec760c5..549cafe 100644
--- a/tools/bots/results.dart
+++ b/tools/bots/results.dart
@@ -8,8 +8,8 @@
 import 'dart:convert';
 import 'dart:io';
 
-/// gsutil.py binary to use.
-final gsutil = Platform.isWindows ? "gsutil.py.bat" : "gsutil.py";
+/// The path to the gsutil script.
+String gsutilPy;
 
 /// Cloud storage location containing results.
 const testResultsStoragePath = "gs://dart-test-results/builders";
@@ -21,15 +21,16 @@
 /// Runs gsutil with the provided [arguments] and returns the standard output.
 /// Returns null if the requested URL didn't exist.
 Future<String> runGsutil(List<String> arguments) async {
-  final processResult = await Process.run(gsutil, arguments,
-      environment: {"DEPOT_TOOLS_UPDATE": "0"});
+  final processResult = await Process.run(
+      "python", [gsutilPy]..addAll(arguments),
+      runInShell: Platform.isWindows);
   if (processResult.exitCode != 0) {
     if (processResult.exitCode == 1 &&
             processResult.stderr.contains("No URLs matched") ||
         processResult.stderr.contains("One or more URLs matched no objects")) {
       return null;
     }
-    throw new Exception("Failed to run: $gsutil $arguments\n"
+    throw new Exception("Failed to run: python $gsutilPy $arguments\n"
         "exitCode: ${processResult.exitCode}\n"
         "stdout:\n${processResult.stdout}\n"
         "stderr:\n${processResult.stderr}");
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 715ce52..863c5af 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -17,6 +17,7 @@
       ".packages",
       "out/ReleaseIA32/dart-sdk/",
       "out/ReleaseX64/dart-sdk/",
+      "out/ReleaseX64/gen/utils/dartdevc/",
       "pkg/",
       "runtime/tests/",
       "samples-dev/",
@@ -41,9 +42,11 @@
       "third_party/observatory_pub_packages/packages/web_components/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
+      "third_party/requirejs/",
       "tools/",
       "xcodebuild/ReleaseIA32/dart-sdk/",
-      "xcodebuild/ReleaseX64/dart-sdk/"
+      "xcodebuild/ReleaseX64/dart-sdk/",
+      "xcodebuild/ReleaseX64/gen/utils/dartdevc/"
     ],
     "dart2js_hostasserts": [
       ".packages",
@@ -76,6 +79,7 @@
       "third_party/d8/",
       "third_party/pkg/",
       "third_party/pkg_tested/",
+      "third_party/requirejs/",
       "tools/",
       "xcodebuild/ReleaseIA32/dart",
       "xcodebuild/ReleaseIA32/dart2js_platform.dill",
@@ -274,13 +278,13 @@
       "options": {
         "vm-options": ["--no-enable-malloc-hooks"]
     }},
-    "dartkp-bare-linux-(debug|release)-x64": {
+    "dartkp-no-bare-linux-(debug|release)-x64": {
       "options": {
-        "vm-options": ["--no-enable-malloc-hooks", "--use-bare-instructions"]
+        "vm-options": ["--no-enable-malloc-hooks", "--no-use-bare-instructions"]
     }},
-    "dartkp-bare-linux-(debug|release)-(simarm|simarm64)": {
+    "dartkp-no-bare-linux-(debug|release)-(simarm|simarm64)": {
       "options": {
-        "vm-options": ["--no-enable-malloc-hooks", "--use-bare-instructions"],
+        "vm-options": ["--no-enable-malloc-hooks", "--no-use-bare-instructions"],
         "use-blobs": true
     }},
     "dartk-(linux|mac)-(debug|release)-(ia32|x64)": { },
@@ -491,7 +495,8 @@
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartkp-android-${mode}-${arch}"
+            "-ndartkp-android-${mode}-${arch}",
+            "-j2"
           ],
           "fileset": "vm-kernel",
           "shards": 15
@@ -552,7 +557,7 @@
         {
           "name": "vm tests",
           "arguments": [
-            "-ndartkp-bare-${system}-${mode}-${arch}"
+            "-ndartkp-no-bare-${system}-${mode}-${arch}"
           ],
           "fileset": "vm-kernel",
           "shards": 10
@@ -763,6 +768,24 @@
           "arguments": ["dart2js_bot", "dartdevc_test"]
         },
         {
+          "name": "ddc co19_2 tests",
+          "arguments": [
+            "-ndartdevc-checked-${system}-release-chrome",
+            "co19_2"
+          ],
+          "shards": 6,
+          "fileset": "dart2js"
+        },
+        {
+          "name": "ddk co19_2 tests",
+          "arguments": [
+            "-ndartdevk-checked-${system}-release-chrome",
+            "co19_2"
+          ],
+          "shards": 6,
+          "fileset": "dart2js"
+        },
+        {
           "name": "ddc tests",
           "arguments": [
             "-ndartdevc-checked-${system}-release-chrome",
@@ -1265,10 +1288,9 @@
         "analyzer-linux-release",
         "analyzer-mac-release",
         "analyzer-win-release",
-        "analyzer-linux-release-analyzer",
-        "analyzer-linux-release-analyzer-new",
-        "analyzer-mac-release-analyzer",
-        "analyzer-win-release-analyzer"
+        "analyzer-linux-release-analyzer-stable",
+        "analyzer-mac-release-analyzer-stable",
+        "analyzer-win-release-analyzer-stable"
       ],
       "meta": {
         "description": "This configuration is used by the analyzer builders."
@@ -1335,7 +1357,7 @@
     {
       "builders": [
         "analyzer-analysis-server-linux",
-        "analyzer-analysis-server-linux-analyzer"
+        "analyzer-analysis-server-linux-analyzer-stable"
       ],
       "meta": {
         "description": "Analyze analyzer related packages."
@@ -1608,7 +1630,7 @@
     {
       "builders": [
         "flutter-analyze",
-        "flutter-analyze-analyzer"
+        "flutter-analyze-analyzer-stable"
       ],
       "meta": {
         "description": "This configuration is used for analyzing flutter."
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 0656f4e3..59a7971 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -194,7 +194,7 @@
     third_party/d8/linux/ia32/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
     out/ReleaseIA32/dart-sdk/bin/dart2js --packages=.packages --out=out.js -m hello.dart
     LD_LIBRARY_PATH=third_party/firefox_jsshell/linux/jsshell/ third_party/firefox_jsshell/linux/jsshell/js -f sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js -f out.js
-    out/ReleaseIA32/dart-sdk/bin/dart2js --trust-type-annotations --trust-primitives --fast-startup --packages=.packages --out=out.js -m hello.dart
+    out/ReleaseIA32/dart-sdk/bin/dart2js --benchmarking-production --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/ia32/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
     out/ReleaseIA32/dart-sdk/bin/dart2js --use-kernel --packages=.packages --out=out.js -m hello.dart
     third_party/d8/linux/ia32/d8 --stack_size=1024 sdk/lib/_internal/js_runtime/lib/preambles/d8.js out.js
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index a63e560..7dbf7aa 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -8033,6 +8033,9 @@
       },
       "createWriter": {},
       "file": {},
+      "fileBlob": {
+        "support_level": "untriaged"
+      },
       "filesystem": {
         "support_level": "untriaged"
       },
@@ -31541,4 +31544,4 @@
     },
     "support_level": "nonstandard"
   }
-}
+}
\ No newline at end of file
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 39736b1..cb81c49 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -741,14 +741,15 @@
 
   def _GetCommonAnnotations(self, interface, member_name=None,
       source_member_name=None):
+    annotations = []
     if member_name:
       key = '%s.%s' % (interface.id, member_name)
       dom_name = '%s.%s' % (interface.javascript_binding_name, member_name)
+      # DomName annotation is needed for dblclick ACX plugin analyzer.
+      if member_name == 'dblclickEvent' or member_name == 'ondblclick':
+        annotations.append("@DomName('" + dom_name + "')")
     else:
       key = interface.id
-      dom_name = interface.javascript_binding_name
-
-    annotations = []
 
     if key in _annotations:
       annotations.extend(_annotations[key])
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 952c629..2ab2be7 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -873,6 +873,8 @@
                            'dynamic', 'dynamic')
 
 dart2js_conversions = monitored.Dict('generator.dart2js_conversions', {
+    # Used to convert Dart function to a JS callback typedef (old style).
+    'Callback set': Conversion('convertDartClosureToJS', 'dynamic', 'dynamic'),
     'Date get':
       Conversion('convertNativeToDart_DateTime', 'dynamic', 'DateTime'),
     'Date set':
@@ -920,6 +922,8 @@
     'any set MessagePort.postMessage': _serialize_SSV,
     'any set Window.postMessage': _serialize_SSV,
     'any set _DOMWindowCrossFrame.postMessage': _serialize_SSV,
+    'any set Worker.postMessage': _serialize_SSV,
+    'any set ServiceWorker.postMessage': _serialize_SSV,
 
     '* get CustomEvent.detail':
       Conversion('convertNativeToDart_SerializedScriptValue',
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 64e9f93..7f7574c6 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -323,7 +323,6 @@
                                              info.operations[0],
                                              info.name,
                                              'call:')
-
     if not method_name:
       if info.name == 'item':
         # FIXME: item should be renamed to operator[], not removed.
@@ -905,24 +904,37 @@
   def _TypeInfo(self, type_name):
     return self._type_registry.TypeInfo(type_name)
 
+  def _CallbackConvert(self, argType, info):
+    if self._database.HasInterface(argType):
+      interface = self._database.GetInterface(argType)
+      if "Callback" in interface.ext_attrs:
+          return interface.ext_attrs['Callback']
+    return None
+
   def _ConvertArgumentTypes(self, stmts_emitter, arguments, argument_count, info):
     temp_version = [0]
     converted_arguments = []
     target_parameters = []
     calling_parameters = []
     for position, arg in enumerate(arguments[:argument_count]):
-      conversion = self._InputConversion(arg.type.id, info.declared_name)
+      callBackInfo = self._CallbackConvert(arg.type.id, info)   # Returns callback arity (# of parameters)
+      if callBackInfo is None:
+        conversion = self._InputConversion(arg.type.id, info.declared_name)
+      else:
+        conversion = self._InputConversion('Callback', info.declared_name)
+
       param_name = arguments[position].id
       if conversion:
         temp_version[0] += 1
         temp_name = '%s_%s' % (param_name, temp_version[0])
         temp_type = conversion.output_type
         stmts_emitter.Emit(
-            '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n',
+            '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n' if callBackInfo is None else '$(INDENT)$TYPE $NAME = $CONVERT($ARG, $ARITY);\n',
             TYPE=TypeOrVar(temp_type),
             NAME=temp_name,
             CONVERT=conversion.function_name,
-            ARG=info.param_infos[position].name)
+            ARG=info.param_infos[position].name,
+            ARITY=callBackInfo)
         converted_arguments.append(temp_name)
         param_type = temp_type
         verified_type = temp_type  # verified by assignment in checked mode.
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 06bd04b..d419464 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -188,6 +188,8 @@
 
 convert_to_future_members = monitored.Set(
   'htmlrenamer.converted_to_future_members', [
+  'Database.changeVersion',
+  'Database.readTransaction',
   'DataTransferItem.getAsString',
   'DirectoryEntry.getDirectory',
   'DirectoryEntry.getFile',
@@ -222,6 +224,9 @@
   'Entry': {
       'getMetadata': [
           'applyExtension(\'Metadata\', value);',
+      ],
+      'getParent': [
+          'applyExtension(\'Entry\', value);',
       ]
   },
   'FileEntry': {
@@ -296,6 +301,7 @@
   'CompositionEvent.initCompositionEvent',
   'CustomEvent.detail',
   'CustomEvent.initCustomEvent',
+  'DataTransferItem.webkitGetAsEntry',
   'DeviceOrientationEvent.initDeviceOrientationEvent',
   'DirectoryEntry.createReader',
   'DirectoryReader.readEntries',
@@ -342,10 +348,14 @@
   'Element.insertAdjacentHTML',
   'Element.scrollIntoView',
   'Element.scrollIntoViewIfNeeded',
-  'Element.removeAttribute',
-  'Element.removeAttributeNS',
+  'Element.getAttribute',
+  'Element.getAttributeNS',
   'Element.hasAttribute',
   'Element.hasAttributeNS',
+  'Element.removeAttribute',
+  'Element.removeAttributeNS',
+  'Element.setAttribute',
+  'Element.setAttributeNS',
   'Element.innerHTML',
   'Element.querySelectorAll',
   # TODO(vsm): These have been converted from int to double in Chrome 36.
@@ -495,19 +505,27 @@
 # Members from the standard dom that exist in the dart:html library with
 # identical functionality but with cleaner names.
 renamed_html_members = monitored.Dict('htmlrenamer.renamed_html_members', {
-    'ConsoleBase.assert': 'assertCondition', 'CSSKeyframesRule.insertRule':
-    'appendRule', 'DirectoryEntry.getDirectory': '_getDirectory',
-    'DirectoryEntry.getFile': '_getFile', 'Document.createCDATASection':
-    'createCDataSection', 'Document.defaultView': 'window', 'Window.CSS': 'css',
+    'ConsoleBase.assert': 'assertCondition',
+    'CSSKeyframesRule.insertRule': 'appendRule',
+    'DirectoryEntry.getDirectory': '_getDirectory',
+    'DirectoryEntry.getFile': '_getFile',
+    'Document.createCDATASection': 'createCDataSection',
+    'Document.defaultView': 'window',
+    'Window.CSS': 'css',
     'Window.webkitNotifications': 'notifications',
     'Window.webkitRequestFileSystem': '_requestFileSystem',
     'Window.webkitResolveLocalFileSystemURL': 'resolveLocalFileSystemUrl',
-    'Navigator.webkitGetUserMedia': '_getUserMedia', 'Node.appendChild':
-    'append', 'Node.cloneNode': 'clone', 'Node.nextSibling': 'nextNode',
-    'Node.parentElement': 'parent', 'Node.previousSibling': 'previousNode',
-    'Node.textContent': 'text', 'SVGElement.className': '_svgClassName',
-    'SVGStopElement.offset': 'gradientOffset', 'URL.createObjectURL':
-    'createObjectUrl', 'URL.revokeObjectURL': 'revokeObjectUrl',
+    'Navigator.webkitGetUserMedia': '_getUserMedia',
+    'Node.appendChild': 'append',
+    'Node.cloneNode': 'clone',
+    'Node.nextSibling': 'nextNode',
+    'Node.parentElement': 'parent',
+    'Node.previousSibling': 'previousNode',
+    'Node.textContent': 'text',
+    'SVGElement.className': '_svgClassName',
+    'SVGStopElement.offset': 'gradientOffset',
+    'URL.createObjectURL': 'createObjectUrl',
+    'URL.revokeObjectURL': 'revokeObjectUrl',
     #'WorkerContext.webkitRequestFileSystem': '_requestFileSystem',
     #'WorkerContext.webkitRequestFileSystemSync': '_requestFileSystemSync',
 
@@ -600,6 +618,7 @@
     'AudioContext.decodeAudioData',
     'AudioBufferSourceNode.looping', # TODO(vsm): Use deprecated IDL annotation
     'CSSStyleDeclaration.getPropertyCSSValue',
+    'HTMLCanvasElement.toBlob',
     'CanvasRenderingContext2D.clearShadow',
     'CanvasRenderingContext2D.drawImageFromRect',
     'CanvasRenderingContext2D.setAlpha',
@@ -727,8 +746,10 @@
     'Element.prepend',
     'Element.removeAttributeNode',
     'Element.set:outerHTML',
+    'Element.setApplyScroll',
     'Element.setAttributeNode',
     'Element.setAttributeNodeNS',
+    'Element.setDistributeScroll',
     'Element.webkitCreateShadowRoot',
     'Element.webkitMatchesSelector',
     'Element.webkitPseudo',
@@ -849,8 +870,6 @@
     'IDBDatabase.transaction', # We do this in a template without the generated implementation at all.
     'Location.valueOf',
     'MessageEvent.data',
-    'MessageEvent.ports',
-    'MessageEvent.webkitInitMessageEvent',
     'MouseEvent.webkitMovementX',
     'MouseEvent.webkitMovementY',
     'MouseEvent.x',
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index b2e06d2..6149474 100644
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -404,7 +404,7 @@
         for annotation in callback_function.annotations:
           callback = callback_function.annotations[annotation]
           cb_interface = IDLInterface(None, callback.name)
-          cb_interface.ext_attrs['Callback'] = None
+          cb_interface.ext_attrs['Callback'] = len(callback.arguments)
           op = IDLOperation(None, cb_interface.id, "handleEvent")
           op.type = IDLType(callback.idl_type)
           op.type = resolveTypedef(op.type)
diff --git a/tools/dom/src/AttributeMap.dart b/tools/dom/src/AttributeMap.dart
index f6a482f..71579e5 100644
--- a/tools/dom/src/AttributeMap.dart
+++ b/tools/dom/src/AttributeMap.dart
@@ -107,11 +107,8 @@
     _element.setAttribute(key, value);
   }
 
-  String remove(Object key) {
-    String value = _element.getAttribute(key);
-    _element._removeAttribute(key);
-    return value;
-  }
+  @pragma('dart2js:tryInline')
+  String remove(Object key) => key is String ? _remove(_element, key) : null;
 
   /**
    * The number of {key, value} pairs in the map.
@@ -121,6 +118,21 @@
   }
 
   bool _matches(_Attr node) => node._namespaceUri == null;
+
+  // 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(
+        // 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)',
+        '#.getAttribute(#)',
+        element,
+        key);
+    JS('', '#.removeAttribute(#)', element, key);
+    return value;
+  }
 }
 
 /**
@@ -143,11 +155,9 @@
     _element.setAttributeNS(_namespace, key, value);
   }
 
-  String remove(Object key) {
-    String value = this[key];
-    _element._removeAttributeNS(_namespace, key);
-    return value;
-  }
+  @pragma('dart2js:tryInline')
+  String remove(Object key) =>
+      key is String ? _remove(_namespace, _element, key) : null;
 
   /**
    * The number of {key, value} pairs in the map.
@@ -157,6 +167,23 @@
   }
 
   bool _matches(_Attr node) => node._namespaceUri == _namespace;
+
+  // Inline this because almost all call sites of [remove] do not use the
+  // 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(
+        // 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)',
+        '#.getAttributeNS(#, #)',
+        element,
+        namespace,
+        key);
+    JS('', '#.removeAttributeNS(#, #)', element, namespace, key);
+    return value;
+  }
 }
 
 /**
diff --git a/tools/dom/src/dart2js_CssClassSet.dart b/tools/dom/src/dart2js_CssClassSet.dart
index c3394aa..098d28f 100644
--- a/tools/dom/src/dart2js_CssClassSet.dart
+++ b/tools/dom/src/dart2js_CssClassSet.dart
@@ -193,9 +193,9 @@
     }
   }
 
-  static void _removeAll(Element _element, Iterable<String> iterable) {
+  static void _removeAll(Element _element, Iterable<Object> iterable) {
     DomTokenList list = _classListOf(_element);
-    for (var value in iterable) {
+    for (String value in iterable) {
       _classListRemove(list, value);
     }
   }
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 436df0a..83a8aa6 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -53,6 +53,7 @@
 import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
 
 export 'dart:math' show Rectangle, Point;
+export 'dart:_internal' show HttpStatus;
 
 $!GENERATED_DART_FILES
 
@@ -161,4 +162,3 @@
     FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
 
 WorkerGlobalScope get _workerSelf => JS('WorkerGlobalScope', 'self');
-
diff --git a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
index 706bc06..29bc8c5 100644
--- a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
@@ -91,6 +91,8 @@
 import 'dart:_foreign_helper' show JS;
 import 'dart:_interceptors' show Interceptor, JSExtendableArray;
 
+import 'dart:_js_helper' show convertDartClosureToJS;
+
 $!GENERATED_DART_FILES
 
 class _KeyRangeFactoryProvider {
diff --git a/tools/dom/templates/html/impl/impl_DataTransferItem.darttemplate b/tools/dom/templates/html/impl/impl_DataTransferItem.darttemplate
new file mode 100644
index 0000000..8294cc1
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_DataTransferItem.darttemplate
@@ -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.
+
+part of $LIBRARYNAME;
+
+$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
+
+  Entry getAsEntry() {
+    Entry entry = _webkitGetAsEntry();
+
+    if (entry.isFile)
+      applyExtension('FileEntry', entry);
+    else if (entry.isDirectory)
+      applyExtension('DirectoryEntry', entry);
+    else
+      applyExtension('Entry', entry);
+
+    return entry;
+  }
+
+$!MEMBERS
+}
diff --git a/tools/dom/templates/html/impl/impl_DirectoryReader.darttemplate b/tools/dom/templates/html/impl/impl_DirectoryReader.darttemplate
index 53bc0ef..06eba12 100644
--- a/tools/dom/templates/html/impl/impl_DirectoryReader.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DirectoryReader.darttemplate
@@ -9,8 +9,16 @@
 
   Future<List<Entry>> readEntries() {
     var completer = new Completer<List<Entry>>();
-    _readEntries((value) {
-      completer.complete(new List<Entry>.from(value));
+    _readEntries((values) {
+      values.forEach((value) {
+        applyExtension('Entry', value);
+        Entry entry = value as Entry;  
+        if (entry.isFile)
+          applyExtension('FileEntry', entry);
+        else if (entry.isDirectory)
+          applyExtension('DirectoryEntry', entry);
+      });
+      completer.complete(new List<Entry>.from(values));
     }, (error) {
       completer.completeError(error);
     });
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 35bd16f..740bc1c 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -563,6 +563,66 @@
     }
   }
 
+  @pragma('dart2js:tryInline')
+  String getAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    return _getAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  String getAttributeNS(String namespaceURI, String name) {
+    // 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');
+    return _getAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  bool hasAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    return _hasAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  bool hasAttributeNS(String namespaceURI, String name) {
+    // 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');
+    return _hasAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void removeAttribute(String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    _removeAttribute(name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void removeAttributeNS(String namespaceURI, String name) {
+    // Protect [name] against string conversion to "null" or "undefined".
+    assert(name != null, 'Attribute name cannot be null');
+    _removeAttributeNS(namespaceURI, name);
+  }
+
+  @pragma('dart2js:tryInline')
+  void setAttribute(String name, String value) {
+    // 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.');
+    _setAttribute(name, value);
+  }
+
+  @pragma('dart2js:tryInline')
+  void setAttributeNS(String namespaceURI, String name, String value) {
+    // 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.');
+    _setAttributeNS(namespaceURI, name, value);
+  }
+
   /**
    * List of the direct children of this element.
    *
@@ -599,6 +659,28 @@
   ElementList<T> querySelectorAll<T extends Element>(String selectors) =>
     new _FrozenElementList<T>._wrap(_querySelectorAll(selectors));
 
+  @JSName('setApplyScroll')
+  void _setApplyScroll(ScrollStateCallback scrollStateCallback, String nativeScrollBehavior) native;
+
+  Future<ScrollState> setApplyScroll(String nativeScrollBehavior) {
+    var completer = new Completer<ScrollState>();
+      _setApplyScroll((value) {
+        completer.complete(value);
+      }, nativeScrollBehavior);
+    return completer.future;
+  }
+
+  @JSName('setDistributeScroll')
+  void _setDistributeScroll(ScrollStateCallback scrollStateCallback, String nativeScrollBehavior) native;
+
+  Future<ScrollState> setDistributeScroll(String nativeScrollBehavior) {
+    var completer = new Completer<ScrollState>();
+      _setDistributeScroll((value) {
+        completer.complete(value);
+      }, nativeScrollBehavior);
+    return completer.future;
+  }
+
   /**
    * The set of CSS classes applied to this element.
    *
diff --git a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
index bfde34a..c935546 100644
--- a/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
+++ b/tools/dom/templates/html/impl/impl_HTMLCanvasElement.darttemplate
@@ -82,4 +82,15 @@
    */
   String toDataUrl([String type = 'image/png', num quality]) =>
       _toDataUrl(type, quality);
+
+  @JSName('toBlob')
+  void _toBlob(BlobCallback callback, String type, [Object arguments]) native;
+
+  Future<Blob> toBlob(String type, [Object arguments]) {
+    var completer = new Completer<Blob>();
+      _toBlob((value) {
+        completer.complete(value);
+      }, type, arguments);
+    return completer.future;
+  }
 }
diff --git a/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg
index 62a45b3..dd1680c 100644
--- a/tools/infra/config/cq.cfg
+++ b/tools/infra/config/cq.cfg
@@ -27,6 +27,7 @@
       builders { name: "dart2js-unit-linux-x64-release-try" }
       builders { name: "ddc-linux-release-chrome-try" }
       builders { name: "front-end-linux-release-x64-try" }
+      builders { name: "gclient-try" }
       builders { name: "pkg-linux-release-try" }
       builders { name: "vm-canary-linux-debug-try" }
       builders { name: "vm-kernel-linux-release-simdbc64-try" }
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
index 458ee6b..b0ef7d7 100644
--- a/tools/patch_sdk.dart
+++ b/tools/patch_sdk.dart
@@ -12,7 +12,11 @@
 import 'dart:math' as math;
 import 'dart:convert' show jsonEncode;
 
-import 'package:analyzer/analyzer.dart';
+// ignore: deprecated_member_use
+import 'package:analyzer/analyzer.dart'
+    show parseCompilationUnit, parseDirectives;
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
 import 'package:path/path.dart' as path;
diff --git a/tools/patches/flutter-engine/apply.sh b/tools/patches/flutter-engine/apply.sh
index b449af1..d1105a5 100755
--- a/tools/patches/flutter-engine/apply.sh
+++ b/tools/patches/flutter-engine/apply.sh
@@ -19,13 +19,13 @@
 # (run inside the root of a flutter engine checkout)
 
 set -e
-if [ ! -e src/third_party/dart ]; then
-  echo "$0: error: "\
-       "This script must be run from the root of a flutter engine checkout" >&2
-  exit 1
-fi
-pinned_dart_sdk=$(grep -E "'dart_revision':.*" src/flutter/DEPS |
-                  sed -E "s/.*'([^']*)',/\1/")
+
+DIR=$(dirname -- "$(which -- "$0")")
+. $DIR/../utils.sh
+
+ensure_in_checkout_root
+
+pinned_dart_sdk=$(get_pinned_dart_version)
 need_runhooks=false
 patch=src/third_party/dart/tools/patches/flutter-engine/${pinned_dart_sdk}.flutter.patch
 if [ -e "$patch" ]; then
diff --git a/tools/patches/flutter-engine/create.sh b/tools/patches/flutter-engine/create.sh
index d9bc6fd..15dad92 100755
--- a/tools/patches/flutter-engine/create.sh
+++ b/tools/patches/flutter-engine/create.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/env bash
 #
 # 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
@@ -15,13 +15,13 @@
 # (run inside the root of a flutter engine checkout)
 
 set -e
-if [ ! -e src/third_party/dart ]; then
-  echo "$0: error: "\
-       "This script must be run from the root of a flutter engine checkout" >&2
-  exit 1
-fi
-pinned_dart_sdk=$(grep -E "'dart_revision':.*" src/flutter/DEPS |
-                  sed -E "s/.*'([^']*)',/\1/")
+
+DIR=$(dirname -- "$(which -- "$0")")
+. $DIR/../utils.sh
+
+ensure_in_checkout_root
+
+pinned_dart_sdk=$(get_pinned_dart_version)
 patch=src/third_party/dart/tools/patches/flutter-engine/$pinned_dart_sdk.patch
 rm -f src/third_party/dart/tools/patches/flutter-engine/*.patch
 (cd src/flutter && git diff) > $patch
diff --git a/tools/patches/flutter-engine/ecd7a88606a4bf896316f56f1b0db6f5469c2623.patch b/tools/patches/flutter-engine/ecd7a88606a4bf896316f56f1b0db6f5469c2623.patch
new file mode 100644
index 0000000..60a8135
--- /dev/null
+++ b/tools/patches/flutter-engine/ecd7a88606a4bf896316f56f1b0db6f5469c2623.patch
@@ -0,0 +1,37 @@
+diff --git a/lib/snapshot/libraries.json b/lib/snapshot/libraries.json
+index a59ae6c66..99ef4cd77 100644
+--- a/lib/snapshot/libraries.json
++++ b/lib/snapshot/libraries.json
+@@ -57,6 +57,14 @@
+         ],
+         "uri": "../../../third_party/dart/sdk/lib/collection/collection.dart"
+       },
++      "ffi": {
++        "patches": [
++          "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart",
++          "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart",
++          "../../../third_party/dart/runtime/lib/ffi_patch.dart"
++        ],
++        "uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
++      },
+       "typed_data": {
+         "patches": "../../../third_party/dart/runtime/lib/typed_data_patch.dart",
+         "uri": "../../../third_party/dart/sdk/lib/typed_data/typed_data.dart"
+diff --git a/lib/snapshot/libraries.yaml b/lib/snapshot/libraries.yaml
+index 26c327705..c4244eaff 100644
+--- a/lib/snapshot/libraries.yaml
++++ b/lib/snapshot/libraries.yaml
+@@ -84,6 +84,13 @@ flutter:
+         - "../../../third_party/dart/runtime/lib/profiler.dart"
+         - "../../../third_party/dart/runtime/lib/timeline.dart"
+ 
++    ffi:
++      uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
++      patches:
++        - "../../../third_party/dart/runtime/lib/ffi_dynamic_library_patch.dart"
++        - "../../../third_party/dart/runtime/lib/ffi_native_type_patch.dart"
++        - "../../../third_party/dart/runtime/lib/ffi_patch.dart"
++
+     _http:
+       uri: "../../../third_party/dart/sdk/lib/_http/http.dart"
+ 
diff --git a/tools/patches/flutter-engine/fdfe40ea95d4e91dc9fc0d6e0a1f5215ab7c4b40.flutter.patch b/tools/patches/flutter-engine/fdfe40ea95d4e91dc9fc0d6e0a1f5215ab7c4b40.flutter.patch
new file mode 100644
index 0000000..e0d443e
--- /dev/null
+++ b/tools/patches/flutter-engine/fdfe40ea95d4e91dc9fc0d6e0a1f5215ab7c4b40.flutter.patch
@@ -0,0 +1,12 @@
+diff --git a/analysis_options.yaml b/analysis_options.yaml
+index 0f3f70d3c..97e5a6453 100644
+--- a/analysis_options.yaml
++++ b/analysis_options.yaml
+@@ -120,7 +120,6 @@ linter:
+     # - parameter_assignments # we do this commonly
+     - prefer_adjacent_string_concatenation
+     - prefer_asserts_in_initializer_lists
+-    - prefer_collection_literals
+     - prefer_conditional_assignment
+     - prefer_const_constructors
+     - prefer_const_constructors_in_immutables
diff --git a/tools/patches/flutter-flutter/15f2b92cce916982b7dd8ce658bbf2a465c06ba4.patch b/tools/patches/flutter-flutter/15f2b92cce916982b7dd8ce658bbf2a465c06ba4.patch
new file mode 100644
index 0000000..00aee00
--- /dev/null
+++ b/tools/patches/flutter-flutter/15f2b92cce916982b7dd8ce658bbf2a465c06ba4.patch
@@ -0,0 +1,59 @@
+diff --git a/packages/flutter/lib/src/painting/text_style.dart b/packages/flutter/lib/src/painting/text_style.dart
+index 821cb475b..c85da65b7 100644
+--- a/packages/flutter/lib/src/painting/text_style.dart
++++ b/packages/flutter/lib/src/painting/text_style.dart
+@@ -822,7 +822,7 @@ class TextStyle extends Diagnosticable {
+       fontStyle: fontStyle,
+       fontFamily: fontFamily,
+       fontSize: (fontSize ?? _defaultFontSize) * textScaleFactor,
+-      lineHeight: height,
++      height: height,
+       maxLines: maxLines,
+       ellipsis: ellipsis,
+       locale: locale,
+diff --git a/packages/flutter/lib/src/rendering/error.dart b/packages/flutter/lib/src/rendering/error.dart
+index 03ab64749..a8552b37b 100644
+--- a/packages/flutter/lib/src/rendering/error.dart
++++ b/packages/flutter/lib/src/rendering/error.dart
+@@ -95,7 +95,7 @@ class RenderErrorBox extends RenderBox {
+ 
+   /// The paragraph style to use when painting [RenderErrorBox] objects.
+   static ui.ParagraphStyle paragraphStyle = ui.ParagraphStyle(
+-    lineHeight: 1.0,
++    height: 1.0,
+   );
+ 
+   @override
+diff --git a/packages/flutter/test/painting/text_style_test.dart b/packages/flutter/test/painting/text_style_test.dart
+index 4d65194e9..f26570aec 100644
+--- a/packages/flutter/test/painting/text_style_test.dart
++++ b/packages/flutter/test/painting/text_style_test.dart
+@@ -169,22 +169,22 @@ void main() {
+     expect(ts2.toString(), 'TextStyle(color: Color(0xff00ff00), decoration: unspecified, decorationColor: unspecified, decorationStyle: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, textBaseline: unspecified, fontFamily: unspecified, fontFamilyFallback: unspecified, fontSize: 10.0, letterSpacing: unspecified, wordSpacing: unspecified, height: 100.0x, locale: unspecified, background: unspecified, foreground: unspecified, shadows: unspecified)');
+ 
+     final ui.ParagraphStyle ps2 = s2.getParagraphStyle(textAlign: TextAlign.center);
+-    expect(ps2, equals(ui.ParagraphStyle(textAlign: TextAlign.center, fontWeight: FontWeight.w800, fontSize: 10.0, lineHeight: 100.0)));
+-    expect(ps2.toString(), 'ParagraphStyle(textAlign: TextAlign.center, textDirection: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 10.0, lineHeight: 100.0x, ellipsis: unspecified, locale: unspecified)');
++    expect(ps2, equals(ui.ParagraphStyle(textAlign: TextAlign.center, fontWeight: FontWeight.w800, fontSize: 10.0, height: 100.0)));
++    expect(ps2.toString(), 'ParagraphStyle(textAlign: TextAlign.center, textDirection: unspecified, fontWeight: FontWeight.w800, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 10.0, height: 100.0x, ellipsis: unspecified, locale: unspecified)');
+     final ui.ParagraphStyle ps5 = s5.getParagraphStyle();
+-    expect(ps5, equals(ui.ParagraphStyle(fontWeight: FontWeight.w700, fontSize: 12.0, lineHeight: 123.0)));
+-    expect(ps5.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 12.0, lineHeight: 123.0x, ellipsis: unspecified, locale: unspecified)');
++    expect(ps5, equals(ui.ParagraphStyle(fontWeight: FontWeight.w700, fontSize: 12.0, height: 123.0)));
++    expect(ps5.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: unspecified, fontWeight: FontWeight.w700, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 12.0, height: 123.0x, ellipsis: unspecified, locale: unspecified)');
+   });
+ 
+ 
+   test('TextStyle with text direction', () {
+     final ui.ParagraphStyle ps6 = const TextStyle().getParagraphStyle(textDirection: TextDirection.ltr);
+     expect(ps6, equals(ui.ParagraphStyle(textDirection: TextDirection.ltr, fontSize: 14.0)));
+-    expect(ps6.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.ltr, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 14.0, lineHeight: unspecified, ellipsis: unspecified, locale: unspecified)');
++    expect(ps6.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.ltr, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 14.0, height: unspecified, ellipsis: unspecified, locale: unspecified)');
+ 
+     final ui.ParagraphStyle ps7 = const TextStyle().getParagraphStyle(textDirection: TextDirection.rtl);
+     expect(ps7, equals(ui.ParagraphStyle(textDirection: TextDirection.rtl, fontSize: 14.0)));
+-    expect(ps7.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.rtl, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 14.0, lineHeight: unspecified, ellipsis: unspecified, locale: unspecified)');
++    expect(ps7.toString(), 'ParagraphStyle(textAlign: unspecified, textDirection: TextDirection.rtl, fontWeight: unspecified, fontStyle: unspecified, maxLines: unspecified, fontFamily: unspecified, fontSize: 14.0, height: unspecified, ellipsis: unspecified, locale: unspecified)');
+   });
+ 
+   test('TextStyle using package font', () {
diff --git a/tools/patches/flutter-flutter/3c118b6c3b42c89f4ef18fce4b27e328f2fd754d.patch b/tools/patches/flutter-flutter/3c118b6c3b42c89f4ef18fce4b27e328f2fd754d.patch
new file mode 100644
index 0000000..acde0c1
--- /dev/null
+++ b/tools/patches/flutter-flutter/3c118b6c3b42c89f4ef18fce4b27e328f2fd754d.patch
@@ -0,0 +1,446 @@
+diff --git a/packages/flutter/test/widgets/text_golden_test.dart b/packages/flutter/test/widgets/text_golden_test.dart
+index 4adb60968..fe08d98e4 100644
+--- a/packages/flutter/test/widgets/text_golden_test.dart
++++ b/packages/flutter/test/widgets/text_golden_test.dart
+@@ -1,440 +1 @@
+-// Copyright 2018 The Chromium Authors. All rights reserved.
+-// Use of this source code is governed by a BSD-style license that can be
+-// found in the LICENSE file.
+-
+-import 'dart:io' show Platform;
+-
+-import 'package:flutter_test/flutter_test.dart';
+-import 'package:flutter/material.dart';
+-import 'package:flutter/widgets.dart';
+-
+-void main() {
+-  testWidgets('Centered text', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text('Hello',
+-              textDirection: TextDirection.ltr,
+-              textAlign: TextAlign.center,
+-              style: TextStyle(color: Color(0xffff0000)),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.Centered.png'),
+-    );
+-
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text('Hello world how are you today',
+-              textDirection: TextDirection.ltr,
+-              textAlign: TextAlign.center,
+-              style: TextStyle(color: Color(0xffff0000)),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.Centered.wrap.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-
+-  testWidgets('Text Foreground', (WidgetTester tester) async {
+-    const Color black = Color(0xFF000000);
+-    const Color red = Color(0xFFFF0000);
+-    const Color blue = Color(0xFF0000FF);
+-    final Shader linearGradient = const LinearGradient(
+-      colors: <Color>[red, blue],
+-    ).createShader(Rect.fromLTWH(0.0, 0.0, 50.0, 20.0));
+-
+-    await tester.pumpWidget(
+-      Align(
+-        alignment: Alignment.topLeft,
+-        child: RepaintBoundary(
+-          child: Text('Hello',
+-            textDirection: TextDirection.ltr,
+-            style: TextStyle(
+-              foreground: Paint()
+-                ..color = black
+-                ..shader = linearGradient
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-
+-    await expectLater(
+-      find.byType(RepaintBoundary),
+-      matchesGoldenFile('text_golden.Foreground.gradient.png'),
+-    );
+-
+-    await tester.pumpWidget(
+-      Align(
+-        alignment: Alignment.topLeft,
+-        child: RepaintBoundary(
+-          child: Text('Hello',
+-            textDirection: TextDirection.ltr,
+-            style: TextStyle(
+-              foreground: Paint()
+-                ..color = black
+-                ..style = PaintingStyle.stroke
+-                ..strokeWidth = 2.0
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-
+-    await expectLater(
+-      find.byType(RepaintBoundary),
+-      matchesGoldenFile('text_golden.Foreground.stroke.png'),
+-    );
+-
+-    await tester.pumpWidget(
+-      Align(
+-        alignment: Alignment.topLeft,
+-        child: RepaintBoundary(
+-          child: Text('Hello',
+-            textDirection: TextDirection.ltr,
+-            style: TextStyle(
+-              foreground: Paint()
+-                ..color = black
+-                ..style = PaintingStyle.stroke
+-                ..strokeWidth = 2.0
+-                ..shader = linearGradient
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-
+-    await expectLater(
+-      find.byType(RepaintBoundary),
+-      matchesGoldenFile('text_golden.Foreground.stroke_and_gradient.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  // TODO(garyq): This test requires an update when the background
+-  // drawing from the beginning of the line bug is fixed. The current
+-  // tested version is not completely correct.
+-  testWidgets('Text Background', (WidgetTester tester) async {
+-    const Color red = Colors.red;
+-    const Color blue = Colors.blue;
+-    const Color translucentGreen = Color(0x5000F000);
+-    const Color translucentDarkRed = Color(0x500F0000);
+-    await tester.pumpWidget(
+-      Align(
+-        alignment: Alignment.topLeft,
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Colors.green,
+-            ),
+-            child: RichText(
+-              textDirection: TextDirection.ltr,
+-              text: TextSpan(
+-                text: 'text1 ',
+-                style: TextStyle(
+-                  color: translucentGreen,
+-                  background: Paint()
+-                    ..color = red.withOpacity(0.5)
+-                ),
+-                children: <TextSpan>[
+-                  TextSpan(
+-                    text: 'text2',
+-                    style: TextStyle(
+-                      color: translucentDarkRed,
+-                      background: Paint()
+-                        ..color = blue.withOpacity(0.5)
+-                    )
+-                  ),
+-                ],
+-              ),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-
+-    await expectLater(
+-      find.byType(RepaintBoundary),
+-      matchesGoldenFile('text_golden.Background.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Text Fade', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-        MaterialApp(
+-          home: Scaffold(
+-            backgroundColor: Colors.transparent,
+-            body: RepaintBoundary(
+-              child: Center(
+-                child: Container(
+-                  width: 200.0,
+-                  height: 200.0,
+-                  color: Colors.green,
+-                  child: Center(
+-                    child: Container(
+-                      width: 100.0,
+-                      color: Colors.blue,
+-                      child: const Text(
+-                        'Pp PPp PPPp PPPPp PPPPpp PPPPppp PPPPppppp ',
+-                        style: TextStyle(color: Colors.black),
+-                        maxLines: 3,
+-                        overflow: TextOverflow.fade,
+-                      ),
+-                    ),
+-                  ),
+-                ),
+-              ),
+-            ),
+-          )
+-        )
+-    );
+-
+-    await expectLater(
+-      find.byType(RepaintBoundary).first,
+-      matchesGoldenFile('text_golden.Fade.1.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Default Strut text', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text('Hello\nLine 2\nLine 3',
+-              textDirection: TextDirection.ltr,
+-              style: TextStyle(),
+-              strutStyle: StrutStyle(),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.StrutDefault.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Strut text 1', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text('Hello\nLine2\nLine3',
+-              textDirection: TextDirection.ltr,
+-              style: TextStyle(),
+-              strutStyle: StrutStyle(
+-                height: 1.5,
+-              ),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.Strut.1.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Strut text 2', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text('Hello\nLine 2\nLine 3',
+-              textDirection: TextDirection.ltr,
+-              style: TextStyle(),
+-              strutStyle: StrutStyle(
+-                height: 1.5,
+-                fontSize: 14,
+-              ),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.Strut.2.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Strut text rich', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 150.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text.rich(
+-              TextSpan(
+-                text: 'Hello\n',
+-                style: TextStyle(
+-                  color: Colors.red,
+-                  fontSize: 30
+-                ),
+-                children: <TextSpan>[
+-                  TextSpan(
+-                    text: 'Second line!\n',
+-                    style: TextStyle(
+-                      fontSize: 5,
+-                      color: Colors.blue,
+-                    ),
+-                  ),
+-                  TextSpan(
+-                    text: 'Third line!\n',
+-                    style: TextStyle(
+-                      fontSize: 25,
+-                      color: Colors.white,
+-                    ),
+-                  ),
+-                ],
+-              ),
+-              textDirection: TextDirection.ltr,
+-              strutStyle: StrutStyle(
+-                fontSize: 14,
+-                height: 1.1,
+-                leading: 0.1,
+-              ),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.Strut.3.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Strut text font fallback', (WidgetTester tester) async {
+-    // Font Fallback
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text('Hello\nLine 2\nLine 3',
+-              textDirection: TextDirection.ltr,
+-              style: TextStyle(),
+-              strutStyle: StrutStyle(
+-                fontFamily: 'FakeFont 1',
+-                fontFamilyFallback: <String>[
+-                  'FakeFont 2',
+-                  'EvilFont 3',
+-                  'Nice Font 4',
+-                  'ahem'
+-                ],
+-                fontSize: 14,
+-              ),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.Strut.4.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-
+-  testWidgets('Strut text rich forceStrutHeight', (WidgetTester tester) async {
+-    await tester.pumpWidget(
+-      Center(
+-        child: RepaintBoundary(
+-          child: Container(
+-            width: 200.0,
+-            height: 100.0,
+-            decoration: const BoxDecoration(
+-              color: Color(0xff00ff00),
+-            ),
+-            child: const Text.rich(
+-              TextSpan(
+-                text: 'Hello\n',
+-                style: TextStyle(
+-                  color: Colors.red,
+-                  fontSize: 30
+-                ),
+-                children: <TextSpan>[
+-                  TextSpan(
+-                    text: 'Second line!\n',
+-                    style: TextStyle(
+-                      fontSize: 9,
+-                      color: Colors.blue,
+-                    ),
+-                  ),
+-                  TextSpan(
+-                    text: 'Third line!\n',
+-                    style: TextStyle(
+-                      fontSize: 27,
+-                      color: Colors.white,
+-                    ),
+-                  ),
+-                ],
+-              ),
+-              textDirection: TextDirection.ltr,
+-              strutStyle: StrutStyle(
+-                fontSize: 14,
+-                height: 1.1,
+-                forceStrutHeight: true,
+-              ),
+-            ),
+-          ),
+-        ),
+-      ),
+-    );
+-    await expectLater(
+-      find.byType(Container),
+-      matchesGoldenFile('text_golden.StrutForce.1.png'),
+-    );
+-  }, skip: !Platform.isLinux);
+-}
++void main() { }
diff --git a/tools/patches/flutter-flutter/apply.sh b/tools/patches/flutter-flutter/apply.sh
new file mode 100755
index 0000000..47043f0
--- /dev/null
+++ b/tools/patches/flutter-flutter/apply.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for 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 applies a patch, if available, to the Flutter Framework. Only a
+# patch is applied for the particular engine.version the flutter framework is
+# using.
+#
+# Usage: src/third_party/dart/tools/patches/flutter-flutter/apply.sh
+# (run inside the root of a flutter checkout)
+
+set -e
+
+DIR=$(dirname -- "$(which -- "$0")")
+. $DIR/../utils.sh
+
+ensure_in_checkout_root
+
+pinned_engine_version=$(get_pinned_flutter_engine_version)
+patch=src/third_party/dart/tools/patches/flutter-flutter/${pinned_engine_version}.patch
+if [ -e "$patch" ]; then
+  (cd flutter && git apply ../$patch)
+fi
diff --git a/tools/patches/flutter-flutter/create.sh b/tools/patches/flutter-flutter/create.sh
new file mode 100755
index 0000000..f0f8511
--- /dev/null
+++ b/tools/patches/flutter-flutter/create.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for 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 produces a patch to the Flutter Framework from the local
+# uncommitted changes in the current engine checkout.
+#
+# Usage: src/third_party/dart/tools/patches/flutter-flutter/create.sh
+# (run inside the root of a flutter engine checkout)
+
+set -e
+
+DIR=$(dirname -- "$(which -- "$0")")
+. $DIR/../utils.sh
+
+ensure_in_checkout_root
+
+pinned_engine_version=$(get_pinned_flutter_engine_version)
+patch=src/third_party/dart/tools/patches/flutter-flutter/$pinned_engine_version.patch
+rm -f src/third_party/dart/tools/patches/flutter-flutter/*.patch
+(cd flutter && git diff) > $patch
+if [ ! -s $patch ]; then
+  rm $patch
+fi
diff --git a/tools/patches/utils.sh b/tools/patches/utils.sh
new file mode 100644
index 0000000..681c707
--- /dev/null
+++ b/tools/patches/utils.sh
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+#
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+die() {
+  echo "$0: error: "\
+       "This script must be run from the root of a flutter engine checkout "\
+       "(containing src/flutter/ and flutter/)" >&2
+  exit 1
+}
+
+ensure_in_checkout_root() {
+  set -e
+  if [ ! -e src/third_party/dart ]; then
+    die
+  fi
+
+  if [ ! -e flutter ]; then
+    die
+  fi
+}
+
+get_pinned_dart_version() {
+  pinned_dart_sdk=$(grep -E "'dart_revision':.*" src/flutter/DEPS |
+                    sed -E "s/.*'([^']*)',/\1/")
+  echo -n $pinned_dart_sdk
+}
+
+get_pinned_flutter_engine_version() {
+  pinned_engine_version=$(cat flutter/bin/internal/engine.version | sed 's/[[:space:]]//')
+  echo -n $pinned_engine_version
+}
diff --git a/tools/test.dart b/tools/test.dart
index cd956ef..ebe3add 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -48,9 +48,10 @@
 }
 
 /// Runs a process and exits likewise if the process exits non-zero.
-Future<ProcessResult> runProcess(
-    String executable, List<String> arguments) async {
-  final processResult = await Process.run(executable, arguments);
+Future<ProcessResult> runProcess(String executable, List<String> arguments,
+    {bool runInShell = false}) async {
+  final processResult =
+      await Process.run(executable, arguments, runInShell: runInShell);
   if (processResult.exitCode != 0) {
     final command =
         ([executable]..addAll(arguments)).map(simpleShellSingleQuote).join(" ");
@@ -63,9 +64,10 @@
 /// Runs a process and exits likewise if the process exits non-zero, but let the
 /// child process inherit out stdio handles.
 Future<ProcessResult> runProcessInheritStdio(
-    String executable, List<String> arguments) async {
+    String executable, List<String> arguments,
+    {bool runInShell = false}) async {
   final process = await Process.start(executable, arguments,
-      mode: ProcessStartMode.inheritStdio);
+      mode: ProcessStartMode.inheritStdio, runInShell: runInShell);
   final exitCode = await process.exitCode;
   final processResult = new ProcessResult(process.pid, exitCode, "", "");
   if (processResult.exitCode != 0) {
@@ -138,7 +140,8 @@
     return commit;
   }
   final arguments = ["merge-base", "$remote/$branch", "HEAD"];
-  final result = await Process.run("git", arguments);
+  final result =
+      await Process.run("git", arguments, runInShell: Platform.isWindows);
   if (result.exitCode != 0) {
     throw new Exception("Failed to run: git ${arguments.join(' ')}\n"
         "stdout:\n${result.stdout}\n"
@@ -204,6 +207,10 @@
     return;
   }
 
+  // Locate gsutil.py.
+  gsutilPy =
+      Platform.script.resolve("../third_party/gsutil/gsutil.py").toFilePath();
+
   final builder = options["builder"];
 
   // Find out where the current HEAD branched.
@@ -273,7 +280,9 @@
       print("".padLeft(80, "="));
       print("$stepName: Running tests");
       print("".padLeft(80, "="));
-      await runProcessInheritStdio("tools/test.py", fullArguments);
+      await runProcessInheritStdio(
+          "python", ["tools/test.py"]..addAll(fullArguments),
+          runInShell: Platform.isWindows);
       stepResultsPaths.add("${stepDirectory.path}/results.json");
       stepLogsPaths.add("${stepDirectory.path}/logs.json");
       // Find the list of tests to deflake.
@@ -309,7 +318,9 @@
             "--test-list=$deflakeListPath",
           ])
           ..addAll(options.rest);
-        await runProcessInheritStdio("tools/test.py", deflakeArguments);
+        await runProcessInheritStdio(
+            "python", ["tools/test.py"]..addAll(deflakeArguments),
+            runInShell: Platform.isWindows);
         deflakingResultsPaths.add("${deflakeDirectory.path}/results.json");
       }
       // Update the flakiness information based on what we've learned.
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index 2db6368..1faea9e 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.dart
@@ -33,6 +33,93 @@
 </html>""";
 }
 
+/// Escape [name] to make it into a valid identifier.
+String _toJSIdentifier(String name) {
+  if (name.length == 0) return r'$';
+
+  // Escape any invalid characters
+  StringBuffer buffer = null;
+  for (int i = 0; i < name.length; i++) {
+    var ch = name[i];
+    var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
+    if (needsEscape && buffer == null) {
+      buffer = StringBuffer(name.substring(0, i));
+    }
+    if (buffer != null) {
+      buffer.write(needsEscape ? '\$${ch.codeUnits.join("")}' : ch);
+    }
+  }
+
+  var result = buffer != null ? '$buffer' : name;
+  // Ensure the identifier first character is not numeric and that the whole
+  // identifier is not a keyword.
+  if (result.startsWith(RegExp('[0-9]')) || _invalidVariableName(result)) {
+    return '\$$result';
+  }
+  return result;
+}
+
+// Invalid characters for identifiers, which would need to be escaped.
+final _invalidCharInIdentifier = RegExp(r'[^A-Za-z_$0-9]');
+
+bool _invalidVariableName(String keyword, {bool strictMode = true}) {
+  switch (keyword) {
+    // http://www.ecma-international.org/ecma-262/6.0/#sec-future-reserved-words
+    case "await":
+
+    case "break":
+    case "case":
+    case "catch":
+    case "class":
+    case "const":
+    case "continue":
+    case "debugger":
+    case "default":
+    case "delete":
+    case "do":
+    case "else":
+    case "enum":
+    case "export":
+    case "extends":
+    case "finally":
+    case "for":
+    case "function":
+    case "if":
+    case "import":
+    case "in":
+    case "instanceof":
+    case "let":
+    case "new":
+    case "return":
+    case "super":
+    case "switch":
+    case "this":
+    case "throw":
+    case "try":
+    case "typeof":
+    case "var":
+    case "void":
+    case "while":
+    case "with":
+      return true;
+    case "arguments":
+    case "eval":
+    // http://www.ecma-international.org/ecma-262/6.0/#sec-future-reserved-words
+    // http://www.ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
+    case "implements":
+    case "interface":
+    case "let":
+    case "package":
+    case "private":
+    case "protected":
+    case "public":
+    case "static":
+    case "yield":
+      return strictMode;
+  }
+  return false;
+}
+
 /// Generates the HTML template file needed to load and run a dartdevc test in
 /// the browser.
 ///
@@ -40,6 +127,7 @@
 /// or extension, like "math_test". The [testJSDir] is the relative path to the
 /// build directory where the dartdevc-generated JS file is stored.
 String dartdevcHtml(String testName, String testJSDir, Compiler compiler) {
+  var testId = _toJSIdentifier(testName);
   var isKernel = compiler == Compiler.dartdevk;
   var sdkPath = isKernel ? 'kernel/amd/dart_sdk' : 'js/amd/dart_sdk';
   var pkgDir = isKernel ? 'pkg_kernel' : 'pkg';
@@ -85,7 +173,7 @@
         src="/root_dart/third_party/requirejs/require.js"></script>
 <script type="text/javascript">
 requirejs(["$testName", "dart_sdk", "async_helper"],
-    function($testName, sdk, async_helper) {  
+    function($testId, sdk, async_helper) {
   sdk.dart.ignoreWhitelistedErrors(false);
   sdk._isolate_helper.startRootIsolate(function() {}, []);
   sdk._debugger.registerDevtoolsFormatter();
@@ -110,8 +198,30 @@
     // lines too.
     return lines.join("\\n");
   };
+
+  let pendingCallbacks = 0;
+  let waitForDone = false;
+
+  sdk.dart.addAsyncCallback = function() {
+    pendingCallbacks++;
+    if (!waitForDone) {
+      // When the first callback is added, signal that test_controller.js
+      // should wait until done.
+      waitForDone = true;
+      dartPrint('unittest-suite-wait-for-done');
+    }
+  };
+
+  sdk.dart.removeAsyncCallback = function() {
+    if (--pendingCallbacks <= 0) {
+      // We might be done with async callbacks. Schedule a microtask to check.
+      Promise.resolve().then(function() {
+        if (pendingCallbacks <= 0) dartPrint('unittest-suite-done');
+      });
+    }
+  };
   
-  dartMainRunner($testName.$testName.main);
+  dartMainRunner($testId.$testId.main);
 });
 </script>
 </body>
diff --git a/tools/testing/dart/command_output.dart b/tools/testing/dart/command_output.dart
index a392933..43caac4 100644
--- a/tools/testing/dart/command_output.dart
+++ b/tools/testing/dart/command_output.dart
@@ -472,7 +472,7 @@
     }
 
     // Handle errors / missing errors
-    if (testCase.expectCompileError) {
+    if (testCase.hasCompileError) {
       if (errors.isNotEmpty) {
         return Expectation.pass;
       }
@@ -629,7 +629,7 @@
     if (hasTimedOut) return Expectation.timeout;
     if (hasNonUtf8) return Expectation.nonUtf8Error;
 
-    if (testCase.expectCompileError) {
+    if (testCase.hasCompileError) {
       if (testCase.hasSyntaxError) {
         // A syntax error is expected.
         return hasSyntaxError
@@ -676,7 +676,7 @@
     if (hasNonUtf8) return Expectation.nonUtf8Error;
 
     // Multitests are handled specially.
-    if (testCase.expectCompileError) {
+    if (testCase.hasCompileError) {
       if (exitCode == _compileErrorExitCode) {
         return Expectation.pass;
       }
@@ -794,7 +794,7 @@
     }
 
     // Multitests are handled specially.
-    if (testCase.expectCompileError) {
+    if (testCase.hasCompileError) {
       // Nonzero exit code of the compiler means compilation failed
       // TODO(kustermann): Do we have a special exit code in that case???
       if (exitCode != 0) {
@@ -836,7 +836,7 @@
     if (hasNonUtf8) return Expectation.nonUtf8Error;
 
     // Handle errors / missing errors
-    if (testCase.expectCompileError) {
+    if (testCase.hasCompileError) {
       return exitCode == 0
           ? Expectation.missingCompileTimeError
           : Expectation.pass;
@@ -897,7 +897,7 @@
     }
 
     // Multitests are handled specially.
-    if (testCase.expectCompileError) {
+    if (testCase.hasCompileError) {
       if (exitCode == VMCommandOutput._compileErrorExitCode ||
           exitCode == kBatchModeCompileTimeErrorExit) {
         return Expectation.pass;
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 58f0143..54dcc46 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -1096,8 +1096,10 @@
     ];
 
     args.add(arguments.where((name) => name.endsWith('.dart')).single);
-    args.addAll(arguments.where(
-        (name) => name.startsWith('-D') || name.startsWith('--packages=')));
+    args.addAll(arguments.where((name) =>
+        name.startsWith('-D') ||
+        name.startsWith('--packages=') ||
+        name.startsWith('--enable-experiment=')));
 
     final bool causalAsyncStacks =
         !arguments.any((String arg) => noCausalAsyncStacksRegExp.hasMatch(arg));
diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
index aa0b4f1..526edff 100644
--- a/tools/testing/dart/configuration.dart
+++ b/tools/testing/dart/configuration.dart
@@ -50,7 +50,6 @@
       this.firefoxPath,
       this.dartPath,
       this.dartPrecompiledPath,
-      this.flutterPath,
       this.taskCount,
       this.shardCount,
       this.shard,
@@ -116,7 +115,6 @@
   bool get useAnalyzerFastaParser => configuration.useAnalyzerFastaParser;
   bool get useBlobs => configuration.useBlobs;
   bool get useSdk => configuration.useSdk;
-  bool get useFastStartup => configuration.useFastStartup;
   bool get useEnableAsserts => configuration.enableAsserts;
   bool get useDart2JSWithKernel => configuration.useDart2JSWithKernel;
   bool get useDart2JSOldFrontend => configuration.useDart2JSOldFrontEnd;
@@ -129,7 +127,6 @@
   final String firefoxPath;
   final String dartPath;
   final String dartPrecompiledPath;
-  final String flutterPath;
   final List<String> testList;
 
   final int taskCount;
@@ -245,7 +242,6 @@
 
     if (isMinified) args.add("--minify");
     if (isCsp) args.add("--csp");
-    if (useFastStartup) args.add("--fast-startup");
     if (useEnableAsserts) args.add("--enable-asserts");
     if (useDart2JSWithKernel) args.add("--use-kernel");
     if (useDart2JSOldFrontend) args.add("--use-old-frontend");
@@ -287,9 +283,6 @@
       case Runtime.firefox:
         location = firefoxPath;
         break;
-      case Runtime.flutter:
-        location = flutterPath;
-        break;
       case Runtime.safari:
         location = safariPath;
         break;
@@ -372,17 +365,6 @@
       isValid = false;
     }
 
-    if (runtime == Runtime.flutter && flutterPath == null) {
-      print("-rflutter requires the flutter engine executable to "
-          "be specified using --flutter");
-      isValid = false;
-    }
-
-    if (runtime == Runtime.flutter && architecture != Architecture.x64) {
-      isValid = false;
-      print("-rflutter is applicable only for --arch=x64");
-    }
-
     return isValid;
   }
 
@@ -463,7 +445,6 @@
         'fasta': usesFasta,
         'use_sdk': useSdk,
         'builder_tag': builderTag,
-        'fast_startup': useFastStartup,
         'timeout': timeout,
         'no_preview_dart_2': noPreviewDart2,
         'use_cfe': useAnalyzerCfe,
diff --git a/tools/testing/dart/environment.dart b/tools/testing/dart/environment.dart
index c06039b..720c72d 100644
--- a/tools/testing/dart/environment.dart
+++ b/tools/testing/dart/environment.dart
@@ -24,7 +24,6 @@
   "dart2js_with_kernel": new _Variable.bool((c) => c.useDart2JSWithKernel),
   "dart2js_old_frontend": new _Variable.bool((c) => c.useDart2JSOldFrontend),
   "enable_asserts": new _Variable.bool((c) => c.useEnableAsserts),
-  "fast_startup": new _Variable.bool((c) => c.useFastStartup),
   "fasta": new _Variable.bool((c) => c.usesFasta),
   "host_checked": new _Variable.bool((c) => c.isHostChecked),
   "host_unchecked": new _Variable.bool((c) => !c.isHostChecked),
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 9247c3b..319c4b8 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -12,9 +12,8 @@
 /// lines of the file, and all of the multitest lines containing that key, in
 /// the same order as in the source file. The new test is expected to pass if
 /// the error type listed is 'ok', and to fail if the error type is 'syntax
-/// error', 'compile-time error', 'runtime error', 'static type warning',
-/// 'dynamic type error', or 'checked mode compile-time error'. The type error
-/// tests fail only in checked mode. There is also a test created from only the
+/// error', 'compile-time error', 'runtime error', or 'static type warning'.
+/// There is also a test created from only the
 /// untagged lines of the file, with key "none", which is expected to pass. This
 /// library extracts these tests, writes them into a temporary directory, and
 /// passes them to the test runner. These tests may be referred to in the status
@@ -64,13 +63,10 @@
 /// eee //# 10: ok
 /// fff
 /// ```
-///
-/// Note that it is possible to indicate more than one acceptable outcome in
-/// the case of dynamic and static type warnings
-///
+//////
 /// ```dart
 /// aaa
-/// ddd //# 07: static type warning, dynamic type error
+/// ddd //# 07: static type warning
 /// fff
 /// ```
 import "dart:async";
@@ -89,9 +85,9 @@
   'compile-time error',
   'runtime error',
   // TODO(rnystrom): Remove these after Dart 1.0 tests are removed.
-  'static type warning',
-  'dynamic type error',
-  'checked mode compile-time error'
+  'static type warning', // This is still a valid analyzer test
+  'dynamic type error', // This is now a no-op
+  'checked mode compile-time error' // This is now a no-op
 ].toSet();
 
 // Note: This function is called directly by:
@@ -222,24 +218,17 @@
       var hasSyntaxError = outcome.contains('syntax error');
       var hasCompileError =
           hasSyntaxError || outcome.contains('compile-time error');
-      var isNegativeIfChecked = outcome.contains('dynamic type error');
-      var hasCompileErrorIfChecked =
-          outcome.contains('checked mode compile-time error');
 
-      if (hotReload) {
-        if (hasCompileError || hasCompileErrorIfChecked) {
-          // Running a test that expects a compilation error with hot reloading
-          // is redundant with a regular run of the test.
-          continue;
-        }
+      if (hotReload && hasCompileError) {
+        // Running a test that expects a compilation error with hot reloading
+        // is redundant with a regular run of the test.
+        continue;
       }
 
       doTest(multitestFilename, filePath,
           hasSyntaxError: hasSyntaxError,
           hasCompileError: hasCompileError,
           hasRuntimeError: hasRuntimeError,
-          isNegativeIfChecked: isNegativeIfChecked,
-          hasCompileErrorIfChecked: hasCompileErrorIfChecked,
           hasStaticWarning: hasStaticWarning,
           multitestKey: key);
     }
diff --git a/tools/testing/dart/options.dart b/tools/testing/dart/options.dart
index b647348..8593b59 100644
--- a/tools/testing/dart/options.dart
+++ b/tools/testing/dart/options.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io';
+import 'dart:convert';
 
 import 'package:smith/smith.dart';
 
@@ -104,7 +105,6 @@
         'runtime',
         '''Where the tests should be run.
 vm:               Run Dart code on the standalone Dart VM.
-flutter:          Run Dart code on the Flutter engine.
 dart_precompiled: Run a precompiled snapshot on the VM without a JIT.
 d8:               Run JavaScript from the command line using v8.
 jsshell:          Run JavaScript from the command line using Firefox js-shell.
@@ -147,8 +147,7 @@
     new _Option(
         'named_configuration',
         '''The named test configuration that supplies the values for all
-test options, specifying how tests should be run. Unimplemented
-currently.''',
+test options, specifying how tests should be run.''',
         abbr: 'n',
         hide: true),
     new _Option.bool('checked', 'Run tests in checked mode.'),
@@ -162,8 +161,6 @@
     new _Option.bool(
         'csp', 'Run tests under Content Security Policy restrictions.',
         hide: true),
-    new _Option.bool('fast_startup', 'Pass the --fast-startup flag to dart2js.',
-        hide: true),
     new _Option.bool('fast_tests',
         'Only run tests that are not marked `Slow` or `Timeout`.'),
     new _Option.bool('enable_asserts',
@@ -238,7 +235,6 @@
         hide: true),
     new _Option.bool('time', 'Print timing information after running tests.'),
     new _Option('dart', 'Path to dart executable.', hide: true),
-    new _Option('flutter', 'Path to flutter executable.', hide: true),
     new _Option('firefox', 'Path to firefox browser executable.', hide: true),
     new _Option('chrome', 'Path to chrome browser executable.', hide: true),
     new _Option('safari', 'Path to safari browser executable.', hide: true),
@@ -294,7 +290,9 @@
     new _Option.int(
         'test_driver_error_port', 'Port for http test driver server errors.',
         defaultsTo: 0, hide: true),
-    new _Option('test_list', 'File containing a list of tests to be executed'),
+    new _Option('test_list', 'File containing a list of tests to be executed',
+        hide: true),
+    new _Option('tests', 'A newline separated list of tests to be executed'),
     new _Option(
         'builder_tag',
         '''Machine specific options that is not captured by the regular test
@@ -343,7 +341,6 @@
     'drt',
     'exclude_suite',
     'firefox',
-    'flutter',
     'local_ip',
     'output_directory',
     'progress',
@@ -506,9 +503,17 @@
     }
 
     // Fetch list of tests to run, if option is present.
-    if (configuration['test_list'] is String) {
-      configuration['test_list_contents'] =
-          File(configuration['test_list'] as String).readAsLinesSync();
+    var testList = configuration['test_list'];
+    if (testList is String) {
+      configuration['test_list_contents'] = File(testList).readAsLinesSync();
+    }
+
+    var tests = configuration['tests'];
+    if (tests is String) {
+      if (configuration.containsKey('test_list_contents')) {
+        _fail('--tests and --test-list cannot be used together');
+      }
+      configuration['test_list_contents'] = LineSplitter.split(tests).toList();
     }
 
     return _createConfigurations(configuration);
@@ -674,7 +679,6 @@
                         data["analyzer_use_fasta_parser"] as bool,
                     useBlobs: data["use_blobs"] as bool,
                     useSdk: data["use_sdk"] as bool,
-                    useFastStartup: data["fast_startup"] as bool,
                     useDart2JSWithKernel: data["dart2js_with_kernel"] as bool,
                     useDart2JSOldFrontEnd: data["dart2js_old_frontend"] as bool,
                     useHotReload: data["hot_reload"] as bool,
@@ -716,7 +720,6 @@
                 firefoxPath: data["firefox"] as String,
                 dartPath: data["dart"] as String,
                 dartPrecompiledPath: data["dart_precompiled"] as String,
-                flutterPath: data["flutter"] as String,
                 keepGeneratedFiles: data["keep_generated_files"] as bool,
                 taskCount: data["tasks"] as int,
                 shardCount: data["shards"] as int,
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 8330b51..af21399 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -44,9 +44,6 @@
       case Runtime.vm:
         return new StandaloneDartRuntimeConfiguration();
 
-      case Runtime.flutter:
-        return new StandaloneFlutterEngineConfiguration();
-
       case Runtime.dartPrecompiled:
         if (configuration.system == System.android) {
           return new DartPrecompiledAdbRuntimeConfiguration(
@@ -231,27 +228,6 @@
   }
 }
 
-/// The flutter engine binary, "sky_shell".
-class StandaloneFlutterEngineConfiguration extends DartVmRuntimeConfiguration {
-  List<Command> computeRuntimeCommands(
-      TestSuite suite,
-      CommandArtifact artifact,
-      List<String> arguments,
-      Map<String, String> environmentOverrides,
-      bool isCrashExpected) {
-    String script = artifact.filename;
-    String type = artifact.mimeType;
-    if (script != null &&
-        type != 'application/dart' &&
-        type != 'application/dart-snapshot') {
-      throw "Flutter Engine cannot run files of type '$type'.";
-    }
-    String executable = suite.flutterEngineBinaryFileName;
-    var args = <String>['--non-interactive']..addAll(arguments);
-    return [Command.vm(executable, args, environmentOverrides)];
-  }
-}
-
 class DartPrecompiledRuntimeConfiguration extends DartVmRuntimeConfiguration {
   final bool useBlobs;
   DartPrecompiledRuntimeConfiguration({bool useBlobs}) : useBlobs = useBlobs;
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index c5a69ec..1a0d7ae 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -31,12 +31,6 @@
       'archs': ['ia32'],
       'compiler': 'dart2js'
     },
-    {
-      'runtimes': ['flutter_engine'],
-      'modes': ['debug', 'release'],
-      'archs': ['x64'],
-      'compiler': 'none'
-    },
   ],
   'windows': [
     {
diff --git a/tools/testing/dart/test_controller.js b/tools/testing/dart/test_controller.js
index 9335407..8a82fce 100644
--- a/tools/testing/dart/test_controller.js
+++ b/tools/testing/dart/test_controller.js
@@ -72,13 +72,6 @@
   }
 }
 
-function printToDOM(message) {
-  var pre = document.createElement('pre');
-  pre.appendChild(document.createTextNode(String(message)));
-  document.body.appendChild(pre);
-  document.body.appendChild(document.createTextNode('\n'));
-}
-
 function printToConsole(message) {
   var consoleAvailable = typeof console === 'object';
 
@@ -110,11 +103,6 @@
   notifyDone('FAIL');
 };
 
-// testRunner is provided by content shell.
-// It is not available in browser tests.
-var testRunner = window.testRunner || window.layoutTestController;
-var isContentShell = testRunner;
-
 var waitForDone = false;
 
 var driverWindowCached = false;
@@ -173,13 +161,7 @@
   // If we are not using the browser controller (e.g. in the none-drt
   // configuration), we need to print 'testOutcome' as it is.
   if (isDone && !usingBrowserController()) {
-    if (isContentShell) {
-      // We need this, since test.dart is looking for 'FAIL\n', 'PASS\n' in the
-      // DOM output of content shell.
-      printToDOM(testOutcome);
-    } else {
-      printToConsole('Test outcome: ' + testOutcome);
-    }
+    printToConsole('Test outcome: ' + testOutcome);
   } else if (usingBrowserController()) {
     // To support in browser launching of tests we post back start and result
     // messages to the window.opener.
@@ -201,9 +183,6 @@
           is_done: isDone
         }), '*');
   }
-  if (isDone) {
-    if (testRunner) testRunner.notifyDone();
-  }
 }
 
 function notifyDone(testOutcome) {
@@ -228,13 +207,6 @@
   if (typeof msg != 'string') return;
   if (msg == 'unittest-suite-wait-for-done') {
     waitForDone = true;
-    if (testRunner) {
-      testRunner.startedDartTest = true;
-    }
-  } else if (msg == 'dart-calling-main') {
-    if (testRunner) {
-      testRunner.startedDartTest = true;
-    }
   } else if (msg == 'dart-main-done') {
     if (!waitForDone) {
       notifyDone('PASS');
@@ -251,10 +223,6 @@
   processMessage(e.data);
 }
 
-if (testRunner) {
-  testRunner.dumpAsText();
-  testRunner.waitUntilDone();
-}
 window.addEventListener('message', onReceive, false);
 
 function onLoad(e) {
diff --git a/tools/testing/dart/test_progress.dart b/tools/testing/dart/test_progress.dart
index e56e891..29117e8 100644
--- a/tools/testing/dart/test_progress.dart
+++ b/tools/testing/dart/test_progress.dart
@@ -613,18 +613,15 @@
 
   final ranAllCommands = test.commandOutputs.length == test.commands.length;
   if (!test.lastCommandOutput.hasTimedOut) {
-    if (!ranAllCommands && !test.expectCompileError) {
+    if (!ranAllCommands && !test.hasCompileError) {
       output.write('Unexpected compile error.');
     } else {
-      if (test.expectCompileError) {
+      if (test.hasCompileError) {
         output.write('Missing expected compile error.');
       }
       if (test.hasRuntimeError) {
         output.write('Missing expected runtime error.');
       }
-      if (test.configuration.isChecked && test.isNegativeIfChecked) {
-        output.write('Missing expected dynamic type error.');
-      }
     }
   }
 }
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 2081403..1b1d03a 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -76,14 +76,10 @@
  */
 class TestCase extends UniqueObject {
   // Flags set in _expectations from the optional argument info.
-  static final int IS_NEGATIVE = 1 << 0;
-  static final int HAS_RUNTIME_ERROR = 1 << 1;
-  static final int HAS_STATIC_WARNING = 1 << 2;
-  static final int IS_NEGATIVE_IF_CHECKED = 1 << 3;
-  static final int HAS_SYNTAX_ERROR = 1 << 4;
-  static final int HAS_COMPILE_ERROR = 1 << 5;
-  static final int HAS_COMPILE_ERROR_IF_CHECKED = 1 << 6;
-  static final int EXPECT_COMPILE_ERROR = 1 << 7;
+  static final int HAS_RUNTIME_ERROR = 1 << 0;
+  static final int HAS_SYNTAX_ERROR = 1 << 1;
+  static final int HAS_COMPILE_ERROR = 1 << 2;
+  static final int HAS_STATIC_WARNING = 1 << 3;
   /**
    * A list of commands to execute. Most test cases have a single command.
    * Dart2js tests have two commands, one to compile the source and another
@@ -102,13 +98,10 @@
 
   TestCase(this.displayName, this.commands, this.configuration,
       this.expectedOutcomes,
-      {bool isNegative: false, TestInformation info}) {
+      {TestInformation info}) {
     // A test case should do something.
     assert(commands.isNotEmpty);
 
-    if (isNegative || displayName.contains("negative_test")) {
-      _expectations |= IS_NEGATIVE;
-    }
     if (info != null) {
       _setExpectations(info);
       hash = info.originTestPath.relativeTo(Repository.dir).toString().hashCode;
@@ -119,20 +112,11 @@
     // We don't want to keep the entire (large) TestInformation structure,
     // so we copy the needed bools into flags set in a single integer.
     if (info.hasRuntimeError) _expectations |= HAS_RUNTIME_ERROR;
-    if (info.hasStaticWarning) _expectations |= HAS_STATIC_WARNING;
-    if (info.isNegativeIfChecked) _expectations |= IS_NEGATIVE_IF_CHECKED;
     if (info.hasSyntaxError) _expectations |= HAS_SYNTAX_ERROR;
     if (info.hasCompileError || info.hasSyntaxError) {
       _expectations |= HAS_COMPILE_ERROR;
     }
-    if (info.hasCompileErrorIfChecked) {
-      _expectations |= HAS_COMPILE_ERROR_IF_CHECKED;
-    }
-    if (info.hasCompileError ||
-        info.hasSyntaxError ||
-        (configuration.isChecked && info.hasCompileErrorIfChecked)) {
-      _expectations |= EXPECT_COMPILE_ERROR;
-    }
+    if (info.hasStaticWarning) _expectations |= HAS_STATIC_WARNING;
   }
 
   TestCase indexedCopy(int index) {
@@ -143,15 +127,14 @@
       ..hash = hash;
   }
 
-  bool get isNegative => _expectations & IS_NEGATIVE != 0;
   bool get hasRuntimeError => _expectations & HAS_RUNTIME_ERROR != 0;
   bool get hasStaticWarning => _expectations & HAS_STATIC_WARNING != 0;
-  bool get isNegativeIfChecked => _expectations & IS_NEGATIVE_IF_CHECKED != 0;
   bool get hasSyntaxError => _expectations & HAS_SYNTAX_ERROR != 0;
   bool get hasCompileError => _expectations & HAS_COMPILE_ERROR != 0;
-  bool get hasCompileErrorIfChecked =>
-      _expectations & HAS_COMPILE_ERROR_IF_CHECKED != 0;
-  bool get expectCompileError => _expectations & EXPECT_COMPILE_ERROR != 0;
+  bool get isNegative =>
+      hasCompileError ||
+      hasRuntimeError && configuration.runtime != Runtime.none ||
+      displayName.contains("negative_test");
 
   bool get unexpectedOutput {
     var outcome = this.result;
@@ -163,19 +146,27 @@
   Expectation get result => lastCommandOutput.result(this);
   Expectation get realResult => lastCommandOutput.realResult(this);
   Expectation get realExpected {
-    if (isNegative || (isNegativeIfChecked && configuration.isChecked)) {
-      return Expectation.fail;
-    }
     if (configuration.compiler == Compiler.specParser) {
       if (hasSyntaxError) {
         return Expectation.syntaxError;
       }
-    } else if ((hasCompileError) ||
-        (hasCompileErrorIfChecked && configuration.isChecked)) {
+    } else if (hasCompileError) {
+      if (hasRuntimeError && configuration.runtime != Runtime.none) {
+        return Expectation.fail;
+      }
       return Expectation.compileTimeError;
     }
-    if (configuration.runtime != Runtime.none && hasRuntimeError) {
-      return Expectation.runtimeError;
+    if (hasRuntimeError) {
+      if (configuration.runtime != Runtime.none) {
+        return Expectation.runtimeError;
+      }
+      return Expectation.pass;
+    }
+    if (displayName.contains("negative_test")) {
+      return Expectation.fail;
+    }
+    if (configuration.compiler == Compiler.dart2analyzer && hasStaticWarning) {
+      return Expectation.staticWarning;
     }
     return Expectation.pass;
   }
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 3afc50e..2bf1708 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -47,8 +47,6 @@
     {bool hasSyntaxError,
     bool hasCompileError,
     bool hasRuntimeError,
-    bool isNegativeIfChecked,
-    bool hasCompileErrorIfChecked,
     bool hasStaticWarning,
     String multitestKey});
 
@@ -185,14 +183,6 @@
         : '$buildDir/dart$executableBinarySuffix';
   }
 
-  /// Returns the name of the flutter engine executable.
-  String get flutterEngineBinaryFileName {
-    // Controlled by user with the option "--flutter".
-    var flutterExecutable = configuration.flutterPath;
-    TestUtils.ensureExists(flutterExecutable, configuration);
-    return flutterExecutable;
-  }
-
   String get dartPrecompiledBinaryFileName {
     // Controlled by user with the option "--dart_precompiled".
     var dartExecutable = configuration.dartPrecompiledPath;
@@ -287,8 +277,7 @@
     var negative = info != null ? isNegative(info) : false;
     var testCase = new TestCase(
         displayName, commands, configuration, expectations,
-        isNegative: negative, info: info);
-
+        info: info);
     if (negative &&
         configuration.runtimeConfiguration.shouldSkipNegativeTests) {
       return;
@@ -314,8 +303,7 @@
     if (configuration.hotReload || configuration.hotReloadRollback) {
       // Handle reload special cases.
       if (expectations.contains(Expectation.compileTimeError) ||
-          testCase.hasCompileError ||
-          testCase.expectCompileError) {
+          testCase.hasCompileError) {
         // Running a test that expects a compilation error with hot reloading
         // is redundant with a regular run of the test.
         return;
@@ -345,22 +333,9 @@
     doTest(testCase);
   }
 
-  bool expectCompileError(TestInformation info) {
-    return info.hasCompileError ||
-        (configuration.isChecked && info.hasCompileErrorIfChecked);
-  }
-
-  bool isNegative(TestInformation info) {
-    if (info.hasRuntimeError && configuration.runtime != Runtime.none) {
-      return true;
-    }
-
-    if (info.isNegativeIfChecked && configuration.isChecked) {
-      return true;
-    }
-
-    return expectCompileError(info);
-  }
+  bool isNegative(TestInformation info) =>
+      info.hasCompileError ||
+      info.hasRuntimeError && configuration.runtime != Runtime.none;
 
   String createGeneratedTestDirectoryHelper(
       String name, String dirname, Path testPath) {
@@ -531,8 +506,6 @@
   bool hasSyntaxError;
   bool hasCompileError;
   bool hasRuntimeError;
-  bool isNegativeIfChecked;
-  bool hasCompileErrorIfChecked;
   bool hasStaticWarning;
   String multitestKey;
 
@@ -543,8 +516,6 @@
       this.hasSyntaxError,
       this.hasCompileError,
       this.hasRuntimeError,
-      this.isNegativeIfChecked,
-      this.hasCompileErrorIfChecked,
       this.hasStaticWarning,
       {this.multitestKey: ''}) {
     assert(filePath.isAbsolute);
@@ -784,7 +755,7 @@
       }
     }
     if (configuration.compilerConfiguration.hasCompiler &&
-        expectCompileError(info)) {
+        info.hasCompileError) {
       // If a compile-time error is expected, and we're testing a
       // compiler, we never need to attempt to run the program (in a
       // browser or otherwise).
@@ -875,7 +846,7 @@
       commands.addAll(compilationArtifact.commands);
     }
 
-    if (expectCompileError(info) &&
+    if (info.hasCompileError &&
         compilerConfiguration.hasCompiler &&
         !compilerConfiguration.runRuntimeDespiteMissingCompileTimeError) {
       // Do not attempt to run the compiled result. A compilation
@@ -908,21 +879,11 @@
         {bool hasSyntaxError,
         bool hasCompileError,
         bool hasRuntimeError,
-        bool isNegativeIfChecked: false,
-        bool hasCompileErrorIfChecked: false,
         bool hasStaticWarning: false,
         String multitestKey}) {
       // Cache the test information for each test case.
-      var info = new TestInformation(
-          filePath,
-          originTestPath,
-          optionsFromFile,
-          hasSyntaxError,
-          hasCompileError,
-          hasRuntimeError,
-          isNegativeIfChecked,
-          hasCompileErrorIfChecked,
-          hasStaticWarning,
+      var info = new TestInformation(filePath, originTestPath, optionsFromFile,
+          hasSyntaxError, hasCompileError, hasRuntimeError, hasStaticWarning,
           multitestKey: multitestKey);
       cachedTests.add(info);
       enqueueTestCaseFromTestInformation(info);
diff --git a/tools/write_dartdoc_options_file.py b/tools/write_dartdoc_options_file.py
new file mode 100755
index 0000000..44f0278
--- /dev/null
+++ b/tools/write_dartdoc_options_file.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import argparse
+import sys
+import utils
+
+def ParseArgs(args):
+  args = args[1:]
+  parser = argparse.ArgumentParser(
+      description='A script to write a custom dartdoc_options.yaml to a file')
+
+  parser.add_argument('--output', '-o',
+      type=str,
+      required=True,
+      help='File to write')
+
+  return parser.parse_args(args)
+
+
+def Main(argv):
+  args = ParseArgs(argv)
+  # TODO(jcollins-g): switch to version numbers when github has its tags synced
+  revision = utils.GetGitRevision()
+  if revision is None:
+    revision = 'master'
+  output = '''dartdoc:
+  categoryOrder: ["Core", "VM", "Web"]
+  linkToSource:
+    root: '.'
+    uriTemplate: 'https://github.com/dart-lang/sdk/blob/%s/sdk/%%f%%#L%%l%%'
+''' % revision
+  with open(args.output, 'w') as f:
+    f.write(output)
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(Main(sys.argv))